File shim-mokx-support.patch of Package shim

From 72a6913fa790c6d504f87eefddd1b2b392185b79 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/16] 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 ee29051..29ea4db 100644
--- a/MokManager.c
+++ b/MokManager.c
@@ -738,23 +738,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;
 		}
 
@@ -771,14 +785,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
@@ -794,17 +808,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");
@@ -812,8 +834,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,
@@ -825,25 +852,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,
@@ -852,7 +889,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;
@@ -861,6 +899,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)
@@ -898,7 +942,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,
@@ -914,10 +958,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;
@@ -927,13 +975,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;
 	}
 
@@ -946,15 +1005,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;
 	}
 
@@ -982,7 +1044,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);
@@ -994,27 +1056,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,
@@ -1477,7 +1550,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);
@@ -1712,8 +1785,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,
@@ -1726,13 +1802,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;
@@ -1761,12 +1841,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++;
 
@@ -1804,12 +1906,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;
@@ -1852,13 +1971,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);
@@ -1892,13 +2020,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,
@@ -1951,8 +2081,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);
@@ -1969,8 +2120,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 8076caa..bab5e92 100644
--- a/shim.c
+++ b/shim.c
@@ -1779,7 +1779,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 697a7b7d80692ea6ed9b9a73ffde1d742eee8850 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/16] 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 29ea4db..2441026 100644
--- a/MokManager.c
+++ b/MokManager.c
@@ -187,9 +187,16 @@ static MokListNode *build_mok_list(UINT32 num, void *Data, UINTN DataSize) {
 			return NULL;
 		}
 
-		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;
+		}
 
 		/* MOK out of bounds? */
 		if (list[count].MokSize > (unsigned long)end -
@@ -402,7 +409,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;
@@ -433,16 +440,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) {
@@ -458,8 +517,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);
 	}
 }
 
@@ -467,7 +526,7 @@ static EFI_STATUS list_keys (void *KeyList, UINTN KeyListSize, CHAR16 *title)
 {
 	INTN MokNum = 0;
 	MokListNode *keys = NULL;
-	INTN key_num = 0;
+	int key_num = 0;
 	CHAR16 **menu_strings;
 	int i;
 
@@ -503,10 +562,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 22b51db7daa834f8746ce3bc4e6670f21ea2311b 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/16] 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 2441026..59df4a6 100644
--- a/MokManager.c
+++ b/MokManager.c
@@ -1018,9 +1018,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;
@@ -1033,7 +1140,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";
@@ -1092,15 +1199,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 3c4c4f8e2b41a127aad6c7e967138639ed162ed1 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/16] 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 59df4a6..31cc06a 100644
--- a/MokManager.c
+++ b/MokManager.c
@@ -1037,14 +1037,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);
@@ -1080,21 +1080,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 2b5292ad76908cbfeba28f9b212a421b1efc50d9 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/16] 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 31cc06a..56839cc 100644
--- a/MokManager.c
+++ b/MokManager.c
@@ -470,12 +470,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;
@@ -560,7 +560,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;
@@ -953,6 +953,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;
@@ -989,17 +990,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 41d29504d597daffde481349e6bc4a6521819941 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/16] 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 bab5e92..8eef64d 100644
--- a/shim.c
+++ b/shim.c
@@ -1749,6 +1749,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)
@@ -2093,6 +2120,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 d424bdcdead0add27c1c1fbd80ba2b8acb7e558f 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 07/16] 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 8eef64d..2c05886 100644
--- a/shim.c
+++ b/shim.c
@@ -518,6 +518,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,
@@ -541,6 +542,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 7767893c145fa3d00b1019547716b1fdfa8d1c53 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 08/16] 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 2c05886..d46494a 100644
--- a/shim.c
+++ b/shim.c
@@ -1816,7 +1816,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


From 195edc629f9d316071f108a6e9390d86329b0e5f Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Thu, 13 Feb 2014 15:05:45 +0800
Subject: [PATCH 09/16] MokManager: calculate the variable size correctly

MokSize of the hash signature list includes the owner GUID,
so we should not add the 16bytes compensation.

Signed-off-by: Gary Ching-Pang Lin <glin@suse.com>
---
 MokManager.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/MokManager.c b/MokManager.c
index 56839cc..af38405 100644
--- a/MokManager.c
+++ b/MokManager.c
@@ -971,7 +971,9 @@ static EFI_STATUS write_back_mok_list (MokListNode *list, INTN key_num,
 		if (list[i].Mok == NULL)
 			continue;
 
-		DataSize += sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_GUID);
+		DataSize += sizeof(EFI_SIGNATURE_LIST);
+		if (CompareGuid(&(list[i].Type), &CertType) == 0)
+			DataSize += sizeof(EFI_GUID);
 		DataSize += list[i].MokSize;
 	}
 
