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