blob: aa479e3e989ea079836fad759b41b99b2b27d4ef [file] [log] [blame]
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Barani Muthukumaran <bmuthuku@codeaurora.org>
Date: Thu, 6 Feb 2020 18:01:33 -0800
Subject: ANDROID: dm: Add wrapped key support in dm-default-key
To prevent keys from being compromised if an attacker acquires read
access to kernel memory, some inline encryption hardware supports
protecting the keys in hardware without software having access to or the
ability to set the plaintext keys. Instead, software only sees "wrapped
keys", which may differ on every boot. The keys can be initially
generated either by software (in which case they need to be imported to
hardware to be wrapped), or directly by the hardware.
Add support for this type of hardware by allowing keys to be flagged as
hardware-wrapped. When used, dm-default-key will pass the wrapped key
to the inline encryption hardware to encryption metadata. The hardware
will internally unwrap the key and derive the metadata encryption key.
This is a reworked version of a patch which was temporily reverted by
https://android-review.googlesource.com/c/kernel/common/+/1867365, and
which originated from
https://android-review.googlesource.com/c/kernel/common/+/1224286.
Bug: 147209885
Bug: 160883801
Bug: 160883266
Bug: 160885805
Test: Validate metadata encryption & FBE with wrapped keys.
Change-Id: I38393727bf71e5d20b3c3ac9d2af62a1864a0a82
Signed-off-by: Barani Muthukumaran <bmuthuku@codeaurora.org>
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
drivers/md/dm-default-key.c | 29 ++++++++++++++++++++---------
1 file changed, 20 insertions(+), 9 deletions(-)
diff --git a/drivers/md/dm-default-key.c b/drivers/md/dm-default-key.c
--- a/drivers/md/dm-default-key.c
+++ b/drivers/md/dm-default-key.c
@@ -9,8 +9,6 @@
#define DM_MSG_PREFIX "default-key"
-#define DM_DEFAULT_KEY_MAX_KEY_SIZE 64
-
static const struct dm_default_key_cipher {
const char *name;
enum blk_crypto_mode_num mode_num;
@@ -48,6 +46,7 @@ struct default_key_c {
unsigned int sector_size;
unsigned int sector_bits;
struct blk_crypto_key key;
+ enum blk_crypto_key_type key_type;
u64 max_dun;
};
@@ -85,7 +84,7 @@ static int default_key_ctr_optional(struct dm_target *ti,
struct default_key_c *dkc = ti->private;
struct dm_arg_set as;
static const struct dm_arg _args[] = {
- {0, 3, "Invalid number of feature args"},
+ {0, 4, "Invalid number of feature args"},
};
unsigned int opt_params;
const char *opt_string;
@@ -118,6 +117,8 @@ static int default_key_ctr_optional(struct dm_target *ti,
}
} else if (!strcmp(opt_string, "iv_large_sectors")) {
iv_large_sectors = true;
+ } else if (!strcmp(opt_string, "wrappedkey_v0")) {
+ dkc->key_type = BLK_CRYPTO_KEY_TYPE_HW_WRAPPED;
} else {
ti->error = "Invalid feature arguments";
return -EINVAL;
@@ -145,7 +146,8 @@ static int default_key_ctr(struct dm_target *ti, unsigned int argc, char **argv)
{
struct default_key_c *dkc;
const struct dm_default_key_cipher *cipher;
- u8 raw_key[DM_DEFAULT_KEY_MAX_KEY_SIZE];
+ u8 raw_key[BLK_CRYPTO_MAX_ANY_KEY_SIZE];
+ unsigned int raw_key_size;
unsigned int dun_bytes;
unsigned long long tmpll;
char dummy;
@@ -162,6 +164,7 @@ static int default_key_ctr(struct dm_target *ti, unsigned int argc, char **argv)
return -ENOMEM;
}
ti->private = dkc;
+ dkc->key_type = BLK_CRYPTO_KEY_TYPE_STANDARD;
/* <cipher> */
dkc->cipher_string = kstrdup(argv[0], GFP_KERNEL);
@@ -178,12 +181,15 @@ static int default_key_ctr(struct dm_target *ti, unsigned int argc, char **argv)
}
/* <key> */
- if (strlen(argv[1]) != 2 * cipher->key_size) {
- ti->error = "Incorrect key size for cipher";
+ raw_key_size = strlen(argv[1]);
+ if (raw_key_size > 2 * BLK_CRYPTO_MAX_ANY_KEY_SIZE ||
+ raw_key_size % 2) {
+ ti->error = "Invalid keysize";
err = -EINVAL;
goto bad;
}
- if (hex2bin(raw_key, argv[1], cipher->key_size) != 0) {
+ raw_key_size /= 2;
+ if (hex2bin(raw_key, argv[1], raw_key_size) != 0) {
ti->error = "Malformed key string";
err = -EINVAL;
goto bad;
@@ -231,7 +237,8 @@ static int default_key_ctr(struct dm_target *ti, unsigned int argc, char **argv)
(dkc->sector_bits - SECTOR_SHIFT);
dun_bytes = DIV_ROUND_UP(fls64(dkc->max_dun), 8);
- err = blk_crypto_init_key(&dkc->key, raw_key, cipher->mode_num,
+ err = blk_crypto_init_key(&dkc->key, raw_key, raw_key_size,
+ dkc->key_type, cipher->mode_num,
dun_bytes, dkc->sector_size);
if (err) {
ti->error = "Error initializing blk-crypto key";
@@ -331,6 +338,8 @@ static void default_key_status(struct dm_target *ti, status_type_t type,
num_feature_args += !!ti->num_discard_bios;
if (dkc->sector_size != SECTOR_SIZE)
num_feature_args += 2;
+ if (dkc->key_type == BLK_CRYPTO_KEY_TYPE_HW_WRAPPED)
+ num_feature_args += 1;
if (num_feature_args != 0) {
DMEMIT(" %d", num_feature_args);
if (ti->num_discard_bios)
@@ -339,6 +348,8 @@ static void default_key_status(struct dm_target *ti, status_type_t type,
DMEMIT(" sector_size:%u", dkc->sector_size);
DMEMIT(" iv_large_sectors");
}
+ if (dkc->key_type == BLK_CRYPTO_KEY_TYPE_HW_WRAPPED)
+ DMEMIT(" wrappedkey_v0");
}
break;
}
@@ -383,7 +394,7 @@ static void default_key_io_hints(struct dm_target *ti,
static struct target_type default_key_target = {
.name = "default-key",
- .version = {2, 0, 0},
+ .version = {2, 1, 0},
.features = DM_TARGET_PASSES_CRYPTO,
.module = THIS_MODULE,
.ctr = default_key_ctr,