@@ -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);
@@ -15,6 +15,7 @@
#include <linux/vmalloc.h>
#include <crypto/public_key.h>
#include <keys/system_keyring.h>
+#include <linux/ima.h>
#include "integrity.h"
@@ -31,6 +32,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
@@ -56,10 +67,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;
@@ -68,14 +91,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;
@@ -101,7 +128,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",
@@ -153,7 +181,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);
@@ -19,7 +19,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];
@@ -44,14 +46,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)) {
@@ -73,8 +77,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;
@@ -92,7 +97,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);
@@ -212,11 +212,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;
}