summaryrefslogtreecommitdiff
path: root/MokManager.c
diff options
context:
space:
mode:
Diffstat (limited to 'MokManager.c')
-rw-r--r--MokManager.c135
1 files changed, 135 insertions, 0 deletions
diff --git a/MokManager.c b/MokManager.c
index ea2a94ec..ce577465 100644
--- a/MokManager.c
+++ b/MokManager.c
@@ -466,10 +466,144 @@ static UINT8 mok_deletion_prompt () {
return 0;
}
+static UINT8 get_password (UINT32 *length, CHAR16 *password)
+{
+ EFI_INPUT_KEY key;
+ CHAR16 input[16];
+ int count = 0;
+
+ do {
+ key = get_keystroke();
+
+ if ((count >= 16 && key.UnicodeChar != CHAR_BACKSPACE) ||
+ key.UnicodeChar == CHAR_NULL ||
+ key.UnicodeChar == CHAR_TAB ||
+ key.UnicodeChar == CHAR_LINEFEED) {
+ continue;
+ }
+
+ if (count == 0 && key.UnicodeChar == CHAR_BACKSPACE) {
+ continue;
+ } else if (key.UnicodeChar == CHAR_BACKSPACE) {
+ Print(L"%c", CHAR_BACKSPACE);
+ input[--count] = '\0';
+ continue;
+ }
+
+ input[count++] = key.UnicodeChar;
+ } while (key.UnicodeChar != CHAR_CARRIAGE_RETURN);
+ Print(L"\n");
+
+ *length = count;
+ CopyMem(password, input, count * sizeof(CHAR16));
+
+ return 1;
+}
+
+static EFI_STATUS compute_pw_hash (void *MokNew, UINTN MokNewSize, CHAR16 *password,
+ UINT32 pw_length, UINT8 *hash)
+{
+ EFI_STATUS status;
+ unsigned int ctxsize;
+ void *ctx = NULL;
+
+ ctxsize = Sha256GetContextSize();
+ ctx = AllocatePool(ctxsize);
+
+ if (!ctx) {
+ Print(L"Unable to allocate memory for hash context\n");
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (!Sha256Init(ctx)) {
+ Print(L"Unable to initialise hash\n");
+ status = EFI_OUT_OF_RESOURCES;
+ goto done;
+ }
+
+ if (!(Sha256Update(ctx, MokNew, MokNewSize))) {
+ Print(L"Unable to generate hash\n");
+ status = EFI_OUT_OF_RESOURCES;
+ goto done;
+ }
+
+ if (!(Sha256Update(ctx, password, pw_length * sizeof(CHAR16)))) {
+ Print(L"Unable to generate hash\n");
+ status = EFI_OUT_OF_RESOURCES;
+ goto done;
+ }
+
+ if (!(Sha256Final(ctx, hash))) {
+ Print(L"Unable to finalise hash\n");
+ status = EFI_OUT_OF_RESOURCES;
+ goto done;
+ }
+
+ status = EFI_SUCCESS;
+done:
+ return status;
+}
+
+static UINT8 compare_hash (UINT8 *hash1, UINT8 *hash2, UINT32 size)
+{
+ int i;
+
+ for (i = 0; i < size; i++) {
+ if (hash1[i] != hash2[i]) {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
static EFI_STATUS store_keys (void *MokNew, UINTN MokNewSize)
{
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[16];
+ UINT32 pw_length;
+ UINT8 fail_count = 0;
+
+ auth_size = SHA256_DIGEST_SIZE;
+ efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokAuth",
+ &shim_lock_guid,
+ &attributes, &auth_size, auth);
+
+
+ if (efi_status != EFI_SUCCESS || auth_size != SHA256_DIGEST_SIZE) {
+ Print(L"Failed to get MokAuth %d\n", efi_status);
+ return efi_status;
+ }
+
+ while (fail_count < 3) {
+ Print(L"Password: ");
+ get_password(&pw_length, password);
+
+ if (pw_length < 8) {
+ Print(L"At 8 characters for the password\n");
+ }
+
+ efi_status = compute_pw_hash(MokNew, MokNewSize, password,
+ pw_length, hash);
+
+ if (efi_status != EFI_SUCCESS) {
+ return efi_status;
+ }
+
+ if (!compare_hash(auth, hash, SHA256_DIGEST_SIZE)) {
+ fail_count++;
+ } else {
+ break;
+ }
+ }
+
+ if (fail_count >= 3)
+ return EFI_ACCESS_DENIED;
/* Write new MOK */
efi_status = uefi_call_wrapper(RT->SetVariable, 5, L"MokList",
@@ -534,6 +668,7 @@ error:
}
FreePool (MokNew);
}
+ delete_variable(L"MokAuth", shim_lock_guid);
return EFI_SUCCESS;
}