Coverage Report

Created: 2026-03-11 06:21

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