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