Home | History | Annotate | Line # | Download | only in dev
cgd.c revision 1.140
      1 /* $NetBSD: cgd.c,v 1.140 2021/10/17 14:42:15 jmcneill 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.140 2021/10/17 14:42:15 jmcneill Exp $");
     34 
     35 #include <sys/types.h>
     36 #include <sys/param.h>
     37 #include <sys/buf.h>
     38 #include <sys/bufq.h>
     39 #include <sys/conf.h>
     40 #include <sys/cpu.h>
     41 #include <sys/device.h>
     42 #include <sys/disk.h>
     43 #include <sys/disklabel.h>
     44 #include <sys/errno.h>
     45 #include <sys/fcntl.h>
     46 #include <sys/ioctl.h>
     47 #include <sys/kmem.h>
     48 #include <sys/module.h>
     49 #include <sys/namei.h> /* for pathbuf */
     50 #include <sys/pool.h>
     51 #include <sys/proc.h>
     52 #include <sys/syslog.h>
     53 #include <sys/systm.h>
     54 #include <sys/vnode.h>
     55 #include <sys/workqueue.h>
     56 
     57 #include <dev/cgd_crypto.h>
     58 #include <dev/cgdvar.h>
     59 #include <dev/dkvar.h>
     60 
     61 #include <miscfs/specfs/specdev.h> /* for v_rdev */
     62 
     63 #include "ioconf.h"
     64 
     65 struct selftest_params {
     66 	const char *alg;
     67 	int encblkno8;
     68 	int blocksize;	/* number of bytes */
     69 	int secsize;
     70 	daddr_t blkno;
     71 	int keylen;	/* number of bits */
     72 	int txtlen;	/* number of bytes */
     73 	const uint8_t *key;
     74 	const uint8_t *ptxt;
     75 	const uint8_t *ctxt;
     76 };
     77 
     78 /* Entry Point Functions */
     79 
     80 static dev_type_open(cgdopen);
     81 static dev_type_close(cgdclose);
     82 static dev_type_read(cgdread);
     83 static dev_type_write(cgdwrite);
     84 static dev_type_ioctl(cgdioctl);
     85 static dev_type_strategy(cgdstrategy);
     86 static dev_type_dump(cgddump);
     87 static dev_type_size(cgdsize);
     88 
     89 const struct bdevsw cgd_bdevsw = {
     90 	.d_open = cgdopen,
     91 	.d_close = cgdclose,
     92 	.d_strategy = cgdstrategy,
     93 	.d_ioctl = cgdioctl,
     94 	.d_dump = cgddump,
     95 	.d_psize = cgdsize,
     96 	.d_discard = nodiscard,
     97 	.d_flag = D_DISK | D_MPSAFE
     98 };
     99 
    100 const struct cdevsw cgd_cdevsw = {
    101 	.d_open = cgdopen,
    102 	.d_close = cgdclose,
    103 	.d_read = cgdread,
    104 	.d_write = cgdwrite,
    105 	.d_ioctl = cgdioctl,
    106 	.d_stop = nostop,
    107 	.d_tty = notty,
    108 	.d_poll = nopoll,
    109 	.d_mmap = nommap,
    110 	.d_kqfilter = nokqfilter,
    111 	.d_discard = nodiscard,
    112 	.d_flag = D_DISK | D_MPSAFE
    113 };
    114 
    115 /*
    116  * Vector 5 from IEEE 1619/D16 truncated to 64 bytes, blkno 1.
    117  */
    118 static const uint8_t selftest_aes_xts_256_ptxt[64] = {
    119 	0x27, 0xa7, 0x47, 0x9b, 0xef, 0xa1, 0xd4, 0x76,
    120 	0x48, 0x9f, 0x30, 0x8c, 0xd4, 0xcf, 0xa6, 0xe2,
    121 	0xa9, 0x6e, 0x4b, 0xbe, 0x32, 0x08, 0xff, 0x25,
    122 	0x28, 0x7d, 0xd3, 0x81, 0x96, 0x16, 0xe8, 0x9c,
    123 	0xc7, 0x8c, 0xf7, 0xf5, 0xe5, 0x43, 0x44, 0x5f,
    124 	0x83, 0x33, 0xd8, 0xfa, 0x7f, 0x56, 0x00, 0x00,
    125 	0x05, 0x27, 0x9f, 0xa5, 0xd8, 0xb5, 0xe4, 0xad,
    126 	0x40, 0xe7, 0x36, 0xdd, 0xb4, 0xd3, 0x54, 0x12,
    127 };
    128 
    129 static const uint8_t selftest_aes_xts_256_ctxt[512] = {
    130 	0x26, 0x4d, 0x3c, 0xa8, 0x51, 0x21, 0x94, 0xfe,
    131 	0xc3, 0x12, 0xc8, 0xc9, 0x89, 0x1f, 0x27, 0x9f,
    132 	0xef, 0xdd, 0x60, 0x8d, 0x0c, 0x02, 0x7b, 0x60,
    133 	0x48, 0x3a, 0x3f, 0xa8, 0x11, 0xd6, 0x5e, 0xe5,
    134 	0x9d, 0x52, 0xd9, 0xe4, 0x0e, 0xc5, 0x67, 0x2d,
    135 	0x81, 0x53, 0x2b, 0x38, 0xb6, 0xb0, 0x89, 0xce,
    136 	0x95, 0x1f, 0x0f, 0x9c, 0x35, 0x59, 0x0b, 0x8b,
    137 	0x97, 0x8d, 0x17, 0x52, 0x13, 0xf3, 0x29, 0xbb,
    138 };
    139 
    140 static const uint8_t selftest_aes_xts_256_key[33] = {
    141 	0x27, 0x18, 0x28, 0x18, 0x28, 0x45, 0x90, 0x45,
    142 	0x23, 0x53, 0x60, 0x28, 0x74, 0x71, 0x35, 0x26,
    143 	0x31, 0x41, 0x59, 0x26, 0x53, 0x58, 0x97, 0x93,
    144 	0x23, 0x84, 0x62, 0x64, 0x33, 0x83, 0x27, 0x95,
    145 	0
    146 };
    147 
    148 /*
    149  * Vector 11 from IEEE 1619/D16 truncated to 64 bytes, blkno 0xffff.
    150  */
    151 static const uint8_t selftest_aes_xts_512_ptxt[64] = {
    152 	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    153 	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
    154 	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
    155 	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
    156 	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
    157 	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
    158 	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
    159 	0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
    160 };
    161 
    162 static const uint8_t selftest_aes_xts_512_ctxt[64] = {
    163 	0x77, 0xa3, 0x12, 0x51, 0x61, 0x8a, 0x15, 0xe6,
    164 	0xb9, 0x2d, 0x1d, 0x66, 0xdf, 0xfe, 0x7b, 0x50,
    165 	0xb5, 0x0b, 0xad, 0x55, 0x23, 0x05, 0xba, 0x02,
    166 	0x17, 0xa6, 0x10, 0x68, 0x8e, 0xff, 0x7e, 0x11,
    167 	0xe1, 0xd0, 0x22, 0x54, 0x38, 0xe0, 0x93, 0x24,
    168 	0x2d, 0x6d, 0xb2, 0x74, 0xfd, 0xe8, 0x01, 0xd4,
    169 	0xca, 0xe0, 0x6f, 0x20, 0x92, 0xc7, 0x28, 0xb2,
    170 	0x47, 0x85, 0x59, 0xdf, 0x58, 0xe8, 0x37, 0xc2,
    171 };
    172 
    173 static const uint8_t selftest_aes_xts_512_key[65] = {
    174 	0x27, 0x18, 0x28, 0x18, 0x28, 0x45, 0x90, 0x45,
    175 	0x23, 0x53, 0x60, 0x28, 0x74, 0x71, 0x35, 0x26,
    176 	0x62, 0x49, 0x77, 0x57, 0x24, 0x70, 0x93, 0x69,
    177 	0x99, 0x59, 0x57, 0x49, 0x66, 0x96, 0x76, 0x27,
    178 	0x31, 0x41, 0x59, 0x26, 0x53, 0x58, 0x97, 0x93,
    179 	0x23, 0x84, 0x62, 0x64, 0x33, 0x83, 0x27, 0x95,
    180 	0x02, 0x88, 0x41, 0x97, 0x16, 0x93, 0x99, 0x37,
    181 	0x51, 0x05, 0x82, 0x09, 0x74, 0x94, 0x45, 0x92,
    182 	0
    183 };
    184 
    185 static const uint8_t selftest_aes_cbc_key[32] = {
    186 	0x27, 0x18, 0x28, 0x18, 0x28, 0x45, 0x90, 0x45,
    187 	0x23, 0x53, 0x60, 0x28, 0x74, 0x71, 0x35, 0x26,
    188 	0x62, 0x49, 0x77, 0x57, 0x24, 0x70, 0x93, 0x69,
    189 	0x99, 0x59, 0x57, 0x49, 0x66, 0x96, 0x76, 0x27,
    190 };
    191 
    192 static const uint8_t selftest_aes_cbc_128_ptxt[64] = {
    193 	0x27, 0xa7, 0x47, 0x9b, 0xef, 0xa1, 0xd4, 0x76,
    194 	0x48, 0x9f, 0x30, 0x8c, 0xd4, 0xcf, 0xa6, 0xe2,
    195 	0xa9, 0x6e, 0x4b, 0xbe, 0x32, 0x08, 0xff, 0x25,
    196 	0x28, 0x7d, 0xd3, 0x81, 0x96, 0x16, 0xe8, 0x9c,
    197 	0xc7, 0x8c, 0xf7, 0xf5, 0xe5, 0x43, 0x44, 0x5f,
    198 	0x83, 0x33, 0xd8, 0xfa, 0x7f, 0x56, 0x00, 0x00,
    199 	0x05, 0x27, 0x9f, 0xa5, 0xd8, 0xb5, 0xe4, 0xad,
    200 	0x40, 0xe7, 0x36, 0xdd, 0xb4, 0xd3, 0x54, 0x12,
    201 };
    202 
    203 static const uint8_t selftest_aes_cbc_128_ctxt[64] = { /* blkno=1 */
    204 	0x93, 0x94, 0x56, 0x36, 0x83, 0xbc, 0xff, 0xa4,
    205 	0xe0, 0x24, 0x34, 0x12, 0xbe, 0xfa, 0xb0, 0x7d,
    206 	0x88, 0x1e, 0xc5, 0x57, 0x55, 0x23, 0x05, 0x0c,
    207 	0x69, 0xa5, 0xc1, 0xda, 0x64, 0xee, 0x74, 0x10,
    208 	0xc2, 0xc5, 0xe6, 0x66, 0xd6, 0xa7, 0x49, 0x1c,
    209 	0x9d, 0x40, 0xb5, 0x0c, 0x9b, 0x6e, 0x1c, 0xe6,
    210 	0xb1, 0x7a, 0x1c, 0xe7, 0x5a, 0xfe, 0xf9, 0x2a,
    211 	0x78, 0xfa, 0xb7, 0x7b, 0x08, 0xdf, 0x8e, 0x51,
    212 };
    213 
    214 static const uint8_t selftest_aes_cbc_256_ptxt[64] = {
    215 	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    216 	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
    217 	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
    218 	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
    219 	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
    220 	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
    221 	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
    222 	0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
    223 };
    224 
    225 static const uint8_t selftest_aes_cbc_256_ctxt[64] = { /* blkno=0xffff */
    226 	0x6c, 0xa3, 0x15, 0x17, 0x51, 0x90, 0xe9, 0x69,
    227 	0x08, 0x36, 0x7b, 0xa6, 0xbb, 0xd1, 0x0b, 0x9e,
    228 	0xcd, 0x6b, 0x1e, 0xaf, 0xb6, 0x2e, 0x62, 0x7d,
    229 	0x8e, 0xde, 0xf0, 0xed, 0x0d, 0x44, 0xe7, 0x31,
    230 	0x26, 0xcf, 0xd5, 0x0b, 0x3e, 0x95, 0x59, 0x89,
    231 	0xdf, 0x5d, 0xd6, 0x9a, 0x00, 0x66, 0xcc, 0x7f,
    232 	0x45, 0xd3, 0x06, 0x58, 0xed, 0xef, 0x49, 0x47,
    233 	0x87, 0x89, 0x17, 0x7d, 0x08, 0x56, 0x50, 0xe1,
    234 };
    235 
    236 static const uint8_t selftest_3des_cbc_key[24] = {
    237 	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    238 	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
    239 	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
    240 };
    241 
    242 static const uint8_t selftest_3des_cbc_ptxt[64] = {
    243 	0x27, 0xa7, 0x47, 0x9b, 0xef, 0xa1, 0xd4, 0x76,
    244 	0x48, 0x9f, 0x30, 0x8c, 0xd4, 0xcf, 0xa6, 0xe2,
    245 	0xa9, 0x6e, 0x4b, 0xbe, 0x32, 0x08, 0xff, 0x25,
    246 	0x28, 0x7d, 0xd3, 0x81, 0x96, 0x16, 0xe8, 0x9c,
    247 	0xc7, 0x8c, 0xf7, 0xf5, 0xe5, 0x43, 0x44, 0x5f,
    248 	0x83, 0x33, 0xd8, 0xfa, 0x7f, 0x56, 0x00, 0x00,
    249 	0x05, 0x27, 0x9f, 0xa5, 0xd8, 0xb5, 0xe4, 0xad,
    250 	0x40, 0xe7, 0x36, 0xdd, 0xb4, 0xd3, 0x54, 0x12,
    251 };
    252 
    253 static const uint8_t selftest_3des_cbc_ctxt[64] = {
    254 	0xa2, 0xfe, 0x81, 0xaa, 0x10, 0x6c, 0xea, 0xb9,
    255 	0x11, 0x58, 0x1f, 0x29, 0xb5, 0x86, 0x71, 0x56,
    256 	0xe9, 0x25, 0x1d, 0x07, 0xb1, 0x69, 0x59, 0x6c,
    257 	0x96, 0x80, 0xf7, 0x54, 0x38, 0xaa, 0xa7, 0xe4,
    258 	0xe8, 0x81, 0xf5, 0x00, 0xbb, 0x1c, 0x00, 0x3c,
    259 	0xba, 0x38, 0x45, 0x97, 0x4c, 0xcf, 0x84, 0x14,
    260 	0x46, 0x86, 0xd9, 0xf4, 0xc5, 0xe2, 0xf0, 0x54,
    261 	0xde, 0x41, 0xf6, 0xa1, 0xef, 0x1b, 0x0a, 0xea,
    262 };
    263 
    264 static const uint8_t selftest_bf_cbc_key[56] = {
    265 	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    266 	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
    267 	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
    268 	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
    269 	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
    270 	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
    271 	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
    272 };
    273 
    274 static const uint8_t selftest_bf_cbc_ptxt[64] = {
    275 	0x27, 0xa7, 0x47, 0x9b, 0xef, 0xa1, 0xd4, 0x76,
    276 	0x48, 0x9f, 0x30, 0x8c, 0xd4, 0xcf, 0xa6, 0xe2,
    277 	0xa9, 0x6e, 0x4b, 0xbe, 0x32, 0x08, 0xff, 0x25,
    278 	0x28, 0x7d, 0xd3, 0x81, 0x96, 0x16, 0xe8, 0x9c,
    279 	0xc7, 0x8c, 0xf7, 0xf5, 0xe5, 0x43, 0x44, 0x5f,
    280 	0x83, 0x33, 0xd8, 0xfa, 0x7f, 0x56, 0x00, 0x00,
    281 	0x05, 0x27, 0x9f, 0xa5, 0xd8, 0xb5, 0xe4, 0xad,
    282 	0x40, 0xe7, 0x36, 0xdd, 0xb4, 0xd3, 0x54, 0x12,
    283 };
    284 
    285 static const uint8_t selftest_bf_cbc_ctxt[64] = {
    286 	0xec, 0xa2, 0xc0, 0x0e, 0xa9, 0x7f, 0x04, 0x1e,
    287 	0x2e, 0x4f, 0x64, 0x07, 0x67, 0x3e, 0xf4, 0x58,
    288 	0x61, 0x5f, 0xd3, 0x50, 0x5e, 0xd3, 0x4d, 0x34,
    289 	0xa0, 0x53, 0xbe, 0x47, 0x75, 0x69, 0x3b, 0x1f,
    290 	0x86, 0xf2, 0xae, 0x8b, 0xb7, 0x91, 0xda, 0xd4,
    291 	0x2b, 0xa5, 0x47, 0x9b, 0x7d, 0x13, 0x30, 0xdd,
    292 	0x7b, 0xad, 0x86, 0x57, 0x51, 0x11, 0x74, 0x42,
    293 	0xb8, 0xbf, 0x69, 0x17, 0x20, 0x0a, 0xf7, 0xda,
    294 };
    295 
    296 static const uint8_t selftest_aes_cbc_encblkno8_zero64[64];
    297 static const uint8_t selftest_aes_cbc_encblkno8_ctxt[64] = {
    298 	0xa2, 0x06, 0x26, 0x26, 0xac, 0xdc, 0xe7, 0xcf,
    299 	0x47, 0x68, 0x24, 0x0e, 0xfa, 0x40, 0x44, 0x83,
    300 	0x07, 0xe1, 0xf4, 0x5d, 0x53, 0x47, 0xa0, 0xfe,
    301 	0xc0, 0x6e, 0x4e, 0xf8, 0x9d, 0x98, 0x63, 0xb8,
    302 	0x2c, 0x27, 0xfa, 0x3a, 0xd5, 0x40, 0xda, 0xdb,
    303 	0xe6, 0xc3, 0xe4, 0xfb, 0x85, 0x53, 0xfb, 0x78,
    304 	0x5d, 0xbd, 0x8f, 0x4c, 0x1a, 0x04, 0x9c, 0x88,
    305 	0x85, 0xec, 0x3c, 0x56, 0x46, 0x1a, 0x6e, 0xf5,
    306 };
    307 
    308 const struct selftest_params selftests[] = {
    309 	{
    310 		.alg = "aes-xts",
    311 		.blocksize = 16,
    312 		.secsize = 512,
    313 		.blkno = 1,
    314 		.keylen = 256,
    315 		.txtlen = sizeof(selftest_aes_xts_256_ptxt),
    316 		.key  = selftest_aes_xts_256_key,
    317 		.ptxt = selftest_aes_xts_256_ptxt,
    318 		.ctxt = selftest_aes_xts_256_ctxt
    319 	},
    320 	{
    321 		.alg = "aes-xts",
    322 		.blocksize = 16,
    323 		.secsize = 512,
    324 		.blkno = 0xffff,
    325 		.keylen = 512,
    326 		.txtlen = sizeof(selftest_aes_xts_512_ptxt),
    327 		.key  = selftest_aes_xts_512_key,
    328 		.ptxt = selftest_aes_xts_512_ptxt,
    329 		.ctxt = selftest_aes_xts_512_ctxt
    330 	},
    331 	{
    332 		.alg = "aes-cbc",
    333 		.blocksize = 16,
    334 		.secsize = 512,
    335 		.blkno = 1,
    336 		.keylen = 128,
    337 		.txtlen = sizeof(selftest_aes_cbc_128_ptxt),
    338 		.key  = selftest_aes_cbc_key,
    339 		.ptxt = selftest_aes_cbc_128_ptxt,
    340 		.ctxt = selftest_aes_cbc_128_ctxt,
    341 	},
    342 	{
    343 		.alg = "aes-cbc",
    344 		.blocksize = 16,
    345 		.secsize = 512,
    346 		.blkno = 0xffff,
    347 		.keylen = 256,
    348 		.txtlen = sizeof(selftest_aes_cbc_256_ptxt),
    349 		.key  = selftest_aes_cbc_key,
    350 		.ptxt = selftest_aes_cbc_256_ptxt,
    351 		.ctxt = selftest_aes_cbc_256_ctxt,
    352 	},
    353 	{
    354 		.alg = "3des-cbc",
    355 		.blocksize = 8,
    356 		.secsize = 512,
    357 		.blkno = 1,
    358 		.keylen = 192,	/* 168 + 3*8 parity bits */
    359 		.txtlen = sizeof(selftest_3des_cbc_ptxt),
    360 		.key  = selftest_3des_cbc_key,
    361 		.ptxt = selftest_3des_cbc_ptxt,
    362 		.ctxt = selftest_3des_cbc_ctxt,
    363 	},
    364 	{
    365 		.alg = "blowfish-cbc",
    366 		.blocksize = 8,
    367 		.secsize = 512,
    368 		.blkno = 1,
    369 		.keylen = 448,
    370 		.txtlen = sizeof(selftest_bf_cbc_ptxt),
    371 		.key  = selftest_bf_cbc_key,
    372 		.ptxt = selftest_bf_cbc_ptxt,
    373 		.ctxt = selftest_bf_cbc_ctxt,
    374 	},
    375 	{
    376 		.alg = "aes-cbc",
    377 		.encblkno8 = 1,
    378 		.blocksize = 16,
    379 		.secsize = 512,
    380 		.blkno = 0,
    381 		.keylen = 128,
    382 		.txtlen = sizeof(selftest_aes_cbc_encblkno8_zero64),
    383 		.key = selftest_aes_cbc_encblkno8_zero64,
    384 		.ptxt = selftest_aes_cbc_encblkno8_zero64,
    385 		.ctxt = selftest_aes_cbc_encblkno8_ctxt,
    386 	},
    387 };
    388 
    389 static int cgd_match(device_t, cfdata_t, void *);
    390 static void cgd_attach(device_t, device_t, void *);
    391 static int cgd_detach(device_t, int);
    392 static struct cgd_softc	*cgd_spawn(int);
    393 static struct cgd_worker *cgd_create_one_worker(void);
    394 static void cgd_destroy_one_worker(struct cgd_worker *);
    395 static struct cgd_worker *cgd_create_worker(void);
    396 static void cgd_destroy_worker(struct cgd_worker *);
    397 static int cgd_destroy(device_t);
    398 
    399 /* Internal Functions */
    400 
    401 static int	cgd_diskstart(device_t, struct buf *);
    402 static void	cgd_diskstart2(struct cgd_softc *, struct cgd_xfer *);
    403 static void	cgdiodone(struct buf *);
    404 static void	cgd_iodone2(struct cgd_softc *, struct cgd_xfer *);
    405 static void	cgd_enqueue(struct cgd_softc *, struct cgd_xfer *);
    406 static void	cgd_process(struct work *, void *);
    407 static int	cgd_dumpblocks(device_t, void *, daddr_t, int);
    408 
    409 static int	cgd_ioctl_set(struct cgd_softc *, void *, struct lwp *);
    410 static int	cgd_ioctl_clr(struct cgd_softc *, struct lwp *);
    411 static int	cgd_ioctl_get(dev_t, void *, struct lwp *);
    412 static int	cgdinit(struct cgd_softc *, const char *, struct vnode *,
    413 			struct lwp *);
    414 static void	cgd_cipher(struct cgd_softc *, void *, const void *,
    415 			   size_t, daddr_t, size_t, int);
    416 
    417 static void	cgd_selftest(void);
    418 
    419 static const struct dkdriver cgddkdriver = {
    420         .d_minphys  = minphys,
    421         .d_open = cgdopen,
    422         .d_close = cgdclose,
    423         .d_strategy = cgdstrategy,
    424         .d_iosize = NULL,
    425         .d_diskstart = cgd_diskstart,
    426         .d_dumpblocks = cgd_dumpblocks,
    427         .d_lastclose = NULL
    428 };
    429 
    430 CFATTACH_DECL3_NEW(cgd, sizeof(struct cgd_softc),
    431     cgd_match, cgd_attach, cgd_detach, NULL, NULL, NULL, DVF_DETACH_SHUTDOWN);
    432 
    433 /* DIAGNOSTIC and DEBUG definitions */
    434 
    435 #if defined(CGDDEBUG) && !defined(DEBUG)
    436 #define DEBUG
    437 #endif
    438 
    439 #ifdef DEBUG
    440 int cgddebug = 0;
    441 
    442 #define CGDB_FOLLOW	0x1
    443 #define CGDB_IO	0x2
    444 #define CGDB_CRYPTO	0x4
    445 
    446 #define IFDEBUG(x,y)		if (cgddebug & (x)) y
    447 #define DPRINTF(x,y)		IFDEBUG(x, printf y)
    448 #define DPRINTF_FOLLOW(y)	DPRINTF(CGDB_FOLLOW, y)
    449 
    450 static void	hexprint(const char *, void *, int);
    451 
    452 #else
    453 #define IFDEBUG(x,y)
    454 #define DPRINTF(x,y)
    455 #define DPRINTF_FOLLOW(y)
    456 #endif
    457 
    458 /* Global variables */
    459 
    460 static kmutex_t cgd_spawning_mtx;
    461 static kcondvar_t cgd_spawning_cv;
    462 static bool cgd_spawning;
    463 static struct cgd_worker *cgd_worker;
    464 static u_int cgd_refcnt;	/* number of users of cgd_worker */
    465 
    466 /* Utility Functions */
    467 
    468 #define CGDUNIT(x)		DISKUNIT(x)
    469 
    470 /* The code */
    471 
    472 static int
    473 cgd_lock(bool intr)
    474 {
    475 	int error = 0;
    476 
    477 	mutex_enter(&cgd_spawning_mtx);
    478 	while (cgd_spawning) {
    479 		if (intr)
    480 			error = cv_wait_sig(&cgd_spawning_cv, &cgd_spawning_mtx);
    481 		else
    482 			cv_wait(&cgd_spawning_cv, &cgd_spawning_mtx);
    483 	}
    484 	if (error == 0)
    485 		cgd_spawning = true;
    486 	mutex_exit(&cgd_spawning_mtx);
    487 	return error;
    488 }
    489 
    490 static void
    491 cgd_unlock(void)
    492 {
    493 	mutex_enter(&cgd_spawning_mtx);
    494 	cgd_spawning = false;
    495 	cv_broadcast(&cgd_spawning_cv);
    496 	mutex_exit(&cgd_spawning_mtx);
    497 }
    498 
    499 static struct cgd_softc *
    500 getcgd_softc(dev_t dev)
    501 {
    502 	return device_lookup_private(&cgd_cd, CGDUNIT(dev));
    503 }
    504 
    505 static int
    506 cgd_match(device_t self, cfdata_t cfdata, void *aux)
    507 {
    508 
    509 	return 1;
    510 }
    511 
    512 static void
    513 cgd_attach(device_t parent, device_t self, void *aux)
    514 {
    515 	struct cgd_softc *sc = device_private(self);
    516 
    517 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_BIO);
    518 	cv_init(&sc->sc_cv, "cgdcv");
    519 	dk_init(&sc->sc_dksc, self, DKTYPE_CGD);
    520 	disk_init(&sc->sc_dksc.sc_dkdev, sc->sc_dksc.sc_xname, &cgddkdriver);
    521 
    522 	if (!pmf_device_register(self, NULL, NULL))
    523 		aprint_error_dev(self,
    524 		    "unable to register power management hooks\n");
    525 }
    526 
    527 
    528 static int
    529 cgd_detach(device_t self, int flags)
    530 {
    531 	int ret;
    532 	const int pmask = 1 << RAW_PART;
    533 	struct cgd_softc *sc = device_private(self);
    534 	struct dk_softc *dksc = &sc->sc_dksc;
    535 
    536 	if (DK_BUSY(dksc, pmask))
    537 		return EBUSY;
    538 
    539 	if (DK_ATTACHED(dksc) &&
    540 	    (ret = cgd_ioctl_clr(sc, curlwp)) != 0)
    541 		return ret;
    542 
    543 	disk_destroy(&dksc->sc_dkdev);
    544 	cv_destroy(&sc->sc_cv);
    545 	mutex_destroy(&sc->sc_lock);
    546 
    547 	return 0;
    548 }
    549 
    550 void
    551 cgdattach(int num)
    552 {
    553 #ifndef _MODULE
    554 	int error;
    555 
    556 	mutex_init(&cgd_spawning_mtx, MUTEX_DEFAULT, IPL_NONE);
    557 	cv_init(&cgd_spawning_cv, "cgspwn");
    558 
    559 	error = config_cfattach_attach(cgd_cd.cd_name, &cgd_ca);
    560 	if (error != 0)
    561 		aprint_error("%s: unable to register cfattach\n",
    562 		    cgd_cd.cd_name);
    563 #endif
    564 
    565 	cgd_selftest();
    566 }
    567 
    568 static struct cgd_softc *
    569 cgd_spawn(int unit)
    570 {
    571 	cfdata_t cf;
    572 	struct cgd_worker *cw;
    573 	struct cgd_softc *sc;
    574 
    575 	cf = kmem_alloc(sizeof(*cf), KM_SLEEP);
    576 	cf->cf_name = cgd_cd.cd_name;
    577 	cf->cf_atname = cgd_cd.cd_name;
    578 	cf->cf_unit = unit;
    579 	cf->cf_fstate = FSTATE_STAR;
    580 
    581 	cw = cgd_create_one_worker();
    582 	if (cw == NULL) {
    583 		kmem_free(cf, sizeof(*cf));
    584 		return NULL;
    585 	}
    586 
    587 	sc = device_private(config_attach_pseudo(cf));
    588 	if (sc == NULL) {
    589 		cgd_destroy_one_worker(cw);
    590 		return NULL;
    591 	}
    592 
    593 	sc->sc_worker = cw;
    594 
    595 	return sc;
    596 }
    597 
    598 static int
    599 cgd_destroy(device_t dev)
    600 {
    601 	struct cgd_softc *sc = device_private(dev);
    602 	struct cgd_worker *cw = sc->sc_worker;
    603 	cfdata_t cf;
    604 	int error;
    605 
    606 	cf = device_cfdata(dev);
    607 	error = config_detach(dev, DETACH_QUIET);
    608 	if (error)
    609 		return error;
    610 
    611 	cgd_destroy_one_worker(cw);
    612 
    613 	kmem_free(cf, sizeof(*cf));
    614 	return 0;
    615 }
    616 
    617 static void
    618 cgd_busy(struct cgd_softc *sc)
    619 {
    620 
    621 	mutex_enter(&sc->sc_lock);
    622 	while (sc->sc_busy)
    623 		cv_wait(&sc->sc_cv, &sc->sc_lock);
    624 	sc->sc_busy = true;
    625 	mutex_exit(&sc->sc_lock);
    626 }
    627 
    628 static void
    629 cgd_unbusy(struct cgd_softc *sc)
    630 {
    631 
    632 	mutex_enter(&sc->sc_lock);
    633 	sc->sc_busy = false;
    634 	cv_broadcast(&sc->sc_cv);
    635 	mutex_exit(&sc->sc_lock);
    636 }
    637 
    638 static struct cgd_worker *
    639 cgd_create_one_worker(void)
    640 {
    641 	KASSERT(cgd_spawning);
    642 
    643 	if (cgd_refcnt++ == 0) {
    644 		KASSERT(cgd_worker == NULL);
    645 		cgd_worker = cgd_create_worker();
    646 	}
    647 
    648 	KASSERT(cgd_worker != NULL);
    649 	return cgd_worker;
    650 }
    651 
    652 static void
    653 cgd_destroy_one_worker(struct cgd_worker *cw)
    654 {
    655 	KASSERT(cgd_spawning);
    656 	KASSERT(cw == cgd_worker);
    657 
    658 	if (--cgd_refcnt == 0) {
    659 		cgd_destroy_worker(cgd_worker);
    660 		cgd_worker = NULL;
    661 	}
    662 }
    663 
    664 static struct cgd_worker *
    665 cgd_create_worker(void)
    666 {
    667 	struct cgd_worker *cw;
    668 	struct workqueue *wq;
    669 	struct pool *cp;
    670 	int error;
    671 
    672 	cw = kmem_alloc(sizeof(struct cgd_worker), KM_SLEEP);
    673 	cp = kmem_alloc(sizeof(struct pool), KM_SLEEP);
    674 
    675 	error = workqueue_create(&wq, "cgd", cgd_process, NULL,
    676 	    PRI_BIO, IPL_BIO, WQ_FPU|WQ_MPSAFE|WQ_PERCPU);
    677 	if (error) {
    678 		kmem_free(cp, sizeof(struct pool));
    679 		kmem_free(cw, sizeof(struct cgd_worker));
    680 		return NULL;
    681 	}
    682 
    683 	cw->cw_cpool = cp;
    684 	cw->cw_wq = wq;
    685 	pool_init(cw->cw_cpool, sizeof(struct cgd_xfer), 0,
    686 	    0, 0, "cgdcpl", NULL, IPL_BIO);
    687 	mutex_init(&cw->cw_lock, MUTEX_DEFAULT, IPL_BIO);
    688 
    689 	return cw;
    690 }
    691 
    692 static void
    693 cgd_destroy_worker(struct cgd_worker *cw)
    694 {
    695 	mutex_destroy(&cw->cw_lock);
    696 
    697 	if (cw->cw_cpool) {
    698 		pool_destroy(cw->cw_cpool);
    699 		kmem_free(cw->cw_cpool, sizeof(struct pool));
    700 	}
    701 	if (cw->cw_wq)
    702 		workqueue_destroy(cw->cw_wq);
    703 
    704 	kmem_free(cw, sizeof(struct cgd_worker));
    705 }
    706 
    707 static int
    708 cgdopen(dev_t dev, int flags, int fmt, struct lwp *l)
    709 {
    710 	struct	cgd_softc *sc;
    711 	int error;
    712 
    713 	DPRINTF_FOLLOW(("cgdopen(0x%"PRIx64", %d)\n", dev, flags));
    714 
    715 	error = cgd_lock(true);
    716 	if (error)
    717 		return error;
    718 	sc = getcgd_softc(dev);
    719 	if (sc == NULL)
    720 		sc = cgd_spawn(CGDUNIT(dev));
    721 	cgd_unlock();
    722 	if (sc == NULL)
    723 		return ENXIO;
    724 
    725 	return dk_open(&sc->sc_dksc, dev, flags, fmt, l);
    726 }
    727 
    728 static int
    729 cgdclose(dev_t dev, int flags, int fmt, struct lwp *l)
    730 {
    731 	struct	cgd_softc *sc;
    732 	struct	dk_softc *dksc;
    733 	int error;
    734 
    735 	DPRINTF_FOLLOW(("cgdclose(0x%"PRIx64", %d)\n", dev, flags));
    736 
    737 	error = cgd_lock(false);
    738 	if (error)
    739 		return error;
    740 	sc = getcgd_softc(dev);
    741 	if (sc == NULL) {
    742 		error = ENXIO;
    743 		goto done;
    744 	}
    745 
    746 	dksc = &sc->sc_dksc;
    747 	if ((error =  dk_close(dksc, dev, flags, fmt, l)) != 0)
    748 		goto done;
    749 
    750 	if (!DK_ATTACHED(dksc)) {
    751 		if ((error = cgd_destroy(sc->sc_dksc.sc_dev)) != 0) {
    752 			device_printf(dksc->sc_dev,
    753 			    "unable to detach instance\n");
    754 			goto done;
    755 		}
    756 	}
    757 
    758 done:
    759 	cgd_unlock();
    760 
    761 	return error;
    762 }
    763 
    764 static void
    765 cgdstrategy(struct buf *bp)
    766 {
    767 	struct	cgd_softc *sc = getcgd_softc(bp->b_dev);
    768 
    769 	DPRINTF_FOLLOW(("cgdstrategy(%p): b_bcount = %ld\n", bp,
    770 	    (long)bp->b_bcount));
    771 
    772 	/*
    773 	 * Reject unaligned writes.
    774 	 */
    775 	if (((uintptr_t)bp->b_data & 3) != 0) {
    776 		bp->b_error = EINVAL;
    777 		goto bail;
    778 	}
    779 
    780 	dk_strategy(&sc->sc_dksc, bp);
    781 	return;
    782 
    783 bail:
    784 	bp->b_resid = bp->b_bcount;
    785 	biodone(bp);
    786 	return;
    787 }
    788 
    789 static int
    790 cgdsize(dev_t dev)
    791 {
    792 	struct cgd_softc *sc = getcgd_softc(dev);
    793 
    794 	DPRINTF_FOLLOW(("cgdsize(0x%"PRIx64")\n", dev));
    795 	if (!sc)
    796 		return -1;
    797 	return dk_size(&sc->sc_dksc, dev);
    798 }
    799 
    800 /*
    801  * cgd_{get,put}data are functions that deal with getting a buffer
    802  * for the new encrypted data.
    803  * We can no longer have a buffer per device, we need a buffer per
    804  * work queue...
    805  */
    806 
    807 static void *
    808 cgd_getdata(struct cgd_softc *sc, unsigned long size)
    809 {
    810 	void *data = NULL;
    811 
    812 	mutex_enter(&sc->sc_lock);
    813 	if (!sc->sc_data_used) {
    814 		sc->sc_data_used = true;
    815 		data = sc->sc_data;
    816 	}
    817 	mutex_exit(&sc->sc_lock);
    818 
    819 	if (data)
    820 		return data;
    821 
    822 	return kmem_intr_alloc(size, KM_NOSLEEP);
    823 }
    824 
    825 static void
    826 cgd_putdata(struct cgd_softc *sc, void *data, unsigned long size)
    827 {
    828 
    829 	if (data == sc->sc_data) {
    830 		mutex_enter(&sc->sc_lock);
    831 		sc->sc_data_used = false;
    832 		mutex_exit(&sc->sc_lock);
    833 	} else
    834 		kmem_intr_free(data, size);
    835 }
    836 
    837 static int
    838 cgd_diskstart(device_t dev, struct buf *bp)
    839 {
    840 	struct	cgd_softc *sc = device_private(dev);
    841 	struct	cgd_worker *cw = sc->sc_worker;
    842 	struct	dk_softc *dksc = &sc->sc_dksc;
    843 	struct	disk_geom *dg = &dksc->sc_dkdev.dk_geom;
    844 	struct	cgd_xfer *cx;
    845 	struct	buf *nbp;
    846 	void *	newaddr;
    847 	daddr_t	bn;
    848 
    849 	DPRINTF_FOLLOW(("cgd_diskstart(%p, %p)\n", dksc, bp));
    850 
    851 	bn = bp->b_rawblkno;
    852 
    853 	/*
    854 	 * We attempt to allocate all of our resources up front, so that
    855 	 * we can fail quickly if they are unavailable.
    856 	 */
    857 	nbp = getiobuf(sc->sc_tvn, false);
    858 	if (nbp == NULL)
    859 		return EAGAIN;
    860 
    861 	cx = pool_get(cw->cw_cpool, PR_NOWAIT);
    862 	if (cx == NULL) {
    863 		putiobuf(nbp);
    864 		return EAGAIN;
    865 	}
    866 
    867 	cx->cx_sc = sc;
    868 	cx->cx_obp = bp;
    869 	cx->cx_nbp = nbp;
    870 	cx->cx_srcv = cx->cx_dstv = bp->b_data;
    871 	cx->cx_blkno = bn;
    872 	cx->cx_secsize = dg->dg_secsize;
    873 
    874 	/*
    875 	 * If we are writing, then we need to encrypt the outgoing
    876 	 * block into a new block of memory.
    877 	 */
    878 	if ((bp->b_flags & B_READ) == 0) {
    879 		newaddr = cgd_getdata(sc, bp->b_bcount);
    880 		if (!newaddr) {
    881 			pool_put(cw->cw_cpool, cx);
    882 			putiobuf(nbp);
    883 			return EAGAIN;
    884 		}
    885 
    886 		cx->cx_dstv = newaddr;
    887 		cx->cx_len = bp->b_bcount;
    888 		cx->cx_dir = CGD_CIPHER_ENCRYPT;
    889 
    890 		cgd_enqueue(sc, cx);
    891 		return 0;
    892 	}
    893 
    894 	cgd_diskstart2(sc, cx);
    895 	return 0;
    896 }
    897 
    898 static void
    899 cgd_diskstart2(struct cgd_softc *sc, struct cgd_xfer *cx)
    900 {
    901 	struct	vnode *vp;
    902 	struct	buf *bp;
    903 	struct	buf *nbp;
    904 
    905 	bp = cx->cx_obp;
    906 	nbp = cx->cx_nbp;
    907 
    908 	nbp->b_data = cx->cx_dstv;
    909 	nbp->b_flags = bp->b_flags;
    910 	nbp->b_oflags = bp->b_oflags;
    911 	nbp->b_cflags = bp->b_cflags;
    912 	nbp->b_iodone = cgdiodone;
    913 	nbp->b_proc = bp->b_proc;
    914 	nbp->b_blkno = btodb(cx->cx_blkno * cx->cx_secsize);
    915 	nbp->b_bcount = bp->b_bcount;
    916 	nbp->b_private = cx;
    917 
    918 	BIO_COPYPRIO(nbp, bp);
    919 
    920 	if ((nbp->b_flags & B_READ) == 0) {
    921 		vp = nbp->b_vp;
    922 		mutex_enter(vp->v_interlock);
    923 		vp->v_numoutput++;
    924 		mutex_exit(vp->v_interlock);
    925 	}
    926 	VOP_STRATEGY(sc->sc_tvn, nbp);
    927 }
    928 
    929 static void
    930 cgdiodone(struct buf *nbp)
    931 {
    932 	struct	cgd_xfer *cx = nbp->b_private;
    933 	struct	buf *obp = cx->cx_obp;
    934 	struct	cgd_softc *sc = getcgd_softc(obp->b_dev);
    935 	struct	dk_softc *dksc = &sc->sc_dksc;
    936 	struct	disk_geom *dg = &dksc->sc_dkdev.dk_geom;
    937 	daddr_t	bn;
    938 
    939 	KDASSERT(sc);
    940 
    941 	DPRINTF_FOLLOW(("cgdiodone(%p)\n", nbp));
    942 	DPRINTF(CGDB_IO, ("cgdiodone: bp %p bcount %d resid %d\n",
    943 	    obp, obp->b_bcount, obp->b_resid));
    944 	DPRINTF(CGDB_IO, (" dev 0x%"PRIx64", nbp %p bn %" PRId64
    945 	    " addr %p bcnt %d\n", nbp->b_dev, nbp, nbp->b_blkno, nbp->b_data,
    946 		nbp->b_bcount));
    947 	if (nbp->b_error != 0) {
    948 		obp->b_error = nbp->b_error;
    949 		DPRINTF(CGDB_IO, ("%s: error %d\n", dksc->sc_xname,
    950 		    obp->b_error));
    951 	}
    952 
    953 	/* Perform the decryption if we are reading.
    954 	 *
    955 	 * Note: use the blocknumber from nbp, since it is what
    956 	 *       we used to encrypt the blocks.
    957 	 */
    958 
    959 	if (nbp->b_flags & B_READ) {
    960 		bn = dbtob(nbp->b_blkno) / dg->dg_secsize;
    961 
    962 		cx->cx_obp     = obp;
    963 		cx->cx_nbp     = nbp;
    964 		cx->cx_dstv    = obp->b_data;
    965 		cx->cx_srcv    = obp->b_data;
    966 		cx->cx_len     = obp->b_bcount;
    967 		cx->cx_blkno   = bn;
    968 		cx->cx_secsize = dg->dg_secsize;
    969 		cx->cx_dir     = CGD_CIPHER_DECRYPT;
    970 
    971 		cgd_enqueue(sc, cx);
    972 		return;
    973 	}
    974 
    975 	cgd_iodone2(sc, cx);
    976 }
    977 
    978 static void
    979 cgd_iodone2(struct cgd_softc *sc, struct cgd_xfer *cx)
    980 {
    981 	struct cgd_worker *cw = sc->sc_worker;
    982 	struct buf *obp = cx->cx_obp;
    983 	struct buf *nbp = cx->cx_nbp;
    984 	struct dk_softc *dksc = &sc->sc_dksc;
    985 
    986 	pool_put(cw->cw_cpool, cx);
    987 
    988 	/* If we allocated memory, free it now... */
    989 	if (nbp->b_data != obp->b_data)
    990 		cgd_putdata(sc, nbp->b_data, nbp->b_bcount);
    991 
    992 	putiobuf(nbp);
    993 
    994 	/* Request is complete for whatever reason */
    995 	obp->b_resid = 0;
    996 	if (obp->b_error != 0)
    997 		obp->b_resid = obp->b_bcount;
    998 
    999 	dk_done(dksc, obp);
   1000 	dk_start(dksc, NULL);
   1001 }
   1002 
   1003 static int
   1004 cgd_dumpblocks(device_t dev, void *va, daddr_t blkno, int nblk)
   1005 {
   1006 	struct cgd_softc *sc = device_private(dev);
   1007 	struct dk_softc *dksc = &sc->sc_dksc;
   1008 	struct disk_geom *dg = &dksc->sc_dkdev.dk_geom;
   1009 	size_t nbytes, blksize;
   1010 	void *buf;
   1011 	int error;
   1012 
   1013 	/*
   1014 	 * dk_dump gives us units of disklabel sectors.  Everything
   1015 	 * else in cgd uses units of diskgeom sectors.  These had
   1016 	 * better agree; otherwise we need to figure out how to convert
   1017 	 * between them.
   1018 	 */
   1019 	KASSERTMSG((dg->dg_secsize == dksc->sc_dkdev.dk_label->d_secsize),
   1020 	    "diskgeom secsize %"PRIu32" != disklabel secsize %"PRIu32,
   1021 	    dg->dg_secsize, dksc->sc_dkdev.dk_label->d_secsize);
   1022 	blksize = dg->dg_secsize;
   1023 
   1024 	/*
   1025 	 * Compute the number of bytes in this request, which dk_dump
   1026 	 * has `helpfully' converted to a number of blocks for us.
   1027 	 */
   1028 	nbytes = nblk*blksize;
   1029 
   1030 	/* Try to acquire a buffer to store the ciphertext.  */
   1031 	buf = cgd_getdata(sc, nbytes);
   1032 	if (buf == NULL)
   1033 		/* Out of memory: give up.  */
   1034 		return ENOMEM;
   1035 
   1036 	/* Encrypt the caller's data into the temporary buffer.  */
   1037 	cgd_cipher(sc, buf, va, nbytes, blkno, blksize, CGD_CIPHER_ENCRYPT);
   1038 
   1039 	/* Pass it on to the underlying disk device.  */
   1040 	error = bdev_dump(sc->sc_tdev, blkno, buf, nbytes);
   1041 
   1042 	/* Release the buffer.  */
   1043 	cgd_putdata(sc, buf, nbytes);
   1044 
   1045 	/* Return any error from the underlying disk device.  */
   1046 	return error;
   1047 }
   1048 
   1049 /* XXX: we should probably put these into dksubr.c, mostly */
   1050 static int
   1051 cgdread(dev_t dev, struct uio *uio, int flags)
   1052 {
   1053 	struct	cgd_softc *sc;
   1054 	struct	dk_softc *dksc;
   1055 
   1056 	DPRINTF_FOLLOW(("cgdread(0x%llx, %p, %d)\n",
   1057 	    (unsigned long long)dev, uio, flags));
   1058 	sc = getcgd_softc(dev);
   1059 	if (sc == NULL)
   1060 		return ENXIO;
   1061 	dksc = &sc->sc_dksc;
   1062 	if (!DK_ATTACHED(dksc))
   1063 		return ENXIO;
   1064 	return physio(cgdstrategy, NULL, dev, B_READ, minphys, uio);
   1065 }
   1066 
   1067 /* XXX: we should probably put these into dksubr.c, mostly */
   1068 static int
   1069 cgdwrite(dev_t dev, struct uio *uio, int flags)
   1070 {
   1071 	struct	cgd_softc *sc;
   1072 	struct	dk_softc *dksc;
   1073 
   1074 	DPRINTF_FOLLOW(("cgdwrite(0x%"PRIx64", %p, %d)\n", dev, uio, flags));
   1075 	sc = getcgd_softc(dev);
   1076 	if (sc == NULL)
   1077 		return ENXIO;
   1078 	dksc = &sc->sc_dksc;
   1079 	if (!DK_ATTACHED(dksc))
   1080 		return ENXIO;
   1081 	return physio(cgdstrategy, NULL, dev, B_WRITE, minphys, uio);
   1082 }
   1083 
   1084 static int
   1085 cgdioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
   1086 {
   1087 	struct	cgd_softc *sc;
   1088 	struct	dk_softc *dksc;
   1089 	int	part = DISKPART(dev);
   1090 	int	pmask = 1 << part;
   1091 	int	error;
   1092 
   1093 	DPRINTF_FOLLOW(("cgdioctl(0x%"PRIx64", %ld, %p, %d, %p)\n",
   1094 	    dev, cmd, data, flag, l));
   1095 
   1096 	switch (cmd) {
   1097 	case CGDIOCGET:
   1098 		return cgd_ioctl_get(dev, data, l);
   1099 	case CGDIOCSET:
   1100 	case CGDIOCCLR:
   1101 		if ((flag & FWRITE) == 0)
   1102 			return EBADF;
   1103 		/* FALLTHROUGH */
   1104 	default:
   1105 		sc = getcgd_softc(dev);
   1106 		if (sc == NULL)
   1107 			return ENXIO;
   1108 		dksc = &sc->sc_dksc;
   1109 		break;
   1110 	}
   1111 
   1112 	switch (cmd) {
   1113 	case CGDIOCSET:
   1114 		cgd_busy(sc);
   1115 		if (DK_ATTACHED(dksc))
   1116 			error = EBUSY;
   1117 		else
   1118 			error = cgd_ioctl_set(sc, data, l);
   1119 		cgd_unbusy(sc);
   1120 		break;
   1121 	case CGDIOCCLR:
   1122 		cgd_busy(sc);
   1123 		if (DK_BUSY(&sc->sc_dksc, pmask))
   1124 			error = EBUSY;
   1125 		else
   1126 			error = cgd_ioctl_clr(sc, l);
   1127 		cgd_unbusy(sc);
   1128 		break;
   1129 	case DIOCGCACHE:
   1130 	case DIOCCACHESYNC:
   1131 		cgd_busy(sc);
   1132 		if (!DK_ATTACHED(dksc)) {
   1133 			cgd_unbusy(sc);
   1134 			error = ENOENT;
   1135 			break;
   1136 		}
   1137 		/*
   1138 		 * We pass this call down to the underlying disk.
   1139 		 */
   1140 		error = VOP_IOCTL(sc->sc_tvn, cmd, data, flag, l->l_cred);
   1141 		cgd_unbusy(sc);
   1142 		break;
   1143 	case DIOCGSECTORALIGN: {
   1144 		struct disk_sectoralign *dsa = data;
   1145 
   1146 		cgd_busy(sc);
   1147 		if (!DK_ATTACHED(dksc)) {
   1148 			cgd_unbusy(sc);
   1149 			error = ENOENT;
   1150 			break;
   1151 		}
   1152 
   1153 		/* Get the underlying disk's sector alignment.  */
   1154 		error = VOP_IOCTL(sc->sc_tvn, cmd, data, flag, l->l_cred);
   1155 		if (error) {
   1156 			cgd_unbusy(sc);
   1157 			break;
   1158 		}
   1159 
   1160 		/* Adjust for the disklabel partition if necessary.  */
   1161 		if (part != RAW_PART) {
   1162 			struct disklabel *lp = dksc->sc_dkdev.dk_label;
   1163 			daddr_t offset = lp->d_partitions[part].p_offset;
   1164 			uint32_t r = offset % dsa->dsa_alignment;
   1165 
   1166 			if (r < dsa->dsa_firstaligned)
   1167 				dsa->dsa_firstaligned = dsa->dsa_firstaligned
   1168 				    - r;
   1169 			else
   1170 				dsa->dsa_firstaligned = (dsa->dsa_firstaligned
   1171 				    + dsa->dsa_alignment) - r;
   1172 		}
   1173 		cgd_unbusy(sc);
   1174 		break;
   1175 	}
   1176 	case DIOCGSTRATEGY:
   1177 	case DIOCSSTRATEGY:
   1178 		if (!DK_ATTACHED(dksc)) {
   1179 			error = ENOENT;
   1180 			break;
   1181 		}
   1182 		/*FALLTHROUGH*/
   1183 	default:
   1184 		error = dk_ioctl(dksc, dev, cmd, data, flag, l);
   1185 		break;
   1186 	case CGDIOCGET:
   1187 		KASSERT(0);
   1188 		error = EINVAL;
   1189 	}
   1190 
   1191 	return error;
   1192 }
   1193 
   1194 static int
   1195 cgddump(dev_t dev, daddr_t blkno, void *va, size_t size)
   1196 {
   1197 	struct	cgd_softc *sc;
   1198 
   1199 	DPRINTF_FOLLOW(("cgddump(0x%"PRIx64", %" PRId64 ", %p, %lu)\n",
   1200 	    dev, blkno, va, (unsigned long)size));
   1201 	sc = getcgd_softc(dev);
   1202 	if (sc == NULL)
   1203 		return ENXIO;
   1204 	return dk_dump(&sc->sc_dksc, dev, blkno, va, size, DK_DUMP_RECURSIVE);
   1205 }
   1206 
   1207 /*
   1208  * XXXrcd:
   1209  *  for now we hardcode the maximum key length.
   1210  */
   1211 #define MAX_KEYSIZE	1024
   1212 
   1213 static const struct {
   1214 	const char *n;
   1215 	int v;
   1216 	int d;
   1217 } encblkno[] = {
   1218 	{ "encblkno",  CGD_CIPHER_CBC_ENCBLKNO8, 1 },
   1219 	{ "encblkno8", CGD_CIPHER_CBC_ENCBLKNO8, 1 },
   1220 	{ "encblkno1", CGD_CIPHER_CBC_ENCBLKNO1, 8 },
   1221 };
   1222 
   1223 /* ARGSUSED */
   1224 static int
   1225 cgd_ioctl_set(struct cgd_softc *sc, void *data, struct lwp *l)
   1226 {
   1227 	struct	 cgd_ioctl *ci = data;
   1228 	struct	 vnode *vp;
   1229 	int	 ret;
   1230 	size_t	 i;
   1231 	size_t	 keybytes;			/* key length in bytes */
   1232 	const char *cp;
   1233 	struct pathbuf *pb;
   1234 	char	 *inbuf;
   1235 	struct dk_softc *dksc = &sc->sc_dksc;
   1236 
   1237 	cp = ci->ci_disk;
   1238 
   1239 	ret = pathbuf_copyin(ci->ci_disk, &pb);
   1240 	if (ret != 0) {
   1241 		return ret;
   1242 	}
   1243 	ret = vn_bdev_openpath(pb, &vp, l);
   1244 	pathbuf_destroy(pb);
   1245 	if (ret != 0) {
   1246 		return ret;
   1247 	}
   1248 
   1249 	inbuf = kmem_alloc(MAX_KEYSIZE, KM_SLEEP);
   1250 
   1251 	if ((ret = cgdinit(sc, cp, vp, l)) != 0)
   1252 		goto bail;
   1253 
   1254 	(void)memset(inbuf, 0, MAX_KEYSIZE);
   1255 	ret = copyinstr(ci->ci_alg, inbuf, 256, NULL);
   1256 	if (ret)
   1257 		goto bail;
   1258 	sc->sc_cfuncs = cryptfuncs_find(inbuf);
   1259 	if (!sc->sc_cfuncs) {
   1260 		ret = EINVAL;
   1261 		goto bail;
   1262 	}
   1263 
   1264 	(void)memset(inbuf, 0, MAX_KEYSIZE);
   1265 	ret = copyinstr(ci->ci_ivmethod, inbuf, MAX_KEYSIZE, NULL);
   1266 	if (ret)
   1267 		goto bail;
   1268 
   1269 	for (i = 0; i < __arraycount(encblkno); i++)
   1270 		if (strcmp(encblkno[i].n, inbuf) == 0)
   1271 			break;
   1272 
   1273 	if (i == __arraycount(encblkno)) {
   1274 		ret = EINVAL;
   1275 		goto bail;
   1276 	}
   1277 
   1278 	keybytes = ci->ci_keylen / 8 + 1;
   1279 	if (keybytes > MAX_KEYSIZE) {
   1280 		ret = EINVAL;
   1281 		goto bail;
   1282 	}
   1283 
   1284 	(void)memset(inbuf, 0, MAX_KEYSIZE);
   1285 	ret = copyin(ci->ci_key, inbuf, keybytes);
   1286 	if (ret)
   1287 		goto bail;
   1288 
   1289 	sc->sc_cdata.cf_blocksize = ci->ci_blocksize;
   1290 	sc->sc_cdata.cf_mode = encblkno[i].v;
   1291 
   1292 	/*
   1293 	 * Print a warning if the user selected the legacy encblkno8
   1294 	 * mistake, and reject it altogether for ciphers that it
   1295 	 * doesn't apply to.
   1296 	 */
   1297 	if (encblkno[i].v != CGD_CIPHER_CBC_ENCBLKNO1) {
   1298 		if (strcmp(sc->sc_cfuncs->cf_name, "aes-cbc") &&
   1299 		    strcmp(sc->sc_cfuncs->cf_name, "3des-cbc") &&
   1300 		    strcmp(sc->sc_cfuncs->cf_name, "blowfish-cbc")) {
   1301 			log(LOG_WARNING, "cgd: %s only makes sense for cbc,"
   1302 			    " not for %s; ignoring\n",
   1303 			    encblkno[i].n, sc->sc_cfuncs->cf_name);
   1304 			sc->sc_cdata.cf_mode = CGD_CIPHER_CBC_ENCBLKNO1;
   1305 		} else {
   1306 			log(LOG_WARNING, "cgd: enabling legacy encblkno8\n");
   1307 		}
   1308 	}
   1309 
   1310 	sc->sc_cdata.cf_keylen = ci->ci_keylen;
   1311 	sc->sc_cdata.cf_priv = sc->sc_cfuncs->cf_init(ci->ci_keylen, inbuf,
   1312 	    &sc->sc_cdata.cf_blocksize);
   1313 	if (sc->sc_cdata.cf_blocksize > CGD_MAXBLOCKSIZE) {
   1314 	    log(LOG_WARNING, "cgd: Disallowed cipher with blocksize %zu > %u\n",
   1315 		sc->sc_cdata.cf_blocksize, CGD_MAXBLOCKSIZE);
   1316 	    sc->sc_cdata.cf_priv = NULL;
   1317 	}
   1318 
   1319 	/*
   1320 	 * The blocksize is supposed to be in bytes. Unfortunately originally
   1321 	 * it was expressed in bits. For compatibility we maintain encblkno
   1322 	 * and encblkno8.
   1323 	 */
   1324 	sc->sc_cdata.cf_blocksize /= encblkno[i].d;
   1325 	(void)explicit_memset(inbuf, 0, MAX_KEYSIZE);
   1326 	if (!sc->sc_cdata.cf_priv) {
   1327 		ret = EINVAL;		/* XXX is this the right error? */
   1328 		goto bail;
   1329 	}
   1330 	kmem_free(inbuf, MAX_KEYSIZE);
   1331 
   1332 	bufq_alloc(&dksc->sc_bufq, "fcfs", 0);
   1333 
   1334 	sc->sc_data = kmem_alloc(MAXPHYS, KM_SLEEP);
   1335 	sc->sc_data_used = false;
   1336 
   1337 	/* Attach the disk. */
   1338 	dk_attach(dksc);
   1339 	disk_attach(&dksc->sc_dkdev);
   1340 
   1341 	disk_set_info(dksc->sc_dev, &dksc->sc_dkdev, NULL);
   1342 
   1343 	/* Discover wedges on this disk. */
   1344 	dkwedge_discover(&dksc->sc_dkdev);
   1345 
   1346 	return 0;
   1347 
   1348 bail:
   1349 	kmem_free(inbuf, MAX_KEYSIZE);
   1350 	(void)vn_close(vp, FREAD|FWRITE, l->l_cred);
   1351 	return ret;
   1352 }
   1353 
   1354 /* ARGSUSED */
   1355 static int
   1356 cgd_ioctl_clr(struct cgd_softc *sc, struct lwp *l)
   1357 {
   1358 	struct	dk_softc *dksc = &sc->sc_dksc;
   1359 
   1360 	if (!DK_ATTACHED(dksc))
   1361 		return ENXIO;
   1362 
   1363 	/* Delete all of our wedges. */
   1364 	dkwedge_delall(&dksc->sc_dkdev);
   1365 
   1366 	/* Kill off any queued buffers. */
   1367 	dk_drain(dksc);
   1368 	bufq_free(dksc->sc_bufq);
   1369 
   1370 	(void)vn_close(sc->sc_tvn, FREAD|FWRITE, l->l_cred);
   1371 	sc->sc_cfuncs->cf_destroy(sc->sc_cdata.cf_priv);
   1372 	kmem_free(sc->sc_tpath, sc->sc_tpathlen);
   1373 	kmem_free(sc->sc_data, MAXPHYS);
   1374 	sc->sc_data_used = false;
   1375 	dk_detach(dksc);
   1376 	disk_detach(&dksc->sc_dkdev);
   1377 
   1378 	return 0;
   1379 }
   1380 
   1381 static int
   1382 cgd_ioctl_get(dev_t dev, void *data, struct lwp *l)
   1383 {
   1384 	struct cgd_softc *sc;
   1385 	struct cgd_user *cgu;
   1386 	int unit, error;
   1387 
   1388 	unit = CGDUNIT(dev);
   1389 	cgu = (struct cgd_user *)data;
   1390 
   1391 	DPRINTF_FOLLOW(("cgd_ioctl_get(0x%"PRIx64", %d, %p, %p)\n",
   1392 			   dev, unit, data, l));
   1393 
   1394 	/* XXX, we always return this units data, so if cgu_unit is
   1395 	 * not -1, that field doesn't match the rest
   1396 	 */
   1397 	if (cgu->cgu_unit == -1)
   1398 		cgu->cgu_unit = unit;
   1399 
   1400 	if (cgu->cgu_unit < 0)
   1401 		return EINVAL;	/* XXX: should this be ENXIO? */
   1402 
   1403 	error = cgd_lock(false);
   1404 	if (error)
   1405 		return error;
   1406 
   1407 	sc = device_lookup_private(&cgd_cd, unit);
   1408 	if (sc == NULL || !DK_ATTACHED(&sc->sc_dksc)) {
   1409 		cgu->cgu_dev = 0;
   1410 		cgu->cgu_alg[0] = '\0';
   1411 		cgu->cgu_blocksize = 0;
   1412 		cgu->cgu_mode = 0;
   1413 		cgu->cgu_keylen = 0;
   1414 	}
   1415 	else {
   1416 		mutex_enter(&sc->sc_lock);
   1417 		cgu->cgu_dev = sc->sc_tdev;
   1418 		strncpy(cgu->cgu_alg, sc->sc_cfuncs->cf_name,
   1419 		    sizeof(cgu->cgu_alg));
   1420 		cgu->cgu_blocksize = sc->sc_cdata.cf_blocksize;
   1421 		cgu->cgu_mode = sc->sc_cdata.cf_mode;
   1422 		cgu->cgu_keylen = sc->sc_cdata.cf_keylen;
   1423 		mutex_exit(&sc->sc_lock);
   1424 	}
   1425 
   1426 	cgd_unlock();
   1427 	return 0;
   1428 }
   1429 
   1430 static int
   1431 cgdinit(struct cgd_softc *sc, const char *cpath, struct vnode *vp,
   1432 	struct lwp *l)
   1433 {
   1434 	struct	disk_geom *dg;
   1435 	int	ret;
   1436 	char	*tmppath;
   1437 	uint64_t psize;
   1438 	unsigned secsize;
   1439 	struct dk_softc *dksc = &sc->sc_dksc;
   1440 
   1441 	sc->sc_tvn = vp;
   1442 	sc->sc_tpath = NULL;
   1443 
   1444 	tmppath = kmem_alloc(MAXPATHLEN, KM_SLEEP);
   1445 	ret = copyinstr(cpath, tmppath, MAXPATHLEN, &sc->sc_tpathlen);
   1446 	if (ret)
   1447 		goto bail;
   1448 	sc->sc_tpath = kmem_alloc(sc->sc_tpathlen, KM_SLEEP);
   1449 	memcpy(sc->sc_tpath, tmppath, sc->sc_tpathlen);
   1450 
   1451 	sc->sc_tdev = vp->v_rdev;
   1452 
   1453 	if ((ret = getdisksize(vp, &psize, &secsize)) != 0)
   1454 		goto bail;
   1455 
   1456 	if (psize == 0) {
   1457 		ret = ENODEV;
   1458 		goto bail;
   1459 	}
   1460 
   1461 	/*
   1462 	 * XXX here we should probe the underlying device.  If we
   1463 	 *     are accessing a partition of type RAW_PART, then
   1464 	 *     we should populate our initial geometry with the
   1465 	 *     geometry that we discover from the device.
   1466 	 */
   1467 	dg = &dksc->sc_dkdev.dk_geom;
   1468 	memset(dg, 0, sizeof(*dg));
   1469 	dg->dg_secperunit = psize;
   1470 	dg->dg_secsize = secsize;
   1471 	dg->dg_ntracks = 1;
   1472 	dg->dg_nsectors = 1024 * 1024 / dg->dg_secsize;
   1473 	dg->dg_ncylinders = dg->dg_secperunit / dg->dg_nsectors;
   1474 
   1475 bail:
   1476 	kmem_free(tmppath, MAXPATHLEN);
   1477 	if (ret && sc->sc_tpath)
   1478 		kmem_free(sc->sc_tpath, sc->sc_tpathlen);
   1479 	return ret;
   1480 }
   1481 
   1482 /*
   1483  * Our generic cipher entry point.  This takes care of the
   1484  * IV mode and passes off the work to the specific cipher.
   1485  * We implement here the IV method ``encrypted block
   1486  * number''.
   1487  *
   1488  * XXXrcd: for now we rely on our own crypto framework defined
   1489  *         in dev/cgd_crypto.c.  This will change when we
   1490  *         get a generic kernel crypto framework.
   1491  */
   1492 
   1493 static void
   1494 blkno2blkno_buf(char *sbuf, daddr_t blkno)
   1495 {
   1496 	int	i;
   1497 
   1498 	/* Set up the blkno in blkno_buf, here we do not care much
   1499 	 * about the final layout of the information as long as we
   1500 	 * can guarantee that each sector will have a different IV
   1501 	 * and that the endianness of the machine will not affect
   1502 	 * the representation that we have chosen.
   1503 	 *
   1504 	 * We choose this representation, because it does not rely
   1505 	 * on the size of buf (which is the blocksize of the cipher),
   1506 	 * but allows daddr_t to grow without breaking existing
   1507 	 * disks.
   1508 	 *
   1509 	 * Note that blkno2blkno_buf does not take a size as input,
   1510 	 * and hence must be called on a pre-zeroed buffer of length
   1511 	 * greater than or equal to sizeof(daddr_t).
   1512 	 */
   1513 	for (i=0; i < sizeof(daddr_t); i++) {
   1514 		*sbuf++ = blkno & 0xff;
   1515 		blkno >>= 8;
   1516 	}
   1517 }
   1518 
   1519 static struct cpu_info *
   1520 cgd_cpu(struct cgd_softc *sc)
   1521 {
   1522 	struct cgd_worker *cw = sc->sc_worker;
   1523 	struct cpu_info *ci = NULL;
   1524 	u_int cidx, i;
   1525 
   1526 	if (cw->cw_busy == 0) {
   1527 		cw->cw_last = cpu_index(curcpu());
   1528 		return NULL;
   1529 	}
   1530 
   1531 	for (i=0, cidx = cw->cw_last+1; i<maxcpus; ++i, ++cidx) {
   1532 		if (cidx >= maxcpus)
   1533 			cidx = 0;
   1534 		ci = cpu_lookup(cidx);
   1535 		if (ci) {
   1536 			cw->cw_last = cidx;
   1537 			break;
   1538 		}
   1539 	}
   1540 
   1541 	return ci;
   1542 }
   1543 
   1544 static void
   1545 cgd_enqueue(struct cgd_softc *sc, struct cgd_xfer *cx)
   1546 {
   1547 	struct cgd_worker *cw = sc->sc_worker;
   1548 	struct cpu_info *ci;
   1549 
   1550 	mutex_enter(&cw->cw_lock);
   1551 	ci = cgd_cpu(sc);
   1552 	cw->cw_busy++;
   1553 	mutex_exit(&cw->cw_lock);
   1554 
   1555 	workqueue_enqueue(cw->cw_wq, &cx->cx_work, ci);
   1556 }
   1557 
   1558 static void
   1559 cgd_process(struct work *wk, void *arg)
   1560 {
   1561 	struct cgd_xfer *cx = (struct cgd_xfer *)wk;
   1562 	struct cgd_softc *sc = cx->cx_sc;
   1563 	struct cgd_worker *cw = sc->sc_worker;
   1564 
   1565 	cgd_cipher(sc, cx->cx_dstv, cx->cx_srcv, cx->cx_len,
   1566 	    cx->cx_blkno, cx->cx_secsize, cx->cx_dir);
   1567 
   1568 	if (cx->cx_dir == CGD_CIPHER_ENCRYPT) {
   1569 		cgd_diskstart2(sc, cx);
   1570 	} else {
   1571 		cgd_iodone2(sc, cx);
   1572 	}
   1573 
   1574 	mutex_enter(&cw->cw_lock);
   1575 	if (cw->cw_busy > 0)
   1576 		cw->cw_busy--;
   1577 	mutex_exit(&cw->cw_lock);
   1578 }
   1579 
   1580 static void
   1581 cgd_cipher(struct cgd_softc *sc, void *dstv, const void *srcv,
   1582     size_t len, daddr_t blkno, size_t secsize, int dir)
   1583 {
   1584 	char		*dst = dstv;
   1585 	const char	*src = srcv;
   1586 	cfunc_cipher	*cipher = sc->sc_cfuncs->cf_cipher;
   1587 	size_t		blocksize = sc->sc_cdata.cf_blocksize;
   1588 	size_t		todo;
   1589 	char		blkno_buf[CGD_MAXBLOCKSIZE] __aligned(CGD_BLOCKALIGN);
   1590 
   1591 	DPRINTF_FOLLOW(("cgd_cipher() dir=%d\n", dir));
   1592 
   1593 	if (sc->sc_cdata.cf_mode == CGD_CIPHER_CBC_ENCBLKNO8)
   1594 		blocksize /= 8;
   1595 
   1596 	KASSERT(len % blocksize == 0);
   1597 	/* ensure that sizeof(daddr_t) <= blocksize (for encblkno IVing) */
   1598 	KASSERT(sizeof(daddr_t) <= blocksize);
   1599 	KASSERT(blocksize <= CGD_MAXBLOCKSIZE);
   1600 
   1601 	for (; len > 0; len -= todo) {
   1602 		todo = MIN(len, secsize);
   1603 
   1604 		memset(blkno_buf, 0x0, blocksize);
   1605 		blkno2blkno_buf(blkno_buf, blkno);
   1606 		IFDEBUG(CGDB_CRYPTO, hexprint("step 1: blkno_buf",
   1607 		    blkno_buf, blocksize));
   1608 
   1609 		/*
   1610 		 * Handle bollocksed up encblkno8 mistake.  We used to
   1611 		 * compute the encryption of a zero block with blkno as
   1612 		 * the CBC IV -- except in an early mistake arising
   1613 		 * from bit/byte confusion, we actually computed the
   1614 		 * encryption of the last of _eight_ zero blocks under
   1615 		 * CBC as the CBC IV.
   1616 		 *
   1617 		 * Encrypting the block number is handled inside the
   1618 		 * cipher dispatch now (even though in practice, both
   1619 		 * CBC and XTS will do the same thing), so we have to
   1620 		 * simulate the block number that would yield the same
   1621 		 * result.  So we encrypt _six_ zero blocks -- the
   1622 		 * first one and the last one are handled inside the
   1623 		 * cipher dispatch.
   1624 		 */
   1625 		if (sc->sc_cdata.cf_mode == CGD_CIPHER_CBC_ENCBLKNO8) {
   1626 			static const uint8_t zero[CGD_MAXBLOCKSIZE];
   1627 			uint8_t iv[CGD_MAXBLOCKSIZE];
   1628 
   1629 			memcpy(iv, blkno_buf, blocksize);
   1630 			cipher(sc->sc_cdata.cf_priv, blkno_buf, zero,
   1631 			    6*blocksize, iv, CGD_CIPHER_ENCRYPT);
   1632 			memmove(blkno_buf, blkno_buf + 5*blocksize, blocksize);
   1633 		}
   1634 
   1635 		cipher(sc->sc_cdata.cf_priv, dst, src, todo, blkno_buf, dir);
   1636 
   1637 		dst += todo;
   1638 		src += todo;
   1639 		blkno++;
   1640 	}
   1641 }
   1642 
   1643 #ifdef DEBUG
   1644 static void
   1645 hexprint(const char *start, void *buf, int len)
   1646 {
   1647 	char	*c = buf;
   1648 
   1649 	KASSERTMSG(len >= 0, "hexprint: called with len < 0");
   1650 	printf("%s: len=%06d 0x", start, len);
   1651 	while (len--)
   1652 		printf("%02x", (unsigned char) *c++);
   1653 }
   1654 #endif
   1655 
   1656 static void
   1657 cgd_selftest(void)
   1658 {
   1659 	struct cgd_softc sc;
   1660 	void *buf;
   1661 
   1662 	for (size_t i = 0; i < __arraycount(selftests); i++) {
   1663 		const char *alg = selftests[i].alg;
   1664 		int encblkno8 = selftests[i].encblkno8;
   1665 		const uint8_t *key = selftests[i].key;
   1666 		int keylen = selftests[i].keylen;
   1667 		int txtlen = selftests[i].txtlen;
   1668 
   1669 		aprint_debug("cgd: self-test %s-%d%s\n", alg, keylen,
   1670 		    encblkno8 ? " (encblkno8)" : "");
   1671 
   1672 		memset(&sc, 0, sizeof(sc));
   1673 
   1674 		sc.sc_cfuncs = cryptfuncs_find(alg);
   1675 		if (sc.sc_cfuncs == NULL)
   1676 			panic("%s not implemented", alg);
   1677 
   1678 		sc.sc_cdata.cf_blocksize = 8 * selftests[i].blocksize;
   1679 		sc.sc_cdata.cf_mode = encblkno8 ? CGD_CIPHER_CBC_ENCBLKNO8 :
   1680 		    CGD_CIPHER_CBC_ENCBLKNO1;
   1681 		sc.sc_cdata.cf_keylen = keylen;
   1682 
   1683 		sc.sc_cdata.cf_priv = sc.sc_cfuncs->cf_init(keylen,
   1684 		    key, &sc.sc_cdata.cf_blocksize);
   1685 		if (sc.sc_cdata.cf_priv == NULL)
   1686 			panic("cf_priv is NULL");
   1687 		if (sc.sc_cdata.cf_blocksize > CGD_MAXBLOCKSIZE)
   1688 			panic("bad block size %zu", sc.sc_cdata.cf_blocksize);
   1689 
   1690 		if (!encblkno8)
   1691 			sc.sc_cdata.cf_blocksize /= 8;
   1692 
   1693 		buf = kmem_alloc(txtlen, KM_SLEEP);
   1694 		memcpy(buf, selftests[i].ptxt, txtlen);
   1695 
   1696 		cgd_cipher(&sc, buf, buf, txtlen, selftests[i].blkno,
   1697 				selftests[i].secsize, CGD_CIPHER_ENCRYPT);
   1698 		if (memcmp(buf, selftests[i].ctxt, txtlen) != 0) {
   1699 			hexdump(printf, "was", buf, txtlen);
   1700 			hexdump(printf, "exp", selftests[i].ctxt, txtlen);
   1701 			panic("cgd %s-%d encryption is broken [%zu]",
   1702 			    selftests[i].alg, keylen, i);
   1703 		}
   1704 
   1705 		cgd_cipher(&sc, buf, buf, txtlen, selftests[i].blkno,
   1706 				selftests[i].secsize, CGD_CIPHER_DECRYPT);
   1707 		if (memcmp(buf, selftests[i].ptxt, txtlen) != 0) {
   1708 			hexdump(printf, "was", buf, txtlen);
   1709 			hexdump(printf, "exp", selftests[i].ptxt, txtlen);
   1710 			panic("cgd %s-%d decryption is broken [%zu]",
   1711 			    selftests[i].alg, keylen, i);
   1712 		}
   1713 
   1714 		kmem_free(buf, txtlen);
   1715 		sc.sc_cfuncs->cf_destroy(sc.sc_cdata.cf_priv);
   1716 	}
   1717 
   1718 	aprint_debug("cgd: self-tests passed\n");
   1719 }
   1720 
   1721 MODULE(MODULE_CLASS_DRIVER, cgd, "blowfish,des,dk_subr,bufq_fcfs");
   1722 
   1723 #ifdef _MODULE
   1724 CFDRIVER_DECL(cgd, DV_DISK, NULL);
   1725 
   1726 devmajor_t cgd_bmajor = -1, cgd_cmajor = -1;
   1727 #endif
   1728 
   1729 static int
   1730 cgd_modcmd(modcmd_t cmd, void *arg)
   1731 {
   1732 	int error = 0;
   1733 
   1734 	switch (cmd) {
   1735 	case MODULE_CMD_INIT:
   1736 #ifdef _MODULE
   1737 		mutex_init(&cgd_spawning_mtx, MUTEX_DEFAULT, IPL_NONE);
   1738 		cv_init(&cgd_spawning_cv, "cgspwn");
   1739 
   1740 		error = config_cfdriver_attach(&cgd_cd);
   1741 		if (error)
   1742 			break;
   1743 
   1744 		error = config_cfattach_attach(cgd_cd.cd_name, &cgd_ca);
   1745 	        if (error) {
   1746 			config_cfdriver_detach(&cgd_cd);
   1747 			aprint_error("%s: unable to register cfattach for"
   1748 			    "%s, error %d\n", __func__, cgd_cd.cd_name, error);
   1749 			break;
   1750 		}
   1751 		/*
   1752 		 * Attach the {b,c}devsw's
   1753 		 */
   1754 		error = devsw_attach("cgd", &cgd_bdevsw, &cgd_bmajor,
   1755 		    &cgd_cdevsw, &cgd_cmajor);
   1756 
   1757 		/*
   1758 		 * If devsw_attach fails, remove from autoconf database
   1759 		 */
   1760 		if (error) {
   1761 			config_cfattach_detach(cgd_cd.cd_name, &cgd_ca);
   1762 			config_cfdriver_detach(&cgd_cd);
   1763 			aprint_error("%s: unable to attach %s devsw, "
   1764 			    "error %d", __func__, cgd_cd.cd_name, error);
   1765 			break;
   1766 		}
   1767 #endif
   1768 		break;
   1769 
   1770 	case MODULE_CMD_FINI:
   1771 #ifdef _MODULE
   1772 		/*
   1773 		 * Remove {b,c}devsw's
   1774 		 */
   1775 		devsw_detach(&cgd_bdevsw, &cgd_cdevsw);
   1776 
   1777 		/*
   1778 		 * Now remove device from autoconf database
   1779 		 */
   1780 		error = config_cfattach_detach(cgd_cd.cd_name, &cgd_ca);
   1781 		if (error) {
   1782 			(void)devsw_attach("cgd", &cgd_bdevsw, &cgd_bmajor,
   1783 			    &cgd_cdevsw, &cgd_cmajor);
   1784 			aprint_error("%s: failed to detach %s cfattach, "
   1785 			    "error %d\n", __func__, cgd_cd.cd_name, error);
   1786  			break;
   1787 		}
   1788 		error = config_cfdriver_detach(&cgd_cd);
   1789 		if (error) {
   1790 			(void)config_cfattach_attach(cgd_cd.cd_name, &cgd_ca);
   1791 			(void)devsw_attach("cgd", &cgd_bdevsw, &cgd_bmajor,
   1792 			    &cgd_cdevsw, &cgd_cmajor);
   1793 			aprint_error("%s: failed to detach %s cfdriver, "
   1794 			    "error %d\n", __func__, cgd_cd.cd_name, error);
   1795 			break;
   1796 		}
   1797 
   1798 		cv_destroy(&cgd_spawning_cv);
   1799 		mutex_destroy(&cgd_spawning_mtx);
   1800 #endif
   1801 		break;
   1802 
   1803 	case MODULE_CMD_STAT:
   1804 		error = ENOTTY;
   1805 		break;
   1806 	default:
   1807 		error = ENOTTY;
   1808 		break;
   1809 	}
   1810 
   1811 	return error;
   1812 }
   1813