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