dm/disk - cleanup, add '.' between name and slices
[dragonfly.git] / sys / dev / disk / dm / dm_target_crypt.c
1 /*
2  * Copyright (c) 2010 The DragonFly Project.  All rights reserved.
3  *
4  * This code is derived from software contributed to The DragonFly Project
5  * by Alex Hornung <ahornung@gmail.com>
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  * 3. Neither the name of The DragonFly Project nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific, prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34
35 /*
36  * This file implements initial version of device-mapper crypt target.
37  */
38 #include <sys/types.h>
39 #include <sys/param.h>
40 #include <sys/endian.h>
41
42 #include <sys/bio.h>
43 #include <sys/buf.h>
44 #include <sys/globaldata.h>
45 #include <sys/kerneldump.h>
46 #include <sys/malloc.h>
47 #include <sys/md5.h>
48 #include <sys/mutex2.h>
49 #include <sys/vnode.h>
50 #include <crypto/sha1.h>
51 #include <crypto/sha2/sha2.h>
52 #include <opencrypto/cryptodev.h>
53 #include <opencrypto/rmd160.h>
54 #include <machine/cpufunc.h>
55
56 #include "dm.h"
57 MALLOC_DEFINE(M_DMCRYPT, "dm_crypt", "Device Mapper Target Crypt");
58
59 struct target_crypt_config;
60
61 typedef void dispatch_t(void *);
62 typedef void ivgen_t(struct target_crypt_config *, u_int8_t *, size_t, off_t,
63     void *);
64
65 typedef int ivgen_ctor_t(struct target_crypt_config *, char *, void **);
66 typedef int ivgen_dtor_t(struct target_crypt_config *, void *);
67
68 struct iv_generator {
69         const char      *name;
70         ivgen_ctor_t    *ctor;
71         ivgen_dtor_t    *dtor;
72         ivgen_t         *gen_iv;
73 };
74
75 struct essiv_ivgen_priv {
76         struct cryptoini        crypto_session;
77         struct objcache *crp_crd_cache;
78         u_int64_t       crypto_sid;
79         size_t          keyhash_len;
80         u_int8_t        crypto_keyhash[SHA512_DIGEST_LENGTH];
81 };
82
83 typedef struct target_crypt_config {
84         size_t  params_len;
85         dm_pdev_t *pdev;
86         char    *status_str;
87         int     crypto_alg;
88         int     crypto_klen;
89         u_int8_t        crypto_key[512>>3];
90
91         u_int64_t       crypto_sid;
92         u_int64_t       block_offset;
93         int64_t         iv_offset;
94         SHA512_CTX      essivsha512_ctx;
95
96         struct cryptoini        crypto_session;
97
98         struct iv_generator     *ivgen;
99         void    *ivgen_priv;
100 } dm_target_crypt_config_t;
101
102 struct dmtc_helper {
103         caddr_t free_addr;
104         caddr_t orig_buf;
105         caddr_t data_buf;
106 };
107
108 struct dmtc_dump_helper {
109         dm_target_crypt_config_t *priv;
110         void *data;
111         size_t length;
112         off_t offset;
113
114         int sectors;
115         int *ident;
116
117         struct cryptodesc crd[128];
118         struct cryptop crp[128];
119         u_char space[65536];
120 };
121
122 static void dmtc_crypto_dispatch(void *arg);
123 static void dmtc_crypto_dump_start(dm_target_crypt_config_t *priv,
124                                 struct dmtc_dump_helper *dump_helper);
125 static void dmtc_crypto_read_start(dm_target_crypt_config_t *priv,
126                                 struct bio *bio);
127 static void dmtc_crypto_write_start(dm_target_crypt_config_t *priv,
128                                 struct bio *bio);
129 static void dmtc_bio_read_done(struct bio *bio);
130 static void dmtc_bio_write_done(struct bio *bio);
131 static int dmtc_crypto_cb_dump_done(struct cryptop *crp);
132 static int dmtc_crypto_cb_read_done(struct cryptop *crp);
133 static int dmtc_crypto_cb_write_done(struct cryptop *crp);
134
135 static ivgen_ctor_t     essiv_ivgen_ctor;
136 static ivgen_dtor_t     essiv_ivgen_dtor;
137 static ivgen_t          essiv_ivgen;
138 static ivgen_t          plain_ivgen;
139
140 static struct iv_generator ivgens[] = {
141         { .name = "essiv", .ctor = essiv_ivgen_ctor, .dtor = essiv_ivgen_dtor,
142             .gen_iv = essiv_ivgen },
143         { .name = "plain", .ctor = NULL, .dtor = NULL, .gen_iv = plain_ivgen },
144         { NULL, NULL, NULL, NULL }
145 };
146
147 struct objcache_malloc_args essiv_ivgen_malloc_args = {
148                 2*sizeof(void *) + (sizeof(struct cryptodesc) +
149                 sizeof(struct cryptop)), M_DMCRYPT };
150
151 /*
152  * Overwrite private information (in buf) to avoid leaking it
153  */
154 static void
155 dmtc_crypto_clear(void *buf, size_t len)
156 {
157         memset(buf, 0xFF, len);
158         bzero(buf, len);
159 }
160
161 /*
162  * ESSIV IV Generator Routines
163  */
164 static int 
165 essiv_ivgen_ctor(struct target_crypt_config *priv, char *iv_hash, void **p_ivpriv)
166 {
167         struct essiv_ivgen_priv *ivpriv;
168         u_int8_t crypto_keyhash[SHA512_DIGEST_LENGTH];
169         unsigned int klen, hashlen;
170         int error;
171
172         klen = (priv->crypto_klen >> 3);
173
174         if (iv_hash == NULL)
175                 return EINVAL;
176
177         if (!strcmp(iv_hash, "sha1")) {
178                 SHA1_CTX ctx;
179
180                 hashlen = SHA1_RESULTLEN;
181                 SHA1Init(&ctx);
182                 SHA1Update(&ctx, priv->crypto_key, priv->crypto_klen>>3);
183                 SHA1Final(crypto_keyhash, &ctx);
184         } else if (!strcmp(iv_hash, "sha256")) {
185                 SHA256_CTX ctx;
186
187                 hashlen = SHA256_DIGEST_LENGTH;
188                 SHA256_Init(&ctx);
189                 SHA256_Update(&ctx, priv->crypto_key, priv->crypto_klen>>3);
190                 SHA256_Final(crypto_keyhash, &ctx);
191         } else if (!strcmp(iv_hash, "sha384")) {
192                 SHA384_CTX ctx;
193
194                 hashlen = SHA384_DIGEST_LENGTH;
195                 SHA384_Init(&ctx);
196                 SHA384_Update(&ctx, priv->crypto_key, priv->crypto_klen>>3);
197                 SHA384_Final(crypto_keyhash, &ctx);
198         } else if (!strcmp(iv_hash, "sha512")) {
199                 SHA512_CTX ctx;
200
201                 hashlen = SHA512_DIGEST_LENGTH;
202                 SHA512_Init(&ctx);
203                 SHA512_Update(&ctx, priv->crypto_key, priv->crypto_klen>>3);
204                 SHA512_Final(crypto_keyhash, &ctx);
205         } else if (!strcmp(iv_hash, "md5")) {
206                 MD5_CTX ctx;
207
208                 hashlen = MD5_DIGEST_LENGTH;
209                 MD5Init(&ctx);
210                 MD5Update(&ctx, priv->crypto_key, priv->crypto_klen>>3);
211                 MD5Final(crypto_keyhash, &ctx);
212         } else if (!strcmp(iv_hash, "rmd160") ||
213                    !strcmp(iv_hash, "ripemd160")) {
214                 RMD160_CTX ctx;
215
216                 hashlen = 160/8;
217                 RMD160Init(&ctx);
218                 RMD160Update(&ctx, priv->crypto_key, priv->crypto_klen>>3);
219                 RMD160Final(crypto_keyhash, &ctx);
220         } else {
221                 return EINVAL;
222         }
223
224         /* Convert hashlen to bits */
225         hashlen <<= 3;
226
227         ivpriv = kmalloc(sizeof(struct essiv_ivgen_priv), M_DMCRYPT,
228             M_WAITOK | M_ZERO);
229         memcpy(ivpriv->crypto_keyhash, crypto_keyhash, sizeof(crypto_keyhash));
230         ivpriv->keyhash_len = sizeof(crypto_keyhash);
231         dmtc_crypto_clear(crypto_keyhash, sizeof(crypto_keyhash));
232
233         ivpriv->crypto_session.cri_alg = priv->crypto_alg;
234         ivpriv->crypto_session.cri_key = (u_int8_t *)ivpriv->crypto_keyhash;
235         ivpriv->crypto_session.cri_klen = hashlen;
236         ivpriv->crypto_session.cri_mlen = 0;
237         ivpriv->crypto_session.cri_next = NULL;
238
239         /*
240          * XXX: in principle we also need to check if the block size of the
241          *      cipher is a valid iv size for the block cipher.
242          */
243
244         error = crypto_newsession(&ivpriv->crypto_sid,
245                                   &ivpriv->crypto_session,
246                                   CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE);
247         if (error) {
248                 kprintf("dm_target_crypt: Error during crypto_newsession "
249                         "for essiv_ivgen, error = %d\n",
250                         error);
251                 dmtc_crypto_clear(ivpriv->crypto_keyhash, ivpriv->keyhash_len);
252                 kfree(ivpriv, M_DMCRYPT);
253                 return ENOTSUP;
254         }
255
256         ivpriv->crp_crd_cache = objcache_create(
257             "dmcrypt-essiv-cache", 0, 0,
258             NULL, NULL, NULL,
259             objcache_malloc_alloc,
260             objcache_malloc_free,
261             &essiv_ivgen_malloc_args );
262
263         *p_ivpriv = ivpriv;
264         return 0;
265 }
266
267 static int 
268 essiv_ivgen_dtor(struct target_crypt_config *priv, void *arg)
269 {
270         struct essiv_ivgen_priv *ivpriv;
271
272         ivpriv = (struct essiv_ivgen_priv *)arg;
273         KKASSERT(ivpriv != NULL);
274
275         crypto_freesession(ivpriv->crypto_sid);
276
277         objcache_destroy(ivpriv->crp_crd_cache);
278
279         dmtc_crypto_clear(ivpriv->crypto_keyhash, ivpriv->keyhash_len);
280         kfree(ivpriv, M_DMCRYPT);
281
282         return 0;
283 }
284
285 static int
286 essiv_ivgen_done(struct cryptop *crp)
287 {
288         struct essiv_ivgen_priv *ivpriv;
289         void *free_addr;
290         void *opaque;
291
292
293         if (crp->crp_etype == EAGAIN)
294                 return crypto_dispatch(crp);
295
296         if (crp->crp_etype != 0) {
297                 kprintf("dm_target_crypt: essiv_ivgen_done, "
298                         "crp->crp_etype = %d\n", crp->crp_etype);
299         }
300
301         free_addr = crp->crp_opaque;
302         /*
303          * In-memory structure is:
304          * |  ivpriv  |  opaque  |     crp     |      crd      |
305          * | (void *) | (void *) |   (cryptop) |  (cryptodesc) |
306          */
307         ivpriv = *((struct essiv_ivgen_priv **)crp->crp_opaque);
308         crp->crp_opaque += sizeof(void *);
309         opaque = *((void **)crp->crp_opaque);
310
311         objcache_put(ivpriv->crp_crd_cache, free_addr);
312         dmtc_crypto_dispatch(opaque);
313         return 0;
314 }
315
316 static void
317 essiv_ivgen(dm_target_crypt_config_t *priv, u_int8_t *iv,
318             size_t iv_len, off_t sector, void *opaque)
319 {
320         struct essiv_ivgen_priv *ivpriv;
321         struct cryptodesc *crd;
322         struct cryptop *crp;
323         caddr_t space, alloc_addr;
324         int error;
325
326         ivpriv = priv->ivgen_priv;
327         KKASSERT(ivpriv != NULL);
328
329         /*
330          * In-memory structure is:
331          * |  ivpriv  |  opaque  |     crp     |      crd      |
332          * | (void *) | (void *) |   (cryptop) |  (cryptodesc) |
333          */
334         alloc_addr = space = objcache_get(ivpriv->crp_crd_cache, M_WAITOK);
335         *((struct essiv_ivgen_priv **)space) = ivpriv;
336         space += sizeof(void *);
337         *((void **)space) = opaque;
338         space += sizeof(void *);
339         crp = (struct cryptop *)space;
340         space += sizeof(struct cryptop);
341         crd = (struct cryptodesc *)space;
342
343         bzero(iv, iv_len);
344         bzero(crd, sizeof(struct cryptodesc));
345         bzero(crp, sizeof(struct cryptop));
346         *((off_t *)iv) = htole64(sector + priv->iv_offset);
347         crp->crp_buf = (caddr_t)iv;
348
349         crp->crp_sid = ivpriv->crypto_sid;
350         crp->crp_ilen = crp->crp_olen = iv_len;
351
352         crp->crp_opaque = alloc_addr;
353
354         crp->crp_callback = essiv_ivgen_done;
355
356         crp->crp_desc = crd;
357         crp->crp_etype = 0;
358         crp->crp_flags = CRYPTO_F_CBIFSYNC | CRYPTO_F_REL | CRYPTO_F_BATCH;
359
360         crd->crd_alg = priv->crypto_alg;
361 #if 0
362         crd->crd_key = (caddr_t)priv->crypto_keyhash;
363         crd->crd_klen = priv->crypto_klen;
364 #endif
365
366         bzero(crd->crd_iv, sizeof(crd->crd_iv));
367
368         crd->crd_skip = 0;
369         crd->crd_len = iv_len;
370         crd->crd_flags = CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
371         crd->crd_flags |= CRD_F_ENCRYPT;
372         crd->crd_next = NULL;
373
374         error = crypto_dispatch(crp);
375         if (error)
376                 kprintf("dm_target_crypt: essiv_ivgen, error = %d\n", error);
377 }
378
379
380 static void
381 plain_ivgen(dm_target_crypt_config_t *priv, u_int8_t *iv,
382             size_t iv_len, off_t sector, void *opaque)
383 {
384         bzero(iv, iv_len);
385         *((uint32_t *)iv) = htole32((uint32_t)(sector + priv->iv_offset));
386         dmtc_crypto_dispatch(opaque);
387 }
388
389
390 #if 0
391 static void
392 geli_ivgen(dm_target_crypt_config_t *priv, u_int8_t *iv,
393            size_t iv_len, off_t sector, void *opaque)
394 {
395
396         SHA512_CTX      ctx512;
397         u_int8_t        md[SHA512_DIGEST_LENGTH]; /* Max. Digest Size */
398
399         memcpy(&ctx512, &priv->essivsha512_ctx, sizeof(SHA512_CTX));
400         SHA512_Update(&ctx512, (u_int8_t*)&sector, sizeof(off_t));
401         SHA512_Final(md, &ctx512);
402
403         memcpy(iv, md, iv_len);
404         dmtc_crypto_dispatch(opaque);
405 }
406 #endif
407
408 #ifdef DM_TARGET_MODULE
409 /*
410  * Every target can be compiled directly to dm driver or as a
411  * separate module this part of target is used for loading targets
412  * to dm driver.
413  * Target can be unloaded from kernel only if there are no users of
414  * it e.g. there are no devices which uses that target.
415  */
416 #include <sys/kernel.h>
417 #include <sys/module.h>
418
419 static int
420 dm_target_crypt_modcmd(modcmd_t cmd, void *arg)
421 {
422         dm_target_t *dmt;
423         int r;
424         dmt = NULL;
425
426         switch (cmd) {
427         case MODULE_CMD_INIT:
428                 if ((dmt = dm_target_lookup("crypt")) != NULL) {
429                         dm_target_unbusy(dmt);
430                         return EEXIST;
431                 }
432                 dmt = dm_target_alloc("crypt");
433
434                 dmt->version[0] = 1;
435                 dmt->version[1] = 6;
436                 dmt->version[2] = 0;
437                 strlcpy(dmt->name, "crypt", DM_MAX_TYPE_NAME);
438                 dmt->init = &dm_target_crypt_init;
439                 dmt->status = &dm_target_crypt_status;
440                 dmt->strategy = &dm_target_crypt_strategy;
441                 dmt->deps = &dm_target_crypt_deps;
442                 dmt->destroy = &dm_target_crypt_destroy;
443                 dmt->upcall = &dm_target_crypt_upcall;
444
445                 r = dm_target_insert(dmt);
446
447                 break;
448
449         case MODULE_CMD_FINI:
450                 r = dm_target_rem("crypt");
451                 break;
452
453         case MODULE_CMD_STAT:
454                 return ENOTTY;
455
456         default:
457                 return ENOTTY;
458         }
459
460         return r;
461 }
462
463 #endif
464
465 /*
466  * Init function called from dm_table_load_ioctl.
467  * cryptsetup actually passes us this:
468  * aes-cbc-essiv:sha256 7997f8af... 0 /dev/ad0s0a 8
469  */
470 static int
471 hex2key(char *hex, size_t key_len, u_int8_t *key)
472 {
473         char hex_buf[3];
474         size_t key_idx;
475
476         hex_buf[2] = 0;
477         for (key_idx = 0; key_idx < key_len; ++key_idx) {
478                 hex_buf[0] = *hex++;
479                 hex_buf[1] = *hex++;
480                 key[key_idx] = (u_int8_t)strtoul(hex_buf, NULL, 16);
481         }
482         hex_buf[0] = 0;
483         hex_buf[1] = 0;
484
485         return 0;
486 }
487
488 int
489 dm_target_crypt_init(dm_dev_t * dmv, void **target_config, char *params)
490 {
491         dm_target_crypt_config_t *priv;
492         size_t len;
493         char **ap, *args[5];
494         char *crypto_alg, *crypto_mode, *iv_mode, *iv_opt, *key, *dev;
495         char *status_str;
496         int i, argc, klen, error;
497         uint64_t iv_offset, block_offset;
498
499         if (params == NULL)
500                 return EINVAL;
501
502         len = strlen(params) + 1;
503         argc = 0;
504
505         status_str = kmalloc(len, M_DMCRYPT, M_WAITOK);
506         /*
507          * Parse a string, containing tokens delimited by white space,
508          * into an argument vector
509          */
510         for (ap = args; ap < &args[5] &&
511             (*ap = strsep(&params, " \t")) != NULL;) {
512                 if (**ap != '\0') {
513                         argc++;
514                         ap++;
515                 }
516         }
517
518         if (argc != 5) {
519                 kprintf("dm_target_crypt: not enough arguments, "
520                         "need exactly 5\n");
521                 kfree(status_str, M_DMCRYPT);
522                 return ENOMEM; /* XXX */
523         }
524
525         crypto_alg = strsep(&args[0], "-");
526         crypto_mode = strsep(&args[0], "-");
527         iv_opt = strsep(&args[0], "-");
528         iv_mode = strsep(&iv_opt, ":");
529         key = args[1];
530         iv_offset = strtouq(args[2], NULL, 0);
531         dev = args[3];
532         block_offset = strtouq(args[4], NULL, 0);
533         /* bits / 8 = bytes, 1 byte = 2 hexa chars, so << 2 */
534         klen = strlen(key) << 2;
535
536 #if 0
537         kprintf("dm_target_crypt - new: dev=%s, crypto_alg=%s, crypto_mode=%s, "
538                 "iv_mode=%s, iv_opt=%s, key=%s, iv_offset=%ju, "
539                 "block_offset=%ju\n",
540                 dev, crypto_alg, crypto_mode, iv_mode, iv_opt, key, iv_offset,
541                 block_offset);
542 #endif
543
544         priv = kmalloc(sizeof(dm_target_crypt_config_t), M_DMCRYPT, M_WAITOK);
545         if (priv == NULL) {
546                 kprintf("dm_target_crypt: could not allocate memory\n");
547                 kfree(status_str, M_DMCRYPT);
548                 return ENOMEM;
549         }
550
551         /* Insert dmp to global pdev list */
552         if ((priv->pdev = dm_pdev_insert(dev)) == NULL) {
553                 kprintf("dm_target_crypt: dm_pdev_insert failed\n");
554                 kfree(status_str, M_DMCRYPT);
555                 return ENOENT;
556         }
557
558         if ((strcmp(crypto_mode, "cbc") != 0) &&
559             !((strcmp(crypto_mode, "xts") == 0) && (strcmp(crypto_alg, "aes") == 0)))
560         {
561                 kprintf("dm_target_crypt: only support 'cbc' chaining mode"
562                     " and aes-xts, invalid mode '%s-%s'\n",
563                     crypto_alg, crypto_mode);
564                 goto notsup;
565         }
566
567         if (!strcmp(crypto_alg, "aes")) {
568                 if (!strcmp(crypto_mode, "xts")) {
569                         priv->crypto_alg = CRYPTO_AES_XTS;
570                         if (klen != 256 && klen != 512)
571                                 goto notsup;
572                 } else if (!strcmp(crypto_mode, "cbc")) {
573                         priv->crypto_alg = CRYPTO_AES_CBC;
574                         if (klen != 128 && klen != 192 && klen != 256)
575                                 goto notsup;
576                 } else {
577                         goto notsup;
578                 }
579                 priv->crypto_klen = klen;
580         } else if (!strcmp(crypto_alg, "blowfish")) {
581                 priv->crypto_alg = CRYPTO_BLF_CBC;
582                 if (klen < 128 || klen > 448 || (klen % 8) != 0)
583                         goto notsup;
584                 priv->crypto_klen = klen;
585         } else if (!strcmp(crypto_alg, "3des") ||
586                    !strncmp(crypto_alg, "des3", 4)) {
587                 priv->crypto_alg = CRYPTO_3DES_CBC;
588                 if (klen != 168)
589                         goto notsup;
590                 priv->crypto_klen = 168;
591         } else if (!strcmp(crypto_alg, "camellia")) {
592                 priv->crypto_alg = CRYPTO_CAMELLIA_CBC;
593                 if (klen != 128 && klen != 192 && klen != 256)
594                         goto notsup;
595                 priv->crypto_klen = klen;
596         } else if (!strcmp(crypto_alg, "skipjack")) {
597                 priv->crypto_alg = CRYPTO_SKIPJACK_CBC;
598                 if (klen != 80)
599                         goto notsup;
600                 priv->crypto_klen = 80;
601         } else if (!strcmp(crypto_alg, "cast5")) {
602                 priv->crypto_alg = CRYPTO_CAST_CBC;
603                 if (klen != 128)
604                         goto notsup;
605                 priv->crypto_klen = 128;
606         } else if (!strcmp(crypto_alg, "null")) {
607                 priv->crypto_alg = CRYPTO_NULL_CBC;
608                 if (klen != 128)
609                         goto notsup;
610                 priv->crypto_klen = 128;
611         } else {
612                 kprintf("dm_target_crypt: Unsupported crypto algorithm: %s\n",
613                         crypto_alg);
614                 goto notsup;
615         }
616
617         /* Save length of param string */
618         priv->params_len = len;
619         priv->block_offset = block_offset;
620         priv->iv_offset = iv_offset - block_offset;
621
622         *target_config = priv;
623
624         dmv->dev_type = DM_CRYPTO_DEV;
625
626         error = hex2key(key, priv->crypto_klen >> 3,
627                         (u_int8_t *)priv->crypto_key);
628
629         if (error) {
630                 kprintf("dm_target_crypt: hex2key failed, "
631                         "invalid key format\n");
632                 goto notsup;
633         }
634
635         /* Handle cmd */
636         for(i = 0; ivgens[i].name != NULL; i++) {
637                 if (!strcmp(iv_mode, ivgens[i].name))
638                         break;
639         }
640
641         if (ivgens[i].name == NULL) {
642                 kprintf("dm_target_crypt: iv_mode='%s' unsupported\n",
643                         iv_mode);       
644                 goto notsup;
645         }
646
647         /* Call our ivgen constructor */
648         if (ivgens[i].ctor != NULL) {
649                 error = ivgens[i].ctor(priv, iv_opt,
650                     &priv->ivgen_priv);
651                 if (error) {
652                         kprintf("dm_target_crypt: ctor for '%s' failed\n",
653                             ivgens[i].name);
654                         goto notsup;
655                 }
656         }
657
658         priv->ivgen = &ivgens[i];
659
660         priv->crypto_session.cri_alg = priv->crypto_alg;
661         priv->crypto_session.cri_key = (u_int8_t *)priv->crypto_key;
662         priv->crypto_session.cri_klen = priv->crypto_klen;
663         priv->crypto_session.cri_mlen = 0;
664         priv->crypto_session.cri_next = NULL;
665
666         error = crypto_newsession(&priv->crypto_sid,
667                                   &priv->crypto_session,
668                                   CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE);
669         if (error) {
670                 kprintf("dm_target_crypt: Error during crypto_newsession, "
671                         "error = %d\n",
672                         error);
673                 goto notsup;
674         }
675
676         memset(key, '0', strlen(key));
677         if (iv_opt) {
678                 ksprintf(status_str, "%s-%s-%s:%s %s %ju %s %ju",
679                     crypto_alg, crypto_mode, iv_mode, iv_opt,
680                     key, iv_offset, dev, block_offset);
681         } else {
682                 ksprintf(status_str, "%s-%s-%s %s %ju %s %ju",
683                     crypto_alg, crypto_mode, iv_mode,
684                     key, iv_offset, dev, block_offset);
685         }
686         priv->status_str = status_str;
687
688         return 0;
689
690 notsup:
691         kprintf("dm_target_crypt: ENOTSUP\n");
692         kfree(status_str, M_DMCRYPT);
693         return ENOTSUP;
694 }
695
696 /* Status routine called to get params string. */
697 char *
698 dm_target_crypt_status(void *target_config)
699 {
700         dm_target_crypt_config_t *priv;
701         char *params;
702
703         priv = target_config;
704
705         /* caller expects use of M_DM */
706         params = kmalloc(DM_MAX_PARAMS_SIZE, M_DM, M_WAITOK);
707
708         ksnprintf(params, DM_MAX_PARAMS_SIZE, "%s",
709             priv->status_str);
710
711         return params;
712 }
713
714 int
715 dm_target_crypt_destroy(dm_table_entry_t * table_en)
716 {
717         dm_target_crypt_config_t *priv;
718
719         /*
720          * Disconnect the crypt config before unbusying the target.
721          */
722         priv = table_en->target_config;
723         if (priv == NULL)
724                 return 0;
725         table_en->target_config = NULL;
726         dm_pdev_decr(priv->pdev);
727
728         dm_target_unbusy(table_en->target);
729
730         /*
731          * Clean up the crypt config
732          *
733          * Overwrite the private information before freeing memory to
734          * avoid leaking it.
735          */
736         if (priv->status_str) {
737                 dmtc_crypto_clear(priv->status_str, strlen(priv->status_str));
738                 kfree(priv->status_str, M_DMCRYPT);
739                 crypto_freesession(priv->crypto_sid);
740         }
741
742         if ((priv->ivgen) && (priv->ivgen->dtor != NULL)) {
743                 priv->ivgen->dtor(priv, priv->ivgen_priv);
744         }
745
746         dmtc_crypto_clear(priv, sizeof(dm_target_crypt_config_t));
747         kfree(priv, M_DMCRYPT);
748
749         return 0;
750 }
751
752 int
753 dm_target_crypt_deps(dm_table_entry_t * table_en, prop_array_t prop_array)
754 {
755         dm_target_crypt_config_t *priv;
756         struct vattr va;
757
758         int error;
759
760         if (table_en->target_config == NULL)
761                 return ENOENT;
762
763         priv = table_en->target_config;
764
765         if ((error = VOP_GETATTR(priv->pdev->pdev_vnode, &va)) != 0)
766                 return error;
767
768         prop_array_add_uint64(prop_array,
769                               (uint64_t)makeudev(va.va_rmajor, va.va_rminor));
770
771         return 0;
772 }
773
774 /* Unsupported for this target. */
775 int
776 dm_target_crypt_upcall(dm_table_entry_t * table_en, struct buf * bp)
777 {
778         return 0;
779 }
780
781 /************************************************************************
782  *                      STRATEGY SUPPORT FUNCTIONS                      *
783  ************************************************************************
784  *
785  * READ PATH:   doio -> bio_read_done -> crypto_work -> crypto_cb_read_done
786  * WRITE PATH:  crypto_work -> crypto_cb_write_done -> doio -> bio_write_done
787  */
788
789 /*
790  * Wrapper around crypto_dispatch() to match dispatch_t type
791  */
792 static void
793 dmtc_crypto_dispatch(void *arg)
794 {
795         struct cryptop *crp;
796
797         crp = (struct cryptop *)arg;
798         KKASSERT(crp != NULL);
799         crypto_dispatch(crp);
800 }
801  
802 /*
803  * Start IO operation, called from dmstrategy routine.
804  */
805 int
806 dm_target_crypt_strategy(dm_table_entry_t *table_en, struct buf *bp)
807 {
808         struct bio *bio;
809
810         dm_target_crypt_config_t *priv;
811         priv = table_en->target_config;
812
813         /* Get rid of stuff we can't really handle */
814         if ((bp->b_cmd == BUF_CMD_READ) || (bp->b_cmd == BUF_CMD_WRITE)) {
815                 if (((bp->b_bcount % DEV_BSIZE) != 0) || (bp->b_bcount == 0)) {
816                         kprintf("dm_target_crypt_strategy: can't really "
817                                 "handle bp->b_bcount = %d\n",
818                                 bp->b_bcount);
819                         bp->b_error = EINVAL;
820                         bp->b_flags |= B_ERROR | B_INVAL;
821                         biodone(&bp->b_bio1);
822                         return 0;
823                 }
824         }
825
826         switch (bp->b_cmd) {
827         case BUF_CMD_READ:
828                 bio = push_bio(&bp->b_bio1);
829                 bio->bio_offset = bp->b_bio1.bio_offset +
830                                   priv->block_offset * DEV_BSIZE;
831                 bio->bio_caller_info1.ptr = priv;
832                 bio->bio_done = dmtc_bio_read_done;
833                 vn_strategy(priv->pdev->pdev_vnode, bio);
834                 break;
835         case BUF_CMD_WRITE:
836                 bio = push_bio(&bp->b_bio1);
837                 bio->bio_offset = bp->b_bio1.bio_offset +
838                                   priv->block_offset * DEV_BSIZE;
839                 bio->bio_caller_info1.ptr = priv;
840                 dmtc_crypto_write_start(priv, bio);
841                 break;
842         default:
843                 vn_strategy(priv->pdev->pdev_vnode, &bp->b_bio1);
844                 break;
845         }
846         return 0;
847 }
848
849 /*
850  * STRATEGY READ PATH PART 1/3 (after read BIO completes)
851  */
852 static void
853 dmtc_bio_read_done(struct bio *bio)
854 {
855         struct bio *obio;
856
857         dm_target_crypt_config_t *priv;
858
859         /*
860          * If a read error occurs we shortcut the operation, otherwise
861          * go on to stage 2.
862          */
863         if (bio->bio_buf->b_flags & B_ERROR) {
864                 obio = pop_bio(bio);
865                 biodone(obio);
866         } else {
867                 priv = bio->bio_caller_info1.ptr;
868                 dmtc_crypto_read_start(priv, bio);
869         }
870 }
871
872 /*
873  * STRATEGY READ PATH PART 2/3
874  */
875 static void
876 dmtc_crypto_read_start(dm_target_crypt_config_t *priv, struct bio *bio)
877 {
878         struct dmtc_helper *dmtc;
879         struct cryptodesc *crd;
880         struct cryptop *crp;
881         struct cryptoini *cri;
882         int i, bytes, sectors, sz;
883         off_t isector;
884         u_char *ptr, *space;
885
886         cri = &priv->crypto_session;
887
888         /*
889          * Note: b_resid no good after read I/O, it will be 0, use
890          *       b_bcount.
891          */
892         bytes = bio->bio_buf->b_bcount;
893         isector = bio->bio_offset / DEV_BSIZE;  /* ivgen salt base? */
894         sectors = bytes / DEV_BSIZE;            /* Number of sectors */
895         sz = sectors * (sizeof(*crp) + sizeof(*crd));
896
897         /*
898          * For reads with bogus page we can't decrypt in place as stuff
899          * can get ripped out from under us.
900          *
901          * XXX actually it looks like we can, and in any case the initial
902          * read already completed and threw crypted data into the buffer
903          * cache buffer.  Disable for now.
904          */
905 #if 0
906         if (bio->bio_buf->b_flags & B_HASBOGUS) {
907                 space = kmalloc(sizeof(struct dmtc_helper) + sz + bytes,
908                                 M_DMCRYPT, M_WAITOK);
909                 dmtc = (struct dmtc_helper *)space;
910                 dmtc->free_addr = space;
911                 space += sizeof(struct dmtc_helper);
912                 dmtc->orig_buf = NULL;
913                 dmtc->data_buf = space + sz;
914                 memcpy(dmtc->data_buf, bio->bio_buf->b_data, bytes);
915         } else
916 #endif
917         {
918                 space = kmalloc(sizeof(struct dmtc_helper) + sz,
919                                 M_DMCRYPT, M_WAITOK);
920                 dmtc = (struct dmtc_helper *)space;
921                 dmtc->free_addr = space;
922                 space += sizeof(struct dmtc_helper);
923                 dmtc->orig_buf = NULL;
924                 dmtc->data_buf = bio->bio_buf->b_data;
925         }
926         bio->bio_caller_info2.ptr = dmtc;
927         bio->bio_buf->b_error = 0;
928
929         /*
930          * Load crypto descriptors (crp/crd loop)
931          */
932         bzero(space, sz);
933         ptr = space;
934         bio->bio_caller_info3.value = sectors;
935         cpu_sfence();
936 #if 0
937         kprintf("Read, bytes = %d (b_bcount), "
938                 "sectors = %d (bio = %p, b_cmd = %d)\n",
939                 bytes, sectors, bio, bio->bio_buf->b_cmd);
940 #endif
941         for (i = 0; i < sectors; i++) {
942                 crp = (struct cryptop *)ptr;
943                 ptr += sizeof(*crp);
944                 crd = (struct cryptodesc *)ptr;
945                 ptr += sizeof (*crd);
946
947                 crp->crp_buf = dmtc->data_buf + i * DEV_BSIZE;
948
949                 crp->crp_sid = priv->crypto_sid;
950                 crp->crp_ilen = crp->crp_olen = DEV_BSIZE;
951
952                 crp->crp_opaque = (void *)bio;
953
954                 crp->crp_callback = dmtc_crypto_cb_read_done;
955                 crp->crp_desc = crd;
956                 crp->crp_etype = 0;
957                 crp->crp_flags = CRYPTO_F_CBIFSYNC | CRYPTO_F_REL |
958                                  CRYPTO_F_BATCH;
959
960                 crd->crd_alg = priv->crypto_alg;
961 #if 0
962                 crd->crd_key = (caddr_t)priv->crypto_key;
963                 crd->crd_klen = priv->crypto_klen;
964 #endif
965
966                 crd->crd_skip = 0;
967                 crd->crd_len = DEV_BSIZE /* XXX */;
968                 crd->crd_flags = CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
969                 crd->crd_next = NULL;
970
971                 crd->crd_flags &= ~CRD_F_ENCRYPT;
972
973                 /*
974                  * Note: last argument is used to generate salt(?) and is
975                  *       a 64 bit value, but the original code passed an
976                  *       int.  Changing it now will break pre-existing
977                  *       crypt volumes.
978                  */
979                 priv->ivgen->gen_iv(priv, crd->crd_iv, sizeof(crd->crd_iv),
980                                     isector + i, crp);
981         }
982 }
983
984 /*
985  * STRATEGY READ PATH PART 3/3
986  */
987 static int
988 dmtc_crypto_cb_read_done(struct cryptop *crp)
989 {
990         struct dmtc_helper *dmtc;
991         struct bio *bio, *obio;
992         int n;
993
994         if (crp->crp_etype == EAGAIN)
995                 return crypto_dispatch(crp);
996
997         bio = (struct bio *)crp->crp_opaque;
998         KKASSERT(bio != NULL);
999
1000         /*
1001          * Cumulative error
1002          */
1003         if (crp->crp_etype) {
1004                 kprintf("dm_target_crypt: dmtc_crypto_cb_read_done "
1005                         "crp_etype = %d\n",
1006                         crp->crp_etype);
1007                 bio->bio_buf->b_error = crp->crp_etype;
1008         }
1009
1010         /*
1011          * On the last chunk of the decryption we do any required copybacks
1012          * and complete the I/O.
1013          */
1014         n = atomic_fetchadd_int(&bio->bio_caller_info3.value, -1);
1015 #if 0
1016         kprintf("dmtc_crypto_cb_read_done %p, n = %d\n", bio, n);
1017 #endif
1018
1019         if (n == 1) {
1020                 /*
1021                  * For the B_HASBOGUS case we didn't decrypt in place,
1022                  * so we need to copy stuff back into the buf.
1023                  *
1024                  * (disabled for now).
1025                  */
1026                 dmtc = bio->bio_caller_info2.ptr;
1027                 if (bio->bio_buf->b_error) {
1028                         bio->bio_buf->b_flags |= B_ERROR;
1029                 }
1030 #if 0
1031                 else if (bio->bio_buf->b_flags & B_HASBOGUS) {
1032                         memcpy(bio->bio_buf->b_data, dmtc->data_buf,
1033                                bio->bio_buf->b_bcount);
1034                 }
1035 #endif
1036                 kfree(dmtc->free_addr, M_DMCRYPT);
1037                 obio = pop_bio(bio);
1038                 biodone(obio);
1039         }
1040         return 0;
1041 }
1042 /* END OF STRATEGY READ SECTION */
1043
1044 /*
1045  * STRATEGY WRITE PATH PART 1/3
1046  */
1047 static void
1048 dmtc_crypto_write_start(dm_target_crypt_config_t *priv, struct bio *bio)
1049 {
1050         struct dmtc_helper *dmtc;
1051         struct cryptodesc *crd;
1052         struct cryptop *crp;
1053         struct cryptoini *cri;
1054         int i, bytes, sectors, sz;
1055         off_t isector;
1056         u_char *ptr, *space;
1057
1058         cri = &priv->crypto_session;
1059
1060         /*
1061          * Use b_bcount for consistency
1062          */
1063         bytes = bio->bio_buf->b_bcount;
1064
1065         isector = bio->bio_offset / DEV_BSIZE;  /* ivgen salt base? */
1066         sectors = bytes / DEV_BSIZE;            /* Number of sectors */
1067         sz = sectors * (sizeof(*crp) + sizeof(*crd));
1068
1069         /*
1070          * For writes and reads with bogus page don't decrypt in place.
1071          */
1072         space = kmalloc(sizeof(struct dmtc_helper) + sz + bytes,
1073                         M_DMCRYPT, M_WAITOK);
1074         dmtc = (struct dmtc_helper *)space;
1075         dmtc->free_addr = space;
1076         space += sizeof(struct dmtc_helper);
1077         memcpy(space + sz, bio->bio_buf->b_data, bytes);
1078
1079         bio->bio_caller_info2.ptr = dmtc;
1080         bio->bio_buf->b_error = 0;
1081
1082         dmtc->orig_buf = bio->bio_buf->b_data;
1083         dmtc->data_buf = space + sz;
1084
1085         /*
1086          * Load crypto descriptors (crp/crd loop)
1087          */
1088         bzero(space, sz);
1089         ptr = space;
1090         bio->bio_caller_info3.value = sectors;
1091         cpu_sfence();
1092 #if 0
1093         kprintf("Write, bytes = %d (b_bcount), "
1094                 "sectors = %d (bio = %p, b_cmd = %d)\n",
1095                 bytes, sectors, bio, bio->bio_buf->b_cmd);
1096 #endif
1097         for (i = 0; i < sectors; i++) {
1098                 crp = (struct cryptop *)ptr;
1099                 ptr += sizeof(*crp);
1100                 crd = (struct cryptodesc *)ptr;
1101                 ptr += sizeof (*crd);
1102
1103                 crp->crp_buf = dmtc->data_buf + i * DEV_BSIZE;
1104
1105                 crp->crp_sid = priv->crypto_sid;
1106                 crp->crp_ilen = crp->crp_olen = DEV_BSIZE;
1107
1108                 crp->crp_opaque = (void *)bio;
1109
1110                 crp->crp_callback = dmtc_crypto_cb_write_done;
1111                 crp->crp_desc = crd;
1112                 crp->crp_etype = 0;
1113                 crp->crp_flags = CRYPTO_F_CBIFSYNC | CRYPTO_F_REL |
1114                                  CRYPTO_F_BATCH;
1115
1116                 crd->crd_alg = priv->crypto_alg;
1117 #if 0
1118                 crd->crd_key = (caddr_t)priv->crypto_key;
1119                 crd->crd_klen = priv->crypto_klen;
1120 #endif
1121
1122                 crd->crd_skip = 0;
1123                 crd->crd_len = DEV_BSIZE /* XXX */;
1124                 crd->crd_flags = CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
1125                 crd->crd_next = NULL;
1126
1127                 crd->crd_flags |= CRD_F_ENCRYPT;
1128
1129                 /*
1130                  * Note: last argument is used to generate salt(?) and is
1131                  *       a 64 bit value, but the original code passed an
1132                  *       int.  Changing it now will break pre-existing
1133                  *       crypt volumes.
1134                  */
1135                 priv->ivgen->gen_iv(priv, crd->crd_iv, sizeof(crd->crd_iv),
1136                                     isector + i, crp);
1137         }
1138 }
1139
1140 /*
1141  * STRATEGY WRITE PATH PART 2/3
1142  */
1143 static int
1144 dmtc_crypto_cb_write_done(struct cryptop *crp)
1145 {
1146         struct dmtc_helper *dmtc;
1147         dm_target_crypt_config_t *priv;
1148         struct bio *bio, *obio;
1149         int n;
1150
1151         if (crp->crp_etype == EAGAIN)
1152                 return crypto_dispatch(crp);
1153
1154         bio = (struct bio *)crp->crp_opaque;
1155         KKASSERT(bio != NULL);
1156
1157         /*
1158          * Cumulative error
1159          */
1160         if (crp->crp_etype != 0) {
1161                 kprintf("dm_target_crypt: dmtc_crypto_cb_write_done "
1162                         "crp_etype = %d\n",
1163                 crp->crp_etype);
1164                 bio->bio_buf->b_error = crp->crp_etype;
1165         }
1166
1167         /*
1168          * On the last chunk of the encryption we issue the write
1169          */
1170         n = atomic_fetchadd_int(&bio->bio_caller_info3.value, -1);
1171 #if 0
1172         kprintf("dmtc_crypto_cb_write_done %p, n = %d\n", bio, n);
1173 #endif
1174
1175         if (n == 1) {
1176                 dmtc = bio->bio_caller_info2.ptr;
1177                 priv = (dm_target_crypt_config_t *)bio->bio_caller_info1.ptr;
1178
1179                 if (bio->bio_buf->b_error) {
1180                         bio->bio_buf->b_flags |= B_ERROR;
1181                         kfree(dmtc->free_addr, M_DMCRYPT);
1182                         obio = pop_bio(bio);
1183                         biodone(obio);
1184                 } else {
1185                         dmtc->orig_buf = bio->bio_buf->b_data;
1186                         bio->bio_buf->b_data = dmtc->data_buf;
1187                         bio->bio_done = dmtc_bio_write_done;
1188                         vn_strategy(priv->pdev->pdev_vnode, bio);
1189                 }
1190         }
1191         return 0;
1192 }
1193
1194 /*
1195  * STRATEGY WRITE PATH PART 3/3
1196  */
1197 static void
1198 dmtc_bio_write_done(struct bio *bio)
1199 {
1200         struct dmtc_helper *dmtc;
1201         struct bio *obio;
1202
1203         dmtc = bio->bio_caller_info2.ptr;
1204         bio->bio_buf->b_data = dmtc->orig_buf;
1205         kfree(dmtc->free_addr, M_DMCRYPT);
1206         obio = pop_bio(bio);
1207         biodone(obio);
1208 }
1209 /* END OF STRATEGY WRITE SECTION */
1210
1211
1212
1213 /* DUMPING MAGIC */
1214
1215 extern int tsleep_crypto_dump;
1216
1217 int
1218 dm_target_crypt_dump(dm_table_entry_t *table_en, void *data, size_t length, off_t offset)
1219 {
1220         static struct dmtc_dump_helper dump_helper;
1221         dm_target_crypt_config_t *priv;
1222         int id;
1223         static int first_call = 1;
1224
1225         priv = table_en->target_config;
1226
1227         if (first_call) {
1228                 first_call = 0;
1229                 dump_reactivate_cpus();
1230         }
1231
1232         /* Magically enable tsleep */
1233         tsleep_crypto_dump = 1;
1234         id = 0;
1235
1236         /*
1237          * 0 length means flush buffers and return
1238          */
1239         if (length == 0) {
1240                 if (priv->pdev->pdev_vnode->v_rdev == NULL) {
1241                         tsleep_crypto_dump = 0;
1242                         return ENXIO;
1243                 }
1244                 dev_ddump(priv->pdev->pdev_vnode->v_rdev,
1245                     data, 0, offset, 0);
1246                 tsleep_crypto_dump = 0;
1247                 return 0;
1248         }
1249
1250         bzero(&dump_helper, sizeof(dump_helper));
1251         dump_helper.priv = priv;
1252         dump_helper.data = data;
1253         dump_helper.length = length;
1254         dump_helper.offset = offset +
1255             priv->block_offset * DEV_BSIZE;
1256         dump_helper.ident = &id;
1257         dmtc_crypto_dump_start(priv, &dump_helper);
1258
1259         /*
1260          * Hackery to make stuff appear synchronous. The crypto callback will
1261          * set id to 1 and call wakeup on it. If the request completed
1262          * synchronously, id will be 1 and we won't bother to sleep. If not,
1263          * the crypto request will complete asynchronously and we sleep until
1264          * it's done.
1265          */
1266         if (id == 0)
1267                 tsleep(&dump_helper, 0, "cryptdump", 0);
1268
1269         dump_helper.offset = dm_pdev_correct_dump_offset(priv->pdev,
1270             dump_helper.offset);
1271
1272         dev_ddump(priv->pdev->pdev_vnode->v_rdev,
1273             dump_helper.space, 0, dump_helper.offset,
1274             dump_helper.length);
1275
1276         tsleep_crypto_dump = 0;
1277         return 0;
1278 }
1279
1280 static void
1281 dmtc_crypto_dump_start(dm_target_crypt_config_t *priv, struct dmtc_dump_helper *dump_helper)
1282 {
1283         struct cryptodesc *crd;
1284         struct cryptop *crp;
1285         struct cryptoini *cri;
1286         int i, bytes, sectors;
1287         off_t isector;
1288
1289         cri = &priv->crypto_session;
1290
1291         bytes = dump_helper->length;
1292
1293         isector = dump_helper->offset / DEV_BSIZE;      /* ivgen salt base? */
1294         sectors = bytes / DEV_BSIZE;            /* Number of sectors */
1295         dump_helper->sectors = sectors;
1296 #if 0
1297         kprintf("Dump, bytes = %d, "
1298                 "sectors = %d, LENGTH=%zu\n", bytes, sectors, dump_helper->length);
1299 #endif
1300         KKASSERT(dump_helper->length <= 65536);
1301
1302         memcpy(dump_helper->space, dump_helper->data, bytes);
1303
1304         cpu_sfence();
1305
1306         for (i = 0; i < sectors; i++) {
1307                 crp = &dump_helper->crp[i];
1308                 crd = &dump_helper->crd[i];
1309
1310                 crp->crp_buf = dump_helper->space + i * DEV_BSIZE;
1311
1312                 crp->crp_sid = priv->crypto_sid;
1313                 crp->crp_ilen = crp->crp_olen = DEV_BSIZE;
1314
1315                 crp->crp_opaque = (void *)dump_helper;
1316
1317                 crp->crp_callback = dmtc_crypto_cb_dump_done;
1318                 crp->crp_desc = crd;
1319                 crp->crp_etype = 0;
1320                 crp->crp_flags = CRYPTO_F_CBIFSYNC | CRYPTO_F_REL |
1321                                  CRYPTO_F_BATCH;
1322
1323                 crd->crd_alg = priv->crypto_alg;
1324
1325                 crd->crd_skip = 0;
1326                 crd->crd_len = DEV_BSIZE /* XXX */;
1327                 crd->crd_flags = CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
1328                 crd->crd_next = NULL;
1329
1330                 crd->crd_flags |= CRD_F_ENCRYPT;
1331
1332                 /*
1333                  * Note: last argument is used to generate salt(?) and is
1334                  *       a 64 bit value, but the original code passed an
1335                  *       int.  Changing it now will break pre-existing
1336                  *       crypt volumes.
1337                  */
1338                 priv->ivgen->gen_iv(priv, crd->crd_iv, sizeof(crd->crd_iv),
1339                                     isector + i, crp);
1340         }
1341 }
1342
1343 static int
1344 dmtc_crypto_cb_dump_done(struct cryptop *crp)
1345 {
1346         struct dmtc_dump_helper *dump_helper;
1347         dm_target_crypt_config_t *priv;
1348         int n;
1349
1350         if (crp->crp_etype == EAGAIN)
1351                 return crypto_dispatch(crp);
1352
1353         dump_helper = (struct dmtc_dump_helper *)crp->crp_opaque;
1354         KKASSERT(dump_helper != NULL);
1355
1356         if (crp->crp_etype != 0) {
1357                 kprintf("dm_target_crypt: dmtc_crypto_cb_dump_done "
1358                         "crp_etype = %d\n",
1359                 crp->crp_etype);
1360                 return crp->crp_etype;
1361         }
1362
1363         /*
1364          * On the last chunk of the encryption we return control
1365          */
1366         n = atomic_fetchadd_int(&dump_helper->sectors, -1);
1367
1368         if (n == 1) {
1369                 priv = (dm_target_crypt_config_t *)dump_helper->priv;
1370                 atomic_add_int(dump_helper->ident, 1);
1371                 wakeup(dump_helper);
1372         }
1373
1374         return 0;
1375 }