Accepting request 148928 from Base:System

- Update shim-mokmanager-new-pw-hash.patch to extend the password
  hash format
- Rename shim.efi as shim-unsigned.efi (forwarded request 148926 from gary_lin)

OBS-URL: https://build.opensuse.org/request/show/148928
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/shim?expand=0&rev=2
This commit is contained in:
Stephan Kulow 2013-01-20 13:53:46 +00:00 committed by Git OBS Bridge
parent d7945289e5
commit 718fa0d383
3 changed files with 380 additions and 3 deletions

View File

@ -1,7 +1,7 @@
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 2/2] Support new password hash
Subject: [PATCH 1/2] Support new password hash
Old password hash: sha256sum(key_list + password)
New password hash: salt + sha256sum(salt + password)
@ -216,3 +216,372 @@ index 97588cb..be2a764 100644
--
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,3 +1,10 @@
-------------------------------------------------------------------
Fri Jan 18 10:06:13 UTC 2013 - glin@suse.com
- Update shim-mokmanager-new-pw-hash.patch to extend the password
hash format
- Rename shim.efi as shim-unsigned.efi
-------------------------------------------------------------------
Wed Jan 16 08:01:55 UTC 2013 - glin@suse.com

View File

@ -73,10 +73,11 @@ chmod +x "make-certs"
# make sure cast warnings don't trigger post build check
make 2>/dev/null
# make VENDOR_CERT_FILE=cert.der VENDOR_DBX_FILE=dbx
mv shim.efi shim-unsigned.efi
%install
install -d %{buildroot}/%{_libdir}/efi
install -m 444 shim.efi %{buildroot}/%{_libdir}/efi
install -m 444 shim-unsigned.efi %{buildroot}/%{_libdir}/efi
install -m 444 MokManager.efi.signed %{buildroot}/%{_libdir}/efi/MokManager.efi
%clean
@ -86,7 +87,7 @@ install -m 444 MokManager.efi.signed %{buildroot}/%{_libdir}/efi/MokManager.efi
%defattr(-,root,root)
%doc COPYRIGHT
%dir %{_libdir}/efi
%{_libdir}/efi/shim.efi
%{_libdir}/efi/shim-unsigned.efi
%{_libdir}/efi/MokManager.efi
%changelog