Home | History | Annotate | Line # | Download | only in dev
cgd.c revision 1.114.4.6
      1 /* $NetBSD: cgd.c,v 1.114.4.6 2017/04/29 10:50:46 pgoyette Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 2002 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Roland C. Dowdeswell.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 #include <sys/cdefs.h>
     33 __KERNEL_RCSID(0, "$NetBSD: cgd.c,v 1.114.4.6 2017/04/29 10:50:46 pgoyette Exp $");
     34 
     35 #include <sys/types.h>
     36 #include <sys/param.h>
     37 #include <sys/systm.h>
     38 #include <sys/proc.h>
     39 #include <sys/errno.h>
     40 #include <sys/buf.h>
     41 #include <sys/bufq.h>
     42 #include <sys/malloc.h>
     43 #include <sys/module.h>
     44 #include <sys/pool.h>
     45 #include <sys/ioctl.h>
     46 #include <sys/device.h>
     47 #include <sys/disk.h>
     48 #include <sys/disklabel.h>
     49 #include <sys/fcntl.h>
     50 #include <sys/namei.h> /* for pathbuf */
     51 #include <sys/vnode.h>
     52 #include <sys/conf.h>
     53 #include <sys/syslog.h>
     54 
     55 #include <dev/dkvar.h>
     56 #include <dev/cgdvar.h>
     57 
     58 #include <miscfs/specfs/specdev.h> /* for v_rdev */
     59 
     60 #include "ioconf.h"
     61 
     62 struct selftest_params {
     63 	const char *alg;
     64 	int blocksize;	/* number of bytes */
     65 	int secsize;
     66 	daddr_t blkno;
     67 	int keylen;	/* number of bits */
     68 	int txtlen;	/* number of bytes */
     69 	const uint8_t *key;
     70 	const uint8_t *ptxt;
     71 	const uint8_t *ctxt;
     72 };
     73 
     74 /* Entry Point Functions */
     75 
     76 static dev_type_open(cgdopen);
     77 static dev_type_close(cgdclose);
     78 static dev_type_read(cgdread);
     79 static dev_type_write(cgdwrite);
     80 static dev_type_ioctl(cgdioctl);
     81 static dev_type_strategy(cgdstrategy);
     82 static dev_type_dump(cgddump);
     83 static dev_type_size(cgdsize);
     84 
     85 const struct bdevsw cgd_bdevsw = {
     86 	DEVSW_MODULE_INIT
     87 	.d_open = cgdopen,
     88 	.d_close = cgdclose,
     89 	.d_strategy = cgdstrategy,
     90 	.d_ioctl = cgdioctl,
     91 	.d_dump = cgddump,
     92 	.d_psize = cgdsize,
     93 	.d_discard = nodiscard,
     94 	.d_flag = D_DISK
     95 };
     96 
     97 const struct cdevsw cgd_cdevsw = {
     98 	DEVSW_MODULE_INIT
     99 	.d_open = cgdopen,
    100 	.d_close = cgdclose,
    101 	.d_read = cgdread,
    102 	.d_write = cgdwrite,
    103 	.d_ioctl = cgdioctl,
    104 	.d_stop = nostop,
    105 	.d_tty = notty,
    106 	.d_poll = nopoll,
    107 	.d_mmap = nommap,
    108 	.d_kqfilter = nokqfilter,
    109 	.d_discard = nodiscard,
    110 	.d_flag = D_DISK
    111 };
    112 
    113 /*
    114  * Vector 5 from IEEE 1619/D16 truncated to 64 bytes, blkno 1.
    115  */
    116 static const uint8_t selftest_aes_xts_256_ptxt[64] = {
    117 	0x27, 0xa7, 0x47, 0x9b, 0xef, 0xa1, 0xd4, 0x76,
    118 	0x48, 0x9f, 0x30, 0x8c, 0xd4, 0xcf, 0xa6, 0xe2,
    119 	0xa9, 0x6e, 0x4b, 0xbe, 0x32, 0x08, 0xff, 0x25,
    120 	0x28, 0x7d, 0xd3, 0x81, 0x96, 0x16, 0xe8, 0x9c,
    121 	0xc7, 0x8c, 0xf7, 0xf5, 0xe5, 0x43, 0x44, 0x5f,
    122 	0x83, 0x33, 0xd8, 0xfa, 0x7f, 0x56, 0x00, 0x00,
    123 	0x05, 0x27, 0x9f, 0xa5, 0xd8, 0xb5, 0xe4, 0xad,
    124 	0x40, 0xe7, 0x36, 0xdd, 0xb4, 0xd3, 0x54, 0x12,
    125 };
    126 
    127 static const uint8_t selftest_aes_xts_256_ctxt[512] = {
    128 	0x26, 0x4d, 0x3c, 0xa8, 0x51, 0x21, 0x94, 0xfe,
    129 	0xc3, 0x12, 0xc8, 0xc9, 0x89, 0x1f, 0x27, 0x9f,
    130 	0xef, 0xdd, 0x60, 0x8d, 0x0c, 0x02, 0x7b, 0x60,
    131 	0x48, 0x3a, 0x3f, 0xa8, 0x11, 0xd6, 0x5e, 0xe5,
    132 	0x9d, 0x52, 0xd9, 0xe4, 0x0e, 0xc5, 0x67, 0x2d,
    133 	0x81, 0x53, 0x2b, 0x38, 0xb6, 0xb0, 0x89, 0xce,
    134 	0x95, 0x1f, 0x0f, 0x9c, 0x35, 0x59, 0x0b, 0x8b,
    135 	0x97, 0x8d, 0x17, 0x52, 0x13, 0xf3, 0x29, 0xbb,
    136 };
    137 
    138 static const uint8_t selftest_aes_xts_256_key[33] = {
    139 	0x27, 0x18, 0x28, 0x18, 0x28, 0x45, 0x90, 0x45,
    140 	0x23, 0x53, 0x60, 0x28, 0x74, 0x71, 0x35, 0x26,
    141 	0x31, 0x41, 0x59, 0x26, 0x53, 0x58, 0x97, 0x93,
    142 	0x23, 0x84, 0x62, 0x64, 0x33, 0x83, 0x27, 0x95,
    143 	0
    144 };
    145 
    146 /*
    147  * Vector 11 from IEEE 1619/D16 truncated to 64 bytes, blkno 0xffff.
    148  */
    149 static const uint8_t selftest_aes_xts_512_ptxt[64] = {
    150 	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    151 	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
    152 	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
    153 	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
    154 	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
    155 	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
    156 	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
    157 	0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
    158 };
    159 
    160 static const uint8_t selftest_aes_xts_512_ctxt[64] = {
    161 	0x77, 0xa3, 0x12, 0x51, 0x61, 0x8a, 0x15, 0xe6,
    162 	0xb9, 0x2d, 0x1d, 0x66, 0xdf, 0xfe, 0x7b, 0x50,
    163 	0xb5, 0x0b, 0xad, 0x55, 0x23, 0x05, 0xba, 0x02,
    164 	0x17, 0xa6, 0x10, 0x68, 0x8e, 0xff, 0x7e, 0x11,
    165 	0xe1, 0xd0, 0x22, 0x54, 0x38, 0xe0, 0x93, 0x24,
    166 	0x2d, 0x6d, 0xb2, 0x74, 0xfd, 0xe8, 0x01, 0xd4,
    167 	0xca, 0xe0, 0x6f, 0x20, 0x92, 0xc7, 0x28, 0xb2,
    168 	0x47, 0x85, 0x59, 0xdf, 0x58, 0xe8, 0x37, 0xc2,
    169 };
    170 
    171 static const uint8_t selftest_aes_xts_512_key[65] = {
    172 	0x27, 0x18, 0x28, 0x18, 0x28, 0x45, 0x90, 0x45,
    173 	0x23, 0x53, 0x60, 0x28, 0x74, 0x71, 0x35, 0x26,
    174 	0x62, 0x49, 0x77, 0x57, 0x24, 0x70, 0x93, 0x69,
    175 	0x99, 0x59, 0x57, 0x49, 0x66, 0x96, 0x76, 0x27,
    176 	0x31, 0x41, 0x59, 0x26, 0x53, 0x58, 0x97, 0x93,
    177 	0x23, 0x84, 0x62, 0x64, 0x33, 0x83, 0x27, 0x95,
    178 	0x02, 0x88, 0x41, 0x97, 0x16, 0x93, 0x99, 0x37,
    179 	0x51, 0x05, 0x82, 0x09, 0x74, 0x94, 0x45, 0x92,
    180 	0
    181 };
    182 
    183 const struct selftest_params selftests[] = {
    184 	{
    185 		.alg = "aes-xts",
    186 		.blocksize = 16,
    187 		.secsize = 512,
    188 		.blkno = 1,
    189 		.keylen = 256,
    190 		.txtlen = sizeof(selftest_aes_xts_256_ptxt),
    191 		.key  = selftest_aes_xts_256_key,
    192 		.ptxt = selftest_aes_xts_256_ptxt,
    193 		.ctxt = selftest_aes_xts_256_ctxt
    194 	},
    195 	{
    196 		.alg = "aes-xts",
    197 		.blocksize = 16,
    198 		.secsize = 512,
    199 		.blkno = 0xffff,
    200 		.keylen = 512,
    201 		.txtlen = sizeof(selftest_aes_xts_512_ptxt),
    202 		.key  = selftest_aes_xts_512_key,
    203 		.ptxt = selftest_aes_xts_512_ptxt,
    204 		.ctxt = selftest_aes_xts_512_ctxt
    205 	}
    206 };
    207 
    208 static int cgd_match(device_t, cfdata_t, void *);
    209 static void cgd_attach(device_t, device_t, void *);
    210 static int cgd_detach(device_t, int);
    211 static struct cgd_softc	*cgd_spawn(int, device_t *);
    212 static int cgd_destroy(device_t);
    213 
    214 /* Internal Functions */
    215 
    216 static int	cgd_diskstart(device_t, struct buf *);
    217 static void	cgdiodone(struct buf *);
    218 static int	cgd_dumpblocks(device_t, void *, daddr_t, int);
    219 
    220 static int	cgd_ioctl_set(struct cgd_softc *, void *, struct lwp *);
    221 static int	cgd_ioctl_clr(struct cgd_softc *, struct lwp *);
    222 static int	cgd_ioctl_get(dev_t, void *, struct lwp *);
    223 static int	cgdinit(struct cgd_softc *, const char *, struct vnode *,
    224 			struct lwp *);
    225 static void	cgd_cipher(struct cgd_softc *, void *, void *,
    226 			   size_t, daddr_t, size_t, int);
    227 
    228 static struct dkdriver cgddkdriver = {
    229         .d_minphys  = minphys,
    230         .d_open = cgdopen,
    231         .d_close = cgdclose,
    232         .d_strategy = cgdstrategy,
    233         .d_iosize = NULL,
    234         .d_diskstart = cgd_diskstart,
    235         .d_dumpblocks = cgd_dumpblocks,
    236         .d_lastclose = NULL
    237 };
    238 
    239 CFATTACH_DECL3_NEW(cgd, sizeof(struct cgd_softc),
    240     cgd_match, cgd_attach, cgd_detach, NULL, NULL, NULL, DVF_DETACH_SHUTDOWN);
    241 extern struct cfdriver cgd_cd;
    242 
    243 /* DIAGNOSTIC and DEBUG definitions */
    244 
    245 #if defined(CGDDEBUG) && !defined(DEBUG)
    246 #define DEBUG
    247 #endif
    248 
    249 #ifdef DEBUG
    250 int cgddebug = 0;
    251 
    252 #define CGDB_FOLLOW	0x1
    253 #define CGDB_IO	0x2
    254 #define CGDB_CRYPTO	0x4
    255 
    256 #define IFDEBUG(x,y)		if (cgddebug & (x)) y
    257 #define DPRINTF(x,y)		IFDEBUG(x, printf y)
    258 #define DPRINTF_FOLLOW(y)	DPRINTF(CGDB_FOLLOW, y)
    259 
    260 static void	hexprint(const char *, void *, int);
    261 
    262 #else
    263 #define IFDEBUG(x,y)
    264 #define DPRINTF(x,y)
    265 #define DPRINTF_FOLLOW(y)
    266 #endif
    267 
    268 #ifdef DIAGNOSTIC
    269 #define DIAGPANIC(x)		panic x
    270 #define DIAGCONDPANIC(x,y)	if (x) panic y
    271 #else
    272 #define DIAGPANIC(x)
    273 #define DIAGCONDPANIC(x,y)
    274 #endif
    275 
    276 /* Global variables */
    277 
    278 /* Utility Functions */
    279 
    280 #define CGDUNIT(x)		DISKUNIT(x)
    281 #define GETCGD_SOFTC(_cs, x, _dv)			\
    282 	if (((_cs) = getcgd_softc(x, &_dv)) == NULL) {	\
    283 		return ENXIO;				\
    284 	}
    285 
    286 /* The code */
    287 
    288 /*
    289  * Lookup the device and return it's softc.  If the device doesn't
    290  * exist, spawn it.
    291  *
    292  * In either case, the device is "acquired", and must be "released"
    293  * by the caller after it is finished with the softc.
    294  */
    295 static struct cgd_softc *
    296 getcgd_softc(dev_t dev, device_t *self)
    297 {
    298 	int	unit = CGDUNIT(dev);
    299 	struct cgd_softc *sc;
    300 
    301 	DPRINTF_FOLLOW(("getcgd_softc(0x%"PRIx64"): unit = %d\n", dev, unit));
    302 
    303 	*self = device_lookup_acquire(&cgd_cd, unit);
    304 
    305 	if (*self == NULL) {
    306 		sc = cgd_spawn(unit, self);
    307 	} else {
    308 		sc = device_private(*self);
    309 	}
    310 
    311 	return sc;
    312 }
    313 
    314 static int
    315 cgd_match(device_t self, cfdata_t cfdata, void *aux)
    316 {
    317 
    318 	return 1;
    319 }
    320 
    321 static void
    322 cgd_attach(device_t parent, device_t self, void *aux)
    323 {
    324 	struct cgd_softc *sc;
    325 
    326 	sc = device_private(self);
    327 
    328 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_BIO);
    329 	dk_init(&sc->sc_dksc, self, DKTYPE_CGD);
    330 	disk_init(&sc->sc_dksc.sc_dkdev, sc->sc_dksc.sc_xname, &cgddkdriver);
    331 
    332 	if (!pmf_device_register(self, NULL, NULL))
    333 		aprint_error_dev(self,
    334 		    "unable to register power management hooks\n");
    335 }
    336 
    337 
    338 /*
    339  * The caller must hold a reference to the device's localcount.
    340  */
    341 static int
    342 cgd_detach(device_t self, int flags)
    343 {
    344 	int ret;
    345 	const int pmask = 1 << RAW_PART;
    346 	struct cgd_softc *sc = device_private(self);
    347 	struct dk_softc *dksc = &sc->sc_dksc;
    348 
    349 	if (DK_BUSY(dksc, pmask))
    350 		return EBUSY;
    351 
    352 	if (DK_ATTACHED(dksc) &&
    353 	    (ret = cgd_ioctl_clr(sc, curlwp)) != 0)
    354 		return ret;
    355 
    356 	disk_destroy(&dksc->sc_dkdev);
    357 	mutex_destroy(&sc->sc_lock);
    358 
    359 	return 0;
    360 }
    361 
    362 void
    363 cgdattach(int num)
    364 {
    365 	int error;
    366 
    367 	error = config_cfattach_attach(cgd_cd.cd_name, &cgd_ca);
    368 	if (error != 0)
    369 		aprint_error("%s: unable to register cfattach\n",
    370 		    cgd_cd.cd_name);
    371 }
    372 
    373 static struct cgd_softc *
    374 cgd_spawn(int unit, device_t *self)
    375 {
    376 	cfdata_t cf;
    377 	struct cgd_softc *sc;
    378 
    379 	cf = malloc(sizeof(*cf), M_DEVBUF, M_WAITOK);
    380 	cf->cf_name = cgd_cd.cd_name;
    381 	cf->cf_atname = cgd_cd.cd_name;
    382 	cf->cf_unit = unit;
    383 	cf->cf_fstate = FSTATE_STAR;
    384 
    385 	if (config_attach_pseudo(cf) == NULL)
    386 		return NULL;
    387 
    388 	if ((*self = device_lookup_acquire(&cgd_cd, unit)) == NULL)
    389 		return NULL;
    390 	else {
    391 		/*
    392 		 * Note that we return while still holding a reference
    393 		 * to the device!
    394 		 */
    395 		sc = device_private(*self);
    396 		return sc;
    397 	}
    398 }
    399 
    400 static int
    401 cgd_destroy(device_t dev)
    402 {
    403 	int error;
    404 	cfdata_t cf;
    405 
    406 	cf = device_cfdata(dev);
    407 	error = config_detach_release(dev, DETACH_QUIET);
    408 	if (error == 0)
    409 		free(cf, M_DEVBUF);
    410 
    411 	return error;
    412 }
    413 
    414 static int
    415 cgdopen(dev_t dev, int flags, int fmt, struct lwp *l)
    416 {
    417 	device_t self;
    418 	int	error;
    419 	struct	cgd_softc *cs;
    420 
    421 	DPRINTF_FOLLOW(("cgdopen(0x%"PRIx64", %d)\n", dev, flags));
    422 	GETCGD_SOFTC(cs, dev, self);
    423 	error = dk_open(&cs->sc_dksc, dev, flags, fmt, l);
    424 	device_release(self);
    425 	return error;
    426 }
    427 
    428 static int
    429 cgdclose(dev_t dev, int flags, int fmt, struct lwp *l)
    430 {
    431 	int error;
    432 	device_t self;
    433 	struct	cgd_softc *cs;
    434 	struct	dk_softc *dksc;
    435 
    436 	DPRINTF_FOLLOW(("cgdclose(0x%"PRIx64", %d)\n", dev, flags));
    437 	GETCGD_SOFTC(cs, dev, self);
    438 	dksc = &cs->sc_dksc;
    439 	if ((error =  dk_close(dksc, dev, flags, fmt, l)) != 0) {
    440 		device_release(self);
    441 		return error;
    442 	}
    443 
    444 	if (!DK_ATTACHED(dksc)) {
    445 		if ((error = cgd_destroy(cs->sc_dksc.sc_dev)) != 0) {
    446 			aprint_error_dev(dksc->sc_dev,
    447 			    "unable to detach instance\n");
    448 		}
    449 		return error;
    450 	}
    451 
    452 	/* Unit is still attached - just return */
    453 	device_release(self);
    454 	return 0;
    455 }
    456 
    457 static void
    458 cgdstrategy(struct buf *bp)
    459 {
    460 	device_t self;
    461 	struct	cgd_softc *cs = getcgd_softc(bp->b_dev, &self);
    462 
    463 	DPRINTF_FOLLOW(("cgdstrategy(%p): b_bcount = %ld\n", bp,
    464 	    (long)bp->b_bcount));
    465 
    466 	if (!cs) {
    467 		bp->b_error = ENXIO;
    468 		goto bail;
    469 	}
    470 
    471 	/*
    472 	 * Reject unaligned writes.
    473 	 */
    474 	if (((uintptr_t)bp->b_data & 3) != 0) {
    475 		bp->b_error = EINVAL;
    476 		goto bail;
    477 	}
    478 
    479 	dk_strategy(&cs->sc_dksc, bp);
    480 	device_release(self);
    481 	return;
    482 
    483 bail:
    484 	bp->b_resid = bp->b_bcount;
    485 	biodone(bp);
    486 	if (self)
    487 		device_release(self);
    488 	return;
    489 }
    490 
    491 static int
    492 cgdsize(dev_t dev)
    493 {
    494 	int retval;
    495 	device_t self;
    496 	struct cgd_softc *cs = getcgd_softc(dev, &self);
    497 
    498 	DPRINTF_FOLLOW(("cgdsize(0x%"PRIx64")\n", dev));
    499 	if (!cs)
    500 		retval = -1;
    501 	else
    502 		retval = dk_size(&cs->sc_dksc, dev);
    503 
    504 	device_release(self);
    505 	return retval;
    506 }
    507 
    508 /*
    509  * cgd_{get,put}data are functions that deal with getting a buffer
    510  * for the new encrypted data.  We have a buffer per device so that
    511  * we can ensure that we can always have a transaction in flight.
    512  * We use this buffer first so that we have one less piece of
    513  * malloc'ed data at any given point.
    514  */
    515 
    516 static void *
    517 cgd_getdata(struct dk_softc *dksc, unsigned long size)
    518 {
    519 	struct	cgd_softc *cs = (struct cgd_softc *)dksc;
    520 	void *	data = NULL;
    521 
    522 	mutex_enter(&cs->sc_lock);
    523 	if (cs->sc_data_used == 0) {
    524 		cs->sc_data_used = 1;
    525 		data = cs->sc_data;
    526 	}
    527 	mutex_exit(&cs->sc_lock);
    528 
    529 	if (data)
    530 		return data;
    531 
    532 	return malloc(size, M_DEVBUF, M_NOWAIT);
    533 }
    534 
    535 static void
    536 cgd_putdata(struct dk_softc *dksc, void *data)
    537 {
    538 	struct	cgd_softc *cs = (struct cgd_softc *)dksc;
    539 
    540 	if (data == cs->sc_data) {
    541 		mutex_enter(&cs->sc_lock);
    542 		cs->sc_data_used = 0;
    543 		mutex_exit(&cs->sc_lock);
    544 	} else {
    545 		free(data, M_DEVBUF);
    546 	}
    547 }
    548 
    549 static int
    550 cgd_diskstart(device_t dev, struct buf *bp)
    551 {
    552 	struct	cgd_softc *cs = device_private(dev);
    553 	struct	dk_softc *dksc = &cs->sc_dksc;
    554 	struct	disk_geom *dg = &dksc->sc_dkdev.dk_geom;
    555 	struct	buf *nbp;
    556 	void *	addr;
    557 	void *	newaddr;
    558 	daddr_t	bn;
    559 	struct	vnode *vp;
    560 
    561 	DPRINTF_FOLLOW(("cgd_diskstart(%p, %p)\n", dksc, bp));
    562 
    563 	bn = bp->b_rawblkno;
    564 
    565 	/*
    566 	 * We attempt to allocate all of our resources up front, so that
    567 	 * we can fail quickly if they are unavailable.
    568 	 */
    569 	nbp = getiobuf(cs->sc_tvn, false);
    570 	if (nbp == NULL)
    571 		return EAGAIN;
    572 
    573 	/*
    574 	 * If we are writing, then we need to encrypt the outgoing
    575 	 * block into a new block of memory.
    576 	 */
    577 	newaddr = addr = bp->b_data;
    578 	if ((bp->b_flags & B_READ) == 0) {
    579 		newaddr = cgd_getdata(dksc, bp->b_bcount);
    580 		if (!newaddr) {
    581 			putiobuf(nbp);
    582 			return EAGAIN;
    583 		}
    584 		cgd_cipher(cs, newaddr, addr, bp->b_bcount, bn,
    585 		    dg->dg_secsize, CGD_CIPHER_ENCRYPT);
    586 	}
    587 
    588 	nbp->b_data = newaddr;
    589 	nbp->b_flags = bp->b_flags;
    590 	nbp->b_oflags = bp->b_oflags;
    591 	nbp->b_cflags = bp->b_cflags;
    592 	nbp->b_iodone = cgdiodone;
    593 	nbp->b_proc = bp->b_proc;
    594 	nbp->b_blkno = btodb(bn * dg->dg_secsize);
    595 	nbp->b_bcount = bp->b_bcount;
    596 	nbp->b_private = bp;
    597 
    598 	BIO_COPYPRIO(nbp, bp);
    599 
    600 	if ((nbp->b_flags & B_READ) == 0) {
    601 		vp = nbp->b_vp;
    602 		mutex_enter(vp->v_interlock);
    603 		vp->v_numoutput++;
    604 		mutex_exit(vp->v_interlock);
    605 	}
    606 	VOP_STRATEGY(cs->sc_tvn, nbp);
    607 
    608 	return 0;
    609 }
    610 
    611 static void
    612 cgdiodone(struct buf *nbp)
    613 {
    614 	device_t self;
    615 	struct	buf *obp = nbp->b_private;
    616 	struct	cgd_softc *cs = getcgd_softc(obp->b_dev, &self);
    617 	struct	dk_softc *dksc = &cs->sc_dksc;
    618 	struct	disk_geom *dg = &dksc->sc_dkdev.dk_geom;
    619 	daddr_t	bn;
    620 
    621 	KDASSERT(cs);
    622 
    623 	DPRINTF_FOLLOW(("cgdiodone(%p)\n", nbp));
    624 	DPRINTF(CGDB_IO, ("cgdiodone: bp %p bcount %d resid %d\n",
    625 	    obp, obp->b_bcount, obp->b_resid));
    626 	DPRINTF(CGDB_IO, (" dev 0x%"PRIx64", nbp %p bn %" PRId64
    627 	    " addr %p bcnt %d\n", nbp->b_dev, nbp, nbp->b_blkno, nbp->b_data,
    628 		nbp->b_bcount));
    629 	if (nbp->b_error != 0) {
    630 		obp->b_error = nbp->b_error;
    631 		DPRINTF(CGDB_IO, ("%s: error %d\n", dksc->sc_xname,
    632 		    obp->b_error));
    633 	}
    634 
    635 	/* Perform the decryption if we are reading.
    636 	 *
    637 	 * Note: use the blocknumber from nbp, since it is what
    638 	 *       we used to encrypt the blocks.
    639 	 */
    640 
    641 	if (nbp->b_flags & B_READ) {
    642 		bn = dbtob(nbp->b_blkno) / dg->dg_secsize;
    643 		cgd_cipher(cs, obp->b_data, obp->b_data, obp->b_bcount,
    644 		    bn, dg->dg_secsize, CGD_CIPHER_DECRYPT);
    645 	}
    646 
    647 	/* If we allocated memory, free it now... */
    648 	if (nbp->b_data != obp->b_data)
    649 		cgd_putdata(dksc, nbp->b_data);
    650 
    651 	putiobuf(nbp);
    652 
    653 	/* Request is complete for whatever reason */
    654 	obp->b_resid = 0;
    655 	if (obp->b_error != 0)
    656 		obp->b_resid = obp->b_bcount;
    657 
    658 	dk_done(dksc, obp);
    659 	device_release(self);
    660 
    661 	dk_start(dksc, NULL);
    662 }
    663 
    664 static int
    665 cgd_dumpblocks(device_t dev, void *va, daddr_t blkno, int nblk)
    666 {
    667 	struct cgd_softc *sc = device_private(dev);
    668 	struct dk_softc *dksc = &sc->sc_dksc;
    669 	struct disk_geom *dg = &dksc->sc_dkdev.dk_geom;
    670 	size_t nbytes, blksize;
    671 	void *buf;
    672 	int error;
    673 
    674 	/*
    675 	 * dk_dump gives us units of disklabel sectors.  Everything
    676 	 * else in cgd uses units of diskgeom sectors.  These had
    677 	 * better agree; otherwise we need to figure out how to convert
    678 	 * between them.
    679 	 */
    680 	KASSERTMSG((dg->dg_secsize == dksc->sc_dkdev.dk_label->d_secsize),
    681 	    "diskgeom secsize %"PRIu32" != disklabel secsize %"PRIu32,
    682 	    dg->dg_secsize, dksc->sc_dkdev.dk_label->d_secsize);
    683 	blksize = dg->dg_secsize;
    684 
    685 	/*
    686 	 * Compute the number of bytes in this request, which dk_dump
    687 	 * has `helpfully' converted to a number of blocks for us.
    688 	 */
    689 	nbytes = nblk*blksize;
    690 
    691 	/* Try to acquire a buffer to store the ciphertext.  */
    692 	buf = cgd_getdata(dksc, nbytes);
    693 	if (buf == NULL)
    694 		/* Out of memory: give up.  */
    695 		return ENOMEM;
    696 
    697 	/* Encrypt the caller's data into the temporary buffer.  */
    698 	cgd_cipher(sc, buf, va, nbytes, blkno, blksize, CGD_CIPHER_ENCRYPT);
    699 
    700 	/* Pass it on to the underlying disk device.  */
    701 	error = bdev_dump(sc->sc_tdev, blkno, buf, nbytes);
    702 
    703 	/* Release the buffer.  */
    704 	cgd_putdata(dksc, buf);
    705 
    706 	/* Return any error from the underlying disk device.  */
    707 	return error;
    708 }
    709 
    710 /* XXX: we should probably put these into dksubr.c, mostly */
    711 static int
    712 cgdread(dev_t dev, struct uio *uio, int flags)
    713 {
    714 	device_t self;
    715 	int	error;
    716 	struct	cgd_softc *cs;
    717 	struct	dk_softc *dksc;
    718 
    719 	DPRINTF_FOLLOW(("cgdread(0x%llx, %p, %d)\n",
    720 	    (unsigned long long)dev, uio, flags));
    721 	GETCGD_SOFTC(cs, dev, self);
    722 	dksc = &cs->sc_dksc;
    723 	if (!DK_ATTACHED(dksc)) {
    724 		device_release(self);
    725 		return ENXIO;
    726 	}
    727 	error = physio(cgdstrategy, NULL, dev, B_READ, minphys, uio);
    728 	device_release(self);
    729 	return error;
    730 }
    731 
    732 /* XXX: we should probably put these into dksubr.c, mostly */
    733 static int
    734 cgdwrite(dev_t dev, struct uio *uio, int flags)
    735 {
    736 	device_t self;
    737 	int	error;
    738 	struct	cgd_softc *cs;
    739 	struct	dk_softc *dksc;
    740 
    741 	DPRINTF_FOLLOW(("cgdwrite(0x%"PRIx64", %p, %d)\n", dev, uio, flags));
    742 	GETCGD_SOFTC(cs, dev, self);
    743 	dksc = &cs->sc_dksc;
    744 	if (!DK_ATTACHED(dksc)) {
    745 		device_release(self);
    746 		return ENXIO;
    747 	}
    748 	error = physio(cgdstrategy, NULL, dev, B_WRITE, minphys, uio);
    749 	device_release(self);
    750 	return error;
    751 }
    752 
    753 static int
    754 cgdioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
    755 {
    756 	device_t self;
    757 	struct	cgd_softc *cs;
    758 	struct	dk_softc *dksc;
    759 	int	part = DISKPART(dev);
    760 	int	pmask = 1 << part;
    761 	int	error = 0;
    762 
    763 	DPRINTF_FOLLOW(("cgdioctl(0x%"PRIx64", %ld, %p, %d, %p)\n",
    764 	    dev, cmd, data, flag, l));
    765 
    766 	switch (cmd) {
    767 	case CGDIOCGET:
    768 		return cgd_ioctl_get(dev, data, l);
    769 	case CGDIOCSET:
    770 	case CGDIOCCLR:
    771 		if ((flag & FWRITE) == 0)
    772 			return EBADF;
    773 		/* FALLTHROUGH */
    774 	default:
    775 		GETCGD_SOFTC(cs, dev, self);
    776 		dksc = &cs->sc_dksc;
    777 		break;
    778 	}
    779 
    780 	switch (cmd) {
    781 	case CGDIOCSET:
    782 		if (DK_ATTACHED(dksc))
    783 			error = EBUSY;
    784 		else
    785 			error = cgd_ioctl_set(cs, data, l);
    786 		break;
    787 	case CGDIOCCLR:
    788 		if (DK_BUSY(&cs->sc_dksc, pmask))
    789 			error = EBUSY;
    790 		else
    791 			error = cgd_ioctl_clr(cs, l);
    792 		break;
    793 	case DIOCGCACHE:
    794 	case DIOCCACHESYNC:
    795 		if (!DK_ATTACHED(dksc))
    796 			return ENOENT;
    797 		/*
    798 		 * We pass this call down to the underlying disk.
    799 		 */
    800 		else
    801 			error = VOP_IOCTL(cs->sc_tvn, cmd, data, flag,
    802 			    l->l_cred);
    803 		break;
    804 	case DIOCGSTRATEGY:
    805 	case DIOCSSTRATEGY:
    806 		if (!DK_ATTACHED(dksc)) {
    807 			error = ENOENT;
    808 			break;
    809 		}
    810 		/*FALLTHROUGH*/
    811 	default:
    812 		error = dk_ioctl(dksc, dev, cmd, data, flag, l);
    813 		break;
    814 	case CGDIOCGET:
    815 		KASSERT(0);
    816 		error = EINVAL;
    817 		break;
    818 	}
    819 	device_release(self);
    820 	return error;
    821 }
    822 
    823 static int
    824 cgddump(dev_t dev, daddr_t blkno, void *va, size_t size)
    825 {
    826 	device_t self;
    827 	int	error;
    828 	struct	cgd_softc *cs;
    829 
    830 	DPRINTF_FOLLOW(("cgddump(0x%"PRIx64", %" PRId64 ", %p, %lu)\n",
    831 	    dev, blkno, va, (unsigned long)size));
    832 	GETCGD_SOFTC(cs, dev, self);
    833 	error = dk_dump(&cs->sc_dksc, dev, blkno, va, size);
    834 	device_release(self);
    835 	return error;
    836 }
    837 
    838 /*
    839  * XXXrcd:
    840  *  for now we hardcode the maximum key length.
    841  */
    842 #define MAX_KEYSIZE	1024
    843 
    844 static const struct {
    845 	const char *n;
    846 	int v;
    847 	int d;
    848 } encblkno[] = {
    849 	{ "encblkno",  CGD_CIPHER_CBC_ENCBLKNO8, 1 },
    850 	{ "encblkno8", CGD_CIPHER_CBC_ENCBLKNO8, 1 },
    851 	{ "encblkno1", CGD_CIPHER_CBC_ENCBLKNO1, 8 },
    852 };
    853 
    854 /* ARGSUSED */
    855 static int
    856 cgd_ioctl_set(struct cgd_softc *cs, void *data, struct lwp *l)
    857 {
    858 	struct	 cgd_ioctl *ci = data;
    859 	struct	 vnode *vp;
    860 	int	 ret;
    861 	size_t	 i;
    862 	size_t	 keybytes;			/* key length in bytes */
    863 	const char *cp;
    864 	struct pathbuf *pb;
    865 	char	 *inbuf;
    866 	struct dk_softc *dksc = &cs->sc_dksc;
    867 
    868 	cp = ci->ci_disk;
    869 
    870 	ret = pathbuf_copyin(ci->ci_disk, &pb);
    871 	if (ret != 0) {
    872 		return ret;
    873 	}
    874 	ret = dk_lookup(pb, l, &vp);
    875 	pathbuf_destroy(pb);
    876 	if (ret != 0) {
    877 		return ret;
    878 	}
    879 
    880 	inbuf = malloc(MAX_KEYSIZE, M_TEMP, M_WAITOK);
    881 
    882 	if ((ret = cgdinit(cs, cp, vp, l)) != 0)
    883 		goto bail;
    884 
    885 	(void)memset(inbuf, 0, MAX_KEYSIZE);
    886 	ret = copyinstr(ci->ci_alg, inbuf, 256, NULL);
    887 	if (ret)
    888 		goto bail;
    889 	cs->sc_cfuncs = cryptfuncs_find(inbuf);
    890 	if (!cs->sc_cfuncs) {
    891 		ret = EINVAL;
    892 		goto bail;
    893 	}
    894 
    895 	(void)memset(inbuf, 0, MAX_KEYSIZE);
    896 	ret = copyinstr(ci->ci_ivmethod, inbuf, MAX_KEYSIZE, NULL);
    897 	if (ret)
    898 		goto bail;
    899 
    900 	for (i = 0; i < __arraycount(encblkno); i++)
    901 		if (strcmp(encblkno[i].n, inbuf) == 0)
    902 			break;
    903 
    904 	if (i == __arraycount(encblkno)) {
    905 		ret = EINVAL;
    906 		goto bail;
    907 	}
    908 
    909 	keybytes = ci->ci_keylen / 8 + 1;
    910 	if (keybytes > MAX_KEYSIZE) {
    911 		ret = EINVAL;
    912 		goto bail;
    913 	}
    914 
    915 	(void)memset(inbuf, 0, MAX_KEYSIZE);
    916 	ret = copyin(ci->ci_key, inbuf, keybytes);
    917 	if (ret)
    918 		goto bail;
    919 
    920 	cs->sc_cdata.cf_blocksize = ci->ci_blocksize;
    921 	cs->sc_cdata.cf_mode = encblkno[i].v;
    922 	cs->sc_cdata.cf_keylen = ci->ci_keylen;
    923 	cs->sc_cdata.cf_priv = cs->sc_cfuncs->cf_init(ci->ci_keylen, inbuf,
    924 	    &cs->sc_cdata.cf_blocksize);
    925 	if (cs->sc_cdata.cf_blocksize > CGD_MAXBLOCKSIZE) {
    926 	    log(LOG_WARNING, "cgd: Disallowed cipher with blocksize %zu > %u\n",
    927 		cs->sc_cdata.cf_blocksize, CGD_MAXBLOCKSIZE);
    928 	    cs->sc_cdata.cf_priv = NULL;
    929 	}
    930 
    931 	/*
    932 	 * The blocksize is supposed to be in bytes. Unfortunately originally
    933 	 * it was expressed in bits. For compatibility we maintain encblkno
    934 	 * and encblkno8.
    935 	 */
    936 	cs->sc_cdata.cf_blocksize /= encblkno[i].d;
    937 	(void)explicit_memset(inbuf, 0, MAX_KEYSIZE);
    938 	if (!cs->sc_cdata.cf_priv) {
    939 		ret = EINVAL;		/* XXX is this the right error? */
    940 		goto bail;
    941 	}
    942 	free(inbuf, M_TEMP);
    943 
    944 	bufq_alloc(&dksc->sc_bufq, "fcfs", 0);
    945 
    946 	cs->sc_data = malloc(MAXPHYS, M_DEVBUF, M_WAITOK);
    947 	cs->sc_data_used = 0;
    948 
    949 	/* Attach the disk. */
    950 	dk_attach(dksc);
    951 	disk_attach(&dksc->sc_dkdev);
    952 
    953 	disk_set_info(dksc->sc_dev, &dksc->sc_dkdev, NULL);
    954 
    955 	/* Discover wedges on this disk. */
    956 	dkwedge_discover(&dksc->sc_dkdev);
    957 
    958 	return 0;
    959 
    960 bail:
    961 	free(inbuf, M_TEMP);
    962 	(void)vn_close(vp, FREAD|FWRITE, l->l_cred);
    963 	return ret;
    964 }
    965 
    966 /* ARGSUSED */
    967 static int
    968 cgd_ioctl_clr(struct cgd_softc *cs, struct lwp *l)
    969 {
    970 	struct	dk_softc *dksc = &cs->sc_dksc;
    971 
    972 	if (!DK_ATTACHED(dksc))
    973 		return ENXIO;
    974 
    975 	/* Delete all of our wedges. */
    976 	dkwedge_delall(&dksc->sc_dkdev);
    977 
    978 	/* Kill off any queued buffers. */
    979 	dk_drain(dksc);
    980 	bufq_free(dksc->sc_bufq);
    981 
    982 	(void)vn_close(cs->sc_tvn, FREAD|FWRITE, l->l_cred);
    983 	cs->sc_cfuncs->cf_destroy(cs->sc_cdata.cf_priv);
    984 	free(cs->sc_tpath, M_DEVBUF);
    985 	free(cs->sc_data, M_DEVBUF);
    986 	cs->sc_data_used = 0;
    987 	dk_detach(dksc);
    988 	disk_detach(&dksc->sc_dkdev);
    989 
    990 	return 0;
    991 }
    992 
    993 static int
    994 cgd_ioctl_get(dev_t dev, void *data, struct lwp *l)
    995 {
    996 	device_t self;
    997 	struct cgd_softc *cs = getcgd_softc(dev, &self);
    998 	struct cgd_user *cgu;
    999 	int unit;
   1000 	struct	dk_softc *dksc = &cs->sc_dksc;
   1001 
   1002 	unit = CGDUNIT(dev);
   1003 	cgu = (struct cgd_user *)data;
   1004 
   1005 	DPRINTF_FOLLOW(("cgd_ioctl_get(0x%"PRIx64", %d, %p, %p)\n",
   1006 			   dev, unit, data, l));
   1007 
   1008 	if (cgu->cgu_unit == -1)
   1009 		cgu->cgu_unit = unit;
   1010 
   1011 	if (cgu->cgu_unit < 0) {
   1012 		device_release(self);
   1013 		return EINVAL;	/* XXX: should this be ENXIO? */
   1014 	}
   1015 
   1016 	/*
   1017 	 * XXX This appears to be redundant, given the initialization
   1018 	 * XXX when it was declared.  Leave it for now, but don't
   1019 	 * XXX take an extra reference to the device!
   1020 	 */
   1021 	cs = device_lookup_private(&cgd_cd, unit);
   1022 	if (cs == NULL || !DK_ATTACHED(dksc)) {
   1023 		cgu->cgu_dev = 0;
   1024 		cgu->cgu_alg[0] = '\0';
   1025 		cgu->cgu_blocksize = 0;
   1026 		cgu->cgu_mode = 0;
   1027 		cgu->cgu_keylen = 0;
   1028 	}
   1029 	else {
   1030 		cgu->cgu_dev = cs->sc_tdev;
   1031 		strlcpy(cgu->cgu_alg, cs->sc_cfuncs->cf_name,
   1032 		    sizeof(cgu->cgu_alg));
   1033 		cgu->cgu_blocksize = cs->sc_cdata.cf_blocksize;
   1034 		cgu->cgu_mode = cs->sc_cdata.cf_mode;
   1035 		cgu->cgu_keylen = cs->sc_cdata.cf_keylen;
   1036 	}
   1037 	device_release(self);
   1038 	return 0;
   1039 }
   1040 
   1041 static int
   1042 cgdinit(struct cgd_softc *cs, const char *cpath, struct vnode *vp,
   1043 	struct lwp *l)
   1044 {
   1045 	struct	disk_geom *dg;
   1046 	int	ret;
   1047 	char	*tmppath;
   1048 	uint64_t psize;
   1049 	unsigned secsize;
   1050 	struct dk_softc *dksc = &cs->sc_dksc;
   1051 
   1052 	cs->sc_tvn = vp;
   1053 	cs->sc_tpath = NULL;
   1054 
   1055 	tmppath = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
   1056 	ret = copyinstr(cpath, tmppath, MAXPATHLEN, &cs->sc_tpathlen);
   1057 	if (ret)
   1058 		goto bail;
   1059 	cs->sc_tpath = malloc(cs->sc_tpathlen, M_DEVBUF, M_WAITOK);
   1060 	memcpy(cs->sc_tpath, tmppath, cs->sc_tpathlen);
   1061 
   1062 	cs->sc_tdev = vp->v_rdev;
   1063 
   1064 	if ((ret = getdisksize(vp, &psize, &secsize)) != 0)
   1065 		goto bail;
   1066 
   1067 	if (psize == 0) {
   1068 		ret = ENODEV;
   1069 		goto bail;
   1070 	}
   1071 
   1072 	/*
   1073 	 * XXX here we should probe the underlying device.  If we
   1074 	 *     are accessing a partition of type RAW_PART, then
   1075 	 *     we should populate our initial geometry with the
   1076 	 *     geometry that we discover from the device.
   1077 	 */
   1078 	dg = &dksc->sc_dkdev.dk_geom;
   1079 	memset(dg, 0, sizeof(*dg));
   1080 	dg->dg_secperunit = psize;
   1081 	dg->dg_secsize = secsize;
   1082 	dg->dg_ntracks = 1;
   1083 	dg->dg_nsectors = 1024 * 1024 / dg->dg_secsize;
   1084 	dg->dg_ncylinders = dg->dg_secperunit / dg->dg_nsectors;
   1085 
   1086 bail:
   1087 	free(tmppath, M_TEMP);
   1088 	if (ret && cs->sc_tpath)
   1089 		free(cs->sc_tpath, M_DEVBUF);
   1090 	return ret;
   1091 }
   1092 
   1093 /*
   1094  * Our generic cipher entry point.  This takes care of the
   1095  * IV mode and passes off the work to the specific cipher.
   1096  * We implement here the IV method ``encrypted block
   1097  * number''.
   1098  *
   1099  * XXXrcd: for now we rely on our own crypto framework defined
   1100  *         in dev/cgd_crypto.c.  This will change when we
   1101  *         get a generic kernel crypto framework.
   1102  */
   1103 
   1104 static void
   1105 blkno2blkno_buf(char *sbuf, daddr_t blkno)
   1106 {
   1107 	int	i;
   1108 
   1109 	/* Set up the blkno in blkno_buf, here we do not care much
   1110 	 * about the final layout of the information as long as we
   1111 	 * can guarantee that each sector will have a different IV
   1112 	 * and that the endianness of the machine will not affect
   1113 	 * the representation that we have chosen.
   1114 	 *
   1115 	 * We choose this representation, because it does not rely
   1116 	 * on the size of buf (which is the blocksize of the cipher),
   1117 	 * but allows daddr_t to grow without breaking existing
   1118 	 * disks.
   1119 	 *
   1120 	 * Note that blkno2blkno_buf does not take a size as input,
   1121 	 * and hence must be called on a pre-zeroed buffer of length
   1122 	 * greater than or equal to sizeof(daddr_t).
   1123 	 */
   1124 	for (i=0; i < sizeof(daddr_t); i++) {
   1125 		*sbuf++ = blkno & 0xff;
   1126 		blkno >>= 8;
   1127 	}
   1128 }
   1129 
   1130 static void
   1131 cgd_cipher(struct cgd_softc *cs, void *dstv, void *srcv,
   1132     size_t len, daddr_t blkno, size_t secsize, int dir)
   1133 {
   1134 	char		*dst = dstv;
   1135 	char		*src = srcv;
   1136 	cfunc_cipher_prep	*ciprep = cs->sc_cfuncs->cf_cipher_prep;
   1137 	cfunc_cipher	*cipher = cs->sc_cfuncs->cf_cipher;
   1138 	struct uio	dstuio;
   1139 	struct uio	srcuio;
   1140 	struct iovec	dstiov[2];
   1141 	struct iovec	srciov[2];
   1142 	size_t		blocksize = cs->sc_cdata.cf_blocksize;
   1143 	size_t		todo;
   1144 	char		blkno_buf[CGD_MAXBLOCKSIZE], *iv;
   1145 
   1146 	DPRINTF_FOLLOW(("cgd_cipher() dir=%d\n", dir));
   1147 
   1148 	DIAGCONDPANIC(len % blocksize != 0,
   1149 	    ("cgd_cipher: len %% blocksize != 0"));
   1150 
   1151 	/* ensure that sizeof(daddr_t) <= blocksize (for encblkno IVing) */
   1152 	DIAGCONDPANIC(sizeof(daddr_t) > blocksize,
   1153 	    ("cgd_cipher: sizeof(daddr_t) > blocksize"));
   1154 
   1155 	DIAGCONDPANIC(blocksize > CGD_MAXBLOCKSIZE,
   1156 	    ("cgd_cipher: blocksize > CGD_MAXBLOCKSIZE"));
   1157 
   1158 	dstuio.uio_iov = dstiov;
   1159 	dstuio.uio_iovcnt = 1;
   1160 
   1161 	srcuio.uio_iov = srciov;
   1162 	srcuio.uio_iovcnt = 1;
   1163 
   1164 	for (; len > 0; len -= todo) {
   1165 		todo = MIN(len, secsize);
   1166 
   1167 		dstiov[0].iov_base = dst;
   1168 		srciov[0].iov_base = src;
   1169 		dstiov[0].iov_len  = todo;
   1170 		srciov[0].iov_len  = todo;
   1171 
   1172 		memset(blkno_buf, 0x0, blocksize);
   1173 		blkno2blkno_buf(blkno_buf, blkno);
   1174 		IFDEBUG(CGDB_CRYPTO, hexprint("step 1: blkno_buf",
   1175 		    blkno_buf, blocksize));
   1176 
   1177 		/*
   1178 		 * Compute an initial IV. All ciphers
   1179 		 * can convert blkno_buf in-place.
   1180 		 */
   1181 		iv = blkno_buf;
   1182 		ciprep(cs->sc_cdata.cf_priv, iv, blkno_buf, blocksize, dir);
   1183 		IFDEBUG(CGDB_CRYPTO, hexprint("step 2: iv", iv, blocksize));
   1184 
   1185 		cipher(cs->sc_cdata.cf_priv, &dstuio, &srcuio, iv, dir);
   1186 
   1187 		dst += todo;
   1188 		src += todo;
   1189 		blkno++;
   1190 	}
   1191 }
   1192 
   1193 #ifdef DEBUG
   1194 static void
   1195 hexprint(const char *start, void *buf, int len)
   1196 {
   1197 	char	*c = buf;
   1198 
   1199 	DIAGCONDPANIC(len < 0, ("hexprint: called with len < 0"));
   1200 	printf("%s: len=%06d 0x", start, len);
   1201 	while (len--)
   1202 		printf("%02x", (unsigned char) *c++);
   1203 }
   1204 #endif
   1205 
   1206 static void
   1207 selftest(void)
   1208 {
   1209 	struct cgd_softc cs;
   1210 	void *buf;
   1211 
   1212 	printf("running cgd selftest ");
   1213 
   1214 	for (size_t i = 0; i < __arraycount(selftests); i++) {
   1215 		const char *alg = selftests[i].alg;
   1216 		const uint8_t *key = selftests[i].key;
   1217 		int keylen = selftests[i].keylen;
   1218 		int txtlen = selftests[i].txtlen;
   1219 
   1220 		printf("%s-%d ", alg, keylen);
   1221 
   1222 		memset(&cs, 0, sizeof(cs));
   1223 
   1224 		cs.sc_cfuncs = cryptfuncs_find(alg);
   1225 		if (cs.sc_cfuncs == NULL)
   1226 			panic("%s not implemented", alg);
   1227 
   1228 		cs.sc_cdata.cf_blocksize = 8 * selftests[i].blocksize;
   1229 		cs.sc_cdata.cf_mode = CGD_CIPHER_CBC_ENCBLKNO1;
   1230 		cs.sc_cdata.cf_keylen = keylen;
   1231 
   1232 		cs.sc_cdata.cf_priv = cs.sc_cfuncs->cf_init(keylen,
   1233 		    key, &cs.sc_cdata.cf_blocksize);
   1234 		if (cs.sc_cdata.cf_priv == NULL)
   1235 			panic("cf_priv is NULL");
   1236 		if (cs.sc_cdata.cf_blocksize > CGD_MAXBLOCKSIZE)
   1237 			panic("bad block size %zu", cs.sc_cdata.cf_blocksize);
   1238 
   1239 		cs.sc_cdata.cf_blocksize /= 8;
   1240 
   1241 		buf = malloc(txtlen, M_DEVBUF, M_WAITOK);
   1242 		memcpy(buf, selftests[i].ptxt, txtlen);
   1243 
   1244 		cgd_cipher(&cs, buf, buf, txtlen, selftests[i].blkno,
   1245 				selftests[i].secsize, CGD_CIPHER_ENCRYPT);
   1246 		if (memcmp(buf, selftests[i].ctxt, txtlen) != 0)
   1247 			panic("encryption is broken");
   1248 
   1249 		cgd_cipher(&cs, buf, buf, txtlen, selftests[i].blkno,
   1250 				selftests[i].secsize, CGD_CIPHER_DECRYPT);
   1251 		if (memcmp(buf, selftests[i].ptxt, txtlen) != 0)
   1252 			panic("decryption is broken");
   1253 
   1254 		free(buf, M_DEVBUF);
   1255 		cs.sc_cfuncs->cf_destroy(cs.sc_cdata.cf_priv);
   1256 	}
   1257 
   1258 	printf("done\n");
   1259 }
   1260 
   1261 MODULE(MODULE_CLASS_DRIVER, cgd, "blowfish,des,dk_subr");
   1262 
   1263 #ifdef _MODULE
   1264 CFDRIVER_DECL(cgd, DV_DISK, NULL);
   1265 
   1266 devmajor_t cgd_bmajor = -1, cgd_cmajor = -1;
   1267 #endif
   1268 
   1269 static int
   1270 cgd_modcmd(modcmd_t cmd, void *arg)
   1271 {
   1272 	int error = 0;
   1273 
   1274 	switch (cmd) {
   1275 	case MODULE_CMD_INIT:
   1276 		selftest();
   1277 #ifdef _MODULE
   1278 		error = config_cfdriver_attach(&cgd_cd);
   1279 		if (error)
   1280 			break;
   1281 
   1282 		error = config_cfattach_attach(cgd_cd.cd_name, &cgd_ca);
   1283 	        if (error) {
   1284 			config_cfdriver_detach(&cgd_cd);
   1285 			aprint_error("%s: unable to register cfattach for "
   1286 			    "%s, error %d\n", __func__, cgd_cd.cd_name, error);
   1287 			break;
   1288 		}
   1289 		/*
   1290 		 * Attach the {b,c}devsw's
   1291 		 */
   1292 		error = devsw_attach("cgd", &cgd_bdevsw, &cgd_bmajor,
   1293 		    &cgd_cdevsw, &cgd_cmajor);
   1294 
   1295 		/*
   1296 		 * If devsw_attach fails, remove from autoconf database
   1297 		 */
   1298 		if (error) {
   1299 			config_cfattach_detach(cgd_cd.cd_name, &cgd_ca);
   1300 			config_cfdriver_detach(&cgd_cd);
   1301 			aprint_error("%s: unable to attach %s devsw, "
   1302 			    "error %d", __func__, cgd_cd.cd_name, error);
   1303 			break;
   1304 		}
   1305 #endif
   1306 		break;
   1307 
   1308 	case MODULE_CMD_FINI:
   1309 #ifdef _MODULE
   1310 		/*
   1311 		 * Remove {b,c}devsw's
   1312 		 */
   1313 		devsw_detach(&cgd_bdevsw, &cgd_cdevsw);
   1314 
   1315 		/*
   1316 		 * Now remove device from autoconf database
   1317 		 */
   1318 		error = config_cfattach_detach(cgd_cd.cd_name, &cgd_ca);
   1319 		if (error) {
   1320 			(void)devsw_attach("cgd", &cgd_bdevsw, &cgd_bmajor,
   1321 			    &cgd_cdevsw, &cgd_cmajor);
   1322 			aprint_error("%s: failed to detach %s cfattach, "
   1323 			    "error %d\n", __func__, cgd_cd.cd_name, error);
   1324 			break;
   1325 		}
   1326 		error = config_cfdriver_detach(&cgd_cd);
   1327 		if (error) {
   1328 			(void)config_cfattach_attach(cgd_cd.cd_name, &cgd_ca);
   1329 			(void)devsw_attach("cgd", &cgd_bdevsw, &cgd_bmajor,
   1330 			    &cgd_cdevsw, &cgd_cmajor);
   1331 			aprint_error("%s: failed to detach %s cfdriver, "
   1332 			    "error %d\n", __func__, cgd_cd.cd_name, error);
   1333 			break;
   1334 		}
   1335 #endif
   1336 		break;
   1337 
   1338 	case MODULE_CMD_STAT:
   1339 		error = ENOTTY;
   1340 		break;
   1341 	default:
   1342 		error = ENOTTY;
   1343 		break;
   1344 	}
   1345 
   1346 	return error;
   1347 }
   1348