* [PATCH V2 1/2] evm: Don't deadlock if a crypto algorithm is unavailable
@ 2018-06-06 21:57 Matthew Garrett
2018-06-06 21:57 ` [PATCH V2 2/2] evm: Allow non-SHA1 digital signatures Matthew Garrett
2018-06-13 6:28 ` [PATCH V2 1/2] evm: Don't deadlock if a crypto algorithm is unavailable Herbert Xu
0 siblings, 2 replies; 5+ messages in thread
From: Matthew Garrett @ 2018-06-06 21:57 UTC (permalink / raw)
To: linux-integrity; +Cc: zohar, linux-crypto, herbert, davem, Matthew Garrett
When EVM attempts to appraise a file signed with a crypto algorithm the
kernel doesn't have support for, it will cause the kernel to trigger a
module load. If the EVM policy includes appraisal of kernel modules this
will in turn call back into EVM - since EVM is holding a lock until the
crypto initialisation is complete, this triggers a deadlock. Add a
CRYPTO_NOLOAD flag and skip module loading if it's set, and add that flag
in the EVM case in order to fail gracefully with an error message
instead of deadlocking.
Signed-off-by: Matthew Garrett <mjg59@google.com>
---
crypto/api.c | 2 +-
include/linux/crypto.h | 5 +++++
security/integrity/evm/evm_crypto.c | 3 ++-
3 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/crypto/api.c b/crypto/api.c
index 0ee632bba064..7aca9f86c5f3 100644
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -229,7 +229,7 @@ static struct crypto_alg *crypto_larval_lookup(const char *name, u32 type,
mask &= ~(CRYPTO_ALG_LARVAL | CRYPTO_ALG_DEAD);
alg = crypto_alg_lookup(name, type, mask);
- if (!alg) {
+ if (!alg && !(mask & CRYPTO_NOLOAD)) {
request_module("crypto-%s", name);
if (!((type ^ CRYPTO_ALG_NEED_FALLBACK) & mask &
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index 6eb06101089f..e8839d3a7559 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -112,6 +112,11 @@
*/
#define CRYPTO_ALG_OPTIONAL_KEY 0x00004000
+/*
+ * Don't trigger module loading
+ */
+#define CRYPTO_NOLOAD 0x00008000
+
/*
* Transform masks and values (for crt_flags).
*/
diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c
index a46fba322340..ccafc9468611 100644
--- a/security/integrity/evm/evm_crypto.c
+++ b/security/integrity/evm/evm_crypto.c
@@ -97,7 +97,8 @@ static struct shash_desc *init_desc(char type)
mutex_lock(&mutex);
if (*tfm)
goto out;
- *tfm = crypto_alloc_shash(algo, 0, CRYPTO_ALG_ASYNC);
+ *tfm = crypto_alloc_shash(algo, 0,
+ CRYPTO_ALG_ASYNC | CRYPTO_NOLOAD);
if (IS_ERR(*tfm)) {
rc = PTR_ERR(*tfm);
pr_err("Can not allocate %s (reason: %ld)\n", algo, rc);
--
2.17.1.1185.g55be947832-goog
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH V2 2/2] evm: Allow non-SHA1 digital signatures
2018-06-06 21:57 [PATCH V2 1/2] evm: Don't deadlock if a crypto algorithm is unavailable Matthew Garrett
@ 2018-06-06 21:57 ` Matthew Garrett
2018-06-07 14:02 ` Mimi Zohar
2018-06-13 6:28 ` [PATCH V2 1/2] evm: Don't deadlock if a crypto algorithm is unavailable Herbert Xu
1 sibling, 1 reply; 5+ messages in thread
From: Matthew Garrett @ 2018-06-06 21:57 UTC (permalink / raw)
To: linux-integrity; +Cc: zohar, linux-crypto, herbert, davem, Matthew Garrett
SHA1 is reasonable in HMAC constructs, but it's desirable to be able to
use stronger hashes in digital signatures. Modify the EVM crypto code so
the hash type is imported from the digital signature and passed down to
the hash calculation code, and return the digest size to higher layers
for validation.
Signed-off-by: Matthew Garrett <mjg59@google.com>
---
security/integrity/evm/evm.h | 10 ++++--
security/integrity/evm/evm_crypto.c | 47 +++++++++++++++--------------
security/integrity/evm/evm_main.c | 19 +++++++-----
3 files changed, 45 insertions(+), 31 deletions(-)
diff --git a/security/integrity/evm/evm.h b/security/integrity/evm/evm.h
index 45c4a89c02ff..a8289fbf2f0c 100644
--- a/security/integrity/evm/evm.h
+++ b/security/integrity/evm/evm.h
@@ -42,6 +42,11 @@ extern struct crypto_shash *hash_tfm;
/* List of EVM protected security xattrs */
extern char *evm_config_xattrnames[];
+struct evm_digest {
+ struct ima_digest_data hdr;
+ char digest[IMA_MAX_DIGEST_SIZE];
+} __packed;
+
int evm_init_key(void);
int evm_update_evmxattr(struct dentry *dentry,
const char *req_xattr_name,
@@ -49,10 +54,11 @@ int evm_update_evmxattr(struct dentry *dentry,
size_t req_xattr_value_len);
int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name,
const char *req_xattr_value,
- size_t req_xattr_value_len, char *digest);
+ size_t req_xattr_value_len, struct evm_digest *data);
int evm_calc_hash(struct dentry *dentry, const char *req_xattr_name,
const char *req_xattr_value,
- size_t req_xattr_value_len, char type, char *digest);
+ size_t req_xattr_value_len, char type,
+ struct evm_digest *data);
int evm_init_hmac(struct inode *inode, const struct xattr *xattr,
char *hmac_val);
int evm_init_secfs(void);
diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c
index ccafc9468611..ff8687232a1a 100644
--- a/security/integrity/evm/evm_crypto.c
+++ b/security/integrity/evm/evm_crypto.c
@@ -21,6 +21,7 @@
#include <linux/evm.h>
#include <keys/encrypted-type.h>
#include <crypto/hash.h>
+#include <crypto/hash_info.h>
#include "evm.h"
#define EVMKEY "evm-key"
@@ -29,7 +30,7 @@ static unsigned char evmkey[MAX_KEY_SIZE];
static int evmkey_len = MAX_KEY_SIZE;
struct crypto_shash *hmac_tfm;
-struct crypto_shash *hash_tfm;
+static struct crypto_shash *evm_tfm[HASH_ALGO__LAST];
static DEFINE_MUTEX(mutex);
@@ -38,7 +39,6 @@ static DEFINE_MUTEX(mutex);
static unsigned long evm_set_key_flags;
static char * const evm_hmac = "hmac(sha1)";
-static char * const evm_hash = "sha1";
/**
* evm_set_key() - set EVM HMAC key from the kernel
@@ -74,10 +74,10 @@ int evm_set_key(void *key, size_t keylen)
}
EXPORT_SYMBOL_GPL(evm_set_key);
-static struct shash_desc *init_desc(char type)
+static struct shash_desc *init_desc(char type, uint8_t hash_algo)
{
long rc;
- char *algo;
+ const char *algo;
struct crypto_shash **tfm;
struct shash_desc *desc;
@@ -89,8 +89,8 @@ static struct shash_desc *init_desc(char type)
tfm = &hmac_tfm;
algo = evm_hmac;
} else {
- tfm = &hash_tfm;
- algo = evm_hash;
+ tfm = &evm_tfm[hash_algo];
+ algo = hash_algo_name[hash_algo];
}
if (*tfm == NULL) {
@@ -187,10 +187,10 @@ static void hmac_add_misc(struct shash_desc *desc, struct inode *inode,
* each xattr, but attempt to re-use the previously allocated memory.
*/
static int evm_calc_hmac_or_hash(struct dentry *dentry,
- const char *req_xattr_name,
- const char *req_xattr_value,
- size_t req_xattr_value_len,
- char type, char *digest)
+ const char *req_xattr_name,
+ const char *req_xattr_value,
+ size_t req_xattr_value_len,
+ uint8_t type, struct evm_digest *data)
{
struct inode *inode = d_backing_inode(dentry);
struct shash_desc *desc;
@@ -204,10 +204,12 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry,
if (!(inode->i_opflags & IOP_XATTR))
return -EOPNOTSUPP;
- desc = init_desc(type);
+ desc = init_desc(type, data->hdr.algo);
if (IS_ERR(desc))
return PTR_ERR(desc);
+ data->hdr.length = crypto_shash_digestsize(desc->tfm);
+
error = -ENODATA;
for (xattrname = evm_config_xattrnames; *xattrname != NULL; xattrname++) {
bool is_ima = false;
@@ -239,7 +241,7 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry,
if (is_ima)
ima_present = true;
}
- hmac_add_misc(desc, inode, type, digest);
+ hmac_add_misc(desc, inode, type, data->digest);
/* Portable EVM signatures must include an IMA hash */
if (type == EVM_XATTR_PORTABLE_DIGSIG && !ima_present)
@@ -252,18 +254,18 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry,
int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name,
const char *req_xattr_value, size_t req_xattr_value_len,
- char *digest)
+ struct evm_digest *data)
{
return evm_calc_hmac_or_hash(dentry, req_xattr_name, req_xattr_value,
- req_xattr_value_len, EVM_XATTR_HMAC, digest);
+ req_xattr_value_len, EVM_XATTR_HMAC, data);
}
int evm_calc_hash(struct dentry *dentry, const char *req_xattr_name,
const char *req_xattr_value, size_t req_xattr_value_len,
- char type, char *digest)
+ char type, struct evm_digest *data)
{
return evm_calc_hmac_or_hash(dentry, req_xattr_name, req_xattr_value,
- req_xattr_value_len, type, digest);
+ req_xattr_value_len, type, data);
}
static int evm_is_immutable(struct dentry *dentry, struct inode *inode)
@@ -303,7 +305,7 @@ int evm_update_evmxattr(struct dentry *dentry, const char *xattr_name,
const char *xattr_value, size_t xattr_value_len)
{
struct inode *inode = d_backing_inode(dentry);
- struct evm_ima_xattr_data xattr_data;
+ struct evm_digest data;
int rc = 0;
/*
@@ -316,13 +318,14 @@ int evm_update_evmxattr(struct dentry *dentry, const char *xattr_name,
if (rc)
return -EPERM;
+ data.hdr.algo = HASH_ALGO_SHA1;
rc = evm_calc_hmac(dentry, xattr_name, xattr_value,
- xattr_value_len, xattr_data.digest);
+ xattr_value_len, &data);
if (rc == 0) {
- xattr_data.type = EVM_XATTR_HMAC;
+ data.hdr.xattr.sha1.type = EVM_XATTR_HMAC;
rc = __vfs_setxattr_noperm(dentry, XATTR_NAME_EVM,
- &xattr_data,
- sizeof(xattr_data), 0);
+ &data.hdr.xattr.data[1],
+ SHA1_DIGEST_SIZE + 1, 0);
} else if (rc == -ENODATA && (inode->i_opflags & IOP_XATTR)) {
rc = __vfs_removexattr(dentry, XATTR_NAME_EVM);
}
@@ -334,7 +337,7 @@ int evm_init_hmac(struct inode *inode, const struct xattr *lsm_xattr,
{
struct shash_desc *desc;
- desc = init_desc(EVM_XATTR_HMAC);
+ desc = init_desc(EVM_XATTR_HMAC, HASH_ALGO_SHA1);
if (IS_ERR(desc)) {
pr_info("init_desc failed\n");
return PTR_ERR(desc);
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index 9ea9c19a545c..88ea9c1962d6 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -25,6 +25,7 @@
#include <linux/magic.h>
#include <crypto/hash.h>
+#include <crypto/hash_info.h>
#include <crypto/algapi.h>
#include "evm.h"
@@ -122,8 +123,9 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
struct integrity_iint_cache *iint)
{
struct evm_ima_xattr_data *xattr_data = NULL;
- struct evm_ima_xattr_data calc;
+ struct signature_v2_hdr *hdr;
enum integrity_status evm_status = INTEGRITY_PASS;
+ struct evm_digest digest;
struct inode *inode;
int rc, xattr_len;
@@ -159,25 +161,28 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
evm_status = INTEGRITY_FAIL;
goto out;
}
+
+ digest.hdr.algo = HASH_ALGO_SHA1;
rc = evm_calc_hmac(dentry, xattr_name, xattr_value,
- xattr_value_len, calc.digest);
+ xattr_value_len, &digest);
if (rc)
break;
- rc = crypto_memneq(xattr_data->digest, calc.digest,
- sizeof(calc.digest));
+ rc = crypto_memneq(xattr_data->digest, digest.digest,
+ SHA1_DIGEST_SIZE);
if (rc)
rc = -EINVAL;
break;
case EVM_IMA_XATTR_DIGSIG:
case EVM_XATTR_PORTABLE_DIGSIG:
+ hdr = (struct signature_v2_hdr *)xattr_data;
+ digest.hdr.algo = hdr->hash_algo;
rc = evm_calc_hash(dentry, xattr_name, xattr_value,
- xattr_value_len, xattr_data->type,
- calc.digest);
+ xattr_value_len, xattr_data->type, &digest);
if (rc)
break;
rc = integrity_digsig_verify(INTEGRITY_KEYRING_EVM,
(const char *)xattr_data, xattr_len,
- calc.digest, sizeof(calc.digest));
+ digest.digest, digest.hdr.length);
if (!rc) {
inode = d_backing_inode(dentry);
--
2.17.1.1185.g55be947832-goog
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH V2 2/2] evm: Allow non-SHA1 digital signatures
2018-06-06 21:57 ` [PATCH V2 2/2] evm: Allow non-SHA1 digital signatures Matthew Garrett
@ 2018-06-07 14:02 ` Mimi Zohar
2018-06-07 20:32 ` Matthew Garrett
0 siblings, 1 reply; 5+ messages in thread
From: Mimi Zohar @ 2018-06-07 14:02 UTC (permalink / raw)
To: Matthew Garrett, linux-integrity
Hi Matthew,
On Wed, 2018-06-06 at 14:57 -0700, Matthew Garrett wrote:
> SHA1 is reasonable in HMAC constructs, but it's desirable to be able to
> use stronger hashes in digital signatures. Modify the EVM crypto code so
> the hash type is imported from the digital signature and passed down to
> the hash calculation code, and return the digest size to higher layers
> for validation.
>
> Signed-off-by: Matthew Garrett <mjg59@google.com>
This patch applies using "quilt push", but not with "git am". Did you
post the associated ima-evm-utils patch?
thanks,
Mimi
> ---
> security/integrity/evm/evm.h | 10 ++++--
> security/integrity/evm/evm_crypto.c | 47 +++++++++++++++--------------
> security/integrity/evm/evm_main.c | 19 +++++++-----
> 3 files changed, 45 insertions(+), 31 deletions(-)
>
> diff --git a/security/integrity/evm/evm.h b/security/integrity/evm/evm.h
> index 45c4a89c02ff..a8289fbf2f0c 100644
> --- a/security/integrity/evm/evm.h
> +++ b/security/integrity/evm/evm.h
> @@ -42,6 +42,11 @@ extern struct crypto_shash *hash_tfm;
> /* List of EVM protected security xattrs */
> extern char *evm_config_xattrnames[];
>
> +struct evm_digest {
> + struct ima_digest_data hdr;
> + char digest[IMA_MAX_DIGEST_SIZE];
> +} __packed;
> +
> int evm_init_key(void);
> int evm_update_evmxattr(struct dentry *dentry,
> const char *req_xattr_name,
> @@ -49,10 +54,11 @@ int evm_update_evmxattr(struct dentry *dentry,
> size_t req_xattr_value_len);
> int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name,
> const char *req_xattr_value,
> - size_t req_xattr_value_len, char *digest);
> + size_t req_xattr_value_len, struct evm_digest *data);
> int evm_calc_hash(struct dentry *dentry, const char *req_xattr_name,
> const char *req_xattr_value,
> - size_t req_xattr_value_len, char type, char *digest);
> + size_t req_xattr_value_len, char type,
> + struct evm_digest *data);
> int evm_init_hmac(struct inode *inode, const struct xattr *xattr,
> char *hmac_val);
> int evm_init_secfs(void);
> diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c
> index ccafc9468611..ff8687232a1a 100644
> --- a/security/integrity/evm/evm_crypto.c
> +++ b/security/integrity/evm/evm_crypto.c
> @@ -21,6 +21,7 @@
> #include <linux/evm.h>
> #include <keys/encrypted-type.h>
> #include <crypto/hash.h>
> +#include <crypto/hash_info.h>
> #include "evm.h"
>
> #define EVMKEY "evm-key"
> @@ -29,7 +30,7 @@ static unsigned char evmkey[MAX_KEY_SIZE];
> static int evmkey_len = MAX_KEY_SIZE;
>
> struct crypto_shash *hmac_tfm;
> -struct crypto_shash *hash_tfm;
> +static struct crypto_shash *evm_tfm[HASH_ALGO__LAST];
>
> static DEFINE_MUTEX(mutex);
>
> @@ -38,7 +39,6 @@ static DEFINE_MUTEX(mutex);
> static unsigned long evm_set_key_flags;
>
> static char * const evm_hmac = "hmac(sha1)";
> -static char * const evm_hash = "sha1";
>
> /**
> * evm_set_key() - set EVM HMAC key from the kernel
> @@ -74,10 +74,10 @@ int evm_set_key(void *key, size_t keylen)
> }
> EXPORT_SYMBOL_GPL(evm_set_key);
>
> -static struct shash_desc *init_desc(char type)
> +static struct shash_desc *init_desc(char type, uint8_t hash_algo)
> {
> long rc;
> - char *algo;
> + const char *algo;
> struct crypto_shash **tfm;
> struct shash_desc *desc;
>
> @@ -89,8 +89,8 @@ static struct shash_desc *init_desc(char type)
> tfm = &hmac_tfm;
> algo = evm_hmac;
> } else {
> - tfm = &hash_tfm;
> - algo = evm_hash;
> + tfm = &evm_tfm[hash_algo];
> + algo = hash_algo_name[hash_algo];
> }
>
> if (*tfm == NULL) {
> @@ -187,10 +187,10 @@ static void hmac_add_misc(struct shash_desc *desc, struct inode *inode,
> * each xattr, but attempt to re-use the previously allocated memory.
> */
> static int evm_calc_hmac_or_hash(struct dentry *dentry,
> - const char *req_xattr_name,
> - const char *req_xattr_value,
> - size_t req_xattr_value_len,
> - char type, char *digest)
> + const char *req_xattr_name,
> + const char *req_xattr_value,
> + size_t req_xattr_value_len,
> + uint8_t type, struct evm_digest *data)
> {
> struct inode *inode = d_backing_inode(dentry);
> struct shash_desc *desc;
> @@ -204,10 +204,12 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry,
> if (!(inode->i_opflags & IOP_XATTR))
> return -EOPNOTSUPP;
>
> - desc = init_desc(type);
> + desc = init_desc(type, data->hdr.algo);
> if (IS_ERR(desc))
> return PTR_ERR(desc);
>
> + data->hdr.length = crypto_shash_digestsize(desc->tfm);
> +
> error = -ENODATA;
> for (xattrname = evm_config_xattrnames; *xattrname != NULL; xattrname++) {
> bool is_ima = false;
> @@ -239,7 +241,7 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry,
> if (is_ima)
> ima_present = true;
> }
> - hmac_add_misc(desc, inode, type, digest);
> + hmac_add_misc(desc, inode, type, data->digest);
>
> /* Portable EVM signatures must include an IMA hash */
> if (type == EVM_XATTR_PORTABLE_DIGSIG && !ima_present)
> @@ -252,18 +254,18 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry,
>
> int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name,
> const char *req_xattr_value, size_t req_xattr_value_len,
> - char *digest)
> + struct evm_digest *data)
> {
> return evm_calc_hmac_or_hash(dentry, req_xattr_name, req_xattr_value,
> - req_xattr_value_len, EVM_XATTR_HMAC, digest);
> + req_xattr_value_len, EVM_XATTR_HMAC, data);
> }
>
> int evm_calc_hash(struct dentry *dentry, const char *req_xattr_name,
> const char *req_xattr_value, size_t req_xattr_value_len,
> - char type, char *digest)
> + char type, struct evm_digest *data)
> {
> return evm_calc_hmac_or_hash(dentry, req_xattr_name, req_xattr_value,
> - req_xattr_value_len, type, digest);
> + req_xattr_value_len, type, data);
> }
>
> static int evm_is_immutable(struct dentry *dentry, struct inode *inode)
> @@ -303,7 +305,7 @@ int evm_update_evmxattr(struct dentry *dentry, const char *xattr_name,
> const char *xattr_value, size_t xattr_value_len)
> {
> struct inode *inode = d_backing_inode(dentry);
> - struct evm_ima_xattr_data xattr_data;
> + struct evm_digest data;
> int rc = 0;
>
> /*
> @@ -316,13 +318,14 @@ int evm_update_evmxattr(struct dentry *dentry, const char *xattr_name,
> if (rc)
> return -EPERM;
>
> + data.hdr.algo = HASH_ALGO_SHA1;
> rc = evm_calc_hmac(dentry, xattr_name, xattr_value,
> - xattr_value_len, xattr_data.digest);
> + xattr_value_len, &data);
> if (rc == 0) {
> - xattr_data.type = EVM_XATTR_HMAC;
> + data.hdr.xattr.sha1.type = EVM_XATTR_HMAC;
> rc = __vfs_setxattr_noperm(dentry, XATTR_NAME_EVM,
> - &xattr_data,
> - sizeof(xattr_data), 0);
> + &data.hdr.xattr.data[1],
> + SHA1_DIGEST_SIZE + 1, 0);
> } else if (rc == -ENODATA && (inode->i_opflags & IOP_XATTR)) {
> rc = __vfs_removexattr(dentry, XATTR_NAME_EVM);
> }
> @@ -334,7 +337,7 @@ int evm_init_hmac(struct inode *inode, const struct xattr *lsm_xattr,
> {
> struct shash_desc *desc;
>
> - desc = init_desc(EVM_XATTR_HMAC);
> + desc = init_desc(EVM_XATTR_HMAC, HASH_ALGO_SHA1);
> if (IS_ERR(desc)) {
> pr_info("init_desc failed\n");
> return PTR_ERR(desc);
> diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
> index 9ea9c19a545c..88ea9c1962d6 100644
> --- a/security/integrity/evm/evm_main.c
> +++ b/security/integrity/evm/evm_main.c
> @@ -25,6 +25,7 @@
> #include <linux/magic.h>
>
> #include <crypto/hash.h>
> +#include <crypto/hash_info.h>
> #include <crypto/algapi.h>
> #include "evm.h"
>
> @@ -122,8 +123,9 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
> struct integrity_iint_cache *iint)
> {
> struct evm_ima_xattr_data *xattr_data = NULL;
> - struct evm_ima_xattr_data calc;
> + struct signature_v2_hdr *hdr;
> enum integrity_status evm_status = INTEGRITY_PASS;
> + struct evm_digest digest;
> struct inode *inode;
> int rc, xattr_len;
>
> @@ -159,25 +161,28 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
> evm_status = INTEGRITY_FAIL;
> goto out;
> }
> +
> + digest.hdr.algo = HASH_ALGO_SHA1;
> rc = evm_calc_hmac(dentry, xattr_name, xattr_value,
> - xattr_value_len, calc.digest);
> + xattr_value_len, &digest);
> if (rc)
> break;
> - rc = crypto_memneq(xattr_data->digest, calc.digest,
> - sizeof(calc.digest));
> + rc = crypto_memneq(xattr_data->digest, digest.digest,
> + SHA1_DIGEST_SIZE);
> if (rc)
> rc = -EINVAL;
> break;
> case EVM_IMA_XATTR_DIGSIG:
> case EVM_XATTR_PORTABLE_DIGSIG:
> + hdr = (struct signature_v2_hdr *)xattr_data;
> + digest.hdr.algo = hdr->hash_algo;
> rc = evm_calc_hash(dentry, xattr_name, xattr_value,
> - xattr_value_len, xattr_data->type,
> - calc.digest);
> + xattr_value_len, xattr_data->type, &digest);
> if (rc)
> break;
> rc = integrity_digsig_verify(INTEGRITY_KEYRING_EVM,
> (const char *)xattr_data, xattr_len,
> - calc.digest, sizeof(calc.digest));
> + digest.digest, digest.hdr.length);
> if (!rc) {
> inode = d_backing_inode(dentry);
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH V2 2/2] evm: Allow non-SHA1 digital signatures
2018-06-07 14:02 ` Mimi Zohar
@ 2018-06-07 20:32 ` Matthew Garrett
0 siblings, 0 replies; 5+ messages in thread
From: Matthew Garrett @ 2018-06-07 20:32 UTC (permalink / raw)
To: Mimi Zohar; +Cc: linux-integrity
On Thu, Jun 7, 2018 at 7:02 AM Mimi Zohar <zohar@linux.vnet.ibm.com> wrote:
>
> Hi Matthew,
>
> On Wed, 2018-06-06 at 14:57 -0700, Matthew Garrett wrote:
> > SHA1 is reasonable in HMAC constructs, but it's desirable to be able to
> > use stronger hashes in digital signatures. Modify the EVM crypto code so
> > the hash type is imported from the digital signature and passed down to
> > the hash calculation code, and return the digest size to higher layers
> > for validation.
> >
> > Signed-off-by: Matthew Garrett <mjg59@google.com>
>
> This patch applies using "quilt push", but not with "git am". Did you
> post the associated ima-evm-utils patch?
That's strange - I sent it with git send-email. I can resend the
userspace patch (the original one allowed non-SHA1 HMACs, but that
doesn't seem helpful, so I'll drop that part)
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH V2 1/2] evm: Don't deadlock if a crypto algorithm is unavailable
2018-06-06 21:57 [PATCH V2 1/2] evm: Don't deadlock if a crypto algorithm is unavailable Matthew Garrett
2018-06-06 21:57 ` [PATCH V2 2/2] evm: Allow non-SHA1 digital signatures Matthew Garrett
@ 2018-06-13 6:28 ` Herbert Xu
1 sibling, 0 replies; 5+ messages in thread
From: Herbert Xu @ 2018-06-13 6:28 UTC (permalink / raw)
To: Matthew Garrett; +Cc: linux-integrity, zohar, linux-crypto, davem
On Wed, Jun 06, 2018 at 02:57:11PM -0700, Matthew Garrett wrote:
> When EVM attempts to appraise a file signed with a crypto algorithm the
> kernel doesn't have support for, it will cause the kernel to trigger a
> module load. If the EVM policy includes appraisal of kernel modules this
> will in turn call back into EVM - since EVM is holding a lock until the
> crypto initialisation is complete, this triggers a deadlock. Add a
> CRYPTO_NOLOAD flag and skip module loading if it's set, and add that flag
> in the EVM case in order to fail gracefully with an error message
> instead of deadlocking.
>
> Signed-off-by: Matthew Garrett <mjg59@google.com>
> ---
> crypto/api.c | 2 +-
> include/linux/crypto.h | 5 +++++
> security/integrity/evm/evm_crypto.c | 3 ++-
> 3 files changed, 8 insertions(+), 2 deletions(-)
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2018-06-13 6:28 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-06-06 21:57 [PATCH V2 1/2] evm: Don't deadlock if a crypto algorithm is unavailable Matthew Garrett
2018-06-06 21:57 ` [PATCH V2 2/2] evm: Allow non-SHA1 digital signatures Matthew Garrett
2018-06-07 14:02 ` Mimi Zohar
2018-06-07 20:32 ` Matthew Garrett
2018-06-13 6:28 ` [PATCH V2 1/2] evm: Don't deadlock if a crypto algorithm is unavailable Herbert Xu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).