shim/shim-mokx-support.patch
Gary Ching-Pang Lin 63a3d1b717 Accepting request 221745 from home:gary_lin:branches:devel:openSUSE:Factory
- Update shim-mokx-support.patch to support the resetting of MOK blacklist
- Fix the variable checking in get_variable_attr
- Improve the boot entry pathes and avoid generating the boot entries that are already there
- Update SUSE certificate
- Update scritps to remove the creation of the temporary nss database
- Remove the kernel version of the build server
- Match the the prefix of the project name properly by escaping the percent sign.

OBS-URL: https://build.opensuse.org/request/show/221745
OBS-URL: https://build.opensuse.org/package/show/devel:openSUSE:Factory/shim?expand=0&rev=57
2014-02-13 01:57:08 +00:00

1200 lines
34 KiB
Diff

From 58b8e54ef60d488886a9f0d0877b7187eb200d07 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Thu, 24 Oct 2013 17:02:08 +0800
Subject: [PATCH 01/10] Support MOK blacklist
The new blacklist, MokListX, stores the keys and hashes that are
banned.
Signed-off-by: Gary Ching-Pang Lin <glin@suse.com>
---
MokManager.c | 241 +++++++++++++++++++++++++++++++++++++++++++++++++----------
shim.c | 3 +-
2 files changed, 202 insertions(+), 42 deletions(-)
diff --git a/MokManager.c b/MokManager.c
index f5ed379..b9b42b6 100644
--- a/MokManager.c
+++ b/MokManager.c
@@ -701,23 +701,37 @@ static EFI_STATUS match_password (PASSWORD_CRYPT *pw_crypt,
return EFI_SUCCESS;
}
-static EFI_STATUS store_keys (void *MokNew, UINTN MokNewSize, int authenticate)
+static EFI_STATUS store_keys (void *MokNew, UINTN MokNewSize, int authenticate,
+ BOOLEAN MokX)
{
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
EFI_STATUS efi_status;
+ CHAR16 *db_name;
+ CHAR16 *auth_name;
UINT8 auth[PASSWORD_CRYPT_SIZE];
UINTN auth_size = PASSWORD_CRYPT_SIZE;
UINT32 attributes;
+ if (MokX) {
+ db_name = L"MokListX";
+ auth_name = L"MokXAuth";
+ } else {
+ db_name = L"MokList";
+ auth_name = L"MokAuth";
+ }
+
if (authenticate) {
- efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokAuth",
+ efi_status = uefi_call_wrapper(RT->GetVariable, 5, auth_name,
&shim_lock_guid,
&attributes, &auth_size, auth);
if (efi_status != EFI_SUCCESS ||
(auth_size != SHA256_DIGEST_SIZE &&
auth_size != PASSWORD_CRYPT_SIZE)) {
- console_error(L"Failed to get MokAuth", efi_status);
+ if (MokX)
+ console_error(L"Failed to get MokXAuth", efi_status);
+ else
+ console_error(L"Failed to get MokAuth", efi_status);
return efi_status;
}
@@ -734,14 +748,14 @@ static EFI_STATUS store_keys (void *MokNew, UINTN MokNewSize, int authenticate)
if (!MokNewSize) {
/* Delete MOK */
- efi_status = uefi_call_wrapper(RT->SetVariable, 5, L"MokList",
+ efi_status = uefi_call_wrapper(RT->SetVariable, 5, db_name,
&shim_lock_guid,
EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS,
0, NULL);
} else {
/* Write new MOK */
- efi_status = uefi_call_wrapper(RT->SetVariable, 5, L"MokList",
+ efi_status = uefi_call_wrapper(RT->SetVariable, 5, db_name,
&shim_lock_guid,
EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
@@ -757,17 +771,25 @@ static EFI_STATUS store_keys (void *MokNew, UINTN MokNewSize, int authenticate)
return EFI_SUCCESS;
}
-static UINTN mok_enrollment_prompt (void *MokNew, UINTN MokNewSize, int auth) {
+static UINTN mok_enrollment_prompt (void *MokNew, UINTN MokNewSize, int auth,
+ BOOLEAN MokX)
+{
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
EFI_STATUS efi_status;
+ CHAR16 *title;
- if (list_keys(MokNew, MokNewSize, L"[Enroll MOK]") != EFI_SUCCESS)
+ if (MokX)
+ title = L"[Enroll MOKX]";
+ else
+ title = L"[Enroll MOK]";
+
+ if (list_keys(MokNew, MokNewSize, title) != EFI_SUCCESS)
return 0;
if (console_yes_no((CHAR16 *[]){L"Enroll the key(s)?", NULL}) == 0)
return 0;
- efi_status = store_keys(MokNew, MokNewSize, auth);
+ efi_status = store_keys(MokNew, MokNewSize, auth, MokX);
if (efi_status != EFI_SUCCESS) {
console_notify(L"Failed to enroll keys\n");
@@ -775,8 +797,13 @@ static UINTN mok_enrollment_prompt (void *MokNew, UINTN MokNewSize, int auth) {
}
if (auth) {
- LibDeleteVariable(L"MokNew", &shim_lock_guid);
- LibDeleteVariable(L"MokAuth", &shim_lock_guid);
+ if (MokX) {
+ LibDeleteVariable(L"MokXNew", &shim_lock_guid);
+ LibDeleteVariable(L"MokXAuth", &shim_lock_guid);
+ } else {
+ LibDeleteVariable(L"MokNew", &shim_lock_guid);
+ LibDeleteVariable(L"MokAuth", &shim_lock_guid);
+ }
console_notify(L"The system must now be rebooted");
uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm,
@@ -788,25 +815,35 @@ static UINTN mok_enrollment_prompt (void *MokNew, UINTN MokNewSize, int auth) {
return 0;
}
-static INTN mok_reset_prompt ()
+static INTN mok_reset_prompt (BOOLEAN MokX)
{
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
EFI_STATUS efi_status;
+ CHAR16 *prompt;
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
- if (console_yes_no((CHAR16 *[]){L"Erase all stored keys?", NULL }) == 0)
+ if (MokX)
+ prompt = L"Erase all stored keys in MokListX?";
+ else
+ prompt = L"Erase all stored keys in MokList?";
+ if (console_yes_no((CHAR16 *[]){prompt, NULL }) == 0)
return 0;
- efi_status = store_keys(NULL, 0, TRUE);
+ efi_status = store_keys(NULL, 0, TRUE, MokX);
if (efi_status != EFI_SUCCESS) {
console_notify(L"Failed to erase keys\n");
return -1;
}
- LibDeleteVariable(L"MokNew", &shim_lock_guid);
- LibDeleteVariable(L"MokAuth", &shim_lock_guid);
+ if (MokX) {
+ LibDeleteVariable(L"MokXNew", &shim_lock_guid);
+ LibDeleteVariable(L"MokXAuth", &shim_lock_guid);
+ } else {
+ LibDeleteVariable(L"MokNew", &shim_lock_guid);
+ LibDeleteVariable(L"MokAuth", &shim_lock_guid);
+ }
console_notify(L"The system must now be rebooted");
uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm,
@@ -815,7 +852,8 @@ static INTN mok_reset_prompt ()
return -1;
}
-static EFI_STATUS write_back_mok_list (MokListNode *list, INTN key_num)
+static EFI_STATUS write_back_mok_list (MokListNode *list, INTN key_num,
+ BOOLEAN MokX)
{
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
EFI_STATUS efi_status;
@@ -824,6 +862,12 @@ static EFI_STATUS write_back_mok_list (MokListNode *list, INTN key_num)
void *Data = NULL, *ptr;
INTN DataSize = 0;
int i;
+ CHAR16 *db_name;
+
+ if (MokX)
+ db_name = L"MokListX";
+ else
+ db_name = L"MokList";
for (i = 0; i < key_num; i++) {
if (list[i].Mok == NULL)
@@ -861,7 +905,7 @@ static EFI_STATUS write_back_mok_list (MokListNode *list, INTN key_num)
sizeof(EFI_GUID) + list[i].MokSize;
}
- efi_status = uefi_call_wrapper(RT->SetVariable, 5, L"MokList",
+ efi_status = uefi_call_wrapper(RT->SetVariable, 5, db_name,
&shim_lock_guid,
EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS,
@@ -877,10 +921,14 @@ static EFI_STATUS write_back_mok_list (MokListNode *list, INTN key_num)
return EFI_SUCCESS;
}
-static EFI_STATUS delete_keys (void *MokDel, UINTN MokDelSize)
+static EFI_STATUS delete_keys (void *MokDel, UINTN MokDelSize, BOOLEAN MokX)
{
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
EFI_STATUS efi_status;
+ CHAR16 *db_name;
+ CHAR16 *auth_name;
+ CHAR16 *err_str1;
+ CHAR16 *err_str2;
UINT8 auth[PASSWORD_CRYPT_SIZE];
UINTN auth_size = PASSWORD_CRYPT_SIZE;
UINT32 attributes;
@@ -890,13 +938,24 @@ static EFI_STATUS delete_keys (void *MokDel, UINTN MokDelSize)
INTN mok_num, del_num;
int i, j;
- efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokDelAuth",
+ if (MokX) {
+ db_name = L"MokListX";
+ auth_name = L"MokXDelAuth";
+ } else {
+ db_name = L"MokList";
+ auth_name = L"MokDelAuth";
+ }
+
+ efi_status = uefi_call_wrapper(RT->GetVariable, 5, auth_name,
&shim_lock_guid,
&attributes, &auth_size, auth);
if (efi_status != EFI_SUCCESS ||
(auth_size != SHA256_DIGEST_SIZE && auth_size != PASSWORD_CRYPT_SIZE)) {
- console_error(L"Failed to get MokDelAuth", efi_status);
+ if (MokX)
+ console_error(L"Failed to get MokXDelAuth", efi_status);
+ else
+ console_error(L"Failed to get MokDelAuth", efi_status);
return efi_status;
}
@@ -909,15 +968,18 @@ static EFI_STATUS delete_keys (void *MokDel, UINTN MokDelSize)
if (efi_status != EFI_SUCCESS)
return EFI_ACCESS_DENIED;
- efi_status = get_variable_attr (L"MokList", &MokListData, &MokListDataSize,
+ efi_status = get_variable_attr (db_name, &MokListData, &MokListDataSize,
shim_lock_guid, &attributes);
if (attributes & EFI_VARIABLE_RUNTIME_ACCESS) {
- console_alertbox((CHAR16 *[]){L"MokList is compromised!",
- L"Erase all keys in MokList!",
- NULL});
- if (LibDeleteVariable(L"MokList", &shim_lock_guid) != EFI_SUCCESS) {
- console_notify(L"Failed to erase MokList");
+ if (MokX) {
+ err_str1 = L"MokListX is compromised!";
+ err_str2 = L"Erase all keys in MokListX!";
+ } else {
+ err_str1 = L"MokList is compromised!";
+ err_str2 = L"Erase all keys in MokList!";
}
+ console_alertbox((CHAR16 *[]){err_str1, err_str2, NULL});
+ LibDeleteVariable(db_name, &shim_lock_guid);
return EFI_ACCESS_DENIED;
}
@@ -945,7 +1007,7 @@ static EFI_STATUS delete_keys (void *MokDel, UINTN MokDelSize)
}
}
- efi_status = write_back_mok_list(mok, mok_num);
+ efi_status = write_back_mok_list(mok, mok_num, MokX);
if (MokListData)
FreePool(MokListData);
@@ -957,27 +1019,38 @@ static EFI_STATUS delete_keys (void *MokDel, UINTN MokDelSize)
return efi_status;
}
-static INTN mok_deletion_prompt (void *MokDel, UINTN MokDelSize)
+static INTN mok_deletion_prompt (void *MokDel, UINTN MokDelSize, BOOLEAN MokX)
{
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
EFI_STATUS efi_status;
+ CHAR16 *title;
+
+ if (MokX)
+ title = L"[Delete MOKX]";
+ else
+ title = L"[Delete MOK]";
- if (list_keys(MokDel, MokDelSize, L"[Delete MOK]") != EFI_SUCCESS) {
+ if (list_keys(MokDel, MokDelSize, title) != EFI_SUCCESS) {
return 0;
}
if (console_yes_no((CHAR16 *[]){L"Delete the key(s)?", NULL}) == 0)
return 0;
- efi_status = delete_keys(MokDel, MokDelSize);
+ efi_status = delete_keys(MokDel, MokDelSize, MokX);
if (efi_status != EFI_SUCCESS) {
console_notify(L"Failed to delete keys");
return -1;
}
- LibDeleteVariable(L"MokDel", &shim_lock_guid);
- LibDeleteVariable(L"MokDelAuth", &shim_lock_guid);
+ if (MokX) {
+ LibDeleteVariable(L"MokXDel", &shim_lock_guid);
+ LibDeleteVariable(L"MokXDelAuth", &shim_lock_guid);
+ } else {
+ LibDeleteVariable(L"MokDel", &shim_lock_guid);
+ LibDeleteVariable(L"MokDelAuth", &shim_lock_guid);
+ }
console_notify(L"The system must now be rebooted");
uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm,
@@ -1396,7 +1469,7 @@ static EFI_STATUS enroll_file (void *data, UINTN datasize, BOOLEAN hash)
goto out;
}
- mok_enrollment_prompt(mokbuffer, mokbuffersize, FALSE);
+ mok_enrollment_prompt(mokbuffer, mokbuffersize, FALSE, FALSE);
out:
if (mokbuffer)
FreePool(mokbuffer);
@@ -1631,8 +1704,11 @@ static int draw_countdown()
typedef enum {
MOK_CONTINUE_BOOT,
MOK_RESET_MOK,
+ MOK_RESET_MOKX,
MOK_ENROLL_MOK,
+ MOK_ENROLL_MOKX,
MOK_DELETE_MOK,
+ MOK_DELETE_MOKX,
MOK_CHANGE_SB,
MOK_SET_PW,
MOK_CHANGE_DB,
@@ -1645,13 +1721,17 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle,
void *MokDel, UINTN MokDelSize,
void *MokSB, UINTN MokSBSize,
void *MokPW, UINTN MokPWSize,
- void *MokDB, UINTN MokDBSize)
+ void *MokDB, UINTN MokDBSize,
+ void *MokXNew, UINTN MokXNewSize,
+ void *MokXDel, UINTN MokXDelSize)
{
CHAR16 **menu_strings;
mok_menu_item *menu_item;
int choice = 0;
UINT32 MokAuth = 0;
UINT32 MokDelAuth = 0;
+ UINT32 MokXAuth = 0;
+ UINT32 MokXDelAuth = 0;
UINTN menucount = 3, i = 0;
EFI_STATUS efi_status;
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
@@ -1680,12 +1760,34 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle,
(auth_size == SHA256_DIGEST_SIZE || auth_size == PASSWORD_CRYPT_SIZE))
MokDelAuth = 1;
+ efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokXAuth",
+ &shim_lock_guid,
+ &attributes, &auth_size, auth);
+
+ if ((efi_status == EFI_SUCCESS) &&
+ (auth_size == SHA256_DIGEST_SIZE || auth_size == PASSWORD_CRYPT_SIZE))
+ MokXAuth = 1;
+
+ efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokXDelAuth",
+ &shim_lock_guid,
+ &attributes, &auth_size, auth);
+
+ if ((efi_status == EFI_SUCCESS) &&
+ (auth_size == SHA256_DIGEST_SIZE || auth_size == PASSWORD_CRYPT_SIZE))
+ MokXDelAuth = 1;
+
if (MokNew || MokAuth)
menucount++;
if (MokDel || MokDelAuth)
menucount++;
+ if (MokXNew || MokXAuth)
+ menucount++;
+
+ if (MokXDel || MokXDelAuth)
+ menucount++;
+
if (MokSB)
menucount++;
@@ -1723,12 +1825,29 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle,
i++;
}
- if (MokDel || MokDelAuth) {
+ if (MokDel || MokDelAuth) {
menu_strings[i] = L"Delete MOK";
menu_item[i] = MOK_DELETE_MOK;
i++;
}
+ if (MokXNew || MokXAuth) {
+ if (!MokXNew) {
+ menu_strings[i] = L"Reset MOKX";
+ menu_item[i] = MOK_RESET_MOKX;
+ } else {
+ menu_strings[i] = L"Enroll MOKX";
+ menu_item[i] = MOK_ENROLL_MOKX;
+ }
+ i++;
+ }
+
+ if (MokXDel || MokXDelAuth) {
+ menu_strings[i] = L"Delete MOKX";
+ menu_item[i] = MOK_DELETE_MOKX;
+ i++;
+ }
+
if (MokSB) {
menu_strings[i] = L"Change Secure Boot state";
menu_item[i] = MOK_CHANGE_SB;
@@ -1771,13 +1890,22 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle,
case MOK_CONTINUE_BOOT:
goto out;
case MOK_RESET_MOK:
- mok_reset_prompt();
+ mok_reset_prompt(FALSE);
break;
case MOK_ENROLL_MOK:
- mok_enrollment_prompt(MokNew, MokNewSize, TRUE);
+ mok_enrollment_prompt(MokNew, MokNewSize, TRUE, FALSE);
break;
case MOK_DELETE_MOK:
- mok_deletion_prompt(MokDel, MokDelSize);
+ mok_deletion_prompt(MokDel, MokDelSize, FALSE);
+ break;
+ case MOK_RESET_MOKX:
+ mok_reset_prompt(TRUE);
+ break;
+ case MOK_ENROLL_MOKX:
+ mok_enrollment_prompt(MokXNew, MokXNewSize, TRUE, TRUE);
+ break;
+ case MOK_DELETE_MOKX:
+ mok_deletion_prompt(MokXDel, MokXDelSize, TRUE);
break;
case MOK_CHANGE_SB:
mok_sb_prompt(MokSB, MokSBSize);
@@ -1811,13 +1939,15 @@ out:
static EFI_STATUS check_mok_request(EFI_HANDLE image_handle)
{
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
- UINTN MokNewSize = 0, MokDelSize = 0, MokSBSize = 0, MokPWSize = 0,
- MokDBSize = 0;
+ UINTN MokNewSize = 0, MokDelSize = 0, MokSBSize = 0, MokPWSize = 0;
+ UINTN MokDBSize = 0, MokXNewSize = 0, MokXDelSize = 0;
void *MokNew = NULL;
void *MokDel = NULL;
void *MokSB = NULL;
void *MokPW = NULL;
void *MokDB = NULL;
+ void *MokXNew = NULL;
+ void *MokXDel = NULL;
EFI_STATUS status;
status = get_variable(L"MokNew", (UINT8 **)&MokNew, &MokNewSize,
@@ -1870,8 +2000,29 @@ static EFI_STATUS check_mok_request(EFI_HANDLE image_handle)
console_error(L"Could not retrieve MokDB", status);
}
+ status = get_variable(L"MokXNew", (UINT8 **)&MokXNew, &MokXNewSize,
+ shim_lock_guid);
+ if (status == EFI_SUCCESS) {
+ if (LibDeleteVariable(L"MokXNew", &shim_lock_guid) != EFI_SUCCESS) {
+ console_notify(L"Failed to delete MokXNew");
+ }
+ } else if (EFI_ERROR(status) && status != EFI_NOT_FOUND) {
+ console_error(L"Could not retrieve MokXNew", status);
+ }
+
+ status = get_variable(L"MokXDel", (UINT8 **)&MokXDel, &MokXDelSize,
+ shim_lock_guid);
+ if (status == EFI_SUCCESS) {
+ if (LibDeleteVariable(L"MokXDel", &shim_lock_guid) != EFI_SUCCESS) {
+ console_notify(L"Failed to delete MokXDel");
+ }
+ } else if (EFI_ERROR(status) && status != EFI_NOT_FOUND) {
+ console_error(L"Could not retrieve MokXDel", status);
+ }
+
enter_mok_menu(image_handle, MokNew, MokNewSize, MokDel, MokDelSize,
- MokSB, MokSBSize, MokPW, MokPWSize, MokDB, MokDBSize);
+ MokSB, MokSBSize, MokPW, MokPWSize, MokDB, MokDBSize,
+ MokXNew, MokXNewSize, MokXDel, MokXDelSize);
if (MokNew)
FreePool (MokNew);
@@ -1888,8 +2039,16 @@ static EFI_STATUS check_mok_request(EFI_HANDLE image_handle)
if (MokDB)
FreePool (MokDB);
+ if (MokXNew)
+ FreePool (MokXNew);
+
+ if (MokXDel)
+ FreePool (MokXDel);
+
LibDeleteVariable(L"MokAuth", &shim_lock_guid);
LibDeleteVariable(L"MokDelAuth", &shim_lock_guid);
+ LibDeleteVariable(L"MokXAuth", &shim_lock_guid);
+ LibDeleteVariable(L"MokXDelAuth", &shim_lock_guid);
return EFI_SUCCESS;
}
diff --git a/shim.c b/shim.c
index cf93d65..2c23a2f 100644
--- a/shim.c
+++ b/shim.c
@@ -1510,7 +1510,8 @@ 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"MokDB")) {
+ check_var(L"MokDel") || check_var(L"MokDB") ||
+ check_var(L"MokXNew") || check_var(L"MokXDel")) {
efi_status = start_image(image_handle, MOK_MANAGER);
if (efi_status != EFI_SUCCESS) {
--
1.8.4.5
From d2980a5cbee887223405a24be44ffd5bb439e3f1 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Thu, 24 Oct 2013 17:32:31 +0800
Subject: [PATCH 02/10] MokManager: show the hash list properly
Signed-off-by: Gary Ching-Pang Lin <glin@suse.com>
---
MokManager.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 71 insertions(+), 11 deletions(-)
diff --git a/MokManager.c b/MokManager.c
index b9b42b6..5575a94 100644
--- a/MokManager.c
+++ b/MokManager.c
@@ -165,9 +165,16 @@ static MokListNode *build_mok_list(UINT32 num, void *Data, UINTN DataSize) {
Cert = (EFI_SIGNATURE_DATA *) (((UINT8 *) CertList) +
sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
- list[count].MokSize = CertList->SignatureSize - sizeof(EFI_GUID);
- list[count].Mok = (void *)Cert->SignatureData;
list[count].Type = CertList->SignatureType;
+ if (CompareGuid (&CertList->SignatureType, &CertType) == 0) {
+ list[count].MokSize = CertList->SignatureSize -
+ sizeof(EFI_GUID);
+ list[count].Mok = (void *)Cert->SignatureData;
+ } else {
+ list[count].MokSize = CertList->SignatureListSize -
+ sizeof(EFI_SIGNATURE_LIST);
+ list[count].Mok = (void *)Cert;
+ }
count++;
dbsize -= CertList->SignatureListSize;
@@ -373,7 +380,7 @@ static void show_x509_info (X509 *X509Cert, UINT8 *hash)
FreePool(text);
}
-static void show_efi_hash (UINT8 *hash)
+static void show_sha256_digest (UINT8 *hash)
{
CHAR16 *text[5];
POOL_PRINT hash_string1;
@@ -404,16 +411,68 @@ static void show_efi_hash (UINT8 *hash)
FreePool(hash_string2.str);
}
-static void show_mok_info (void *Mok, UINTN MokSize)
+static void show_efi_hash (void *Mok, UINTN MokSize)
+{
+ UINTN sig_size;
+ UINTN hash_num;
+ UINT8 *hash;
+ CHAR16 **menu_strings;
+ int key_num = 0;
+ int i;
+
+ sig_size = SHA256_DIGEST_SIZE + sizeof(EFI_GUID);
+ if ((MokSize % sig_size) != 0) {
+ console_errorbox(L"Corrupted Hash List");
+ return;
+ }
+ hash_num = MokSize / sig_size;
+
+ if (hash_num == 1) {
+ hash = (UINT8 *)Mok + sizeof(EFI_GUID);
+ show_sha256_digest(hash);
+ return;
+ }
+
+ menu_strings = AllocateZeroPool(sizeof(CHAR16 *) * (hash_num + 2));
+ if (!menu_strings) {
+ console_errorbox(L"Out of Resources");
+ return;
+ }
+ for (i=0; i<hash_num; i++) {
+ menu_strings[i] = PoolPrint(L"View hash %d", i);
+ }
+ menu_strings[i] = StrDuplicate(L"Continue");
+ menu_strings[i+1] = NULL;
+
+ while (key_num < hash_num) {
+ key_num = console_select((CHAR16 *[]){ L"[Hash List]", NULL },
+ menu_strings, 0);
+
+ if (key_num < 0 || key_num >= hash_num)
+ break;
+
+ hash = (UINT8 *)Mok + sig_size*key_num + sizeof(EFI_GUID);
+ show_sha256_digest(hash);
+ }
+
+ for (i=0; menu_strings[i] != NULL; i++)
+ FreePool(menu_strings[i]);
+
+ FreePool(menu_strings);
+}
+
+static void show_mok_info (EFI_GUID Type, void *Mok, UINTN MokSize)
{
EFI_STATUS efi_status;
UINT8 hash[SHA1_DIGEST_SIZE];
X509 *X509Cert;
+ EFI_GUID CertType = X509_GUID;
+ EFI_GUID HashType = EFI_CERT_SHA256_GUID;
if (!Mok || MokSize == 0)
return;
- if (MokSize != SHA256_DIGEST_SIZE) {
+ if (CompareGuid (&Type, &CertType) == 0) {
efi_status = get_sha1sum(Mok, MokSize, hash);
if (efi_status != EFI_SUCCESS) {
@@ -429,8 +488,8 @@ static void show_mok_info (void *Mok, UINTN MokSize)
console_notify(L"Not a valid X509 certificate");
return;
}
- } else {
- show_efi_hash(Mok);
+ } else if (CompareGuid (&Type, &HashType) == 0) {
+ show_efi_hash(Mok, MokSize);
}
}
@@ -438,7 +497,7 @@ static EFI_STATUS list_keys (void *KeyList, UINTN KeyListSize, CHAR16 *title)
{
UINT32 MokNum = 0;
MokListNode *keys = NULL;
- INTN key_num = 0;
+ int key_num = 0;
CHAR16 **menu_strings;
int i;
@@ -472,10 +531,11 @@ static EFI_STATUS list_keys (void *KeyList, UINTN KeyListSize, CHAR16 *title)
key_num = console_select((CHAR16 *[]){ title, NULL },
menu_strings, 0);
- if (key_num < 0)
+ if (key_num < 0 || key_num >= MokNum)
break;
- else if (key_num < MokNum)
- show_mok_info(keys[key_num].Mok, keys[key_num].MokSize);
+
+ show_mok_info(keys[key_num].Type, keys[key_num].Mok,
+ keys[key_num].MokSize);
}
for (i=0; menu_strings[i] != NULL; i++)
--
1.8.4.5
From 9c4b5d58385c64056adb5386c097219665f2f50d Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Fri, 25 Oct 2013 16:54:25 +0800
Subject: [PATCH 03/10] MokManager: delete the hash properly
Signed-off-by: Gary Ching-Pang Lin <glin@suse.com>
---
MokManager.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 114 insertions(+), 10 deletions(-)
diff --git a/MokManager.c b/MokManager.c
index 5575a94..23bdeef 100644
--- a/MokManager.c
+++ b/MokManager.c
@@ -981,9 +981,116 @@ static EFI_STATUS write_back_mok_list (MokListNode *list, INTN key_num,
return EFI_SUCCESS;
}
+static void delete_cert (void *key, UINT32 key_size,
+ MokListNode *mok, INTN mok_num)
+{
+ EFI_GUID CertType = X509_GUID;
+ int i;
+
+ for (i = 0; i < mok_num; i++) {
+ if (CompareGuid(&(mok[i].Type), &CertType) != 0)
+ continue;
+
+ if (mok[i].MokSize == key_size &&
+ CompareMem(key, mok[i].Mok, key_size) == 0) {
+ /* Remove the key */
+ mok[i].Mok = NULL;
+ mok[i].MokSize = 0;
+ }
+ }
+}
+
+static int match_hash (UINT8 *hash, UINT32 hash_size,
+ void *hash_list, UINT32 list_num)
+{
+ UINT8 *ptr;
+ int i;
+
+ ptr = hash_list + sizeof(EFI_GUID);
+ for (i = 0; i < list_num; i++) {
+ if (CompareMem(hash, ptr, hash_size) == 0)
+ return i;
+ ptr += hash_size + sizeof(EFI_GUID);
+ }
+
+ return -1;
+}
+
+static void mem_move (void *dest, void *src, UINTN size)
+{
+ UINT8 *d, *s;
+ int i;
+
+ d = (UINT8 *)dest;
+ s = (UINT8 *)src;
+ for (i = 0; i < size; i++)
+ d[i] = s[i];
+}
+
+static void delete_hash_in_list (UINT8 *hash, UINT32 hash_size,
+ MokListNode *mok, INTN mok_num)
+{
+ EFI_GUID HashType = EFI_CERT_SHA256_GUID;
+ UINT32 sig_size;
+ int i, del_ind;
+ void *start, *end;
+ UINT32 remain;
+
+ sig_size = hash_size + sizeof(EFI_GUID);
+
+ for (i = 0; i < mok_num; i++) {
+ if ((CompareGuid(&(mok[i].Type), &HashType) != 0) ||
+ (mok[i].MokSize < sig_size))
+ continue;
+
+ del_ind = match_hash(hash, hash_size, mok[i].Mok,
+ mok[i].MokSize);
+ if (del_ind < 0)
+ continue;
+ /* Remove the hash */
+ if (sig_size == mok[i].MokSize) {
+ mok[i].Mok = NULL;
+ mok[i].MokSize = 0;
+ } else {
+ start = mok[i].Mok + del_ind * sig_size;
+ end = start + sig_size;
+ remain = mok[i].MokSize - (del_ind + 1)*sig_size;
+
+ mem_move(start, end, remain);
+ mok[i].MokSize -= sig_size;
+ }
+ }
+}
+
+static void delete_hash_list (void *hash_list, UINT32 list_size,
+ MokListNode *mok, INTN mok_num)
+{
+ UINT32 hash_size;
+ UINT32 hash_num;
+ UINT32 sig_size;
+ UINT8 *hash;
+ int i;
+
+ hash_size = SHA256_DIGEST_SIZE;
+ sig_size = hash_size + sizeof(EFI_GUID);
+ if (list_size < sig_size)
+ return;
+
+ hash_num = list_size / sig_size;
+
+ hash = hash_list + sizeof(EFI_GUID);
+
+ for (i = 0; i < hash_num; i++) {
+ delete_hash_in_list (hash, hash_size, mok, mok_num);
+ hash += sig_size;
+ }
+}
+
static EFI_STATUS delete_keys (void *MokDel, UINTN MokDelSize, BOOLEAN MokX)
{
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+ EFI_GUID CertType = X509_GUID;
+ EFI_GUID HashType = EFI_CERT_SHA256_GUID;
EFI_STATUS efi_status;
CHAR16 *db_name;
CHAR16 *auth_name;
@@ -996,7 +1103,7 @@ static EFI_STATUS delete_keys (void *MokDel, UINTN MokDelSize, BOOLEAN MokX)
UINTN MokListDataSize = 0;
MokListNode *mok, *del_key;
INTN mok_num, del_num;
- int i, j;
+ int i;
if (MokX) {
db_name = L"MokListX";
@@ -1055,15 +1162,12 @@ static EFI_STATUS delete_keys (void *MokDel, UINTN MokDelSize, BOOLEAN MokX)
/* Search and destroy */
for (i = 0; i < del_num; i++) {
- UINT32 key_size = del_key[i].MokSize;
- void *key = del_key[i].Mok;
- for (j = 0; j < mok_num; j++) {
- if (mok[j].MokSize == key_size &&
- CompareMem(key, mok[j].Mok, key_size) == 0) {
- /* Remove the key */
- mok[j].Mok = NULL;
- mok[j].MokSize = 0;
- }
+ if (CompareGuid(&(del_key[i].Type), &CertType) == 0) {
+ delete_cert(del_key[i].Mok, del_key[i].MokSize,
+ mok, mok_num);
+ } else if (CompareGuid(&(del_key[i].Type), &HashType) == 0) {
+ delete_hash_list(del_key[i].Mok, del_key[i].MokSize,
+ mok, mok_num);
}
}
--
1.8.4.5
From 54ce2f9605990c00f9cafae7cab22a1c885828c1 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Fri, 25 Oct 2013 17:05:10 +0800
Subject: [PATCH 04/10] MokManager: Match all hashes in the list
Signed-off-by: Gary Ching-Pang Lin <glin@suse.com>
---
MokManager.c | 24 ++++++++++++++----------
1 file changed, 14 insertions(+), 10 deletions(-)
diff --git a/MokManager.c b/MokManager.c
index 23bdeef..5b40e19 100644
--- a/MokManager.c
+++ b/MokManager.c
@@ -1000,14 +1000,14 @@ static void delete_cert (void *key, UINT32 key_size,
}
}
-static int match_hash (UINT8 *hash, UINT32 hash_size,
+static int match_hash (UINT8 *hash, UINT32 hash_size, int start,
void *hash_list, UINT32 list_num)
{
UINT8 *ptr;
int i;
ptr = hash_list + sizeof(EFI_GUID);
- for (i = 0; i < list_num; i++) {
+ for (i = start; i < list_num; i++) {
if (CompareMem(hash, ptr, hash_size) == 0)
return i;
ptr += hash_size + sizeof(EFI_GUID);
@@ -1043,21 +1043,25 @@ static void delete_hash_in_list (UINT8 *hash, UINT32 hash_size,
(mok[i].MokSize < sig_size))
continue;
- del_ind = match_hash(hash, hash_size, mok[i].Mok,
+ del_ind = match_hash(hash, hash_size, 0, mok[i].Mok,
mok[i].MokSize);
- if (del_ind < 0)
- continue;
- /* Remove the hash */
- if (sig_size == mok[i].MokSize) {
- mok[i].Mok = NULL;
- mok[i].MokSize = 0;
- } else {
+ while (del_ind >= 0) {
+ /* Remove the hash */
+ if (sig_size == mok[i].MokSize) {
+ mok[i].Mok = NULL;
+ mok[i].MokSize = 0;
+ break;
+ }
+
start = mok[i].Mok + del_ind * sig_size;
end = start + sig_size;
remain = mok[i].MokSize - (del_ind + 1)*sig_size;
mem_move(start, end, remain);
mok[i].MokSize -= sig_size;
+
+ del_ind = match_hash(hash, hash_size, del_ind,
+ mok[i].Mok, mok[i].MokSize);
}
}
}
--
1.8.4.5
From 4c1912c8521cca4d320a1417abff6f7954809a20 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Fri, 25 Oct 2013 18:30:48 +0800
Subject: [PATCH 05/10] MokManager: Write the hash list properly
also return to the previous entry in the list
Signed-off-by: Gary Ching-Pang Lin <glin@suse.com>
---
MokManager.c | 30 +++++++++++++++++++-----------
1 file changed, 19 insertions(+), 11 deletions(-)
diff --git a/MokManager.c b/MokManager.c
index 5b40e19..e79a8e0 100644
--- a/MokManager.c
+++ b/MokManager.c
@@ -441,12 +441,12 @@ static void show_efi_hash (void *Mok, UINTN MokSize)
for (i=0; i<hash_num; i++) {
menu_strings[i] = PoolPrint(L"View hash %d", i);
}
- menu_strings[i] = StrDuplicate(L"Continue");
+ menu_strings[i] = StrDuplicate(L"Back");
menu_strings[i+1] = NULL;
while (key_num < hash_num) {
key_num = console_select((CHAR16 *[]){ L"[Hash List]", NULL },
- menu_strings, 0);
+ menu_strings, key_num);
if (key_num < 0 || key_num >= hash_num)
break;
@@ -529,7 +529,7 @@ static EFI_STATUS list_keys (void *KeyList, UINTN KeyListSize, CHAR16 *title)
while (key_num < MokNum) {
key_num = console_select((CHAR16 *[]){ title, NULL },
- menu_strings, 0);
+ menu_strings, key_num);
if (key_num < 0 || key_num >= MokNum)
break;
@@ -916,6 +916,7 @@ static EFI_STATUS write_back_mok_list (MokListNode *list, INTN key_num,
BOOLEAN MokX)
{
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+ EFI_GUID CertType = X509_GUID;
EFI_STATUS efi_status;
EFI_SIGNATURE_LIST *CertList;
EFI_SIGNATURE_DATA *CertData;
@@ -952,17 +953,24 @@ static EFI_STATUS write_back_mok_list (MokListNode *list, INTN key_num,
sizeof(EFI_SIGNATURE_LIST));
CertList->SignatureType = list[i].Type;
- CertList->SignatureListSize = list[i].MokSize +
- sizeof(EFI_SIGNATURE_LIST) +
- sizeof(EFI_SIGNATURE_DATA) - 1;
CertList->SignatureHeaderSize = 0;
- CertList->SignatureSize = list[i].MokSize + sizeof(EFI_GUID);
- CertData->SignatureOwner = shim_lock_guid;
- CopyMem(CertData->SignatureData, list[i].Mok, list[i].MokSize);
+ if (CompareGuid(&(list[i].Type), &CertType) == 0) {
+ CertList->SignatureListSize = list[i].MokSize +
+ sizeof(EFI_SIGNATURE_LIST) +
+ sizeof(EFI_GUID);
+ CertList->SignatureSize = list[i].MokSize + sizeof(EFI_GUID);
- ptr = (uint8_t *)ptr + sizeof(EFI_SIGNATURE_LIST) +
- sizeof(EFI_GUID) + list[i].MokSize;
+ CertData->SignatureOwner = shim_lock_guid;
+ CopyMem(CertData->SignatureData, list[i].Mok, list[i].MokSize);
+ } else {
+ CertList->SignatureListSize = list[i].MokSize +
+ sizeof(EFI_SIGNATURE_LIST);
+ CertList->SignatureSize = SHA256_DIGEST_SIZE + sizeof(EFI_GUID);
+
+ CopyMem(CertData, list[i].Mok, list[i].MokSize);
+ }
+ ptr = (uint8_t *)ptr + CertList->SignatureListSize;
}
efi_status = uefi_call_wrapper(RT->SetVariable, 5, db_name,
--
1.8.4.5
From 8b96a93bda39617efbe51f24d1dc606ad8835d26 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Mon, 28 Oct 2013 15:08:40 +0800
Subject: [PATCH 06/10] Copy the MOK blacklist to a RT variable
Signed-off-by: Gary Ching-Pang Lin <glin@suse.com>
---
shim.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/shim.c b/shim.c
index 2c23a2f..ccb3071 100644
--- a/shim.c
+++ b/shim.c
@@ -1480,6 +1480,33 @@ EFI_STATUS mirror_mok_list()
}
/*
+ * Copy the boot-services only MokListX variable to the runtime-accessible
+ * MokListXRT variable. It's not marked NV, so the OS can't modify it.
+ */
+EFI_STATUS mirror_mok_list_x()
+{
+ EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+ EFI_STATUS efi_status;
+ UINT8 *Data = NULL;
+ UINTN DataSize = 0;
+
+ efi_status = get_variable(L"MokListX", &Data, &DataSize, shim_lock_guid);
+ if (efi_status != EFI_SUCCESS)
+ return efi_status;
+
+ efi_status = uefi_call_wrapper(RT->SetVariable, 5, L"MokListXRT",
+ &shim_lock_guid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS
+ | EFI_VARIABLE_RUNTIME_ACCESS,
+ DataSize, Data);
+ if (efi_status != EFI_SUCCESS) {
+ console_error(L"Failed to set MokListRT", efi_status);
+ }
+
+ return efi_status;
+}
+
+/*
* Check if a variable exists
*/
static BOOLEAN check_var(CHAR16 *varname)
@@ -1799,6 +1826,8 @@ EFI_STATUS efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *passed_systab)
*/
efi_status = mirror_mok_list();
+ efi_status = mirror_mok_list_x();
+
/*
* Create the runtime MokIgnoreDB variable so the kernel can make
* use of it
--
1.8.4.5
From 044d04dbed3ef3f2f3004a770e3751eabc052c2c Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Mon, 28 Oct 2013 16:36:34 +0800
Subject: [PATCH 07/10] No newline for console_notify
Signed-off-by: Gary Ching-Pang Lin <glin@suse.com>
---
shim.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/shim.c b/shim.c
index ccb3071..e30a464 100644
--- a/shim.c
+++ b/shim.c
@@ -470,7 +470,7 @@ static BOOLEAN secure_mode (void)
if (sb != 1) {
if (verbose)
- console_notify(L"Secure boot not enabled\n");
+ console_notify(L"Secure boot not enabled");
return FALSE;
}
@@ -483,7 +483,7 @@ static BOOLEAN secure_mode (void)
if (setupmode == 1) {
if (verbose)
- console_notify(L"Platform is in setup mode\n");
+ console_notify(L"Platform is in setup mode");
return FALSE;
}
--
1.8.4.5
From 0e97d1576fcc1924f0f17b7f31baf1dd74a7f83e Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Mon, 4 Nov 2013 14:45:33 +0800
Subject: [PATCH 08/10] Verify the EFI images with MOK blacklist
Signed-off-by: Gary Ching-Pang Lin <glin@suse.com>
---
shim.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/shim.c b/shim.c
index e30a464..efd3d85 100644
--- a/shim.c
+++ b/shim.c
@@ -365,6 +365,7 @@ static EFI_STATUS check_blacklist (WIN_CERTIFICATE_EFI_PKCS *cert,
UINT8 *sha256hash, UINT8 *sha1hash)
{
EFI_GUID secure_var = EFI_IMAGE_SECURITY_DATABASE_GUID;
+ EFI_GUID shim_var = SHIM_LOCK_GUID;
EFI_SIGNATURE_LIST *dbx = (EFI_SIGNATURE_LIST *)vendor_dbx;
if (check_db_hash_in_ram(dbx, vendor_dbx_size, sha256hash,
@@ -388,6 +389,14 @@ static EFI_STATUS check_blacklist (WIN_CERTIFICATE_EFI_PKCS *cert,
if (cert && check_db_cert(L"dbx", secure_var, cert, sha256hash) ==
DATA_FOUND)
return EFI_ACCESS_DENIED;
+ if (check_db_hash(L"MokListX", shim_var, sha256hash, SHA256_DIGEST_SIZE,
+ EFI_CERT_SHA256_GUID) == DATA_FOUND) {
+ return EFI_ACCESS_DENIED;
+ }
+ if (cert && check_db_cert(L"MokListX", shim_var, cert, sha256hash) ==
+ DATA_FOUND) {
+ return EFI_ACCESS_DENIED;
+ }
return EFI_SUCCESS;
}
--
1.8.4.5
From a166edaa42ef96eaf5b000d0e4ad71779b745d68 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Mon, 4 Nov 2013 17:51:55 +0800
Subject: [PATCH 09/10] Exclude ca.crt while signing EFI images
If ca.crt was added into the certificate database, ca.crt would be the first
certificate in the signature. Because shim couldn't verify ca.crt with the
embedded shim.cer, it failed to load MokManager.efi.signed and
fallback.efi.signed.
Signed-off-by: Gary Ching-Pang Lin <glin@suse.com>
---
Makefile | 1 -
1 file changed, 1 deletion(-)
diff --git a/Makefile b/Makefile
index e65d28d..5e3fa9e 100644
--- a/Makefile
+++ b/Makefile
@@ -72,7 +72,6 @@ version.c : version.c.in
certdb/secmod.db: shim.crt
-mkdir certdb
- certutil -A -n 'my CA' -d certdb/ -t CT,CT,CT -i ca.crt
pk12util -d certdb/ -i shim.p12 -W "" -K ""
certutil -d certdb/ -A -i shim.crt -n shim -t u
--
1.8.4.5
From cce37bfa5298e8e9c12d3509c78592f711699c4f Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Tue, 11 Feb 2014 14:11:15 +0800
Subject: [PATCH 10/10] Make shim to check MokXAuth for MOKX reset
Signed-off-by: Gary Ching-Pang Lin <glin@suse.com>
---
shim.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/shim.c b/shim.c
index efd3d85..7093c45 100644
--- a/shim.c
+++ b/shim.c
@@ -1547,7 +1547,8 @@ 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"MokDB") ||
- check_var(L"MokXNew") || check_var(L"MokXDel")) {
+ check_var(L"MokXNew") || check_var(L"MokXDel") ||
+ check_var(L"MokXAuth")) {
efi_status = start_image(image_handle, MOK_MANAGER);
if (efi_status != EFI_SUCCESS) {
--
1.8.4.5