blob: b832f013566ff7c5a9f9abf4d03a3f029d564861 [file] [log] [blame]
AKASHI Takahiro063499e2020-07-21 19:35:19 +09001// SPDX-License-Identifier: GPL-2.0-or-later
2/* Verify the signature on a PKCS#7 message.
3 *
4 * Imported from crypto/asymmetric_keys/pkcs7_verify.c of linux 5.7
5 * with modification marked as __UBOOT__.
6 *
7 * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
8 * Written by David Howells (dhowells@redhat.com)
9 */
10
11#define pr_fmt(fmt) "PKCS7: "fmt
12#ifdef __UBOOT__
AKASHI Takahiro05329fa2020-07-21 19:35:20 +090013#include <image.h>
AKASHI Takahiro063499e2020-07-21 19:35:19 +090014#include <string.h>
15#include <linux/bitops.h>
16#include <linux/compat.h>
17#include <linux/asn1.h>
Alexandru Gagniuc0bcb28d2021-02-19 12:45:10 -060018#include <u-boot/hash-checksum.h>
AKASHI Takahiro063499e2020-07-21 19:35:19 +090019#include <crypto/public_key.h>
20#include <crypto/pkcs7_parser.h>
21#else
22#include <linux/kernel.h>
23#include <linux/export.h>
24#include <linux/slab.h>
25#include <linux/err.h>
26#include <linux/asn1.h>
27#include <crypto/hash.h>
28#include <crypto/hash_info.h>
29#include <crypto/public_key.h>
30#include "pkcs7_parser.h"
31#endif
32
33/*
AKASHI Takahiro05329fa2020-07-21 19:35:20 +090034 * pkcs7_digest - Digest the relevant parts of the PKCS#7 data
35 * @pkcs7: PKCS7 Signed Data
36 * @sinfo: PKCS7 Signed Info
37 *
38 * Digest the relevant parts of the PKCS#7 data, @pkcs7, using signature
39 * information in @sinfo. But if there are authentication attributes,
40 * i.e. signed image case, the digest must be calculated against
41 * the authentication attributes.
42 *
43 * Return: 0 - on success, non-zero error code - otherwise
AKASHI Takahiro063499e2020-07-21 19:35:19 +090044 */
45#ifdef __UBOOT__
46static int pkcs7_digest(struct pkcs7_message *pkcs7,
47 struct pkcs7_signed_info *sinfo)
48{
AKASHI Takahiro05329fa2020-07-21 19:35:20 +090049 struct public_key_signature *sig = sinfo->sig;
50 struct image_region regions[2];
51 int ret = 0;
52
Sughosh Ganu4366a242020-12-30 19:27:01 +053053 /*
54 * [RFC2315 9.3]
55 * If the authenticated attributes are present,
56 * the message-digest is calculated on the
57 * attributes present in the
58 * authenticatedAttributes field and not just
59 * the contents field
60 */
61 if (!sinfo->authattrs && sig->digest)
AKASHI Takahiro05329fa2020-07-21 19:35:20 +090062 return 0;
63
64 if (!sinfo->sig->hash_algo)
65 return -ENOPKG;
66 if (!strcmp(sinfo->sig->hash_algo, "sha256"))
67 sig->digest_size = SHA256_SUM_LEN;
Dhananjay Phadkee146a2c2022-03-15 10:19:32 -070068 else if (!strcmp(sinfo->sig->hash_algo, "sha384"))
69 sig->digest_size = SHA384_SUM_LEN;
70 else if (!strcmp(sinfo->sig->hash_algo, "sha512"))
71 sig->digest_size = SHA512_SUM_LEN;
AKASHI Takahiro05329fa2020-07-21 19:35:20 +090072 else if (!strcmp(sinfo->sig->hash_algo, "sha1"))
73 sig->digest_size = SHA1_SUM_LEN;
74 else
75 return -ENOPKG;
76
Sughosh Ganu4366a242020-12-30 19:27:01 +053077 /*
78 * Calculate the hash only if the data is present.
79 * In case of authenticated variable and capsule,
80 * the hash has already been calculated on the
81 * efi_image_regions and populated
82 */
83 if (pkcs7->data) {
84 sig->digest = calloc(1, sig->digest_size);
85 if (!sig->digest) {
86 pr_warn("Sig %u: Out of memory\n", sinfo->index);
87 return -ENOMEM;
88 }
89
90 regions[0].data = pkcs7->data;
91 regions[0].size = pkcs7->data_len;
92
93 /* Digest the message [RFC2315 9.3] */
94 hash_calculate(sinfo->sig->hash_algo, regions, 1, sig->digest);
AKASHI Takahiro05329fa2020-07-21 19:35:20 +090095 }
96
AKASHI Takahiro05329fa2020-07-21 19:35:20 +090097 /* However, if there are authenticated attributes, there must be a
98 * message digest attribute amongst them which corresponds to the
99 * digest we just calculated.
100 */
101 if (sinfo->authattrs) {
102 u8 tag;
103
104 if (!sinfo->msgdigest) {
105 pr_warn("Sig %u: No messageDigest\n", sinfo->index);
106 ret = -EKEYREJECTED;
107 goto error;
108 }
109
110 if (sinfo->msgdigest_len != sig->digest_size) {
111 pr_debug("Sig %u: Invalid digest size (%u)\n",
112 sinfo->index, sinfo->msgdigest_len);
113 ret = -EBADMSG;
114 goto error;
115 }
116
117 if (memcmp(sig->digest, sinfo->msgdigest,
118 sinfo->msgdigest_len) != 0) {
119 pr_debug("Sig %u: Message digest doesn't match\n",
120 sinfo->index);
121 ret = -EKEYREJECTED;
122 goto error;
123 }
124
125 /* We then calculate anew, using the authenticated attributes
126 * as the contents of the digest instead. Note that we need to
127 * convert the attributes from a CONT.0 into a SET before we
128 * hash it.
129 */
130 memset(sig->digest, 0, sig->digest_size);
131
132 tag = 0x31;
133 regions[0].data = &tag;
134 regions[0].size = 1;
135 regions[1].data = sinfo->authattrs;
136 regions[1].size = sinfo->authattrs_len;
137
138 hash_calculate(sinfo->sig->hash_algo, regions, 2, sig->digest);
139
140 ret = 0;
141 }
142error:
143 return ret;
AKASHI Takahiro063499e2020-07-21 19:35:19 +0900144}
AKASHI Takahiro05329fa2020-07-21 19:35:20 +0900145#else /* !__UBOOT__ */
AKASHI Takahiro063499e2020-07-21 19:35:19 +0900146static int pkcs7_digest(struct pkcs7_message *pkcs7,
147 struct pkcs7_signed_info *sinfo)
148{
149 struct public_key_signature *sig = sinfo->sig;
150 struct crypto_shash *tfm;
151 struct shash_desc *desc;
152 size_t desc_size;
153 int ret;
154
155 kenter(",%u,%s", sinfo->index, sinfo->sig->hash_algo);
156
157 /* The digest was calculated already. */
158 if (sig->digest)
159 return 0;
160
161 if (!sinfo->sig->hash_algo)
162 return -ENOPKG;
163
164 /* Allocate the hashing algorithm we're going to need and find out how
165 * big the hash operational data will be.
166 */
167 tfm = crypto_alloc_shash(sinfo->sig->hash_algo, 0, 0);
168 if (IS_ERR(tfm))
169 return (PTR_ERR(tfm) == -ENOENT) ? -ENOPKG : PTR_ERR(tfm);
170
171 desc_size = crypto_shash_descsize(tfm) + sizeof(*desc);
172 sig->digest_size = crypto_shash_digestsize(tfm);
173
174 ret = -ENOMEM;
175 sig->digest = kmalloc(sig->digest_size, GFP_KERNEL);
176 if (!sig->digest)
177 goto error_no_desc;
178
179 desc = kzalloc(desc_size, GFP_KERNEL);
180 if (!desc)
181 goto error_no_desc;
182
183 desc->tfm = tfm;
184
185 /* Digest the message [RFC2315 9.3] */
186 ret = crypto_shash_digest(desc, pkcs7->data, pkcs7->data_len,
187 sig->digest);
188 if (ret < 0)
189 goto error;
190 pr_devel("MsgDigest = [%*ph]\n", 8, sig->digest);
191
192 /* However, if there are authenticated attributes, there must be a
193 * message digest attribute amongst them which corresponds to the
194 * digest we just calculated.
195 */
196 if (sinfo->authattrs) {
197 u8 tag;
198
199 if (!sinfo->msgdigest) {
200 pr_warn("Sig %u: No messageDigest\n", sinfo->index);
201 ret = -EKEYREJECTED;
202 goto error;
203 }
204
205 if (sinfo->msgdigest_len != sig->digest_size) {
206 pr_debug("Sig %u: Invalid digest size (%u)\n",
207 sinfo->index, sinfo->msgdigest_len);
208 ret = -EBADMSG;
209 goto error;
210 }
211
212 if (memcmp(sig->digest, sinfo->msgdigest,
213 sinfo->msgdigest_len) != 0) {
214 pr_debug("Sig %u: Message digest doesn't match\n",
215 sinfo->index);
216 ret = -EKEYREJECTED;
217 goto error;
218 }
219
220 /* We then calculate anew, using the authenticated attributes
221 * as the contents of the digest instead. Note that we need to
222 * convert the attributes from a CONT.0 into a SET before we
223 * hash it.
224 */
225 memset(sig->digest, 0, sig->digest_size);
226
227 ret = crypto_shash_init(desc);
228 if (ret < 0)
229 goto error;
230 tag = ASN1_CONS_BIT | ASN1_SET;
231 ret = crypto_shash_update(desc, &tag, 1);
232 if (ret < 0)
233 goto error;
234 ret = crypto_shash_finup(desc, sinfo->authattrs,
235 sinfo->authattrs_len, sig->digest);
236 if (ret < 0)
237 goto error;
238 pr_devel("AADigest = [%*ph]\n", 8, sig->digest);
239 }
240
241error:
242 kfree(desc);
243error_no_desc:
244 crypto_free_shash(tfm);
245 kleave(" = %d", ret);
246 return ret;
247}
248
249int pkcs7_get_digest(struct pkcs7_message *pkcs7, const u8 **buf, u32 *len,
250 enum hash_algo *hash_algo)
251{
252 struct pkcs7_signed_info *sinfo = pkcs7->signed_infos;
253 int i, ret;
254
255 /*
256 * This function doesn't support messages with more than one signature.
257 */
258 if (sinfo == NULL || sinfo->next != NULL)
259 return -EBADMSG;
260
261 ret = pkcs7_digest(pkcs7, sinfo);
262 if (ret)
263 return ret;
264
265 *buf = sinfo->sig->digest;
266 *len = sinfo->sig->digest_size;
267
268 for (i = 0; i < HASH_ALGO__LAST; i++)
269 if (!strcmp(hash_algo_name[i], sinfo->sig->hash_algo)) {
270 *hash_algo = i;
271 break;
272 }
273
274 return 0;
275}
276#endif /* !__UBOOT__ */
277
278/*
279 * Find the key (X.509 certificate) to use to verify a PKCS#7 message. PKCS#7
280 * uses the issuer's name and the issuing certificate serial number for
281 * matching purposes. These must match the certificate issuer's name (not
282 * subject's name) and the certificate serial number [RFC 2315 6.7].
283 */
284static int pkcs7_find_key(struct pkcs7_message *pkcs7,
285 struct pkcs7_signed_info *sinfo)
286{
287 struct x509_certificate *x509;
288 unsigned certix = 1;
289
290 kenter("%u", sinfo->index);
291
292 for (x509 = pkcs7->certs; x509; x509 = x509->next, certix++) {
293 /* I'm _assuming_ that the generator of the PKCS#7 message will
294 * encode the fields from the X.509 cert in the same way in the
295 * PKCS#7 message - but I can't be 100% sure of that. It's
296 * possible this will need element-by-element comparison.
297 */
298 if (!asymmetric_key_id_same(x509->id, sinfo->sig->auth_ids[0]))
299 continue;
300 pr_devel("Sig %u: Found cert serial match X.509[%u]\n",
301 sinfo->index, certix);
302
303 if (strcmp(x509->pub->pkey_algo, sinfo->sig->pkey_algo) != 0) {
304 pr_warn("Sig %u: X.509 algo and PKCS#7 sig algo don't match\n",
305 sinfo->index);
306 continue;
307 }
308
309 sinfo->signer = x509;
310 return 0;
311 }
312
313 /* The relevant X.509 cert isn't found here, but it might be found in
314 * the trust keyring.
315 */
316 pr_debug("Sig %u: Issuing X.509 cert not found (#%*phN)\n",
317 sinfo->index,
318 sinfo->sig->auth_ids[0]->len, sinfo->sig->auth_ids[0]->data);
319 return 0;
320}
321
322/*
AKASHI Takahiro5ee81c62020-07-21 19:35:21 +0900323 * pkcs7_verify_sig_chain - Verify the internal certificate chain as best
324 * as we can.
325 * @pkcs7: PKCS7 Signed Data
326 * @sinfo: PKCS7 Signed Info
327 * @signer: Singer's certificate
328 *
329 * Build up and verify the internal certificate chain against a signature
330 * in @sinfo, using certificates contained in @pkcs7 as best as we can.
331 * If the chain reaches the end, the last certificate will be returned
332 * in @signer.
333 *
334 * Return: 0 - on success, non-zero error code - otherwise
AKASHI Takahiro063499e2020-07-21 19:35:19 +0900335 */
AKASHI Takahiro5ee81c62020-07-21 19:35:21 +0900336#ifdef __UBOOT__
337static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
338 struct pkcs7_signed_info *sinfo,
339 struct x509_certificate **signer)
340#else
AKASHI Takahiro063499e2020-07-21 19:35:19 +0900341static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
342 struct pkcs7_signed_info *sinfo)
AKASHI Takahiro5ee81c62020-07-21 19:35:21 +0900343#endif
AKASHI Takahiro063499e2020-07-21 19:35:19 +0900344{
345 struct public_key_signature *sig;
346 struct x509_certificate *x509 = sinfo->signer, *p;
347 struct asymmetric_key_id *auth;
348 int ret;
349
350 kenter("");
351
AKASHI Takahiro5ee81c62020-07-21 19:35:21 +0900352 *signer = NULL;
353
AKASHI Takahiro063499e2020-07-21 19:35:19 +0900354 for (p = pkcs7->certs; p; p = p->next)
355 p->seen = false;
356
357 for (;;) {
358 pr_debug("verify %s: %*phN\n",
359 x509->subject,
360 x509->raw_serial_size, x509->raw_serial);
361 x509->seen = true;
362
363 if (x509->blacklisted) {
364 /* If this cert is blacklisted, then mark everything
365 * that depends on this as blacklisted too.
366 */
367 sinfo->blacklisted = true;
368 for (p = sinfo->signer; p != x509; p = p->signer)
369 p->blacklisted = true;
370 pr_debug("- blacklisted\n");
AKASHI Takahiro5ee81c62020-07-21 19:35:21 +0900371#ifdef __UBOOT__
372 *signer = x509;
373#endif
AKASHI Takahiro063499e2020-07-21 19:35:19 +0900374 return 0;
375 }
376
377 if (x509->unsupported_key)
378 goto unsupported_crypto_in_x509;
379
380 pr_debug("- issuer %s\n", x509->issuer);
381 sig = x509->sig;
382 if (sig->auth_ids[0])
383 pr_debug("- authkeyid.id %*phN\n",
384 sig->auth_ids[0]->len, sig->auth_ids[0]->data);
385 if (sig->auth_ids[1])
386 pr_debug("- authkeyid.skid %*phN\n",
387 sig->auth_ids[1]->len, sig->auth_ids[1]->data);
388
389 if (x509->self_signed) {
390 /* If there's no authority certificate specified, then
391 * the certificate must be self-signed and is the root
392 * of the chain. Likewise if the cert is its own
393 * authority.
394 */
395 if (x509->unsupported_sig)
396 goto unsupported_crypto_in_x509;
397 x509->signer = x509;
398 pr_debug("- self-signed\n");
AKASHI Takahiro5ee81c62020-07-21 19:35:21 +0900399#ifdef __UBOOT__
400 *signer = x509;
401#endif
AKASHI Takahiro063499e2020-07-21 19:35:19 +0900402 return 0;
403 }
404
405 /* Look through the X.509 certificates in the PKCS#7 message's
406 * list to see if the next one is there.
407 */
408 auth = sig->auth_ids[0];
409 if (auth) {
410 pr_debug("- want %*phN\n", auth->len, auth->data);
411 for (p = pkcs7->certs; p; p = p->next) {
412 pr_debug("- cmp [%u] %*phN\n",
413 p->index, p->id->len, p->id->data);
414 if (asymmetric_key_id_same(p->id, auth))
415 goto found_issuer_check_skid;
416 }
417 } else if (sig->auth_ids[1]) {
418 auth = sig->auth_ids[1];
419 pr_debug("- want %*phN\n", auth->len, auth->data);
420 for (p = pkcs7->certs; p; p = p->next) {
421 if (!p->skid)
422 continue;
423 pr_debug("- cmp [%u] %*phN\n",
424 p->index, p->skid->len, p->skid->data);
425 if (asymmetric_key_id_same(p->skid, auth))
426 goto found_issuer;
427 }
428 }
429
430 /* We didn't find the root of this chain */
431 pr_debug("- top\n");
AKASHI Takahiro5ee81c62020-07-21 19:35:21 +0900432#ifdef __UBOOT__
433 *signer = x509;
434#endif
AKASHI Takahiro063499e2020-07-21 19:35:19 +0900435 return 0;
436
437 found_issuer_check_skid:
438 /* We matched issuer + serialNumber, but if there's an
439 * authKeyId.keyId, that must match the CA subjKeyId also.
440 */
441 if (sig->auth_ids[1] &&
442 !asymmetric_key_id_same(p->skid, sig->auth_ids[1])) {
443 pr_warn("Sig %u: X.509 chain contains auth-skid nonmatch (%u->%u)\n",
444 sinfo->index, x509->index, p->index);
445 return -EKEYREJECTED;
446 }
447 found_issuer:
448 pr_debug("- subject %s\n", p->subject);
449 if (p->seen) {
450 pr_warn("Sig %u: X.509 chain contains loop\n",
451 sinfo->index);
AKASHI Takahiro5ee81c62020-07-21 19:35:21 +0900452#ifdef __UBOOT__
453 *signer = p;
454#endif
AKASHI Takahiro063499e2020-07-21 19:35:19 +0900455 return 0;
456 }
457 ret = public_key_verify_signature(p->pub, x509->sig);
458 if (ret < 0)
459 return ret;
460 x509->signer = p;
461 if (x509 == p) {
462 pr_debug("- self-signed\n");
AKASHI Takahiro5ee81c62020-07-21 19:35:21 +0900463#ifdef __UBOOT__
464 *signer = p;
465#endif
AKASHI Takahiro063499e2020-07-21 19:35:19 +0900466 return 0;
467 }
468 x509 = p;
469#ifndef __UBOOT__
470 might_sleep();
471#endif
472 }
473
474unsupported_crypto_in_x509:
475 /* Just prune the certificate chain at this point if we lack some
476 * crypto module to go further. Note, however, we don't want to set
477 * sinfo->unsupported_crypto as the signed info block may still be
478 * validatable against an X.509 cert lower in the chain that we have a
479 * trusted copy of.
480 */
481 return 0;
482}
483
484/*
AKASHI Takahiro5ee81c62020-07-21 19:35:21 +0900485 * pkcs7_verify_one - Verify one signed information block from a PKCS#7
486 * message.
487 * @pkcs7: PKCS7 Signed Data
488 * @sinfo: PKCS7 Signed Info
489 * @signer: Signer's certificate
490 *
491 * Verify one signature in @sinfo and follow the certificate chain.
492 * If the chain reaches the end, the last certificate will be returned
493 * in @signer.
494 *
495 * Return: 0 - on success, non-zero error code - otherwise
AKASHI Takahiro063499e2020-07-21 19:35:19 +0900496 */
AKASHI Takahiro5ee81c62020-07-21 19:35:21 +0900497#ifdef __UBOOT__
AKASHI Takahiro063499e2020-07-21 19:35:19 +0900498int pkcs7_verify_one(struct pkcs7_message *pkcs7,
AKASHI Takahiro5ee81c62020-07-21 19:35:21 +0900499 struct pkcs7_signed_info *sinfo,
500 struct x509_certificate **signer)
501#else
502static int pkcs7_verify_one(struct pkcs7_message *pkcs7,
503 struct pkcs7_signed_info *sinfo)
504#endif
AKASHI Takahiro063499e2020-07-21 19:35:19 +0900505{
506 int ret;
507
508 kenter(",%u", sinfo->index);
509
510 /* First of all, digest the data in the PKCS#7 message and the
511 * signed information block
512 */
513 ret = pkcs7_digest(pkcs7, sinfo);
514 if (ret < 0)
515 return ret;
516
517 /* Find the key for the signature if there is one */
518 ret = pkcs7_find_key(pkcs7, sinfo);
519 if (ret < 0)
520 return ret;
521
522 if (!sinfo->signer)
523 return 0;
524
525 pr_devel("Using X.509[%u] for sig %u\n",
526 sinfo->signer->index, sinfo->index);
527
528 /* Check that the PKCS#7 signing time is valid according to the X.509
529 * certificate. We can't, however, check against the system clock
530 * since that may not have been set yet and may be wrong.
531 */
532 if (test_bit(sinfo_has_signing_time, &sinfo->aa_set)) {
533 if (sinfo->signing_time < sinfo->signer->valid_from ||
534 sinfo->signing_time > sinfo->signer->valid_to) {
535 pr_warn("Message signed outside of X.509 validity window\n");
536 return -EKEYREJECTED;
537 }
538 }
539
540 /* Verify the PKCS#7 binary against the key */
541 ret = public_key_verify_signature(sinfo->signer->pub, sinfo->sig);
542 if (ret < 0)
543 return ret;
544
545 pr_devel("Verified signature %u\n", sinfo->index);
546
547 /* Verify the internal certificate chain */
AKASHI Takahiro5ee81c62020-07-21 19:35:21 +0900548 return pkcs7_verify_sig_chain(pkcs7, sinfo, signer);
AKASHI Takahiro063499e2020-07-21 19:35:19 +0900549}
550
551#ifndef __UBOOT__
552/**
553 * pkcs7_verify - Verify a PKCS#7 message
554 * @pkcs7: The PKCS#7 message to be verified
555 * @usage: The use to which the key is being put
556 *
557 * Verify a PKCS#7 message is internally consistent - that is, the data digest
558 * matches the digest in the AuthAttrs and any signature in the message or one
559 * of the X.509 certificates it carries that matches another X.509 cert in the
560 * message can be verified.
561 *
562 * This does not look to match the contents of the PKCS#7 message against any
563 * external public keys.
564 *
565 * Returns, in order of descending priority:
566 *
567 * (*) -EKEYREJECTED if a key was selected that had a usage restriction at
568 * odds with the specified usage, or:
569 *
570 * (*) -EKEYREJECTED if a signature failed to match for which we found an
571 * appropriate X.509 certificate, or:
572 *
573 * (*) -EBADMSG if some part of the message was invalid, or:
574 *
575 * (*) 0 if a signature chain passed verification, or:
576 *
577 * (*) -EKEYREJECTED if a blacklisted key was encountered, or:
578 *
579 * (*) -ENOPKG if none of the signature chains are verifiable because suitable
580 * crypto modules couldn't be found.
581 */
582int pkcs7_verify(struct pkcs7_message *pkcs7,
583 enum key_being_used_for usage)
584{
585 struct pkcs7_signed_info *sinfo;
586 int actual_ret = -ENOPKG;
587 int ret;
588
589 kenter("");
590
591 switch (usage) {
592 case VERIFYING_MODULE_SIGNATURE:
593 if (pkcs7->data_type != OID_data) {
594 pr_warn("Invalid module sig (not pkcs7-data)\n");
595 return -EKEYREJECTED;
596 }
597 if (pkcs7->have_authattrs) {
598 pr_warn("Invalid module sig (has authattrs)\n");
599 return -EKEYREJECTED;
600 }
601 break;
602 case VERIFYING_FIRMWARE_SIGNATURE:
603 if (pkcs7->data_type != OID_data) {
604 pr_warn("Invalid firmware sig (not pkcs7-data)\n");
605 return -EKEYREJECTED;
606 }
607 if (!pkcs7->have_authattrs) {
608 pr_warn("Invalid firmware sig (missing authattrs)\n");
609 return -EKEYREJECTED;
610 }
611 break;
612 case VERIFYING_KEXEC_PE_SIGNATURE:
613 if (pkcs7->data_type != OID_msIndirectData) {
614 pr_warn("Invalid kexec sig (not Authenticode)\n");
615 return -EKEYREJECTED;
616 }
617 /* Authattr presence checked in parser */
618 break;
619 case VERIFYING_UNSPECIFIED_SIGNATURE:
620 if (pkcs7->data_type != OID_data) {
621 pr_warn("Invalid unspecified sig (not pkcs7-data)\n");
622 return -EKEYREJECTED;
623 }
624 break;
625 default:
626 return -EINVAL;
627 }
628
629 for (sinfo = pkcs7->signed_infos; sinfo; sinfo = sinfo->next) {
630 ret = pkcs7_verify_one(pkcs7, sinfo);
631 if (sinfo->blacklisted) {
632 if (actual_ret == -ENOPKG)
633 actual_ret = -EKEYREJECTED;
634 continue;
635 }
636 if (ret < 0) {
637 if (ret == -ENOPKG) {
638 sinfo->unsupported_crypto = true;
639 continue;
640 }
641 kleave(" = %d", ret);
642 return ret;
643 }
644 actual_ret = 0;
645 }
646
647 kleave(" = %d", actual_ret);
648 return actual_ret;
649}
650EXPORT_SYMBOL_GPL(pkcs7_verify);
651
652/**
653 * pkcs7_supply_detached_data - Supply the data needed to verify a PKCS#7 message
654 * @pkcs7: The PKCS#7 message
655 * @data: The data to be verified
656 * @datalen: The amount of data
657 *
658 * Supply the detached data needed to verify a PKCS#7 message. Note that no
659 * attempt to retain/pin the data is made. That is left to the caller. The
660 * data will not be modified by pkcs7_verify() and will not be freed when the
661 * PKCS#7 message is freed.
662 *
663 * Returns -EINVAL if data is already supplied in the message, 0 otherwise.
664 */
665int pkcs7_supply_detached_data(struct pkcs7_message *pkcs7,
666 const void *data, size_t datalen)
667{
668 if (pkcs7->data) {
669 pr_debug("Data already supplied\n");
670 return -EINVAL;
671 }
672 pkcs7->data = data;
673 pkcs7->data_len = datalen;
674 return 0;
675}
676#endif /* __UBOOT__ */