From: Lakshmi Ramasubramanian <nramas@linux.microsoft.com>
To: linux-integrity@vger.kernel.org
Cc: zohar@linux.ibm.com, jamorris@linux.microsoft.com,
sashal@kernel.org, kgoldman@us.ibm.com,
nramas@linux.microsoft.com
Subject: [PATCH 1/1] KEYS: Measure keys in trusted keyring
Date: Tue, 27 Aug 2019 17:27:35 -0700 [thread overview]
Message-ID: <20190828002735.31025-2-nramas@linux.microsoft.com> (raw)
In-Reply-To: <20190828002735.31025-1-nramas@linux.microsoft.com>
Measure keys in the trusted keyring. If CONFIG_SECONDARY_TRUSTED_KEYRING
is enabled then the trusted keys keyring is secondary_trusted_keys.
Otherwise, the trusted keys keyring is builtin_trusted_keys.
This measurement is in addition to IMA measuring module\file
signature. It adds more information for attestation service
to validate the client has known good keys in the trusted
keyring.
Signed-off-by: Lakshmi Ramasubramanian <nramas@linux.microsoft.com>
---
certs/system_keyring.c | 15 ++++++
include/keys/system_keyring.h | 4 ++
include/linux/key.h | 21 ++++++++
security/integrity/ima/Kconfig | 14 ++++++
security/integrity/ima/ima_init.c | 84 +++++++++++++++++++++++++++++++
security/keys/keyring.c | 63 +++++++++++++++++++++++
6 files changed, 201 insertions(+)
diff --git a/certs/system_keyring.c b/certs/system_keyring.c
index 1eba08a1af82..221eabee70b4 100644
--- a/certs/system_keyring.c
+++ b/certs/system_keyring.c
@@ -283,3 +283,18 @@ void __init set_platform_trusted_keys(struct key *keyring)
platform_trusted_keys = keyring;
}
#endif
+
+#ifdef CONFIG_IMA_MEASURE_TRUSTED_KEYS
+struct key *get_trusted_keys(void)
+{
+ struct key *trusted_keys;
+
+#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
+ trusted_keys = secondary_trusted_keys;
+#else
+ trusted_keys = builtin_trusted_keys;
+#endif
+
+ return trusted_keys;
+}
+#endif /* CONFIG_IMA_MEASURE_TRUSTED_KEYS */
diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h
index c1a96fdf598b..789782a1d5a9 100644
--- a/include/keys/system_keyring.h
+++ b/include/keys/system_keyring.h
@@ -66,4 +66,8 @@ static inline void set_platform_trusted_keys(struct key *keyring)
}
#endif
+#ifdef CONFIG_IMA_MEASURE_TRUSTED_KEYS
+extern struct key *get_trusted_keys(void);
+#endif /* CONFIG_IMA_MEASURE_TRUSTED_KEYS */
+
#endif /* _KEYS_SYSTEM_KEYRING_H */
diff --git a/include/linux/key.h b/include/linux/key.h
index 50028338a4cc..843198b94677 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -408,6 +408,27 @@ extern key_ref_t lookup_user_key(key_serial_t id, unsigned long flags,
key_perm_t perm);
extern void key_free_user_ns(struct user_namespace *);
+typedef int (*key_iterator_func)(void *key, u32 keylen,
+ const char *description);
+
+/*
+ * Context data used to iterate through the keys in a keyring.
+ *
+ * size - Total number of keys in the keyring
+ * enumerated - Number of keys that have been enumerated so far
+ * iterator - Pointer to the function called for each key
+ */
+struct keyring_iterator {
+ size_t size;
+ size_t enumerated;
+ key_iterator_func iterator;
+};
+
+#ifdef CONFIG_IMA_MEASURE_TRUSTED_KEYS
+extern long keyring_read_trusted_keys(
+ struct keyring_iterator *key_iterator);
+#endif /* CONFIG_IMA_MEASURE_TRUSTED_KEYS */
+
/*
* The permissions required on a key that we're looking up.
*/
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index 2ced99dde694..f33237da0add 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -297,3 +297,17 @@ config IMA_APPRAISE_SIGNED_INIT
default n
help
This option requires user-space init to be signed.
+
+config IMA_MEASURE_TRUSTED_KEYS
+ bool "Measure the keys in the Trusted Keys keyring"
+ depends on IMA
+ default n
+ help
+ This option enables measurement of the public key of
+ the keys in the Trusted Keys keyring during
+ IMA initialization. Depending on the kernel configuration
+ the trusted keyring could be one of the following:
+ if CONFIG_SECONDARY_TRUSTED_KEYRING is enabled then
+ secondary_trusted_keys
+ else
+ builtin_trusted_keys
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c
index 5d55ade5f3b9..987939f6c0f6 100644
--- a/security/integrity/ima/ima_init.c
+++ b/security/integrity/ima/ima_init.c
@@ -89,6 +89,83 @@ static int __init ima_add_boot_aggregate(void)
return result;
}
+#ifdef CONFIG_IMA_MEASURE_TRUSTED_KEYS
+int __init store_trusted_keyring_key(void *key,
+ u32 keylen, const char *key_description)
+{
+ static const char op[] = "store_trusted_keyring_key";
+ const char *audit_cause = "ENOMEM";
+ struct ima_template_entry *entry;
+ struct integrity_iint_cache tmp_iint, *iint = &tmp_iint;
+ struct ima_event_data event_data = {iint, NULL, key_description,
+ NULL, 0, NULL};
+ int result = -ENOMEM;
+ int violation = 0;
+ struct {
+ struct ima_digest_data hdr;
+ char digest[IMA_MAX_DIGEST_SIZE];
+ } hash;
+
+ if (key == NULL || keylen == 0)
+ return 0;
+
+ memset(iint, 0, sizeof(*iint));
+ memset(&hash, 0, sizeof(hash));
+ iint->ima_hash = &hash.hdr;
+ iint->ima_hash->algo = HASH_ALGO_SHA1;
+ iint->ima_hash->length = SHA1_DIGEST_SIZE;
+
+ result = ima_calc_buffer_hash(key, keylen, &hash.hdr);
+ if (result < 0) {
+ audit_cause = "hashing_error";
+ goto err_out;
+ }
+
+ result = ima_alloc_init_template(&event_data, &entry, NULL);
+ if (result < 0) {
+ audit_cause = "alloc_entry";
+ goto err_out;
+ }
+
+ result = ima_store_template(entry, violation, NULL,
+ key_description,
+ CONFIG_IMA_MEASURE_PCR_IDX);
+ if (result < 0) {
+ ima_free_template_entry(entry);
+ audit_cause = "store_entry";
+ goto err_out;
+ }
+ return 0;
+err_out:
+ integrity_audit_msg(AUDIT_INTEGRITY_PCR, NULL,
+ key_description, op,
+ audit_cause, result, 0);
+ return result;
+}
+
+int __init ima_add_trusted_keyring_keys(int (*store_trusted_key)(
+ void *key,
+ u32 keylen,
+ const char *key_description))
+{
+ struct keyring_iterator key_iterator;
+ int rc = 0;
+
+ /* Retrieve the information on keys in
+ * the Built-In Trusted Keys keyring.
+ */
+ key_iterator.size = 0;
+ key_iterator.enumerated = 0;
+ key_iterator.iterator = store_trusted_key;
+ rc = keyring_read_trusted_keys(&key_iterator);
+ if (rc < 0)
+ pr_err("Failed %d to read keys in trusted_keys\n", rc);
+
+ return rc;
+}
+
+#endif /* CONFIG_IMA_MEASURE_TRUSTED_KEYS */
+
#ifdef CONFIG_IMA_LOAD_X509
void __init ima_load_x509(void)
{
@@ -129,6 +206,13 @@ int __init ima_init(void)
if (rc != 0)
return rc;
+#ifdef CONFIG_IMA_MEASURE_TRUSTED_KEYS
+ /* Measure keys from builtin trusted keys keyring. */
+ rc = ima_add_trusted_keyring_keys(store_trusted_keyring_key);
+ if (rc != 0)
+ return rc;
+#endif /* CONFIG_IMA_MEASURE_TRUSTED_KEYS */
+
ima_init_policy();
return ima_fs_init();
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index febf36c6ddc5..fe84923b3c1c 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -16,6 +16,9 @@
#include <linux/nsproxy.h>
#include <keys/keyring-type.h>
#include <keys/user-type.h>
+#include <keys/asymmetric-type.h>
+#include <keys/system_keyring.h>
+#include <crypto/public_key.h>
#include <linux/assoc_array_priv.h>
#include <linux/uaccess.h>
#include <net/net_namespace.h>
@@ -1790,3 +1793,63 @@ void keyring_restriction_gc(struct key *keyring, struct key_type *dead_type)
kleave(" [restriction gc]");
}
+
+#ifdef CONFIG_IMA_MEASURE_TRUSTED_KEYS
+static int keyring_keys_iterator(const void *object, void *data)
+{
+ struct keyring_iterator *key_iterator = data;
+ const struct key *key = keyring_ptr_to_key(object);
+ const struct public_key *pk;
+ int rc = 0;
+
+ if (key_iterator->enumerated < key_iterator->size) {
+ key_iterator->enumerated++;
+ pk = key->payload.data[asym_crypto];
+ if ((pk != NULL) &&
+ (pk->keylen > 0) &&
+ (key->description != NULL)) {
+ rc = key_iterator->iterator(pk->key,
+ pk->keylen,
+ key->description);
+ }
+ }
+
+ return rc;
+}
+
+/*
+ * Read a list of keys from the given keyring.
+ * keyring - Keyring to read the list of keys from
+ * key_iterator - Keyring iterator
+ */
+long keyring_read_keys(
+ const struct key *keyring,
+ struct keyring_iterator *key_iterator)
+{
+ long ret = 0;
+
+ kenter("{%d}", key_serial(keyring));
+
+ key_iterator->size = keyring->keys.nr_leaves_on_tree;
+ key_iterator->enumerated = 0;
+ ret = assoc_array_iterate(&keyring->keys,
+ keyring_keys_iterator,
+ key_iterator);
+ if (ret == 0)
+ kleave(" = %ld [ok]", ret);
+ else
+ kleave(" = %ld [error]", ret);
+
+ return ret;
+}
+
+/*
+ * Read a list of keys from the trusted_keys keyring.
+ * key_iterator - Keyring iterator
+ */
+long keyring_read_trusted_keys(
+ struct keyring_iterator *key_iterator)
+{
+ return keyring_read_keys(get_trusted_keys(), key_iterator);
+}
+#endif /* CONFIG_IMA_MEASURE_TRUSTED_KEYS */
--
2.17.1
next prev parent reply other threads:[~2019-08-28 0:27 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-08-28 0:27 [PATCH 0/1] KEYS: Measure keys in trusted keyring Lakshmi Ramasubramanian
2019-08-28 0:27 ` Lakshmi Ramasubramanian [this message]
2019-09-02 22:04 ` [PATCH 1/1] " Mimi Zohar
2019-08-29 1:11 ` [PATCH 0/1] " Mimi Zohar
2019-08-30 2:43 ` Lakshmi Ramasubramanian
2019-08-30 18:41 ` Mimi Zohar
2019-09-03 15:54 ` Lakshmi Ramasubramanian
2019-09-09 13:31 ` Mimi Zohar
2019-09-09 21:34 ` James Morris
2019-09-19 13:18 ` Sasha Levin
2019-09-19 17:12 ` Mimi Zohar
2019-10-04 19:29 ` Lakshmi Ramasubramanian
2019-10-04 19:57 ` Mimi Zohar
2019-10-04 20:10 ` Lakshmi Ramasubramanian
2019-10-04 21:58 ` Mimi Zohar
2019-10-05 0:10 ` Lakshmi Ramasubramanian
2019-10-06 13:17 ` Mimi Zohar
2019-10-07 15:03 ` Lakshmi Ramasubramanian
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190828002735.31025-2-nramas@linux.microsoft.com \
--to=nramas@linux.microsoft.com \
--cc=jamorris@linux.microsoft.com \
--cc=kgoldman@us.ibm.com \
--cc=linux-integrity@vger.kernel.org \
--cc=sashal@kernel.org \
--cc=zohar@linux.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).