1*e7f57d2cSEric Biggers // SPDX-License-Identifier: GPL-2.0-only 2*e7f57d2cSEric Biggers /* 3*e7f57d2cSEric Biggers * Copyright 2024 Google LLC 4*e7f57d2cSEric Biggers */ 5*e7f57d2cSEric Biggers 6*e7f57d2cSEric Biggers #include <linux/blk-crypto.h> 7*e7f57d2cSEric Biggers #include <linux/ctype.h> 8*e7f57d2cSEric Biggers #include <linux/device-mapper.h> 9*e7f57d2cSEric Biggers #include <linux/hex.h> 10*e7f57d2cSEric Biggers #include <linux/module.h> 11*e7f57d2cSEric Biggers #include <keys/user-type.h> 12*e7f57d2cSEric Biggers 13*e7f57d2cSEric Biggers #define DM_MSG_PREFIX "inlinecrypt" 14*e7f57d2cSEric Biggers 15*e7f57d2cSEric Biggers static const struct dm_inlinecrypt_cipher { 16*e7f57d2cSEric Biggers const char *name; 17*e7f57d2cSEric Biggers enum blk_crypto_mode_num mode_num; 18*e7f57d2cSEric Biggers } dm_inlinecrypt_ciphers[] = { 19*e7f57d2cSEric Biggers { 20*e7f57d2cSEric Biggers .name = "aes-xts-plain64", 21*e7f57d2cSEric Biggers .mode_num = BLK_ENCRYPTION_MODE_AES_256_XTS, 22*e7f57d2cSEric Biggers }, 23*e7f57d2cSEric Biggers }; 24*e7f57d2cSEric Biggers 25*e7f57d2cSEric Biggers /** 26*e7f57d2cSEric Biggers * struct inlinecrypt_ctx - private data of an inlinecrypt target 27*e7f57d2cSEric Biggers * @dev: the underlying device 28*e7f57d2cSEric Biggers * @start: starting sector of the range of @dev which this target actually maps. 29*e7f57d2cSEric Biggers * For this purpose a "sector" is 512 bytes. 30*e7f57d2cSEric Biggers * @cipher_string: the name of the encryption algorithm being used 31*e7f57d2cSEric Biggers * @key_size: size of the encryption key in bytes 32*e7f57d2cSEric Biggers * @iv_offset: starting offset for IVs. IVs are generated as if the target were 33*e7f57d2cSEric Biggers * preceded by @iv_offset 512-byte sectors. 34*e7f57d2cSEric Biggers * @sector_size: crypto sector size in bytes (usually 4096) 35*e7f57d2cSEric Biggers * @sector_bits: log2(sector_size) 36*e7f57d2cSEric Biggers * @key: the encryption key to use 37*e7f57d2cSEric Biggers * @max_dun: the maximum DUN that may be used (computed from other params) 38*e7f57d2cSEric Biggers */ 39*e7f57d2cSEric Biggers struct inlinecrypt_ctx { 40*e7f57d2cSEric Biggers struct dm_dev *dev; 41*e7f57d2cSEric Biggers sector_t start; 42*e7f57d2cSEric Biggers const char *cipher_string; 43*e7f57d2cSEric Biggers unsigned int key_size; 44*e7f57d2cSEric Biggers u64 iv_offset; 45*e7f57d2cSEric Biggers unsigned int sector_size; 46*e7f57d2cSEric Biggers unsigned int sector_bits; 47*e7f57d2cSEric Biggers struct blk_crypto_key key; 48*e7f57d2cSEric Biggers u64 max_dun; 49*e7f57d2cSEric Biggers }; 50*e7f57d2cSEric Biggers 51*e7f57d2cSEric Biggers static const struct dm_inlinecrypt_cipher * 52*e7f57d2cSEric Biggers lookup_cipher(const char *cipher_string) 53*e7f57d2cSEric Biggers { 54*e7f57d2cSEric Biggers int i; 55*e7f57d2cSEric Biggers 56*e7f57d2cSEric Biggers for (i = 0; i < ARRAY_SIZE(dm_inlinecrypt_ciphers); i++) { 57*e7f57d2cSEric Biggers if (strcmp(cipher_string, dm_inlinecrypt_ciphers[i].name) == 0) 58*e7f57d2cSEric Biggers return &dm_inlinecrypt_ciphers[i]; 59*e7f57d2cSEric Biggers } 60*e7f57d2cSEric Biggers return NULL; 61*e7f57d2cSEric Biggers } 62*e7f57d2cSEric Biggers 63*e7f57d2cSEric Biggers static void inlinecrypt_dtr(struct dm_target *ti) 64*e7f57d2cSEric Biggers { 65*e7f57d2cSEric Biggers struct inlinecrypt_ctx *ctx = ti->private; 66*e7f57d2cSEric Biggers 67*e7f57d2cSEric Biggers if (ctx->dev) { 68*e7f57d2cSEric Biggers if (ctx->key.size) 69*e7f57d2cSEric Biggers blk_crypto_evict_key(ctx->dev->bdev, &ctx->key); 70*e7f57d2cSEric Biggers dm_put_device(ti, ctx->dev); 71*e7f57d2cSEric Biggers } 72*e7f57d2cSEric Biggers kfree_sensitive(ctx->cipher_string); 73*e7f57d2cSEric Biggers kfree_sensitive(ctx); 74*e7f57d2cSEric Biggers } 75*e7f57d2cSEric Biggers 76*e7f57d2cSEric Biggers #ifdef CONFIG_KEYS 77*e7f57d2cSEric Biggers 78*e7f57d2cSEric Biggers static bool contains_whitespace(const char *str) 79*e7f57d2cSEric Biggers { 80*e7f57d2cSEric Biggers while (*str) 81*e7f57d2cSEric Biggers if (isspace(*str++)) 82*e7f57d2cSEric Biggers return true; 83*e7f57d2cSEric Biggers return false; 84*e7f57d2cSEric Biggers } 85*e7f57d2cSEric Biggers 86*e7f57d2cSEric Biggers static int set_key_user(struct key *key, char *bin_key, 87*e7f57d2cSEric Biggers const unsigned int bin_key_size) 88*e7f57d2cSEric Biggers { 89*e7f57d2cSEric Biggers const struct user_key_payload *ukp; 90*e7f57d2cSEric Biggers 91*e7f57d2cSEric Biggers ukp = user_key_payload_locked(key); 92*e7f57d2cSEric Biggers if (!ukp) 93*e7f57d2cSEric Biggers return -EKEYREVOKED; 94*e7f57d2cSEric Biggers 95*e7f57d2cSEric Biggers if (bin_key_size != ukp->datalen) 96*e7f57d2cSEric Biggers return -EINVAL; 97*e7f57d2cSEric Biggers 98*e7f57d2cSEric Biggers memcpy(bin_key, ukp->data, bin_key_size); 99*e7f57d2cSEric Biggers 100*e7f57d2cSEric Biggers return 0; 101*e7f57d2cSEric Biggers } 102*e7f57d2cSEric Biggers 103*e7f57d2cSEric Biggers static int inlinecrypt_get_keyring_key(const char *key_string, u8 *bin_key, 104*e7f57d2cSEric Biggers const unsigned int bin_key_size) 105*e7f57d2cSEric Biggers { 106*e7f57d2cSEric Biggers char *key_desc; 107*e7f57d2cSEric Biggers int ret; 108*e7f57d2cSEric Biggers struct key_type *type; 109*e7f57d2cSEric Biggers struct key *key; 110*e7f57d2cSEric Biggers int (*set_key)(struct key *key, char *bin_key, 111*e7f57d2cSEric Biggers const unsigned int bin_key_size); 112*e7f57d2cSEric Biggers 113*e7f57d2cSEric Biggers /* 114*e7f57d2cSEric Biggers * Reject key_string with whitespace. dm core currently lacks code for 115*e7f57d2cSEric Biggers * proper whitespace escaping in arguments on DM_TABLE_STATUS path. 116*e7f57d2cSEric Biggers */ 117*e7f57d2cSEric Biggers if (contains_whitespace(key_string)) { 118*e7f57d2cSEric Biggers DMERR("whitespace chars not allowed in key string"); 119*e7f57d2cSEric Biggers return -EINVAL; 120*e7f57d2cSEric Biggers } 121*e7f57d2cSEric Biggers 122*e7f57d2cSEric Biggers /* look for next ':' separating key_type from key_description */ 123*e7f57d2cSEric Biggers key_desc = strchr(key_string, ':'); 124*e7f57d2cSEric Biggers if (!key_desc || key_desc == key_string || !strlen(key_desc + 1)) 125*e7f57d2cSEric Biggers return -EINVAL; 126*e7f57d2cSEric Biggers 127*e7f57d2cSEric Biggers if (!strncmp(key_string, "logon:", key_desc - key_string + 1)) { 128*e7f57d2cSEric Biggers type = &key_type_logon; 129*e7f57d2cSEric Biggers set_key = set_key_user; 130*e7f57d2cSEric Biggers } else { 131*e7f57d2cSEric Biggers return -EINVAL; 132*e7f57d2cSEric Biggers } 133*e7f57d2cSEric Biggers 134*e7f57d2cSEric Biggers key = request_key(type, key_desc + 1, NULL); 135*e7f57d2cSEric Biggers if (IS_ERR(key)) 136*e7f57d2cSEric Biggers return PTR_ERR(key); 137*e7f57d2cSEric Biggers 138*e7f57d2cSEric Biggers down_read(&key->sem); 139*e7f57d2cSEric Biggers 140*e7f57d2cSEric Biggers ret = set_key(key, (char *)bin_key, bin_key_size); 141*e7f57d2cSEric Biggers 142*e7f57d2cSEric Biggers up_read(&key->sem); 143*e7f57d2cSEric Biggers key_put(key); 144*e7f57d2cSEric Biggers 145*e7f57d2cSEric Biggers return ret; 146*e7f57d2cSEric Biggers } 147*e7f57d2cSEric Biggers 148*e7f57d2cSEric Biggers static int get_key_size(char **key_string) 149*e7f57d2cSEric Biggers { 150*e7f57d2cSEric Biggers char *colon, dummy; 151*e7f57d2cSEric Biggers int ret; 152*e7f57d2cSEric Biggers 153*e7f57d2cSEric Biggers if (*key_string[0] != ':') { 154*e7f57d2cSEric Biggers ret = strlen(*key_string); 155*e7f57d2cSEric Biggers 156*e7f57d2cSEric Biggers if (ret > 2 * BLK_CRYPTO_MAX_ANY_KEY_SIZE 157*e7f57d2cSEric Biggers || ret % 2 158*e7f57d2cSEric Biggers || !ret) { 159*e7f57d2cSEric Biggers DMERR("Invalid keysize"); 160*e7f57d2cSEric Biggers return -EINVAL; 161*e7f57d2cSEric Biggers } 162*e7f57d2cSEric Biggers return ret >> 1; 163*e7f57d2cSEric Biggers } 164*e7f57d2cSEric Biggers 165*e7f57d2cSEric Biggers /* look for next ':' in key string */ 166*e7f57d2cSEric Biggers colon = strpbrk(*key_string + 1, ":"); 167*e7f57d2cSEric Biggers if (!colon) 168*e7f57d2cSEric Biggers return -EINVAL; 169*e7f57d2cSEric Biggers 170*e7f57d2cSEric Biggers if (sscanf(*key_string + 1, "%u%c", &ret, &dummy) != 2 || dummy != ':') 171*e7f57d2cSEric Biggers return -EINVAL; 172*e7f57d2cSEric Biggers 173*e7f57d2cSEric Biggers /* remaining key string should be :<logon|user>:<key_desc> */ 174*e7f57d2cSEric Biggers *key_string = colon; 175*e7f57d2cSEric Biggers 176*e7f57d2cSEric Biggers return ret; 177*e7f57d2cSEric Biggers } 178*e7f57d2cSEric Biggers 179*e7f57d2cSEric Biggers #else 180*e7f57d2cSEric Biggers 181*e7f57d2cSEric Biggers static int inlinecrypt_get_keyring_key(const char *key_string, u8 *bin_key, 182*e7f57d2cSEric Biggers const unsigned int bin_key_size) 183*e7f57d2cSEric Biggers { 184*e7f57d2cSEric Biggers return -EINVAL; 185*e7f57d2cSEric Biggers } 186*e7f57d2cSEric Biggers 187*e7f57d2cSEric Biggers static int get_key_size(char **key_string) 188*e7f57d2cSEric Biggers { 189*e7f57d2cSEric Biggers int key_hex_size = strlen(*key_string); 190*e7f57d2cSEric Biggers 191*e7f57d2cSEric Biggers if (*key_string[0] == ':') 192*e7f57d2cSEric Biggers return -EINVAL; 193*e7f57d2cSEric Biggers 194*e7f57d2cSEric Biggers if (key_hex_size > 2 * BLK_CRYPTO_MAX_ANY_KEY_SIZE 195*e7f57d2cSEric Biggers || key_hex_size % 2 196*e7f57d2cSEric Biggers || !key_hex_size) { 197*e7f57d2cSEric Biggers DMERR("Invalid keysize"); 198*e7f57d2cSEric Biggers return -EINVAL; 199*e7f57d2cSEric Biggers } 200*e7f57d2cSEric Biggers 201*e7f57d2cSEric Biggers return key_hex_size >> 1; 202*e7f57d2cSEric Biggers } 203*e7f57d2cSEric Biggers 204*e7f57d2cSEric Biggers #endif /* CONFIG_KEYS */ 205*e7f57d2cSEric Biggers 206*e7f57d2cSEric Biggers static int inlinecrypt_get_key(const char *key_string, 207*e7f57d2cSEric Biggers u8 key[BLK_CRYPTO_MAX_ANY_KEY_SIZE], 208*e7f57d2cSEric Biggers const unsigned int key_size) 209*e7f57d2cSEric Biggers { 210*e7f57d2cSEric Biggers int ret = 0; 211*e7f57d2cSEric Biggers 212*e7f57d2cSEric Biggers if (key_size > BLK_CRYPTO_MAX_ANY_KEY_SIZE) { 213*e7f57d2cSEric Biggers DMERR("Invalid keysize"); 214*e7f57d2cSEric Biggers return -EINVAL; 215*e7f57d2cSEric Biggers } 216*e7f57d2cSEric Biggers 217*e7f57d2cSEric Biggers /* ':' means the key is in kernel keyring, short-circuit normal key processing */ 218*e7f57d2cSEric Biggers if (key_string[0] == ':') { 219*e7f57d2cSEric Biggers /* key string should be :<logon|user>:<key_desc> */ 220*e7f57d2cSEric Biggers ret = inlinecrypt_get_keyring_key(key_string + 1, key, key_size); 221*e7f57d2cSEric Biggers goto out; 222*e7f57d2cSEric Biggers } 223*e7f57d2cSEric Biggers 224*e7f57d2cSEric Biggers if (hex2bin(key, key_string, key_size) != 0) 225*e7f57d2cSEric Biggers ret = -EINVAL; 226*e7f57d2cSEric Biggers 227*e7f57d2cSEric Biggers out: 228*e7f57d2cSEric Biggers return ret; 229*e7f57d2cSEric Biggers } 230*e7f57d2cSEric Biggers 231*e7f57d2cSEric Biggers static int inlinecrypt_ctr_optional(struct dm_target *ti, 232*e7f57d2cSEric Biggers unsigned int argc, char **argv) 233*e7f57d2cSEric Biggers { 234*e7f57d2cSEric Biggers struct inlinecrypt_ctx *ctx = ti->private; 235*e7f57d2cSEric Biggers struct dm_arg_set as; 236*e7f57d2cSEric Biggers static const struct dm_arg _args[] = { 237*e7f57d2cSEric Biggers {0, 3, "Invalid number of feature args"}, 238*e7f57d2cSEric Biggers }; 239*e7f57d2cSEric Biggers unsigned int opt_params; 240*e7f57d2cSEric Biggers const char *opt_string; 241*e7f57d2cSEric Biggers bool iv_large_sectors = false; 242*e7f57d2cSEric Biggers char dummy; 243*e7f57d2cSEric Biggers int err; 244*e7f57d2cSEric Biggers 245*e7f57d2cSEric Biggers as.argc = argc; 246*e7f57d2cSEric Biggers as.argv = argv; 247*e7f57d2cSEric Biggers 248*e7f57d2cSEric Biggers err = dm_read_arg_group(_args, &as, &opt_params, &ti->error); 249*e7f57d2cSEric Biggers if (err) 250*e7f57d2cSEric Biggers return err; 251*e7f57d2cSEric Biggers 252*e7f57d2cSEric Biggers while (opt_params--) { 253*e7f57d2cSEric Biggers opt_string = dm_shift_arg(&as); 254*e7f57d2cSEric Biggers if (!opt_string) { 255*e7f57d2cSEric Biggers ti->error = "Not enough feature arguments"; 256*e7f57d2cSEric Biggers return -EINVAL; 257*e7f57d2cSEric Biggers } 258*e7f57d2cSEric Biggers if (!strcmp(opt_string, "allow_discards")) { 259*e7f57d2cSEric Biggers ti->num_discard_bios = 1; 260*e7f57d2cSEric Biggers } else if (sscanf(opt_string, "sector_size:%u%c", 261*e7f57d2cSEric Biggers &ctx->sector_size, &dummy) == 1) { 262*e7f57d2cSEric Biggers if (ctx->sector_size < SECTOR_SIZE || 263*e7f57d2cSEric Biggers ctx->sector_size > 4096 || 264*e7f57d2cSEric Biggers !is_power_of_2(ctx->sector_size)) { 265*e7f57d2cSEric Biggers ti->error = "Invalid sector_size"; 266*e7f57d2cSEric Biggers return -EINVAL; 267*e7f57d2cSEric Biggers } 268*e7f57d2cSEric Biggers } else if (!strcmp(opt_string, "iv_large_sectors")) { 269*e7f57d2cSEric Biggers iv_large_sectors = true; 270*e7f57d2cSEric Biggers } else { 271*e7f57d2cSEric Biggers ti->error = "Invalid feature arguments"; 272*e7f57d2cSEric Biggers return -EINVAL; 273*e7f57d2cSEric Biggers } 274*e7f57d2cSEric Biggers } 275*e7f57d2cSEric Biggers 276*e7f57d2cSEric Biggers /* dm-inlinecrypt doesn't implement iv_large_sectors=false. */ 277*e7f57d2cSEric Biggers if (ctx->sector_size != SECTOR_SIZE && !iv_large_sectors) { 278*e7f57d2cSEric Biggers ti->error = "iv_large_sectors must be specified"; 279*e7f57d2cSEric Biggers return -EINVAL; 280*e7f57d2cSEric Biggers } 281*e7f57d2cSEric Biggers 282*e7f57d2cSEric Biggers return 0; 283*e7f57d2cSEric Biggers } 284*e7f57d2cSEric Biggers 285*e7f57d2cSEric Biggers /* 286*e7f57d2cSEric Biggers * Construct an inlinecrypt mapping: 287*e7f57d2cSEric Biggers * <cipher> [<key>|:<key_size>:<logon>:<key_description>] <iv_offset> <dev_path> <start> 288*e7f57d2cSEric Biggers * 289*e7f57d2cSEric Biggers * This syntax matches dm-crypt's, but the set of supported functionality has 290*e7f57d2cSEric Biggers * been stripped down. 291*e7f57d2cSEric Biggers */ 292*e7f57d2cSEric Biggers static int inlinecrypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) 293*e7f57d2cSEric Biggers { 294*e7f57d2cSEric Biggers struct inlinecrypt_ctx *ctx; 295*e7f57d2cSEric Biggers const struct dm_inlinecrypt_cipher *cipher; 296*e7f57d2cSEric Biggers u8 raw_key[BLK_CRYPTO_MAX_ANY_KEY_SIZE]; 297*e7f57d2cSEric Biggers unsigned int dun_bytes; 298*e7f57d2cSEric Biggers unsigned long long tmpll; 299*e7f57d2cSEric Biggers char dummy; 300*e7f57d2cSEric Biggers int err; 301*e7f57d2cSEric Biggers 302*e7f57d2cSEric Biggers if (argc < 5) { 303*e7f57d2cSEric Biggers ti->error = "Not enough arguments"; 304*e7f57d2cSEric Biggers return -EINVAL; 305*e7f57d2cSEric Biggers } 306*e7f57d2cSEric Biggers 307*e7f57d2cSEric Biggers ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); 308*e7f57d2cSEric Biggers if (!ctx) { 309*e7f57d2cSEric Biggers ti->error = "Out of memory"; 310*e7f57d2cSEric Biggers return -ENOMEM; 311*e7f57d2cSEric Biggers } 312*e7f57d2cSEric Biggers ti->private = ctx; 313*e7f57d2cSEric Biggers 314*e7f57d2cSEric Biggers /* <cipher> */ 315*e7f57d2cSEric Biggers ctx->cipher_string = kstrdup(argv[0], GFP_KERNEL); 316*e7f57d2cSEric Biggers if (!ctx->cipher_string) { 317*e7f57d2cSEric Biggers ti->error = "Out of memory"; 318*e7f57d2cSEric Biggers err = -ENOMEM; 319*e7f57d2cSEric Biggers goto bad; 320*e7f57d2cSEric Biggers } 321*e7f57d2cSEric Biggers cipher = lookup_cipher(ctx->cipher_string); 322*e7f57d2cSEric Biggers if (!cipher) { 323*e7f57d2cSEric Biggers ti->error = "Unsupported cipher"; 324*e7f57d2cSEric Biggers err = -EINVAL; 325*e7f57d2cSEric Biggers goto bad; 326*e7f57d2cSEric Biggers } 327*e7f57d2cSEric Biggers 328*e7f57d2cSEric Biggers /* <key> */ 329*e7f57d2cSEric Biggers err = get_key_size(&argv[1]); 330*e7f57d2cSEric Biggers if (err < 0) { 331*e7f57d2cSEric Biggers ti->error = "Cannot parse key size"; 332*e7f57d2cSEric Biggers return -EINVAL; 333*e7f57d2cSEric Biggers } 334*e7f57d2cSEric Biggers ctx->key_size = err; 335*e7f57d2cSEric Biggers 336*e7f57d2cSEric Biggers err = inlinecrypt_get_key(argv[1], raw_key, ctx->key_size); 337*e7f57d2cSEric Biggers if (err) { 338*e7f57d2cSEric Biggers ti->error = "Malformed key string"; 339*e7f57d2cSEric Biggers goto bad; 340*e7f57d2cSEric Biggers } 341*e7f57d2cSEric Biggers 342*e7f57d2cSEric Biggers /* <iv_offset> */ 343*e7f57d2cSEric Biggers if (sscanf(argv[2], "%llu%c", &ctx->iv_offset, &dummy) != 1) { 344*e7f57d2cSEric Biggers ti->error = "Invalid iv_offset sector"; 345*e7f57d2cSEric Biggers err = -EINVAL; 346*e7f57d2cSEric Biggers goto bad; 347*e7f57d2cSEric Biggers } 348*e7f57d2cSEric Biggers 349*e7f57d2cSEric Biggers /* <dev_path> */ 350*e7f57d2cSEric Biggers err = dm_get_device(ti, argv[3], dm_table_get_mode(ti->table), 351*e7f57d2cSEric Biggers &ctx->dev); 352*e7f57d2cSEric Biggers if (err) { 353*e7f57d2cSEric Biggers ti->error = "Device lookup failed"; 354*e7f57d2cSEric Biggers goto bad; 355*e7f57d2cSEric Biggers } 356*e7f57d2cSEric Biggers 357*e7f57d2cSEric Biggers /* <start> */ 358*e7f57d2cSEric Biggers if (sscanf(argv[4], "%llu%c", &tmpll, &dummy) != 1 || 359*e7f57d2cSEric Biggers tmpll != (sector_t)tmpll) { 360*e7f57d2cSEric Biggers ti->error = "Invalid start sector"; 361*e7f57d2cSEric Biggers err = -EINVAL; 362*e7f57d2cSEric Biggers goto bad; 363*e7f57d2cSEric Biggers } 364*e7f57d2cSEric Biggers ctx->start = tmpll; 365*e7f57d2cSEric Biggers 366*e7f57d2cSEric Biggers /* optional arguments */ 367*e7f57d2cSEric Biggers ctx->sector_size = SECTOR_SIZE; 368*e7f57d2cSEric Biggers if (argc > 5) { 369*e7f57d2cSEric Biggers err = inlinecrypt_ctr_optional(ti, argc - 5, &argv[5]); 370*e7f57d2cSEric Biggers if (err) 371*e7f57d2cSEric Biggers goto bad; 372*e7f57d2cSEric Biggers } 373*e7f57d2cSEric Biggers ctx->sector_bits = ilog2(ctx->sector_size); 374*e7f57d2cSEric Biggers if (ti->len & ((ctx->sector_size >> SECTOR_SHIFT) - 1)) { 375*e7f57d2cSEric Biggers ti->error = "Device size is not a multiple of sector_size"; 376*e7f57d2cSEric Biggers err = -EINVAL; 377*e7f57d2cSEric Biggers goto bad; 378*e7f57d2cSEric Biggers } 379*e7f57d2cSEric Biggers if (ctx->iv_offset & ((ctx->sector_size >> SECTOR_SHIFT) - 1)) { 380*e7f57d2cSEric Biggers ti->error = "Wrong alignment of iv_offset sector"; 381*e7f57d2cSEric Biggers err = -EINVAL; 382*e7f57d2cSEric Biggers } 383*e7f57d2cSEric Biggers 384*e7f57d2cSEric Biggers ctx->max_dun = (ctx->iv_offset + ti->len - 1) >> 385*e7f57d2cSEric Biggers (ctx->sector_bits - SECTOR_SHIFT); 386*e7f57d2cSEric Biggers dun_bytes = DIV_ROUND_UP(fls64(ctx->max_dun), 8); 387*e7f57d2cSEric Biggers 388*e7f57d2cSEric Biggers err = blk_crypto_init_key(&ctx->key, raw_key, ctx->key_size, 389*e7f57d2cSEric Biggers BLK_CRYPTO_KEY_TYPE_RAW, 390*e7f57d2cSEric Biggers cipher->mode_num, dun_bytes, 391*e7f57d2cSEric Biggers ctx->sector_size); 392*e7f57d2cSEric Biggers if (err) { 393*e7f57d2cSEric Biggers ti->error = "Error initializing blk-crypto key"; 394*e7f57d2cSEric Biggers goto bad; 395*e7f57d2cSEric Biggers } 396*e7f57d2cSEric Biggers 397*e7f57d2cSEric Biggers err = blk_crypto_start_using_key(ctx->dev->bdev, &ctx->key); 398*e7f57d2cSEric Biggers if (err) { 399*e7f57d2cSEric Biggers ti->error = "Error starting to use blk-crypto"; 400*e7f57d2cSEric Biggers goto bad; 401*e7f57d2cSEric Biggers } 402*e7f57d2cSEric Biggers 403*e7f57d2cSEric Biggers ti->num_flush_bios = 1; 404*e7f57d2cSEric Biggers 405*e7f57d2cSEric Biggers err = 0; 406*e7f57d2cSEric Biggers goto out; 407*e7f57d2cSEric Biggers 408*e7f57d2cSEric Biggers bad: 409*e7f57d2cSEric Biggers inlinecrypt_dtr(ti); 410*e7f57d2cSEric Biggers out: 411*e7f57d2cSEric Biggers memzero_explicit(raw_key, sizeof(raw_key)); 412*e7f57d2cSEric Biggers return err; 413*e7f57d2cSEric Biggers } 414*e7f57d2cSEric Biggers 415*e7f57d2cSEric Biggers static int inlinecrypt_map(struct dm_target *ti, struct bio *bio) 416*e7f57d2cSEric Biggers { 417*e7f57d2cSEric Biggers const struct inlinecrypt_ctx *ctx = ti->private; 418*e7f57d2cSEric Biggers sector_t sector_in_target; 419*e7f57d2cSEric Biggers u64 dun[BLK_CRYPTO_DUN_ARRAY_SIZE] = {}; 420*e7f57d2cSEric Biggers 421*e7f57d2cSEric Biggers bio_set_dev(bio, ctx->dev->bdev); 422*e7f57d2cSEric Biggers 423*e7f57d2cSEric Biggers /* 424*e7f57d2cSEric Biggers * If the bio is a device-level request which doesn't target a specific 425*e7f57d2cSEric Biggers * sector, there's nothing more to do. 426*e7f57d2cSEric Biggers */ 427*e7f57d2cSEric Biggers if (bio_sectors(bio) == 0) 428*e7f57d2cSEric Biggers return DM_MAPIO_REMAPPED; 429*e7f57d2cSEric Biggers 430*e7f57d2cSEric Biggers /* 431*e7f57d2cSEric Biggers * The bio should never have an encryption context already, since 432*e7f57d2cSEric Biggers * dm-inlinecrypt doesn't pass through any inline encryption 433*e7f57d2cSEric Biggers * capabilities to the layer above it. 434*e7f57d2cSEric Biggers */ 435*e7f57d2cSEric Biggers if (WARN_ON_ONCE(bio_has_crypt_ctx(bio))) 436*e7f57d2cSEric Biggers return DM_MAPIO_KILL; 437*e7f57d2cSEric Biggers 438*e7f57d2cSEric Biggers /* Map the bio's sector to the underlying device. (512-byte sectors) */ 439*e7f57d2cSEric Biggers sector_in_target = dm_target_offset(ti, bio->bi_iter.bi_sector); 440*e7f57d2cSEric Biggers bio->bi_iter.bi_sector = ctx->start + sector_in_target; 441*e7f57d2cSEric Biggers /* 442*e7f57d2cSEric Biggers * If the bio doesn't have any data (e.g. if it's a DISCARD request), 443*e7f57d2cSEric Biggers * there's nothing more to do. 444*e7f57d2cSEric Biggers */ 445*e7f57d2cSEric Biggers if (!bio_has_data(bio)) 446*e7f57d2cSEric Biggers return DM_MAPIO_REMAPPED; 447*e7f57d2cSEric Biggers 448*e7f57d2cSEric Biggers /* Calculate the DUN and enforce data-unit (crypto sector) alignment. */ 449*e7f57d2cSEric Biggers dun[0] = ctx->iv_offset + sector_in_target; /* 512-byte sectors */ 450*e7f57d2cSEric Biggers if (dun[0] & ((ctx->sector_size >> SECTOR_SHIFT) - 1)) 451*e7f57d2cSEric Biggers return DM_MAPIO_KILL; 452*e7f57d2cSEric Biggers dun[0] >>= ctx->sector_bits - SECTOR_SHIFT; /* crypto sectors */ 453*e7f57d2cSEric Biggers 454*e7f57d2cSEric Biggers /* 455*e7f57d2cSEric Biggers * This check isn't necessary as we should have calculated max_dun 456*e7f57d2cSEric Biggers * correctly, but be safe. 457*e7f57d2cSEric Biggers */ 458*e7f57d2cSEric Biggers if (WARN_ON_ONCE(dun[0] > ctx->max_dun)) 459*e7f57d2cSEric Biggers return DM_MAPIO_KILL; 460*e7f57d2cSEric Biggers 461*e7f57d2cSEric Biggers bio_crypt_set_ctx(bio, &ctx->key, dun, GFP_NOIO); 462*e7f57d2cSEric Biggers 463*e7f57d2cSEric Biggers /* 464*e7f57d2cSEric Biggers * Since we've added an encryption context to the bio and 465*e7f57d2cSEric Biggers * blk-crypto-fallback may be needed to process it, it's necessary to 466*e7f57d2cSEric Biggers * use the fallback-aware bio submission code rather than 467*e7f57d2cSEric Biggers * unconditionally returning DM_MAPIO_REMAPPED. 468*e7f57d2cSEric Biggers * 469*e7f57d2cSEric Biggers * To get the correct accounting for a dm target in the case where 470*e7f57d2cSEric Biggers * __blk_crypto_submit_bio() doesn't take ownership of the bio (returns 471*e7f57d2cSEric Biggers * true), call __blk_crypto_submit_bio() directly and return 472*e7f57d2cSEric Biggers * DM_MAPIO_REMAPPED in that case, rather than relying on 473*e7f57d2cSEric Biggers * blk_crypto_submit_bio() which calls submit_bio() in that case. 474*e7f57d2cSEric Biggers * 475*e7f57d2cSEric Biggers * TODO: blk-crypto fallback write slow-path currently double-accounts 476*e7f57d2cSEric Biggers * IO in vmstat, as encrypted bios are submitted via submit_bio(). 477*e7f57d2cSEric Biggers * This does not affect data correctness. Consider fixing this if 478*e7f57d2cSEric Biggers * a cleaner accounting model for derived bios is introduced. 479*e7f57d2cSEric Biggers */ 480*e7f57d2cSEric Biggers if (__blk_crypto_submit_bio(bio)) 481*e7f57d2cSEric Biggers return DM_MAPIO_REMAPPED; 482*e7f57d2cSEric Biggers return DM_MAPIO_SUBMITTED; 483*e7f57d2cSEric Biggers } 484*e7f57d2cSEric Biggers 485*e7f57d2cSEric Biggers static void inlinecrypt_status(struct dm_target *ti, status_type_t type, 486*e7f57d2cSEric Biggers unsigned int status_flags, char *result, 487*e7f57d2cSEric Biggers unsigned int maxlen) 488*e7f57d2cSEric Biggers { 489*e7f57d2cSEric Biggers const struct inlinecrypt_ctx *ctx = ti->private; 490*e7f57d2cSEric Biggers unsigned int sz = 0; 491*e7f57d2cSEric Biggers int num_feature_args = 0; 492*e7f57d2cSEric Biggers 493*e7f57d2cSEric Biggers switch (type) { 494*e7f57d2cSEric Biggers case STATUSTYPE_INFO: 495*e7f57d2cSEric Biggers case STATUSTYPE_IMA: 496*e7f57d2cSEric Biggers result[0] = '\0'; 497*e7f57d2cSEric Biggers break; 498*e7f57d2cSEric Biggers 499*e7f57d2cSEric Biggers case STATUSTYPE_TABLE: 500*e7f57d2cSEric Biggers /* 501*e7f57d2cSEric Biggers * Warning: like dm-crypt, dm-inlinecrypt includes the key in 502*e7f57d2cSEric Biggers * the returned table. Userspace is responsible for redacting 503*e7f57d2cSEric Biggers * the key when needed. 504*e7f57d2cSEric Biggers */ 505*e7f57d2cSEric Biggers DMEMIT("%s %*phN %llu %s %llu", ctx->cipher_string, 506*e7f57d2cSEric Biggers ctx->key.size, ctx->key.bytes, ctx->iv_offset, 507*e7f57d2cSEric Biggers ctx->dev->name, ctx->start); 508*e7f57d2cSEric Biggers num_feature_args += !!ti->num_discard_bios; 509*e7f57d2cSEric Biggers if (ctx->sector_size != SECTOR_SIZE) 510*e7f57d2cSEric Biggers num_feature_args += 2; 511*e7f57d2cSEric Biggers if (num_feature_args != 0) { 512*e7f57d2cSEric Biggers DMEMIT(" %d", num_feature_args); 513*e7f57d2cSEric Biggers if (ti->num_discard_bios) 514*e7f57d2cSEric Biggers DMEMIT(" allow_discards"); 515*e7f57d2cSEric Biggers if (ctx->sector_size != SECTOR_SIZE) { 516*e7f57d2cSEric Biggers DMEMIT(" sector_size:%u", ctx->sector_size); 517*e7f57d2cSEric Biggers DMEMIT(" iv_large_sectors"); 518*e7f57d2cSEric Biggers } 519*e7f57d2cSEric Biggers } 520*e7f57d2cSEric Biggers break; 521*e7f57d2cSEric Biggers } 522*e7f57d2cSEric Biggers } 523*e7f57d2cSEric Biggers 524*e7f57d2cSEric Biggers static int inlinecrypt_prepare_ioctl(struct dm_target *ti, 525*e7f57d2cSEric Biggers struct block_device **bdev, unsigned int cmd, 526*e7f57d2cSEric Biggers unsigned long arg, bool *forward) 527*e7f57d2cSEric Biggers { 528*e7f57d2cSEric Biggers const struct inlinecrypt_ctx *ctx = ti->private; 529*e7f57d2cSEric Biggers const struct dm_dev *dev = ctx->dev; 530*e7f57d2cSEric Biggers 531*e7f57d2cSEric Biggers *bdev = dev->bdev; 532*e7f57d2cSEric Biggers 533*e7f57d2cSEric Biggers /* Only pass ioctls through if the device sizes match exactly. */ 534*e7f57d2cSEric Biggers return ctx->start != 0 || ti->len != bdev_nr_sectors(dev->bdev); 535*e7f57d2cSEric Biggers } 536*e7f57d2cSEric Biggers 537*e7f57d2cSEric Biggers static int inlinecrypt_iterate_devices(struct dm_target *ti, 538*e7f57d2cSEric Biggers iterate_devices_callout_fn fn, 539*e7f57d2cSEric Biggers void *data) 540*e7f57d2cSEric Biggers { 541*e7f57d2cSEric Biggers const struct inlinecrypt_ctx *ctx = ti->private; 542*e7f57d2cSEric Biggers 543*e7f57d2cSEric Biggers return fn(ti, ctx->dev, ctx->start, ti->len, data); 544*e7f57d2cSEric Biggers } 545*e7f57d2cSEric Biggers 546*e7f57d2cSEric Biggers #ifdef CONFIG_BLK_DEV_ZONED 547*e7f57d2cSEric Biggers static int inlinecrypt_report_zones(struct dm_target *ti, 548*e7f57d2cSEric Biggers struct dm_report_zones_args *args, 549*e7f57d2cSEric Biggers unsigned int nr_zones) 550*e7f57d2cSEric Biggers { 551*e7f57d2cSEric Biggers const struct inlinecrypt_ctx *ctx = ti->private; 552*e7f57d2cSEric Biggers 553*e7f57d2cSEric Biggers return dm_report_zones(ctx->dev->bdev, ctx->start, 554*e7f57d2cSEric Biggers ctx->start + dm_target_offset(ti, args->next_sector), 555*e7f57d2cSEric Biggers args, nr_zones); 556*e7f57d2cSEric Biggers } 557*e7f57d2cSEric Biggers #else 558*e7f57d2cSEric Biggers #define inlinecrypt_report_zones NULL 559*e7f57d2cSEric Biggers #endif 560*e7f57d2cSEric Biggers 561*e7f57d2cSEric Biggers static void inlinecrypt_io_hints(struct dm_target *ti, 562*e7f57d2cSEric Biggers struct queue_limits *limits) 563*e7f57d2cSEric Biggers { 564*e7f57d2cSEric Biggers const struct inlinecrypt_ctx *ctx = ti->private; 565*e7f57d2cSEric Biggers const unsigned int sector_size = ctx->sector_size; 566*e7f57d2cSEric Biggers 567*e7f57d2cSEric Biggers limits->logical_block_size = 568*e7f57d2cSEric Biggers max_t(unsigned int, limits->logical_block_size, sector_size); 569*e7f57d2cSEric Biggers limits->physical_block_size = 570*e7f57d2cSEric Biggers max_t(unsigned int, limits->physical_block_size, sector_size); 571*e7f57d2cSEric Biggers limits->io_min = max_t(unsigned int, limits->io_min, sector_size); 572*e7f57d2cSEric Biggers limits->dma_alignment = limits->logical_block_size - 1; 573*e7f57d2cSEric Biggers } 574*e7f57d2cSEric Biggers 575*e7f57d2cSEric Biggers static struct target_type inlinecrypt_target = { 576*e7f57d2cSEric Biggers .name = "inlinecrypt", 577*e7f57d2cSEric Biggers .version = {1, 0, 0}, 578*e7f57d2cSEric Biggers /* 579*e7f57d2cSEric Biggers * Do not set DM_TARGET_PASSES_CRYPTO, since dm-inlinecrypt consumes the 580*e7f57d2cSEric Biggers * crypto capability itself. 581*e7f57d2cSEric Biggers */ 582*e7f57d2cSEric Biggers .features = DM_TARGET_ZONED_HM, 583*e7f57d2cSEric Biggers .module = THIS_MODULE, 584*e7f57d2cSEric Biggers .ctr = inlinecrypt_ctr, 585*e7f57d2cSEric Biggers .dtr = inlinecrypt_dtr, 586*e7f57d2cSEric Biggers .map = inlinecrypt_map, 587*e7f57d2cSEric Biggers .status = inlinecrypt_status, 588*e7f57d2cSEric Biggers .prepare_ioctl = inlinecrypt_prepare_ioctl, 589*e7f57d2cSEric Biggers .iterate_devices = inlinecrypt_iterate_devices, 590*e7f57d2cSEric Biggers .report_zones = inlinecrypt_report_zones, 591*e7f57d2cSEric Biggers .io_hints = inlinecrypt_io_hints, 592*e7f57d2cSEric Biggers }; 593*e7f57d2cSEric Biggers 594*e7f57d2cSEric Biggers module_dm(inlinecrypt); 595*e7f57d2cSEric Biggers 596*e7f57d2cSEric Biggers MODULE_AUTHOR("Eric Biggers <ebiggers@google.com>"); 597*e7f57d2cSEric Biggers MODULE_AUTHOR("Linlin Zhang <linlin.zhang@oss.qualcomm.com>"); 598*e7f57d2cSEric Biggers MODULE_DESCRIPTION(DM_NAME " target for inline encryption"); 599*e7f57d2cSEric Biggers MODULE_LICENSE("GPL"); 600