aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeeraj Soni <neersoni@codeaurora.org>2020-08-08 21:50:47 +0530
committerGerrit - the friendly Code Review server <code-review@localhost>2020-09-19 22:25:50 -0700
commitf2fd9ea91cae6b30ada3989228c3c4981489a223 (patch)
treed58cfc41b27a921e0d3b1051131f337cc4d04144
parent3da487329d65afc2061d72e7d303a5f9f141f307 (diff)
Handle variable encryption key sizesLA.UM.8.15.r2-01300-KAMORTA.0
With system having capability to use both hardware keymanager and secure world to process data encryption keys software need to have capability to handle variable length of encryption keys. Change-Id: I8a039883bd1ded70ac5901f24574bb01905ca460 Signed-off-by: Neeraj Soni <neersoni@codeaurora.org>
-rw-r--r--fs/crypto/fscrypt_ice.h7
-rw-r--r--fs/crypto/fscrypt_private.h1
-rw-r--r--fs/crypto/keyinfo.c30
3 files changed, 25 insertions, 13 deletions
diff --git a/fs/crypto/fscrypt_ice.h b/fs/crypto/fscrypt_ice.h
index 84de010ec60a..cc77fe5e7120 100644
--- a/fs/crypto/fscrypt_ice.h
+++ b/fs/crypto/fscrypt_ice.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*/
#ifndef _FSCRYPT_ICE_H
@@ -36,7 +36,10 @@ bool fscrypt_is_ice_encryption_info_equal(const struct inode *inode1,
static inline size_t fscrypt_get_ice_encryption_key_size(
const struct inode *inode)
{
- return FS_AES_256_XTS_KEY_SIZE / 2;
+ if (inode && inode->i_crypt_info)
+ return inode->i_crypt_info->key_size;
+
+ return 0;
}
static inline size_t fscrypt_get_ice_encryption_salt_size(
diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h
index a4a55d521f6e..1b40486fefdd 100644
--- a/fs/crypto/fscrypt_private.h
+++ b/fs/crypto/fscrypt_private.h
@@ -98,6 +98,7 @@ struct fscrypt_info {
u8 ci_master_key_descriptor[FS_KEY_DESCRIPTOR_SIZE];
u8 ci_nonce[FS_KEY_DERIVATION_NONCE_SIZE];
u8 ci_raw_key[FS_MAX_KEY_SIZE];
+ size_t key_size;
};
typedef enum {
diff --git a/fs/crypto/keyinfo.c b/fs/crypto/keyinfo.c
index a22c31621850..0a774c72743e 100644
--- a/fs/crypto/keyinfo.c
+++ b/fs/crypto/keyinfo.c
@@ -81,7 +81,7 @@ static struct key *
find_and_lock_process_key(const char *prefix,
const u8 descriptor[FS_KEY_DESCRIPTOR_SIZE],
unsigned int min_keysize,
- const struct fscrypt_key **payload_ret)
+ const struct fscrypt_key **payload_ret, size_t *size)
{
char *description;
struct key *key;
@@ -105,16 +105,20 @@ find_and_lock_process_key(const char *prefix,
goto invalid;
payload = (const struct fscrypt_key *)ukp->data;
+ *size = payload->size;
- if (ukp->datalen != sizeof(struct fscrypt_key) ||
- payload->size < 1 || payload->size > FS_MAX_KEY_SIZE) {
+ if (ukp->datalen == 72)
+ *size = 64;
+
+ if (ukp->datalen > sizeof(struct fscrypt_key) ||
+ *size < 1 || *size > FS_MAX_KEY_SIZE) {
fscrypt_warn(NULL,
"key with description '%s' has invalid payload",
key->description);
goto invalid;
}
- if (payload->size < min_keysize) {
+ if (*size < 64) {
fscrypt_warn(NULL,
"key with description '%s' is too short (got %u bytes, need %u+ bytes)",
key->description, payload->size, min_keysize);
@@ -122,6 +126,7 @@ find_and_lock_process_key(const char *prefix,
}
*payload_ret = payload;
+
return key;
invalid:
@@ -165,7 +170,7 @@ static struct fscrypt_mode available_modes[] = {
[FS_ENCRYPTION_MODE_PRIVATE] = {
.friendly_name = "ice",
.cipher_str = "xts(aes)",
- .keysize = 64,
+ .keysize = 100,
.ivsize = 16,
.inline_encryption = true,
},
@@ -209,7 +214,8 @@ select_encryption_mode(const struct fscrypt_info *ci, const struct inode *inode)
/* Find the master key, then derive the inode's actual encryption key */
static int find_and_derive_key(const struct inode *inode,
const struct fscrypt_context *ctx,
- u8 *derived_key, const struct fscrypt_mode *mode)
+ u8 *derived_key, const struct fscrypt_mode *mode,
+ size_t *size)
{
struct key *key;
const struct fscrypt_key *payload;
@@ -217,11 +223,11 @@ static int find_and_derive_key(const struct inode *inode,
key = find_and_lock_process_key(FS_KEY_DESC_PREFIX,
ctx->master_key_descriptor,
- mode->keysize, &payload);
+ mode->keysize, &payload, size);
if (key == ERR_PTR(-ENOKEY) && inode->i_sb->s_cop->key_prefix) {
key = find_and_lock_process_key(inode->i_sb->s_cop->key_prefix,
ctx->master_key_descriptor,
- mode->keysize, &payload);
+ mode->keysize, &payload, size);
}
if (IS_ERR(key))
return PTR_ERR(key);
@@ -242,7 +248,7 @@ static int find_and_derive_key(const struct inode *inode,
err = 0;
}
} else if (mode->inline_encryption) {
- memcpy(derived_key, payload->raw, mode->keysize);
+ memcpy(derived_key, payload->raw, *size);
err = 0;
} else {
err = derive_key_aes(payload->raw, ctx, derived_key,
@@ -541,6 +547,7 @@ int fscrypt_get_encryption_info(struct inode *inode)
struct fscrypt_mode *mode;
u8 *raw_key = NULL;
int res;
+ size_t size;
if (fscrypt_has_encryption_key(inode))
return 0;
@@ -599,7 +606,7 @@ int fscrypt_get_encryption_info(struct inode *inode)
if (!raw_key)
goto out;
- res = find_and_derive_key(inode, &ctx, raw_key, mode);
+ res = find_and_derive_key(inode, &ctx, raw_key, mode, &size);
if (res)
goto out;
@@ -608,7 +615,8 @@ int fscrypt_get_encryption_info(struct inode *inode)
if (res)
goto out;
} else {
- memcpy(crypt_info->ci_raw_key, raw_key, mode->keysize);
+ memcpy(crypt_info->ci_raw_key, raw_key, size);
+ crypt_info->key_size = size;
}
if (cmpxchg_release(&inode->i_crypt_info, NULL, crypt_info) == NULL)