2 * Copyright (c) 2010 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Alex Hornung <ahornung@gmail.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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.
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
36 * This file implements initial version of device-mapper crypt target.
38 #include <sys/types.h>
39 #include <sys/param.h>
40 #include <sys/endian.h>
44 #include <sys/malloc.h>
46 #include <sys/vnode.h>
47 #include <crypto/sha1.h>
48 #include <crypto/sha2/sha2.h>
49 #include <opencrypto/cryptodev.h>
50 #include <opencrypto/rmd160.h>
53 MALLOC_DEFINE(M_DMCRYPT, "dm_crypt", "Device Mapper Target Crypt");
55 struct target_crypt_config;
56 typedef void ivgen_t(struct target_crypt_config *, u_int8_t *, size_t, off_t);
58 typedef struct target_crypt_config {
64 u_int8_t crypto_key[512>>3];
65 u_int8_t crypto_keyhash[SHA512_DIGEST_LENGTH];
67 u_int64_t block_offset;
69 SHA512_CTX essivsha512_ctx;
70 struct cryptoini crypto_session;
71 ivgen_t *crypto_ivgen;
72 } dm_target_crypt_config_t;
80 static void dmtc_crypto_read_start(dm_target_crypt_config_t *priv,
82 static void dmtc_crypto_write_start(dm_target_crypt_config_t *priv,
84 static void dmtc_bio_read_done(struct bio *bio);
85 static void dmtc_bio_write_done(struct bio *bio);
86 static int dmtc_crypto_cb_read_done(struct cryptop *crp);
87 static int dmtc_crypto_cb_write_done(struct cryptop *crp);
90 * Support routines for dm_target_crypt_init
93 essiv_hash_mkey(dm_target_crypt_config_t *priv, char *iv_hash)
97 klen = (priv->crypto_klen >> 3);
102 if (!strcmp(iv_hash, "sha1")) {
105 if (klen != SHA1_RESULTLEN)
109 SHA1Update(&ctx, priv->crypto_key, priv->crypto_klen>>3);
110 SHA1Final(priv->crypto_keyhash, &ctx);
111 } else if (!strcmp(iv_hash, "sha256")) {
114 if (klen != SHA256_DIGEST_LENGTH)
118 SHA256_Update(&ctx, priv->crypto_key, priv->crypto_klen>>3);
119 SHA256_Final(priv->crypto_keyhash, &ctx);
120 } else if (!strcmp(iv_hash, "sha384")) {
123 if (klen != SHA384_DIGEST_LENGTH)
127 SHA384_Update(&ctx, priv->crypto_key, priv->crypto_klen>>3);
128 SHA384_Final(priv->crypto_keyhash, &ctx);
129 } else if (!strcmp(iv_hash, "sha512")) {
132 if (klen != SHA512_DIGEST_LENGTH)
136 SHA512_Update(&ctx, priv->crypto_key, priv->crypto_klen>>3);
137 SHA512_Final(priv->crypto_keyhash, &ctx);
138 } else if (!strcmp(iv_hash, "md5")) {
141 if (klen != MD5_DIGEST_LENGTH)
145 MD5Update(&ctx, priv->crypto_key, priv->crypto_klen>>3);
146 MD5Final(priv->crypto_keyhash, &ctx);
147 } else if (!strcmp(iv_hash, "rmd160") ||
148 !strcmp(iv_hash, "ripemd160")) {
155 RMD160Update(&ctx, priv->crypto_key, priv->crypto_klen>>3);
156 RMD160Final(priv->crypto_keyhash, &ctx);
165 essiv_ivgen_done(struct cryptop *crp)
168 if (crp->crp_etype == EAGAIN)
169 return crypto_dispatch(crp);
171 if (crp->crp_etype != 0) {
172 kprintf("dm_target_crypt: essiv_ivgen_done, "
173 "crp->crp_etype = %d\n", crp->crp_etype);
176 atomic_add_int((int *)crp->crp_opaque, 1);
177 wakeup(crp->crp_opaque);
182 plain_ivgen(dm_target_crypt_config_t *priv, u_int8_t *iv,
183 size_t iv_len, off_t sector)
186 *((off_t *)iv) = htole64(sector + priv->iv_offset);
190 essiv_ivgen(dm_target_crypt_config_t *priv, u_int8_t *iv,
191 size_t iv_len, off_t sector)
193 struct cryptodesc crd;
199 *((off_t *)iv) = htole64(sector + priv->iv_offset);
200 crp.crp_buf = (caddr_t)iv;
202 crp.crp_sid = priv->crypto_sid;
203 crp.crp_ilen = crp.crp_olen = iv_len;
205 crp.crp_opaque = (void *)&id;
207 crp.crp_callback = essiv_ivgen_done;
211 crp.crp_flags = CRYPTO_F_CBIFSYNC | CRYPTO_F_REL;
213 crd.crd_alg = priv->crypto_alg;
214 crd.crd_key = (caddr_t)priv->crypto_keyhash;
215 crd.crd_klen = priv->crypto_klen;
217 bzero(crd.crd_iv, sizeof(crd.crd_iv));
220 crd.crd_len = iv_len;
221 crd.crd_flags = CRD_F_KEY_EXPLICIT | CRD_F_IV_EXPLICIT |
223 crd.crd_flags |= CRD_F_ENCRYPT;
226 error = crypto_dispatch(&crp);
228 kprintf("dm_target_crypt: essiv_ivgen, error = %d\n", error);
231 * id is modified in the callback, so that if crypto_dispatch finishes
232 * synchronously we don't tsleep() forever.
235 tsleep((void *)&error, 0, "essivgen", 0);
241 geli_ivgen(dm_target_crypt_config_t *priv, u_int8_t *iv,
242 size_t iv_len, off_t sector)
246 u_int8_t md[SHA512_DIGEST_LENGTH]; /* Max. Digest Size */
248 memcpy(&ctx512, &priv->essivsha512_ctx, sizeof(SHA512_CTX));
249 SHA512_Update(&ctx512, (u_int8_t*)§or, sizeof(off_t));
250 SHA512_Final(md, &ctx512);
252 memcpy(iv, md, iv_len);
257 #ifdef DM_TARGET_MODULE
259 * Every target can be compiled directly to dm driver or as a
260 * separate module this part of target is used for loading targets
262 * Target can be unloaded from kernel only if there are no users of
263 * it e.g. there are no devices which uses that target.
265 #include <sys/kernel.h>
266 #include <sys/module.h>
269 dm_target_crypt_modcmd(modcmd_t cmd, void *arg)
276 case MODULE_CMD_INIT:
277 if ((dmt = dm_target_lookup("crypt")) != NULL) {
278 dm_target_unbusy(dmt);
281 dmt = dm_target_alloc("crypt");
286 strlcpy(dmt->name, "crypt", DM_MAX_TYPE_NAME);
287 dmt->init = &dm_target_crypt_init;
288 dmt->status = &dm_target_crypt_status;
289 dmt->strategy = &dm_target_crypt_strategy;
290 dmt->deps = &dm_target_crypt_deps;
291 dmt->destroy = &dm_target_crypt_destroy;
292 dmt->upcall = &dm_target_crypt_upcall;
294 r = dm_target_insert(dmt);
298 case MODULE_CMD_FINI:
299 r = dm_target_rem("crypt");
302 case MODULE_CMD_STAT:
315 * Init function called from dm_table_load_ioctl.
316 * cryptsetup actually passes us this:
317 * aes-cbc-essiv:sha256 7997f8af... 0 /dev/ad0s0a 8
320 hex2key(char *hex, size_t hex_length, u_int8_t *key)
326 bzero(hex_buf, sizeof(hex_buf));
328 for (; hex_length > 0; hex_length -= 2) {
331 key[key_idx++] = (u_int8_t)strtoul(hex_buf, NULL, 16);
338 dm_target_crypt_init(dm_dev_t * dmv, void **target_config, char *params)
340 dm_target_crypt_config_t *priv;
343 char *crypto_alg, *crypto_mode, *iv_mode, *iv_opt, *key, *dev;
345 int argc, klen, error;
346 uint64_t iv_offset, block_offset;
351 len = strlen(params) + 1;
354 status_str = kstrdup(params, M_DMCRYPT);
356 * Parse a string, containing tokens delimited by white space,
357 * into an argument vector
359 for (ap = args; ap < &args[5] &&
360 (*ap = strsep(¶ms, " \t")) != NULL;) {
368 kprintf("dm_target_crypt: not enough arguments, "
370 kfree(status_str, M_DMCRYPT);
371 return ENOMEM; /* XXX */
374 crypto_alg = strsep(&args[0], "-");
375 crypto_mode = strsep(&args[0], "-");
376 iv_opt = strsep(&args[0], "-");
377 iv_mode = strsep(&iv_opt, ":");
379 iv_offset = strtouq(args[2], NULL, 0);
381 block_offset = strtouq(args[4], NULL, 0);
382 /* bits / 8 = bytes, 1 byte = 2 hexa chars, so << 2 */
383 klen = strlen(key) << 2;
385 kprintf("dm_target_crypt: dev=%s, crypto_alg=%s, crypto_mode=%s, "
386 "iv_mode=%s, iv_opt=%s, key=%s, iv_offset=%ju, "
387 "block_offset=%ju\n",
388 dev, crypto_alg, crypto_mode, iv_mode, iv_opt, key, iv_offset,
391 priv = kmalloc(sizeof(dm_target_crypt_config_t), M_DMCRYPT, M_WAITOK);
393 kprintf("dm_target_crypt: could not allocate memory\n");
394 kfree(status_str, M_DMCRYPT);
398 /* Insert dmp to global pdev list */
399 if ((priv->pdev = dm_pdev_insert(dev)) == NULL) {
400 kprintf("dm_target_crypt: dm_pdev_insert failed\n");
401 kfree(status_str, M_DMCRYPT);
405 if (strcmp(crypto_mode, "cbc") != 0) {
406 kprintf("dm_target_crypt: only support 'cbc' chaining mode, "
407 "invalid mode '%s'\n", crypto_mode);
411 if (!strcmp(crypto_alg, "aes")) {
412 priv->crypto_alg = CRYPTO_AES_CBC;
413 if (klen != 128 && klen != 192 && klen != 256)
415 priv->crypto_klen = klen;
416 } else if (!strcmp(crypto_alg, "blowfish")) {
417 priv->crypto_alg = CRYPTO_BLF_CBC;
418 if (klen < 128 || klen > 448 || (klen % 8) != 0)
420 priv->crypto_klen = klen;
422 } else if (!strcmp(crypto_alg, "3des") ||
423 !strncmp(crypto_alg, "des3", 4)) {
424 priv->crypto_alg = CRYPTO_3DES_CBC;
427 priv->crypto_klen = 168;
428 } else if (!strcmp(crypto_alg, "camellia")) {
429 priv->crypto_alg = CRYPTO_CAMELLIA_CBC;
430 if (klen != 128 && klen != 192 && klen != 256)
432 priv->crypto_klen = klen;
433 } else if (!strcmp(crypto_alg, "skipjack")) {
434 priv->crypto_alg = CRYPTO_SKIPJACK_CBC;
437 priv->crypto_klen = 80;
438 } else if (!strcmp(crypto_alg, "cast5")) {
439 priv->crypto_alg = CRYPTO_CAST_CBC;
442 priv->crypto_klen = 128;
443 } else if (!strcmp(crypto_alg, "null")) {
444 priv->crypto_alg = CRYPTO_NULL_CBC;
447 priv->crypto_klen = 128;
449 kprintf("dm_target_crypt: Unsupported crypto algorithm: %s\n",
454 /* Save length of param string */
455 priv->params_len = len;
456 priv->block_offset = block_offset;
457 priv->iv_offset = iv_offset;
459 *target_config = priv;
461 dmv->dev_type = DM_CRYPTO_DEV;
463 priv->crypto_session.cri_alg = priv->crypto_alg;
464 priv->crypto_session.cri_klen = priv->crypto_klen;
465 priv->crypto_session.cri_mlen = 0;
467 error = hex2key(key, priv->crypto_klen >> 3,
468 (u_int8_t *)priv->crypto_key);
471 kprintf("dm_target_crypt: hex2key failed, "
472 "invalid key format\n");
476 if (!strcmp(iv_mode, "essiv")) {
477 error = essiv_hash_mkey(priv, iv_opt);
479 kprintf("dm_target_crypt: essiv_hash_mkey failed\n");
482 priv->crypto_ivgen = essiv_ivgen;
483 } else if (!strcmp(iv_mode, "plain")) {
484 priv->crypto_ivgen = plain_ivgen;
486 kprintf("dm_target_crypt: only support iv_mode='essiv' and "
487 "'plain', iv_mode='%s' unsupported\n",
491 priv->crypto_session.cri_key = (u_int8_t *)priv->crypto_key;
492 priv->crypto_session.cri_next = NULL;
494 error = crypto_newsession(&priv->crypto_sid,
495 &priv->crypto_session,
496 CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE);
498 kprintf("dm_target_crypt: Error during crypto_newsession, "
504 priv->status_str = status_str;
508 kprintf("dm_target_crypt: ENOTSUP\n");
509 kfree(status_str, M_DMCRYPT);
513 /* Status routine called to get params string. */
515 dm_target_crypt_status(void *target_config)
517 dm_target_crypt_config_t *priv;
520 priv = target_config;
522 /* caller expects use of M_DM */
523 params = kmalloc(DM_MAX_PARAMS_SIZE, M_DM, M_WAITOK);
525 ksnprintf(params, DM_MAX_PARAMS_SIZE, "%s",
532 dm_target_crypt_destroy(dm_table_entry_t * table_en)
534 dm_target_crypt_config_t *priv;
537 * Disconnect the crypt config before unbusying the target.
539 priv = table_en->target_config;
542 table_en->target_config = NULL;
543 dm_pdev_decr(priv->pdev);
545 dm_target_unbusy(table_en->target);
548 * Clean up the crypt config
550 * Overwrite the private information before freeing memory to
553 memset(priv->status_str, 0xFF, strlen(priv->status_str));
554 bzero(priv->status_str, strlen(priv->status_str));
555 kfree(priv->status_str, M_DMCRYPT);
557 memset(priv, 0xFF, sizeof(dm_target_crypt_config_t));
558 bzero(priv, sizeof(dm_target_crypt_config_t));
559 kfree(priv, M_DMCRYPT);
565 dm_target_crypt_deps(dm_table_entry_t * table_en, prop_array_t prop_array)
567 dm_target_crypt_config_t *priv;
572 if (table_en->target_config == NULL)
575 priv = table_en->target_config;
577 if ((error = VOP_GETATTR(priv->pdev->pdev_vnode, &va)) != 0)
580 prop_array_add_uint64(prop_array,
581 (uint64_t)makeudev(va.va_rmajor, va.va_rminor));
586 /* Unsupported for this target. */
588 dm_target_crypt_upcall(dm_table_entry_t * table_en, struct buf * bp)
593 /************************************************************************
594 * STRATEGY SUPPORT FUNCTIONS *
595 ************************************************************************
597 * READ PATH: doio -> bio_read_done -> crypto_work -> crypto_cb_read_done
598 * WRITE PATH: crypto_work -> crypto_cb_write_done -> doio -> bio_write_done
602 * Start IO operation, called from dmstrategy routine.
605 dm_target_crypt_strategy(dm_table_entry_t *table_en, struct buf *bp)
609 dm_target_crypt_config_t *priv;
610 priv = table_en->target_config;
612 /* Get rid of stuff we can't really handle */
613 if ((bp->b_cmd == BUF_CMD_READ) || (bp->b_cmd == BUF_CMD_WRITE)) {
614 if (((bp->b_bcount % DEV_BSIZE) != 0) || (bp->b_bcount == 0)) {
615 kprintf("dm_target_crypt_strategy: can't really "
616 "handle bp->b_bcount = %d\n",
618 bp->b_error = EINVAL;
619 bp->b_flags |= B_ERROR | B_INVAL;
620 biodone(&bp->b_bio1);
627 bio = push_bio(&bp->b_bio1);
628 bio->bio_offset = bp->b_bio1.bio_offset +
629 priv->block_offset * DEV_BSIZE;
630 bio->bio_caller_info1.ptr = priv;
631 bio->bio_done = dmtc_bio_read_done;
632 vn_strategy(priv->pdev->pdev_vnode, bio);
635 bio = push_bio(&bp->b_bio1);
636 bio->bio_offset = bp->b_bio1.bio_offset +
637 priv->block_offset * DEV_BSIZE;
638 bio->bio_caller_info1.ptr = priv;
639 dmtc_crypto_write_start(priv, bio);
642 vn_strategy(priv->pdev->pdev_vnode, &bp->b_bio1);
649 * STRATEGY READ PATH PART 1/3 (after read BIO completes)
652 dmtc_bio_read_done(struct bio *bio)
656 dm_target_crypt_config_t *priv;
659 * If a read error occurs we shortcut the operation, otherwise
662 if (bio->bio_buf->b_flags & B_ERROR) {
666 priv = bio->bio_caller_info1.ptr;
667 dmtc_crypto_read_start(priv, bio);
672 * STRATEGY READ PATH PART 2/3
675 dmtc_crypto_read_start(dm_target_crypt_config_t *priv, struct bio *bio)
677 struct dmtc_helper *dmtc;
678 struct cryptodesc *crd;
680 struct cryptoini *cri;
681 int error, i, bytes, isector, sectors, sz;
684 cri = &priv->crypto_session;
687 * Note: b_resid no good after read I/O, it will be 0, use
690 bytes = bio->bio_buf->b_bcount;
691 isector = bio->bio_offset / DEV_BSIZE; /* Initial sector */
692 sectors = bytes / DEV_BSIZE; /* Number of sectors */
693 sz = sectors * (sizeof(*crp) + sizeof(*crd));
696 * For reads with bogus page we can't decrypt in place as stuff
697 * can get ripped out from under us.
699 if (bio->bio_buf->b_flags & B_HASBOGUS) {
700 space = kmalloc(sizeof(struct dmtc_helper) + sz + bytes,
701 M_DMCRYPT, M_WAITOK);
702 dmtc = (struct dmtc_helper *)space;
703 dmtc->free_addr = space;
704 space += sizeof(struct dmtc_helper);
705 memcpy(space + sz, bio->bio_buf->b_data, bytes);
706 dmtc->data_buf = space + sz;
708 space = kmalloc(sizeof(struct dmtc_helper) + sz,
709 M_DMCRYPT, M_WAITOK);
710 dmtc = (struct dmtc_helper *)space;
711 dmtc->free_addr = space;
712 space += sizeof(struct dmtc_helper);
713 dmtc->data_buf = bio->bio_buf->b_data;
715 bio->bio_caller_info2.ptr = dmtc;
716 bio->bio_buf->b_error = 0;
719 * Load crypto descriptors (crp/crd loop)
722 bio->bio_caller_info3.value = sectors;
724 kprintf("Read, bytes = %d (b_bcount), "
725 "sectors = %d (bio = %p, b_cmd = %d)\n",
726 bytes, sectors, bio, bio->bio_buf->b_cmd);
728 for (i = 0; i < sectors; i++) {
729 crp = (struct cryptop *)ptr;
731 crd = (struct cryptodesc *)ptr;
732 ptr += sizeof (*crd);
734 crp->crp_buf = dmtc->data_buf + i * DEV_BSIZE;
736 crp->crp_sid = priv->crypto_sid;
737 crp->crp_ilen = crp->crp_olen = DEV_BSIZE;
739 crp->crp_opaque = (void *)bio;
741 crp->crp_callback = dmtc_crypto_cb_read_done;
744 crp->crp_flags = CRYPTO_F_CBIFSYNC | CRYPTO_F_REL;
746 crd->crd_alg = priv->crypto_alg;
747 crd->crd_key = (caddr_t)priv->crypto_key;
748 crd->crd_klen = priv->crypto_klen;
750 priv->crypto_ivgen(priv, crd->crd_iv, sizeof(crd->crd_iv),
754 crd->crd_len = DEV_BSIZE /* XXX */;
755 crd->crd_flags = CRD_F_KEY_EXPLICIT | CRD_F_IV_EXPLICIT |
757 crd->crd_next = NULL;
759 crd->crd_flags &= ~CRD_F_ENCRYPT;
761 error = crypto_dispatch(crp);
766 * STRATEGY READ PATH PART 3/3
769 dmtc_crypto_cb_read_done(struct cryptop *crp)
771 struct dmtc_helper *dmtc;
772 struct bio *bio, *obio;
775 if (crp->crp_etype == EAGAIN)
776 return crypto_dispatch(crp);
778 bio = (struct bio *)crp->crp_opaque;
779 KKASSERT(bio != NULL);
781 n = atomic_fetchadd_int(&bio->bio_caller_info3.value, -1);
783 kprintf("dmtc_crypto_cb_read_done %p, n = %d\n", bio, n);
789 if (crp->crp_etype) {
790 kprintf("dm_target_crypt: dmtc_crypto_cb_read_done "
793 bio->bio_buf->b_error = crp->crp_etype;
797 * On the last chunk of the decryption we do any required copybacks
798 * and complete the I/O.
802 * For the B_HASBOGUS case we didn't decrypt in place,
803 * so we need to copy stuff back into the buf.
805 dmtc = bio->bio_caller_info2.ptr;
806 if (bio->bio_buf->b_error) {
807 bio->bio_buf->b_flags |= B_ERROR;
808 } else if (bio->bio_buf->b_flags & B_HASBOGUS) {
809 memcpy(bio->bio_buf->b_data, dmtc->data_buf,
810 bio->bio_buf->b_bcount);
812 kfree(dmtc->free_addr, M_DMCRYPT);
818 /* END OF STRATEGY READ SECTION */
821 * STRATEGY WRITE PATH PART 1/3
824 dmtc_crypto_write_start(dm_target_crypt_config_t *priv, struct bio *bio)
826 struct dmtc_helper *dmtc;
827 struct cryptodesc *crd;
829 struct cryptoini *cri;
830 int error, i, bytes, isector, sectors, sz;
833 cri = &priv->crypto_session;
836 * Use b_bcount for consistency
838 bytes = bio->bio_buf->b_bcount;
840 isector = bio->bio_offset / DEV_BSIZE; /* Initial sector */
841 sectors = bytes / DEV_BSIZE; /* Number of sectors */
842 sz = sectors * (sizeof(*crp) + sizeof(*crd));
845 * For writes and reads with bogus page don't decrypt in place.
847 space = kmalloc(sizeof(struct dmtc_helper) + sz + bytes,
848 M_DMCRYPT, M_WAITOK);
849 dmtc = (struct dmtc_helper *)space;
850 dmtc->free_addr = space;
851 space += sizeof(struct dmtc_helper);
852 memcpy(space + sz, bio->bio_buf->b_data, bytes);
854 bio->bio_caller_info2.ptr = dmtc;
855 bio->bio_buf->b_error = 0;
857 dmtc->orig_buf = bio->bio_buf->b_data;
858 dmtc->data_buf = space + sz;
861 * Load crypto descriptors (crp/crd loop)
864 bio->bio_caller_info3.value = sectors;
866 kprintf("Write, bytes = %d (b_bcount), "
867 "sectors = %d (bio = %p, b_cmd = %d)\n",
868 bytes, sectors, bio, bio->bio_buf->b_cmd);
870 for (i = 0; i < sectors; i++) {
871 crp = (struct cryptop *)ptr;
873 crd = (struct cryptodesc *)ptr;
874 ptr += sizeof (*crd);
876 crp->crp_buf = dmtc->data_buf + i * DEV_BSIZE;
878 crp->crp_sid = priv->crypto_sid;
879 crp->crp_ilen = crp->crp_olen = DEV_BSIZE;
881 crp->crp_opaque = (void *)bio;
883 crp->crp_callback = dmtc_crypto_cb_write_done;
886 crp->crp_flags = CRYPTO_F_CBIFSYNC | CRYPTO_F_REL;
888 crd->crd_alg = priv->crypto_alg;
889 crd->crd_key = (caddr_t)priv->crypto_key;
890 crd->crd_klen = priv->crypto_klen;
892 priv->crypto_ivgen(priv, crd->crd_iv, sizeof(crd->crd_iv),
896 crd->crd_len = DEV_BSIZE /* XXX */;
897 crd->crd_flags = CRD_F_KEY_EXPLICIT | CRD_F_IV_EXPLICIT |
899 crd->crd_next = NULL;
901 crd->crd_flags |= CRD_F_ENCRYPT;
902 error = crypto_dispatch(crp);
907 * STRATEGY WRITE PATH PART 2/3
910 dmtc_crypto_cb_write_done(struct cryptop *crp)
912 struct dmtc_helper *dmtc;
913 dm_target_crypt_config_t *priv;
914 struct bio *bio, *obio;
917 if (crp->crp_etype == EAGAIN)
918 return crypto_dispatch(crp);
920 bio = (struct bio *)crp->crp_opaque;
921 KKASSERT(bio != NULL);
923 n = atomic_fetchadd_int(&bio->bio_caller_info3.value, -1);
925 kprintf("dmtc_crypto_cb_write_done %p, n = %d\n", bio, n);
931 if (crp->crp_etype != 0) {
932 kprintf("dm_target_crypt: dmtc_crypto_cb_write_done "
935 bio->bio_buf->b_error = crp->crp_etype;
939 * On the last chunk of the encryption we issue the write
942 dmtc = bio->bio_caller_info2.ptr;
943 priv = (dm_target_crypt_config_t *)bio->bio_caller_info1.ptr;
945 if (bio->bio_buf->b_error) {
946 bio->bio_buf->b_flags |= B_ERROR;
947 kfree(dmtc->free_addr, M_DMCRYPT);
951 dmtc->orig_buf = bio->bio_buf->b_data;
952 bio->bio_buf->b_data = dmtc->data_buf;
953 bio->bio_done = dmtc_bio_write_done;
954 vn_strategy(priv->pdev->pdev_vnode, bio);
961 * STRATEGY WRITE PATH PART 3/3
964 dmtc_bio_write_done(struct bio *bio)
966 struct dmtc_helper *dmtc;
969 dmtc = bio->bio_caller_info2.ptr;
970 bio->bio_buf->b_data = dmtc->orig_buf;
971 kfree(dmtc->free_addr, M_DMCRYPT);
975 /* END OF STRATEGY WRITE SECTION */