-- 
1.8.4.5


From b5bdd25de7cfda1b6b23780b947d979abfae0782 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Mon, 17 Feb 2014 17:49:55 +0800
Subject: [PATCH 10/16] MokManager: fix the hash list counting in delete

match_hash() requests the number of keys in a list and it was
mistakenly replaced with the size of the Mok node. This would
made MokManager to remove the whole Mok node instead of one
hash.

Signed-off-by: Gary Ching-Pang Lin <glin@suse.com>
---
 MokManager.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/MokManager.c b/MokManager.c
index af38405..5901f65 100644
--- a/MokManager.c
+++ b/MokManager.c
@@ -1079,6 +1079,7 @@ static void delete_hash_in_list (UINT8 *hash, UINT32 hash_size,
 {
 	EFI_GUID HashType = EFI_CERT_SHA256_GUID;
 	UINT32 sig_size;
+	UINT32 list_num;
 	int i, del_ind;
 	void *start, *end;
 	UINT32 remain;
@@ -1090,8 +1091,10 @@ static void delete_hash_in_list (UINT8 *hash, UINT32 hash_size,
 		    (mok[i].MokSize < sig_size))
 			continue;
 
+		list_num = mok[i].MokSize / sig_size;
+
 		del_ind = match_hash(hash, hash_size, 0, mok[i].Mok,
-				     mok[i].MokSize);
+				     list_num);
 		while (del_ind >= 0) {
 			/* Remove the hash */
 			if (sig_size == mok[i].MokSize) {
@@ -1106,9 +1109,10 @@ static void delete_hash_in_list (UINT8 *hash, UINT32 hash_size,
 
 			mem_move(start, end, remain);
 			mok[i].MokSize -= sig_size;
+			list_num--;
 
 			del_ind = match_hash(hash, hash_size, del_ind,
-					     mok[i].Mok, mok[i].MokSize);
+					     mok[i].Mok, list_num);
 		}
 	}
 }
-- 
1.8.4.5


From a660b38e1bfafab7cfe6699a01e672aba40e7a36 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Thu, 3 Apr 2014 18:26:37 +0800
Subject: [PATCH 11/16] MokManager: Support SHA1 hash in MOK

Add SHA1 hash support and amend the code to make it easier to support
other SHA digests.
---
 MokManager.c | 121 ++++++++++++++++++++++++++++++++++++-----------------------
 1 file changed, 75 insertions(+), 46 deletions(-)

diff --git a/MokManager.c b/MokManager.c
index 5901f65..4ab54ed 100644
--- a/MokManager.c
+++ b/MokManager.c
@@ -93,11 +93,53 @@ done:
 	return status;
 }
 
+static BOOLEAN is_sha_hash (EFI_GUID Type)
+{
+	EFI_GUID Sha1 = EFI_CERT_SHA1_GUID;
+	EFI_GUID Sha256 = EFI_CERT_SHA256_GUID;
+
+	if (CompareGuid(&Type, &Sha1) == 0)
+		return TRUE;
+	else if (CompareGuid(&Type, &Sha256) == 0)
+		return TRUE;
+
+	return FALSE;
+}
+
+static UINT32 sha_size (EFI_GUID Type)
+{
+	EFI_GUID Sha1 = EFI_CERT_SHA1_GUID;
+	EFI_GUID Sha256 = EFI_CERT_SHA256_GUID;
+
+	if (CompareGuid(&Type, &Sha1) == 0)
+		return SHA1_DIGEST_SIZE;
+	else if (CompareGuid(&Type, &Sha256) == 0)
+		return SHA256_DIGEST_SIZE;
+
+	return 0;
+}
+
+static BOOLEAN is_valid_siglist (EFI_GUID Type, UINT32 SigSize)
+{
+	EFI_GUID CertType = X509_GUID;
+	UINT32 hash_sig_size;
+
+	if (CompareGuid (&Type, &CertType) == 0 && SigSize != 0)
+		return TRUE;
+
+	if (!is_sha_hash (Type))
+		return FALSE;
+
+	hash_sig_size = sha_size (Type) + sizeof(EFI_GUID);
+	if (SigSize != hash_sig_size)
+		return FALSE;
+
+	return TRUE;
+}
+
 static UINT32 count_keys(void *Data, UINTN DataSize)
 {
 	EFI_SIGNATURE_LIST *CertList = Data;
-	EFI_GUID CertType = X509_GUID;
-	EFI_GUID HashType = EFI_CERT_SHA256_GUID;
 	UINTN dbsize = DataSize;
 	UINT32 MokNum = 0;
 	void *end = Data + DataSize;
@@ -112,18 +154,7 @@ static UINT32 count_keys(void *Data, UINTN DataSize)
 			return 0;
 		}
 
