Home | History | Annotate | Line # | Download | only in dev
cgd.c revision 1.91.2.8
      1 /* $NetBSD: cgd.c,v 1.91.2.8 2017/08/28 17:52:00 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.8 2017/08/28 17:52:00 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 DIOCGCACHE:
    719 	case DIOCCACHESYNC:
    720 		if (!DK_ATTACHED(dksc))
    721 			return ENOENT;
    722 		/*
    723 		 * We pass this call down to the underlying disk.
    724 		 */
    725 		return VOP_IOCTL(cs->sc_tvn, cmd, data, flag, l->l_cred);
    726 	case DIOCGSTRATEGY:
    727 	case DIOCSSTRATEGY:
    728 		if (!DK_ATTACHED(dksc))
    729 			return ENOENT;
    730 		/*FALLTHROUGH*/
    731 	default:
    732 		return dk_ioctl(dksc, dev, cmd, data, flag, l);
    733 	case CGDIOCGET:
    734 		KASSERT(0);
    735 		return EINVAL;
    736 	}
    737 }
    738 
    739 static int
    740 cgddump(dev_t dev, daddr_t blkno, void *va, size_t size)
    741 {
    742 	struct	cgd_softc *cs;
    743 
    744 	DPRINTF_FOLLOW(("cgddump(0x%"PRIx64", %" PRId64 ", %p, %lu)\n",
    745 	    dev, blkno, va, (unsigned long)size));
    746 	GETCGD_SOFTC(cs, dev);
    747 	return dk_dump(&cs->sc_dksc, dev, blkno, va, size);
    748 }
    749 
    750 /*
    751  * XXXrcd:
    752  *  for now we hardcode the maximum key length.
    753  */
    754 #define MAX_KEYSIZE	1024
    755 
    756 static const struct {
    757 	const char *n;
    758 	int v;
    759 	int d;
    760 } encblkno[] = {
    761 	{ "encblkno",  CGD_CIPHER_CBC_ENCBLKNO8, 1 },
    762 	{ "encblkno8", CGD_CIPHER_CBC_ENCBLKNO8, 1 },
    763 	{ "encblkno1", CGD_CIPHER_CBC_ENCBLKNO1, 8 },
    764 };
    765 
    766 /* ARGSUSED */
    767 static int
    768 cgd_ioctl_set(struct cgd_softc *cs, void *data, struct lwp *l)
    769 {
    770 	struct	 cgd_ioctl *ci = data;
    771 	struct	 vnode *vp;
    772 	int	 ret;
    773 	size_t	 i;
    774 	size_t	 keybytes;			/* key length in bytes */
    775 	const char *cp;
    776 	struct pathbuf *pb;
    777 	char	 *inbuf;
    778 	struct dk_softc *dksc = &cs->sc_dksc;
    779 
    780 	cp = ci->ci_disk;
    781 
    782 	ret = pathbuf_copyin(ci->ci_disk, &pb);
    783 	if (ret != 0) {
    784 		return ret;
    785 	}
    786 	ret = dk_lookup(pb, l, &vp);
    787 	pathbuf_destroy(pb);
    788 	if (ret != 0) {
    789 		return ret;
    790 	}
    791 
    792 	inbuf = malloc(MAX_KEYSIZE, M_TEMP, M_WAITOK);
    793 
    794 	if ((ret = cgdinit(cs, cp, vp, l)) != 0)
    795 		goto bail;
    796 
    797 	(void)memset(inbuf, 0, MAX_KEYSIZE);
    798 	ret = copyinstr(ci->ci_alg, inbuf, 256, NULL);
    799 	if (ret)
    800 		goto bail;
    801 	cs->sc_cfuncs = cryptfuncs_find(inbuf);
    802 	if (!cs->sc_cfuncs) {
    803 		ret = EINVAL;
    804 		goto bail;
    805 	}
    806 
    807 	(void)memset(inbuf, 0, MAX_KEYSIZE);
    808 	ret = copyinstr(ci->ci_ivmethod, inbuf, MAX_KEYSIZE, NULL);
    809 	if (ret)
    810 		goto bail;
    811 
    812 	for (i = 0; i < __arraycount(encblkno); i++)
    813 		if (strcmp(encblkno[i].n, inbuf) == 0)
    814 			break;
    815 
    816 	if (i == __arraycount(encblkno)) {
    817 		ret = EINVAL;
    818 		goto bail;
    819 	}
    820 
    821 	keybytes = ci->ci_keylen / 8 + 1;
    822 	if (keybytes > MAX_KEYSIZE) {
    823 		ret = EINVAL;
    824 		goto bail;
    825 	}
    826 
    827 	(void)memset(inbuf, 0, MAX_KEYSIZE);
    828 	ret = copyin(ci->ci_key, inbuf, keybytes);
    829 	if (ret)
    830 		goto bail;
    831 
    832 	cs->sc_cdata.cf_blocksize = ci->ci_blocksize;
    833 	cs->sc_cdata.cf_mode = encblkno[i].v;
    834 	cs->sc_cdata.cf_keylen = ci->ci_keylen;
    835 	cs->sc_cdata.cf_priv = cs->sc_cfuncs->cf_init(ci->ci_keylen, inbuf,
    836 	    &cs->sc_cdata.cf_blocksize);
    837 	if (cs->sc_cdata.cf_blocksize > CGD_MAXBLOCKSIZE) {
    838 	    log(LOG_WARNING, "cgd: Disallowed cipher with blocksize %zu > %u\n",
    839 		cs->sc_cdata.cf_blocksize, CGD_MAXBLOCKSIZE);
    840 	    cs->sc_cdata.cf_priv = NULL;
    841 	}
    842 
    843 	/*
    844 	 * The blocksize is supposed to be in bytes. Unfortunately originally
    845 	 * it was expressed in bits. For compatibility we maintain encblkno
    846 	 * and encblkno8.
    847 	 */
    848 	cs->sc_cdata.cf_blocksize /= encblkno[i].d;
    849 	(void)explicit_memset(inbuf, 0, MAX_KEYSIZE);
    850 	if (!cs->sc_cdata.cf_priv) {
    851 		ret = EINVAL;		/* XXX is this the right error? */
    852 		goto bail;
    853 	}
    854 	free(inbuf, M_TEMP);
    855 
    856 	bufq_alloc(&dksc->sc_bufq, "fcfs", 0);
    857 
    858 	cs->sc_data = malloc(MAXPHYS, M_DEVBUF, M_WAITOK);
    859 	cs->sc_data_used = 0;
    860 
    861 	/* Attach the disk. */
    862 	dk_attach(dksc);
    863 	disk_attach(&dksc->sc_dkdev);
    864 
    865 	disk_set_info(dksc->sc_dev, &dksc->sc_dkdev, NULL);
    866 
    867 	/* Discover wedges on this disk. */
    868 	dkwedge_discover(&dksc->sc_dkdev);
    869 
    870 	return 0;
    871 
    872 bail:
    873 	free(inbuf, M_TEMP);
    874 	(void)vn_close(vp, FREAD|FWRITE, l->l_cred);
    875 	return ret;
    876 }
    877 
    878 /* ARGSUSED */
    879 static int
    880 cgd_ioctl_clr(struct cgd_softc *cs, struct lwp *l)
    881 {
    882 	struct	dk_softc *dksc = &cs->sc_dksc;
    883 
    884 	if (!DK_ATTACHED(dksc))
    885 		return ENXIO;
    886 
    887 	/* Delete all of our wedges. */
    888 	dkwedge_delall(&dksc->sc_dkdev);
    889 
    890 	/* Kill off any queued buffers. */
    891 	dk_drain(dksc);
    892 	bufq_free(dksc->sc_bufq);
    893 
    894 	(void)vn_close(cs->sc_tvn, FREAD|FWRITE, l->l_cred);
    895 	cs->sc_cfuncs->cf_destroy(cs->sc_cdata.cf_priv);
    896 	free(cs->sc_tpath, M_DEVBUF);
    897 	free(cs->sc_data, M_DEVBUF);
    898 	cs->sc_data_used = 0;
    899 	dk_detach(dksc);
    900 	disk_detach(&dksc->sc_dkdev);
    901 
    902 	return 0;
    903 }
    904 
    905 static int
    906 cgd_ioctl_get(dev_t dev, void *data, struct lwp *l)
    907 {
    908 	struct cgd_softc *cs = getcgd_softc(dev);
    909 	struct cgd_user *cgu;
    910 	int unit;
    911 	struct	dk_softc *dksc = &cs->sc_dksc;
    912 
    913 	unit = CGDUNIT(dev);
    914 	cgu = (struct cgd_user *)data;
    915 
    916 	DPRINTF_FOLLOW(("cgd_ioctl_get(0x%"PRIx64", %d, %p, %p)\n",
    917 			   dev, unit, data, l));
    918 
    919 	if (cgu->cgu_unit == -1)
    920 		cgu->cgu_unit = unit;
    921 
    922 	if (cgu->cgu_unit < 0)
    923 		return EINVAL;	/* XXX: should this be ENXIO? */
    924 
    925 	cs = device_lookup_private(&cgd_cd, unit);
    926 	if (cs == NULL || !DK_ATTACHED(dksc)) {
    927 		cgu->cgu_dev = 0;
    928 		cgu->cgu_alg[0] = '\0';
    929 		cgu->cgu_blocksize = 0;
    930 		cgu->cgu_mode = 0;
    931 		cgu->cgu_keylen = 0;
    932 	}
    933 	else {
    934 		cgu->cgu_dev = cs->sc_tdev;
    935 		strlcpy(cgu->cgu_alg, cs->sc_cfuncs->cf_name,
    936 		    sizeof(cgu->cgu_alg));
    937 		cgu->cgu_blocksize = cs->sc_cdata.cf_blocksize;
    938 		cgu->cgu_mode = cs->sc_cdata.cf_mode;
    939 		cgu->cgu_keylen = cs->sc_cdata.cf_keylen;
    940 	}
    941 	return 0;
    942 }
    943 
    944 static int
    945 cgdinit(struct cgd_softc *cs, const char *cpath, struct vnode *vp,
    946 	struct lwp *l)
    947 {
    948 	struct	disk_geom *dg;
    949 	int	ret;
    950 	char	*tmppath;
    951 	uint64_t psize;
    952 	unsigned secsize;
    953 	struct dk_softc *dksc = &cs->sc_dksc;
    954 
    955 	cs->sc_tvn = vp;
    956 	cs->sc_tpath = NULL;
    957 
    958 	tmppath = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
    959 	ret = copyinstr(cpath, tmppath, MAXPATHLEN, &cs->sc_tpathlen);
    960 	if (ret)
    961 		goto bail;
    962 	cs->sc_tpath = malloc(cs->sc_tpathlen, M_DEVBUF, M_WAITOK);
    963 	memcpy(cs->sc_tpath, tmppath, cs->sc_tpathlen);
    964 
    965 	cs->sc_tdev = vp->v_rdev;
    966 
    967 	if ((ret = getdisksize(vp, &psize, &secsize)) != 0)
    968 		goto bail;
    969 
    970 	if (psize == 0) {
    971 		ret = ENODEV;
    972 		goto bail;
    973 	}
    974 
    975 	/*
    976 	 * XXX here we should probe the underlying device.  If we
    977 	 *     are accessing a partition of type RAW_PART, then
    978 	 *     we should populate our initial geometry with the
    979 	 *     geometry that we discover from the device.
    980 	 */
    981 	dg = &dksc->sc_dkdev.dk_geom;
    982 	memset(dg, 0, sizeof(*dg));
    983 	dg->dg_secperunit = psize;
    984 	dg->dg_secsize = secsize;
    985 	dg->dg_ntracks = 1;
    986 	dg->dg_nsectors = 1024 * 1024 / dg->dg_secsize;
    987 	dg->dg_ncylinders = dg->dg_secperunit / dg->dg_nsectors;
    988 
    989 bail:
    990 	free(tmppath, M_TEMP);
    991 	if (ret && cs->sc_tpath)
    992 		free(cs->sc_tpath, M_DEVBUF);
    993 	return ret;
    994 }
    995 
    996 /*
    997  * Our generic cipher entry point.  This takes care of the
    998  * IV mode and passes off the work to the specific cipher.
    999  * We implement here the IV method ``encrypted block
   1000  * number''.
   1001  *
   1002  * XXXrcd: for now we rely on our own crypto framework defined
   1003  *         in dev/cgd_crypto.c.  This will change when we
   1004  *         get a generic kernel crypto framework.
   1005  */
   1006 
   1007 static void
   1008 blkno2blkno_buf(char *sbuf, daddr_t blkno)
   1009 {
   1010 	int	i;
   1011 
   1012 	/* Set up the blkno in blkno_buf, here we do not care much
   1013 	 * about the final layout of the information as long as we
   1014 	 * can guarantee that each sector will have a different IV
   1015 	 * and that the endianness of the machine will not affect
   1016 	 * the representation that we have chosen.
   1017 	 *
   1018 	 * We choose this representation, because it does not rely
   1019 	 * on the size of buf (which is the blocksize of the cipher),
   1020 	 * but allows daddr_t to grow without breaking existing
   1021 	 * disks.
   1022 	 *
   1023 	 * Note that blkno2blkno_buf does not take a size as input,
   1024 	 * and hence must be called on a pre-zeroed buffer of length
   1025 	 * greater than or equal to sizeof(daddr_t).
   1026 	 */
   1027 	for (i=0; i < sizeof(daddr_t); i++) {
   1028 		*sbuf++ = blkno & 0xff;
   1029 		blkno >>= 8;
   1030 	}
   1031 }
   1032 
   1033 static void
   1034 cgd_cipher(struct cgd_softc *cs, void *dstv, void *srcv,
   1035     size_t len, daddr_t blkno, size_t secsize, int dir)
   1036 {
   1037 	char		*dst = dstv;
   1038 	char		*src = srcv;
   1039 	cfunc_cipher_prep	*ciprep = cs->sc_cfuncs->cf_cipher_prep;
   1040 	cfunc_cipher	*cipher = cs->sc_cfuncs->cf_cipher;
   1041 	struct uio	dstuio;
   1042 	struct uio	srcuio;
   1043 	struct iovec	dstiov[2];
   1044 	struct iovec	srciov[2];
   1045 	size_t		blocksize = cs->sc_cdata.cf_blocksize;
   1046 	size_t		todo;
   1047 	char		blkno_buf[CGD_MAXBLOCKSIZE], *iv;
   1048 
   1049 	DPRINTF_FOLLOW(("cgd_cipher() dir=%d\n", dir));
   1050 
   1051 	DIAGCONDPANIC(len % blocksize != 0,
   1052 	    ("cgd_cipher: len %% blocksize != 0"));
   1053 
   1054 	/* ensure that sizeof(daddr_t) <= blocksize (for encblkno IVing) */
   1055 	DIAGCONDPANIC(sizeof(daddr_t) > blocksize,
   1056 	    ("cgd_cipher: sizeof(daddr_t) > blocksize"));
   1057 
   1058 	DIAGCONDPANIC(blocksize > CGD_MAXBLOCKSIZE,
   1059 	    ("cgd_cipher: blocksize > CGD_MAXBLOCKSIZE"));
   1060 
   1061 	dstuio.uio_iov = dstiov;
   1062 	dstuio.uio_iovcnt = 1;
   1063 
   1064 	srcuio.uio_iov = srciov;
   1065 	srcuio.uio_iovcnt = 1;
   1066 
   1067 	for (; len > 0; len -= todo) {
   1068 		todo = MIN(len, secsize);
   1069 
   1070 		dstiov[0].iov_base = dst;
   1071 		srciov[0].iov_base = src;
   1072 		dstiov[0].iov_len  = todo;
   1073 		srciov[0].iov_len  = todo;
   1074 
   1075 		memset(blkno_buf, 0x0, blocksize);
   1076 		blkno2blkno_buf(blkno_buf, blkno);
   1077 		IFDEBUG(CGDB_CRYPTO, hexprint("step 1: blkno_buf",
   1078 		    blkno_buf, blocksize));
   1079 
   1080 		/*
   1081 		 * Compute an initial IV. All ciphers
   1082 		 * can convert blkno_buf in-place.
   1083 		 */
   1084 		iv = blkno_buf;
   1085 		ciprep(cs->sc_cdata.cf_priv, iv, blkno_buf, blocksize, dir);
   1086 		IFDEBUG(CGDB_CRYPTO, hexprint("step 2: iv", iv, blocksize));
   1087 
   1088 		cipher(cs->sc_cdata.cf_priv, &dstuio, &srcuio, iv, dir);
   1089 
   1090 		dst += todo;
   1091 		src += todo;
   1092 		blkno++;
   1093 	}
   1094 }
   1095 
   1096 #ifdef DEBUG
   1097 static void
   1098 hexprint(const char *start, void *buf, int len)
   1099 {
   1100 	char	*c = buf;
   1101 
   1102 	DIAGCONDPANIC(len < 0, ("hexprint: called with len < 0"));
   1103 	printf("%s: len=%06d 0x", start, len);
   1104 	while (len--)
   1105 		printf("%02x", (unsigned char) *c++);
   1106 }
   1107 #endif
   1108 
   1109 static void
   1110 selftest(void)
   1111 {
   1112 	struct cgd_softc cs;
   1113 	void *buf;
   1114 
   1115 	printf("running cgd selftest ");
   1116 
   1117 	for (size_t i = 0; i < __arraycount(selftests); i++) {
   1118 		const char *alg = selftests[i].alg;
   1119 		const uint8_t *key = selftests[i].key;
   1120 		int keylen = selftests[i].keylen;
   1121 		int txtlen = selftests[i].txtlen;
   1122 
   1123 		printf("%s-%d ", alg, keylen);
   1124 
   1125 		memset(&cs, 0, sizeof(cs));
   1126 
   1127 		cs.sc_cfuncs = cryptfuncs_find(alg);
   1128 		if (cs.sc_cfuncs == NULL)
   1129 			panic("%s not implemented", alg);
   1130 
   1131 		cs.sc_cdata.cf_blocksize = 8 * selftests[i].blocksize;
   1132 		cs.sc_cdata.cf_mode = CGD_CIPHER_CBC_ENCBLKNO1;
   1133 		cs.sc_cdata.cf_keylen = keylen;
   1134 
   1135 		cs.sc_cdata.cf_priv = cs.sc_cfuncs->cf_init(keylen,
   1136 		    key, &cs.sc_cdata.cf_blocksize);
   1137 		if (cs.sc_cdata.cf_priv == NULL)
   1138 			panic("cf_priv is NULL");
   1139 		if (cs.sc_cdata.cf_blocksize > CGD_MAXBLOCKSIZE)
   1140 			panic("bad block size %zu", cs.sc_cdata.cf_blocksize);
   1141 
   1142 		cs.sc_cdata.cf_blocksize /= 8;
   1143 
   1144 		buf = malloc(txtlen, M_DEVBUF, M_WAITOK);
   1145 		memcpy(buf, selftests[i].ptxt, txtlen);
   1146 
   1147 		cgd_cipher(&cs, buf, buf, txtlen, selftests[i].blkno,
   1148 				selftests[i].secsize, CGD_CIPHER_ENCRYPT);
   1149 		if (memcmp(buf, selftests[i].ctxt, txtlen) != 0)
   1150 			panic("encryption is broken");
   1151 
   1152 		cgd_cipher(&cs, buf, buf, txtlen, selftests[i].blkno,
   1153 				selftests[i].secsize, CGD_CIPHER_DECRYPT);
   1154 		if (memcmp(buf, selftests[i].ptxt, txtlen) != 0)
   1155 			panic("decryption is broken");
   1156 
   1157 		free(buf, M_DEVBUF);
   1158 		cs.sc_cfuncs->cf_destroy(cs.sc_cdata.cf_priv);
   1159 	}
   1160 
   1161 	printf("done\n");
   1162 }
   1163 
   1164 MODULE(MODULE_CLASS_DRIVER, cgd, "blowfish,des,dk_subr");
   1165 
   1166 #ifdef _MODULE
   1167 CFDRIVER_DECL(cgd, DV_DISK, NULL);
   1168 
   1169 devmajor_t cgd_bmajor = -1, cgd_cmajor = -1;
   1170 #endif
   1171 
   1172 static int
   1173 cgd_modcmd(modcmd_t cmd, void *arg)
   1174 {
   1175 	int error = 0;
   1176 
   1177 	switch (cmd) {
   1178 	case MODULE_CMD_INIT:
   1179 		selftest();
   1180 #ifdef _MODULE
   1181 		error = config_cfdriver_attach(&cgd_cd);
   1182 		if (error)
   1183 			break;
   1184 
   1185 		error = config_cfattach_attach(cgd_cd.cd_name, &cgd_ca);
   1186 	        if (error) {
   1187 			config_cfdriver_detach(&cgd_cd);
   1188 			aprint_error("%s: unable to register cfattach for"
   1189 			    "%s, error %d\n", __func__, cgd_cd.cd_name, error);
   1190 			break;
   1191 		}
   1192 		/*
   1193 		 * Attach the {b,c}devsw's
   1194 		 */
   1195 		error = devsw_attach("cgd", &cgd_bdevsw, &cgd_bmajor,
   1196 		    &cgd_cdevsw, &cgd_cmajor);
   1197 
   1198 		/*
   1199 		 * If devsw_attach fails, remove from autoconf database
   1200 		 */
   1201 		if (error) {
   1202 			config_cfattach_detach(cgd_cd.cd_name, &cgd_ca);
   1203 			config_cfdriver_detach(&cgd_cd);
   1204 			aprint_error("%s: unable to attach %s devsw, "
   1205 			    "error %d", __func__, cgd_cd.cd_name, error);
   1206 			break;
   1207 		}
   1208 #endif
   1209 		break;
   1210 
   1211 	case MODULE_CMD_FINI:
   1212 #ifdef _MODULE
   1213 		/*
   1214 		 * Remove {b,c}devsw's
   1215 		 */
   1216 		devsw_detach(&cgd_bdevsw, &cgd_cdevsw);
   1217 
   1218 		/*
   1219 		 * Now remove device from autoconf database
   1220 		 */
   1221 		error = config_cfattach_detach(cgd_cd.cd_name, &cgd_ca);
   1222 		if (error) {
   1223 			(void)devsw_attach("cgd", &cgd_bdevsw, &cgd_bmajor,
   1224 			    &cgd_cdevsw, &cgd_cmajor);
   1225 			aprint_error("%s: failed to detach %s cfattach, "
   1226 			    "error %d\n", __func__, cgd_cd.cd_name, error);
   1227  			break;
   1228 		}
   1229 		error = config_cfdriver_detach(&cgd_cd);
   1230 		if (error) {
   1231 			(void)config_cfattach_attach(cgd_cd.cd_name, &cgd_ca);
   1232 			(void)devsw_attach("cgd", &cgd_bdevsw, &cgd_bmajor,
   1233 			    &cgd_cdevsw, &cgd_cmajor);
   1234 			aprint_error("%s: failed to detach %s cfdriver, "
   1235 			    "error %d\n", __func__, cgd_cd.cd_name, error);
   1236 			break;
   1237 		}
   1238 #endif
   1239 		break;
   1240 
   1241 	case MODULE_CMD_STAT:
   1242 		error = ENOTTY;
   1243 		break;
   1244 	default:
   1245 		error = ENOTTY;
   1246 		break;
   1247 	}
   1248 
   1249 	return error;
   1250 }
   1251