提交 1939da70 编写于 作者: K Krzysztof Struczynski 提交者: Zheng Zengkai

integrity: Add key domain tag to the search criteria

hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I49KW1
CVE: NA

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

Add key domain tag to the search criteria in digsig module. If the
domain tag is not set for the keys from the given keyring, it is set to
NULL and the behaviour is unchanged.

The key domain tag is added to the ima appraisal keys loaded to the
system ima keyring.
Signed-off-by: NKrzysztof Struczynski <krzysztof.struczynski@huawei.com>
Reviewed-by: NZhang Tianxing <zhangtianxing3@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 60499d14
......@@ -44,13 +44,16 @@ struct signature_hdr {
#if defined(CONFIG_SIGNATURE) || defined(CONFIG_SIGNATURE_MODULE)
int digsig_verify(struct key *keyring, const char *sig, int siglen,
const char *digest, int digestlen);
int digsig_verify(struct key *keyring, struct key_tag *domain_tag,
const char *sig, int siglen, const char *digest,
int digestlen);
#else
static inline int digsig_verify(struct key *keyring, const char *sig,
int siglen, const char *digest, int digestlen)
static inline int digsig_verify(struct key *keyring,
struct key_tag *domain_tag,
const char *sig, int siglen, const char *digest,
int digestlen)
{
return -EOPNOTSUPP;
}
......
......@@ -196,8 +196,8 @@ static int digsig_verify_rsa(struct key *key,
* Normally hash of the content is used as a data for this function.
*
*/
int digsig_verify(struct key *keyring, const char *sig, int siglen,
const char *data, int datalen)
int digsig_verify(struct key *keyring, struct key_tag *domain_tag,
const char *sig, int siglen, const char *data, int datalen)
{
int err = -ENOMEM;
struct signature_hdr *sh = (struct signature_hdr *)sig;
......@@ -217,14 +217,15 @@ int digsig_verify(struct key *keyring, const char *sig, int siglen,
if (keyring) {
/* search in specific keyring */
key_ref_t kref;
kref = keyring_search(make_key_ref(keyring, 1UL),
&key_type_user, name, true);
kref = keyring_search_tag(make_key_ref(keyring, 1UL),
&key_type_user, name,
domain_tag, true);
if (IS_ERR(kref))
key = ERR_CAST(kref);
else
key = key_ref_to_ptr(kref);
} else {
key = request_key(&key_type_user, name, NULL);
key = request_key_tag(&key_type_user, name, domain_tag, NULL);
}
if (IS_ERR(key)) {
pr_err("key not found, id: %s\n", name);
......
......@@ -16,6 +16,7 @@
#include <linux/vmalloc.h>
#include <crypto/public_key.h>
#include <keys/system_keyring.h>
#include <linux/ima.h>
#include "integrity.h"
......@@ -32,6 +33,16 @@ static const char * const keyring_name[INTEGRITY_KEYRING_MAX] = {
".platform",
};
static unsigned long keyring_alloc_flags[INTEGRITY_KEYRING_MAX] = {
KEY_ALLOC_NOT_IN_QUOTA,
#ifdef CONFIG_IMA_NS
KEY_ALLOC_NOT_IN_QUOTA | KEY_ALLOC_DOMAIN_IMA,
#else
KEY_ALLOC_NOT_IN_QUOTA,
#endif
KEY_ALLOC_NOT_IN_QUOTA,
};
#ifdef CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY
#define restrict_link_to_ima restrict_link_by_builtin_and_secondary_trusted
#else
......@@ -57,10 +68,22 @@ static struct key *integrity_keyring_from_id(const unsigned int id)
return keyring[id];
}
static struct key_tag *domain_tag_from_id(const unsigned int id)
{
if (id >= INTEGRITY_KEYRING_MAX)
return ERR_PTR(-EINVAL);
if (id == INTEGRITY_KEYRING_IMA)
return current->nsproxy->ima_ns->key_domain;
return NULL;
}
int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
const char *digest, int digestlen)
{
struct key *keyring;
struct key_tag *domain_tag;
if (siglen < 2)
return -EINVAL;
......@@ -69,14 +92,18 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
if (IS_ERR(keyring))
return PTR_ERR(keyring);
domain_tag = domain_tag_from_id(id);
if (IS_ERR(domain_tag))
return PTR_ERR(domain_tag);
switch (sig[1]) {
case 1:
/* v1 API expect signature without xattr type */
return digsig_verify(keyring, sig + 1, siglen - 1, digest,
digestlen);
return digsig_verify(keyring, domain_tag,
sig + 1, siglen - 1, digest, digestlen);
case 2:
return asymmetric_verify(keyring, sig, siglen, digest,
digestlen);
return asymmetric_verify(keyring, domain_tag, sig, siglen,
digest, digestlen);
}
return -EOPNOTSUPP;
......@@ -102,7 +129,8 @@ static int __init __integrity_init_keyring(const unsigned int id,
keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0),
KGIDT_INIT(0), cred, perm,
KEY_ALLOC_NOT_IN_QUOTA, restriction, NULL);
keyring_alloc_flags[id],
restriction, NULL);
if (IS_ERR(keyring[id])) {
err = PTR_ERR(keyring[id]);
pr_info("Can't allocate %s keyring (%d)\n",
......@@ -154,7 +182,7 @@ int __init integrity_add_key(const unsigned int id, const void *data,
key = key_create_or_update(make_key_ref(keyring[id], 1), "asymmetric",
NULL, data, size, perm,
KEY_ALLOC_NOT_IN_QUOTA);
keyring_alloc_flags[id]);
if (IS_ERR(key)) {
rc = PTR_ERR(key);
pr_err("Problem loading X.509 certificate %d\n", rc);
......
......@@ -20,7 +20,9 @@
/*
* Request an asymmetric key.
*/
static struct key *request_asymmetric_key(struct key *keyring, uint32_t keyid)
static struct key *request_asymmetric_key(struct key *keyring,
struct key_tag *domain_tag,
uint32_t keyid)
{
struct key *key;
char name[12];
......@@ -45,14 +47,16 @@ static struct key *request_asymmetric_key(struct key *keyring, uint32_t keyid)
/* search in specific keyring */
key_ref_t kref;
kref = keyring_search(make_key_ref(keyring, 1),
&key_type_asymmetric, name, true);
kref = keyring_search_tag(make_key_ref(keyring, 1),
&key_type_asymmetric, name,
domain_tag, true);
if (IS_ERR(kref))
key = ERR_CAST(kref);
else
key = key_ref_to_ptr(kref);
} else {
key = request_key(&key_type_asymmetric, name, NULL);
key = request_key_tag(&key_type_asymmetric,
name, domain_tag, NULL);
}
if (IS_ERR(key)) {
......@@ -89,8 +93,9 @@ static struct key *request_asymmetric_key(struct key *keyring, uint32_t keyid)
return key;
}
int asymmetric_verify(struct key *keyring, const char *sig,
int siglen, const char *data, int datalen)
int asymmetric_verify(struct key *keyring, struct key_tag *domain_tag,
const char *sig, int siglen,
const char *data, int datalen)
{
struct public_key_signature pks;
struct signature_v2_hdr *hdr = (struct signature_v2_hdr *)sig;
......@@ -108,7 +113,8 @@ int asymmetric_verify(struct key *keyring, const char *sig,
if (hdr->hash_algo >= HASH_ALGO__LAST)
return -ENOPKG;
key = request_asymmetric_key(keyring, be32_to_cpu(hdr->keyid));
key = request_asymmetric_key(keyring, domain_tag,
be32_to_cpu(hdr->keyid));
if (IS_ERR(key))
return PTR_ERR(key);
......
......@@ -256,11 +256,14 @@ static inline int __init integrity_load_cert(const unsigned int id,
#endif /* CONFIG_INTEGRITY_SIGNATURE */
#ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS
int asymmetric_verify(struct key *keyring, const char *sig,
int siglen, const char *data, int datalen);
int asymmetric_verify(struct key *keyring, struct key_tag *domain_tag,
const char *sig, int siglen,
const char *data, int datalen);
#else
static inline int asymmetric_verify(struct key *keyring, const char *sig,
int siglen, const char *data, int datalen)
static inline int asymmetric_verify(struct key *keyring,
struct key_tag *domain_tag,
const char *sig, int siglen,
const char *data, int datalen)
{
return -EOPNOTSUPP;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册