d5a7089d6a132606ec6d7cdb961de15011a54bfb
[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/malloc.h>
45 #include <sys/md5.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>
52
53 #include "dm.h"
54 MALLOC_DEFINE(M_DMCRYPT, "dm_crypt", "Device Mapper Target Crypt");
55
56 struct target_crypt_config;
57 typedef void ivgen_t(struct target_crypt_config *, u_int8_t *, size_t, off_t);
58
59 typedef struct target_crypt_config {
60         size_t  params_len;
61         dm_pdev_t *pdev;
62         char    *status_str;
63         int     crypto_alg;
64         int     crypto_klen;
65         u_int8_t        crypto_key[512>>3];
66         u_int8_t        crypto_keyhash[SHA512_DIGEST_LENGTH];
67         u_int64_t       crypto_sid;
68         u_int64_t       block_offset;
69         u_int64_t       iv_offset;
70         SHA512_CTX      essivsha512_ctx;
71         struct cryptoini        crypto_session;
72         ivgen_t *crypto_ivgen;
73 } dm_target_crypt_config_t;
74
75 struct dmtc_helper {
76         caddr_t free_addr;
77         caddr_t orig_buf;
78         caddr_t data_buf;
79 };
80
81 static void dmtc_crypto_read_start(dm_target_crypt_config_t *priv,
82                                 struct bio *bio);
83 static void dmtc_crypto_write_start(dm_target_crypt_config_t *priv,
84                                 struct bio *bio);
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);
89
90 /*
91  * Support routines for dm_target_crypt_init
92  */
93 static int
94 essiv_hash_mkey(dm_target_crypt_config_t *priv, char *iv_hash)
95 {
96         unsigned int klen;
97
98         klen = (priv->crypto_klen >> 3);
99
100         if (iv_hash == NULL)
101                 return EINVAL;
102
103         if (!strcmp(iv_hash, "sha1")) {
104                 SHA1_CTX ctx;
105
106                 if (klen != SHA1_RESULTLEN)
107                         return EINVAL;
108
109                 SHA1Init(&ctx);
110                 SHA1Update(&ctx, priv->crypto_key, priv->crypto_klen>>3);
111                 SHA1Final(priv->crypto_keyhash, &ctx);
112         } else if (!strcmp(iv_hash, "sha256")) {
113                 SHA256_CTX ctx;
114
115                 if (klen != SHA256_DIGEST_LENGTH)
116                         return EINVAL;
117
118                 SHA256_Init(&ctx);
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")) {
122                 SHA384_CTX ctx;
123
124                 if (klen != SHA384_DIGEST_LENGTH)
125                         return EINVAL;
126
127                 SHA384_Init(&ctx);
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")) {
131                 SHA512_CTX ctx;
132
133                 if (klen != SHA512_DIGEST_LENGTH)
134                         return EINVAL;
135
136                 SHA512_Init(&ctx);
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")) {
140                 MD5_CTX ctx;
141
142                 if (klen != MD5_DIGEST_LENGTH)
143                         return EINVAL;
144
145                 MD5Init(&ctx);
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")) {
150                 RMD160_CTX ctx;
151
152                 if (klen != (160/8))
153                         return EINVAL;
154
155                 RMD160Init(&ctx);
156                 RMD160Update(&ctx, priv->crypto_key, priv->crypto_klen>>3);
157                 RMD160Final(priv->crypto_keyhash, &ctx);
158         } else {
159                 return EINVAL;
160         }
161
162         return 0;
163 }
164
165 static int
166 essiv_ivgen_done(struct cryptop *crp)
167 {
168
169         if (crp->crp_etype == EAGAIN)
170                 return crypto_dispatch(crp);
171
172         if (crp->crp_etype != 0) {
173                 kprintf("dm_target_crypt: essiv_ivgen_done, "
174                         "crp->crp_etype = %d\n", crp->crp_etype);
175         }
176
177         atomic_add_int((int *)crp->crp_opaque, 1);
178         wakeup(crp->crp_opaque);
179         return 0;
180 }
181
182 static void
183 plain_ivgen(dm_target_crypt_config_t *priv, u_int8_t *iv,
184             size_t iv_len, off_t sector)
185 {
186         bzero(iv, iv_len);
187         *((off_t *)iv) = htole64(sector + priv->iv_offset);
188 }
189
190 static void
191 essiv_ivgen(dm_target_crypt_config_t *priv, u_int8_t *iv,
192             size_t iv_len, off_t sector)
193 {
194         struct cryptodesc crd;
195         struct cryptop crp;
196         int error, id;
197
198         id = 0;
199         bzero(iv, iv_len);
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;
204
205         crp.crp_sid = priv->crypto_sid;
206         crp.crp_ilen = crp.crp_olen = iv_len;
207
208         crp.crp_opaque = (void *)&id;
209
210         crp.crp_callback = essiv_ivgen_done;
211
212         crp.crp_desc = &crd;
213         crp.crp_etype = 0;
214         crp.crp_flags = CRYPTO_F_CBIFSYNC | CRYPTO_F_REL;
215
216         crd.crd_alg = priv->crypto_alg;
217         crd.crd_key = (caddr_t)priv->crypto_keyhash;
218         crd.crd_klen = priv->crypto_klen;
219
220         bzero(crd.crd_iv, sizeof(crd.crd_iv));
221
222         crd.crd_skip = 0;
223         crd.crd_len = iv_len;
224         crd.crd_flags = CRD_F_KEY_EXPLICIT | CRD_F_IV_EXPLICIT |
225                         CRD_F_IV_PRESENT;
226         crd.crd_flags |= CRD_F_ENCRYPT;
227         crd.crd_next = NULL;
228
229         error = crypto_dispatch(&crp);
230         if (error)
231                 kprintf("dm_target_crypt: essiv_ivgen, error = %d\n", error);
232
233         /*
234          * id is modified in the callback, so that if crypto_dispatch finishes
235          * synchronously we don't tsleep() forever.
236          */
237         if (id == 0)
238                 tsleep((void *)&error, 0, "essivgen", 0);
239 }
240
241 #if 0
242
243 static void
244 geli_ivgen(dm_target_crypt_config_t *priv, u_int8_t *iv,
245            size_t iv_len, off_t sector)
246 {
247
248         SHA512_CTX      ctx512;
249         u_int8_t        md[SHA512_DIGEST_LENGTH]; /* Max. Digest Size */
250
251         memcpy(&ctx512, &priv->essivsha512_ctx, sizeof(SHA512_CTX));
252         SHA512_Update(&ctx512, (u_int8_t*)&sector, sizeof(off_t));
253         SHA512_Final(md, &ctx512);
254
255         memcpy(iv, md, iv_len);
256 }
257
258 #endif
259
260 #ifdef DM_TARGET_MODULE
261 /*
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
264  * to dm driver.
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.
267  */
268 #include <sys/kernel.h>
269 #include <sys/module.h>
270
271 static int
272 dm_target_crypt_modcmd(modcmd_t cmd, void *arg)
273 {
274         dm_target_t *dmt;
275         int r;
276         dmt = NULL;
277
278         switch (cmd) {
279         case MODULE_CMD_INIT:
280                 if ((dmt = dm_target_lookup("crypt")) != NULL) {
281                         dm_target_unbusy(dmt);
282                         return EEXIST;
283                 }
284                 dmt = dm_target_alloc("crypt");
285
286                 dmt->version[0] = 1;
287                 dmt->version[1] = 0;
288                 dmt->version[2] = 0;
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;
296
297                 r = dm_target_insert(dmt);
298
299                 break;
300
301         case MODULE_CMD_FINI:
302                 r = dm_target_rem("crypt");
303                 break;
304
305         case MODULE_CMD_STAT:
306                 return ENOTTY;
307
308         default:
309                 return ENOTTY;
310         }
311
312         return r;
313 }
314
315 #endif
316
317 /*
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
321  */
322 static int
323 hex2key(char *hex, size_t hex_length, u_int8_t *key)
324 {
325         char hex_buf[3];
326         size_t key_idx;
327
328         key_idx = 0;
329         bzero(hex_buf, sizeof(hex_buf));
330
331         for (; hex_length > 0; hex_length -= 2) {
332                 hex_buf[0] = *hex++;
333                 hex_buf[1] = *hex++;
334                 key[key_idx++] = (u_int8_t)strtoul(hex_buf, NULL, 16);
335         }
336
337         return 0;
338 }
339
340 int
341 dm_target_crypt_init(dm_dev_t * dmv, void **target_config, char *params)
342 {
343         dm_target_crypt_config_t *priv;
344         size_t len;
345         char **ap, *args[5];
346         char *crypto_alg, *crypto_mode, *iv_mode, *iv_opt, *key, *dev;
347         char *status_str;
348         int argc, klen, error;
349         uint64_t iv_offset, block_offset;
350
351         if (params == NULL)
352                 return EINVAL;
353
354         len = strlen(params) + 1;
355         argc = 0;
356
357         status_str = kstrdup(params, M_DMCRYPT);
358         /*
359          * Parse a string, containing tokens delimited by white space,
360          * into an argument vector
361          */
362         for (ap = args; ap < &args[5] &&
363             (*ap = strsep(&params, " \t")) != NULL;) {
364                 if (**ap != '\0') {
365                         argc++;
366                         ap++;
367                 }
368         }
369
370         if (argc != 5) {
371                 kprintf("dm_target_crypt: not enough arguments, "
372                         "need exactly 5\n");
373                 kfree(status_str, M_DMCRYPT);
374                 return ENOMEM; /* XXX */
375         }
376
377         crypto_alg = strsep(&args[0], "-");
378         crypto_mode = strsep(&args[0], "-");
379         iv_opt = strsep(&args[0], "-");
380         iv_mode = strsep(&iv_opt, ":");
381         key = args[1];
382         iv_offset = strtouq(args[2], NULL, 0);
383         dev = args[3];
384         block_offset = strtouq(args[4], NULL, 0);
385         /* bits / 8 = bytes, 1 byte = 2 hexa chars, so << 2 */
386         klen = strlen(key) << 2;
387
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,
392                 block_offset);
393
394         priv = kmalloc(sizeof(dm_target_crypt_config_t), M_DMCRYPT, M_WAITOK);
395         if (priv == NULL) {
396                 kprintf("dm_target_crypt: could not allocate memory\n");
397                 kfree(status_str, M_DMCRYPT);
398                 return ENOMEM;
399         }
400
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);
405                 return ENOENT;
406         }
407
408         if (strcmp(crypto_mode, "cbc") != 0) {
409                 kprintf("dm_target_crypt: only support 'cbc' chaining mode, "
410                         "invalid mode '%s'\n", crypto_mode);
411                 goto notsup;
412         }
413
414         if (!strcmp(crypto_alg, "aes")) {
415                 priv->crypto_alg = CRYPTO_AES_CBC;
416                 if (klen != 128 && klen != 192 && klen != 256)
417                         goto notsup;
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)
422                         goto notsup;
423                 priv->crypto_klen = klen;
424
425         } else if (!strcmp(crypto_alg, "3des") ||
426                    !strncmp(crypto_alg, "des3", 4)) {
427                 priv->crypto_alg = CRYPTO_3DES_CBC;
428                 if (klen != 168)
429                         goto notsup;
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)
434                         goto notsup;
435                 priv->crypto_klen = klen;
436         } else if (!strcmp(crypto_alg, "skipjack")) {
437                 priv->crypto_alg = CRYPTO_SKIPJACK_CBC;
438                 if (klen != 80)
439                         goto notsup;
440                 priv->crypto_klen = 80;
441         } else if (!strcmp(crypto_alg, "cast5")) {
442                 priv->crypto_alg = CRYPTO_CAST_CBC;
443                 if (klen != 128)
444                         goto notsup;
445                 priv->crypto_klen = 128;
446         } else if (!strcmp(crypto_alg, "null")) {
447                 priv->crypto_alg = CRYPTO_NULL_CBC;
448                 if (klen != 128)
449                         goto notsup;
450                 priv->crypto_klen = 128;
451         } else {
452                 kprintf("dm_target_crypt: Unsupported crypto algorithm: %s\n",
453                         crypto_alg);
454                 goto notsup;
455         }
456
457         /* Save length of param string */
458         priv->params_len = len;
459         priv->block_offset = block_offset;
460         priv->iv_offset = iv_offset;
461
462         *target_config = priv;
463
464         dmv->dev_type = DM_CRYPTO_DEV;
465
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;
469
470         error = hex2key(key, priv->crypto_klen >> 3,
471                         (u_int8_t *)priv->crypto_key);
472
473         if (error) {
474                 kprintf("dm_target_crypt: hex2key failed, "
475                         "invalid key format\n");
476                 goto notsup;
477         }
478
479         if (!strcmp(iv_mode, "essiv")) {
480                 error = essiv_hash_mkey(priv, iv_opt);
481                 if (error) {
482                         kprintf("dm_target_crypt: essiv_hash_mkey failed\n");
483                         goto notsup;
484                 }
485                 priv->crypto_ivgen = essiv_ivgen;
486         } else if (!strcmp(iv_mode, "plain")) {
487                 priv->crypto_ivgen = plain_ivgen;
488         } else {
489                 kprintf("dm_target_crypt: only support iv_mode='essiv' and "
490                         "'plain', iv_mode='%s' unsupported\n",
491                         iv_mode);
492         }
493
494         priv->crypto_session.cri_key = (u_int8_t *)priv->crypto_key;
495         priv->crypto_session.cri_next = NULL;
496
497         error = crypto_newsession(&priv->crypto_sid,
498                                   &priv->crypto_session,
499                                   CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE);
500         if (error) {
501                 kprintf("dm_target_crypt: Error during crypto_newsession, "
502                         "error = %d\n",
503                         error);
504                 goto notsup;
505         }
506
507         priv->status_str = status_str;
508         return 0;
509
510 notsup:
511         kprintf("dm_target_crypt: ENOTSUP\n");
512         kfree(status_str, M_DMCRYPT);
513         return ENOTSUP;
514 }
515
516 /* Status routine called to get params string. */
517 char *
518 dm_target_crypt_status(void *target_config)
519 {
520         dm_target_crypt_config_t *priv;
521         char *params;
522
523         priv = target_config;
524
525         /* caller expects use of M_DM */
526         params = kmalloc(DM_MAX_PARAMS_SIZE, M_DM, M_WAITOK);
527
528         ksnprintf(params, DM_MAX_PARAMS_SIZE, "%s",
529             priv->status_str);
530
531         return params;
532 }
533
534 int
535 dm_target_crypt_destroy(dm_table_entry_t * table_en)
536 {
537         dm_target_crypt_config_t *priv;
538
539         /*
540          * Disconnect the crypt config before unbusying the target.
541          */
542         priv = table_en->target_config;
543         if (priv == NULL)
544                 return 0;
545         table_en->target_config = NULL;
546         dm_pdev_decr(priv->pdev);
547
548         dm_target_unbusy(table_en->target);
549
550         /*
551          * Clean up the crypt config
552          *
553          * Overwrite the private information before freeing memory to
554          * avoid leaking it.
555          */
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);
559
560         memset(priv, 0xFF, sizeof(dm_target_crypt_config_t));
561         bzero(priv, sizeof(dm_target_crypt_config_t));
562         kfree(priv, M_DMCRYPT);
563
564         return 0;
565 }
566
567 int
568 dm_target_crypt_deps(dm_table_entry_t * table_en, prop_array_t prop_array)
569 {
570         dm_target_crypt_config_t *priv;
571         struct vattr va;
572
573         int error;
574
575         if (table_en->target_config == NULL)
576                 return ENOENT;
577
578         priv = table_en->target_config;
579
580         if ((error = VOP_GETATTR(priv->pdev->pdev_vnode, &va)) != 0)
581                 return error;
582
583         prop_array_add_uint64(prop_array,
584                               (uint64_t)makeudev(va.va_rmajor, va.va_rminor));
585
586         return 0;
587 }
588
589 /* Unsupported for this target. */
590 int
591 dm_target_crypt_upcall(dm_table_entry_t * table_en, struct buf * bp)
592 {
593         return 0;
594 }
595
596 /************************************************************************
597  *                      STRATEGY SUPPORT FUNCTIONS                      *
598  ************************************************************************
599  *
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
602  */
603
604 /*
605  * Start IO operation, called from dmstrategy routine.
606  */
607 int
608 dm_target_crypt_strategy(dm_table_entry_t *table_en, struct buf *bp)
609 {
610         struct bio *bio;
611
612         dm_target_crypt_config_t *priv;
613         priv = table_en->target_config;
614
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",
620                                 bp->b_bcount);
621                         bp->b_error = EINVAL;
622                         bp->b_flags |= B_ERROR | B_INVAL;
623                         biodone(&bp->b_bio1);
624                         return 0;
625                 }
626         }
627
628         switch (bp->b_cmd) {
629         case BUF_CMD_READ:
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);
636                 break;
637         case BUF_CMD_WRITE:
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);
643                 break;
644         default:
645                 vn_strategy(priv->pdev->pdev_vnode, &bp->b_bio1);
646                 break;
647         }
648         return 0;
649 }
650
651 /*
652  * STRATEGY READ PATH PART 1/3 (after read BIO completes)
653  */
654 static void
655 dmtc_bio_read_done(struct bio *bio)
656 {
657         struct bio *obio;
658
659         dm_target_crypt_config_t *priv;
660
661         /*
662          * If a read error occurs we shortcut the operation, otherwise
663          * go on to stage 2.
664          */
665         if (bio->bio_buf->b_flags & B_ERROR) {
666                 obio = pop_bio(bio);
667                 biodone(obio);
668         } else {
669                 priv = bio->bio_caller_info1.ptr;
670                 dmtc_crypto_read_start(priv, bio);
671         }
672 }
673
674 /*
675  * STRATEGY READ PATH PART 2/3
676  */
677 static void
678 dmtc_crypto_read_start(dm_target_crypt_config_t *priv, struct bio *bio)
679 {
680         struct dmtc_helper *dmtc;
681         struct cryptodesc *crd;
682         struct cryptop *crp;
683         struct cryptoini *cri;
684         int error, i, bytes, isector, sectors, sz;
685         u_char *ptr, *space;
686
687         cri = &priv->crypto_session;
688
689         /*
690          * Note: b_resid no good after read I/O, it will be 0, use
691          *       b_bcount.
692          */
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));
697
698         /*
699          * For reads with bogus page we can't decrypt in place as stuff
700          * can get ripped out from under us.
701          *
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.
705          */
706 #if 0
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);
716         } else
717 #endif
718         {
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;
726         }
727         bio->bio_caller_info2.ptr = dmtc;
728         bio->bio_buf->b_error = 0;
729
730         /*
731          * Load crypto descriptors (crp/crd loop)
732          */
733         bzero(space, sz);
734         ptr = space;
735         bio->bio_caller_info3.value = sectors;
736         cpu_sfence();
737 #if 0
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);
741 #endif
742         for (i = 0; i < sectors; i++) {
743                 crp = (struct cryptop *)ptr;
744                 ptr += sizeof(*crp);
745                 crd = (struct cryptodesc *)ptr;
746                 ptr += sizeof (*crd);
747
748                 crp->crp_buf = dmtc->data_buf + i * DEV_BSIZE;
749
750                 crp->crp_sid = priv->crypto_sid;
751                 crp->crp_ilen = crp->crp_olen = DEV_BSIZE;
752
753                 crp->crp_opaque = (void *)bio;
754
755                 crp->crp_callback = dmtc_crypto_cb_read_done;
756                 crp->crp_desc = crd;
757                 crp->crp_etype = 0;
758                 crp->crp_flags = CRYPTO_F_CBIFSYNC | CRYPTO_F_REL |
759                                  CRYPTO_F_BATCH;
760
761                 crd->crd_alg = priv->crypto_alg;
762                 crd->crd_key = (caddr_t)priv->crypto_key;
763                 crd->crd_klen = priv->crypto_klen;
764
765                 /*
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
769                  *       crypt volumes.
770                  */
771                 priv->crypto_ivgen(priv, crd->crd_iv, sizeof(crd->crd_iv),
772                                    (int)(isector + i));
773
774                 crd->crd_skip = 0;
775                 crd->crd_len = DEV_BSIZE /* XXX */;
776                 crd->crd_flags = CRD_F_KEY_EXPLICIT | CRD_F_IV_EXPLICIT |
777                                  CRD_F_IV_PRESENT;
778                 crd->crd_next = NULL;
779
780                 crd->crd_flags &= ~CRD_F_ENCRYPT;
781
782                 error = crypto_dispatch(crp);
783         }
784 }
785
786 /*
787  * STRATEGY READ PATH PART 3/3
788  */
789 static int
790 dmtc_crypto_cb_read_done(struct cryptop *crp)
791 {
792         struct dmtc_helper *dmtc;
793         struct bio *bio, *obio;
794         int n;
795
796         if (crp->crp_etype == EAGAIN)
797                 return crypto_dispatch(crp);
798
799         bio = (struct bio *)crp->crp_opaque;
800         KKASSERT(bio != NULL);
801
802         /*
803          * Cumulative error
804          */
805         if (crp->crp_etype) {
806                 kprintf("dm_target_crypt: dmtc_crypto_cb_read_done "
807                         "crp_etype = %d\n",
808                         crp->crp_etype);
809                 bio->bio_buf->b_error = crp->crp_etype;
810         }
811
812         /*
813          * On the last chunk of the decryption we do any required copybacks
814          * and complete the I/O.
815          */
816         n = atomic_fetchadd_int(&bio->bio_caller_info3.value, -1);
817 #if 0
818         kprintf("dmtc_crypto_cb_read_done %p, n = %d\n", bio, n);
819 #endif
820
821         if (n == 1) {
822                 /*
823                  * For the B_HASBOGUS case we didn't decrypt in place,
824                  * so we need to copy stuff back into the buf.
825                  *
826                  * (disabled for now).
827                  */
828                 dmtc = bio->bio_caller_info2.ptr;
829                 if (bio->bio_buf->b_error) {
830                         bio->bio_buf->b_flags |= B_ERROR;
831                 }
832 #if 0
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);
836                 }
837 #endif
838                 kfree(dmtc->free_addr, M_DMCRYPT);
839                 obio = pop_bio(bio);
840                 biodone(obio);
841         }
842         return 0;
843 }
844 /* END OF STRATEGY READ SECTION */
845
846 /*
847  * STRATEGY WRITE PATH PART 1/3
848  */
849 static void
850 dmtc_crypto_write_start(dm_target_crypt_config_t *priv, struct bio *bio)
851 {
852         struct dmtc_helper *dmtc;
853         struct cryptodesc *crd;
854         struct cryptop *crp;
855         struct cryptoini *cri;
856         int error, i, bytes, isector, sectors, sz;
857         u_char *ptr, *space;
858
859         cri = &priv->crypto_session;
860
861         /*
862          * Use b_bcount for consistency
863          */
864         bytes = bio->bio_buf->b_bcount;
865
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));
869
870         /*
871          * For writes and reads with bogus page don't decrypt in place.
872          */
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);
879
880         bio->bio_caller_info2.ptr = dmtc;
881         bio->bio_buf->b_error = 0;
882
883         dmtc->orig_buf = bio->bio_buf->b_data;
884         dmtc->data_buf = space + sz;
885
886         /*
887          * Load crypto descriptors (crp/crd loop)
888          */
889         bzero(space, sz);
890         ptr = space;
891         bio->bio_caller_info3.value = sectors;
892         cpu_sfence();
893 #if 0
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);
897 #endif
898         for (i = 0; i < sectors; i++) {
899                 crp = (struct cryptop *)ptr;
900                 ptr += sizeof(*crp);
901                 crd = (struct cryptodesc *)ptr;
902                 ptr += sizeof (*crd);
903
904                 crp->crp_buf = dmtc->data_buf + i * DEV_BSIZE;
905
906                 crp->crp_sid = priv->crypto_sid;
907                 crp->crp_ilen = crp->crp_olen = DEV_BSIZE;
908
909                 crp->crp_opaque = (void *)bio;
910
911                 crp->crp_callback = dmtc_crypto_cb_write_done;
912                 crp->crp_desc = crd;
913                 crp->crp_etype = 0;
914                 crp->crp_flags = CRYPTO_F_CBIFSYNC | CRYPTO_F_REL |
915                                  CRYPTO_F_BATCH;
916
917                 crd->crd_alg = priv->crypto_alg;
918                 crd->crd_key = (caddr_t)priv->crypto_key;
919                 crd->crd_klen = priv->crypto_klen;
920
921                 /*
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
925                  *       crypt volumes.
926                  */
927                 priv->crypto_ivgen(priv, crd->crd_iv, sizeof(crd->crd_iv),
928                                    (int)(isector + i));
929
930                 crd->crd_skip = 0;
931                 crd->crd_len = DEV_BSIZE /* XXX */;
932                 crd->crd_flags = CRD_F_KEY_EXPLICIT | CRD_F_IV_EXPLICIT |
933                                  CRD_F_IV_PRESENT;
934                 crd->crd_next = NULL;
935
936                 crd->crd_flags |= CRD_F_ENCRYPT;
937                 error = crypto_dispatch(crp);
938         }
939 }
940
941 /*
942  * STRATEGY WRITE PATH PART 2/3
943  */
944 static int
945 dmtc_crypto_cb_write_done(struct cryptop *crp)
946 {
947         struct dmtc_helper *dmtc;
948         dm_target_crypt_config_t *priv;
949         struct bio *bio, *obio;
950         int n;
951
952         if (crp->crp_etype == EAGAIN)
953                 return crypto_dispatch(crp);
954
955         bio = (struct bio *)crp->crp_opaque;
956         KKASSERT(bio != NULL);
957
958         /*
959          * Cumulative error
960          */
961         if (crp->crp_etype != 0) {
962                 kprintf("dm_target_crypt: dmtc_crypto_cb_write_done "
963                         "crp_etype = %d\n",
964                 crp->crp_etype);
965                 bio->bio_buf->b_error = crp->crp_etype;
966         }
967
968         /*
969          * On the last chunk of the encryption we issue the write
970          */
971         n = atomic_fetchadd_int(&bio->bio_caller_info3.value, -1);
972 #if 0
973         kprintf("dmtc_crypto_cb_write_done %p, n = %d\n", bio, n);
974 #endif
975
976         if (n == 1) {
977                 dmtc = bio->bio_caller_info2.ptr;
978                 priv = (dm_target_crypt_config_t *)bio->bio_caller_info1.ptr;
979
980                 if (bio->bio_buf->b_error) {
981                         bio->bio_buf->b_flags |= B_ERROR;
982                         kfree(dmtc->free_addr, M_DMCRYPT);
983                         obio = pop_bio(bio);
984                         biodone(obio);
985                 } else {
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);
990                 }
991         }
992         return 0;
993 }
994
995 /*
996  * STRATEGY WRITE PATH PART 3/3
997  */
998 static void
999 dmtc_bio_write_done(struct bio *bio)
1000 {
1001         struct dmtc_helper *dmtc;
1002         struct bio *obio;
1003
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);
1008         biodone(obio);
1009 }
1010 /* END OF STRATEGY WRITE SECTION */