Skip to content

Commit d55201c

Browse files
committed
Merge branch 'keys-trust' into keys-next
Here's a set of patches that changes how certificates/keys are determined to be trusted. That's currently a two-step process: (1) Up until recently, when an X.509 certificate was parsed - no matter the source - it was judged against the keys in .system_keyring, assuming those keys to be trusted if they have KEY_FLAG_TRUSTED set upon them. This has just been changed such that any key in the .ima_mok keyring, if configured, may also be used to judge the trustworthiness of a new certificate, whether or not the .ima_mok keyring is meant to be consulted for whatever process is being undertaken. If a certificate is determined to be trustworthy, KEY_FLAG_TRUSTED will be set upon a key it is loaded into (if it is loaded into one), no matter what the key is going to be loaded for. (2) If an X.509 certificate is loaded into a key, then that key - if KEY_FLAG_TRUSTED gets set upon it - can be linked into any keyring with KEY_FLAG_TRUSTED_ONLY set upon it. This was meant to be the system keyring only, but has been extended to various IMA keyrings. A user can at will link any key marked KEY_FLAG_TRUSTED into any keyring marked KEY_FLAG_TRUSTED_ONLY if the relevant permissions masks permit it. These patches change that: (1) Trust becomes a matter of consulting the ring of trusted keys supplied when the trust is evaluated only. (2) Every keyring can be supplied with its own manager function to restrict what may be added to that keyring. This is called whenever a key is to be linked into the keyring to guard against a key being created in one keyring and then linked across. This function is supplied with the keyring and the key type and payload[*] of the key being linked in for use in its evaluation. It is permitted to use other data also, such as the contents of other keyrings such as the system keyrings. [*] The type and payload are supplied instead of a key because as an optimisation this function may be called whilst creating a key and so may reject the proposed key between preparse and allocation. (3) A default manager function is provided that permits keys to be restricted to only asymmetric keys that are vouched for by the contents of the system keyring. A second manager function is provided that just rejects with EPERM. (4) A key allocation flag, KEY_ALLOC_BYPASS_RESTRICTION, is made available so that the kernel can initialise keyrings with keys that form the root of the trust relationship. (5) KEY_FLAG_TRUSTED and KEY_FLAG_TRUSTED_ONLY are removed, along with key_preparsed_payload::trusted. This change also makes it possible in future for userspace to create a private set of trusted keys and then to have it sealed by setting a manager function where the private set is wholly independent of the kernel's trust relationships. Further changes in the set involve extracting certain IMA special keyrings and making them generally global: (*) .system_keyring is renamed to .builtin_trusted_keys and remains read only. It carries only keys built in to the kernel. It may be where UEFI keys should be loaded - though that could better be the new secondary keyring (see below) or a separate UEFI keyring. (*) An optional secondary system keyring (called .secondary_trusted_keys) is added to replace the IMA MOK keyring. (*) Keys can be added to the secondary keyring by root if the keys can be vouched for by either ring of system keys. (*) Module signing and kexec only use .builtin_trusted_keys and do not use the new secondary keyring. (*) Config option SYSTEM_TRUSTED_KEYS now depends on ASYMMETRIC_KEY_TYPE as that's the only type currently permitted on the system keyrings. (*) A new config option, IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY, is provided to allow keys to be added to IMA keyrings, subject to the restriction that such keys are validly signed by a key already in the system keyrings. If this option is enabled, but secondary keyrings aren't, additions to the IMA keyrings will be restricted to signatures verifiable by keys in the builtin system keyring only. Signed-off-by: David Howells <dhowells@redhat.com>
2 parents b6e17c1 + 56104cf commit d55201c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+673
-517
lines changed

Documentation/security/keys.txt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1029,6 +1029,10 @@ payload contents" for more information.
10291029
struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
10301030
const struct cred *cred,
10311031
key_perm_t perm,
1032+
int (*restrict_link)(struct key *,
1033+
const struct key_type *,
1034+
unsigned long,
1035+
const union key_payload *),
10321036
unsigned long flags,
10331037
struct key *dest);
10341038

@@ -1040,6 +1044,24 @@ payload contents" for more information.
10401044
KEY_ALLOC_NOT_IN_QUOTA in flags if the keyring shouldn't be accounted
10411045
towards the user's quota). Error ENOMEM can also be returned.
10421046

