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