]> git.proxmox.com Git - efi-boot-shim.git/blame - shim.c
Force usage of newest revocations at build time
[efi-boot-shim.git] / shim.c
CommitLineData
031e5cce
SM
1// SPDX-License-Identifier: BSD-2-Clause-Patent
2
f898777d
MG
3/*
4 * shim - trivial UEFI first-stage bootloader
5 *
031e5cce
SM
6 * Copyright Red Hat, Inc
7 * Author: Matthew Garrett
f898777d
MG
8 *
9 * Significant portions of this code are derived from Tianocore
10 * (http://tianocore.sf.net) and are Copyright 2009-2012 Intel
11 * Corporation.
12 */
13
f4b24734 14#include "shim.h"
031e5cce
SM
15#if defined(ENABLE_SHIM_CERT)
16#include "shim_cert.h"
17#endif /* defined(ENABLE_SHIM_CERT) */
7bf7a6d0 18
b6f94dbe
MTL
19#include <openssl/err.h>
20#include <openssl/bn.h>
21#include <openssl/dh.h>
22#include <openssl/ocsp.h>
23#include <openssl/pkcs12.h>
24#include <openssl/rand.h>
25#include <openssl/crypto.h>
26#include <openssl/ssl.h>
62f0afa2
MTL
27#include <openssl/x509.h>
28#include <openssl/x509v3.h>
b6f94dbe 29#include <openssl/rsa.h>
031e5cce 30#include <openssl/dso.h>
b6f94dbe
MTL
31
32#include <Library/BaseCryptLib.h>
62f0afa2 33
f892ac66 34#include <stdint.h>
62f0afa2
MTL
35
36#define OID_EKU_MODSIGN "1.3.6.1.4.1.2312.16.1.2"
f898777d 37
7f055335 38static EFI_SYSTEM_TABLE *systab;
f4173af1 39static EFI_HANDLE global_image_handle;
031e5cce
SM
40static EFI_LOADED_IMAGE *shim_li;
41static EFI_LOADED_IMAGE shim_li_bak;
7f055335 42
031e5cce 43list_t sbat_var;
cb59de38 44
f898777d
MG
45/*
46 * The vendor certificate used for validating the second stage loader
47 */
a1f28635 48extern struct {
031e5cce
SM
49 UINT32 vendor_authorized_size;
50 UINT32 vendor_deauthorized_size;
51 UINT32 vendor_authorized_offset;
52 UINT32 vendor_deauthorized_offset;
a1f28635
PJ
53} cert_table;
54
c13fc2f7
MG
55#define EFI_IMAGE_SECURITY_DATABASE_GUID { 0xd719b2cb, 0x3d3a, 0x4596, { 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f }}
56
c16548d0
MG
57typedef enum {
58 DATA_FOUND,
59 DATA_NOT_FOUND,
60 VAR_NOT_FOUND
61} CHECK_STATUS;
62
13422973
GCPL
63typedef struct {
64 UINT32 MokSize;
65 UINT8 *Mok;
66} MokListNode;
67
b6f94dbe
MTL
68static void
69drain_openssl_errors(void)
70{
71 unsigned long err = -1;
72 while (err != 0)
73 err = ERR_get_error();
74}
75
b8070380
GCPL
76static BOOLEAN verify_x509(UINT8 *Cert, UINTN CertSize)
77{
78 UINTN length;
79
80 if (!Cert || CertSize < 4)
81 return FALSE;
82
83 /*
84 * A DER encoding x509 certificate starts with SEQUENCE(0x30),
85 * the number of length bytes, and the number of value bytes.
86 * The size of a x509 certificate is usually between 127 bytes
87 * and 64KB. For convenience, assume the number of value bytes
88 * is 2, i.e. the second byte is 0x82.
89 */
031e5cce
SM
90 if (Cert[0] != 0x30 || Cert[1] != 0x82) {
91 dprint(L"cert[0:1] is [%02x%02x], should be [%02x%02x]\n",
92 Cert[0], Cert[1], 0x30, 0x82);
b8070380 93 return FALSE;
031e5cce 94 }
b8070380
GCPL
95
96 length = Cert[2]<<8 | Cert[3];
031e5cce
SM
97 if (length != (CertSize - 4)) {
98 dprint(L"Cert length is %ld, expecting %ld\n",
99 length, CertSize);
b8070380 100 return FALSE;
031e5cce 101 }
b8070380
GCPL
102
103 return TRUE;
104}
105
62f0afa2
MTL
106static BOOLEAN verify_eku(UINT8 *Cert, UINTN CertSize)
107{
108 X509 *x509;
109 CONST UINT8 *Temp = Cert;
110 EXTENDED_KEY_USAGE *eku;
111 ASN1_OBJECT *module_signing;
112
031e5cce
SM
113 module_signing = OBJ_nid2obj(OBJ_create(OID_EKU_MODSIGN,
114 "modsign-eku",
115 "modsign-eku"));
62f0afa2
MTL
116
117 x509 = d2i_X509 (NULL, &Temp, (long) CertSize);
118 if (x509 != NULL) {
119 eku = X509_get_ext_d2i(x509, NID_ext_key_usage, NULL, NULL);
120
121 if (eku) {
122 int i = 0;
123 for (i = 0; i < sk_ASN1_OBJECT_num(eku); i++) {
124 ASN1_OBJECT *key_usage = sk_ASN1_OBJECT_value(eku, i);
125
126 if (OBJ_cmp(module_signing, key_usage) == 0)
127 return FALSE;
128 }
129 EXTENDED_KEY_USAGE_free(eku);
130 }
131
132 X509_free(x509);
133 }
134
031e5cce 135 OBJ_cleanup();
62f0afa2 136
031e5cce 137 return TRUE;
7bf7a6d0
MTL
138}
139
5f0a358b
PJ
140static CHECK_STATUS check_db_cert_in_ram(EFI_SIGNATURE_LIST *CertList,
141 UINTN dbsize,
142 WIN_CERTIFICATE_EFI_PKCS *data,
b6f94dbe
MTL
143 UINT8 *hash, CHAR16 *dbname,
144 EFI_GUID guid)
3df68c18 145{
3df68c18 146 EFI_SIGNATURE_DATA *Cert;
b8070380 147 UINTN CertSize;
c13fc2f7 148 BOOLEAN IsFound = FALSE;
031e5cce 149 int i = 0;
c16548d0 150
c16548d0 151 while ((dbsize > 0) && (dbsize >= CertList->SignatureListSize)) {
f892ac66 152 if (CompareGuid (&CertList->SignatureType, &EFI_CERT_TYPE_X509_GUID) == 0) {
c16548d0 153 Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
b8070380 154 CertSize = CertList->SignatureSize - sizeof(EFI_GUID);
031e5cce 155 dprint(L"trying to verify cert %d (%s)\n", i++, dbname);
b8070380 156 if (verify_x509(Cert->SignatureData, CertSize)) {
62f0afa2 157 if (verify_eku(Cert->SignatureData, CertSize)) {
031e5cce 158 drain_openssl_errors();
62f0afa2
MTL
159 IsFound = AuthenticodeVerify (data->CertData,
160 data->Hdr.dwLength - sizeof(data->Hdr),
161 Cert->SignatureData,
162 CertSize,
163 hash, SHA256_DIGEST_SIZE);
b6f94dbe 164 if (IsFound) {
031e5cce
SM
165 dprint(L"AuthenticodeVerify() succeeded: %d\n", IsFound);
166 tpm_measure_variable(dbname, guid, CertList->SignatureSize, Cert);
b6f94dbe 167 drain_openssl_errors();
f892ac66 168 return DATA_FOUND;
b6f94dbe
MTL
169 } else {
170 LogError(L"AuthenticodeVerify(): %d\n", IsFound);
171 }
62f0afa2 172 }
b8070380 173 } else if (verbose) {
031e5cce
SM
174 console_print(L"Not a DER encoded x.509 Certificate");
175 dprint(L"cert:\n");
176 dhexdumpat(Cert->SignatureData, CertSize, 0);
c16548d0 177 }
c16548d0
MG
178 }
179
180 dbsize -= CertList->SignatureListSize;
181 CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);
182 }
183
c16548d0
MG
184 return DATA_NOT_FOUND;
185}
186
5f0a358b
PJ
187static CHECK_STATUS check_db_cert(CHAR16 *dbname, EFI_GUID guid,
188 WIN_CERTIFICATE_EFI_PKCS *data, UINT8 *hash)
c16548d0 189{
5f0a358b 190 CHECK_STATUS rc;
c16548d0 191 EFI_STATUS efi_status;
c16548d0 192 EFI_SIGNATURE_LIST *CertList;
c16548d0 193 UINTN dbsize = 0;
7f0208a0 194 UINT8 *db;
3df68c18 195
7f0208a0 196 efi_status = get_variable(dbname, &db, &dbsize, guid);
f892ac66 197 if (EFI_ERROR(efi_status))
c16548d0 198 return VAR_NOT_FOUND;
3df68c18 199
7f0208a0 200 CertList = (EFI_SIGNATURE_LIST *)db;
3df68c18 201
b6f94dbe 202 rc = check_db_cert_in_ram(CertList, dbsize, data, hash, dbname, guid);
5f0a358b
PJ
203
204 FreePool(db);
205
206 return rc;
207}
208
20f6cde6
MG
209/*
210 * Check a hash against an EFI_SIGNATURE_LIST in a buffer
211 */
5f0a358b
PJ
212static CHECK_STATUS check_db_hash_in_ram(EFI_SIGNATURE_LIST *CertList,
213 UINTN dbsize, UINT8 *data,
b6f94dbe
MTL
214 int SignatureSize, EFI_GUID CertType,
215 CHAR16 *dbname, EFI_GUID guid)
5f0a358b
PJ
216{
217 EFI_SIGNATURE_DATA *Cert;
218 UINTN CertCount, Index;
219 BOOLEAN IsFound = FALSE;
220
c16548d0 221 while ((dbsize > 0) && (dbsize >= CertList->SignatureListSize)) {
d71240bf 222 CertCount = (CertList->SignatureListSize -sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
3df68c18 223 Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
c13fc2f7 224 if (CompareGuid(&CertList->SignatureType, &CertType) == 0) {
3df68c18 225 for (Index = 0; Index < CertCount; Index++) {
c16548d0 226 if (CompareMem (Cert->SignatureData, data, SignatureSize) == 0) {
3df68c18
MG
227 //
228 // Find the signature in database.
229 //
230 IsFound = TRUE;
031e5cce 231 tpm_measure_variable(dbname, guid, CertList->SignatureSize, Cert);
3df68c18
MG
232 break;
233 }
234
235 Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize);
236 }
237 if (IsFound) {
238 break;
239 }
240 }
241
c16548d0 242 dbsize -= CertList->SignatureListSize;
3df68c18
MG
243 CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);
244 }
245
3df68c18 246 if (IsFound)
c16548d0
MG
247 return DATA_FOUND;
248
249 return DATA_NOT_FOUND;
250}
251
20f6cde6
MG
252/*
253 * Check a hash against an EFI_SIGNATURE_LIST in a UEFI variable
254 */
5f0a358b
PJ
255static CHECK_STATUS check_db_hash(CHAR16 *dbname, EFI_GUID guid, UINT8 *data,
256 int SignatureSize, EFI_GUID CertType)
257{
258 EFI_STATUS efi_status;
259 EFI_SIGNATURE_LIST *CertList;
5f0a358b 260 UINTN dbsize = 0;
7f0208a0 261 UINT8 *db;
5f0a358b 262
7f0208a0 263 efi_status = get_variable(dbname, &db, &dbsize, guid);
f892ac66 264 if (EFI_ERROR(efi_status)) {
5f0a358b
PJ
265 return VAR_NOT_FOUND;
266 }
267
7f0208a0 268 CertList = (EFI_SIGNATURE_LIST *)db;
5f0a358b
PJ
269
270 CHECK_STATUS rc = check_db_hash_in_ram(CertList, dbsize, data,
b6f94dbe
MTL
271 SignatureSize, CertType,
272 dbname, guid);
5f0a358b
PJ
273 FreePool(db);
274 return rc;
275
276}
277
20f6cde6
MG
278/*
279 * Check whether the binary signature or hash are present in dbx or the
031e5cce 280 * built-in denylist
20f6cde6 281 */
031e5cce
SM
282static EFI_STATUS check_denylist (WIN_CERTIFICATE_EFI_PKCS *cert,
283 UINT8 *sha256hash, UINT8 *sha1hash)
c16548d0 284{
031e5cce 285 EFI_SIGNATURE_LIST *dbx = (EFI_SIGNATURE_LIST *)vendor_deauthorized;
0a6565c5 286
031e5cce 287 if (check_db_hash_in_ram(dbx, vendor_deauthorized_size, sha256hash,
f892ac66
MTL
288 SHA256_DIGEST_SIZE, EFI_CERT_SHA256_GUID, L"dbx",
289 EFI_SECURE_BOOT_DB_GUID) == DATA_FOUND) {
b6f94dbe 290 LogError(L"binary sha256hash found in vendor dbx\n");
f4173af1 291 return EFI_SECURITY_VIOLATION;
b6f94dbe 292 }
031e5cce 293 if (check_db_hash_in_ram(dbx, vendor_deauthorized_size, sha1hash,
f892ac66
MTL
294 SHA1_DIGEST_SIZE, EFI_CERT_SHA1_GUID, L"dbx",
295 EFI_SECURE_BOOT_DB_GUID) == DATA_FOUND) {
b6f94dbe 296 LogError(L"binary sha1hash found in vendor dbx\n");
f4173af1 297 return EFI_SECURITY_VIOLATION;
b6f94dbe 298 }
f892ac66 299 if (cert &&
031e5cce 300 check_db_cert_in_ram(dbx, vendor_deauthorized_size, cert, sha256hash, L"dbx",
f892ac66 301 EFI_SECURE_BOOT_DB_GUID) == DATA_FOUND) {
b6f94dbe 302 LogError(L"cert sha256hash found in vendor dbx\n");
f4173af1 303 return EFI_SECURITY_VIOLATION;
b6f94dbe 304 }
f892ac66
MTL
305 if (check_db_hash(L"dbx", EFI_SECURE_BOOT_DB_GUID, sha256hash,
306 SHA256_DIGEST_SIZE, EFI_CERT_SHA256_GUID) == DATA_FOUND) {
b6f94dbe 307 LogError(L"binary sha256hash found in system dbx\n");
f4173af1 308 return EFI_SECURITY_VIOLATION;
b6f94dbe 309 }
f892ac66
MTL
310 if (check_db_hash(L"dbx", EFI_SECURE_BOOT_DB_GUID, sha1hash,
311 SHA1_DIGEST_SIZE, EFI_CERT_SHA1_GUID) == DATA_FOUND) {
b6f94dbe 312 LogError(L"binary sha1hash found in system dbx\n");
f4173af1 313 return EFI_SECURITY_VIOLATION;
b6f94dbe 314 }
f892ac66
MTL
315 if (cert &&
316 check_db_cert(L"dbx", EFI_SECURE_BOOT_DB_GUID,
317 cert, sha256hash) == DATA_FOUND) {
b6f94dbe 318 LogError(L"cert sha256hash found in system dbx\n");
f4173af1 319 return EFI_SECURITY_VIOLATION;
b6f94dbe 320 }
f892ac66
MTL
321 if (check_db_hash(L"MokListX", SHIM_LOCK_GUID, sha256hash,
322 SHA256_DIGEST_SIZE, EFI_CERT_SHA256_GUID) == DATA_FOUND) {
b6f94dbe 323 LogError(L"binary sha256hash found in Mok dbx\n");
f4173af1 324 return EFI_SECURITY_VIOLATION;
d3819813 325 }
f892ac66
MTL
326 if (cert &&
327 check_db_cert(L"MokListX", SHIM_LOCK_GUID,
328 cert, sha256hash) == DATA_FOUND) {
b6f94dbe 329 LogError(L"cert sha256hash found in Mok dbx\n");
f4173af1 330 return EFI_SECURITY_VIOLATION;
d3819813 331 }
3df68c18 332
b6f94dbe 333 drain_openssl_errors();
3df68c18
MG
334 return EFI_SUCCESS;
335}
336
cbef697a
PJ
337static void update_verification_method(verification_method_t method)
338{
339 if (verification_method == VERIFIED_BY_NOTHING)
340 verification_method = method;
341}
342
20f6cde6
MG
343/*
344 * Check whether the binary signature or hash are present in db or MokList
345 */
031e5cce 346static EFI_STATUS check_allowlist (WIN_CERTIFICATE_EFI_PKCS *cert,
ce6a5748 347 UINT8 *sha256hash, UINT8 *sha1hash)
b2058cf8 348{
47ebeb62 349 if (!ignore_db) {
f892ac66 350 if (check_db_hash(L"db", EFI_SECURE_BOOT_DB_GUID, sha256hash, SHA256_DIGEST_SIZE,
47ebeb62
JB
351 EFI_CERT_SHA256_GUID) == DATA_FOUND) {
352 update_verification_method(VERIFIED_BY_HASH);
353 return EFI_SUCCESS;
b6f94dbe
MTL
354 } else {
355 LogError(L"check_db_hash(db, sha256hash) != DATA_FOUND\n");
47ebeb62 356 }
f892ac66 357 if (check_db_hash(L"db", EFI_SECURE_BOOT_DB_GUID, sha1hash, SHA1_DIGEST_SIZE,
47ebeb62
JB
358 EFI_CERT_SHA1_GUID) == DATA_FOUND) {
359 verification_method = VERIFIED_BY_HASH;
360 update_verification_method(VERIFIED_BY_HASH);
361 return EFI_SUCCESS;
b6f94dbe
MTL
362 } else {
363 LogError(L"check_db_hash(db, sha1hash) != DATA_FOUND\n");
47ebeb62 364 }
f892ac66 365 if (cert && check_db_cert(L"db", EFI_SECURE_BOOT_DB_GUID, cert, sha256hash)
8044a321 366 == DATA_FOUND) {
47ebeb62
JB
367 verification_method = VERIFIED_BY_CERT;
368 update_verification_method(VERIFIED_BY_CERT);
369 return EFI_SUCCESS;
031e5cce 370 } else if (cert) {
b6f94dbe 371 LogError(L"check_db_cert(db, sha256hash) != DATA_FOUND\n");
47ebeb62 372 }
cbef697a 373 }
47ebeb62 374
031e5cce
SM
375#if defined(VENDOR_DB_FILE)
376 EFI_SIGNATURE_LIST *db = (EFI_SIGNATURE_LIST *)vendor_db;
377
378 if (check_db_hash_in_ram(db, vendor_db_size,
379 sha256hash, SHA256_DIGEST_SIZE,
380 EFI_CERT_SHA256_GUID, L"vendor_db",
381 EFI_SECURE_BOOT_DB_GUID) == DATA_FOUND) {
382 verification_method = VERIFIED_BY_HASH;
383 update_verification_method(VERIFIED_BY_HASH);
384 return EFI_SUCCESS;
385 } else {
386 LogError(L"check_db_hash(vendor_db, sha256hash) != DATA_FOUND\n");
387 }
388 if (cert &&
389 check_db_cert_in_ram(db, vendor_db_size,
390 cert, sha256hash, L"vendor_db",
391 EFI_SECURE_BOOT_DB_GUID) == DATA_FOUND) {
392 verification_method = VERIFIED_BY_CERT;
393 update_verification_method(VERIFIED_BY_CERT);
394 return EFI_SUCCESS;
395 } else if (cert) {
396 LogError(L"check_db_cert(vendor_db, sha256hash) != DATA_FOUND\n");
397 }
398#endif
399
2dd2f760 400 if (check_db_hash(L"MokListRT", SHIM_LOCK_GUID, sha256hash,
f892ac66
MTL
401 SHA256_DIGEST_SIZE, EFI_CERT_SHA256_GUID)
402 == DATA_FOUND) {
cbef697a
PJ
403 verification_method = VERIFIED_BY_HASH;
404 update_verification_method(VERIFIED_BY_HASH);
0a6565c5 405 return EFI_SUCCESS;
b6f94dbe 406 } else {
2dd2f760 407 LogError(L"check_db_hash(MokListRT, sha256hash) != DATA_FOUND\n");
cbef697a 408 }
2dd2f760 409 if (cert && check_db_cert(L"MokListRT", SHIM_LOCK_GUID, cert, sha256hash)
f892ac66 410 == DATA_FOUND) {
cbef697a
PJ
411 verification_method = VERIFIED_BY_CERT;
412 update_verification_method(VERIFIED_BY_CERT);
b2058cf8 413 return EFI_SUCCESS;
031e5cce 414 } else if (cert) {
2dd2f760 415 LogError(L"check_db_cert(MokListRT, sha256hash) != DATA_FOUND\n");
cbef697a 416 }
b2058cf8 417
cbef697a 418 update_verification_method(VERIFIED_BY_NOTHING);
031e5cce 419 return EFI_NOT_FOUND;
b2058cf8
MG
420}
421
6279b58e
MG
422/*
423 * Check whether we're in Secure Boot and user mode
424 */
031e5cce 425BOOLEAN secure_mode (void)
6279b58e 426{
d3819813 427 static int first = 1;
e60f1181 428 if (user_insecure_mode)
9eaadb0d
MG
429 return FALSE;
430
7a72592b 431 if (variable_is_secureboot() != 1) {
8529e0f7
SM
432 if (verbose && !in_protocol && first) {
433 CHAR16 *title = L"Secure boot not enabled";
434 CHAR16 *message = L"Press any key to continue";
435 console_countdown(title, message, 5);
436 }
d3819813 437 first = 0;
6b1f8796
PJ
438 return FALSE;
439 }
6279b58e 440
9ea3d9b4
PJ
441 /* If we /do/ have "SecureBoot", but /don't/ have "SetupMode",
442 * then the implementation is bad, but we assume that secure boot is
443 * enabled according to the status of "SecureBoot". If we have both
444 * of them, then "SetupMode" may tell us additional data, and we need
445 * to consider it.
446 */
447 if (variable_is_setupmode(0) == 1) {
8529e0f7
SM
448 if (verbose && !in_protocol && first) {
449 CHAR16 *title = L"Platform is in setup mode";
450 CHAR16 *message = L"Press any key to continue";
451 console_countdown(title, message, 5);
452 }
031e5cce
SM
453 first = 0;
454 return FALSE;
cbe21407
MG
455 }
456
031e5cce
SM
457 first = 0;
458 return TRUE;
b2fe1780
MG
459}
460
031e5cce
SM
461static EFI_STATUS
462verify_one_signature(WIN_CERTIFICATE_EFI_PKCS *sig,
463 UINT8 *sha256hash, UINT8 *sha1hash)
b2fe1780
MG
464{
465 EFI_STATUS efi_status;
7f055335 466
20f6cde6 467 /*
031e5cce 468 * Ensure that the binary isn't forbidden
20f6cde6 469 */
031e5cce
SM
470 drain_openssl_errors();
471 efi_status = check_denylist(sig, sha256hash, sha1hash);
f892ac66 472 if (EFI_ERROR(efi_status)) {
031e5cce
SM
473 perror(L"Binary is forbidden: %r\n", efi_status);
474 PrintErrors();
475 ClearErrors();
476 crypterr(efi_status);
b2fe1780
MG
477 return efi_status;
478 }
479
20f6cde6 480 /*
031e5cce
SM
481 * Check whether the binary is authorized in any of the firmware
482 * databases
20f6cde6 483 */
031e5cce
SM
484 drain_openssl_errors();
485 efi_status = check_allowlist(sig, sha256hash, sha1hash);
486 if (EFI_ERROR(efi_status)) {
487 if (efi_status != EFI_NOT_FOUND) {
488 dprint(L"check_allowlist(): %r\n", efi_status);
489 PrintErrors();
490 ClearErrors();
491 crypterr(efi_status);
492 }
493 } else {
494 drain_openssl_errors();
f892ac66
MTL
495 return efi_status;
496 }
7f055335 497
031e5cce
SM
498 efi_status = EFI_NOT_FOUND;
499#if defined(ENABLE_SHIM_CERT)
500 /*
501 * Check against the shim build key
502 */
503 drain_openssl_errors();
504 if (build_cert && build_cert_size) {
505 dprint("verifying against shim cert\n");
506 }
507 if (build_cert && build_cert_size &&
508 AuthenticodeVerify(sig->CertData,
509 sig->Hdr.dwLength - sizeof(sig->Hdr),
510 build_cert, build_cert_size, sha256hash,
511 SHA256_DIGEST_SIZE)) {
512 dprint(L"AuthenticodeVerify(shim_cert) succeeded\n");
513 update_verification_method(VERIFIED_BY_CERT);
514 tpm_measure_variable(L"Shim", SHIM_LOCK_GUID,
515 build_cert_size, build_cert);
516 efi_status = EFI_SUCCESS;
517 drain_openssl_errors();
518 return efi_status;
519 } else {
520 dprint(L"AuthenticodeVerify(shim_cert) failed\n");
521 PrintErrors();
522 ClearErrors();
523 crypterr(EFI_NOT_FOUND);
7f055335 524 }
031e5cce 525#endif /* defined(ENABLE_SHIM_CERT) */
7f055335 526
031e5cce
SM
527#if defined(VENDOR_CERT_FILE)
528 /*
529 * And finally, check against shim's built-in key
d3819813 530 */
031e5cce
SM
531 drain_openssl_errors();
532 if (vendor_cert_size) {
533 dprint("verifying against vendor_cert\n");
534 }
535 if (vendor_cert_size &&
536 AuthenticodeVerify(sig->CertData,
537 sig->Hdr.dwLength - sizeof(sig->Hdr),
538 vendor_cert, vendor_cert_size,
539 sha256hash, SHA256_DIGEST_SIZE)) {
540 dprint(L"AuthenticodeVerify(vendor_cert) succeeded\n");
541 update_verification_method(VERIFIED_BY_CERT);
542 tpm_measure_variable(L"Shim", SHIM_LOCK_GUID,
543 vendor_cert_size, vendor_cert);
544 efi_status = EFI_SUCCESS;
545 drain_openssl_errors();
546 return efi_status;
547 } else {
548 dprint(L"AuthenticodeVerify(vendor_cert) failed\n");
549 PrintErrors();
550 ClearErrors();
551 crypterr(EFI_NOT_FOUND);
0e6b0195 552 }
031e5cce 553#endif /* defined(VENDOR_CERT_FILE) */
0e6b0195 554
031e5cce
SM
555 return efi_status;
556}
b2fe1780 557
031e5cce
SM
558/*
559 * Check that the signature is valid and matches the binary
560 */
561EFI_STATUS
e6ace38a
SM
562verify_buffer_authenticode (char *data, int datasize,
563 PE_COFF_LOADER_IMAGE_CONTEXT *context,
564 UINT8 *sha256hash, UINT8 *sha1hash)
031e5cce
SM
565{
566 EFI_STATUS ret_efi_status;
567 size_t size = datasize;
568 size_t offset = 0;
569 unsigned int i = 0;
d3819813 570
031e5cce
SM
571 if (datasize < 0)
572 return EFI_INVALID_PARAMETER;
d3819813 573
d3819813 574 /*
031e5cce
SM
575 * Clear OpenSSL's error log, because we get some DSO unimplemented
576 * errors during its intialization, and we don't want those to look
577 * like they're the reason for validation failures.
d3819813 578 */
031e5cce 579 drain_openssl_errors();
a16340e3 580
031e5cce
SM
581 ret_efi_status = generate_hash(data, datasize, context, sha256hash, sha1hash);
582 if (EFI_ERROR(ret_efi_status)) {
583 dprint(L"generate_hash: %r\n", ret_efi_status);
584 PrintErrors();
585 ClearErrors();
586 crypterr(ret_efi_status);
587 return ret_efi_status;
588 }
a16340e3 589
20f6cde6 590 /*
031e5cce 591 * Ensure that the binary isn't forbidden by hash
20f6cde6 592 */
031e5cce
SM
593 drain_openssl_errors();
594 ret_efi_status = check_denylist(NULL, sha256hash, sha1hash);
595 if (EFI_ERROR(ret_efi_status)) {
596// perror(L"Binary is forbidden\n");
597// dprint(L"Binary is forbidden: %r\n", ret_efi_status);
598 PrintErrors();
599 ClearErrors();
600 crypterr(ret_efi_status);
601 return ret_efi_status;
602 }
7de74e67 603
031e5cce
SM
604 /*
605 * Check whether the binary is authorized by hash in any of the
606 * firmware databases
607 */
608 drain_openssl_errors();
609 ret_efi_status = check_allowlist(NULL, sha256hash, sha1hash);
610 if (EFI_ERROR(ret_efi_status)) {
611 LogError(L"check_allowlist(): %r\n", ret_efi_status);
612 dprint(L"check_allowlist: %r\n", ret_efi_status);
613 if (ret_efi_status != EFI_NOT_FOUND) {
614 dprint(L"check_allowlist(): %r\n", ret_efi_status);
615 PrintErrors();
616 ClearErrors();
617 crypterr(ret_efi_status);
618 return ret_efi_status;
a16340e3 619 }
031e5cce
SM
620 } else {
621 drain_openssl_errors();
622 return ret_efi_status;
623 }
a16340e3 624
031e5cce
SM
625 if (context->SecDir->Size == 0) {
626 dprint(L"No signatures found\n");
627 return EFI_SECURITY_VIOLATION;
628 }
a16340e3 629
fd2d9f03
SM
630 if (checked_add(context->SecDir->Size, context->SecDir->VirtualAddress, &offset) ||
631 offset > size) {
031e5cce
SM
632 perror(L"Certificate Database size is too large\n");
633 return EFI_INVALID_PARAMETER;
634 }
d3819813 635
fd2d9f03 636 offset = 0;
031e5cce
SM
637 ret_efi_status = EFI_NOT_FOUND;
638 do {
639 WIN_CERTIFICATE_EFI_PKCS *sig = NULL;
640 size_t sz;
d3819813 641
031e5cce
SM
642 sig = ImageAddress(data, size,
643 context->SecDir->VirtualAddress + offset);
644 if (!sig)
645 break;
62f0afa2 646
fd2d9f03
SM
647 if ((uint64_t)(uintptr_t)&sig[1]
648 > (uint64_t)(uintptr_t)data + datasize) {
649 perror(L"Certificate size is too large for secruity database");
650 return EFI_INVALID_PARAMETER;
651 }
652
031e5cce
SM
653 sz = offset + offsetof(WIN_CERTIFICATE_EFI_PKCS, Hdr.dwLength)
654 + sizeof(sig->Hdr.dwLength);
655 if (sz > context->SecDir->Size) {
656 perror(L"Certificate size is too large for secruity database");
657 return EFI_INVALID_PARAMETER;
658 }
b2fe1780 659
031e5cce
SM
660 sz = sig->Hdr.dwLength;
661 if (sz > context->SecDir->Size - offset) {
662 perror(L"Certificate size is too large for secruity database");
663 return EFI_INVALID_PARAMETER;
62f0afa2 664 }
b2fe1780 665
031e5cce
SM
666 if (sz < sizeof(sig->Hdr)) {
667 perror(L"Certificate size is too small for certificate data");
668 return EFI_INVALID_PARAMETER;
669 }
486bf03e 670
031e5cce
SM
671 if (sig->Hdr.wCertificateType == WIN_CERT_TYPE_PKCS_SIGNED_DATA) {
672 EFI_STATUS efi_status;
486bf03e 673
031e5cce 674 dprint(L"Attempting to verify signature %d:\n", i++);
b2fe1780 675
031e5cce 676 efi_status = verify_one_signature(sig, sha256hash, sha1hash);
5fe882ba 677
031e5cce
SM
678 /*
679 * If we didn't get EFI_SECURITY_VIOLATION from
680 * checking the hashes above, then any dbx entries are
681 * for a certificate, not this individual binary.
682 *
683 * So don't clobber successes with security violation
684 * here; that just means it isn't a success.
685 */
686 if (ret_efi_status != EFI_SUCCESS)
687 ret_efi_status = efi_status;
688 } else {
689 perror(L"Unsupported certificate type %x\n",
690 sig->Hdr.wCertificateType);
691 }
692 offset = ALIGN_VALUE(offset + sz, 8);
693 } while (offset < context->SecDir->Size);
09e2c939 694
031e5cce
SM
695 if (ret_efi_status != EFI_SUCCESS) {
696 dprint(L"Binary is not authorized\n");
697 PrintErrors();
698 ClearErrors();
699 crypterr(EFI_SECURITY_VIOLATION);
700 ret_efi_status = EFI_SECURITY_VIOLATION;
0e6b0195 701 }
031e5cce
SM
702 drain_openssl_errors();
703 return ret_efi_status;
b2fe1780
MG
704}
705
e6ace38a
SM
706/*
707 * Check that the binary is permitted to load by SBAT.
708 */
709EFI_STATUS
710verify_buffer_sbat (char *data, int datasize,
711 PE_COFF_LOADER_IMAGE_CONTEXT *context)
712{
713 int i;
714 EFI_IMAGE_SECTION_HEADER *Section;
715 char *SBATBase = NULL;
716 size_t SBATSize = 0;
717
718 Section = context->FirstSection;
719 for (i = 0; i < context->NumberOfSections; i++, Section++) {
fd2d9f03
SM
720 if ((uint64_t)(uintptr_t)&Section[1]
721 > (uintptr_t)(uintptr_t)data + datasize) {
722 perror(L"Section exceeds bounds of image\n");
723 return EFI_UNSUPPORTED;
724 }
725
e6ace38a
SM
726 if (CompareMem(Section->Name, ".sbat\0\0\0", 8) != 0)
727 continue;
728
729 if (SBATBase || SBATSize) {
730 perror(L"Image has multiple SBAT sections\n");
731 return EFI_UNSUPPORTED;
732 }
733
734 if (Section->NumberOfRelocations != 0 ||
735 Section->PointerToRelocations != 0) {
736 perror(L"SBAT section has relocations\n");
737 return EFI_UNSUPPORTED;
738 }
739
740 /* The virtual size corresponds to the size of the SBAT
741 * metadata and isn't necessarily a multiple of the file
742 * alignment. The on-disk size is a multiple of the file
743 * alignment and is zero padded. Make sure that the
744 * on-disk size is at least as large as virtual size,
745 * and ignore the section if it isn't. */
746 if (Section->SizeOfRawData &&
747 Section->SizeOfRawData >= Section->Misc.VirtualSize) {
fd2d9f03 748 uint64_t boundary;
e6ace38a
SM
749 SBATBase = ImageAddress(data, datasize,
750 Section->PointerToRawData);
751 SBATSize = Section->SizeOfRawData;
752 dprint(L"sbat section base:0x%lx size:0x%lx\n",
753 SBATBase, SBATSize);
fd2d9f03
SM
754 if (checked_add((uint64_t)(uintptr_t)SBATBase, SBATSize, &boundary) ||
755 (boundary > (uint64_t)(uintptr_t)data + datasize)) {
756 perror(L"Section exceeds bounds of image\n");
757 return EFI_UNSUPPORTED;
758 }
e6ace38a
SM
759 }
760 }
761
762 return verify_sbat_section(SBATBase, SBATSize);
763}
764
765/*
766 * Check that the signature is valid and matches the binary and that
767 * the binary is permitted to load by SBAT.
768 */
769EFI_STATUS
770verify_buffer (char *data, int datasize,
771 PE_COFF_LOADER_IMAGE_CONTEXT *context,
772 UINT8 *sha256hash, UINT8 *sha1hash)
773{
774 EFI_STATUS efi_status;
775
fd2d9f03 776 efi_status = verify_buffer_authenticode(data, datasize, context, sha256hash, sha1hash);
e6ace38a
SM
777 if (EFI_ERROR(efi_status))
778 return efi_status;
779
fd2d9f03 780 return verify_buffer_sbat(data, datasize, context);
e6ace38a
SM
781}
782
6d6b0221 783static int
8529e0f7 784is_removable_media_path(EFI_LOADED_IMAGE *li)
6d6b0221 785{
6d6b0221 786 unsigned int pathlen = 0;
fe8527aa 787 CHAR16 *bootpath = NULL;
fe8527aa 788 int ret = 0;
6d6b0221 789
2e7fc28d 790 bootpath = DevicePathToStr(li->FilePath);
6d6b0221
PJ
791
792 /* Check the beginning of the string and the end, to avoid
793 * caring about which arch this is. */
794 /* I really don't know why, but sometimes bootpath gives us
795 * L"\\EFI\\BOOT\\/BOOTX64.EFI". So just handle that here...
796 */
797 if (StrnCaseCmp(bootpath, L"\\EFI\\BOOT\\BOOT", 14) &&
d3819813
MTL
798 StrnCaseCmp(bootpath, L"\\EFI\\BOOT\\/BOOT", 15) &&
799 StrnCaseCmp(bootpath, L"EFI\\BOOT\\BOOT", 13) &&
800 StrnCaseCmp(bootpath, L"EFI\\BOOT\\/BOOT", 14))
fe8527aa 801 goto error;
2e7fc28d 802
6d6b0221
PJ
803 pathlen = StrLen(bootpath);
804 if (pathlen < 5 || StrCaseCmp(bootpath + pathlen - 4, L".EFI"))
fe8527aa 805 goto error;
6d6b0221 806
8529e0f7
SM
807 ret = 1;
808
809error:
810 if (bootpath)
811 FreePool(bootpath);
812
813 return ret;
814}
815
816static int
817should_use_fallback(EFI_HANDLE image_handle)
818{
819 EFI_LOADED_IMAGE *li;
820 EFI_FILE_IO_INTERFACE *fio = NULL;
821 EFI_FILE *vh = NULL;
822 EFI_FILE *fh = NULL;
823 EFI_STATUS efi_status;
824 int ret = 0;
825
826 efi_status = BS->HandleProtocol(image_handle, &EFI_LOADED_IMAGE_GUID,
827 (void **)&li);
828 if (EFI_ERROR(efi_status)) {
829 perror(L"Could not get image for boot" EFI_ARCH L".efi: %r\n",
830 efi_status);
831 return 0;
832 }
833
834 if (!is_removable_media_path(li))
835 goto error;
836
837 efi_status = BS->HandleProtocol(li->DeviceHandle, &FileSystemProtocol,
838 (void **) &fio);
f892ac66
MTL
839 if (EFI_ERROR(efi_status)) {
840 perror(L"Could not get fio for li->DeviceHandle: %r\n",
841 efi_status);
fe8527aa 842 goto error;
c9d11306 843 }
e50cfe37 844
f892ac66
MTL
845 efi_status = fio->OpenVolume(fio, &vh);
846 if (EFI_ERROR(efi_status)) {
847 perror(L"Could not open fio volume: %r\n", efi_status);
fe8527aa 848 goto error;
c9d11306 849 }
6d6b0221 850
f892ac66
MTL
851 efi_status = vh->Open(vh, &fh, L"\\EFI\\BOOT" FALLBACK,
852 EFI_FILE_MODE_READ, 0);
853 if (EFI_ERROR(efi_status)) {
b32a3ce1
PJ
854 /* Do not print the error here - this is an acceptable case
855 * for removable media, where we genuinely don't want
856 * fallback.efi to exist.
f892ac66
MTL
857 * Print(L"Could not open \"\\EFI\\BOOT%s\": %r\n", FALLBACK,
858 * efi_status);
b32a3ce1 859 */
fe8527aa 860 goto error;
6d6b0221 861 }
6d6b0221 862
fe8527aa
GCPL
863 ret = 1;
864error:
d3819813 865 if (fh)
f892ac66 866 fh->Close(fh);
d3819813 867 if (vh)
f892ac66 868 vh->Close(vh);
fe8527aa
GCPL
869
870 return ret;
6d6b0221 871}
db54b0a4 872/*
20f6cde6 873 * Open the second stage bootloader and read it into a buffer
db54b0a4 874 */
822d089e
GCPL
875static EFI_STATUS load_image (EFI_LOADED_IMAGE *li, void **data,
876 int *datasize, CHAR16 *PathName)
db54b0a4 877{
db54b0a4
MG
878 EFI_STATUS efi_status;
879 EFI_HANDLE device;
880 EFI_FILE_INFO *fileinfo = NULL;
881 EFI_FILE_IO_INTERFACE *drive;
882 EFI_FILE *root, *grub;
6eb1eca4 883 UINTN buffersize = sizeof(EFI_FILE_INFO);
db54b0a4
MG
884
885 device = li->DeviceHandle;
f898777d 886
031e5cce 887 dprint(L"attempting to load %s\n", PathName);
20f6cde6
MG
888 /*
889 * Open the device
890 */
8529e0f7
SM
891 efi_status = BS->HandleProtocol(device, &EFI_SIMPLE_FILE_SYSTEM_GUID,
892 (void **) &drive);
f892ac66 893 if (EFI_ERROR(efi_status)) {
e50cfe37 894 perror(L"Failed to find fs: %r\n", efi_status);
0db1af8a
MG
895 goto error;
896 }
f898777d 897
f892ac66
MTL
898 efi_status = drive->OpenVolume(drive, &root);
899 if (EFI_ERROR(efi_status)) {
e50cfe37 900 perror(L"Failed to open fs: %r\n", efi_status);
0db1af8a
MG
901 goto error;
902 }
f898777d 903
20f6cde6
MG
904 /*
905 * And then open the file
906 */
f892ac66
MTL
907 efi_status = root->Open(root, &grub, PathName, EFI_FILE_MODE_READ, 0);
908 if (EFI_ERROR(efi_status)) {
e50cfe37 909 perror(L"Failed to open %s - %r\n", PathName, efi_status);
0db1af8a
MG
910 goto error;
911 }
912
913 fileinfo = AllocatePool(buffersize);
914
915 if (!fileinfo) {
e50cfe37 916 perror(L"Unable to allocate file info buffer\n");
0db1af8a
MG
917 efi_status = EFI_OUT_OF_RESOURCES;
918 goto error;
f898777d
MG
919 }
920
20f6cde6
MG
921 /*
922 * Find out how big the file is in order to allocate the storage
923 * buffer
924 */
f892ac66
MTL
925 efi_status = grub->GetInfo(grub, &EFI_FILE_INFO_GUID, &buffersize,
926 fileinfo);
f898777d 927 if (efi_status == EFI_BUFFER_TOO_SMALL) {
cbe21407 928 FreePool(fileinfo);
f898777d
MG
929 fileinfo = AllocatePool(buffersize);
930 if (!fileinfo) {
e50cfe37 931 perror(L"Unable to allocate file info buffer\n");
0db1af8a
MG
932 efi_status = EFI_OUT_OF_RESOURCES;
933 goto error;
f898777d 934 }
f892ac66
MTL
935 efi_status = grub->GetInfo(grub, &EFI_FILE_INFO_GUID,
936 &buffersize, fileinfo);
f898777d
MG
937 }
938
f892ac66 939 if (EFI_ERROR(efi_status)) {
e50cfe37 940 perror(L"Unable to get file info: %r\n", efi_status);
0db1af8a 941 goto error;
f898777d
MG
942 }
943
944 buffersize = fileinfo->FileSize;
7db60bd8 945 *data = AllocatePool(buffersize);
7db60bd8 946 if (!*data) {
e50cfe37 947 perror(L"Unable to allocate file buffer\n");
0db1af8a
MG
948 efi_status = EFI_OUT_OF_RESOURCES;
949 goto error;
f898777d 950 }
20f6cde6
MG
951
952 /*
953 * Perform the actual read
954 */
f892ac66 955 efi_status = grub->Read(grub, &buffersize, *data);
0db1af8a
MG
956 if (efi_status == EFI_BUFFER_TOO_SMALL) {
957 FreePool(*data);
958 *data = AllocatePool(buffersize);
f892ac66 959 efi_status = grub->Read(grub, &buffersize, *data);
f898777d 960 }
f892ac66
MTL
961 if (EFI_ERROR(efi_status)) {
962 perror(L"Unexpected return from initial read: %r, buffersize %x\n",
963 efi_status, buffersize);
0db1af8a 964 goto error;
f898777d
MG
965 }
966
7db60bd8 967 *datasize = buffersize;
f898777d 968
cbe21407
MG
969 FreePool(fileinfo);
970
f898777d 971 return EFI_SUCCESS;
0db1af8a
MG
972error:
973 if (*data) {
974 FreePool(*data);
975 *data = NULL;
976 }
6f161626 977
0db1af8a
MG
978 if (fileinfo)
979 FreePool(fileinfo);
980 return efi_status;
f898777d
MG
981}
982
20f6cde6
MG
983/*
984 * Protocol entry point. If secure boot is enabled, verify that the provided
985 * buffer is signed with a trusted key.
986 */
db54b0a4 987EFI_STATUS shim_verify (void *buffer, UINT32 size)
f4b24734 988{
f892ac66 989 EFI_STATUS efi_status = EFI_SUCCESS;
f4b24734 990 PE_COFF_LOADER_IMAGE_CONTEXT context;
b6f94dbe
MTL
991 UINT8 sha1hash[SHA1_DIGEST_SIZE];
992 UINT8 sha256hash[SHA256_DIGEST_SIZE];
f4b24734 993
f892ac66
MTL
994 if ((INT32)size < 0)
995 return EFI_INVALID_PARAMETER;
996
cbef697a 997 loader_is_participating = 1;
e50cfe37 998 in_protocol = 1;
cbef697a 999
f892ac66
MTL
1000 efi_status = read_header(buffer, size, &context);
1001 if (EFI_ERROR(efi_status))
d3819813 1002 goto done;
6279b58e 1003
f892ac66
MTL
1004 efi_status = generate_hash(buffer, size, &context,
1005 sha256hash, sha1hash);
1006 if (EFI_ERROR(efi_status))
e50cfe37 1007 goto done;
f4b24734 1008
f892ac66
MTL
1009 /* Measure the binary into the TPM */
1010#ifdef REQUIRE_TPM
1011 efi_status =
1012#endif
031e5cce
SM
1013 tpm_log_pe((EFI_PHYSICAL_ADDRESS)(UINTN)buffer, size, 0, NULL,
1014 sha1hash, 4);
f892ac66
MTL
1015#ifdef REQUIRE_TPM
1016 if (EFI_ERROR(efi_status))
1017 goto done;
1018#endif
1019
1020 if (!secure_mode()) {
1021 efi_status = EFI_SUCCESS;
b6f94dbe 1022 goto done;
f892ac66 1023 }
b6f94dbe 1024
031e5cce
SM
1025 efi_status = verify_buffer(buffer, size,
1026 &context, sha256hash, sha1hash);
e50cfe37
GCPL
1027done:
1028 in_protocol = 0;
f892ac66 1029 return efi_status;
e50cfe37
GCPL
1030}
1031
1032static EFI_STATUS shim_hash (char *data, int datasize,
1033 PE_COFF_LOADER_IMAGE_CONTEXT *context,
1034 UINT8 *sha256hash, UINT8 *sha1hash)
1035{
f892ac66
MTL
1036 EFI_STATUS efi_status;
1037
1038 if (datasize < 0)
1039 return EFI_INVALID_PARAMETER;
e50cfe37
GCPL
1040
1041 in_protocol = 1;
f892ac66
MTL
1042 efi_status = generate_hash(data, datasize, context,
1043 sha256hash, sha1hash);
e50cfe37
GCPL
1044 in_protocol = 0;
1045
f892ac66 1046 return efi_status;
e50cfe37
GCPL
1047}
1048
1049static EFI_STATUS shim_read_header(void *data, unsigned int datasize,
1050 PE_COFF_LOADER_IMAGE_CONTEXT *context)
1051{
f892ac66 1052 EFI_STATUS efi_status;
e50cfe37
GCPL
1053
1054 in_protocol = 1;
f892ac66 1055 efi_status = read_header(data, datasize, context);
e50cfe37 1056 in_protocol = 0;
f4b24734 1057
f892ac66 1058 return efi_status;
f4b24734
MG
1059}
1060
031e5cce
SM
1061VOID
1062restore_loaded_image(VOID)
1063{
1064 if (shim_li->FilePath)
1065 FreePool(shim_li->FilePath);
1066
1067 /*
1068 * Restore our original loaded image values
1069 */
1070 CopyMem(shim_li, &shim_li_bak, sizeof(shim_li_bak));
1071}
1072
fd2d9f03
SM
1073/* If gets used on static data it probably needs boundary checking */
1074void
1075str16_to_str8(CHAR16 *str16, CHAR8 **str8)
1076{
1077 int i = 0;
1078
1079 while (str16[i++] != '\0');
1080 *str8 = (CHAR8 *)AllocatePool((i + 1) * sizeof (CHAR8));
1081
1082 i = 0;
1083 while (str16[i] != '\0') {
1084 (*str8)[i] = (CHAR8)str16[i];
1085 i++;
1086 }
1087 (*str8)[i] = '\0';
1088}
1089
20f6cde6
MG
1090/*
1091 * Load and run an EFI executable
1092 */
e6ace38a
SM
1093EFI_STATUS read_image(EFI_HANDLE image_handle, CHAR16 *ImagePath,
1094 CHAR16 **PathName, void **data, int *datasize)
822d089e
GCPL
1095{
1096 EFI_STATUS efi_status;
1c595706 1097 void *sourcebuffer = NULL;
fbc486b5 1098 UINT64 sourcesize = 0;
fd2d9f03 1099 CHAR8 *netbootname;
822d089e 1100
20f6cde6
MG
1101 /*
1102 * We need to refer to the loaded image protocol on the running
1103 * binary in order to find our path
1104 */
8529e0f7
SM
1105 efi_status = BS->HandleProtocol(image_handle, &EFI_LOADED_IMAGE_GUID,
1106 (void **)&shim_li);
f892ac66 1107 if (EFI_ERROR(efi_status)) {
e50cfe37 1108 perror(L"Unable to init protocol\n");
cec6a0a9
GCPL
1109 return efi_status;
1110 }
1111
20f6cde6
MG
1112 /*
1113 * Build a new path from the existing one plus the executable name
1114 */
e6ace38a 1115 efi_status = generate_path_from_image_path(shim_li, ImagePath, PathName);
f892ac66
MTL
1116 if (EFI_ERROR(efi_status)) {
1117 perror(L"Unable to generate path %s: %r\n", ImagePath,
1118 efi_status);
e6ace38a 1119 return efi_status;
cec6a0a9
GCPL
1120 }
1121
031e5cce 1122 if (findNetboot(shim_li->DeviceHandle)) {
fd2d9f03
SM
1123 str16_to_str8(ImagePath, &netbootname);
1124 efi_status = parseNetbootinfo(image_handle, netbootname);
f892ac66 1125 if (EFI_ERROR(efi_status)) {
e50cfe37 1126 perror(L"Netboot parsing failed: %r\n", efi_status);
1c595706
MG
1127 return EFI_PROTOCOL_ERROR;
1128 }
fd2d9f03 1129 FreePool(netbootname);
1c595706
MG
1130 efi_status = FetchNetbootimage(image_handle, &sourcebuffer,
1131 &sourcesize);
f892ac66
MTL
1132 if (EFI_ERROR(efi_status)) {
1133 perror(L"Unable to fetch TFTP image: %r\n",
1134 efi_status);
1c595706
MG
1135 return efi_status;
1136 }
e6ace38a
SM
1137 *data = sourcebuffer;
1138 *datasize = sourcesize;
031e5cce 1139 } else if (find_httpboot(shim_li->DeviceHandle)) {
fd2d9f03 1140 str16_to_str8(ImagePath, &netbootname);
f892ac66
MTL
1141 efi_status = httpboot_fetch_buffer (image_handle,
1142 &sourcebuffer,
fd2d9f03
SM
1143 &sourcesize,
1144 netbootname);
f892ac66 1145 if (EFI_ERROR(efi_status)) {
fd2d9f03
SM
1146 perror(L"Unable to fetch HTTP image %a: %r\n",
1147 netbootname, efi_status);
62f0afa2
MTL
1148 return efi_status;
1149 }
e6ace38a
SM
1150 *data = sourcebuffer;
1151 *datasize = sourcesize;
1c595706 1152 } else {
4ad234f1
MG
1153 /*
1154 * Read the new executable off disk
1155 */
e6ace38a 1156 efi_status = load_image(shim_li, data, datasize, *PathName);
f892ac66
MTL
1157 if (EFI_ERROR(efi_status)) {
1158 perror(L"Failed to load image %s: %r\n",
1159 PathName, efi_status);
b6f94dbe
MTL
1160 PrintErrors();
1161 ClearErrors();
e6ace38a 1162 return efi_status;
1c595706 1163 }
822d089e
GCPL
1164 }
1165
e6ace38a 1166 if (*datasize < 0)
f892ac66 1167 efi_status = EFI_INVALID_PARAMETER;
e6ace38a
SM
1168
1169 return efi_status;
1170}
1171
1172/*
1173 * Load and run an EFI executable
1174 */
1175EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath)
1176{
1177 EFI_STATUS efi_status;
1178 EFI_IMAGE_ENTRY_POINT entry_point;
1179 EFI_PHYSICAL_ADDRESS alloc_address;
1180 UINTN alloc_pages;
1181 CHAR16 *PathName = NULL;
1182 void *data = NULL;
1183 int datasize = 0;
1184
1185 efi_status = read_image(image_handle, ImagePath, &PathName, &data,
1186 &datasize);
1187 if (EFI_ERROR(efi_status))
f892ac66 1188 goto done;
f892ac66 1189
20f6cde6
MG
1190 /*
1191 * We need to modify the loaded image protocol entry before running
1192 * the new binary, so back it up
1193 */
031e5cce
SM
1194 CopyMem(&shim_li_bak, shim_li, sizeof(shim_li_bak));
1195
1196 /*
1197 * Update the loaded image with the second stage loader file path
1198 */
1199 shim_li->FilePath = FileDevicePath(NULL, PathName);
1200 if (!shim_li->FilePath) {
1201 perror(L"Unable to update loaded image file path\n");
1202 efi_status = EFI_OUT_OF_RESOURCES;
1203 goto restore;
1204 }
822d089e 1205
20f6cde6
MG
1206 /*
1207 * Verify and, if appropriate, relocate and execute the executable
1208 */
031e5cce 1209 efi_status = handle_image(data, datasize, shim_li, &entry_point,
f892ac66
MTL
1210 &alloc_address, &alloc_pages);
1211 if (EFI_ERROR(efi_status)) {
e50cfe37 1212 perror(L"Failed to load image: %r\n", efi_status);
b6f94dbe
MTL
1213 PrintErrors();
1214 ClearErrors();
031e5cce 1215 goto restore;
822d089e
GCPL
1216 }
1217
cbef697a
PJ
1218 loader_is_participating = 0;
1219
20f6cde6
MG
1220 /*
1221 * The binary is trusted and relocated. Run it
1222 */
f892ac66 1223 efi_status = entry_point(image_handle, systab);
822d089e 1224
031e5cce
SM
1225restore:
1226 restore_loaded_image();
822d089e 1227done:
cbe21407
MG
1228 if (PathName)
1229 FreePool(PathName);
1230
1231 if (data)
1232 FreePool(data);
1233
822d089e
GCPL
1234 return efi_status;
1235}
1236
20f6cde6
MG
1237/*
1238 * Load and run grub. If that fails because grub isn't trusted, load and
1239 * run MokManager.
1240 */
db54b0a4 1241EFI_STATUS init_grub(EFI_HANDLE image_handle)
b2fe1780
MG
1242{
1243 EFI_STATUS efi_status;
d3819813 1244 int use_fb = should_use_fallback(image_handle);
f4b24734 1245
d3819813 1246 efi_status = start_image(image_handle, use_fb ? FALLBACK :second_stage);
f4173af1
MTL
1247 if (efi_status == EFI_SECURITY_VIOLATION ||
1248 efi_status == EFI_ACCESS_DENIED) {
ef8c9962 1249 efi_status = start_image(image_handle, MOK_MANAGER);
f892ac66
MTL
1250 if (EFI_ERROR(efi_status)) {
1251 console_print(L"start_image() returned %r\n", efi_status);
fd2d9f03 1252 usleep(2000000);
d3819813
MTL
1253 return efi_status;
1254 }
1255
1256 efi_status = start_image(image_handle,
1257 use_fb ? FALLBACK : second_stage);
1258 }
1259
8529e0f7
SM
1260 // If the filename is invalid, or the file does not exist,
1261 // just fallback to the default loader.
1262 if (!use_fb && (efi_status == EFI_INVALID_PARAMETER ||
1263 efi_status == EFI_NOT_FOUND)) {
1264 console_print(
1265 L"start_image() returned %r, falling back to default loader\n",
1266 efi_status);
fd2d9f03 1267 usleep(2000000);
8529e0f7
SM
1268 load_options = NULL;
1269 load_options_size = 0;
1270 efi_status = start_image(image_handle, DEFAULT_LOADER);
d3819813
MTL
1271 }
1272
031e5cce 1273 if (EFI_ERROR(efi_status)) {
8529e0f7 1274 console_print(L"start_image() returned %r\n", efi_status);
fd2d9f03 1275 usleep(2000000);
031e5cce
SM
1276 }
1277
8529e0f7 1278 return efi_status;
f4173af1
MTL
1279}
1280
09e2c939
GCPL
1281/*
1282 * Check the load options to specify the second stage loader
1283 */
1284EFI_STATUS set_second_stage (EFI_HANDLE image_handle)
1285{
f892ac66 1286 EFI_STATUS efi_status;
f4173af1 1287 EFI_LOADED_IMAGE *li = NULL;
8529e0f7
SM
1288
1289 second_stage = DEFAULT_LOADER;
09e2c939
GCPL
1290 load_options = NULL;
1291 load_options_size = 0;
1292
8529e0f7
SM
1293 efi_status = BS->HandleProtocol(image_handle, &LoadedImageProtocol,
1294 (void **) &li);
f892ac66
MTL
1295 if (EFI_ERROR(efi_status)) {
1296 perror (L"Failed to get load options: %r\n", efi_status);
1297 return efi_status;
09e2c939
GCPL
1298 }
1299
8529e0f7 1300#if defined(DISABLE_REMOVABLE_LOAD_OPTIONS)
f892ac66 1301 /*
8529e0f7
SM
1302 * boot services build very strange load options, and we might misparse them,
1303 * causing boot failures on removable media.
f892ac66 1304 */
8529e0f7
SM
1305 if (is_removable_media_path(li)) {
1306 dprint("Invoked from removable media path, ignoring boot options");
f892ac66 1307 return EFI_SUCCESS;
031e5cce 1308 }
8529e0f7 1309#endif
031e5cce 1310
8529e0f7
SM
1311 efi_status = parse_load_options(li);
1312 if (EFI_ERROR(efi_status)) {
1313 perror (L"Failed to get load options: %r\n", efi_status);
1314 return efi_status;
09e2c939
GCPL
1315 }
1316
1317 return EFI_SUCCESS;
1318}
1319
b6f94dbe
MTL
1320static void
1321init_openssl(void)
1322{
b6f94dbe 1323 OPENSSL_init();
b6f94dbe
MTL
1324 ERR_load_ERR_strings();
1325 ERR_load_BN_strings();
1326 ERR_load_RSA_strings();
1327 ERR_load_DH_strings();
1328 ERR_load_EVP_strings();
1329 ERR_load_BUF_strings();
1330 ERR_load_OBJ_strings();
1331 ERR_load_PEM_strings();
1332 ERR_load_X509_strings();
1333 ERR_load_ASN1_strings();
1334 ERR_load_CONF_strings();
1335 ERR_load_CRYPTO_strings();
1336 ERR_load_COMP_strings();
1337 ERR_load_BIO_strings();
1338 ERR_load_PKCS7_strings();
1339 ERR_load_X509V3_strings();
1340 ERR_load_PKCS12_strings();
1341 ERR_load_RAND_strings();
1342 ERR_load_DSO_strings();
1343 ERR_load_OCSP_strings();
1344}
1345
cf90edff
PJ
1346static SHIM_LOCK shim_lock_interface;
1347static EFI_HANDLE shim_lock_handle;
1348
1349EFI_STATUS
1350install_shim_protocols(void)
1351{
f892ac66 1352 SHIM_LOCK *shim_lock;
cf90edff 1353 EFI_STATUS efi_status;
d3819813 1354
f892ac66
MTL
1355 /*
1356 * Did another instance of shim earlier already install the
1357 * protocol? If so, get rid of it.
1358 *
1359 * We have to uninstall shim's protocol here, because if we're
1360 * On the fallback.efi path, then our call pathway is:
1361 *
1362 * shim->fallback->shim->grub
1363 * ^ ^ ^
1364 * | | \- gets protocol #0
1365 * | \- installs its protocol (#1)
1366 * \- installs its protocol (#0)
1367 * and if we haven't removed this, then grub will get the *first*
1368 * shim's protocol, but it'll get the second shim's systab
1369 * replacements. So even though it will participate and verify
1370 * the kernel, the systab never finds out.
1371 */
1372 efi_status = LibLocateProtocol(&SHIM_LOCK_GUID, (VOID **)&shim_lock);
1373 if (!EFI_ERROR(efi_status))
1374 uninstall_shim_protocols();
d3819813 1375
cf90edff
PJ
1376 /*
1377 * Install the protocol
1378 */
8529e0f7
SM
1379 efi_status = BS->InstallProtocolInterface(&shim_lock_handle,
1380 &SHIM_LOCK_GUID,
1381 EFI_NATIVE_INTERFACE,
1382 &shim_lock_interface);
cf90edff
PJ
1383 if (EFI_ERROR(efi_status)) {
1384 console_error(L"Could not install security protocol",
1385 efi_status);
1386 return efi_status;
1387 }
1388
f892ac66
MTL
1389 if (!secure_mode())
1390 return EFI_SUCCESS;
1391
cf90edff
PJ
1392#if defined(OVERRIDE_SECURITY_POLICY)
1393 /*
1394 * Install the security protocol hook
1395 */
1396 security_policy_install(shim_verify);
1397#endif
1398
1399 return EFI_SUCCESS;
1400}
1401
1402void
1403uninstall_shim_protocols(void)
db54b0a4 1404{
f892ac66
MTL
1405 /*
1406 * If we're back here then clean everything up before exiting
1407 */
8529e0f7
SM
1408 BS->UninstallProtocolInterface(shim_lock_handle, &SHIM_LOCK_GUID,
1409 &shim_lock_interface);
d3819813
MTL
1410
1411 if (!secure_mode())
1412 return;
1413
cf90edff
PJ
1414#if defined(OVERRIDE_SECURITY_POLICY)
1415 /*
1416 * Clean up the security protocol hook
1417 */
1418 security_policy_uninstall();
1419#endif
cf90edff
PJ
1420}
1421
fd2d9f03
SM
1422static void
1423check_section_helper(char *section_name, int len, void **pointer,
1424 EFI_IMAGE_SECTION_HEADER *Section, void *data,
1425 int datasize, size_t minsize)
1426{
1427 if (CompareMem(Section->Name, section_name, len) == 0) {
1428 *pointer = ImageAddress(data, datasize, Section->PointerToRawData);
1429 if (Section->SizeOfRawData < minsize) {
1430 dprint(L"found and rejected %.*a bad size\n", len, section_name);
1431 dprint(L"minsize: %d\n", minsize);
1432 dprint(L"rawsize: %d\n", Section->SizeOfRawData);
1433 return ;
1434 }
1435 if (!*pointer) {
1436 return ;
1437 }
1438 dprint(L"found %.*a\n", len, section_name);
1439 }
1440}
1441
1442#define check_section(section_name, pointer, section, data, datasize, minsize) \
1443 check_section_helper(section_name, sizeof(section_name) - 1, pointer, \
1444 section, data, datasize, minsize)
1445
1446EFI_STATUS
1447load_revocations_file(EFI_HANDLE image_handle, CHAR16 *PathName)
1448{
1449 EFI_STATUS efi_status = EFI_SUCCESS;
1450 PE_COFF_LOADER_IMAGE_CONTEXT context;
1451 EFI_IMAGE_SECTION_HEADER *Section;
1452 int datasize = 0;
1453 void *data = NULL;
1454 unsigned int i;
1455 char *sbat_var_automatic = NULL;
1456 char *sbat_var_latest = NULL;
1457 uint8_t *ssps_automatic = NULL;
1458 uint8_t *sspv_automatic = NULL;
1459 uint8_t *ssps_latest = NULL;
1460 uint8_t *sspv_latest = NULL;
1461
1462 efi_status = read_image(image_handle, L"revocations.efi", &PathName,
1463 &data, &datasize);
1464 if (EFI_ERROR(efi_status))
1465 return efi_status;
1466
1467 efi_status = verify_image(data, datasize, shim_li, &context);
1468 if (EFI_ERROR(efi_status)) {
1469 dprint(L"revocations failed to verify\n");
1470 return efi_status;
1471 }
1472 dprint(L"verified revocations\n");
1473
1474 Section = context.FirstSection;
1475 for (i = 0; i < context.NumberOfSections; i++, Section++) {
1476 dprint(L"checking section \"%c%c%c%c%c%c%c%c\"\n", (char *)Section->Name);
1477 check_section(".sbata\0\0", (void **)&sbat_var_automatic, Section,
1478 data, datasize, sizeof(SBAT_VAR_ORIGINAL));
1479 check_section(".sbatl\0\0", (void **)&sbat_var_latest, Section,
1480 data, datasize, sizeof(SBAT_VAR_ORIGINAL));
1481 check_section(".sspva\0\0", (void **)&sspv_automatic, Section,
1482 data, datasize, SSPVER_SIZE);
1483 check_section(".sspsa\0\0", (void **)&ssps_automatic, Section,
1484 data, datasize, SSPSIG_SIZE);
1485 check_section(".sspvl\0\0", (void **)&sspv_latest, Section,
1486 data, datasize, SSPVER_SIZE);
1487 check_section(".sspsl\0\0", (void **)&ssps_latest, Section,
1488 data, datasize, SSPSIG_SIZE);
1489 }
1490
1491 if (sbat_var_latest && sbat_var_automatic) {
1492 dprint(L"attempting to update SBAT_LEVEL\n");
1493 efi_status = set_sbat_uefi_variable(sbat_var_automatic,
1494 sbat_var_latest);
1495 } else {
1496 dprint(L"no data for SBAT_LEVEL\n");
1497 }
1498
1499 if ((sspv_automatic && ssps_automatic) || (sspv_latest && ssps_latest)) {
1500 dprint(L"attempting to update SkuSiPolicy\n");
1501 efi_status = set_ssp_uefi_variable(sspv_automatic, ssps_automatic,
1502 sspv_latest, ssps_latest);
1503
1504 } else {
1505 dprint(L"no data for SkuSiPolicy\n");
1506 }
1507
1508 FreePool(data);
1509 return efi_status;
1510}
1511
e6ace38a
SM
1512EFI_STATUS
1513load_cert_file(EFI_HANDLE image_handle, CHAR16 *filename, CHAR16 *PathName)
1514{
1515 EFI_STATUS efi_status;
e6ace38a
SM
1516 PE_COFF_LOADER_IMAGE_CONTEXT context;
1517 EFI_IMAGE_SECTION_HEADER *Section;
1518 EFI_SIGNATURE_LIST *certlist;
1519 void *pointer;
1520 UINT32 original;
1521 int datasize = 0;
1522 void *data = NULL;
1523 int i;
1524
1525 efi_status = read_image(image_handle, filename, &PathName,
1526 &data, &datasize);
1527 if (EFI_ERROR(efi_status))
1528 return efi_status;
1529
2dd2f760 1530 efi_status = verify_image(data, datasize, shim_li, &context);
e6ace38a
SM
1531 if (EFI_ERROR(efi_status))
1532 return efi_status;
1533
1534 Section = context.FirstSection;
1535 for (i = 0; i < context.NumberOfSections; i++, Section++) {
1536 if (CompareMem(Section->Name, ".db\0\0\0\0\0", 8) == 0) {
1537 original = user_cert_size;
1538 if (Section->SizeOfRawData < sizeof(EFI_SIGNATURE_LIST)) {
1539 continue;
1540 }
1541 pointer = ImageAddress(data, datasize,
1542 Section->PointerToRawData);
1543 if (!pointer) {
1544 continue;
1545 }
1546 certlist = pointer;
1547 user_cert_size += certlist->SignatureListSize;;
1548 user_cert = ReallocatePool(user_cert, original,
1549 user_cert_size);
2dd2f760
SM
1550 CopyMem(user_cert + original, pointer,
1551 certlist->SignatureListSize);
e6ace38a
SM
1552 }
1553 }
1554 FreePool(data);
1555 return EFI_SUCCESS;
1556}
1557
fd2d9f03
SM
1558/*
1559 * Read additional certificates and SBAT Level requirements from files
1560 * (after verifying signatures)
1561 */
e6ace38a 1562EFI_STATUS
fd2d9f03 1563load_unbundled_trust(EFI_HANDLE image_handle)
e6ace38a
SM
1564{
1565 EFI_STATUS efi_status;
1566 EFI_LOADED_IMAGE *li = NULL;
1567 CHAR16 *PathName = NULL;
1568 EFI_FILE *root, *dir;
1569 EFI_FILE_INFO *info;
1570 EFI_HANDLE device;
1571 EFI_FILE_IO_INTERFACE *drive;
1572 UINTN buffersize = 0;
1573 void *buffer = NULL;
fd2d9f03 1574 BOOLEAN search_revocations = TRUE;
e6ace38a
SM
1575
1576 efi_status = gBS->HandleProtocol(image_handle, &EFI_LOADED_IMAGE_GUID,
1577 (void **)&li);
1578 if (EFI_ERROR(efi_status)) {
1579 perror(L"Unable to init protocol\n");
1580 return efi_status;
1581 }
1582
1583 efi_status = generate_path_from_image_path(li, L"", &PathName);
1584 if (EFI_ERROR(efi_status))
1585 goto done;
1586
1587 device = li->DeviceHandle;
1588 efi_status = gBS->HandleProtocol(device, &EFI_SIMPLE_FILE_SYSTEM_GUID,
1589 (void **)&drive);
1590 if (EFI_ERROR(efi_status)) {
fd2d9f03
SM
1591 dprint(L"Failed to find fs on local drive (netboot?): %r \n",
1592 efi_status);
1593 /*
1594 * Network boot cases do not support reading a directory. Try
1595 * to read revocations.efi to pull in any unbundled SBATLevel
1596 * updates unconditionally in those cases. This may produce
1597 * console noise when the file is not present.
1598 */
1599 load_cert_file(image_handle, REVOCATIONFILE, PathName);
e6ace38a
SM
1600 goto done;
1601 }
1602
1603 efi_status = drive->OpenVolume(drive, &root);
1604 if (EFI_ERROR(efi_status)) {
1605 perror(L"Failed to open fs: %r\n", efi_status);
1606 goto done;
1607 }
1608
1609 efi_status = root->Open(root, &dir, PathName, EFI_FILE_MODE_READ, 0);
1610 if (EFI_ERROR(efi_status)) {
1611 perror(L"Failed to open %s - %r\n", PathName, efi_status);
1612 goto done;
1613 }
1614
fd2d9f03
SM
1615 if (!secure_mode())
1616 goto done;
1617
1618
1619 while (true) {
1620 UINTN old = buffersize;
1621
e6ace38a
SM
1622 efi_status = dir->Read(dir, &buffersize, buffer);
1623 if (efi_status == EFI_BUFFER_TOO_SMALL) {
fd2d9f03
SM
1624 if (buffersize == old) {
1625 /*
1626 * Some UEFI drivers or firmwares are not compliant with
1627 * the EFI_FILE_PROTOCOL.Read() specs and do not return the
1628 * required buffer size along with EFI_BUFFER_TOO_SMALL.
1629 * Work around this by progressively increasing the buffer
1630 * size, up to a certain point, until the call succeeds.
1631 */
1632 perror(L"Error reading directory %s - non-compliant UEFI driver or firmware!\n",
1633 PathName);
1634 buffersize = (buffersize < 4) ? 4 : buffersize * 2;
1635 if (buffersize > 1024)
1636 goto done;
1637 }
e6ace38a 1638 buffer = ReallocatePool(buffer, old, buffersize);
fd2d9f03
SM
1639 if (buffer == NULL) {
1640 perror(L"Failed to read directory %s - %r\n",
1641 PathName, EFI_OUT_OF_RESOURCES);
1642 goto done;
1643 }
e6ace38a
SM
1644 continue;
1645 } else if (EFI_ERROR(efi_status)) {
1646 perror(L"Failed to read directory %s - %r\n", PathName,
fd2d9f03 1647 efi_status);
e6ace38a
SM
1648 goto done;
1649 }
1650
1651 info = (EFI_FILE_INFO *)buffer;
fd2d9f03
SM
1652 if (buffersize == 0 || !info) {
1653 if (search_revocations) {
1654 search_revocations = FALSE;
1655 efi_status = root->Open(root, &dir, PathName,
1656 EFI_FILE_MODE_READ, 0);
1657 if (EFI_ERROR(efi_status)) {
1658 perror(L"Failed to open %s - %r\n",
1659 PathName, efi_status);
1660 goto done;
1661 }
1662 continue;
1663 } else {
1664 goto done;
1665 }
1666 }
e6ace38a 1667
fd2d9f03
SM
1668 /*
1669 * In the event that there are unprocessed revocation
1670 * additions, they could be intended to ban any *new* trust
1671 * anchors we find here. With that in mind, we always want to
1672 * do a pass of loading revocations before we try to add
1673 * anything new to our allowlist. This is done by making two
1674 * passes over the directory, first to search for the
1675 * revocations.efi file then to search for shim_certificate.efi
1676 */
1677 if (search_revocations &&
1678 StrCaseCmp(info->FileName, REVOCATIONFILE) == 0) {
1679 load_revocations_file(image_handle, PathName);
1680 search_revocations = FALSE;
1681 efi_status = root->Open(root, &dir, PathName,
1682 EFI_FILE_MODE_READ, 0);
1683 if (EFI_ERROR(efi_status)) {
1684 perror(L"Failed to open %s - %r\n",
1685 PathName, efi_status);
1686 goto done;
1687 }
1688 }
1689
1690 if (!search_revocations &&
1691 StrCaseCmp(info->FileName, L"shim_certificate.efi") == 0) {
e6ace38a
SM
1692 load_cert_file(image_handle, info->FileName, PathName);
1693 }
1694 }
1695done:
1696 FreePool(buffer);
1697 FreePool(PathName);
1698 return efi_status;
1699}
1700
d3819813
MTL
1701EFI_STATUS
1702shim_init(void)
1703{
031e5cce
SM
1704 EFI_STATUS efi_status;
1705
f892ac66 1706 dprint(L"%a", shim_version);
d3819813
MTL
1707
1708 /* Set the second stage loader */
031e5cce
SM
1709 efi_status = set_second_stage(global_image_handle);
1710 if (EFI_ERROR(efi_status)) {
1711 perror(L"set_second_stage() failed: %r\n", efi_status);
1712 return efi_status;
1713 }
d3819813
MTL
1714
1715 if (secure_mode()) {
031e5cce 1716 if (vendor_authorized_size || vendor_deauthorized_size) {
d3819813
MTL
1717 /*
1718 * If shim includes its own certificates then ensure
1719 * that anything it boots has performed some
1720 * validation of the next image.
1721 */
1722 hook_system_services(systab);
1723 loader_is_participating = 0;
1724 }
1725
d3819813 1726 }
f892ac66 1727
031e5cce
SM
1728 hook_exit(systab);
1729
1730 efi_status = install_shim_protocols();
1731 if (EFI_ERROR(efi_status))
1732 perror(L"install_shim_protocols() failed: %r\n", efi_status);
1733
1734 return efi_status;
d3819813
MTL
1735}
1736
1737void
1738shim_fini(void)
1739{
031e5cce
SM
1740 if (secure_mode())
1741 cleanup_sbat_var(&sbat_var);
1742
f892ac66
MTL
1743 /*
1744 * Remove our protocols
1745 */
1746 uninstall_shim_protocols();
1747
d3819813 1748 if (secure_mode()) {
d3819813
MTL
1749
1750 /*
1751 * Remove our hooks from system services.
1752 */
1753 unhook_system_services();
d3819813
MTL
1754 }
1755
031e5cce
SM
1756 unhook_exit();
1757
f892ac66 1758 console_fini();
d3819813
MTL
1759}
1760
1761extern EFI_STATUS
1762efi_main(EFI_HANDLE passed_image_handle, EFI_SYSTEM_TABLE *passed_systab);
1763
1764static void
1765__attribute__((__optimize__("0")))
1766debug_hook(void)
1767{
d3819813
MTL
1768 UINT8 *data = NULL;
1769 UINTN dataSize = 0;
1770 EFI_STATUS efi_status;
031e5cce 1771 register volatile UINTN x = 0;
d3819813
MTL
1772 extern char _text, _data;
1773
1774 if (x)
1775 return;
1776
e6ace38a 1777 efi_status = get_variable(DEBUG_VAR_NAME, &data, &dataSize,
f892ac66 1778 SHIM_LOCK_GUID);
d3819813
MTL
1779 if (EFI_ERROR(efi_status)) {
1780 return;
1781 }
1782
f892ac66
MTL
1783 FreePool(data);
1784
1785 console_print(L"add-symbol-file "DEBUGDIR
1786 L"shim" EFI_ARCH L".efi.debug 0x%08x -s .data 0x%08x\n",
1787 &_text, &_data);
d3819813 1788
f892ac66 1789 console_print(L"Pausing for debugger attachment.\n");
031e5cce 1790 console_print(L"To disable this, remove the EFI variable %s-%g .\n",
e6ace38a 1791 DEBUG_VAR_NAME, &SHIM_LOCK_GUID);
d3819813
MTL
1792 x = 1;
1793 while (x++) {
1794 /* Make this so it can't /totally/ DoS us. */
1795#if defined(__x86_64__) || defined(__i386__) || defined(__i686__)
1796 if (x > 4294967294ULL)
1797 break;
d3819813
MTL
1798#elif defined(__aarch64__)
1799 if (x > 1000)
1800 break;
d3819813
MTL
1801#else
1802 if (x > 12000)
1803 break;
d3819813 1804#endif
8529e0f7 1805 wait_for_debug();
d3819813
MTL
1806 }
1807 x = 1;
1808}
1809
031e5cce
SM
1810typedef enum {
1811 COLD_RESET,
1812 EXIT_FAILURE,
1813 EXIT_SUCCESS, // keep this one last
1814} devel_egress_action;
1815
1816void
1817devel_egress(devel_egress_action action UNUSED)
1818{
1819#ifdef ENABLE_SHIM_DEVEL
1820 char *reasons[] = {
1821 [COLD_RESET] = "reset",
1822 [EXIT_FAILURE] = "exit",
1823 };
1824 if (action == EXIT_SUCCESS)
1825 return;
1826
1827 console_print(L"Waiting to %a...", reasons[action]);
1828 for (size_t sleepcount = 0; sleepcount < 10; sleepcount++) {
1829 console_print(L"%d...", 10 - sleepcount);
fd2d9f03 1830 usleep(1000000);
031e5cce
SM
1831 }
1832 console_print(L"\ndoing %a\n", action);
1833
1834 if (action == COLD_RESET)
8529e0f7 1835 RT->ResetSystem(EfiResetCold, EFI_SECURITY_VIOLATION, 0, NULL);
031e5cce
SM
1836#endif
1837}
1838
d3819813
MTL
1839EFI_STATUS
1840efi_main (EFI_HANDLE passed_image_handle, EFI_SYSTEM_TABLE *passed_systab)
cf90edff 1841{
0a232ca9 1842 EFI_STATUS efi_status;
f4173af1 1843 EFI_HANDLE image_handle;
db54b0a4 1844
cbef697a
PJ
1845 verification_method = VERIFIED_BY_NOTHING;
1846
031e5cce
SM
1847 vendor_authorized_size = cert_table.vendor_authorized_size;
1848 vendor_authorized = (UINT8 *)&cert_table + cert_table.vendor_authorized_offset;
1849
1850 vendor_deauthorized_size = cert_table.vendor_deauthorized_size;
1851 vendor_deauthorized = (UINT8 *)&cert_table + cert_table.vendor_deauthorized_offset;
1852
1853#if defined(ENABLE_SHIM_CERT)
1854 build_cert_size = sizeof(shim_cert);
1855 build_cert = shim_cert;
1856#endif /* defined(ENABLE_SHIM_CERT) */
1857
f892ac66 1858 CHAR16 *msgs[] = {
031e5cce
SM
1859 L"import_mok_state() failed",
1860 L"shim_init() failed",
1861 L"import of SBAT data failed",
1862 L"SBAT self-check failed",
8119f718 1863 SBAT_VAR_NAME L" UEFI variable setting failed",
f892ac66
MTL
1864 NULL
1865 };
031e5cce
SM
1866 enum {
1867 IMPORT_MOK_STATE,
1868 SHIM_INIT,
1869 IMPORT_SBAT,
1870 SBAT_SELF_CHECK,
1871 SET_SBAT,
1872 } msg = IMPORT_MOK_STATE;
a1f28635 1873
20f6cde6
MG
1874 /*
1875 * Set up the shim lock protocol so that grub and MokManager can
1876 * call back in and use shim functions
1877 */
db54b0a4 1878 shim_lock_interface.Verify = shim_verify;
e50cfe37
GCPL
1879 shim_lock_interface.Hash = shim_hash;
1880 shim_lock_interface.Context = shim_read_header;
db54b0a4
MG
1881
1882 systab = passed_systab;
f4173af1 1883 image_handle = global_image_handle = passed_image_handle;
db54b0a4 1884
20f6cde6
MG
1885 /*
1886 * Ensure that gnu-efi functions are available
1887 */
db54b0a4 1888 InitializeLib(image_handle, systab);
031e5cce 1889 setup_verbosity();
db54b0a4 1890
031e5cce
SM
1891 dprint(L"vendor_authorized:0x%08lx vendor_authorized_size:%lu\n",
1892 vendor_authorized, vendor_authorized_size);
1893 dprint(L"vendor_deauthorized:0x%08lx vendor_deauthorized_size:%lu\n",
1894 vendor_deauthorized, vendor_deauthorized_size);
b6f94dbe 1895
d3819813
MTL
1896 /*
1897 * if SHIM_DEBUG is set, wait for a debugger to attach.
1898 */
1899 debug_hook();
0fb089ee 1900
fd2d9f03 1901 efi_status = set_sbat_uefi_variable_internal();
031e5cce 1902 if (EFI_ERROR(efi_status) && secure_mode()) {
8119f718 1903 perror(L"%s variable initialization failed\n", SBAT_VAR_NAME);
031e5cce
SM
1904 msg = SET_SBAT;
1905 goto die;
1906 } else if (EFI_ERROR(efi_status)) {
8119f718
SM
1907 dprint(L"%s variable initialization failed: %r\n",
1908 SBAT_VAR_NAME, efi_status);
031e5cce 1909 }
fd2d9f03
SM
1910 efi_status = set_ssp_uefi_variable_internal();
1911 if (EFI_ERROR(efi_status)) {
1912 dprint(L"%s variable initialization failed: %r\n",
1913 SSPVER_VAR_NAME, efi_status);
1914 }
1915 dprint(L"%s variable initialization done\n", SSPVER_VAR_NAME);
031e5cce
SM
1916
1917 if (secure_mode()) {
1918 char *sbat_start = (char *)&_sbat;
1919 char *sbat_end = (char *)&_esbat;
1920
1921 INIT_LIST_HEAD(&sbat_var);
fd2d9f03 1922 efi_status = parse_sbat_var(&sbat_var, NULL);
031e5cce 1923 if (EFI_ERROR(efi_status)) {
8119f718
SM
1924 perror(L"Parsing %s variable failed: %r\n",
1925 SBAT_VAR_NAME, efi_status);
031e5cce
SM
1926 msg = IMPORT_SBAT;
1927 goto die;
1928 }
1929
e6ace38a 1930 efi_status = verify_sbat_section(sbat_start, sbat_end - sbat_start - 1);
031e5cce
SM
1931 if (EFI_ERROR(efi_status)) {
1932 perror(L"Verifiying shim SBAT data failed: %r\n",
1933 efi_status);
1934 msg = SBAT_SELF_CHECK;
1935 goto die;
1936 }
8119f718 1937 dprint(L"SBAT self-check succeeded\n");
031e5cce
SM
1938 }
1939
1940 init_openssl();
1941
fd2d9f03
SM
1942 efi_status = load_unbundled_trust(global_image_handle);
1943 if (EFI_ERROR(efi_status)) {
1944 LogError(L"Failed to load addon certificates / sbat level\n");
e6ace38a
SM
1945 }
1946
d3819813 1947 /*
f892ac66
MTL
1948 * Before we do anything else, validate our non-volatile,
1949 * boot-services-only state variables are what we think they are.
d3819813 1950 */
f892ac66 1951 efi_status = import_mok_state(image_handle);
8529e0f7
SM
1952 if (!secure_mode() &&
1953 (efi_status == EFI_INVALID_PARAMETER ||
1954 efi_status == EFI_OUT_OF_RESOURCES)) {
031e5cce
SM
1955 /*
1956 * Make copy failures fatal only if secure_mode is enabled, or
8529e0f7
SM
1957 * the error was anything else than EFI_INVALID_PARAMETER or
1958 * EFI_OUT_OF_RESOURCES.
031e5cce
SM
1959 * There are non-secureboot firmware implementations that don't
1960 * reserve enough EFI variable memory to fit the variable.
1961 */
1962 console_print(L"Importing MOK states has failed: %s: %r\n",
1963 msgs[msg], efi_status);
1964 console_print(L"Continuing boot since secure mode is disabled");
1965 } else if (EFI_ERROR(efi_status)) {
f892ac66
MTL
1966die:
1967 console_print(L"Something has gone seriously wrong: %s: %r\n",
1968 msgs[msg], efi_status);
031e5cce
SM
1969#if defined(ENABLE_SHIM_DEVEL)
1970 devel_egress(COLD_RESET);
1971#else
fd2d9f03 1972 usleep(5000000);
8529e0f7
SM
1973 RT->ResetSystem(EfiResetShutdown, EFI_SECURITY_VIOLATION,
1974 0, NULL);
031e5cce 1975#endif
d3819813 1976 }
09e2c939 1977
fd2d9f03
SM
1978 /*
1979 * This variable is supposed to be set by second stages, so ensure it is
1980 * not set when we are starting up.
1981 */
1982 (void) del_variable(SHIM_RETAIN_PROTOCOL_VAR_NAME, SHIM_LOCK_GUID);
1983
d3819813
MTL
1984 efi_status = shim_init();
1985 if (EFI_ERROR(efi_status)) {
031e5cce 1986 msg = SHIM_INIT;
f892ac66 1987 goto die;
d3819813
MTL
1988 }
1989
20f6cde6
MG
1990 /*
1991 * Tell the user that we're in insecure mode if necessary
1992 */
e60f1181 1993 if (user_insecure_mode) {
f892ac66 1994 console_print(L"Booting in insecure mode\n");
fd2d9f03 1995 usleep(2000000);
9eaadb0d
MG
1996 }
1997
0283024e 1998 /*
d3819813 1999 * Hand over control to the second stage bootloader
0283024e 2000 */
d3819813 2001 efi_status = init_grub(image_handle);
bc71a15e 2002
d3819813 2003 shim_fini();
031e5cce 2004 devel_egress(EFI_ERROR(efi_status) ? EXIT_FAILURE : EXIT_SUCCESS);
0a232ca9 2005 return efi_status;
b2fe1780 2006}