Home | History | Annotate | Line # | Download | only in dev
cgd.c revision 1.116.10.4
      1 /* $NetBSD: cgd.c,v 1.116.10.4 2021/12/14 19:05:11 martin 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.116.10.4 2021/12/14 19:05:11 martin 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/kmem.h>
     43 #include <sys/module.h>
     44 #include <sys/pool.h>
     45 #include <sys/ioctl.h>
     46 #include <sys/device.h>
     47 #include <sys/disk.h>
     48 #include <sys/disklabel.h>
     49 #include <sys/fcntl.h>
     50 #include <sys/namei.h> /* for pathbuf */
     51 #include <sys/vnode.h>
     52 #include <sys/conf.h>
     53 #include <sys/syslog.h>
     54 #include <sys/workqueue.h>
     55 #include <sys/cpu.h>
     56 
     57 #include <dev/dkvar.h>
     58 #include <dev/cgdvar.h>
     59 
     60 #include <miscfs/specfs/specdev.h> /* for v_rdev */
     61 
     62 #include "ioconf.h"
     63 
     64 struct selftest_params {
     65 	const char *alg;
     66 	int blocksize;	/* number of bytes */
     67 	int secsize;
     68 	daddr_t blkno;
     69 	int keylen;	/* number of bits */
     70 	int txtlen;	/* number of bytes */
     71 	const uint8_t *key;
     72 	const uint8_t *ptxt;
     73 	const uint8_t *ctxt;
     74 };
     75 
     76 /* Entry Point Functions */
     77 
     78 static dev_type_open(cgdopen);
     79 static dev_type_close(cgdclose);
     80 static dev_type_read(cgdread);
     81 static dev_type_write(cgdwrite);
     82 static dev_type_ioctl(cgdioctl);
     83 static dev_type_strategy(cgdstrategy);
     84 static dev_type_dump(cgddump);
     85 static dev_type_size(cgdsize);
     86 
     87 const struct bdevsw cgd_bdevsw = {
     88 	.d_open = cgdopen,
     89 	.d_close = cgdclose,
     90 	.d_strategy = cgdstrategy,
     91 	.d_ioctl = cgdioctl,
     92 	.d_dump = cgddump,
     93 	.d_psize = cgdsize,
     94 	.d_discard = nodiscard,
     95 	.d_flag = D_DISK | D_MPSAFE
     96 };
     97 
     98 const struct cdevsw cgd_cdevsw = {
     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 | D_MPSAFE
    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);
    212 static struct cgd_worker *cgd_create_one_worker(void);
    213 static void cgd_destroy_one_worker(struct cgd_worker *);
    214 static struct cgd_worker *cgd_create_worker(void);
    215 static void cgd_destroy_worker(struct cgd_worker *);
    216 static int cgd_destroy(device_t);
    217 
    218 /* Internal Functions */
    219 
    220 static int	cgd_diskstart(device_t, struct buf *);
    221 static void	cgd_diskstart2(struct cgd_softc *, struct cgd_xfer *);
    222 static void	cgdiodone(struct buf *);
    223 static void	cgd_iodone2(struct cgd_softc *, struct cgd_xfer *);
    224 static void	cgd_enqueue(struct cgd_softc *, struct cgd_xfer *);
    225 static void	cgd_process(struct work *, void *);
    226 static int	cgd_dumpblocks(device_t, void *, daddr_t, int);
    227 
    228 static int	cgd_ioctl_set(struct cgd_softc *, void *, struct lwp *);
    229 static int	cgd_ioctl_clr(struct cgd_softc *, struct lwp *);
    230 static int	cgd_ioctl_get(dev_t, void *, struct lwp *);
    231 static int	cgdinit(struct cgd_softc *, const char *, struct vnode *,
    232 			struct lwp *);
    233 static void	cgd_cipher(struct cgd_softc *, void *, void *,
    234 			   size_t, daddr_t, size_t, int);
    235 
    236 static struct dkdriver cgddkdriver = {
    237         .d_minphys  = minphys,
    238         .d_open = cgdopen,
    239         .d_close = cgdclose,
    240         .d_strategy = cgdstrategy,
    241         .d_iosize = NULL,
    242         .d_diskstart = cgd_diskstart,
    243         .d_dumpblocks = cgd_dumpblocks,
    244         .d_lastclose = NULL
    245 };
    246 
    247 CFATTACH_DECL3_NEW(cgd, sizeof(struct cgd_softc),
    248     cgd_match, cgd_attach, cgd_detach, NULL, NULL, NULL, DVF_DETACH_SHUTDOWN);
    249 
    250 /* DIAGNOSTIC and DEBUG definitions */
    251 
    252 #if defined(CGDDEBUG) && !defined(DEBUG)
    253 #define DEBUG
    254 #endif
    255 
    256 #ifdef DEBUG
    257 int cgddebug = 0;
    258 
    259 #define CGDB_FOLLOW	0x1
    260 #define CGDB_IO	0x2
    261 #define CGDB_CRYPTO	0x4
    262 
    263 #define IFDEBUG(x,y)		if (cgddebug & (x)) y
    264 #define DPRINTF(x,y)		IFDEBUG(x, printf y)
    265 #define DPRINTF_FOLLOW(y)	DPRINTF(CGDB_FOLLOW, y)
    266 
    267 static void	hexprint(const char *, void *, int);
    268 
    269 #else
    270 #define IFDEBUG(x,y)
    271 #define DPRINTF(x,y)
    272 #define DPRINTF_FOLLOW(y)
    273 #endif
    274 
    275 #ifdef DIAGNOSTIC
    276 #define DIAGPANIC(x)		panic x
    277 #define DIAGCONDPANIC(x,y)	if (x) panic y
    278 #else
    279 #define DIAGPANIC(x)
    280 #define DIAGCONDPANIC(x,y)
    281 #endif
    282 
    283 /* Global variables */
    284 
    285 static kmutex_t cgd_spawning_mtx;
    286 static kcondvar_t cgd_spawning_cv;
    287 static bool cgd_spawning;
    288 static struct cgd_worker *cgd_worker;
    289 static u_int cgd_refcnt;	/* number of users of cgd_worker */
    290 
    291 /* Utility Functions */
    292 
    293 #define CGDUNIT(x)		DISKUNIT(x)
    294 
    295 /* The code */
    296 
    297 static int
    298 cgd_lock(bool intr)
    299 {
    300 	int error = 0;
    301 
    302 	mutex_enter(&cgd_spawning_mtx);
    303 	while (cgd_spawning) {
    304 		if (intr)
    305 			error = cv_wait_sig(&cgd_spawning_cv, &cgd_spawning_mtx);
    306 		else
    307 			cv_wait(&cgd_spawning_cv, &cgd_spawning_mtx);
    308 	}
    309 	if (error == 0)
    310 		cgd_spawning = true;
    311 	mutex_exit(&cgd_spawning_mtx);
    312 	return error;
    313 }
    314 
    315 static void
    316 cgd_unlock(void)
    317 {
    318 	mutex_enter(&cgd_spawning_mtx);
    319 	cgd_spawning = false;
    320 	cv_broadcast(&cgd_spawning_cv);
    321 	mutex_exit(&cgd_spawning_mtx);
    322 }
    323 
    324 static struct cgd_softc *
    325 getcgd_softc(dev_t dev)
    326 {
    327 	return device_lookup_private(&cgd_cd, CGDUNIT(dev));
    328 }
    329 
    330 static int
    331 cgd_match(device_t self, cfdata_t cfdata, void *aux)
    332 {
    333 
    334 	return 1;
    335 }
    336 
    337 static void
    338 cgd_attach(device_t parent, device_t self, void *aux)
    339 {
    340 	struct cgd_softc *sc = device_private(self);
    341 
    342 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_BIO);
    343 	cv_init(&sc->sc_cv, "cgdcv");
    344 	dk_init(&sc->sc_dksc, self, DKTYPE_CGD);
    345 	disk_init(&sc->sc_dksc.sc_dkdev, sc->sc_dksc.sc_xname, &cgddkdriver);
    346 
    347 	if (!pmf_device_register(self, NULL, NULL))
    348 		aprint_error_dev(self,
    349 		    "unable to register power management hooks\n");
    350 }
    351 
    352 
    353 static int
    354 cgd_detach(device_t self, int flags)
    355 {
    356 	int ret;
    357 	const int pmask = 1 << RAW_PART;
    358 	struct cgd_softc *sc = device_private(self);
    359 	struct dk_softc *dksc = &sc->sc_dksc;
    360 
    361 	if (DK_BUSY(dksc, pmask))
    362 		return EBUSY;
    363 
    364 	if (DK_ATTACHED(dksc) &&
    365 	    (ret = cgd_ioctl_clr(sc, curlwp)) != 0)
    366 		return ret;
    367 
    368 	disk_destroy(&dksc->sc_dkdev);
    369 	cv_destroy(&sc->sc_cv);
    370 	mutex_destroy(&sc->sc_lock);
    371 
    372 	return 0;
    373 }
    374 
    375 void
    376 cgdattach(int num)
    377 {
    378 #ifndef _MODULE
    379 	int error;
    380 
    381 	mutex_init(&cgd_spawning_mtx, MUTEX_DEFAULT, IPL_NONE);
    382 	cv_init(&cgd_spawning_cv, "cgspwn");
    383 
    384 	error = config_cfattach_attach(cgd_cd.cd_name, &cgd_ca);
    385 	if (error != 0)
    386 		aprint_error("%s: unable to register cfattach\n",
    387 		    cgd_cd.cd_name);
    388 #endif
    389 }
    390 
    391 static struct cgd_softc *
    392 cgd_spawn(int unit)
    393 {
    394 	cfdata_t cf;
    395 	struct cgd_worker *cw;
    396 	struct cgd_softc *sc;
    397 
    398 	cf = kmem_alloc(sizeof(*cf), KM_SLEEP);
    399 	cf->cf_name = cgd_cd.cd_name;
    400 	cf->cf_atname = cgd_cd.cd_name;
    401 	cf->cf_unit = unit;
    402 	cf->cf_fstate = FSTATE_STAR;
    403 
    404 	cw = cgd_create_one_worker();
    405 	if (cw == NULL) {
    406 		kmem_free(cf, sizeof(*cf));
    407 		return NULL;
    408 	}
    409 
    410 	sc = device_private(config_attach_pseudo(cf));
    411 	if (sc == NULL) {
    412 		cgd_destroy_one_worker(cw);
    413 		return NULL;
    414 	}
    415 
    416 	sc->sc_worker = cw;
    417 
    418 	return sc;
    419 }
    420 
    421 static int
    422 cgd_destroy(device_t dev)
    423 {
    424 	struct cgd_softc *sc = device_private(dev);
    425 	struct cgd_worker *cw = sc->sc_worker;
    426 	cfdata_t cf;
    427 	int error;
    428 
    429 	cf = device_cfdata(dev);
    430 	error = config_detach(dev, DETACH_QUIET);
    431 	if (error)
    432 		return error;
    433 
    434 	cgd_destroy_one_worker(cw);
    435 
    436 	kmem_free(cf, sizeof(*cf));
    437 	return 0;
    438 }
    439 
    440 static void
    441 cgd_busy(struct cgd_softc *sc)
    442 {
    443 
    444 	mutex_enter(&sc->sc_lock);
    445 	while (sc->sc_busy)
    446 		cv_wait(&sc->sc_cv, &sc->sc_lock);
    447 	sc->sc_busy = true;
    448 	mutex_exit(&sc->sc_lock);
    449 }
    450 
    451 static void
    452 cgd_unbusy(struct cgd_softc *sc)
    453 {
    454 
    455 	mutex_enter(&sc->sc_lock);
    456 	sc->sc_busy = false;
    457 	cv_broadcast(&sc->sc_cv);
    458 	mutex_exit(&sc->sc_lock);
    459 }
    460 
    461 static struct cgd_worker *
    462 cgd_create_one_worker(void)
    463 {
    464 	KASSERT(cgd_spawning);
    465 
    466 	if (cgd_refcnt++ == 0) {
    467 		KASSERT(cgd_worker == NULL);
    468 		cgd_worker = cgd_create_worker();
    469 	}
    470 
    471 	KASSERT(cgd_worker != NULL);
    472 	return cgd_worker;
    473 }
    474 
    475 static void
    476 cgd_destroy_one_worker(struct cgd_worker *cw)
    477 {
    478 	KASSERT(cgd_spawning);
    479 	KASSERT(cw == cgd_worker);
    480 
    481 	if (--cgd_refcnt == 0) {
    482 		cgd_destroy_worker(cgd_worker);
    483 		cgd_worker = NULL;
    484 	}
    485 }
    486 
    487 static struct cgd_worker *
    488 cgd_create_worker(void)
    489 {
    490 	struct cgd_worker *cw;
    491 	struct workqueue *wq;
    492 	struct pool *cp;
    493 	int error;
    494 
    495 	cw = kmem_alloc(sizeof(struct cgd_worker), KM_SLEEP);
    496 	cp = kmem_alloc(sizeof(struct pool), KM_SLEEP);
    497 
    498 	error = workqueue_create(&wq, "cgd", cgd_process, NULL,
    499 	                         PRI_BIO, IPL_BIO, WQ_MPSAFE | WQ_PERCPU);
    500 	if (error) {
    501 		kmem_free(cp, sizeof(struct pool));
    502 		kmem_free(cw, sizeof(struct cgd_worker));
    503 		return NULL;
    504 	}
    505 
    506 	cw->cw_cpool = cp;
    507 	cw->cw_wq = wq;
    508 	pool_init(cw->cw_cpool, sizeof(struct cgd_xfer), 0,
    509 	    0, 0, "cgdcpl", NULL, IPL_BIO);
    510 
    511 	mutex_init(&cw->cw_lock, MUTEX_DEFAULT, IPL_BIO);
    512 
    513 	return cw;
    514 }
    515 
    516 static void
    517 cgd_destroy_worker(struct cgd_worker *cw)
    518 {
    519 
    520 	/*
    521 	 * Wait for all worker threads to complete before destroying
    522 	 * the rest of the cgd_worker.
    523 	 */
    524 	if (cw->cw_wq)
    525 		workqueue_destroy(cw->cw_wq);
    526 
    527 	mutex_destroy(&cw->cw_lock);
    528 
    529 	if (cw->cw_cpool) {
    530 		pool_destroy(cw->cw_cpool);
    531 		kmem_free(cw->cw_cpool, sizeof(struct pool));
    532 	}
    533 
    534 	kmem_free(cw, sizeof(struct cgd_worker));
    535 }
    536 
    537 static int
    538 cgdopen(dev_t dev, int flags, int fmt, struct lwp *l)
    539 {
    540 	struct	cgd_softc *sc;
    541 	int error;
    542 
    543 	DPRINTF_FOLLOW(("cgdopen(0x%"PRIx64", %d)\n", dev, flags));
    544 
    545 	error = cgd_lock(true);
    546 	if (error)
    547 		return error;
    548 	sc = getcgd_softc(dev);
    549 	if (sc == NULL)
    550 		sc = cgd_spawn(CGDUNIT(dev));
    551 	cgd_unlock();
    552 	if (sc == NULL)
    553 		return ENXIO;
    554 
    555 	return dk_open(&sc->sc_dksc, dev, flags, fmt, l);
    556 }
    557 
    558 static int
    559 cgdclose(dev_t dev, int flags, int fmt, struct lwp *l)
    560 {
    561 	struct	cgd_softc *sc;
    562 	struct	dk_softc *dksc;
    563 	int error;
    564 
    565 	DPRINTF_FOLLOW(("cgdclose(0x%"PRIx64", %d)\n", dev, flags));
    566 
    567 	error = cgd_lock(false);
    568 	if (error)
    569 		return error;
    570 	sc = getcgd_softc(dev);
    571 	if (sc == NULL) {
    572 		error = ENXIO;
    573 		goto done;
    574 	}
    575 
    576 	dksc = &sc->sc_dksc;
    577 	if ((error =  dk_close(dksc, dev, flags, fmt, l)) != 0)
    578 		goto done;
    579 
    580 	if (!DK_ATTACHED(dksc)) {
    581 		if ((error = cgd_destroy(sc->sc_dksc.sc_dev)) != 0) {
    582 			device_printf(dksc->sc_dev,
    583 			    "unable to detach instance\n");
    584 			goto done;
    585 		}
    586 	}
    587 
    588 done:
    589 	cgd_unlock();
    590 
    591 	return error;
    592 }
    593 
    594 static void
    595 cgdstrategy(struct buf *bp)
    596 {
    597 	struct	cgd_softc *sc = getcgd_softc(bp->b_dev);
    598 
    599 	DPRINTF_FOLLOW(("cgdstrategy(%p): b_bcount = %ld\n", bp,
    600 	    (long)bp->b_bcount));
    601 
    602 	/*
    603 	 * Reject unaligned writes.
    604 	 */
    605 	if (((uintptr_t)bp->b_data & 3) != 0) {
    606 		bp->b_error = EINVAL;
    607 		goto bail;
    608 	}
    609 
    610 	dk_strategy(&sc->sc_dksc, bp);
    611 	return;
    612 
    613 bail:
    614 	bp->b_resid = bp->b_bcount;
    615 	biodone(bp);
    616 	return;
    617 }
    618 
    619 static int
    620 cgdsize(dev_t dev)
    621 {
    622 	struct cgd_softc *sc = getcgd_softc(dev);
    623 
    624 	DPRINTF_FOLLOW(("cgdsize(0x%"PRIx64")\n", dev));
    625 	if (!sc)
    626 		return -1;
    627 	return dk_size(&sc->sc_dksc, dev);
    628 }
    629 
    630 /*
    631  * cgd_{get,put}data are functions that deal with getting a buffer
    632  * for the new encrypted data.
    633  * We can no longer have a buffer per device, we need a buffer per
    634  * work queue...
    635  */
    636 
    637 static void *
    638 cgd_getdata(struct cgd_softc *sc, unsigned long size)
    639 {
    640 	void *data = NULL;
    641 
    642 	mutex_enter(&sc->sc_lock);
    643 	if (!sc->sc_data_used) {
    644 		sc->sc_data_used = true;
    645 		data = sc->sc_data;
    646 	}
    647 	mutex_exit(&sc->sc_lock);
    648 
    649 	if (data)
    650 		return data;
    651 
    652 	return kmem_intr_alloc(size, KM_NOSLEEP);
    653 }
    654 
    655 static void
    656 cgd_putdata(struct cgd_softc *sc, void *data, unsigned long size)
    657 {
    658 
    659 	if (data == sc->sc_data) {
    660 		mutex_enter(&sc->sc_lock);
    661 		sc->sc_data_used = false;
    662 		mutex_exit(&sc->sc_lock);
    663 	} else
    664 		kmem_intr_free(data, size);
    665 }
    666 
    667 static int
    668 cgd_diskstart(device_t dev, struct buf *bp)
    669 {
    670 	struct	cgd_softc *sc = device_private(dev);
    671 	struct	cgd_worker *cw = sc->sc_worker;
    672 	struct	dk_softc *dksc = &sc->sc_dksc;
    673 	struct	disk_geom *dg = &dksc->sc_dkdev.dk_geom;
    674 	struct	cgd_xfer *cx;
    675 	struct	buf *nbp;
    676 	void *	newaddr;
    677 	daddr_t	bn;
    678 
    679 	DPRINTF_FOLLOW(("cgd_diskstart(%p, %p)\n", dksc, bp));
    680 
    681 	bn = bp->b_rawblkno;
    682 
    683 	/*
    684 	 * We attempt to allocate all of our resources up front, so that
    685 	 * we can fail quickly if they are unavailable.
    686 	 */
    687 	nbp = getiobuf(sc->sc_tvn, false);
    688 	if (nbp == NULL)
    689 		return EAGAIN;
    690 
    691 	cx = pool_get(cw->cw_cpool, PR_NOWAIT);
    692 	if (cx == NULL) {
    693 		putiobuf(nbp);
    694 		return EAGAIN;
    695 	}
    696 
    697 	cx->cx_sc = sc;
    698 	cx->cx_obp = bp;
    699 	cx->cx_nbp = nbp;
    700 	cx->cx_srcv = cx->cx_dstv = bp->b_data;
    701 	cx->cx_blkno = bn;
    702 	cx->cx_secsize = dg->dg_secsize;
    703 
    704 	/*
    705 	 * If we are writing, then we need to encrypt the outgoing
    706 	 * block into a new block of memory.
    707 	 */
    708 	if ((bp->b_flags & B_READ) == 0) {
    709 		newaddr = cgd_getdata(sc, bp->b_bcount);
    710 		if (!newaddr) {
    711 			pool_put(cw->cw_cpool, cx);
    712 			putiobuf(nbp);
    713 			return EAGAIN;
    714 		}
    715 
    716 		cx->cx_dstv = newaddr;
    717 		cx->cx_len = bp->b_bcount;
    718 		cx->cx_dir = CGD_CIPHER_ENCRYPT;
    719 
    720 		cgd_enqueue(sc, cx);
    721 		return 0;
    722 	}
    723 
    724 	cgd_diskstart2(sc, cx);
    725 	return 0;
    726 }
    727 
    728 static void
    729 cgd_diskstart2(struct cgd_softc *sc, struct cgd_xfer *cx)
    730 {
    731 	struct	vnode *vp;
    732 	struct	buf *bp;
    733 	struct	buf *nbp;
    734 
    735 	bp = cx->cx_obp;
    736 	nbp = cx->cx_nbp;
    737 
    738 	nbp->b_data = cx->cx_dstv;
    739 	nbp->b_flags = bp->b_flags;
    740 	nbp->b_oflags = bp->b_oflags;
    741 	nbp->b_cflags = bp->b_cflags;
    742 	nbp->b_iodone = cgdiodone;
    743 	nbp->b_proc = bp->b_proc;
    744 	nbp->b_blkno = btodb(cx->cx_blkno * cx->cx_secsize);
    745 	nbp->b_bcount = bp->b_bcount;
    746 	nbp->b_private = cx;
    747 
    748 	BIO_COPYPRIO(nbp, bp);
    749 
    750 	if ((nbp->b_flags & B_READ) == 0) {
    751 		vp = nbp->b_vp;
    752 		mutex_enter(vp->v_interlock);
    753 		vp->v_numoutput++;
    754 		mutex_exit(vp->v_interlock);
    755 	}
    756 	VOP_STRATEGY(sc->sc_tvn, nbp);
    757 }
    758 
    759 static void
    760 cgdiodone(struct buf *nbp)
    761 {
    762 	struct	cgd_xfer *cx = nbp->b_private;
    763 	struct	buf *obp = cx->cx_obp;
    764 	struct	cgd_softc *sc = getcgd_softc(obp->b_dev);
    765 	struct	dk_softc *dksc = &sc->sc_dksc;
    766 	struct	disk_geom *dg = &dksc->sc_dkdev.dk_geom;
    767 	daddr_t	bn;
    768 
    769 	KDASSERT(sc);
    770 
    771 	DPRINTF_FOLLOW(("cgdiodone(%p)\n", nbp));
    772 	DPRINTF(CGDB_IO, ("cgdiodone: bp %p bcount %d resid %d\n",
    773 	    obp, obp->b_bcount, obp->b_resid));
    774 	DPRINTF(CGDB_IO, (" dev 0x%"PRIx64", nbp %p bn %" PRId64
    775 	    " addr %p bcnt %d\n", nbp->b_dev, nbp, nbp->b_blkno, nbp->b_data,
    776 		nbp->b_bcount));
    777 	if (nbp->b_error != 0) {
    778 		obp->b_error = nbp->b_error;
    779 		DPRINTF(CGDB_IO, ("%s: error %d\n", dksc->sc_xname,
    780 		    obp->b_error));
    781 	}
    782 
    783 	/* Perform the decryption if we are reading.
    784 	 *
    785 	 * Note: use the blocknumber from nbp, since it is what
    786 	 *       we used to encrypt the blocks.
    787 	 */
    788 
    789 	if (nbp->b_flags & B_READ) {
    790 		bn = dbtob(nbp->b_blkno) / dg->dg_secsize;
    791 
    792 		cx->cx_obp     = obp;
    793 		cx->cx_nbp     = nbp;
    794 		cx->cx_dstv    = obp->b_data;
    795 		cx->cx_srcv    = obp->b_data;
    796 		cx->cx_len     = obp->b_bcount;
    797 		cx->cx_blkno   = bn;
    798 		cx->cx_secsize = dg->dg_secsize;
    799 		cx->cx_dir     = CGD_CIPHER_DECRYPT;
    800 
    801 		cgd_enqueue(sc, cx);
    802 		return;
    803 	}
    804 
    805 	cgd_iodone2(sc, cx);
    806 }
    807 
    808 static void
    809 cgd_iodone2(struct cgd_softc *sc, struct cgd_xfer *cx)
    810 {
    811 	struct cgd_worker *cw = sc->sc_worker;
    812 	struct buf *obp = cx->cx_obp;
    813 	struct buf *nbp = cx->cx_nbp;
    814 	struct dk_softc *dksc = &sc->sc_dksc;
    815 
    816 	pool_put(cw->cw_cpool, cx);
    817 
    818 	/* If we allocated memory, free it now... */
    819 	if (nbp->b_data != obp->b_data)
    820 		cgd_putdata(sc, nbp->b_data, nbp->b_bcount);
    821 
    822 	putiobuf(nbp);
    823 
    824 	/* Request is complete for whatever reason */
    825 	obp->b_resid = 0;
    826 	if (obp->b_error != 0)
    827 		obp->b_resid = obp->b_bcount;
    828 
    829 	dk_done(dksc, obp);
    830 	dk_start(dksc, NULL);
    831 }
    832 
    833 static int
    834 cgd_dumpblocks(device_t dev, void *va, daddr_t blkno, int nblk)
    835 {
    836 	struct cgd_softc *sc = device_private(dev);
    837 	struct dk_softc *dksc = &sc->sc_dksc;
    838 	struct disk_geom *dg = &dksc->sc_dkdev.dk_geom;
    839 	size_t nbytes, blksize;
    840 	void *buf;
    841 	int error;
    842 
    843 	/*
    844 	 * dk_dump gives us units of disklabel sectors.  Everything
    845 	 * else in cgd uses units of diskgeom sectors.  These had
    846 	 * better agree; otherwise we need to figure out how to convert
    847 	 * between them.
    848 	 */
    849 	KASSERTMSG((dg->dg_secsize == dksc->sc_dkdev.dk_label->d_secsize),
    850 	    "diskgeom secsize %"PRIu32" != disklabel secsize %"PRIu32,
    851 	    dg->dg_secsize, dksc->sc_dkdev.dk_label->d_secsize);
    852 	blksize = dg->dg_secsize;
    853 
    854 	/*
    855 	 * Compute the number of bytes in this request, which dk_dump
    856 	 * has `helpfully' converted to a number of blocks for us.
    857 	 */
    858 	nbytes = nblk*blksize;
    859 
    860 	/* Try to acquire a buffer to store the ciphertext.  */
    861 	buf = cgd_getdata(sc, nbytes);
    862 	if (buf == NULL)
    863 		/* Out of memory: give up.  */
    864 		return ENOMEM;
    865 
    866 	/* Encrypt the caller's data into the temporary buffer.  */
    867 	cgd_cipher(sc, buf, va, nbytes, blkno, blksize, CGD_CIPHER_ENCRYPT);
    868 
    869 	/* Pass it on to the underlying disk device.  */
    870 	error = bdev_dump(sc->sc_tdev, blkno, buf, nbytes);
    871 
    872 	/* Release the buffer.  */
    873 	cgd_putdata(sc, buf, nbytes);
    874 
    875 	/* Return any error from the underlying disk device.  */
    876 	return error;
    877 }
    878 
    879 /* XXX: we should probably put these into dksubr.c, mostly */
    880 static int
    881 cgdread(dev_t dev, struct uio *uio, int flags)
    882 {
    883 	struct	cgd_softc *sc;
    884 	struct	dk_softc *dksc;
    885 
    886 	DPRINTF_FOLLOW(("cgdread(0x%llx, %p, %d)\n",
    887 	    (unsigned long long)dev, uio, flags));
    888 	sc = getcgd_softc(dev);
    889 	if (sc == NULL)
    890 		return ENXIO;
    891 	dksc = &sc->sc_dksc;
    892 	if (!DK_ATTACHED(dksc))
    893 		return ENXIO;
    894 	return physio(cgdstrategy, NULL, dev, B_READ, minphys, uio);
    895 }
    896 
    897 /* XXX: we should probably put these into dksubr.c, mostly */
    898 static int
    899 cgdwrite(dev_t dev, struct uio *uio, int flags)
    900 {
    901 	struct	cgd_softc *sc;
    902 	struct	dk_softc *dksc;
    903 
    904 	DPRINTF_FOLLOW(("cgdwrite(0x%"PRIx64", %p, %d)\n", dev, uio, flags));
    905 	sc = getcgd_softc(dev);
    906 	if (sc == NULL)
    907 		return ENXIO;
    908 	dksc = &sc->sc_dksc;
    909 	if (!DK_ATTACHED(dksc))
    910 		return ENXIO;
    911 	return physio(cgdstrategy, NULL, dev, B_WRITE, minphys, uio);
    912 }
    913 
    914 static int
    915 cgdioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
    916 {
    917 	struct	cgd_softc *sc;
    918 	struct	dk_softc *dksc;
    919 	int	part = DISKPART(dev);
    920 	int	pmask = 1 << part;
    921 	int	error;
    922 
    923 	DPRINTF_FOLLOW(("cgdioctl(0x%"PRIx64", %ld, %p, %d, %p)\n",
    924 	    dev, cmd, data, flag, l));
    925 
    926 	switch (cmd) {
    927 	case CGDIOCGET:
    928 		return cgd_ioctl_get(dev, data, l);
    929 	case CGDIOCSET:
    930 	case CGDIOCCLR:
    931 		if ((flag & FWRITE) == 0)
    932 			return EBADF;
    933 		/* FALLTHROUGH */
    934 	default:
    935 		sc = getcgd_softc(dev);
    936 		if (sc == NULL)
    937 			return ENXIO;
    938 		dksc = &sc->sc_dksc;
    939 		break;
    940 	}
    941 
    942 	switch (cmd) {
    943 	case CGDIOCSET:
    944 		cgd_busy(sc);
    945 		if (DK_ATTACHED(dksc))
    946 			error = EBUSY;
    947 		else
    948 			error = cgd_ioctl_set(sc, data, l);
    949 		cgd_unbusy(sc);
    950 		break;
    951 	case CGDIOCCLR:
    952 		cgd_busy(sc);
    953 		if (DK_BUSY(&sc->sc_dksc, pmask))
    954 			error = EBUSY;
    955 		else
    956 			error = cgd_ioctl_clr(sc, l);
    957 		cgd_unbusy(sc);
    958 		break;
    959 	case DIOCGCACHE:
    960 	case DIOCCACHESYNC:
    961 		cgd_busy(sc);
    962 		if (!DK_ATTACHED(dksc)) {
    963 			cgd_unbusy(sc);
    964 			error = ENOENT;
    965 			break;
    966 		}
    967 		/*
    968 		 * We pass this call down to the underlying disk.
    969 		 */
    970 		error = VOP_IOCTL(sc->sc_tvn, cmd, data, flag, l->l_cred);
    971 		cgd_unbusy(sc);
    972 		break;
    973 	case DIOCGSECTORALIGN: {
    974 		struct disk_sectoralign *dsa = data;
    975 
    976 		cgd_busy(sc);
    977 		if (!DK_ATTACHED(dksc)) {
    978 			cgd_unbusy(sc);
    979 			error = ENOENT;
    980 			break;
    981 		}
    982 
    983 		/* Get the underlying disk's sector alignment.  */
    984 		error = VOP_IOCTL(sc->sc_tvn, cmd, data, flag, l->l_cred);
    985 		if (error) {
    986 			cgd_unbusy(sc);
    987 			break;
    988 		}
    989 
    990 		/* Adjust for the disklabel partition if necessary.  */
    991 		if (part != RAW_PART) {
    992 			struct disklabel *lp = dksc->sc_dkdev.dk_label;
    993 			daddr_t offset = lp->d_partitions[part].p_offset;
    994 			uint32_t r = offset % dsa->dsa_alignment;
    995 
    996 			if (r < dsa->dsa_firstaligned)
    997 				dsa->dsa_firstaligned = dsa->dsa_firstaligned
    998 				    - r;
    999 			else
   1000 				dsa->dsa_firstaligned = (dsa->dsa_firstaligned
   1001 				    + dsa->dsa_alignment) - r;
   1002 		}
   1003 		cgd_unbusy(sc);
   1004 		break;
   1005 	}
   1006 	case DIOCGSTRATEGY:
   1007 	case DIOCSSTRATEGY:
   1008 		if (!DK_ATTACHED(dksc)) {
   1009 			error = ENOENT;
   1010 			break;
   1011 		}
   1012 		/*FALLTHROUGH*/
   1013 	default:
   1014 		error = dk_ioctl(dksc, dev, cmd, data, flag, l);
   1015 		break;
   1016 	case CGDIOCGET:
   1017 		KASSERT(0);
   1018 		error = EINVAL;
   1019 	}
   1020 
   1021 	return error;
   1022 }
   1023 
   1024 static int
   1025 cgddump(dev_t dev, daddr_t blkno, void *va, size_t size)
   1026 {
   1027 	struct	cgd_softc *sc;
   1028 
   1029 	DPRINTF_FOLLOW(("cgddump(0x%"PRIx64", %" PRId64 ", %p, %lu)\n",
   1030 	    dev, blkno, va, (unsigned long)size));
   1031 	sc = getcgd_softc(dev);
   1032 	if (sc == NULL)
   1033 		return ENXIO;
   1034 	return dk_dump(&sc->sc_dksc, dev, blkno, va, size, DK_DUMP_RECURSIVE);
   1035 }
   1036 
   1037 /*
   1038  * XXXrcd:
   1039  *  for now we hardcode the maximum key length.
   1040  */
   1041 #define MAX_KEYSIZE	1024
   1042 
   1043 static const struct {
   1044 	const char *n;
   1045 	int v;
   1046 	int d;
   1047 } encblkno[] = {
   1048 	{ "encblkno",  CGD_CIPHER_CBC_ENCBLKNO8, 1 },
   1049 	{ "encblkno8", CGD_CIPHER_CBC_ENCBLKNO8, 1 },
   1050 	{ "encblkno1", CGD_CIPHER_CBC_ENCBLKNO1, 8 },
   1051 };
   1052 
   1053 /* ARGSUSED */
   1054 static int
   1055 cgd_ioctl_set(struct cgd_softc *sc, void *data, struct lwp *l)
   1056 {
   1057 	struct	 cgd_ioctl *ci = data;
   1058 	struct	 vnode *vp;
   1059 	int	 ret;
   1060 	size_t	 i;
   1061 	size_t	 keybytes;			/* key length in bytes */
   1062 	const char *cp;
   1063 	struct pathbuf *pb;
   1064 	char	 *inbuf;
   1065 	struct dk_softc *dksc = &sc->sc_dksc;
   1066 
   1067 	cp = ci->ci_disk;
   1068 
   1069 	ret = pathbuf_copyin(ci->ci_disk, &pb);
   1070 	if (ret != 0) {
   1071 		return ret;
   1072 	}
   1073 	ret = dk_lookup(pb, l, &vp);
   1074 	pathbuf_destroy(pb);
   1075 	if (ret != 0) {
   1076 		return ret;
   1077 	}
   1078 
   1079 	inbuf = kmem_alloc(MAX_KEYSIZE, KM_SLEEP);
   1080 
   1081 	if ((ret = cgdinit(sc, cp, vp, l)) != 0)
   1082 		goto bail;
   1083 
   1084 	(void)memset(inbuf, 0, MAX_KEYSIZE);
   1085 	ret = copyinstr(ci->ci_alg, inbuf, 256, NULL);
   1086 	if (ret)
   1087 		goto bail;
   1088 	sc->sc_cfuncs = cryptfuncs_find(inbuf);
   1089 	if (!sc->sc_cfuncs) {
   1090 		ret = EINVAL;
   1091 		goto bail;
   1092 	}
   1093 
   1094 	(void)memset(inbuf, 0, MAX_KEYSIZE);
   1095 	ret = copyinstr(ci->ci_ivmethod, inbuf, MAX_KEYSIZE, NULL);
   1096 	if (ret)
   1097 		goto bail;
   1098 
   1099 	for (i = 0; i < __arraycount(encblkno); i++)
   1100 		if (strcmp(encblkno[i].n, inbuf) == 0)
   1101 			break;
   1102 
   1103 	if (i == __arraycount(encblkno)) {
   1104 		ret = EINVAL;
   1105 		goto bail;
   1106 	}
   1107 
   1108 	keybytes = ci->ci_keylen / 8 + 1;
   1109 	if (keybytes > MAX_KEYSIZE) {
   1110 		ret = EINVAL;
   1111 		goto bail;
   1112 	}
   1113 
   1114 	(void)memset(inbuf, 0, MAX_KEYSIZE);
   1115 	ret = copyin(ci->ci_key, inbuf, keybytes);
   1116 	if (ret)
   1117 		goto bail;
   1118 
   1119 	sc->sc_cdata.cf_blocksize = ci->ci_blocksize;
   1120 	sc->sc_cdata.cf_mode = encblkno[i].v;
   1121 	sc->sc_cdata.cf_keylen = ci->ci_keylen;
   1122 	sc->sc_cdata.cf_priv = sc->sc_cfuncs->cf_init(ci->ci_keylen, inbuf,
   1123 	    &sc->sc_cdata.cf_blocksize);
   1124 	if (sc->sc_cdata.cf_blocksize > CGD_MAXBLOCKSIZE) {
   1125 	    log(LOG_WARNING, "cgd: Disallowed cipher with blocksize %zu > %u\n",
   1126 		sc->sc_cdata.cf_blocksize, CGD_MAXBLOCKSIZE);
   1127 	    sc->sc_cdata.cf_priv = NULL;
   1128 	}
   1129 
   1130 	/*
   1131 	 * The blocksize is supposed to be in bytes. Unfortunately originally
   1132 	 * it was expressed in bits. For compatibility we maintain encblkno
   1133 	 * and encblkno8.
   1134 	 */
   1135 	sc->sc_cdata.cf_blocksize /= encblkno[i].d;
   1136 	(void)explicit_memset(inbuf, 0, MAX_KEYSIZE);
   1137 	if (!sc->sc_cdata.cf_priv) {
   1138 		ret = EINVAL;		/* XXX is this the right error? */
   1139 		goto bail;
   1140 	}
   1141 	kmem_free(inbuf, MAX_KEYSIZE);
   1142 
   1143 	bufq_alloc(&dksc->sc_bufq, "fcfs", 0);
   1144 
   1145 	sc->sc_data = kmem_alloc(MAXPHYS, KM_SLEEP);
   1146 	sc->sc_data_used = false;
   1147 
   1148 	/* Attach the disk. */
   1149 	dk_attach(dksc);
   1150 	disk_attach(&dksc->sc_dkdev);
   1151 
   1152 	disk_set_info(dksc->sc_dev, &dksc->sc_dkdev, NULL);
   1153 
   1154 	/* Discover wedges on this disk. */
   1155 	dkwedge_discover(&dksc->sc_dkdev);
   1156 
   1157 	return 0;
   1158 
   1159 bail:
   1160 	kmem_free(inbuf, MAX_KEYSIZE);
   1161 	(void)vn_close(vp, FREAD|FWRITE, l->l_cred);
   1162 	return ret;
   1163 }
   1164 
   1165 /* ARGSUSED */
   1166 static int
   1167 cgd_ioctl_clr(struct cgd_softc *sc, struct lwp *l)
   1168 {
   1169 	struct	dk_softc *dksc = &sc->sc_dksc;
   1170 
   1171 	if (!DK_ATTACHED(dksc))
   1172 		return ENXIO;
   1173 
   1174 	/* Delete all of our wedges. */
   1175 	dkwedge_delall(&dksc->sc_dkdev);
   1176 
   1177 	/* Kill off any queued buffers. */
   1178 	dk_drain(dksc);
   1179 	bufq_free(dksc->sc_bufq);
   1180 
   1181 	(void)vn_close(sc->sc_tvn, FREAD|FWRITE, l->l_cred);
   1182 	sc->sc_cfuncs->cf_destroy(sc->sc_cdata.cf_priv);
   1183 	kmem_free(sc->sc_tpath, sc->sc_tpathlen);
   1184 	kmem_free(sc->sc_data, MAXPHYS);
   1185 	sc->sc_data_used = false;
   1186 	dk_detach(dksc);
   1187 	disk_detach(&dksc->sc_dkdev);
   1188 
   1189 	return 0;
   1190 }
   1191 
   1192 static int
   1193 cgd_ioctl_get(dev_t dev, void *data, struct lwp *l)
   1194 {
   1195 	struct cgd_softc *sc;
   1196 	struct cgd_user *cgu;
   1197 	int unit, error;
   1198 
   1199 	unit = CGDUNIT(dev);
   1200 	cgu = (struct cgd_user *)data;
   1201 
   1202 	DPRINTF_FOLLOW(("cgd_ioctl_get(0x%"PRIx64", %d, %p, %p)\n",
   1203 			   dev, unit, data, l));
   1204 
   1205 	/* XXX, we always return this units data, so if cgu_unit is
   1206 	 * not -1, that field doesn't match the rest
   1207 	 */
   1208 	if (cgu->cgu_unit == -1)
   1209 		cgu->cgu_unit = unit;
   1210 
   1211 	if (cgu->cgu_unit < 0)
   1212 		return EINVAL;	/* XXX: should this be ENXIO? */
   1213 
   1214 	error = cgd_lock(false);
   1215 	if (error)
   1216 		return error;
   1217 
   1218 	sc = device_lookup_private(&cgd_cd, unit);
   1219 	if (sc == NULL || !DK_ATTACHED(&sc->sc_dksc)) {
   1220 		cgu->cgu_dev = 0;
   1221 		cgu->cgu_alg[0] = '\0';
   1222 		cgu->cgu_blocksize = 0;
   1223 		cgu->cgu_mode = 0;
   1224 		cgu->cgu_keylen = 0;
   1225 	}
   1226 	else {
   1227 		mutex_enter(&sc->sc_lock);
   1228 		cgu->cgu_dev = sc->sc_tdev;
   1229 		strncpy(cgu->cgu_alg, sc->sc_cfuncs->cf_name,
   1230 		    sizeof(cgu->cgu_alg));
   1231 		cgu->cgu_blocksize = sc->sc_cdata.cf_blocksize;
   1232 		cgu->cgu_mode = sc->sc_cdata.cf_mode;
   1233 		cgu->cgu_keylen = sc->sc_cdata.cf_keylen;
   1234 		mutex_exit(&sc->sc_lock);
   1235 	}
   1236 
   1237 	cgd_unlock();
   1238 	return 0;
   1239 }
   1240 
   1241 static int
   1242 cgdinit(struct cgd_softc *sc, const char *cpath, struct vnode *vp,
   1243 	struct lwp *l)
   1244 {
   1245 	struct	disk_geom *dg;
   1246 	int	ret;
   1247 	char	*tmppath;
   1248 	uint64_t psize;
   1249 	unsigned secsize;
   1250 	struct dk_softc *dksc = &sc->sc_dksc;
   1251 
   1252 	sc->sc_tvn = vp;
   1253 	sc->sc_tpath = NULL;
   1254 
   1255 	tmppath = kmem_alloc(MAXPATHLEN, KM_SLEEP);
   1256 	ret = copyinstr(cpath, tmppath, MAXPATHLEN, &sc->sc_tpathlen);
   1257 	if (ret)
   1258 		goto bail;
   1259 	sc->sc_tpath = kmem_alloc(sc->sc_tpathlen, KM_SLEEP);
   1260 	memcpy(sc->sc_tpath, tmppath, sc->sc_tpathlen);
   1261 
   1262 	sc->sc_tdev = vp->v_rdev;
   1263 
   1264 	if ((ret = getdisksize(vp, &psize, &secsize)) != 0)
   1265 		goto bail;
   1266 
   1267 	if (psize == 0) {
   1268 		ret = ENODEV;
   1269 		goto bail;
   1270 	}
   1271 
   1272 	/*
   1273 	 * XXX here we should probe the underlying device.  If we
   1274 	 *     are accessing a partition of type RAW_PART, then
   1275 	 *     we should populate our initial geometry with the
   1276 	 *     geometry that we discover from the device.
   1277 	 */
   1278 	dg = &dksc->sc_dkdev.dk_geom;
   1279 	memset(dg, 0, sizeof(*dg));
   1280 	dg->dg_secperunit = psize;
   1281 	dg->dg_secsize = secsize;
   1282 	dg->dg_ntracks = 1;
   1283 	dg->dg_nsectors = 1024 * 1024 / dg->dg_secsize;
   1284 	dg->dg_ncylinders = dg->dg_secperunit / dg->dg_nsectors;
   1285 
   1286 bail:
   1287 	kmem_free(tmppath, MAXPATHLEN);
   1288 	if (ret && sc->sc_tpath)
   1289 		kmem_free(sc->sc_tpath, sc->sc_tpathlen);
   1290 	return ret;
   1291 }
   1292 
   1293 /*
   1294  * Our generic cipher entry point.  This takes care of the
   1295  * IV mode and passes off the work to the specific cipher.
   1296  * We implement here the IV method ``encrypted block
   1297  * number''.
   1298  *
   1299  * XXXrcd: for now we rely on our own crypto framework defined
   1300  *         in dev/cgd_crypto.c.  This will change when we
   1301  *         get a generic kernel crypto framework.
   1302  */
   1303 
   1304 static void
   1305 blkno2blkno_buf(char *sbuf, daddr_t blkno)
   1306 {
   1307 	int	i;
   1308 
   1309 	/* Set up the blkno in blkno_buf, here we do not care much
   1310 	 * about the final layout of the information as long as we
   1311 	 * can guarantee that each sector will have a different IV
   1312 	 * and that the endianness of the machine will not affect
   1313 	 * the representation that we have chosen.
   1314 	 *
   1315 	 * We choose this representation, because it does not rely
   1316 	 * on the size of buf (which is the blocksize of the cipher),
   1317 	 * but allows daddr_t to grow without breaking existing
   1318 	 * disks.
   1319 	 *
   1320 	 * Note that blkno2blkno_buf does not take a size as input,
   1321 	 * and hence must be called on a pre-zeroed buffer of length
   1322 	 * greater than or equal to sizeof(daddr_t).
   1323 	 */
   1324 	for (i=0; i < sizeof(daddr_t); i++) {
   1325 		*sbuf++ = blkno & 0xff;
   1326 		blkno >>= 8;
   1327 	}
   1328 }
   1329 
   1330 static struct cpu_info *
   1331 cgd_cpu(struct cgd_softc *sc)
   1332 {
   1333 	struct cgd_worker *cw = sc->sc_worker;
   1334 	struct cpu_info *ci = NULL;
   1335 	u_int cidx, i;
   1336 
   1337 	if (cw->cw_busy == 0) {
   1338 		cw->cw_last = cpu_index(curcpu());
   1339 		return NULL;
   1340 	}
   1341 
   1342 	for (i=0, cidx = cw->cw_last+1; i<maxcpus; ++i, ++cidx) {
   1343 		if (cidx >= maxcpus)
   1344 			cidx = 0;
   1345 		ci = cpu_lookup(cidx);
   1346 		if (ci) {
   1347 			cw->cw_last = cidx;
   1348 			break;
   1349 		}
   1350 	}
   1351 
   1352 	return ci;
   1353 }
   1354 
   1355 static void
   1356 cgd_enqueue(struct cgd_softc *sc, struct cgd_xfer *cx)
   1357 {
   1358 	struct cgd_worker *cw = sc->sc_worker;
   1359 	struct cpu_info *ci;
   1360 
   1361 	mutex_enter(&cw->cw_lock);
   1362 	ci = cgd_cpu(sc);
   1363 	cw->cw_busy++;
   1364 	mutex_exit(&cw->cw_lock);
   1365 
   1366 	workqueue_enqueue(cw->cw_wq, &cx->cx_work, ci);
   1367 }
   1368 
   1369 static void
   1370 cgd_process(struct work *wk, void *arg)
   1371 {
   1372 	struct cgd_xfer *cx = (struct cgd_xfer *)wk;
   1373 	struct cgd_softc *sc = cx->cx_sc;
   1374 	struct cgd_worker *cw = sc->sc_worker;
   1375 
   1376 	cgd_cipher(sc, cx->cx_dstv, cx->cx_srcv, cx->cx_len,
   1377 	    cx->cx_blkno, cx->cx_secsize, cx->cx_dir);
   1378 
   1379 	if (cx->cx_dir == CGD_CIPHER_ENCRYPT) {
   1380 		cgd_diskstart2(sc, cx);
   1381 	} else {
   1382 		cgd_iodone2(sc, cx);
   1383 	}
   1384 
   1385 	mutex_enter(&cw->cw_lock);
   1386 	if (cw->cw_busy > 0)
   1387 		cw->cw_busy--;
   1388 	mutex_exit(&cw->cw_lock);
   1389 }
   1390 
   1391 static void
   1392 cgd_cipher(struct cgd_softc *sc, void *dstv, void *srcv,
   1393     size_t len, daddr_t blkno, size_t secsize, int dir)
   1394 {
   1395 	char		*dst = dstv;
   1396 	char		*src = srcv;
   1397 	cfunc_cipher_prep	*ciprep = sc->sc_cfuncs->cf_cipher_prep;
   1398 	cfunc_cipher	*cipher = sc->sc_cfuncs->cf_cipher;
   1399 	struct uio	dstuio;
   1400 	struct uio	srcuio;
   1401 	struct iovec	dstiov[2];
   1402 	struct iovec	srciov[2];
   1403 	size_t		blocksize = sc->sc_cdata.cf_blocksize;
   1404 	size_t		todo;
   1405 	char		blkno_buf[CGD_MAXBLOCKSIZE], *iv;
   1406 
   1407 	DPRINTF_FOLLOW(("cgd_cipher() dir=%d\n", dir));
   1408 
   1409 	DIAGCONDPANIC(len % blocksize != 0,
   1410 	    ("cgd_cipher: len %% blocksize != 0"));
   1411 
   1412 	/* ensure that sizeof(daddr_t) <= blocksize (for encblkno IVing) */
   1413 	DIAGCONDPANIC(sizeof(daddr_t) > blocksize,
   1414 	    ("cgd_cipher: sizeof(daddr_t) > blocksize"));
   1415 
   1416 	DIAGCONDPANIC(blocksize > CGD_MAXBLOCKSIZE,
   1417 	    ("cgd_cipher: blocksize > CGD_MAXBLOCKSIZE"));
   1418 
   1419 	dstuio.uio_iov = dstiov;
   1420 	dstuio.uio_iovcnt = 1;
   1421 
   1422 	srcuio.uio_iov = srciov;
   1423 	srcuio.uio_iovcnt = 1;
   1424 
   1425 	for (; len > 0; len -= todo) {
   1426 		todo = MIN(len, secsize);
   1427 
   1428 		dstiov[0].iov_base = dst;
   1429 		srciov[0].iov_base = src;
   1430 		dstiov[0].iov_len  = todo;
   1431 		srciov[0].iov_len  = todo;
   1432 
   1433 		memset(blkno_buf, 0x0, blocksize);
   1434 		blkno2blkno_buf(blkno_buf, blkno);
   1435 		IFDEBUG(CGDB_CRYPTO, hexprint("step 1: blkno_buf",
   1436 		    blkno_buf, blocksize));
   1437 
   1438 		/*
   1439 		 * Compute an initial IV. All ciphers
   1440 		 * can convert blkno_buf in-place.
   1441 		 */
   1442 		iv = blkno_buf;
   1443 		ciprep(sc->sc_cdata.cf_priv, iv, blkno_buf, blocksize, dir);
   1444 		IFDEBUG(CGDB_CRYPTO, hexprint("step 2: iv", iv, blocksize));
   1445 
   1446 		cipher(sc->sc_cdata.cf_priv, &dstuio, &srcuio, iv, dir);
   1447 
   1448 		dst += todo;
   1449 		src += todo;
   1450 		blkno++;
   1451 	}
   1452 }
   1453 
   1454 #ifdef DEBUG
   1455 static void
   1456 hexprint(const char *start, void *buf, int len)
   1457 {
   1458 	char	*c = buf;
   1459 
   1460 	DIAGCONDPANIC(len < 0, ("hexprint: called with len < 0"));
   1461 	printf("%s: len=%06d 0x", start, len);
   1462 	while (len--)
   1463 		printf("%02x", (unsigned char) *c++);
   1464 }
   1465 #endif
   1466 
   1467 static void
   1468 selftest(void)
   1469 {
   1470 	struct cgd_softc sc;
   1471 	void *buf;
   1472 
   1473 	printf("running cgd selftest ");
   1474 
   1475 	for (size_t i = 0; i < __arraycount(selftests); i++) {
   1476 		const char *alg = selftests[i].alg;
   1477 		const uint8_t *key = selftests[i].key;
   1478 		int keylen = selftests[i].keylen;
   1479 		int txtlen = selftests[i].txtlen;
   1480 
   1481 		printf("%s-%d ", alg, keylen);
   1482 
   1483 		memset(&sc, 0, sizeof(sc));
   1484 
   1485 		sc.sc_cfuncs = cryptfuncs_find(alg);
   1486 		if (sc.sc_cfuncs == NULL)
   1487 			panic("%s not implemented", alg);
   1488 
   1489 		sc.sc_cdata.cf_blocksize = 8 * selftests[i].blocksize;
   1490 		sc.sc_cdata.cf_mode = CGD_CIPHER_CBC_ENCBLKNO1;
   1491 		sc.sc_cdata.cf_keylen = keylen;
   1492 
   1493 		sc.sc_cdata.cf_priv = sc.sc_cfuncs->cf_init(keylen,
   1494 		    key, &sc.sc_cdata.cf_blocksize);
   1495 		if (sc.sc_cdata.cf_priv == NULL)
   1496 			panic("cf_priv is NULL");
   1497 		if (sc.sc_cdata.cf_blocksize > CGD_MAXBLOCKSIZE)
   1498 			panic("bad block size %zu", sc.sc_cdata.cf_blocksize);
   1499 
   1500 		sc.sc_cdata.cf_blocksize /= 8;
   1501 
   1502 		buf = kmem_alloc(txtlen, KM_SLEEP);
   1503 		memcpy(buf, selftests[i].ptxt, txtlen);
   1504 
   1505 		cgd_cipher(&sc, buf, buf, txtlen, selftests[i].blkno,
   1506 				selftests[i].secsize, CGD_CIPHER_ENCRYPT);
   1507 		if (memcmp(buf, selftests[i].ctxt, txtlen) != 0)
   1508 			panic("encryption is broken");
   1509 
   1510 		cgd_cipher(&sc, buf, buf, txtlen, selftests[i].blkno,
   1511 				selftests[i].secsize, CGD_CIPHER_DECRYPT);
   1512 		if (memcmp(buf, selftests[i].ptxt, txtlen) != 0)
   1513 			panic("decryption is broken");
   1514 
   1515 		kmem_free(buf, txtlen);
   1516 		sc.sc_cfuncs->cf_destroy(sc.sc_cdata.cf_priv);
   1517 	}
   1518 
   1519 	printf("done\n");
   1520 }
   1521 
   1522 MODULE(MODULE_CLASS_DRIVER, cgd, "blowfish,des,dk_subr,bufq_fcfs");
   1523 
   1524 #ifdef _MODULE
   1525 CFDRIVER_DECL(cgd, DV_DISK, NULL);
   1526 
   1527 devmajor_t cgd_bmajor = -1, cgd_cmajor = -1;
   1528 #endif
   1529 
   1530 static int
   1531 cgd_modcmd(modcmd_t cmd, void *arg)
   1532 {
   1533 	int error = 0;
   1534 
   1535 	switch (cmd) {
   1536 	case MODULE_CMD_INIT:
   1537 		selftest();
   1538 #ifdef _MODULE
   1539 		mutex_init(&cgd_spawning_mtx, MUTEX_DEFAULT, IPL_NONE);
   1540 		cv_init(&cgd_spawning_cv, "cgspwn");
   1541 
   1542 		error = config_cfdriver_attach(&cgd_cd);
   1543 		if (error)
   1544 			break;
   1545 
   1546 		error = config_cfattach_attach(cgd_cd.cd_name, &cgd_ca);
   1547 	        if (error) {
   1548 			config_cfdriver_detach(&cgd_cd);
   1549 			aprint_error("%s: unable to register cfattach for"
   1550 			    "%s, error %d\n", __func__, cgd_cd.cd_name, error);
   1551 			break;
   1552 		}
   1553 		/*
   1554 		 * Attach the {b,c}devsw's
   1555 		 */
   1556 		error = devsw_attach("cgd", &cgd_bdevsw, &cgd_bmajor,
   1557 		    &cgd_cdevsw, &cgd_cmajor);
   1558 
   1559 		/*
   1560 		 * If devsw_attach fails, remove from autoconf database
   1561 		 */
   1562 		if (error) {
   1563 			config_cfattach_detach(cgd_cd.cd_name, &cgd_ca);
   1564 			config_cfdriver_detach(&cgd_cd);
   1565 			aprint_error("%s: unable to attach %s devsw, "
   1566 			    "error %d", __func__, cgd_cd.cd_name, error);
   1567 			break;
   1568 		}
   1569 #endif
   1570 		break;
   1571 
   1572 	case MODULE_CMD_FINI:
   1573 #ifdef _MODULE
   1574 		/*
   1575 		 * Remove {b,c}devsw's
   1576 		 */
   1577 		devsw_detach(&cgd_bdevsw, &cgd_cdevsw);
   1578 
   1579 		/*
   1580 		 * Now remove device from autoconf database
   1581 		 */
   1582 		error = config_cfattach_detach(cgd_cd.cd_name, &cgd_ca);
   1583 		if (error) {
   1584 			(void)devsw_attach("cgd", &cgd_bdevsw, &cgd_bmajor,
   1585 			    &cgd_cdevsw, &cgd_cmajor);
   1586 			aprint_error("%s: failed to detach %s cfattach, "
   1587 			    "error %d\n", __func__, cgd_cd.cd_name, error);
   1588  			break;
   1589 		}
   1590 		error = config_cfdriver_detach(&cgd_cd);
   1591 		if (error) {
   1592 			(void)config_cfattach_attach(cgd_cd.cd_name, &cgd_ca);
   1593 			(void)devsw_attach("cgd", &cgd_bdevsw, &cgd_bmajor,
   1594 			    &cgd_cdevsw, &cgd_cmajor);
   1595 			aprint_error("%s: failed to detach %s cfdriver, "
   1596 			    "error %d\n", __func__, cgd_cd.cd_name, error);
   1597 			break;
   1598 		}
   1599 
   1600 		cv_destroy(&cgd_spawning_cv);
   1601 		mutex_destroy(&cgd_spawning_mtx);
   1602 #endif
   1603 		break;
   1604 
   1605 	case MODULE_CMD_STAT:
   1606 		error = ENOTTY;
   1607 		break;
   1608 	default:
   1609 		error = ENOTTY;
   1610 		break;
   1611 	}
   1612 
   1613 	return error;
   1614 }
   1615