blob: f60c0e1f79328fb9c05f2d4c1a38e41300aebde8 [file] [log] [blame]
AKASHI Takahiro593e17d2020-04-14 11:51:39 +09001// 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 <image.h>
11#include <hexdump.h>
12#include <malloc.h>
AKASHI Takahiro1115edd2020-07-21 19:35:22 +090013#include <crypto/pkcs7.h>
AKASHI Takahiroe3f5c9c2020-04-21 09:38:17 +090014#include <crypto/pkcs7_parser.h>
AKASHI Takahiro1115edd2020-07-21 19:35:22 +090015#include <crypto/public_key.h>
AKASHI Takahiro593e17d2020-04-14 11:51:39 +090016#include <linux/compat.h>
17#include <linux/oid_registry.h>
18#include <u-boot/rsa.h>
19#include <u-boot/sha256.h>
AKASHI Takahiro593e17d2020-04-14 11:51:39 +090020
21const efi_guid_t efi_guid_image_security_database =
22 EFI_IMAGE_SECURITY_DATABASE_GUID;
23const efi_guid_t efi_guid_sha256 = EFI_CERT_SHA256_GUID;
24const efi_guid_t efi_guid_cert_rsa2048 = EFI_CERT_RSA2048_GUID;
25const efi_guid_t efi_guid_cert_x509 = EFI_CERT_X509_GUID;
26const efi_guid_t efi_guid_cert_x509_sha256 = EFI_CERT_X509_SHA256_GUID;
AKASHI Takahiroa4292ec2020-05-29 15:41:18 +090027const efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID;
AKASHI Takahiro593e17d2020-04-14 11:51:39 +090028
29#ifdef CONFIG_EFI_SECURE_BOOT
30
31/**
32 * efi_hash_regions - calculate a hash value
AKASHI Takahiro1e64d0b2020-07-08 14:01:55 +090033 * @regs: Array of regions
34 * @count: Number of regions
AKASHI Takahiro593e17d2020-04-14 11:51:39 +090035 * @hash: Pointer to a pointer to buffer holding a hash value
36 * @size: Size of buffer to be returned
37 *
38 * Calculate a sha256 value of @regs and return a value in @hash.
39 *
40 * Return: true on success, false on error
41 */
AKASHI Takahiro1e64d0b2020-07-08 14:01:55 +090042static bool efi_hash_regions(struct image_region *regs, int count,
43 void **hash, size_t *size)
AKASHI Takahiro593e17d2020-04-14 11:51:39 +090044{
AKASHI Takahiro593e17d2020-04-14 11:51:39 +090045 if (!*hash) {
AKASHI Takahiro1e64d0b2020-07-08 14:01:55 +090046 *hash = calloc(1, SHA256_SUM_LEN);
47 if (!*hash) {
48 EFI_PRINT("Out of memory\n");
49 return false;
50 }
AKASHI Takahiro593e17d2020-04-14 11:51:39 +090051 }
AKASHI Takahiro1e64d0b2020-07-08 14:01:55 +090052 if (size)
53 *size = SHA256_SUM_LEN;
AKASHI Takahiro593e17d2020-04-14 11:51:39 +090054
AKASHI Takahiro1e64d0b2020-07-08 14:01:55 +090055 hash_calculate("sha256", regs, count, *hash);
AKASHI Takahiro593e17d2020-04-14 11:51:39 +090056#ifdef DEBUG
AKASHI Takahiro3e9019d42020-06-09 14:09:33 +090057 EFI_PRINT("hash calculated:\n");
AKASHI Takahiro593e17d2020-04-14 11:51:39 +090058 print_hex_dump(" ", DUMP_PREFIX_OFFSET, 16, 1,
59 *hash, SHA256_SUM_LEN, false);
60#endif
61
62 return true;
63}
64
65/**
AKASHI Takahiro7926dfb2020-07-08 14:01:57 +090066 * efi_signature_lookup_digest - search for an image's digest in sigdb
67 * @regs: List of regions to be authenticated
68 * @db: Signature database for trusted certificates
69 *
70 * A message digest of image pointed to by @regs is calculated and
71 * its hash value is compared to entries in signature database pointed
72 * to by @db.
73 *
74 * Return: true if found, false if not
75 */
76bool efi_signature_lookup_digest(struct efi_image_regions *regs,
77 struct efi_signature_store *db)
78{
79 struct efi_signature_store *siglist;
80 struct efi_sig_data *sig_data;
81 void *hash = NULL;
82 size_t size = 0;
83 bool found = false;
84
85 EFI_PRINT("%s: Enter, %p, %p\n", __func__, regs, db);
86
87 if (!regs || !db || !db->sig_data_list)
88 goto out;
89
90 for (siglist = db; siglist; siglist = siglist->next) {
91 /* TODO: support other hash algorithms */
92 if (guidcmp(&siglist->sig_type, &efi_guid_sha256)) {
93 EFI_PRINT("Digest algorithm is not supported: %pUl\n",
94 &siglist->sig_type);
95 break;
96 }
97
98 if (!efi_hash_regions(regs->reg, regs->num, &hash, &size)) {
99 EFI_PRINT("Digesting an image failed\n");
100 break;
101 }
102
103 for (sig_data = siglist->sig_data_list; sig_data;
104 sig_data = sig_data->next) {
105#ifdef DEBUG
106 EFI_PRINT("Msg digest in database:\n");
107 print_hex_dump(" ", DUMP_PREFIX_OFFSET, 16, 1,
108 sig_data->data, sig_data->size, false);
109#endif
110 if (sig_data->size == size &&
111 !memcmp(sig_data->data, hash, size)) {
112 found = true;
113 free(hash);
114 goto out;
115 }
116 }
117
118 free(hash);
119 hash = NULL;
120 }
121
122out:
123 EFI_PRINT("%s: Exit, found: %d\n", __func__, found);
124 return found;
125}
126
127/**
AKASHI Takahiro1115edd2020-07-21 19:35:22 +0900128 * efi_lookup_certificate - find a certificate within db
129 * @msg: Signature
130 * @db: Signature database
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900131 *
AKASHI Takahiro1115edd2020-07-21 19:35:22 +0900132 * Search signature database pointed to by @db and find a certificate
133 * pointed to by @cert.
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900134 *
AKASHI Takahiro1115edd2020-07-21 19:35:22 +0900135 * Return: true if found, false otherwise.
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900136 */
AKASHI Takahiro1115edd2020-07-21 19:35:22 +0900137static bool efi_lookup_certificate(struct x509_certificate *cert,
138 struct efi_signature_store *db)
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900139{
AKASHI Takahiro1115edd2020-07-21 19:35:22 +0900140 struct efi_signature_store *siglist;
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900141 struct efi_sig_data *sig_data;
AKASHI Takahiro1115edd2020-07-21 19:35:22 +0900142 struct image_region reg[1];
143 void *hash = NULL, *hash_tmp = NULL;
144 size_t size = 0;
145 bool found = false;
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900146
AKASHI Takahiro1115edd2020-07-21 19:35:22 +0900147 EFI_PRINT("%s: Enter, %p, %p\n", __func__, cert, db);
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900148
AKASHI Takahiro1115edd2020-07-21 19:35:22 +0900149 if (!cert || !db || !db->sig_data_list)
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900150 goto out;
AKASHI Takahiro1115edd2020-07-21 19:35:22 +0900151
152 /*
153 * TODO: identify a certificate using sha256 digest
154 * Is there any better way?
155 */
156 /* calculate hash of TBSCertificate */
157 reg[0].data = cert->tbs;
158 reg[0].size = cert->tbs_size;
159 if (!efi_hash_regions(reg, 1, &hash, &size))
160 goto out;
161
162 EFI_PRINT("%s: searching for %s\n", __func__, cert->subject);
163 for (siglist = db; siglist; siglist = siglist->next) {
164 /* only with x509 certificate */
165 if (guidcmp(&siglist->sig_type, &efi_guid_cert_x509))
166 continue;
167
168 for (sig_data = siglist->sig_data_list; sig_data;
169 sig_data = sig_data->next) {
170 struct x509_certificate *cert_tmp;
171
172 cert_tmp = x509_cert_parse(sig_data->data,
173 sig_data->size);
174 if (IS_ERR_OR_NULL(cert_tmp))
175 continue;
176
177 reg[0].data = cert_tmp->tbs;
178 reg[0].size = cert_tmp->tbs_size;
179 if (!efi_hash_regions(reg, 1, &hash_tmp, NULL))
180 goto out;
181
182 x509_free_certificate(cert_tmp);
183
184 if (!memcmp(hash, hash_tmp, size)) {
185 found = true;
186 goto out;
187 }
188 }
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900189 }
AKASHI Takahiro1115edd2020-07-21 19:35:22 +0900190out:
191 free(hash);
192 free(hash_tmp);
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900193
AKASHI Takahiro1115edd2020-07-21 19:35:22 +0900194 EFI_PRINT("%s: Exit, found: %d\n", __func__, found);
195 return found;
196}
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900197
AKASHI Takahiro1115edd2020-07-21 19:35:22 +0900198/**
199 * efi_verify_certificate - verify certificate's signature with database
200 * @signer: Certificate
201 * @db: Signature database
202 * @root: Certificate to verify @signer
203 *
204 * Determine if certificate pointed to by @signer may be verified
205 * by one of certificates in signature database pointed to by @db.
206 *
207 * Return: true if certificate is verified, false otherwise.
208 */
209static bool efi_verify_certificate(struct x509_certificate *signer,
210 struct efi_signature_store *db,
211 struct x509_certificate **root)
212{
213 struct efi_signature_store *siglist;
214 struct efi_sig_data *sig_data;
215 struct x509_certificate *cert;
216 bool verified = false;
217 int ret;
218
219 EFI_PRINT("%s: Enter, %p, %p\n", __func__, signer, db);
220
221 if (!signer || !db || !db->sig_data_list)
222 goto out;
223
224 for (siglist = db; siglist; siglist = siglist->next) {
225 /* only with x509 certificate */
226 if (guidcmp(&siglist->sig_type, &efi_guid_cert_x509))
227 continue;
228
229 for (sig_data = siglist->sig_data_list; sig_data;
230 sig_data = sig_data->next) {
231 cert = x509_cert_parse(sig_data->data, sig_data->size);
232 if (IS_ERR_OR_NULL(cert)) {
233 EFI_PRINT("Cannot parse x509 certificate\n");
234 continue;
235 }
236
237 ret = public_key_verify_signature(cert->pub,
238 signer->sig);
239 if (!ret) {
240 verified = true;
241 if (root)
242 *root = cert;
243 else
244 x509_free_certificate(cert);
245 goto out;
246 }
247 x509_free_certificate(cert);
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900248 }
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900249 }
250
251out:
AKASHI Takahiro3e9019d42020-06-09 14:09:33 +0900252 EFI_PRINT("%s: Exit, verified: %d\n", __func__, verified);
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900253 return verified;
254}
255
256/**
AKASHI Takahiro11bafb22020-07-08 14:01:56 +0900257 * efi_signature_check_revocation - check revocation with dbx
258 * @sinfo: Signer's info
259 * @cert: x509 certificate
260 * @dbx: Revocation signature database
261 *
262 * Search revocation signature database pointed to by @dbx and find
263 * an entry matching to certificate pointed to by @cert.
264 *
265 * While this entry contains revocation time, we don't support timestamp
266 * protocol at this time and any image will be unconditionally revoked
267 * when this match occurs.
268 *
269 * Return: true if check passed, false otherwise.
270 */
271static bool efi_signature_check_revocation(struct pkcs7_signed_info *sinfo,
272 struct x509_certificate *cert,
273 struct efi_signature_store *dbx)
274{
275 struct efi_signature_store *siglist;
276 struct efi_sig_data *sig_data;
277 struct image_region reg[1];
278 void *hash = NULL;
279 size_t size = 0;
280 time64_t revoc_time;
281 bool revoked = false;
282
283 EFI_PRINT("%s: Enter, %p, %p, %p\n", __func__, sinfo, cert, dbx);
284
285 if (!sinfo || !cert || !dbx || !dbx->sig_data_list)
286 goto out;
287
288 EFI_PRINT("Checking revocation against %s\n", cert->subject);
289 for (siglist = dbx; siglist; siglist = siglist->next) {
290 if (guidcmp(&siglist->sig_type, &efi_guid_cert_x509_sha256))
291 continue;
292
293 /* calculate hash of TBSCertificate */
294 reg[0].data = cert->tbs;
295 reg[0].size = cert->tbs_size;
296 if (!efi_hash_regions(reg, 1, &hash, &size))
297 goto out;
298
299 for (sig_data = siglist->sig_data_list; sig_data;
300 sig_data = sig_data->next) {
301 /*
302 * struct efi_cert_x509_sha256 {
303 * u8 tbs_hash[256/8];
304 * time64_t revocation_time;
305 * };
306 */
307#ifdef DEBUG
308 if (sig_data->size >= size) {
309 EFI_PRINT("hash in db:\n");
310 print_hex_dump(" ", DUMP_PREFIX_OFFSET,
311 16, 1,
312 sig_data->data, size, false);
313 }
314#endif
315 if ((sig_data->size < size + sizeof(time64_t)) ||
316 memcmp(sig_data->data, hash, size))
317 continue;
318
319 memcpy(&revoc_time, sig_data->data + size,
320 sizeof(revoc_time));
321 EFI_PRINT("revocation time: 0x%llx\n", revoc_time);
322 /*
323 * TODO: compare signing timestamp in sinfo
324 * with revocation time
325 */
326
327 revoked = true;
328 free(hash);
329 goto out;
330 }
331 free(hash);
332 hash = NULL;
333 }
334out:
335 EFI_PRINT("%s: Exit, revoked: %d\n", __func__, revoked);
336 return !revoked;
337}
338
339/**
340 * efi_signature_verify_one - verify signatures with database
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900341 * @regs: List of regions to be authenticated
342 * @msg: Signature
AKASHI Takahiro11bafb22020-07-08 14:01:56 +0900343 * @db: Signature database
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900344 *
AKASHI Takahiro11bafb22020-07-08 14:01:56 +0900345 * All the signature pointed to by @msg against image pointed to by @regs
346 * will be verified by signature database pointed to by @db.
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900347 *
AKASHI Takahiro11bafb22020-07-08 14:01:56 +0900348 * Return: true if verification for one of signatures passed, false
349 * otherwise
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900350 */
AKASHI Takahiro11bafb22020-07-08 14:01:56 +0900351bool efi_signature_verify_one(struct efi_image_regions *regs,
352 struct pkcs7_message *msg,
353 struct efi_signature_store *db)
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900354{
AKASHI Takahiro11bafb22020-07-08 14:01:56 +0900355 struct pkcs7_signed_info *sinfo;
AKASHI Takahiro1115edd2020-07-21 19:35:22 +0900356 struct x509_certificate *signer;
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900357 bool verified = false;
AKASHI Takahiro1115edd2020-07-21 19:35:22 +0900358 int ret;
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900359
AKASHI Takahiro11bafb22020-07-08 14:01:56 +0900360 EFI_PRINT("%s: Enter, %p, %p, %p\n", __func__, regs, msg, db);
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900361
362 if (!db)
363 goto out;
364
365 if (!db->sig_data_list)
366 goto out;
367
AKASHI Takahiro11bafb22020-07-08 14:01:56 +0900368 EFI_PRINT("%s: Verify signed image with db\n", __func__);
369 for (sinfo = msg->signed_infos; sinfo; sinfo = sinfo->next) {
370 EFI_PRINT("Signed Info: digest algo: %s, pkey algo: %s\n",
371 sinfo->sig->hash_algo, sinfo->sig->pkey_algo);
372
AKASHI Takahiro1115edd2020-07-21 19:35:22 +0900373 EFI_PRINT("Verifying certificate chain\n");
374 signer = NULL;
375 ret = pkcs7_verify_one(msg, sinfo, &signer);
376 if (ret == -ENOPKG)
377 continue;
378
379 if (ret < 0 || !signer)
380 goto out;
381
382 if (sinfo->blacklisted)
383 continue;
384
385 EFI_PRINT("Verifying last certificate in chain\n");
386 if (signer->self_signed) {
387 if (efi_lookup_certificate(signer, db)) {
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900388 verified = true;
389 goto out;
390 }
AKASHI Takahiro1115edd2020-07-21 19:35:22 +0900391 } else if (efi_verify_certificate(signer, db, NULL)) {
392 verified = true;
393 goto out;
394 }
395 EFI_PRINT("Valid certificate not in db\n");
AKASHI Takahiro11bafb22020-07-08 14:01:56 +0900396 }
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900397
AKASHI Takahiro11bafb22020-07-08 14:01:56 +0900398out:
399 EFI_PRINT("%s: Exit, verified: %d\n", __func__, verified);
400 return verified;
401}
402
AKASHI Takahiro1115edd2020-07-21 19:35:22 +0900403/*
404 * efi_signature_verify - verify signatures with db and dbx
AKASHI Takahiro11bafb22020-07-08 14:01:56 +0900405 * @regs: List of regions to be authenticated
406 * @msg: Signature
407 * @db: Signature database for trusted certificates
408 * @dbx: Revocation signature database
409 *
410 * All the signature pointed to by @msg against image pointed to by @regs
411 * will be verified by signature database pointed to by @db and @dbx.
412 *
413 * Return: true if verification for all signatures passed, false otherwise
414 */
AKASHI Takahiro1115edd2020-07-21 19:35:22 +0900415bool efi_signature_verify(struct efi_image_regions *regs,
416 struct pkcs7_message *msg,
417 struct efi_signature_store *db,
418 struct efi_signature_store *dbx)
AKASHI Takahiro11bafb22020-07-08 14:01:56 +0900419{
AKASHI Takahiro1115edd2020-07-21 19:35:22 +0900420 struct pkcs7_signed_info *sinfo;
421 struct x509_certificate *signer, *root;
AKASHI Takahiro11bafb22020-07-08 14:01:56 +0900422 bool verified = false;
AKASHI Takahiro1115edd2020-07-21 19:35:22 +0900423 int ret;
AKASHI Takahiro11bafb22020-07-08 14:01:56 +0900424
425 EFI_PRINT("%s: Enter, %p, %p, %p, %p\n", __func__, regs, msg, db, dbx);
426
AKASHI Takahiro7926dfb2020-07-08 14:01:57 +0900427 if (!regs || !msg || !db || !db->sig_data_list)
AKASHI Takahiro11bafb22020-07-08 14:01:56 +0900428 goto out;
429
AKASHI Takahiro1115edd2020-07-21 19:35:22 +0900430 for (sinfo = msg->signed_infos; sinfo; sinfo = sinfo->next) {
AKASHI Takahiro3e9019d42020-06-09 14:09:33 +0900431 EFI_PRINT("Signed Info: digest algo: %s, pkey algo: %s\n",
AKASHI Takahiro1115edd2020-07-21 19:35:22 +0900432 sinfo->sig->hash_algo, sinfo->sig->pkey_algo);
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900433
AKASHI Takahiro1115edd2020-07-21 19:35:22 +0900434 /*
435 * only for authenticated variable.
436 *
437 * If this function is called for image,
438 * hash calculation will be done in
439 * pkcs7_verify_one().
440 */
441 if (!msg->data &&
442 !efi_hash_regions(regs->reg, regs->num,
443 (void **)&sinfo->sig->digest, NULL)) {
444 EFI_PRINT("Digesting an image failed\n");
AKASHI Takahiro11bafb22020-07-08 14:01:56 +0900445 goto out;
446 }
447
AKASHI Takahiro1115edd2020-07-21 19:35:22 +0900448 EFI_PRINT("Verifying certificate chain\n");
449 signer = NULL;
450 ret = pkcs7_verify_one(msg, sinfo, &signer);
451 if (ret == -ENOPKG)
AKASHI Takahiro11bafb22020-07-08 14:01:56 +0900452 continue;
453
AKASHI Takahiro1115edd2020-07-21 19:35:22 +0900454 if (ret < 0 || !signer)
455 goto out;
456
457 if (sinfo->blacklisted)
458 goto out;
459
460 EFI_PRINT("Verifying last certificate in chain\n");
461 if (signer->self_signed) {
462 if (efi_lookup_certificate(signer, db))
463 if (efi_signature_check_revocation(sinfo,
464 signer, dbx))
465 continue;
466 } else if (efi_verify_certificate(signer, db, &root)) {
467 bool check;
468
469 check = efi_signature_check_revocation(sinfo, root,
470 dbx);
471 x509_free_certificate(root);
472 if (check)
473 continue;
474 }
475
476 EFI_PRINT("Certificate chain didn't reach trusted CA\n");
AKASHI Takahiro11bafb22020-07-08 14:01:56 +0900477 goto out;
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900478 }
AKASHI Takahiro11bafb22020-07-08 14:01:56 +0900479 verified = true;
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900480out:
AKASHI Takahiro3e9019d42020-06-09 14:09:33 +0900481 EFI_PRINT("%s: Exit, verified: %d\n", __func__, verified);
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900482 return verified;
483}
484
485/**
AKASHI Takahiro11bafb22020-07-08 14:01:56 +0900486 * efi_signature_check_signers - check revocation against all signers with dbx
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900487 * @msg: Signature
AKASHI Takahiro11bafb22020-07-08 14:01:56 +0900488 * @dbx: Revocation signature database
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900489 *
AKASHI Takahiro11bafb22020-07-08 14:01:56 +0900490 * Determine if none of signers' certificates in @msg are revoked
491 * by signature database pointed to by @dbx.
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900492 *
AKASHI Takahiro11bafb22020-07-08 14:01:56 +0900493 * Return: true if all signers passed, false otherwise.
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900494 */
AKASHI Takahiro11bafb22020-07-08 14:01:56 +0900495bool efi_signature_check_signers(struct pkcs7_message *msg,
496 struct efi_signature_store *dbx)
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900497{
AKASHI Takahiro11bafb22020-07-08 14:01:56 +0900498 struct pkcs7_signed_info *sinfo;
499 bool revoked = false;
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900500
AKASHI Takahiro3e9019d42020-06-09 14:09:33 +0900501 EFI_PRINT("%s: Enter, %p, %p\n", __func__, msg, dbx);
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900502
AKASHI Takahiro11bafb22020-07-08 14:01:56 +0900503 if (!msg || !dbx)
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900504 goto out;
505
AKASHI Takahiro11bafb22020-07-08 14:01:56 +0900506 for (sinfo = msg->signed_infos; sinfo; sinfo = sinfo->next) {
507 if (sinfo->signer &&
508 !efi_signature_check_revocation(sinfo, sinfo->signer,
509 dbx)) {
510 revoked = true;
511 break;
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900512 }
513 }
514out:
AKASHI Takahiro11bafb22020-07-08 14:01:56 +0900515 EFI_PRINT("%s: Exit, revoked: %d\n", __func__, revoked);
516 return !revoked;
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900517}
518
519/**
Heinrich Schuchardt28164c92020-07-01 20:01:52 +0200520 * efi_image_region_add() - add an entry of region
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900521 * @regs: Pointer to array of regions
Heinrich Schuchardt28164c92020-07-01 20:01:52 +0200522 * @start: Start address of region (included)
523 * @end: End address of region (excluded)
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900524 * @nocheck: flag against overlapped regions
525 *
Heinrich Schuchardt28164c92020-07-01 20:01:52 +0200526 * Take one entry of region [@start, @end[ and insert it into the list.
527 *
528 * * If @nocheck is false, the list will be sorted ascending by address.
529 * Overlapping entries will not be allowed.
530 *
531 * * If @nocheck is true, the list will be sorted ascending by sequence
532 * of adding the entries. Overlapping is allowed.
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900533 *
Heinrich Schuchardt30f92ce2020-05-03 16:29:00 +0200534 * Return: status code
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900535 */
536efi_status_t efi_image_region_add(struct efi_image_regions *regs,
537 const void *start, const void *end,
538 int nocheck)
539{
540 struct image_region *reg;
541 int i, j;
542
543 if (regs->num >= regs->max) {
AKASHI Takahiro3e9019d42020-06-09 14:09:33 +0900544 EFI_PRINT("%s: no more room for regions\n", __func__);
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900545 return EFI_OUT_OF_RESOURCES;
546 }
547
548 if (end < start)
549 return EFI_INVALID_PARAMETER;
550
551 for (i = 0; i < regs->num; i++) {
552 reg = &regs->reg[i];
553 if (nocheck)
554 continue;
555
Heinrich Schuchardt28164c92020-07-01 20:01:52 +0200556 /* new data after registered region */
557 if (start >= reg->data + reg->size)
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900558 continue;
559
Heinrich Schuchardt28164c92020-07-01 20:01:52 +0200560 /* new data preceding registered region */
561 if (end <= reg->data) {
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900562 for (j = regs->num - 1; j >= i; j--)
Heinrich Schuchardt28164c92020-07-01 20:01:52 +0200563 memcpy(&regs->reg[j + 1], &regs->reg[j],
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900564 sizeof(*reg));
565 break;
566 }
Heinrich Schuchardt28164c92020-07-01 20:01:52 +0200567
568 /* new data overlapping registered region */
569 EFI_PRINT("%s: new region already part of another\n", __func__);
570 return EFI_INVALID_PARAMETER;
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900571 }
572
573 reg = &regs->reg[i];
574 reg->data = start;
575 reg->size = end - start;
576 regs->num++;
577
578 return EFI_SUCCESS;
579}
AKASHI Takahirobe6296d2020-04-14 11:51:40 +0900580
581/**
582 * efi_sigstore_free - free signature store
583 * @sigstore: Pointer to signature store structure
584 *
585 * Feee all the memories held in signature store and itself,
586 * which were allocated by efi_sigstore_parse_sigdb().
587 */
588void efi_sigstore_free(struct efi_signature_store *sigstore)
589{
590 struct efi_signature_store *sigstore_next;
591 struct efi_sig_data *sig_data, *sig_data_next;
592
593 while (sigstore) {
594 sigstore_next = sigstore->next;
595
596 sig_data = sigstore->sig_data_list;
597 while (sig_data) {
598 sig_data_next = sig_data->next;
599 free(sig_data->data);
600 free(sig_data);
601 sig_data = sig_data_next;
602 }
603
604 free(sigstore);
605 sigstore = sigstore_next;
606 }
607}
608
609/**
610 * efi_sigstore_parse_siglist - parse a signature list
611 * @name: Pointer to signature list
612 *
613 * Parse signature list and instantiate a signature store structure.
614 * Signature database is a simple concatenation of one or more
615 * signature list(s).
616 *
617 * Return: Pointer to signature store on success, NULL on error
618 */
619static struct efi_signature_store *
620efi_sigstore_parse_siglist(struct efi_signature_list *esl)
621{
622 struct efi_signature_store *siglist = NULL;
623 struct efi_sig_data *sig_data, *sig_data_next;
624 struct efi_signature_data *esd;
625 size_t left;
626
627 /*
628 * UEFI specification defines certificate types:
629 * for non-signed images,
630 * EFI_CERT_SHA256_GUID
631 * EFI_CERT_RSA2048_GUID
632 * EFI_CERT_RSA2048_SHA256_GUID
633 * EFI_CERT_SHA1_GUID
634 * EFI_CERT_RSA2048_SHA_GUID
635 * EFI_CERT_SHA224_GUID
636 * EFI_CERT_SHA384_GUID
637 * EFI_CERT_SHA512_GUID
638 *
639 * for signed images,
640 * EFI_CERT_X509_GUID
641 * NOTE: Each certificate will normally be in a separate
642 * EFI_SIGNATURE_LIST as the size may vary depending on
643 * its algo's.
644 *
645 * for timestamp revocation of certificate,
646 * EFI_CERT_X509_SHA512_GUID
647 * EFI_CERT_X509_SHA256_GUID
648 * EFI_CERT_X509_SHA384_GUID
649 */
650
651 if (esl->signature_list_size
652 <= (sizeof(*esl) + esl->signature_header_size)) {
AKASHI Takahiro3e9019d42020-06-09 14:09:33 +0900653 EFI_PRINT("Siglist in wrong format\n");
AKASHI Takahirobe6296d2020-04-14 11:51:40 +0900654 return NULL;
655 }
656
657 /* Create a head */
658 siglist = calloc(sizeof(*siglist), 1);
659 if (!siglist) {
AKASHI Takahiro3e9019d42020-06-09 14:09:33 +0900660 EFI_PRINT("Out of memory\n");
AKASHI Takahirobe6296d2020-04-14 11:51:40 +0900661 goto err;
662 }
663 memcpy(&siglist->sig_type, &esl->signature_type, sizeof(efi_guid_t));
664
665 /* Go through the list */
666 sig_data_next = NULL;
667 left = esl->signature_list_size
668 - (sizeof(*esl) + esl->signature_header_size);
669 esd = (struct efi_signature_data *)
670 ((u8 *)esl + sizeof(*esl) + esl->signature_header_size);
671
AKASHI Takahiro964d5322020-04-21 09:38:57 +0900672 while (left > 0) {
AKASHI Takahirobe6296d2020-04-14 11:51:40 +0900673 /* Signature must exist if there is remaining data. */
674 if (left < esl->signature_size) {
AKASHI Takahiro3e9019d42020-06-09 14:09:33 +0900675 EFI_PRINT("Certificate is too small\n");
AKASHI Takahirobe6296d2020-04-14 11:51:40 +0900676 goto err;
677 }
678
679 sig_data = calloc(esl->signature_size
680 - sizeof(esd->signature_owner), 1);
681 if (!sig_data) {
AKASHI Takahiro3e9019d42020-06-09 14:09:33 +0900682 EFI_PRINT("Out of memory\n");
AKASHI Takahirobe6296d2020-04-14 11:51:40 +0900683 goto err;
684 }
685
686 /* Append signature data */
687 memcpy(&sig_data->owner, &esd->signature_owner,
688 sizeof(efi_guid_t));
689 sig_data->size = esl->signature_size
690 - sizeof(esd->signature_owner);
691 sig_data->data = malloc(sig_data->size);
692 if (!sig_data->data) {
AKASHI Takahiro3e9019d42020-06-09 14:09:33 +0900693 EFI_PRINT("Out of memory\n");
AKASHI Takahirobe6296d2020-04-14 11:51:40 +0900694 goto err;
695 }
696 memcpy(sig_data->data, esd->signature_data, sig_data->size);
697
698 sig_data->next = sig_data_next;
699 sig_data_next = sig_data;
700
701 /* Next */
702 esd = (struct efi_signature_data *)
703 ((u8 *)esd + esl->signature_size);
704 left -= esl->signature_size;
705 }
706 siglist->sig_data_list = sig_data_next;
707
708 return siglist;
709
710err:
711 efi_sigstore_free(siglist);
712
713 return NULL;
714}
715
716/**
717 * efi_sigstore_parse_sigdb - parse a signature database variable
718 * @name: Variable's name
719 *
720 * Read in a value of signature database variable pointed to by
721 * @name, parse it and instantiate a signature store structure.
722 *
723 * Return: Pointer to signature store on success, NULL on error
724 */
725struct efi_signature_store *efi_sigstore_parse_sigdb(u16 *name)
726{
727 struct efi_signature_store *sigstore = NULL, *siglist;
728 struct efi_signature_list *esl;
729 const efi_guid_t *vendor;
730 void *db;
731 efi_uintn_t db_size;
732 efi_status_t ret;
733
734 if (!u16_strcmp(name, L"PK") || !u16_strcmp(name, L"KEK")) {
735 vendor = &efi_global_variable_guid;
736 } else if (!u16_strcmp(name, L"db") || !u16_strcmp(name, L"dbx")) {
737 vendor = &efi_guid_image_security_database;
738 } else {
AKASHI Takahiro3e9019d42020-06-09 14:09:33 +0900739 EFI_PRINT("unknown signature database, %ls\n", name);
AKASHI Takahirobe6296d2020-04-14 11:51:40 +0900740 return NULL;
741 }
742
743 /* retrieve variable data */
744 db_size = 0;
745 ret = EFI_CALL(efi_get_variable(name, vendor, NULL, &db_size, NULL));
746 if (ret == EFI_NOT_FOUND) {
AKASHI Takahiro3e9019d42020-06-09 14:09:33 +0900747 EFI_PRINT("variable, %ls, not found\n", name);
AKASHI Takahirobe6296d2020-04-14 11:51:40 +0900748 sigstore = calloc(sizeof(*sigstore), 1);
749 return sigstore;
750 } else if (ret != EFI_BUFFER_TOO_SMALL) {
AKASHI Takahiro3e9019d42020-06-09 14:09:33 +0900751 EFI_PRINT("Getting variable, %ls, failed\n", name);
AKASHI Takahirobe6296d2020-04-14 11:51:40 +0900752 return NULL;
753 }
754
755 db = malloc(db_size);
756 if (!db) {
AKASHI Takahiro3e9019d42020-06-09 14:09:33 +0900757 EFI_PRINT("Out of memory\n");
AKASHI Takahirobe6296d2020-04-14 11:51:40 +0900758 return NULL;
759 }
760
761 ret = EFI_CALL(efi_get_variable(name, vendor, NULL, &db_size, db));
762 if (ret != EFI_SUCCESS) {
AKASHI Takahiro3e9019d42020-06-09 14:09:33 +0900763 EFI_PRINT("Getting variable, %ls, failed\n", name);
AKASHI Takahirobe6296d2020-04-14 11:51:40 +0900764 goto err;
765 }
766
767 /* Parse siglist list */
768 esl = db;
769 while (db_size > 0) {
770 /* List must exist if there is remaining data. */
771 if (db_size < sizeof(*esl)) {
AKASHI Takahiro3e9019d42020-06-09 14:09:33 +0900772 EFI_PRINT("variable, %ls, in wrong format\n", name);
AKASHI Takahirobe6296d2020-04-14 11:51:40 +0900773 goto err;
774 }
775
776 if (db_size < esl->signature_list_size) {
AKASHI Takahiro3e9019d42020-06-09 14:09:33 +0900777 EFI_PRINT("variable, %ls, in wrong format\n", name);
AKASHI Takahirobe6296d2020-04-14 11:51:40 +0900778 goto err;
779 }
780
781 /* Parse a single siglist. */
782 siglist = efi_sigstore_parse_siglist(esl);
783 if (!siglist) {
AKASHI Takahiro3e9019d42020-06-09 14:09:33 +0900784 EFI_PRINT("Parsing signature list of %ls failed\n",
785 name);
AKASHI Takahirobe6296d2020-04-14 11:51:40 +0900786 goto err;
787 }
788
789 /* Append siglist */
790 siglist->next = sigstore;
791 sigstore = siglist;
792
793 /* Next */
794 db_size -= esl->signature_list_size;
795 esl = (void *)esl + esl->signature_list_size;
796 }
797 free(db);
798
799 return sigstore;
800
801err:
802 efi_sigstore_free(sigstore);
803 free(db);
804
805 return NULL;
806}
AKASHI Takahiro593e17d2020-04-14 11:51:39 +0900807#endif /* CONFIG_EFI_SECURE_BOOT */