|
|
1bbb7a |
From ab26d9a5c035cd56e1b1ae8b0ef74e059fe61d77 Mon Sep 17 00:00:00 2001
|
|
|
1bbb7a |
From: Patrick Uiterwijk <patrick@puiterwijk.org>
|
|
|
1bbb7a |
Date: Sat, 21 Jul 2018 04:12:57 +0200
|
|
|
1bbb7a |
Subject: [PATCH] Implement vendor EFI Signature List (ESL)
|
|
|
1bbb7a |
|
|
|
1bbb7a |
Signed-off-by: Patrick Uiterwijk <patrick@puiterwijk.org>
|
|
|
1bbb7a |
---
|
|
|
1bbb7a |
Make.defaults | 3 ++
|
|
|
1bbb7a |
cert.S | 30 ++++++++++++++++++
|
|
|
1bbb7a |
mok.c | 86 +++++++++++++++++++++++++++------------------------
|
|
|
1bbb7a |
shim.c | 25 +++++++++++++++
|
|
|
1bbb7a |
shim.h | 2 ++
|
|
|
1bbb7a |
5 files changed, 106 insertions(+), 40 deletions(-)
|
|
|
1bbb7a |
|
|
|
1bbb7a |
diff --git a/Make.defaults b/Make.defaults
|
|
|
1bbb7a |
index 4c26c1a..0f9b979 100644
|
|
|
1bbb7a |
--- a/Make.defaults
|
|
|
1bbb7a |
+++ b/Make.defaults
|
|
|
1bbb7a |
@@ -126,6 +126,9 @@ CFLAGS += "-DEFI_ARCH=L\"$(ARCH_SUFFIX)\"" "-DDEBUGDIR=L\"/usr/lib/debug/usr/sha
|
|
|
1bbb7a |
ifneq ($(origin VENDOR_CERT_FILE), undefined)
|
|
|
1bbb7a |
CFLAGS += -DVENDOR_CERT_FILE=\"$(VENDOR_CERT_FILE)\"
|
|
|
1bbb7a |
endif
|
|
|
1bbb7a |
+ifneq ($(origin VENDOR_ESL_FILE), undefined)
|
|
|
1bbb7a |
+ CFLAGS += -DVENDOR_ESL_FILE=\"$(VENDOR_ESL_FILE)\"
|
|
|
1bbb7a |
+endif
|
|
|
1bbb7a |
ifneq ($(origin VENDOR_DBX_FILE), undefined)
|
|
|
1bbb7a |
CFLAGS += -DVENDOR_DBX_FILE=\"$(VENDOR_DBX_FILE)\"
|
|
|
1bbb7a |
endif
|
|
|
1bbb7a |
diff --git a/cert.S b/cert.S
|
|
|
1bbb7a |
index cfc4525..7ad782a 100644
|
|
|
1bbb7a |
--- a/cert.S
|
|
|
1bbb7a |
+++ b/cert.S
|
|
|
1bbb7a |
@@ -8,12 +8,18 @@ cert_table:
|
|
|
1bbb7a |
#else
|
|
|
1bbb7a |
.long 0
|
|
|
1bbb7a |
#endif
|
|
|
1bbb7a |
+#if defined(VENDOR_ESL_FILE)
|
|
|
1bbb7a |
+ .long vendor_esl_priv_end - vendor_esl_priv
|
|
|
1bbb7a |
+#else
|
|
|
1bbb7a |
+ .long 0
|
|
|
1bbb7a |
+#endif
|
|
|
1bbb7a |
#if defined(VENDOR_DBX_FILE)
|
|
|
1bbb7a |
.long vendor_dbx_priv_end - vendor_dbx_priv
|
|
|
1bbb7a |
#else
|
|
|
1bbb7a |
.long 0
|
|
|
1bbb7a |
#endif
|
|
|
1bbb7a |
.long vendor_cert_priv - cert_table
|
|
|
1bbb7a |
+ .long vendor_esl_priv - cert_table
|
|
|
1bbb7a |
.long vendor_dbx_priv - cert_table
|
|
|
1bbb7a |
#if defined(VENDOR_CERT_FILE)
|
|
|
1bbb7a |
.data
|
|
|
1bbb7a |
@@ -39,6 +45,30 @@ vendor_cert_priv:
|
|
|
1bbb7a |
.section .vendor_cert, "a", %progbits
|
|
|
1bbb7a |
vendor_cert_priv_end:
|
|
|
1bbb7a |
#endif
|
|
|
1bbb7a |
+#if defined(VENDOR_ESL_FILE)
|
|
|
1bbb7a |
+ .data
|
|
|
1bbb7a |
+ .align 1
|
|
|
1bbb7a |
+ .type vendor_esl_priv, %object
|
|
|
1bbb7a |
+ .size vendor_esl_priv, vendor_esl_priv_end-vendor_esl_priv
|
|
|
1bbb7a |
+ .section .vendor_cert, "a", %progbits
|
|
|
1bbb7a |
+vendor_esl_priv:
|
|
|
1bbb7a |
+.incbin VENDOR_ESL_FILE
|
|
|
1bbb7a |
+vendor_esl_priv_end:
|
|
|
1bbb7a |
+#else
|
|
|
1bbb7a |
+ .bss
|
|
|
1bbb7a |
+ .type vendor_esl_priv, %object
|
|
|
1bbb7a |
+ .size vendor_esl_priv, 1
|
|
|
1bbb7a |
+ .section .vendor_cert, "a", %progbits
|
|
|
1bbb7a |
+vendor_esl_priv:
|
|
|
1bbb7a |
+ .zero 1
|
|
|
1bbb7a |
+
|
|
|
1bbb7a |
+ .data
|
|
|
1bbb7a |
+ .align 4
|
|
|
1bbb7a |
+ .type vendor_esl_size_priv, %object
|
|
|
1bbb7a |
+ .size vendor_esl_size_priv, 4
|
|
|
1bbb7a |
+ .section .vendor_cert, "a", %progbits
|
|
|
1bbb7a |
+vendor_esl_priv_end:
|
|
|
1bbb7a |
+#endif
|
|
|
1bbb7a |
#if defined(VENDOR_DBX_FILE)
|
|
|
1bbb7a |
.data
|
|
|
1bbb7a |
.align 1
|
|
|
1bbb7a |
diff --git a/mok.c b/mok.c
|
|
|
1bbb7a |
index 2b9d796..f52e286 100644
|
|
|
1bbb7a |
--- a/mok.c
|
|
|
1bbb7a |
+++ b/mok.c
|
|
|
1bbb7a |
@@ -62,12 +62,6 @@ struct mok_state_variable {
|
|
|
1bbb7a |
EFI_GUID *guid;
|
|
|
1bbb7a |
UINT8 *data;
|
|
|
1bbb7a |
UINTN data_size;
|
|
|
1bbb7a |
- /*
|
|
|
1bbb7a |
- * These two are indirect pointers just to make initialization
|
|
|
1bbb7a |
- * saner...
|
|
|
1bbb7a |
- */
|
|
|
1bbb7a |
- UINT8 **addend_source;
|
|
|
1bbb7a |
- UINT32 *addend_size;
|
|
|
1bbb7a |
UINT32 yes_attr;
|
|
|
1bbb7a |
UINT32 no_attr;
|
|
|
1bbb7a |
UINT32 flags;
|
|
|
1bbb7a |
@@ -75,10 +69,11 @@ struct mok_state_variable {
|
|
|
1bbb7a |
UINT8 *state;
|
|
|
1bbb7a |
};
|
|
|
1bbb7a |
|
|
|
1bbb7a |
-#define MOK_MIRROR_KEYDB 0x01
|
|
|
1bbb7a |
-#define MOK_MIRROR_DELETE_FIRST 0x02
|
|
|
1bbb7a |
-#define MOK_VARIABLE_MEASURE 0x04
|
|
|
1bbb7a |
-#define MOK_VARIABLE_LOG 0x08
|
|
|
1bbb7a |
+#define MOK_MIRROR_KEYDB 0x01
|
|
|
1bbb7a |
+#define MOK_MIRROR_DELETE_FIRST 0x02
|
|
|
1bbb7a |
+#define MOK_VARIABLE_MEASURE 0x04
|
|
|
1bbb7a |
+#define MOK_VARIABLE_LOG 0x08
|
|
|
1bbb7a |
+#define MOK_VARIABLE_APPEND_CERT 0x10
|
|
|
1bbb7a |
|
|
|
1bbb7a |
struct mok_state_variable mok_state_variables[] = {
|
|
|
1bbb7a |
{.name = L"MokList",
|
|
|
1bbb7a |
@@ -88,10 +83,9 @@ struct mok_state_variable mok_state_variables[] = {
|
|
|
1bbb7a |
.yes_attr = EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
|
|
1bbb7a |
EFI_VARIABLE_NON_VOLATILE,
|
|
|
1bbb7a |
.no_attr = EFI_VARIABLE_RUNTIME_ACCESS,
|
|
|
1bbb7a |
- .addend_source = &vendor_cert,
|
|
|
1bbb7a |
- .addend_size = &vendor_cert_size,
|
|
|
1bbb7a |
.flags = MOK_MIRROR_KEYDB |
|
|
|
1bbb7a |
- MOK_VARIABLE_LOG,
|
|
|
1bbb7a |
+ MOK_VARIABLE_LOG |
|
|
|
1bbb7a |
+ MOK_VARIABLE_APPEND_CERT,
|
|
|
1bbb7a |
.pcr = 14,
|
|
|
1bbb7a |
},
|
|
|
1bbb7a |
{.name = L"MokListX",
|
|
|
1bbb7a |
@@ -139,40 +133,54 @@ mirror_one_mok_variable(struct mok_state_variable *v)
|
|
|
1bbb7a |
uint8_t *p = NULL;
|
|
|
1bbb7a |
|
|
|
1bbb7a |
if ((v->flags & MOK_MIRROR_KEYDB) &&
|
|
|
1bbb7a |
- v->addend_source && *v->addend_source &&
|
|
|
1bbb7a |
- v->addend_size && *v->addend_size) {
|
|
|
1bbb7a |
- EFI_SIGNATURE_LIST *CertList = NULL;
|
|
|
1bbb7a |
- EFI_SIGNATURE_DATA *CertData = NULL;
|
|
|
1bbb7a |
- FullDataSize = v->data_size
|
|
|
1bbb7a |
- + sizeof (*CertList)
|
|
|
1bbb7a |
- + sizeof (EFI_GUID)
|
|
|
1bbb7a |
- + *v->addend_size;
|
|
|
1bbb7a |
+ (v->flags & MOK_VARIABLE_APPEND_CERT)) {
|
|
|
1bbb7a |
+ FullDataSize = v->data_size;
|
|
|
1bbb7a |
+
|
|
|
1bbb7a |
+ if (vendor_esl_size) {
|
|
|
1bbb7a |
+ FullDataSize += vendor_esl_size;
|
|
|
1bbb7a |
+ }
|
|
|
1bbb7a |
+ if (vendor_cert_size) {
|
|
|
1bbb7a |
+ FullDataSize += sizeof (EFI_SIGNATURE_LIST)
|
|
|
1bbb7a |
+ + sizeof (EFI_GUID)
|
|
|
1bbb7a |
+ + vendor_cert_size;
|
|
|
1bbb7a |
+ }
|
|
|
1bbb7a |
+
|
|
|
1bbb7a |
FullData = AllocatePool(FullDataSize);
|
|
|
1bbb7a |
if (!FullData) {
|
|
|
1bbb7a |
perror(L"Failed to allocate space for MokListRT\n");
|
|
|
1bbb7a |
return EFI_OUT_OF_RESOURCES;
|
|
|
1bbb7a |
}
|
|
|
1bbb7a |
p = FullData;
|
|
|
1bbb7a |
-
|
|
|
1bbb7a |
if (!EFI_ERROR(efi_status) && v->data_size > 0) {
|
|
|
1bbb7a |
CopyMem(p, v->data, v->data_size);
|
|
|
1bbb7a |
p += v->data_size;
|
|
|
1bbb7a |
}
|
|
|
1bbb7a |
- CertList = (EFI_SIGNATURE_LIST *)p;
|
|
|
1bbb7a |
- p += sizeof (*CertList);
|
|
|
1bbb7a |
- CertData = (EFI_SIGNATURE_DATA *)p;
|
|
|
1bbb7a |
- p += sizeof (EFI_GUID);
|
|
|
1bbb7a |
-
|
|
|
1bbb7a |
- CertList->SignatureType = EFI_CERT_TYPE_X509_GUID;
|
|
|
1bbb7a |
- CertList->SignatureListSize = *v->addend_size
|
|
|
1bbb7a |
- + sizeof (*CertList)
|
|
|
1bbb7a |
- + sizeof (*CertData)
|
|
|
1bbb7a |
- -1;
|
|
|
1bbb7a |
- CertList->SignatureHeaderSize = 0;
|
|
|
1bbb7a |
- CertList->SignatureSize = *v->addend_size + sizeof (EFI_GUID);
|
|
|
1bbb7a |
-
|
|
|
1bbb7a |
- CertData->SignatureOwner = SHIM_LOCK_GUID;
|
|
|
1bbb7a |
- CopyMem(p, *v->addend_source, *v->addend_size);
|
|
|
1bbb7a |
+
|
|
|
1bbb7a |
+ if (vendor_esl_size) {
|
|
|
1bbb7a |
+ CopyMem(p, vendor_esl, vendor_esl_size);
|
|
|
1bbb7a |
+ p += vendor_esl_size;
|
|
|
1bbb7a |
+ }
|
|
|
1bbb7a |
+
|
|
|
1bbb7a |
+ if (vendor_cert_size) {
|
|
|
1bbb7a |
+ EFI_SIGNATURE_LIST *CertList = NULL;
|
|
|
1bbb7a |
+ EFI_SIGNATURE_DATA *CertData = NULL;
|
|
|
1bbb7a |
+
|
|
|
1bbb7a |
+ CertList = (EFI_SIGNATURE_LIST *)p;
|
|
|
1bbb7a |
+ p += sizeof (*CertList);
|
|
|
1bbb7a |
+ CertData = (EFI_SIGNATURE_DATA *)p;
|
|
|
1bbb7a |
+ p += sizeof (EFI_GUID);
|
|
|
1bbb7a |
+
|
|
|
1bbb7a |
+ CertList->SignatureType = EFI_CERT_TYPE_X509_GUID;
|
|
|
1bbb7a |
+ CertList->SignatureListSize = vendor_cert_size
|
|
|
1bbb7a |
+ + sizeof (*CertList)
|
|
|
1bbb7a |
+ + sizeof (*CertData)
|
|
|
1bbb7a |
+ -1;
|
|
|
1bbb7a |
+ CertList->SignatureHeaderSize = 0;
|
|
|
1bbb7a |
+ CertList->SignatureSize = vendor_cert_size + sizeof (EFI_GUID);
|
|
|
1bbb7a |
+
|
|
|
1bbb7a |
+ CertData->SignatureOwner = SHIM_LOCK_GUID;
|
|
|
1bbb7a |
+ CopyMem(p, vendor_cert, vendor_cert_size);
|
|
|
1bbb7a |
+ }
|
|
|
1bbb7a |
|
|
|
1bbb7a |
if (v->data && v->data_size)
|
|
|
1bbb7a |
FreePool(v->data);
|
|
|
1bbb7a |
@@ -247,9 +255,7 @@ EFI_STATUS import_mok_state(EFI_HANDLE image_handle)
|
|
|
1bbb7a |
UINT32 attrs = 0;
|
|
|
1bbb7a |
BOOLEAN delete = FALSE, present, addend;
|
|
|
1bbb7a |
|
|
|
1bbb7a |
- addend = (v->addend_source && v->addend_size &&
|
|
|
1bbb7a |
- *v->addend_source && *v->addend_size)
|
|
|
1bbb7a |
- ? TRUE : FALSE;
|
|
|
1bbb7a |
+ addend = (v->flags & MOK_VARIABLE_APPEND_CERT) != 0;
|
|
|
1bbb7a |
|
|
|
1bbb7a |
efi_status = get_variable_attr(v->name,
|
|
|
1bbb7a |
&v->data, &v->data_size,
|
|
|
1bbb7a |
diff --git a/shim.c b/shim.c
|
|
|
1bbb7a |
index 0015534..15b29fb 100644
|
|
|
1bbb7a |
--- a/shim.c
|
|
|
1bbb7a |
+++ b/shim.c
|
|
|
1bbb7a |
@@ -66,14 +66,18 @@ static UINT32 load_options_size;
|
|
|
1bbb7a |
*/
|
|
|
1bbb7a |
extern struct {
|
|
|
1bbb7a |
UINT32 vendor_cert_size;
|
|
|
1bbb7a |
+ UINT32 vendor_esl_size;
|
|
|
1bbb7a |
UINT32 vendor_dbx_size;
|
|
|
1bbb7a |
UINT32 vendor_cert_offset;
|
|
|
1bbb7a |
+ UINT32 vendor_esl_offset;
|
|
|
1bbb7a |
UINT32 vendor_dbx_offset;
|
|
|
1bbb7a |
} cert_table;
|
|
|
1bbb7a |
|
|
|
1bbb7a |
UINT32 vendor_cert_size;
|
|
|
1bbb7a |
+UINT32 vendor_esl_size;
|
|
|
1bbb7a |
UINT32 vendor_dbx_size;
|
|
|
1bbb7a |
UINT8 *vendor_cert;
|
|
|
1bbb7a |
+UINT8 *vendor_esl;
|
|
|
1bbb7a |
UINT8 *vendor_dbx;
|
|
|
1bbb7a |
|
|
|
1bbb7a |
/*
|
|
|
1bbb7a |
@@ -1059,6 +1063,25 @@ static EFI_STATUS verify_buffer (char *data, int datasize,
|
|
|
1bbb7a |
}
|
|
|
1bbb7a |
#endif /* defined(ENABLE_SHIM_CERT) */
|
|
|
1bbb7a |
|
|
|
1bbb7a |
+ /*
|
|
|
1bbb7a |
+ * Check against a built-in EFI Signature List (ESL)
|
|
|
1bbb7a |
+ */
|
|
|
1bbb7a |
+ if (vendor_esl_size &&
|
|
|
1bbb7a |
+ check_db_cert_in_ram((EFI_SIGNATURE_LIST*)vendor_esl,
|
|
|
1bbb7a |
+ vendor_esl_size,
|
|
|
1bbb7a |
+ cert,
|
|
|
1bbb7a |
+ sha256hash,
|
|
|
1bbb7a |
+ L"Shim",
|
|
|
1bbb7a |
+ SHIM_LOCK_GUID) == DATA_FOUND) {
|
|
|
1bbb7a |
+ update_verification_method(VERIFIED_BY_CERT);
|
|
|
1bbb7a |
+ // tpm_measurement is done by check_db_cert_in_ram
|
|
|
1bbb7a |
+ efi_status = EFI_SUCCESS;
|
|
|
1bbb7a |
+ drain_openssl_errors();
|
|
|
1bbb7a |
+ return efi_status;
|
|
|
1bbb7a |
+ } else {
|
|
|
1bbb7a |
+ LogError(L"check_db_cert_in_ram(vendor_esl) failed\n");
|
|
|
1bbb7a |
+ }
|
|
|
1bbb7a |
+
|
|
|
1bbb7a |
/*
|
|
|
1bbb7a |
* And finally, check against shim's built-in key
|
|
|
1bbb7a |
*/
|
|
|
1bbb7a |
@@ -2535,8 +2558,10 @@ efi_main (EFI_HANDLE passed_image_handle, EFI_SYSTEM_TABLE *passed_systab)
|
|
|
1bbb7a |
verification_method = VERIFIED_BY_NOTHING;
|
|
|
1bbb7a |
|
|
|
1bbb7a |
vendor_cert_size = cert_table.vendor_cert_size;
|
|
|
1bbb7a |
+ vendor_esl_size = cert_table.vendor_esl_size;
|
|
|
1bbb7a |
vendor_dbx_size = cert_table.vendor_dbx_size;
|
|
|
1bbb7a |
vendor_cert = (UINT8 *)&cert_table + cert_table.vendor_cert_offset;
|
|
|
1bbb7a |
+ vendor_esl = (UINT8 *)&cert_table + cert_table.vendor_esl_offset;
|
|
|
1bbb7a |
vendor_dbx = (UINT8 *)&cert_table + cert_table.vendor_dbx_offset;
|
|
|
1bbb7a |
CHAR16 *msgs[] = {
|
|
|
1bbb7a |
L"import_mok_state() failed\n",
|
|
|
1bbb7a |
diff --git a/shim.h b/shim.h
|
|
|
1bbb7a |
index 04e770b..fb58b69 100644
|
|
|
1bbb7a |
--- a/shim.h
|
|
|
1bbb7a |
+++ b/shim.h
|
|
|
1bbb7a |
@@ -169,8 +169,10 @@ extern EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath);
|
|
|
1bbb7a |
extern EFI_STATUS import_mok_state(EFI_HANDLE image_handle);
|
|
|
1bbb7a |
|
|
|
1bbb7a |
extern UINT32 vendor_cert_size;
|
|
|
1bbb7a |
+extern UINT32 vendor_esl_size;
|
|
|
1bbb7a |
extern UINT32 vendor_dbx_size;
|
|
|
1bbb7a |
extern UINT8 *vendor_cert;
|
|
|
1bbb7a |
+extern UINT8 *vendor_esl;
|
|
|
1bbb7a |
extern UINT8 *vendor_dbx;
|
|
|
1bbb7a |
|
|
|
1bbb7a |
extern UINT8 user_insecure_mode;
|
|
|
1bbb7a |
--
|
|
|
1bbb7a |
2.18.1
|
|
|
1bbb7a |
|