This source file includes following definitions.
- pkcs7_digest
- pkcs7_get_digest
- pkcs7_find_key
- pkcs7_verify_sig_chain
- pkcs7_verify_one
- pkcs7_verify
- pkcs7_supply_detached_data
1
2
3
4
5
6
7
8 #define pr_fmt(fmt) "PKCS7: "fmt
9 #include <linux/kernel.h>
10 #include <linux/export.h>
11 #include <linux/slab.h>
12 #include <linux/err.h>
13 #include <linux/asn1.h>
14 #include <crypto/hash.h>
15 #include <crypto/hash_info.h>
16 #include <crypto/public_key.h>
17 #include "pkcs7_parser.h"
18
19
20
21
22 static int pkcs7_digest(struct pkcs7_message *pkcs7,
23 struct pkcs7_signed_info *sinfo)
24 {
25 struct public_key_signature *sig = sinfo->sig;
26 struct crypto_shash *tfm;
27 struct shash_desc *desc;
28 size_t desc_size;
29 int ret;
30
31 kenter(",%u,%s", sinfo->index, sinfo->sig->hash_algo);
32
33
34 if (sig->digest)
35 return 0;
36
37 if (!sinfo->sig->hash_algo)
38 return -ENOPKG;
39
40
41
42
43 tfm = crypto_alloc_shash(sinfo->sig->hash_algo, 0, 0);
44 if (IS_ERR(tfm))
45 return (PTR_ERR(tfm) == -ENOENT) ? -ENOPKG : PTR_ERR(tfm);
46
47 desc_size = crypto_shash_descsize(tfm) + sizeof(*desc);
48 sig->digest_size = crypto_shash_digestsize(tfm);
49
50 ret = -ENOMEM;
51 sig->digest = kmalloc(sig->digest_size, GFP_KERNEL);
52 if (!sig->digest)
53 goto error_no_desc;
54
55 desc = kzalloc(desc_size, GFP_KERNEL);
56 if (!desc)
57 goto error_no_desc;
58
59 desc->tfm = tfm;
60
61
62 ret = crypto_shash_digest(desc, pkcs7->data, pkcs7->data_len,
63 sig->digest);
64 if (ret < 0)
65 goto error;
66 pr_devel("MsgDigest = [%*ph]\n", 8, sig->digest);
67
68
69
70
71
72 if (sinfo->authattrs) {
73 u8 tag;
74
75 if (!sinfo->msgdigest) {
76 pr_warn("Sig %u: No messageDigest\n", sinfo->index);
77 ret = -EKEYREJECTED;
78 goto error;
79 }
80
81 if (sinfo->msgdigest_len != sig->digest_size) {
82 pr_debug("Sig %u: Invalid digest size (%u)\n",
83 sinfo->index, sinfo->msgdigest_len);
84 ret = -EBADMSG;
85 goto error;
86 }
87
88 if (memcmp(sig->digest, sinfo->msgdigest,
89 sinfo->msgdigest_len) != 0) {
90 pr_debug("Sig %u: Message digest doesn't match\n",
91 sinfo->index);
92 ret = -EKEYREJECTED;
93 goto error;
94 }
95
96
97
98
99
100
101 memset(sig->digest, 0, sig->digest_size);
102
103 ret = crypto_shash_init(desc);
104 if (ret < 0)
105 goto error;
106 tag = ASN1_CONS_BIT | ASN1_SET;
107 ret = crypto_shash_update(desc, &tag, 1);
108 if (ret < 0)
109 goto error;
110 ret = crypto_shash_finup(desc, sinfo->authattrs,
111 sinfo->authattrs_len, sig->digest);
112 if (ret < 0)
113 goto error;
114 pr_devel("AADigest = [%*ph]\n", 8, sig->digest);
115 }
116
117 error:
118 kfree(desc);
119 error_no_desc:
120 crypto_free_shash(tfm);
121 kleave(" = %d", ret);
122 return ret;
123 }
124
125 int pkcs7_get_digest(struct pkcs7_message *pkcs7, const u8 **buf, u32 *len,
126 enum hash_algo *hash_algo)
127 {
128 struct pkcs7_signed_info *sinfo = pkcs7->signed_infos;
129 int i, ret;
130
131
132
133
134 if (sinfo == NULL || sinfo->next != NULL)
135 return -EBADMSG;
136
137 ret = pkcs7_digest(pkcs7, sinfo);
138 if (ret)
139 return ret;
140
141 *buf = sinfo->sig->digest;
142 *len = sinfo->sig->digest_size;
143
144 for (i = 0; i < HASH_ALGO__LAST; i++)
145 if (!strcmp(hash_algo_name[i], sinfo->sig->hash_algo)) {
146 *hash_algo = i;
147 break;
148 }
149
150 return 0;
151 }
152
153
154
155
156
157
158
159 static int pkcs7_find_key(struct pkcs7_message *pkcs7,
160 struct pkcs7_signed_info *sinfo)
161 {
162 struct x509_certificate *x509;
163 unsigned certix = 1;
164
165 kenter("%u", sinfo->index);
166
167 for (x509 = pkcs7->certs; x509; x509 = x509->next, certix++) {
168
169
170
171
172
173 if (!asymmetric_key_id_same(x509->id, sinfo->sig->auth_ids[0]))
174 continue;
175 pr_devel("Sig %u: Found cert serial match X.509[%u]\n",
176 sinfo->index, certix);
177
178 if (strcmp(x509->pub->pkey_algo, sinfo->sig->pkey_algo) != 0) {
179 pr_warn("Sig %u: X.509 algo and PKCS#7 sig algo don't match\n",
180 sinfo->index);
181 continue;
182 }
183
184 sinfo->signer = x509;
185 return 0;
186 }
187
188
189
190
191 pr_debug("Sig %u: Issuing X.509 cert not found (#%*phN)\n",
192 sinfo->index,
193 sinfo->sig->auth_ids[0]->len, sinfo->sig->auth_ids[0]->data);
194 return 0;
195 }
196
197
198
199
200 static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
201 struct pkcs7_signed_info *sinfo)
202 {
203 struct public_key_signature *sig;
204 struct x509_certificate *x509 = sinfo->signer, *p;
205 struct asymmetric_key_id *auth;
206 int ret;
207
208 kenter("");
209
210 for (p = pkcs7->certs; p; p = p->next)
211 p->seen = false;
212
213 for (;;) {
214 pr_debug("verify %s: %*phN\n",
215 x509->subject,
216 x509->raw_serial_size, x509->raw_serial);
217 x509->seen = true;
218
219 if (x509->blacklisted) {
220
221
222
223 sinfo->blacklisted = true;
224 for (p = sinfo->signer; p != x509; p = p->signer)
225 p->blacklisted = true;
226 pr_debug("- blacklisted\n");
227 return 0;
228 }
229
230 if (x509->unsupported_key)
231 goto unsupported_crypto_in_x509;
232
233 pr_debug("- issuer %s\n", x509->issuer);
234 sig = x509->sig;
235 if (sig->auth_ids[0])
236 pr_debug("- authkeyid.id %*phN\n",
237 sig->auth_ids[0]->len, sig->auth_ids[0]->data);
238 if (sig->auth_ids[1])
239 pr_debug("- authkeyid.skid %*phN\n",
240 sig->auth_ids[1]->len, sig->auth_ids[1]->data);
241
242 if (x509->self_signed) {
243
244
245
246
247
248 if (x509->unsupported_sig)
249 goto unsupported_crypto_in_x509;
250 x509->signer = x509;
251 pr_debug("- self-signed\n");
252 return 0;
253 }
254
255
256
257
258 auth = sig->auth_ids[0];
259 if (auth) {
260 pr_debug("- want %*phN\n", auth->len, auth->data);
261 for (p = pkcs7->certs; p; p = p->next) {
262 pr_debug("- cmp [%u] %*phN\n",
263 p->index, p->id->len, p->id->data);
264 if (asymmetric_key_id_same(p->id, auth))
265 goto found_issuer_check_skid;
266 }
267 } else if (sig->auth_ids[1]) {
268 auth = sig->auth_ids[1];
269 pr_debug("- want %*phN\n", auth->len, auth->data);
270 for (p = pkcs7->certs; p; p = p->next) {
271 if (!p->skid)
272 continue;
273 pr_debug("- cmp [%u] %*phN\n",
274 p->index, p->skid->len, p->skid->data);
275 if (asymmetric_key_id_same(p->skid, auth))
276 goto found_issuer;
277 }
278 }
279
280
281 pr_debug("- top\n");
282 return 0;
283
284 found_issuer_check_skid:
285
286
287
288 if (sig->auth_ids[1] &&
289 !asymmetric_key_id_same(p->skid, sig->auth_ids[1])) {
290 pr_warn("Sig %u: X.509 chain contains auth-skid nonmatch (%u->%u)\n",
291 sinfo->index, x509->index, p->index);
292 return -EKEYREJECTED;
293 }
294 found_issuer:
295 pr_debug("- subject %s\n", p->subject);
296 if (p->seen) {
297 pr_warn("Sig %u: X.509 chain contains loop\n",
298 sinfo->index);
299 return 0;
300 }
301 ret = public_key_verify_signature(p->pub, x509->sig);
302 if (ret < 0)
303 return ret;
304 x509->signer = p;
305 if (x509 == p) {
306 pr_debug("- self-signed\n");
307 return 0;
308 }
309 x509 = p;
310 might_sleep();
311 }
312
313 unsupported_crypto_in_x509:
314
315
316
317
318
319
320 return 0;
321 }
322
323
324
325
326 static int pkcs7_verify_one(struct pkcs7_message *pkcs7,
327 struct pkcs7_signed_info *sinfo)
328 {
329 int ret;
330
331 kenter(",%u", sinfo->index);
332
333
334
335
336 ret = pkcs7_digest(pkcs7, sinfo);
337 if (ret < 0)
338 return ret;
339
340
341 ret = pkcs7_find_key(pkcs7, sinfo);
342 if (ret < 0)
343 return ret;
344
345 if (!sinfo->signer)
346 return 0;
347
348 pr_devel("Using X.509[%u] for sig %u\n",
349 sinfo->signer->index, sinfo->index);
350
351
352
353
354
355 if (test_bit(sinfo_has_signing_time, &sinfo->aa_set)) {
356 if (sinfo->signing_time < sinfo->signer->valid_from ||
357 sinfo->signing_time > sinfo->signer->valid_to) {
358 pr_warn("Message signed outside of X.509 validity window\n");
359 return -EKEYREJECTED;
360 }
361 }
362
363
364 ret = public_key_verify_signature(sinfo->signer->pub, sinfo->sig);
365 if (ret < 0)
366 return ret;
367
368 pr_devel("Verified signature %u\n", sinfo->index);
369
370
371 return pkcs7_verify_sig_chain(pkcs7, sinfo);
372 }
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404 int pkcs7_verify(struct pkcs7_message *pkcs7,
405 enum key_being_used_for usage)
406 {
407 struct pkcs7_signed_info *sinfo;
408 int actual_ret = -ENOPKG;
409 int ret;
410
411 kenter("");
412
413 switch (usage) {
414 case VERIFYING_MODULE_SIGNATURE:
415 if (pkcs7->data_type != OID_data) {
416 pr_warn("Invalid module sig (not pkcs7-data)\n");
417 return -EKEYREJECTED;
418 }
419 if (pkcs7->have_authattrs) {
420 pr_warn("Invalid module sig (has authattrs)\n");
421 return -EKEYREJECTED;
422 }
423 break;
424 case VERIFYING_FIRMWARE_SIGNATURE:
425 if (pkcs7->data_type != OID_data) {
426 pr_warn("Invalid firmware sig (not pkcs7-data)\n");
427 return -EKEYREJECTED;
428 }
429 if (!pkcs7->have_authattrs) {
430 pr_warn("Invalid firmware sig (missing authattrs)\n");
431 return -EKEYREJECTED;
432 }
433 break;
434 case VERIFYING_KEXEC_PE_SIGNATURE:
435 if (pkcs7->data_type != OID_msIndirectData) {
436 pr_warn("Invalid kexec sig (not Authenticode)\n");
437 return -EKEYREJECTED;
438 }
439
440 break;
441 case VERIFYING_UNSPECIFIED_SIGNATURE:
442 if (pkcs7->data_type != OID_data) {
443 pr_warn("Invalid unspecified sig (not pkcs7-data)\n");
444 return -EKEYREJECTED;
445 }
446 break;
447 default:
448 return -EINVAL;
449 }
450
451 for (sinfo = pkcs7->signed_infos; sinfo; sinfo = sinfo->next) {
452 ret = pkcs7_verify_one(pkcs7, sinfo);
453 if (sinfo->blacklisted) {
454 if (actual_ret == -ENOPKG)
455 actual_ret = -EKEYREJECTED;
456 continue;
457 }
458 if (ret < 0) {
459 if (ret == -ENOPKG) {
460 sinfo->unsupported_crypto = true;
461 continue;
462 }
463 kleave(" = %d", ret);
464 return ret;
465 }
466 actual_ret = 0;
467 }
468
469 kleave(" = %d", actual_ret);
470 return actual_ret;
471 }
472 EXPORT_SYMBOL_GPL(pkcs7_verify);
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487 int pkcs7_supply_detached_data(struct pkcs7_message *pkcs7,
488 const void *data, size_t datalen)
489 {
490 if (pkcs7->data) {
491 pr_debug("Data already supplied\n");
492 return -EINVAL;
493 }
494 pkcs7->data = data;
495 pkcs7->data_len = datalen;
496 return 0;
497 }