1047+
If restrict_link not NULL, it should point to a function that will be
1048+
called each time an attempt is made to link a key into the new keyring.
1049+
This function is called to check whether a key may be added into the keying
1050+
or not. Callers of key_create_or_update() within the kernel can pass
1051+
KEY_ALLOC_BYPASS_RESTRICTION to suppress the check. An example of using
1052+
this is to manage rings of cryptographic keys that are set up when the
1053+
kernel boots where userspace is also permitted to add keys - provided they
1054+
can be verified by a key the kernel already has.
1055+
1056+
When called, the restriction function will be passed the keyring being
1057+
added to, the key flags value and the type and payload of the key being
1058+
added. Note that when a new key is being created, this is called between
1059+
payload preparsing and actual key creation. The function should return 0
1060+
to allow the link or an error to reject it.
1061+
1062+
A convenience function, restrict_link_reject, exists to always return
1063+
-EPERM to in this case.
1064+
10431065

10441066
(*) To check the validity of a key, this function can be called:
10451067

arch/x86/kernel/kexec-bzimage64.c

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@
1919
#include <linux/kernel.h>
2020
#include <linux/mm.h>
2121
#include <linux/efi.h>
22-
#include <linux/verify_pefile.h>
23-
#include <keys/system_keyring.h>
22+
#include <linux/verification.h>
2423

2524
#include <asm/bootparam.h>
2625
#include <asm/setup.h>
@@ -529,18 +528,9 @@ static int bzImage64_cleanup(void *loader_data)
529528
#ifdef CONFIG_KEXEC_BZIMAGE_VERIFY_SIG
530529
static int bzImage64_verify_sig(const char *kernel, unsigned long kernel_len)
531530
{
532-
bool trusted;
533-
int ret;
534-
535-
ret = verify_pefile_signature(kernel, kernel_len,
536-
system_trusted_keyring,
537-
VERIFYING_KEXEC_PE_SIGNATURE,
538-
&trusted);
539-
if (ret < 0)
540-
return ret;
541-
if (!trusted)
542-
return -EKEYREJECTED;
543-
return 0;
531+
return verify_pefile_signature(kernel, kernel_len,
532+
NULL,
533+
VERIFYING_KEXEC_PE_SIGNATURE);
544534
}
545535
#endif
546536

certs/Kconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ config MODULE_SIG_KEY
1717
config SYSTEM_TRUSTED_KEYRING
1818
bool "Provide system-wide ring of trusted keys"
1919
depends on KEYS
20+
depends on ASYMMETRIC_KEY_TYPE
2021
help
2122
Provide a system keyring to which trusted keys can be added. Keys in
2223
the keyring are considered to be trusted. Keys may be added at will
@@ -55,4 +56,12 @@ config SYSTEM_EXTRA_CERTIFICATE_SIZE
5556
This is the number of bytes reserved in the kernel image for a
5657
certificate to be inserted.
5758

59+
config SECONDARY_TRUSTED_KEYRING
60+
bool "Provide a keyring to which extra trustable keys may be added"
61+
depends on SYSTEM_TRUSTED_KEYRING
62+
help
63+
If set, provide a keyring to which extra keys may be added, provided
64+
those keys are not blacklisted and are vouched for by a key built
65+
into the kernel or already in the secondary trusted keyring.
66+
5867
endmenu

certs/system_keyring.c

Lines changed: 113 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -18,29 +18,88 @@
1818
#include <keys/system_keyring.h>
1919
#include <crypto/pkcs7.h>
2020

21-
struct key *system_trusted_keyring;
22-
EXPORT_SYMBOL_GPL(system_trusted_keyring);
21+
static struct key *builtin_trusted_keys;
22+
#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
23+
static struct key *secondary_trusted_keys;
24+
#endif
2325

2426
extern __initconst const u8 system_certificate_list[];
2527
extern __initconst const unsigned long system_certificate_list_size;
2628

