Skip to content

Commit 0250abc

Browse files
author
James Morris
committed
Merge tag 'keys-next-20160505' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs into next
2 parents 74f430c + d55201c commit 0250abc

Some content is hidden

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

56 files changed

+1341
-717
lines changed

Documentation/security/keys.txt

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,36 @@ The keyctl syscall functions are:
823823
A process must have search permission on the key for this function to be
824824
successful.
825825

826+
(*) Compute a Diffie-Hellman shared secret or public key
827+
828+
long keyctl(KEYCTL_DH_COMPUTE, struct keyctl_dh_params *params,
829+
char *buffer, size_t buflen);
830+
831+
The params struct contains serial numbers for three keys:
832+
833+
- The prime, p, known to both parties
834+
- The local private key
835+
- The base integer, which is either a shared generator or the
836+
remote public key
837+
838+
The value computed is:
839+
840+
result = base ^ private (mod prime)
841+
842+
If the base is the shared generator, the result is the local
843+
public key. If the base is the remote public key, the result is
844+
the shared secret.
845+
846+
The buffer length must be at least the length of the prime, or zero.
847+
848+
If the buffer length is nonzero, the length of the result is
849+
returned when it is successfully calculated and copied in to the
850+
buffer. When the buffer length is zero, the minimum required
851+
buffer length is returned.
852+
853+
This function will return error EOPNOTSUPP if the key type is not
854+
supported, error ENOKEY if the key could not be found, or error
855+
EACCES if the key is not readable by the caller.
826856

827857
===============
828858
KERNEL SERVICES
@@ -999,6 +1029,10 @@ payload contents" for more information.
9991029
struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
10001030
const struct cred *cred,
10011031
key_perm_t perm,
1032+
int (*restrict_link)(struct key *,
1033+
const struct key_type *,
1034+
unsigned long,
1035+
const union key_payload *),
10021036
unsigned long flags,
10031037
struct key *dest);
10041038

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

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+
10131065

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

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)