提交 c79f6084 编写于 作者: R Roberto Sassu 提交者: Zheng Zengkai

evm: Propagate choice of HMAC algorithm in evm_crypto.c

hulk inclusion
category: feature
feature: IMA Digest Lists extension
bugzilla: 46797

-------------------------------------------------

Commit 5feeb611 ("evm: Allow non-SHA1 digital signatures") introduced
the possibility to use different hash algorithm for signatures, but kept
the algorithm for the HMAC hard-coded (SHA1). Switching to a different
algorithm for HMAC would require to change the code in different places.

This patch introduces a new global variable called evm_hash_algo, and
consistently uses it whenever EVM perform HMAC-related operations. It also
introduces a new kernel configuration option called CONFIG_EVM_DEFAULT_HASH
so that evm_hash_algo can be defined at kernel compilation time.
Signed-off-by: NRoberto Sassu <roberto.sassu@huawei.com>
Acked-by: NHanjun Guo <guohanjun@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
Signed-off-by: NTianxing Zhang <zhangtianxing3@huawei.com>
Reviewed-by: NJason Yan <yanaijie@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 1b8602d0
...@@ -13,6 +13,38 @@ config EVM ...@@ -13,6 +13,38 @@ config EVM
If you are unsure how to answer this question, answer N. If you are unsure how to answer this question, answer N.
choice
prompt "Default EVM hash algorithm"
default EVM_DEFAULT_HASH_SHA256
depends on EVM
help
Select the default hash algorithm used for the HMAC.
config EVM_DEFAULT_HASH_SHA1
bool "SHA1 (default)"
depends on CRYPTO_SHA1=y
config EVM_DEFAULT_HASH_SHA256
bool "SHA256"
depends on CRYPTO_SHA256=y
config EVM_DEFAULT_HASH_SHA512
bool "SHA512"
depends on CRYPTO_SHA512=y
config EVM_DEFAULT_HASH_WP512
bool "WP512"
depends on CRYPTO_WP512=y
endchoice
config EVM_DEFAULT_HASH
string
depends on EVM
default "sha1" if EVM_DEFAULT_HASH_SHA1
default "sha256" if EVM_DEFAULT_HASH_SHA256
default "sha512" if EVM_DEFAULT_HASH_SHA512
default "wp512" if EVM_DEFAULT_HASH_WP512
config EVM_ATTR_FSUUID config EVM_ATTR_FSUUID
bool "FSUUID (version 2)" bool "FSUUID (version 2)"
default y default y
......
...@@ -32,6 +32,7 @@ struct xattr_list { ...@@ -32,6 +32,7 @@ struct xattr_list {
}; };
extern int evm_initialized; extern int evm_initialized;
extern enum hash_algo evm_hash_algo;
#define EVM_ATTR_FSUUID 0x0001 #define EVM_ATTR_FSUUID 0x0001
......
...@@ -33,7 +33,7 @@ static DEFINE_MUTEX(mutex); ...@@ -33,7 +33,7 @@ static DEFINE_MUTEX(mutex);
static unsigned long evm_set_key_flags; static unsigned long evm_set_key_flags;
static const char evm_hmac[] = "hmac(sha1)"; enum hash_algo evm_hash_algo __ro_after_init = HASH_ALGO_SHA1;
/** /**
* evm_set_key() - set EVM HMAC key from the kernel * evm_set_key() - set EVM HMAC key from the kernel
...@@ -74,8 +74,12 @@ static struct shash_desc *init_desc(char type, uint8_t hash_algo) ...@@ -74,8 +74,12 @@ static struct shash_desc *init_desc(char type, uint8_t hash_algo)
long rc; long rc;
const char *algo; const char *algo;
struct crypto_shash **tfm, *tmp_tfm = NULL; struct crypto_shash **tfm, *tmp_tfm = NULL;
char evm_hmac[CRYPTO_MAX_ALG_NAME];
struct shash_desc *desc; struct shash_desc *desc;
snprintf(evm_hmac, sizeof(evm_hmac), "hmac(%s)",
CONFIG_EVM_DEFAULT_HASH);
if (type == EVM_XATTR_HMAC) { if (type == EVM_XATTR_HMAC) {
if (!(evm_initialized & EVM_INIT_HMAC)) { if (!(evm_initialized & EVM_INIT_HMAC)) {
pr_err_once("HMAC key is not set\n"); pr_err_once("HMAC key is not set\n");
...@@ -320,14 +324,15 @@ int evm_update_evmxattr(struct dentry *dentry, const char *xattr_name, ...@@ -320,14 +324,15 @@ int evm_update_evmxattr(struct dentry *dentry, const char *xattr_name,
if (rc) if (rc)
return -EPERM; return -EPERM;
data.hdr.algo = HASH_ALGO_SHA1; data.hdr.algo = evm_hash_algo;
rc = evm_calc_hmac(dentry, xattr_name, xattr_value, rc = evm_calc_hmac(dentry, xattr_name, xattr_value,
xattr_value_len, &data); xattr_value_len, &data);
if (rc == 0) { if (rc == 0) {
data.hdr.xattr.sha1.type = EVM_XATTR_HMAC; data.hdr.xattr.sha1.type = EVM_XATTR_HMAC;
rc = __vfs_setxattr_noperm(dentry, XATTR_NAME_EVM, rc = __vfs_setxattr_noperm(dentry, XATTR_NAME_EVM,
&data.hdr.xattr.data[1], &data.hdr.xattr.data[1],
SHA1_DIGEST_SIZE + 1, 0); hash_digest_size[evm_hash_algo] + 1,
0);
} else if (rc == -ENODATA && (inode->i_opflags & IOP_XATTR)) { } else if (rc == -ENODATA && (inode->i_opflags & IOP_XATTR)) {
rc = __vfs_removexattr(dentry, XATTR_NAME_EVM); rc = __vfs_removexattr(dentry, XATTR_NAME_EVM);
} }
...@@ -339,7 +344,7 @@ int evm_init_hmac(struct inode *inode, const struct xattr *lsm_xattr, ...@@ -339,7 +344,7 @@ int evm_init_hmac(struct inode *inode, const struct xattr *lsm_xattr,
{ {
struct shash_desc *desc; struct shash_desc *desc;
desc = init_desc(EVM_XATTR_HMAC, HASH_ALGO_SHA1); desc = init_desc(EVM_XATTR_HMAC, evm_hash_algo);
if (IS_ERR(desc)) { if (IS_ERR(desc)) {
pr_info("init_desc failed\n"); pr_info("init_desc failed\n");
return PTR_ERR(desc); return PTR_ERR(desc);
...@@ -352,7 +357,7 @@ int evm_init_hmac(struct inode *inode, const struct xattr *lsm_xattr, ...@@ -352,7 +357,7 @@ int evm_init_hmac(struct inode *inode, const struct xattr *lsm_xattr,
} }
/* /*
* Get the key from the TPM for the SHA1-HMAC * Get the key from the TPM for the HMAC
*/ */
int evm_init_key(void) int evm_init_key(void)
{ {
......
...@@ -213,17 +213,17 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry, ...@@ -213,17 +213,17 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
/* check value type */ /* check value type */
switch (xattr_data->type) { switch (xattr_data->type) {
case EVM_XATTR_HMAC: case EVM_XATTR_HMAC:
if (xattr_len != sizeof(struct evm_xattr)) { if (xattr_len != hash_digest_size[evm_hash_algo] + 1) {
evm_status = INTEGRITY_FAIL; evm_status = INTEGRITY_FAIL;
goto out; goto out;
} }
digest.hdr.algo = HASH_ALGO_SHA1; digest.hdr.algo = evm_hash_algo;
rc = evm_calc_hmac(dentry, xattr_name, xattr_value, rc = evm_calc_hmac(dentry, xattr_name, xattr_value,
xattr_value_len, &digest); xattr_value_len, &digest);
if (rc) if (rc)
break; break;
rc = crypto_memneq(xattr_data->data, digest.digest, rc = crypto_memneq(xattr_data->data, digest.digest,
SHA1_DIGEST_SIZE); hash_digest_size[evm_hash_algo]);
if (rc) if (rc)
rc = -EINVAL; rc = -EINVAL;
break; break;
...@@ -780,7 +780,7 @@ int evm_inode_init_security(struct inode *inode, ...@@ -780,7 +780,7 @@ int evm_inode_init_security(struct inode *inode,
goto out; goto out;
evm_xattr->value = xattr_data; evm_xattr->value = xattr_data;
evm_xattr->value_len = sizeof(*xattr_data); evm_xattr->value_len = hash_digest_size[evm_hash_algo] + 1;
evm_xattr->name = XATTR_EVM_SUFFIX; evm_xattr->name = XATTR_EVM_SUFFIX;
return 0; return 0;
out: out:
...@@ -802,9 +802,14 @@ void __init evm_load_x509(void) ...@@ -802,9 +802,14 @@ void __init evm_load_x509(void)
static int __init init_evm(void) static int __init init_evm(void)
{ {
int error; int error, i;
struct list_head *pos, *q; struct list_head *pos, *q;
i = match_string(hash_algo_name, HASH_ALGO__LAST,
CONFIG_EVM_DEFAULT_HASH);
if (i >= 0)
evm_hash_algo = i;
evm_init_config(); evm_init_config();
error = integrity_init_keyring(INTEGRITY_KEYRING_EVM); error = integrity_init_keyring(INTEGRITY_KEYRING_EVM);
......
...@@ -92,7 +92,7 @@ struct evm_ima_xattr_data { ...@@ -92,7 +92,7 @@ struct evm_ima_xattr_data {
/* Only used in the EVM HMAC code. */ /* Only used in the EVM HMAC code. */
struct evm_xattr { struct evm_xattr {
struct evm_ima_xattr_data data; struct evm_ima_xattr_data data;
u8 digest[SHA1_DIGEST_SIZE]; u8 digest[SHA512_DIGEST_SIZE];
} __packed; } __packed;
#define IMA_MAX_DIGEST_SIZE 64 #define IMA_MAX_DIGEST_SIZE 64
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册