Skip to content

Commit f9f5797

Browse files
Linlin ZhangMikulas Patocka
authored andcommitted
dm-inlinecrypt: add support for hardware-wrapped keys
Add support for hardware-wrapped encryption keys to the dm-inlinecrypt target. Introduce a new optional argument <key_type> to indicate whether the provided key is a raw key or a hardware-wrapped key. Based on this flag, the appropriate blk-crypto key type is selected when initializing the key. This allows dm-inlinecrypt to work with hardware that requires keys to be wrapped and managed by the underlying inline encryption engine. Update the target argument parsing accordingly and pass the key type to blk_crypto_init_key(). Documentation is also updated to reflect the new parameter and usage. Signed-off-by: Linlin Zhang <linlin.zhang@oss.qualcomm.com> Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Fixes: e7f57d2 ("dm-inlinecrypt: add target for inline block device encryption")
1 parent 5aa0f92 commit f9f5797

2 files changed

Lines changed: 54 additions & 29 deletions

File tree

Documentation/admin-guide/device-mapper/dm-inlinecrypt.rst

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,18 +39,19 @@ Parameters::
3939

4040
<key_string>
4141
The kernel keyring key is identified by string in following format:
42-
<key_size>:<key_type>:<key_description>.
42+
<key_size>:<keyring_type>:<key_description>.
4343

4444
<key_size>
4545
The encryption key size in bytes. The kernel key payload size must match
4646
the value passed in <key_size>.
4747

48-
<key_type>
49-
Either 'logon', or 'trusted' kernel key type.
48+
<keyring_type>
49+
The type of the key inside the kernel keyring. It can be either 'logon',
50+
or 'trusted' kernel key type.
5051

5152
<key_description>
5253
The kernel keyring key description inlinecrypt target should look for
53-
when loading key of <key_type>.
54+
when loading key of <keyring_type>.
5455

5556
<iv_offset>
5657
The IV offset is a sector count that is added to the sector number
@@ -70,7 +71,12 @@ Parameters::
7071
Otherwise #opt_params is the number of following arguments.
7172

7273
Example of optional parameters section:
73-
allow_discards sector_size:4096 iv_large_sectors
74+
keytype:raw allow_discards sector_size:4096 iv_large_sectors
75+
76+
<key_type>
77+
The type of the key as seen by the block layer, either standard or
78+
hardware-wrapped. The string is supplied in the table as <keytype:raw>
79+
or <keytype:hw-wrapped>.
7480

7581
allow_discards
7682
Block discard requests (a.k.a. TRIM) are passed through the inlinecrypt
@@ -113,11 +119,11 @@ using dmsetup
113119

114120
#!/bin/sh
115121
# Create a inlinecrypt device using dmsetup
116-
dmsetup create inlinecrypt1 --table "0 `blockdev --getsz $1` inlinecrypt aes-xts-plain64 babebabebabebabebabebabebabebabebabebabebabebabebabebabebabebabe 0 $1 0"
122+
dmsetup create inlinecrypt1 --table "0 `blockdev --getsz $1` inlinecrypt aes-xts-plain64 babebabebabebabebabebabebabebabebabebabebabebabebabebabebabebabe 0 0 $1 0 1 keytype:raw"
117123

118124
::
119125

120126
#!/bin/sh
121127
# Create a inlinecrypt device using dmsetup when encryption key is stored in keyring service
122-
dmsetup create inlinecrypt2 --table "0 `blockdev --getsz $1` inlinecrypt aes-xts-plain64 :64:logon:fde:dminlinecrypt_test_key 0 $1 0"
128+
dmsetup create inlinecrypt2 --table "0 `blockdev --getsz $1` inlinecrypt aes-xts-plain64 :64:logon:fde:dminlinecrypt_test_key 0 0 $1 0 1 keytype:raw"
123129

drivers/md/dm-inlinecrypt.c

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ static const struct dm_inlinecrypt_cipher {
3333
* preceded by @iv_offset 512-byte sectors.
3434
* @sector_size: crypto sector size in bytes (usually 4096)
3535
* @sector_bits: log2(sector_size)
36+
* @key_type: type of the key -- either raw or hardware-wrapped
3637
* @key: the encryption key to use
3738
* @max_dun: the maximum DUN that may be used (computed from other params)
3839
*/
@@ -44,6 +45,7 @@ struct inlinecrypt_ctx {
4445
u64 iv_offset;
4546
unsigned int sector_size;
4647
unsigned int sector_bits;
48+
enum blk_crypto_key_type key_type;
4749
struct blk_crypto_key key;
4850
u64 max_dun;
4951
};
@@ -83,32 +85,32 @@ static bool contains_whitespace(const char *str)
8385
return false;
8486
}
8587

86-
static int set_key_user(struct key *key, char *bin_key,
87-
const unsigned int bin_key_size)
88+
static int set_key_user(struct key *key, char *key_bytes,
89+
const unsigned int key_bytes_size)
8890
{
8991
const struct user_key_payload *ukp;
9092

9193
ukp = user_key_payload_locked(key);
9294
if (!ukp)
9395
return -EKEYREVOKED;
9496

95-
if (bin_key_size != ukp->datalen)
97+
if (key_bytes_size != ukp->datalen)
9698
return -EINVAL;
9799

98-
memcpy(bin_key, ukp->data, bin_key_size);
100+
memcpy(key_bytes, ukp->data, key_bytes_size);
99101

100102
return 0;
101103
}
102104