-		if ((CompareGuid (&CertList->SignatureType, &CertType) != 0) &&
-		    (CompareGuid (&CertList->SignatureType, &HashType) != 0)) {
-			console_notify(L"Doesn't look like a key or hash");
-			dbsize -= CertList->SignatureListSize;
-			CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList +
-						  CertList->SignatureListSize);
-			continue;
-		}
-
-		if ((CompareGuid (&CertList->SignatureType, &CertType) != 0) &&
-		    (CertList->SignatureSize != 48)) {
-			console_notify(L"Doesn't look like a valid hash");
+		if (!is_valid_siglist(CertList->SignatureType, CertList->SignatureSize)) {
 			dbsize -= CertList->SignatureListSize;
 			CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList +
 						  CertList->SignatureListSize);
@@ -144,7 +175,6 @@ static MokListNode *build_mok_list(UINT32 num, void *Data, UINTN DataSize) {
 	EFI_SIGNATURE_LIST *CertList = Data;
 	EFI_SIGNATURE_DATA *Cert;
 	EFI_GUID CertType = X509_GUID;
-	EFI_GUID HashType = EFI_CERT_SHA256_GUID;
 	UINTN dbsize = DataSize;
 	UINTN count = 0;
 	void *end = Data + DataSize;
@@ -162,16 +192,7 @@ static MokListNode *build_mok_list(UINT32 num, void *Data, UINTN DataSize) {
 			FreePool(list);
 			return NULL;
 		}
-		if ((CompareGuid (&CertList->SignatureType, &CertType) != 0) &&
-		    (CompareGuid (&CertList->SignatureType, &HashType) != 0)) {
-			dbsize -= CertList->SignatureListSize;
-			CertList = (EFI_SIGNATURE_LIST *)((UINT8 *) CertList +
-						  CertList->SignatureListSize);
-			continue;
-		}
-
-		if ((CompareGuid (&CertList->SignatureType, &HashType) == 0) &&
-		    (CertList->SignatureSize != 48)) {
+		if (!is_valid_siglist(CertList->SignatureType, CertList->SignatureSize)) {
 			dbsize -= CertList->SignatureListSize;
 			CertList = (EFI_SIGNATURE_LIST *)((UINT8 *) CertList +
 						  CertList->SignatureListSize);
@@ -409,22 +430,34 @@ static void show_x509_info (X509 *X509Cert, UINT8 *hash)
 	FreePool(text);
 }
 
-static void show_sha256_digest (UINT8 *hash)
+static void show_sha_digest (EFI_GUID Type, UINT8 *hash)
 {
+	EFI_GUID Sha1 = EFI_CERT_SHA1_GUID;
+	EFI_GUID Sha256 = EFI_CERT_SHA256_GUID;
 	CHAR16 *text[5];
 	POOL_PRINT hash_string1;
 	POOL_PRINT hash_string2;
 	int i;
+	int length;
+
+	if (CompareGuid(&Type, &Sha1) == 0) {
+		length = SHA1_DIGEST_SIZE;
+		text[0] = L"SHA1 hash";
+	} else if (CompareGuid(&Type, &Sha256) == 0) {
+		length = SHA256_DIGEST_SIZE;
+		text[0] = L"SHA256 hash";
+	} else {
+		return;
+	}
 
 	ZeroMem(&hash_string1, sizeof(hash_string1));
 	ZeroMem(&hash_string2, sizeof(hash_string2));
 
-	text[0] = L"SHA256 hash";
 	text[1] = L"";
 
-	for (i=0; i<16; i++)
+	for (i=0; i<length/2; i++)
 		CatPrint(&hash_string1, L"%02x ", hash[i]);
-	for (i=16; i<32; i++)
+	for (i=length/2; i<length; i++)
 		CatPrint(&hash_string2, L"%02x ", hash[i]);
 
 	text[2] = hash_string1.str;
@@ -440,7 +473,7 @@ static void show_sha256_digest (UINT8 *hash)
 		FreePool(hash_string2.str);
 }
 
-static void show_efi_hash (void *Mok, UINTN MokSize)
+static void show_efi_hash (EFI_GUID Type, void *Mok, UINTN MokSize)
 {
 	UINTN sig_size;
 	UINTN hash_num;
@@ -449,7 +482,7 @@ static void show_efi_hash (void *Mok, UINTN MokSize)
 	int key_num = 0;
 	int i;
 
-	sig_size = SHA256_DIGEST_SIZE + sizeof(EFI_GUID);
+	sig_size = sha_size(Type) + sizeof(EFI_GUID);
 	if ((MokSize % sig_size) != 0) {
 		console_errorbox(L"Corrupted Hash List");
 		return;
@@ -458,7 +491,7 @@ static void show_efi_hash (void *Mok, UINTN MokSize)
 
 	if (hash_num == 1) {
 		hash = (UINT8 *)Mok + sizeof(EFI_GUID);
-		show_sha256_digest(hash);
+		show_sha_digest(Type, hash);
 		return;
 	}
 
@@ -481,7 +514,7 @@ static void show_efi_hash (void *Mok, UINTN MokSize)
 			break;
 
 		hash = (UINT8 *)Mok + sig_size*key_num + sizeof(EFI_GUID);
-		show_sha256_digest(hash);
+		show_sha_digest(Type, hash);
 	}
 
 	for (i=0; menu_strings[i] != NULL; i++)
@@ -496,7 +529,6 @@ static void show_mok_info (EFI_GUID Type, void *Mok, UINTN MokSize)
 	UINT8 hash[SHA1_DIGEST_SIZE];
 	X509 *X509Cert;
 	EFI_GUID CertType = X509_GUID;
-	EFI_GUID HashType = EFI_CERT_SHA256_GUID;
 
 	if (!Mok || MokSize == 0)
 		return;
@@ -517,8 +549,8 @@ static void show_mok_info (EFI_GUID Type, void *Mok, UINTN MokSize)
 			console_notify(L"Not a valid X509 certificate");
 			return;
 		}
-	} else if (CompareGuid (&Type, &HashType) == 0) {
-		show_efi_hash(Mok, MokSize);
+	} else if (is_sha_hash(Type)) {
+		show_efi_hash(Type, Mok, MokSize);
 	}
 }
 
@@ -1005,7 +1037,7 @@ static EFI_STATUS write_back_mok_list (MokListNode *list, INTN key_num,
 		} else {
 			CertList->SignatureListSize = list[i].MokSize +
 						      sizeof(EFI_SIGNATURE_LIST);
-			CertList->SignatureSize = SHA256_DIGEST_SIZE + sizeof(EFI_GUID);
+			CertList->SignatureSize = sha_size(list[i].Type) + sizeof(EFI_GUID);
 
 			CopyMem(CertData, list[i].Mok, list[i].MokSize);
 		}
@@ -1077,7 +1109,6 @@ static void mem_move (void *dest, void *src, UINTN size)
 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;
 	UINT32 list_num;
 	int i, del_ind;
@@ -1087,8 +1118,7 @@ static void delete_hash_in_list (UINT8 *hash, UINT32 hash_size,
 	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))
