From 5d0e0f3e36af10729221f8e8f177aae4fba0bb90059189869d7d6a3a2b36f6b5 Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Fri, 18 Jan 2013 10:20:49 +0000 Subject: [PATCH] Accepting request 148927 from home:gary_lin:branches:Base:System - Update mokutil-support-new-pw-hash.patch to extend the password hash format OBS-URL: https://build.opensuse.org/request/show/148927 OBS-URL: https://build.opensuse.org/package/show/Base:System/mokutil?expand=0&rev=4 --- mokutil-support-new-pw-hash.patch | 355 +++++++++++++++++++++++++++++- mokutil.changes | 6 + 2 files changed, 352 insertions(+), 9 deletions(-) diff --git a/mokutil-support-new-pw-hash.patch b/mokutil-support-new-pw-hash.patch index 82702e2..a5f6e8b 100644 --- a/mokutil-support-new-pw-hash.patch +++ b/mokutil-support-new-pw-hash.patch @@ -1,7 +1,7 @@ From bd29992e580e9a48dc698e2e108c73b51a98f05f Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Wed, 9 Jan 2013 15:44:42 +0800 -Subject: [PATCH 1/9] Use getopt() to parse options +Subject: [PATCH 01/10] Use getopt() to parse options --- src/mokutil.c | 259 +++++++++++++++++++++++++++------------------------------ @@ -350,7 +350,7 @@ index ea8481a..2ab005c 100644 From 32a919cd2ca89ea0dfcc7644c05a3cf88cbb13c4 Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Wed, 9 Jan 2013 17:37:30 +0800 -Subject: [PATCH 2/9] Adopt new password hash format +Subject: [PATCH 02/10] Adopt new password hash format old format: MokNew + sha256sum(MokNew + password) new format: salt + sha256sum(salt + password) @@ -555,7 +555,7 @@ index 2ab005c..61c432d 100644 From 326082d300337b347ae2cc42808ce905dd92eb3b Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Wed, 9 Jan 2013 17:59:01 +0800 -Subject: [PATCH 3/9] Close the key file +Subject: [PATCH 03/10] Close the key file --- src/mokutil.c | 2 ++ @@ -581,7 +581,7 @@ index 61c432d..86d5328 100644 From 97d977246991f750827764fb48662c8be4b40f78 Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Thu, 10 Jan 2013 17:07:36 +0800 -Subject: [PATCH 4/9] Get rid of misused while statement +Subject: [PATCH 04/10] Get rid of misused while statement --- src/mokutil.c | 4 ++-- @@ -616,7 +616,7 @@ index 86d5328..36783cb 100644 From ca1978555253562c4ad39ff8b050cbbbe485474b Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Thu, 10 Jan 2013 17:24:58 +0800 -Subject: [PATCH 5/9] Read the password hash from the file +Subject: [PATCH 05/10] Read the password hash from the file --- src/mokutil.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++----------- @@ -916,7 +916,7 @@ index 36783cb..4b9002e 100644 From c45ffc0d42c0564cf817a1682c0cbd5be164197d Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Thu, 10 Jan 2013 18:29:17 +0800 -Subject: [PATCH 6/9] Add a new command to generate the password hash +Subject: [PATCH 06/10] Add a new command to generate the password hash --- src/mokutil.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- @@ -1053,7 +1053,7 @@ index 4b9002e..fdb1a2b 100644 From ba347d456e80101b7c4306e7b30465c47c0fbea6 Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Tue, 15 Jan 2013 16:14:32 +0800 -Subject: [PATCH 7/9] Amend help +Subject: [PATCH 07/10] Amend help --- src/mokutil.c | 59 ++++++++++++++++++++++----------------------------------- @@ -1136,7 +1136,7 @@ index fdb1a2b..72a651a 100644 From f1a1c7abd8fde13afcb5196c599c662109936d49 Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Tue, 15 Jan 2013 17:48:04 +0800 -Subject: [PATCH 8/9] New commands to revoke the import or delete request +Subject: [PATCH 08/10] New commands to revoke the import or delete request --- src/mokutil.c | 58 +++++++++++++++++++++++++++++++++++---------------------- @@ -1254,7 +1254,7 @@ index 72a651a..7392845 100644 From 5cd7872982361be10755e3c8e7ecf228da92e164 Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Wed, 16 Jan 2013 15:12:28 +0800 -Subject: [PATCH 9/9] Apply stricter permissions to some variables +Subject: [PATCH 09/10] Apply stricter permissions to some variables The UEFI variables which contain the password or the password hash should not be accessed by normal users. @@ -1340,3 +1340,340 @@ index 7392845..c1a0ffc 100644 -- 1.7.10.4 + +From 47645170396e2800980044c7054bcd1078bbba93 Mon Sep 17 00:00:00 2001 +From: Gary Ching-Pang Lin +Date: Fri, 18 Jan 2013 17:47:04 +0800 +Subject: [PATCH 10/10] Extend the password hash format + +Several new fields were added to support hash from /etc/shadow. + +[Hash Method][Interation Count][Salt Size][Salt][hash] + +Besides, the salt is hashed with the 8-bit char password instead of +an efi_char16_t password array. +--- + src/PasswordHash.h | 33 ++++++++++++++++ + src/mokutil.c | 106 +++++++++++++++++++++++++++++----------------------- + 2 files changed, 93 insertions(+), 46 deletions(-) + create mode 100644 src/PasswordHash.h + +diff --git a/src/PasswordHash.h b/src/PasswordHash.h +new file mode 100644 +index 0000000..2aeded6 +--- /dev/null ++++ b/src/PasswordHash.h +@@ -0,0 +1,33 @@ ++#ifndef __PASSWORD_HASH_H__ ++#define __PASSWORD_HASH_H__ ++ ++#include ++ ++#define PASSWORD_HASH_SIZE 88 ++ ++/* The max salt size (in bits) */ ++#define T_DES_SALT_MAX 12 ++#define E_BSI_DES_SALT_MAX 24 ++#define MD5_SALT_MAX 48 ++#define SHA256_SALT_MAX 96 ++#define SHA512_SALT_MAX 96 ++#define BLOWFISH_SALT_MAX 128 ++ ++enum HashMethod { ++ Tranditional_DES = 0, ++ Extend_BSDI_DES, ++ MD5_BASED, ++ SHA256_BASED, ++ SHA512_BASED, ++ BLOWFISH_BASED ++}; ++ ++typedef struct { ++ uint16_t method; ++ uint32_t iter_count; ++ uint16_t salt_size; ++ uint8_t salt[16]; ++ uint8_t hash[64]; ++} __attribute__ ((packed)) pw_hash_t; ++ ++#endif /* __PASSWORD_HASH_H__ */ +diff --git a/src/mokutil.c b/src/mokutil.c +index c1a0ffc..38039b9 100644 +--- a/src/mokutil.c ++++ b/src/mokutil.c +@@ -13,6 +13,7 @@ + + #include "efi.h" + #include "signature.h" ++#include "PasswordHash.h" + + #define SHIM_LOCK_GUID \ + EFI_GUID (0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23) +@@ -20,8 +21,6 @@ EFI_GUID (0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, + #define PASSWORD_MAX 16 + #define PASSWORD_MIN 8 + +-#define SALT_SIZE 16 +- + #define HELP 0x1 + #define LIST_ENROLLED 0x2 + #define LIST_NEW 0x4 +@@ -359,37 +358,35 @@ error: + return ret; + } + +-static void +-generate_salt (uint8_t salt[], unsigned int salt_len) ++static unsigned int ++generate_salt (uint8_t salt[], unsigned int max_size, unsigned int min_size) + { ++ unsigned int salt_len = max_size / 8; + int i; + + srand (time (NULL)); + + for (i = 0; i < salt_len; i++) + salt[i] = rand() % 256; ++ ++ return max_size; + } + + static int + generate_hash (void *salt, unsigned int salt_len, char *password, + int pw_len, uint8_t *auth) + { +- efi_char16_t efichar_pass[PASSWORD_MAX+1]; +- unsigned long efichar_len; + SHA256_CTX ctx; + + if (!password || !auth) + return -1; + +- efichar_len = efichar_from_char (efichar_pass, password, +- (PASSWORD_MAX+1)*sizeof(efi_char16_t)); +- + SHA256_Init (&ctx); + + if (salt) + SHA256_Update (&ctx, salt, salt_len); + +- SHA256_Update (&ctx, efichar_pass, efichar_len); ++ SHA256_Update (&ctx, password, pw_len); + + SHA256_Final (auth, &ctx); + +@@ -412,7 +409,7 @@ char_to_int (const char c) + } + + static int +-read_hex_array (const char *string, char *out, int len) ++read_hex_array (const char *string, uint8_t *out, unsigned int len) + { + int i, digit_1, digit_2; + +@@ -422,17 +419,18 @@ read_hex_array (const char *string, char *out, int len) + if (digit_1 < 0 || digit_2 < 0) + return -1; + +- out[i] = (char)digit_1 * 16 + (char)digit_2; ++ out[i] = (uint8_t)digit_1 * 16 + (uint8_t)digit_2; + } + + return 0; + } + + static int +-get_hash_from_file (const char *file, void *salt, void *hash) ++get_hash_from_file (const char *file, pw_hash_t *pw_hash) + { + FILE *fptr; +- char salt_string[2*SALT_SIZE]; ++ unsigned int method, iter_count, salt_size; ++ char salt_string[2*(SHA256_SALT_MAX/8)]; + char hash_string[2*SHA256_DIGEST_LENGTH]; + + fptr = fopen (file, "r"); +@@ -441,19 +439,24 @@ get_hash_from_file (const char *file, void *salt, void *hash) + return -1; + } + +- memset (salt_string, 0, 2*SALT_SIZE); ++ memset (salt_string, 0, 2*(SHA256_SALT_MAX/8)); + memset (hash_string, 0, 2*SHA256_DIGEST_LENGTH); + +- fscanf (fptr, "%32c.%64c", salt_string, hash_string); ++ fscanf (fptr, "%x.%x.%x.%24c.%64c", &method, &iter_count, &salt_size, ++ salt_string, hash_string); + + fclose (fptr); + +- if (read_hex_array (salt_string, salt, SALT_SIZE) < 0) { ++ pw_hash->method = (uint16_t)method; ++ pw_hash->iter_count = (uint32_t)iter_count; ++ pw_hash->salt_size = (uint16_t)salt_size; ++ ++ if (read_hex_array (salt_string, pw_hash->salt, salt_size/8) < 0) { + fprintf (stderr, "Corrupted salt\n"); + return -1; + } + +- if (read_hex_array (hash_string, hash, SHA256_DIGEST_LENGTH) < 0) { ++ if (read_hex_array (hash_string, pw_hash->hash, SHA256_DIGEST_LENGTH) < 0) { + fprintf (stderr, "Corrupted hash\n"); + return -1; + } +@@ -467,13 +470,16 @@ update_request (void *new_list, int list_len, uint8_t import, + { + efi_variable_t var; + const char *req_name, *auth_name; +- uint8_t salt[SALT_SIZE]; +- uint8_t hash[SHA256_DIGEST_LENGTH]; +- uint8_t auth[SALT_SIZE + SHA256_DIGEST_LENGTH]; ++ pw_hash_t pw_hash; + char *password = NULL; + int pw_len; + int ret = -1; + ++ bzero (&pw_hash, sizeof(pw_hash_t)); ++ pw_hash.method = SHA256_BASED; ++ pw_hash.iter_count = 1; ++ pw_hash.salt_size = SHA256_SALT_MAX; ++ + if (import) { + req_name = "MokNew"; + auth_name = "MokAuth"; +@@ -483,7 +489,7 @@ update_request (void *new_list, int list_len, uint8_t import, + } + + if (hash_file) { +- if (get_hash_from_file (hash_file, salt, hash) < 0) { ++ if (get_hash_from_file (hash_file, &pw_hash) < 0) { + fprintf (stderr, "Failed to read hash\n"); + goto error; + } +@@ -493,14 +499,13 @@ update_request (void *new_list, int list_len, uint8_t import, + goto error; + } + +- generate_salt (salt, SALT_SIZE); +- if (generate_hash (salt, SALT_SIZE, password, pw_len, hash) < 0) { ++ generate_salt (pw_hash.salt, SHA256_SALT_MAX, 0); ++ if (generate_hash (pw_hash.salt, SHA256_SALT_MAX/8, password, ++ pw_len, pw_hash.hash) < 0) { + fprintf (stderr, "Couldn't generate hash\n"); + goto error; + } + } +- memcpy (auth, salt, SALT_SIZE); +- memcpy (auth + SALT_SIZE, hash, SHA256_DIGEST_LENGTH); + + if (new_list) { + /* Write MokNew*/ +@@ -522,9 +527,9 @@ update_request (void *new_list, int list_len, uint8_t import, + test_and_delete_var (req_name); + } + +- /* Write MokAuth */ +- var.Data = auth; +- var.DataSize = SHA256_DIGEST_LENGTH + SALT_SIZE; ++ /* Write MokAuth or MokDelAuth */ ++ var.Data = (void *)&pw_hash; ++ var.DataSize = PASSWORD_HASH_SIZE; + var.VariableName = auth_name; + + var.VendorGuid = SHIM_LOCK_GUID; +@@ -848,15 +853,18 @@ static int + set_password (const char *hash_file) + { + efi_variable_t var; +- uint8_t salt[SALT_SIZE]; +- uint8_t hash[SHA256_DIGEST_LENGTH]; +- uint8_t auth[SHA256_DIGEST_LENGTH + SALT_SIZE]; ++ pw_hash_t pw_hash; + char *password = NULL; + int pw_len; + int ret = -1; + ++ bzero (&pw_hash, sizeof(pw_hash_t)); ++ pw_hash.method = SHA256_BASED; ++ pw_hash.iter_count = 1; ++ pw_hash.salt_size = SHA256_SALT_MAX; ++ + if (hash_file) { +- if (get_hash_from_file (hash_file, salt, hash) < 0) { ++ if (get_hash_from_file (hash_file, &pw_hash) < 0) { + fprintf (stderr, "Failed to read hash\n"); + goto error; + } +@@ -866,17 +874,16 @@ set_password (const char *hash_file) + goto error; + } + +- generate_salt (salt, SALT_SIZE); +- if (generate_hash (salt, SALT_SIZE, password, pw_len, hash) < 0) { ++ generate_salt (pw_hash.salt, SHA256_SALT_MAX, 0); ++ if (generate_hash (pw_hash.salt, SHA256_SALT_MAX/8, password, ++ pw_len, pw_hash.hash) < 0) { + fprintf (stderr, "Couldn't generate hash\n"); + goto error; + } + } +- memcpy (auth, salt, SALT_SIZE); +- memcpy (auth + SALT_SIZE, hash, SHA256_DIGEST_LENGTH); + +- var.Data = auth; +- var.DataSize = SHA256_DIGEST_LENGTH + SALT_SIZE; ++ var.Data = (void *)&pw_hash; ++ var.DataSize = PASSWORD_HASH_SIZE; + var.VariableName = "MokPW"; + + var.VendorGuid = SHIM_LOCK_GUID; +@@ -1044,11 +1051,15 @@ reset_moks (const char *hash_file) + static int + generate_pw_hash (const char *input_pw) + { +- uint8_t salt[SALT_SIZE]; +- uint8_t hash[SHA256_DIGEST_LENGTH]; ++ pw_hash_t pw_hash; + char *password = NULL; + int pw_len, i, ret = -1; + ++ bzero (&pw_hash, sizeof(pw_hash_t)); ++ pw_hash.method = SHA256_BASED; ++ pw_hash.iter_count = 1; ++ pw_hash.salt_size = SHA256_SALT_MAX; ++ + if (input_pw) { + pw_len = strlen (input_pw); + if (pw_len > PASSWORD_MAX || pw_len < PASSWORD_MIN) { +@@ -1070,19 +1081,22 @@ generate_pw_hash (const char *input_pw) + } + } + +- generate_salt (salt, SALT_SIZE); +- if (generate_hash (salt, SALT_SIZE, password, pw_len, hash) < 0) { ++ generate_salt (pw_hash.salt, SHA256_SALT_MAX, 0); ++ if (generate_hash (pw_hash.salt, SHA256_SALT_MAX/8, password, ++ pw_len, pw_hash.hash) < 0) { + fprintf (stderr, "Couldn't generate hash\n"); + goto error; + } + + /* Print the salt and hash */ +- for (i = 0; i < SALT_SIZE; i++) { +- printf ("%x%x", salt[i]/16, salt[i]%16); ++ printf ("%x.%x.%x.", pw_hash.method, pw_hash.iter_count, ++ pw_hash.salt_size); ++ for (i = 0; i < (SHA256_SALT_MAX/8); i++) { ++ printf ("%x%x", pw_hash.salt[i]/16, pw_hash.salt[i]%16); + } + putchar ('.'); + for (i = 0; i < SHA256_DIGEST_LENGTH; i++) +- printf ("%x%x", hash[i]/16, hash[i]%16); ++ printf ("%x%x", pw_hash.hash[i]/16, pw_hash.hash[i]%16); + putchar ('\n'); + + ret = 0; +-- +1.7.10.4 + diff --git a/mokutil.changes b/mokutil.changes index e22a2ab..ea06c6c 100644 --- a/mokutil.changes +++ b/mokutil.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Fri Jan 18 10:05:27 UTC 2013 - glin@suse.com + +- Update mokutil-support-new-pw-hash.patch to extend the password + hash format + ------------------------------------------------------------------- Wed Jan 16 08:41:15 UTC 2013 - glin@suse.com