aboutsummaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'crypto')
-rw-r--r--crypto/asymmetric_keys/Kconfig7
-rw-r--r--crypto/asymmetric_keys/Makefile5
-rw-r--r--crypto/asymmetric_keys/asymmetric_keys.h2
-rw-r--r--crypto/asymmetric_keys/asymmetric_type.c96
-rw-r--r--crypto/asymmetric_keys/mscode_parser.c21
-rw-r--r--crypto/asymmetric_keys/pkcs7_key_type.c72
-rw-r--r--crypto/asymmetric_keys/pkcs7_parser.c58
-rw-r--r--crypto/asymmetric_keys/pkcs7_parser.h11
-rw-r--r--crypto/asymmetric_keys/pkcs7_trust.c43
-rw-r--r--crypto/asymmetric_keys/pkcs7_verify.c107
-rw-r--r--crypto/asymmetric_keys/public_key.c20
-rw-r--r--crypto/asymmetric_keys/restrict.c108
-rw-r--r--crypto/asymmetric_keys/signature.c18
-rw-r--r--crypto/asymmetric_keys/verify_pefile.c40
-rw-r--r--crypto/asymmetric_keys/verify_pefile.h5
-rw-r--r--crypto/asymmetric_keys/x509_cert_parser.c52
-rw-r--r--crypto/asymmetric_keys/x509_parser.h12
-rw-r--r--crypto/asymmetric_keys/x509_public_key.c297
-rw-r--r--crypto/crypto_user.c1
19 files changed, 506 insertions, 469 deletions
diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig
index 91a7e047a765..331f6baf2df8 100644
--- a/crypto/asymmetric_keys/Kconfig
+++ b/crypto/asymmetric_keys/Kconfig
@@ -1,5 +1,5 @@
1menuconfig ASYMMETRIC_KEY_TYPE 1menuconfig ASYMMETRIC_KEY_TYPE
2 tristate "Asymmetric (public-key cryptographic) key type" 2 bool "Asymmetric (public-key cryptographic) key type"
3 depends on KEYS 3 depends on KEYS
4 help 4 help
5 This option provides support for a key type that holds the data for 5 This option provides support for a key type that holds the data for
@@ -13,6 +13,7 @@ config ASYMMETRIC_PUBLIC_KEY_SUBTYPE
13 tristate "Asymmetric public-key crypto algorithm subtype" 13 tristate "Asymmetric public-key crypto algorithm subtype"
14 select MPILIB 14 select MPILIB
15 select CRYPTO_HASH_INFO 15 select CRYPTO_HASH_INFO
16 select CRYPTO_AKCIPHER
16 help 17 help
17 This option provides support for asymmetric public key type handling. 18 This option provides support for asymmetric public key type handling.
18 If signature generation and/or verification are to be used, 19 If signature generation and/or verification are to be used,
@@ -40,8 +41,7 @@ config PKCS7_MESSAGE_PARSER
40 41
41config PKCS7_TEST_KEY 42config PKCS7_TEST_KEY
42 tristate "PKCS#7 testing key type" 43 tristate "PKCS#7 testing key type"
43 depends on PKCS7_MESSAGE_PARSER 44 depends on SYSTEM_DATA_VERIFICATION
44 select SYSTEM_TRUSTED_KEYRING
45 help 45 help
46 This option provides a type of key that can be loaded up from a 46 This option provides a type of key that can be loaded up from a
47 PKCS#7 message - provided the message is signed by a trusted key. If 47 PKCS#7 message - provided the message is signed by a trusted key. If
@@ -54,6 +54,7 @@ config PKCS7_TEST_KEY
54config SIGNED_PE_FILE_VERIFICATION 54config SIGNED_PE_FILE_VERIFICATION
55 bool "Support for PE file signature verification" 55 bool "Support for PE file signature verification"
56 depends on PKCS7_MESSAGE_PARSER=y 56 depends on PKCS7_MESSAGE_PARSER=y
57 depends on SYSTEM_DATA_VERIFICATION
57 select ASN1 58 select ASN1
58 select OID_REGISTRY 59 select OID_REGISTRY
59 help 60 help
diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile
index f90486256f01..6516855bec18 100644
--- a/crypto/asymmetric_keys/Makefile
+++ b/crypto/asymmetric_keys/Makefile
@@ -4,7 +4,10 @@
4 4
5obj-$(CONFIG_ASYMMETRIC_KEY_TYPE) += asymmetric_keys.o 5obj-$(CONFIG_ASYMMETRIC_KEY_TYPE) += asymmetric_keys.o
6 6
7asymmetric_keys-y := asymmetric_type.o signature.o 7asymmetric_keys-y := \
8 asymmetric_type.o \
9 restrict.o \
10 signature.o
8 11
9obj-$(CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += public_key.o 12obj-$(CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += public_key.o
10 13
diff --git a/crypto/asymmetric_keys/asymmetric_keys.h b/crypto/asymmetric_keys/asymmetric_keys.h
index 1d450b580245..ca8e9ac34ce6 100644
--- a/crypto/asymmetric_keys/asymmetric_keys.h
+++ b/crypto/asymmetric_keys/asymmetric_keys.h
@@ -9,6 +9,8 @@
9 * 2 of the Licence, or (at your option) any later version. 9 * 2 of the Licence, or (at your option) any later version.
10 */ 10 */
11 11
12#include <keys/asymmetric-type.h>
13
12extern struct asymmetric_key_id *asymmetric_key_hex_to_key_id(const char *id); 14extern struct asymmetric_key_id *asymmetric_key_hex_to_key_id(const char *id);
13 15
14extern int __asymmetric_key_hex_to_key_id(const char *id, 16extern int __asymmetric_key_hex_to_key_id(const char *id,
diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c
index 9f2165b27d52..6600181d5d01 100644
--- a/crypto/asymmetric_keys/asymmetric_type.c
+++ b/crypto/asymmetric_keys/asymmetric_type.c
@@ -35,6 +35,95 @@ static LIST_HEAD(asymmetric_key_parsers);
35static DECLARE_RWSEM(asymmetric_key_parsers_sem); 35static DECLARE_RWSEM(asymmetric_key_parsers_sem);
36 36
37/** 37/**
38 * find_asymmetric_key - Find a key by ID.
39 * @keyring: The keys to search.
40 * @id_0: The first ID to look for or NULL.
41 * @id_1: The second ID to look for or NULL.
42 * @partial: Use partial match if true, exact if false.
43 *
44 * Find a key in the given keyring by identifier. The preferred identifier is
45 * the id_0 and the fallback identifier is the id_1. If both are given, the
46 * lookup is by the former, but the latter must also match.
47 */
48struct key *find_asymmetric_key(struct key *keyring,
49 const struct asymmetric_key_id *id_0,
50 const struct asymmetric_key_id *id_1,
51 bool partial)
52{
53 struct key *key;
54 key_ref_t ref;
55 const char *lookup;
56 char *req, *p;
57 int len;
58
59 if (id_0) {
60 lookup = id_0->data;
61 len = id_0->len;
62 } else {
63 lookup = id_1->data;
64 len = id_1->len;
65 }
66
67 /* Construct an identifier "id:<keyid>". */
68 p = req = kmalloc(2 + 1 + len * 2 + 1, GFP_KERNEL);
69 if (!req)
70 return ERR_PTR(-ENOMEM);
71
72 if (partial) {
73 *p++ = 'i';
74 *p++ = 'd';
75 } else {
76 *p++ = 'e';
77 *p++ = 'x';
78 }
79 *p++ = ':';
80 p = bin2hex(p, lookup, len);
81 *p = 0;
82
83 pr_debug("Look up: \"%s\"\n", req);
84
85 ref = keyring_search(make_key_ref(keyring, 1),
86 &key_type_asymmetric, req);
87 if (IS_ERR(ref))
88 pr_debug("Request for key '%s' err %ld\n", req, PTR_ERR(ref));
89 kfree(req);
90
91 if (IS_ERR(ref)) {
92 switch (PTR_ERR(ref)) {
93 /* Hide some search errors */
94 case -EACCES:
95 case -ENOTDIR:
96 case -EAGAIN:
97 return ERR_PTR(-ENOKEY);
98 default:
99 return ERR_CAST(ref);
100 }
101 }
102
103 key = key_ref_to_ptr(ref);
104 if (id_0 && id_1) {
105 const struct asymmetric_key_ids *kids = asymmetric_key_ids(key);
106
107 if (!kids->id[0]) {
108 pr_debug("First ID matches, but second is missing\n");
109 goto reject;
110 }
111 if (!asymmetric_key_id_same(id_1, kids->id[1])) {
112 pr_debug("First ID matches, but second does not\n");
113 goto reject;
114 }
115 }
116
117 pr_devel("<==%s() = 0 [%x]\n", __func__, key_serial(key));
118 return key;
119
120reject:
121 key_put(key);
122 return ERR_PTR(-EKEYREJECTED);
123}
124EXPORT_SYMBOL_GPL(find_asymmetric_key);
125
126/**
38 * asymmetric_key_generate_id: Construct an asymmetric key ID 127 * asymmetric_key_generate_id: Construct an asymmetric key ID
39 * @val_1: First binary blob 128 * @val_1: First binary blob
40 * @len_1: Length of first binary blob 129 * @len_1: Length of first binary blob
@@ -331,7 +420,8 @@ static void asymmetric_key_free_preparse(struct key_preparsed_payload *prep)
331 pr_devel("==>%s()\n", __func__); 420 pr_devel("==>%s()\n", __func__);
332 421
333 if (subtype) { 422 if (subtype) {
334 subtype->destroy(prep->payload.data[asym_crypto]); 423 subtype->destroy(prep->payload.data[asym_crypto],
424 prep->payload.data[asym_auth]);
335 module_put(subtype->owner); 425 module_put(subtype->owner);
336 } 426 }
337 asymmetric_key_free_kids(kids); 427 asymmetric_key_free_kids(kids);
@@ -346,13 +436,15 @@ static void asymmetric_key_destroy(struct key *key)
346 struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key); 436 struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key);
347 struct asymmetric_key_ids *kids = key->payload.data[asym_key_ids]; 437 struct asymmetric_key_ids *kids = key->payload.data[asym_key_ids];
348 void *data = key->payload.data[asym_crypto]; 438 void *data = key->payload.data[asym_crypto];
439 void *auth = key->payload.data[asym_auth];
349 440
350 key->payload.data[asym_crypto] = NULL; 441 key->payload.data[asym_crypto] = NULL;
351 key->payload.data[asym_subtype] = NULL; 442 key->payload.data[asym_subtype] = NULL;
352 key->payload.data[asym_key_ids] = NULL; 443 key->payload.data[asym_key_ids] = NULL;
444 key->payload.data[asym_auth] = NULL;
353 445
354 if (subtype) { 446 if (subtype) {
355 subtype->destroy(data); 447 subtype->destroy(data, auth);
356 module_put(subtype->owner); 448 module_put(subtype->owner);
357 } 449 }
358 450
diff --git a/crypto/asymmetric_keys/mscode_parser.c b/crypto/asymmetric_keys/mscode_parser.c
index 3242cbfaeaa2..6a76d5c70ef6 100644
--- a/crypto/asymmetric_keys/mscode_parser.c
+++ b/crypto/asymmetric_keys/mscode_parser.c
@@ -21,19 +21,13 @@
21/* 21/*
22 * Parse a Microsoft Individual Code Signing blob 22 * Parse a Microsoft Individual Code Signing blob
23 */ 23 */
24int mscode_parse(struct pefile_context *ctx) 24int mscode_parse(void *_ctx, const void *content_data, size_t data_len,
25 size_t asn1hdrlen)
25{ 26{
26 const void *content_data; 27 struct pefile_context *ctx = _ctx;
27 size_t data_len;
28 int ret;
29
30 ret = pkcs7_get_content_data(ctx->pkcs7, &content_data, &data_len, 1);
31
32 if (ret) {
33 pr_debug("PKCS#7 message does not contain data\n");
34 return ret;
35 }
36 28
29 content_data -= asn1hdrlen;
30 data_len += asn1hdrlen;
37 pr_devel("Data: %zu [%*ph]\n", data_len, (unsigned)(data_len), 31 pr_devel("Data: %zu [%*ph]\n", data_len, (unsigned)(data_len),
38 content_data); 32 content_data);
39 33
@@ -129,7 +123,6 @@ int mscode_note_digest(void *context, size_t hdrlen,
129{ 123{
130 struct pefile_context *ctx = context; 124 struct pefile_context *ctx = context;
131 125
132 ctx->digest = value; 126 ctx->digest = kmemdup(value, vlen, GFP_KERNEL);
133 ctx->digest_len = vlen; 127 return ctx->digest ? 0 : -ENOMEM;
134 return 0;
135} 128}
diff --git a/crypto/asymmetric_keys/pkcs7_key_type.c b/crypto/asymmetric_keys/pkcs7_key_type.c
index e2d0edbbc71a..1063b644efcd 100644
--- a/crypto/asymmetric_keys/pkcs7_key_type.c
+++ b/crypto/asymmetric_keys/pkcs7_key_type.c
@@ -13,12 +13,9 @@
13#include <linux/key.h> 13#include <linux/key.h>
14#include <linux/err.h> 14#include <linux/err.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/verification.h>
16#include <linux/key-type.h> 17#include <linux/key-type.h>
17#include <keys/asymmetric-type.h>
18#include <crypto/pkcs7.h>
19#include <keys/user-type.h> 18#include <keys/user-type.h>
20#include <keys/system_keyring.h>
21#include "pkcs7_parser.h"
22 19
23MODULE_LICENSE("GPL"); 20MODULE_LICENSE("GPL");
24MODULE_DESCRIPTION("PKCS#7 testing key type"); 21MODULE_DESCRIPTION("PKCS#7 testing key type");
@@ -29,60 +26,47 @@ MODULE_PARM_DESC(pkcs7_usage,
29 "Usage to specify when verifying the PKCS#7 message"); 26 "Usage to specify when verifying the PKCS#7 message");
30 27
31/* 28/*
32 * Preparse a PKCS#7 wrapped and validated data blob. 29 * Retrieve the PKCS#7 message content.
33 */ 30 */
34static int pkcs7_preparse(struct key_preparsed_payload *prep) 31static int pkcs7_view_content(void *ctx, const void *data, size_t len,
32 size_t asn1hdrlen)
35{ 33{
36 enum key_being_used_for usage = pkcs7_usage; 34 struct key_preparsed_payload *prep = ctx;
37 struct pkcs7_message *pkcs7; 35 const void *saved_prep_data;
38 const void *data, *saved_prep_data; 36 size_t saved_prep_datalen;
39 size_t datalen, saved_prep_datalen;
40 bool trusted;
41 int ret; 37 int ret;
42 38
43 kenter("");
44
45 if (usage >= NR__KEY_BEING_USED_FOR) {
46 pr_err("Invalid usage type %d\n", usage);
47 return -EINVAL;
48 }
49
50 saved_prep_data = prep->data; 39 saved_prep_data = prep->data;
51 saved_prep_datalen = prep->datalen; 40 saved_prep_datalen = prep->datalen;
52 pkcs7 = pkcs7_parse_message(saved_prep_data, saved_prep_datalen);
53 if (IS_ERR(pkcs7)) {
54 ret = PTR_ERR(pkcs7);
55 goto error;
56 }
57
58 ret = pkcs7_verify(pkcs7, usage);
59 if (ret < 0)
60 goto error_free;
61
62 ret = pkcs7_validate_trust(pkcs7, system_trusted_keyring, &trusted);
63 if (ret < 0)
64 goto error_free;
65 if (!trusted)
66 pr_warn("PKCS#7 message doesn't chain back to a trusted key\n");
67
68 ret = pkcs7_get_content_data(pkcs7, &data, &datalen, false);
69 if (ret < 0)
70 goto error_free;
71
72 prep->data = data; 41 prep->data = data;
73 prep->datalen = datalen; 42 prep->datalen = len;
43
74 ret = user_preparse(prep); 44 ret = user_preparse(prep);
45
75 prep->data = saved_prep_data; 46 prep->data = saved_prep_data;
76 prep->datalen = saved_prep_datalen; 47 prep->datalen = saved_prep_datalen;
77
78error_free:
79 pkcs7_free_message(pkcs7);
80error:
81 kleave(" = %d", ret);
82 return ret; 48 return ret;
83} 49}
84 50
85/* 51/*
52 * Preparse a PKCS#7 wrapped and validated data blob.
53 */
54static int pkcs7_preparse(struct key_preparsed_payload *prep)
55{
56 enum key_being_used_for usage = pkcs7_usage;
57
58 if (usage >= NR__KEY_BEING_USED_FOR) {
59 pr_err("Invalid usage type %d\n", usage);
60 return -EINVAL;
61 }
62
63 return verify_pkcs7_signature(NULL, 0,
64 prep->data, prep->datalen,
65 (void *)1UL, usage,
66 pkcs7_view_content, prep);
67}
68
69/*
86 * user defined keys take an arbitrary string as the description and an 70 * user defined keys take an arbitrary string as the description and an
87 * arbitrary blob of data as the payload 71 * arbitrary blob of data as the payload
88 */ 72 */
diff --git a/crypto/asymmetric_keys/pkcs7_parser.c b/crypto/asymmetric_keys/pkcs7_parser.c
index bdd0d753ce5d..af4cd8649117 100644
--- a/crypto/asymmetric_keys/pkcs7_parser.c
+++ b/crypto/asymmetric_keys/pkcs7_parser.c
@@ -44,9 +44,7 @@ struct pkcs7_parse_context {
44static void pkcs7_free_signed_info(struct pkcs7_signed_info *sinfo) 44static void pkcs7_free_signed_info(struct pkcs7_signed_info *sinfo)
45{ 45{
46 if (sinfo) { 46 if (sinfo) {
47 kfree(sinfo->sig.s); 47 public_key_signature_free(sinfo->sig);
48 kfree(sinfo->sig.digest);
49 kfree(sinfo->signing_cert_id);
50 kfree(sinfo); 48 kfree(sinfo);
51 } 49 }
52} 50}
@@ -125,6 +123,10 @@ struct pkcs7_message *pkcs7_parse_message(const void *data, size_t datalen)
125 ctx->sinfo = kzalloc(sizeof(struct pkcs7_signed_info), GFP_KERNEL); 123 ctx->sinfo = kzalloc(sizeof(struct pkcs7_signed_info), GFP_KERNEL);
126 if (!ctx->sinfo) 124 if (!ctx->sinfo)
127 goto out_no_sinfo; 125 goto out_no_sinfo;
126 ctx->sinfo->sig = kzalloc(sizeof(struct public_key_signature),
127 GFP_KERNEL);
128 if (!ctx->sinfo->sig)
129 goto out_no_sig;
128 130
129 ctx->data = (unsigned long)data; 131 ctx->data = (unsigned long)data;
130 ctx->ppcerts = &ctx->certs; 132 ctx->ppcerts = &ctx->certs;
@@ -150,6 +152,7 @@ out:
150 ctx->certs = cert->next; 152 ctx->certs = cert->next;
151 x509_free_certificate(cert); 153 x509_free_certificate(cert);
152 } 154 }
155out_no_sig:
153 pkcs7_free_signed_info(ctx->sinfo); 156 pkcs7_free_signed_info(ctx->sinfo);
154out_no_sinfo: 157out_no_sinfo:
155 pkcs7_free_message(ctx->msg); 158 pkcs7_free_message(ctx->msg);
@@ -165,24 +168,25 @@ EXPORT_SYMBOL_GPL(pkcs7_parse_message);
165 * @pkcs7: The preparsed PKCS#7 message to access 168 * @pkcs7: The preparsed PKCS#7 message to access
166 * @_data: Place to return a pointer to the data 169 * @_data: Place to return a pointer to the data
167 * @_data_len: Place to return the data length 170 * @_data_len: Place to return the data length
168 * @want_wrapper: True if the ASN.1 object header should be included in the data 171 * @_headerlen: Size of ASN.1 header not included in _data
169 * 172 *
170 * Get access to the data content of the PKCS#7 message, including, optionally, 173 * Get access to the data content of the PKCS#7 message. The size of the
171 * the header of the ASN.1 object that contains it. Returns -ENODATA if the 174 * header of the ASN.1 object that contains it is also provided and can be used
172 * data object was missing from the message. 175 * to adjust *_data and *_data_len to get the entire object.
176 *
177 * Returns -ENODATA if the data object was missing from the message.
173 */ 178 */
174int pkcs7_get_content_data(const struct pkcs7_message *pkcs7, 179int pkcs7_get_content_data(const struct pkcs7_message *pkcs7,
175 const void **_data, size_t *_data_len, 180 const void **_data, size_t *_data_len,
176 bool want_wrapper) 181 size_t *_headerlen)
177{ 182{
178 size_t wrapper;
179
180 if (!pkcs7->data) 183 if (!pkcs7->data)
181 return -ENODATA; 184 return -ENODATA;
182 185
183 wrapper = want_wrapper ? pkcs7->data_hdrlen : 0; 186 *_data = pkcs7->data;
184 *_data = pkcs7->data - wrapper; 187 *_data_len = pkcs7->data_len;
185 *_data_len = pkcs7->data_len + wrapper; 188 if (_headerlen)
189 *_headerlen = pkcs7->data_hdrlen;
186 return 0; 190 return 0;
187} 191}
188EXPORT_SYMBOL_GPL(pkcs7_get_content_data); 192EXPORT_SYMBOL_GPL(pkcs7_get_content_data);
@@ -218,25 +222,25 @@ int pkcs7_sig_note_digest_algo(void *context, size_t hdrlen,
218 222
219 switch (ctx->last_oid) { 223 switch (ctx->last_oid) {
220 case OID_md4: 224 case OID_md4:
221 ctx->sinfo->sig.hash_algo = "md4"; 225 ctx->sinfo->sig->hash_algo = "md4";
222 break; 226 break;
223 case OID_md5: 227 case OID_md5:
224 ctx->sinfo->sig.hash_algo = "md5"; 228 ctx->sinfo->sig->hash_algo = "md5";
225 break; 229 break;
226 case OID_sha1: 230 case OID_sha1:
227 ctx->sinfo->sig.hash_algo = "sha1"; 231 ctx->sinfo->sig->hash_algo = "sha1";
228 break; 232 break;
229 case OID_sha256: 233 case OID_sha256:
230 ctx->sinfo->sig.hash_algo = "sha256"; 234 ctx->sinfo->sig->hash_algo = "sha256";
231 break; 235 break;
232 case OID_sha384: 236 case OID_sha384:
233 ctx->sinfo->sig.hash_algo = "sha384"; 237 ctx->sinfo->sig->hash_algo = "sha384";
234 break; 238 break;
235 case OID_sha512: 239 case OID_sha512:
236 ctx->sinfo->sig.hash_algo = "sha512"; 240 ctx->sinfo->sig->hash_algo = "sha512";
237 break; 241 break;
238 case OID_sha224: 242 case OID_sha224:
239 ctx->sinfo->sig.hash_algo = "sha224"; 243 ctx->sinfo->sig->hash_algo = "sha224";
240 break; 244 break;
241 default: 245 default:
242 printk("Unsupported digest algo: %u\n", ctx->last_oid); 246 printk("Unsupported digest algo: %u\n", ctx->last_oid);
@@ -256,7 +260,7 @@ int pkcs7_sig_note_pkey_algo(void *context, size_t hdrlen,
256 260
257 switch (ctx->last_oid) { 261 switch (ctx->last_oid) {
258 case OID_rsaEncryption: 262 case OID_rsaEncryption:
259 ctx->sinfo->sig.pkey_algo = "rsa"; 263 ctx->sinfo->sig->pkey_algo = "rsa";
260 break; 264 break;
261 default: 265 default:
262 printk("Unsupported pkey algo: %u\n", ctx->last_oid); 266 printk("Unsupported pkey algo: %u\n", ctx->last_oid);
@@ -616,11 +620,11 @@ int pkcs7_sig_note_signature(void *context, size_t hdrlen,
616{ 620{
617 struct pkcs7_parse_context *ctx = context; 621 struct pkcs7_parse_context *ctx = context;
618 622
619 ctx->sinfo->sig.s = kmemdup(value, vlen, GFP_KERNEL); 623 ctx->sinfo->sig->s = kmemdup(value, vlen, GFP_KERNEL);
620 if (!ctx->sinfo->sig.s) 624 if (!ctx->sinfo->sig->s)
621 return -ENOMEM; 625 return -ENOMEM;
622 626
623 ctx->sinfo->sig.s_size = vlen; 627 ctx->sinfo->sig->s_size = vlen;
624 return 0; 628 return 0;
625} 629}
626 630
@@ -656,12 +660,16 @@ int pkcs7_note_signed_info(void *context, size_t hdrlen,
656 660
657 pr_devel("SINFO KID: %u [%*phN]\n", kid->len, kid->len, kid->data); 661 pr_devel("SINFO KID: %u [%*phN]\n", kid->len, kid->len, kid->data);
658 662
659 sinfo->signing_cert_id = kid; 663 sinfo->sig->auth_ids[0] = kid;
660 sinfo->index = ++ctx->sinfo_index; 664 sinfo->index = ++ctx->sinfo_index;
661 *ctx->ppsinfo = sinfo; 665 *ctx->ppsinfo = sinfo;
662 ctx->ppsinfo = &sinfo->next; 666 ctx->ppsinfo = &sinfo->next;
663 ctx->sinfo = kzalloc(sizeof(struct pkcs7_signed_info), GFP_KERNEL); 667 ctx->sinfo = kzalloc(sizeof(struct pkcs7_signed_info), GFP_KERNEL);
664 if (!ctx->sinfo) 668 if (!ctx->sinfo)
665 return -ENOMEM; 669 return -ENOMEM;
670 ctx->sinfo->sig = kzalloc(sizeof(struct public_key_signature),
671 GFP_KERNEL);
672 if (!ctx->sinfo->sig)
673 return -ENOMEM;
666 return 0; 674 return 0;
667} 675}
diff --git a/crypto/asymmetric_keys/pkcs7_parser.h b/crypto/asymmetric_keys/pkcs7_parser.h
index a66b19ebcf47..f4e81074f5e0 100644
--- a/crypto/asymmetric_keys/pkcs7_parser.h
+++ b/crypto/asymmetric_keys/pkcs7_parser.h
@@ -22,7 +22,6 @@ struct pkcs7_signed_info {
22 struct pkcs7_signed_info *next; 22 struct pkcs7_signed_info *next;
23 struct x509_certificate *signer; /* Signing certificate (in msg->certs) */ 23 struct x509_certificate *signer; /* Signing certificate (in msg->certs) */
24 unsigned index; 24 unsigned index;
25 bool trusted;
26 bool unsupported_crypto; /* T if not usable due to missing crypto */ 25 bool unsupported_crypto; /* T if not usable due to missing crypto */
27 26
28 /* Message digest - the digest of the Content Data (or NULL) */ 27 /* Message digest - the digest of the Content Data (or NULL) */
@@ -41,19 +40,17 @@ struct pkcs7_signed_info {
41#define sinfo_has_ms_statement_type 5 40#define sinfo_has_ms_statement_type 5
42 time64_t signing_time; 41 time64_t signing_time;
43 42
44 /* Issuing cert serial number and issuer's name [PKCS#7 or CMS ver 1]
45 * or issuing cert's SKID [CMS ver 3].
46 */
47 struct asymmetric_key_id *signing_cert_id;
48
49 /* Message signature. 43 /* Message signature.
50 * 44 *
51 * This contains the generated digest of _either_ the Content Data or 45 * This contains the generated digest of _either_ the Content Data or
52 * the Authenticated Attributes [RFC2315 9.3]. If the latter, one of 46 * the Authenticated Attributes [RFC2315 9.3]. If the latter, one of
53 * the attributes contains the digest of the the Content Data within 47 * the attributes contains the digest of the the Content Data within
54 * it. 48 * it.
49 *
50 * THis also contains the issuing cert serial number and issuer's name
51 * [PKCS#7 or CMS ver 1] or issuing cert's SKID [CMS ver 3].
55 */ 52 */
56 struct public_key_signature sig; 53 struct public_key_signature *sig;
57}; 54};
58 55
59struct pkcs7_message { 56struct pkcs7_message {
diff --git a/crypto/asymmetric_keys/pkcs7_trust.c b/crypto/asymmetric_keys/pkcs7_trust.c
index 7d7a39b47c62..f6a009d88a33 100644
--- a/crypto/asymmetric_keys/pkcs7_trust.c
+++ b/crypto/asymmetric_keys/pkcs7_trust.c
@@ -27,10 +27,9 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
27 struct pkcs7_signed_info *sinfo, 27 struct pkcs7_signed_info *sinfo,
28 struct key *trust_keyring) 28 struct key *trust_keyring)
29{ 29{
30 struct public_key_signature *sig = &sinfo->sig; 30 struct public_key_signature *sig = sinfo->sig;
31 struct x509_certificate *x509, *last = NULL, *p; 31 struct x509_certificate *x509, *last = NULL, *p;
32 struct key *key; 32 struct key *key;
33 bool trusted;
34 int ret; 33 int ret;
35 34
36 kenter(",%u,", sinfo->index); 35 kenter(",%u,", sinfo->index);
@@ -42,10 +41,8 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
42 41
43 for (x509 = sinfo->signer; x509; x509 = x509->signer) { 42 for (x509 = sinfo->signer; x509; x509 = x509->signer) {
44 if (x509->seen) { 43 if (x509->seen) {
45 if (x509->verified) { 44 if (x509->verified)
46 trusted = x509->trusted;
47 goto verified; 45 goto verified;
48 }
49 kleave(" = -ENOKEY [cached]"); 46 kleave(" = -ENOKEY [cached]");
50 return -ENOKEY; 47 return -ENOKEY;
51 } 48 }
@@ -54,9 +51,8 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
54 /* Look to see if this certificate is present in the trusted 51 /* Look to see if this certificate is present in the trusted
55 * keys. 52 * keys.
56 */ 53 */
57 key = x509_request_asymmetric_key(trust_keyring, 54 key = find_asymmetric_key(trust_keyring,
58 x509->id, x509->skid, 55 x509->id, x509->skid, false);
59 false);
60 if (!IS_ERR(key)) { 56 if (!IS_ERR(key)) {
61 /* One of the X.509 certificates in the PKCS#7 message 57 /* One of the X.509 certificates in the PKCS#7 message
62 * is apparently the same as one we already trust. 58 * is apparently the same as one we already trust.
@@ -80,17 +76,17 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
80 76
81 might_sleep(); 77 might_sleep();
82 last = x509; 78 last = x509;
83 sig = &last->sig; 79 sig = last->sig;
84 } 80 }
85 81
86 /* No match - see if the root certificate has a signer amongst the 82 /* No match - see if the root certificate has a signer amongst the
87 * trusted keys. 83 * trusted keys.
88 */ 84 */
89 if (last && (last->akid_id || last->akid_skid)) { 85 if (last && (last->sig->auth_ids[0] || last->sig->auth_ids[1])) {
90 key = x509_request_asymmetric_key(trust_keyring, 86 key = find_asymmetric_key(trust_keyring,
91 last->akid_id, 87 last->sig->auth_ids[0],
92 last->akid_skid, 88 last->sig->auth_ids[1],
93 false); 89 false);
94 if (!IS_ERR(key)) { 90 if (!IS_ERR(key)) {
95 x509 = last; 91 x509 = last;
96 pr_devel("sinfo %u: Root cert %u signer is key %x\n", 92 pr_devel("sinfo %u: Root cert %u signer is key %x\n",
@@ -104,10 +100,8 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
104 /* As a last resort, see if we have a trusted public key that matches 100 /* As a last resort, see if we have a trusted public key that matches
105 * the signed info directly. 101 * the signed info directly.
106 */ 102 */
107 key = x509_request_asymmetric_key(trust_keyring, 103 key = find_asymmetric_key(trust_keyring,
108 sinfo->signing_cert_id, 104 sinfo->sig->auth_ids[0], NULL, false);
109 NULL,
110 false);
111 if (!IS_ERR(key)) { 105 if (!IS_ERR(key)) {
112 pr_devel("sinfo %u: Direct signer is key %x\n", 106 pr_devel("sinfo %u: Direct signer is key %x\n",
113 sinfo->index, key_serial(key)); 107 sinfo->index, key_serial(key));
@@ -122,7 +116,6 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
122 116
123matched: 117matched:
124 ret = verify_signature(key, sig); 118 ret = verify_signature(key, sig);
125 trusted = test_bit(KEY_FLAG_TRUSTED, &key->flags);
126 key_put(key); 119 key_put(key);
127 if (ret < 0) { 120 if (ret < 0) {
128 if (ret == -ENOMEM) 121 if (ret == -ENOMEM)
@@ -134,12 +127,9 @@ matched:
134verified: 127verified:
135 if (x509) { 128 if (x509) {
136 x509->verified = true; 129 x509->verified = true;
137 for (p = sinfo->signer; p != x509; p = p->signer) { 130 for (p = sinfo->signer; p != x509; p = p->signer)
138 p->verified = true; 131 p->verified = true;
139 p->trusted = trusted;
140 }
141 } 132 }
142 sinfo->trusted = trusted;
143 kleave(" = 0"); 133 kleave(" = 0");
144 return 0; 134 return 0;
145} 135}
@@ -148,7 +138,6 @@ verified:
148 * pkcs7_validate_trust - Validate PKCS#7 trust chain 138 * pkcs7_validate_trust - Validate PKCS#7 trust chain
149 * @pkcs7: The PKCS#7 certificate to validate 139 * @pkcs7: The PKCS#7 certificate to validate
150 * @trust_keyring: Signing certificates to use as starting points 140 * @trust_keyring: Signing certificates to use as starting points
151 * @_trusted: Set to true if trustworth, false otherwise
152 * 141 *
153 * Validate that the certificate chain inside the PKCS#7 message intersects 142 * Validate that the certificate chain inside the PKCS#7 message intersects
154 * keys we already know and trust. 143 * keys we already know and trust.
@@ -170,16 +159,13 @@ verified:
170 * May also return -ENOMEM. 159 * May also return -ENOMEM.
171 */ 160 */
172int pkcs7_validate_trust(struct pkcs7_message *pkcs7, 161int pkcs7_validate_trust(struct pkcs7_message *pkcs7,
173 struct key *trust_keyring, 162 struct key *trust_keyring)
174 bool *_trusted)
175{ 163{
176 struct pkcs7_signed_info *sinfo; 164 struct pkcs7_signed_info *sinfo;
177 struct x509_certificate *p; 165 struct x509_certificate *p;
178 int cached_ret = -ENOKEY; 166 int cached_ret = -ENOKEY;
179 int ret; 167 int ret;
180 168
181 *_trusted = false;
182
183 for (p = pkcs7->certs; p; p = p->next) 169 for (p = pkcs7->certs; p; p = p->next)
184 p->seen = false; 170 p->seen = false;
185 171
@@ -193,7 +179,6 @@ int pkcs7_validate_trust(struct pkcs7_message *pkcs7,
193 cached_ret = -ENOPKG; 179 cached_ret = -ENOPKG;
194 continue; 180 continue;
195 case 0: 181 case 0:
196 *_trusted |= sinfo->trusted;
197 cached_ret = 0; 182 cached_ret = 0;
198 continue; 183 continue;
199 default: 184 default:
diff --git a/crypto/asymmetric_keys/pkcs7_verify.c b/crypto/asymmetric_keys/pkcs7_verify.c
index 50be2a15e531..44b746e9df1b 100644
--- a/crypto/asymmetric_keys/pkcs7_verify.c
+++ b/crypto/asymmetric_keys/pkcs7_verify.c
@@ -25,34 +25,36 @@
25static int pkcs7_digest(struct pkcs7_message *pkcs7, 25static int pkcs7_digest(struct pkcs7_message *pkcs7,
26 struct pkcs7_signed_info *sinfo) 26 struct pkcs7_signed_info *sinfo)
27{ 27{
28 struct public_key_signature *sig = sinfo->sig;
28 struct crypto_shash *tfm; 29 struct crypto_shash *tfm;
29 struct shash_desc *desc; 30 struct shash_desc *desc;
30 size_t digest_size, desc_size; 31 size_t desc_size;
31 void *digest;
32 int ret; 32 int ret;
33 33
34 kenter(",%u,%s", sinfo->index, sinfo->sig.hash_algo); 34 kenter(",%u,%s", sinfo->index, sinfo->sig->hash_algo);
35 35
36 if (!sinfo->sig.hash_algo) 36 if (!sinfo->sig->hash_algo)
37 return -ENOPKG; 37 return -ENOPKG;
38 38
39 /* Allocate the hashing algorithm we're going to need and find out how 39 /* Allocate the hashing algorithm we're going to need and find out how
40 * big the hash operational data will be. 40 * big the hash operational data will be.
41 */ 41 */
42 tfm = crypto_alloc_shash(sinfo->sig.hash_algo, 0, 0); 42 tfm = crypto_alloc_shash(sinfo->sig->hash_algo, 0, 0);
43 if (IS_ERR(tfm)) 43 if (IS_ERR(tfm))
44 return (PTR_ERR(tfm) == -ENOENT) ? -ENOPKG : PTR_ERR(tfm); 44 return (PTR_ERR(tfm) == -ENOENT) ? -ENOPKG : PTR_ERR(tfm);
45 45
46 desc_size = crypto_shash_descsize(tfm) + sizeof(*desc); 46 desc_size = crypto_shash_descsize(tfm) + sizeof(*desc);
47 sinfo->sig.digest_size = digest_size = crypto_shash_digestsize(tfm); 47 sig->digest_size = crypto_shash_digestsize(tfm);
48 48
49 ret = -ENOMEM; 49 ret = -ENOMEM;
50 digest = kzalloc(ALIGN(digest_size, __alignof__(*desc)) + desc_size, 50 sig->digest = kmalloc(sig->digest_size, GFP_KERNEL);
51 GFP_KERNEL); 51 if (!sig->digest)
52 if (!digest) 52 goto error_no_desc;
53
54 desc = kzalloc(desc_size, GFP_KERNEL);
55 if (!desc)
53 goto error_no_desc; 56 goto error_no_desc;
54 57
55 desc = PTR_ALIGN(digest + digest_size, __alignof__(*desc));
56 desc->tfm = tfm; 58 desc->tfm = tfm;
57 desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; 59 desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
58 60
@@ -60,10 +62,11 @@ static int pkcs7_digest(struct pkcs7_message *pkcs7,
60 ret = crypto_shash_init(desc); 62 ret = crypto_shash_init(desc);
61 if (ret < 0) 63 if (ret < 0)
62 goto error; 64 goto error;
63 ret = crypto_shash_finup(desc, pkcs7->data, pkcs7->data_len, digest); 65 ret = crypto_shash_finup(desc, pkcs7->data, pkcs7->data_len,
66 sig->digest);
64 if (ret < 0) 67 if (ret < 0)
65 goto error; 68 goto error;
66 pr_devel("MsgDigest = [%*ph]\n", 8, digest); 69 pr_devel("MsgDigest = [%*ph]\n", 8, sig->digest);
67 70
68 /* However, if there are authenticated attributes, there must be a 71 /* However, if there are authenticated attributes, there must be a
69 * message digest attribute amongst them which corresponds to the 72 * message digest attribute amongst them which corresponds to the
@@ -78,14 +81,15 @@ static int pkcs7_digest(struct pkcs7_message *pkcs7,
78 goto error; 81 goto error;
79 } 82 }
80 83
81 if (sinfo->msgdigest_len != sinfo->sig.digest_size) { 84 if (sinfo->msgdigest_len != sig->digest_size) {
82 pr_debug("Sig %u: Invalid digest size (%u)\n", 85 pr_debug("Sig %u: Invalid digest size (%u)\n",
83 sinfo->index, sinfo->msgdigest_len); 86 sinfo->index, sinfo->msgdigest_len);
84 ret = -EBADMSG; 87 ret = -EBADMSG;
85 goto error; 88 goto error;
86 } 89 }
87 90
88 if (memcmp(digest, sinfo->msgdigest, sinfo->msgdigest_len) != 0) { 91 if (memcmp(sig->digest, sinfo->msgdigest,
92 sinfo->msgdigest_len) != 0) {
89 pr_debug("Sig %u: Message digest doesn't match\n", 93 pr_debug("Sig %u: Message digest doesn't match\n",
90 sinfo->index); 94 sinfo->index);
91 ret = -EKEYREJECTED; 95 ret = -EKEYREJECTED;
@@ -97,7 +101,7 @@ static int pkcs7_digest(struct pkcs7_message *pkcs7,
97 * convert the attributes from a CONT.0 into a SET before we 101 * convert the attributes from a CONT.0 into a SET before we
98 * hash it. 102 * hash it.
99 */ 103 */
100 memset(digest, 0, sinfo->sig.digest_size); 104 memset(sig->digest, 0, sig->digest_size);
101 105
102 ret = crypto_shash_init(desc); 106 ret = crypto_shash_init(desc);
103 if (ret < 0) 107 if (ret < 0)
@@ -107,17 +111,14 @@ static int pkcs7_digest(struct pkcs7_message *pkcs7,
107 if (ret < 0) 111 if (ret < 0)
108 goto error; 112 goto error;
109 ret = crypto_shash_finup(desc, sinfo->authattrs, 113 ret = crypto_shash_finup(desc, sinfo->authattrs,
110 sinfo->authattrs_len, digest); 114 sinfo->authattrs_len, sig->digest);
111 if (ret < 0) 115 if (ret < 0)
112 goto error; 116 goto error;
113 pr_devel("AADigest = [%*ph]\n", 8, digest); 117 pr_devel("AADigest = [%*ph]\n", 8, sig->digest);
114 } 118 }
115 119
116 sinfo->sig.digest = digest;
117 digest = NULL;
118
119error: 120error:
120 kfree(digest); 121 kfree(desc);
121error_no_desc: 122error_no_desc:
122 crypto_free_shash(tfm); 123 crypto_free_shash(tfm);
123 kleave(" = %d", ret); 124 kleave(" = %d", ret);
@@ -144,12 +145,12 @@ static int pkcs7_find_key(struct pkcs7_message *pkcs7,
144 * PKCS#7 message - but I can't be 100% sure of that. It's 145 * PKCS#7 message - but I can't be 100% sure of that. It's
145 * possible this will need element-by-element comparison. 146 * possible this will need element-by-element comparison.
146 */ 147 */
147 if (!asymmetric_key_id_same(x509->id, sinfo->signing_cert_id)) 148 if (!asymmetric_key_id_same(x509->id, sinfo->sig->auth_ids[0]))
148 continue; 149 continue;
149 pr_devel("Sig %u: Found cert serial match X.509[%u]\n", 150 pr_devel("Sig %u: Found cert serial match X.509[%u]\n",
150 sinfo->index, certix); 151 sinfo->index, certix);
151 152
152 if (x509->pub->pkey_algo != sinfo->sig.pkey_algo) { 153 if (x509->pub->pkey_algo != sinfo->sig->pkey_algo) {
153 pr_warn("Sig %u: X.509 algo and PKCS#7 sig algo don't match\n", 154 pr_warn("Sig %u: X.509 algo and PKCS#7 sig algo don't match\n",
154 sinfo->index); 155 sinfo->index);
155 continue; 156 continue;
@@ -164,7 +165,7 @@ static int pkcs7_find_key(struct pkcs7_message *pkcs7,
164 */ 165 */
165 pr_debug("Sig %u: Issuing X.509 cert not found (#%*phN)\n", 166 pr_debug("Sig %u: Issuing X.509 cert not found (#%*phN)\n",
166 sinfo->index, 167 sinfo->index,
167 sinfo->signing_cert_id->len, sinfo->signing_cert_id->data); 168 sinfo->sig->auth_ids[0]->len, sinfo->sig->auth_ids[0]->data);
168 return 0; 169 return 0;
169} 170}
170 171
@@ -174,6 +175,7 @@ static int pkcs7_find_key(struct pkcs7_message *pkcs7,
174static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7, 175static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
175 struct pkcs7_signed_info *sinfo) 176 struct pkcs7_signed_info *sinfo)
176{ 177{
178 struct public_key_signature *sig;
177 struct x509_certificate *x509 = sinfo->signer, *p; 179 struct x509_certificate *x509 = sinfo->signer, *p;
178 struct asymmetric_key_id *auth; 180 struct asymmetric_key_id *auth;
179 int ret; 181 int ret;
@@ -188,34 +190,26 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
188 x509->subject, 190 x509->subject,
189 x509->raw_serial_size, x509->raw_serial); 191 x509->raw_serial_size, x509->raw_serial);
190 x509->seen = true; 192 x509->seen = true;
191 ret = x509_get_sig_params(x509); 193 if (x509->unsupported_key)
192 if (ret < 0) 194 goto unsupported_crypto_in_x509;
193 goto maybe_missing_crypto_in_x509;
194 195
195 pr_debug("- issuer %s\n", x509->issuer); 196 pr_debug("- issuer %s\n", x509->issuer);
196 if (x509->akid_id) 197 sig = x509->sig;
198 if (sig->auth_ids[0])
197 pr_debug("- authkeyid.id %*phN\n", 199 pr_debug("- authkeyid.id %*phN\n",
198 x509->akid_id->len, x509->akid_id->data); 200 sig->auth_ids[0]->len, sig->auth_ids[0]->data);
199 if (x509->akid_skid) 201 if (sig->auth_ids[1])
200 pr_debug("- authkeyid.skid %*phN\n", 202 pr_debug("- authkeyid.skid %*phN\n",
201 x509->akid_skid->len, x509->akid_skid->data); 203 sig->auth_ids[1]->len, sig->auth_ids[1]->data);
202 204
203 if ((!x509->akid_id && !x509->akid_skid) || 205 if (x509->self_signed) {
204 strcmp(x509->subject, x509->issuer) == 0) {
205 /* If there's no authority certificate specified, then 206 /* If there's no authority certificate specified, then
206 * the certificate must be self-signed and is the root 207 * the certificate must be self-signed and is the root
207 * of the chain. Likewise if the cert is its own 208 * of the chain. Likewise if the cert is its own
208 * authority. 209 * authority.
209 */ 210 */
210 pr_debug("- no auth?\n"); 211 if (x509->unsupported_sig)
211 if (x509->raw_subject_size != x509->raw_issuer_size || 212 goto unsupported_crypto_in_x509;
212 memcmp(x509->raw_subject, x509->raw_issuer,
213 x509->raw_issuer_size) != 0)
214 return 0;
215
216 ret = x509_check_signature(x509->pub, x509);
217 if (ret < 0)
218 goto maybe_missing_crypto_in_x509;
219 x509->signer = x509; 213 x509->signer = x509;
220 pr_debug("- self-signed\n"); 214 pr_debug("- self-signed\n");
221 return 0; 215 return 0;
@@ -224,7 +218,7 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
224 /* Look through the X.509 certificates in the PKCS#7 message's 218 /* Look through the X.509 certificates in the PKCS#7 message's
225 * list to see if the next one is there. 219 * list to see if the next one is there.
226 */ 220 */
227 auth = x509->akid_id; 221 auth = sig->auth_ids[0];
228 if (auth) { 222 if (auth) {
229 pr_debug("- want %*phN\n", auth->len, auth->data); 223 pr_debug("- want %*phN\n", auth->len, auth->data);
230 for (p = pkcs7->certs; p; p = p->next) { 224 for (p = pkcs7->certs; p; p = p->next) {
@@ -234,7 +228,7 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
234 goto found_issuer_check_skid; 228 goto found_issuer_check_skid;
235 } 229 }
236 } else { 230 } else {
237 auth = x509->akid_skid; 231 auth = sig->auth_ids[1];
238 pr_debug("- want %*phN\n", auth->len, auth->data); 232 pr_debug("- want %*phN\n", auth->len, auth->data);
239 for (p = pkcs7->certs; p; p = p->next) { 233 for (p = pkcs7->certs; p; p = p->next) {
240 if (!p->skid) 234 if (!p->skid)
@@ -254,8 +248,8 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
254 /* We matched issuer + serialNumber, but if there's an 248 /* We matched issuer + serialNumber, but if there's an
255 * authKeyId.keyId, that must match the CA subjKeyId also. 249 * authKeyId.keyId, that must match the CA subjKeyId also.
256 */ 250 */
257 if (x509->akid_skid && 251 if (sig->auth_ids[1] &&
258 !asymmetric_key_id_same(p->skid, x509->akid_skid)) { 252 !asymmetric_key_id_same(p->skid, sig->auth_ids[1])) {
259 pr_warn("Sig %u: X.509 chain contains auth-skid nonmatch (%u->%u)\n", 253 pr_warn("Sig %u: X.509 chain contains auth-skid nonmatch (%u->%u)\n",
260 sinfo->index, x509->index, p->index); 254 sinfo->index, x509->index, p->index);
261 return -EKEYREJECTED; 255 return -EKEYREJECTED;
@@ -267,7 +261,7 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
267 sinfo->index); 261 sinfo->index);
268 return 0; 262 return 0;
269 } 263 }
270 ret = x509_check_signature(p->pub, x509); 264 ret = public_key_verify_signature(p->pub, p->sig);
271 if (ret < 0) 265 if (ret < 0)
272 return ret; 266 return ret;
273 x509->signer = p; 267 x509->signer = p;
@@ -279,16 +273,14 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
279 might_sleep(); 273 might_sleep();
280 } 274 }
281 275
282maybe_missing_crypto_in_x509: 276unsupported_crypto_in_x509:
283 /* Just prune the certificate chain at this point if we lack some 277 /* Just prune the certificate chain at this point if we lack some
284 * crypto module to go further. Note, however, we don't want to set 278 * crypto module to go further. Note, however, we don't want to set
285 * sinfo->missing_crypto as the signed info block may still be 279 * sinfo->unsupported_crypto as the signed info block may still be
286 * validatable against an X.509 cert lower in the chain that we have a 280 * validatable against an X.509 cert lower in the chain that we have a
287 * trusted copy of. 281 * trusted copy of.
288 */ 282 */
289 if (ret == -ENOPKG) 283 return 0;
290 return 0;
291 return ret;
292} 284}
293 285
294/* 286/*
@@ -332,7 +324,7 @@ static int pkcs7_verify_one(struct pkcs7_message *pkcs7,
332 } 324 }
333 325
334 /* Verify the PKCS#7 binary against the key */ 326 /* Verify the PKCS#7 binary against the key */
335 ret = public_key_verify_signature(sinfo->signer->pub, &sinfo->sig); 327 ret = public_key_verify_signature(sinfo->signer->pub, sinfo->sig);
336 if (ret < 0) 328 if (ret < 0)
337 return ret; 329 return ret;
338 330
@@ -375,9 +367,8 @@ int pkcs7_verify(struct pkcs7_message *pkcs7,
375 enum key_being_used_for usage) 367 enum key_being_used_for usage)
376{ 368{
377 struct pkcs7_signed_info *sinfo; 369 struct pkcs7_signed_info *sinfo;
378 struct x509_certificate *x509;
379 int enopkg = -ENOPKG; 370 int enopkg = -ENOPKG;
380 int ret, n; 371 int ret;
381 372
382 kenter(""); 373 kenter("");
383 374
@@ -419,12 +410,6 @@ int pkcs7_verify(struct pkcs7_message *pkcs7,
419 return -EINVAL; 410 return -EINVAL;
420 } 411 }
421 412
422 for (n = 0, x509 = pkcs7->certs; x509; x509 = x509->next, n++) {
423 ret = x509_get_sig_params(x509);
424 if (ret < 0)
425 return ret;
426 }
427
428 for (sinfo = pkcs7->signed_infos; sinfo; sinfo = sinfo->next) { 413 for (sinfo = pkcs7->signed_infos; sinfo; sinfo = sinfo->next) {
429 ret = pkcs7_verify_one(pkcs7, sinfo); 414 ret = pkcs7_verify_one(pkcs7, sinfo);
430 if (ret < 0) { 415 if (ret < 0) {
diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c
index 0f8b264b3961..fd76b5fc3b3a 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -39,15 +39,23 @@ static void public_key_describe(const struct key *asymmetric_key,
39/* 39/*
40 * Destroy a public key algorithm key. 40 * Destroy a public key algorithm key.
41 */ 41 */
42void public_key_destroy(void *payload) 42void public_key_free(struct public_key *key)
43{ 43{
44 struct public_key *key = payload; 44 if (key) {
45
46 if (key)
47 kfree(key->key); 45 kfree(key->key);
48 kfree(key); 46 kfree(key);
47 }
48}
49EXPORT_SYMBOL_GPL(public_key_free);
50
51/*
52 * Destroy a public key algorithm key.
53 */
54static void public_key_destroy(void *payload0, void *payload3)
55{
56 public_key_free(payload0);
57 public_key_signature_free(payload3);
49} 58}
50EXPORT_SYMBOL_GPL(public_key_destroy);
51 59
52struct public_key_completion { 60struct public_key_completion {
53 struct completion completion; 61 struct completion completion;
diff --git a/crypto/asymmetric_keys/restrict.c b/crypto/asymmetric_keys/restrict.c
new file mode 100644
index 000000000000..ac4bddf669de
--- /dev/null
+++ b/crypto/asymmetric_keys/restrict.c
@@ -0,0 +1,108 @@
1/* Instantiate a public key crypto key from an X.509 Certificate
2 *
3 * Copyright (C) 2012, 2016 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11
12#define pr_fmt(fmt) "ASYM: "fmt
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/err.h>
16#include <crypto/public_key.h>
17#include "asymmetric_keys.h"
18
19static bool use_builtin_keys;
20static struct asymmetric_key_id *ca_keyid;
21
22#ifndef MODULE
23static struct {
24 struct asymmetric_key_id id;
25 unsigned char data[10];
26} cakey;
27
28static int __init ca_keys_setup(char *str)
29{
30 if (!str) /* default system keyring */
31 return 1;
32
33 if (strncmp(str, "id:", 3) == 0) {
34 struct asymmetric_key_id *p = &cakey.id;
35 size_t hexlen = (strlen(str) - 3) / 2;
36 int ret;
37
38 if (hexlen == 0 || hexlen > sizeof(cakey.data)) {
39 pr_err("Missing or invalid ca_keys id\n");
40 return 1;
41 }
42
43 ret = __asymmetric_key_hex_to_key_id(str + 3, p, hexlen);
44 if (ret < 0)
45 pr_err("Unparsable ca_keys id hex string\n");
46 else
47 ca_keyid = p; /* owner key 'id:xxxxxx' */
48 } else if (strcmp(str, "builtin") == 0) {
49 use_builtin_keys = true;
50 }
51
52 return 1;
53}
54__setup("ca_keys=", ca_keys_setup);
55#endif
56
57/**
58 * restrict_link_by_signature - Restrict additions to a ring of public keys
59 * @trust_keyring: A ring of keys that can be used to vouch for the new cert.
60 * @type: The type of key being added.
61 * @payload: The payload of the new key.
62 *
63 * Check the new certificate against the ones in the trust keyring. If one of
64 * those is the signing key and validates the new certificate, then mark the
65 * new certificate as being trusted.
66 *
67 * Returns 0 if the new certificate was accepted, -ENOKEY if we couldn't find a
68 * matching parent certificate in the trusted list, -EKEYREJECTED if the
69 * signature check fails or the key is blacklisted and some other error if
70 * there is a matching certificate but the signature check cannot be performed.
71 */
72int restrict_link_by_signature(struct key *trust_keyring,
73 const struct key_type *type,
74 const union key_payload *payload)
75{
76 const struct public_key_signature *sig;
77 struct key *key;
78 int ret;
79
80 pr_devel("==>%s()\n", __func__);
81
82 if (!trust_keyring)
83 return -ENOKEY;
84
85 if (type != &key_type_asymmetric)
86 return -EOPNOTSUPP;
87
88 sig = payload->data[asym_auth];
89 if (!sig->auth_ids[0] && !sig->auth_ids[1])
90 return 0;
91
92 if (ca_keyid && !asymmetric_key_id_partial(sig->auth_ids[1], ca_keyid))
93 return -EPERM;
94
95 /* See if we have a key that signed this one. */
96 key = find_asymmetric_key(trust_keyring,
97 sig->auth_ids[0], sig->auth_ids[1],
98 false);
99 if (IS_ERR(key))
100 return -ENOKEY;
101
102 if (use_builtin_keys && !test_bit(KEY_FLAG_BUILTIN, &key->flags))
103 ret = -ENOKEY;
104 else
105 ret = verify_signature(key, sig);
106 key_put(key);
107 return ret;
108}
diff --git a/crypto/asymmetric_keys/signature.c b/crypto/asymmetric_keys/signature.c
index 004d5fc8e56b..11b7ba170904 100644
--- a/crypto/asymmetric_keys/signature.c
+++ b/crypto/asymmetric_keys/signature.c
@@ -15,9 +15,27 @@
15#include <keys/asymmetric-subtype.h> 15#include <keys/asymmetric-subtype.h>
16#include <linux/export.h> 16#include <linux/export.h>
17#include <linux/err.h> 17#include <linux/err.h>
18#include <linux/slab.h>
18#include <crypto/public_key.h> 19#include <crypto/public_key.h>
19#include "asymmetric_keys.h" 20#include "asymmetric_keys.h"
20 21
22/*
23 * Destroy a public key signature.
24 */
25void public_key_signature_free(struct public_key_signature *sig)
26{
27 int i;
28
29 if (sig) {
30 for (i = 0; i < ARRAY_SIZE(sig->auth_ids); i++)
31 kfree(sig->auth_ids[i]);
32 kfree(sig->s);
33 kfree(sig->digest);
34 kfree(sig);
35 }
36}
37EXPORT_SYMBOL_GPL(public_key_signature_free);
38
21/** 39/**
22 * verify_signature - Initiate the use of an asymmetric key to verify a signature 40 * verify_signature - Initiate the use of an asymmetric key to verify a signature
23 * @key: The asymmetric key to verify against 41 * @key: The asymmetric key to verify against
diff --git a/crypto/asymmetric_keys/verify_pefile.c b/crypto/asymmetric_keys/verify_pefile.c
index 7e8c2338ae25..672a94c2c3ff 100644
--- a/crypto/asymmetric_keys/verify_pefile.c
+++ b/crypto/asymmetric_keys/verify_pefile.c
@@ -16,7 +16,7 @@
16#include <linux/err.h> 16#include <linux/err.h>
17#include <linux/pe.h> 17#include <linux/pe.h>
18#include <linux/asn1.h> 18#include <linux/asn1.h>
19#include <crypto/pkcs7.h> 19#include <linux/verification.h>
20#include <crypto/hash.h> 20#include <crypto/hash.h>
21#include "verify_pefile.h" 21#include "verify_pefile.h"
22 22
@@ -392,9 +392,8 @@ error_no_desc:
392 * verify_pefile_signature - Verify the signature on a PE binary image 392 * verify_pefile_signature - Verify the signature on a PE binary image
393 * @pebuf: Buffer containing the PE binary image 393 * @pebuf: Buffer containing the PE binary image
394 * @pelen: Length of the binary image 394 * @pelen: Length of the binary image
395 * @trust_keyring: Signing certificates to use as starting points 395 * @trust_keys: Signing certificate(s) to use as starting points
396 * @usage: The use to which the key is being put. 396 * @usage: The use to which the key is being put.
397 * @_trusted: Set to true if trustworth, false otherwise
398 * 397 *
399 * Validate that the certificate chain inside the PKCS#7 message inside the PE 398 * Validate that the certificate chain inside the PKCS#7 message inside the PE
400 * binary image intersects keys we already know and trust. 399 * binary image intersects keys we already know and trust.
@@ -418,14 +417,10 @@ error_no_desc:
418 * May also return -ENOMEM. 417 * May also return -ENOMEM.
419 */ 418 */
420int verify_pefile_signature(const void *pebuf, unsigned pelen, 419int verify_pefile_signature(const void *pebuf, unsigned pelen,
421 struct key *trusted_keyring, 420 struct key *trusted_keys,
422 enum key_being_used_for usage, 421 enum key_being_used_for usage)
423 bool *_trusted)
424{ 422{
425 struct pkcs7_message *pkcs7;
426 struct pefile_context ctx; 423 struct pefile_context ctx;
427 const void *data;
428 size_t datalen;
429 int ret; 424 int ret;
430 425
431 kenter(""); 426 kenter("");
@@ -439,19 +434,10 @@ int verify_pefile_signature(const void *pebuf, unsigned pelen,
439 if (ret < 0) 434 if (ret < 0)
440 return ret; 435 return ret;
441 436
442 pkcs7 = pkcs7_parse_message(pebuf + ctx.sig_offset, ctx.sig_len); 437 ret = verify_pkcs7_signature(NULL, 0,
443 if (IS_ERR(pkcs7)) 438 pebuf + ctx.sig_offset, ctx.sig_len,
444 return PTR_ERR(pkcs7); 439 trusted_keys, usage,
445 ctx.pkcs7 = pkcs7; 440 mscode_parse, &ctx);
446
447 ret = pkcs7_get_content_data(ctx.pkcs7, &data, &datalen, false);
448 if (ret < 0 || datalen == 0) {
449 pr_devel("PKCS#7 message does not contain data\n");
450 ret = -EBADMSG;
451 goto error;
452 }
453
454 ret = mscode_parse(&ctx);
455 if (ret < 0) 441 if (ret < 0)
456 goto error; 442 goto error;
457 443
@@ -462,16 +448,8 @@ int verify_pefile_signature(const void *pebuf, unsigned pelen,
462 * contents. 448 * contents.
463 */ 449 */
464 ret = pefile_digest_pe(pebuf, pelen, &ctx); 450 ret = pefile_digest_pe(pebuf, pelen, &ctx);
465 if (ret < 0)
466 goto error;
467
468 ret = pkcs7_verify(pkcs7, usage);
469 if (ret < 0)
470 goto error;
471
472 ret = pkcs7_validate_trust(pkcs7, trusted_keyring, _trusted);
473 451
474error: 452error:
475 pkcs7_free_message(ctx.pkcs7); 453 kfree(ctx.digest);
476 return ret; 454 return ret;
477} 455}
diff --git a/crypto/asymmetric_keys/verify_pefile.h b/crypto/asymmetric_keys/verify_pefile.h
index a133eb81a492..cd4d20930728 100644
--- a/crypto/asymmetric_keys/verify_pefile.h
+++ b/crypto/asymmetric_keys/verify_pefile.h
@@ -9,7 +9,6 @@
9 * 2 of the Licence, or (at your option) any later version. 9 * 2 of the Licence, or (at your option) any later version.
10 */ 10 */
11 11
12#include <linux/verify_pefile.h>
13#include <crypto/pkcs7.h> 12#include <crypto/pkcs7.h>
14#include <crypto/hash_info.h> 13#include <crypto/hash_info.h>
15 14
@@ -23,7 +22,6 @@ struct pefile_context {
23 unsigned sig_offset; 22 unsigned sig_offset;
24 unsigned sig_len; 23 unsigned sig_len;
25 const struct section_header *secs; 24 const struct section_header *secs;
26 struct pkcs7_message *pkcs7;
27 25
28 /* PKCS#7 MS Individual Code Signing content */ 26 /* PKCS#7 MS Individual Code Signing content */
29 const void *digest; /* Digest */ 27 const void *digest; /* Digest */
@@ -39,4 +37,5 @@ struct pefile_context {
39/* 37/*
40 * mscode_parser.c 38 * mscode_parser.c
41 */ 39 */
42extern int mscode_parse(struct pefile_context *ctx); 40extern int mscode_parse(void *_ctx, const void *content_data, size_t data_len,
41 size_t asn1hdrlen);
diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c
index 4a29bac70060..865f46ea724f 100644
--- a/crypto/asymmetric_keys/x509_cert_parser.c
+++ b/crypto/asymmetric_keys/x509_cert_parser.c
@@ -47,15 +47,12 @@ struct x509_parse_context {
47void x509_free_certificate(struct x509_certificate *cert) 47void x509_free_certificate(struct x509_certificate *cert)
48{ 48{
49 if (cert) { 49 if (cert) {
50 public_key_destroy(cert->pub); 50 public_key_free(cert->pub);
51 public_key_signature_free(cert->sig);
51 kfree(cert->issuer); 52 kfree(cert->issuer);
52 kfree(cert->subject); 53 kfree(cert->subject);
53 kfree(cert->id); 54 kfree(cert->id);
54 kfree(cert->skid); 55 kfree(cert->skid);
55 kfree(cert->akid_id);
56 kfree(cert->akid_skid);
57 kfree(cert->sig.digest);
58 kfree(cert->sig.s);
59 kfree(cert); 56 kfree(cert);
60 } 57 }
61} 58}
@@ -78,6 +75,9 @@ struct x509_certificate *x509_cert_parse(const void *data, size_t datalen)
78 cert->pub = kzalloc(sizeof(struct public_key), GFP_KERNEL); 75 cert->pub = kzalloc(sizeof(struct public_key), GFP_KERNEL);
79 if (!cert->pub) 76 if (!cert->pub)
80 goto error_no_ctx; 77 goto error_no_ctx;
78 cert->sig = kzalloc(sizeof(struct public_key_signature), GFP_KERNEL);
79 if (!cert->sig)
80 goto error_no_ctx;
81 ctx = kzalloc(sizeof(struct x509_parse_context), GFP_KERNEL); 81 ctx = kzalloc(sizeof(struct x509_parse_context), GFP_KERNEL);
82 if (!ctx) 82 if (!ctx)
83 goto error_no_ctx; 83 goto error_no_ctx;
@@ -108,6 +108,11 @@ struct x509_certificate *x509_cert_parse(const void *data, size_t datalen)
108 108
109 cert->pub->keylen = ctx->key_size; 109 cert->pub->keylen = ctx->key_size;
110 110
111 /* Grab the signature bits */
112 ret = x509_get_sig_params(cert);
113 if (ret < 0)
114 goto error_decode;
115
111 /* Generate cert issuer + serial number key ID */ 116 /* Generate cert issuer + serial number key ID */
112 kid = asymmetric_key_generate_id(cert->raw_serial, 117 kid = asymmetric_key_generate_id(cert->raw_serial,
113 cert->raw_serial_size, 118 cert->raw_serial_size,
@@ -119,6 +124,11 @@ struct x509_certificate *x509_cert_parse(const void *data, size_t datalen)
119 } 124 }
120 cert->id = kid; 125 cert->id = kid;
121 126
127 /* Detect self-signed certificates */
128 ret = x509_check_for_self_signed(cert);
129 if (ret < 0)
130 goto error_decode;
131
122 kfree(ctx); 132 kfree(ctx);
123 return cert; 133 return cert;
124 134
@@ -188,33 +198,33 @@ int x509_note_pkey_algo(void *context, size_t hdrlen,
188 return -ENOPKG; /* Unsupported combination */ 198 return -ENOPKG; /* Unsupported combination */
189 199
190 case OID_md4WithRSAEncryption: 200 case OID_md4WithRSAEncryption:
191 ctx->cert->sig.hash_algo = "md4"; 201 ctx->cert->sig->hash_algo = "md4";
192 ctx->cert->sig.pkey_algo = "rsa"; 202 ctx->cert->sig->pkey_algo = "rsa";
193 break; 203 break;
194 204
195 case OID_sha1WithRSAEncryption: 205 case OID_sha1WithRSAEncryption:
196 ctx->cert->sig.hash_algo = "sha1"; 206 ctx->cert->sig->hash_algo = "sha1";
197 ctx->cert->sig.pkey_algo = "rsa"; 207 ctx->cert->sig->pkey_algo = "rsa";
198 break; 208 break;
199 209
200 case OID_sha256WithRSAEncryption: 210 case OID_sha256WithRSAEncryption:
201 ctx->cert->sig.hash_algo = "sha256"; 211 ctx->cert->sig->hash_algo = "sha256";
202 ctx->cert->sig.pkey_algo = "rsa"; 212 ctx->cert->sig->pkey_algo = "rsa";
203 break; 213 break;
204 214
205 case OID_sha384WithRSAEncryption: 215 case OID_sha384WithRSAEncryption:
206 ctx->cert->sig.hash_algo = "sha384"; 216 ctx->cert->sig->hash_algo = "sha384";
207 ctx->cert->sig.pkey_algo = "rsa"; 217 ctx->cert->sig->pkey_algo = "rsa";
208 break; 218 break;
209 219
210 case OID_sha512WithRSAEncryption: 220 case OID_sha512WithRSAEncryption:
211 ctx->cert->sig.hash_algo = "sha512"; 221 ctx->cert->sig->hash_algo = "sha512";
212 ctx->cert->sig.pkey_algo = "rsa"; 222 ctx->cert->sig->pkey_algo = "rsa";
213 break; 223 break;
214 224
215 case OID_sha224WithRSAEncryption: 225 case OID_sha224WithRSAEncryption:
216 ctx->cert->sig.hash_algo = "sha224"; 226 ctx->cert->sig->hash_algo = "sha224";
217 ctx->cert->sig.pkey_algo = "rsa"; 227 ctx->cert->sig->pkey_algo = "rsa";
218 break; 228 break;
219 } 229 }
220 230
@@ -572,14 +582,14 @@ int x509_akid_note_kid(void *context, size_t hdrlen,
572 582
573 pr_debug("AKID: keyid: %*phN\n", (int)vlen, value); 583 pr_debug("AKID: keyid: %*phN\n", (int)vlen, value);
574 584
575 if (ctx->cert->akid_skid) 585 if (ctx->cert->sig->auth_ids[1])
576 return 0; 586 return 0;
577 587
578 kid = asymmetric_key_generate_id(value, vlen, "", 0); 588 kid = asymmetric_key_generate_id(value, vlen, "", 0);
579 if (IS_ERR(kid)) 589 if (IS_ERR(kid))
580 return PTR_ERR(kid); 590 return PTR_ERR(kid);
581 pr_debug("authkeyid %*phN\n", kid->len, kid->data); 591 pr_debug("authkeyid %*phN\n", kid->len, kid->data);
582 ctx->cert->akid_skid = kid; 592 ctx->cert->sig->auth_ids[1] = kid;
583 return 0; 593 return 0;
584} 594}
585 595
@@ -611,7 +621,7 @@ int x509_akid_note_serial(void *context, size_t hdrlen,
611 621
612 pr_debug("AKID: serial: %*phN\n", (int)vlen, value); 622 pr_debug("AKID: serial: %*phN\n", (int)vlen, value);
613 623
614 if (!ctx->akid_raw_issuer || ctx->cert->akid_id) 624 if (!ctx->akid_raw_issuer || ctx->cert->sig->auth_ids[0])
615 return 0; 625 return 0;
616 626
617 kid = asymmetric_key_generate_id(value, 627 kid = asymmetric_key_generate_id(value,
@@ -622,6 +632,6 @@ int x509_akid_note_serial(void *context, size_t hdrlen,
622 return PTR_ERR(kid); 632 return PTR_ERR(kid);
623 633
624 pr_debug("authkeyid %*phN\n", kid->len, kid->data); 634 pr_debug("authkeyid %*phN\n", kid->len, kid->data);
625 ctx->cert->akid_id = kid; 635 ctx->cert->sig->auth_ids[0] = kid;
626 return 0; 636 return 0;
627} 637}
diff --git a/crypto/asymmetric_keys/x509_parser.h b/crypto/asymmetric_keys/x509_parser.h
index dbeed6018e63..05eef1c68881 100644
--- a/crypto/asymmetric_keys/x509_parser.h
+++ b/crypto/asymmetric_keys/x509_parser.h
@@ -17,13 +17,11 @@ struct x509_certificate {
17 struct x509_certificate *next; 17 struct x509_certificate *next;
18 struct x509_certificate *signer; /* Certificate that signed this one */ 18 struct x509_certificate *signer; /* Certificate that signed this one */
19 struct public_key *pub; /* Public key details */ 19 struct public_key *pub; /* Public key details */
20 struct public_key_signature sig; /* Signature parameters */ 20 struct public_key_signature *sig; /* Signature parameters */
21 char *issuer; /* Name of certificate issuer */ 21 char *issuer; /* Name of certificate issuer */
22 char *subject; /* Name of certificate subject */ 22 char *subject; /* Name of certificate subject */
23 struct asymmetric_key_id *id; /* Issuer + Serial number */ 23 struct asymmetric_key_id *id; /* Issuer + Serial number */
24 struct asymmetric_key_id *skid; /* Subject + subjectKeyId (optional) */ 24 struct asymmetric_key_id *skid; /* Subject + subjectKeyId (optional) */
25 struct asymmetric_key_id *akid_id; /* CA AuthKeyId matching ->id (optional) */
26 struct asymmetric_key_id *akid_skid; /* CA AuthKeyId matching ->skid (optional) */
27 time64_t valid_from; 25 time64_t valid_from;
28 time64_t valid_to; 26 time64_t valid_to;
29 const void *tbs; /* Signed data */ 27 const void *tbs; /* Signed data */
@@ -41,8 +39,9 @@ struct x509_certificate {
41 unsigned index; 39 unsigned index;
42 bool seen; /* Infinite recursion prevention */ 40 bool seen; /* Infinite recursion prevention */
43 bool verified; 41 bool verified;
44 bool trusted; 42 bool self_signed; /* T if self-signed (check unsupported_sig too) */
45 bool unsupported_crypto; /* T if can't be verified due to missing crypto */ 43 bool unsupported_key; /* T if key uses unsupported crypto */
44 bool unsupported_sig; /* T if signature uses unsupported crypto */
46}; 45};
47 46
48/* 47/*
@@ -58,5 +57,4 @@ extern int x509_decode_time(time64_t *_t, size_t hdrlen,
58 * x509_public_key.c 57 * x509_public_key.c
59 */ 58 */
60extern int x509_get_sig_params(struct x509_certificate *cert); 59extern int x509_get_sig_params(struct x509_certificate *cert);
61extern int x509_check_signature(const struct public_key *pub, 60extern int x509_check_for_self_signed(struct x509_certificate *cert);
62 struct x509_certificate *cert);
diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c
index 733c046aacc6..fb732296cd36 100644
--- a/crypto/asymmetric_keys/x509_public_key.c
+++ b/crypto/asymmetric_keys/x509_public_key.c
@@ -20,256 +20,133 @@
20#include "asymmetric_keys.h" 20#include "asymmetric_keys.h"
21#include "x509_parser.h" 21#include "x509_parser.h"
22 22
23static bool use_builtin_keys;
24static struct asymmetric_key_id *ca_keyid;
25
26#ifndef MODULE
27static struct {
28 struct asymmetric_key_id id;
29 unsigned char data[10];
30} cakey;
31
32static int __init ca_keys_setup(char *str)
33{
34 if (!str) /* default system keyring */
35 return 1;
36
37 if (strncmp(str, "id:", 3) == 0) {
38 struct asymmetric_key_id *p = &cakey.id;
39 size_t hexlen = (strlen(str) - 3) / 2;
40 int ret;
41
42 if (hexlen == 0 || hexlen > sizeof(cakey.data)) {
43 pr_err("Missing or invalid ca_keys id\n");
44 return 1;
45 }
46
47 ret = __asymmetric_key_hex_to_key_id(str + 3, p, hexlen);
48 if (ret < 0)
49 pr_err("Unparsable ca_keys id hex string\n");
50 else
51 ca_keyid = p; /* owner key 'id:xxxxxx' */
52 } else if (strcmp(str, "builtin") == 0) {
53 use_builtin_keys = true;
54 }
55
56 return 1;
57}
58__setup("ca_keys=", ca_keys_setup);
59#endif
60
61/**
62 * x509_request_asymmetric_key - Request a key by X.509 certificate params.
63 * @keyring: The keys to search.
64 * @id: The issuer & serialNumber to look for or NULL.
65 * @skid: The subjectKeyIdentifier to look for or NULL.
66 * @partial: Use partial match if true, exact if false.
67 *
68 * Find a key in the given keyring by identifier. The preferred identifier is
69 * the issuer + serialNumber and the fallback identifier is the
70 * subjectKeyIdentifier. If both are given, the lookup is by the former, but
71 * the latter must also match.
72 */
73struct key *x509_request_asymmetric_key(struct key *keyring,
74 const struct asymmetric_key_id *id,
75 const struct asymmetric_key_id *skid,
76 bool partial)
77{
78 struct key *key;
79 key_ref_t ref;
80 const char *lookup;
81 char *req, *p;
82 int len;
83
84 if (id) {
85 lookup = id->data;
86 len = id->len;
87 } else {
88 lookup = skid->data;
89 len = skid->len;
90 }
91
92 /* Construct an identifier "id:<keyid>". */
93 p = req = kmalloc(2 + 1 + len * 2 + 1, GFP_KERNEL);
94 if (!req)
95 return ERR_PTR(-ENOMEM);
96
97 if (partial) {
98 *p++ = 'i';
99 *p++ = 'd';
100 } else {
101 *p++ = 'e';
102 *p++ = 'x';
103 }
104 *p++ = ':';
105 p = bin2hex(p, lookup, len);
106 *p = 0;
107
108 pr_debug("Look up: \"%s\"\n", req);
109
110 ref = keyring_search(make_key_ref(keyring, 1),
111 &key_type_asymmetric, req);
112 if (IS_ERR(ref))
113 pr_debug("Request for key '%s' err %ld\n", req, PTR_ERR(ref));
114 kfree(req);
115
116 if (IS_ERR(ref)) {
117 switch (PTR_ERR(ref)) {
118 /* Hide some search errors */
119 case -EACCES:
120 case -ENOTDIR:
121 case -EAGAIN:
122 return ERR_PTR(-ENOKEY);
123 default:
124 return ERR_CAST(ref);
125 }
126 }
127
128 key = key_ref_to_ptr(ref);
129 if (id && skid) {
130 const struct asymmetric_key_ids *kids = asymmetric_key_ids(key);
131 if (!kids->id[1]) {
132 pr_debug("issuer+serial match, but expected SKID missing\n");
133 goto reject;
134 }
135 if (!asymmetric_key_id_same(skid, kids->id[1])) {
136 pr_debug("issuer+serial match, but SKID does not\n");
137 goto reject;
138 }
139 }
140
141 pr_devel("<==%s() = 0 [%x]\n", __func__, key_serial(key));
142 return key;
143
144reject:
145 key_put(key);
146 return ERR_PTR(-EKEYREJECTED);
147}
148EXPORT_SYMBOL_GPL(x509_request_asymmetric_key);
149
150/* 23/*
151 * Set up the signature parameters in an X.509 certificate. This involves 24 * Set up the signature parameters in an X.509 certificate. This involves
152 * digesting the signed data and extracting the signature. 25 * digesting the signed data and extracting the signature.
153 */ 26 */
154int x509_get_sig_params(struct x509_certificate *cert) 27int x509_get_sig_params(struct x509_certificate *cert)
155{ 28{
29 struct public_key_signature *sig = cert->sig;
156 struct crypto_shash *tfm; 30 struct crypto_shash *tfm;
157 struct shash_desc *desc; 31 struct shash_desc *desc;
158 size_t digest_size, desc_size; 32 size_t desc_size;
159 void *digest;
160 int ret; 33 int ret;
161 34
162 pr_devel("==>%s()\n", __func__); 35 pr_devel("==>%s()\n", __func__);
163 36
164 if (cert->unsupported_crypto) 37 if (!cert->pub->pkey_algo)
165 return -ENOPKG; 38 cert->unsupported_key = true;
166 if (cert->sig.s) 39
40 if (!sig->pkey_algo)
41 cert->unsupported_sig = true;
42
43 /* We check the hash if we can - even if we can't then verify it */
44 if (!sig->hash_algo) {
45 cert->unsupported_sig = true;
167 return 0; 46 return 0;
47 }
168 48
169 cert->sig.s = kmemdup(cert->raw_sig, cert->raw_sig_size, 49 sig->s = kmemdup(cert->raw_sig, cert->raw_sig_size, GFP_KERNEL);
170 GFP_KERNEL); 50 if (!sig->s)
171 if (!cert->sig.s)
172 return -ENOMEM; 51 return -ENOMEM;
173 52
174 cert->sig.s_size = cert->raw_sig_size; 53 sig->s_size = cert->raw_sig_size;
175 54
176 /* Allocate the hashing algorithm we're going to need and find out how 55 /* Allocate the hashing algorithm we're going to need and find out how
177 * big the hash operational data will be. 56 * big the hash operational data will be.
178 */ 57 */
179 tfm = crypto_alloc_shash(cert->sig.hash_algo, 0, 0); 58 tfm = crypto_alloc_shash(sig->hash_algo, 0, 0);
180 if (IS_ERR(tfm)) { 59 if (IS_ERR(tfm)) {
181 if (PTR_ERR(tfm) == -ENOENT) { 60 if (PTR_ERR(tfm) == -ENOENT) {
182 cert->unsupported_crypto = true; 61 cert->unsupported_sig = true;
183 return -ENOPKG; 62 return 0;
184 } 63 }
185 return PTR_ERR(tfm); 64 return PTR_ERR(tfm);
186 } 65 }
187 66
188 desc_size = crypto_shash_descsize(tfm) + sizeof(*desc); 67 desc_size = crypto_shash_descsize(tfm) + sizeof(*desc);
189 digest_size = crypto_shash_digestsize(tfm); 68 sig->digest_size = crypto_shash_digestsize(tfm);
190 69
191 /* We allocate the hash operational data storage on the end of the
192 * digest storage space.
193 */
194 ret = -ENOMEM; 70 ret = -ENOMEM;
195 digest = kzalloc(ALIGN(digest_size, __alignof__(*desc)) + desc_size, 71 sig->digest = kmalloc(sig->digest_size, GFP_KERNEL);
196 GFP_KERNEL); 72 if (!sig->digest)
197 if (!digest)
198 goto error; 73 goto error;
199 74
200 cert->sig.digest = digest; 75 desc = kzalloc(desc_size, GFP_KERNEL);
201 cert->sig.digest_size = digest_size; 76 if (!desc)
77 goto error;
202 78
203 desc = PTR_ALIGN(digest + digest_size, __alignof__(*desc));
204 desc->tfm = tfm; 79 desc->tfm = tfm;
205 desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; 80 desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
206 81
207 ret = crypto_shash_init(desc); 82 ret = crypto_shash_init(desc);
208 if (ret < 0) 83 if (ret < 0)
209 goto error; 84 goto error_2;
210 might_sleep(); 85 might_sleep();
211 ret = crypto_shash_finup(desc, cert->tbs, cert->tbs_size, digest); 86 ret = crypto_shash_finup(desc, cert->tbs, cert->tbs_size, sig->digest);
87
88error_2:
89 kfree(desc);
212error: 90error:
213 crypto_free_shash(tfm); 91 crypto_free_shash(tfm);
214 pr_devel("<==%s() = %d\n", __func__, ret); 92 pr_devel("<==%s() = %d\n", __func__, ret);
215 return ret; 93 return ret;
216} 94}
217EXPORT_SYMBOL_GPL(x509_get_sig_params);
218 95
219/* 96/*
220 * Check the signature on a certificate using the provided public key 97 * Check for self-signedness in an X.509 cert and if found, check the signature
98 * immediately if we can.
221 */ 99 */
222int x509_check_signature(const struct public_key *pub, 100int x509_check_for_self_signed(struct x509_certificate *cert)
223 struct x509_certificate *cert)
224{ 101{
225 int ret; 102 int ret = 0;
226 103
227 pr_devel("==>%s()\n", __func__); 104 pr_devel("==>%s()\n", __func__);
228 105
229 ret = x509_get_sig_params(cert); 106 if (cert->raw_subject_size != cert->raw_issuer_size ||
230 if (ret < 0) 107 memcmp(cert->raw_subject, cert->raw_issuer,
231 return ret; 108 cert->raw_issuer_size) != 0)
109 goto not_self_signed;
110
111 if (cert->sig->auth_ids[0] || cert->sig->auth_ids[1]) {
112 /* If the AKID is present it may have one or two parts. If
113 * both are supplied, both must match.
114 */
115 bool a = asymmetric_key_id_same(cert->skid, cert->sig->auth_ids[1]);
116 bool b = asymmetric_key_id_same(cert->id, cert->sig->auth_ids[0]);
117
118 if (!a && !b)
119 goto not_self_signed;
120
121 ret = -EKEYREJECTED;
122 if (((a && !b) || (b && !a)) &&
123 cert->sig->auth_ids[0] && cert->sig->auth_ids[1])
124 goto out;
125 }
232 126
233 ret = public_key_verify_signature(pub, &cert->sig); 127 ret = -EKEYREJECTED;
234 if (ret == -ENOPKG) 128 if (cert->pub->pkey_algo != cert->sig->pkey_algo)
235 cert->unsupported_crypto = true; 129 goto out;
236 pr_debug("Cert Verification: %d\n", ret);
237 return ret;
238}
239EXPORT_SYMBOL_GPL(x509_check_signature);
240 130
241/* 131 ret = public_key_verify_signature(cert->pub, cert->sig);
242 * Check the new certificate against the ones in the trust keyring. If one of 132 if (ret < 0) {
243 * those is the signing key and validates the new certificate, then mark the 133 if (ret == -ENOPKG) {
244 * new certificate as being trusted. 134 cert->unsupported_sig = true;
245 * 135 ret = 0;
246 * Return 0 if the new certificate was successfully validated, 1 if we couldn't 136 }
247 * find a matching parent certificate in the trusted list and an error if there 137 goto out;
248 * is a matching certificate but the signature check fails.
249 */
250static int x509_validate_trust(struct x509_certificate *cert,
251 struct key *trust_keyring)
252{
253 struct key *key;
254 int ret = 1;
255
256 if (!trust_keyring)
257 return -EOPNOTSUPP;
258
259 if (ca_keyid && !asymmetric_key_id_partial(cert->akid_skid, ca_keyid))
260 return -EPERM;
261
262 key = x509_request_asymmetric_key(trust_keyring,
263 cert->akid_id, cert->akid_skid,
264 false);
265 if (!IS_ERR(key)) {
266 if (!use_builtin_keys
267 || test_bit(KEY_FLAG_BUILTIN, &key->flags))
268 ret = x509_check_signature(key->payload.data[asym_crypto],
269 cert);
270 key_put(key);
271 } 138 }
139
140 pr_devel("Cert Self-signature verified");
141 cert->self_signed = true;
142
143out:
144 pr_devel("<==%s() = %d\n", __func__, ret);
272 return ret; 145 return ret;
146
147not_self_signed:
148 pr_devel("<==%s() = 0 [not]\n", __func__);
149 return 0;
273} 150}
274 151
275/* 152/*
@@ -291,34 +168,22 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
291 pr_devel("Cert Issuer: %s\n", cert->issuer); 168 pr_devel("Cert Issuer: %s\n", cert->issuer);
292 pr_devel("Cert Subject: %s\n", cert->subject); 169 pr_devel("Cert Subject: %s\n", cert->subject);
293 170
294 if (!cert->pub->pkey_algo || 171 if (cert->unsupported_key) {
295 !cert->sig.pkey_algo ||
296 !cert->sig.hash_algo) {
297 ret = -ENOPKG; 172 ret = -ENOPKG;
298 goto error_free_cert; 173 goto error_free_cert;
299 } 174 }
300 175
301 pr_devel("Cert Key Algo: %s\n", cert->pub->pkey_algo); 176 pr_devel("Cert Key Algo: %s\n", cert->pub->pkey_algo);
302 pr_devel("Cert Valid period: %lld-%lld\n", cert->valid_from, cert->valid_to); 177 pr_devel("Cert Valid period: %lld-%lld\n", cert->valid_from, cert->valid_to);
303 pr_devel("Cert Signature: %s + %s\n",
304 cert->sig.pkey_algo,
305 cert->sig.hash_algo);
306 178
307 cert->pub->id_type = "X509"; 179 cert->pub->id_type = "X509";
308 180
309 /* Check the signature on the key if it appears to be self-signed */ 181 if (cert->unsupported_sig) {
310 if ((!cert->akid_skid && !cert->akid_id) || 182 public_key_signature_free(cert->sig);
311 asymmetric_key_id_same(cert->skid, cert->akid_skid) || 183 cert->sig = NULL;
312 asymmetric_key_id_same(cert->id, cert->akid_id)) { 184 } else {
313 ret = x509_check_signature(cert->pub, cert); /* self-signed */ 185 pr_devel("Cert Signature: %s + %s\n",
314 if (ret < 0) 186 cert->sig->pkey_algo, cert->sig->hash_algo);
315 goto error_free_cert;
316 } else if (!prep->trusted) {
317 ret = x509_validate_trust(cert, get_system_trusted_keyring());
318 if (ret)
319 ret = x509_validate_trust(cert, get_ima_mok_keyring());
320 if (!ret)
321 prep->trusted = 1;
322 } 187 }
323 188
324 /* Propose a description */ 189 /* Propose a description */
@@ -353,6 +218,7 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
353 prep->payload.data[asym_subtype] = &public_key_subtype; 218 prep->payload.data[asym_subtype] = &public_key_subtype;
354 prep->payload.data[asym_key_ids] = kids; 219 prep->payload.data[asym_key_ids] = kids;
355 prep->payload.data[asym_crypto] = cert->pub; 220 prep->payload.data[asym_crypto] = cert->pub;
221 prep->payload.data[asym_auth] = cert->sig;
356 prep->description = desc; 222 prep->description = desc;
357 prep->quotalen = 100; 223 prep->quotalen = 100;
358 224
@@ -360,6 +226,7 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
360 cert->pub = NULL; 226 cert->pub = NULL;
361 cert->id = NULL; 227 cert->id = NULL;
362 cert->skid = NULL; 228 cert->skid = NULL;
229 cert->sig = NULL;
363 desc = NULL; 230 desc = NULL;
364 ret = 0; 231 ret = 0;
365 232
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index 43fe85f20d57..7097a3395b25 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -455,6 +455,7 @@ static const int crypto_msg_min[CRYPTO_NR_MSGTYPES] = {
455 [CRYPTO_MSG_NEWALG - CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg), 455 [CRYPTO_MSG_NEWALG - CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg),
456 [CRYPTO_MSG_DELALG - CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg), 456 [CRYPTO_MSG_DELALG - CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg),
457 [CRYPTO_MSG_UPDATEALG - CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg), 457 [CRYPTO_MSG_UPDATEALG - CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg),
458 [CRYPTO_MSG_GETALG - CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg),
458 [CRYPTO_MSG_DELRNG - CRYPTO_MSG_BASE] = 0, 459 [CRYPTO_MSG_DELRNG - CRYPTO_MSG_BASE] = 0,
459}; 460};
460 461