+		if (!is_sha_hash(mok[i].Type) || (mok[i].MokSize < sig_size))
 			continue;
 
 		list_num = mok[i].MokSize / sig_size;
@@ -1117,7 +1147,7 @@ static void delete_hash_in_list (UINT8 *hash, UINT32 hash_size,
 	}
 }
 
-static void delete_hash_list (void *hash_list, UINT32 list_size,
+static void delete_hash_list (EFI_GUID Type, void *hash_list, UINT32 list_size,
 			      MokListNode *mok, INTN mok_num)
 {
 	UINT32 hash_size;
@@ -1126,7 +1156,7 @@ static void delete_hash_list (void *hash_list, UINT32 list_size,
 	UINT8 *hash;
 	int i;
 
-	hash_size = SHA256_DIGEST_SIZE;
+	hash_size = sha_size (Type);
 	sig_size = hash_size + sizeof(EFI_GUID);
 	if (list_size < sig_size)
 		return;
@@ -1145,7 +1175,6 @@ 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;
@@ -1220,9 +1249,9 @@ static EFI_STATUS delete_keys (void *MokDel, UINTN MokDelSize, BOOLEAN MokX)
 		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);
+		} else if (is_sha_hash(del_key[i].Type)) {
+			delete_hash_list(del_key[i].Type, del_key[i].Mok,
+					 del_key[i].MokSize, mok, mok_num);
 		}
 	}
 
-- 
1.8.4.5