103-
static int inlinecrypt_get_keyring_key(const char *key_string, u8 *bin_key,
104-
const unsigned int bin_key_size)
105+
static int inlinecrypt_get_keyring_key(const char *key_string, u8 *key_bytes,
106+
const unsigned int key_bytes_size)
105107
{
106108
char *key_desc;
107109
int ret;
108110
struct key_type *type;
109111
struct key *key;
110-
int (*set_key)(struct key *key, char *bin_key,
111-
const unsigned int bin_key_size);
112+
int (*set_key)(struct key *key, char *key_bytes,
113+
const unsigned int key_bytes_size);
112114

113115
/*
114116
* Reject key_string with whitespace. dm core currently lacks code for
@@ -137,7 +139,7 @@ static int inlinecrypt_get_keyring_key(const char *key_string, u8 *bin_key,
137139

138140
down_read(&key->sem);
139141

140-
ret = set_key(key, (char *)bin_key, bin_key_size);
142+
ret = set_key(key, (char *)key_bytes, key_bytes_size);
141143

142144
up_read(&key->sem);
143145
key_put(key);
@@ -178,8 +180,8 @@ static int get_key_size(char **key_string)
178180

179181
#else
180182

181-
static int inlinecrypt_get_keyring_key(const char *key_string, u8 *bin_key,
182-
const unsigned int bin_key_size)
183+
static int inlinecrypt_get_keyring_key(const char *key_string, u8 *key_bytes,
184+
const unsigned int key_bytes_size)
183185
{
184186
return -EINVAL;
185187
}
@@ -234,7 +236,7 @@ static int inlinecrypt_ctr_optional(struct dm_target *ti,
234236
struct inlinecrypt_ctx *ctx = ti->private;
235237
struct dm_arg_set as;
236238
static const struct dm_arg _args[] = {
237-
{0, 3, "Invalid number of feature args"},
239+
{0, 4, "Invalid number of feature args"},
238240
};
239241
unsigned int opt_params;
240242
const char *opt_string;
@@ -255,7 +257,23 @@ static int inlinecrypt_ctr_optional(struct dm_target *ti,
255257
ti->error = "Not enough feature arguments";
256258
return -EINVAL;
257259
}
258-
if (!strcmp(opt_string, "allow_discards")) {
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")) {
259277
ti->num_discard_bios = 1;
260278
} else if (sscanf(opt_string, "sector_size:%u%c",
261279
&ctx->sector_size, &dummy) == 1) {
@@ -293,7 +311,7 @@ static int inlinecrypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
293311
{
294312
struct inlinecrypt_ctx *ctx;
295313
const struct dm_inlinecrypt_cipher *cipher;
296-
u8 raw_key[BLK_CRYPTO_MAX_ANY_KEY_SIZE];
314+
u8 key_bytes[BLK_CRYPTO_MAX_ANY_KEY_SIZE];
297315
unsigned int dun_bytes;
298316
unsigned long long tmpll;
299317
char dummy;
@@ -333,7 +351,7 @@ static int inlinecrypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
333351
}
334352
ctx->key_size = err;
335353

336-
err = inlinecrypt_get_key(argv[1], raw_key, ctx->key_size);
354+
err = inlinecrypt_get_key(argv[1], key_bytes, ctx->key_size);
337355
if (err) {
338356
ti->error = "Malformed key string";
339357
goto bad;
@@ -365,6 +383,7 @@ static int inlinecrypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
365383

366384
/* optional arguments */
367385
ctx->sector_size = SECTOR_SIZE;
386+
ctx->key_type = BLK_CRYPTO_KEY_TYPE_RAW;
368387
if (argc > 5) {
369388
err = inlinecrypt_ctr_optional(ti, argc - 5, &argv[5]);
370389
if (err)
@@ -385,10 +404,9 @@ static int inlinecrypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
385404
(ctx->sector_bits - SECTOR_SHIFT);
386405
dun_bytes = DIV_ROUND_UP(fls64(ctx->max_dun), 8);
387406

388-
err = blk_crypto_init_key(&ctx->key, raw_key, ctx->key_size,
389-
BLK_CRYPTO_KEY_TYPE_RAW,
390-
cipher->mode_num, dun_bytes,
391-
ctx->sector_size);
407+
err = blk_crypto_init_key(&ctx->key, key_bytes, ctx->key_size,
408+
ctx->key_type, cipher->mode_num,
409+
dun_bytes, ctx->sector_size);
392410
if (err) {
393411
ti->error = "Error initializing blk-crypto key";
394412
goto bad;
@@ -408,7 +426,7 @@ static int inlinecrypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
408426
bad:
409427
inlinecrypt_dtr(ti);
410428
out:
411-
memzero_explicit(raw_key, sizeof(raw_key));
429+
memzero_explicit(key_bytes, sizeof(key_bytes));
412430
return err;
413431
}
414432

@@ -502,8 +520,9 @@ static void inlinecrypt_status(struct dm_target *ti, status_type_t type,
502520
* the returned table. Userspace is responsible for redacting
503521
* the key when needed.
504522
*/
505-
DMEMIT("%s %*phN %llu %s %llu", ctx->cipher_string,
506-
ctx->key.size, ctx->key.bytes, ctx->iv_offset,
523+
DMEMIT("%s %*phN %u %llu %s %llu", ctx->cipher_string,
524+
ctx->key.size, ctx->key.bytes,
525+
ctx->key_type, ctx->iv_offset,
507526
ctx->dev->name, ctx->start);
508527
num_feature_args += !!ti->num_discard_bios;
509528
if (ctx->sector_size != SECTOR_SIZE)

0 commit comments

Comments
 (0)