summaryrefslogtreecommitdiff
path: root/shim.c
diff options
context:
space:
mode:
authorJosh Boyer <jwboyer@fedoraproject.org>2013-10-01 11:49:22 -0400
committerPeter Jones <pjones@redhat.com>2013-10-02 11:29:34 -0400
commitef0383d008aa2114392f27125601514ae97b16a1 (patch)
treee7ad226ad04a7d2b869af495ff2f360b7e5880fc /shim.c
parent91c5a05037598425757b3a9ab76619ff2f48fc20 (diff)
downloadefi-boot-shim-ef0383d008aa2114392f27125601514ae97b16a1.tar.gz
efi-boot-shim-ef0383d008aa2114392f27125601514ae97b16a1.zip
Add support for disabling db for verification
Provide a mechanism for a physically present end user to disable the use of db when doing signature verification. This is handled by the OS passing down a variable that contains a UINT32 and a SHA256 hash. If this variable is present, MokManager prompts the user to choose whether to enable or disable the use of db for verification purposes (depending on the value of the UINT32). They are then asked to type the passphrase that matches the hash. This then saves a boot services variable which is checked by shim, and if set will cause shim to not use db for verification purposes. If db is to be ignored, shim will export a runtime variable called 'MokIgnoreDB' for the OS to query at runtime. Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org>
Diffstat (limited to 'shim.c')
-rw-r--r--shim.c107
1 files changed, 91 insertions, 16 deletions
diff --git a/shim.c b/shim.c
index f311914d..690cb091 100644
--- a/shim.c
+++ b/shim.c
@@ -86,6 +86,7 @@ int loader_is_participating;
#define EFI_IMAGE_SECURITY_DATABASE_GUID { 0xd719b2cb, 0x3d3a, 0x4596, { 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f }}
UINT8 insecure_mode;
+UINT8 ignore_db;
typedef enum {
DATA_FOUND,
@@ -393,28 +394,31 @@ static EFI_STATUS check_whitelist (WIN_CERTIFICATE_EFI_PKCS *cert,
EFI_GUID secure_var = EFI_IMAGE_SECURITY_DATABASE_GUID;
EFI_GUID shim_var = SHIM_LOCK_GUID;
- if (check_db_hash(L"db", secure_var, sha256hash, SHA256_DIGEST_SIZE,
- EFI_CERT_SHA256_GUID) == DATA_FOUND) {
- update_verification_method(VERIFIED_BY_HASH);
- return EFI_SUCCESS;
- }
- if (check_db_hash(L"db", secure_var, sha1hash, SHA1_DIGEST_SIZE,
- EFI_CERT_SHA1_GUID) == DATA_FOUND) {
- verification_method = VERIFIED_BY_HASH;
- update_verification_method(VERIFIED_BY_HASH);
- return EFI_SUCCESS;
+ if (!ignore_db) {
+ if (check_db_hash(L"db", secure_var, sha256hash, SHA256_DIGEST_SIZE,
+ EFI_CERT_SHA256_GUID) == DATA_FOUND) {
+ update_verification_method(VERIFIED_BY_HASH);
+ return EFI_SUCCESS;
+ }
+ if (check_db_hash(L"db", secure_var, sha1hash, SHA1_DIGEST_SIZE,
+ EFI_CERT_SHA1_GUID) == DATA_FOUND) {
+ verification_method = VERIFIED_BY_HASH;
+ update_verification_method(VERIFIED_BY_HASH);
+ return EFI_SUCCESS;
+ }
+ if (check_db_cert(L"db", secure_var, cert, sha256hash) == DATA_FOUND) {
+ verification_method = VERIFIED_BY_CERT;
+ update_verification_method(VERIFIED_BY_CERT);
+ return EFI_SUCCESS;
+ }
}
+
if (check_db_hash(L"MokList", shim_var, sha256hash, SHA256_DIGEST_SIZE,
EFI_CERT_SHA256_GUID) == DATA_FOUND) {
verification_method = VERIFIED_BY_HASH;
update_verification_method(VERIFIED_BY_HASH);
return EFI_SUCCESS;
}
- if (check_db_cert(L"db", secure_var, cert, sha256hash) == DATA_FOUND) {
- verification_method = VERIFIED_BY_CERT;
- update_verification_method(VERIFIED_BY_CERT);
- return EFI_SUCCESS;
- }
if (check_db_cert(L"MokList", shim_var, cert, sha256hash) == DATA_FOUND) {
verification_method = VERIFIED_BY_CERT;
update_verification_method(VERIFIED_BY_CERT);
@@ -1428,7 +1432,7 @@ EFI_STATUS check_mok_request(EFI_HANDLE image_handle)
if (check_var(L"MokNew") || check_var(L"MokSB") ||
check_var(L"MokPW") || check_var(L"MokAuth") ||
- check_var(L"MokDel")) {
+ check_var(L"MokDel") || check_var(L"MokDB")) {
efi_status = start_image(image_handle, MOK_MANAGER);
if (efi_status != EFI_SUCCESS) {
@@ -1482,6 +1486,71 @@ static EFI_STATUS check_mok_sb (void)
}
/*
+ * Verify that MokDBState is valid, and if appropriate set ignore db mode
+ */
+
+static EFI_STATUS check_mok_db (void)
+{
+ EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+ EFI_STATUS status = EFI_SUCCESS;
+ UINT8 *MokDBState = NULL;
+ UINTN MokDBStateSize = 0;
+ UINT32 attributes;
+
+ status = get_variable_attr(L"MokDBState", &MokDBState, &MokDBStateSize,
+ shim_lock_guid, &attributes);
+
+ if (status != EFI_SUCCESS)
+ return EFI_ACCESS_DENIED;
+
+ ignore_db = 0;
+
+ /*
+ * Delete and ignore the variable if it's been set from or could be
+ * modified by the OS
+ */
+ if (attributes & EFI_VARIABLE_RUNTIME_ACCESS) {
+ Print(L"MokDBState is compromised! Clearing it\n");
+ if (LibDeleteVariable(L"MokDBState", &shim_lock_guid) != EFI_SUCCESS) {
+ Print(L"Failed to erase MokDBState\n");
+ }
+ status = EFI_ACCESS_DENIED;
+ } else {
+ if (*(UINT8 *)MokDBState == 1) {
+ ignore_db = 1;
+ }
+ }
+
+ FreePool(MokDBState);
+
+ return status;
+}
+
+static EFI_STATUS mok_ignore_db()
+{
+ EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+ EFI_STATUS efi_status = EFI_SUCCESS;
+ UINT8 Data = 1;
+ UINTN DataSize = sizeof(UINT8);
+
+ check_mok_db();
+
+ if (ignore_db) {
+ efi_status = uefi_call_wrapper(RT->SetVariable, 5, L"MokIgnoreDB",
+ &shim_lock_guid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS
+ | EFI_VARIABLE_RUNTIME_ACCESS,
+ DataSize, (void *)&Data);
+ if (efi_status != EFI_SUCCESS) {
+ Print(L"Failed to set MokIgnoreDB %d\n", efi_status);
+ }
+ }
+
+ return efi_status;
+
+}
+
+/*
* Check the load options to specify the second stage loader
*/
EFI_STATUS set_second_stage (EFI_HANDLE image_handle)
@@ -1653,6 +1722,12 @@ EFI_STATUS efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *passed_systab)
efi_status = mirror_mok_list();
/*
+ * Create the runtime MokIgnoreDB variable so the kernel can make
+ * use of it
+ */
+ efi_status = mok_ignore_db();
+
+ /*
* Hand over control to the second stage bootloader
*/