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>
43 #include <sys/malloc.h>
44 #include <sys/vnode.h>
45 #include <crypto/sha1.h>
46 #include <crypto/sha2/sha2.h>
47 #include <opencrypto/cryptodev.h>
50 MALLOC_DEFINE(M_DMCRYPT, "dm_crypt", "Device Mapper Target Crypt");
53 * HMAC-SHA-224/256/384/512 implementation
54 * Last update: 06/15/2005
55 * Issue date: 06/15/2005
57 * Copyright (C) 2005 Olivier Gay <olivier.gay@a3.epfl.ch>
58 * All rights reserved.
60 * Redistribution and use in source and binary forms, with or without
61 * modification, are permitted provided that the following conditions
63 * 1. Redistributions of source code must retain the above copyright
64 * notice, this list of conditions and the following disclaimer.
65 * 2. Redistributions in binary form must reproduce the above copyright
66 * notice, this list of conditions and the following disclaimer in the
67 * documentation and/or other materials provided with the distribution.
68 * 3. Neither the name of the project nor the names of its contributors
69 * may be used to endorse or promote products derived from this software
70 * without specific prior written permission.
72 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
73 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
74 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
75 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
76 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
77 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
78 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
79 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
80 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
81 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
86 SHA512_CTX ctx_inside;
87 SHA512_CTX ctx_outside;
90 SHA512_CTX ctx_inside_reinit;
91 SHA512_CTX ctx_outside_reinit;
93 unsigned char block_ipad[SHA512_BLOCK_LENGTH];
94 unsigned char block_opad[SHA512_BLOCK_LENGTH];
97 /* HMAC-SHA-512 functions */
99 hmac_sha512_init(hmac_sha512_ctx *ctx, unsigned char *key,
100 unsigned int key_size)
105 unsigned char *key_used;
106 unsigned char key_temp[SHA512_DIGEST_LENGTH];
109 if (key_size == SHA512_BLOCK_LENGTH) {
111 num = SHA512_BLOCK_LENGTH;
113 if (key_size > SHA512_BLOCK_LENGTH){
115 num = SHA512_DIGEST_LENGTH;
116 SHA512_Data(key, key_size, key_used);
117 } else { /* key_size > SHA512_BLOCK_LENGTH */
121 fill = SHA512_BLOCK_LENGTH - num;
123 memset(ctx->block_ipad + num, 0x36, fill);
124 memset(ctx->block_opad + num, 0x5c, fill);
127 for (i = 0; i < num; i++) {
128 ctx->block_ipad[i] = key_used[i] ^ 0x36;
129 ctx->block_opad[i] = key_used[i] ^ 0x5c;
132 SHA512_Init(&ctx->ctx_inside);
133 SHA512_Update(&ctx->ctx_inside, ctx->block_ipad, SHA512_BLOCK_LENGTH);
135 SHA512_Init(&ctx->ctx_outside);
136 SHA512_Update(&ctx->ctx_outside, ctx->block_opad,
137 SHA512_BLOCK_LENGTH);
139 /* for hmac_reinit */
140 memcpy(&ctx->ctx_inside_reinit, &ctx->ctx_inside,
142 memcpy(&ctx->ctx_outside_reinit, &ctx->ctx_outside,
148 hmac_sha512_reinit(hmac_sha512_ctx *ctx)
150 memcpy(&ctx->ctx_inside, &ctx->ctx_inside_reinit,
152 memcpy(&ctx->ctx_outside, &ctx->ctx_outside_reinit,
158 hmac_sha512_update(hmac_sha512_ctx *ctx, unsigned char *message,
159 unsigned int message_len)
161 SHA512_Update(&ctx->ctx_inside, message, message_len);
165 hmac_sha512_final(hmac_sha512_ctx *ctx, unsigned char *mac,
166 unsigned int mac_size)
168 unsigned char digest_inside[SHA512_DIGEST_LENGTH];
169 unsigned char mac_temp[SHA512_DIGEST_LENGTH];
171 SHA512_Final(digest_inside, &ctx->ctx_inside);
172 SHA512_Update(&ctx->ctx_outside, digest_inside, SHA512_DIGEST_LENGTH);
173 SHA512_Final(mac_temp, &ctx->ctx_outside);
174 memcpy(mac, mac_temp, mac_size);
178 hmac_sha512(unsigned char *key, unsigned int key_size,
179 unsigned char *message, unsigned int message_len,
180 unsigned char *mac, unsigned mac_size)
184 hmac_sha512_init(&ctx, key, key_size);
185 hmac_sha512_update(&ctx, message, message_len);
186 hmac_sha512_final(&ctx, mac, mac_size);
190 * pkcs5_pbkdf2 function
191 * Copyright (c) 2008 Damien Bergamini <damien.bergamini@free.fr>
193 * Permission to use, copy, modify, and distribute this software for any
194 * purpose with or without fee is hereby granted, provided that the above
195 * copyright notice and this permission notice appear in all copies.
197 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
198 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
199 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
200 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
201 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
202 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
203 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
207 * Password-Based Key Derivation Function 2 (PKCS #5 v2.0).
208 * Code based on IEEE Std 802.11-2007, Annex H.4.2.
211 pkcs5_pbkdf2(const char *pass, size_t pass_len, const char *salt, size_t salt_len,
212 u_int8_t *key, size_t key_len, u_int rounds)
214 u_int8_t *asalt, obuf[SHA512_DIGEST_LENGTH];
215 u_int8_t d1[SHA512_DIGEST_LENGTH], d2[SHA512_DIGEST_LENGTH];
220 if (rounds < 1 || key_len == 0)
222 if (salt_len == 0 || salt_len > SIZE_MAX - 1)
224 if ((asalt = kmalloc(salt_len + 4, M_TEMP, M_WAITOK)) == NULL)
225 return -1; /* XXX: this is not possible */
227 memcpy(asalt, salt, salt_len);
229 for (count = 1; key_len > 0; count++) {
230 asalt[salt_len + 0] = (count >> 24) & 0xff;
231 asalt[salt_len + 1] = (count >> 16) & 0xff;
232 asalt[salt_len + 2] = (count >> 8) & 0xff;
233 asalt[salt_len + 3] = count & 0xff;
234 hmac_sha512(__DECONST(char *, pass), pass_len, asalt, salt_len + 4, d1, sizeof(d1));
235 memcpy(obuf, d1, sizeof(obuf));
237 for (i = 1; i < rounds; i++) {
238 hmac_sha512(__DECONST(char *, pass), pass_len, d1, sizeof(d1), d2, sizeof(d2));
239 memcpy(d1, d2, sizeof(d1));
240 for (j = 0; j < sizeof(obuf); j++)
244 r = MIN(key_len, SHA512_DIGEST_LENGTH);
245 memcpy(key, obuf, r);
249 bzero(asalt, salt_len + 4);
250 kfree(asalt, M_TEMP);
251 bzero(d1, sizeof(d1));
252 bzero(d2, sizeof(d2));
253 bzero(obuf, sizeof(obuf));
259 /* ---------------------------------------------------------------------- */
261 struct target_crypt_config;
262 typedef void ivgen_t(struct target_crypt_config *, u_int8_t *, size_t, off_t);
264 typedef struct target_crypt_config {
269 u_int8_t crypto_key[512>>3];
270 u_int8_t crypto_keyhash[SHA512_DIGEST_LENGTH];
271 u_int64_t crypto_sid;
272 SHA512_CTX essivsha512_ctx;
273 struct cryptoini crypto_session;
274 ivgen_t *crypto_ivgen;
276 } dm_target_crypt_config_t;
278 static void dm_target_crypt_work(dm_target_crypt_config_t *priv, struct bio *bio);
279 static void dm_target_crypt_read_done(struct bio *bio);
280 static void dm_target_crypt_write_done(struct bio *bio);
281 static int dm_target_crypt_crypto_done_read(struct cryptop *crp);
282 static int dm_target_crypt_crypto_done_write(struct cryptop *crp);
286 essiv_hash_mkey(dm_target_crypt_config_t *priv)
293 if (priv->crypto_klen <= 128) {
295 SHA1Update(&ctxsha1, priv->crypto_key, priv->crypto_klen>>3);
296 SHA1Final(priv->crypto_keyhash, &ctxsha1);
297 } else if (priv->crypto_klen <= 256) {
298 SHA256_Init(&ctx256);
299 SHA256_Update(&ctx256, priv->crypto_key, priv->crypto_klen>>3);
300 SHA256_Final(priv->crypto_keyhash, &ctx256);
301 } else if (priv->crypto_klen <= 384) {
302 SHA384_Init(&ctx384);
303 SHA384_Update(&ctx384, priv->crypto_key, priv->crypto_klen>>3);
304 SHA384_Final(priv->crypto_keyhash, &ctx384);
305 } else if (priv->crypto_klen <= 512) {
306 SHA512_Init(&ctx512);
307 SHA512_Update(&ctx512, priv->crypto_key, priv->crypto_klen>>3);
308 SHA512_Final(priv->crypto_keyhash, &ctx512);
310 panic("Unexpected crypto_klen = %d", priv->crypto_klen);
315 essiv_ivgen_done(struct cryptop *crp)
318 if (crp->crp_etype == EAGAIN)
319 return crypto_dispatch(crp);
321 if (crp->crp_etype != 0) {
322 kprintf("essiv_ivgen_done, crp->crp_etype = %d\n", crp->crp_etype);
325 atomic_add_int((int *)crp->crp_opaque, 1);
326 wakeup(crp->crp_opaque);
331 essiv_ivgen(dm_target_crypt_config_t *priv, u_int8_t *iv, size_t iv_len, off_t sector)
333 struct cryptodesc crd;
339 *((off_t *)iv) = sector;
340 crp.crp_buf = (caddr_t)iv;
342 crp.crp_sid = priv->crypto_sid;
343 crp.crp_ilen = crp.crp_olen = iv_len;
345 crp.crp_opaque = (void *)&id;
347 crp.crp_callback = essiv_ivgen_done;
351 crp.crp_flags = CRYPTO_F_CBIFSYNC | CRYPTO_F_REL;
353 crd.crd_alg = priv->crypto_alg;
354 crd.crd_key = (caddr_t)priv->crypto_keyhash;
355 crd.crd_klen = priv->crypto_klen;
357 bzero(crd.crd_iv, sizeof(crd.crd_iv));
360 crd.crd_len = iv_len;
361 crd.crd_flags = CRD_F_KEY_EXPLICIT | CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
362 crd.crd_flags |= CRD_F_ENCRYPT;
365 error = crypto_dispatch(&crp);
367 kprintf("essiv_ivgen, error = %d\n", error);
370 * id is modified in the callback, so that if crypto_dispatch finishes
371 * synchronously we don't tsleep() forever.
374 tsleep((void *)&error, 0, "essivgen", 0);
379 alt_ivgen(dm_target_crypt_config_t *priv, u_int8_t *iv, size_t iv_len, off_t sector)
383 u_int8_t md[SHA512_DIGEST_LENGTH]; /* Max. Digest Size */
385 memcpy(&ctx512, &priv->essivsha512_ctx, sizeof(SHA512_CTX));
386 SHA512_Update(&ctx512, (u_int8_t*)§or, sizeof(off_t));
387 SHA512_Final(md, &ctx512);
389 memcpy(iv, md, iv_len);
398 dm_target_crypt_work(dm_target_crypt_config_t *priv, struct bio *bio)
400 struct dmtc_helper *dmtc;
401 struct cryptodesc *crd;
403 struct cryptoini *cri;
405 int error, i, bytes, isector, sectors, write, sz;
406 u_char *ptr, *space, *data;
408 cri = &priv->crypto_session;
410 write = (bio->bio_buf->b_cmd == BUF_CMD_WRITE) ? 1 : 0;
411 bytes = bio->bio_buf->b_bcount; /* XXX: b_resid no good after reads... == 0 */
412 isector = bio->bio_offset/DEV_BSIZE; /* Initial sector */
413 sectors = bytes/DEV_BSIZE; /* Number of sectors affected by bio */
414 sz = sectors * (sizeof(*crp) + sizeof(*crd));
417 space = kmalloc(sizeof(struct dmtc_helper) + sz + bytes, M_DMCRYPT, M_WAITOK);
418 dmtc = (struct dmtc_helper *)space;
419 dmtc->free_addr = space;
420 dmtc->orig_buf = bio->bio_buf->b_data;
421 space += sizeof(struct dmtc_helper);
422 memcpy(space + sz, bio->bio_buf->b_data, bytes);
423 bio->bio_caller_info2.ptr = dmtc;
424 bio->bio_buf->b_data = data = space + sz;
426 space = kmalloc(sz, M_DMCRYPT, M_WAITOK);
427 data = bio->bio_buf->b_data;
428 bio->bio_caller_info2.ptr = space;
432 bio->bio_caller_info3.value = sectors;
433 kprintf("Write? %d, bytes = %d (b_bcount), sectors = %d (bio = %p, b_cmd = %d)\n", write, bytes, sectors, bio, bio->bio_buf->b_cmd);
435 for (i = 0; i < sectors; i++) {
436 crp = (struct cryptop *)ptr;
438 crd = (struct cryptodesc *)ptr;
439 ptr += sizeof (*crd);
441 crp->crp_buf = (data + i*DEV_BSIZE);
443 crp->crp_sid = priv->crypto_sid;
444 crp->crp_ilen = crp->crp_olen = DEV_BSIZE;
446 crp->crp_opaque = (void *)bio;
449 crp->crp_callback = dm_target_crypt_crypto_done_write;
451 crp->crp_callback = dm_target_crypt_crypto_done_read;
454 crp->crp_flags = CRYPTO_F_CBIFSYNC | CRYPTO_F_REL;
456 crd->crd_alg = priv->crypto_alg;
457 crd->crd_key = (caddr_t)priv->crypto_key;
458 crd->crd_klen = priv->crypto_klen;
460 bzero(crd->crd_iv, EALG_MAX_BLOCK_LEN);
461 alt_ivgen(priv, crd->crd_iv, sizeof(crd->crd_iv), isector + i);
462 essiv_ivgen(priv, crd->crd_iv, sizeof(crd->crd_iv), isector + i);
464 priv->crypto_ivgen(priv, crd->crd_iv, sizeof(crd->crd_iv), isector + i);
467 crd->crd_len = DEV_BSIZE /* XXX */;
468 crd->crd_flags = CRD_F_KEY_EXPLICIT | CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
469 crd->crd_next = NULL;
472 crd->crd_flags |= CRD_F_ENCRYPT;
474 crd->crd_flags &= ~CRD_F_ENCRYPT;
476 error = crypto_dispatch(crp);
481 dm_target_crypt_read_done(struct bio *bio)
483 dm_target_crypt_config_t *priv;
485 priv = bio->bio_caller_info1.ptr;
486 kprintf("dm_target_crypt_read_done %p\n", bio);
488 dm_target_crypt_work(priv, bio);
492 dm_target_crypt_write_done(struct bio *bio)
494 struct dmtc_helper *dmtc;
497 kprintf("dm_target_crypt_write_done %p\n", bio);
498 dmtc = bio->bio_caller_info2.ptr;
499 bio->bio_buf->b_data = dmtc->orig_buf;
500 kfree(dmtc->free_addr, M_DMCRYPT);
506 dm_target_crypt_crypto_done_read(struct cryptop *crp)
508 struct bio *bio, *obio;
511 if (crp->crp_etype == EAGAIN)
512 return crypto_dispatch(crp);
514 bio = (struct bio *)crp->crp_opaque;
515 KKASSERT(bio != NULL);
517 n = atomic_fetchadd_int(&bio->bio_caller_info3.value, -1);
519 kprintf("dm_target_crypt_crypto_done_read %p, n = %d\n", bio, n);
521 if (crp->crp_etype != 0) {
522 kprintf("dm_target_crypt_crypto_done_read crp_etype = %d\n", crp->crp_etype);
523 /* XXX: Print something out */
524 bio->bio_buf->b_error = crp->crp_etype;
527 kprintf("dm_target_crypt_crypt_done_read: n == 1\n");
528 kfree(bio->bio_caller_info2.ptr, M_DMCRYPT);
529 /* This is the last chunk of the read */
538 dm_target_crypt_crypto_done_write(struct cryptop *crp)
540 struct dmtc_helper *dmtc;
541 dm_target_crypt_config_t *priv;
542 struct bio *bio, *obio;
545 if (crp->crp_etype == EAGAIN)
546 return crypto_dispatch(crp);
548 bio = (struct bio *)crp->crp_opaque;
549 KKASSERT(bio != NULL);
551 n = atomic_fetchadd_int(&bio->bio_caller_info3.value, -1);
553 kprintf("dm_target_crypt_crypto_done_write %p, n = %d\n", bio, n);
555 if (crp->crp_etype != 0) {
556 kprintf("dm_target_crypt_crypto_done_write crp_etype = %d\n", crp->crp_etype);
557 /* XXX: Print something out */
558 bio->bio_buf->b_error = crp->crp_etype;
561 kprintf("dm_target_crypt_crypt_done_write: n == 1\n");
562 /* This is the last chunk of the write */
563 if (bio->bio_buf->b_error != 0) {
565 dmtc = bio->bio_caller_info2.ptr;
566 bio->bio_buf->b_data = dmtc->orig_buf;
567 kfree(dmtc->free_addr, M_DMCRYPT);
571 priv = (dm_target_crypt_config_t *)bio->bio_caller_info1.ptr;
572 vn_strategy(priv->pdev->pdev_vnode, bio);
580 strategy -> read_done -> crypto_work -> crypto_done_read -> FINISH READ
581 strategy -> crypto_work -> crypto_done_write -> write dispatch -> write_done -> FINISH WRITE
584 #ifdef DM_TARGET_MODULE
586 * Every target can be compiled directly to dm driver or as a
587 * separate module this part of target is used for loading targets
589 * Target can be unloaded from kernel only if there are no users of
590 * it e.g. there are no devices which uses that target.
592 #include <sys/kernel.h>
593 #include <sys/module.h>
596 dm_target_crypt_modcmd(modcmd_t cmd, void *arg)
603 case MODULE_CMD_INIT:
604 if ((dmt = dm_target_lookup("crypt")) != NULL) {
605 dm_target_unbusy(dmt);
608 dmt = dm_target_alloc("crypt");
613 strlcpy(dmt->name, "crypt", DM_MAX_TYPE_NAME);
614 dmt->init = &dm_target_crypt_init;
615 dmt->status = &dm_target_crypt_status;
616 dmt->strategy = &dm_target_crypt_strategy;
617 dmt->deps = &dm_target_crypt_deps;
618 dmt->destroy = &dm_target_crypt_destroy;
619 dmt->upcall = &dm_target_crypt_upcall;
621 r = dm_target_insert(dmt);
625 case MODULE_CMD_FINI:
626 r = dm_target_rem("crypt");
629 case MODULE_CMD_STAT:
641 * Init function called from dm_table_load_ioctl.
643 * <device> <crypto algorithm>[-<keysize>] <iv generator> <passphrase>
644 * /dev/foo aes-256 essiv foobar
647 dm_target_crypt_init(dm_dev_t * dmv, void **target_config, char *params)
649 dm_target_crypt_config_t *priv;
652 int argc, klen, error;
657 len = strlen(params) + 1;
661 * Parse a string, containing tokens delimited by white space,
662 * into an argument vector
664 for (ap = args; ap < &args[4] &&
665 (*ap = strsep(¶ms, " \t")) != NULL;) {
672 kprintf("\nCrypto target init function called, argc = %d!!\n", argc);
674 kprintf("not enough arguments for target crypt\n");
675 return ENOMEM; /* XXX */
678 kprintf("Crypto target - device name %s -- algorithm %s\n\n", args[0], args[1]);
680 if ((priv = kmalloc(sizeof(dm_target_crypt_config_t), M_DMCRYPT, M_NOWAIT))
682 kprintf("kmalloc in dm_target_crypt_init failed, M_NOWAIT to blame\n");
686 /* Insert dmp to global pdev list */
687 if ((priv->pdev = dm_pdev_insert(args[0])) == NULL) {
688 kprintf("dm_pdev_insert failed\n");
692 if (!strncmp(args[1], "aes-", 4)) {
693 priv->crypto_alg = CRYPTO_AES_CBC;
694 klen = atoi(args[1]+4);
695 if (klen != 128 && klen != 192 && klen != 256)
697 priv->crypto_klen = klen;
699 } else if (!strncmp(args[1], "blowfish-", 9)) {
700 priv->crypto_alg = CRYPTO_BLF_CBC;
701 klen = atoi(args[1]+9);
702 if (klen < 128 || klen > 448 || (klen % 8) != 0)
704 priv->crypto_klen = klen;
706 } else if (!strcmp(args[1], "3DES")) {
707 priv->crypto_alg = CRYPTO_3DES_CBC;
708 priv->crypto_klen = 168;
710 } else if (!strncmp(args[1], "camellia-", 9)) {
711 priv->crypto_alg = CRYPTO_CAMELLIA_CBC;
712 klen = atoi(args[1]+9);
713 if (klen != 128 && klen != 192 && klen != 256)
715 priv->crypto_klen = klen;
717 } else if (!strcmp(args[1], "skipjack")) {
718 priv->crypto_alg = CRYPTO_SKIPJACK_CBC;
719 priv->crypto_klen = 80;
721 } else if (!strcmp(args[1], "CAST-128")) {
722 priv->crypto_alg = CRYPTO_CAST_CBC;
723 priv->crypto_klen = 128;
725 } else if (!strcmp(args[1], "null")) {
726 priv->crypto_alg = CRYPTO_NULL_CBC;
727 priv->crypto_klen = 128;
730 /* Save length of param string */
731 priv->params_len = len;
733 *target_config = priv;
735 dmv->dev_type = DM_CRYPTO_DEV;
737 priv->crypto_session.cri_alg = priv->crypto_alg;
738 priv->crypto_session.cri_klen = priv->crypto_klen;
739 priv->crypto_session.cri_mlen = 0;
740 error = pkcs5_pbkdf2(args[3], strlen(args[3]),
741 "This is the salt", 16, /* XXX !!!!!!!!!!!!! */
742 (u_int8_t *)priv->crypto_key, priv->crypto_klen >> 3,
745 panic("dm_target_crypt: pkcs5_pbkdf2 returned error!");
747 kprintf("priv->crypto_klen >> 3 = %d\n", priv->crypto_klen >> 3);
750 if (!strcmp(args[2], "essiv")) {
751 essiv_hash_mkey(priv);
752 priv->crypto_ivgen = essiv_ivgen;
754 SHA512_Init(&priv->essivsha512_ctx);
755 SHA512_Update(&priv->essivsha512_ctx, (u_int8_t*)priv->crypto_key, priv->crypto_klen >> 3);
756 priv->crypto_ivgen = alt_ivgen;
759 priv->crypto_session.cri_key = (u_int8_t *)priv->crypto_key;
760 priv->crypto_session.cri_next = NULL;
762 error = crypto_newsession(&priv->crypto_sid,
763 &priv->crypto_session,
764 CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE);
766 kprintf("Error during crypto_newsession, error = %d\n", error);
770 /* XXX: eventually support some on-disk metadata */
774 kprintf("returning ENOTSUP from crypt_init thingie... notsup label\n");
778 /* Status routine called to get params string. */
780 dm_target_crypt_status(void *target_config)
782 dm_target_crypt_config_t *priv;
785 priv = target_config;
787 if ((params = kmalloc(DM_MAX_PARAMS_SIZE, M_DMCRYPT, M_WAITOK)) == NULL)
790 ksnprintf(params, DM_MAX_PARAMS_SIZE, "%s",
796 /* Strategy routine called from dm_strategy. */
798 * Do IO operation, called from dmstrategy routine.
801 dm_target_crypt_strategy(dm_table_entry_t * table_en, struct buf * bp)
805 dm_target_crypt_config_t *priv;
806 priv = table_en->target_config;
808 /* Get rid of stuff we can't really handle */
809 if ((bp->b_cmd == BUF_CMD_READ) || (bp->b_cmd == BUF_CMD_WRITE)) {
810 if (((bp->b_bcount % DEV_BSIZE) != 0) || (bp->b_bcount == 0)) {
811 kprintf("dm_target_crypt_strategy: can't really handle bp->b_bcount = %d\n", bp->b_bcount);
812 bp->b_error = EINVAL;
813 bp->b_flags |= B_ERROR | B_INVAL;
814 biodone(&bp->b_bio1);
821 bio = push_bio(&bp->b_bio1);
822 bio->bio_offset = bp->b_bio1.bio_offset;
823 bio->bio_caller_info1.ptr = priv;
824 bio->bio_done = dm_target_crypt_read_done;
825 vn_strategy(priv->pdev->pdev_vnode, bio);
829 bio = push_bio(&bp->b_bio1);
830 bio->bio_offset = bp->b_bio1.bio_offset;
831 bio->bio_caller_info1.ptr = priv;
832 bio->bio_done = dm_target_crypt_write_done;
833 dm_target_crypt_work(priv, bio);
837 vn_strategy(priv->pdev->pdev_vnode, &bp->b_bio1);
845 dm_target_crypt_destroy(dm_table_entry_t * table_en)
847 dm_target_crypt_config_t *priv;
849 priv = table_en->target_config;
854 dm_pdev_decr(priv->pdev);
856 /* Unbusy target so we can unload it */
857 dm_target_unbusy(table_en->target);
859 kfree(priv, M_DMCRYPT);
861 table_en->target_config = NULL;
867 dm_target_crypt_deps(dm_table_entry_t * table_en, prop_array_t prop_array)
869 dm_target_crypt_config_t *priv;
874 if (table_en->target_config == NULL)
877 priv = table_en->target_config;
879 if ((error = VOP_GETATTR(priv->pdev->pdev_vnode, &va)) != 0)
882 prop_array_add_uint64(prop_array, (uint64_t) makeudev(va.va_rmajor, va.va_rminor));
887 /* Unsupported for this target. */
889 dm_target_crypt_upcall(dm_table_entry_t * table_en, struct buf * bp)