From 4895ca3919bce61154b2a6a95c9102b6a1665678 Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Thu, 20 Dec 2012 12:55:59 +0800 Subject: Clear the screen before erasing keys --- MokManager.c | 1 + 1 file changed, 1 insertion(+) (limited to 'MokManager.c') diff --git a/MokManager.c b/MokManager.c index 5802d274..c6f84d88 100644 --- a/MokManager.c +++ b/MokManager.c @@ -675,6 +675,7 @@ static INTN mok_deletion_prompt (void *MokNew, void *data2, void *data3) { UINT32 length; EFI_STATUS efi_status; + uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut); Print(L"Erase all stored keys? (y/N): "); get_line (&length, line, 1, 1); -- cgit v1.2.3 From a64ab2ec6b99ab38e72b7b480e1c3e935bf6921e Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Thu, 27 Dec 2012 11:42:45 +0800 Subject: Reboot the system after enrolling/erasing keys --- MokManager.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'MokManager.c') diff --git a/MokManager.c b/MokManager.c index c6f84d88..7d6650e6 100644 --- a/MokManager.c +++ b/MokManager.c @@ -637,6 +637,7 @@ static EFI_STATUS store_keys (void *MokNew, UINTN MokNewSize, int authenticate) } static UINTN mok_enrollment_prompt (void *MokNew, UINTN MokNewSize, int auth) { + EFI_GUID shim_lock_guid = SHIM_LOCK_GUID; CHAR16 line[1]; UINT32 length; EFI_STATUS efi_status; @@ -657,6 +658,19 @@ static UINTN mok_enrollment_prompt (void *MokNew, UINTN MokNewSize, int auth) { Print(L"Failed to enroll keys\n"); return -1; } + + if (auth) { + LibDeleteVariable(L"MokNew", &shim_lock_guid); + LibDeleteVariable(L"MokAuth", &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; + } + return 0; } } while (line[0] != 'N' && line[0] != 'n'); @@ -671,6 +685,7 @@ static INTN mok_enrollment_prompt_callback (void *MokNew, void *data2, } static INTN mok_deletion_prompt (void *MokNew, void *data2, void *data3) { + EFI_GUID shim_lock_guid = SHIM_LOCK_GUID; CHAR16 line[1]; UINT32 length; EFI_STATUS efi_status; @@ -687,6 +702,16 @@ static INTN mok_deletion_prompt (void *MokNew, void *data2, void *data3) { Print(L"Failed to erase keys\n"); return -1; } + + LibDeleteVariable(L"MokNew", &shim_lock_guid); + LibDeleteVariable(L"MokAuth", &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; } return 0; -- cgit v1.2.3 From 262d671419f1266cbe0e83b7fa3aa85e3b91ddfe Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Thu, 27 Dec 2012 11:42:54 +0800 Subject: Add a general function for password matching --- MokManager.c | 148 +++++++++++++++++++++++------------------------------------ 1 file changed, 57 insertions(+), 91 deletions(-) (limited to 'MokManager.c') diff --git a/MokManager.c b/MokManager.c index 7d6650e6..ffe37ff7 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, -- cgit v1.2.3 From a05c7c57d9a81d0989e478419a54ab9c88f1fb9a Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Thu, 27 Dec 2012 11:42:54 +0800 Subject: MOK doesn't include the signature owner --- MokManager.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'MokManager.c') diff --git a/MokManager.c b/MokManager.c index ffe37ff7..ddf12deb 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); -- cgit v1.2.3 From 92a136d823e211b60656872ee43ade8693057ee1 Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Thu, 3 Jan 2013 12:20:22 +0800 Subject: Add support for deleting specific keys --- MokManager.c | 336 +++++++++++++++++++++++++++++++++++++++++++++++++++-------- shim.c | 3 +- 2 files changed, 293 insertions(+), 46 deletions(-) (limited to 'MokManager.c') diff --git a/MokManager.c b/MokManager.c index ddf12deb..bfcbfd67 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 44301dd1..dcf1c516 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) { -- cgit v1.2.3 From 4a88de5816a7ac416d30dbd66e5117f5d4c2c74d Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Thu, 3 Jan 2013 12:20:30 +0800 Subject: Make sure the menu shows when the callback fails Since Pause() doesn't clear the key from the input queue, the next ReadKeyStroke reads the queued key instead of the new one. If the user presses "Enter", MokManager exits directly without showing the menu again. --- MokManager.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'MokManager.c') diff --git a/MokManager.c b/MokManager.c index bfcbfd67..97588cb6 100644 --- a/MokManager.c +++ b/MokManager.c @@ -1241,6 +1241,9 @@ static void run_menu (CHAR16 *header, UINTN lines, struct menu_item *items, if (ret < 0) { Print(L"Press a key to continue\n"); Pause(); + /* Clear the key in the queue */ + uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, + ST->ConIn, &key); } draw_menu (header, lines, items, count); pos = 0; -- cgit v1.2.3