summaryrefslogtreecommitdiff
path: root/MokManager.c
diff options
context:
space:
mode:
authorGary Ching-Pang Lin <glin@suse.com>2012-09-24 15:48:01 +0800
committerGary Ching-Pang Lin <glin@suse.com>2012-09-24 15:48:01 +0800
commit215e462b10134c421a8c1d041a420feec1e0a1cf (patch)
treef17ba423c276c18da5d90082c133ac249decffb6 /MokManager.c
parent5d328c6c4545bddd789e136be63d12beed0cd6af (diff)
downloadefi-boot-shim-215e462b10134c421a8c1d041a420feec1e0a1cf.tar.gz
efi-boot-shim-215e462b10134c421a8c1d041a420feec1e0a1cf.zip
Request a password to verify the key list
The password must contain 8 characters at least and 16 characters at most and will be hashed with the key list altogether. The keys in MokNew won't be allowed to be enrolled unless the user provides the correct password.
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;
}