Accepting request 184039 from home:gary_lin:branches:devel:openSUSE:Factory

- Update to 0.4
- Rebase patches
  + shim-suse-build.patch
  + shim-mokmanager-support-crypt-hash-method.patch
  + shim-bnc804631-fix-broken-bootpath.patch
  + shim-bnc798043-no-doulbe-separators.patch
  + shim-bnc807760-change-pxe-2nd-loader-name.patch
  + shim-bnc808106-correct-certcount.patch 
  + shim-mokmanager-ui-revamp.patch
- Add patches
  + shim-merge-lf-loader-code.patch: merge the Linux Foundation
    loader UI code
  + shim-fix-pointer-casting.patch: fix a casting issue and the
    size of an empty vendor cert
  + shim-fix-simple-file-selector.patch: fix the buffer allocation
    in the simple file selector
- Remove upstreamed patches
  + shim-support-mok-delete.patch
  + shim-reboot-after-changes.patch
  + shim-clear-queued-key.patch
  + shim-local-key-sign-mokmanager.patch
  + shim-get-2nd-stage-loader.patch
  + shim-fix-loadoptions.patch
- Remove unused patch: shim-mokmanager-new-pw-hash.patch and
  shim-keep-unsigned-mokmanager.patch
- Install the vendor certificate to /etc/uefi/certs

OBS-URL: https://build.opensuse.org/request/show/184039
OBS-URL: https://build.opensuse.org/package/show/devel:openSUSE:Factory/shim?expand=0&rev=28
This commit is contained in:
Gary Ching-Pang Lin 2013-07-23 04:44:22 +00:00 committed by Git OBS Bridge
parent e6e545b72a
commit 16ab868efc
22 changed files with 7305 additions and 13138 deletions

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:866b1d73d022baa4874dede94bfd2525954b986db9497e6a8f6f2c7e5fea5852
size 940450

3
shim-0.4.tar.bz2 Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:442c5ea22e50aeea816fc83e4a328e48d9429eefb706fa55de3d7c8b05aea0e7
size 966676

View File