From 66098cc304ae505d20dc6b6cbdcf8861cd11a9fc Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Wed, 9 Apr 2014 16:49:25 +0800
Subject: [PATCH 12/16] MokManager: fix the return value and type

There are some functions that the return value and the type
didn't match.

Signed-off-by: Gary Ching-Pang Lin <glin@suse.com>
---
 MokManager.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/MokManager.c b/MokManager.c
index 4ab54ed..78d831e 100644
--- a/MokManager.c
+++ b/MokManager.c
@@ -565,7 +565,7 @@ static EFI_STATUS list_keys (void *KeyList, UINTN KeyListSize, CHAR16 *title)
 	if (KeyListSize < (sizeof(EFI_SIGNATURE_LIST) +
 			   sizeof(EFI_SIGNATURE_DATA))) {
 		console_notify(L"No MOK keys found");
-		return 0;
+		return EFI_NOT_FOUND;
 	}
 
 	MokNum = count_keys(KeyList, KeyListSize);
@@ -575,7 +575,7 @@ static EFI_STATUS list_keys (void *KeyList, UINTN KeyListSize, CHAR16 *title)
 
 	if (!keys) {
 		console_notify(L"Failed to construct key list");
-		return 0;
+		return EFI_ABORTED;
 	}
 
 	menu_strings = AllocateZeroPool(sizeof(CHAR16 *) * (MokNum + 2));
@@ -900,7 +900,7 @@ 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 INTN mok_enrollment_prompt (void *MokNew, UINTN MokNewSize, int auth,
 				    BOOLEAN MokX)
 {
 	EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
-- 
1.8.4.5


From 3d4fb965556a4a0508d8bc5570203ae210ed9836 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Thu, 10 Apr 2014 14:39:43 +0800
Subject: [PATCH 13/16] MokManager: Add more key list safe checks

Signed-off-by: Gary Ching-Pang Lin <glin@suse.com>
---
 MokManager.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 56 insertions(+), 6 deletions(-)

diff --git a/MokManager.c b/MokManager.c
index 78d831e..1a67a39 100644
--- a/MokManager.c
+++ b/MokManager.c
@@ -154,6 +154,12 @@ static UINT32 count_keys(void *Data, UINTN DataSize)
 			return 0;
 		}
 
+		if (CertList->SignatureListSize == 0 ||
+		    CertList->SignatureListSize <= CertList->SignatureSize) {
+			console_errorbox(L"Corrupted signature list");
+			return 0;
+		}
+
 		if (!is_valid_siglist(CertList->SignatureType, CertList->SignatureSize)) {
 			dbsize -= CertList->SignatureListSize;
 			CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList +
@@ -569,12 +575,13 @@ static EFI_STATUS list_keys (void *KeyList, UINTN KeyListSize, CHAR16 *title)
 	}
 
 	MokNum = count_keys(KeyList, KeyListSize);
-	if (MokNum == 0)
-		return 0;
+	if (MokNum == 0) {
+		console_errorbox(L"Invalid key list");
+		return EFI_ABORTED;
+	}
 	keys = build_mok_list(MokNum, KeyList, KeyListSize);
-
 	if (!keys) {
-		console_notify(L"Failed to construct key list");
+		console_errorbox(L"Failed to construct key list");
 		return EFI_ABORTED;
 	}
 
@@ -1221,7 +1228,13 @@ static EFI_STATUS delete_keys (void *MokDel, UINTN MokDelSize, BOOLEAN MokX)
 
 	efi_status = get_variable_attr (db_name, &MokListData, &MokListDataSize,
 				        shim_lock_guid, &attributes);
