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;
58 typedef void dispatch_t(void *);
59 typedef void ivgen_t(struct target_crypt_config *, u_int8_t *, size_t, off_t,
62 typedef int ivgen_ctor_t(struct target_crypt_config *, char *, void **);
63 typedef int ivgen_dtor_t(struct target_crypt_config *, void *);
72 struct essiv_ivgen_priv {
73 struct cryptoini crypto_session;
74 struct objcache *crp_crd_cache;
77 u_int8_t crypto_keyhash[SHA512_DIGEST_LENGTH];
80 typedef struct target_crypt_config {
86 u_int8_t crypto_key[512>>3];
89 u_int64_t block_offset;
91 SHA512_CTX essivsha512_ctx;
93 struct cryptoini crypto_session;
95 struct iv_generator *ivgen;
97 } dm_target_crypt_config_t;
105 static void dmtc_crypto_dispatch(void *arg);
106 static void dmtc_crypto_read_start(dm_target_crypt_config_t *priv,
108 static void dmtc_crypto_write_start(dm_target_crypt_config_t *priv,
110 static void dmtc_bio_read_done(struct bio *bio);
111 static void dmtc_bio_write_done(struct bio *bio);
112 static int dmtc_crypto_cb_read_done(struct cryptop *crp);
113 static int dmtc_crypto_cb_write_done(struct cryptop *crp);
115 static ivgen_ctor_t essiv_ivgen_ctor;
116 static ivgen_dtor_t essiv_ivgen_dtor;
117 static ivgen_t essiv_ivgen;
118 static ivgen_t plain_ivgen;
120 static struct iv_generator ivgens[] = {
121 { .name = "essiv", .ctor = essiv_ivgen_ctor, .dtor = essiv_ivgen_dtor,
122 .gen_iv = essiv_ivgen },
123 { .name = "plain", .ctor = NULL, .dtor = NULL, .gen_iv = plain_ivgen },
124 { NULL, NULL, NULL, NULL }
127 struct objcache_malloc_args essiv_ivgen_malloc_args = {
128 2*sizeof(void *) + (sizeof(struct cryptodesc) +
129 sizeof(struct cryptop)), M_DMCRYPT };
132 * Overwrite private information (in buf) to avoid leaking it
135 dmtc_crypto_clear(void *buf, size_t len)
137 memset(buf, 0xFF, len);
142 * ESSIV IV Generator Routines
145 essiv_ivgen_ctor(struct target_crypt_config *priv, char *iv_hash, void **p_ivpriv)
147 struct essiv_ivgen_priv *ivpriv;
148 u_int8_t crypto_keyhash[SHA512_DIGEST_LENGTH];
149 unsigned int klen, hashlen;
152 klen = (priv->crypto_klen >> 3);
157 if (!strcmp(iv_hash, "sha1")) {
160 hashlen = SHA1_RESULTLEN;
162 SHA1Update(&ctx, priv->crypto_key, priv->crypto_klen>>3);
163 SHA1Final(crypto_keyhash, &ctx);
164 } else if (!strcmp(iv_hash, "sha256")) {
167 hashlen = SHA256_DIGEST_LENGTH;
169 SHA256_Update(&ctx, priv->crypto_key, priv->crypto_klen>>3);
170 SHA256_Final(crypto_keyhash, &ctx);
171 } else if (!strcmp(iv_hash, "sha384")) {
174 hashlen = SHA384_DIGEST_LENGTH;
176 SHA384_Update(&ctx, priv->crypto_key, priv->crypto_klen>>3);
177 SHA384_Final(crypto_keyhash, &ctx);
178 } else if (!strcmp(iv_hash, "sha512")) {
181 hashlen = SHA512_DIGEST_LENGTH;
183 SHA512_Update(&ctx, priv->crypto_key, priv->crypto_klen>>3);
184 SHA512_Final(crypto_keyhash, &ctx);
185 } else if (!strcmp(iv_hash, "md5")) {
188 hashlen = MD5_DIGEST_LENGTH;
190 MD5Update(&ctx, priv->crypto_key, priv->crypto_klen>>3);
191 MD5Final(crypto_keyhash, &ctx);
192 } else if (!strcmp(iv_hash, "rmd160") ||
193 !strcmp(iv_hash, "ripemd160")) {
198 RMD160Update(&ctx, priv->crypto_key, priv->crypto_klen>>3);
199 RMD160Final(crypto_keyhash, &ctx);
204 /* Convert hashlen to bits */
207 ivpriv = kmalloc(sizeof(struct essiv_ivgen_priv), M_DMCRYPT,
209 memcpy(ivpriv->crypto_keyhash, crypto_keyhash, sizeof(crypto_keyhash));
210 ivpriv->keyhash_len = sizeof(crypto_keyhash);
211 dmtc_crypto_clear(crypto_keyhash, sizeof(crypto_keyhash));
213 ivpriv->crypto_session.cri_alg = priv->crypto_alg;
214 ivpriv->crypto_session.cri_key = (u_int8_t *)ivpriv->crypto_keyhash;
215 ivpriv->crypto_session.cri_klen = hashlen;
216 ivpriv->crypto_session.cri_mlen = 0;
217 ivpriv->crypto_session.cri_next = NULL;
220 * XXX: in principle we also need to check if the block size of the
221 * cipher is a valid iv size for the block cipher.
224 error = crypto_newsession(&ivpriv->crypto_sid,
225 &ivpriv->crypto_session,
226 CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE);
228 kprintf("dm_target_crypt: Error during crypto_newsession "
229 "for essiv_ivgen, error = %d\n",
231 dmtc_crypto_clear(ivpriv->crypto_keyhash, ivpriv->keyhash_len);
232 kfree(ivpriv, M_DMCRYPT);
236 ivpriv->crp_crd_cache = objcache_create(
237 "dmcrypt-essiv-cache", 0, 0,
239 objcache_malloc_alloc,
240 objcache_malloc_free,
241 &essiv_ivgen_malloc_args );
248 essiv_ivgen_dtor(struct target_crypt_config *priv, void *arg)
250 struct essiv_ivgen_priv *ivpriv;
252 ivpriv = (struct essiv_ivgen_priv *)arg;
253 KKASSERT(ivpriv != NULL);
255 crypto_freesession(ivpriv->crypto_sid);
257 objcache_destroy(ivpriv->crp_crd_cache);
259 dmtc_crypto_clear(ivpriv->crypto_keyhash, ivpriv->keyhash_len);
260 kfree(ivpriv, M_DMCRYPT);
266 essiv_ivgen_done(struct cryptop *crp)
268 struct essiv_ivgen_priv *ivpriv;
272 if (crp->crp_etype == EAGAIN)
273 return crypto_dispatch(crp);
275 if (crp->crp_etype != 0) {
276 kprintf("dm_target_crypt: essiv_ivgen_done, "
277 "crp->crp_etype = %d\n", crp->crp_etype);
280 free_addr = crp->crp_opaque;
282 * In-memory structure is:
283 * | ivpriv | opaque | crp | crd |
284 * | (void *) | (void *) | (cryptop) | (cryptodesc) |
286 ivpriv = *((struct essiv_ivgen_priv **)crp->crp_opaque);
287 crp->crp_opaque += sizeof(void *);
288 opaque = *((void **)crp->crp_opaque);
290 objcache_put(ivpriv->crp_crd_cache, free_addr);
291 dmtc_crypto_dispatch(opaque);
296 essiv_ivgen(dm_target_crypt_config_t *priv, u_int8_t *iv,
297 size_t iv_len, off_t sector, void *opaque)
299 struct essiv_ivgen_priv *ivpriv;
300 struct cryptodesc *crd;
302 caddr_t space, alloc_addr;
305 ivpriv = priv->ivgen_priv;
306 KKASSERT(ivpriv != NULL);
309 * In-memory structure is:
310 * | ivpriv | opaque | crp | crd |
311 * | (void *) | (void *) | (cryptop) | (cryptodesc) |
313 alloc_addr = space = objcache_get(ivpriv->crp_crd_cache, M_WAITOK);
314 *((struct essiv_ivgen_priv **)space) = ivpriv;
315 space += sizeof(void *);
316 *((void **)space) = opaque;
317 space += sizeof(void *);
318 crp = (struct cryptop *)space;
319 space += sizeof(struct cryptop);
320 crd = (struct cryptodesc *)space;
323 bzero(crd, sizeof(struct cryptodesc));
324 bzero(crp, sizeof(struct cryptop));
325 *((off_t *)iv) = htole64(sector + priv->iv_offset);
326 crp->crp_buf = (caddr_t)iv;
328 crp->crp_sid = ivpriv->crypto_sid;
329 crp->crp_ilen = crp->crp_olen = iv_len;
331 crp->crp_opaque = alloc_addr;
333 crp->crp_callback = essiv_ivgen_done;
337 crp->crp_flags = CRYPTO_F_CBIFSYNC | CRYPTO_F_REL | CRYPTO_F_BATCH;
339 crd->crd_alg = priv->crypto_alg;
341 crd->crd_key = (caddr_t)priv->crypto_keyhash;
342 crd->crd_klen = priv->crypto_klen;
345 bzero(crd->crd_iv, sizeof(crd->crd_iv));
348 crd->crd_len = iv_len;
349 crd->crd_flags = CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
350 crd->crd_flags |= CRD_F_ENCRYPT;
351 crd->crd_next = NULL;
353 error = crypto_dispatch(crp);
355 kprintf("dm_target_crypt: essiv_ivgen, error = %d\n", error);
360 plain_ivgen(dm_target_crypt_config_t *priv, u_int8_t *iv,
361 size_t iv_len, off_t sector, void *opaque)
364 *((uint32_t *)iv) = htole32((uint32_t)(sector + priv->iv_offset));
365 dmtc_crypto_dispatch(opaque);
371 geli_ivgen(dm_target_crypt_config_t *priv, u_int8_t *iv,
372 size_t iv_len, off_t sector, void *opaque)
376 u_int8_t md[SHA512_DIGEST_LENGTH]; /* Max. Digest Size */
378 memcpy(&ctx512, &priv->essivsha512_ctx, sizeof(SHA512_CTX));
379 SHA512_Update(&ctx512, (u_int8_t*)§or, sizeof(off_t));
380 SHA512_Final(md, &ctx512);
382 memcpy(iv, md, iv_len);
383 dmtc_crypto_dispatch(opaque);
387 #ifdef DM_TARGET_MODULE
389 * Every target can be compiled directly to dm driver or as a
390 * separate module this part of target is used for loading targets
392 * Target can be unloaded from kernel only if there are no users of
393 * it e.g. there are no devices which uses that target.
395 #include <sys/kernel.h>
396 #include <sys/module.h>
399 dm_target_crypt_modcmd(modcmd_t cmd, void *arg)
406 case MODULE_CMD_INIT:
407 if ((dmt = dm_target_lookup("crypt")) != NULL) {
408 dm_target_unbusy(dmt);
411 dmt = dm_target_alloc("crypt");
416 strlcpy(dmt->name, "crypt", DM_MAX_TYPE_NAME);
417 dmt->init = &dm_target_crypt_init;
418 dmt->status = &dm_target_crypt_status;
419 dmt->strategy = &dm_target_crypt_strategy;
420 dmt->deps = &dm_target_crypt_deps;
421 dmt->destroy = &dm_target_crypt_destroy;
422 dmt->upcall = &dm_target_crypt_upcall;
424 r = dm_target_insert(dmt);
428 case MODULE_CMD_FINI:
429 r = dm_target_rem("crypt");
432 case MODULE_CMD_STAT:
445 * Init function called from dm_table_load_ioctl.
446 * cryptsetup actually passes us this:
447 * aes-cbc-essiv:sha256 7997f8af... 0 /dev/ad0s0a 8
450 hex2key(char *hex, size_t key_len, u_int8_t *key)
456 for (key_idx = 0; key_idx < key_len; ++key_idx) {
459 key[key_idx] = (u_int8_t)strtoul(hex_buf, NULL, 16);
468 dm_target_crypt_init(dm_dev_t * dmv, void **target_config, char *params)
470 dm_target_crypt_config_t *priv;
473 char *crypto_alg, *crypto_mode, *iv_mode, *iv_opt, *key, *dev;
475 int i, argc, klen, error;
476 uint64_t iv_offset, block_offset;
481 len = strlen(params) + 1;
484 status_str = kstrdup(params, M_DMCRYPT);
486 * Parse a string, containing tokens delimited by white space,
487 * into an argument vector
489 for (ap = args; ap < &args[5] &&
490 (*ap = strsep(¶ms, " \t")) != NULL;) {
498 kprintf("dm_target_crypt: not enough arguments, "
500 kfree(status_str, M_DMCRYPT);
501 return ENOMEM; /* XXX */
504 crypto_alg = strsep(&args[0], "-");
505 crypto_mode = strsep(&args[0], "-");
506 iv_opt = strsep(&args[0], "-");
507 iv_mode = strsep(&iv_opt, ":");
509 iv_offset = strtouq(args[2], NULL, 0);
511 block_offset = strtouq(args[4], NULL, 0);
512 /* bits / 8 = bytes, 1 byte = 2 hexa chars, so << 2 */
513 klen = strlen(key) << 2;
515 kprintf("dm_target_crypt - new: dev=%s, crypto_alg=%s, crypto_mode=%s, "
516 "iv_mode=%s, iv_opt=%s, key=%s, iv_offset=%ju, "
517 "block_offset=%ju\n",
518 dev, crypto_alg, crypto_mode, iv_mode, iv_opt, key, iv_offset,
521 priv = kmalloc(sizeof(dm_target_crypt_config_t), M_DMCRYPT, M_WAITOK);
523 kprintf("dm_target_crypt: could not allocate memory\n");
524 kfree(status_str, M_DMCRYPT);
528 /* Insert dmp to global pdev list */
529 if ((priv->pdev = dm_pdev_insert(dev)) == NULL) {
530 kprintf("dm_target_crypt: dm_pdev_insert failed\n");
531 kfree(status_str, M_DMCRYPT);
535 if ((strcmp(crypto_mode, "cbc") != 0) &&
536 !((strcmp(crypto_mode, "xts") == 0) && (strcmp(crypto_alg, "aes") == 0)))
538 kprintf("dm_target_crypt: only support 'cbc' chaining mode"
539 " and aes-xts, invalid mode '%s-%s'\n",
540 crypto_alg, crypto_mode);
544 if (!strcmp(crypto_alg, "aes")) {
545 if (!strcmp(crypto_mode, "xts")) {
546 priv->crypto_alg = CRYPTO_AES_XTS;
547 if (klen != 256 && klen != 512)
549 } else if (!strcmp(crypto_mode, "cbc")) {
550 priv->crypto_alg = CRYPTO_AES_CBC;
551 if (klen != 128 && klen != 192 && klen != 256)
556 priv->crypto_klen = klen;
557 } else if (!strcmp(crypto_alg, "blowfish")) {
558 priv->crypto_alg = CRYPTO_BLF_CBC;
559 if (klen < 128 || klen > 448 || (klen % 8) != 0)
561 priv->crypto_klen = klen;
562 } else if (!strcmp(crypto_alg, "3des") ||
563 !strncmp(crypto_alg, "des3", 4)) {
564 priv->crypto_alg = CRYPTO_3DES_CBC;
567 priv->crypto_klen = 168;
568 } else if (!strcmp(crypto_alg, "camellia")) {
569 priv->crypto_alg = CRYPTO_CAMELLIA_CBC;
570 if (klen != 128 && klen != 192 && klen != 256)
572 priv->crypto_klen = klen;
573 } else if (!strcmp(crypto_alg, "skipjack")) {
574 priv->crypto_alg = CRYPTO_SKIPJACK_CBC;
577 priv->crypto_klen = 80;
578 } else if (!strcmp(crypto_alg, "cast5")) {
579 priv->crypto_alg = CRYPTO_CAST_CBC;
582 priv->crypto_klen = 128;
583 } else if (!strcmp(crypto_alg, "null")) {
584 priv->crypto_alg = CRYPTO_NULL_CBC;
587 priv->crypto_klen = 128;
589 kprintf("dm_target_crypt: Unsupported crypto algorithm: %s\n",
594 /* Save length of param string */
595 priv->params_len = len;
596 priv->block_offset = block_offset;
597 priv->iv_offset = iv_offset - block_offset;
599 *target_config = priv;
601 dmv->dev_type = DM_CRYPTO_DEV;
603 error = hex2key(key, priv->crypto_klen >> 3,
604 (u_int8_t *)priv->crypto_key);
607 kprintf("dm_target_crypt: hex2key failed, "
608 "invalid key format\n");
613 for(i = 0; ivgens[i].name != NULL; i++) {
614 if (!strcmp(iv_mode, ivgens[i].name))
618 if (ivgens[i].name == NULL) {
619 kprintf("dm_target_crypt: iv_mode='%s' unsupported\n",
624 /* Call our ivgen constructor */
625 if (ivgens[i].ctor != NULL) {
626 error = ivgens[i].ctor(priv, iv_opt,
629 kprintf("dm_target_crypt: ctor for '%s' failed\n",
635 priv->ivgen = &ivgens[i];
637 priv->crypto_session.cri_alg = priv->crypto_alg;
638 priv->crypto_session.cri_key = (u_int8_t *)priv->crypto_key;
639 priv->crypto_session.cri_klen = priv->crypto_klen;
640 priv->crypto_session.cri_mlen = 0;
641 priv->crypto_session.cri_next = NULL;
643 error = crypto_newsession(&priv->crypto_sid,
644 &priv->crypto_session,
645 CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE);
647 kprintf("dm_target_crypt: Error during crypto_newsession, "
653 priv->status_str = status_str;
657 kprintf("dm_target_crypt: ENOTSUP\n");
658 kfree(status_str, M_DMCRYPT);
662 /* Status routine called to get params string. */
664 dm_target_crypt_status(void *target_config)
666 dm_target_crypt_config_t *priv;
669 priv = target_config;
671 /* caller expects use of M_DM */
672 params = kmalloc(DM_MAX_PARAMS_SIZE, M_DM, M_WAITOK);
674 ksnprintf(params, DM_MAX_PARAMS_SIZE, "%s",
681 dm_target_crypt_destroy(dm_table_entry_t * table_en)
683 dm_target_crypt_config_t *priv;
686 * Disconnect the crypt config before unbusying the target.
688 priv = table_en->target_config;
691 table_en->target_config = NULL;
692 dm_pdev_decr(priv->pdev);
694 dm_target_unbusy(table_en->target);
697 * Clean up the crypt config
699 * Overwrite the private information before freeing memory to
702 if (priv->status_str) {
703 dmtc_crypto_clear(priv->status_str, strlen(priv->status_str));
704 kfree(priv->status_str, M_DMCRYPT);
705 crypto_freesession(priv->crypto_sid);
708 if ((priv->ivgen) && (priv->ivgen->dtor != NULL)) {
709 priv->ivgen->dtor(priv, priv->ivgen_priv);
712 dmtc_crypto_clear(priv, sizeof(dm_target_crypt_config_t));
713 kfree(priv, M_DMCRYPT);
719 dm_target_crypt_deps(dm_table_entry_t * table_en, prop_array_t prop_array)
721 dm_target_crypt_config_t *priv;
726 if (table_en->target_config == NULL)
729 priv = table_en->target_config;
731 if ((error = VOP_GETATTR(priv->pdev->pdev_vnode, &va)) != 0)
734 prop_array_add_uint64(prop_array,
735 (uint64_t)makeudev(va.va_rmajor, va.va_rminor));
740 /* Unsupported for this target. */
742 dm_target_crypt_upcall(dm_table_entry_t * table_en, struct buf * bp)
747 /************************************************************************
748 * STRATEGY SUPPORT FUNCTIONS *
749 ************************************************************************
751 * READ PATH: doio -> bio_read_done -> crypto_work -> crypto_cb_read_done
752 * WRITE PATH: crypto_work -> crypto_cb_write_done -> doio -> bio_write_done
756 * Wrapper around crypto_dispatch() to match dispatch_t type
759 dmtc_crypto_dispatch(void *arg)
763 crp = (struct cryptop *)arg;
764 KKASSERT(crp != NULL);
765 crypto_dispatch(crp);
769 * Start IO operation, called from dmstrategy routine.
772 dm_target_crypt_strategy(dm_table_entry_t *table_en, struct buf *bp)
776 dm_target_crypt_config_t *priv;
777 priv = table_en->target_config;
779 /* Get rid of stuff we can't really handle */
780 if ((bp->b_cmd == BUF_CMD_READ) || (bp->b_cmd == BUF_CMD_WRITE)) {
781 if (((bp->b_bcount % DEV_BSIZE) != 0) || (bp->b_bcount == 0)) {
782 kprintf("dm_target_crypt_strategy: can't really "
783 "handle bp->b_bcount = %d\n",
785 bp->b_error = EINVAL;
786 bp->b_flags |= B_ERROR | B_INVAL;
787 biodone(&bp->b_bio1);
794 bio = push_bio(&bp->b_bio1);
795 bio->bio_offset = bp->b_bio1.bio_offset +
796 priv->block_offset * DEV_BSIZE;
797 bio->bio_caller_info1.ptr = priv;
798 bio->bio_done = dmtc_bio_read_done;
799 vn_strategy(priv->pdev->pdev_vnode, bio);
802 bio = push_bio(&bp->b_bio1);
803 bio->bio_offset = bp->b_bio1.bio_offset +
804 priv->block_offset * DEV_BSIZE;
805 bio->bio_caller_info1.ptr = priv;
806 dmtc_crypto_write_start(priv, bio);
809 vn_strategy(priv->pdev->pdev_vnode, &bp->b_bio1);
816 * STRATEGY READ PATH PART 1/3 (after read BIO completes)
819 dmtc_bio_read_done(struct bio *bio)
823 dm_target_crypt_config_t *priv;
826 * If a read error occurs we shortcut the operation, otherwise
829 if (bio->bio_buf->b_flags & B_ERROR) {
833 priv = bio->bio_caller_info1.ptr;
834 dmtc_crypto_read_start(priv, bio);
839 * STRATEGY READ PATH PART 2/3
842 dmtc_crypto_read_start(dm_target_crypt_config_t *priv, struct bio *bio)
844 struct dmtc_helper *dmtc;
845 struct cryptodesc *crd;
847 struct cryptoini *cri;
848 int i, bytes, sectors, sz;
852 cri = &priv->crypto_session;
855 * Note: b_resid no good after read I/O, it will be 0, use
858 bytes = bio->bio_buf->b_bcount;
859 isector = bio->bio_offset / DEV_BSIZE; /* ivgen salt base? */
860 sectors = bytes / DEV_BSIZE; /* Number of sectors */
861 sz = sectors * (sizeof(*crp) + sizeof(*crd));
864 * For reads with bogus page we can't decrypt in place as stuff
865 * can get ripped out from under us.
867 * XXX actually it looks like we can, and in any case the initial
868 * read already completed and threw crypted data into the buffer
869 * cache buffer. Disable for now.
872 if (bio->bio_buf->b_flags & B_HASBOGUS) {
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 dmtc->orig_buf = NULL;
879 dmtc->data_buf = space + sz;
880 memcpy(dmtc->data_buf, bio->bio_buf->b_data, bytes);
884 space = kmalloc(sizeof(struct dmtc_helper) + sz,
885 M_DMCRYPT, M_WAITOK);
886 dmtc = (struct dmtc_helper *)space;
887 dmtc->free_addr = space;
888 space += sizeof(struct dmtc_helper);
889 dmtc->orig_buf = NULL;
890 dmtc->data_buf = bio->bio_buf->b_data;
892 bio->bio_caller_info2.ptr = dmtc;
893 bio->bio_buf->b_error = 0;
896 * Load crypto descriptors (crp/crd loop)
900 bio->bio_caller_info3.value = sectors;
903 kprintf("Read, bytes = %d (b_bcount), "
904 "sectors = %d (bio = %p, b_cmd = %d)\n",
905 bytes, sectors, bio, bio->bio_buf->b_cmd);
907 for (i = 0; i < sectors; i++) {
908 crp = (struct cryptop *)ptr;
910 crd = (struct cryptodesc *)ptr;
911 ptr += sizeof (*crd);
913 crp->crp_buf = dmtc->data_buf + i * DEV_BSIZE;
915 crp->crp_sid = priv->crypto_sid;
916 crp->crp_ilen = crp->crp_olen = DEV_BSIZE;
918 crp->crp_opaque = (void *)bio;
920 crp->crp_callback = dmtc_crypto_cb_read_done;
923 crp->crp_flags = CRYPTO_F_CBIFSYNC | CRYPTO_F_REL |
926 crd->crd_alg = priv->crypto_alg;
928 crd->crd_key = (caddr_t)priv->crypto_key;
929 crd->crd_klen = priv->crypto_klen;
933 crd->crd_len = DEV_BSIZE /* XXX */;
934 crd->crd_flags = CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
935 crd->crd_next = NULL;
937 crd->crd_flags &= ~CRD_F_ENCRYPT;
940 * Note: last argument is used to generate salt(?) and is
941 * a 64 bit value, but the original code passed an
942 * int. Changing it now will break pre-existing
945 priv->ivgen->gen_iv(priv, crd->crd_iv, sizeof(crd->crd_iv),
951 * STRATEGY READ PATH PART 3/3
954 dmtc_crypto_cb_read_done(struct cryptop *crp)
956 struct dmtc_helper *dmtc;
957 struct bio *bio, *obio;
960 if (crp->crp_etype == EAGAIN)
961 return crypto_dispatch(crp);
963 bio = (struct bio *)crp->crp_opaque;
964 KKASSERT(bio != NULL);
969 if (crp->crp_etype) {
970 kprintf("dm_target_crypt: dmtc_crypto_cb_read_done "
973 bio->bio_buf->b_error = crp->crp_etype;
977 * On the last chunk of the decryption we do any required copybacks
978 * and complete the I/O.
980 n = atomic_fetchadd_int(&bio->bio_caller_info3.value, -1);
982 kprintf("dmtc_crypto_cb_read_done %p, n = %d\n", bio, n);
987 * For the B_HASBOGUS case we didn't decrypt in place,
988 * so we need to copy stuff back into the buf.
990 * (disabled for now).
992 dmtc = bio->bio_caller_info2.ptr;
993 if (bio->bio_buf->b_error) {
994 bio->bio_buf->b_flags |= B_ERROR;
997 else if (bio->bio_buf->b_flags & B_HASBOGUS) {
998 memcpy(bio->bio_buf->b_data, dmtc->data_buf,
999 bio->bio_buf->b_bcount);
1002 kfree(dmtc->free_addr, M_DMCRYPT);
1003 obio = pop_bio(bio);
1008 /* END OF STRATEGY READ SECTION */
1011 * STRATEGY WRITE PATH PART 1/3
1014 dmtc_crypto_write_start(dm_target_crypt_config_t *priv, struct bio *bio)
1016 struct dmtc_helper *dmtc;
1017 struct cryptodesc *crd;
1018 struct cryptop *crp;
1019 struct cryptoini *cri;
1020 int i, bytes, sectors, sz;
1022 u_char *ptr, *space;
1024 cri = &priv->crypto_session;
1027 * Use b_bcount for consistency
1029 bytes = bio->bio_buf->b_bcount;
1031 isector = bio->bio_offset / DEV_BSIZE; /* ivgen salt base? */
1032 sectors = bytes / DEV_BSIZE; /* Number of sectors */
1033 sz = sectors * (sizeof(*crp) + sizeof(*crd));
1036 * For writes and reads with bogus page don't decrypt in place.
1038 space = kmalloc(sizeof(struct dmtc_helper) + sz + bytes,
1039 M_DMCRYPT, M_WAITOK);
1040 dmtc = (struct dmtc_helper *)space;
1041 dmtc->free_addr = space;
1042 space += sizeof(struct dmtc_helper);
1043 memcpy(space + sz, bio->bio_buf->b_data, bytes);
1045 bio->bio_caller_info2.ptr = dmtc;
1046 bio->bio_buf->b_error = 0;
1048 dmtc->orig_buf = bio->bio_buf->b_data;
1049 dmtc->data_buf = space + sz;
1052 * Load crypto descriptors (crp/crd loop)
1056 bio->bio_caller_info3.value = sectors;
1059 kprintf("Write, bytes = %d (b_bcount), "
1060 "sectors = %d (bio = %p, b_cmd = %d)\n",
1061 bytes, sectors, bio, bio->bio_buf->b_cmd);
1063 for (i = 0; i < sectors; i++) {
1064 crp = (struct cryptop *)ptr;
1065 ptr += sizeof(*crp);
1066 crd = (struct cryptodesc *)ptr;
1067 ptr += sizeof (*crd);
1069 crp->crp_buf = dmtc->data_buf + i * DEV_BSIZE;
1071 crp->crp_sid = priv->crypto_sid;
1072 crp->crp_ilen = crp->crp_olen = DEV_BSIZE;
1074 crp->crp_opaque = (void *)bio;
1076 crp->crp_callback = dmtc_crypto_cb_write_done;
1077 crp->crp_desc = crd;
1079 crp->crp_flags = CRYPTO_F_CBIFSYNC | CRYPTO_F_REL |
1082 crd->crd_alg = priv->crypto_alg;
1084 crd->crd_key = (caddr_t)priv->crypto_key;
1085 crd->crd_klen = priv->crypto_klen;
1089 crd->crd_len = DEV_BSIZE /* XXX */;
1090 crd->crd_flags = CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
1091 crd->crd_next = NULL;
1093 crd->crd_flags |= CRD_F_ENCRYPT;
1096 * Note: last argument is used to generate salt(?) and is
1097 * a 64 bit value, but the original code passed an
1098 * int. Changing it now will break pre-existing
1101 priv->ivgen->gen_iv(priv, crd->crd_iv, sizeof(crd->crd_iv),
1107 * STRATEGY WRITE PATH PART 2/3
1110 dmtc_crypto_cb_write_done(struct cryptop *crp)
1112 struct dmtc_helper *dmtc;
1113 dm_target_crypt_config_t *priv;
1114 struct bio *bio, *obio;
1117 if (crp->crp_etype == EAGAIN)
1118 return crypto_dispatch(crp);
1120 bio = (struct bio *)crp->crp_opaque;
1121 KKASSERT(bio != NULL);
1126 if (crp->crp_etype != 0) {
1127 kprintf("dm_target_crypt: dmtc_crypto_cb_write_done "
1130 bio->bio_buf->b_error = crp->crp_etype;
1134 * On the last chunk of the encryption we issue the write
1136 n = atomic_fetchadd_int(&bio->bio_caller_info3.value, -1);
1138 kprintf("dmtc_crypto_cb_write_done %p, n = %d\n", bio, n);
1142 dmtc = bio->bio_caller_info2.ptr;
1143 priv = (dm_target_crypt_config_t *)bio->bio_caller_info1.ptr;
1145 if (bio->bio_buf->b_error) {
1146 bio->bio_buf->b_flags |= B_ERROR;
1147 kfree(dmtc->free_addr, M_DMCRYPT);
1148 obio = pop_bio(bio);
1151 dmtc->orig_buf = bio->bio_buf->b_data;
1152 bio->bio_buf->b_data = dmtc->data_buf;
1153 bio->bio_done = dmtc_bio_write_done;
1154 vn_strategy(priv->pdev->pdev_vnode, bio);
1161 * STRATEGY WRITE PATH PART 3/3
1164 dmtc_bio_write_done(struct bio *bio)
1166 struct dmtc_helper *dmtc;
1169 dmtc = bio->bio_caller_info2.ptr;
1170 bio->bio_buf->b_data = dmtc->orig_buf;
1171 kfree(dmtc->free_addr, M_DMCRYPT);
1172 obio = pop_bio(bio);
1175 /* END OF STRATEGY WRITE SECTION */