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>
51 #include <machine/cpufunc.h>
54 MALLOC_DEFINE(M_DMCRYPT, "dm_crypt", "Device Mapper Target Crypt");
56 struct target_crypt_config;
57 typedef void ivgen_t(struct target_crypt_config *, u_int8_t *, size_t, off_t);
59 typedef struct target_crypt_config {
65 u_int8_t crypto_key[512>>3];
66 u_int8_t crypto_keyhash[SHA512_DIGEST_LENGTH];
68 u_int64_t block_offset;
70 SHA512_CTX essivsha512_ctx;
71 struct cryptoini crypto_session;
72 ivgen_t *crypto_ivgen;
73 } dm_target_crypt_config_t;
81 static void dmtc_crypto_read_start(dm_target_crypt_config_t *priv,
83 static void dmtc_crypto_write_start(dm_target_crypt_config_t *priv,
85 static void dmtc_bio_read_done(struct bio *bio);
86 static void dmtc_bio_write_done(struct bio *bio);
87 static int dmtc_crypto_cb_read_done(struct cryptop *crp);
88 static int dmtc_crypto_cb_write_done(struct cryptop *crp);
91 * Support routines for dm_target_crypt_init
94 essiv_hash_mkey(dm_target_crypt_config_t *priv, char *iv_hash)
98 klen = (priv->crypto_klen >> 3);
103 if (!strcmp(iv_hash, "sha1")) {
106 if (klen != SHA1_RESULTLEN)
110 SHA1Update(&ctx, priv->crypto_key, priv->crypto_klen>>3);
111 SHA1Final(priv->crypto_keyhash, &ctx);
112 } else if (!strcmp(iv_hash, "sha256")) {
115 if (klen != SHA256_DIGEST_LENGTH)
119 SHA256_Update(&ctx, priv->crypto_key, priv->crypto_klen>>3);
120 SHA256_Final(priv->crypto_keyhash, &ctx);
121 } else if (!strcmp(iv_hash, "sha384")) {
124 if (klen != SHA384_DIGEST_LENGTH)
128 SHA384_Update(&ctx, priv->crypto_key, priv->crypto_klen>>3);
129 SHA384_Final(priv->crypto_keyhash, &ctx);
130 } else if (!strcmp(iv_hash, "sha512")) {
133 if (klen != SHA512_DIGEST_LENGTH)
137 SHA512_Update(&ctx, priv->crypto_key, priv->crypto_klen>>3);
138 SHA512_Final(priv->crypto_keyhash, &ctx);
139 } else if (!strcmp(iv_hash, "md5")) {
142 if (klen != MD5_DIGEST_LENGTH)
146 MD5Update(&ctx, priv->crypto_key, priv->crypto_klen>>3);
147 MD5Final(priv->crypto_keyhash, &ctx);
148 } else if (!strcmp(iv_hash, "rmd160") ||
149 !strcmp(iv_hash, "ripemd160")) {
156 RMD160Update(&ctx, priv->crypto_key, priv->crypto_klen>>3);
157 RMD160Final(priv->crypto_keyhash, &ctx);
166 essiv_ivgen_done(struct cryptop *crp)
169 if (crp->crp_etype == EAGAIN)
170 return crypto_dispatch(crp);
172 if (crp->crp_etype != 0) {
173 kprintf("dm_target_crypt: essiv_ivgen_done, "
174 "crp->crp_etype = %d\n", crp->crp_etype);
177 atomic_add_int((int *)crp->crp_opaque, 1);
178 wakeup(crp->crp_opaque);
183 plain_ivgen(dm_target_crypt_config_t *priv, u_int8_t *iv,
184 size_t iv_len, off_t sector)
187 *((off_t *)iv) = htole64(sector + priv->iv_offset);
191 essiv_ivgen(dm_target_crypt_config_t *priv, u_int8_t *iv,
192 size_t iv_len, off_t sector)
194 struct cryptodesc crd;
200 bzero(&crd, sizeof(crd));
201 bzero(&crp, sizeof(crp));
202 *((off_t *)iv) = htole64(sector + priv->iv_offset);
203 crp.crp_buf = (caddr_t)iv;
205 crp.crp_sid = priv->crypto_sid;
206 crp.crp_ilen = crp.crp_olen = iv_len;
208 crp.crp_opaque = (void *)&id;
210 crp.crp_callback = essiv_ivgen_done;
214 crp.crp_flags = CRYPTO_F_CBIFSYNC | CRYPTO_F_REL;
216 crd.crd_alg = priv->crypto_alg;
217 crd.crd_key = (caddr_t)priv->crypto_keyhash;
218 crd.crd_klen = priv->crypto_klen;
220 bzero(crd.crd_iv, sizeof(crd.crd_iv));
223 crd.crd_len = iv_len;
224 crd.crd_flags = CRD_F_KEY_EXPLICIT | CRD_F_IV_EXPLICIT |
226 crd.crd_flags |= CRD_F_ENCRYPT;
229 error = crypto_dispatch(&crp);
231 kprintf("dm_target_crypt: essiv_ivgen, error = %d\n", error);
234 * id is modified in the callback, so that if crypto_dispatch finishes
235 * synchronously we don't tsleep() forever.
238 tsleep((void *)&error, 0, "essivgen", 0);
244 geli_ivgen(dm_target_crypt_config_t *priv, u_int8_t *iv,
245 size_t iv_len, off_t sector)
249 u_int8_t md[SHA512_DIGEST_LENGTH]; /* Max. Digest Size */
251 memcpy(&ctx512, &priv->essivsha512_ctx, sizeof(SHA512_CTX));
252 SHA512_Update(&ctx512, (u_int8_t*)§or, sizeof(off_t));
253 SHA512_Final(md, &ctx512);
255 memcpy(iv, md, iv_len);
260 #ifdef DM_TARGET_MODULE
262 * Every target can be compiled directly to dm driver or as a
263 * separate module this part of target is used for loading targets
265 * Target can be unloaded from kernel only if there are no users of
266 * it e.g. there are no devices which uses that target.
268 #include <sys/kernel.h>
269 #include <sys/module.h>
272 dm_target_crypt_modcmd(modcmd_t cmd, void *arg)
279 case MODULE_CMD_INIT:
280 if ((dmt = dm_target_lookup("crypt")) != NULL) {
281 dm_target_unbusy(dmt);
284 dmt = dm_target_alloc("crypt");
289 strlcpy(dmt->name, "crypt", DM_MAX_TYPE_NAME);
290 dmt->init = &dm_target_crypt_init;
291 dmt->status = &dm_target_crypt_status;
292 dmt->strategy = &dm_target_crypt_strategy;
293 dmt->deps = &dm_target_crypt_deps;
294 dmt->destroy = &dm_target_crypt_destroy;
295 dmt->upcall = &dm_target_crypt_upcall;
297 r = dm_target_insert(dmt);
301 case MODULE_CMD_FINI:
302 r = dm_target_rem("crypt");
305 case MODULE_CMD_STAT:
318 * Init function called from dm_table_load_ioctl.
319 * cryptsetup actually passes us this:
320 * aes-cbc-essiv:sha256 7997f8af... 0 /dev/ad0s0a 8
323 hex2key(char *hex, size_t hex_length, u_int8_t *key)
329 bzero(hex_buf, sizeof(hex_buf));
331 for (; hex_length > 0; hex_length -= 2) {
334 key[key_idx++] = (u_int8_t)strtoul(hex_buf, NULL, 16);
341 dm_target_crypt_init(dm_dev_t * dmv, void **target_config, char *params)
343 dm_target_crypt_config_t *priv;
346 char *crypto_alg, *crypto_mode, *iv_mode, *iv_opt, *key, *dev;
348 int argc, klen, error;
349 uint64_t iv_offset, block_offset;
354 len = strlen(params) + 1;
357 status_str = kstrdup(params, M_DMCRYPT);
359 * Parse a string, containing tokens delimited by white space,
360 * into an argument vector
362 for (ap = args; ap < &args[5] &&
363 (*ap = strsep(¶ms, " \t")) != NULL;) {
371 kprintf("dm_target_crypt: not enough arguments, "
373 kfree(status_str, M_DMCRYPT);
374 return ENOMEM; /* XXX */
377 crypto_alg = strsep(&args[0], "-");
378 crypto_mode = strsep(&args[0], "-");
379 iv_opt = strsep(&args[0], "-");
380 iv_mode = strsep(&iv_opt, ":");
382 iv_offset = strtouq(args[2], NULL, 0);
384 block_offset = strtouq(args[4], NULL, 0);
385 /* bits / 8 = bytes, 1 byte = 2 hexa chars, so << 2 */
386 klen = strlen(key) << 2;
388 kprintf("dm_target_crypt: dev=%s, crypto_alg=%s, crypto_mode=%s, "
389 "iv_mode=%s, iv_opt=%s, key=%s, iv_offset=%ju, "
390 "block_offset=%ju\n",
391 dev, crypto_alg, crypto_mode, iv_mode, iv_opt, key, iv_offset,
394 priv = kmalloc(sizeof(dm_target_crypt_config_t), M_DMCRYPT, M_WAITOK);
396 kprintf("dm_target_crypt: could not allocate memory\n");
397 kfree(status_str, M_DMCRYPT);
401 /* Insert dmp to global pdev list */
402 if ((priv->pdev = dm_pdev_insert(dev)) == NULL) {
403 kprintf("dm_target_crypt: dm_pdev_insert failed\n");
404 kfree(status_str, M_DMCRYPT);
408 if (strcmp(crypto_mode, "cbc") != 0) {
409 kprintf("dm_target_crypt: only support 'cbc' chaining mode, "
410 "invalid mode '%s'\n", crypto_mode);
414 if (!strcmp(crypto_alg, "aes")) {
415 priv->crypto_alg = CRYPTO_AES_CBC;
416 if (klen != 128 && klen != 192 && klen != 256)
418 priv->crypto_klen = klen;
419 } else if (!strcmp(crypto_alg, "blowfish")) {
420 priv->crypto_alg = CRYPTO_BLF_CBC;
421 if (klen < 128 || klen > 448 || (klen % 8) != 0)
423 priv->crypto_klen = klen;
425 } else if (!strcmp(crypto_alg, "3des") ||
426 !strncmp(crypto_alg, "des3", 4)) {
427 priv->crypto_alg = CRYPTO_3DES_CBC;
430 priv->crypto_klen = 168;
431 } else if (!strcmp(crypto_alg, "camellia")) {
432 priv->crypto_alg = CRYPTO_CAMELLIA_CBC;
433 if (klen != 128 && klen != 192 && klen != 256)
435 priv->crypto_klen = klen;
436 } else if (!strcmp(crypto_alg, "skipjack")) {
437 priv->crypto_alg = CRYPTO_SKIPJACK_CBC;
440 priv->crypto_klen = 80;
441 } else if (!strcmp(crypto_alg, "cast5")) {
442 priv->crypto_alg = CRYPTO_CAST_CBC;
445 priv->crypto_klen = 128;
446 } else if (!strcmp(crypto_alg, "null")) {
447 priv->crypto_alg = CRYPTO_NULL_CBC;
450 priv->crypto_klen = 128;
452 kprintf("dm_target_crypt: Unsupported crypto algorithm: %s\n",
457 /* Save length of param string */
458 priv->params_len = len;
459 priv->block_offset = block_offset;
460 priv->iv_offset = iv_offset;
462 *target_config = priv;
464 dmv->dev_type = DM_CRYPTO_DEV;
466 priv->crypto_session.cri_alg = priv->crypto_alg;
467 priv->crypto_session.cri_klen = priv->crypto_klen;
468 priv->crypto_session.cri_mlen = 0;
470 error = hex2key(key, priv->crypto_klen >> 3,
471 (u_int8_t *)priv->crypto_key);
474 kprintf("dm_target_crypt: hex2key failed, "
475 "invalid key format\n");
479 if (!strcmp(iv_mode, "essiv")) {
480 error = essiv_hash_mkey(priv, iv_opt);
482 kprintf("dm_target_crypt: essiv_hash_mkey failed\n");
485 priv->crypto_ivgen = essiv_ivgen;
486 } else if (!strcmp(iv_mode, "plain")) {
487 priv->crypto_ivgen = plain_ivgen;
489 kprintf("dm_target_crypt: only support iv_mode='essiv' and "
490 "'plain', iv_mode='%s' unsupported\n",
494 priv->crypto_session.cri_key = (u_int8_t *)priv->crypto_key;
495 priv->crypto_session.cri_next = NULL;
497 error = crypto_newsession(&priv->crypto_sid,
498 &priv->crypto_session,
499 CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE);
501 kprintf("dm_target_crypt: Error during crypto_newsession, "
507 priv->status_str = status_str;
511 kprintf("dm_target_crypt: ENOTSUP\n");
512 kfree(status_str, M_DMCRYPT);
516 /* Status routine called to get params string. */
518 dm_target_crypt_status(void *target_config)
520 dm_target_crypt_config_t *priv;
523 priv = target_config;
525 /* caller expects use of M_DM */
526 params = kmalloc(DM_MAX_PARAMS_SIZE, M_DM, M_WAITOK);
528 ksnprintf(params, DM_MAX_PARAMS_SIZE, "%s",
535 dm_target_crypt_destroy(dm_table_entry_t * table_en)
537 dm_target_crypt_config_t *priv;
540 * Disconnect the crypt config before unbusying the target.
542 priv = table_en->target_config;
545 table_en->target_config = NULL;
546 dm_pdev_decr(priv->pdev);
548 dm_target_unbusy(table_en->target);
551 * Clean up the crypt config
553 * Overwrite the private information before freeing memory to
556 memset(priv->status_str, 0xFF, strlen(priv->status_str));
557 bzero(priv->status_str, strlen(priv->status_str));
558 kfree(priv->status_str, M_DMCRYPT);
560 memset(priv, 0xFF, sizeof(dm_target_crypt_config_t));
561 bzero(priv, sizeof(dm_target_crypt_config_t));
562 kfree(priv, M_DMCRYPT);
568 dm_target_crypt_deps(dm_table_entry_t * table_en, prop_array_t prop_array)
570 dm_target_crypt_config_t *priv;
575 if (table_en->target_config == NULL)
578 priv = table_en->target_config;
580 if ((error = VOP_GETATTR(priv->pdev->pdev_vnode, &va)) != 0)
583 prop_array_add_uint64(prop_array,
584 (uint64_t)makeudev(va.va_rmajor, va.va_rminor));
589 /* Unsupported for this target. */
591 dm_target_crypt_upcall(dm_table_entry_t * table_en, struct buf * bp)
596 /************************************************************************
597 * STRATEGY SUPPORT FUNCTIONS *
598 ************************************************************************
600 * READ PATH: doio -> bio_read_done -> crypto_work -> crypto_cb_read_done
601 * WRITE PATH: crypto_work -> crypto_cb_write_done -> doio -> bio_write_done
605 * Start IO operation, called from dmstrategy routine.
608 dm_target_crypt_strategy(dm_table_entry_t *table_en, struct buf *bp)
612 dm_target_crypt_config_t *priv;
613 priv = table_en->target_config;
615 /* Get rid of stuff we can't really handle */
616 if ((bp->b_cmd == BUF_CMD_READ) || (bp->b_cmd == BUF_CMD_WRITE)) {
617 if (((bp->b_bcount % DEV_BSIZE) != 0) || (bp->b_bcount == 0)) {
618 kprintf("dm_target_crypt_strategy: can't really "
619 "handle bp->b_bcount = %d\n",
621 bp->b_error = EINVAL;
622 bp->b_flags |= B_ERROR | B_INVAL;
623 biodone(&bp->b_bio1);
630 bio = push_bio(&bp->b_bio1);
631 bio->bio_offset = bp->b_bio1.bio_offset +
632 priv->block_offset * DEV_BSIZE;
633 bio->bio_caller_info1.ptr = priv;
634 bio->bio_done = dmtc_bio_read_done;
635 vn_strategy(priv->pdev->pdev_vnode, bio);
638 bio = push_bio(&bp->b_bio1);
639 bio->bio_offset = bp->b_bio1.bio_offset +
640 priv->block_offset * DEV_BSIZE;
641 bio->bio_caller_info1.ptr = priv;
642 dmtc_crypto_write_start(priv, bio);
645 vn_strategy(priv->pdev->pdev_vnode, &bp->b_bio1);
652 * STRATEGY READ PATH PART 1/3 (after read BIO completes)
655 dmtc_bio_read_done(struct bio *bio)
659 dm_target_crypt_config_t *priv;
662 * If a read error occurs we shortcut the operation, otherwise
665 if (bio->bio_buf->b_flags & B_ERROR) {
669 priv = bio->bio_caller_info1.ptr;
670 dmtc_crypto_read_start(priv, bio);
675 * STRATEGY READ PATH PART 2/3
678 dmtc_crypto_read_start(dm_target_crypt_config_t *priv, struct bio *bio)
680 struct dmtc_helper *dmtc;
681 struct cryptodesc *crd;
683 struct cryptoini *cri;
684 int error, i, bytes, isector, sectors, sz;
687 cri = &priv->crypto_session;
690 * Note: b_resid no good after read I/O, it will be 0, use
693 bytes = bio->bio_buf->b_bcount;
694 isector = (int)(bio->bio_offset / DEV_BSIZE); /* ivgen salt base? */
695 sectors = bytes / DEV_BSIZE; /* Number of sectors */
696 sz = sectors * (sizeof(*crp) + sizeof(*crd));
699 * For reads with bogus page we can't decrypt in place as stuff
700 * can get ripped out from under us.
702 * XXX actually it looks like we can, and in any case the initial
703 * read already completed and threw crypted data into the buffer
704 * cache buffer. Disable for now.
707 if (bio->bio_buf->b_flags & B_HASBOGUS) {
708 space = kmalloc(sizeof(struct dmtc_helper) + sz + bytes,
709 M_DMCRYPT, M_WAITOK);
710 dmtc = (struct dmtc_helper *)space;
711 dmtc->free_addr = space;
712 space += sizeof(struct dmtc_helper);
713 dmtc->orig_buf = NULL;
714 dmtc->data_buf = space + sz;
715 memcpy(dmtc->data_buf, bio->bio_buf->b_data, bytes);
719 space = kmalloc(sizeof(struct dmtc_helper) + sz,
720 M_DMCRYPT, M_WAITOK);
721 dmtc = (struct dmtc_helper *)space;
722 dmtc->free_addr = space;
723 space += sizeof(struct dmtc_helper);
724 dmtc->orig_buf = NULL;
725 dmtc->data_buf = bio->bio_buf->b_data;
727 bio->bio_caller_info2.ptr = dmtc;
728 bio->bio_buf->b_error = 0;
731 * Load crypto descriptors (crp/crd loop)
735 bio->bio_caller_info3.value = sectors;
738 kprintf("Read, bytes = %d (b_bcount), "
739 "sectors = %d (bio = %p, b_cmd = %d)\n",
740 bytes, sectors, bio, bio->bio_buf->b_cmd);
742 for (i = 0; i < sectors; i++) {
743 crp = (struct cryptop *)ptr;
745 crd = (struct cryptodesc *)ptr;
746 ptr += sizeof (*crd);
748 crp->crp_buf = dmtc->data_buf + i * DEV_BSIZE;
750 crp->crp_sid = priv->crypto_sid;
751 crp->crp_ilen = crp->crp_olen = DEV_BSIZE;
753 crp->crp_opaque = (void *)bio;
755 crp->crp_callback = dmtc_crypto_cb_read_done;
758 crp->crp_flags = CRYPTO_F_CBIFSYNC | CRYPTO_F_REL |
761 crd->crd_alg = priv->crypto_alg;
762 crd->crd_key = (caddr_t)priv->crypto_key;
763 crd->crd_klen = priv->crypto_klen;
766 * Note: last argument is used to generate salt(?) and is
767 * a 64 bit value, but the original code passed an
768 * int. Changing it now will break pre-existing
771 priv->crypto_ivgen(priv, crd->crd_iv, sizeof(crd->crd_iv),
775 crd->crd_len = DEV_BSIZE /* XXX */;
776 crd->crd_flags = CRD_F_KEY_EXPLICIT | CRD_F_IV_EXPLICIT |
778 crd->crd_next = NULL;
780 crd->crd_flags &= ~CRD_F_ENCRYPT;
782 error = crypto_dispatch(crp);
787 * STRATEGY READ PATH PART 3/3
790 dmtc_crypto_cb_read_done(struct cryptop *crp)
792 struct dmtc_helper *dmtc;
793 struct bio *bio, *obio;
796 if (crp->crp_etype == EAGAIN)
797 return crypto_dispatch(crp);
799 bio = (struct bio *)crp->crp_opaque;
800 KKASSERT(bio != NULL);
805 if (crp->crp_etype) {
806 kprintf("dm_target_crypt: dmtc_crypto_cb_read_done "
809 bio->bio_buf->b_error = crp->crp_etype;
813 * On the last chunk of the decryption we do any required copybacks
814 * and complete the I/O.
816 n = atomic_fetchadd_int(&bio->bio_caller_info3.value, -1);
818 kprintf("dmtc_crypto_cb_read_done %p, n = %d\n", bio, n);
823 * For the B_HASBOGUS case we didn't decrypt in place,
824 * so we need to copy stuff back into the buf.
826 * (disabled for now).
828 dmtc = bio->bio_caller_info2.ptr;
829 if (bio->bio_buf->b_error) {
830 bio->bio_buf->b_flags |= B_ERROR;
833 else if (bio->bio_buf->b_flags & B_HASBOGUS) {
834 memcpy(bio->bio_buf->b_data, dmtc->data_buf,
835 bio->bio_buf->b_bcount);
838 kfree(dmtc->free_addr, M_DMCRYPT);
844 /* END OF STRATEGY READ SECTION */
847 * STRATEGY WRITE PATH PART 1/3
850 dmtc_crypto_write_start(dm_target_crypt_config_t *priv, struct bio *bio)
852 struct dmtc_helper *dmtc;
853 struct cryptodesc *crd;
855 struct cryptoini *cri;
856 int error, i, bytes, isector, sectors, sz;
859 cri = &priv->crypto_session;
862 * Use b_bcount for consistency
864 bytes = bio->bio_buf->b_bcount;
866 isector = (int)(bio->bio_offset / DEV_BSIZE); /* ivgen salt base? */
867 sectors = bytes / DEV_BSIZE; /* Number of sectors */
868 sz = sectors * (sizeof(*crp) + sizeof(*crd));
871 * For writes and reads with bogus page don't decrypt in place.
873 space = kmalloc(sizeof(struct dmtc_helper) + sz + bytes,
874 M_DMCRYPT, M_WAITOK);
875 dmtc = (struct dmtc_helper *)space;
876 dmtc->free_addr = space;
877 space += sizeof(struct dmtc_helper);
878 memcpy(space + sz, bio->bio_buf->b_data, bytes);
880 bio->bio_caller_info2.ptr = dmtc;
881 bio->bio_buf->b_error = 0;
883 dmtc->orig_buf = bio->bio_buf->b_data;
884 dmtc->data_buf = space + sz;
887 * Load crypto descriptors (crp/crd loop)
891 bio->bio_caller_info3.value = sectors;
894 kprintf("Write, bytes = %d (b_bcount), "
895 "sectors = %d (bio = %p, b_cmd = %d)\n",
896 bytes, sectors, bio, bio->bio_buf->b_cmd);
898 for (i = 0; i < sectors; i++) {
899 crp = (struct cryptop *)ptr;
901 crd = (struct cryptodesc *)ptr;
902 ptr += sizeof (*crd);
904 crp->crp_buf = dmtc->data_buf + i * DEV_BSIZE;
906 crp->crp_sid = priv->crypto_sid;
907 crp->crp_ilen = crp->crp_olen = DEV_BSIZE;
909 crp->crp_opaque = (void *)bio;
911 crp->crp_callback = dmtc_crypto_cb_write_done;
914 crp->crp_flags = CRYPTO_F_CBIFSYNC | CRYPTO_F_REL |
917 crd->crd_alg = priv->crypto_alg;
918 crd->crd_key = (caddr_t)priv->crypto_key;
919 crd->crd_klen = priv->crypto_klen;
922 * Note: last argument is used to generate salt(?) and is
923 * a 64 bit value, but the original code passed an
924 * int. Changing it now will break pre-existing
927 priv->crypto_ivgen(priv, crd->crd_iv, sizeof(crd->crd_iv),
931 crd->crd_len = DEV_BSIZE /* XXX */;
932 crd->crd_flags = CRD_F_KEY_EXPLICIT | CRD_F_IV_EXPLICIT |
934 crd->crd_next = NULL;
936 crd->crd_flags |= CRD_F_ENCRYPT;
937 error = crypto_dispatch(crp);
942 * STRATEGY WRITE PATH PART 2/3
945 dmtc_crypto_cb_write_done(struct cryptop *crp)
947 struct dmtc_helper *dmtc;
948 dm_target_crypt_config_t *priv;
949 struct bio *bio, *obio;
952 if (crp->crp_etype == EAGAIN)
953 return crypto_dispatch(crp);
955 bio = (struct bio *)crp->crp_opaque;
956 KKASSERT(bio != NULL);
961 if (crp->crp_etype != 0) {
962 kprintf("dm_target_crypt: dmtc_crypto_cb_write_done "
965 bio->bio_buf->b_error = crp->crp_etype;
969 * On the last chunk of the encryption we issue the write
971 n = atomic_fetchadd_int(&bio->bio_caller_info3.value, -1);
973 kprintf("dmtc_crypto_cb_write_done %p, n = %d\n", bio, n);
977 dmtc = bio->bio_caller_info2.ptr;
978 priv = (dm_target_crypt_config_t *)bio->bio_caller_info1.ptr;
980 if (bio->bio_buf->b_error) {
981 bio->bio_buf->b_flags |= B_ERROR;
982 kfree(dmtc->free_addr, M_DMCRYPT);
986 dmtc->orig_buf = bio->bio_buf->b_data;
987 bio->bio_buf->b_data = dmtc->data_buf;
988 bio->bio_done = dmtc_bio_write_done;
989 vn_strategy(priv->pdev->pdev_vnode, bio);
996 * STRATEGY WRITE PATH PART 3/3
999 dmtc_bio_write_done(struct bio *bio)
1001 struct dmtc_helper *dmtc;
1004 dmtc = bio->bio_caller_info2.ptr;
1005 bio->bio_buf->b_data = dmtc->orig_buf;
1006 kfree(dmtc->free_addr, M_DMCRYPT);
1007 obio = pop_bio(bio);
1010 /* END OF STRATEGY WRITE SECTION */