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