1*f603807bSTomohiro Kusumi /* 2*f603807bSTomohiro Kusumi * Copyright (c) 2010 The DragonFly Project. All rights reserved. 3*f603807bSTomohiro Kusumi * 4*f603807bSTomohiro Kusumi * This code is derived from software contributed to The DragonFly Project 5*f603807bSTomohiro Kusumi * by Alex Hornung <ahornung@gmail.com> 6*f603807bSTomohiro Kusumi * 7*f603807bSTomohiro Kusumi * Redistribution and use in source and binary forms, with or without 8*f603807bSTomohiro Kusumi * modification, are permitted provided that the following conditions 9*f603807bSTomohiro Kusumi * are met: 10*f603807bSTomohiro Kusumi * 11*f603807bSTomohiro Kusumi * 1. Redistributions of source code must retain the above copyright 12*f603807bSTomohiro Kusumi * notice, this list of conditions and the following disclaimer. 13*f603807bSTomohiro Kusumi * 2. Redistributions in binary form must reproduce the above copyright 14*f603807bSTomohiro Kusumi * notice, this list of conditions and the following disclaimer in 15*f603807bSTomohiro Kusumi * the documentation and/or other materials provided with the 16*f603807bSTomohiro Kusumi * distribution. 17*f603807bSTomohiro Kusumi * 3. Neither the name of The DragonFly Project nor the names of its 18*f603807bSTomohiro Kusumi * contributors may be used to endorse or promote products derived 19*f603807bSTomohiro Kusumi * from this software without specific, prior written permission. 20*f603807bSTomohiro Kusumi * 21*f603807bSTomohiro Kusumi * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22*f603807bSTomohiro Kusumi * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23*f603807bSTomohiro Kusumi * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24*f603807bSTomohiro Kusumi * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25*f603807bSTomohiro Kusumi * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26*f603807bSTomohiro Kusumi * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 27*f603807bSTomohiro Kusumi * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28*f603807bSTomohiro Kusumi * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 29*f603807bSTomohiro Kusumi * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30*f603807bSTomohiro Kusumi * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 31*f603807bSTomohiro Kusumi * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32*f603807bSTomohiro Kusumi * SUCH DAMAGE. 33*f603807bSTomohiro Kusumi */ 34*f603807bSTomohiro Kusumi 35*f603807bSTomohiro Kusumi /* 36*f603807bSTomohiro Kusumi * This file implements initial version of device-mapper crypt target. 37*f603807bSTomohiro Kusumi */ 38*f603807bSTomohiro Kusumi #include <sys/endian.h> 39*f603807bSTomohiro Kusumi 40*f603807bSTomohiro Kusumi #include <sys/bio.h> 41*f603807bSTomohiro Kusumi #include <sys/globaldata.h> 42*f603807bSTomohiro Kusumi #include <sys/kerneldump.h> 43*f603807bSTomohiro Kusumi #include <sys/malloc.h> 44*f603807bSTomohiro Kusumi #include <sys/mpipe.h> 45*f603807bSTomohiro Kusumi #include <sys/md5.h> 46*f603807bSTomohiro Kusumi #include <sys/mutex2.h> 47*f603807bSTomohiro Kusumi #include <crypto/sha1.h> 48*f603807bSTomohiro Kusumi #include <crypto/sha2/sha2.h> 49*f603807bSTomohiro Kusumi #include <opencrypto/cryptodev.h> 50*f603807bSTomohiro Kusumi #include <opencrypto/rmd160.h> 51*f603807bSTomohiro Kusumi #include <machine/cpufunc.h> 52*f603807bSTomohiro Kusumi #include <cpu/atomic.h> 53*f603807bSTomohiro Kusumi 54*f603807bSTomohiro Kusumi #include <sys/ktr.h> 55*f603807bSTomohiro Kusumi 56*f603807bSTomohiro Kusumi #include <dev/disk/dm/dm.h> 57*f603807bSTomohiro Kusumi MALLOC_DEFINE(M_DMCRYPT, "dm_crypt", "Device Mapper Target Crypt"); 58*f603807bSTomohiro Kusumi 59*f603807bSTomohiro Kusumi KTR_INFO_MASTER(dmcrypt); 60*f603807bSTomohiro Kusumi 61*f603807bSTomohiro Kusumi #if !defined(KTR_DMCRYPT) 62*f603807bSTomohiro Kusumi #define KTR_DMCRYPT KTR_ALL 63*f603807bSTomohiro Kusumi #endif 64*f603807bSTomohiro Kusumi 65*f603807bSTomohiro Kusumi KTR_INFO(KTR_DMCRYPT, dmcrypt, crypto_dispatch, 0, 66*f603807bSTomohiro Kusumi "crypto_dispatch(%p)", struct cryptop *crp); 67*f603807bSTomohiro Kusumi KTR_INFO(KTR_DMCRYPT, dmcrypt, crypt_strategy, 0, 68*f603807bSTomohiro Kusumi "crypt_strategy(b_cmd = %d, bp = %p)", int cmd, struct buf *bp); 69*f603807bSTomohiro Kusumi KTR_INFO(KTR_DMCRYPT, dmcrypt, crypto_write_start, 1, 70*f603807bSTomohiro Kusumi "crypto_write_start(crp = %p, bp = %p, sector = %d/%d)", 71*f603807bSTomohiro Kusumi struct cryptop *crp, struct buf *bp, int i, int sectors); 72*f603807bSTomohiro Kusumi KTR_INFO(KTR_DMCRYPT, dmcrypt, crypto_cb_write_done, 1, 73*f603807bSTomohiro Kusumi "crypto_cb_write_done(crp = %p, bp = %p, n = %d)", 74*f603807bSTomohiro Kusumi struct cryptop *crp, struct buf *bp, int n); 75*f603807bSTomohiro Kusumi KTR_INFO(KTR_DMCRYPT, dmcrypt, bio_write_done, 1, 76*f603807bSTomohiro Kusumi "bio_write_done(bp = %p)", struct buf *bp); 77*f603807bSTomohiro Kusumi KTR_INFO(KTR_DMCRYPT, dmcrypt, crypto_write_retry, 1, 78*f603807bSTomohiro Kusumi "crypto_write_retry(crp = %p)", struct buf *bp); 79*f603807bSTomohiro Kusumi KTR_INFO(KTR_DMCRYPT, dmcrypt, bio_read_done, 2, 80*f603807bSTomohiro Kusumi "bio_read_done(bp = %p)", struct buf *bp); 81*f603807bSTomohiro Kusumi KTR_INFO(KTR_DMCRYPT, dmcrypt, crypto_read_start, 2, 82*f603807bSTomohiro Kusumi "crypto_read_start(crp = %p, bp = %p, sector = %d/%d)", 83*f603807bSTomohiro Kusumi struct cryptop *crp, struct buf *bp, int i, int sectors); 84*f603807bSTomohiro Kusumi KTR_INFO(KTR_DMCRYPT, dmcrypt, crypto_cb_read_done, 2, 85*f603807bSTomohiro Kusumi "crypto_cb_read_done(crp = %p, bp = %p, n = %d)", 86*f603807bSTomohiro Kusumi struct cryptop *crp, struct buf *bp, int n); 87*f603807bSTomohiro Kusumi 88*f603807bSTomohiro Kusumi struct target_crypt_config; 89*f603807bSTomohiro Kusumi 90*f603807bSTomohiro Kusumi typedef void dispatch_t(void *); 91*f603807bSTomohiro Kusumi typedef void ivgen_t(struct target_crypt_config *, u_int8_t *, size_t, off_t, 92*f603807bSTomohiro Kusumi void *); 93*f603807bSTomohiro Kusumi 94*f603807bSTomohiro Kusumi typedef int ivgen_ctor_t(struct target_crypt_config *, char *, void **); 95*f603807bSTomohiro Kusumi typedef int ivgen_dtor_t(struct target_crypt_config *, void *); 96*f603807bSTomohiro Kusumi 97*f603807bSTomohiro Kusumi struct iv_generator { 98*f603807bSTomohiro Kusumi const char *name; 99*f603807bSTomohiro Kusumi ivgen_ctor_t *ctor; 100*f603807bSTomohiro Kusumi ivgen_dtor_t *dtor; 101*f603807bSTomohiro Kusumi ivgen_t *gen_iv; 102*f603807bSTomohiro Kusumi }; 103*f603807bSTomohiro Kusumi 104*f603807bSTomohiro Kusumi struct essiv_ivgen_priv { 105*f603807bSTomohiro Kusumi struct cryptoini crypto_session; 106*f603807bSTomohiro Kusumi struct objcache *crp_crd_cache; 107*f603807bSTomohiro Kusumi u_int64_t crypto_sid; 108*f603807bSTomohiro Kusumi size_t keyhash_len; 109*f603807bSTomohiro Kusumi u_int8_t crypto_keyhash[SHA512_DIGEST_LENGTH]; 110*f603807bSTomohiro Kusumi }; 111*f603807bSTomohiro Kusumi 112*f603807bSTomohiro Kusumi typedef struct target_crypt_config { 113*f603807bSTomohiro Kusumi size_t params_len; 114*f603807bSTomohiro Kusumi dm_pdev_t *pdev; 115*f603807bSTomohiro Kusumi char *status_str; 116*f603807bSTomohiro Kusumi int crypto_alg; 117*f603807bSTomohiro Kusumi int crypto_klen; 118*f603807bSTomohiro Kusumi u_int8_t crypto_key[512>>3]; 119*f603807bSTomohiro Kusumi 120*f603807bSTomohiro Kusumi u_int64_t crypto_sid; 121*f603807bSTomohiro Kusumi u_int64_t block_offset; 122*f603807bSTomohiro Kusumi int64_t iv_offset; 123*f603807bSTomohiro Kusumi SHA512_CTX essivsha512_ctx; 124*f603807bSTomohiro Kusumi 125*f603807bSTomohiro Kusumi struct cryptoini crypto_session; 126*f603807bSTomohiro Kusumi 127*f603807bSTomohiro Kusumi struct iv_generator *ivgen; 128*f603807bSTomohiro Kusumi void *ivgen_priv; 129*f603807bSTomohiro Kusumi 130*f603807bSTomohiro Kusumi struct malloc_pipe read_mpipe; 131*f603807bSTomohiro Kusumi struct malloc_pipe write_mpipe; 132*f603807bSTomohiro Kusumi } dm_target_crypt_config_t; 133*f603807bSTomohiro Kusumi 134*f603807bSTomohiro Kusumi struct dmtc_helper { 135*f603807bSTomohiro Kusumi dm_target_crypt_config_t *priv; 136*f603807bSTomohiro Kusumi caddr_t free_addr; 137*f603807bSTomohiro Kusumi caddr_t orig_buf; 138*f603807bSTomohiro Kusumi caddr_t data_buf; 139*f603807bSTomohiro Kusumi }; 140*f603807bSTomohiro Kusumi 141*f603807bSTomohiro Kusumi struct dmtc_dump_helper { 142*f603807bSTomohiro Kusumi dm_target_crypt_config_t *priv; 143*f603807bSTomohiro Kusumi void *data; 144*f603807bSTomohiro Kusumi size_t length; 145*f603807bSTomohiro Kusumi off_t offset; 146*f603807bSTomohiro Kusumi 147*f603807bSTomohiro Kusumi int sectors; 148*f603807bSTomohiro Kusumi int *ident; 149*f603807bSTomohiro Kusumi 150*f603807bSTomohiro Kusumi struct cryptodesc crd[128]; 151*f603807bSTomohiro Kusumi struct cryptop crp[128]; 152*f603807bSTomohiro Kusumi u_char space[65536]; 153*f603807bSTomohiro Kusumi }; 154*f603807bSTomohiro Kusumi 155*f603807bSTomohiro Kusumi #define DMTC_BUF_SIZE_WRITE \ 156*f603807bSTomohiro Kusumi MAXPHYS + sizeof(struct dmtc_helper) + \ 157*f603807bSTomohiro Kusumi MAXPHYS/DEV_BSIZE*(sizeof(struct cryptop) + sizeof(struct cryptodesc)) 158*f603807bSTomohiro Kusumi #define DMTC_BUF_SIZE_READ \ 159*f603807bSTomohiro Kusumi sizeof(struct dmtc_helper) + \ 160*f603807bSTomohiro Kusumi MAXPHYS/DEV_BSIZE*(sizeof(struct cryptop) + sizeof(struct cryptodesc)) 161*f603807bSTomohiro Kusumi 162*f603807bSTomohiro Kusumi static void dmtc_crypto_dispatch(void *arg); 163*f603807bSTomohiro Kusumi static void dmtc_crypto_dump_start(dm_target_crypt_config_t *priv, 164*f603807bSTomohiro Kusumi struct dmtc_dump_helper *dump_helper); 165*f603807bSTomohiro Kusumi static void dmtc_crypto_read_start(dm_target_crypt_config_t *priv, 166*f603807bSTomohiro Kusumi struct bio *bio); 167*f603807bSTomohiro Kusumi static void dmtc_crypto_write_start(dm_target_crypt_config_t *priv, 168*f603807bSTomohiro Kusumi struct bio *bio); 169*f603807bSTomohiro Kusumi static void dmtc_bio_read_done(struct bio *bio); 170*f603807bSTomohiro Kusumi static void dmtc_bio_write_done(struct bio *bio); 171*f603807bSTomohiro Kusumi static int dmtc_crypto_cb_dump_done(struct cryptop *crp); 172*f603807bSTomohiro Kusumi static int dmtc_crypto_cb_read_done(struct cryptop *crp); 173*f603807bSTomohiro Kusumi static int dmtc_crypto_cb_write_done(struct cryptop *crp); 174*f603807bSTomohiro Kusumi 175*f603807bSTomohiro Kusumi static ivgen_ctor_t essiv_ivgen_ctor; 176*f603807bSTomohiro Kusumi static ivgen_dtor_t essiv_ivgen_dtor; 177*f603807bSTomohiro Kusumi static ivgen_t essiv_ivgen; 178*f603807bSTomohiro Kusumi static ivgen_t plain_ivgen; 179*f603807bSTomohiro Kusumi static ivgen_t plain64_ivgen; 180*f603807bSTomohiro Kusumi 181*f603807bSTomohiro Kusumi static struct iv_generator ivgens[] = { 182*f603807bSTomohiro Kusumi { .name = "essiv", .ctor = essiv_ivgen_ctor, .dtor = essiv_ivgen_dtor, 183*f603807bSTomohiro Kusumi .gen_iv = essiv_ivgen }, 184*f603807bSTomohiro Kusumi { .name = "plain", .ctor = NULL, .dtor = NULL, .gen_iv = plain_ivgen }, 185*f603807bSTomohiro Kusumi { .name = "plain64", .ctor = NULL, .dtor = NULL, .gen_iv = plain64_ivgen }, 186*f603807bSTomohiro Kusumi { NULL, NULL, NULL, NULL } 187*f603807bSTomohiro Kusumi }; 188*f603807bSTomohiro Kusumi 189*f603807bSTomohiro Kusumi struct objcache_malloc_args essiv_ivgen_malloc_args = { 190*f603807bSTomohiro Kusumi 2*sizeof(void *) + (sizeof(struct cryptodesc) + 191*f603807bSTomohiro Kusumi sizeof(struct cryptop)), M_DMCRYPT }; 192*f603807bSTomohiro Kusumi 193*f603807bSTomohiro Kusumi static void 194*f603807bSTomohiro Kusumi dmtc_init_mpipe(struct target_crypt_config *priv) 195*f603807bSTomohiro Kusumi { 196*f603807bSTomohiro Kusumi int nmax; 197*f603807bSTomohiro Kusumi 198*f603807bSTomohiro Kusumi nmax = (physmem*2/1000*PAGE_SIZE)/(DMTC_BUF_SIZE_WRITE + DMTC_BUF_SIZE_READ) + 1; 199*f603807bSTomohiro Kusumi 200*f603807bSTomohiro Kusumi if (nmax < 2) 201*f603807bSTomohiro Kusumi nmax = 2; 202*f603807bSTomohiro Kusumi 203*f603807bSTomohiro Kusumi kprintf("dm_target_crypt: Setting min/max mpipe buffers: %d/%d\n", 2, nmax); 204*f603807bSTomohiro Kusumi 205*f603807bSTomohiro Kusumi mpipe_init(&priv->write_mpipe, M_DMCRYPT, DMTC_BUF_SIZE_WRITE, 206*f603807bSTomohiro Kusumi 2, nmax, MPF_NOZERO | MPF_CALLBACK, NULL, NULL, NULL); 207*f603807bSTomohiro Kusumi mpipe_init(&priv->read_mpipe, M_DMCRYPT, DMTC_BUF_SIZE_READ, 208*f603807bSTomohiro Kusumi 2, nmax, MPF_NOZERO | MPF_CALLBACK, NULL, NULL, NULL); 209*f603807bSTomohiro Kusumi } 210*f603807bSTomohiro Kusumi 211*f603807bSTomohiro Kusumi static void 212*f603807bSTomohiro Kusumi dmtc_destroy_mpipe(struct target_crypt_config *priv) 213*f603807bSTomohiro Kusumi { 214*f603807bSTomohiro Kusumi mpipe_done(&priv->write_mpipe); 215*f603807bSTomohiro Kusumi mpipe_done(&priv->read_mpipe); 216*f603807bSTomohiro Kusumi } 217*f603807bSTomohiro Kusumi 218*f603807bSTomohiro Kusumi /* 219*f603807bSTomohiro Kusumi * Overwrite private information (in buf) to avoid leaking it 220*f603807bSTomohiro Kusumi */ 221*f603807bSTomohiro Kusumi static void 222*f603807bSTomohiro Kusumi dmtc_crypto_clear(void *buf, size_t len) 223*f603807bSTomohiro Kusumi { 224*f603807bSTomohiro Kusumi memset(buf, 0xFF, len); 225*f603807bSTomohiro Kusumi bzero(buf, len); 226*f603807bSTomohiro Kusumi } 227*f603807bSTomohiro Kusumi 228*f603807bSTomohiro Kusumi /* 229*f603807bSTomohiro Kusumi * ESSIV IV Generator Routines 230*f603807bSTomohiro Kusumi */ 231*f603807bSTomohiro Kusumi static int 232*f603807bSTomohiro Kusumi essiv_ivgen_ctor(struct target_crypt_config *priv, char *iv_hash, void **p_ivpriv) 233*f603807bSTomohiro Kusumi { 234*f603807bSTomohiro Kusumi struct essiv_ivgen_priv *ivpriv; 235*f603807bSTomohiro Kusumi u_int8_t crypto_keyhash[SHA512_DIGEST_LENGTH]; 236*f603807bSTomohiro Kusumi unsigned int klen, hashlen; 237*f603807bSTomohiro Kusumi int error; 238*f603807bSTomohiro Kusumi 239*f603807bSTomohiro Kusumi klen = (priv->crypto_klen >> 3); 240*f603807bSTomohiro Kusumi 241*f603807bSTomohiro Kusumi if (iv_hash == NULL) 242*f603807bSTomohiro Kusumi return EINVAL; 243*f603807bSTomohiro Kusumi 244*f603807bSTomohiro Kusumi if (!strcmp(iv_hash, "sha1")) { 245*f603807bSTomohiro Kusumi SHA1_CTX ctx; 246*f603807bSTomohiro Kusumi 247*f603807bSTomohiro Kusumi hashlen = SHA1_RESULTLEN; 248*f603807bSTomohiro Kusumi SHA1Init(&ctx); 249*f603807bSTomohiro Kusumi SHA1Update(&ctx, priv->crypto_key, klen); 250*f603807bSTomohiro Kusumi SHA1Final(crypto_keyhash, &ctx); 251*f603807bSTomohiro Kusumi } else if (!strcmp(iv_hash, "sha256")) { 252*f603807bSTomohiro Kusumi SHA256_CTX ctx; 253*f603807bSTomohiro Kusumi 254*f603807bSTomohiro Kusumi hashlen = SHA256_DIGEST_LENGTH; 255*f603807bSTomohiro Kusumi SHA256_Init(&ctx); 256*f603807bSTomohiro Kusumi SHA256_Update(&ctx, priv->crypto_key, klen); 257*f603807bSTomohiro Kusumi SHA256_Final(crypto_keyhash, &ctx); 258*f603807bSTomohiro Kusumi } else if (!strcmp(iv_hash, "sha384")) { 259*f603807bSTomohiro Kusumi SHA384_CTX ctx; 260*f603807bSTomohiro Kusumi 261*f603807bSTomohiro Kusumi hashlen = SHA384_DIGEST_LENGTH; 262*f603807bSTomohiro Kusumi SHA384_Init(&ctx); 263*f603807bSTomohiro Kusumi SHA384_Update(&ctx, priv->crypto_key, klen); 264*f603807bSTomohiro Kusumi SHA384_Final(crypto_keyhash, &ctx); 265*f603807bSTomohiro Kusumi } else if (!strcmp(iv_hash, "sha512")) { 266*f603807bSTomohiro Kusumi SHA512_CTX ctx; 267*f603807bSTomohiro Kusumi 268*f603807bSTomohiro Kusumi hashlen = SHA512_DIGEST_LENGTH; 269*f603807bSTomohiro Kusumi SHA512_Init(&ctx); 270*f603807bSTomohiro Kusumi SHA512_Update(&ctx, priv->crypto_key, klen); 271*f603807bSTomohiro Kusumi SHA512_Final(crypto_keyhash, &ctx); 272*f603807bSTomohiro Kusumi } else if (!strcmp(iv_hash, "md5")) { 273*f603807bSTomohiro Kusumi MD5_CTX ctx; 274*f603807bSTomohiro Kusumi 275*f603807bSTomohiro Kusumi hashlen = MD5_DIGEST_LENGTH; 276*f603807bSTomohiro Kusumi MD5Init(&ctx); 277*f603807bSTomohiro Kusumi MD5Update(&ctx, priv->crypto_key, klen); 278*f603807bSTomohiro Kusumi MD5Final(crypto_keyhash, &ctx); 279*f603807bSTomohiro Kusumi } else if (!strcmp(iv_hash, "rmd160") || 280*f603807bSTomohiro Kusumi !strcmp(iv_hash, "ripemd160")) { 281*f603807bSTomohiro Kusumi RMD160_CTX ctx; 282*f603807bSTomohiro Kusumi 283*f603807bSTomohiro Kusumi hashlen = 160/8; 284*f603807bSTomohiro Kusumi RMD160Init(&ctx); 285*f603807bSTomohiro Kusumi RMD160Update(&ctx, priv->crypto_key, klen); 286*f603807bSTomohiro Kusumi RMD160Final(crypto_keyhash, &ctx); 287*f603807bSTomohiro Kusumi } else { 288*f603807bSTomohiro Kusumi return EINVAL; 289*f603807bSTomohiro Kusumi } 290*f603807bSTomohiro Kusumi 291*f603807bSTomohiro Kusumi /* Convert hashlen to bits */ 292*f603807bSTomohiro Kusumi hashlen <<= 3; 293*f603807bSTomohiro Kusumi 294*f603807bSTomohiro Kusumi ivpriv = kmalloc(sizeof(struct essiv_ivgen_priv), M_DMCRYPT, 295*f603807bSTomohiro Kusumi M_WAITOK | M_ZERO); 296*f603807bSTomohiro Kusumi memcpy(ivpriv->crypto_keyhash, crypto_keyhash, sizeof(crypto_keyhash)); 297*f603807bSTomohiro Kusumi ivpriv->keyhash_len = sizeof(crypto_keyhash); 298*f603807bSTomohiro Kusumi dmtc_crypto_clear(crypto_keyhash, sizeof(crypto_keyhash)); 299*f603807bSTomohiro Kusumi 300*f603807bSTomohiro Kusumi ivpriv->crypto_session.cri_alg = priv->crypto_alg; 301*f603807bSTomohiro Kusumi ivpriv->crypto_session.cri_key = (u_int8_t *)ivpriv->crypto_keyhash; 302*f603807bSTomohiro Kusumi ivpriv->crypto_session.cri_klen = hashlen; 303*f603807bSTomohiro Kusumi ivpriv->crypto_session.cri_mlen = 0; 304*f603807bSTomohiro Kusumi ivpriv->crypto_session.cri_next = NULL; 305*f603807bSTomohiro Kusumi 306*f603807bSTomohiro Kusumi /* 307*f603807bSTomohiro Kusumi * XXX: in principle we also need to check if the block size of the 308*f603807bSTomohiro Kusumi * cipher is a valid iv size for the block cipher. 309*f603807bSTomohiro Kusumi */ 310*f603807bSTomohiro Kusumi 311*f603807bSTomohiro Kusumi error = crypto_newsession(&ivpriv->crypto_sid, 312*f603807bSTomohiro Kusumi &ivpriv->crypto_session, 313*f603807bSTomohiro Kusumi CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE); 314*f603807bSTomohiro Kusumi if (error) { 315*f603807bSTomohiro Kusumi kprintf("dm_target_crypt: Error during crypto_newsession " 316*f603807bSTomohiro Kusumi "for essiv_ivgen, error = %d\n", 317*f603807bSTomohiro Kusumi error); 318*f603807bSTomohiro Kusumi dmtc_crypto_clear(ivpriv->crypto_keyhash, ivpriv->keyhash_len); 319*f603807bSTomohiro Kusumi kfree(ivpriv, M_DMCRYPT); 320*f603807bSTomohiro Kusumi return ENOTSUP; 321*f603807bSTomohiro Kusumi } 322*f603807bSTomohiro Kusumi 323*f603807bSTomohiro Kusumi ivpriv->crp_crd_cache = objcache_create( 324*f603807bSTomohiro Kusumi "dmcrypt-essiv-cache", 0, 0, 325*f603807bSTomohiro Kusumi NULL, NULL, NULL, 326*f603807bSTomohiro Kusumi objcache_malloc_alloc, 327*f603807bSTomohiro Kusumi objcache_malloc_free, 328*f603807bSTomohiro Kusumi &essiv_ivgen_malloc_args ); 329*f603807bSTomohiro Kusumi 330*f603807bSTomohiro Kusumi *p_ivpriv = ivpriv; 331*f603807bSTomohiro Kusumi return 0; 332*f603807bSTomohiro Kusumi } 333*f603807bSTomohiro Kusumi 334*f603807bSTomohiro Kusumi static int 335*f603807bSTomohiro Kusumi essiv_ivgen_dtor(struct target_crypt_config *priv, void *arg) 336*f603807bSTomohiro Kusumi { 337*f603807bSTomohiro Kusumi struct essiv_ivgen_priv *ivpriv; 338*f603807bSTomohiro Kusumi 339*f603807bSTomohiro Kusumi ivpriv = (struct essiv_ivgen_priv *)arg; 340*f603807bSTomohiro Kusumi KKASSERT(ivpriv != NULL); 341*f603807bSTomohiro Kusumi 342*f603807bSTomohiro Kusumi crypto_freesession(ivpriv->crypto_sid); 343*f603807bSTomohiro Kusumi 344*f603807bSTomohiro Kusumi objcache_destroy(ivpriv->crp_crd_cache); 345*f603807bSTomohiro Kusumi 346*f603807bSTomohiro Kusumi dmtc_crypto_clear(ivpriv->crypto_keyhash, ivpriv->keyhash_len); 347*f603807bSTomohiro Kusumi kfree(ivpriv, M_DMCRYPT); 348*f603807bSTomohiro Kusumi 349*f603807bSTomohiro Kusumi return 0; 350*f603807bSTomohiro Kusumi } 351*f603807bSTomohiro Kusumi 352*f603807bSTomohiro Kusumi static int 353*f603807bSTomohiro Kusumi essiv_ivgen_done(struct cryptop *crp) 354*f603807bSTomohiro Kusumi { 355*f603807bSTomohiro Kusumi struct essiv_ivgen_priv *ivpriv; 356*f603807bSTomohiro Kusumi void *free_addr; 357*f603807bSTomohiro Kusumi void *opaque; 358*f603807bSTomohiro Kusumi 359*f603807bSTomohiro Kusumi 360*f603807bSTomohiro Kusumi if (crp->crp_etype == EAGAIN) 361*f603807bSTomohiro Kusumi return crypto_dispatch(crp); 362*f603807bSTomohiro Kusumi 363*f603807bSTomohiro Kusumi if (crp->crp_etype != 0) { 364*f603807bSTomohiro Kusumi kprintf("dm_target_crypt: essiv_ivgen_done, " 365*f603807bSTomohiro Kusumi "crp->crp_etype = %d\n", crp->crp_etype); 366*f603807bSTomohiro Kusumi } 367*f603807bSTomohiro Kusumi 368*f603807bSTomohiro Kusumi free_addr = crp->crp_opaque; 369*f603807bSTomohiro Kusumi /* 370*f603807bSTomohiro Kusumi * In-memory structure is: 371*f603807bSTomohiro Kusumi * | ivpriv | opaque | crp | crd | 372*f603807bSTomohiro Kusumi * | (void *) | (void *) | (cryptop) | (cryptodesc) | 373*f603807bSTomohiro Kusumi */ 374*f603807bSTomohiro Kusumi ivpriv = *((struct essiv_ivgen_priv **)crp->crp_opaque); 375*f603807bSTomohiro Kusumi crp->crp_opaque += sizeof(void *); 376*f603807bSTomohiro Kusumi opaque = *((void **)crp->crp_opaque); 377*f603807bSTomohiro Kusumi 378*f603807bSTomohiro Kusumi objcache_put(ivpriv->crp_crd_cache, free_addr); 379*f603807bSTomohiro Kusumi dmtc_crypto_dispatch(opaque); 380*f603807bSTomohiro Kusumi return 0; 381*f603807bSTomohiro Kusumi } 382*f603807bSTomohiro Kusumi 383*f603807bSTomohiro Kusumi static void 384*f603807bSTomohiro Kusumi essiv_ivgen(dm_target_crypt_config_t *priv, u_int8_t *iv, 385*f603807bSTomohiro Kusumi size_t iv_len, off_t sector, void *opaque) 386*f603807bSTomohiro Kusumi { 387*f603807bSTomohiro Kusumi struct essiv_ivgen_priv *ivpriv; 388*f603807bSTomohiro Kusumi struct cryptodesc *crd; 389*f603807bSTomohiro Kusumi struct cryptop *crp; 390*f603807bSTomohiro Kusumi caddr_t space, alloc_addr; 391*f603807bSTomohiro Kusumi int error; 392*f603807bSTomohiro Kusumi 393*f603807bSTomohiro Kusumi ivpriv = priv->ivgen_priv; 394*f603807bSTomohiro Kusumi KKASSERT(ivpriv != NULL); 395*f603807bSTomohiro Kusumi 396*f603807bSTomohiro Kusumi /* 397*f603807bSTomohiro Kusumi * In-memory structure is: 398*f603807bSTomohiro Kusumi * | ivpriv | opaque | crp | crd | 399*f603807bSTomohiro Kusumi * | (void *) | (void *) | (cryptop) | (cryptodesc) | 400*f603807bSTomohiro Kusumi */ 401*f603807bSTomohiro Kusumi alloc_addr = space = objcache_get(ivpriv->crp_crd_cache, M_WAITOK); 402*f603807bSTomohiro Kusumi *((struct essiv_ivgen_priv **)space) = ivpriv; 403*f603807bSTomohiro Kusumi space += sizeof(void *); 404*f603807bSTomohiro Kusumi *((void **)space) = opaque; 405*f603807bSTomohiro Kusumi space += sizeof(void *); 406*f603807bSTomohiro Kusumi crp = (struct cryptop *)space; 407*f603807bSTomohiro Kusumi space += sizeof(struct cryptop); 408*f603807bSTomohiro Kusumi crd = (struct cryptodesc *)space; 409*f603807bSTomohiro Kusumi 410*f603807bSTomohiro Kusumi bzero(iv, iv_len); 411*f603807bSTomohiro Kusumi bzero(crd, sizeof(struct cryptodesc)); 412*f603807bSTomohiro Kusumi bzero(crp, sizeof(struct cryptop)); 413*f603807bSTomohiro Kusumi *((off_t *)iv) = htole64(sector + priv->iv_offset); 414*f603807bSTomohiro Kusumi crp->crp_buf = (caddr_t)iv; 415*f603807bSTomohiro Kusumi 416*f603807bSTomohiro Kusumi crp->crp_sid = ivpriv->crypto_sid; 417*f603807bSTomohiro Kusumi crp->crp_ilen = crp->crp_olen = iv_len; 418*f603807bSTomohiro Kusumi 419*f603807bSTomohiro Kusumi crp->crp_opaque = alloc_addr; 420*f603807bSTomohiro Kusumi 421*f603807bSTomohiro Kusumi crp->crp_callback = essiv_ivgen_done; 422*f603807bSTomohiro Kusumi 423*f603807bSTomohiro Kusumi crp->crp_desc = crd; 424*f603807bSTomohiro Kusumi crp->crp_etype = 0; 425*f603807bSTomohiro Kusumi crp->crp_flags = CRYPTO_F_CBIFSYNC | CRYPTO_F_REL | CRYPTO_F_BATCH; 426*f603807bSTomohiro Kusumi 427*f603807bSTomohiro Kusumi crd->crd_alg = priv->crypto_alg; 428*f603807bSTomohiro Kusumi #if 0 429*f603807bSTomohiro Kusumi crd->crd_key = (caddr_t)priv->crypto_keyhash; 430*f603807bSTomohiro Kusumi crd->crd_klen = priv->crypto_klen; 431*f603807bSTomohiro Kusumi #endif 432*f603807bSTomohiro Kusumi 433*f603807bSTomohiro Kusumi bzero(crd->crd_iv, sizeof(crd->crd_iv)); 434*f603807bSTomohiro Kusumi 435*f603807bSTomohiro Kusumi crd->crd_skip = 0; 436*f603807bSTomohiro Kusumi crd->crd_len = iv_len; 437*f603807bSTomohiro Kusumi crd->crd_flags = CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT; 438*f603807bSTomohiro Kusumi crd->crd_flags |= CRD_F_ENCRYPT; 439*f603807bSTomohiro Kusumi crd->crd_next = NULL; 440*f603807bSTomohiro Kusumi 441*f603807bSTomohiro Kusumi error = crypto_dispatch(crp); 442*f603807bSTomohiro Kusumi if (error) 443*f603807bSTomohiro Kusumi kprintf("dm_target_crypt: essiv_ivgen, error = %d\n", error); 444*f603807bSTomohiro Kusumi } 445*f603807bSTomohiro Kusumi 446*f603807bSTomohiro Kusumi 447*f603807bSTomohiro Kusumi static void 448*f603807bSTomohiro Kusumi plain_ivgen(dm_target_crypt_config_t *priv, u_int8_t *iv, 449*f603807bSTomohiro Kusumi size_t iv_len, off_t sector, void *opaque) 450*f603807bSTomohiro Kusumi { 451*f603807bSTomohiro Kusumi bzero(iv, iv_len); 452*f603807bSTomohiro Kusumi *((uint32_t *)iv) = htole32((uint32_t)(sector + priv->iv_offset)); 453*f603807bSTomohiro Kusumi dmtc_crypto_dispatch(opaque); 454*f603807bSTomohiro Kusumi } 455*f603807bSTomohiro Kusumi 456*f603807bSTomohiro Kusumi static void 457*f603807bSTomohiro Kusumi plain64_ivgen(dm_target_crypt_config_t *priv, u_int8_t *iv, 458*f603807bSTomohiro Kusumi size_t iv_len, off_t sector, void *opaque) 459*f603807bSTomohiro Kusumi { 460*f603807bSTomohiro Kusumi bzero(iv, iv_len); 461*f603807bSTomohiro Kusumi *((uint64_t *)iv) = htole64((uint64_t)(sector + priv->iv_offset)); 462*f603807bSTomohiro Kusumi dmtc_crypto_dispatch(opaque); 463*f603807bSTomohiro Kusumi } 464*f603807bSTomohiro Kusumi 465*f603807bSTomohiro Kusumi #if 0 466*f603807bSTomohiro Kusumi static void 467*f603807bSTomohiro Kusumi geli_ivgen(dm_target_crypt_config_t *priv, u_int8_t *iv, 468*f603807bSTomohiro Kusumi size_t iv_len, off_t sector, void *opaque) 469*f603807bSTomohiro Kusumi { 470*f603807bSTomohiro Kusumi 471*f603807bSTomohiro Kusumi SHA512_CTX ctx512; 472*f603807bSTomohiro Kusumi u_int8_t md[SHA512_DIGEST_LENGTH]; /* Max. Digest Size */ 473*f603807bSTomohiro Kusumi 474*f603807bSTomohiro Kusumi memcpy(&ctx512, &priv->essivsha512_ctx, sizeof(SHA512_CTX)); 475*f603807bSTomohiro Kusumi SHA512_Update(&ctx512, (u_int8_t*)§or, sizeof(off_t)); 476*f603807bSTomohiro Kusumi SHA512_Final(md, &ctx512); 477*f603807bSTomohiro Kusumi 478*f603807bSTomohiro Kusumi memcpy(iv, md, iv_len); 479*f603807bSTomohiro Kusumi dmtc_crypto_dispatch(opaque); 480*f603807bSTomohiro Kusumi } 481*f603807bSTomohiro Kusumi #endif 482*f603807bSTomohiro Kusumi 483*f603807bSTomohiro Kusumi /* 484*f603807bSTomohiro Kusumi * Init function called from dm_table_load_ioctl. 485*f603807bSTomohiro Kusumi * cryptsetup actually passes us this: 486*f603807bSTomohiro Kusumi * aes-cbc-essiv:sha256 7997f8af... 0 /dev/ad0s0a 8 487*f603807bSTomohiro Kusumi */ 488*f603807bSTomohiro Kusumi static int 489*f603807bSTomohiro Kusumi hex2key(char *hex, size_t key_len, u_int8_t *key) 490*f603807bSTomohiro Kusumi { 491*f603807bSTomohiro Kusumi char hex_buf[3]; 492*f603807bSTomohiro Kusumi size_t key_idx; 493*f603807bSTomohiro Kusumi 494*f603807bSTomohiro Kusumi hex_buf[2] = 0; 495*f603807bSTomohiro Kusumi for (key_idx = 0; key_idx < key_len; ++key_idx) { 496*f603807bSTomohiro Kusumi hex_buf[0] = *hex++; 497*f603807bSTomohiro Kusumi hex_buf[1] = *hex++; 498*f603807bSTomohiro Kusumi key[key_idx] = (u_int8_t)strtoul(hex_buf, NULL, 16); 499*f603807bSTomohiro Kusumi } 500*f603807bSTomohiro Kusumi hex_buf[0] = 0; 501*f603807bSTomohiro Kusumi hex_buf[1] = 0; 502*f603807bSTomohiro Kusumi 503*f603807bSTomohiro Kusumi return 0; 504*f603807bSTomohiro Kusumi } 505*f603807bSTomohiro Kusumi 506*f603807bSTomohiro Kusumi static int 507*f603807bSTomohiro Kusumi dm_target_crypt_init(dm_table_entry_t *table_en, int argc, char **argv) 508*f603807bSTomohiro Kusumi { 509*f603807bSTomohiro Kusumi dm_target_crypt_config_t *priv; 510*f603807bSTomohiro Kusumi size_t len; 511*f603807bSTomohiro Kusumi char *crypto_alg, *crypto_mode, *iv_mode, *iv_opt, *key, *dev; 512*f603807bSTomohiro Kusumi char *status_str; 513*f603807bSTomohiro Kusumi int i, klen, error; 514*f603807bSTomohiro Kusumi uint64_t iv_offset, block_offset; 515*f603807bSTomohiro Kusumi 516*f603807bSTomohiro Kusumi if (argc != 5) { 517*f603807bSTomohiro Kusumi kprintf("dm_target_crypt: not enough arguments, " 518*f603807bSTomohiro Kusumi "need exactly 5\n"); 519*f603807bSTomohiro Kusumi return EINVAL; 520*f603807bSTomohiro Kusumi } 521*f603807bSTomohiro Kusumi 522*f603807bSTomohiro Kusumi len = 0; 523*f603807bSTomohiro Kusumi for (i = 0; i < argc; i++) { 524*f603807bSTomohiro Kusumi len += strlen(argv[i]); 525*f603807bSTomohiro Kusumi len++; 526*f603807bSTomohiro Kusumi } 527*f603807bSTomohiro Kusumi /* len is strlen() of input string +1 */ 528*f603807bSTomohiro Kusumi status_str = kmalloc(len, M_DMCRYPT, M_WAITOK); 529*f603807bSTomohiro Kusumi 530*f603807bSTomohiro Kusumi crypto_alg = strsep(&argv[0], "-"); 531*f603807bSTomohiro Kusumi crypto_mode = strsep(&argv[0], "-"); 532*f603807bSTomohiro Kusumi iv_opt = strsep(&argv[0], "-"); 533*f603807bSTomohiro Kusumi iv_mode = strsep(&iv_opt, ":"); 534*f603807bSTomohiro Kusumi key = argv[1]; 535*f603807bSTomohiro Kusumi iv_offset = strtouq(argv[2], NULL, 0); 536*f603807bSTomohiro Kusumi dev = argv[3]; 537*f603807bSTomohiro Kusumi block_offset = strtouq(argv[4], NULL, 0); 538*f603807bSTomohiro Kusumi /* bits / 8 = bytes, 1 byte = 2 hexa chars, so << 2 */ 539*f603807bSTomohiro Kusumi klen = strlen(key) << 2; 540*f603807bSTomohiro Kusumi 541*f603807bSTomohiro Kusumi #if 0 542*f603807bSTomohiro Kusumi kprintf("dm_target_crypt - new: dev=%s, crypto_alg=%s, crypto_mode=%s, " 543*f603807bSTomohiro Kusumi "iv_mode=%s, iv_opt=%s, key=%s, iv_offset=%ju, " 544*f603807bSTomohiro Kusumi "block_offset=%ju\n", 545*f603807bSTomohiro Kusumi dev, crypto_alg, crypto_mode, iv_mode, iv_opt, key, iv_offset, 546*f603807bSTomohiro Kusumi block_offset); 547*f603807bSTomohiro Kusumi #endif 548*f603807bSTomohiro Kusumi 549*f603807bSTomohiro Kusumi priv = kmalloc(sizeof(dm_target_crypt_config_t), M_DMCRYPT, M_WAITOK); 550*f603807bSTomohiro Kusumi 551*f603807bSTomohiro Kusumi /* Insert dmp to global pdev list */ 552*f603807bSTomohiro Kusumi if ((priv->pdev = dm_pdev_insert(dev)) == NULL) { 553*f603807bSTomohiro Kusumi kprintf("dm_target_crypt: dm_pdev_insert failed\n"); 554*f603807bSTomohiro Kusumi kfree(status_str, M_DMCRYPT); 555*f603807bSTomohiro Kusumi return ENOENT; 556*f603807bSTomohiro Kusumi } 557*f603807bSTomohiro Kusumi 558*f603807bSTomohiro Kusumi /* 559*f603807bSTomohiro Kusumi * This code checks for valid combinations of algorithm and mode. 560*f603807bSTomohiro Kusumi * Currently supported options are: 561*f603807bSTomohiro Kusumi * 562*f603807bSTomohiro Kusumi * *-cbc 563*f603807bSTomohiro Kusumi * aes-xts 564*f603807bSTomohiro Kusumi * twofish-xts 565*f603807bSTomohiro Kusumi * serpent-xts 566*f603807bSTomohiro Kusumi */ 567*f603807bSTomohiro Kusumi if ((strcmp(crypto_mode, "cbc") != 0) && 568*f603807bSTomohiro Kusumi !((strcmp(crypto_mode, "xts") == 0) && 569*f603807bSTomohiro Kusumi ((strcmp(crypto_alg, "aes") == 0) || 570*f603807bSTomohiro Kusumi (strcmp(crypto_alg, "twofish") == 0) || 571*f603807bSTomohiro Kusumi (strcmp(crypto_alg, "serpent") == 0)))) 572*f603807bSTomohiro Kusumi { 573*f603807bSTomohiro Kusumi kprintf("dm_target_crypt: only support 'cbc' chaining mode," 574*f603807bSTomohiro Kusumi " aes-xts, twofish-xts and serpent-xts, " 575*f603807bSTomohiro Kusumi "invalid mode '%s-%s'\n", 576*f603807bSTomohiro Kusumi crypto_alg, crypto_mode); 577*f603807bSTomohiro Kusumi goto notsup; 578*f603807bSTomohiro Kusumi } 579*f603807bSTomohiro Kusumi 580*f603807bSTomohiro Kusumi if (!strcmp(crypto_alg, "aes")) { 581*f603807bSTomohiro Kusumi if (!strcmp(crypto_mode, "xts")) { 582*f603807bSTomohiro Kusumi priv->crypto_alg = CRYPTO_AES_XTS; 583*f603807bSTomohiro Kusumi if (klen != 256 && klen != 512) 584*f603807bSTomohiro Kusumi goto notsup; 585*f603807bSTomohiro Kusumi } else if (!strcmp(crypto_mode, "cbc")) { 586*f603807bSTomohiro Kusumi priv->crypto_alg = CRYPTO_AES_CBC; 587*f603807bSTomohiro Kusumi if (klen != 128 && klen != 192 && klen != 256) 588*f603807bSTomohiro Kusumi goto notsup; 589*f603807bSTomohiro Kusumi } else { 590*f603807bSTomohiro Kusumi goto notsup; 591*f603807bSTomohiro Kusumi } 592*f603807bSTomohiro Kusumi priv->crypto_klen = klen; 593*f603807bSTomohiro Kusumi } else if (!strcmp(crypto_alg, "twofish")) { 594*f603807bSTomohiro Kusumi if (!strcmp(crypto_mode, "xts")) { 595*f603807bSTomohiro Kusumi priv->crypto_alg = CRYPTO_TWOFISH_XTS; 596*f603807bSTomohiro Kusumi if (klen != 256 && klen != 512) 597*f603807bSTomohiro Kusumi goto notsup; 598*f603807bSTomohiro Kusumi } else if (!strcmp(crypto_mode, "cbc")) { 599*f603807bSTomohiro Kusumi priv->crypto_alg = CRYPTO_TWOFISH_CBC; 600*f603807bSTomohiro Kusumi if (klen != 128 && klen != 192 && klen != 256) 601*f603807bSTomohiro Kusumi goto notsup; 602*f603807bSTomohiro Kusumi } else { 603*f603807bSTomohiro Kusumi goto notsup; 604*f603807bSTomohiro Kusumi } 605*f603807bSTomohiro Kusumi priv->crypto_klen = klen; 606*f603807bSTomohiro Kusumi } else if (!strcmp(crypto_alg, "serpent")) { 607*f603807bSTomohiro Kusumi if (!strcmp(crypto_mode, "xts")) { 608*f603807bSTomohiro Kusumi priv->crypto_alg = CRYPTO_SERPENT_XTS; 609*f603807bSTomohiro Kusumi if (klen != 256 && klen != 512) 610*f603807bSTomohiro Kusumi goto notsup; 611*f603807bSTomohiro Kusumi } else if (!strcmp(crypto_mode, "cbc")) { 612*f603807bSTomohiro Kusumi priv->crypto_alg = CRYPTO_SERPENT_CBC; 613*f603807bSTomohiro Kusumi if (klen != 128 && klen != 192 && klen != 256) 614*f603807bSTomohiro Kusumi goto notsup; 615*f603807bSTomohiro Kusumi } else { 616*f603807bSTomohiro Kusumi goto notsup; 617*f603807bSTomohiro Kusumi } 618*f603807bSTomohiro Kusumi priv->crypto_klen = klen; 619*f603807bSTomohiro Kusumi } else if (!strcmp(crypto_alg, "blowfish")) { 620*f603807bSTomohiro Kusumi priv->crypto_alg = CRYPTO_BLF_CBC; 621*f603807bSTomohiro Kusumi if (klen < 128 || klen > 448 || (klen % 8) != 0) 622*f603807bSTomohiro Kusumi goto notsup; 623*f603807bSTomohiro Kusumi priv->crypto_klen = klen; 624*f603807bSTomohiro Kusumi } else if (!strcmp(crypto_alg, "3des") || 625*f603807bSTomohiro Kusumi !strncmp(crypto_alg, "des3", 4)) { 626*f603807bSTomohiro Kusumi priv->crypto_alg = CRYPTO_3DES_CBC; 627*f603807bSTomohiro Kusumi if (klen != 168) 628*f603807bSTomohiro Kusumi goto notsup; 629*f603807bSTomohiro Kusumi priv->crypto_klen = 168; 630*f603807bSTomohiro Kusumi } else if (!strcmp(crypto_alg, "camellia")) { 631*f603807bSTomohiro Kusumi priv->crypto_alg = CRYPTO_CAMELLIA_CBC; 632*f603807bSTomohiro Kusumi if (klen != 128 && klen != 192 && klen != 256) 633*f603807bSTomohiro Kusumi goto notsup; 634*f603807bSTomohiro Kusumi priv->crypto_klen = klen; 635*f603807bSTomohiro Kusumi } else if (!strcmp(crypto_alg, "skipjack")) { 636*f603807bSTomohiro Kusumi priv->crypto_alg = CRYPTO_SKIPJACK_CBC; 637*f603807bSTomohiro Kusumi if (klen != 80) 638*f603807bSTomohiro Kusumi goto notsup; 639*f603807bSTomohiro Kusumi priv->crypto_klen = 80; 640*f603807bSTomohiro Kusumi } else if (!strcmp(crypto_alg, "cast5")) { 641*f603807bSTomohiro Kusumi priv->crypto_alg = CRYPTO_CAST_CBC; 642*f603807bSTomohiro Kusumi if (klen != 128) 643*f603807bSTomohiro Kusumi goto notsup; 644*f603807bSTomohiro Kusumi priv->crypto_klen = 128; 645*f603807bSTomohiro Kusumi } else if (!strcmp(crypto_alg, "null")) { 646*f603807bSTomohiro Kusumi priv->crypto_alg = CRYPTO_NULL_CBC; 647*f603807bSTomohiro Kusumi if (klen != 128) 648*f603807bSTomohiro Kusumi goto notsup; 649*f603807bSTomohiro Kusumi priv->crypto_klen = 128; 650*f603807bSTomohiro Kusumi } else { 651*f603807bSTomohiro Kusumi kprintf("dm_target_crypt: Unsupported crypto algorithm: %s\n", 652*f603807bSTomohiro Kusumi crypto_alg); 653*f603807bSTomohiro Kusumi goto notsup; 654*f603807bSTomohiro Kusumi } 655*f603807bSTomohiro Kusumi 656*f603807bSTomohiro Kusumi /* Save length of param string */ 657*f603807bSTomohiro Kusumi priv->params_len = len; 658*f603807bSTomohiro Kusumi priv->block_offset = block_offset; 659*f603807bSTomohiro Kusumi priv->iv_offset = iv_offset - block_offset; 660*f603807bSTomohiro Kusumi 661*f603807bSTomohiro Kusumi dm_table_add_deps(table_en, priv->pdev); 662*f603807bSTomohiro Kusumi 663*f603807bSTomohiro Kusumi dm_table_init_target(table_en, DM_CRYPTO_DEV, priv); 664*f603807bSTomohiro Kusumi 665*f603807bSTomohiro Kusumi error = hex2key(key, priv->crypto_klen >> 3, 666*f603807bSTomohiro Kusumi (u_int8_t *)priv->crypto_key); 667*f603807bSTomohiro Kusumi 668*f603807bSTomohiro Kusumi if (error) { 669*f603807bSTomohiro Kusumi kprintf("dm_target_crypt: hex2key failed, " 670*f603807bSTomohiro Kusumi "invalid key format\n"); 671*f603807bSTomohiro Kusumi goto notsup; 672*f603807bSTomohiro Kusumi } 673*f603807bSTomohiro Kusumi 674*f603807bSTomohiro Kusumi /* Handle cmd */ 675*f603807bSTomohiro Kusumi for(i = 0; ivgens[i].name != NULL; i++) { 676*f603807bSTomohiro Kusumi if (!strcmp(iv_mode, ivgens[i].name)) 677*f603807bSTomohiro Kusumi break; 678*f603807bSTomohiro Kusumi } 679*f603807bSTomohiro Kusumi 680*f603807bSTomohiro Kusumi if (ivgens[i].name == NULL) { 681*f603807bSTomohiro Kusumi kprintf("dm_target_crypt: iv_mode='%s' unsupported\n", 682*f603807bSTomohiro Kusumi iv_mode); 683*f603807bSTomohiro Kusumi goto notsup; 684*f603807bSTomohiro Kusumi } 685*f603807bSTomohiro Kusumi 686*f603807bSTomohiro Kusumi /* Call our ivgen constructor */ 687*f603807bSTomohiro Kusumi if (ivgens[i].ctor != NULL) { 688*f603807bSTomohiro Kusumi error = ivgens[i].ctor(priv, iv_opt, 689*f603807bSTomohiro Kusumi &priv->ivgen_priv); 690*f603807bSTomohiro Kusumi if (error) { 691*f603807bSTomohiro Kusumi kprintf("dm_target_crypt: ctor for '%s' failed\n", 692*f603807bSTomohiro Kusumi ivgens[i].name); 693*f603807bSTomohiro Kusumi goto notsup; 694*f603807bSTomohiro Kusumi } 695*f603807bSTomohiro Kusumi } 696*f603807bSTomohiro Kusumi 697*f603807bSTomohiro Kusumi priv->ivgen = &ivgens[i]; 698*f603807bSTomohiro Kusumi 699*f603807bSTomohiro Kusumi priv->crypto_session.cri_alg = priv->crypto_alg; 700*f603807bSTomohiro Kusumi priv->crypto_session.cri_key = (u_int8_t *)priv->crypto_key; 701*f603807bSTomohiro Kusumi priv->crypto_session.cri_klen = priv->crypto_klen; 702*f603807bSTomohiro Kusumi priv->crypto_session.cri_mlen = 0; 703*f603807bSTomohiro Kusumi priv->crypto_session.cri_next = NULL; 704*f603807bSTomohiro Kusumi 705*f603807bSTomohiro Kusumi error = crypto_newsession(&priv->crypto_sid, 706*f603807bSTomohiro Kusumi &priv->crypto_session, 707*f603807bSTomohiro Kusumi CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE); 708*f603807bSTomohiro Kusumi if (error) { 709*f603807bSTomohiro Kusumi kprintf("dm_target_crypt: Error during crypto_newsession, " 710*f603807bSTomohiro Kusumi "error = %d\n", 711*f603807bSTomohiro Kusumi error); 712*f603807bSTomohiro Kusumi goto notsup; 713*f603807bSTomohiro Kusumi } 714*f603807bSTomohiro Kusumi 715*f603807bSTomohiro Kusumi memset(key, '0', strlen(key)); 716*f603807bSTomohiro Kusumi if (iv_opt) { 717*f603807bSTomohiro Kusumi ksprintf(status_str, "%s-%s-%s:%s %s %ju %s %ju", 718*f603807bSTomohiro Kusumi crypto_alg, crypto_mode, iv_mode, iv_opt, 719*f603807bSTomohiro Kusumi key, iv_offset, dev, block_offset); 720*f603807bSTomohiro Kusumi } else { 721*f603807bSTomohiro Kusumi ksprintf(status_str, "%s-%s-%s %s %ju %s %ju", 722*f603807bSTomohiro Kusumi crypto_alg, crypto_mode, iv_mode, 723*f603807bSTomohiro Kusumi key, iv_offset, dev, block_offset); 724*f603807bSTomohiro Kusumi } 725*f603807bSTomohiro Kusumi priv->status_str = status_str; 726*f603807bSTomohiro Kusumi 727*f603807bSTomohiro Kusumi /* Initialize mpipes */ 728*f603807bSTomohiro Kusumi dmtc_init_mpipe(priv); 729*f603807bSTomohiro Kusumi 730*f603807bSTomohiro Kusumi return 0; 731*f603807bSTomohiro Kusumi 732*f603807bSTomohiro Kusumi notsup: 733*f603807bSTomohiro Kusumi kprintf("dm_target_crypt: ENOTSUP\n"); 734*f603807bSTomohiro Kusumi kfree(status_str, M_DMCRYPT); 735*f603807bSTomohiro Kusumi return ENOTSUP; 736*f603807bSTomohiro Kusumi } 737*f603807bSTomohiro Kusumi 738*f603807bSTomohiro Kusumi /* Table routine called to get params string. */ 739*f603807bSTomohiro Kusumi static char * 740*f603807bSTomohiro Kusumi dm_target_crypt_table(void *target_config) 741*f603807bSTomohiro Kusumi { 742*f603807bSTomohiro Kusumi dm_target_crypt_config_t *priv; 743*f603807bSTomohiro Kusumi char *params; 744*f603807bSTomohiro Kusumi 745*f603807bSTomohiro Kusumi priv = target_config; 746*f603807bSTomohiro Kusumi 747*f603807bSTomohiro Kusumi params = dm_alloc_string(DM_MAX_PARAMS_SIZE); 748*f603807bSTomohiro Kusumi 749*f603807bSTomohiro Kusumi ksnprintf(params, DM_MAX_PARAMS_SIZE, "%s", 750*f603807bSTomohiro Kusumi priv->status_str); 751*f603807bSTomohiro Kusumi 752*f603807bSTomohiro Kusumi return params; 753*f603807bSTomohiro Kusumi } 754*f603807bSTomohiro Kusumi 755*f603807bSTomohiro Kusumi static int 756*f603807bSTomohiro Kusumi dm_target_crypt_destroy(dm_table_entry_t *table_en) 757*f603807bSTomohiro Kusumi { 758*f603807bSTomohiro Kusumi dm_target_crypt_config_t *priv; 759*f603807bSTomohiro Kusumi 760*f603807bSTomohiro Kusumi /* 761*f603807bSTomohiro Kusumi * Disconnect the crypt config before unbusying the target. 762*f603807bSTomohiro Kusumi */ 763*f603807bSTomohiro Kusumi priv = table_en->target_config; 764*f603807bSTomohiro Kusumi if (priv == NULL) 765*f603807bSTomohiro Kusumi return 0; 766*f603807bSTomohiro Kusumi dm_pdev_decr(priv->pdev); 767*f603807bSTomohiro Kusumi 768*f603807bSTomohiro Kusumi /* 769*f603807bSTomohiro Kusumi * Clean up the crypt config 770*f603807bSTomohiro Kusumi * 771*f603807bSTomohiro Kusumi * Overwrite the private information before freeing memory to 772*f603807bSTomohiro Kusumi * avoid leaking it. 773*f603807bSTomohiro Kusumi */ 774*f603807bSTomohiro Kusumi if (priv->status_str) { 775*f603807bSTomohiro Kusumi dmtc_crypto_clear(priv->status_str, strlen(priv->status_str)); 776*f603807bSTomohiro Kusumi kfree(priv->status_str, M_DMCRYPT); 777*f603807bSTomohiro Kusumi crypto_freesession(priv->crypto_sid); 778*f603807bSTomohiro Kusumi } 779*f603807bSTomohiro Kusumi 780*f603807bSTomohiro Kusumi if ((priv->ivgen) && (priv->ivgen->dtor != NULL)) { 781*f603807bSTomohiro Kusumi priv->ivgen->dtor(priv, priv->ivgen_priv); 782*f603807bSTomohiro Kusumi } 783*f603807bSTomohiro Kusumi 784*f603807bSTomohiro Kusumi /* Destroy mpipes */ 785*f603807bSTomohiro Kusumi dmtc_destroy_mpipe(priv); 786*f603807bSTomohiro Kusumi 787*f603807bSTomohiro Kusumi dmtc_crypto_clear(priv, sizeof(dm_target_crypt_config_t)); 788*f603807bSTomohiro Kusumi kfree(priv, M_DMCRYPT); 789*f603807bSTomohiro Kusumi 790*f603807bSTomohiro Kusumi return 0; 791*f603807bSTomohiro Kusumi } 792*f603807bSTomohiro Kusumi 793*f603807bSTomohiro Kusumi /************************************************************************ 794*f603807bSTomohiro Kusumi * STRATEGY SUPPORT FUNCTIONS * 795*f603807bSTomohiro Kusumi ************************************************************************ 796*f603807bSTomohiro Kusumi * 797*f603807bSTomohiro Kusumi * READ PATH: doio -> bio_read_done -> crypto_work -> crypto_cb_read_done 798*f603807bSTomohiro Kusumi * WRITE PATH: crypto_work -> crypto_cb_write_done -> doio -> bio_write_done 799*f603807bSTomohiro Kusumi */ 800*f603807bSTomohiro Kusumi 801*f603807bSTomohiro Kusumi /* 802*f603807bSTomohiro Kusumi * Wrapper around crypto_dispatch() to match dispatch_t type 803*f603807bSTomohiro Kusumi */ 804*f603807bSTomohiro Kusumi static void 805*f603807bSTomohiro Kusumi dmtc_crypto_dispatch(void *arg) 806*f603807bSTomohiro Kusumi { 807*f603807bSTomohiro Kusumi struct cryptop *crp; 808*f603807bSTomohiro Kusumi 809*f603807bSTomohiro Kusumi crp = (struct cryptop *)arg; 810*f603807bSTomohiro Kusumi KKASSERT(crp != NULL); 811*f603807bSTomohiro Kusumi KTR_LOG(dmcrypt_crypto_dispatch, crp); 812*f603807bSTomohiro Kusumi crypto_dispatch(crp); 813*f603807bSTomohiro Kusumi } 814*f603807bSTomohiro Kusumi 815*f603807bSTomohiro Kusumi /* 816*f603807bSTomohiro Kusumi * Start IO operation, called from dmstrategy routine. 817*f603807bSTomohiro Kusumi */ 818*f603807bSTomohiro Kusumi static int 819*f603807bSTomohiro Kusumi dm_target_crypt_strategy(dm_table_entry_t *table_en, struct buf *bp) 820*f603807bSTomohiro Kusumi { 821*f603807bSTomohiro Kusumi struct bio *bio; 822*f603807bSTomohiro Kusumi 823*f603807bSTomohiro Kusumi dm_target_crypt_config_t *priv; 824*f603807bSTomohiro Kusumi priv = table_en->target_config; 825*f603807bSTomohiro Kusumi 826*f603807bSTomohiro Kusumi /* Get rid of stuff we can't really handle */ 827*f603807bSTomohiro Kusumi if ((bp->b_cmd == BUF_CMD_READ) || (bp->b_cmd == BUF_CMD_WRITE)) { 828*f603807bSTomohiro Kusumi if (((bp->b_bcount % DEV_BSIZE) != 0) || (bp->b_bcount == 0)) { 829*f603807bSTomohiro Kusumi kprintf("dm_target_crypt_strategy: can't really " 830*f603807bSTomohiro Kusumi "handle bp->b_bcount = %d\n", 831*f603807bSTomohiro Kusumi bp->b_bcount); 832*f603807bSTomohiro Kusumi bp->b_error = EINVAL; 833*f603807bSTomohiro Kusumi bp->b_flags |= B_ERROR | B_INVAL; 834*f603807bSTomohiro Kusumi biodone(&bp->b_bio1); 835*f603807bSTomohiro Kusumi return 0; 836*f603807bSTomohiro Kusumi } 837*f603807bSTomohiro Kusumi } 838*f603807bSTomohiro Kusumi 839*f603807bSTomohiro Kusumi KTR_LOG(dmcrypt_crypt_strategy, bp->b_cmd, bp); 840*f603807bSTomohiro Kusumi 841*f603807bSTomohiro Kusumi switch (bp->b_cmd) { 842*f603807bSTomohiro Kusumi case BUF_CMD_READ: 843*f603807bSTomohiro Kusumi bio = push_bio(&bp->b_bio1); 844*f603807bSTomohiro Kusumi bio->bio_offset = bp->b_bio1.bio_offset + 845*f603807bSTomohiro Kusumi priv->block_offset * DEV_BSIZE; 846*f603807bSTomohiro Kusumi bio->bio_caller_info1.ptr = priv; 847*f603807bSTomohiro Kusumi bio->bio_done = dmtc_bio_read_done; 848*f603807bSTomohiro Kusumi vn_strategy(priv->pdev->pdev_vnode, bio); 849*f603807bSTomohiro Kusumi break; 850*f603807bSTomohiro Kusumi case BUF_CMD_WRITE: 851*f603807bSTomohiro Kusumi bio = push_bio(&bp->b_bio1); 852*f603807bSTomohiro Kusumi bio->bio_offset = bp->b_bio1.bio_offset + 853*f603807bSTomohiro Kusumi priv->block_offset * DEV_BSIZE; 854*f603807bSTomohiro Kusumi bio->bio_caller_info1.ptr = priv; 855*f603807bSTomohiro Kusumi dmtc_crypto_write_start(priv, bio); 856*f603807bSTomohiro Kusumi break; 857*f603807bSTomohiro Kusumi default: 858*f603807bSTomohiro Kusumi vn_strategy(priv->pdev->pdev_vnode, &bp->b_bio1); 859*f603807bSTomohiro Kusumi break; 860*f603807bSTomohiro Kusumi } 861*f603807bSTomohiro Kusumi return 0; 862*f603807bSTomohiro Kusumi } 863*f603807bSTomohiro Kusumi 864*f603807bSTomohiro Kusumi /* 865*f603807bSTomohiro Kusumi * STRATEGY READ PATH PART 1/3 (after read BIO completes) 866*f603807bSTomohiro Kusumi */ 867*f603807bSTomohiro Kusumi static void 868*f603807bSTomohiro Kusumi dmtc_bio_read_done(struct bio *bio) 869*f603807bSTomohiro Kusumi { 870*f603807bSTomohiro Kusumi struct bio *obio; 871*f603807bSTomohiro Kusumi 872*f603807bSTomohiro Kusumi dm_target_crypt_config_t *priv; 873*f603807bSTomohiro Kusumi 874*f603807bSTomohiro Kusumi KTR_LOG(dmcrypt_bio_read_done, bio->bio_buf); 875*f603807bSTomohiro Kusumi 876*f603807bSTomohiro Kusumi /* 877*f603807bSTomohiro Kusumi * If a read error occurs we shortcut the operation, otherwise 878*f603807bSTomohiro Kusumi * go on to stage 2. 879*f603807bSTomohiro Kusumi */ 880*f603807bSTomohiro Kusumi if (bio->bio_buf->b_flags & B_ERROR) { 881*f603807bSTomohiro Kusumi obio = pop_bio(bio); 882*f603807bSTomohiro Kusumi biodone(obio); 883*f603807bSTomohiro Kusumi } else { 884*f603807bSTomohiro Kusumi priv = bio->bio_caller_info1.ptr; 885*f603807bSTomohiro Kusumi dmtc_crypto_read_start(priv, bio); 886*f603807bSTomohiro Kusumi } 887*f603807bSTomohiro Kusumi } 888*f603807bSTomohiro Kusumi 889*f603807bSTomohiro Kusumi /* 890*f603807bSTomohiro Kusumi * STRATEGY READ PATH PART 2/3 891*f603807bSTomohiro Kusumi */ 892*f603807bSTomohiro Kusumi static void 893*f603807bSTomohiro Kusumi dmtc_crypto_read_retry(void *arg1, void *arg2) 894*f603807bSTomohiro Kusumi { 895*f603807bSTomohiro Kusumi dm_target_crypt_config_t *priv = arg1; 896*f603807bSTomohiro Kusumi struct bio *bio = arg2; 897*f603807bSTomohiro Kusumi 898*f603807bSTomohiro Kusumi dmtc_crypto_read_start(priv, bio); 899*f603807bSTomohiro Kusumi } 900*f603807bSTomohiro Kusumi 901*f603807bSTomohiro Kusumi static void 902*f603807bSTomohiro Kusumi dmtc_crypto_read_start(dm_target_crypt_config_t *priv, struct bio *bio) 903*f603807bSTomohiro Kusumi { 904*f603807bSTomohiro Kusumi struct dmtc_helper *dmtc; 905*f603807bSTomohiro Kusumi struct cryptodesc *crd; 906*f603807bSTomohiro Kusumi struct cryptop *crp; 907*f603807bSTomohiro Kusumi int i, bytes, sectors, sz; 908*f603807bSTomohiro Kusumi off_t isector; 909*f603807bSTomohiro Kusumi u_char *ptr, *space; 910*f603807bSTomohiro Kusumi 911*f603807bSTomohiro Kusumi /* 912*f603807bSTomohiro Kusumi * Note: b_resid no good after read I/O, it will be 0, use 913*f603807bSTomohiro Kusumi * b_bcount. 914*f603807bSTomohiro Kusumi */ 915*f603807bSTomohiro Kusumi bytes = bio->bio_buf->b_bcount; 916*f603807bSTomohiro Kusumi isector = bio->bio_offset / DEV_BSIZE; /* ivgen salt base? */ 917*f603807bSTomohiro Kusumi sectors = bytes / DEV_BSIZE; /* Number of sectors */ 918*f603807bSTomohiro Kusumi sz = sectors * (sizeof(*crp) + sizeof(*crd)); 919*f603807bSTomohiro Kusumi 920*f603807bSTomohiro Kusumi /* 921*f603807bSTomohiro Kusumi * For reads with bogus page we can't decrypt in place as stuff 922*f603807bSTomohiro Kusumi * can get ripped out from under us. 923*f603807bSTomohiro Kusumi * 924*f603807bSTomohiro Kusumi * XXX actually it looks like we can, and in any case the initial 925*f603807bSTomohiro Kusumi * read already completed and threw crypted data into the buffer 926*f603807bSTomohiro Kusumi * cache buffer. Disable for now. 927*f603807bSTomohiro Kusumi */ 928*f603807bSTomohiro Kusumi space = mpipe_alloc_callback(&priv->read_mpipe, 929*f603807bSTomohiro Kusumi dmtc_crypto_read_retry, priv, bio); 930*f603807bSTomohiro Kusumi if (space == NULL) 931*f603807bSTomohiro Kusumi return; 932*f603807bSTomohiro Kusumi 933*f603807bSTomohiro Kusumi dmtc = (struct dmtc_helper *)space; 934*f603807bSTomohiro Kusumi dmtc->free_addr = space; 935*f603807bSTomohiro Kusumi space += sizeof(struct dmtc_helper); 936*f603807bSTomohiro Kusumi dmtc->orig_buf = NULL; 937*f603807bSTomohiro Kusumi dmtc->data_buf = bio->bio_buf->b_data; 938*f603807bSTomohiro Kusumi dmtc->priv = priv; 939*f603807bSTomohiro Kusumi bio->bio_caller_info2.ptr = dmtc; 940*f603807bSTomohiro Kusumi bio->bio_buf->b_error = 0; 941*f603807bSTomohiro Kusumi 942*f603807bSTomohiro Kusumi /* 943*f603807bSTomohiro Kusumi * Load crypto descriptors (crp/crd loop) 944*f603807bSTomohiro Kusumi */ 945*f603807bSTomohiro Kusumi bzero(space, sz); 946*f603807bSTomohiro Kusumi ptr = space; 947*f603807bSTomohiro Kusumi bio->bio_caller_info3.value = sectors; 948*f603807bSTomohiro Kusumi cpu_sfence(); 949*f603807bSTomohiro Kusumi #if 0 950*f603807bSTomohiro Kusumi kprintf("Read, bytes = %d (b_bcount), " 951*f603807bSTomohiro Kusumi "sectors = %d (bio = %p, b_cmd = %d)\n", 952*f603807bSTomohiro Kusumi bytes, sectors, bio, bio->bio_buf->b_cmd); 953*f603807bSTomohiro Kusumi #endif 954*f603807bSTomohiro Kusumi for (i = 0; i < sectors; i++) { 955*f603807bSTomohiro Kusumi crp = (struct cryptop *)ptr; 956*f603807bSTomohiro Kusumi ptr += sizeof(*crp); 957*f603807bSTomohiro Kusumi crd = (struct cryptodesc *)ptr; 958*f603807bSTomohiro Kusumi ptr += sizeof (*crd); 959*f603807bSTomohiro Kusumi 960*f603807bSTomohiro Kusumi crp->crp_buf = dmtc->data_buf + i * DEV_BSIZE; 961*f603807bSTomohiro Kusumi 962*f603807bSTomohiro Kusumi crp->crp_sid = priv->crypto_sid; 963*f603807bSTomohiro Kusumi crp->crp_ilen = crp->crp_olen = DEV_BSIZE; 964*f603807bSTomohiro Kusumi 965*f603807bSTomohiro Kusumi crp->crp_opaque = (void *)bio; 966*f603807bSTomohiro Kusumi 967*f603807bSTomohiro Kusumi crp->crp_callback = dmtc_crypto_cb_read_done; 968*f603807bSTomohiro Kusumi crp->crp_desc = crd; 969*f603807bSTomohiro Kusumi crp->crp_etype = 0; 970*f603807bSTomohiro Kusumi crp->crp_flags = CRYPTO_F_CBIFSYNC | CRYPTO_F_REL | 971*f603807bSTomohiro Kusumi CRYPTO_F_BATCH; 972*f603807bSTomohiro Kusumi 973*f603807bSTomohiro Kusumi crd->crd_alg = priv->crypto_alg; 974*f603807bSTomohiro Kusumi #if 0 975*f603807bSTomohiro Kusumi crd->crd_key = (caddr_t)priv->crypto_key; 976*f603807bSTomohiro Kusumi crd->crd_klen = priv->crypto_klen; 977*f603807bSTomohiro Kusumi #endif 978*f603807bSTomohiro Kusumi 979*f603807bSTomohiro Kusumi crd->crd_skip = 0; 980*f603807bSTomohiro Kusumi crd->crd_len = DEV_BSIZE /* XXX */; 981*f603807bSTomohiro Kusumi crd->crd_flags = CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT; 982*f603807bSTomohiro Kusumi crd->crd_next = NULL; 983*f603807bSTomohiro Kusumi 984*f603807bSTomohiro Kusumi crd->crd_flags &= ~CRD_F_ENCRYPT; 985*f603807bSTomohiro Kusumi 986*f603807bSTomohiro Kusumi KTR_LOG(dmcrypt_crypto_read_start, crp, bio->bio_buf, i, 987*f603807bSTomohiro Kusumi sectors); 988*f603807bSTomohiro Kusumi 989*f603807bSTomohiro Kusumi /* 990*f603807bSTomohiro Kusumi * Note: last argument is used to generate salt(?) and is 991*f603807bSTomohiro Kusumi * a 64 bit value, but the original code passed an 992*f603807bSTomohiro Kusumi * int. Changing it now will break pre-existing 993*f603807bSTomohiro Kusumi * crypt volumes. 994*f603807bSTomohiro Kusumi */ 995*f603807bSTomohiro Kusumi priv->ivgen->gen_iv(priv, crd->crd_iv, sizeof(crd->crd_iv), 996*f603807bSTomohiro Kusumi isector + i, crp); 997*f603807bSTomohiro Kusumi } 998*f603807bSTomohiro Kusumi } 999*f603807bSTomohiro Kusumi 1000*f603807bSTomohiro Kusumi /* 1001*f603807bSTomohiro Kusumi * STRATEGY READ PATH PART 3/3 1002*f603807bSTomohiro Kusumi */ 1003*f603807bSTomohiro Kusumi static int 1004*f603807bSTomohiro Kusumi dmtc_crypto_cb_read_done(struct cryptop *crp) 1005*f603807bSTomohiro Kusumi { 1006*f603807bSTomohiro Kusumi struct dmtc_helper *dmtc; 1007*f603807bSTomohiro Kusumi struct bio *bio, *obio; 1008*f603807bSTomohiro Kusumi int n; 1009*f603807bSTomohiro Kusumi 1010*f603807bSTomohiro Kusumi if (crp->crp_etype == EAGAIN) 1011*f603807bSTomohiro Kusumi return crypto_dispatch(crp); 1012*f603807bSTomohiro Kusumi 1013*f603807bSTomohiro Kusumi bio = (struct bio *)crp->crp_opaque; 1014*f603807bSTomohiro Kusumi KKASSERT(bio != NULL); 1015*f603807bSTomohiro Kusumi 1016*f603807bSTomohiro Kusumi /* 1017*f603807bSTomohiro Kusumi * Cumulative error 1018*f603807bSTomohiro Kusumi */ 1019*f603807bSTomohiro Kusumi if (crp->crp_etype) { 1020*f603807bSTomohiro Kusumi kprintf("dm_target_crypt: dmtc_crypto_cb_read_done " 1021*f603807bSTomohiro Kusumi "crp_etype = %d\n", 1022*f603807bSTomohiro Kusumi crp->crp_etype); 1023*f603807bSTomohiro Kusumi bio->bio_buf->b_error = crp->crp_etype; 1024*f603807bSTomohiro Kusumi } 1025*f603807bSTomohiro Kusumi 1026*f603807bSTomohiro Kusumi /* 1027*f603807bSTomohiro Kusumi * On the last chunk of the decryption we do any required copybacks 1028*f603807bSTomohiro Kusumi * and complete the I/O. 1029*f603807bSTomohiro Kusumi */ 1030*f603807bSTomohiro Kusumi n = atomic_fetchadd_int(&bio->bio_caller_info3.value, -1); 1031*f603807bSTomohiro Kusumi #if 0 1032*f603807bSTomohiro Kusumi kprintf("dmtc_crypto_cb_read_done %p, n = %d\n", bio, n); 1033*f603807bSTomohiro Kusumi #endif 1034*f603807bSTomohiro Kusumi 1035*f603807bSTomohiro Kusumi KTR_LOG(dmcrypt_crypto_cb_read_done, crp, bio->bio_buf, n); 1036*f603807bSTomohiro Kusumi 1037*f603807bSTomohiro Kusumi if (n == 1) { 1038*f603807bSTomohiro Kusumi /* 1039*f603807bSTomohiro Kusumi * For the B_HASBOGUS case we didn't decrypt in place, 1040*f603807bSTomohiro Kusumi * so we need to copy stuff back into the buf. 1041*f603807bSTomohiro Kusumi * 1042*f603807bSTomohiro Kusumi * (disabled for now). 1043*f603807bSTomohiro Kusumi */ 1044*f603807bSTomohiro Kusumi dmtc = bio->bio_caller_info2.ptr; 1045*f603807bSTomohiro Kusumi if (bio->bio_buf->b_error) { 1046*f603807bSTomohiro Kusumi bio->bio_buf->b_flags |= B_ERROR; 1047*f603807bSTomohiro Kusumi } 1048*f603807bSTomohiro Kusumi #if 0 1049*f603807bSTomohiro Kusumi else if (bio->bio_buf->b_flags & B_HASBOGUS) { 1050*f603807bSTomohiro Kusumi memcpy(bio->bio_buf->b_data, dmtc->data_buf, 1051*f603807bSTomohiro Kusumi bio->bio_buf->b_bcount); 1052*f603807bSTomohiro Kusumi } 1053*f603807bSTomohiro Kusumi #endif 1054*f603807bSTomohiro Kusumi mpipe_free(&dmtc->priv->read_mpipe, dmtc->free_addr); 1055*f603807bSTomohiro Kusumi obio = pop_bio(bio); 1056*f603807bSTomohiro Kusumi biodone(obio); 1057*f603807bSTomohiro Kusumi } 1058*f603807bSTomohiro Kusumi return 0; 1059*f603807bSTomohiro Kusumi } 1060*f603807bSTomohiro Kusumi /* END OF STRATEGY READ SECTION */ 1061*f603807bSTomohiro Kusumi 1062*f603807bSTomohiro Kusumi /* 1063*f603807bSTomohiro Kusumi * STRATEGY WRITE PATH PART 1/3 1064*f603807bSTomohiro Kusumi */ 1065*f603807bSTomohiro Kusumi 1066*f603807bSTomohiro Kusumi static void 1067*f603807bSTomohiro Kusumi dmtc_crypto_write_retry(void *arg1, void *arg2) 1068*f603807bSTomohiro Kusumi { 1069*f603807bSTomohiro Kusumi dm_target_crypt_config_t *priv = arg1; 1070*f603807bSTomohiro Kusumi struct bio *bio = arg2; 1071*f603807bSTomohiro Kusumi 1072*f603807bSTomohiro Kusumi KTR_LOG(dmcrypt_crypto_write_retry, bio->bio_buf); 1073*f603807bSTomohiro Kusumi 1074*f603807bSTomohiro Kusumi dmtc_crypto_write_start(priv, bio); 1075*f603807bSTomohiro Kusumi } 1076*f603807bSTomohiro Kusumi 1077*f603807bSTomohiro Kusumi static void 1078*f603807bSTomohiro Kusumi dmtc_crypto_write_start(dm_target_crypt_config_t *priv, struct bio *bio) 1079*f603807bSTomohiro Kusumi { 1080*f603807bSTomohiro Kusumi struct dmtc_helper *dmtc; 1081*f603807bSTomohiro Kusumi struct cryptodesc *crd; 1082*f603807bSTomohiro Kusumi struct cryptop *crp; 1083*f603807bSTomohiro Kusumi int i, bytes, sectors, sz; 1084*f603807bSTomohiro Kusumi off_t isector; 1085*f603807bSTomohiro Kusumi u_char *ptr, *space; 1086*f603807bSTomohiro Kusumi 1087*f603807bSTomohiro Kusumi /* 1088*f603807bSTomohiro Kusumi * Use b_bcount for consistency 1089*f603807bSTomohiro Kusumi */ 1090*f603807bSTomohiro Kusumi bytes = bio->bio_buf->b_bcount; 1091*f603807bSTomohiro Kusumi 1092*f603807bSTomohiro Kusumi isector = bio->bio_offset / DEV_BSIZE; /* ivgen salt base? */ 1093*f603807bSTomohiro Kusumi sectors = bytes / DEV_BSIZE; /* Number of sectors */ 1094*f603807bSTomohiro Kusumi sz = sectors * (sizeof(*crp) + sizeof(*crd)); 1095*f603807bSTomohiro Kusumi 1096*f603807bSTomohiro Kusumi /* 1097*f603807bSTomohiro Kusumi * For writes and reads with bogus page don't decrypt in place. 1098*f603807bSTomohiro Kusumi */ 1099*f603807bSTomohiro Kusumi space = mpipe_alloc_callback(&priv->write_mpipe, 1100*f603807bSTomohiro Kusumi dmtc_crypto_write_retry, priv, bio); 1101*f603807bSTomohiro Kusumi if (space == NULL) 1102*f603807bSTomohiro Kusumi return; 1103*f603807bSTomohiro Kusumi 1104*f603807bSTomohiro Kusumi dmtc = (struct dmtc_helper *)space; 1105*f603807bSTomohiro Kusumi dmtc->free_addr = space; 1106*f603807bSTomohiro Kusumi space += sizeof(struct dmtc_helper); 1107*f603807bSTomohiro Kusumi memcpy(space + sz, bio->bio_buf->b_data, bytes); 1108*f603807bSTomohiro Kusumi 1109*f603807bSTomohiro Kusumi bio->bio_caller_info2.ptr = dmtc; 1110*f603807bSTomohiro Kusumi bio->bio_buf->b_error = 0; 1111*f603807bSTomohiro Kusumi 1112*f603807bSTomohiro Kusumi dmtc->orig_buf = bio->bio_buf->b_data; 1113*f603807bSTomohiro Kusumi dmtc->data_buf = space + sz; 1114*f603807bSTomohiro Kusumi dmtc->priv = priv; 1115*f603807bSTomohiro Kusumi 1116*f603807bSTomohiro Kusumi /* 1117*f603807bSTomohiro Kusumi * Load crypto descriptors (crp/crd loop) 1118*f603807bSTomohiro Kusumi */ 1119*f603807bSTomohiro Kusumi bzero(space, sz); 1120*f603807bSTomohiro Kusumi ptr = space; 1121*f603807bSTomohiro Kusumi bio->bio_caller_info3.value = sectors; 1122*f603807bSTomohiro Kusumi cpu_sfence(); 1123*f603807bSTomohiro Kusumi #if 0 1124*f603807bSTomohiro Kusumi kprintf("Write, bytes = %d (b_bcount), " 1125*f603807bSTomohiro Kusumi "sectors = %d (bio = %p, b_cmd = %d)\n", 1126*f603807bSTomohiro Kusumi bytes, sectors, bio, bio->bio_buf->b_cmd); 1127*f603807bSTomohiro Kusumi #endif 1128*f603807bSTomohiro Kusumi for (i = 0; i < sectors; i++) { 1129*f603807bSTomohiro Kusumi crp = (struct cryptop *)ptr; 1130*f603807bSTomohiro Kusumi ptr += sizeof(*crp); 1131*f603807bSTomohiro Kusumi crd = (struct cryptodesc *)ptr; 1132*f603807bSTomohiro Kusumi ptr += sizeof (*crd); 1133*f603807bSTomohiro Kusumi 1134*f603807bSTomohiro Kusumi crp->crp_buf = dmtc->data_buf + i * DEV_BSIZE; 1135*f603807bSTomohiro Kusumi 1136*f603807bSTomohiro Kusumi crp->crp_sid = priv->crypto_sid; 1137*f603807bSTomohiro Kusumi crp->crp_ilen = crp->crp_olen = DEV_BSIZE; 1138*f603807bSTomohiro Kusumi 1139*f603807bSTomohiro Kusumi crp->crp_opaque = (void *)bio; 1140*f603807bSTomohiro Kusumi 1141*f603807bSTomohiro Kusumi crp->crp_callback = dmtc_crypto_cb_write_done; 1142*f603807bSTomohiro Kusumi crp->crp_desc = crd; 1143*f603807bSTomohiro Kusumi crp->crp_etype = 0; 1144*f603807bSTomohiro Kusumi crp->crp_flags = CRYPTO_F_CBIFSYNC | CRYPTO_F_REL | 1145*f603807bSTomohiro Kusumi CRYPTO_F_BATCH; 1146*f603807bSTomohiro Kusumi 1147*f603807bSTomohiro Kusumi crd->crd_alg = priv->crypto_alg; 1148*f603807bSTomohiro Kusumi #if 0 1149*f603807bSTomohiro Kusumi crd->crd_key = (caddr_t)priv->crypto_key; 1150*f603807bSTomohiro Kusumi crd->crd_klen = priv->crypto_klen; 1151*f603807bSTomohiro Kusumi #endif 1152*f603807bSTomohiro Kusumi 1153*f603807bSTomohiro Kusumi crd->crd_skip = 0; 1154*f603807bSTomohiro Kusumi crd->crd_len = DEV_BSIZE /* XXX */; 1155*f603807bSTomohiro Kusumi crd->crd_flags = CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT; 1156*f603807bSTomohiro Kusumi crd->crd_next = NULL; 1157*f603807bSTomohiro Kusumi 1158*f603807bSTomohiro Kusumi crd->crd_flags |= CRD_F_ENCRYPT; 1159*f603807bSTomohiro Kusumi 1160*f603807bSTomohiro Kusumi /* 1161*f603807bSTomohiro Kusumi * Note: last argument is used to generate salt(?) and is 1162*f603807bSTomohiro Kusumi * a 64 bit value, but the original code passed an 1163*f603807bSTomohiro Kusumi * int. Changing it now will break pre-existing 1164*f603807bSTomohiro Kusumi * crypt volumes. 1165*f603807bSTomohiro Kusumi */ 1166*f603807bSTomohiro Kusumi 1167*f603807bSTomohiro Kusumi KTR_LOG(dmcrypt_crypto_write_start, crp, bio->bio_buf, 1168*f603807bSTomohiro Kusumi i, sectors); 1169*f603807bSTomohiro Kusumi 1170*f603807bSTomohiro Kusumi priv->ivgen->gen_iv(priv, crd->crd_iv, sizeof(crd->crd_iv), 1171*f603807bSTomohiro Kusumi isector + i, crp); 1172*f603807bSTomohiro Kusumi } 1173*f603807bSTomohiro Kusumi } 1174*f603807bSTomohiro Kusumi 1175*f603807bSTomohiro Kusumi /* 1176*f603807bSTomohiro Kusumi * STRATEGY WRITE PATH PART 2/3 1177*f603807bSTomohiro Kusumi */ 1178*f603807bSTomohiro Kusumi static int 1179*f603807bSTomohiro Kusumi dmtc_crypto_cb_write_done(struct cryptop *crp) 1180*f603807bSTomohiro Kusumi { 1181*f603807bSTomohiro Kusumi struct dmtc_helper *dmtc; 1182*f603807bSTomohiro Kusumi dm_target_crypt_config_t *priv; 1183*f603807bSTomohiro Kusumi struct bio *bio, *obio; 1184*f603807bSTomohiro Kusumi int n; 1185*f603807bSTomohiro Kusumi 1186*f603807bSTomohiro Kusumi if (crp->crp_etype == EAGAIN) 1187*f603807bSTomohiro Kusumi return crypto_dispatch(crp); 1188*f603807bSTomohiro Kusumi 1189*f603807bSTomohiro Kusumi bio = (struct bio *)crp->crp_opaque; 1190*f603807bSTomohiro Kusumi KKASSERT(bio != NULL); 1191*f603807bSTomohiro Kusumi 1192*f603807bSTomohiro Kusumi /* 1193*f603807bSTomohiro Kusumi * Cumulative error 1194*f603807bSTomohiro Kusumi */ 1195*f603807bSTomohiro Kusumi if (crp->crp_etype != 0) { 1196*f603807bSTomohiro Kusumi kprintf("dm_target_crypt: dmtc_crypto_cb_write_done " 1197*f603807bSTomohiro Kusumi "crp_etype = %d\n", 1198*f603807bSTomohiro Kusumi crp->crp_etype); 1199*f603807bSTomohiro Kusumi bio->bio_buf->b_error = crp->crp_etype; 1200*f603807bSTomohiro Kusumi } 1201*f603807bSTomohiro Kusumi 1202*f603807bSTomohiro Kusumi /* 1203*f603807bSTomohiro Kusumi * On the last chunk of the encryption we issue the write 1204*f603807bSTomohiro Kusumi */ 1205*f603807bSTomohiro Kusumi n = atomic_fetchadd_int(&bio->bio_caller_info3.value, -1); 1206*f603807bSTomohiro Kusumi #if 0 1207*f603807bSTomohiro Kusumi kprintf("dmtc_crypto_cb_write_done %p, n = %d\n", bio, n); 1208*f603807bSTomohiro Kusumi #endif 1209*f603807bSTomohiro Kusumi 1210*f603807bSTomohiro Kusumi KTR_LOG(dmcrypt_crypto_cb_write_done, crp, bio->bio_buf, n); 1211*f603807bSTomohiro Kusumi 1212*f603807bSTomohiro Kusumi if (n == 1) { 1213*f603807bSTomohiro Kusumi dmtc = bio->bio_caller_info2.ptr; 1214*f603807bSTomohiro Kusumi priv = (dm_target_crypt_config_t *)bio->bio_caller_info1.ptr; 1215*f603807bSTomohiro Kusumi 1216*f603807bSTomohiro Kusumi if (bio->bio_buf->b_error) { 1217*f603807bSTomohiro Kusumi bio->bio_buf->b_flags |= B_ERROR; 1218*f603807bSTomohiro Kusumi mpipe_free(&dmtc->priv->write_mpipe, dmtc->free_addr); 1219*f603807bSTomohiro Kusumi obio = pop_bio(bio); 1220*f603807bSTomohiro Kusumi biodone(obio); 1221*f603807bSTomohiro Kusumi } else { 1222*f603807bSTomohiro Kusumi dmtc->orig_buf = bio->bio_buf->b_data; 1223*f603807bSTomohiro Kusumi bio->bio_buf->b_data = dmtc->data_buf; 1224*f603807bSTomohiro Kusumi bio->bio_done = dmtc_bio_write_done; 1225*f603807bSTomohiro Kusumi vn_strategy(priv->pdev->pdev_vnode, bio); 1226*f603807bSTomohiro Kusumi } 1227*f603807bSTomohiro Kusumi } 1228*f603807bSTomohiro Kusumi return 0; 1229*f603807bSTomohiro Kusumi } 1230*f603807bSTomohiro Kusumi 1231*f603807bSTomohiro Kusumi /* 1232*f603807bSTomohiro Kusumi * STRATEGY WRITE PATH PART 3/3 1233*f603807bSTomohiro Kusumi */ 1234*f603807bSTomohiro Kusumi static void 1235*f603807bSTomohiro Kusumi dmtc_bio_write_done(struct bio *bio) 1236*f603807bSTomohiro Kusumi { 1237*f603807bSTomohiro Kusumi struct dmtc_helper *dmtc; 1238*f603807bSTomohiro Kusumi struct bio *obio; 1239*f603807bSTomohiro Kusumi 1240*f603807bSTomohiro Kusumi dmtc = bio->bio_caller_info2.ptr; 1241*f603807bSTomohiro Kusumi bio->bio_buf->b_data = dmtc->orig_buf; 1242*f603807bSTomohiro Kusumi mpipe_free(&dmtc->priv->write_mpipe, dmtc->free_addr); 1243*f603807bSTomohiro Kusumi 1244*f603807bSTomohiro Kusumi KTR_LOG(dmcrypt_bio_write_done, bio->bio_buf); 1245*f603807bSTomohiro Kusumi 1246*f603807bSTomohiro Kusumi obio = pop_bio(bio); 1247*f603807bSTomohiro Kusumi biodone(obio); 1248*f603807bSTomohiro Kusumi } 1249*f603807bSTomohiro Kusumi /* END OF STRATEGY WRITE SECTION */ 1250*f603807bSTomohiro Kusumi 1251*f603807bSTomohiro Kusumi 1252*f603807bSTomohiro Kusumi 1253*f603807bSTomohiro Kusumi /* DUMPING MAGIC */ 1254*f603807bSTomohiro Kusumi 1255*f603807bSTomohiro Kusumi extern int tsleep_crypto_dump; 1256*f603807bSTomohiro Kusumi 1257*f603807bSTomohiro Kusumi static int 1258*f603807bSTomohiro Kusumi dm_target_crypt_dump(dm_table_entry_t *table_en, void *data, size_t length, off_t offset) 1259*f603807bSTomohiro Kusumi { 1260*f603807bSTomohiro Kusumi static struct dmtc_dump_helper dump_helper; 1261*f603807bSTomohiro Kusumi dm_target_crypt_config_t *priv; 1262*f603807bSTomohiro Kusumi int id; 1263*f603807bSTomohiro Kusumi static int first_call = 1; 1264*f603807bSTomohiro Kusumi 1265*f603807bSTomohiro Kusumi priv = table_en->target_config; 1266*f603807bSTomohiro Kusumi 1267*f603807bSTomohiro Kusumi if (first_call) { 1268*f603807bSTomohiro Kusumi first_call = 0; 1269*f603807bSTomohiro Kusumi dump_reactivate_cpus(); 1270*f603807bSTomohiro Kusumi } 1271*f603807bSTomohiro Kusumi 1272*f603807bSTomohiro Kusumi /* Magically enable tsleep */ 1273*f603807bSTomohiro Kusumi tsleep_crypto_dump = 1; 1274*f603807bSTomohiro Kusumi id = 0; 1275*f603807bSTomohiro Kusumi 1276*f603807bSTomohiro Kusumi /* 1277*f603807bSTomohiro Kusumi * 0 length means flush buffers and return 1278*f603807bSTomohiro Kusumi */ 1279*f603807bSTomohiro Kusumi if (length == 0) { 1280*f603807bSTomohiro Kusumi if (priv->pdev->pdev_vnode->v_rdev == NULL) { 1281*f603807bSTomohiro Kusumi tsleep_crypto_dump = 0; 1282*f603807bSTomohiro Kusumi return ENXIO; 1283*f603807bSTomohiro Kusumi } 1284*f603807bSTomohiro Kusumi dev_ddump(priv->pdev->pdev_vnode->v_rdev, 1285*f603807bSTomohiro Kusumi data, 0, offset, 0); 1286*f603807bSTomohiro Kusumi tsleep_crypto_dump = 0; 1287*f603807bSTomohiro Kusumi return 0; 1288*f603807bSTomohiro Kusumi } 1289*f603807bSTomohiro Kusumi 1290*f603807bSTomohiro Kusumi bzero(&dump_helper, sizeof(dump_helper)); 1291*f603807bSTomohiro Kusumi dump_helper.priv = priv; 1292*f603807bSTomohiro Kusumi dump_helper.data = data; 1293*f603807bSTomohiro Kusumi dump_helper.length = length; 1294*f603807bSTomohiro Kusumi dump_helper.offset = offset + 1295*f603807bSTomohiro Kusumi priv->block_offset * DEV_BSIZE; 1296*f603807bSTomohiro Kusumi dump_helper.ident = &id; 1297*f603807bSTomohiro Kusumi dmtc_crypto_dump_start(priv, &dump_helper); 1298*f603807bSTomohiro Kusumi 1299*f603807bSTomohiro Kusumi /* 1300*f603807bSTomohiro Kusumi * Hackery to make stuff appear synchronous. The crypto callback will 1301*f603807bSTomohiro Kusumi * set id to 1 and call wakeup on it. If the request completed 1302*f603807bSTomohiro Kusumi * synchronously, id will be 1 and we won't bother to sleep. If not, 1303*f603807bSTomohiro Kusumi * the crypto request will complete asynchronously and we sleep until 1304*f603807bSTomohiro Kusumi * it's done. 1305*f603807bSTomohiro Kusumi */ 1306*f603807bSTomohiro Kusumi if (id == 0) 1307*f603807bSTomohiro Kusumi tsleep(&dump_helper, 0, "cryptdump", 0); 1308*f603807bSTomohiro Kusumi 1309*f603807bSTomohiro Kusumi dump_helper.offset = dm_pdev_correct_dump_offset(priv->pdev, 1310*f603807bSTomohiro Kusumi dump_helper.offset); 1311*f603807bSTomohiro Kusumi 1312*f603807bSTomohiro Kusumi dev_ddump(priv->pdev->pdev_vnode->v_rdev, 1313*f603807bSTomohiro Kusumi dump_helper.space, 0, dump_helper.offset, 1314*f603807bSTomohiro Kusumi dump_helper.length); 1315*f603807bSTomohiro Kusumi 1316*f603807bSTomohiro Kusumi tsleep_crypto_dump = 0; 1317*f603807bSTomohiro Kusumi return 0; 1318*f603807bSTomohiro Kusumi } 1319*f603807bSTomohiro Kusumi 1320*f603807bSTomohiro Kusumi static void 1321*f603807bSTomohiro Kusumi dmtc_crypto_dump_start(dm_target_crypt_config_t *priv, struct dmtc_dump_helper *dump_helper) 1322*f603807bSTomohiro Kusumi { 1323*f603807bSTomohiro Kusumi struct cryptodesc *crd; 1324*f603807bSTomohiro Kusumi struct cryptop *crp; 1325*f603807bSTomohiro Kusumi int i, bytes, sectors; 1326*f603807bSTomohiro Kusumi off_t isector; 1327*f603807bSTomohiro Kusumi 1328*f603807bSTomohiro Kusumi bytes = dump_helper->length; 1329*f603807bSTomohiro Kusumi 1330*f603807bSTomohiro Kusumi isector = dump_helper->offset / DEV_BSIZE; /* ivgen salt base? */ 1331*f603807bSTomohiro Kusumi sectors = bytes / DEV_BSIZE; /* Number of sectors */ 1332*f603807bSTomohiro Kusumi dump_helper->sectors = sectors; 1333*f603807bSTomohiro Kusumi #if 0 1334*f603807bSTomohiro Kusumi kprintf("Dump, bytes = %d, " 1335*f603807bSTomohiro Kusumi "sectors = %d, LENGTH=%zu\n", bytes, sectors, dump_helper->length); 1336*f603807bSTomohiro Kusumi #endif 1337*f603807bSTomohiro Kusumi KKASSERT(dump_helper->length <= 65536); 1338*f603807bSTomohiro Kusumi 1339*f603807bSTomohiro Kusumi memcpy(dump_helper->space, dump_helper->data, bytes); 1340*f603807bSTomohiro Kusumi 1341*f603807bSTomohiro Kusumi cpu_sfence(); 1342*f603807bSTomohiro Kusumi 1343*f603807bSTomohiro Kusumi for (i = 0; i < sectors; i++) { 1344*f603807bSTomohiro Kusumi crp = &dump_helper->crp[i]; 1345*f603807bSTomohiro Kusumi crd = &dump_helper->crd[i]; 1346*f603807bSTomohiro Kusumi 1347*f603807bSTomohiro Kusumi crp->crp_buf = dump_helper->space + i * DEV_BSIZE; 1348*f603807bSTomohiro Kusumi 1349*f603807bSTomohiro Kusumi crp->crp_sid = priv->crypto_sid; 1350*f603807bSTomohiro Kusumi crp->crp_ilen = crp->crp_olen = DEV_BSIZE; 1351*f603807bSTomohiro Kusumi 1352*f603807bSTomohiro Kusumi crp->crp_opaque = (void *)dump_helper; 1353*f603807bSTomohiro Kusumi 1354*f603807bSTomohiro Kusumi crp->crp_callback = dmtc_crypto_cb_dump_done; 1355*f603807bSTomohiro Kusumi crp->crp_desc = crd; 1356*f603807bSTomohiro Kusumi crp->crp_etype = 0; 1357*f603807bSTomohiro Kusumi crp->crp_flags = CRYPTO_F_CBIFSYNC | CRYPTO_F_REL | 1358*f603807bSTomohiro Kusumi CRYPTO_F_BATCH; 1359*f603807bSTomohiro Kusumi 1360*f603807bSTomohiro Kusumi crd->crd_alg = priv->crypto_alg; 1361*f603807bSTomohiro Kusumi 1362*f603807bSTomohiro Kusumi crd->crd_skip = 0; 1363*f603807bSTomohiro Kusumi crd->crd_len = DEV_BSIZE /* XXX */; 1364*f603807bSTomohiro Kusumi crd->crd_flags = CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT; 1365*f603807bSTomohiro Kusumi crd->crd_next = NULL; 1366*f603807bSTomohiro Kusumi 1367*f603807bSTomohiro Kusumi crd->crd_flags |= CRD_F_ENCRYPT; 1368*f603807bSTomohiro Kusumi 1369*f603807bSTomohiro Kusumi /* 1370*f603807bSTomohiro Kusumi * Note: last argument is used to generate salt(?) and is 1371*f603807bSTomohiro Kusumi * a 64 bit value, but the original code passed an 1372*f603807bSTomohiro Kusumi * int. Changing it now will break pre-existing 1373*f603807bSTomohiro Kusumi * crypt volumes. 1374*f603807bSTomohiro Kusumi */ 1375*f603807bSTomohiro Kusumi priv->ivgen->gen_iv(priv, crd->crd_iv, sizeof(crd->crd_iv), 1376*f603807bSTomohiro Kusumi isector + i, crp); 1377*f603807bSTomohiro Kusumi } 1378*f603807bSTomohiro Kusumi } 1379*f603807bSTomohiro Kusumi 1380*f603807bSTomohiro Kusumi static int 1381*f603807bSTomohiro Kusumi dmtc_crypto_cb_dump_done(struct cryptop *crp) 1382*f603807bSTomohiro Kusumi { 1383*f603807bSTomohiro Kusumi struct dmtc_dump_helper *dump_helper; 1384*f603807bSTomohiro Kusumi int n; 1385*f603807bSTomohiro Kusumi 1386*f603807bSTomohiro Kusumi if (crp->crp_etype == EAGAIN) 1387*f603807bSTomohiro Kusumi return crypto_dispatch(crp); 1388*f603807bSTomohiro Kusumi 1389*f603807bSTomohiro Kusumi dump_helper = (struct dmtc_dump_helper *)crp->crp_opaque; 1390*f603807bSTomohiro Kusumi KKASSERT(dump_helper != NULL); 1391*f603807bSTomohiro Kusumi 1392*f603807bSTomohiro Kusumi if (crp->crp_etype != 0) { 1393*f603807bSTomohiro Kusumi kprintf("dm_target_crypt: dmtc_crypto_cb_dump_done " 1394*f603807bSTomohiro Kusumi "crp_etype = %d\n", 1395*f603807bSTomohiro Kusumi crp->crp_etype); 1396*f603807bSTomohiro Kusumi return crp->crp_etype; 1397*f603807bSTomohiro Kusumi } 1398*f603807bSTomohiro Kusumi 1399*f603807bSTomohiro Kusumi /* 1400*f603807bSTomohiro Kusumi * On the last chunk of the encryption we return control 1401*f603807bSTomohiro Kusumi */ 1402*f603807bSTomohiro Kusumi n = atomic_fetchadd_int(&dump_helper->sectors, -1); 1403*f603807bSTomohiro Kusumi 1404*f603807bSTomohiro Kusumi if (n == 1) { 1405*f603807bSTomohiro Kusumi atomic_add_int(dump_helper->ident, 1); 1406*f603807bSTomohiro Kusumi wakeup(dump_helper); 1407*f603807bSTomohiro Kusumi } 1408*f603807bSTomohiro Kusumi 1409*f603807bSTomohiro Kusumi return 0; 1410*f603807bSTomohiro Kusumi } 1411*f603807bSTomohiro Kusumi 1412*f603807bSTomohiro Kusumi static int 1413*f603807bSTomohiro Kusumi dmtc_mod_handler(module_t mod, int type, void *unused) 1414*f603807bSTomohiro Kusumi { 1415*f603807bSTomohiro Kusumi dm_target_t *dmt = NULL; 1416*f603807bSTomohiro Kusumi int err = 0; 1417*f603807bSTomohiro Kusumi 1418*f603807bSTomohiro Kusumi switch (type) { 1419*f603807bSTomohiro Kusumi case MOD_LOAD: 1420*f603807bSTomohiro Kusumi if ((dmt = dm_target_lookup("crypt")) != NULL) { 1421*f603807bSTomohiro Kusumi dm_target_unbusy(dmt); 1422*f603807bSTomohiro Kusumi return EEXIST; 1423*f603807bSTomohiro Kusumi } 1424*f603807bSTomohiro Kusumi dmt = dm_target_alloc("crypt"); 1425*f603807bSTomohiro Kusumi dmt->version[0] = 1; 1426*f603807bSTomohiro Kusumi dmt->version[1] = 6; 1427*f603807bSTomohiro Kusumi dmt->version[2] = 0; 1428*f603807bSTomohiro Kusumi dmt->init = &dm_target_crypt_init; 1429*f603807bSTomohiro Kusumi dmt->destroy = &dm_target_crypt_destroy; 1430*f603807bSTomohiro Kusumi dmt->strategy = &dm_target_crypt_strategy; 1431*f603807bSTomohiro Kusumi dmt->table = &dm_target_crypt_table; 1432*f603807bSTomohiro Kusumi dmt->dump = &dm_target_crypt_dump; 1433*f603807bSTomohiro Kusumi 1434*f603807bSTomohiro Kusumi err = dm_target_insert(dmt); 1435*f603807bSTomohiro Kusumi if (!err) 1436*f603807bSTomohiro Kusumi kprintf("dm_target_crypt: Successfully initialized\n"); 1437*f603807bSTomohiro Kusumi break; 1438*f603807bSTomohiro Kusumi 1439*f603807bSTomohiro Kusumi case MOD_UNLOAD: 1440*f603807bSTomohiro Kusumi err = dm_target_remove("crypt"); 1441*f603807bSTomohiro Kusumi if (err == 0) { 1442*f603807bSTomohiro Kusumi kprintf("dm_target_crypt: unloaded\n"); 1443*f603807bSTomohiro Kusumi } 1444*f603807bSTomohiro Kusumi break; 1445*f603807bSTomohiro Kusumi } 1446*f603807bSTomohiro Kusumi 1447*f603807bSTomohiro Kusumi return err; 1448*f603807bSTomohiro Kusumi } 1449*f603807bSTomohiro Kusumi 1450*f603807bSTomohiro Kusumi DM_TARGET_MODULE(dm_target_crypt, dmtc_mod_handler); 1451