]> git.proxmox.com Git - efi-boot-shim.git/blame - shim.c
Update the 32-bit format patch after upstream review
[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
f892ac66
MTL
400 if (check_db_hash(L"MokList", SHIM_LOCK_GUID, sha256hash,
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
MTL
406 } else {
407 LogError(L"check_db_hash(MokList, sha256hash) != DATA_FOUND\n");
cbef697a 408 }
f892ac66
MTL
409 if (cert && check_db_cert(L"MokList", SHIM_LOCK_GUID, cert, sha256hash)
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) {
b6f94dbe 415 LogError(L"check_db_cert(MokList, 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
562verify_buffer (char *data, int datasize,
563 PE_COFF_LOADER_IMAGE_CONTEXT *context,
564 UINT8 *sha256hash, UINT8 *sha1hash)
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
031e5cce
SM
630 if (context->SecDir->Size >= size) {
631 perror(L"Certificate Database size is too large\n");
632 return EFI_INVALID_PARAMETER;
633 }
d3819813 634
031e5cce
SM
635 ret_efi_status = EFI_NOT_FOUND;
636 do {
637 WIN_CERTIFICATE_EFI_PKCS *sig = NULL;
638 size_t sz;
d3819813 639
031e5cce
SM
640 sig = ImageAddress(data, size,
641 context->SecDir->VirtualAddress + offset);
642 if (!sig)
643 break;
62f0afa2 644
031e5cce
SM
645 sz = offset + offsetof(WIN_CERTIFICATE_EFI_PKCS, Hdr.dwLength)
646 + sizeof(sig->Hdr.dwLength);
647 if (sz > context->SecDir->Size) {
648 perror(L"Certificate size is too large for secruity database");
649 return EFI_INVALID_PARAMETER;
650 }
b2fe1780 651
031e5cce
SM
652 sz = sig->Hdr.dwLength;
653 if (sz > context->SecDir->Size - offset) {
654 perror(L"Certificate size is too large for secruity database");
655 return EFI_INVALID_PARAMETER;
62f0afa2 656 }
b2fe1780 657
031e5cce
SM
658 if (sz < sizeof(sig->Hdr)) {
659 perror(L"Certificate size is too small for certificate data");
660 return EFI_INVALID_PARAMETER;
661 }
486bf03e 662
031e5cce
SM
663 if (sig->Hdr.wCertificateType == WIN_CERT_TYPE_PKCS_SIGNED_DATA) {
664 EFI_STATUS efi_status;
486bf03e 665
031e5cce 666 dprint(L"Attempting to verify signature %d:\n", i++);
b2fe1780 667
031e5cce 668 efi_status = verify_one_signature(sig, sha256hash, sha1hash);
5fe882ba 669
031e5cce
SM
670 /*
671 * If we didn't get EFI_SECURITY_VIOLATION from
672 * checking the hashes above, then any dbx entries are
673 * for a certificate, not this individual binary.
674 *
675 * So don't clobber successes with security violation
676 * here; that just means it isn't a success.
677 */
678 if (ret_efi_status != EFI_SUCCESS)
679 ret_efi_status = efi_status;
680 } else {
681 perror(L"Unsupported certificate type %x\n",
682 sig->Hdr.wCertificateType);
683 }
684 offset = ALIGN_VALUE(offset + sz, 8);
685 } while (offset < context->SecDir->Size);
09e2c939 686
031e5cce
SM
687 if (ret_efi_status != EFI_SUCCESS) {
688 dprint(L"Binary is not authorized\n");
689 PrintErrors();
690 ClearErrors();
691 crypterr(EFI_SECURITY_VIOLATION);
692 ret_efi_status = EFI_SECURITY_VIOLATION;
0e6b0195 693 }
031e5cce
SM
694 drain_openssl_errors();
695 return ret_efi_status;
b2fe1780
MG
696}
697
6d6b0221 698static int
8529e0f7 699is_removable_media_path(EFI_LOADED_IMAGE *li)
6d6b0221 700{
6d6b0221 701 unsigned int pathlen = 0;
fe8527aa 702 CHAR16 *bootpath = NULL;
fe8527aa 703 int ret = 0;
6d6b0221 704
2e7fc28d 705 bootpath = DevicePathToStr(li->FilePath);
6d6b0221
PJ
706
707 /* Check the beginning of the string and the end, to avoid
708 * caring about which arch this is. */
709 /* I really don't know why, but sometimes bootpath gives us
710 * L"\\EFI\\BOOT\\/BOOTX64.EFI". So just handle that here...
711 */
712 if (StrnCaseCmp(bootpath, L"\\EFI\\BOOT\\BOOT", 14) &&
d3819813
MTL
713 StrnCaseCmp(bootpath, L"\\EFI\\BOOT\\/BOOT", 15) &&
714 StrnCaseCmp(bootpath, L"EFI\\BOOT\\BOOT", 13) &&
715 StrnCaseCmp(bootpath, L"EFI\\BOOT\\/BOOT", 14))
fe8527aa 716 goto error;
2e7fc28d 717
6d6b0221
PJ
718 pathlen = StrLen(bootpath);
719 if (pathlen < 5 || StrCaseCmp(bootpath + pathlen - 4, L".EFI"))
fe8527aa 720 goto error;
6d6b0221 721
8529e0f7
SM
722 ret = 1;
723
724error:
725 if (bootpath)
726 FreePool(bootpath);
727
728 return ret;
729}
730
731static int
732should_use_fallback(EFI_HANDLE image_handle)
733{
734 EFI_LOADED_IMAGE *li;
735 EFI_FILE_IO_INTERFACE *fio = NULL;
736 EFI_FILE *vh = NULL;
737 EFI_FILE *fh = NULL;
738 EFI_STATUS efi_status;
739 int ret = 0;
740
741 efi_status = BS->HandleProtocol(image_handle, &EFI_LOADED_IMAGE_GUID,
742 (void **)&li);
743 if (EFI_ERROR(efi_status)) {
744 perror(L"Could not get image for boot" EFI_ARCH L".efi: %r\n",
745 efi_status);
746 return 0;
747 }
748
749 if (!is_removable_media_path(li))
750 goto error;
751
752 efi_status = BS->HandleProtocol(li->DeviceHandle, &FileSystemProtocol,
753 (void **) &fio);
f892ac66
MTL
754 if (EFI_ERROR(efi_status)) {
755 perror(L"Could not get fio for li->DeviceHandle: %r\n",
756 efi_status);
fe8527aa 757 goto error;
c9d11306 758 }
e50cfe37 759
f892ac66
MTL
760 efi_status = fio->OpenVolume(fio, &vh);
761 if (EFI_ERROR(efi_status)) {
762 perror(L"Could not open fio volume: %r\n", efi_status);
fe8527aa 763 goto error;
c9d11306 764 }
6d6b0221 765
f892ac66
MTL
766 efi_status = vh->Open(vh, &fh, L"\\EFI\\BOOT" FALLBACK,
767 EFI_FILE_MODE_READ, 0);
768 if (EFI_ERROR(efi_status)) {
b32a3ce1
PJ
769 /* Do not print the error here - this is an acceptable case
770 * for removable media, where we genuinely don't want
771 * fallback.efi to exist.
f892ac66
MTL
772 * Print(L"Could not open \"\\EFI\\BOOT%s\": %r\n", FALLBACK,
773 * efi_status);
b32a3ce1 774 */
fe8527aa 775 goto error;
6d6b0221 776 }
6d6b0221 777
fe8527aa
GCPL
778 ret = 1;
779error:
d3819813 780 if (fh)
f892ac66 781 fh->Close(fh);
d3819813 782 if (vh)
f892ac66 783 vh->Close(vh);
fe8527aa
GCPL
784
785 return ret;
6d6b0221 786}
db54b0a4 787/*
20f6cde6 788 * Open the second stage bootloader and read it into a buffer
db54b0a4 789 */
822d089e
GCPL
790static EFI_STATUS load_image (EFI_LOADED_IMAGE *li, void **data,
791 int *datasize, CHAR16 *PathName)
db54b0a4 792{
db54b0a4
MG
793 EFI_STATUS efi_status;
794 EFI_HANDLE device;
795 EFI_FILE_INFO *fileinfo = NULL;
796 EFI_FILE_IO_INTERFACE *drive;
797 EFI_FILE *root, *grub;
6eb1eca4 798 UINTN buffersize = sizeof(EFI_FILE_INFO);
db54b0a4
MG
799
800 device = li->DeviceHandle;
f898777d 801
031e5cce 802 dprint(L"attempting to load %s\n", PathName);
20f6cde6
MG
803 /*
804 * Open the device
805 */
8529e0f7
SM
806 efi_status = BS->HandleProtocol(device, &EFI_SIMPLE_FILE_SYSTEM_GUID,
807 (void **) &drive);
f892ac66 808 if (EFI_ERROR(efi_status)) {
e50cfe37 809 perror(L"Failed to find fs: %r\n", efi_status);
0db1af8a
MG
810 goto error;
811 }
f898777d 812
f892ac66
MTL
813 efi_status = drive->OpenVolume(drive, &root);
814 if (EFI_ERROR(efi_status)) {
e50cfe37 815 perror(L"Failed to open fs: %r\n", efi_status);
0db1af8a
MG
816 goto error;
817 }
f898777d 818
20f6cde6
MG
819 /*
820 * And then open the file
821 */
f892ac66
MTL
822 efi_status = root->Open(root, &grub, PathName, EFI_FILE_MODE_READ, 0);
823 if (EFI_ERROR(efi_status)) {
e50cfe37 824 perror(L"Failed to open %s - %r\n", PathName, efi_status);
0db1af8a
MG
825 goto error;
826 }
827
828 fileinfo = AllocatePool(buffersize);
829
830 if (!fileinfo) {
e50cfe37 831 perror(L"Unable to allocate file info buffer\n");
0db1af8a
MG
832 efi_status = EFI_OUT_OF_RESOURCES;
833 goto error;
f898777d
MG
834 }
835
20f6cde6
MG
836 /*
837 * Find out how big the file is in order to allocate the storage
838 * buffer
839 */
f892ac66
MTL
840 efi_status = grub->GetInfo(grub, &EFI_FILE_INFO_GUID, &buffersize,
841 fileinfo);
f898777d 842 if (efi_status == EFI_BUFFER_TOO_SMALL) {
cbe21407 843 FreePool(fileinfo);
f898777d
MG
844 fileinfo = AllocatePool(buffersize);
845 if (!fileinfo) {
e50cfe37 846 perror(L"Unable to allocate file info buffer\n");
0db1af8a
MG
847 efi_status = EFI_OUT_OF_RESOURCES;
848 goto error;
f898777d 849 }
f892ac66
MTL
850 efi_status = grub->GetInfo(grub, &EFI_FILE_INFO_GUID,
851 &buffersize, fileinfo);
f898777d
MG
852 }
853
f892ac66 854 if (EFI_ERROR(efi_status)) {
e50cfe37 855 perror(L"Unable to get file info: %r\n", efi_status);
0db1af8a 856 goto error;
f898777d
MG
857 }
858
859 buffersize = fileinfo->FileSize;
7db60bd8 860 *data = AllocatePool(buffersize);
7db60bd8 861 if (!*data) {
e50cfe37 862 perror(L"Unable to allocate file buffer\n");
0db1af8a
MG
863 efi_status = EFI_OUT_OF_RESOURCES;
864 goto error;
f898777d 865 }
20f6cde6
MG
866
867 /*
868 * Perform the actual read
869 */
f892ac66 870 efi_status = grub->Read(grub, &buffersize, *data);
0db1af8a
MG
871 if (efi_status == EFI_BUFFER_TOO_SMALL) {
872 FreePool(*data);
873 *data = AllocatePool(buffersize);
f892ac66 874 efi_status = grub->Read(grub, &buffersize, *data);
f898777d 875 }
f892ac66
MTL
876 if (EFI_ERROR(efi_status)) {
877 perror(L"Unexpected return from initial read: %r, buffersize %x\n",
878 efi_status, buffersize);
0db1af8a 879 goto error;
f898777d
MG
880 }
881
7db60bd8 882 *datasize = buffersize;
f898777d 883
cbe21407
MG
884 FreePool(fileinfo);
885
f898777d 886 return EFI_SUCCESS;
0db1af8a
MG
887error:
888 if (*data) {
889 FreePool(*data);
890 *data = NULL;
891 }
6f161626 892
0db1af8a
MG
893 if (fileinfo)
894 FreePool(fileinfo);
895 return efi_status;
f898777d
MG
896}
897
20f6cde6
MG
898/*
899 * Protocol entry point. If secure boot is enabled, verify that the provided
900 * buffer is signed with a trusted key.
901 */
db54b0a4 902EFI_STATUS shim_verify (void *buffer, UINT32 size)
f4b24734 903{
f892ac66 904 EFI_STATUS efi_status = EFI_SUCCESS;
f4b24734 905 PE_COFF_LOADER_IMAGE_CONTEXT context;
b6f94dbe
MTL
906 UINT8 sha1hash[SHA1_DIGEST_SIZE];
907 UINT8 sha256hash[SHA256_DIGEST_SIZE];
f4b24734 908
f892ac66
MTL
909 if ((INT32)size < 0)
910 return EFI_INVALID_PARAMETER;
911
cbef697a 912 loader_is_participating = 1;
e50cfe37 913 in_protocol = 1;
cbef697a 914
f892ac66
MTL
915 efi_status = read_header(buffer, size, &context);
916 if (EFI_ERROR(efi_status))
d3819813 917 goto done;
6279b58e 918
f892ac66
MTL
919 efi_status = generate_hash(buffer, size, &context,
920 sha256hash, sha1hash);
921 if (EFI_ERROR(efi_status))
e50cfe37 922 goto done;
f4b24734 923
f892ac66
MTL
924 /* Measure the binary into the TPM */
925#ifdef REQUIRE_TPM
926 efi_status =
927#endif
031e5cce
SM
928 tpm_log_pe((EFI_PHYSICAL_ADDRESS)(UINTN)buffer, size, 0, NULL,
929 sha1hash, 4);
f892ac66
MTL
930#ifdef REQUIRE_TPM
931 if (EFI_ERROR(efi_status))
932 goto done;
933#endif
934
935 if (!secure_mode()) {
936 efi_status = EFI_SUCCESS;
b6f94dbe 937 goto done;
f892ac66 938 }
b6f94dbe 939
031e5cce
SM
940 efi_status = verify_buffer(buffer, size,
941 &context, sha256hash, sha1hash);
e50cfe37
GCPL
942done:
943 in_protocol = 0;
f892ac66 944 return efi_status;
e50cfe37
GCPL
945}
946
947static EFI_STATUS shim_hash (char *data, int datasize,
948 PE_COFF_LOADER_IMAGE_CONTEXT *context,
949 UINT8 *sha256hash, UINT8 *sha1hash)
950{
f892ac66
MTL
951 EFI_STATUS efi_status;
952
953 if (datasize < 0)
954 return EFI_INVALID_PARAMETER;
e50cfe37
GCPL
955
956 in_protocol = 1;
f892ac66
MTL
957 efi_status = generate_hash(data, datasize, context,
958 sha256hash, sha1hash);
e50cfe37
GCPL
959 in_protocol = 0;
960
f892ac66 961 return efi_status;
e50cfe37
GCPL
962}
963
964static EFI_STATUS shim_read_header(void *data, unsigned int datasize,
965 PE_COFF_LOADER_IMAGE_CONTEXT *context)
966{
f892ac66 967 EFI_STATUS efi_status;
e50cfe37
GCPL
968
969 in_protocol = 1;
f892ac66 970 efi_status = read_header(data, datasize, context);
e50cfe37 971 in_protocol = 0;
f4b24734 972
f892ac66 973 return efi_status;
f4b24734
MG
974}
975
031e5cce
SM
976VOID
977restore_loaded_image(VOID)
978{
979 if (shim_li->FilePath)
980 FreePool(shim_li->FilePath);
981
982 /*
983 * Restore our original loaded image values
984 */
985 CopyMem(shim_li, &shim_li_bak, sizeof(shim_li_bak));
986}
987
20f6cde6
MG
988/*
989 * Load and run an EFI executable
990 */
cec6a0a9 991EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath)
822d089e
GCPL
992{
993 EFI_STATUS efi_status;
f892ac66
MTL
994 EFI_IMAGE_ENTRY_POINT entry_point;
995 EFI_PHYSICAL_ADDRESS alloc_address;
996 UINTN alloc_pages;
1c595706
MG
997 CHAR16 *PathName = NULL;
998 void *sourcebuffer = NULL;
fbc486b5 999 UINT64 sourcesize = 0;
822d089e 1000 void *data = NULL;
031e5cce 1001 int datasize = 0;
822d089e 1002
20f6cde6
MG
1003 /*
1004 * We need to refer to the loaded image protocol on the running
1005 * binary in order to find our path
1006 */
8529e0f7
SM
1007 efi_status = BS->HandleProtocol(image_handle, &EFI_LOADED_IMAGE_GUID,
1008 (void **)&shim_li);
f892ac66 1009 if (EFI_ERROR(efi_status)) {
e50cfe37 1010 perror(L"Unable to init protocol\n");
cec6a0a9
GCPL
1011 return efi_status;
1012 }
1013
20f6cde6
MG
1014 /*
1015 * Build a new path from the existing one plus the executable name
1016 */
031e5cce 1017 efi_status = generate_path_from_image_path(shim_li, ImagePath, &PathName);
f892ac66
MTL
1018 if (EFI_ERROR(efi_status)) {
1019 perror(L"Unable to generate path %s: %r\n", ImagePath,
1020 efi_status);
cec6a0a9
GCPL
1021 goto done;
1022 }
1023
031e5cce 1024 if (findNetboot(shim_li->DeviceHandle)) {
1c595706 1025 efi_status = parseNetbootinfo(image_handle);
f892ac66 1026 if (EFI_ERROR(efi_status)) {
e50cfe37 1027 perror(L"Netboot parsing failed: %r\n", efi_status);
1c595706
MG
1028 return EFI_PROTOCOL_ERROR;
1029 }
1030 efi_status = FetchNetbootimage(image_handle, &sourcebuffer,
1031 &sourcesize);
f892ac66
MTL
1032 if (EFI_ERROR(efi_status)) {
1033 perror(L"Unable to fetch TFTP image: %r\n",
1034 efi_status);
1c595706
MG
1035 return efi_status;
1036 }
1037 data = sourcebuffer;
1038 datasize = sourcesize;
031e5cce 1039 } else if (find_httpboot(shim_li->DeviceHandle)) {
f892ac66
MTL
1040 efi_status = httpboot_fetch_buffer (image_handle,
1041 &sourcebuffer,
62f0afa2 1042 &sourcesize);
f892ac66
MTL
1043 if (EFI_ERROR(efi_status)) {
1044 perror(L"Unable to fetch HTTP image: %r\n",
1045 efi_status);
62f0afa2
MTL
1046 return efi_status;
1047 }
1048 data = sourcebuffer;
1049 datasize = sourcesize;
1c595706 1050 } else {
4ad234f1
MG
1051 /*
1052 * Read the new executable off disk
1053 */
031e5cce 1054 efi_status = load_image(shim_li, &data, &datasize, PathName);
f892ac66
MTL
1055 if (EFI_ERROR(efi_status)) {
1056 perror(L"Failed to load image %s: %r\n",
1057 PathName, efi_status);
b6f94dbe
MTL
1058 PrintErrors();
1059 ClearErrors();
1c595706
MG
1060 goto done;
1061 }
822d089e
GCPL
1062 }
1063
f892ac66
MTL
1064 if (datasize < 0) {
1065 efi_status = EFI_INVALID_PARAMETER;
1066 goto done;
1067 }
1068
20f6cde6
MG
1069 /*
1070 * We need to modify the loaded image protocol entry before running
1071 * the new binary, so back it up
1072 */
031e5cce
SM
1073 CopyMem(&shim_li_bak, shim_li, sizeof(shim_li_bak));
1074
1075 /*
1076 * Update the loaded image with the second stage loader file path
1077 */
1078 shim_li->FilePath = FileDevicePath(NULL, PathName);
1079 if (!shim_li->FilePath) {
1080 perror(L"Unable to update loaded image file path\n");
1081 efi_status = EFI_OUT_OF_RESOURCES;
1082 goto restore;
1083 }
822d089e 1084
20f6cde6
MG
1085 /*
1086 * Verify and, if appropriate, relocate and execute the executable
1087 */
031e5cce 1088 efi_status = handle_image(data, datasize, shim_li, &entry_point,
f892ac66
MTL
1089 &alloc_address, &alloc_pages);
1090 if (EFI_ERROR(efi_status)) {
e50cfe37 1091 perror(L"Failed to load image: %r\n", efi_status);
b6f94dbe
MTL
1092 PrintErrors();
1093 ClearErrors();
031e5cce 1094 goto restore;
822d089e
GCPL
1095 }
1096
cbef697a
PJ
1097 loader_is_participating = 0;
1098
20f6cde6
MG
1099 /*
1100 * The binary is trusted and relocated. Run it
1101 */
f892ac66 1102 efi_status = entry_point(image_handle, systab);
822d089e 1103
031e5cce
SM
1104restore:
1105 restore_loaded_image();
822d089e 1106done:
cbe21407
MG
1107 if (PathName)
1108 FreePool(PathName);
1109
1110 if (data)
1111 FreePool(data);
1112
822d089e
GCPL
1113 return efi_status;
1114}
1115
20f6cde6
MG
1116/*
1117 * Load and run grub. If that fails because grub isn't trusted, load and
1118 * run MokManager.
1119 */
db54b0a4 1120EFI_STATUS init_grub(EFI_HANDLE image_handle)
b2fe1780
MG
1121{
1122 EFI_STATUS efi_status;
d3819813 1123 int use_fb = should_use_fallback(image_handle);
f4b24734 1124
d3819813 1125 efi_status = start_image(image_handle, use_fb ? FALLBACK :second_stage);
f4173af1
MTL
1126 if (efi_status == EFI_SECURITY_VIOLATION ||
1127 efi_status == EFI_ACCESS_DENIED) {
ef8c9962 1128 efi_status = start_image(image_handle, MOK_MANAGER);
f892ac66
MTL
1129 if (EFI_ERROR(efi_status)) {
1130 console_print(L"start_image() returned %r\n", efi_status);
b6f94dbe 1131 msleep(2000000);
d3819813
MTL
1132 return efi_status;
1133 }
1134
1135 efi_status = start_image(image_handle,
1136 use_fb ? FALLBACK : second_stage);
1137 }
1138
8529e0f7
SM
1139 // If the filename is invalid, or the file does not exist,
1140 // just fallback to the default loader.
1141 if (!use_fb && (efi_status == EFI_INVALID_PARAMETER ||
1142 efi_status == EFI_NOT_FOUND)) {
1143 console_print(
1144 L"start_image() returned %r, falling back to default loader\n",
1145 efi_status);
b6f94dbe 1146 msleep(2000000);
8529e0f7
SM
1147 load_options = NULL;
1148 load_options_size = 0;
1149 efi_status = start_image(image_handle, DEFAULT_LOADER);
d3819813
MTL
1150 }
1151
031e5cce 1152 if (EFI_ERROR(efi_status)) {
8529e0f7
SM
1153 console_print(L"start_image() returned %r\n", efi_status);
1154 msleep(2000000);
031e5cce
SM
1155 }
1156
8529e0f7 1157 return efi_status;
f4173af1
MTL
1158}
1159
09e2c939
GCPL
1160/*
1161 * Check the load options to specify the second stage loader
1162 */
1163EFI_STATUS set_second_stage (EFI_HANDLE image_handle)
1164{
f892ac66 1165 EFI_STATUS efi_status;
f4173af1 1166 EFI_LOADED_IMAGE *li = NULL;
8529e0f7
SM
1167
1168 second_stage = DEFAULT_LOADER;
09e2c939
GCPL
1169 load_options = NULL;
1170 load_options_size = 0;
1171
8529e0f7
SM
1172 efi_status = BS->HandleProtocol(image_handle, &LoadedImageProtocol,
1173 (void **) &li);
f892ac66
MTL
1174 if (EFI_ERROR(efi_status)) {
1175 perror (L"Failed to get load options: %r\n", efi_status);
1176 return efi_status;
09e2c939
GCPL
1177 }
1178
8529e0f7 1179#if defined(DISABLE_REMOVABLE_LOAD_OPTIONS)
f892ac66 1180 /*
8529e0f7
SM
1181 * boot services build very strange load options, and we might misparse them,
1182 * causing boot failures on removable media.
f892ac66 1183 */
8529e0f7
SM
1184 if (is_removable_media_path(li)) {
1185 dprint("Invoked from removable media path, ignoring boot options");
f892ac66 1186 return EFI_SUCCESS;
031e5cce 1187 }
8529e0f7 1188#endif
031e5cce 1189
8529e0f7
SM
1190 efi_status = parse_load_options(li);
1191 if (EFI_ERROR(efi_status)) {
1192 perror (L"Failed to get load options: %r\n", efi_status);
1193 return efi_status;
09e2c939
GCPL
1194 }
1195
1196 return EFI_SUCCESS;
1197}
1198
b6f94dbe 1199static void *
031e5cce 1200ossl_malloc(size_t num)
b6f94dbe
MTL
1201{
1202 return AllocatePool(num);
1203}
1204
1205static void
031e5cce 1206ossl_free(void *addr)
b6f94dbe
MTL
1207{
1208 FreePool(addr);
1209}
1210
1211static void
1212init_openssl(void)
1213{
1214 CRYPTO_set_mem_functions(ossl_malloc, NULL, ossl_free);
1215 OPENSSL_init();
1216 CRYPTO_set_mem_functions(ossl_malloc, NULL, ossl_free);
1217 ERR_load_ERR_strings();
1218 ERR_load_BN_strings();
1219 ERR_load_RSA_strings();
1220 ERR_load_DH_strings();
1221 ERR_load_EVP_strings();
1222 ERR_load_BUF_strings();
1223 ERR_load_OBJ_strings();
1224 ERR_load_PEM_strings();
1225 ERR_load_X509_strings();
1226 ERR_load_ASN1_strings();
1227 ERR_load_CONF_strings();
1228 ERR_load_CRYPTO_strings();
1229 ERR_load_COMP_strings();
1230 ERR_load_BIO_strings();
1231 ERR_load_PKCS7_strings();
1232 ERR_load_X509V3_strings();
1233 ERR_load_PKCS12_strings();
1234 ERR_load_RAND_strings();
1235 ERR_load_DSO_strings();
1236 ERR_load_OCSP_strings();
1237}
1238
cf90edff
PJ
1239static SHIM_LOCK shim_lock_interface;
1240static EFI_HANDLE shim_lock_handle;
1241
1242EFI_STATUS
1243install_shim_protocols(void)
1244{
f892ac66 1245 SHIM_LOCK *shim_lock;
cf90edff 1246 EFI_STATUS efi_status;
d3819813 1247
f892ac66
MTL
1248 /*
1249 * Did another instance of shim earlier already install the
1250 * protocol? If so, get rid of it.
1251 *
1252 * We have to uninstall shim's protocol here, because if we're
1253 * On the fallback.efi path, then our call pathway is:
1254 *
1255 * shim->fallback->shim->grub
1256 * ^ ^ ^
1257 * | | \- gets protocol #0
1258 * | \- installs its protocol (#1)
1259 * \- installs its protocol (#0)
1260 * and if we haven't removed this, then grub will get the *first*
1261 * shim's protocol, but it'll get the second shim's systab
1262 * replacements. So even though it will participate and verify
1263 * the kernel, the systab never finds out.
1264 */
1265 efi_status = LibLocateProtocol(&SHIM_LOCK_GUID, (VOID **)&shim_lock);
1266 if (!EFI_ERROR(efi_status))
1267 uninstall_shim_protocols();
d3819813 1268
cf90edff
PJ
1269 /*
1270 * Install the protocol
1271 */
8529e0f7
SM
1272 efi_status = BS->InstallProtocolInterface(&shim_lock_handle,
1273 &SHIM_LOCK_GUID,
1274 EFI_NATIVE_INTERFACE,
1275 &shim_lock_interface);
cf90edff
PJ
1276 if (EFI_ERROR(efi_status)) {
1277 console_error(L"Could not install security protocol",
1278 efi_status);
1279 return efi_status;
1280 }
1281
f892ac66
MTL
1282 if (!secure_mode())
1283 return EFI_SUCCESS;
1284
cf90edff
PJ
1285#if defined(OVERRIDE_SECURITY_POLICY)
1286 /*
1287 * Install the security protocol hook
1288 */
1289 security_policy_install(shim_verify);
1290#endif
1291
1292 return EFI_SUCCESS;
1293}
1294
1295void
1296uninstall_shim_protocols(void)
db54b0a4 1297{
f892ac66
MTL
1298 /*
1299 * If we're back here then clean everything up before exiting
1300 */
8529e0f7
SM
1301 BS->UninstallProtocolInterface(shim_lock_handle, &SHIM_LOCK_GUID,
1302 &shim_lock_interface);
d3819813
MTL
1303
1304 if (!secure_mode())
1305 return;
1306
cf90edff
PJ
1307#if defined(OVERRIDE_SECURITY_POLICY)
1308 /*
1309 * Clean up the security protocol hook
1310 */
1311 security_policy_uninstall();
1312#endif
cf90edff
PJ
1313}
1314
d3819813
MTL
1315EFI_STATUS
1316shim_init(void)
1317{
031e5cce
SM
1318 EFI_STATUS efi_status;
1319
f892ac66 1320 dprint(L"%a", shim_version);
d3819813
MTL
1321
1322 /* Set the second stage loader */
031e5cce
SM
1323 efi_status = set_second_stage(global_image_handle);
1324 if (EFI_ERROR(efi_status)) {
1325 perror(L"set_second_stage() failed: %r\n", efi_status);
1326 return efi_status;
1327 }
d3819813
MTL
1328
1329 if (secure_mode()) {
031e5cce 1330 if (vendor_authorized_size || vendor_deauthorized_size) {
d3819813
MTL
1331 /*
1332 * If shim includes its own certificates then ensure
1333 * that anything it boots has performed some
1334 * validation of the next image.
1335 */
1336 hook_system_services(systab);
1337 loader_is_participating = 0;
1338 }
1339
d3819813 1340 }
f892ac66 1341
031e5cce
SM
1342 hook_exit(systab);
1343
1344 efi_status = install_shim_protocols();
1345 if (EFI_ERROR(efi_status))
1346 perror(L"install_shim_protocols() failed: %r\n", efi_status);
1347
1348 return efi_status;
d3819813
MTL
1349}
1350
1351void
1352shim_fini(void)
1353{
031e5cce
SM
1354 if (secure_mode())
1355 cleanup_sbat_var(&sbat_var);
1356
f892ac66
MTL
1357 /*
1358 * Remove our protocols
1359 */
1360 uninstall_shim_protocols();
1361
d3819813 1362 if (secure_mode()) {
d3819813
MTL
1363
1364 /*
1365 * Remove our hooks from system services.
1366 */
1367 unhook_system_services();
d3819813
MTL
1368 }
1369
031e5cce
SM
1370 unhook_exit();
1371
f892ac66 1372 console_fini();
d3819813
MTL
1373}
1374
1375extern EFI_STATUS
1376efi_main(EFI_HANDLE passed_image_handle, EFI_SYSTEM_TABLE *passed_systab);
1377
1378static void
1379__attribute__((__optimize__("0")))
1380debug_hook(void)
1381{
d3819813
MTL
1382 UINT8 *data = NULL;
1383 UINTN dataSize = 0;
1384 EFI_STATUS efi_status;
031e5cce 1385 register volatile UINTN x = 0;
d3819813
MTL
1386 extern char _text, _data;
1387
031e5cce
SM
1388 const CHAR16 * const debug_var_name =
1389#ifdef ENABLE_SHIM_DEVEL
1390 L"SHIM_DEVEL_DEBUG";
1391#else
1392 L"SHIM_DEBUG";
1393#endif
1394
d3819813
MTL
1395 if (x)
1396 return;
1397
031e5cce 1398 efi_status = get_variable(debug_var_name, &data, &dataSize,
f892ac66 1399 SHIM_LOCK_GUID);
d3819813
MTL
1400 if (EFI_ERROR(efi_status)) {
1401 return;
1402 }
1403
f892ac66
MTL
1404 FreePool(data);
1405
1406 console_print(L"add-symbol-file "DEBUGDIR
1407 L"shim" EFI_ARCH L".efi.debug 0x%08x -s .data 0x%08x\n",
1408 &_text, &_data);
d3819813 1409
f892ac66 1410 console_print(L"Pausing for debugger attachment.\n");
031e5cce
SM
1411 console_print(L"To disable this, remove the EFI variable %s-%g .\n",
1412 debug_var_name, &SHIM_LOCK_GUID);
d3819813
MTL
1413 x = 1;
1414 while (x++) {
1415 /* Make this so it can't /totally/ DoS us. */
1416#if defined(__x86_64__) || defined(__i386__) || defined(__i686__)
1417 if (x > 4294967294ULL)
1418 break;
d3819813
MTL
1419#elif defined(__aarch64__)
1420 if (x > 1000)
1421 break;
d3819813
MTL
1422#else
1423 if (x > 12000)
1424 break;
d3819813 1425#endif
8529e0f7 1426 wait_for_debug();
d3819813
MTL
1427 }
1428 x = 1;
1429}
1430
031e5cce
SM
1431typedef enum {
1432 COLD_RESET,
1433 EXIT_FAILURE,
1434 EXIT_SUCCESS, // keep this one last
1435} devel_egress_action;
1436
1437void
1438devel_egress(devel_egress_action action UNUSED)
1439{
1440#ifdef ENABLE_SHIM_DEVEL
1441 char *reasons[] = {
1442 [COLD_RESET] = "reset",
1443 [EXIT_FAILURE] = "exit",
1444 };
1445 if (action == EXIT_SUCCESS)
1446 return;
1447
1448 console_print(L"Waiting to %a...", reasons[action]);
1449 for (size_t sleepcount = 0; sleepcount < 10; sleepcount++) {
1450 console_print(L"%d...", 10 - sleepcount);
1451 msleep(1000000);
1452 }
1453 console_print(L"\ndoing %a\n", action);
1454
1455 if (action == COLD_RESET)
8529e0f7 1456 RT->ResetSystem(EfiResetCold, EFI_SECURITY_VIOLATION, 0, NULL);
031e5cce
SM
1457#endif
1458}
1459
d3819813
MTL
1460EFI_STATUS
1461efi_main (EFI_HANDLE passed_image_handle, EFI_SYSTEM_TABLE *passed_systab)
cf90edff 1462{
0a232ca9 1463 EFI_STATUS efi_status;
f4173af1 1464 EFI_HANDLE image_handle;
db54b0a4 1465
cbef697a
PJ
1466 verification_method = VERIFIED_BY_NOTHING;
1467
031e5cce
SM
1468 vendor_authorized_size = cert_table.vendor_authorized_size;
1469 vendor_authorized = (UINT8 *)&cert_table + cert_table.vendor_authorized_offset;
1470
1471 vendor_deauthorized_size = cert_table.vendor_deauthorized_size;
1472 vendor_deauthorized = (UINT8 *)&cert_table + cert_table.vendor_deauthorized_offset;
1473
1474#if defined(ENABLE_SHIM_CERT)
1475 build_cert_size = sizeof(shim_cert);
1476 build_cert = shim_cert;
1477#endif /* defined(ENABLE_SHIM_CERT) */
1478
f892ac66 1479 CHAR16 *msgs[] = {
031e5cce
SM
1480 L"import_mok_state() failed",
1481 L"shim_init() failed",
1482 L"import of SBAT data failed",
1483 L"SBAT self-check failed",
8119f718 1484 SBAT_VAR_NAME L" UEFI variable setting failed",
f892ac66
MTL
1485 NULL
1486 };
031e5cce
SM
1487 enum {
1488 IMPORT_MOK_STATE,
1489 SHIM_INIT,
1490 IMPORT_SBAT,
1491 SBAT_SELF_CHECK,
1492 SET_SBAT,
1493 } msg = IMPORT_MOK_STATE;
a1f28635 1494
20f6cde6
MG
1495 /*
1496 * Set up the shim lock protocol so that grub and MokManager can
1497 * call back in and use shim functions
1498 */
db54b0a4 1499 shim_lock_interface.Verify = shim_verify;
e50cfe37
GCPL
1500 shim_lock_interface.Hash = shim_hash;
1501 shim_lock_interface.Context = shim_read_header;
db54b0a4
MG
1502
1503 systab = passed_systab;
f4173af1 1504 image_handle = global_image_handle = passed_image_handle;
db54b0a4 1505
20f6cde6
MG
1506 /*
1507 * Ensure that gnu-efi functions are available
1508 */
db54b0a4 1509 InitializeLib(image_handle, systab);
031e5cce 1510 setup_verbosity();
db54b0a4 1511
031e5cce
SM
1512 dprint(L"vendor_authorized:0x%08lx vendor_authorized_size:%lu\n",
1513 vendor_authorized, vendor_authorized_size);
1514 dprint(L"vendor_deauthorized:0x%08lx vendor_deauthorized_size:%lu\n",
1515 vendor_deauthorized, vendor_deauthorized_size);
b6f94dbe 1516
d3819813
MTL
1517 /*
1518 * if SHIM_DEBUG is set, wait for a debugger to attach.
1519 */
1520 debug_hook();
0fb089ee 1521
031e5cce
SM
1522 efi_status = set_sbat_uefi_variable();
1523 if (EFI_ERROR(efi_status) && secure_mode()) {
8119f718 1524 perror(L"%s variable initialization failed\n", SBAT_VAR_NAME);
031e5cce
SM
1525 msg = SET_SBAT;
1526 goto die;
1527 } else if (EFI_ERROR(efi_status)) {
8119f718
SM
1528 dprint(L"%s variable initialization failed: %r\n",
1529 SBAT_VAR_NAME, efi_status);
031e5cce
SM
1530 }
1531
1532 if (secure_mode()) {
1533 char *sbat_start = (char *)&_sbat;
1534 char *sbat_end = (char *)&_esbat;
1535
1536 INIT_LIST_HEAD(&sbat_var);
1537 efi_status = parse_sbat_var(&sbat_var);
1538 if (EFI_ERROR(efi_status)) {
8119f718
SM
1539 perror(L"Parsing %s variable failed: %r\n",
1540 SBAT_VAR_NAME, efi_status);
031e5cce
SM
1541 msg = IMPORT_SBAT;
1542 goto die;
1543 }
1544
8119f718 1545 efi_status = handle_sbat(sbat_start, sbat_end - sbat_start - 1);
031e5cce
SM
1546 if (EFI_ERROR(efi_status)) {
1547 perror(L"Verifiying shim SBAT data failed: %r\n",
1548 efi_status);
1549 msg = SBAT_SELF_CHECK;
1550 goto die;
1551 }
8119f718 1552 dprint(L"SBAT self-check succeeded\n");
031e5cce
SM
1553 }
1554
1555 init_openssl();
1556
d3819813 1557 /*
f892ac66
MTL
1558 * Before we do anything else, validate our non-volatile,
1559 * boot-services-only state variables are what we think they are.
d3819813 1560 */
f892ac66 1561 efi_status = import_mok_state(image_handle);
8529e0f7
SM
1562 if (!secure_mode() &&
1563 (efi_status == EFI_INVALID_PARAMETER ||
1564 efi_status == EFI_OUT_OF_RESOURCES)) {
031e5cce
SM
1565 /*
1566 * Make copy failures fatal only if secure_mode is enabled, or
8529e0f7
SM
1567 * the error was anything else than EFI_INVALID_PARAMETER or
1568 * EFI_OUT_OF_RESOURCES.
031e5cce
SM
1569 * There are non-secureboot firmware implementations that don't
1570 * reserve enough EFI variable memory to fit the variable.
1571 */
1572 console_print(L"Importing MOK states has failed: %s: %r\n",
1573 msgs[msg], efi_status);
1574 console_print(L"Continuing boot since secure mode is disabled");
1575 } else if (EFI_ERROR(efi_status)) {
f892ac66
MTL
1576die:
1577 console_print(L"Something has gone seriously wrong: %s: %r\n",
1578 msgs[msg], efi_status);
031e5cce
SM
1579#if defined(ENABLE_SHIM_DEVEL)
1580 devel_egress(COLD_RESET);
1581#else
b6f94dbe 1582 msleep(5000000);
8529e0f7
SM
1583 RT->ResetSystem(EfiResetShutdown, EFI_SECURITY_VIOLATION,
1584 0, NULL);
031e5cce 1585#endif
d3819813 1586 }
09e2c939 1587
d3819813
MTL
1588 efi_status = shim_init();
1589 if (EFI_ERROR(efi_status)) {
031e5cce 1590 msg = SHIM_INIT;
f892ac66 1591 goto die;
d3819813
MTL
1592 }
1593
20f6cde6
MG
1594 /*
1595 * Tell the user that we're in insecure mode if necessary
1596 */
e60f1181 1597 if (user_insecure_mode) {
f892ac66 1598 console_print(L"Booting in insecure mode\n");
b6f94dbe 1599 msleep(2000000);
9eaadb0d
MG
1600 }
1601
0283024e 1602 /*
d3819813 1603 * Hand over control to the second stage bootloader
0283024e 1604 */
d3819813 1605 efi_status = init_grub(image_handle);
bc71a15e 1606
d3819813 1607 shim_fini();
031e5cce 1608 devel_egress(EFI_ERROR(efi_status) ? EXIT_FAILURE : EXIT_SUCCESS);
0a232ca9 1609 return efi_status;
b2fe1780 1610}