1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright (c) 2018 Patrick Wildt <patrick@blueri.se>
4 * Copyright (c) 2019 Linaro Limited, Author: AKASHI Takahiro
5 */
6
7 #include <common.h>
8 #include <charset.h>
9 #include <efi_loader.h>
10 #include <efi_variable.h>
11 #include <image.h>
12 #include <hexdump.h>
13 #include <malloc.h>
14 #include <crypto/pkcs7.h>
15 #include <crypto/pkcs7_parser.h>
16 #include <crypto/public_key.h>
17 #include <linux/compat.h>
18 #include <linux/oid_registry.h>
19 #include <u-boot/hash-checksum.h>
20 #include <u-boot/rsa.h>
21 #include <u-boot/sha256.h>
22
23 const efi_guid_t efi_guid_sha256 = EFI_CERT_SHA256_GUID;
24 const efi_guid_t efi_guid_cert_rsa2048 = EFI_CERT_RSA2048_GUID;
25 const efi_guid_t efi_guid_cert_x509 = EFI_CERT_X509_GUID;
26 const efi_guid_t efi_guid_cert_x509_sha256 = EFI_CERT_X509_SHA256_GUID;
27 const efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID;
28
29 static u8 pkcs7_hdr[] = {
30 /* SEQUENCE */
31 0x30, 0x82, 0x05, 0xc7,
32 /* OID: pkcs7-signedData */
33 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02,
34 /* Context Structured? */
35 0xa0, 0x82, 0x05, 0xb8,
36 };
37
38 /**
39 * efi_parse_pkcs7_header - parse a signature in payload
40 * @buf: Pointer to payload's value
41 * @buflen: Length of @buf
42 * @tmpbuf: Pointer to temporary buffer
43 *
44 * Parse a signature embedded in payload's value and instantiate
45 * a pkcs7_message structure. Since pkcs7_parse_message() accepts only
46 * pkcs7's signedData, some header needed be prepended for correctly
47 * parsing authentication data
48 * A temporary buffer will be allocated if needed, and it should be
49 * kept valid during the authentication because some data in the buffer
50 * will be referenced by efi_signature_verify().
51 *
52 * Return: Pointer to pkcs7_message structure on success, NULL on error
53 */
efi_parse_pkcs7_header(const void * buf,size_t buflen,u8 ** tmpbuf)54 struct pkcs7_message *efi_parse_pkcs7_header(const void *buf,
55 size_t buflen,
56 u8 **tmpbuf)
57 {
58 u8 *ebuf;
59 size_t ebuflen, len;
60 struct pkcs7_message *msg;
61
62 /*
63 * This is the best assumption to check if the binary is
64 * already in a form of pkcs7's signedData.
65 */
66 if (buflen > sizeof(pkcs7_hdr) &&
67 !memcmp(&((u8 *)buf)[4], &pkcs7_hdr[4], 11)) {
68 msg = pkcs7_parse_message(buf, buflen);
69 if (IS_ERR(msg))
70 return NULL;
71 return msg;
72 }
73
74 /*
75 * Otherwise, we should add a dummy prefix sequence for pkcs7
76 * message parser to be able to process.
77 * NOTE: EDK2 also uses similar hack in WrapPkcs7Data()
78 * in CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7VerifyCommon.c
79 * TODO:
80 * The header should be composed in a more refined manner.
81 */
82 EFI_PRINT("Makeshift prefix added to authentication data\n");
83 ebuflen = sizeof(pkcs7_hdr) + buflen;
84 if (ebuflen <= 0x7f) {
85 EFI_PRINT("Data is too short\n");
86 return NULL;
87 }
88
89 ebuf = malloc(ebuflen);
90 if (!ebuf) {
91 EFI_PRINT("Out of memory\n");
92 return NULL;
93 }
94
95 memcpy(ebuf, pkcs7_hdr, sizeof(pkcs7_hdr));
96 memcpy(ebuf + sizeof(pkcs7_hdr), buf, buflen);
97 len = ebuflen - 4;
98 ebuf[2] = (len >> 8) & 0xff;
99 ebuf[3] = len & 0xff;
100 len = ebuflen - 0x13;
101 ebuf[0x11] = (len >> 8) & 0xff;
102 ebuf[0x12] = len & 0xff;
103
104 msg = pkcs7_parse_message(ebuf, ebuflen);
105
106 if (IS_ERR(msg)) {
107 free(ebuf);
108 return NULL;
109 }
110
111 *tmpbuf = ebuf;
112 return msg;
113 }
114
115 /**
116 * efi_hash_regions - calculate a hash value
117 * @regs: Array of regions
118 * @count: Number of regions
119 * @hash: Pointer to a pointer to buffer holding a hash value
120 * @size: Size of buffer to be returned
121 *
122 * Calculate a sha256 value of @regs and return a value in @hash.
123 *
124 * Return: true on success, false on error
125 */
efi_hash_regions(struct image_region * regs,int count,void ** hash,size_t * size)126 static bool efi_hash_regions(struct image_region *regs, int count,
127 void **hash, size_t *size)
128 {
129 if (!*hash) {
130 *hash = calloc(1, SHA256_SUM_LEN);
131 if (!*hash) {
132 EFI_PRINT("Out of memory\n");
133 return false;
134 }
135 }
136 if (size)
137 *size = SHA256_SUM_LEN;
138
139 hash_calculate("sha256", regs, count, *hash);
140 #ifdef DEBUG
141 EFI_PRINT("hash calculated:\n");
142 print_hex_dump(" ", DUMP_PREFIX_OFFSET, 16, 1,
143 *hash, SHA256_SUM_LEN, false);
144 #endif
145
146 return true;
147 }
148
149 /**
150 * efi_signature_lookup_digest - search for an image's digest in sigdb
151 * @regs: List of regions to be authenticated
152 * @db: Signature database for trusted certificates
153 *
154 * A message digest of image pointed to by @regs is calculated and
155 * its hash value is compared to entries in signature database pointed
156 * to by @db.
157 *
158 * Return: true if found, false if not
159 */
efi_signature_lookup_digest(struct efi_image_regions * regs,struct efi_signature_store * db)160 bool efi_signature_lookup_digest(struct efi_image_regions *regs,
161 struct efi_signature_store *db)
162 {
163 struct efi_signature_store *siglist;
164 struct efi_sig_data *sig_data;
165 void *hash = NULL;
166 size_t size = 0;
167 bool found = false;
168
169 EFI_PRINT("%s: Enter, %p, %p\n", __func__, regs, db);
170
171 if (!regs || !db || !db->sig_data_list)
172 goto out;
173
174 for (siglist = db; siglist; siglist = siglist->next) {
175 /* TODO: support other hash algorithms */
176 if (guidcmp(&siglist->sig_type, &efi_guid_sha256)) {
177 EFI_PRINT("Digest algorithm is not supported: %pUl\n",
178 &siglist->sig_type);
179 break;
180 }
181
182 if (!efi_hash_regions(regs->reg, regs->num, &hash, &size)) {
183 EFI_PRINT("Digesting an image failed\n");
184 break;
185 }
186
187 for (sig_data = siglist->sig_data_list; sig_data;
188 sig_data = sig_data->next) {
189 #ifdef DEBUG
190 EFI_PRINT("Msg digest in database:\n");
191 print_hex_dump(" ", DUMP_PREFIX_OFFSET, 16, 1,
192 sig_data->data, sig_data->size, false);
193 #endif
194 if (sig_data->size == size &&
195 !memcmp(sig_data->data, hash, size)) {
196 found = true;
197 free(hash);
198 goto out;
199 }
200 }
201
202 free(hash);
203 hash = NULL;
204 }
205
206 out:
207 EFI_PRINT("%s: Exit, found: %d\n", __func__, found);
208 return found;
209 }
210
211 /**
212 * efi_lookup_certificate - find a certificate within db
213 * @msg: Signature
214 * @db: Signature database
215 *
216 * Search signature database pointed to by @db and find a certificate
217 * pointed to by @cert.
218 *
219 * Return: true if found, false otherwise.
220 */
efi_lookup_certificate(struct x509_certificate * cert,struct efi_signature_store * db)221 static bool efi_lookup_certificate(struct x509_certificate *cert,
222 struct efi_signature_store *db)
223 {
224 struct efi_signature_store *siglist;
225 struct efi_sig_data *sig_data;
226 struct image_region reg[1];
227 void *hash = NULL, *hash_tmp = NULL;
228 size_t size = 0;
229 bool found = false;
230
231 EFI_PRINT("%s: Enter, %p, %p\n", __func__, cert, db);
232
233 if (!cert || !db || !db->sig_data_list)
234 goto out;
235
236 /*
237 * TODO: identify a certificate using sha256 digest
238 * Is there any better way?
239 */
240 /* calculate hash of TBSCertificate */
241 reg[0].data = cert->tbs;
242 reg[0].size = cert->tbs_size;
243 if (!efi_hash_regions(reg, 1, &hash, &size))
244 goto out;
245
246 EFI_PRINT("%s: searching for %s\n", __func__, cert->subject);
247 for (siglist = db; siglist; siglist = siglist->next) {
248 /* only with x509 certificate */
249 if (guidcmp(&siglist->sig_type, &efi_guid_cert_x509))
250 continue;
251
252 for (sig_data = siglist->sig_data_list; sig_data;
253 sig_data = sig_data->next) {
254 struct x509_certificate *cert_tmp;
255
256 cert_tmp = x509_cert_parse(sig_data->data,
257 sig_data->size);
258 if (IS_ERR_OR_NULL(cert_tmp))
259 continue;
260
261 EFI_PRINT("%s: against %s\n", __func__,
262 cert_tmp->subject);
263 reg[0].data = cert_tmp->tbs;
264 reg[0].size = cert_tmp->tbs_size;
265 if (!efi_hash_regions(reg, 1, &hash_tmp, NULL))
266 goto out;
267
268 x509_free_certificate(cert_tmp);
269
270 if (!memcmp(hash, hash_tmp, size)) {
271 found = true;
272 goto out;
273 }
274 }
275 }
276 out:
277 free(hash);
278 free(hash_tmp);
279
280 EFI_PRINT("%s: Exit, found: %d\n", __func__, found);
281 return found;
282 }
283
284 /**
285 * efi_verify_certificate - verify certificate's signature with database
286 * @signer: Certificate
287 * @db: Signature database
288 * @root: Certificate to verify @signer
289 *
290 * Determine if certificate pointed to by @signer may be verified
291 * by one of certificates in signature database pointed to by @db.
292 *
293 * Return: true if certificate is verified, false otherwise.
294 */
efi_verify_certificate(struct x509_certificate * signer,struct efi_signature_store * db,struct x509_certificate ** root)295 static bool efi_verify_certificate(struct x509_certificate *signer,
296 struct efi_signature_store *db,
297 struct x509_certificate **root)
298 {
299 struct efi_signature_store *siglist;
300 struct efi_sig_data *sig_data;
301 struct x509_certificate *cert;
302 bool verified = false;
303 int ret;
304
305 EFI_PRINT("%s: Enter, %p, %p\n", __func__, signer, db);
306
307 if (!signer || !db || !db->sig_data_list)
308 goto out;
309
310 for (siglist = db; siglist; siglist = siglist->next) {
311 /* only with x509 certificate */
312 if (guidcmp(&siglist->sig_type, &efi_guid_cert_x509))
313 continue;
314
315 for (sig_data = siglist->sig_data_list; sig_data;
316 sig_data = sig_data->next) {
317 cert = x509_cert_parse(sig_data->data, sig_data->size);
318 if (IS_ERR_OR_NULL(cert)) {
319 EFI_PRINT("Cannot parse x509 certificate\n");
320 continue;
321 }
322
323 ret = public_key_verify_signature(cert->pub,
324 signer->sig);
325 if (!ret) {
326 verified = true;
327 if (root)
328 *root = cert;
329 else
330 x509_free_certificate(cert);
331 goto out;
332 }
333 x509_free_certificate(cert);
334 }
335 }
336
337 out:
338 EFI_PRINT("%s: Exit, verified: %d\n", __func__, verified);
339 return verified;
340 }
341
342 /**
343 * efi_signature_check_revocation - check revocation with dbx
344 * @sinfo: Signer's info
345 * @cert: x509 certificate
346 * @dbx: Revocation signature database
347 *
348 * Search revocation signature database pointed to by @dbx and find
349 * an entry matching to certificate pointed to by @cert.
350 *
351 * While this entry contains revocation time, we don't support timestamp
352 * protocol at this time and any image will be unconditionally revoked
353 * when this match occurs.
354 *
355 * Return: true if check passed (not found), false otherwise.
356 */
efi_signature_check_revocation(struct pkcs7_signed_info * sinfo,struct x509_certificate * cert,struct efi_signature_store * dbx)357 static bool efi_signature_check_revocation(struct pkcs7_signed_info *sinfo,
358 struct x509_certificate *cert,
359 struct efi_signature_store *dbx)
360 {
361 struct efi_signature_store *siglist;
362 struct efi_sig_data *sig_data;
363 struct image_region reg[1];
364 void *hash = NULL;
365 size_t size = 0;
366 time64_t revoc_time;
367 bool revoked = false;
368
369 EFI_PRINT("%s: Enter, %p, %p, %p\n", __func__, sinfo, cert, dbx);
370
371 if (!sinfo || !cert || !dbx || !dbx->sig_data_list)
372 goto out;
373
374 EFI_PRINT("Checking revocation against %s\n", cert->subject);
375 for (siglist = dbx; siglist; siglist = siglist->next) {
376 if (guidcmp(&siglist->sig_type, &efi_guid_cert_x509_sha256))
377 continue;
378
379 /* calculate hash of TBSCertificate */
380 reg[0].data = cert->tbs;
381 reg[0].size = cert->tbs_size;
382 if (!efi_hash_regions(reg, 1, &hash, &size))
383 goto out;
384
385 for (sig_data = siglist->sig_data_list; sig_data;
386 sig_data = sig_data->next) {
387 /*
388 * struct efi_cert_x509_sha256 {
389 * u8 tbs_hash[256/8];
390 * time64_t revocation_time;
391 * };
392 */
393 #ifdef DEBUG
394 if (sig_data->size >= size) {
395 EFI_PRINT("hash in db:\n");
396 print_hex_dump(" ", DUMP_PREFIX_OFFSET,
397 16, 1,
398 sig_data->data, size, false);
399 }
400 #endif
401 if ((sig_data->size < size + sizeof(time64_t)) ||
402 memcmp(sig_data->data, hash, size))
403 continue;
404
405 memcpy(&revoc_time, sig_data->data + size,
406 sizeof(revoc_time));
407 EFI_PRINT("revocation time: 0x%llx\n", revoc_time);
408 /*
409 * TODO: compare signing timestamp in sinfo
410 * with revocation time
411 */
412
413 revoked = true;
414 free(hash);
415 goto out;
416 }
417 free(hash);
418 hash = NULL;
419 }
420 out:
421 EFI_PRINT("%s: Exit, revoked: %d\n", __func__, revoked);
422 return !revoked;
423 }
424
425 /*
426 * efi_signature_verify - verify signatures with db and dbx
427 * @regs: List of regions to be authenticated
428 * @msg: Signature
429 * @db: Signature database for trusted certificates
430 * @dbx: Revocation signature database
431 *
432 * All the signature pointed to by @msg against image pointed to by @regs
433 * will be verified by signature database pointed to by @db and @dbx.
434 *
435 * Return: true if verification for all signatures passed, false otherwise
436 */
efi_signature_verify(struct efi_image_regions * regs,struct pkcs7_message * msg,struct efi_signature_store * db,struct efi_signature_store * dbx)437 bool efi_signature_verify(struct efi_image_regions *regs,
438 struct pkcs7_message *msg,
439 struct efi_signature_store *db,
440 struct efi_signature_store *dbx)
441 {
442 struct pkcs7_signed_info *sinfo;
443 struct x509_certificate *signer, *root;
444 bool verified = false;
445 int ret;
446
447 EFI_PRINT("%s: Enter, %p, %p, %p, %p\n", __func__, regs, msg, db, dbx);
448
449 if (!regs || !msg || !db || !db->sig_data_list)
450 goto out;
451
452 for (sinfo = msg->signed_infos; sinfo; sinfo = sinfo->next) {
453 EFI_PRINT("Signed Info: digest algo: %s, pkey algo: %s\n",
454 sinfo->sig->hash_algo, sinfo->sig->pkey_algo);
455
456 /*
457 * only for authenticated variable.
458 *
459 * If this function is called for image,
460 * hash calculation will be done in
461 * pkcs7_verify_one().
462 */
463 if (!msg->data &&
464 !efi_hash_regions(regs->reg, regs->num,
465 (void **)&sinfo->sig->digest, NULL)) {
466 EFI_PRINT("Digesting an image failed\n");
467 goto out;
468 }
469
470 EFI_PRINT("Verifying certificate chain\n");
471 signer = NULL;
472 ret = pkcs7_verify_one(msg, sinfo, &signer);
473 if (ret == -ENOPKG)
474 continue;
475
476 if (ret < 0 || !signer)
477 goto out;
478
479 if (sinfo->blacklisted)
480 goto out;
481
482 EFI_PRINT("Verifying last certificate in chain\n");
483 if (signer->self_signed) {
484 if (efi_lookup_certificate(signer, db))
485 if (efi_signature_check_revocation(sinfo,
486 signer, dbx))
487 break;
488 } else if (efi_verify_certificate(signer, db, &root)) {
489 bool check;
490
491 check = efi_signature_check_revocation(sinfo, root,
492 dbx);
493 x509_free_certificate(root);
494 if (check)
495 break;
496 }
497
498 EFI_PRINT("Certificate chain didn't reach trusted CA\n");
499 }
500 if (sinfo)
501 verified = true;
502 out:
503 EFI_PRINT("%s: Exit, verified: %d\n", __func__, verified);
504 return verified;
505 }
506
507 /**
508 * efi_signature_check_signers - check revocation against all signers with dbx
509 * @msg: Signature
510 * @dbx: Revocation signature database
511 *
512 * Determine if none of signers' certificates in @msg are revoked
513 * by signature database pointed to by @dbx.
514 *
515 * Return: true if all signers passed, false otherwise.
516 */
efi_signature_check_signers(struct pkcs7_message * msg,struct efi_signature_store * dbx)517 bool efi_signature_check_signers(struct pkcs7_message *msg,
518 struct efi_signature_store *dbx)
519 {
520 struct pkcs7_signed_info *sinfo;
521 bool revoked = false;
522
523 EFI_PRINT("%s: Enter, %p, %p\n", __func__, msg, dbx);
524
525 if (!msg || !dbx)
526 goto out;
527
528 for (sinfo = msg->signed_infos; sinfo; sinfo = sinfo->next) {
529 if (sinfo->signer &&
530 !efi_signature_check_revocation(sinfo, sinfo->signer,
531 dbx)) {
532 revoked = true;
533 break;
534 }
535 }
536 out:
537 EFI_PRINT("%s: Exit, revoked: %d\n", __func__, revoked);
538 return !revoked;
539 }
540
541 /**
542 * efi_sigstore_free - free signature store
543 * @sigstore: Pointer to signature store structure
544 *
545 * Feee all the memories held in signature store and itself,
546 * which were allocated by efi_sigstore_parse_sigdb().
547 */
efi_sigstore_free(struct efi_signature_store * sigstore)548 void efi_sigstore_free(struct efi_signature_store *sigstore)
549 {
550 struct efi_signature_store *sigstore_next;
551 struct efi_sig_data *sig_data, *sig_data_next;
552
553 while (sigstore) {
554 sigstore_next = sigstore->next;
555
556 sig_data = sigstore->sig_data_list;
557 while (sig_data) {
558 sig_data_next = sig_data->next;
559 free(sig_data->data);
560 free(sig_data);
561 sig_data = sig_data_next;
562 }
563
564 free(sigstore);
565 sigstore = sigstore_next;
566 }
567 }
568
569 /**
570 * efi_sigstore_parse_siglist - parse a signature list
571 * @name: Pointer to signature list
572 *
573 * Parse signature list and instantiate a signature store structure.
574 * Signature database is a simple concatenation of one or more
575 * signature list(s).
576 *
577 * Return: Pointer to signature store on success, NULL on error
578 */
579 static struct efi_signature_store *
efi_sigstore_parse_siglist(struct efi_signature_list * esl)580 efi_sigstore_parse_siglist(struct efi_signature_list *esl)
581 {
582 struct efi_signature_store *siglist = NULL;
583 struct efi_sig_data *sig_data, *sig_data_next;
584 struct efi_signature_data *esd;
585 size_t left;
586
587 /*
588 * UEFI specification defines certificate types:
589 * for non-signed images,
590 * EFI_CERT_SHA256_GUID
591 * EFI_CERT_RSA2048_GUID
592 * EFI_CERT_RSA2048_SHA256_GUID
593 * EFI_CERT_SHA1_GUID
594 * EFI_CERT_RSA2048_SHA_GUID
595 * EFI_CERT_SHA224_GUID
596 * EFI_CERT_SHA384_GUID
597 * EFI_CERT_SHA512_GUID
598 *
599 * for signed images,
600 * EFI_CERT_X509_GUID
601 * NOTE: Each certificate will normally be in a separate
602 * EFI_SIGNATURE_LIST as the size may vary depending on
603 * its algo's.
604 *
605 * for timestamp revocation of certificate,
606 * EFI_CERT_X509_SHA512_GUID
607 * EFI_CERT_X509_SHA256_GUID
608 * EFI_CERT_X509_SHA384_GUID
609 */
610
611 if (esl->signature_list_size
612 <= (sizeof(*esl) + esl->signature_header_size)) {
613 EFI_PRINT("Siglist in wrong format\n");
614 return NULL;
615 }
616
617 /* Create a head */
618 siglist = calloc(sizeof(*siglist), 1);
619 if (!siglist) {
620 EFI_PRINT("Out of memory\n");
621 goto err;
622 }
623 memcpy(&siglist->sig_type, &esl->signature_type, sizeof(efi_guid_t));
624
625 /* Go through the list */
626 sig_data_next = NULL;
627 left = esl->signature_list_size
628 - (sizeof(*esl) + esl->signature_header_size);
629 esd = (struct efi_signature_data *)
630 ((u8 *)esl + sizeof(*esl) + esl->signature_header_size);
631
632 while (left > 0) {
633 /* Signature must exist if there is remaining data. */
634 if (left < esl->signature_size) {
635 EFI_PRINT("Certificate is too small\n");
636 goto err;
637 }
638
639 sig_data = calloc(esl->signature_size
640 - sizeof(esd->signature_owner), 1);
641 if (!sig_data) {
642 EFI_PRINT("Out of memory\n");
643 goto err;
644 }
645
646 /* Append signature data */
647 memcpy(&sig_data->owner, &esd->signature_owner,
648 sizeof(efi_guid_t));
649 sig_data->size = esl->signature_size
650 - sizeof(esd->signature_owner);
651 sig_data->data = malloc(sig_data->size);
652 if (!sig_data->data) {
653 EFI_PRINT("Out of memory\n");
654 goto err;
655 }
656 memcpy(sig_data->data, esd->signature_data, sig_data->size);
657
658 sig_data->next = sig_data_next;
659 sig_data_next = sig_data;
660
661 /* Next */
662 esd = (struct efi_signature_data *)
663 ((u8 *)esd + esl->signature_size);
664 left -= esl->signature_size;
665 }
666 siglist->sig_data_list = sig_data_next;
667
668 return siglist;
669
670 err:
671 efi_sigstore_free(siglist);
672
673 return NULL;
674 }
675
676 /**
677 * efi_sigstore_parse_sigdb - parse the signature list and populate
678 * the signature store
679 *
680 * @sig_list: Pointer to the signature list
681 * @size: Size of the signature list
682 *
683 * Parse the efi signature list and instantiate a signature store
684 * structure.
685 *
686 * Return: Pointer to signature store on success, NULL on error
687 */
efi_build_signature_store(void * sig_list,efi_uintn_t size)688 struct efi_signature_store *efi_build_signature_store(void *sig_list,
689 efi_uintn_t size)
690 {
691 struct efi_signature_list *esl;
692 struct efi_signature_store *sigstore = NULL, *siglist;
693
694 esl = sig_list;
695 while (size > 0) {
696 /* List must exist if there is remaining data. */
697 if (size < sizeof(*esl)) {
698 EFI_PRINT("Signature list in wrong format\n");
699 goto err;
700 }
701
702 if (size < esl->signature_list_size) {
703 EFI_PRINT("Signature list in wrong format\n");
704 goto err;
705 }
706
707 /* Parse a single siglist. */
708 siglist = efi_sigstore_parse_siglist(esl);
709 if (!siglist) {
710 EFI_PRINT("Parsing of signature list of failed\n");
711 goto err;
712 }
713
714 /* Append siglist */
715 siglist->next = sigstore;
716 sigstore = siglist;
717
718 /* Next */
719 size -= esl->signature_list_size;
720 esl = (void *)esl + esl->signature_list_size;
721 }
722 free(sig_list);
723
724 return sigstore;
725
726 err:
727 efi_sigstore_free(sigstore);
728 free(sig_list);
729
730 return NULL;
731 }
732
733 /**
734 * efi_sigstore_parse_sigdb - parse a signature database variable
735 * @name: Variable's name
736 *
737 * Read in a value of signature database variable pointed to by
738 * @name, parse it and instantiate a signature store structure.
739 *
740 * Return: Pointer to signature store on success, NULL on error
741 */
efi_sigstore_parse_sigdb(u16 * name)742 struct efi_signature_store *efi_sigstore_parse_sigdb(u16 *name)
743 {
744 const efi_guid_t *vendor;
745 void *db;
746 efi_uintn_t db_size;
747
748 vendor = efi_auth_var_get_guid(name);
749 db = efi_get_var(name, vendor, &db_size);
750 if (!db) {
751 EFI_PRINT("variable, %ls, not found\n", name);
752 return calloc(sizeof(struct efi_signature_store), 1);
753 }
754
755 return efi_build_signature_store(db, db_size);
756 }
757