File shim-support-mok-delete.patch of Package shim

From 5abe73ab8177f0d831ff04ca67a8ed92ef09ca8b Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Thu, 20 Dec 2012 17:02:35 +0800
Subject: [PATCH 1/3] Add a general function for password matching

---
 MokManager.c |  148 ++++++++++++++++++++++------------------------------------
 1 file changed, 57 insertions(+), 91 deletions(-)

diff --git a/MokManager.c b/MokManager.c
index 7d6650e..ffe37ff 100644
--- a/MokManager.c
+++ b/MokManager.c
@@ -558,17 +558,61 @@ done:
 	return status;
 }
 
+static EFI_STATUS match_password (void *Data, UINTN DataSize,
+				  UINT8 auth[SHA256_DIGEST_SIZE],
+				  CHAR16 *prompt)
+{
+	EFI_STATUS efi_status;
+	UINT8 hash[SHA256_DIGEST_SIZE];
+	CHAR16 password[PASSWORD_MAX];
+	UINT32 pw_length;
+	UINT8 fail_count = 0;
+
+	while (fail_count < 3) {
+		if (prompt) {
+			Print(L"%s", prompt);
+		} else {
+			Print(L"Password: ");
+		}
+		get_line(&pw_length, password, PASSWORD_MAX, 0);
+
+		if (pw_length < PASSWORD_MIN || pw_length > PASSWORD_MAX) {
+			Print(L"Invalid password length\n");
+			fail_count++;
+			continue;
+		}
+
+		efi_status = compute_pw_hash(Data, DataSize, password,
+					     pw_length, hash);
+
+		if (efi_status != EFI_SUCCESS) {
+			Print(L"Unable to generate password hash\n");
+			fail_count++;
+			continue;
+		}
+
+		if (CompareMem(auth, hash, SHA256_DIGEST_SIZE) != 0) {
+			Print(L"Password doesn't match\n");
+			fail_count++;
+			continue;
+		}
+
+		break;
+	}
+
+	if (fail_count >= 3)
+		return EFI_ACCESS_DENIED;
+
+	return EFI_SUCCESS;
+}
+
 static EFI_STATUS store_keys (void *MokNew, UINTN MokNewSize, int authenticate)
 {
 	EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
 	EFI_STATUS efi_status;
-	UINT8 hash[SHA256_DIGEST_SIZE];
 	UINT8 auth[SHA256_DIGEST_SIZE];
 	UINTN auth_size;
 	UINT32 attributes;
-	CHAR16 password[PASSWORD_MAX];
-	UINT32 pw_length;
-	UINT8 fail_count = 0;
 
 	if (authenticate) {
 		auth_size = SHA256_DIGEST_SIZE;
@@ -582,32 +626,8 @@ static EFI_STATUS store_keys (void *MokNew, UINTN MokNewSize, int authenticate)
 			return efi_status;
 		}
 
-		while (fail_count < 3) {
-			Print(L"Password(%d-%d characters): ",
-			      PASSWORD_MIN, PASSWORD_MAX);
-			get_line(&pw_length, password, PASSWORD_MAX, 0);
-
-			if (pw_length < 8) {
-				Print(L"At least %d characters for the password\n",
-				      PASSWORD_MIN);
-			}
-
-			efi_status = compute_pw_hash(MokNew, MokNewSize, password,
-						     pw_length, hash);
-
-			if (efi_status != EFI_SUCCESS) {
-				return efi_status;
-			}
-
-			if (CompareMem(auth, hash, SHA256_DIGEST_SIZE) != 0) {
-				Print(L"Password doesn't match\n");
-				fail_count++;
-			} else {
-				break;
-			}
-		}
-
-		if (fail_count >= 3)
+		efi_status = match_password(MokNew, MokNewSize, auth, NULL);
+		if (efi_status != EFI_SUCCESS)
 			return EFI_ACCESS_DENIED;
 	}
 
