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