From: Mimi Zohar <zohar@linux.vnet.ibm.com>
To: linux-security-module <linux-security-module@vger.kernel.org>
Cc: Mimi Zohar <zohar@linux.vnet.ibm.com>,
Dmitry Kasatkin <d.kasatkin@samsung.com>,
David Howells <dhowells@redhat.com>,
Josh Boyer <jwboyer@redhat.com>,
keyrings <keyrings@linux-nfs.org>,
linux-kernel <linux-kernel@vger.kernel.org>
Subject: [RFC PATCH v4 4/4] KEYS: define an owner trusted keyring
Date: Wed, 28 May 2014 11:09:44 -0400 [thread overview]
Message-ID: <1401289784-31340-5-git-send-email-zohar@linux.vnet.ibm.com> (raw)
In-Reply-To: <1401289784-31340-1-git-send-email-zohar@linux.vnet.ibm.com>
(UEFI) secure boot provides a signature chain of trust rooted in
hardware. The signature chain of trust includes the Machine Owner
Keys(MOKs), which cannot be modified without physical presence.
Instead of allowing public keys, with certificates signed by any
key on the system trusted keyring, to be added to a trusted
keyring, this patch further restricts the certificates to those
signed by the machine owner's key or chosen key.
This patch defines an owner trusted keyring, defines a new boot
command line option 'keyring=' to designate the machine owner's
chosen key, and renames the function get_system_trusted_keyring()
to get_system_or_owner_trusted_keyring().
This patch permits the machine owner to safely identify their own
or chosen key, without requiring it to be builtin the kernel.
Signed-off-by: Mimi Zohar<zohar@linux.vnet.ibm.com>
---
crypto/asymmetric_keys/x509_public_key.c | 3 +-
include/keys/system_keyring.h | 15 ++++--
include/linux/key.h | 4 ++
kernel/system_keyring.c | 85 ++++++++++++++++++++++++++++++++
security/keys/key.c | 20 ++++++++
5 files changed, 121 insertions(+), 6 deletions(-)
diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c
index 1af8a30..6d52790 100644
--- a/crypto/asymmetric_keys/x509_public_key.c
+++ b/crypto/asymmetric_keys/x509_public_key.c
@@ -237,7 +237,8 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
if (ret < 0)
goto error_free_cert;
} else {
- ret = x509_validate_trust(cert, get_system_trusted_keyring());
+ ret = x509_validate_trust(cert,
+ get_system_or_owner_trusted_keyring());
if (!ret)
prep->trusted = 1;
}
diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h
index 72665eb..f665c33 100644
--- a/include/keys/system_keyring.h
+++ b/include/keys/system_keyring.h
@@ -17,15 +17,20 @@
#include <linux/key.h>
extern struct key *system_trusted_keyring;
-static inline struct key *get_system_trusted_keyring(void)
-{
- return system_trusted_keyring;
-}
+extern struct key *owner_trusted_keyring;
+
+extern struct key *get_system_or_owner_trusted_keyring(void);
+extern void load_owner_identified_uefi_key(key_ref_t key);
+
#else
-static inline struct key *get_system_trusted_keyring(void)
+static inline struct key *get_system_or_owner_trusted_keyring(void)
{
return NULL;
}
+
+static void load_owner_identified_uefi_key(key_ref_t key)
+{
+}
#endif
#endif /* _KEYS_SYSTEM_KEYRING_H */
diff --git a/include/linux/key.h b/include/linux/key.h
index cd0abb8..861843a 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -267,6 +267,10 @@ extern int wait_for_key_construction(struct key *key, bool intr);
extern int key_validate(const struct key *key);
+extern int key_match(key_ref_t key,
+ const char *type,
+ const char *description);
+
extern key_ref_t key_create_or_update(key_ref_t keyring,
const char *type,
const char *description,
diff --git a/kernel/system_keyring.c b/kernel/system_keyring.c
index 52ebc70..e9b14ac 100644
--- a/kernel/system_keyring.c
+++ b/kernel/system_keyring.c
@@ -19,11 +19,75 @@
#include "module-internal.h"
struct key *system_trusted_keyring;
+struct key *owner_trusted_keyring;
EXPORT_SYMBOL_GPL(system_trusted_keyring);
extern __initconst const u8 system_certificate_list[];
extern __initconst const unsigned long system_certificate_list_size;
+static int use_owner_trusted_keyring;
+
+static char *owner_keyid;
+static int builtin_keyring;
+static int __init default_keyring_set(char *str)
+{
+ if (!str) /* default: builtin */
+ return 1;
+
+ if (strcmp(str, "system") == 0) /* use system keyring */
+ ;
+ else if (strcmp(str, "builtin") == 0) /* only builtin keys */
+ builtin_keyring = 1;
+ else
+ owner_keyid = str; /* owner local key 'id:xxxxxx' */
+ return 1;
+}
+__setup("keyring=", default_keyring_set);
+
+/*
+ * Load the owner identified key on the 'owner' trusted keyring.
+ */
+void load_owner_identified_uefi_key(key_ref_t key)
+{
+ if (!owner_keyid || use_owner_trusted_keyring)
+ return;
+
+ if (!key_match(key, "asymmetric", owner_keyid))
+ return;
+
+ if (key_link(owner_trusted_keyring, key_ref_to_ptr(key)) == 0) {
+ set_bit(KEY_FLAG_TRUSTED_ONLY, &owner_trusted_keyring->flags);
+ use_owner_trusted_keyring = 1;
+ pr_notice("Loaded X.509 cert '%s' on .owner_keyring\n",
+ key_ref_to_ptr(key)->description);
+ }
+}
+
+static void load_owner_identified_builtin_key(key_ref_t key)
+{
+ if (!owner_keyid && !builtin_keyring)
+ return;
+
+ if (!builtin_keyring && !key_match(key, "asymmetric", owner_keyid))
+ return;
+
+ if (key_link(owner_trusted_keyring, key_ref_to_ptr(key)) == 0) {
+ set_bit(KEY_FLAG_TRUSTED_ONLY, &owner_trusted_keyring->flags);
+ use_owner_trusted_keyring = 1;
+ pr_notice("Loaded X.509 cert '%s' on .owner_keyring\n",
+ key_ref_to_ptr(key)->description);
+ }
+}
+
+/*
+ * Use the owner_trusted_keyring if available
+ */
+struct key *get_system_or_owner_trusted_keyring(void)
+{
+ return use_owner_trusted_keyring ? owner_trusted_keyring :
+ system_trusted_keyring;
+}
+
/*
* Load the compiled-in keys
*/
@@ -50,6 +114,25 @@ static __init int system_trusted_keyring_init(void)
device_initcall(system_trusted_keyring_init);
/*
+ * Load the owner trusted key
+ */
+static __init int owner_trusted_keyring_init(void)
+{
+ pr_notice("Initialize the owner trusted keyring\n");
+
+ owner_trusted_keyring =
+ keyring_alloc(".owner_keyring",
+ KUIDT_INIT(0), KGIDT_INIT(0), current_cred(),
+ ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
+ KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH),
+ KEY_ALLOC_NOT_IN_QUOTA, NULL);
+ if (IS_ERR(owner_trusted_keyring))
+ panic("Can't allocate owner trusted keyring\n");
+ return 0;
+}
+device_initcall(owner_trusted_keyring_init);
+
+/*
* Load the compiled-in list of X.509 certificates.
*/
static __init int load_system_certificate_list(void)
@@ -91,6 +174,8 @@ static __init int load_system_certificate_list(void)
} else {
pr_notice("Loaded X.509 cert '%s'\n",
key_ref_to_ptr(key)->description);
+
+ load_owner_identified_builtin_key(key);
key_ref_put(key);
}
p += plen;
diff --git a/security/keys/key.c b/security/keys/key.c
index 2048a11..b448ab1 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -701,6 +701,26 @@ void key_type_put(struct key_type *ktype)
up_read(&key_types_sem);
}
+/*
+ * Use the key type's match function to compare the key's id.
+ */
+int key_match(key_ref_t key, const char *type, const char *description)
+{
+ struct keyring_index_key index_key;
+ int ret = 0;
+
+ index_key.type = key_type_lookup(type);
+ if (IS_ERR(index_key.type))
+ goto out;
+
+ if (index_key.type->match &&
+ index_key.type->match(key_ref_to_ptr(key), description))
+ ret = 1;
+ key_type_put(index_key.type);
+out:
+ return ret;
+}
+
/*
* Attempt to update an existing key.
*
--
1.8.1.4
next prev parent reply other threads:[~2014-05-28 15:10 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-05-28 15:09 [RFC PATCH v4 0/4] ima: extending secure boot certificate chain Mimi Zohar
2014-05-28 15:09 ` [RFC PATCH v4 1/4] KEYS: special dot prefixed keyring name bug fix Mimi Zohar
2014-05-30 15:58 ` Dmitry Kasatkin
2014-05-30 17:58 ` Mimi Zohar
[not found] ` <CACE9dm-n4R9CSjfzpzCaYrSWDxCOsgX7w2Cvn4gkR6-Z82Qypg@mail.gmail.com>
2014-05-30 19:12 ` Mimi Zohar
2014-05-30 20:45 ` Dmitry Kasatkin
2014-05-28 15:09 ` [RFC PATCH v4 2/4] KEYS: verify a certificate is signed by a 'trusted' key Mimi Zohar
2014-05-28 15:09 ` [RFC PATCH v4 3/4] ima: define '.ima' as a builtin 'trusted' keyring Mimi Zohar
2014-05-28 18:55 ` Dmitry Kasatkin
2014-05-28 19:26 ` Mimi Zohar
2014-05-30 16:05 ` Dmitry Kasatkin
2014-06-09 11:06 ` Mimi Zohar
2014-06-09 11:43 ` Dmitry Kasatkin
2014-05-28 15:09 ` Mimi Zohar [this message]
2014-05-30 22:37 ` [RFC PATCH v4 4/4] KEYS: define an owner trusted keyring Dmitry Kasatkin
2014-06-01 2:14 ` Mimi Zohar
2014-06-02 10:48 ` Dmitry Kasatkin
2014-06-02 11:33 ` Mimi Zohar
2014-06-02 11:40 ` Dmitry Kasatkin
2014-06-02 11:54 ` Mimi Zohar
2014-06-02 11:55 ` Josh Boyer
2014-06-03 15:02 ` Mimi Zohar
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=1401289784-31340-5-git-send-email-zohar@linux.vnet.ibm.com \
--to=zohar@linux.vnet.ibm.com \
--cc=d.kasatkin@samsung.com \
--cc=dhowells@redhat.com \
--cc=jwboyer@redhat.com \
--cc=keyrings@linux-nfs.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
/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
Powered by JetHome