-	if (attributes & EFI_VARIABLE_RUNTIME_ACCESS) {
+	if (efi_status != EFI_SUCCESS) {
+		if (MokX)
+			console_errorbox(L"Failed to retrieve MokListX");
+		else
+			console_errorbox(L"Failed to retrieve MokList");
+		return EFI_ABORTED;
+	} else if (attributes & EFI_VARIABLE_RUNTIME_ACCESS) {
 		if (MokX) {
 			err_str1 = L"MokListX is compromised!";
 			err_str2 = L"Erase all keys in MokListX!";
@@ -1230,7 +1243,11 @@ static EFI_STATUS delete_keys (void *MokDel, UINTN MokDelSize, BOOLEAN MokX)
 			err_str2 = L"Erase all keys in MokList!";
 		}
 		console_alertbox((CHAR16 *[]){err_str1, err_str2, NULL});
-		LibDeleteVariable(db_name, &shim_lock_guid);
+		uefi_call_wrapper(RT->SetVariable, 5, db_name,
+				  &shim_lock_guid,
+				  EFI_VARIABLE_NON_VOLATILE |
+				  EFI_VARIABLE_BOOTSERVICE_ACCESS,
+				  0, NULL);
 		return EFI_ACCESS_DENIED;
 	}
 
@@ -1240,9 +1257,41 @@ static EFI_STATUS delete_keys (void *MokDel, UINTN MokDelSize, BOOLEAN MokX)
 
 	/* Construct lists */
 	mok_num = count_keys(MokListData, MokListDataSize);
+	if (mok_num == 0) {
+		if (MokX) {
+			err_str1 = L"Failed to construct the key list of MokListX";
+			err_str2 = L"Reset MokListX!";
+		} else {
+			err_str1 = L"Failed to construct the key list of MokList";
+			err_str2 = L"Reset MokList!";
+		}
+		console_alertbox((CHAR16 *[]){err_str1, err_str2, NULL});
+		uefi_call_wrapper(RT->SetVariable, 5, db_name,
+				  &shim_lock_guid,
+				  EFI_VARIABLE_NON_VOLATILE |
+				  EFI_VARIABLE_BOOTSERVICE_ACCESS,
+				  0, NULL);
+		efi_status = EFI_ABORTED;
+		goto error;
+	}
 	mok = build_mok_list(mok_num, MokListData, MokListDataSize);
+	if (!mok) {
+		console_errorbox(L"Failed to construct key list");
+		efi_status = EFI_ABORTED;
+		goto error;
+	}
 	del_num = count_keys(MokDel, MokDelSize);
+	if (del_num == 0) {
+		console_errorbox(L"Invalid key delete list");
+		efi_status = EFI_ABORTED;
+		goto error;
+	}
 	del_key = build_mok_list(del_num, MokDel, MokDelSize);
+	if (!del_key) {
+		console_errorbox(L"Failed to construct key list");
+		efi_status = EFI_ABORTED;
+		goto error;
+	}
 
 	/* Search and destroy */
 	for (i = 0; i < del_num; i++) {
@@ -1257,6 +1306,7 @@ static EFI_STATUS delete_keys (void *MokDel, UINTN MokDelSize, BOOLEAN MokX)
 
 	efi_status = write_back_mok_list(mok, mok_num, MokX);
 
+error:
 	if (MokListData)
 		FreePool(MokListData);
 	if (mok)
-- 
1.8.4.5


From 8d5456736bae63490a528f6ac12f677bc770cf41 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Thu, 10 Apr 2014 15:29:14 +0800
Subject: [PATCH 14/16] MokManager: Support SHA224, SHA384, and SHA512

Signed-off-by: Gary Ching-Pang Lin <glin@suse.com>
---
 MokManager.c | 40 +++++++++++++++++++++++++++++++++++++---
 1 file changed, 37 insertions(+), 3 deletions(-)

diff --git a/MokManager.c b/MokManager.c
index 1a67a39..9607d2f 100644
--- a/MokManager.c
+++ b/MokManager.c
@@ -25,6 +25,9 @@
 #define EFI_VARIABLE_APPEND_WRITE 0x00000040
 
 EFI_GUID SHIM_LOCK_GUID = { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} };
+EFI_GUID EFI_CERT_SHA224_GUID = { 0xb6e5233, 0xa65c, 0x44c9, {0x94, 0x7, 0xd9, 0xab, 0x83, 0xbf, 0xc8, 0xbd} };
+EFI_GUID EFI_CERT_SHA384_GUID = { 0xff3e5307, 0x9fd0, 0x48c9, {0x85, 0xf1, 0x8a, 0xd5, 0x6c, 0x70, 0x1e, 0x1} };
+EFI_GUID EFI_CERT_SHA512_GUID = { 0x93e0fae, 0xa6c4, 0x4f50, {0x9f, 0x1b, 0xd4, 0x1e, 0x2b, 0x89, 0xc1, 0x9a} };
 
 #define CERT_STRING L"Select an X509 certificate to enroll:\n\n"
 #define HASH_STRING L"Select a file to trust:\n\n"
@@ -96,12 +99,21 @@ done:
 static BOOLEAN is_sha_hash (EFI_GUID Type)
 {
 	EFI_GUID Sha1 = EFI_CERT_SHA1_GUID;
+	EFI_GUID Sha224 = EFI_CERT_SHA224_GUID;
 	EFI_GUID Sha256 = EFI_CERT_SHA256_GUID;
+	EFI_GUID Sha384 = EFI_CERT_SHA384_GUID;
+	EFI_GUID Sha512 = EFI_CERT_SHA512_GUID;
 
 	if (CompareGuid(&Type, &Sha1) == 0)
 		return TRUE;
+	else if (CompareGuid(&Type, &Sha224) == 0)
+		return TRUE;
 	else if (CompareGuid(&Type, &Sha256) == 0)
 		return TRUE;
+	else if (CompareGuid(&Type, &Sha384) == 0)
+		return TRUE;
+	else if (CompareGuid(&Type, &Sha512) == 0)
+		return TRUE;
 
 	return FALSE;
 }
@@ -109,12 +121,21 @@ static BOOLEAN is_sha_hash (EFI_GUID Type)
 static UINT32 sha_size (EFI_GUID Type)
 {
 	EFI_GUID Sha1 = EFI_CERT_SHA1_GUID;
+	EFI_GUID Sha224 = EFI_CERT_SHA224_GUID;
 	EFI_GUID Sha256 = EFI_CERT_SHA256_GUID;
+	EFI_GUID Sha384 = EFI_CERT_SHA384_GUID;
+	EFI_GUID Sha512 = EFI_CERT_SHA512_GUID;
 
 	if (CompareGuid(&Type, &Sha1) == 0)
 		return SHA1_DIGEST_SIZE;
+	else if (CompareGuid(&Type, &Sha224) == 0)
+		return SHA224_DIGEST_LENGTH;
 	else if (CompareGuid(&Type, &Sha256) == 0)
 		return SHA256_DIGEST_SIZE;
+	else if (CompareGuid(&Type, &Sha384) == 0)
+		return SHA384_DIGEST_LENGTH;
+	else if (CompareGuid(&Type, &Sha512) == 0)
+		return SHA512_DIGEST_LENGTH;
 
 	return 0;
 }
@@ -439,7 +460,10 @@ static void show_x509_info (X509 *X509Cert, UINT8 *hash)
 static void show_sha_digest (EFI_GUID Type, UINT8 *hash)
 {
 	EFI_GUID Sha1 = EFI_CERT_SHA1_GUID;
+	EFI_GUID Sha224 = EFI_CERT_SHA224_GUID;
 	EFI_GUID Sha256 = EFI_CERT_SHA256_GUID;
+	EFI_GUID Sha384 = EFI_CERT_SHA384_GUID;
+	EFI_GUID Sha512 = EFI_CERT_SHA512_GUID;
 	CHAR16 *text[5];
 	POOL_PRINT hash_string1;
 	POOL_PRINT hash_string2;
@@ -449,9 +473,18 @@ static void show_sha_digest (EFI_GUID Type, UINT8 *hash)
 	if (CompareGuid(&Type, &Sha1) == 0) {
 		length = SHA1_DIGEST_SIZE;
 		text[0] = L"SHA1 hash";
+	} else if (CompareGuid(&Type, &Sha224) == 0) {
+		length = SHA224_DIGEST_LENGTH;
+		text[0] = L"SHA224 hash";
 	} else if (CompareGuid(&Type, &Sha256) == 0) {
 		length = SHA256_DIGEST_SIZE;
 		text[0] = L"SHA256 hash";
+	} else if (CompareGuid(&Type, &Sha384) == 0) {
+		length = SHA384_DIGEST_LENGTH;
+		text[0] = L"SHA384 hash";
+	} else if (CompareGuid(&Type, &Sha512) == 0) {
+		length = SHA512_DIGEST_LENGTH;
+		text[0] = L"SHA512 hash";
 	} else {
 		return;
 	}
@@ -1113,7 +1146,7 @@ static void mem_move (void *dest, void *src, UINTN size)
 		d[i] = s[i];
 }
 
-static void delete_hash_in_list (UINT8 *hash, UINT32 hash_size,
+static void delete_hash_in_list (EFI_GUID Type, UINT8 *hash, UINT32 hash_size,
 				 MokListNode *mok, INTN mok_num)
 {
 	UINT32 sig_size;
@@ -1125,7 +1158,8 @@ static void delete_hash_in_list (UINT8 *hash, UINT32 hash_size,
 	sig_size = hash_size + sizeof(EFI_GUID);
 
 	for (i = 0; i < mok_num; i++) {
-		if (!is_sha_hash(mok[i].Type) || (mok[i].MokSize < sig_size))
+		if ((CompareGuid(&(mok[i].Type), &Type) != 0) ||
+		    (mok[i].MokSize < sig_size))
 			continue;
 
 		list_num = mok[i].MokSize / sig_size;
@@ -1173,7 +1207,7 @@ static void delete_hash_list (EFI_GUID Type, void *hash_list, UINT32 list_size,
 	hash = hash_list + sizeof(EFI_GUID);
 
 	for (i = 0; i < hash_num; i++) {
-		delete_hash_in_list (hash, hash_size, mok, mok_num);
+		delete_hash_in_list (Type, hash, hash_size, mok, mok_num);
 		hash += sig_size;
 	}
 }
-- 
1.8.4.5


From 2d0e330fb06a7d26810f86dcfdb59b045d444b51 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Thu, 10 Apr 2014 15:55:35 +0800
Subject: [PATCH 15/16] MokManager: Discard the list contains an invalid
 signature

Signed-off-by: Gary Ching-Pang Lin <glin@suse.com>
---
 MokManager.c | 15 +++++----------
 1 file changed, 5 insertions(+), 10 deletions(-)

diff --git a/MokManager.c b/MokManager.c
index 9607d2f..046f779 100644
--- a/MokManager.c
+++ b/MokManager.c
@@ -182,10 +182,8 @@ static UINT32 count_keys(void *Data, UINTN DataSize)
 		}
 
 		if (!is_valid_siglist(CertList->SignatureType, CertList->SignatureSize)) {
-			dbsize -= CertList->SignatureListSize;
-			CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList +
-						  CertList->SignatureListSize);
-			continue;
+			console_errorbox(L"Invalid signature list found");
+			return 0;
 		}
 
 		MokNum++;
@@ -219,12 +217,9 @@ static MokListNode *build_mok_list(UINT32 num, void *Data, UINTN DataSize) {
 			FreePool(list);
 			return NULL;
 		}
-		if (!is_valid_siglist(CertList->SignatureType, CertList->SignatureSize)) {
-			dbsize -= CertList->SignatureListSize;
-			CertList = (EFI_SIGNATURE_LIST *)((UINT8 *) CertList +
-						  CertList->SignatureListSize);
-			continue;
-		}
+
+		/* Omit the signature check here since we already did it
+		   in count_keys() */
 
 		Cert = (EFI_SIGNATURE_DATA *) (((UINT8 *) CertList) +
 		  sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
-- 
1.8.4.5


From 658c3ac8ea38ac057f21278c9d10ba8aae28b0a5 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Tue, 28 Oct 2014 11:21:51 +0800
Subject: [PATCH 16/16] MokManager: fix comparison between signed and unsigned
 integer

Patch from Johannes Segitz <jsegitz@suse.com>
---
 MokManager.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/MokManager.c b/MokManager.c
index 046f779..442ab8f 100644
--- a/MokManager.c
+++ b/MokManager.c
@@ -513,8 +513,8 @@ static void show_efi_hash (EFI_GUID Type, void *Mok, UINTN MokSize)
 	UINTN hash_num;
 	UINT8 *hash;
 	CHAR16 **menu_strings;
-	int key_num = 0;
-	int i;
+	UINTN key_num = 0;
+	UINTN i;
 
 	sig_size = sha_size(Type) + sizeof(EFI_GUID);
 	if ((MokSize % sig_size) != 0) {
@@ -592,7 +592,7 @@ static EFI_STATUS list_keys (void *KeyList, UINTN KeyListSize, CHAR16 *title)
 {
 	INTN MokNum = 0;
 	MokListNode *keys = NULL;
-	int key_num = 0;
+	UINT32 key_num = 0;
 	CHAR16 **menu_strings;
 	int i;
 
@@ -1118,7 +1118,7 @@ static int match_hash (UINT8 *hash, UINT32 hash_size, int start,
 		       void *hash_list, UINT32 list_num)
 {
 	UINT8 *ptr;
-	int i;
+	UINTN i;
 
 	ptr = hash_list + sizeof(EFI_GUID);
 	for (i = start; i < list_num; i++) {
@@ -1133,7 +1133,7 @@ static int match_hash (UINT8 *hash, UINT32 hash_size, int start,
 static void mem_move (void *dest, void *src, UINTN size)
 {
 	UINT8 *d, *s;
-	int i;
+	UINTN i;
 
 	d = (UINT8 *)dest;
 	s = (UINT8 *)src;
@@ -1190,7 +1190,7 @@ static void delete_hash_list (EFI_GUID Type, void *hash_list, UINT32 list_size,
 	UINT32 hash_num;
 	UINT32 sig_size;
 	UINT8 *hash;
-	int i;
+	UINT32 i;
 
 	hash_size = sha_size (Type);
 	sig_size = hash_size + sizeof(EFI_GUID);
-- 
1.8.4.5

openSUSE Build Service is sponsored by