Skip to content

Commit 091f6e2

Browse files
committed
MODSIGN: Extract the blob PKCS#7 signature verifier from module signing
Extract the function that drives the PKCS#7 signature verification given a data blob and a PKCS#7 blob out from the module signing code and lump it with the system keyring code as it's generic. This makes it independent of module config options and opens it to use by the firmware loader. Signed-off-by: David Howells <dhowells@redhat.com> Cc: Luis R. Rodriguez <mcgrof@suse.com> Cc: Rusty Russell <rusty@rustcorp.com.au> Cc: Ming Lei <ming.lei@canonical.com> Cc: Seth Forshee <seth.forshee@canonical.com> Cc: Kyle McMartin <kyle@kernel.org>
1 parent 1c39449 commit 091f6e2

File tree

4 files changed

+75
-53
lines changed

4 files changed

+75
-53
lines changed

include/keys/system_keyring.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,9 @@ static inline struct key *get_system_trusted_keyring(void)
2828
}
2929
#endif
3030

31+
#ifdef CONFIG_SYSTEM_DATA_VERIFICATION
32+
extern int system_verify_data(const void *data, unsigned long len,
33+
const void *raw_pkcs7, size_t pkcs7_len);
34+
#endif
35+
3136
#endif /* _KEYS_SYSTEM_KEYRING_H */

init/Kconfig

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1752,6 +1752,24 @@ config SYSTEM_TRUSTED_KEYRING
17521752

17531753
Keys in this keyring are used by module signature checking.
17541754

1755+
config SYSTEM_DATA_VERIFICATION
1756+
def_bool n
1757+
select SYSTEM_TRUSTED_KEYRING
1758+
select KEYS
1759+
select CRYPTO
1760+
select ASYMMETRIC_KEY_TYPE
1761+
select ASYMMETRIC_PUBLIC_KEY_SUBTYPE
1762+
select PUBLIC_KEY_ALGO_RSA
1763+
select ASN1
1764+
select OID_REGISTRY
1765+
select X509_CERTIFICATE_PARSER
1766+
select PKCS7_MESSAGE_PARSER
1767+
help
1768+
Provide PKCS#7 message verification using the contents of the system
1769+
trusted keyring to provide public keys. This then can be used for
1770+
module verification, kexec image verification and firmware blob
1771+
verification.
1772+
17551773
config PROFILING
17561774
bool "Profiling support"
17571775
help
@@ -1860,16 +1878,7 @@ config MODULE_SRCVERSION_ALL
18601878
config MODULE_SIG
18611879
bool "Module signature verification"
18621880
depends on MODULES
1863-
select SYSTEM_TRUSTED_KEYRING
1864-
select KEYS
1865-
select CRYPTO
1866-
select ASYMMETRIC_KEY_TYPE
1867-
select ASYMMETRIC_PUBLIC_KEY_SUBTYPE
1868-
select PUBLIC_KEY_ALGO_RSA
1869-
select ASN1
1870-
select OID_REGISTRY
1871-
select X509_CERTIFICATE_PARSER
1872-
select PKCS7_MESSAGE_PARSER
1881+
select SYSTEM_DATA_VERIFICATION
18731882
help
18741883
Check modules for valid signatures upon load: the signature
18751884
is simply appended to the module. For more information see

kernel/module_signing.c

Lines changed: 1 addition & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,8 @@
1010
*/
1111

1212
#include <linux/kernel.h>
13-
#include <linux/err.h>
1413
#include <keys/system_keyring.h>
1514
#include <crypto/public_key.h>
16-
#include <crypto/pkcs7.h>
1715
#include "module-internal.h"
1816

1917
/*
@@ -36,46 +34,6 @@ struct module_signature {
3634
__be32 sig_len; /* Length of signature data */
3735
};
3836