29+
/**
30+
* restrict_link_to_builtin_trusted - Restrict keyring addition by built in CA
31+
*
32+
* Restrict the addition of keys into a keyring based on the key-to-be-added
33+
* being vouched for by a key in the built in system keyring.
34+
*/
35+
int restrict_link_by_builtin_trusted(struct key *keyring,
36+
const struct key_type *type,
37+
const union key_payload *payload)
38+
{
39+
return restrict_link_by_signature(builtin_trusted_keys, type, payload);
40+
}
41+
42+
#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
43+
/**
44+
* restrict_link_by_builtin_and_secondary_trusted - Restrict keyring
45+
* addition by both builtin and secondary keyrings
46+
*
47+
* Restrict the addition of keys into a keyring based on the key-to-be-added
48+
* being vouched for by a key in either the built-in or the secondary system
49+
* keyrings.
50+
*/
51+
int restrict_link_by_builtin_and_secondary_trusted(
52+
struct key *keyring,
53+
const struct key_type *type,
54+
const union key_payload *payload)
55+
{
56+
/* If we have a secondary trusted keyring, then that contains a link
57+
* through to the builtin keyring and the search will follow that link.
58+
*/
59+
if (type == &key_type_keyring &&
60+
keyring == secondary_trusted_keys &&
61+
payload == &builtin_trusted_keys->payload)
62+
/* Allow the builtin keyring to be added to the secondary */
63+
return 0;
64+
65+
return restrict_link_by_signature(secondary_trusted_keys, type, payload);
66+
}
67+
#endif
68+
2769
/*
28-
* Load the compiled-in keys
70+
* Create the trusted keyrings
2971
*/
3072
static __init int system_trusted_keyring_init(void)
3173
{
32-
pr_notice("Initialise system trusted keyring\n");
74+
pr_notice("Initialise system trusted keyrings\n");
3375

34-
system_trusted_keyring =
35-
keyring_alloc(".system_keyring",
76+
builtin_trusted_keys =
77+
keyring_alloc(".builtin_trusted_keys",
3678
KUIDT_INIT(0), KGIDT_INIT(0), current_cred(),
3779
((KEY_POS_ALL & ~KEY_POS_SETATTR) |
3880
KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH),
39-
KEY_ALLOC_NOT_IN_QUOTA, NULL);
40-
if (IS_ERR(system_trusted_keyring))
41-
panic("Can't allocate system trusted keyring\n");
81+
KEY_ALLOC_NOT_IN_QUOTA,
82+
NULL, NULL);
83+
if (IS_ERR(builtin_trusted_keys))
84+
panic("Can't allocate builtin trusted keyring\n");
85+
86+
#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
87+
secondary_trusted_keys =
88+
keyring_alloc(".secondary_trusted_keys",
89+
KUIDT_INIT(0), KGIDT_INIT(0), current_cred(),
90+
((KEY_POS_ALL & ~KEY_POS_SETATTR) |
91+
KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH |
92+
KEY_USR_WRITE),
93+
KEY_ALLOC_NOT_IN_QUOTA,
94+
restrict_link_by_builtin_and_secondary_trusted,
95+
NULL);
96+
if (IS_ERR(secondary_trusted_keys))
97+
panic("Can't allocate secondary trusted keyring\n");
98+
99+
if (key_link(secondary_trusted_keys, builtin_trusted_keys) < 0)
100+
panic("Can't link trusted keyrings\n");
101+
#endif
42102

43-
set_bit(KEY_FLAG_TRUSTED_ONLY, &system_trusted_keyring->flags);
44103
return 0;
45104
}
46105

@@ -76,16 +135,16 @@ static __init int load_system_certificate_list(void)
76135
if (plen > end - p)
77136
goto dodgy_cert;
78137