@@ -819,9 +839,7 @@ static INTN mok_pw_prompt (void *MokPW, void *data2, void *data3) {
 	EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
 	EFI_STATUS efi_status;
 	UINTN MokPWSize = (UINTN)data2;
-	UINT8 fail_count = 0;
 	UINT8 hash[SHA256_DIGEST_SIZE];
-	CHAR16 password[PASSWORD_MAX];
 	UINT32 length;
 	CHAR16 line[1];
 
@@ -849,34 +867,8 @@ static INTN mok_pw_prompt (void *MokPW, void *data2, void *data3) {
 		return 0;
 	}
 
-	while (fail_count < 3) {
-		Print(L"Confirm MOK passphrase: ");
-		get_line(&length, password, PASSWORD_MAX, 0);
-
-		if ((length < PASSWORD_MIN) || (length > PASSWORD_MAX)) {
-			Print(L"Invalid password length\n");
-			fail_count++;
-			continue;
-		}
-
-		efi_status = compute_pw_hash(NULL, 0, password, length, hash);
-
-		if (efi_status != EFI_SUCCESS) {
-			Print(L"Unable to generate password hash\n");
-			fail_count++;
-			continue;
-		}
-
-		if (CompareMem(MokPW, hash, SHA256_DIGEST_SIZE) != 0) {
-			Print(L"Password doesn't match\n");
-			fail_count++;
-			continue;
-		}
-
-		break;
-	}
-
-	if (fail_count >= 3) {
+	efi_status = match_password(NULL, 0, MokPW, L"Confirm MOK passphrase: ");
+	if (efi_status != EFI_SUCCESS) {
 		Print(L"Password limit reached\n");
 		return -1;
 	}
@@ -1483,12 +1475,8 @@ static BOOLEAN verify_pw(void)
 {
 	EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
 	EFI_STATUS efi_status;
-	CHAR16 password[PASSWORD_MAX];
-	UINT8 fail_count = 0;
-	UINT8 hash[SHA256_DIGEST_SIZE];
 	UINT8 pwhash[SHA256_DIGEST_SIZE];
 	UINTN size = SHA256_DIGEST_SIZE;
-	UINT32 length;
 	UINT32 attributes;
 
 	efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokPWStore",
@@ -1508,35 +1496,13 @@ static BOOLEAN verify_pw(void)
 
 	uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
 
-	while (fail_count < 3) {
-		Print(L"Enter MOK password: ");
-		get_line(&length, password, PASSWORD_MAX, 0);
-
-		if (length < PASSWORD_MIN || length > PASSWORD_MAX) {
-			Print(L"Invalid password length\n");
-			fail_count++;
-			continue;
-		}
-
-		efi_status = compute_pw_hash(NULL, 0, password, length, hash);
-
-		if (efi_status != EFI_SUCCESS) {
-			Print(L"Unable to generate password hash\n");
-			fail_count++;
-			continue;
-		}
-
-		if (CompareMem(pwhash, hash, SHA256_DIGEST_SIZE) != 0) {
-			Print(L"Password doesn't match\n");
-			fail_count++;
-			continue;
-		}
-
-		return TRUE;
+	efi_status = match_password(NULL, 0, pwhash, L"Enter MOK password: ");
+	if (efi_status != EFI_SUCCESS) {
+		Print(L"Password limit reached\n");
+		return FALSE;
 	}
 
-	Print(L"Password limit reached\n");
-	return FALSE;
+	return TRUE;
 }
 
 static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle, void *MokNew,
-- 
1.7.10.4


From 0c6a8a7501f2eb4e751c33090c6763044d131b96 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Fri, 21 Dec 2012 15:02:09 +0800
Subject: [PATCH 2/3] MOK doesn't include the signature owner

---
 MokManager.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/MokManager.c b/MokManager.c
index ffe37ff..ddf12de 100644
--- a/MokManager.c
+++ b/MokManager.c
@@ -124,7 +124,7 @@ 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;
+		list[count].MokSize = CertList->SignatureSize - sizeof(EFI_GUID);
 		list[count].Mok = (void *)Cert->SignatureData;
 
 		count++;
@@ -317,7 +317,7 @@ static void show_mok_info (void *Mok, UINTN MokSize)
 	if (!Mok || MokSize == 0)
 		return;
 
-	if (MokSize != 48) {
+	if (MokSize != SHA256_DIGEST_SIZE) {
 		if (X509ConstructCertificate(Mok, MokSize,
 				 (UINT8 **) &X509Cert) && X509Cert != NULL) {
 			show_x509_info(X509Cert);
-- 
1.7.10.4


From 990dcdb6a6cea2a22ef237b68630aa30784184c4 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Fri, 21 Dec 2012 17:59:31 +0800
Subject: [PATCH 3/3] Add support for deleting specific keys

---
 MokManager.c |  336 ++++++++++++++++++++++++++++++++++++++++++++++++++--------
 shim.c       |    3 +-
 2 files changed, 293 insertions(+), 46 deletions(-)

diff --git a/MokManager.c b/MokManager.c
index ddf12de..bfcbfd6 100644
--- a/MokManager.c
+++ b/MokManager.c
@@ -31,6 +31,7 @@ struct menu_item {
 typedef struct {
 	UINT32 MokSize;
 	UINT8 *Mok;
+	EFI_GUID Type;
 } __attribute__ ((packed)) MokListNode;
 
 typedef struct {
@@ -39,6 +40,32 @@ typedef struct {
 	CHAR16 Password[PASSWORD_MAX];
 } __attribute__ ((packed)) MokSBvar;
 
+static EFI_STATUS get_variable (CHAR16 *name, EFI_GUID guid, UINT32 *attributes,
+				UINTN *size, void **buffer)
+{
+	EFI_STATUS efi_status;
+	char allocate = !(*size);
+
+	efi_status = uefi_call_wrapper(RT->GetVariable, 5, name, &guid,
+				       attributes, size, buffer);
+
+	if (efi_status != EFI_BUFFER_TOO_SMALL || !allocate) {
+		return efi_status;
+	}
+
+	*buffer = AllocatePool(*size);
+
+	if (!*buffer) {
+		Print(L"Unable to allocate variable buffer\n");
+		return EFI_OUT_OF_RESOURCES;
+	}
+
+	efi_status = uefi_call_wrapper(RT->GetVariable, 5, name, &guid,
+				       attributes, size, *buffer);
+
+	return efi_status;
+}
+
 static EFI_INPUT_KEY get_keystroke (void)
 {
 	EFI_INPUT_KEY key;
@@ -88,6 +115,42 @@ done:
 	return status;
 }
 
+static UINT32 count_keys(void *Data, UINTN DataSize)
+{
+	EFI_SIGNATURE_LIST *CertList = Data;
+	EFI_GUID CertType = EfiCertX509Guid;
+	EFI_GUID HashType = EfiHashSha256Guid;
+	UINTN dbsize = DataSize;
+	UINT32 MokNum = 0;
+
+	while ((dbsize > 0) && (dbsize >= CertList->SignatureListSize)) {
+		if ((CompareGuid (&CertList->SignatureType, &CertType) != 0) &&
+		    (CompareGuid (&CertList->SignatureType, &HashType) != 0)) {
+			Print(L"Doesn't look like a key or hash\n");
+			dbsize -= CertList->SignatureListSize;
+			CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList +
+						  CertList->SignatureListSize);
+			continue;
+		}
+
+		if ((CompareGuid (&CertList->SignatureType, &CertType) != 0) &&
+		    (CertList->SignatureSize != 48)) {
+			Print(L"Doesn't look like a valid hash\n");
+			dbsize -= CertList->SignatureListSize;
+			CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList +
+						  CertList->SignatureListSize);
+			continue;
+		}
+
+		MokNum++;
+		dbsize -= CertList->SignatureListSize;
+		CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList +
+						  CertList->SignatureListSize);
+	}
+
+	return MokNum;
+}
+
 static MokListNode *build_mok_list(UINT32 num, void *Data, UINTN DataSize) {
 	MokListNode *list;
 	EFI_SIGNATURE_LIST *CertList = Data;
@@ -126,6 +189,7 @@ static MokListNode *build_mok_list(UINT32 num, void *Data, UINTN DataSize) {
 
 		list[count].MokSize = CertList->SignatureSize - sizeof(EFI_GUID);
 		list[count].Mok = (void *)Cert->SignatureData;
+		list[count].Type = CertList->SignatureType;
 
 		count++;
 		dbsize -= CertList->SignatureListSize;
@@ -391,61 +455,35 @@ static INTN get_number ()
 	return (INTN)Atoi(input);
 }
 
-static UINT8 list_keys (void *MokNew, UINTN MokNewSize)
+static UINT8 list_keys (void *KeyList, UINTN KeyListSize, CHAR16 *title)
 {
 	UINT32 MokNum = 0;
 	MokListNode *keys = NULL;
 	INTN key_num = 0;
 	UINT8 initial = 1;
-	EFI_SIGNATURE_LIST *CertList = MokNew;
-	EFI_GUID CertType = EfiCertX509Guid;
-	EFI_GUID HashType = EfiHashSha256Guid;
-	UINTN dbsize = MokNewSize;
 
-	if (MokNewSize < (sizeof(EFI_SIGNATURE_LIST) +
-			  sizeof(EFI_SIGNATURE_DATA))) {
+	if (KeyListSize < (sizeof(EFI_SIGNATURE_LIST) +
+			   sizeof(EFI_SIGNATURE_DATA))) {
 		Print(L"No keys\n");
 		Pause();
 		return 0;
 	}
 
-	while ((dbsize > 0) && (dbsize >= CertList->SignatureListSize)) {
-		if ((CompareGuid (&CertList->SignatureType, &CertType) != 0) &&
-		    (CompareGuid (&CertList->SignatureType, &HashType) != 0)) {
-			Print(L"Doesn't look like a key or hash\n");
-			dbsize -= CertList->SignatureListSize;
-			CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList +
-						  CertList->SignatureListSize);
-			continue;
-		}
-
-		if ((CompareGuid (&CertList->SignatureType, &CertType) != 0) &&
-		    (CertList->SignatureSize != 48)) {
-			Print(L"Doesn't look like a valid hash\n");
-			dbsize -= CertList->SignatureListSize;
-			CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList +
-						  CertList->SignatureListSize);
-			continue;
-		}
-
-		MokNum++;
-		dbsize -= CertList->SignatureListSize;
-		CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList +
-						  CertList->SignatureListSize);
-	}
-
-	keys = build_mok_list(MokNum, MokNew, MokNewSize);
+	MokNum = count_keys(KeyList, KeyListSize);
+	keys = build_mok_list(MokNum, KeyList, KeyListSize);
 
 	if (!keys) {
-		Print(L"Failed to construct key list in MokNew\n");
+		Print(L"Failed to construct key list\n");
 		return 0;
 	}
 
 	do {
 		uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
+		if (title)
+			Print(L"%s\n", title);
 		Print(L"Input the key number to show the details of the key or\n"
 		      L"type \'0\' to continue\n\n");
-		Print(L"%d key(s) in the new key list\n\n", MokNum);
+		Print(L"%d key(s) in the key list\n\n", MokNum);
 
 		if (key_num > MokNum) {
 			Print(L"[Key %d]\n", key_num);
@@ -663,7 +701,7 @@ static UINTN mok_enrollment_prompt (void *MokNew, UINTN MokNewSize, int auth) {
 	EFI_STATUS efi_status;
 
 	do {
-		if (!list_keys(MokNew, MokNewSize)) {
+		if (!list_keys(MokNew, MokNewSize, L"[Enroll MOK]")) {
 			return 0;
 		}
 
@@ -704,7 +742,8 @@ static INTN mok_enrollment_prompt_callback (void *MokNew, void *data2,
 	return mok_enrollment_prompt(MokNew, (UINTN)data2, TRUE);
 }
 
-static INTN mok_deletion_prompt (void *MokNew, void *data2, void *data3) {
+static INTN mok_reset_prompt (void *MokNew, void *data2, void *data3)
+{
 	EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
 	CHAR16 line[1];
 	UINT32 length;
@@ -737,6 +776,180 @@ static INTN mok_deletion_prompt (void *MokNew, void *data2, void *data3) {
 	return 0;
 }
 
+static EFI_STATUS write_back_mok_list (MokListNode *list, INTN key_num)
+{
+	EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+	EFI_STATUS efi_status;
+	EFI_SIGNATURE_LIST *CertList;
+	EFI_SIGNATURE_DATA *CertData;
+	void *Data = NULL, *ptr;
+	INTN DataSize = 0;
+	int i;
+
+	for (i = 0; i < key_num; i++) {
+		if (list[i].Mok == NULL)
+			continue;
+
+		DataSize += sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_GUID);
+		DataSize += list[i].MokSize;
+	}
+
+	Data = AllocatePool(DataSize);
+	if (Data == NULL && DataSize != 0)
+		return EFI_OUT_OF_RESOURCES;
+
+	ptr = Data;
+
+	for (i = 0; i < key_num; i++) {
+		if (list[i].Mok == NULL)
+			continue;
+
+		CertList = (EFI_SIGNATURE_LIST *)ptr;
+		CertData = (EFI_SIGNATURE_DATA *)(((uint8_t *)ptr) +
+			   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);
+
+		ptr = (uint8_t *)ptr + sizeof(EFI_SIGNATURE_LIST) +
+		      sizeof(EFI_GUID) + list[i].MokSize;
+	}
+
+	efi_status = uefi_call_wrapper(RT->SetVariable, 5, L"MokList",
+				       &shim_lock_guid,
+				       EFI_VARIABLE_NON_VOLATILE
+				       | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+				       DataSize, Data);
+	if (Data)
+		FreePool(Data);
+
+	if (efi_status != EFI_SUCCESS) {
+		Print(L"Failed to set variable %d\n", efi_status);
+		return efi_status;
+	}
+
+	return EFI_SUCCESS;
+}
+
+static EFI_STATUS delete_keys (void *MokDel, UINTN MokDelSize)
+{
+	EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+	EFI_STATUS efi_status;
+	UINT8 auth[SHA256_DIGEST_SIZE];
+	UINTN auth_size = SHA256_DIGEST_SIZE;
+	UINT32 attributes;
+	void *MokListData = NULL;
+	UINTN MokListDataSize = 0;
+	MokListNode *mok, *del_key;
+	INTN mok_num, del_num;
+	int i, j;
+
+	efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokDelAuth",
+				       &shim_lock_guid,
+				       &attributes, &auth_size, auth);
+
+	if (efi_status != EFI_SUCCESS || auth_size != SHA256_DIGEST_SIZE) {
+		Print(L"Failed to get MokDelAuth %d\n", efi_status);
+		return efi_status;
+	}
+
+	efi_status = match_password(MokDel, MokDelSize, auth, NULL);
+	if (efi_status != EFI_SUCCESS)
+		return EFI_ACCESS_DENIED;
+
+	efi_status = get_variable(L"MokList", shim_lock_guid, &attributes,
+				  &MokListDataSize, &MokListData);
+
+	if (attributes & EFI_VARIABLE_RUNTIME_ACCESS) {
+		Print(L"MokList is compromised!\nErase all keys in MokList!\n");
+		if (LibDeleteVariable(L"MokList", &shim_lock_guid) != EFI_SUCCESS) {
+			Print(L"Failed to erase MokList\n");
+		}
+		return EFI_ACCESS_DENIED;
+	}
+
+	/* Nothing to do */
+	if (!MokListData || MokListDataSize == 0)
+		return EFI_SUCCESS;
+
+	/* Construct lists */
+	mok_num = count_keys(MokListData, MokListDataSize);
+	mok = build_mok_list(mok_num, MokListData, MokListDataSize);
+	del_num = count_keys(MokDel, MokDelSize);
+	del_key = build_mok_list(del_num, MokDel, MokDelSize);
+
+	/* 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;
+			}
+		}
+	}
+
+	efi_status = write_back_mok_list(mok, mok_num);
+
+	if (MokListData)
+		FreePool(MokListData);
+	if (mok)
+		FreePool(mok);
+	if (del_key)
+		FreePool(del_key);
+
+	return efi_status;
+}
+
+static INTN mok_deletion_prompt (void *MokDel, void *data2, void *data3)
+{
+	EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+	UINTN MokDelSize = (UINTN)data2;
+	CHAR16 line[1];
+	UINT32 length;
+	EFI_STATUS efi_status;
+
+	do {
+		if (!list_keys(MokDel, MokDelSize, L"[Delete MOK]")) {
+			return 0;
+		}
+
+		Print(L"Delete the key(s)? (y/n): ");
+
+		get_line (&length, line, 1, 1);
+
+		if (line[0] == 'Y' || line[0] == 'y') {
+			efi_status = delete_keys(MokDel, MokDelSize);
+
+			if (efi_status != EFI_SUCCESS) {
+				Print(L"Failed to delete keys\n");
+				return -1;
+			}
+
+			LibDeleteVariable(L"MokDel", &shim_lock_guid);
+			LibDeleteVariable(L"MokDelAuth", &shim_lock_guid);
+
+			Print(L"\nPress a key to reboot system\n");
+			Pause();
+			uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm,
+					  EFI_SUCCESS, 0, NULL);
+			Print(L"Failed to reboot\n");
+			return -1;
+		}
+	} while (line[0] != 'N' && line[0] != 'n');
+	return -1;
+}
+
 static INTN mok_sb_prompt (void *MokSB, void *data2, void *data3) {
 	EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
 	EFI_STATUS efi_status;
@@ -1505,12 +1718,15 @@ static BOOLEAN verify_pw(void)
 	return TRUE;
 }
 
-static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle, void *MokNew,
-				 UINTN MokNewSize, void *MokSB,
-				 UINTN MokSBSize, void *MokPW, UINTN MokPWSize)
+static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle,
+				 void *MokNew, UINTN MokNewSize,
+				 void *MokDel, UINTN MokDelSize,
+				 void *MokSB, UINTN MokSBSize,
+				 void *MokPW, UINTN MokPWSize)
 {
 	struct menu_item *menu_item;
 	UINT32 MokAuth = 0;
+	UINT32 MokDelAuth = 0;
 	UINTN menucount = 3, i = 0;
 	EFI_STATUS efi_status;
 	EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
@@ -1528,9 +1744,19 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle, void *MokNew,
 	if ((efi_status == EFI_SUCCESS) && (auth_size == SHA256_DIGEST_SIZE))
 		MokAuth = 1;
 
+	efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokDelAuth",
+					       &shim_lock_guid,
+					       &attributes, &auth_size, auth);
+
+	if ((efi_status == EFI_SUCCESS) && (auth_size == SHA256_DIGEST_SIZE))
+		MokDelAuth = 1;
+
 	if (MokNew || MokAuth)
 		menucount++;
 
+	if (MokDel || MokDelAuth)
+		menucount++;
+
 	if (MokSB)
 		menucount++;
 
@@ -1550,9 +1776,9 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle, void *MokNew,
 
 	if (MokNew || MokAuth) {
 		if (!MokNew) {
-			menu_item[i].text = StrDuplicate(L"Delete MOK");
+			menu_item[i].text = StrDuplicate(L"Reset MOK");
 			menu_item[i].colour = EFI_WHITE;
-			menu_item[i].callback = mok_deletion_prompt;
+			menu_item[i].callback = mok_reset_prompt;
 		} else {
 			menu_item[i].text = StrDuplicate(L"Enroll MOK");
 			menu_item[i].colour = EFI_WHITE;
@@ -1563,6 +1789,15 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle, void *MokNew,
 		i++;
 	}
 
+	if (MokDel || MokDelAuth) {
+		menu_item[i].text = StrDuplicate(L"Delete MOK");
+		menu_item[i].colour = EFI_WHITE;
+		menu_item[i].data = MokDel;
+		menu_item[i].data2 = (void *)MokDelSize;
+		menu_item[i].callback = mok_deletion_prompt;
+		i++;
+	}
+
 	if (MokSB) {
 		menu_item[i].text = StrDuplicate(L"Change Secure Boot state");
 		menu_item[i].colour = EFI_WHITE;
@@ -1605,19 +1840,22 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle, void *MokNew,
 static EFI_STATUS check_mok_request(EFI_HANDLE image_handle)
 {
 	EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
-	UINTN MokNewSize = 0, MokSBSize = 0, MokPWSize = 0;
+	UINTN MokNewSize = 0, MokDelSize = 0, MokSBSize = 0, MokPWSize = 0;
 	void *MokNew = NULL;
+	void *MokDel = NULL;
 	void *MokSB = NULL;
 	void *MokPW = NULL;
 
 	MokNew = LibGetVariableAndSize(L"MokNew", &shim_lock_guid, &MokNewSize);
 
+	MokDel = LibGetVariableAndSize(L"MokDel", &shim_lock_guid, &MokDelSize);
+
 	MokSB = LibGetVariableAndSize(L"MokSB", &shim_lock_guid, &MokSBSize);
 
 	MokPW = LibGetVariableAndSize(L"MokPW", &shim_lock_guid, &MokPWSize);
 
-	enter_mok_menu(image_handle, MokNew, MokNewSize, MokSB, MokSBSize,
-		       MokPW, MokPWSize);
+	enter_mok_menu(image_handle, MokNew, MokNewSize, MokDel, MokDelSize,
+		       MokSB, MokSBSize, MokPW, MokPWSize);
 
 	if (MokNew) {
 		if (LibDeleteVariable(L"MokNew", &shim_lock_guid) != EFI_SUCCESS) {
@@ -1626,6 +1864,13 @@ static EFI_STATUS check_mok_request(EFI_HANDLE image_handle)
 		FreePool (MokNew);
 	}
 
+	if (MokDel) {
+		if (LibDeleteVariable(L"MokDel", &shim_lock_guid) != EFI_SUCCESS) {
+			Print(L"Failed to delete MokDel\n");
+		}
+		FreePool (MokDel);
+	}
+
 	if (MokSB) {
 		if (LibDeleteVariable(L"MokSB", &shim_lock_guid) != EFI_SUCCESS) {
 			Print(L"Failed to delete MokSB\n");
@@ -1641,6 +1886,7 @@ static EFI_STATUS check_mok_request(EFI_HANDLE image_handle)
 	}
 
 	LibDeleteVariable(L"MokAuth", &shim_lock_guid);
+	LibDeleteVariable(L"MokDelAuth", &shim_lock_guid);
 
 	return EFI_SUCCESS;
 }
diff --git a/shim.c b/shim.c
index 44301dd..dcf1c51 100644
--- a/shim.c
+++ b/shim.c
@@ -1271,7 +1271,8 @@ EFI_STATUS check_mok_request(EFI_HANDLE image_handle)
 	EFI_STATUS efi_status;
 
 	if (check_var(L"MokNew") || check_var(L"MokSB") ||
-	    check_var(L"MokPW") || check_var(L"MokAuth")) {
+	    check_var(L"MokPW") || check_var(L"MokAuth") ||
+	    check_var(L"MokDel")) {
 		efi_status = start_image(image_handle, MOK_MANAGER);
 
 		if (efi_status != EFI_SUCCESS) {
-- 
1.7.10.4

openSUSE Build Service is sponsored by