Merge pull request #24189 from medhefgo/boot-secure
boot: Follow-up fixes for #20255
This commit is contained in:
+26
-8
@@ -244,20 +244,38 @@
|
||||
<ulink url="https://edk2-docs.gitbook.io/understanding-the-uefi-secure-boot-chain/secure_boot_chain_in_uefi/uefi_secure_boot">
|
||||
EDK2 documentation</ulink>.</para>
|
||||
|
||||
<para>A complete set of UEFI variable includes <filename>db.esl</filename>, <filename>KEK.esl</filename>
|
||||
and <filename>PK.esl</filename>. Note that these files need to be authenticated UEFI variables. See
|
||||
<para>A complete set of UEFI variable includes <filename>db.auth</filename>, <filename>KEK.auth</filename>
|
||||
and <filename>PK.auth</filename>. Note that these files need to be authenticated UEFI variables. See
|
||||
below for an example of how to generate them from regular X.509 keys.</para>
|
||||
|
||||
<programlisting>uuid=$(systemd-id128 new --)
|
||||
<programlisting>uuid=$(systemd-id128 new --uuid)
|
||||
for key in PK KEK db; do
|
||||
openssl req -new -x509 -subj "/CN=${key}/ -keyout "${key}.key" -out "${key}.crt"
|
||||
openssl req -new -x509 -subj "/CN=${key}/" -keyout "${key}.key" -out "${key}.crt"
|
||||
openssl x509 -outform DER -in "${key}.crt" -out "${key}.cer"
|
||||
cert-to-efi-sig-list -g "${uuid}" "${key}.crt" "${key}.tmp"
|
||||
cert-to-efi-sig-list -g "${uuid}" "${key}.crt" "${key}.esl"
|
||||
done
|
||||
|
||||
sign-efi-sig-list -c PK.crt -k PK.key PK PK.tmp PK.esl
|
||||
sign-efi-sig-list -c PK.crt -k PK.key KEK KEK.tmp KEK.esl
|
||||
sign-efi-sig-list -c KEK.crt -k KEK.key db db.tmp db.esl
|
||||
for key in MicWinProPCA2011_2011-10-19.crt MicCorUEFCA2011_2011-06-27.crt MicCorKEKCA2011_2011-06-24.crt; do
|
||||
curl "https://www.microsoft.com/pkiops/certs/${key}" --output "${key}"
|
||||
sbsiglist --owner 77fa9abd-0359-4d32-bd60-28f4e78f784b --type x509 --output "${key%crt}esl" "${key}"
|
||||
done
|
||||
|
||||
# Optionally add Microsoft Windows Production CA 2011 (needed to boot into Windows).
|
||||
cat MicWinProPCA2011_2011-10-19.esl >> db.esl
|
||||
|
||||
# Optionally add Microsoft Corporation UEFI CA 2011 (for firmware drivers / option ROMs
|
||||
# and third-party boot loaders (including shim). This is highly recommended on real
|
||||
# hardware as not including this may soft-brick your device (see next paragraph).
|
||||
cat MicCorUEFCA2011_2011-06-27.esl >> db.esl
|
||||
|
||||
# Optionally add Microsoft Corporation KEK CA 2011. Recommended if either of the
|
||||
# Microsoft keys is used as the official UEFI revocation database is signed with this
|
||||
# key. The revocation database can be updated with <citerefentry><refentrytitle>fwupdmgr</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
|
||||
cat MicCorKEKCA2011_2011-06-24.esl >> KEK.esl
|
||||
|
||||
sign-efi-sig-list -c PK.crt -k PK.key PK PK.esl PK.auth
|
||||
sign-efi-sig-list -c PK.crt -k PK.key KEK KEK.esl KEK.auth
|
||||
sign-efi-sig-list -c KEK.crt -k KEK.key db db.esl db.auth
|
||||
</programlisting>
|
||||
|
||||
<para>This feature is considered dangerous because even if all the required files are signed with the
|
||||
|
||||
@@ -319,7 +319,7 @@
|
||||
similar, to extend the native firmware support.</para>
|
||||
|
||||
<para>Enrollment of Secure Boot variables can be performed manually or automatically if files are available
|
||||
under <filename>/keys/<replaceable>NAME</replaceable>/{db,KEK,PK}.esl</filename>, <replaceable>NAME</replaceable>
|
||||
under <filename>/keys/<replaceable>NAME</replaceable>/{db,KEK,PK}.auth</filename>, <replaceable>NAME</replaceable>
|
||||
being the display name for the set of variables in the menu. If one of the sets is named <filename>auto</filename>
|
||||
then it might be enrolled automatically depending on whether <literal>secure-boot-enroll</literal> is set
|
||||
to force or not.</para>
|
||||
|
||||
+2
-2
@@ -2690,8 +2690,8 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
/* if auto enrollment is activated, we try to load keys for the given entry. */
|
||||
if (entry->type == LOADER_SECURE_BOOT_KEYS && config.secure_boot_enroll != ENROLL_OFF) {
|
||||
err = secure_boot_enroll_at(root_dir, entry->path);
|
||||
if (err == EFI_SUCCESS)
|
||||
return EFI_SUCCESS;
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,12 +43,17 @@ EFI_STATUS secure_boot_enroll_at(EFI_FILE *root_dir, const char16_t *path) {
|
||||
|
||||
clear_screen(COLOR_NORMAL);
|
||||
|
||||
Print(L"Enrolling secure boot keys from directory: \\loader\\keys\\%s\n"
|
||||
Print(L"Enrolling secure boot keys from directory: %s\n"
|
||||
L"Warning: Enrolling custom Secure Boot keys might soft-brick your machine!\n",
|
||||
path);
|
||||
|
||||
unsigned timeout_sec = 15;
|
||||
for(;;) {
|
||||
/* Enrolling secure boot keys is safe to do in virtualized environments as there is nothing
|
||||
* we can brick there. */
|
||||
if (in_hypervisor())
|
||||
break;
|
||||
|
||||
PrintAt(0, ST->ConOut->Mode->CursorRow, L"Enrolling in %2u s, press any key to abort.", timeout_sec);
|
||||
|
||||
uint64_t key;
|
||||
@@ -81,9 +86,9 @@ EFI_STATUS secure_boot_enroll_at(EFI_FILE *root_dir, const char16_t *path) {
|
||||
char *buffer;
|
||||
size_t size;
|
||||
} sb_vars[] = {
|
||||
{ u"db", u"db.esl", EFI_IMAGE_SECURITY_DATABASE_VARIABLE, NULL, 0 },
|
||||
{ u"KEK", u"KEK.esl", EFI_GLOBAL_VARIABLE, NULL, 0 },
|
||||
{ u"PK", u"PK.esl", EFI_GLOBAL_VARIABLE, NULL, 0 },
|
||||
{ u"db", u"db.auth", EFI_IMAGE_SECURITY_DATABASE_VARIABLE, NULL, 0 },
|
||||
{ u"KEK", u"KEK.auth", EFI_GLOBAL_VARIABLE, NULL, 0 },
|
||||
{ u"PK", u"PK.auth", EFI_GLOBAL_VARIABLE, NULL, 0 },
|
||||
};
|
||||
|
||||
/* Make sure all keys files exist before we start enrolling them by loading them from the disk first. */
|
||||
|
||||
+4
-22
@@ -2,35 +2,17 @@
|
||||
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
#include <cpuid.h>
|
||||
#endif
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "ticks.h"
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
static bool in_hypervisor(void) {
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
|
||||
/* The TSC might or might not be virtualized in VMs (and thus might not be accurate or start at zero
|
||||
* at boot), depending on hypervisor and CPU functionality. If it's not virtualized it's not useful
|
||||
* for keeping time, hence don't attempt to use it.
|
||||
*
|
||||
* This is a dumbed down version of src/basic/virt.c's detect_vm() that safely works in the UEFI
|
||||
* environment. */
|
||||
|
||||
if (__get_cpuid(1, &eax, &ebx, &ecx, &edx) == 0)
|
||||
return false;
|
||||
|
||||
return !!(ecx & 0x80000000U);
|
||||
}
|
||||
#endif
|
||||
#include "util.h"
|
||||
|
||||
#ifdef __x86_64__
|
||||
static uint64_t ticks_read(void) {
|
||||
uint64_t a, d;
|
||||
|
||||
/* The TSC might or might not be virtualized in VMs (and thus might not be accurate or start at zero
|
||||
* at boot), depending on hypervisor and CPU functionality. If it's not virtualized it's not useful
|
||||
* for keeping time, hence don't attempt to use it. */
|
||||
if (in_hypervisor())
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
# include <cpuid.h>
|
||||
#endif
|
||||
|
||||
#include "ticks.h"
|
||||
#include "util.h"
|
||||
@@ -768,3 +771,17 @@ EFI_STATUS make_file_device_path(EFI_HANDLE device, const char16_t *file, EFI_DE
|
||||
SetDevicePathEndNode(dp);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
bool in_hypervisor(void) {
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
|
||||
/* This is a dumbed down version of src/basic/virt.c's detect_vm() that safely works in the UEFI
|
||||
* environment. */
|
||||
|
||||
if (__get_cpuid(1, &eax, &ebx, &ecx, &edx) == 0)
|
||||
return false;
|
||||
|
||||
return !!(ecx & 0x80000000U);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -179,3 +179,11 @@ static inline void beep(UINTN beep_count) {}
|
||||
|
||||
EFI_STATUS open_volume(EFI_HANDLE device, EFI_FILE **ret_file);
|
||||
EFI_STATUS make_file_device_path(EFI_HANDLE device, const char16_t *file, EFI_DEVICE_PATH **ret_dp);
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
bool in_hypervisor(void);
|
||||
#else
|
||||
static inline bool in_hypervisor(void) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user