79-
key = key_create_or_update(make_key_ref(system_trusted_keyring, 1),
138+
key = key_create_or_update(make_key_ref(builtin_trusted_keys, 1),
80139
"asymmetric",
81140
NULL,
82141
p,
83142
plen,
84143
((KEY_POS_ALL & ~KEY_POS_SETATTR) |
85144
KEY_USR_VIEW | KEY_USR_READ),
86145
KEY_ALLOC_NOT_IN_QUOTA |
87-
KEY_ALLOC_TRUSTED |
88-
KEY_ALLOC_BUILT_IN);
146+
KEY_ALLOC_BUILT_IN |
147+
KEY_ALLOC_BYPASS_RESTRICTION);
89148
if (IS_ERR(key)) {
90149
pr_err("Problem loading in-kernel X.509 certificate (%ld)\n",
91150
PTR_ERR(key));
@@ -108,27 +167,35 @@ late_initcall(load_system_certificate_list);
108167
#ifdef CONFIG_SYSTEM_DATA_VERIFICATION
109168

110169
/**
111-
* Verify a PKCS#7-based signature on system data.
112-
* @data: The data to be verified.
170+
* verify_pkcs7_signature - Verify a PKCS#7-based signature on system data.
171+
* @data: The data to be verified (NULL if expecting internal data).
113172
* @len: Size of @data.
114173
* @raw_pkcs7: The PKCS#7 message that is the signature.
115174
* @pkcs7_len: The size of @raw_pkcs7.
175+
* @trusted_keys: Trusted keys to use (NULL for builtin trusted keys only,
176+
* (void *)1UL for all trusted keys).
116177
* @usage: The use to which the key is being put.
178+
* @view_content: Callback to gain access to content.
179+
* @ctx: Context for callback.
117180
*/
118-
int system_verify_data(const void *data, unsigned long len,
119-
const void *raw_pkcs7, size_t pkcs7_len,
120-
enum key_being_used_for usage)
181+
int verify_pkcs7_signature(const void *data, size_t len,
182+
const void *raw_pkcs7, size_t pkcs7_len,
183+
struct key *trusted_keys,
184+
enum key_being_used_for usage,
185+
int (*view_content)(void *ctx,
186+
const void *data, size_t len,
187+
size_t asn1hdrlen),
188+
void *ctx)
121189
{
122190
struct pkcs7_message *pkcs7;
123-
bool trusted;
124191
int ret;
125192

126193
pkcs7 = pkcs7_parse_message(raw_pkcs7, pkcs7_len);
127194
if (IS_ERR(pkcs7))
128195
return PTR_ERR(pkcs7);
129196

130197
/* The data should be detached - so we need to supply it. */
131-
if (pkcs7_supply_detached_data(pkcs7, data, len) < 0) {
198+
if (data && pkcs7_supply_detached_data(pkcs7, data, len) < 0) {
132199
pr_err("PKCS#7 signature with non-detached data\n");
133200
ret = -EBADMSG;
134201
goto error;
@@ -138,20 +205,40 @@ int system_verify_data(const void *data, unsigned long len,
138205
if (ret < 0)
139206
goto error;
140207

141-
ret = pkcs7_validate_trust(pkcs7, system_trusted_keyring, &trusted);
142-
if (ret < 0)
208+
if (!trusted_keys) {
209+
trusted_keys = builtin_trusted_keys;
210+
} else if (trusted_keys == (void *)1UL) {
211+
#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
212+
trusted_keys = secondary_trusted_keys;
213+
#else
214+
trusted_keys = builtin_trusted_keys;
215+
#endif
216+
}
217+
ret = pkcs7_validate_trust(pkcs7, trusted_keys);
218+
if (ret < 0) {
219+
if (ret == -ENOKEY)
220+
pr_err("PKCS#7 signature not signed with a trusted key\n");
143221
goto error;
222+
}
223+
224+
if (view_content) {
225+
size_t asn1hdrlen;
226+
227+
ret = pkcs7_get_content_data(pkcs7, &data, &len, &asn1hdrlen);
228+
if (ret < 0) {
229+
if (ret == -ENODATA)
230+
pr_devel("PKCS#7 message does not contain data\n");
231+
goto error;
232+
}
144233

145-
if (!trusted) {
146-
pr_err("PKCS#7 signature not signed with a trusted key\n");
147-
ret = -ENOKEY;
234+
ret = view_content(ctx, data, len, asn1hdrlen);
148235
}
149236

150237
error:
151238
pkcs7_free_message(pkcs7);
152239
pr_devel("<==%s() = %d\n", __func__, ret);
153240
return ret;
154241
}
155-
EXPORT_SYMBOL_GPL(system_verify_data);
242+
EXPORT_SYMBOL_GPL(verify_pkcs7_signature);
156243

157244
#endif /* CONFIG_SYSTEM_DATA_VERIFICATION */

crypto/asymmetric_keys/Kconfig

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
menuconfig ASYMMETRIC_KEY_TYPE
2-
tristate "Asymmetric (public-key cryptographic) key type"
2+
bool "Asymmetric (public-key cryptographic) key type"
33
depends on KEYS
44
help
55
This option provides support for a key type that holds the data for
@@ -40,8 +40,7 @@ config PKCS7_MESSAGE_PARSER
4040

4141
config PKCS7_TEST_KEY
4242
tristate "PKCS#7 testing key type"
43-
depends on PKCS7_MESSAGE_PARSER
44-
select SYSTEM_TRUSTED_KEYRING
43+
depends on SYSTEM_DATA_VERIFICATION
4544
help
4645
This option provides a type of key that can be loaded up from a
4746
PKCS#7 message - provided the message is signed by a trusted key. If
@@ -54,6 +53,7 @@ config PKCS7_TEST_KEY
5453
config SIGNED_PE_FILE_VERIFICATION
5554
bool "Support for PE file signature verification"
5655
depends on PKCS7_MESSAGE_PARSER=y
56+
depends on SYSTEM_DATA_VERIFICATION
5757
select ASN1
5858
select OID_REGISTRY
5959
help

crypto/asymmetric_keys/Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44

55
obj-$(CONFIG_ASYMMETRIC_KEY_TYPE) += asymmetric_keys.o
66

7-
asymmetric_keys-y := asymmetric_type.o signature.o
7+
asymmetric_keys-y := \
8+
asymmetric_type.o \
9+
restrict.o \
10+
signature.o
811

912
obj-$(CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += public_key.o
1013

crypto/asymmetric_keys/asymmetric_keys.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
* 2 of the Licence, or (at your option) any later version.
1010
*/
1111

12+
#include <keys/asymmetric-type.h>
13+
1214
extern struct asymmetric_key_id *asymmetric_key_hex_to_key_id(const char *id);
1315

1416
extern int __asymmetric_key_hex_to_key_id(const char *id,

0 commit comments

Comments
 (0)