39-
/*
40-
* Verify a PKCS#7-based signature on a module.
41-
*/
42-
static int mod_verify_pkcs7(const void *mod, unsigned long modlen,
43-
const void *raw_pkcs7, size_t pkcs7_len)
44-
{
45-
struct pkcs7_message *pkcs7;
46-
bool trusted;
47-
int ret;
48-
49-
pkcs7 = pkcs7_parse_message(raw_pkcs7, pkcs7_len);
50-
if (IS_ERR(pkcs7))
51-
return PTR_ERR(pkcs7);
52-
53-
/* The data should be detached - so we need to supply it. */
54-
if (pkcs7_supply_detached_data(pkcs7, mod, modlen) < 0) {
55-
pr_err("PKCS#7 signature with non-detached data\n");
56-
ret = -EBADMSG;
57-
goto error;
58-
}
59-
60-
ret = pkcs7_verify(pkcs7);
61-
if (ret < 0)
62-
goto error;
63-
64-
ret = pkcs7_validate_trust(pkcs7, system_trusted_keyring, &trusted);
65-
if (ret < 0)
66-
goto error;
67-
68-
if (!trusted) {
69-
pr_err("PKCS#7 signature not signed with a trusted key\n");
70-
ret = -ENOKEY;
71-
}
72-
73-
error:
74-
pkcs7_free_message(pkcs7);
75-
pr_devel("<==%s() = %d\n", __func__, ret);
76-
return ret;
77-
}
78-
7937
/*
8038
* Verify the signature on a module.
8139
*/
@@ -114,5 +72,5 @@ int mod_verify_sig(const void *mod, unsigned long *_modlen)
11472
return -EBADMSG;
11573
}
11674

117-
return mod_verify_pkcs7(mod, modlen, mod + modlen, sig_len);
75+
return system_verify_data(mod, modlen, mod + modlen, sig_len);
11876
}

kernel/system_keyring.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <linux/err.h>
1717
#include <keys/asymmetric-type.h>
1818
#include <keys/system_keyring.h>
19+
#include <crypto/pkcs7.h>
1920

2021
struct key *system_trusted_keyring;
2122
EXPORT_SYMBOL_GPL(system_trusted_keyring);
@@ -103,3 +104,52 @@ static __init int load_system_certificate_list(void)
103104
return 0;
104105
}
105106
late_initcall(load_system_certificate_list);
107+
108+
#ifdef CONFIG_SYSTEM_DATA_VERIFICATION
109+
110+
/**
111+
* Verify a PKCS#7-based signature on system data.
112+
* @data: The data to be verified.
113+
* @len: Size of @data.
114+
* @raw_pkcs7: The PKCS#7 message that is the signature.
115+
* @pkcs7_len: The size of @raw_pkcs7.
116+
*/
117+
int system_verify_data(const void *data, unsigned long len,
118+
const void *raw_pkcs7, size_t pkcs7_len)
119+
{
120+
struct pkcs7_message *pkcs7;
121+
bool trusted;
122+
int ret;
123+
124+
pkcs7 = pkcs7_parse_message(raw_pkcs7, pkcs7_len);
125+
if (IS_ERR(pkcs7))
126+
return PTR_ERR(pkcs7);
127+
128+
/* The data should be detached - so we need to supply it. */
129+
if (pkcs7_supply_detached_data(pkcs7, data, len) < 0) {
130+
pr_err("PKCS#7 signature with non-detached data\n");
131+
ret = -EBADMSG;
132+
goto error;
133+
}
134+
135+
ret = pkcs7_verify(pkcs7);
136+
if (ret < 0)
137+
goto error;
138+
139+
ret = pkcs7_validate_trust(pkcs7, system_trusted_keyring, &trusted);
140+
if (ret < 0)
141+
goto error;
142+
143+
if (!trusted) {
144+
pr_err("PKCS#7 signature not signed with a trusted key\n");
145+
ret = -ENOKEY;
146+
}
147+
148+
error:
149+
pkcs7_free_message(pkcs7);
150+
pr_devel("<==%s() = %d\n", __func__, ret);
151+
return ret;
152+
}
153+
EXPORT_SYMBOL_GPL(system_verify_data);
154+
155+
#endif /* CONFIG_SYSTEM_DATA_VERIFICATION */

0 commit comments

Comments
 (0)