11
11
12
12
#include <linux/kernel.h>
13
13
#include <linux/err.h>
14
- #include <crypto/public_key.h>
15
- #include <crypto/hash.h>
16
- #include <keys/asymmetric-type.h>
17
14
#include <keys/system_keyring.h>
15
+ #include <crypto/public_key.h>
16
+ #include <crypto/pkcs7.h>
18
17
#include "module-internal.h"
19
18
20
19
/*
28
27
* - Information block
29
28
*/
30
29
struct module_signature {
31
- u8 algo ; /* Public-key crypto algorithm [enum pkey_algo ] */
32
- u8 hash ; /* Digest algorithm [enum hash_algo ] */
33
- u8 id_type ; /* Key identifier type [enum pkey_id_type ] */
34
- u8 signer_len ; /* Length of signer's name */
35
- u8 key_id_len ; /* Length of key identifier */
30
+ u8 algo ; /* Public-key crypto algorithm [0 ] */
31
+ u8 hash ; /* Digest algorithm [0 ] */
32
+ u8 id_type ; /* Key identifier type [PKEY_ID_PKCS7 ] */
33
+ u8 signer_len ; /* Length of signer's name [0] */
34
+ u8 key_id_len ; /* Length of key identifier [0] */
36
35
u8 __pad [3 ];
37
36
__be32 sig_len ; /* Length of signature data */
38
37
};
39
38
40
39
/*
41
- * Digest the module contents .
40
+ * Verify a PKCS#7-based signature on a module .
42
41
*/
43
- static struct public_key_signature * mod_make_digest (enum hash_algo hash ,
44
- const void * mod ,
45
- unsigned long modlen )
42
+ static int mod_verify_pkcs7 (const void * mod , unsigned long modlen ,
43
+ const void * raw_pkcs7 , size_t pkcs7_len )
46
44
{
47
- struct public_key_signature * pks ;
48
- struct crypto_shash * tfm ;
49
- struct shash_desc * desc ;
50
- size_t digest_size , desc_size ;
45
+ struct pkcs7_message * pkcs7 ;
46
+ bool trusted ;
51
47
int ret ;
52
48
53
- pr_devel ("==>%s()\n" , __func__ );
54
-
55
- /* Allocate the hashing algorithm we're going to need and find out how
56
- * big the hash operational data will be.
57
- */
58
- tfm = crypto_alloc_shash (hash_algo_name [hash ], 0 , 0 );
59
- if (IS_ERR (tfm ))
60
- return (PTR_ERR (tfm ) == - ENOENT ) ? ERR_PTR (- ENOPKG ) : ERR_CAST (tfm );
61
-
62
- desc_size = crypto_shash_descsize (tfm ) + sizeof (* desc );
63
- digest_size = crypto_shash_digestsize (tfm );
64
-
65
- /* We allocate the hash operational data storage on the end of our
66
- * context data and the digest output buffer on the end of that.
67
- */
68
- ret = - ENOMEM ;
69
- pks = kzalloc (digest_size + sizeof (* pks ) + desc_size , GFP_KERNEL );
70
- if (!pks )
71
- goto error_no_pks ;
72
-
73
- pks -> pkey_hash_algo = hash ;
74
- pks -> digest = (u8 * )pks + sizeof (* pks ) + desc_size ;
75
- pks -> digest_size = digest_size ;
76
-
77
- desc = (void * )pks + sizeof (* pks );
78
- desc -> tfm = tfm ;
79
- desc -> flags = CRYPTO_TFM_REQ_MAY_SLEEP ;
80
-
81
- ret = crypto_shash_init (desc );
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 );
82
61
if (ret < 0 )
83
62
goto error ;
84
63
85
- ret = crypto_shash_finup ( desc , mod , modlen , pks -> digest );
64
+ ret = pkcs7_validate_trust ( pkcs7 , system_trusted_keyring , & trusted );
86
65
if (ret < 0 )
87
66
goto error ;
88
67
89
- crypto_free_shash (tfm );
90
- pr_devel ("<==%s() = ok\n" , __func__ );
91
- return pks ;
68
+ if (!trusted ) {
69
+ pr_err ("PKCS#7 signature not signed with a trusted key\n" );
70
+ ret = - ENOKEY ;
71
+ }
92
72
93
73
error :
94
- kfree (pks );
95
- error_no_pks :
96
- crypto_free_shash (tfm );
74
+ pkcs7_free_message (pkcs7 );
97
75
pr_devel ("<==%s() = %d\n" , __func__ , ret );
98
- return ERR_PTR (ret );
99
- }
100
-
101
- /*
102
- * Extract an MPI array from the signature data. This represents the actual
103
- * signature. Each raw MPI is prefaced by a BE 2-byte value indicating the
104
- * size of the MPI in bytes.
105
- *
106
- * RSA signatures only have one MPI, so currently we only read one.
107
- */
108
- static int mod_extract_mpi_array (struct public_key_signature * pks ,
109
- const void * data , size_t len )
110
- {
111
- size_t nbytes ;
112
- MPI mpi ;
113
-
114
- if (len < 3 )
115
- return - EBADMSG ;
116
- nbytes = ((const u8 * )data )[0 ] << 8 | ((const u8 * )data )[1 ];
117
- data += 2 ;
118
- len -= 2 ;
119
- if (len != nbytes )
120
- return - EBADMSG ;
121
-
122
- mpi = mpi_read_raw_data (data , nbytes );
123
- if (!mpi )
124
- return - ENOMEM ;
125
- pks -> mpi [0 ] = mpi ;
126
- pks -> nr_mpi = 1 ;
127
- return 0 ;
128
- }
129
-
130
- /*
131
- * Request an asymmetric key.
132
- */
133
- static struct key * request_asymmetric_key (const char * signer , size_t signer_len ,
134
- const u8 * key_id , size_t key_id_len )
135
- {
136
- key_ref_t key ;
137
- size_t i ;
138
- char * id , * q ;
139
-
140
- pr_devel ("==>%s(,%zu,,%zu)\n" , __func__ , signer_len , key_id_len );
141
-
142
- /* Construct an identifier. */
143
- id = kmalloc (signer_len + 2 + key_id_len * 2 + 1 , GFP_KERNEL );
144
- if (!id )
145
- return ERR_PTR (- ENOKEY );
146
-
147
- memcpy (id , signer , signer_len );
148
-
149
- q = id + signer_len ;
150
- * q ++ = ':' ;
151
- * q ++ = ' ' ;
152
- for (i = 0 ; i < key_id_len ; i ++ ) {
153
- * q ++ = hex_asc [* key_id >> 4 ];
154
- * q ++ = hex_asc [* key_id ++ & 0x0f ];
155
- }
156
-
157
- * q = 0 ;
158
-
159
- pr_debug ("Look up: \"%s\"\n" , id );
160
-
161
- key = keyring_search (make_key_ref (system_trusted_keyring , 1 ),
162
- & key_type_asymmetric , id );
163
- if (IS_ERR (key ))
164
- pr_warn ("Request for unknown module key '%s' err %ld\n" ,
165
- id , PTR_ERR (key ));
166
- kfree (id );
167
-
168
- if (IS_ERR (key )) {
169
- switch (PTR_ERR (key )) {
170
- /* Hide some search errors */
171
- case - EACCES :
172
- case - ENOTDIR :
173
- case - EAGAIN :
174
- return ERR_PTR (- ENOKEY );
175
- default :
176
- return ERR_CAST (key );
177
- }
178
- }
179
-
180
- pr_devel ("<==%s() = 0 [%x]\n" , __func__ , key_serial (key_ref_to_ptr (key )));
181
- return key_ref_to_ptr (key );
76
+ return ret ;
182
77
}
183
78
184
79
/*
185
80
* Verify the signature on a module.
186
81
*/
187
82
int mod_verify_sig (const void * mod , unsigned long * _modlen )
188
83
{
189
- struct public_key_signature * pks ;
190
84
struct module_signature ms ;
191
- struct key * key ;
192
- const void * sig ;
193
85
size_t modlen = * _modlen , sig_len ;
194
- int ret ;
195
86
196
87
pr_devel ("==>%s(,%zu)\n" , __func__ , modlen );
197
88
@@ -205,46 +96,23 @@ int mod_verify_sig(const void *mod, unsigned long *_modlen)
205
96
if (sig_len >= modlen )
206
97
return - EBADMSG ;
207
98
modlen -= sig_len ;
208
- if ((size_t )ms .signer_len + ms .key_id_len >= modlen )
209
- return - EBADMSG ;
210
- modlen -= (size_t )ms .signer_len + ms .key_id_len ;
211
-
212
99
* _modlen = modlen ;
213
- sig = mod + modlen ;
214
-
215
- /* For the moment, only support RSA and X.509 identifiers */
216
- if (ms .algo != PKEY_ALGO_RSA ||
217
- ms .id_type != PKEY_ID_X509 )
218
- return - ENOPKG ;
219
100
220
- if (ms .hash >= PKEY_HASH__LAST ||
221
- ! hash_algo_name [ ms . hash ])
101
+ if (ms .id_type != PKEY_ID_PKCS7 ) {
102
+ pr_err ( "Module is not signed with expected PKCS#7 message\n" );
222
103
return - ENOPKG ;
223
-
224
- key = request_asymmetric_key (sig , ms .signer_len ,
225
- sig + ms .signer_len , ms .key_id_len );
226
- if (IS_ERR (key ))
227
- return PTR_ERR (key );
228
-
229
- pks = mod_make_digest (ms .hash , mod , modlen );
230
- if (IS_ERR (pks )) {
231
- ret = PTR_ERR (pks );
232
- goto error_put_key ;
233
104
}
234
105
235
- ret = mod_extract_mpi_array (pks , sig + ms .signer_len + ms .key_id_len ,
236
- sig_len );
237
- if (ret < 0 )
238
- goto error_free_pks ;
239
-
240
- ret = verify_signature (key , pks );
241
- pr_devel ("verify_signature() = %d\n" , ret );
106
+ if (ms .algo != 0 ||
107
+ ms .hash != 0 ||
108
+ ms .signer_len != 0 ||
109
+ ms .key_id_len != 0 ||
110
+ ms .__pad [0 ] != 0 ||
111
+ ms .__pad [1 ] != 0 ||
112
+ ms .__pad [2 ] != 0 ) {
113
+ pr_err ("PKCS#7 signature info has unexpected non-zero params\n" );
114
+ return - EBADMSG ;
115
+ }
242
116
243
- error_free_pks :
244
- mpi_free (pks -> rsa .s );
245
- kfree (pks );
246
- error_put_key :
247
- key_put (key );
248
- pr_devel ("<==%s() = %d\n" , __func__ , ret );
249
- return ret ;
117
+ return mod_verify_pkcs7 (mod , modlen , mod + modlen , sig_len );
250
118
}
0 commit comments