@ -1,17 +1,17 @@
From 5c736550e8f7645f39df6948785ab5cae2201418 Mon Sep 17 00:00:00 2001
From cf7f87688efab2712f41b47eaad32e75ec730653 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Fri, 1 Mar 2013 18:04:06 +0800
Subject: [PATCH] Remove double-separators from the bootpath
---
shim.c | 27 ++++++++++++++++++++-------
shim.c | 27 ++++++++++++++++++++-------
1 file changed, 20 insertions(+), 7 deletions(-)
diff --git a/shim.c b/shim.c
index 690d064..c36b641 100644
index 0622c72..806f065 100644
--- a/shim.c
+++ b/shim.c
@@ -907,7 +907,7 @@ static EFI_STATUS generate_path(EFI_LOADED_IMAGE *li, CHAR16 *ImagePath,
@@ -969,7 +969,7 @@ static EFI_STATUS generate_path(EFI_LOADED_IMAGE *li, CHAR16 *ImagePath,
{
EFI_DEVICE_PATH *devpath;
EFI_HANDLE device;
@ -20,7 +20,7 @@ index 690d064..c36b641 100644
unsigned int pathlen = 0;
EFI_STATUS efi_status = EFI_SUCCESS;
CHAR16 *bootpath;
@@ -927,14 +927,27 @@ static EFI_STATUS generate_path(EFI_LOADED_IMAGE *li, CHAR16 *ImagePath,
@@ -989,14 +989,27 @@ static EFI_STATUS generate_path(EFI_LOADED_IMAGE *li, CHAR16 *ImagePath,
if (bootpath[i] == '/')
bootpath[i] = '\\';
}
@ -55,5 +55,5 @@ index 690d064..c36b641 100644
while (*ImagePath == '\\')
ImagePath++;
--
1.7.10.4
1.8.1.4

View File

@ -1,4 +1,4 @@
From 6b70850baa958b196ec332cf0224ffa9d5a81f5f Mon Sep 17 00:00:00 2001
From bfffac234fabdf8110e8e8c53557d57d61320098 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Thu, 21 Feb 2013 17:49:29 +0800
Subject: [PATCH] Fix the broken bootpath
@ -12,14 +12,14 @@ Subject: [PATCH] Fix the broken bootpath
Based on the patch from Michal Marek <mmarek@suse.com>
---
shim.c | 22 +++++++++++++++++-----
shim.c | 22 +++++++++++++++++-----
1 file changed, 17 insertions(+), 5 deletions(-)
diff --git a/shim.c b/shim.c
index 37a5898..690d064 100644
index 94b9710..0622c72 100644
--- a/shim.c
+++ b/shim.c
@@ -919,15 +919,25 @@ static EFI_STATUS generate_path(EFI_LOADED_IMAGE *li, CHAR16 *ImagePath,
@@ -981,15 +981,25 @@ static EFI_STATUS generate_path(EFI_LOADED_IMAGE *li, CHAR16 *ImagePath,
pathlen = StrLen(bootpath);
@ -50,7 +50,7 @@ index 37a5898..690d064 100644
*PathName = AllocatePool(StrSize(bootpath) + StrSize(ImagePath));
@@ -944,6 +954,8 @@ static EFI_STATUS generate_path(EFI_LOADED_IMAGE *li, CHAR16 *ImagePath,
@@ -1007,6 +1017,8 @@ static EFI_STATUS generate_path(EFI_LOADED_IMAGE *li, CHAR16 *ImagePath,
*grubpath = FileDevicePath(device, *PathName);
error:
@ -60,5 +60,5 @@ index 37a5898..690d064 100644
}
--
1.7.10.4
1.8.1.4

View File

@ -1,11 +1,11 @@
From 8222b5f6dd8ff34368173b86ae6108cb792802a7 Mon Sep 17 00:00:00 2001
From 9cf8c7fefdcfb5930cb96091676a67cc0c0402b9 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Thu, 7 Mar 2013 11:59:44 +0800
Subject: [PATCH] Define the PXE 2nd stage loader in the beginning of the file
Make it easier to change the PXE 2nd stage loader.
---
netboot.c | 12 +++++++-----
netboot.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/netboot.c b/netboot.c
@ -54,5 +54,5 @@ index 90fb9cb..ae723c7 100644
/* Note we don't capture the filename option here because we know its shim.efi
--
1.7.10.4
1.8.1.4

View File

@ -1,17 +1,17 @@
From 822b44b8d978449a43fb2cd7bcd1381d961d0b25 Mon Sep 17 00:00:00 2001
From 37b8af226ea8e3af467944b3b6253218ba13838c Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Fri, 8 Mar 2013 14:44:50 +0800
Subject: [PATCH] Correct the certificate count of the signature list
---
shim.c | 4 ++--
shim.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/shim.c b/shim.c
index c36b641..1daa84b 100644
index 806f065..7219d53 100644
--- a/shim.c
+++ b/shim.c
@@ -228,7 +228,7 @@ static CHECK_STATUS check_db_cert_in_ram(EFI_SIGNATURE_LIST *CertList,
@@ -230,7 +230,7 @@ static CHECK_STATUS check_db_cert_in_ram(EFI_SIGNATURE_LIST *CertList,
while ((dbsize > 0) && (dbsize >= CertList->SignatureListSize)) {
if (CompareGuid (&CertList->SignatureType, &CertType) == 0) {
@ -20,7 +20,7 @@ index c36b641..1daa84b 100644
Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
for (Index = 0; Index < CertCount; Index++) {
IsFound = AuthenticodeVerify (data->CertData,
@@ -293,7 +293,7 @@ static CHECK_STATUS check_db_hash_in_ram(EFI_SIGNATURE_LIST *CertList,
@@ -295,7 +295,7 @@ static CHECK_STATUS check_db_hash_in_ram(EFI_SIGNATURE_LIST *CertList,
BOOLEAN IsFound = FALSE;
while ((dbsize > 0) && (dbsize >= CertList->SignatureListSize)) {
@ -30,5 +30,5 @@ index c36b641..1daa84b 100644
if (CompareGuid(&CertList->SignatureType, &CertType) == 0) {
for (Index = 0; Index < CertCount; Index++) {
--
1.7.10.4
1.8.1.4

View File

@ -1,30 +0,0 @@
From daa6a7519caa23ef69b9a879bc70789a0669b3e3 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Wed, 26 Dec 2012 11:44:46 +0800
Subject: [PATCH] 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(+)
diff --git a/MokManager.c b/MokManager.c
index bfcbfd6..97588cb 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;
--
1.7.10.4

View File

@ -1,84 +0,0 @@
commit f23f6b726bd12b28befd5a064c47a8a249d80a59
Author: Gary Ching-Pang Lin <glin@suse.com>
Date: Mon Jan 14 16:53:19 2013 +0800
Adopt the UEFI shell style LoadOptions
The previous commit, 14d4b8e, caused shim failed to parse the name
of the 2nd stage loader in UEFI shell. Amend parsing of the name the
2nd stage loader to be compatible with UEFI shell.
To create an boot entry for elilo.efi:
# efibootmgr -c -L "shim elilo" -l "efi\\shim.efi" -u "shim.efi elilo.efi"
diff --git a/shim.c b/shim.c
index dcf1c51..37a5898 100644
--- a/shim.c
+++ b/shim.c
@@ -1330,6 +1330,8 @@ EFI_STATUS set_second_stage (EFI_HANDLE image_handle)
EFI_LOADED_IMAGE *li;
CHAR16 *start = NULL, *c;
int i, remaining_size = 0;
+ CHAR16 *loader_str = NULL;
+ int loader_len = 0;
second_stage = DEFAULT_LOADER;
load_options = NULL;
@@ -1351,6 +1353,11 @@ EFI_STATUS set_second_stage (EFI_HANDLE image_handle)
return EFI_BAD_BUFFER_SIZE;
}
+ /*
+ * UEFI shell copies the whole line of the command into LoadOptions.
+ * We ignore the string before the first L' ', i.e. the name of this
+ * program.
+ */
for (i = 0; i < li->LoadOptionsSize; i += 2) {
c = (CHAR16 *)(li->LoadOptions + i);
if (*c == L' ') {
@@ -1360,9 +1367,30 @@ EFI_STATUS set_second_stage (EFI_HANDLE image_handle)
break;
}
}
+ if (!start || remaining_size <= 0)
+ return EFI_SUCCESS;
- second_stage = (CHAR16 *)li->LoadOptions;
- if (start && remaining_size > 0) {
+ for (i = 0; start[i] != '\0'; i++) {
+ if (start[i] == L' ' || start[i] == L'\0')
+ break;
+ loader_len++;
+ }
+
+ /*
+ * Setup the name of the alternative loader and the LoadOptions for
+ * the loader
+ */
+ if (loader_len > 0) {
+ loader_str = AllocatePool((loader_len + 1) * sizeof(CHAR16));
+ if (!loader_str) {
+ Print(L"Failed to allocate loader string\n");
+ return EFI_OUT_OF_RESOURCES;
+ }
+ for (i = 0; i < loader_len; i++)
+ loader_str[i] = start[i];
+ loader_str[loader_len] = L'\0';
+
+ second_stage = loader_str;
load_options = start;
load_options_size = remaining_size;
}
@@ -1439,5 +1467,11 @@ EFI_STATUS efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *passed_systab)
uefi_call_wrapper(BS->UninstallProtocolInterface, 3, handle,
&shim_lock_guid, &shim_lock_interface);
+ /*
+ * Free the space allocated for the alternative 2nd stage loader
+ */
+ if (load_options_size > 0)
+ FreePool(second_stage);
+
return efi_status;
}

View File

@ -0,0 +1,61 @@
From 23002e8e5c03800845afae8aaa7e42770c3e5d17 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Tue, 11 Jun 2013 14:58:25 -0400
Subject: [PATCH] Fix some pointer casting issues.
This also fixes the size of an empty vendor_cert or dbx_cert.
Signed-off-by: Peter Jones <shim-owner@fedoraproject.org>
---
cert.S | 2 +-
shim.c | 9 +++++----
2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/cert.S b/cert.S
index 2ed9b6d..66a05b8 100644
--- a/cert.S
+++ b/cert.S
@@ -32,5 +32,5 @@ vendor_cert:
.size vendor_cert_size, 4
.section .vendor_cert, "a", @progbits
vendor_cert_size:
- .long 1
+ .long 0
#endif
diff --git a/shim.c b/shim.c
index 94b9710..7d43f04 100644
--- a/shim.c
+++ b/shim.c
@@ -59,7 +59,7 @@ static UINT32 load_options_size;
*/
extern UINT8 vendor_cert[];
extern UINT32 vendor_cert_size;
-extern EFI_SIGNATURE_LIST *vendor_dbx;
+extern UINT8 vendor_dbx[];
extern UINT32 vendor_dbx_size;
#define EFI_IMAGE_SECURITY_DATABASE_GUID { 0xd719b2cb, 0x3d3a, 0x4596, { 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f }}
@@ -359,16 +359,17 @@ static EFI_STATUS check_blacklist (WIN_CERTIFICATE_EFI_PKCS *cert,
UINT8 *sha256hash, UINT8 *sha1hash)
{
EFI_GUID secure_var = EFI_IMAGE_SECURITY_DATABASE_GUID;
+ EFI_SIGNATURE_LIST *dbx = (EFI_SIGNATURE_LIST *)vendor_dbx;
- if (check_db_hash_in_ram(vendor_dbx, vendor_dbx_size, sha256hash,
+ if (check_db_hash_in_ram(dbx, vendor_dbx_size, sha256hash,
SHA256_DIGEST_SIZE, EfiHashSha256Guid) ==
DATA_FOUND)
return EFI_ACCESS_DENIED;
- if (check_db_hash_in_ram(vendor_dbx, vendor_dbx_size, sha1hash,
+ if (check_db_hash_in_ram(dbx, vendor_dbx_size, sha1hash,
SHA1_DIGEST_SIZE, EfiHashSha1Guid) ==
DATA_FOUND)
return EFI_ACCESS_DENIED;
- if (check_db_cert_in_ram(vendor_dbx, vendor_dbx_size, cert,
+ if (check_db_cert_in_ram(dbx, vendor_dbx_size, cert,
sha256hash) == DATA_FOUND)
return EFI_ACCESS_DENIED;
--
1.8.1.4

View File

@ -0,0 +1,149 @@
From ed9cf192de86c58e9c5397afa48de7b6d7bab7a7 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Thu, 30 May 2013 14:05:59 +0800
Subject: [PATCH 1/2] simple_file: Allocate buffers for file entries
The dir filter appends L'/' to the directory entries without
allocating a new buffer, and this could crash the whole program.
---
lib/simple_file.c | 42 ++++++++++++++++++++++++++++++++++--------
1 file changed, 34 insertions(+), 8 deletions(-)
diff --git a/lib/simple_file.c b/lib/simple_file.c
index 0e5ecd2..e288272 100644
--- a/lib/simple_file.c
+++ b/lib/simple_file.c
@@ -344,9 +344,12 @@ simple_dir_filter(EFI_HANDLE image, CHAR16 *name, CHAR16 *filter,
goto next;
if (next->Attribute & EFI_FILE_DIRECTORY) {
- (*result)[(*count)] = next->FileName;
- (*result)[(*count)][len] = '/';
- (*result)[(*count)++][len + 1] = '\0';
+ (*result)[(*count)] = PoolPrint(L"%s/", next->FileName);
+ if (!(*result)[(*count)]) {
+ Print(L"Failed to allocate buffer");
+ return EFI_OUT_OF_RESOURCES;
+ }
+ (*count)++;
goto next;
}
@@ -354,7 +357,12 @@ simple_dir_filter(EFI_HANDLE image, CHAR16 *name, CHAR16 *filter,
offs = StrLen(filterarr[c]);
if (StrCmp(&next->FileName[len - offs], filterarr[c]) == 0) {
- (*result)[(*count)++] = next->FileName;
+ (*result)[(*count)] = StrDuplicate(next->FileName);
+ if (!(*result)[(*count)]) {
+ Print(L"Failed to allocate buffer");
+ return EFI_OUT_OF_RESOURCES;
+ }
+ (*count)++;
} else {
continue;
}
@@ -362,7 +370,7 @@ simple_dir_filter(EFI_HANDLE image, CHAR16 *name, CHAR16 *filter,
}
next:
- if (StrCmp(next->FileName, L"../") == 0) {
+ if (StrCmp(next->FileName, L"..") == 0) {
/* place .. directory first */
CHAR16 *tmp = (*result)[(*count) - 1];
@@ -392,6 +400,15 @@ simple_dir_filter(EFI_HANDLE image, CHAR16 *name, CHAR16 *filter,
return status;
}
+static void
+free_entries(CHAR16 **entries, int count)
+{
+ int i;
+
+ for (i = 0; i<count; i++)
+ FreePool(entries[i]);
+}
+
void
simple_file_selector(EFI_HANDLE *im, CHAR16 **title, CHAR16 *name,
CHAR16 *filter, CHAR16 **result)
@@ -436,8 +453,6 @@ simple_file_selector(EFI_HANDLE *im, CHAR16 **title, CHAR16 *name,
/* ESC key */
goto out_free;
selected = entries[select];
- FreePool(entries);
- entries = NULL;
/* note that memory used by selected is valid until dmp is freed */
len = StrLen(selected);
if (selected[len - 1] == '/') {
@@ -445,6 +460,9 @@ simple_file_selector(EFI_HANDLE *im, CHAR16 **title, CHAR16 *name,
/* stay where we are */
if (StrCmp(selected, L"./") == 0) {
+ free_entries(entries, count);
+ FreePool(entries);
+ entries = NULL;
FreePool(dmp);
goto redo;
} else if (StrCmp(selected, L"../") == 0) {
@@ -463,6 +481,9 @@ simple_file_selector(EFI_HANDLE *im, CHAR16 **title, CHAR16 *name,
if (StrCmp(name, L"\\") != 0
&& StrCmp(&name[i], L"..") != 0) {
name[i] = '\0';
+ free_entries(entries, count);
+ FreePool(entries);
+ entries = NULL;
FreePool(dmp);
goto redo;
}
@@ -478,6 +499,9 @@ simple_file_selector(EFI_HANDLE *im, CHAR16 **title, CHAR16 *name,
/* remove trailing / */
newname[StrLen(newname) - 1] = '\0';
+ free_entries(entries, count);
+ FreePool(entries);
+ entries = NULL;
FreePool(dmp);
FreePool(name);
name = newname;
@@ -494,8 +518,10 @@ simple_file_selector(EFI_HANDLE *im, CHAR16 **title, CHAR16 *name,
out_free:
FreePool(dmp);
- if (entries)
+ if (entries) {
+ free_entries(entries, count);
FreePool(entries);
+ }
out_free_name:
FreePool(name);
}
--
1.8.1.4
From 33080500e6bf33324a7c1463f4608f3f21d923b3 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Thu, 30 May 2013 14:10:56 +0800
Subject: [PATCH 2/2] Clean lib/, too
---
Makefile | 1 +
1 file changed, 1 insertion(+)
diff --git a/Makefile b/Makefile
index f64f409..ed47360 100644
--- a/Makefile
+++ b/Makefile
@@ -109,6 +109,7 @@ lib/lib.a:
clean:
$(MAKE) -C Cryptlib clean
$(MAKE) -C Cryptlib/OpenSSL clean
+ $(MAKE) -C lib clean
rm -rf $(TARGET) $(OBJS) $(MOK_OBJS) $(FALLBACK_OBJS) $(KEYS) certdb
rm -f *.debug *.so *.efi
--
1.8.1.4

View File

@ -1,123 +0,0 @@
commit 940425a8bce6bf1b556dc48189884b4a82d8d420
Author: Gary Ching-Pang Lin <glin@suse.com>
Date: Thu Dec 6 17:47:26 2012 +0800
Get the second stage loader from the Load Options
This commit replaces the 2nd stage loader path with the first
argument in the Load Options and moves the rest arguments (if any)
to the Load Options for the 2nd stage loader.
For example, to make shim to load elilo.efi, just create a new
boot entry with efibootmgr:
# efibootmgr -c -L "shim elilo" -l "efi\\shim.efi" -u "elilo.efi"
diff --git a/shim.c b/shim.c
index c3aae9e..44301dd 100644
--- a/shim.c
+++ b/shim.c
@@ -42,12 +42,16 @@
#include "netboot.h"
#include "shim_cert.h"
-#define SECOND_STAGE L"\\grub.efi"
+#define DEFAULT_LOADER L"\\grub.efi"
#define MOK_MANAGER L"\\MokManager.efi"
static EFI_SYSTEM_TABLE *systab;
static EFI_STATUS (EFIAPI *entry_point) (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table);
+static CHAR16 *second_stage;
+static void *load_options;
+static UINT32 load_options_size;
+
/*
* The vendor certificate used for validating the second stage loader
*/
@@ -881,6 +885,10 @@ static EFI_STATUS handle_image (void *data, unsigned int datasize,
li->ImageBase = buffer;
li->ImageSize = context.ImageSize;
+ /* Pass the load options to the second stage loader */
+ li->LoadOptions = load_options;
+ li->LoadOptionsSize = load_options_size;
+
if (!entry_point) {
Print(L"Invalid entry point\n");
FreePool(buffer);
@@ -1192,7 +1200,7 @@ EFI_STATUS init_grub(EFI_HANDLE image_handle)
{
EFI_STATUS efi_status;
- efi_status = start_image(image_handle, SECOND_STAGE);
+ efi_status = start_image(image_handle, second_stage);
if (efi_status != EFI_SUCCESS)
efi_status = start_image(image_handle, MOK_MANAGER);
@@ -1312,6 +1320,55 @@ static EFI_STATUS check_mok_sb (void)
return status;
}
+/*
+ * Check the load options to specify the second stage loader
+ */
+EFI_STATUS set_second_stage (EFI_HANDLE image_handle)
+{
+ EFI_STATUS status;
+ EFI_LOADED_IMAGE *li;
+ CHAR16 *start = NULL, *c;
+ int i, remaining_size = 0;
+
+ second_stage = DEFAULT_LOADER;
+ load_options = NULL;
+ load_options_size = 0;
+
+ status = uefi_call_wrapper(BS->HandleProtocol, 3, image_handle,
+ &LoadedImageProtocol, (void **) &li);
+ if (status != EFI_SUCCESS) {
+ Print (L"Failed to get load options\n");
+ return status;
+ }
+
+ /* Expect a CHAR16 string with at least one CHAR16 */
+ if (li->LoadOptionsSize < 4 || li->LoadOptionsSize % 2 != 0) {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+ c = (CHAR16 *)(li->LoadOptions + (li->LoadOptionsSize - 2));
+ if (*c != L'\0') {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ for (i = 0; i < li->LoadOptionsSize; i += 2) {
+ c = (CHAR16 *)(li->LoadOptions + i);
+ if (*c == L' ') {
+ *c = L'\0';
+ start = c + 1;
+ remaining_size = li->LoadOptionsSize - i - 2;
+ break;
+ }
+ }
+
+ second_stage = (CHAR16 *)li->LoadOptions;
+ if (start && remaining_size > 0) {
+ load_options = start;
+ load_options_size = remaining_size;
+ }
+
+ return EFI_SUCCESS;
+}
+
EFI_STATUS efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *passed_systab)
{
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
@@ -1334,6 +1391,9 @@ EFI_STATUS efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *passed_systab)
*/
InitializeLib(image_handle, systab);
+ /* Set the second stage loader */
+ set_second_stage (image_handle);
+
/*
* Check whether the user has configured the system to run in
* insecure mode

View File

@ -1,13 +0,0 @@
diff --git a/Makefile b/Makefile
index 9217ba1..cd1c688 100644
--- a/Makefile
+++ b/Makefile
@@ -28,7 +28,7 @@ LDFLAGS = -nostdlib -znocombreloc -T $(EFI_LDS) -shared -Bsymbolic -L$(EFI_PATH
VERSION = 0.2
-TARGET = shim.efi MokManager.efi.signed
+TARGET = shim.efi MokManager.efi.signed MokManager.efi
OBJS = shim.o netboot.o cert.o dbx.o
KEYS = shim_cert.h ocsp.* ca.* shim.crt shim.csr shim.p12 shim.pem shim.key
SOURCES = shim.c shim.h netboot.c signature.h PeImage.h

View File

@ -1,722 +0,0 @@
From 6d50f87a06ff70d2075863f4c145235c081263d6 Mon Sep 17 00:00:00 2001
From: Matthew Garrett <mjg59@srcf.ucam.org>
Date: Sat, 24 Nov 2012 00:07:11 -0500
Subject: [PATCH 1/2] Sign MokManager with a locally-generated key
shim needs to verify that MokManager hasn't been modified, but we want to
be able to support configurations where shim is shipped without a vendor
certificate. This patch adds support for generating a certificate at build
time, incorporating the public half into shim and signing MokManager with
the private half. It uses pesign and nss, but still requires openssl for
key generation. Anyone using sbsign will need to figure this out for
themselves.
---
Makefile | 28 ++-
make-certs | 554 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
shim.c | 24 ++-
3 files changed, 597 insertions(+), 9 deletions(-)
create mode 100755 make-certs
diff --git a/Makefile b/Makefile
index b266018..412eba5 100644
--- a/Makefile
+++ b/Makefile
@@ -28,15 +28,33 @@ LDFLAGS = -nostdlib -znocombreloc -T $(EFI_LDS) -shared -Bsymbolic -L$(EFI_PATH
VERSION = 0.2
-TARGET = shim.efi MokManager.efi
+TARGET = shim.efi MokManager.efi.signed
OBJS = shim.o netboot.o cert.o dbx.o
+KEYS = shim_cert.h ocsp.* ca.* shim.crt shim.csr shim.p12 shim.pem shim.key
SOURCES = shim.c shim.h netboot.c signature.h PeImage.h
MOK_OBJS = MokManager.o
MOK_SOURCES = MokManager.c shim.h
all: $(TARGET)
-shim.o: $(SOURCES)
+shim.crt:
+ ./make-certs shim shim@xn--u4h.net all codesign 1.3.6.1.4.1.311.10.3.1 </dev/null
+
+shim.cer: shim.crt
+ openssl x509 -outform der -in $< -out $@
+
+shim_cert.h: shim.cer
+ echo "static UINT8 shim_cert[] = {" > $@
+ hexdump -v -e '1/1 "0x%02x, "' $< >> $@
+ echo "};" >> $@
+
+certdb/secmod.db: shim.crt
+ -mkdir certdb
+ certutil -A -n 'my CA' -d certdb/ -t CT,CT,CT -i ca.crt
+ pk12util -d certdb/ -i shim.p12 -W "" -K ""
+ certutil -d certdb/ -A -i shim.crt -n shim -t u
+
+shim.o: $(SOURCES) shim_cert.h
cert.o : cert.S
$(CC) $(CFLAGS) -c -o $@ $<
@@ -70,10 +88,14 @@ Cryptlib/OpenSSL/libopenssl.a:
-j .debug_line -j .debug_str -j .debug_ranges \
--target=efi-app-$(ARCH) $^ $@.debug
+%.efi.signed: %.efi certdb/secmod.db
+ pesign -n certdb -i $< -c "shim" -s -o $@ -f
+
clean:
$(MAKE) -C Cryptlib clean
$(MAKE) -C Cryptlib/OpenSSL clean
- rm -f $(TARGET) $(OBJS)
+ rm -rf $(TARGET) $(OBJS) $(MOK_OBJS) $(KEYS) certdb
+ rm -f *.debug *.so
GITTAG = $(VERSION)
diff --git a/make-certs b/make-certs
new file mode 100755
index 0000000..3e9293b
--- /dev/null
+++ b/make-certs
@@ -0,0 +1,554 @@
+#!/bin/bash -e
+#
+# Generate a root CA cert for signing, and then a subject cert.
+# Usage: make-certs.sh hostname [user[@domain]] [more ...]
+# For testing only, probably still has some bugs in it.
+#
+
+DOMAIN=xn--u4h.net
+DAYS=365
+KEYTYPE=RSA
+KEYSIZE=2048
+DIGEST=SHA256
+CRLHOURS=24
+CRLDAYS=
+
+# Cleanup temporary files at exit.
+touch openssl.cnf
+newcertdir=`mktemp -d`
+cleanup() {
+ test -f openssl.cnf && rm -f openssl.cnf
+ test -f ca.txt && rm -f ca.txt
+ test -f ocsp.txt && rm -f ocsp.txt
+ test -n "$newcertdir" && rm -fr "$newcertdir"
+}
+trap cleanup EXIT
+
+# The first argument is either a common name value or a flag indicating that
+# we're doing something other than issuing a cert.
+commonname="$1"
+refresh_crl=false
+revoke_cert=false
+ocsp_serve=false
+if test "x$commonname" = "x-refresh-crl" ; then
+ refresh_crl=true
+ commonname="$1"
+fi
+if test "x$commonname" = "x-refresh_crl" ; then
+ refresh_crl=true
+ commonname="$1"
+fi
+if test "x$commonname" = "x-revoke" ; then
+ revoke_cert=true
+ shift
+ commonname="$1"
+fi
+if test "x$commonname" = "x-ocsp" ; then
+ ocsp_serve=true
+ commonname="$1"
+fi
+if test "x$commonname" = x ; then
+ echo Usage: `basename $0` 'commonname' user'[@domain]' '[more [...]]'
+ echo Usage: `basename $0` -revoke 'commonname'
+ echo Usage: `basename $0` -ocsp
+ echo Usage: `basename $0` -refresh-crl
+ echo More:
+ echo -e \\tKey usage: "[sign|signing|encrypt|encryption|all]"
+ echo -e \\tAuthority Access Info OCSP responder: "ocsp:URI"
+ echo -e \\tCRL distribution point: "crl:URI"
+ echo -e \\tSubject Alternative Name:
+ echo -e \\t\\tHostname: "*"
+ echo -e \\t\\tIP address: w.x.y.z
+ echo -e \\t\\tEmail address: "*@*.com/edu/net/org/local"
+ echo -e \\t\\tKerberos principal name: "*@*.COM/EDU/NET/ORG/LOCAL"
+ echo -e \\tExtended key usage:
+ echo -e \\t\\t1....
+ echo -e \\t\\t2....
+ echo -e \\t\\tid-kp-server-auth \| tls-server
+ echo -e \\t\\tid-kp-client-auth \| tls-client
+ echo -e \\t\\tid-kp-email-protection \| email
+ echo -e \\t\\tid-ms-kp-sc-logon \| id-ms-sc-logon
+ echo -e \\t\\tid-pkinit-kp-client-auth \| id-pkinit-client
+ echo -e \\t\\tid-pkinit-kp-kdc \| id-pkinit-kdc
+ echo -e \\t\\tca \| CA
+ exit 1
+fi
+
+# Choose a user name part for email attributes.
+GIVENUSER=$2
+test x"$GIVENUSER" = x && GIVENUSER=$USER
+echo "$GIVENUSER" | grep -q @ || GIVENUSER="$GIVENUSER"@$DOMAIN
+DOMAIN=`echo "$GIVENUSER" | cut -f2- -d@`
+
+shift || true
+shift || true
+
+# Done already?
+done=:
+
+keygen() {
+ case "$KEYTYPE" in
+ DSA)
+ openssl dsaparam -out "$1".param $KEYSIZE
+ openssl gendsa "$1".param
+ ;;
+ RSA|*)
+ #openssl genrsa $KEYSIZE -passout pass:qweqwe
+ openssl genrsa $KEYSIZE
+ #openssl genrsa $KEYSIZE -nodes
+ ;;
+ esac
+}
+
+# Set some defaults.
+CA=FALSE
+if test -s ca.crldp.uri.txt ; then
+ crlval="`cat ca.crldp.uri.txt`"
+ crl="URI:$crlval"
+fi
+if test -s ca.ocsp.uri.txt ; then
+ aiaval="`cat ca.ocsp.uri.txt`"
+ aia="OCSP;URI:$aiaval"
+fi
+if test -s ca.domain.txt ; then
+ domval="`cat ca.domain.txt`"
+ if test -n "$domval" ; then
+ DOMAIN="$domval"
+ fi
+fi
+
+# Parse the arguments which indicate what sort of information we want.
+while test $# -gt 0 ; do
+ type=
+ value="$1"
+ case "$value" in
+ RSA|rsa)
+ KEYTYPE=RSA
+ ;;
+ DSA|dsa)
+ KEYTYPE=DSA
+ ;;
+ OCSP:*|ocsp:*)
+ aiaval=`echo "$value" | cut -f2- -d:`
+ aia="OCSP;URI:$aiaval"
+ ;;
+ CRL:*|crl:*)
+ crlval=`echo "$value" | cut -f2- -d:`
+ crl="URI:$crlval"
+ ;;
+ signing|sign)
+ keyusage="${keyusage:+${keyusage},}nonRepudiation,digitalSignature"
+ ;;
+ encryption|encrypt)
+ keyusage="${keyusage:+${keyusage},}keyEncipherment,dataEncipherment"
+ ;;
+ all)
+ keyusage="digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement,keyCertSign,cRLSign,encipherOnly,decipherOnly"
+ ;;
+ ca|CA)
+ CA=TRUE
+ keyusage="${keyusage:+${keyusage},}nonRepudiation,digitalSignature,keyEncipherment,dataEncipherment,keyAgreement,keyCertSign,cRLSign"
+ ;;
+ 1.*|2.*|id-*|tls-*|email|mail|codesign)
+ ekuval=`echo "$value" | tr '[A-Z]' '[a-z]' | sed 's,\-,,g'`
+ case "$ekuval" in
+ idkpserverauth|tlsserver) ekuval=1.3.6.1.5.5.7.3.1;;
+ idkpclientauth|tlsclient) ekuval=1.3.6.1.5.5.7.3.2;;
+ idkpemailprotection|email|mail) ekuval=1.3.6.1.5.5.7.3.4;;
+ idkpcodesign|codesign) ekuval=1.3.6.1.5.5.7.3.3;;
+ idmskpsclogon|idmssclogon) ekuval=1.3.6.1.4.1.311.20.2.2;;
+ idpkinitkpclientauth|idpkinitclient) ekuval=1.3.6.1.5.2.3.4;;
+ idpkinitkpkdc|idpkinitkdc) ekuval=1.3.6.1.5.2.3.5;;
+ esac
+ if test -z "$eku" ; then
+ eku="$ekuval"
+ else
+ eku="$eku,$ekuval"
+ fi
+ ;;
+ *@*.COM|*@*.EDU|*@*.NET|*@*.ORG|*@*.LOCAL)
+ luser=`echo "$value" | tr '[A-Z]' '[a-z]'`
+ if test "$luser" = "$value" ; then
+ luser=
+ fi
+ type="otherName:1.3.6.1.5.2.2;SEQUENCE:$value,${luser:+otherName:1.3.6.1.4.1.311.20.2.3;UTF8:${luser},}otherName:1.3.6.1.4.1.311.20.2.3;UTF8"
+ unset luser
+ principals="$principals $value"
+ ;;
+ *@*.com|*@*.edu|*@*.net|*@*.org|*@*.local) type=email;;
+ [0-9]*.[0-9]*.[0-9]*.[0-9]*) type=IP;;
+ *) type=DNS;;
+ esac
+ if test -n "$type" ; then
+ newvalue="${type}:$value"
+ if test -z "$altnames" ; then
+ altnames="${newvalue}"
+ else
+ altnames="${altnames},${newvalue}"
+ fi
+ fi
+ shift
+done
+
+# Build the configuration file, including bits on how to construct the CA
+# certificate, an OCSP responder certificate, and the issued certificate.
+cat > openssl.cnf <<- EOF
+[ca]
+default_ca = issuer
+
+[issuer]
+private_key = `pwd`/ca.key
+certificate = `pwd`/ca.crt
+database = `pwd`/ca.db
+serial = `pwd`/ca.srl
+default_md = $DIGEST
+new_certs_dir = $newcertdir
+policy = no_policy
+
+[no_policy]
+
+[req_oids]
+domainComponent = 0.9.2342.19200300.100.1.25
+
+[req_ca]
+prompt = no
+oid_section = req_oids
+distinguished_name = req_ca_name
+default_md = $DIGEST
+subjectKeyIdentifier=hash
+
+[req_ca_name]
+C=US
+#stateOrProvinceName=SomeState
+localityName=SomeCity
+O=SomeOrg
+EOF
+#echo $DOMAIN | awk 'BEGIN {FS="."}{for(i=NF;i>0;i--){print NF-i ".domainComponent="$i;}}' >> openssl.cnf
+cat >> openssl.cnf <<- EOF
+#commonName = Test Certifying CA
+
+[v3_ca]
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid:always
+#authorityKeyIdentifier=keyid:always,issuer:always
+keyUsage=nonRepudiation,digitalSignature,keyEncipherment,dataEncipherment,keyAgreement,keyCertSign,cRLSign
+basicConstraints=critical,CA:TRUE
+nsComment="Testing CA Certificate"
+EOF
+if test -n "$aia" ; then
+ echo "authorityInfoAccess = ${aia}" >> openssl.cnf
+ echo -n "$aiaval" > ca.ocsp.uri.txt
+fi
+if test -n "$crl" ; then
+ echo "crlDistributionPoints = ${crl}" >> openssl.cnf
+ echo -n "$crlval" > ca.crldp.uri.txt
+fi
+echo "$DOMAIN" > ca.domain.txt
+cat >> openssl.cnf <<- EOF
+
+[req_ocsp]
+prompt = no
+oid_section = req_oids
+distinguished_name = req_ocsp_name
+default_md = $DIGEST
+
+[req_ocsp_name]
+C=US
+#stateOrProvinceName=SomeState
+localityName=SomeOrg
+O=SomeOrg
+EOF
+#echo $DOMAIN | awk 'BEGIN {FS="."}{for(i=NF;i>0;i--){print NF-i ".domainComponent="$i;}}' >> openssl.cnf
+cat >> openssl.cnf <<- EOF
+#commonName = OCSP Signer for Test Certifying CA
+
+[v3_ocsp]
+subjectKeyIdentifier=hash
+#authorityKeyIdentifier=keyid:always,issuer:always
+authorityKeyIdentifier=keyid:always
+keyUsage=digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement,keyCertSign,cRLSign
+extendedKeyUsage=1.3.6.1.5.5.7.3.9
+#basicConstraints=CA:FALSE
+basicConstraints=CA:TRUE
+nsComment="Testing OCSP Certificate"
+1.3.6.1.5.5.7.48.1.5=ASN1:NULL
+EOF
+if test -n "$aia" ; then
+ echo "authorityInfoAccess = ${aia}" >> openssl.cnf
+fi
+if test -n "$crl" ; then
+ echo "crlDistributionPoints = ${crl}" >> openssl.cnf
+fi
+cat >> openssl.cnf <<- EOF
+
+[req_issued]
+prompt = no
+oid_section = req_oids
+distinguished_name = req_issued_name
+default_md = $DIGEST
+
+[req_issued_name]
+C=US
+#stateOrProvinceName=SomeState
+localityName=SomeCity
+O=SomeOrg
+EOF
+#echo $DOMAIN | awk 'BEGIN {FS="."}{for(i=NF;i>0;i--){print NF-i ".domainComponent="$i;}}' >> openssl.cnf
+#mail = $GIVENUSER
+cat >> openssl.cnf <<- EOF
+commonName = $commonname
+
+[v3_issued]
+#certificatePolicies=2.5.29.32.0${eku:+,${eku}}
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid:always
+#authorityKeyIdentifier=keyid:always,issuer:always
+EOF
+if test -n "$aia" ; then
+ echo "authorityInfoAccess = ${aia}" >> openssl.cnf
+fi
+if test -n "$crl" ; then
+ echo "crlDistributionPoints = ${crl}" >> openssl.cnf
+fi
+if test -n "$keyusage" ; then
+ echo "keyUsage = critical,${keyusage}" >> openssl.cnf
+fi
+if test -n "$altnames" ; then
+ echo "subjectAltName = ${altnames}" >> openssl.cnf
+fi
+if test -n "$eku" ; then
+ echo "extendedKeyUsage = ${eku}" >> openssl.cnf
+ :
+fi
+if test "x$CA" = xTRUE ; then
+ echo "basicConstraints=critical,CA:TRUE" >> openssl.cnf
+ echo 'nsComment="Testing CA Certificate for '"$commonname"'"' >> openssl.cnf
+else
+ echo "basicConstraints=CA:FALSE" >> openssl.cnf
+ echo 'nsComment="Testing Certificate for '"$commonname"'"' >> openssl.cnf
+fi
+for value in $principals; do
+ user=`echo "$value" | cut -f1 -d@`
+ realm=`echo "$value" | cut -f2- -d@`
+ echo "" >> openssl.cnf
+ echo "[$value]" >> openssl.cnf
+ echo "realm=EXPLICIT:0,GeneralString:$realm" >> openssl.cnf
+ echo "kerberosname=EXPLICIT:1,SEQUENCE:krb5$user" >> openssl.cnf
+
+ echo "" >> openssl.cnf
+ echo "[krb5$user]" >> openssl.cnf
+ echo "nametype=EXPLICIT:0,INTEGER:1" >> openssl.cnf
+ echo "namelist=EXPLICIT:1,SEQUENCE:krb5basic$user" >> openssl.cnf
+
+ echo "[krb5basic$user]" >> openssl.cnf
+ count=0
+ for part in `echo "$user" | sed 's,/, ,g'` ; do
+ echo "$count.part=GeneralString:$part" >> openssl.cnf
+ count=`expr "$count" + 1`
+ done
+done
+
+# Create the data files for a new CA.
+if ! test -s ca.srl ; then
+ (dd if=/dev/urandom bs=8 count=1 2> /dev/null) | od -t x1c | head -n 1 | awk '{$1="00";OFS="";print}' > ca.srl
+else
+ echo "You already have a ca.srl file; not replacing."
+fi
+if ! test -s ca.db ; then
+ touch ca.db
+else
+ echo "You already have a ca.db file; not replacing."
+fi
+if ! test -s ca.db.attr ; then
+ touch ca.db.attr
+else
+ echo "You already have a ca.db.attr file; not replacing."
+fi
+
+# If we need a CA key, generate one.
+if ! test -s ca.key ; then
+ umask=`umask -p`
+ umask 077
+ keygen ca > ca.key 2> /dev/null
+ $umask
+else
+ echo "You already have a ca.key file; not replacing."
+ done=echo
+fi
+
+# If we need a CA certificate, generate one.
+if ! test -s ca.crt ; then
+ sed -i -e 's,^\[req_ca\]$,\[req\],g' `pwd`/openssl.cnf
+ openssl req -config `pwd`/openssl.cnf -new -key ca.key > ca.csr 2> /dev/null -passin pass:shim
+ sed -i -e 's,^\[req\]$,\[req_ca\],g' `pwd`/openssl.cnf
+ openssl x509 -extfile `pwd`/openssl.cnf -CAserial ca.srl -signkey ca.key -extensions v3_ca -req -in ca.csr -days $DAYS -out ca.crt ; : 2> /dev/null
+ openssl x509 -noout -text -in ca.crt > ca.txt
+ cat ca.crt >> ca.txt
+ cat ca.txt > ca.crt
+ rm ca.txt
+ cat ca.crt > ca.chain.crt
+else
+ echo "You already have a ca.crt file; not replacing."
+ done=echo
+fi
+
+# If we need an OCSP key, generate one.
+if ! test -s ocsp.key ; then
+ umask=`umask -p`
+ umask 077
+ keygen ocsp > ocsp.key 2> /dev/null
+ $umask
+else
+ echo "You already have an ocsp.key file; not replacing."
+ done=echo
+fi
+
+# Generate the OCSP signing cert. Set the X.509v3 basic constraints and EKU.
+if ! test -s ocsp.crt ; then
+ sed -i -e 's,^\[req_ocsp\]$,\[req\],g' `pwd`/openssl.cnf
+ openssl req -config `pwd`/openssl.cnf -new -key ocsp.key > ocsp.csr 2> /dev/null
+ sed -i -e 's,^\[req\]$,\[req_ocsp\],g' `pwd`/openssl.cnf
+ openssl ca -batch -config `pwd`/openssl.cnf -extensions v3_ocsp -preserveDN -in ocsp.csr -days $DAYS -out ocsp.crt 2> /dev/null
+ openssl x509 -noout -text -in ocsp.crt > ocsp.txt
+ cat ocsp.crt >> ocsp.txt
+ cat ocsp.txt > ocsp.crt
+ rm ocsp.txt
+else
+ echo "You already have an ocsp.crt file; not replacing."
+ done=echo
+fi
+
+# If we were told to revoke the certificate with the specified common name,
+# do so.
+if $revoke_cert ; then
+ openssl ca -config `pwd`/openssl.cnf -revoke "$commonname".crt
+fi
+
+# Always refresh the CRL.
+openssl ca -config `pwd`/openssl.cnf -gencrl ${CRLHOURS:+-crlhours ${CRLHOURS}} ${CRLDAYS:+-crldays ${CRLDAYS}} -out ca.crl.pem
+openssl crl -in ca.crl.pem -outform der -out ca.crl
+openssl crl -in ca.crl -inform der -noout -text > ca.crl.pem
+openssl crl -in ca.crl -inform der >> ca.crl.pem
+
+# If we were told to start up the mini OCSP server, do so.
+if $ocsp_serve ; then
+ openssl ocsp -text -index `pwd`/ca.db -CA `pwd`/ca.crt -rsigner `pwd`/ocsp.crt -rkey `pwd`/ocsp.key -rother `pwd`/ocsp.crt -port "`cut -f3 -d/ ca.ocsp.uri.txt | sed -r 's,(^[^:]*),0.0.0.0,g'`"
+ exit 0
+fi
+
+# If we're just here to do a revocation or refresh the CRL, we're done.
+if $revoke_cert || $refresh_crl ; then
+ exit 0
+fi
+
+# Create a new serial number and whatnot if this is a new sub-CA.
+if test "x$CA" = xTRUE ; then
+ if ! test -d "$commonname" ; then
+ mkdir "$commonname"
+ fi
+ if ! test -s "$commonname/ca.srl" ; then
+ (dd if=/dev/urandom bs=8 count=1 2> /dev/null) | od -t x1c | head -n 1 | awk '{$1="00";OFS="";print}' > "$commonname/ca.srl"
+ else
+ echo "You already have a $commonname/ca.srl file; not replacing."
+ fi
+ if test -n "$aia" ; then
+ echo -n "$aiaval" > "$commonname/ca.ocsp.uri.txt"
+ fi
+ if test -n "$crl" ; then
+ echo -n "$crlval" > "$commonname/ca.crldp.uri.txt"
+ fi
+ echo "$DOMAIN" > "$commonname/ca.domain.txt"
+ touch "$commonname/ca.db" "$commonname/ca.db.attr"
+ cert="$commonname/ca.crt"
+ csr="$commonname/ca.csr"
+ key="$commonname/ca.key"
+ pem="$commonname/ca.pem"
+ pfx="$commonname/ca.p12"
+ ln -s ../`basename $0` "$commonname"/
+else
+ cert="$commonname.crt"
+ csr="$commonname.csr"
+ key="$commonname.key"
+ pem="$commonname.pem"
+ pfx="$commonname.p12"
+fi
+
+# Generate the subject's certificate. Set the X.509v3 basic constraints.
+if ! test -s "$cert" ; then
+ # Generate another key, unless we have a key or CSR.
+ if ! test -s "$key" && ! test -s "$csr" ; then
+ umask=`umask -p`
+ umask 077
+ keygen "$commonname" > "$key" 2> /dev/null
+ $umask
+ else
+ echo "You already have a $key or $csr file; not replacing."
+ done=echo
+ fi
+
+ if ! test -s "$csr" ; then
+ sed -i -e 's,^\[req_issued\]$,\[req\],g' `pwd`/openssl.cnf
+ openssl req -config `pwd`/openssl.cnf -new -key "$key" > "$csr" 2> /dev/null
+ sed -i -e 's,^\[req\]$,\[req_issued\],g' `pwd`/openssl.cnf
+ fi
+ openssl ca -batch -config `pwd`/openssl.cnf -extensions v3_issued -preserveDN -in "$csr" -days $DAYS -out "$cert" 2> /dev/null
+ openssl x509 -noout -text -in "$cert" > "$cert.txt"
+ cat "$cert" >> "$cert.txt"
+ cat "$cert.txt" > "$cert"
+ rm -f "$cert.txt"
+else
+ echo "You already have a $cert file; not replacing."
+ done=echo
+fi
+
+if test -s ca.chain.crt ; then
+ chain=ca.chain.crt
+else
+ chain=ca.crt
+fi
+if test "x$CA" = xTRUE ; then
+ cat "$chain" "$cert" > "$commonname/ca.chain.crt"
+fi
+
+# Create ca.pem and the subject's name.pem for the benefit of applications
+# which expect both the private key and the certificate in one file.
+umask=`umask -p`
+umask 077
+if ! test -s ca.pem ; then
+ cat ca.key ca.crt > ca.pem
+else
+ echo "You already have a ca.pem file; not replacing."
+ done=echo
+fi
+if ! test -s "$pem" ; then
+ cat "$key" "$cert" > "$pem"
+else
+ echo "You already have a $pem file; not replacing."
+ done=echo
+fi
+if ! test -s "$pfx" ; then
+ #openssl pkcs12 -export -inkey "$key" -in "$cert" -name "$commonname" -out "$pfx" -nodes -passout pass:qweqwe
+ openssl pkcs12 -export -inkey "$key" -in "$cert" -name "$commonname" -out "$pfx" -nodes -passout pass:
+else
+ echo "You already have a $pfx file; not replacing."
+ done=echo
+fi
+$umask
+$done
+
+echo CA certificate:
+openssl x509 -noout -issuer -in ca.crt | sed s,=\ ,\ ,g
+openssl x509 -noout -subject -in ca.crt | sed s,=\ ,\ ,g
+echo
+echo End entity certificate:
+openssl x509 -noout -issuer -in "$cert" | sed s,=\ ,\ ,g
+openssl x509 -noout -subject -in "$cert" | sed s,=\ ,\ ,g
+openssl x509 -noout -serial -in "$cert" | sed s,=,\ ,g
+echo
+echo PKCS12 bag:
+openssl pkcs12 -in "$pfx" -nodes -nokeys -nocerts -info -passin pass:
+#openssl pkcs12 -in "$pfx" -nodes -nokeys -nocerts -info -passin pass:qweqwe
+echo
+echo Verifying:
+echo + openssl verify -CAfile "$chain" "$cert"
+openssl verify -CAfile "$chain" "$cert"
diff --git a/shim.c b/shim.c
index 8130ed8..4d490b9 100644
--- a/shim.c
+++ b/shim.c
@@ -40,6 +40,7 @@
#include "shim.h"
#include "signature.h"
#include "netboot.h"
+#include "shim_cert.h"
#define SECOND_STAGE L"\\grub.efi"
#define MOK_MANAGER L"\\MokManager.efi"
@@ -415,6 +416,8 @@ static BOOLEAN secure_mode (void)
UINT8 sb, setupmode;
UINT32 attributes;
+ return TRUE;
+
if (insecure_mode)
return FALSE;
@@ -696,6 +699,19 @@ static EFI_STATUS verify_buffer (char *data, int datasize,
}
/*
+ * Check against the shim build key
+ */
+ if (AuthenticodeVerify(cert->CertData,
+ context->SecDir->Size - sizeof(cert->Hdr),
+ shim_cert, sizeof(shim_cert), sha256hash,
+ SHA256_DIGEST_SIZE)) {
+ status = EFI_SUCCESS;
+ Print(L"Binary is verified by the vendor certificate\n");
+ return status;
+ }
+
+
+ /*
* And finally, check against shim's built-in key
*/
if (AuthenticodeVerify(cert->CertData,
@@ -1180,12 +1196,8 @@ EFI_STATUS init_grub(EFI_HANDLE image_handle)
efi_status = start_image(image_handle, SECOND_STAGE);
- if (efi_status != EFI_SUCCESS) {
- if (efi_status == EFI_ACCESS_DENIED)
- efi_status = start_image(image_handle, MOK_MANAGER);
- else
- Print(L"Failed to start grub\n");
- }
+ if (efi_status != EFI_SUCCESS)
+ efi_status = start_image(image_handle, MOK_MANAGER);
done:
return efi_status;
--
1.7.10.4
From 9c0c64ebde4ec504fc4e4d92ea18b889b1ccd498 Mon Sep 17 00:00:00 2001
From: Matthew Garrett <mjg59@srcf.ucam.org>
Date: Tue, 27 Nov 2012 23:52:27 -0500
Subject: [PATCH 2/2] Remove debug code
secure_mode() was altered to always return true for debug purposes, and this
accidentally got committed to mainline. Fix that.
---
shim.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/shim.c b/shim.c
index 4d490b9..c3aae9e 100644
--- a/shim.c
+++ b/shim.c
@@ -416,8 +416,6 @@ static BOOLEAN secure_mode (void)
UINT8 sb, setupmode;
UINT32 attributes;
- return TRUE;
-
if (insecure_mode)
return FALSE;
--
1.7.10.4

File diff suppressed because it is too large Load Diff

View File

@ -1,587 +0,0 @@
From 6e816e3e0f8b2013c1bccd67ec27db10ccaabc67 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Tue, 15 Jan 2013 18:01:41 +0800
Subject: [PATCH 1/2] Support new password hash
Old password hash: sha256sum(key_list + password)
New password hash: salt + sha256sum(salt + password)
---
MokManager.c | 91 ++++++++++++++++++++++++++++++++++++++++++----------------
1 file changed, 67 insertions(+), 24 deletions(-)
diff --git a/MokManager.c b/MokManager.c
index 97588cb..be2a764 100644
--- a/MokManager.c
+++ b/MokManager.c
@@ -19,6 +19,9 @@
#define CERT_STRING L"Select an X509 certificate to enroll:\n\n"
#define HASH_STRING L"Select a file to trust:\n\n"
+#define SALT_LEN 16
+#define AUTH_LEN (SALT_LEN + SHA256_DIGEST_SIZE)
+
struct menu_item {
CHAR16 *text;
INTN (* callback)(void *data, void *data2, void *data3);
@@ -648,23 +651,30 @@ static EFI_STATUS store_keys (void *MokNew, UINTN MokNewSize, int authenticate)
{
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
EFI_STATUS efi_status;
- UINT8 auth[SHA256_DIGEST_SIZE];
- UINTN auth_size;
+ UINT8 data[AUTH_LEN], *auth, *salt;
+ UINTN auth_size = AUTH_LEN;
UINT32 attributes;
if (authenticate) {
- auth_size = SHA256_DIGEST_SIZE;
efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokAuth",
&shim_lock_guid,
- &attributes, &auth_size, auth);
+ &attributes, &auth_size, data);
- if (efi_status != EFI_SUCCESS || auth_size != SHA256_DIGEST_SIZE) {
+ if (efi_status != EFI_SUCCESS ||
+ (auth_size != SHA256_DIGEST_SIZE && auth_size != AUTH_LEN)) {
Print(L"Failed to get MokAuth %d\n", efi_status);
return efi_status;
}
- efi_status = match_password(MokNew, MokNewSize, auth, NULL);
+ if (auth_size == AUTH_LEN) {
+ salt = data;
+ auth = data + SALT_LEN;
+ efi_status = match_password(salt, SALT_LEN, auth, NULL);
+ } else {
+ auth = data;
+ efi_status = match_password(MokNew, MokNewSize, auth, NULL);
+ }
if (efi_status != EFI_SUCCESS)
return EFI_ACCESS_DENIED;
}
@@ -842,8 +852,8 @@ 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;
+ UINT8 data[AUTH_LEN], *auth, *salt;;
+ UINTN auth_size = AUTH_LEN;
UINT32 attributes;
void *MokListData = NULL;
UINTN MokListDataSize = 0;
@@ -853,14 +863,22 @@ static EFI_STATUS delete_keys (void *MokDel, UINTN MokDelSize)
efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokDelAuth",
&shim_lock_guid,
- &attributes, &auth_size, auth);
+ &attributes, &auth_size, data);
- if (efi_status != EFI_SUCCESS || auth_size != SHA256_DIGEST_SIZE) {
+ if (efi_status != EFI_SUCCESS ||
+ (auth_size != SHA256_DIGEST_SIZE && auth_size != AUTH_LEN)) {
Print(L"Failed to get MokDelAuth %d\n", efi_status);
return efi_status;
}
- efi_status = match_password(MokDel, MokDelSize, auth, NULL);
+ if (auth_size == AUTH_LEN) {
+ salt = data;
+ auth = data + SALT_LEN;
+ efi_status = match_password(salt, SALT_LEN, auth, NULL);
+ } else {
+ auth = data;
+ efi_status = match_password(MokDel, MokDelSize, auth, NULL);
+ }
if (efi_status != EFI_SUCCESS)
return EFI_ACCESS_DENIED;
@@ -1052,20 +1070,29 @@ 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 hash[SHA256_DIGEST_SIZE];
+ UINT8 hash[AUTH_LEN], *auth, *salt;
+ UINT8 clear = 0;
UINT32 length;
CHAR16 line[1];
- if (MokPWSize != SHA256_DIGEST_SIZE) {
+ if (MokPWSize != SHA256_DIGEST_SIZE && MokPWSize != AUTH_LEN) {
Print(L"Invalid MokPW variable contents\n");
return -1;
}
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
- SetMem(hash, SHA256_DIGEST_SIZE, 0);
+ SetMem(hash, AUTH_LEN, 0);
+
+ if (MokPWSize == AUTH_LEN) {
+ if (CompareMem(MokPW, hash, AUTH_LEN) == 0)
+ clear = 1;
+ } else {
+ if (CompareMem(MokPW, hash, SHA256_DIGEST_SIZE) == 0)
+ clear = 1;
+ }
- if (CompareMem(MokPW, hash, SHA256_DIGEST_SIZE) == 0) {
+ if (clear) {
Print(L"Clear MOK password? (y/n): ");
do {
@@ -1080,7 +1107,14 @@ static INTN mok_pw_prompt (void *MokPW, void *data2, void *data3) {
return 0;
}
- efi_status = match_password(NULL, 0, MokPW, L"Confirm MOK passphrase: ");
+ if (MokPWSize == AUTH_LEN) {
+ salt = MokPW;
+ auth = MokPW + SALT_LEN;
+ efi_status = match_password(salt, SALT_LEN, auth, L"Confirm MOK passphrase: ");
+ } else {
+ efi_status = match_password(NULL, 0, MokPW, L"Confirm MOK passphrase: ");
+ }
+
if (efi_status != EFI_SUCCESS) {
Print(L"Password limit reached\n");
return -1;
@@ -1691,8 +1725,8 @@ static BOOLEAN verify_pw(void)
{
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
EFI_STATUS efi_status;
- UINT8 pwhash[SHA256_DIGEST_SIZE];
- UINTN size = SHA256_DIGEST_SIZE;
+ UINT8 pwhash[AUTH_LEN], *auth, *salt;
+ UINTN size = AUTH_LEN;
UINT32 attributes;
efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokPWStore",
@@ -1704,7 +1738,8 @@ static BOOLEAN verify_pw(void)
* known value, so there's no safety advantage in failing to validate
* purely because of a failure to read the variable
*/
- if (efi_status != EFI_SUCCESS)
+ if (efi_status != EFI_SUCCESS ||
+ (size != SHA256_DIGEST_SIZE && size != AUTH_LEN))
return TRUE;
if (attributes & EFI_VARIABLE_RUNTIME_ACCESS)
@@ -1712,7 +1747,13 @@ static BOOLEAN verify_pw(void)
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
- efi_status = match_password(NULL, 0, pwhash, L"Enter MOK password: ");
+ if (size == AUTH_LEN) {
+ salt = pwhash;
+ auth = pwhash + SALT_LEN;
+ efi_status = match_password(salt, SALT_LEN, auth, L"Enter MOK password: ");
+ } else {
+ efi_status = match_password(NULL, 0, pwhash, L"Enter MOK password: ");
+ }
if (efi_status != EFI_SUCCESS) {
Print(L"Password limit reached\n");
return FALSE;
@@ -1733,8 +1774,8 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle,
UINTN menucount = 3, i = 0;
EFI_STATUS efi_status;
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
- UINT8 auth[SHA256_DIGEST_SIZE];
- UINTN auth_size = SHA256_DIGEST_SIZE;
+ UINT8 auth[AUTH_LEN];
+ UINTN auth_size = AUTH_LEN;
UINT32 attributes;
if (verify_pw() == FALSE)
@@ -1744,14 +1785,16 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle,
&shim_lock_guid,
&attributes, &auth_size, auth);
- if ((efi_status == EFI_SUCCESS) && (auth_size == SHA256_DIGEST_SIZE))
+ if ((efi_status == EFI_SUCCESS) &&
+ (auth_size == SHA256_DIGEST_SIZE || auth_size == AUTH_LEN))
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))
+ if ((efi_status == EFI_SUCCESS) &&
+ (auth_size == SHA256_DIGEST_SIZE || auth_size == AUTH_LEN))
MokDelAuth = 1;
if (MokNew || MokAuth)
--
1.7.10.4
From cf448e938a54ee3006f0fca214b83e0a40499ea5 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Fri, 18 Jan 2013 15:51:02 +0800
Subject: [PATCH 2/2] Extend the password hash format
Several new fields were added to support hash from /etc/shadow.
Affected variables: MokAuth, MokDelAuth, MokPW, MokPWStore
[Hash Method][Interation Count][Salt Size][Salt][hash]
Besides, the password is converted to a 8-bit char array before
hashing with salt.
---
MokManager.c | 145 +++++++++++++++++++++++++++++++++-----------------------
PasswordHash.h | 23 +++++++++
2 files changed, 110 insertions(+), 58 deletions(-)
create mode 100644 PasswordHash.h
diff --git a/MokManager.c b/MokManager.c
index be2a764..9c8f32f 100644
--- a/MokManager.c
+++ b/MokManager.c
@@ -5,6 +5,7 @@
#include "shim.h"
#include "signature.h"
#include "PeImage.h"
+#include "PasswordHash.h"
#define PASSWORD_MAX 16
#define PASSWORD_MIN 8
@@ -19,9 +20,6 @@
#define CERT_STRING L"Select an X509 certificate to enroll:\n\n"
#define HASH_STRING L"Select a file to trust:\n\n"
-#define SALT_LEN 16
-#define AUTH_LEN (SALT_LEN + SHA256_DIGEST_SIZE)
-
struct menu_item {
CHAR16 *text;
INTN (* callback)(void *data, void *data2, void *data3);
@@ -553,8 +551,8 @@ static UINT8 get_line (UINT32 *length, CHAR16 *line, UINT32 line_max, UINT8 show
return 1;
}
-static EFI_STATUS compute_pw_hash (void *MokNew, UINTN MokNewSize, CHAR16 *password,
- UINT32 pw_length, UINT8 *hash)
+static EFI_STATUS compute_pw_hash (void *Data, UINTN DataSize, UINT8 *password,
+ UINT32 pw_length, UINT8 *hash)
{
EFI_STATUS status;
unsigned int ctxsize;
@@ -574,15 +572,15 @@ static EFI_STATUS compute_pw_hash (void *MokNew, UINTN MokNewSize, CHAR16 *passw
goto done;
}
- if (MokNew && MokNewSize) {
- if (!(Sha256Update(ctx, MokNew, MokNewSize))) {
+ if (Data && DataSize) {
+ if (!(Sha256Update(ctx, Data, DataSize))) {
Print(L"Unable to generate hash\n");
status = EFI_OUT_OF_RESOURCES;
goto done;
}
}
- if (!(Sha256Update(ctx, password, pw_length * sizeof(CHAR16)))) {
+ if (!(Sha256Update(ctx, password, pw_length))) {
Print(L"Unable to generate hash\n");
status = EFI_OUT_OF_RESOURCES;
goto done;
@@ -599,15 +597,34 @@ done:
return status;
}
-static EFI_STATUS match_password (void *Data, UINTN DataSize,
- UINT8 auth[SHA256_DIGEST_SIZE],
- CHAR16 *prompt)
+static EFI_STATUS match_password (PASSWORD_HASH *pw_hash,
+ void *Data, UINTN DataSize,
+ UINT8 *auth, CHAR16 *prompt)
{
EFI_STATUS efi_status;
UINT8 hash[SHA256_DIGEST_SIZE];
+ UINT8 *auth_hash;
+ UINT32 auth_size;
CHAR16 password[PASSWORD_MAX];
UINT32 pw_length;
UINT8 fail_count = 0;
+ int i;
+
+ if (pw_hash) {
+ /*
+ * Only support sha256 now and ignore iter_count
+ */
+ if(pw_hash->method != SHA256_BASED)
+ return EFI_INVALID_PARAMETER;
+ auth_hash = pw_hash->hash;
+ /* FIXME assign auth_size according to pw_hash->method */
+ auth_size = SHA256_DIGEST_SIZE;
+ } else if (auth) {
+ auth_hash = auth;
+ auth_size = SHA256_DIGEST_SIZE;
+ } else {
+ return EFI_INVALID_PARAMETER;
+ }
while (fail_count < 3) {
if (prompt) {
@@ -623,16 +640,31 @@ static EFI_STATUS match_password (void *Data, UINTN DataSize,
continue;
}
- efi_status = compute_pw_hash(Data, DataSize, password,
- pw_length, hash);
-
+ /*
+ * Compute password hash
+ */
+ if (pw_hash) {
+ char pw_ascii[PASSWORD_MAX];
+ for (i = 0; i < pw_length; i++)
+ pw_ascii[i] = (char)password[i];
+
+ /* FIXME calculate a proper salt_size */
+ efi_status = compute_pw_hash(pw_hash->salt, (pw_hash->salt_size)/8,
+ (UINT8 *)pw_ascii, pw_length, hash);
+ } else {
+ /*
+ * For backward compatibility
+ */
+ efi_status = compute_pw_hash(Data, DataSize, (UINT8 *)password,
+ pw_length * sizeof(CHAR16), 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) {
+ if (CompareMem(auth_hash, hash, auth_size) != 0) {
Print(L"Password doesn't match\n");
fail_count++;
continue;
@@ -651,29 +683,28 @@ static EFI_STATUS store_keys (void *MokNew, UINTN MokNewSize, int authenticate)
{
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
EFI_STATUS efi_status;
- UINT8 data[AUTH_LEN], *auth, *salt;
- UINTN auth_size = AUTH_LEN;
+ UINT8 auth[PASSWORD_HASH_SIZE];
+ UINTN auth_size = PASSWORD_HASH_SIZE;
UINT32 attributes;
if (authenticate) {
efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokAuth",
&shim_lock_guid,
- &attributes, &auth_size, data);
-
+ &attributes, &auth_size, auth);
if (efi_status != EFI_SUCCESS ||
- (auth_size != SHA256_DIGEST_SIZE && auth_size != AUTH_LEN)) {
+ (auth_size != SHA256_DIGEST_SIZE &&
+ auth_size != PASSWORD_HASH_SIZE)) {
Print(L"Failed to get MokAuth %d\n", efi_status);
return efi_status;
}
- if (auth_size == AUTH_LEN) {
- salt = data;
- auth = data + SALT_LEN;
- efi_status = match_password(salt, SALT_LEN, auth, NULL);
+ if (auth_size == PASSWORD_HASH_SIZE) {
+ efi_status = match_password((PASSWORD_HASH *)auth,
+ NULL, 0, NULL, NULL);
} else {
- auth = data;
- efi_status = match_password(MokNew, MokNewSize, auth, NULL);
+ efi_status = match_password(NULL, MokNew, MokNewSize,
+ auth, NULL);
}
if (efi_status != EFI_SUCCESS)
return EFI_ACCESS_DENIED;
@@ -852,8 +883,8 @@ static EFI_STATUS delete_keys (void *MokDel, UINTN MokDelSize)
{
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
EFI_STATUS efi_status;
- UINT8 data[AUTH_LEN], *auth, *salt;;
- UINTN auth_size = AUTH_LEN;
+ UINT8 auth[PASSWORD_HASH_SIZE];
+ UINTN auth_size = PASSWORD_HASH_SIZE;
UINT32 attributes;
void *MokListData = NULL;
UINTN MokListDataSize = 0;
@@ -863,21 +894,19 @@ static EFI_STATUS delete_keys (void *MokDel, UINTN MokDelSize)
efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokDelAuth",
&shim_lock_guid,
- &attributes, &auth_size, data);
+ &attributes, &auth_size, auth);
if (efi_status != EFI_SUCCESS ||
- (auth_size != SHA256_DIGEST_SIZE && auth_size != AUTH_LEN)) {
+ (auth_size != SHA256_DIGEST_SIZE && auth_size != PASSWORD_HASH_SIZE)) {
Print(L"Failed to get MokDelAuth %d\n", efi_status);
return efi_status;
}
- if (auth_size == AUTH_LEN) {
- salt = data;
- auth = data + SALT_LEN;
- efi_status = match_password(salt, SALT_LEN, auth, NULL);
+ if (auth_size == PASSWORD_HASH_SIZE) {
+ efi_status = match_password((PASSWORD_HASH *)auth, NULL, 0,
+ NULL, NULL);
} else {
- auth = data;
- efi_status = match_password(MokDel, MokDelSize, auth, NULL);
+ efi_status = match_password(NULL, MokDel, MokDelSize, auth, NULL);
}
if (efi_status != EFI_SUCCESS)
return EFI_ACCESS_DENIED;
@@ -1070,22 +1099,22 @@ 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 hash[AUTH_LEN], *auth, *salt;
+ UINT8 hash[PASSWORD_HASH_SIZE];
UINT8 clear = 0;
UINT32 length;
CHAR16 line[1];
- if (MokPWSize != SHA256_DIGEST_SIZE && MokPWSize != AUTH_LEN) {
+ if (MokPWSize != SHA256_DIGEST_SIZE && MokPWSize != PASSWORD_HASH_SIZE) {
Print(L"Invalid MokPW variable contents\n");
return -1;
}
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
- SetMem(hash, AUTH_LEN, 0);
+ SetMem(hash, PASSWORD_HASH_SIZE, 0);
- if (MokPWSize == AUTH_LEN) {
- if (CompareMem(MokPW, hash, AUTH_LEN) == 0)
+ if (MokPWSize == PASSWORD_HASH_SIZE) {
+ if (CompareMem(MokPW, hash, PASSWORD_HASH_SIZE) == 0)
clear = 1;
} else {
if (CompareMem(MokPW, hash, SHA256_DIGEST_SIZE) == 0)
@@ -1107,12 +1136,12 @@ static INTN mok_pw_prompt (void *MokPW, void *data2, void *data3) {
return 0;
}
- if (MokPWSize == AUTH_LEN) {
- salt = MokPW;
- auth = MokPW + SALT_LEN;
- efi_status = match_password(salt, SALT_LEN, auth, L"Confirm MOK passphrase: ");
+ if (MokPWSize == PASSWORD_HASH_SIZE) {
+ efi_status = match_password((PASSWORD_HASH *)MokPW, NULL, 0,
+ NULL, L"Confirm MOK passphrase: ");
} else {
- efi_status = match_password(NULL, 0, MokPW, L"Confirm MOK passphrase: ");
+ efi_status = match_password(NULL, NULL, 0, MokPW,
+ L"Confirm MOK passphrase: ");
}
if (efi_status != EFI_SUCCESS) {
@@ -1725,8 +1754,8 @@ static BOOLEAN verify_pw(void)
{
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
EFI_STATUS efi_status;
- UINT8 pwhash[AUTH_LEN], *auth, *salt;
- UINTN size = AUTH_LEN;
+ UINT8 pwhash[PASSWORD_HASH_SIZE];
+ UINTN size = PASSWORD_HASH_SIZE;
UINT32 attributes;
efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokPWStore",
@@ -1739,7 +1768,7 @@ static BOOLEAN verify_pw(void)
* purely because of a failure to read the variable
*/
if (efi_status != EFI_SUCCESS ||
- (size != SHA256_DIGEST_SIZE && size != AUTH_LEN))
+ (size != SHA256_DIGEST_SIZE && size != PASSWORD_HASH_SIZE))
return TRUE;
if (attributes & EFI_VARIABLE_RUNTIME_ACCESS)
@@ -1747,12 +1776,12 @@ static BOOLEAN verify_pw(void)
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
- if (size == AUTH_LEN) {
- salt = pwhash;
- auth = pwhash + SALT_LEN;
- efi_status = match_password(salt, SALT_LEN, auth, L"Enter MOK password: ");
+ if (size == PASSWORD_HASH_SIZE) {
+ efi_status = match_password((PASSWORD_HASH *)pwhash, NULL, 0,
+ NULL, L"Enter MOK password: ");
} else {
- efi_status = match_password(NULL, 0, pwhash, L"Enter MOK password: ");
+ efi_status = match_password(NULL, NULL, 0, pwhash,
+ L"Enter MOK password: ");
}
if (efi_status != EFI_SUCCESS) {
Print(L"Password limit reached\n");
@@ -1774,8 +1803,8 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle,
UINTN menucount = 3, i = 0;
EFI_STATUS efi_status;
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
- UINT8 auth[AUTH_LEN];
- UINTN auth_size = AUTH_LEN;
+ UINT8 auth[PASSWORD_HASH_SIZE];
+ UINTN auth_size = PASSWORD_HASH_SIZE;
UINT32 attributes;
if (verify_pw() == FALSE)
@@ -1786,7 +1815,7 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle,
&attributes, &auth_size, auth);
if ((efi_status == EFI_SUCCESS) &&
- (auth_size == SHA256_DIGEST_SIZE || auth_size == AUTH_LEN))
+ (auth_size == SHA256_DIGEST_SIZE || auth_size == PASSWORD_HASH_SIZE))
MokAuth = 1;
efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokDelAuth",
@@ -1794,7 +1823,7 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle,
&attributes, &auth_size, auth);
if ((efi_status == EFI_SUCCESS) &&
- (auth_size == SHA256_DIGEST_SIZE || auth_size == AUTH_LEN))
+ (auth_size == SHA256_DIGEST_SIZE || auth_size == PASSWORD_HASH_SIZE))
MokDelAuth = 1;
if (MokNew || MokAuth)
diff --git a/PasswordHash.h b/PasswordHash.h
new file mode 100644
index 0000000..70ee441
--- /dev/null
+++ b/PasswordHash.h
@@ -0,0 +1,23 @@
+#ifndef __PASSWORD_HASH_H__
+#define __PASSWORD_HASH_H__
+
+#define PASSWORD_HASH_SIZE 88
+
+enum HashMethod {
+ Tranditional_DES = 0,
+ Extend_BSDI_DES,
+ MD5_BASED,
+ SHA256_BASED,
+ SHA512_BASED,
+ BLOWFISH_BASED
+};
+
+typedef struct {
+ UINT16 method;
+ UINT32 iter_count;
+ UINT16 salt_size;
+ UINT8 salt[16];
+ UINT8 hash[64];
+} __attribute__ ((packed)) PASSWORD_HASH;
+
+#endif /* __PASSWORD_HASH_H__ */
--
1.7.10.4

View File

@ -1,31 +1,28 @@
From d046361f872467ed4a8481968ffb089596f6ae30 Mon Sep 17 00:00:00 2001
From 1c373e8acff0bd08cfd6a596d2df732fd5324627 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Wed, 23 Jan 2013 18:33:01 +0800
Subject: [PATCH 1/6] Adopt the crypt_r() hash style
Date: Tue, 15 Jan 2013 18:01:41 +0800
Subject: [PATCH 1/5] MokManager: support crypt() password hash
1. This commit implements the sha256-based hash method used in crypt_r()
in glibc.
The password format is introduced for the password hash generated by crypt(),
so that the user can import the password hash from /etc/shadow. The packager,
especially those who packages 3rd party drivers, can utilize this feature to
import a 3rd party certificate without interfering the package installation.
2. The password length now is allowed to be 1 to 256 characters.
3. The size of password hash structure is changed and the extra space
is reserved for the future use.
This commit implements the sha256-based crypt() hash function.
---
Makefile | 6 +--
MokManager.c | 88 +++++++++++++++++++--------------------
PasswordCrypt.c | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
PasswordCrypt.h | 26 ++++++++++++
PasswordHash.h | 23 -----------
5 files changed, 196 insertions(+), 71 deletions(-)
Makefile | 6 +--
MokManager.c | 151 +++++++++++++++++++++++++++++++++++++++++---------------
PasswordCrypt.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++
PasswordCrypt.h | 26 ++++++++++
4 files changed, 264 insertions(+), 43 deletions(-)
create mode 100644 PasswordCrypt.c
create mode 100644 PasswordCrypt.h
delete mode 100644 PasswordHash.h
diff --git a/Makefile b/Makefile
index 412eba5..321c3f5 100644
index 50b5898..fa303e4 100644
--- a/Makefile
+++ b/Makefile
@@ -32,8 +32,8 @@ TARGET = shim.efi MokManager.efi.signed
@@ -36,8 +36,8 @@ TARGET = shim.efi MokManager.efi.signed fallback.efi.signed
OBJS = shim.o netboot.o cert.o dbx.o
KEYS = shim_cert.h ocsp.* ca.* shim.crt shim.csr shim.p12 shim.pem shim.key
SOURCES = shim.c shim.h netboot.c signature.h PeImage.h
@ -33,29 +30,31 @@ index 412eba5..321c3f5 100644
-MOK_SOURCES = MokManager.c shim.h
+MOK_OBJS = MokManager.o PasswordCrypt.o
+MOK_SOURCES = MokManager.c shim.h PasswordCrypt.c PasswordCrypt.h
FALLBACK_OBJS = fallback.o
FALLBACK_SRCS = fallback.c
all: $(TARGET)
@@ -65,7 +65,7 @@ dbx.o : dbx.S
shim.so: $(OBJS) Cryptlib/libcryptlib.a Cryptlib/OpenSSL/libopenssl.a
@@ -76,7 +76,7 @@ fallback.o: $(FALLBACK_SRCS)
fallback.so: $(FALLBACK_OBJS)
$(LD) -o $@ $(LDFLAGS) $^ $(EFI_LIBS)
-MokManager.o: $(SOURCES)
+MokManager.o: $(MOK_SOURCES)
MokManager.so: $(MOK_OBJS) Cryptlib/libcryptlib.a Cryptlib/OpenSSL/libopenssl.a
$(LD) -o $@ $(LDFLAGS) $^ $(EFI_LIBS)
MokManager.so: $(MOK_OBJS) Cryptlib/libcryptlib.a Cryptlib/OpenSSL/libopenssl.a lib/lib.a
$(LD) -o $@ $(LDFLAGS) $^ $(EFI_LIBS) lib/lib.a
diff --git a/MokManager.c b/MokManager.c
index 9c8f32f..6b0e6f3 100644
index 60e799a..6cf24e6 100644
--- a/MokManager.c
+++ b/MokManager.c
@@ -5,11 +5,11 @@
@@ -5,13 +5,14 @@
#include "shim.h"
#include "signature.h"
#include "PeImage.h"
-#include "PasswordHash.h"
+#include "PasswordCrypt.h"
#include "include/console.h"
#include "include/simple_file.h"
-#define PASSWORD_MAX 16
-#define PASSWORD_MIN 8
-#define SB_PASSWORD_LEN 8
@ -65,7 +64,7 @@ index 9c8f32f..6b0e6f3 100644
#ifndef SHIM_VENDOR
#define SHIM_VENDOR L"Shim"
@@ -38,7 +38,7 @@ typedef struct {
@@ -28,7 +29,7 @@ typedef struct {
typedef struct {
UINT32 MokSBState;
UINT32 PWLen;
@ -74,219 +73,288 @@ index 9c8f32f..6b0e6f3 100644
} __attribute__ ((packed)) MokSBvar;
static EFI_STATUS get_variable (CHAR16 *name, EFI_GUID guid, UINT32 *attributes,
@@ -597,11 +597,11 @@ done:
@@ -571,8 +572,8 @@ static UINT8 get_line (UINT32 *length, CHAR16 *line, UINT32 line_max, UINT8 show
return 1;
}
-static EFI_STATUS compute_pw_hash (void *MokNew, UINTN MokNewSize, CHAR16 *password,
- UINT32 pw_length, UINT8 *hash)
+static EFI_STATUS compute_pw_hash (void *Data, UINTN DataSize, UINT8 *password,
+ UINT32 pw_length, UINT8 *hash)
{
EFI_STATUS status;
unsigned int ctxsize;
@@ -592,15 +593,15 @@ static EFI_STATUS compute_pw_hash (void *MokNew, UINTN MokNewSize, CHAR16 *passw
goto done;
}
- if (MokNew && MokNewSize) {
- if (!(Sha256Update(ctx, MokNew, MokNewSize))) {
+ if (Data && DataSize) {
+ if (!(Sha256Update(ctx, Data, DataSize))) {
console_notify(L"Unable to generate hash");
status = EFI_OUT_OF_RESOURCES;
goto done;
}
}
- if (!(Sha256Update(ctx, password, pw_length * sizeof(CHAR16)))) {
+ if (!(Sha256Update(ctx, password, pw_length))) {
console_notify(L"Unable to generate hash");
status = EFI_OUT_OF_RESOURCES;
goto done;
@@ -617,15 +618,34 @@ done:
return status;
}
-static EFI_STATUS match_password (PASSWORD_HASH *pw_hash,
-static EFI_STATUS match_password (void *Data, UINTN DataSize,
- UINT8 auth[SHA256_DIGEST_SIZE],
- CHAR16 *prompt)
+static EFI_STATUS match_password (PASSWORD_CRYPT *pw_crypt,
void *Data, UINTN DataSize,
UINT8 *auth, CHAR16 *prompt)
+ void *Data, UINTN DataSize,
+ UINT8 *auth, CHAR16 *prompt)
{
- EFI_STATUS efi_status;
+ EFI_STATUS status;
UINT8 hash[SHA256_DIGEST_SIZE];
UINT8 *auth_hash;
UINT32 auth_size;
@@ -610,14 +610,14 @@ static EFI_STATUS match_password (PASSWORD_HASH *pw_hash,
+ UINT8 *auth_hash;
+ UINT32 auth_size;
CHAR16 password[PASSWORD_MAX];
UINT32 pw_length;
UINT8 fail_count = 0;
int i;
- if (pw_hash) {
+ int i;
+
+ if (pw_crypt) {
/*
- * Only support sha256 now and ignore iter_count
+ /*
+ * Only support sha256 now
*/
- if(pw_hash->method != SHA256_BASED)
+ */
+ if(pw_crypt->method != SHA256_BASED)
return EFI_INVALID_PARAMETER;
- auth_hash = pw_hash->hash;
- /* FIXME assign auth_size according to pw_hash->method */
+ return EFI_INVALID_PARAMETER;
+ auth_hash = pw_crypt->hash;
+ /* FIXME assign auth_size according to pw_crypt->method */
auth_size = SHA256_DIGEST_SIZE;
} else if (auth) {
auth_hash = auth;
@@ -643,22 +643,20 @@ static EFI_STATUS match_password (PASSWORD_HASH *pw_hash,
/*
* Compute password hash
*/
- if (pw_hash) {
+ if (pw_crypt) {
char pw_ascii[PASSWORD_MAX];
for (i = 0; i < pw_length; i++)
pw_ascii[i] = (char)password[i];
+ auth_size = SHA256_DIGEST_SIZE;
+ } else if (auth) {
+ auth_hash = auth;
+ auth_size = SHA256_DIGEST_SIZE;
+ } else {
+ return EFI_INVALID_PARAMETER;
+ }
- /* FIXME calculate a proper salt_size */
- efi_status = compute_pw_hash(pw_hash->salt, (pw_hash->salt_size)/8,
- (UINT8 *)pw_ascii, pw_length, hash);
while (fail_count < 3) {
if (prompt) {
@@ -641,16 +661,30 @@ static EFI_STATUS match_password (void *Data, UINTN DataSize,
continue;
}
- efi_status = compute_pw_hash(Data, DataSize, password,
- pw_length, hash);
+ /*
+ * Compute password hash
+ */
+ if (pw_crypt) {
+ char pw_ascii[PASSWORD_MAX + 1];
+ for (i = 0; i < pw_length; i++)
+ pw_ascii[i] = (char)password[i];
+ pw_ascii[pw_length] = '\0';
- if (efi_status != EFI_SUCCESS) {
+ status = password_crypt(pw_ascii, pw_length, pw_crypt, hash);
} else {
/*
* For backward compatibility
*/
- efi_status = compute_pw_hash(Data, DataSize, (UINT8 *)password,
- pw_length * sizeof(CHAR16), hash);
+ } else {
+ /*
+ * For backward compatibility
+ */
+ status = compute_pw_hash(Data, DataSize, (UINT8 *)password,
+ pw_length * sizeof(CHAR16), hash);
}
- if (efi_status != EFI_SUCCESS) {
+ }
+ if (status != EFI_SUCCESS) {
Print(L"Unable to generate password hash\n");
fail_count++;
continue;
@@ -683,8 +681,8 @@ static EFI_STATUS store_keys (void *MokNew, UINTN MokNewSize, int authenticate)
}
- if (CompareMem(auth, hash, SHA256_DIGEST_SIZE) != 0) {
+ if (CompareMem(auth_hash, hash, auth_size) != 0) {
Print(L"Password doesn't match\n");
fail_count++;
continue;
@@ -669,23 +703,29 @@ static EFI_STATUS store_keys (void *MokNew, UINTN MokNewSize, int authenticate)
{
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
EFI_STATUS efi_status;
- UINT8 auth[PASSWORD_HASH_SIZE];
- UINTN auth_size = PASSWORD_HASH_SIZE;
- UINT8 auth[SHA256_DIGEST_SIZE];
- UINTN auth_size;
+ UINT8 auth[PASSWORD_CRYPT_SIZE];
+ UINTN auth_size = PASSWORD_CRYPT_SIZE;
UINT32 attributes;
if (authenticate) {
@@ -694,13 +692,13 @@ static EFI_STATUS store_keys (void *MokNew, UINTN MokNewSize, int authenticate)
- 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 &&
- auth_size != PASSWORD_HASH_SIZE)) {
-
- if (efi_status != EFI_SUCCESS || auth_size != SHA256_DIGEST_SIZE) {
+ if (efi_status != EFI_SUCCESS ||
+ (auth_size != SHA256_DIGEST_SIZE &&
+ auth_size != PASSWORD_CRYPT_SIZE)) {
Print(L"Failed to get MokAuth %d\n", efi_status);
console_error(L"Failed to get MokAuth", efi_status);
return efi_status;
}
- if (auth_size == PASSWORD_HASH_SIZE) {
- efi_status = match_password((PASSWORD_HASH *)auth,
- efi_status = match_password(MokNew, MokNewSize, auth, NULL);
+ if (auth_size == PASSWORD_CRYPT_SIZE) {
+ efi_status = match_password((PASSWORD_CRYPT *)auth,
NULL, 0, NULL, NULL);
} else {
efi_status = match_password(NULL, MokNew, MokNewSize,
@@ -883,8 +881,8 @@ static EFI_STATUS delete_keys (void *MokDel, UINTN MokDelSize)
+ NULL, 0, NULL, NULL);
+ } else {
+ efi_status = match_password(NULL, MokNew, MokNewSize,
+ auth, NULL);
+ }
if (efi_status != EFI_SUCCESS)
return EFI_ACCESS_DENIED;
}
@@ -839,8 +879,8 @@ static EFI_STATUS delete_keys (void *MokDel, UINTN MokDelSize)
{
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
EFI_STATUS efi_status;
- UINT8 auth[PASSWORD_HASH_SIZE];
- UINTN auth_size = PASSWORD_HASH_SIZE;
- UINT8 auth[SHA256_DIGEST_SIZE];
- UINTN auth_size = SHA256_DIGEST_SIZE;
+ UINT8 auth[PASSWORD_CRYPT_SIZE];
+ UINTN auth_size = PASSWORD_CRYPT_SIZE;
UINT32 attributes;
void *MokListData = NULL;
UINTN MokListDataSize = 0;
@@ -897,13 +895,13 @@ static EFI_STATUS delete_keys (void *MokDel, UINTN MokDelSize)
@@ -852,12 +892,18 @@ static EFI_STATUS delete_keys (void *MokDel, UINTN MokDelSize)
&shim_lock_guid,
&attributes, &auth_size, auth);
if (efi_status != EFI_SUCCESS ||
- (auth_size != SHA256_DIGEST_SIZE && auth_size != PASSWORD_HASH_SIZE)) {
- if (efi_status != EFI_SUCCESS || auth_size != SHA256_DIGEST_SIZE) {
+ if (efi_status != EFI_SUCCESS ||
+ (auth_size != SHA256_DIGEST_SIZE && auth_size != PASSWORD_CRYPT_SIZE)) {
Print(L"Failed to get MokDelAuth %d\n", efi_status);
console_error(L"Failed to get MokDelAuth", efi_status);
return efi_status;
}
- if (auth_size == PASSWORD_HASH_SIZE) {
- efi_status = match_password((PASSWORD_HASH *)auth, NULL, 0,
- efi_status = match_password(MokDel, MokDelSize, auth, NULL);
+ if (auth_size == PASSWORD_CRYPT_SIZE) {
+ efi_status = match_password((PASSWORD_CRYPT *)auth, NULL, 0,
NULL, NULL);
} else {
efi_status = match_password(NULL, MokDel, MokDelSize, auth, NULL);
@@ -1099,22 +1097,22 @@ static INTN mok_pw_prompt (void *MokPW, void *data2, void *data3) {
+ NULL, NULL);
+ } else {
+ efi_status = match_password(NULL, MokDel, MokDelSize, auth, NULL);
+ }
if (efi_status != EFI_SUCCESS)
return EFI_ACCESS_DENIED;
@@ -1030,18 +1076,27 @@ static INTN mok_sb_prompt (void *MokSB, UINTN MokSBSize) {
static INTN mok_pw_prompt (void *MokPW, UINTN MokPWSize) {
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
EFI_STATUS efi_status;
UINTN MokPWSize = (UINTN)data2;
- UINT8 hash[PASSWORD_HASH_SIZE];
- UINT8 hash[SHA256_DIGEST_SIZE];
+ UINT8 hash[PASSWORD_CRYPT_SIZE];
UINT8 clear = 0;
UINT32 length;
CHAR16 line[1];
+ UINT8 clear = 0;
- if (MokPWSize != SHA256_DIGEST_SIZE && MokPWSize != PASSWORD_HASH_SIZE) {
- if (MokPWSize != SHA256_DIGEST_SIZE) {
+ if (MokPWSize != SHA256_DIGEST_SIZE && MokPWSize != PASSWORD_CRYPT_SIZE) {
Print(L"Invalid MokPW variable contents\n");
console_notify(L"Invalid MokPW variable contents");
return -1;
}
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
- SetMem(hash, PASSWORD_HASH_SIZE, 0);
- SetMem(hash, SHA256_DIGEST_SIZE, 0);
+ SetMem(hash, PASSWORD_CRYPT_SIZE, 0);
- if (MokPWSize == PASSWORD_HASH_SIZE) {
- if (CompareMem(MokPW, hash, PASSWORD_HASH_SIZE) == 0)
+
+ if (MokPWSize == PASSWORD_CRYPT_SIZE) {
+ if (CompareMem(MokPW, hash, PASSWORD_CRYPT_SIZE) == 0)
clear = 1;
} else {
if (CompareMem(MokPW, hash, SHA256_DIGEST_SIZE) == 0)
@@ -1136,8 +1134,8 @@ static INTN mok_pw_prompt (void *MokPW, void *data2, void *data3) {
+ clear = 1;
+ } else {
+ if (CompareMem(MokPW, hash, SHA256_DIGEST_SIZE) == 0)
+ clear = 1;
+ }
- if (CompareMem(MokPW, hash, SHA256_DIGEST_SIZE) == 0) {
+ if (clear) {
if (console_yes_no((CHAR16 *[]){L"Clear MOK password?", NULL}) == 0)
return 0;
@@ -1050,7 +1105,14 @@ static INTN mok_pw_prompt (void *MokPW, UINTN MokPWSize) {
return 0;
}
- if (MokPWSize == PASSWORD_HASH_SIZE) {
- efi_status = match_password((PASSWORD_HASH *)MokPW, NULL, 0,
- efi_status = match_password(NULL, 0, MokPW, L"Confirm MOK passphrase: ");
+ if (MokPWSize == PASSWORD_CRYPT_SIZE) {
+ efi_status = match_password((PASSWORD_CRYPT *)MokPW, NULL, 0,
NULL, L"Confirm MOK passphrase: ");
} else {
efi_status = match_password(NULL, NULL, 0, MokPW,
@@ -1754,8 +1752,8 @@ static BOOLEAN verify_pw(void)
+ NULL, L"Confirm MOK passphrase: ");
+ } else {
+ efi_status = match_password(NULL, NULL, 0, MokPW,
+ L"Confirm MOK passphrase: ");
+ }
+
if (efi_status != EFI_SUCCESS) {
console_notify(L"Password limit reached");
return -1;
@@ -1265,8 +1327,8 @@ static BOOLEAN verify_pw(void)
{
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
EFI_STATUS efi_status;
- UINT8 pwhash[PASSWORD_HASH_SIZE];
- UINTN size = PASSWORD_HASH_SIZE;
- UINT8 pwhash[SHA256_DIGEST_SIZE];
- UINTN size = SHA256_DIGEST_SIZE;
+ UINT8 pwhash[PASSWORD_CRYPT_SIZE];
+ UINTN size = PASSWORD_CRYPT_SIZE;
UINT32 attributes;
efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokPWStore",
@@ -1768,7 +1766,7 @@ static BOOLEAN verify_pw(void)
@@ -1278,7 +1340,8 @@ static BOOLEAN verify_pw(void)
* known value, so there's no safety advantage in failing to validate
* purely because of a failure to read the variable
*/
if (efi_status != EFI_SUCCESS ||
- (size != SHA256_DIGEST_SIZE && size != PASSWORD_HASH_SIZE))
- if (efi_status != EFI_SUCCESS)
+ if (efi_status != EFI_SUCCESS ||
+ (size != SHA256_DIGEST_SIZE && size != PASSWORD_CRYPT_SIZE))
return TRUE;
if (attributes & EFI_VARIABLE_RUNTIME_ACCESS)
@@ -1776,8 +1774,8 @@ static BOOLEAN verify_pw(void)
@@ -1286,7 +1349,13 @@ static BOOLEAN verify_pw(void)
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
- if (size == PASSWORD_HASH_SIZE) {
- efi_status = match_password((PASSWORD_HASH *)pwhash, NULL, 0,
- efi_status = match_password(NULL, 0, pwhash, L"Enter MOK password: ");
+ if (size == PASSWORD_CRYPT_SIZE) {
+ efi_status = match_password((PASSWORD_CRYPT *)pwhash, NULL, 0,
NULL, L"Enter MOK password: ");
} else {
efi_status = match_password(NULL, NULL, 0, pwhash,
@@ -1803,8 +1801,8 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle,
+ NULL, L"Enter MOK password: ");
+ } else {
+ efi_status = match_password(NULL, NULL, 0, pwhash,
+ L"Enter MOK password: ");
+ }
if (efi_status != EFI_SUCCESS) {
console_notify(L"Password limit reached");
return FALSE;
@@ -1320,8 +1389,8 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle,
UINTN menucount = 3, i = 0;
EFI_STATUS efi_status;
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
- UINT8 auth[PASSWORD_HASH_SIZE];
- UINTN auth_size = PASSWORD_HASH_SIZE;
- UINT8 auth[SHA256_DIGEST_SIZE];
- UINTN auth_size = SHA256_DIGEST_SIZE;
+ UINT8 auth[PASSWORD_CRYPT_SIZE];
+ UINTN auth_size = PASSWORD_CRYPT_SIZE;
UINT32 attributes;
EFI_STATUS ret = EFI_SUCCESS;
if (verify_pw() == FALSE)
@@ -1815,7 +1813,7 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle,
@@ -1332,14 +1401,16 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle,
&shim_lock_guid,
&attributes, &auth_size, auth);
if ((efi_status == EFI_SUCCESS) &&
- (auth_size == SHA256_DIGEST_SIZE || auth_size == PASSWORD_HASH_SIZE))
- if ((efi_status == EFI_SUCCESS) && (auth_size == SHA256_DIGEST_SIZE))
+ if ((efi_status == EFI_SUCCESS) &&
+ (auth_size == SHA256_DIGEST_SIZE || auth_size == PASSWORD_CRYPT_SIZE))
MokAuth = 1;
efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokDelAuth",
@@ -1823,7 +1821,7 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle,
&shim_lock_guid,
&attributes, &auth_size, auth);
if ((efi_status == EFI_SUCCESS) &&
- (auth_size == SHA256_DIGEST_SIZE || auth_size == PASSWORD_HASH_SIZE))
- if ((efi_status == EFI_SUCCESS) && (auth_size == SHA256_DIGEST_SIZE))
+ if ((efi_status == EFI_SUCCESS) &&
+ (auth_size == SHA256_DIGEST_SIZE || auth_size == PASSWORD_CRYPT_SIZE))
MokDelAuth = 1;
@ -453,69 +521,40 @@ index 0000000..c9e377a
+ const PASSWORD_CRYPT *pw_hash, UINT8 *hash);
+
+#endif /* __PASSWORD_CRYPT_H__ */
diff --git a/PasswordHash.h b/PasswordHash.h
deleted file mode 100644
index 70ee441..0000000
--- a/PasswordHash.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef __PASSWORD_HASH_H__
-#define __PASSWORD_HASH_H__
-
-#define PASSWORD_HASH_SIZE 88
-
-enum HashMethod {
- Tranditional_DES = 0,
- Extend_BSDI_DES,
- MD5_BASED,
- SHA256_BASED,
- SHA512_BASED,
- BLOWFISH_BASED
-};
-
-typedef struct {
- UINT16 method;
- UINT32 iter_count;
- UINT16 salt_size;
- UINT8 salt[16];
- UINT8 hash[64];
-} __attribute__ ((packed)) PASSWORD_HASH;
-
-#endif /* __PASSWORD_HASH_H__ */
--
1.7.10.4
1.8.1.4
From 1e3f6fa2e149980d337365d55728da74ed76fe1f Mon Sep 17 00:00:00 2001
From 7c52801530ff684044e97e4070b91816d75a5089 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Thu, 24 Jan 2013 18:24:49 +0800
Subject: [PATCH 2/6] Support SHA512-based crypt() hash
Subject: [PATCH 2/5] MokManager: support SHA512-based crypt() hash
---
Cryptlib/OpenSSL/Makefile | 2 +-
MokManager.c | 12 ++---
PasswordCrypt.c | 114 +++++++++++++++++++++++++++++++++++++++++++++
PasswordCrypt.h | 1 +
Cryptlib/OpenSSL/Makefile | 2 +-
MokManager.c | 12 ++---
PasswordCrypt.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++
PasswordCrypt.h | 1 +
4 files changed, 120 insertions(+), 9 deletions(-)
diff --git a/Cryptlib/OpenSSL/Makefile b/Cryptlib/OpenSSL/Makefile
index 7fde382..c44c008 100644
index 1960b6b..f8ab841 100644
--- a/Cryptlib/OpenSSL/Makefile
+++ b/Cryptlib/OpenSSL/Makefile
@@ -10,7 +10,7 @@ LIB_GCC = $(shell $(CC) -print-libgcc-file-name)
EFI_LIBS = -lefi -lgnuefi $(LIB_GCC)
CFLAGS = -ggdb -O0 -I. -I.. -I../Include/ -Icrypto -fno-stack-protector -fno-strict-aliasing -fpic -fshort-wchar -nostdinc \
- -Wall $(EFI_INCLUDES) -DOPENSSL_SYSNAME_UWIN -DOPENSSL_SYS_UEFI -DL_ENDIAN -DSIXTY_FOUR_BIT_LONG -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DOPENSSL_NO_CAMELLIA -DOPENSSL_NO_SEED -DOPENSSL_NO_RC5 -DOPENSSL_NO_MDC2 -DOPENSSL_NO_SOCK -DOPENSSL_NO_CMS -DOPENSSL_NO_JPAKE -DOPENSSL_NO_CAPIENG -DOPENSSL_NO_ERR -DOPENSSL_NO_KRB5 -DOPENSSL_NO_DYNAMIC_ENGINE -DGETPID_IS_MEANINGLESS -DOPENSSL_NO_STDIO -DOPENSSL_NO_FP_API -DOPENSSL_NO_DGRAM -DOPENSSL_NO_SHA0 -DOPENSSL_NO_SHA512 -DOPENSSL_NO_LHASH -DOPENSSL_NO_HW -DOPENSSL_NO_OCSP -DOPENSSL_NO_LOCKING -DOPENSSL_NO_DEPRECATED -DOPENSSL_SMALL_FOOTPRINT -DPEDANTIC -mno-red-zone
+ -Wall $(EFI_INCLUDES) -DOPENSSL_SYSNAME_UWIN -DOPENSSL_SYS_UEFI -DL_ENDIAN -DSIXTY_FOUR_BIT_LONG -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DOPENSSL_NO_CAMELLIA -DOPENSSL_NO_SEED -DOPENSSL_NO_RC5 -DOPENSSL_NO_MDC2 -DOPENSSL_NO_SOCK -DOPENSSL_NO_CMS -DOPENSSL_NO_JPAKE -DOPENSSL_NO_CAPIENG -DOPENSSL_NO_ERR -DOPENSSL_NO_KRB5 -DOPENSSL_NO_DYNAMIC_ENGINE -DGETPID_IS_MEANINGLESS -DOPENSSL_NO_STDIO -DOPENSSL_NO_FP_API -DOPENSSL_NO_DGRAM -DOPENSSL_NO_SHA0 -DOPENSSL_NO_LHASH -DOPENSSL_NO_HW -DOPENSSL_NO_OCSP -DOPENSSL_NO_LOCKING -DOPENSSL_NO_DEPRECATED -DOPENSSL_SMALL_FOOTPRINT -DPEDANTIC -mno-red-zone
CFLAGS = -ggdb -O0 -I. -I.. -I../Include/ -Icrypto -fno-stack-protector -fno-strict-aliasing -fpic -fshort-wchar -nostdinc -mno-mmx -mno-sse -mno-red-zone -maccumulate-outgoing-args \
- -Wall $(EFI_INCLUDES) -DOPENSSL_SYSNAME_UWIN -DOPENSSL_SYS_UEFI -DL_ENDIAN -DSIXTY_FOUR_BIT_LONG -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DOPENSSL_NO_CAMELLIA -DOPENSSL_NO_SEED -DOPENSSL_NO_RC5 -DOPENSSL_NO_MDC2 -DOPENSSL_NO_SOCK -DOPENSSL_NO_CMS -DOPENSSL_NO_JPAKE -DOPENSSL_NO_CAPIENG -DOPENSSL_NO_ERR -DOPENSSL_NO_KRB5 -DOPENSSL_NO_DYNAMIC_ENGINE -DGETPID_IS_MEANINGLESS -DOPENSSL_NO_STDIO -DOPENSSL_NO_FP_API -DOPENSSL_NO_DGRAM -DOPENSSL_NO_SHA0 -DOPENSSL_NO_SHA512 -DOPENSSL_NO_LHASH -DOPENSSL_NO_HW -DOPENSSL_NO_OCSP -DOPENSSL_NO_LOCKING -DOPENSSL_NO_DEPRECATED -DOPENSSL_SMALL_FOOTPRINT -DPEDANTIC
+ -Wall $(EFI_INCLUDES) -DOPENSSL_SYSNAME_UWIN -DOPENSSL_SYS_UEFI -DL_ENDIAN -DSIXTY_FOUR_BIT_LONG -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DOPENSSL_NO_CAMELLIA -DOPENSSL_NO_SEED -DOPENSSL_NO_RC5 -DOPENSSL_NO_MDC2 -DOPENSSL_NO_SOCK -DOPENSSL_NO_CMS -DOPENSSL_NO_JPAKE -DOPENSSL_NO_CAPIENG -DOPENSSL_NO_ERR -DOPENSSL_NO_KRB5 -DOPENSSL_NO_DYNAMIC_ENGINE -DGETPID_IS_MEANINGLESS -DOPENSSL_NO_STDIO -DOPENSSL_NO_FP_API -DOPENSSL_NO_DGRAM -DOPENSSL_NO_SHA0 -DOPENSSL_NO_LHASH -DOPENSSL_NO_HW -DOPENSSL_NO_OCSP -DOPENSSL_NO_LOCKING -DOPENSSL_NO_DEPRECATED -DOPENSSL_SMALL_FOOTPRINT -DPEDANTIC
ifeq ($(ARCH),x86_64)
CFLAGS += -DEFI_FUNCTION_WRAPPER
CFLAGS += -DEFI_FUNCTION_WRAPPER -DGNU_EFI_USE_MS_ABI
endif
diff --git a/MokManager.c b/MokManager.c
index 6b0e6f3..65465ec 100644
index 6cf24e6..b05a52f 100644
--- a/MokManager.c
+++ b/MokManager.c
@@ -602,7 +602,7 @@ static EFI_STATUS match_password (PASSWORD_CRYPT *pw_crypt,
@@ -623,7 +623,7 @@ static EFI_STATUS match_password (PASSWORD_CRYPT *pw_crypt,
UINT8 *auth, CHAR16 *prompt)
{
EFI_STATUS status;
@ -524,7 +563,7 @@ index 6b0e6f3..65465ec 100644
UINT8 *auth_hash;
UINT32 auth_size;
CHAR16 password[PASSWORD_MAX];
@@ -611,14 +611,10 @@ static EFI_STATUS match_password (PASSWORD_CRYPT *pw_crypt,
@@ -632,14 +632,10 @@ static EFI_STATUS match_password (PASSWORD_CRYPT *pw_crypt,
int i;
if (pw_crypt) {
@ -695,28 +734,28 @@ index c9e377a..144bf84 100644
#endif /* __PASSWORD_CRYPT_H__ */
--
1.7.10.4
1.8.1.4
From 4df0fbdeda91a42bad688c88f3cebb313ce99484 Mon Sep 17 00:00:00 2001
From df4644c036ff9d02cbcc08b5902eccb58e8bc305 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Fri, 25 Jan 2013 18:27:31 +0800
Subject: [PATCH 3/6] Support blowfish-based crypt() hash
Date: Fri, 17 May 2013 15:10:57 +0800
Subject: [PATCH 3/5] MokManager: support blowfish-based crypt() hash
---
Makefile | 4 +-
PasswordCrypt.c | 26 +-
crypt_blowfish.c | 822 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
crypt_blowfish.h | 22 ++
Makefile | 4 +-
PasswordCrypt.c | 26 +-
crypt_blowfish.c | 822 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
crypt_blowfish.h | 22 ++
4 files changed, 869 insertions(+), 5 deletions(-)
create mode 100644 crypt_blowfish.c
create mode 100644 crypt_blowfish.h
diff --git a/Makefile b/Makefile
index 321c3f5..b4916f1 100644
index fa303e4..77f3e52 100644
--- a/Makefile
+++ b/Makefile
@@ -32,8 +32,8 @@ TARGET = shim.efi MokManager.efi.signed
@@ -36,8 +36,8 @@ TARGET = shim.efi MokManager.efi.signed fallback.efi.signed
OBJS = shim.o netboot.o cert.o dbx.o
KEYS = shim_cert.h ocsp.* ca.* shim.crt shim.csr shim.p12 shim.pem shim.key
SOURCES = shim.c shim.h netboot.c signature.h PeImage.h
@ -724,8 +763,8 @@ index 321c3f5..b4916f1 100644
-MOK_SOURCES = MokManager.c shim.h PasswordCrypt.c PasswordCrypt.h
+MOK_OBJS = MokManager.o PasswordCrypt.o crypt_blowfish.o
+MOK_SOURCES = MokManager.c shim.h PasswordCrypt.c PasswordCrypt.h crypt_blowfish.c crypt_blowfish.h
all: $(TARGET)
FALLBACK_OBJS = fallback.o
FALLBACK_SRCS = fallback.c
diff --git a/PasswordCrypt.c b/PasswordCrypt.c
index a62512e..38b980f 100644
@ -1643,16 +1682,16 @@ index 0000000..dc3bd56
+ char *output, int size);
+#endif
--
1.7.10.4
1.8.1.4
From eeda23de3deaa6e13c51e1f831a72a2007029cfb Mon Sep 17 00:00:00 2001
From 05ad901e17bbc64f32ecffc64c6f3d253ecb099b Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Tue, 29 Jan 2013 12:09:34 +0800
Subject: [PATCH 4/6] Support MD5-based crypt() hash
Subject: [PATCH 4/5] MokManager: support MD5-based crypt() hash
---
PasswordCrypt.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
PasswordCrypt.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 67 insertions(+), 1 deletion(-)
diff --git a/PasswordCrypt.c b/PasswordCrypt.c
@ -1745,17 +1784,17 @@ index 38b980f..8483498 100644
status = sha256_crypt(password, pw_length, (char *)pw_crypt->salt,
pw_crypt->salt_size, pw_crypt->iter_count,
--
1.7.10.4
1.8.1.4
From cd8e7b8a25023523f30ed065b892aa2bb1b619d6 Mon Sep 17 00:00:00 2001
From 95d17e05d4bfdec193ae7c076542be496b2ae6e7 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Tue, 29 Jan 2013 17:10:10 +0800
Subject: [PATCH 5/6] Support Tradition DES hash
Subject: [PATCH 5/5] MokManager: support Tradition DES hash
---
PasswordCrypt.c | 28 +++++++++++++++++++++++-----
PasswordCrypt.h | 2 +-
PasswordCrypt.c | 28 +++++++++++++++++++++++-----
PasswordCrypt.h | 2 +-
2 files changed, 24 insertions(+), 6 deletions(-)
diff --git a/PasswordCrypt.c b/PasswordCrypt.c
@ -1835,34 +1874,5 @@ index 144bf84..b726f32 100644
MD5_BASED,
SHA256_BASED,
--
1.7.10.4
From 982d008347669cd6d5699764f23820b9c50d622f Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Tue, 29 Jan 2013 17:41:21 +0800
Subject: [PATCH 6/6] Append a null character to the ASCII password string
---
MokManager.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/MokManager.c b/MokManager.c
index 65465ec..e27c2c1 100644
--- a/MokManager.c
+++ b/MokManager.c
@@ -640,9 +640,10 @@ static EFI_STATUS match_password (PASSWORD_CRYPT *pw_crypt,
* Compute password hash
*/
if (pw_crypt) {
- char pw_ascii[PASSWORD_MAX];
+ char pw_ascii[PASSWORD_MAX + 1];
for (i = 0; i < pw_length; i++)
pw_ascii[i] = (char)password[i];
+ pw_ascii[pw_length] = '\0';
status = password_crypt(pw_ascii, pw_length, pw_crypt, hash);
} else {
--
1.7.10.4
1.8.1.4

File diff suppressed because it is too large Load Diff

View File

@ -1,94 +0,0 @@
From 10f0f58b03b3bcc56797744f25be15b226b51a50 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Mon, 10 Dec 2012 17:54:05 +0800
Subject: [PATCH 1/2] Clear the screen before erasing keys
---
MokManager.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/MokManager.c b/MokManager.c
index 5802d27..c6f84d8 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);
--
1.7.10.4
From 510dafda53cd56210d7ff634b1c630d3645150f0 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Mon, 10 Dec 2012 18:24:45 +0800
Subject: [PATCH 2/2] Reboot the system after enrolling/erasing keys
---
MokManager.c | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/MokManager.c b/MokManager.c
index c6f84d8..7d6650e 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;
--
1.7.10.4

View File

@ -1,763 +0,0 @@
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

View File

@ -1,11 +1,13 @@
Index: shim-0.2/Makefile
===================================================================
--- shim-0.2.orig/Makefile
+++ shim-0.2/Makefile
---
Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/Makefile
+++ b/Makefile
@@ -6,7 +6,7 @@ LIB_PATH = /usr/lib64
EFI_INCLUDE = /usr/include/efi
EFI_INCLUDES = -nostdinc -ICryptlib -ICryptlib/Include -I$(EFI_INCLUDE) -I$(EFI_INCLUDE)/$(ARCH) -I$(EFI_INCLUDE)/protocol
EFI_INCLUDES = -nostdinc -ICryptlib -ICryptlib/Include -I$(EFI_INCLUDE) -I$(EFI_INCLUDE)/$(ARCH) -I$(EFI_INCLUDE)/protocol
-EFI_PATH = /usr/lib64/gnuefi
+EFI_PATH = /usr/lib64

View File

@ -1,3 +1,33 @@
-------------------------------------------------------------------
Tue Jul 23 03:55:05 UTC 2013 - glin@suse.com
- Update to 0.4
- Rebase patches
+ shim-suse-build.patch
+ shim-mokmanager-support-crypt-hash-method.patch
+ shim-bnc804631-fix-broken-bootpath.patch
+ shim-bnc798043-no-doulbe-separators.patch
+ shim-bnc807760-change-pxe-2nd-loader-name.patch
+ shim-bnc808106-correct-certcount.patch
+ shim-mokmanager-ui-revamp.patch
- Add patches
+ shim-merge-lf-loader-code.patch: merge the Linux Foundation
loader UI code
+ shim-fix-pointer-casting.patch: fix a casting issue and the
size of an empty vendor cert
+ shim-fix-simple-file-selector.patch: fix the buffer allocation
in the simple file selector
- Remove upstreamed patches
+ shim-support-mok-delete.patch
+ shim-reboot-after-changes.patch
+ shim-clear-queued-key.patch
+ shim-local-key-sign-mokmanager.patch
+ shim-get-2nd-stage-loader.patch
+ shim-fix-loadoptions.patch
- Remove unused patch: shim-mokmanager-new-pw-hash.patch and
shim-keep-unsigned-mokmanager.patch
- Install the vendor certificate to /etc/uefi/certs
-------------------------------------------------------------------
Wed May 8 06:40:12 UTC 2013 - glin@suse.com

View File

@ -19,7 +19,7 @@
# needssslcertforbuild
Name: shim
Version: 0.2
Version: 0.4
Release: 0
Summary: UEFI shim loader
License: BSD-2-Clause
@ -35,35 +35,25 @@ Source3: shim-install
Source4: SLES-UEFI-CA-Certificate.crt
# PATCH-FIX-SUSE shim-suse-build.patch glin@suse.com -- Adjust Makefile for the build service
Patch0: shim-suse-build.patch
# PATCH-FIX-UPSTREAM shim-local-key-sign-mokmanager.patch glin@suse.com -- Sign MokManager.efi with the local generated certificate
Patch1: shim-local-key-sign-mokmanager.patch
# PATCH-FEATURE-UPSTREAM shim-get-2nd-stage-loader.patch glin@suse.com -- Get the second stage loader path from the load options
Patch2: shim-get-2nd-stage-loader.patch
# PATCH-FIX-UPSTREAM shim-reboot-after-changes.patch glin@suse.com -- Reboot the system after enrolling or erasing keys
Patch3: shim-reboot-after-changes.patch
# PATCH-FIX-UPSTREAM shim-clear-queued-key.patch glin@suse.com -- Clear the queued key to show the menu properly
Patch5: shim-clear-queued-key.patch
# PATCH-FIX-UPSTREAM shim-fix-loadoptions.patch bnc#798043 glin@suse.com -- Adopt the UEFI shell style LoadOptions
Patch6: shim-fix-loadoptions.patch
# PATCH-FIX-UPSTREAM shim-support-mok-delete.patch glin@suse.com -- Support for deleting specific keys
Patch7: shim-support-mok-delete.patch
# PATCH-FIX-UPSTREAM shim-mokmanager-new-pw-hash.patch glin@suse.com -- Support the new password hash
Patch8: shim-mokmanager-new-pw-hash.patch
# PATCH-FIX-UPSTREAM shim-fix-pointer-casting.patch glin@suse.com -- Fix a casting issue and the size of an empty vendor_cert or dbx_cert.
Patch1: shim-fix-pointer-casting.patch
# PATCH-FIX-UPSTREAM shim-merge-lf-loader-code.patch glin@suse.com -- Merge the Linux Foundation loader UI code
Patch2: shim-merge-lf-loader-code.patch
# PATCH-FIX-UPSTREAM shim-fix-simple-file-selector.patch glin@suse.com -- Fix the buffer allocation in the simple file selector
Patch3: shim-fix-simple-file-selector.patch
# PATCH-FIX-UPSTREAM shim-mokmanager-support-crypt-hash-method.patch glin@suse.com -- Support the password hashes from /etc/shadow
Patch9: shim-mokmanager-support-crypt-hash-method.patch
# PATCH-FIX-OPENSUSE shim-keep-unsigned-mokmanager.patch glin@suse.com -- Keep MokManager.efi and sign it with the openSUSE key later
Patch10: shim-keep-unsigned-mokmanager.patch
Patch4: shim-mokmanager-support-crypt-hash-method.patch
# PATCH-FIX-UPSTREAM shim-bnc804631-fix-broken-bootpath.patch bnc#804631 glin@suse.com -- Fix the broken bootpath generated in generate_path()
Patch11: shim-bnc804631-fix-broken-bootpath.patch
Patch5: shim-bnc804631-fix-broken-bootpath.patch
# PATCH-FIX-UPSTREAM shim-bnc798043-no-doulbe-separators.patch bnc#798043 glin@suse.com -- Remove all double-separators from the bootpath
Patch12: shim-bnc798043-no-doulbe-separators.patch
Patch6: shim-bnc798043-no-doulbe-separators.patch
# PATCH-FIX-UPSTREAM shim-bnc807760-change-pxe-2nd-loader-name.patch bnc#807760 glin@suse.com -- Change the PXE 2nd stage loader to match the filename we are using
Patch13: shim-bnc807760-change-pxe-2nd-loader-name.patch
Patch7: shim-bnc807760-change-pxe-2nd-loader-name.patch
# PATCH-FIX-UPSTREAM shim-bnc808106-correct-certcount.patch bnc#808106 glin@suse.com -- Correct the certifcate count of the signature list
Patch14: shim-bnc808106-correct-certcount.patch
Patch8: shim-bnc808106-correct-certcount.patch
# PATCH-FIX-UPSTREAM shim-mokmanager-ui-revamp.patch glin@suse.com -- Revamp the MokManager UI
Patch15: shim-mokmanager-ui-revamp.patch
BuildRequires: gnu-efi >= 3.0q
Patch9: shim-mokmanager-ui-revamp.patch
BuildRequires: gnu-efi >= 3.0t
BuildRequires: mozilla-nss-tools
BuildRequires: openssl >= 0.9.8
BuildRequires: pesign
@ -89,17 +79,12 @@ Authors:
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%patch5 -p1
%patch6 -p1
%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
%patch11 -p1
%patch12 -p1
%patch13 -p1
%patch14 -p1
%patch15 -p1
%build
chmod +x "make-certs"
@ -134,20 +119,25 @@ openssl x509 -in $cert -outform DER -out shim-$suffix.der
touch shim.crt
touch shim.cer
# make sure cast warnings don't trigger post build check
make VENDOR_CERT_FILE=shim-$suffix.der shim.efi MokManager.efi 2>/dev/null
make VENDOR_CERT_FILE=shim-$suffix.der shim.efi MokManager.efi fallback.efi 2>/dev/null
# make VENDOR_CERT_FILE=cert.der VENDOR_DBX_FILE=dbx
mv shim.efi shim-$suffix.efi
%install
export BRP_PESIGN_FILES='%{_libdir}/efi/shim*.efi %{_libdir}/efi/MokManager.efi'
export BRP_PESIGN_FILES='%{_libdir}/efi/shim*.efi %{_libdir}/efi/MokManager.efi %{_libdir}/efi/fallback.efi'
install -d %{buildroot}/%{_libdir}/efi
install -m 444 shim-*.efi %{buildroot}/%{_libdir}/efi
install -m 644 shim-*.efi %{buildroot}/%{_libdir}/efi
install -m 444 shim-*.der %{buildroot}/%{_libdir}/efi
# FIXME: install signed shim here
install -m 444 %{SOURCE1} %{buildroot}/%{_libdir}/efi/shim.efi
install -m 444 MokManager.efi %{buildroot}/%{_libdir}/efi/MokManager.efi
install -m 644 %{SOURCE1} %{buildroot}/%{_libdir}/efi/shim.efi
install -m 644 MokManager.efi %{buildroot}/%{_libdir}/efi/MokManager.efi
install -m 644 fallback.efi %{buildroot}/%{_libdir}/efi/fallback.efi
install -d %{buildroot}/%{_sbindir}
install -m 755 %{SOURCE3} %{buildroot}/%{_sbindir}/
# install SUSE certificate
CERT_NAME=$(openssl x509 -sha1 -fingerprint -inform DER -in shim-*.der | grep "SHA1 Fingerprint" | cut -c 18- | cut -d ":" -f 1,2,3,4 | sed 's/://g')
install -d %{buildroot}/%{_sysconfdir}/uefi/certs/
install -m 444 shim-*.der %{buildroot}/%{_sysconfdir}/uefi/certs/$CERT_NAME.crt
%clean
%{?buildroot:%__rm -rf "%{buildroot}"}
@ -163,6 +153,10 @@ install -m 755 %{SOURCE3} %{buildroot}/%{_sbindir}/
%{_libdir}/efi/shim-*.efi
%{_libdir}/efi/shim-*.der
%{_libdir}/efi/MokManager.efi
%{_libdir}/efi/fallback.efi
%{_sbindir}/shim-install
%dir %{_sysconfdir}/uefi/
%dir %{_sysconfdir}/uefi/certs/
%{_sysconfdir}/uefi/certs/*.crt
%changelog