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