diff options
author | Neeraj Soni <neersoni@codeaurora.org> | 2020-08-08 21:50:47 +0530 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2020-09-19 22:25:50 -0700 |
commit | f2fd9ea91cae6b30ada3989228c3c4981489a223 (patch) | |
tree | d58cfc41b27a921e0d3b1051131f337cc4d04144 | |
parent | 3da487329d65afc2061d72e7d303a5f9f141f307 (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.h | 7 | ||||
-rw-r--r-- | fs/crypto/fscrypt_private.h | 1 | ||||
-rw-r--r-- | fs/crypto/keyinfo.c | 30 |
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) |