summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2016-04-06 11:14:24 -0400
committerDavid Howells <dhowells@redhat.com>2016-04-06 11:14:24 -0400
commite68503bd6836ba765dc8e0ee77ea675fedc07e41 (patch)
tree31ebec81d2f52adc89796dd063468235bfd1cc0e
parentad3043fda39db0361d9601685356db4512e914be (diff)
KEYS: Generalise system_verify_data() to provide access to internal content
Generalise system_verify_data() to provide access to internal content through a callback. This allows all the PKCS#7 stuff to be hidden inside this function and removed from the PE file parser and the PKCS#7 test key. If external content is not required, NULL should be passed as data to the function. If the callback is not required, that can be set to NULL. The function is now called verify_pkcs7_signature() to contrast with verify_pefile_signature() and the definitions of both have been moved into linux/verification.h along with the key_being_used_for enum. Signed-off-by: David Howells <dhowells@redhat.com>
-rw-r--r--arch/x86/kernel/kexec-bzimage64.c18
-rw-r--r--certs/system_keyring.c45
-rw-r--r--crypto/asymmetric_keys/Kconfig4
-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.c21
-rw-r--r--crypto/asymmetric_keys/verify_pefile.c40
-rw-r--r--crypto/asymmetric_keys/verify_pefile.h5
-rw-r--r--include/crypto/pkcs7.h3
-rw-r--r--include/crypto/public_key.h14
-rw-r--r--include/keys/asymmetric-type.h1
-rw-r--r--include/keys/system_keyring.h7
-rw-r--r--include/linux/verification.h50
-rw-r--r--include/linux/verify_pefile.h22
-rw-r--r--kernel/module_signing.c5
15 files changed, 155 insertions, 173 deletions
diff --git a/arch/x86/kernel/kexec-bzimage64.c b/arch/x86/kernel/kexec-bzimage64.c
index 2af478e3fd4e..f2356bda2b05 100644
--- a/arch/x86/kernel/kexec-bzimage64.c
+++ b/arch/x86/kernel/kexec-bzimage64.c
@@ -19,8 +19,7 @@
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20#include <linux/mm.h> 20#include <linux/mm.h>
21#include <linux/efi.h> 21#include <linux/efi.h>
22#include <linux/verify_pefile.h> 22#include <linux/verification.h>
23#include <keys/system_keyring.h>
24 23
25#include <asm/bootparam.h> 24#include <asm/bootparam.h>
26#include <asm/setup.h> 25#include <asm/setup.h>
@@ -529,18 +528,9 @@ static int bzImage64_cleanup(void *loader_data)
529#ifdef CONFIG_KEXEC_BZIMAGE_VERIFY_SIG 528#ifdef CONFIG_KEXEC_BZIMAGE_VERIFY_SIG
530static int bzImage64_verify_sig(const char *kernel, unsigned long kernel_len) 529static int bzImage64_verify_sig(const char *kernel, unsigned long kernel_len)
531{ 530{
532 bool trusted; 531 return verify_pefile_signature(kernel, kernel_len,
533 int ret; 532 NULL,
534 533 VERIFYING_KEXEC_PE_SIGNATURE);
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;
544} 534}
545#endif 535#endif
546 536
diff --git a/certs/system_keyring.c b/certs/system_keyring.c
index f4180326c2e1..a83bffedc0aa 100644
--- a/certs/system_keyring.c
+++ b/certs/system_keyring.c
@@ -108,16 +108,25 @@ late_initcall(load_system_certificate_list);
108#ifdef CONFIG_SYSTEM_DATA_VERIFICATION 108#ifdef CONFIG_SYSTEM_DATA_VERIFICATION
109 109
110/** 110/**
111 * Verify a PKCS#7-based signature on system data. 111 * verify_pkcs7_signature - Verify a PKCS#7-based signature on system data.
112 * @data: The data to be verified. 112 * @data: The data to be verified (NULL if expecting internal data).
113 * @len: Size of @data. 113 * @len: Size of @data.
114 * @raw_pkcs7: The PKCS#7 message that is the signature. 114 * @raw_pkcs7: The PKCS#7 message that is the signature.
115 * @pkcs7_len: The size of @raw_pkcs7. 115 * @pkcs7_len: The size of @raw_pkcs7.
116 * @trusted_keys: Trusted keys to use (NULL for system_trusted_keyring).
116 * @usage: The use to which the key is being put. 117 * @usage: The use to which the key is being put.
118 * @view_content: Callback to gain access to content.
119 * @ctx: Context for callback.
117 */ 120 */
118int system_verify_data(const void *data, unsigned long len, 121int verify_pkcs7_signature(const void *data, size_t len,
119 const void *raw_pkcs7, size_t pkcs7_len, 122 const void *raw_pkcs7, size_t pkcs7_len,
120 enum key_being_used_for usage) 123 struct key *trusted_keys,
124 int untrusted_error,
125 enum key_being_used_for usage,
126 int (*view_content)(void *ctx,
127 const void *data, size_t len,
128 size_t asn1hdrlen),
129 void *ctx)
121{ 130{
122 struct pkcs7_message *pkcs7; 131 struct pkcs7_message *pkcs7;
123 bool trusted; 132 bool trusted;
@@ -128,7 +137,7 @@ int system_verify_data(const void *data, unsigned long len,
128 return PTR_ERR(pkcs7); 137 return PTR_ERR(pkcs7);
129 138
130 /* The data should be detached - so we need to supply it. */ 139 /* The data should be detached - so we need to supply it. */
131 if (pkcs7_supply_detached_data(pkcs7, data, len) < 0) { 140 if (data && pkcs7_supply_detached_data(pkcs7, data, len) < 0) {
132 pr_err("PKCS#7 signature with non-detached data\n"); 141 pr_err("PKCS#7 signature with non-detached data\n");
133 ret = -EBADMSG; 142 ret = -EBADMSG;
134 goto error; 143 goto error;
@@ -138,13 +147,29 @@ int system_verify_data(const void *data, unsigned long len,
138 if (ret < 0) 147 if (ret < 0)
139 goto error; 148 goto error;
140 149
141 ret = pkcs7_validate_trust(pkcs7, system_trusted_keyring, &trusted); 150 if (!trusted_keys)
151 trusted_keys = system_trusted_keyring;
152 ret = pkcs7_validate_trust(pkcs7, trusted_keys, &trusted);
142 if (ret < 0) 153 if (ret < 0)
143 goto error; 154 goto error;
144 155
145 if (!trusted) { 156 if (!trusted && untrusted_error) {
146 pr_err("PKCS#7 signature not signed with a trusted key\n"); 157 pr_err("PKCS#7 signature not signed with a trusted key\n");
147 ret = -ENOKEY; 158 ret = untrusted_error;
159 goto error;
160 }
161
162 if (view_content) {
163 size_t asn1hdrlen;
164
165 ret = pkcs7_get_content_data(pkcs7, &data, &len, &asn1hdrlen);
166 if (ret < 0) {
167 if (ret == -ENODATA)
168 pr_devel("PKCS#7 message does not contain data\n");
169 goto error;
170 }
171
172 ret = view_content(ctx, data, len, asn1hdrlen);
148 } 173 }
149 174
150error: 175error:
@@ -152,6 +177,6 @@ error:
152 pr_devel("<==%s() = %d\n", __func__, ret); 177 pr_devel("<==%s() = %d\n", __func__, ret);
153 return ret; 178 return ret;
154} 179}
155EXPORT_SYMBOL_GPL(system_verify_data); 180EXPORT_SYMBOL_GPL(verify_pkcs7_signature);
156 181
157#endif /* CONFIG_SYSTEM_DATA_VERIFICATION */ 182#endif /* CONFIG_SYSTEM_DATA_VERIFICATION */
diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig
index 91a7e047a765..f7d2ef9789d8 100644
--- a/crypto/asymmetric_keys/Kconfig
+++ b/crypto/asymmetric_keys/Kconfig
@@ -40,8 +40,7 @@ config PKCS7_MESSAGE_PARSER
40 40
41config PKCS7_TEST_KEY 41config PKCS7_TEST_KEY
42 tristate "PKCS#7 testing key type" 42 tristate "PKCS#7 testing key type"
43 depends on PKCS7_MESSAGE_PARSER 43 depends on SYSTEM_DATA_VERIFICATION
44 select SYSTEM_TRUSTED_KEYRING
45 help 44 help
46 This option provides a type of key that can be loaded up from a 45 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 46 PKCS#7 message - provided the message is signed by a trusted key. If
@@ -54,6 +53,7 @@ config PKCS7_TEST_KEY
54config SIGNED_PE_FILE_VERIFICATION 53config SIGNED_PE_FILE_VERIFICATION
55 bool "Support for PE file signature verification" 54 bool "Support for PE file signature verification"
56 depends on PKCS7_MESSAGE_PARSER=y 55 depends on PKCS7_MESSAGE_PARSER=y
56 depends on SYSTEM_DATA_VERIFICATION
57 select ASN1 57 select ASN1
58 select OID_REGISTRY 58 select OID_REGISTRY
59 help 59 help
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..ab9bf5363ecd 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 NULL, -ENOKEY, 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 835701613125..af4cd8649117 100644
--- a/crypto/asymmetric_keys/pkcs7_parser.c
+++ b/crypto/asymmetric_keys/pkcs7_parser.c
@@ -168,24 +168,25 @@ EXPORT_SYMBOL_GPL(pkcs7_parse_message);
168 * @pkcs7: The preparsed PKCS#7 message to access 168 * @pkcs7: The preparsed PKCS#7 message to access
169 * @_data: Place to return a pointer to the data 169 * @_data: Place to return a pointer to the data
170 * @_data_len: Place to return the data length 170 * @_data_len: Place to return the data length
171 * @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
172 * 172 *
173 * 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
174 * 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
175 * 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.
176 */ 178 */
177int pkcs7_get_content_data(const struct pkcs7_message *pkcs7, 179int pkcs7_get_content_data(const struct pkcs7_message *pkcs7,
178 const void **_data, size_t *_data_len, 180 const void **_data, size_t *_data_len,
179 bool want_wrapper) 181 size_t *_headerlen)
180{ 182{
181 size_t wrapper;
182
183 if (!pkcs7->data) 183 if (!pkcs7->data)
184 return -ENODATA; 184 return -ENODATA;
185 185
186 wrapper = want_wrapper ? pkcs7->data_hdrlen : 0; 186 *_data = pkcs7->data;
187 *_data = pkcs7->data - wrapper; 187 *_data_len = pkcs7->data_len;
188 *_data_len = pkcs7->data_len + wrapper; 188 if (_headerlen)
189 *_headerlen = pkcs7->data_hdrlen;
189 return 0; 190 return 0;
190} 191}
191EXPORT_SYMBOL_GPL(pkcs7_get_content_data); 192EXPORT_SYMBOL_GPL(pkcs7_get_content_data);
diff --git a/crypto/asymmetric_keys/verify_pefile.c b/crypto/asymmetric_keys/verify_pefile.c
index 7e8c2338ae25..265351075b0e 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, -EKEYREJECTED, 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/include/crypto/pkcs7.h b/include/crypto/pkcs7.h
index 441aff9b5aa7..8323e3e57131 100644
--- a/include/crypto/pkcs7.h
+++ b/include/crypto/pkcs7.h
@@ -12,6 +12,7 @@
12#ifndef _CRYPTO_PKCS7_H 12#ifndef _CRYPTO_PKCS7_H
13#define _CRYPTO_PKCS7_H 13#define _CRYPTO_PKCS7_H
14 14
15#include <linux/verification.h>
15#include <crypto/public_key.h> 16#include <crypto/public_key.h>
16 17
17struct key; 18struct key;
@@ -26,7 +27,7 @@ extern void pkcs7_free_message(struct pkcs7_message *pkcs7);
26 27
27extern int pkcs7_get_content_data(const struct pkcs7_message *pkcs7, 28extern int pkcs7_get_content_data(const struct pkcs7_message *pkcs7,
28 const void **_data, size_t *_datalen, 29 const void **_data, size_t *_datalen,
29 bool want_wrapper); 30 size_t *_headerlen);
30 31
31/* 32/*
32 * pkcs7_trust.c 33 * pkcs7_trust.c
diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h
index 2f5de5c1a3a0..b3928e801b8c 100644
--- a/include/crypto/public_key.h
+++ b/include/crypto/public_key.h
@@ -15,20 +15,6 @@
15#define _LINUX_PUBLIC_KEY_H 15#define _LINUX_PUBLIC_KEY_H
16 16
17/* 17/*
18 * The use to which an asymmetric key is being put.
19 */
20enum key_being_used_for {
21 VERIFYING_MODULE_SIGNATURE,
22 VERIFYING_FIRMWARE_SIGNATURE,
23 VERIFYING_KEXEC_PE_SIGNATURE,
24 VERIFYING_KEY_SIGNATURE,
25 VERIFYING_KEY_SELF_SIGNATURE,
26 VERIFYING_UNSPECIFIED_SIGNATURE,
27 NR__KEY_BEING_USED_FOR
28};
29extern const char *const key_being_used_for[NR__KEY_BEING_USED_FOR];
30
31/*
32 * Cryptographic data for the public-key subtype of the asymmetric key type. 18 * Cryptographic data for the public-key subtype of the asymmetric key type.
33 * 19 *
34 * Note that this may include private part of the key as well as the public 20 * Note that this may include private part of the key as well as the public
diff --git a/include/keys/asymmetric-type.h b/include/keys/asymmetric-type.h
index 70a8775bb444..d1e23dda4363 100644
--- a/include/keys/asymmetric-type.h
+++ b/include/keys/asymmetric-type.h
@@ -15,6 +15,7 @@
15#define _KEYS_ASYMMETRIC_TYPE_H 15#define _KEYS_ASYMMETRIC_TYPE_H
16 16
17#include <linux/key-type.h> 17#include <linux/key-type.h>
18#include <linux/verification.h>
18 19
19extern struct key_type key_type_asymmetric; 20extern struct key_type key_type_asymmetric;
20 21
diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h
index 39fd38cfa8c9..b2d645ac35a0 100644
--- a/include/keys/system_keyring.h
+++ b/include/keys/system_keyring.h
@@ -15,6 +15,7 @@
15#ifdef CONFIG_SYSTEM_TRUSTED_KEYRING 15#ifdef CONFIG_SYSTEM_TRUSTED_KEYRING
16 16
17#include <linux/key.h> 17#include <linux/key.h>
18#include <linux/verification.h>
18#include <crypto/public_key.h> 19#include <crypto/public_key.h>
19 20
20extern struct key *system_trusted_keyring; 21extern struct key *system_trusted_keyring;
@@ -29,12 +30,6 @@ static inline struct key *get_system_trusted_keyring(void)
29} 30}
30#endif 31#endif
31 32
32#ifdef CONFIG_SYSTEM_DATA_VERIFICATION
33extern int system_verify_data(const void *data, unsigned long len,
34 const void *raw_pkcs7, size_t pkcs7_len,
35 enum key_being_used_for usage);
36#endif
37
38#ifdef CONFIG_IMA_MOK_KEYRING 33#ifdef CONFIG_IMA_MOK_KEYRING
39extern struct key *ima_mok_keyring; 34extern struct key *ima_mok_keyring;
40extern struct key *ima_blacklist_keyring; 35extern struct key *ima_blacklist_keyring;
diff --git a/include/linux/verification.h b/include/linux/verification.h
new file mode 100644
index 000000000000..bb0fcf941cb7
--- /dev/null
+++ b/include/linux/verification.h
@@ -0,0 +1,50 @@
1/* Signature verification
2 *
3 * Copyright (C) 2014 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#ifndef _LINUX_VERIFICATION_H
13#define _LINUX_VERIFICATION_H
14
15/*
16 * The use to which an asymmetric key is being put.
17 */
18enum key_being_used_for {
19 VERIFYING_MODULE_SIGNATURE,
20 VERIFYING_FIRMWARE_SIGNATURE,
21 VERIFYING_KEXEC_PE_SIGNATURE,
22 VERIFYING_KEY_SIGNATURE,
23 VERIFYING_KEY_SELF_SIGNATURE,
24 VERIFYING_UNSPECIFIED_SIGNATURE,
25 NR__KEY_BEING_USED_FOR
26};
27extern const char *const key_being_used_for[NR__KEY_BEING_USED_FOR];
28
29#ifdef CONFIG_SYSTEM_DATA_VERIFICATION
30
31struct key;
32
33extern int verify_pkcs7_signature(const void *data, size_t len,
34 const void *raw_pkcs7, size_t pkcs7_len,
35 struct key *trusted_keys,
36 int untrusted_error,
37 enum key_being_used_for usage,
38 int (*view_content)(void *ctx,
39 const void *data, size_t len,
40 size_t asn1hdrlen),
41 void *ctx);
42
43#ifdef CONFIG_SIGNED_PE_FILE_VERIFICATION
44extern int verify_pefile_signature(const void *pebuf, unsigned pelen,
45 struct key *trusted_keys,
46 enum key_being_used_for usage);
47#endif
48
49#endif /* CONFIG_SYSTEM_DATA_VERIFICATION */
50#endif /* _LINUX_VERIFY_PEFILE_H */
diff --git a/include/linux/verify_pefile.h b/include/linux/verify_pefile.h
deleted file mode 100644
index da2049b5161c..000000000000
--- a/include/linux/verify_pefile.h
+++ /dev/null
@@ -1,22 +0,0 @@
1/* Signed PE file verification
2 *
3 * Copyright (C) 2014 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#ifndef _LINUX_VERIFY_PEFILE_H
13#define _LINUX_VERIFY_PEFILE_H
14
15#include <crypto/public_key.h>
16
17extern int verify_pefile_signature(const void *pebuf, unsigned pelen,
18 struct key *trusted_keyring,
19 enum key_being_used_for usage,
20 bool *_trusted);
21
22#endif /* _LINUX_VERIFY_PEFILE_H */
diff --git a/kernel/module_signing.c b/kernel/module_signing.c
index 64b9dead4a07..593aace88a02 100644
--- a/kernel/module_signing.c
+++ b/kernel/module_signing.c
@@ -80,6 +80,7 @@ int mod_verify_sig(const void *mod, unsigned long *_modlen)
80 return -EBADMSG; 80 return -EBADMSG;
81 } 81 }
82 82
83 return system_verify_data(mod, modlen, mod + modlen, sig_len, 83 return verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len,
84 VERIFYING_MODULE_SIGNATURE); 84 NULL, -ENOKEY, VERIFYING_MODULE_SIGNATURE,
85 NULL, NULL);
85} 86}