From 44db4978c235659f96fe247376ee12d0d5db4e05e8abe30a92cb73f3710aa9ea Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Thu, 25 Jul 2013 10:27:41 +0000 Subject: [PATCH] Accepting request 184304 from home:gary_lin:branches:Base:System - Update to 0.2.0 + Generate the password hash with crypt() by default instead of the original sha256 password hash + Add an option to import the root password hash + Amend error messages, help, and man page OBS-URL: https://build.opensuse.org/request/show/184304 OBS-URL: https://build.opensuse.org/package/show/Base:System/mokutil?expand=0&rev=10 --- mokutil-0.1.0.tar.bz2 | 3 - mokutil-0.2.0.tar.bz2 | 3 + mokutil-allow-password-from-pipe.patch | 50 - mokutil-bnc809215-improve-wording.patch | 105 - mokutil-bnc809703-check-pending-request.patch | 340 --- mokutil-lcrypt-ldflag.patch | 29 - mokutil-no-duplicate-keys-imported.patch | 283 --- mokutil-probe-secure-boot-state.patch | 111 - mokutil-support-crypt-hash-methods.patch | 1911 ----------------- mokutil-support-delete-keys.patch | 835 ------- mokutil-support-new-pw-hash.patch | 1342 ------------ mokutil-update-man-page.patch | 124 -- mokutil.changes | 20 + mokutil.spec | 33 +- 14 files changed, 24 insertions(+), 5165 deletions(-) delete mode 100644 mokutil-0.1.0.tar.bz2 create mode 100644 mokutil-0.2.0.tar.bz2 delete mode 100644 mokutil-allow-password-from-pipe.patch delete mode 100644 mokutil-bnc809215-improve-wording.patch delete mode 100644 mokutil-bnc809703-check-pending-request.patch delete mode 100644 mokutil-lcrypt-ldflag.patch delete mode 100644 mokutil-no-duplicate-keys-imported.patch delete mode 100644 mokutil-probe-secure-boot-state.patch delete mode 100644 mokutil-support-crypt-hash-methods.patch delete mode 100644 mokutil-support-delete-keys.patch delete mode 100644 mokutil-support-new-pw-hash.patch delete mode 100644 mokutil-update-man-page.patch diff --git a/mokutil-0.1.0.tar.bz2 b/mokutil-0.1.0.tar.bz2 deleted file mode 100644 index a4559da..0000000 --- a/mokutil-0.1.0.tar.bz2 +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:739a241e18cc5b89c46eecc473568fb295952598ff518e7af90f81900afb62d4 -size 94722 diff --git a/mokutil-0.2.0.tar.bz2 b/mokutil-0.2.0.tar.bz2 new file mode 100644 index 0000000..aa6c653 --- /dev/null +++ b/mokutil-0.2.0.tar.bz2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:03cf595bd1b4d4a17dc1814b0529b25505d57429d583e7f9489ef0a2354b320e +size 102028 diff --git a/mokutil-allow-password-from-pipe.patch b/mokutil-allow-password-from-pipe.patch deleted file mode 100644 index 9c8d986..0000000 --- a/mokutil-allow-password-from-pipe.patch +++ /dev/null @@ -1,50 +0,0 @@ -commit adce7208ddcb65daac83ea3429aa8586d9cc4ea5 -Author: Gary Ching-Pang Lin -Date: Wed Jan 2 17:30:07 2013 +0800 - - Only change terminal settings - - tcgetattr() will fail if we send password through a pipeline instead - of a TTY. - -diff --git a/src/mokutil.c b/src/mokutil.c -index a99e355..ea8481a 100644 ---- a/src/mokutil.c -+++ b/src/mokutil.c -@@ -278,22 +278,27 @@ read_hidden_line (char **line, size_t *n) - { - struct termios old, new; - int nread; -+ int isTTY = isatty(fileno (stdin)); - -- /* Turn echoing off and fail if we can't. */ -- if (tcgetattr (fileno (stdin), &old) != 0) -- return -1; -+ if (isTTY) { -+ /* Turn echoing off and fail if we can't. */ -+ if (tcgetattr (fileno (stdin), &old) != 0) -+ return -1; - -- new = old; -- new.c_lflag &= ~ECHO; -+ new = old; -+ new.c_lflag &= ~ECHO; - -- if (tcsetattr (fileno (stdin), TCSAFLUSH, &new) != 0) -- return -1; -+ if (tcsetattr (fileno (stdin), TCSAFLUSH, &new) != 0) -+ return -1; -+ } - - /* Read the password. */ - nread = getline (line, n, stdin); - -- /* Restore terminal. */ -- (void) tcsetattr (fileno (stdin), TCSAFLUSH, &old); -+ if (isTTY) { -+ /* Restore terminal. */ -+ (void) tcsetattr (fileno (stdin), TCSAFLUSH, &old); -+ } - - /* Remove the newline */ - (*line)[nread-1] = '\0'; diff --git a/mokutil-bnc809215-improve-wording.patch b/mokutil-bnc809215-improve-wording.patch deleted file mode 100644 index 870637e..0000000 --- a/mokutil-bnc809215-improve-wording.patch +++ /dev/null @@ -1,105 +0,0 @@ -commit 08e7fbbfec644406b5f6f3ce787444bc5e2c4b3d -Author: Gary Ching-Pang Lin -Date: Fri Mar 29 12:12:00 2013 +0800 - - Make the error message more understandable - -diff --git a/src/efilib.c b/src/efilib.c -index cb1aca6..1b72cd9 100644 ---- a/src/efilib.c -+++ b/src/efilib.c -@@ -5,6 +5,7 @@ - #include - #include - #include -+#include - #include "efi.h" - - #define SYSFS_DIR_EFI_VARS "/sys/firmware/efi/efivars" -@@ -95,7 +96,9 @@ read_variable (efi_variable_t *var) - snprintf (filename, PATH_MAX-1, "%s/%s", SYSFS_DIR_EFI_VARS, name); - fd = open (filename, O_RDONLY); - if (fd == -1) { -- return EFI_NOT_FOUND; -+ if (errno == ENOENT) -+ return EFI_NOT_FOUND; -+ return EFI_INVALID_PARAMETER; - } - - if (fstat (fd, &buf) != 0) { -diff --git a/src/mokutil.c b/src/mokutil.c -index 27ebf09..3f89db2 100644 ---- a/src/mokutil.c -+++ b/src/mokutil.c -@@ -236,14 +236,20 @@ static int - list_enrolled_keys () - { - efi_variable_t var; -+ efi_status_t status; - int ret; - - memset (&var, 0, sizeof(var)); - var.VariableName = "MokListRT"; -- - var.VendorGuid = SHIM_LOCK_GUID; - -- if (read_variable (&var) != EFI_SUCCESS) { -+ status = read_variable (&var); -+ if (status != EFI_SUCCESS) { -+ if (status == EFI_NOT_FOUND) { -+ printf ("MokListRT is empty\n"); -+ return 0; -+ } -+ - fprintf (stderr, "Failed to read MokListRT\n"); - return -1; - } -@@ -258,14 +264,20 @@ static int - list_new_keys () - { - efi_variable_t var; -+ efi_status_t status; - int ret; - - memset (&var, 0, sizeof(var)); - var.VariableName = "MokNew"; -- - var.VendorGuid = SHIM_LOCK_GUID; - -- if (read_variable (&var) != EFI_SUCCESS) { -+ status = read_variable (&var); -+ if (status != EFI_SUCCESS) { -+ if (status == EFI_NOT_FOUND) { -+ printf ("No MOK new key request\n"); -+ return 0; -+ } -+ - fprintf (stderr, "Failed to read MokNew\n"); - return -1; - } -@@ -812,6 +824,7 @@ static int - export_moks () - { - efi_variable_t var; -+ efi_status_t status; - char filename[PATH_MAX]; - uint32_t mok_num; - MokListNode *list; -@@ -822,10 +835,15 @@ export_moks () - - memset (&var, 0, sizeof(var)); - var.VariableName = "MokListRT"; -- - var.VendorGuid = SHIM_LOCK_GUID; - -- if (read_variable (&var) != EFI_SUCCESS) { -+ status = read_variable (&var); -+ if (status != EFI_SUCCESS) { -+ if (status == EFI_NOT_FOUND) { -+ printf ("MokListRT is empty\n"); -+ return 0; -+ } -+ - fprintf (stderr, "Failed to read MokListRT\n"); - return -1; - } diff --git a/mokutil-bnc809703-check-pending-request.patch b/mokutil-bnc809703-check-pending-request.patch deleted file mode 100644 index d60e670..0000000 --- a/mokutil-bnc809703-check-pending-request.patch +++ /dev/null @@ -1,340 +0,0 @@ -From 9a114bb26e81f3b2764d84b8a6f5b9bd2e1528de Mon Sep 17 00:00:00 2001 -From: Gary Ching-Pang Lin -Date: Fri, 29 Mar 2013 18:00:55 +0800 -Subject: [PATCH 1/3] Delete key from the pending request - ---- - src/mokutil.c | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---- - 1 file changed, 108 insertions(+), 8 deletions(-) - -diff --git a/src/mokutil.c b/src/mokutil.c -index 3f89db2..01a1b79 100644 ---- a/src/mokutil.c -+++ b/src/mokutil.c -@@ -49,8 +49,9 @@ EFI_GUID (0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, - #define SETTINGS_LEN (DEFAULT_SALT_SIZE*2) - - typedef struct { -- uint32_t mok_size; -- void *mok; -+ EFI_SIGNATURE_LIST *header; -+ uint32_t mok_size; -+ void *mok; - } MokListNode; - - typedef struct { -@@ -154,8 +155,9 @@ build_mok_list (void *data, unsigned long data_size, uint32_t *mok_num) - return NULL; - } - -+ list[count].header = CertList; - list[count].mok_size = CertList->SignatureSize - sizeof(efi_guid_t); -- list[count].mok = (void *)Cert->SignatureData; -+ list[count].mok = (void *)Cert->SignatureData; - - count++; - dbsize -= CertList->SignatureListSize; -@@ -233,6 +235,74 @@ list_keys (efi_variable_t *var) - } - - static int -+delete_key_from_list (void *mok, uint32_t mok_size, -+ const char *var_name, efi_guid_t guid) -+{ -+ efi_variable_t var; -+ MokListNode *list; -+ uint32_t mok_num, total, remain; -+ void *ptr, *data = NULL; -+ int i, del_ind, ret = 0; -+ -+ if (!var_name || !mok || mok_size == 0) -+ return 0; -+ -+ memset (&var, 0, sizeof(var)); -+ var.VariableName = var_name; -+ var.VendorGuid = guid; -+ -+ if (read_variable (&var) != EFI_SUCCESS) -+ return 0; -+ -+ total = var.DataSize; -+ -+ list = build_mok_list (var.Data, var.DataSize, &mok_num); -+ if (list == NULL) -+ goto done; -+ -+ for (i = 0; i < mok_num; i++) { -+ if (list[i].mok_size != mok_size) -+ continue; -+ -+ if (memcmp (list[i].mok, mok, mok_size) == 0) { -+ /* Remove this key */ -+ del_ind = i; -+ data = (void *)list[i].header; -+ ptr = data + list[i].header->SignatureListSize; -+ total -= list[i].header->SignatureListSize; -+ break; -+ } -+ } -+ -+ /* the key is not in this list */ -+ if (data == NULL) -+ return 0; -+ -+ /* Move the rest of the keys */ -+ remain = 0; -+ for (i = del_ind + 1; i < mok_num; i++) -+ remain += list[i].header->SignatureListSize; -+ if (remain > 0) -+ memmove (data, ptr, remain); -+ -+ var.DataSize = total; -+ var.Attributes = EFI_VARIABLE_NON_VOLATILE -+ | EFI_VARIABLE_BOOTSERVICE_ACCESS -+ | EFI_VARIABLE_RUNTIME_ACCESS; -+ -+ if (edit_protected_variable (&var) != EFI_SUCCESS) { -+ fprintf (stderr, "Failed to write %s\n", var_name); -+ goto done; -+ } -+ -+ ret = 1; -+done: -+ free (var.Data); -+ -+ return ret; -+} -+ -+static int - list_enrolled_keys () - { - efi_variable_t var; -@@ -658,6 +728,34 @@ is_valid_request (void *mok, uint32_t mok_size, uint8_t import) - } - - static int -+in_pending_request (void *mok, uint32_t mok_size, uint8_t import) -+{ -+ efi_variable_t authvar; -+ const char *var_name = import ? "MokDel" : "MokNew"; -+ -+ if (!mok || mok_size == 0) -+ return 0; -+ -+ memset (&authvar, 0, sizeof(authvar)); -+ authvar.VariableName = import ? "MokDelAuth" : "MokAuth"; -+ authvar.VendorGuid = SHIM_LOCK_GUID; -+ -+ if (read_variable (&authvar) != EFI_SUCCESS) { -+ return 0; -+ } -+ -+ free (authvar.Data); -+ /* Check if the password hash is in the old format */ -+ if (authvar.DataSize == SHA256_DIGEST_LENGTH) -+ return 0; -+ -+ if (delete_key_from_list (mok, mok_size, var_name, SHIM_LOCK_GUID)) -+ return 1; -+ -+ return 0; -+} -+ -+static int - issue_mok_request (char **files, uint32_t total, uint8_t import, - const char *hash_file, const int root_pw) - { -@@ -678,10 +776,7 @@ issue_mok_request (char **files, uint32_t total, uint8_t import, - if (!files) - return -1; - -- if (import) -- req_name = "MokNew"; -- else -- req_name = "MokDel"; -+ req_name = import ? "MokNew" : "MokDel"; - - sizes = malloc (total * sizeof(uint32_t)); - -@@ -692,6 +787,7 @@ issue_mok_request (char **files, uint32_t total, uint8_t import, - goto error; - } - -+ /* get the sizes of the key files */ - for (i = 0; i < total; i++) { - if (stat (files[i], &buf) != 0) { - fprintf (stderr, "Failed to get file status, %s\n", -@@ -752,6 +848,10 @@ issue_mok_request (char **files, uint32_t total, uint8_t import, - if (is_valid_request (ptr, sizes[i], import)) { - ptr += sizes[i]; - real_size += sizes[i] + sizeof(EFI_SIGNATURE_LIST) + sizeof(efi_guid_t); -+ } else if (in_pending_request (ptr, sizes[i], import)) { -+ printf ("Removed %s from %s\n", files[i], import ? "MokDel" : "MokNew"); -+ -+ ptr -= sizeof(EFI_SIGNATURE_LIST) + sizeof(efi_guid_t); - } else { - printf ("Skip %s\n", files[i]); - ptr -= sizeof(EFI_SIGNATURE_LIST) + sizeof(efi_guid_t); -@@ -760,7 +860,7 @@ issue_mok_request (char **files, uint32_t total, uint8_t import, - close (fd); - } - -- /* All keys are enrolled, nothing to do here... */ -+ /* All keys are in the list, nothing to do here... */ - if (real_size == 0) { - ret = 0; - goto error; --- -1.8.1.4 - - -From d00c50c0eb73c27b1c49d8d947b99e24a4da4a66 Mon Sep 17 00:00:00 2001 -From: Gary Ching-Pang Lin -Date: Fri, 29 Mar 2013 14:21:00 +0800 -Subject: [PATCH 2/3] Remove the unnecessary command flags - ---- - src/mokutil.c | 47 ++++++++++++++++++++++------------------------- - 1 file changed, 22 insertions(+), 25 deletions(-) - -diff --git a/src/mokutil.c b/src/mokutil.c -index 01a1b79..6c3a135 100644 ---- a/src/mokutil.c -+++ b/src/mokutil.c -@@ -40,9 +40,7 @@ EFI_GUID (0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, - #define SB_STATE 0x800 - #define TEST_KEY 0x1000 - #define RESET 0x2000 --#define HASH_FILE 0x4000 --#define GENERATE_PW_HASH 0x8000 --#define ROOT_PW 0x10000 -+#define GENERATE_PW_HASH 0x4000 - - #define DEFAULT_CRYPT_METHOD SHA512_BASED - #define DEFAULT_SALT_SIZE SHA512_SALT_MAX -@@ -1247,6 +1245,7 @@ main (int argc, char *argv[]) - const char *option; - int c, i, f_ind, total = 0; - unsigned int command = 0; -+ int use_root_pw = 0; - int ret = -1; - - while (1) { -@@ -1329,7 +1328,6 @@ main (int argc, char *argv[]) - case 'f': - hash_file = strdup (optarg); - -- command |= HASH_FILE; - break; - case 'g': - if (optarg) -@@ -1341,7 +1339,7 @@ main (int argc, char *argv[]) - command |= PASSWORD; - break; - case 'P': -- command |= ROOT_PW; -+ use_root_pw = 1; - break; - case 't': - key_file = strdup (optarg); -@@ -1360,6 +1358,9 @@ main (int argc, char *argv[]) - } - } - -+ if (hash_file && use_root_pw) -+ command |= HELP; -+ - switch (command) { - case LIST_ENROLLED: - ret = list_enrolled_keys (); -@@ -1368,18 +1369,16 @@ main (int argc, char *argv[]) - ret = list_new_keys (); - break; - case IMPORT: -- case IMPORT | HASH_FILE: -- ret = import_moks (files, total, hash_file, 0); -- break; -- case IMPORT | ROOT_PW: -- ret = import_moks (files, total, NULL, 1); -+ if (use_root_pw) -+ ret = import_moks (files, total, NULL, 1); -+ else -+ ret = import_moks (files, total, hash_file, 0); - break; - case DELETE: -- case DELETE | HASH_FILE: -- ret = delete_moks (files, total, hash_file, 0); -- break; -- case DELETE | ROOT_PW: -- ret = delete_moks (files, total, NULL, 1); -+ if (use_root_pw) -+ ret = delete_moks (files, total, NULL, 1); -+ else -+ ret = delete_moks (files, total, hash_file, 0); - break; - case REVOKE_IMPORT: - ret = revoke_request (1); -@@ -1391,11 +1390,10 @@ main (int argc, char *argv[]) - ret = export_moks (); - break; - case PASSWORD: -- case PASSWORD | HASH_FILE: -- ret = set_password (hash_file, 0); -- break; -- case PASSWORD | ROOT_PW: -- ret = set_password (NULL, 1); -+ if (use_root_pw) -+ ret = set_password (NULL, 1); -+ else -+ ret = set_password (hash_file, 0); - break; - case DISABLE_VALIDATION: - ret = disable_validation (); -@@ -1410,11 +1408,10 @@ main (int argc, char *argv[]) - ret = test_key (key_file); - break; - case RESET: -- case RESET | HASH_FILE: -- ret = reset_moks (hash_file, 0); -- break; -- case RESET | ROOT_PW: -- ret = reset_moks (NULL, 1); -+ if (use_root_pw) -+ ret = reset_moks (NULL, 1); -+ else -+ ret = reset_moks (hash_file, 0); - break; - case GENERATE_PW_HASH: - ret = generate_pw_hash (input_pw); --- -1.8.1.4 - - -From 3c3725784cd31d867443675cb5aa6698b952ac2b Mon Sep 17 00:00:00 2001 -From: Gary Ching-Pang Lin -Date: Tue, 2 Apr 2013 11:29:01 +0800 -Subject: [PATCH 3/3] Show help if there is no key to be imported/deleted - ---- - src/mokutil.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/src/mokutil.c b/src/mokutil.c -index 6c3a135..58566f9 100644 ---- a/src/mokutil.c -+++ b/src/mokutil.c -@@ -1317,6 +1317,11 @@ main (int argc, char *argv[]) - total++; - } - -+ if (total == 0) { -+ command |= HELP; -+ break; -+ } -+ - files = malloc (total * sizeof (char *)); - for (i = 0; i < total; i++) { - f_ind = i + optind - 1; --- -1.8.1.4 - diff --git a/mokutil-lcrypt-ldflag.patch b/mokutil-lcrypt-ldflag.patch deleted file mode 100644 index f98a574..0000000 --- a/mokutil-lcrypt-ldflag.patch +++ /dev/null @@ -1,29 +0,0 @@ -From aa48dc644fbf775970d01a368c532d0668015f18 Mon Sep 17 00:00:00 2001 -From: Gary Ching-Pang Lin -Date: Wed, 30 Jan 2013 16:30:23 +0800 -Subject: [PATCH] Include lcrypt in LDFLAGS - ---- - src/Makefile.am | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/Makefile.am b/src/Makefile.am -index afe1752..de7ddca 100644 ---- a/src/Makefile.am -+++ b/src/Makefile.am -@@ -1,10 +1,10 @@ - bin_PROGRAMS = mokutil - - mokutil_CFLAGS = $(OPENSSL_CFLAGS) \ -- -lcrypt \ - $(WARNINGFLAGS_C) - --mokutil_LDADD = $(OPENSSL_LIBS) -+mokutil_LDADD = $(OPENSSL_LIBS) \ -+ -lcrypt - - mokutil_SOURCES = efi.h \ - efilib.c \ --- -1.7.10.4 - diff --git a/mokutil-no-duplicate-keys-imported.patch b/mokutil-no-duplicate-keys-imported.patch deleted file mode 100644 index 358954e..0000000 --- a/mokutil-no-duplicate-keys-imported.patch +++ /dev/null @@ -1,283 +0,0 @@ -From 0e1ac853fb889b3d8d00e3a4751f388b0b8d8f26 Mon Sep 17 00:00:00 2001 -From: Gary Ching-Pang Lin -Date: Wed, 5 Dec 2012 11:12:43 +0800 -Subject: [PATCH 1/4] Correct MOK size and SignatureSize - -The MOK size didn't include the SignatureOwner GUID. -The SignatureData header size was added twice accidentally. ---- - src/mokutil.c | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - -diff --git a/src/mokutil.c b/src/mokutil.c -index 1c32828..1b8465f 100644 ---- a/src/mokutil.c -+++ b/src/mokutil.c -@@ -143,7 +143,7 @@ build_mok_list (void *data, unsigned long data_size, uint32_t *mok_num) - return NULL; - } - -- list[count].mok_size = CertList->SignatureSize; -+ list[count].mok_size = CertList->SignatureSize - sizeof(efi_guid_t); - list[count].mok = (void *)Cert->SignatureData; - - count++; -@@ -497,8 +497,7 @@ import_moks (char **files, uint32_t total) - CertList->SignatureListSize = sizes[i] + - sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_SIGNATURE_DATA) - 1; - CertList->SignatureHeaderSize = 0; -- CertList->SignatureSize = sizes[i] + -- sizeof(EFI_SIGNATURE_DATA) + 16; -+ CertList->SignatureSize = sizes[i] + sizeof(efi_guid_t); - CertData->SignatureOwner = SHIM_LOCK_GUID; - - fd = open (files[i], O_RDONLY); --- -1.7.10.4 - - -From 69955da3819da3abaf198e5dae038c44814df5c0 Mon Sep 17 00:00:00 2001 -From: Gary Ching-Pang Lin -Date: Wed, 5 Dec 2012 11:24:58 +0800 -Subject: [PATCH 2/4] Don't import duplicate keys - -This commit compares keys in PK, KEK, db, MokListRT, and MokNew -before issuing a new request to avoid enrolling keys twice. ---- - src/mokutil.c | 128 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- - 1 file changed, 124 insertions(+), 4 deletions(-) - -diff --git a/src/mokutil.c b/src/mokutil.c -index 1b8465f..cf38422 100644 ---- a/src/mokutil.c -+++ b/src/mokutil.c -@@ -333,8 +333,8 @@ get_password (char **password, int *len, int min, int max) - } - - static int --generate_auth (void *new_list, int list_len, char *password, int pw_len, -- uint8_t *auth) -+generate_auth (void *new_list, unsigned long list_len, char *password, -+ int pw_len, uint8_t *auth) - { - efi_char16_t efichar_pass[PASSWORD_MAX+1]; - unsigned long efichar_len; -@@ -444,12 +444,97 @@ is_valid_cert (void *cert, uint32_t cert_size) - } - - static int -+is_duplicate (const void *cert, const uint32_t cert_size, const char *db_name, -+ efi_guid_t guid) -+{ -+ efi_variable_t var; -+ uint32_t mok_num; -+ MokListNode *list; -+ int i, ret = 0; -+ -+ if (!cert || cert_size == 0 || !db_name) -+ return 0; -+ -+ memset (&var, 0, sizeof(var)); -+ var.VariableName = db_name; -+ var.VendorGuid = guid; -+ -+ if (read_variable (&var) != EFI_SUCCESS) -+ return 0; -+ -+ list = build_mok_list (var.Data, var.DataSize, &mok_num); -+ if (list == NULL) { -+ goto done; -+ } -+ -+ for (i = 0; i < mok_num; i++) { -+ if (list[i].mok_size != cert_size) -+ continue; -+ -+ if (memcmp (list[i].mok, cert, cert_size) == 0) { -+ ret = 1; -+ break; -+ } -+ } -+ -+done: -+ free (var.Data); -+ -+ return ret; -+} -+ -+static int -+verify_mok_new (void *mok_new, unsigned long mok_new_size) -+{ -+ efi_variable_t mok_auth; -+ uint8_t auth[SHA256_DIGEST_LENGTH]; -+ char *password; -+ int pw_len, fail = 0; -+ size_t n; -+ int ret = 0; -+ -+ memset (&mok_auth, 0, sizeof(mok_auth)); -+ mok_auth.VariableName = "MokAuth"; -+ mok_auth.VendorGuid = SHIM_LOCK_GUID; -+ if (read_variable (&mok_auth) == EFI_SUCCESS) -+ return 0; -+ -+ while (fail < 3) { -+ printf ("input old password: "); -+ pw_len = read_hidden_line (&password, &n); -+ printf ("\n"); -+ -+ if (pw_len > PASSWORD_MAX || pw_len < PASSWORD_MIN) { -+ free (password); -+ fprintf (stderr, "invalid password\n"); -+ fail++; -+ continue; -+ } -+ -+ generate_auth (mok_new, mok_new_size, password, pw_len, auth); -+ if (memcmp (auth, mok_auth.Data, SHA256_DIGEST_LENGTH) == 0) { -+ ret = 1; -+ break; -+ } -+ -+ fail++; -+ } -+ -+ if (mok_auth.Data) -+ free (mok_auth.Data); -+ -+ return ret; -+} -+ -+static int - import_moks (char **files, uint32_t total) - { -+ efi_variable_t mok_new; - void *new_list = NULL; - void *ptr; - struct stat buf; - unsigned long list_size = 0; -+ unsigned long real_size = 0; - uint32_t *sizes = NULL; - int fd = -1; - ssize_t read_size; -@@ -481,6 +566,12 @@ import_moks (char **files, uint32_t total) - list_size += sizeof(EFI_SIGNATURE_LIST) * total; - list_size += sizeof(efi_guid_t) * total; - -+ memset (&mok_new, 0, sizeof(mok_new)); -+ mok_new.VariableName = "MokNew"; -+ mok_new.VendorGuid = SHIM_LOCK_GUID; -+ if (read_variable (&mok_new) == EFI_SUCCESS) -+ list_size += mok_new.DataSize; -+ - new_list = malloc (list_size); - if (!new_list) { - fprintf (stderr, "Failed to allocate space for MokNew\n"); -@@ -518,17 +609,46 @@ import_moks (char **files, uint32_t total) - fprintf (stderr, "Warning!!! %s is not a valid x509 certificate in DER format\n", - files[i]); - } -- ptr += sizes[i]; -+ -+ /* whether this key is already enrolled... */ -+ if (!is_duplicate (ptr, sizes[i], "PK", EFI_GLOBAL_VARIABLE) && -+ !is_duplicate (ptr, sizes[i], "KEK", EFI_GLOBAL_VARIABLE) && -+ !is_duplicate (ptr, sizes[i], "db", EFI_GLOBAL_VARIABLE) && -+ !is_duplicate (ptr, sizes[i], "MokListRT", SHIM_LOCK_GUID) && -+ !is_duplicate (ptr, sizes[i], "MokNew", SHIM_LOCK_GUID)) { -+ ptr += sizes[i]; -+ real_size += sizes[i] + sizeof(EFI_SIGNATURE_LIST) + sizeof(efi_guid_t); -+ } else { -+ ptr -= sizeof(EFI_SIGNATURE_LIST) + sizeof(efi_guid_t); -+ } - - close (fd); - } - -- if (update_request (new_list, list_size) < 0) { -+ /* All keys are enrolled, nothing to do here... */ -+ if (real_size == 0) { -+ ret = 0; -+ goto error; -+ } -+ -+ /* append the keys in MokNew */ -+ if (mok_new.Data) { -+ /* request the previous password to verify the keys */ -+ if (!verify_mok_new (mok_new.Data, mok_new.DataSize)) { -+ goto error; -+ } -+ -+ memcpy (ptr, mok_new.Data, mok_new.DataSize); -+ } -+ -+ if (update_request (new_list, real_size) < 0) { - goto error; - } - - ret = 0; - error: -+ if (mok_new.Data) -+ free (mok_new.Data); - if (sizes) - free (sizes); - if (new_list) --- -1.7.10.4 - - -From 10046350e223b6912bd9c3a7031f06779cb326bb Mon Sep 17 00:00:00 2001 -From: Gary Ching-Pang Lin -Date: Fri, 7 Dec 2012 15:57:50 +0800 -Subject: [PATCH 3/4] Check MokAuth correctly - ---- - src/mokutil.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/src/mokutil.c b/src/mokutil.c -index cf38422..9d56a90 100644 ---- a/src/mokutil.c -+++ b/src/mokutil.c -@@ -496,8 +496,10 @@ verify_mok_new (void *mok_new, unsigned long mok_new_size) - memset (&mok_auth, 0, sizeof(mok_auth)); - mok_auth.VariableName = "MokAuth"; - mok_auth.VendorGuid = SHIM_LOCK_GUID; -- if (read_variable (&mok_auth) == EFI_SUCCESS) -+ if (read_variable (&mok_auth) != EFI_SUCCESS) { -+ fprintf (stderr, "Failed to read MokAuth\n"); - return 0; -+ } - - while (fail < 3) { - printf ("input old password: "); --- -1.7.10.4 - - -From 9674b3249fef0d2ba00364f9f120f1ef17b710fc Mon Sep 17 00:00:00 2001 -From: Gary Ching-Pang Lin -Date: Fri, 7 Dec 2012 15:58:30 +0800 -Subject: [PATCH 4/4] Really append the old request to the new one... - ---- - src/mokutil.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/src/mokutil.c b/src/mokutil.c -index 9d56a90..aba1cfb 100644 ---- a/src/mokutil.c -+++ b/src/mokutil.c -@@ -640,7 +640,8 @@ import_moks (char **files, uint32_t total) - goto error; - } - -- memcpy (ptr, mok_new.Data, mok_new.DataSize); -+ memcpy (new_list + real_size, mok_new.Data, mok_new.DataSize); -+ real_size += mok_new.DataSize; - } - - if (update_request (new_list, real_size) < 0) { --- -1.7.10.4 - diff --git a/mokutil-probe-secure-boot-state.patch b/mokutil-probe-secure-boot-state.patch deleted file mode 100644 index 36e1ca9..0000000 --- a/mokutil-probe-secure-boot-state.patch +++ /dev/null @@ -1,111 +0,0 @@ -commit b2602eee326c15df8d23baa44f9e9e3e8b6bad93 -Author: Gary Ching-Pang Lin -Date: Mon Dec 3 17:45:41 2012 +0800 - - Probe the state of SecureBoot - -diff --git a/src/mokutil.c b/src/mokutil.c -index 3707220..1c32828 100644 ---- a/src/mokutil.c -+++ b/src/mokutil.c -@@ -40,6 +40,7 @@ enum Command { - COMMAND_PASSWORD, - COMMAND_DISABLE_VALIDATION, - COMMAND_ENABLE_VALIDATION, -+ COMMAND_SB_STATE, - }; - - static void -@@ -48,22 +49,33 @@ print_help () - printf("Usage:\n"); - printf("List the enrolled keys:\n"); - printf(" mokutil --list-enrolled\n\n"); -+ - printf("List the keys to be enrolled:\n"); - printf(" mokutil --list-new\n\n"); -+ - printf("Import keys:\n"); - printf(" mokutil --import ...\n\n"); -+ - printf("Request to delete all keys\n"); - printf(" mokutil --delete-all\n\n"); -+ - printf("Revoke the request:\n"); - printf(" mokutil --revoke\n\n"); -+ - printf("Export enrolled keys to files:\n"); - printf(" mokutil --export\n\n"); -+ - printf("Set MOK password:\n"); - printf(" mokutil --password\n\n"); -+ - printf("Disable signature validation:\n"); - printf(" mokutil --disable-validation\n\n"); -+ - printf("Enable signature validation:\n"); - printf(" mokutil --enable-validation\n\n"); -+ -+ printf("SecureBoot State:\n"); -+ printf(" mokutil --sb-state\n\n"); - } - - static int -@@ -709,7 +721,36 @@ enable_validation() - { - return set_validation(1); - } -- -+ -+static int -+sb_state () -+{ -+ efi_variable_t var; -+ char *state; -+ -+ memset (&var, 0, sizeof(var)); -+ var.VariableName = "SecureBoot"; -+ var.VendorGuid = EFI_GLOBAL_VARIABLE; -+ -+ if (read_variable (&var) != EFI_SUCCESS) { -+ fprintf (stderr, "Failed to read SecureBoot\n"); -+ return -1; -+ } -+ -+ state = (char *)var.Data; -+ if (*state == 1) { -+ printf ("SecureBoot enabled\n"); -+ } else if (*state == 0) { -+ printf ("SecureBoot disabled\n"); -+ } else { -+ printf ("SecureBoot unknown"); -+ } -+ -+ free (var.Data); -+ -+ return 0; -+} -+ - int - main (int argc, char *argv[]) - { -@@ -786,6 +827,10 @@ main (int argc, char *argv[]) - - command = COMMAND_ENABLE_VALIDATION; - -+ } else if (strcmp (argv[1], "--sb-state") == 0) { -+ -+ command = COMMAND_SB_STATE; -+ - } else { - fprintf (stderr, "Unknown argument: %s\n\n", argv[1]); - print_help (); -@@ -820,6 +865,9 @@ main (int argc, char *argv[]) - case COMMAND_ENABLE_VALIDATION: - enable_validation (); - break; -+ case COMMAND_SB_STATE: -+ sb_state (); -+ break; - default: - fprintf (stderr, "Unknown command\n"); - break; diff --git a/mokutil-support-crypt-hash-methods.patch b/mokutil-support-crypt-hash-methods.patch deleted file mode 100644 index a1586f0..0000000 --- a/mokutil-support-crypt-hash-methods.patch +++ /dev/null @@ -1,1911 +0,0 @@ -From c5d08b63d47db48bd239599f8fb53b13f879e1ff Mon Sep 17 00:00:00 2001 -From: Gary Ching-Pang Lin -Date: Wed, 23 Jan 2013 18:31:19 +0800 -Subject: [PATCH 1/9] Use crypt_r() to generate the password hash - -1. We now use crypt_r() from glibc to generate the password hash. - -2. The password length is changed to be compatible with the password - hash from /etc/shadow. - -3. The password hash structure was modified to be compatible with - the change in MokManager. ---- - configure.ac | 2 +- - src/Makefile.am | 3 + - src/PasswordHash.h | 33 -------- - src/mokutil.c | 219 ++++++++++++++++++++++---------------------------- - src/password-crypt.c | 218 +++++++++++++++++++++++++++++++++++++++++++++++++ - src/password-crypt.h | 42 ++++++++++ - 6 files changed, 359 insertions(+), 158 deletions(-) - delete mode 100644 src/PasswordHash.h - create mode 100644 src/password-crypt.c - create mode 100644 src/password-crypt.h - -diff --git a/configure.ac b/configure.ac -index 468b108..894790e 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -15,7 +15,7 @@ AM_PROG_CC_C_O - AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], [turn on debug]), CFLAGS="$CFLAGS -g") - - # Checks for header files. --AC_CHECK_HEADERS([fcntl.h stdint.h stdlib.h string.h unistd.h]) -+AC_CHECK_HEADERS([fcntl.h stdint.h stdlib.h string.h unistd.h crypt.h]) - - # Checks for typedefs, structures, and compiler characteristics. - AC_C_INLINE -diff --git a/src/Makefile.am b/src/Makefile.am -index 036a62a..afe1752 100644 ---- a/src/Makefile.am -+++ b/src/Makefile.am -@@ -1,6 +1,7 @@ - bin_PROGRAMS = mokutil - - mokutil_CFLAGS = $(OPENSSL_CFLAGS) \ -+ -lcrypt \ - $(WARNINGFLAGS_C) - - mokutil_LDADD = $(OPENSSL_LIBS) -@@ -8,4 +9,6 @@ mokutil_LDADD = $(OPENSSL_LIBS) - mokutil_SOURCES = efi.h \ - efilib.c \ - signature.h \ -+ password-crypt.h \ -+ password-crypt.c \ - mokutil.c -diff --git a/src/PasswordHash.h b/src/PasswordHash.h -deleted file mode 100644 -index 2aeded6..0000000 ---- a/src/PasswordHash.h -+++ /dev/null -@@ -1,33 +0,0 @@ --#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 38039b9..f71cb6a 100644 ---- a/src/mokutil.c -+++ b/src/mokutil.c -@@ -11,15 +11,20 @@ - #include - #include - -+#define __USE_GNU -+#include -+ - #include "efi.h" - #include "signature.h" --#include "PasswordHash.h" -+#include "password-crypt.h" - - #define SHIM_LOCK_GUID \ - EFI_GUID (0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23) - --#define PASSWORD_MAX 16 --#define PASSWORD_MIN 8 -+#define PASSWORD_MAX 256 -+#define PASSWORD_MIN 1 -+#define SB_PASSWORD_MAX 16 -+#define SB_PASSWORD_MIN 8 - - #define HELP 0x1 - #define LIST_ENROLLED 0x2 -@@ -38,6 +43,9 @@ EFI_GUID (0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, - #define HASH_FILE 0x4000 - #define GENERATE_PW_HASH 0x8000 - -+#define DEFAULT_CRYPT_METHOD SHA256_BASED -+#define DEFAULT_SALT_SIZE SHA256_SALT_MAX -+ - typedef struct { - uint32_t mok_size; - void *mok; -@@ -46,7 +54,7 @@ typedef struct { - typedef struct { - uint32_t mok_sb_state; - uint32_t password_length; -- uint16_t password[PASSWORD_MAX]; -+ uint16_t password[SB_PASSWORD_MAX]; - } MokSBVar; - - static void -@@ -71,8 +79,6 @@ print_help () - printf (" --test-key \t\t\tTest if the key is enrolled or not\n"); - printf (" --reset\t\t\t\tReset MOK list\n"); - printf (" --generate-hash[=password]\t\tGenerate the password hash\n"); -- printf ("\n"); -- printf ("Suboptions:\n"); - printf (" --hash-file \t\tUse the specific password hash\n"); - printf (" \t\t(Only valid with --import, --delete,\n"); - printf (" \t\t --password, and --reset)\n"); -@@ -310,7 +316,7 @@ get_password (char **password, int *len, int min, int max) - fail = 0; - - while (fail < 3) { -- printf ("input password (%d~%d characters): ", min, max); -+ printf ("input password: "); - len_1 = read_hidden_line (&password_1, &n); - printf ("\n"); - -@@ -361,103 +367,79 @@ error: - static unsigned int - generate_salt (uint8_t salt[], unsigned int max_size, unsigned int min_size) - { -- unsigned int salt_len = max_size / 8; -+ unsigned int salt_size = max_size; - int i; - -+ /* TODO use a better random number generator */ - srand (time (NULL)); - -- for (i = 0; i < salt_len; i++) -- salt[i] = rand() % 256; -+ for (i = 0; i < salt_size; i++) -+ salt[i] = int_to_b64 (rand() % 0x3f); - -- return max_size; -+ return salt_size; - } - - static int --generate_hash (void *salt, unsigned int salt_len, char *password, -- int pw_len, uint8_t *auth) -+generate_hash (pw_crypt_t *pw_crypt, char *password, int pw_len) - { -- SHA256_CTX ctx; -- -- if (!password || !auth) -+ pw_crypt_t new_crypt; -+ struct crypt_data data; -+ char settings[64]; -+ char *crypt_string; -+ const char *prefix; -+ int hash_len, prefix_len; -+ -+ if (!password || !pw_crypt) - return -1; - -- SHA256_Init (&ctx); -- -- if (salt) -- SHA256_Update (&ctx, salt, salt_len); -- -- SHA256_Update (&ctx, password, pw_len); -- -- SHA256_Final (auth, &ctx); -- -- return 0; --} -- --static int --char_to_int (const char c) --{ -- if (c >= '0' && c <= '9') -- return (c - '0'); -- -- if (c >= 'A' && c <= 'F') -- return (c - 'A' + 10); -- -- if (c >= 'a' && c <= 'f') -- return (c - 'a' + 10); -+ prefix = get_crypt_prefix (pw_crypt->method); -+ if (!prefix) -+ return -1; -+ prefix_len = strlen(prefix); - -- return -1; --} -+ strncpy (settings, prefix, prefix_len); -+ strncpy (settings + prefix_len, (const char *)pw_crypt->salt, -+ pw_crypt->salt_size); -+ settings[pw_crypt->salt_size + prefix_len] = '\0'; - --static int --read_hex_array (const char *string, uint8_t *out, unsigned int len) --{ -- int i, digit_1, digit_2; -+ crypt_string = crypt_r (password, settings, &data); -+ if (!crypt_string) -+ return -1; - -- for (i = 0; i < len; i++) { -- digit_1 = char_to_int (string[2*i]); -- digit_2 = char_to_int (string[2*i + 1]); -- if (digit_1 < 0 || digit_2 < 0) -- return -1; -+ if (decode_pass (crypt_string, &new_crypt) < 0) -+ return -1; - -- out[i] = (uint8_t)digit_1 * 16 + (uint8_t)digit_2; -- } -+ hash_len = get_hash_size (new_crypt.method); -+ if (hash_len < 0) -+ return -1; -+ memcpy (pw_crypt->hash, new_crypt.hash, hash_len); -+ pw_crypt->iter_count = new_crypt.iter_count; - - return 0; - } - - static int --get_hash_from_file (const char *file, pw_hash_t *pw_hash) -+get_hash_from_file (const char *file, pw_crypt_t *pw_crypt) - { -- FILE *fptr; -- unsigned int method, iter_count, salt_size; -- char salt_string[2*(SHA256_SALT_MAX/8)]; -- char hash_string[2*SHA256_DIGEST_LENGTH]; -+ char string[300]; -+ ssize_t read_len; -+ int fd; - -- fptr = fopen (file, "r"); -- if (fptr == NULL) { -+ fd = open (file, O_RDONLY); -+ if (fd < 0) { - fprintf (stderr, "Failed to open %s\n", file); - return -1; - } -+ read_len = read (fd, string, 300); -+ close (fd); - -- memset (salt_string, 0, 2*(SHA256_SALT_MAX/8)); -- memset (hash_string, 0, 2*SHA256_DIGEST_LENGTH); -- -- fscanf (fptr, "%x.%x.%x.%24c.%64c", &method, &iter_count, &salt_size, -- salt_string, hash_string); -- -- fclose (fptr); -- -- 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"); -+ if (string[read_len] != '\0') { -+ fprintf (stderr, "corrupted string\n"); - return -1; - } - -- if (read_hex_array (hash_string, pw_hash->hash, SHA256_DIGEST_LENGTH) < 0) { -- fprintf (stderr, "Corrupted hash\n"); -+ if (decode_pass (string, pw_crypt) < 0) { -+ fprintf (stderr, "Failed to parse the string\n"); - return -1; - } - -@@ -470,15 +452,13 @@ update_request (void *new_list, int list_len, uint8_t import, - { - efi_variable_t var; - const char *req_name, *auth_name; -- pw_hash_t pw_hash; -+ pw_crypt_t pw_crypt; - 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; -+ bzero (&pw_crypt, sizeof(pw_crypt_t)); -+ pw_crypt.method = DEFAULT_CRYPT_METHOD; - - if (import) { - req_name = "MokNew"; -@@ -489,7 +469,7 @@ update_request (void *new_list, int list_len, uint8_t import, - } - - if (hash_file) { -- if (get_hash_from_file (hash_file, &pw_hash) < 0) { -+ if (get_hash_from_file (hash_file, &pw_crypt) < 0) { - fprintf (stderr, "Failed to read hash\n"); - goto error; - } -@@ -499,9 +479,10 @@ update_request (void *new_list, int list_len, uint8_t import, - goto error; - } - -- 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) { -+ pw_crypt.salt_size = generate_salt (pw_crypt.salt, -+ DEFAULT_SALT_SIZE, -+ DEFAULT_SALT_SIZE); -+ if (generate_hash (&pw_crypt, password, pw_len) < 0) { - fprintf (stderr, "Couldn't generate hash\n"); - goto error; - } -@@ -528,8 +509,8 @@ update_request (void *new_list, int list_len, uint8_t import, - } - - /* Write MokAuth or MokDelAuth */ -- var.Data = (void *)&pw_hash; -- var.DataSize = PASSWORD_HASH_SIZE; -+ var.Data = (void *)&pw_crypt; -+ var.DataSize = PASSWORD_CRYPT_SIZE; - var.VariableName = auth_name; - - var.VendorGuid = SHIM_LOCK_GUID; -@@ -853,18 +834,16 @@ static int - set_password (const char *hash_file) - { - efi_variable_t var; -- pw_hash_t pw_hash; -+ pw_crypt_t pw_crypt; - 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; -+ bzero (&pw_crypt, sizeof(pw_crypt_t)); -+ pw_crypt.method = DEFAULT_CRYPT_METHOD; - - if (hash_file) { -- if (get_hash_from_file (hash_file, &pw_hash) < 0) { -+ if (get_hash_from_file (hash_file, &pw_crypt) < 0) { - fprintf (stderr, "Failed to read hash\n"); - goto error; - } -@@ -874,16 +853,17 @@ set_password (const char *hash_file) - goto error; - } - -- 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) { -+ pw_crypt.salt_size = generate_salt (pw_crypt.salt, -+ DEFAULT_SALT_SIZE, -+ DEFAULT_SALT_SIZE); -+ if (generate_hash (&pw_crypt, password, pw_len) < 0) { - fprintf (stderr, "Couldn't generate hash\n"); - goto error; - } - } - -- var.Data = (void *)&pw_hash; -- var.DataSize = PASSWORD_HASH_SIZE; -+ var.Data = (void *)&pw_crypt; -+ var.DataSize = PASSWORD_CRYPT_SIZE; - var.VariableName = "MokPW"; - - var.VendorGuid = SHIM_LOCK_GUID; -@@ -910,10 +890,11 @@ set_validation (uint32_t state) - MokSBVar sbvar; - char *password = NULL; - int pw_len; -- efi_char16_t efichar_pass[PASSWORD_MAX]; -+ efi_char16_t efichar_pass[SB_PASSWORD_MAX]; - int ret = -1; - -- if (get_password (&password, &pw_len, PASSWORD_MIN, PASSWORD_MAX) < 0) { -+ printf ("password length: %d~%d\n", SB_PASSWORD_MIN, SB_PASSWORD_MAX); -+ if (get_password (&password, &pw_len, SB_PASSWORD_MIN, SB_PASSWORD_MAX) < 0) { - fprintf (stderr, "Abort\n"); - goto error; - } -@@ -921,10 +902,10 @@ set_validation (uint32_t state) - sbvar.password_length = pw_len; - - efichar_from_char (efichar_pass, password, -- PASSWORD_MAX * sizeof(efi_char16_t)); -+ SB_PASSWORD_MAX * sizeof(efi_char16_t)); - - memcpy(sbvar.password, efichar_pass, -- PASSWORD_MAX * sizeof(efi_char16_t)); -+ SB_PASSWORD_MAX * sizeof(efi_char16_t)); - - sbvar.mok_sb_state = state; - -@@ -1051,20 +1032,16 @@ reset_moks (const char *hash_file) - static int - generate_pw_hash (const char *input_pw) - { -- pw_hash_t pw_hash; -+ struct crypt_data data; -+ char settings[SHA256_SALT_MAX + 3 + 1]; - 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; -+ char *crypt_string; -+ int pw_len, ret = -1; - - if (input_pw) { - pw_len = strlen (input_pw); - if (pw_len > PASSWORD_MAX || pw_len < PASSWORD_MIN) { -- fprintf (stderr, "password should be %d~%d characters\n", -- PASSWORD_MIN, PASSWORD_MAX); -+ fprintf (stderr, "invalid password length\n"); - return -1; - } - -@@ -1081,23 +1058,17 @@ generate_pw_hash (const char *input_pw) - } - } - -- 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"); -+ strncpy (settings, "$5$", 3); -+ generate_salt ((uint8_t *)(settings + 3), SHA256_SALT_MAX, 0); -+ settings[SHA256_SALT_MAX + 3] = '\0'; -+ -+ crypt_string = crypt_r (password, settings, &data); -+ if (!crypt_string) { -+ fprintf (stderr, "Failed to generate hash\n"); - goto error; - } - -- /* Print the salt and hash */ -- 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", pw_hash.hash[i]/16, pw_hash.hash[i]%16); -- putchar ('\n'); -+ printf ("%s\n", crypt_string); - - ret = 0; - error: -diff --git a/src/password-crypt.c b/src/password-crypt.c -new file mode 100644 -index 0000000..f004049 ---- /dev/null -+++ b/src/password-crypt.c -@@ -0,0 +1,218 @@ -+#include -+#include -+#include -+#include -+#include "password-crypt.h" -+ -+#define MIN(a,b) ((a)<(b)?(a):(b)) -+ -+#define SHA256_DEFAULT_ROUNDS 5000 -+ -+static const char b64t[64] = -+"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; -+ -+static const char sha256_prefix[] = "$5$"; -+static const char sha512_prefix[] = "$6$"; -+ -+static const char sha256_rounds_prefix[] = "rounds="; -+ -+static int restore_sha256_array (const char *string, uint8_t *hash); -+ -+int -+get_hash_size (int method) -+{ -+ switch (method) { -+ case TRANDITIONAL_DES: -+ return 64 / 8; /* per "man crypt" */ -+ case EXTEND_BSDI_DES: -+ return 64 / 8; /* per "man crypt" */ -+ case MD5_BASED: -+ return MD5_DIGEST_LENGTH; -+ case SHA256_BASED: -+ return SHA256_DIGEST_LENGTH; -+ case SHA512_BASED: -+ return SHA512_DIGEST_LENGTH; -+ case BLOWFISH_BASED: -+ return 184 / 8; /* per "man crypt" */ -+ } -+ -+ return -1; -+} -+ -+const char * -+get_crypt_prefix (int method) -+{ -+ switch (method) { -+ case TRANDITIONAL_DES: -+ return ""; /* per "man crypt" */ -+ case EXTEND_BSDI_DES: -+ return "_"; /* per "man crypt" */ -+ case MD5_BASED: -+ return "$1$"; -+ case SHA256_BASED: -+ return "$5$"; -+ case SHA512_BASED: -+ return "$6$"; -+ case BLOWFISH_BASED: -+ return "$2y$"; /* per "man crypt" */ -+ } -+ -+ return NULL; -+} -+ -+static int -+decode_sha256_pass (const char *string, pw_crypt_t *pw_crypt) -+{ -+ /* Expected string: (rounds=[0-9]{1,9}\$)?([./0-9A-Za-z]{1,16})?\$[./0-9A-Za-z]{43} */ -+ char *tmp, *ptr = (char *)string; -+ char *b64_hash; -+ int count = 0; -+ -+ /* get rounds */ -+ pw_crypt->iter_count = SHA256_DEFAULT_ROUNDS; -+ if (strncmp (ptr, sha256_rounds_prefix, sizeof(sha256_rounds_prefix) - 1) == 0) { -+ const char *num = ptr + sizeof(sha256_rounds_prefix) - 1; -+ char *endp; -+ unsigned long int srounds = strtoul (num, &endp, 10); -+ if (*endp == '$') { -+ ptr = endp + 1; -+ pw_crypt->iter_count = (uint32_t)srounds; -+ } else { -+ return -1; -+ } -+ } -+ -+ /* get salt */ -+ for (tmp = ptr; *tmp != '$'; tmp++) { -+ if (tmp == '\0') -+ return -1; -+ count++; -+ } -+ count = MIN(count, SHA256_SALT_MAX); -+ memcpy (pw_crypt->salt, ptr, count); -+ pw_crypt->salt_size = count; -+ ptr = tmp + 1; -+ -+ /* get hash */ -+ if (strlen(ptr) < SHA256_B64_LENGTH) -+ return -1; -+ b64_hash = malloc (SHA256_B64_LENGTH + 1); -+ if (!b64_hash) -+ return -1; -+ memcpy (b64_hash, ptr, SHA256_B64_LENGTH); -+ b64_hash[SHA256_B64_LENGTH] = '\0'; -+ -+ if (restore_sha256_array (b64_hash, pw_crypt->hash) < 0) -+ return -1; -+ -+ free (b64_hash); -+ -+ return 0; -+} -+ -+int -+decode_pass (const char *crypt_pass, pw_crypt_t *pw_crypt) -+{ -+ if (!pw_crypt) -+ return -1; -+ -+ if (strncmp (crypt_pass, sha256_prefix, 3) == 0) { -+ pw_crypt->method = SHA256_BASED; -+ return decode_sha256_pass (crypt_pass + 3, pw_crypt); -+ } -+ -+ return -1; -+} -+ -+char -+int_to_b64 (const int i) -+{ -+ return b64t[i & 0x3f]; -+} -+ -+int -+b64_to_int (const char c) -+{ -+ if (c == '.') -+ return 0; -+ -+ if (c == '/') -+ return 1; -+ -+ if (c >= '0' && c <= '9') -+ return (c - '0' + 2); -+ -+ if (c >= 'A' && c <= 'Z') -+ return (c - 'A' + 12); -+ -+ if (c >= 'a' && c <= 'z') -+ return (c - 'a' + 38); -+ -+ return -1; -+} -+ -+static int -+split_24bit (const char *string, uint8_t *hash, int start, int n, -+ uint32_t b2, uint32_t b1, uint32_t b0) -+{ -+ uint32_t tmp = 0; -+ int i, value; -+ -+ for (i = start; i < start + n; i++) { -+ value = b64_to_int (string[i]); -+ if (value < 0) -+ return -1; -+ tmp |= value << (6*(i - start)); -+ } -+ -+ hash[b0] = (uint8_t)(tmp & 0xff); -+ hash[b1] = (uint8_t)((tmp >> 8) & 0xff); -+ hash[b2] = (uint8_t)((tmp >> 16) & 0xff); -+ -+ return 0; -+} -+ -+int -+restore_sha256_array (const char *string, uint8_t *hash) -+{ -+ uint32_t tmp = 0; -+ int i, value; -+ -+ if (strlen (string) != SHA256_B64_LENGTH) -+ return -1; -+ -+ if (split_24bit (string, hash, 0, 4, 0, 10, 20) < 0) -+ return -1; -+ if (split_24bit (string, hash, 4, 4, 21, 1, 11) < 0) -+ return -1; -+ if (split_24bit (string, hash, 8, 4, 12, 22, 2) < 0) -+ return -1; -+ if (split_24bit (string, hash, 12, 4, 3, 13, 23) < 0) -+ return -1; -+ if (split_24bit (string, hash, 16, 4, 24, 4, 14) < 0) -+ return -1; -+ if (split_24bit (string, hash, 20, 4, 15, 25, 5) < 0) -+ return -1; -+ if (split_24bit (string, hash, 24, 4, 6, 16, 26) < 0) -+ return -1; -+ if (split_24bit (string, hash, 28, 4, 27, 7, 17) < 0) -+ return -1; -+ if (split_24bit (string, hash, 32, 4, 18, 28, 8) < 0) -+ return -1; -+ if (split_24bit (string, hash, 36, 4, 9, 19, 29) < 0) -+ return -1; -+ -+ for (i = 40; i < 43 ; i++) { -+ value = b64_to_int (string[i]); -+ if (value < 0) -+ return -1; -+ tmp |= value << (6*(i - 40)); -+ } -+ -+ hash[30] = (uint8_t)(tmp & 0xff); -+ hash[31] = (uint8_t)((tmp >> 8) & 0xff); -+ -+ return 0; -+} -+ -+ -diff --git a/src/password-crypt.h b/src/password-crypt.h -new file mode 100644 -index 0000000..149a05e ---- /dev/null -+++ b/src/password-crypt.h -@@ -0,0 +1,42 @@ -+#ifndef __PASSWORD_CRYPT_H__ -+#define __PASSWORD_CRYPT_H__ -+ -+#include -+ -+/* The max salt size (in characters [./0-9A-Za-z]) */ -+#define T_DES_SALT_MAX 2 -+#define E_BSI_DES_SALT_MAX 4 -+#define MD5_SALT_MAX 8 -+#define SHA256_SALT_MAX 16 -+#define SHA512_SALT_MAX 16 -+/* The max salt size of Blowfish in UINT8 */ -+#define BLOWFISH_SALT_MAX 16 -+ -+enum HashMethod { -+ TRANDITIONAL_DES = 0, -+ EXTEND_BSDI_DES, -+ MD5_BASED, -+ SHA256_BASED, -+ SHA512_BASED, -+ BLOWFISH_BASED -+}; -+ -+typedef struct { -+ uint16_t method; -+ uint64_t iter_count; -+ uint16_t salt_size; -+ uint8_t salt[32]; -+ uint8_t hash[128]; -+} __attribute__ ((packed)) pw_crypt_t; -+ -+#define PASSWORD_CRYPT_SIZE sizeof(pw_crypt_t) -+ -+#define SHA256_B64_LENGTH 43 -+ -+int get_hash_size (int method); -+const char *get_crypt_prefix (int method); -+int decode_pass (const char *crypt_pass, pw_crypt_t *pw_crypt); -+char int_to_b64 (const int i); -+int b64_to_int (const char c); -+ -+#endif /* __PASSWORD_CRYPT_H__ */ --- -1.7.10.4 - - -From 80ddd5d426e96d251f53bf5653a3bd20aebb32ab Mon Sep 17 00:00:00 2001 -From: Gary Ching-Pang Lin -Date: Thu, 24 Jan 2013 18:37:33 +0800 -Subject: [PATCH 2/9] Support SHA512-based crypt_r() hash - ---- - src/mokutil.c | 23 ++++++--- - src/password-crypt.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++++-- - src/password-crypt.h | 1 + - 3 files changed, 140 insertions(+), 11 deletions(-) - -diff --git a/src/mokutil.c b/src/mokutil.c -index f71cb6a..d1c3763 100644 ---- a/src/mokutil.c -+++ b/src/mokutil.c -@@ -43,8 +43,9 @@ EFI_GUID (0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, - #define HASH_FILE 0x4000 - #define GENERATE_PW_HASH 0x8000 - --#define DEFAULT_CRYPT_METHOD SHA256_BASED --#define DEFAULT_SALT_SIZE SHA256_SALT_MAX -+#define DEFAULT_CRYPT_METHOD SHA512_BASED -+#define DEFAULT_SALT_SIZE SHA512_SALT_MAX -+#define SETTINGS_LEN (DEFAULT_SALT_SIZE*2) - - typedef struct { - uint32_t mok_size; -@@ -384,7 +385,7 @@ generate_hash (pw_crypt_t *pw_crypt, char *password, int pw_len) - { - pw_crypt_t new_crypt; - struct crypt_data data; -- char settings[64]; -+ char settings[SETTINGS_LEN]; - char *crypt_string; - const char *prefix; - int hash_len, prefix_len; -@@ -1033,9 +1034,11 @@ static int - generate_pw_hash (const char *input_pw) - { - struct crypt_data data; -- char settings[SHA256_SALT_MAX + 3 + 1]; -+ char settings[SETTINGS_LEN]; - char *password = NULL; - char *crypt_string; -+ const char *prefix; -+ int prefix_len; - int pw_len, ret = -1; - - if (input_pw) { -@@ -1058,9 +1061,15 @@ generate_pw_hash (const char *input_pw) - } - } - -- strncpy (settings, "$5$", 3); -- generate_salt ((uint8_t *)(settings + 3), SHA256_SALT_MAX, 0); -- settings[SHA256_SALT_MAX + 3] = '\0'; -+ prefix = get_crypt_prefix (DEFAULT_CRYPT_METHOD); -+ if (!prefix) -+ return -1; -+ prefix_len = strlen(prefix); -+ -+ strncpy (settings, prefix, prefix_len); -+ generate_salt ((uint8_t *)(settings + prefix_len), -+ DEFAULT_SALT_SIZE, DEFAULT_SALT_SIZE); -+ settings[DEFAULT_SALT_SIZE + prefix_len] = '\0'; - - crypt_string = crypt_r (password, settings, &data); - if (!crypt_string) { -diff --git a/src/password-crypt.c b/src/password-crypt.c -index f004049..84ee079 100644 ---- a/src/password-crypt.c -+++ b/src/password-crypt.c -@@ -7,6 +7,7 @@ - #define MIN(a,b) ((a)<(b)?(a):(b)) - - #define SHA256_DEFAULT_ROUNDS 5000 -+#define SHA512_DEFAULT_ROUNDS 5000 - - static const char b64t[64] = - "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; -@@ -14,9 +15,10 @@ static const char b64t[64] = - static const char sha256_prefix[] = "$5$"; - static const char sha512_prefix[] = "$6$"; - --static const char sha256_rounds_prefix[] = "rounds="; -+static const char sha_rounds_prefix[] = "rounds="; - - static int restore_sha256_array (const char *string, uint8_t *hash); -+static int restore_sha512_array (const char *string, uint8_t *hash); - - int - get_hash_size (int method) -@@ -70,8 +72,8 @@ decode_sha256_pass (const char *string, pw_crypt_t *pw_crypt) - - /* get rounds */ - pw_crypt->iter_count = SHA256_DEFAULT_ROUNDS; -- if (strncmp (ptr, sha256_rounds_prefix, sizeof(sha256_rounds_prefix) - 1) == 0) { -- const char *num = ptr + sizeof(sha256_rounds_prefix) - 1; -+ if (strncmp (ptr, sha_rounds_prefix, sizeof(sha_rounds_prefix) - 1) == 0) { -+ const char *num = ptr + sizeof(sha_rounds_prefix) - 1; - char *endp; - unsigned long int srounds = strtoul (num, &endp, 10); - if (*endp == '$') { -@@ -110,6 +112,56 @@ decode_sha256_pass (const char *string, pw_crypt_t *pw_crypt) - return 0; - } - -+static int -+decode_sha512_pass (const char *string, pw_crypt_t *pw_crypt) -+{ -+ /* Expected string: (rounds=[0-9]{1,9}\$)?([./0-9A-Za-z]{1,16})?\$[./0-9A-Za-z]{86} */ -+ char *tmp, *ptr = (char *)string; -+ char *b64_hash; -+ int count = 0; -+ -+ /* get rounds */ -+ pw_crypt->iter_count = SHA512_DEFAULT_ROUNDS; -+ if (strncmp (ptr, sha_rounds_prefix, sizeof(sha_rounds_prefix) - 1) == 0) { -+ const char *num = ptr + sizeof(sha_rounds_prefix) - 1; -+ char *endp; -+ unsigned long int srounds = strtoul (num, &endp, 10); -+ if (*endp == '$') { -+ ptr = endp + 1; -+ pw_crypt->iter_count = (uint32_t)srounds; -+ } else { -+ return -1; -+ } -+ } -+ -+ /* get salt */ -+ for (tmp = ptr; *tmp != '$'; tmp++) { -+ if (tmp == '\0') -+ return -1; -+ count++; -+ } -+ count = MIN(count, SHA512_SALT_MAX); -+ memcpy (pw_crypt->salt, ptr, count); -+ pw_crypt->salt_size = count; -+ ptr = tmp + 1; -+ -+ /* get hash */ -+ if (strlen(ptr) < SHA512_B64_LENGTH) -+ return -1; -+ b64_hash = malloc (SHA512_B64_LENGTH + 1); -+ if (!b64_hash) -+ return -1; -+ memcpy (b64_hash, ptr, SHA512_B64_LENGTH); -+ b64_hash[SHA512_B64_LENGTH] = '\0'; -+ -+ if (restore_sha512_array (b64_hash, pw_crypt->hash) < 0) -+ return -1; -+ -+ free (b64_hash); -+ -+ return 0; -+} -+ - int - decode_pass (const char *crypt_pass, pw_crypt_t *pw_crypt) - { -@@ -118,7 +170,12 @@ decode_pass (const char *crypt_pass, pw_crypt_t *pw_crypt) - - if (strncmp (crypt_pass, sha256_prefix, 3) == 0) { - pw_crypt->method = SHA256_BASED; -- return decode_sha256_pass (crypt_pass + 3, pw_crypt); -+ return decode_sha256_pass (crypt_pass + strlen (sha256_prefix), pw_crypt); -+ } -+ -+ if (strncmp (crypt_pass, sha512_prefix, 3) == 0) { -+ pw_crypt->method = SHA512_BASED; -+ return decode_sha512_pass (crypt_pass + strlen (sha512_prefix), pw_crypt); - } - - return -1; -@@ -215,4 +272,66 @@ restore_sha256_array (const char *string, uint8_t *hash) - return 0; - } - -+int -+restore_sha512_array (const char *string, uint8_t *hash) -+{ -+ uint32_t tmp = 0; -+ int value1, value2; -+ -+ if (strlen (string) != SHA512_B64_LENGTH) -+ return -1; -+ -+ if (split_24bit (string, hash, 0, 4, 0, 21, 42) < 0) -+ return -1; -+ if (split_24bit (string, hash, 4, 4, 22, 43, 1) < 0) -+ return -1; -+ if (split_24bit (string, hash, 8, 4, 44, 2, 23) < 0) -+ return -1; -+ if (split_24bit (string, hash, 12, 4, 3, 24, 45) < 0) -+ return -1; -+ if (split_24bit (string, hash, 16, 4, 25, 46, 4) < 0) -+ return -1; -+ if (split_24bit (string, hash, 20, 4, 47, 5, 26) < 0) -+ return -1; -+ if (split_24bit (string, hash, 24, 4, 6, 27, 48) < 0) -+ return -1; -+ if (split_24bit (string, hash, 28, 4, 28, 49, 7) < 0) -+ return -1; -+ if (split_24bit (string, hash, 32, 4, 50, 8, 29) < 0) -+ return -1; -+ if (split_24bit (string, hash, 36, 4, 9, 30, 51) < 0) -+ return -1; -+ if (split_24bit (string, hash, 40, 4, 31, 52, 10) < 0) -+ return -1; -+ if (split_24bit (string, hash, 44, 4, 53, 11, 32) < 0) -+ return -1; -+ if (split_24bit (string, hash, 48, 4, 12, 33, 54) < 0) -+ return -1; -+ if (split_24bit (string, hash, 52, 4, 34, 55, 13) < 0) -+ return -1; -+ if (split_24bit (string, hash, 56, 4, 56, 14, 35) < 0) -+ return -1; -+ if (split_24bit (string, hash, 60, 4, 15, 36, 57) < 0) -+ return -1; -+ if (split_24bit (string, hash, 64, 4, 37, 58, 16) < 0) -+ return -1; -+ if (split_24bit (string, hash, 68, 4, 59, 17, 38) < 0) -+ return -1; -+ if (split_24bit (string, hash, 72, 4, 18, 39, 60) < 0) -+ return -1; -+ if (split_24bit (string, hash, 76, 4, 40, 61, 19) < 0) -+ return -1; -+ if (split_24bit (string, hash, 80, 4, 62, 20, 41) < 0) -+ return -1; -+ -+ value1 = b64_to_int (string[85]); -+ if (value1 < 0) -+ return -1; -+ value2 = b64_to_int (string[84]); -+ if (value2 < 0) -+ return -1; -+ tmp = (value1 << 6) | value2; -+ hash[63] = (uint8_t)tmp; - -+ return 0; -+} -diff --git a/src/password-crypt.h b/src/password-crypt.h -index 149a05e..a1f7710 100644 ---- a/src/password-crypt.h -+++ b/src/password-crypt.h -@@ -32,6 +32,7 @@ typedef struct { - #define PASSWORD_CRYPT_SIZE sizeof(pw_crypt_t) - - #define SHA256_B64_LENGTH 43 -+#define SHA512_B64_LENGTH 86 - - int get_hash_size (int method); - const char *get_crypt_prefix (int method); --- -1.7.10.4 - - -From 032018daddfe6bca086c5ef1f79d147e3ac0b02a Mon Sep 17 00:00:00 2001 -From: Gary Ching-Pang Lin -Date: Fri, 25 Jan 2013 14:22:02 +0800 -Subject: [PATCH 3/9] Add the new option to import root password hash - ---- - src/mokutil.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++----------- - 1 file changed, 63 insertions(+), 15 deletions(-) - -diff --git a/src/mokutil.c b/src/mokutil.c -index d1c3763..006eff1 100644 ---- a/src/mokutil.c -+++ b/src/mokutil.c -@@ -7,6 +7,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -42,6 +43,7 @@ EFI_GUID (0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, - #define RESET 0x2000 - #define HASH_FILE 0x4000 - #define GENERATE_PW_HASH 0x8000 -+#define ROOT_PW 0x10000 - - #define DEFAULT_CRYPT_METHOD SHA512_BASED - #define DEFAULT_SALT_SIZE SHA512_SALT_MAX -@@ -83,6 +85,9 @@ print_help () - printf (" --hash-file \t\tUse the specific password hash\n"); - printf (" \t\t(Only valid with --import, --delete,\n"); - printf (" \t\t --password, and --reset)\n"); -+ printf (" --root-pw\t\t\t\tUse the root password\n"); -+ printf (" \t\t\t\t(Only valid with --import, --delete,\n"); -+ printf (" \t\t\t\t --password, and --reset)\n"); - } - - static int -@@ -448,8 +453,23 @@ get_hash_from_file (const char *file, pw_crypt_t *pw_crypt) - } - - static int -+get_password_from_shadow (pw_crypt_t *pw_crypt) -+{ -+ struct spwd *pw_ent; -+ -+ pw_ent = getspnam ("root"); -+ if (!pw_ent) -+ return -1; -+ -+ if (decode_pass (pw_ent->sp_pwdp, pw_crypt) < 0) -+ return -1; -+ -+ return 0; -+} -+ -+static int - update_request (void *new_list, int list_len, uint8_t import, -- const char *hash_file) -+ const char *hash_file, const int root_pw) - { - efi_variable_t var; - const char *req_name, *auth_name; -@@ -474,6 +494,11 @@ update_request (void *new_list, int list_len, uint8_t import, - fprintf (stderr, "Failed to read hash\n"); - goto error; - } -+ } else if (root_pw) { -+ if (get_password_from_shadow (&pw_crypt) < 0) { -+ fprintf (stderr, "Failed to get root password hash\n"); -+ goto error; -+ } - } else { - if (get_password (&password, &pw_len, PASSWORD_MIN, PASSWORD_MAX) < 0) { - fprintf (stderr, "Abort\n"); -@@ -618,7 +643,7 @@ is_valid_request (void *mok, uint32_t mok_size, uint8_t import) - - static int - issue_mok_request (char **files, uint32_t total, uint8_t import, -- const char *hash_file) -+ const char *hash_file, const int root_pw) - { - efi_variable_t old_req; - const char *req_name; -@@ -731,7 +756,7 @@ issue_mok_request (char **files, uint32_t total, uint8_t import, - real_size += old_req.DataSize; - } - -- if (update_request (new_list, real_size, import, hash_file) < 0) { -+ if (update_request (new_list, real_size, import, hash_file, root_pw) < 0) { - goto error; - } - -@@ -748,15 +773,17 @@ error: - } - - static int --import_moks (char **files, uint32_t total, const char *hash_file) -+import_moks (char **files, uint32_t total, const char *hash_file, -+ const int root_pw) - { -- return issue_mok_request (files, total, 1, hash_file); -+ return issue_mok_request (files, total, 1, hash_file, root_pw); - } - - static int --delete_moks (char **files, uint32_t total, const char *hash_file) -+delete_moks (char **files, uint32_t total, const char *hash_file, -+ const int root_pw) - { -- return issue_mok_request (files, total, 0, hash_file); -+ return issue_mok_request (files, total, 0, hash_file, root_pw); - } - - static int -@@ -832,7 +859,7 @@ error: - } - - static int --set_password (const char *hash_file) -+set_password (const char *hash_file, const int root_pw) - { - efi_variable_t var; - pw_crypt_t pw_crypt; -@@ -848,6 +875,11 @@ set_password (const char *hash_file) - fprintf (stderr, "Failed to read hash\n"); - goto error; - } -+ } else if (root_pw) { -+ if (get_password_from_shadow (&pw_crypt) < 0) { -+ fprintf (stderr, "Failed to get root password hash\n"); -+ goto error; -+ } - } else { - if (get_password (&password, &pw_len, PASSWORD_MIN, PASSWORD_MAX) < 0) { - fprintf (stderr, "Abort\n"); -@@ -1020,9 +1052,9 @@ error: - } - - static int --reset_moks (const char *hash_file) -+reset_moks (const char *hash_file, const int root_pw) - { -- if (update_request (NULL, 0, 1, hash_file)) { -+ if (update_request (NULL, 0, 1, hash_file, root_pw)) { - fprintf (stderr, "Failed to issue a reset request\n"); - return -1; - } -@@ -1117,11 +1149,12 @@ main (int argc, char *argv[]) - {"reset", no_argument, 0, 0 }, - {"hash-file", required_argument, 0, 'f'}, - {"generate-hash", optional_argument, 0, 'g'}, -+ {"root-pw", no_argument, 0, 'P'}, - {0, 0, 0, 0} - }; - - int option_index = 0; -- c = getopt_long (argc, argv, "d:f:g::hi:pt:x", -+ c = getopt_long (argc, argv, "d:f:g::hi:pt:xP", - long_options, &option_index); - - if (c == -1) -@@ -1189,6 +1222,9 @@ main (int argc, char *argv[]) - case 'p': - command |= PASSWORD; - break; -+ case 'P': -+ command |= ROOT_PW; -+ break; - case 't': - key_file = strdup (optarg); - -@@ -1215,11 +1251,17 @@ main (int argc, char *argv[]) - break; - case IMPORT: - case IMPORT | HASH_FILE: -- ret = import_moks (files, total, hash_file); -+ ret = import_moks (files, total, hash_file, 0); -+ break; -+ case IMPORT | ROOT_PW: -+ ret = import_moks (files, total, NULL, 1); - break; - case DELETE: - case DELETE | HASH_FILE: -- ret = delete_moks (files, total, hash_file); -+ ret = delete_moks (files, total, hash_file, 0); -+ break; -+ case DELETE | ROOT_PW: -+ ret = delete_moks (files, total, NULL, 1); - break; - case REVOKE_IMPORT: - ret = revoke_request (1); -@@ -1232,7 +1274,10 @@ main (int argc, char *argv[]) - break; - case PASSWORD: - case PASSWORD | HASH_FILE: -- ret = set_password (hash_file); -+ ret = set_password (hash_file, 0); -+ break; -+ case PASSWORD | ROOT_PW: -+ ret = set_password (NULL, 1); - break; - case DISABLE_VALIDATION: - ret = disable_validation (); -@@ -1248,7 +1293,10 @@ main (int argc, char *argv[]) - break; - case RESET: - case RESET | HASH_FILE: -- ret = reset_moks (hash_file); -+ ret = reset_moks (hash_file, 0); -+ break; -+ case RESET | ROOT_PW: -+ ret = reset_moks (NULL, 1); - break; - case GENERATE_PW_HASH: - ret = generate_pw_hash (input_pw); --- -1.7.10.4 - - -From 282c97b30c87687e43a019fcde3db8d809f8d227 Mon Sep 17 00:00:00 2001 -From: Gary Ching-Pang Lin -Date: Fri, 25 Jan 2013 18:29:06 +0800 -Subject: [PATCH 4/9] Support blowfish-based crypt() hash - ---- - src/mokutil.c | 15 +++++++++++++++ - src/password-crypt.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++-- - src/password-crypt.h | 3 +-- - 3 files changed, 62 insertions(+), 4 deletions(-) - -diff --git a/src/mokutil.c b/src/mokutil.c -index 006eff1..b6c665d 100644 ---- a/src/mokutil.c -+++ b/src/mokutil.c -@@ -508,10 +508,18 @@ update_request (void *new_list, int list_len, uint8_t import, - pw_crypt.salt_size = generate_salt (pw_crypt.salt, - DEFAULT_SALT_SIZE, - DEFAULT_SALT_SIZE); -+ - if (generate_hash (&pw_crypt, password, pw_len) < 0) { - fprintf (stderr, "Couldn't generate hash\n"); - goto error; - } -+ if (pw_crypt.method == BLOWFISH_BASED) { -+ const char *prefix = get_crypt_prefix (BLOWFISH_BASED); -+ memmove (pw_crypt.salt + 7, pw_crypt.salt, BLOWFISH_SALT_MAX); -+ memcpy (pw_crypt.salt, prefix, 7); -+ pw_crypt.salt[7 + BLOWFISH_SALT_MAX] = '\0'; -+ pw_crypt.salt_size = BLOWFISH_SALT_MAX + 7 + 1; -+ } - } - - if (new_list) { -@@ -893,6 +901,13 @@ set_password (const char *hash_file, const int root_pw) - fprintf (stderr, "Couldn't generate hash\n"); - goto error; - } -+ if (pw_crypt.method == BLOWFISH_BASED) { -+ const char *prefix = get_crypt_prefix (BLOWFISH_BASED); -+ memmove (pw_crypt.salt + 7, pw_crypt.salt, BLOWFISH_SALT_MAX); -+ memcpy (pw_crypt.salt, prefix, 7); -+ pw_crypt.salt[7 + BLOWFISH_SALT_MAX] = '\0'; -+ pw_crypt.salt_size = BLOWFISH_SALT_MAX + 7 + 1; -+ } - } - - var.Data = (void *)&pw_crypt; -diff --git a/src/password-crypt.c b/src/password-crypt.c -index 84ee079..3ecb6ff 100644 ---- a/src/password-crypt.c -+++ b/src/password-crypt.c -@@ -6,6 +6,8 @@ - - #define MIN(a,b) ((a)<(b)?(a):(b)) - -+#define BLOWFISH_HASH_SIZE 31 /* 184 / 6 + 1 */ -+ - #define SHA256_DEFAULT_ROUNDS 5000 - #define SHA512_DEFAULT_ROUNDS 5000 - -@@ -15,6 +17,10 @@ static const char b64t[64] = - static const char sha256_prefix[] = "$5$"; - static const char sha512_prefix[] = "$6$"; - -+static const char bf_a_prefix[] = "$2a$"; -+static const char bf_x_prefix[] = "$2x$"; -+static const char bf_y_prefix[] = "$2y$"; -+ - static const char sha_rounds_prefix[] = "rounds="; - - static int restore_sha256_array (const char *string, uint8_t *hash); -@@ -35,7 +41,7 @@ get_hash_size (int method) - case SHA512_BASED: - return SHA512_DIGEST_LENGTH; - case BLOWFISH_BASED: -- return 184 / 8; /* per "man crypt" */ -+ return BLOWFISH_HASH_SIZE; - } - - return -1; -@@ -56,7 +62,7 @@ get_crypt_prefix (int method) - case SHA512_BASED: - return "$6$"; - case BLOWFISH_BASED: -- return "$2y$"; /* per "man crypt" */ -+ return "$2y$10$"; /* FIXME change the count */ - } - - return NULL; -@@ -162,6 +168,37 @@ decode_sha512_pass (const char *string, pw_crypt_t *pw_crypt) - return 0; - } - -+static int -+decode_blowfish_pass (const char *string, pw_crypt_t *pw_crypt) -+{ -+ /* Expected string: \$2[axy]\$[0-9]{2}\$[./A-Za-z0-9]{53} */ -+ /* Store the first (22+7) bytes in salt[] and the rest in hash */ -+ -+ if (strlen(string) != (53 + 7)) -+ return -1; -+ -+ if (string[0] != '$' || -+ string[1] != '2' || -+ (string[2] != 'a' && string[2] != 'x' && string[2] != 'y') || -+ string[3] != '$' || -+ string[4] < '0' || string[4] > '3' || -+ string[5] < '0' || string[5] > '9' || -+ (string[4] == '3' && string[5] > '1') || -+ string[6] != '$') { -+ return -1; -+ } -+ -+ pw_crypt->iter_count = 0; -+ -+ memcpy (pw_crypt->salt, string, (22 + 7)); -+ pw_crypt->salt[22 + 7] = '\0'; -+ pw_crypt->salt_size = 22 + 7 + 1; -+ -+ memcpy (pw_crypt->hash, string + 22 + 7, BLOWFISH_HASH_SIZE); -+ -+ return 0; -+} -+ - int - decode_pass (const char *crypt_pass, pw_crypt_t *pw_crypt) - { -@@ -178,6 +215,13 @@ decode_pass (const char *crypt_pass, pw_crypt_t *pw_crypt) - return decode_sha512_pass (crypt_pass + strlen (sha512_prefix), pw_crypt); - } - -+ if (strncmp (crypt_pass, bf_a_prefix, 4) == 0 || -+ strncmp (crypt_pass, bf_x_prefix, 4) == 0 || -+ strncmp (crypt_pass, bf_y_prefix, 4) == 0) { -+ pw_crypt->method = BLOWFISH_BASED; -+ return decode_blowfish_pass (crypt_pass, pw_crypt); -+ } -+ - return -1; - } - -diff --git a/src/password-crypt.h b/src/password-crypt.h -index a1f7710..701dfd9 100644 ---- a/src/password-crypt.h -+++ b/src/password-crypt.h -@@ -9,8 +9,7 @@ - #define MD5_SALT_MAX 8 - #define SHA256_SALT_MAX 16 - #define SHA512_SALT_MAX 16 --/* The max salt size of Blowfish in UINT8 */ --#define BLOWFISH_SALT_MAX 16 -+#define BLOWFISH_SALT_MAX 22 - - enum HashMethod { - TRANDITIONAL_DES = 0, --- -1.7.10.4 - - -From 97f0dec8aa8f63a7ef81e060a512b13bcdf4e3a7 Mon Sep 17 00:00:00 2001 -From: Gary Ching-Pang Lin -Date: Mon, 28 Jan 2013 16:12:44 +0800 -Subject: [PATCH 5/9] Simplify the hash generation - ---- - src/mokutil.c | 30 +++++++++--------------------- - 1 file changed, 9 insertions(+), 21 deletions(-) - -diff --git a/src/mokutil.c b/src/mokutil.c -index b6c665d..ecf9e00 100644 ---- a/src/mokutil.c -+++ b/src/mokutil.c -@@ -403,6 +403,10 @@ generate_hash (pw_crypt_t *pw_crypt, char *password, int pw_len) - return -1; - prefix_len = strlen(prefix); - -+ pw_crypt->salt_size = generate_salt (pw_crypt->salt, -+ DEFAULT_SALT_SIZE, -+ DEFAULT_SALT_SIZE); -+ - strncpy (settings, prefix, prefix_len); - strncpy (settings + prefix_len, (const char *)pw_crypt->salt, - pw_crypt->salt_size); -@@ -421,6 +425,11 @@ generate_hash (pw_crypt_t *pw_crypt, char *password, int pw_len) - memcpy (pw_crypt->hash, new_crypt.hash, hash_len); - pw_crypt->iter_count = new_crypt.iter_count; - -+ if (pw_crypt->method == BLOWFISH_BASED) { -+ pw_crypt->salt_size = new_crypt.salt_size; -+ memcpy (pw_crypt->salt, new_crypt.salt, new_crypt.salt_size); -+ } -+ - return 0; - } - -@@ -505,21 +514,10 @@ update_request (void *new_list, int list_len, uint8_t import, - goto error; - } - -- pw_crypt.salt_size = generate_salt (pw_crypt.salt, -- DEFAULT_SALT_SIZE, -- DEFAULT_SALT_SIZE); -- - if (generate_hash (&pw_crypt, password, pw_len) < 0) { - fprintf (stderr, "Couldn't generate hash\n"); - goto error; - } -- if (pw_crypt.method == BLOWFISH_BASED) { -- const char *prefix = get_crypt_prefix (BLOWFISH_BASED); -- memmove (pw_crypt.salt + 7, pw_crypt.salt, BLOWFISH_SALT_MAX); -- memcpy (pw_crypt.salt, prefix, 7); -- pw_crypt.salt[7 + BLOWFISH_SALT_MAX] = '\0'; -- pw_crypt.salt_size = BLOWFISH_SALT_MAX + 7 + 1; -- } - } - - if (new_list) { -@@ -894,20 +892,10 @@ set_password (const char *hash_file, const int root_pw) - goto error; - } - -- pw_crypt.salt_size = generate_salt (pw_crypt.salt, -- DEFAULT_SALT_SIZE, -- DEFAULT_SALT_SIZE); - if (generate_hash (&pw_crypt, password, pw_len) < 0) { - fprintf (stderr, "Couldn't generate hash\n"); - goto error; - } -- if (pw_crypt.method == BLOWFISH_BASED) { -- const char *prefix = get_crypt_prefix (BLOWFISH_BASED); -- memmove (pw_crypt.salt + 7, pw_crypt.salt, BLOWFISH_SALT_MAX); -- memcpy (pw_crypt.salt, prefix, 7); -- pw_crypt.salt[7 + BLOWFISH_SALT_MAX] = '\0'; -- pw_crypt.salt_size = BLOWFISH_SALT_MAX + 7 + 1; -- } - } - - var.Data = (void *)&pw_crypt; --- -1.7.10.4 - - -From 9205203a929aac32fc1e4a53cd8e1c1bb74cfde3 Mon Sep 17 00:00:00 2001 -From: Gary Ching-Pang Lin -Date: Tue, 29 Jan 2013 12:16:17 +0800 -Subject: [PATCH 6/9] Support MD5-based crypt() hash - ---- - src/password-crypt.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++ - src/password-crypt.h | 1 + - 2 files changed, 77 insertions(+) - -diff --git a/src/password-crypt.c b/src/password-crypt.c -index 3ecb6ff..e435ad3 100644 ---- a/src/password-crypt.c -+++ b/src/password-crypt.c -@@ -14,6 +14,8 @@ - static const char b64t[64] = - "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - -+static const char md5_prefix[] = "$1$"; -+ - static const char sha256_prefix[] = "$5$"; - static const char sha512_prefix[] = "$6$"; - -@@ -23,6 +25,7 @@ static const char bf_y_prefix[] = "$2y$"; - - static const char sha_rounds_prefix[] = "rounds="; - -+static int restore_md5_array (const char *string, uint8_t *hash); - static int restore_sha256_array (const char *string, uint8_t *hash); - static int restore_sha512_array (const char *string, uint8_t *hash); - -@@ -69,6 +72,39 @@ get_crypt_prefix (int method) - } - - static int -+decode_md5_pass (const char *string, pw_crypt_t *pw_crypt) -+{ -+ /* Expected string: [./0-9A-Za-z]{1,8}\$[./0-9A-Za-z]{22} */ -+ char *tmp, *ptr = (char *)string; -+ char b64_hash[MD5_B64_LENGTH + 1]; -+ int count = 0; -+ -+ pw_crypt->iter_count = 1000; -+ -+ /* get salt */ -+ for (tmp = ptr; *tmp != '$'; tmp++) { -+ if (*tmp == '\0') -+ return -1; -+ count++; -+ } -+ count = MIN(count, MD5_SALT_MAX); -+ memcpy (pw_crypt->salt, ptr, count); -+ pw_crypt->salt_size = count; -+ ptr = tmp + 1; -+ -+ /* get hash */ -+ if (strlen(ptr) != MD5_B64_LENGTH) -+ return -1; -+ memcpy (b64_hash, ptr, MD5_B64_LENGTH); -+ b64_hash[MD5_B64_LENGTH] = '\0'; -+ -+ if (restore_md5_array (b64_hash, pw_crypt->hash) < 0) -+ return -1; -+ -+ return 0; -+} -+ -+static int - decode_sha256_pass (const char *string, pw_crypt_t *pw_crypt) - { - /* Expected string: (rounds=[0-9]{1,9}\$)?([./0-9A-Za-z]{1,16})?\$[./0-9A-Za-z]{43} */ -@@ -205,6 +241,11 @@ decode_pass (const char *crypt_pass, pw_crypt_t *pw_crypt) - if (!pw_crypt) - return -1; - -+ if (strncmp (crypt_pass, md5_prefix, 3) == 0) { -+ pw_crypt->method = MD5_BASED; -+ return decode_md5_pass (crypt_pass + strlen (md5_prefix), pw_crypt); -+ } -+ - if (strncmp (crypt_pass, sha256_prefix, 3) == 0) { - pw_crypt->method = SHA256_BASED; - return decode_sha256_pass (crypt_pass + strlen (sha256_prefix), pw_crypt); -@@ -273,6 +314,41 @@ split_24bit (const char *string, uint8_t *hash, int start, int n, - return 0; - } - -+int restore_md5_array (const char *string, uint8_t *hash) -+{ -+ uint32_t tmp = 0; -+ int value1, value2; -+ -+ if (strlen (string) != MD5_B64_LENGTH) -+ return -1; -+ -+ if (split_24bit (string, hash, 0, 4, 0, 6, 12) < 0) -+ return -1; -+ -+ if (split_24bit (string, hash, 4, 4, 1, 7, 13) < 0) -+ return -1; -+ -+ if (split_24bit (string, hash, 8, 4, 2, 8, 14) < 0) -+ return -1; -+ -+ if (split_24bit (string, hash, 12, 4, 3, 9, 15) < 0) -+ return -1; -+ -+ if (split_24bit (string, hash, 16, 4, 4, 10, 5) < 0) -+ return -1; -+ -+ value1 = b64_to_int (string[21]); -+ if (value1 < 0) -+ return -1; -+ value2 = b64_to_int (string[20]); -+ if (value2 < 0) -+ return -1; -+ tmp = (value1 << 6) | value2; -+ hash[11] = (uint8_t)tmp; -+ -+ return 0; -+} -+ - int - restore_sha256_array (const char *string, uint8_t *hash) - { -diff --git a/src/password-crypt.h b/src/password-crypt.h -index 701dfd9..aba6975 100644 ---- a/src/password-crypt.h -+++ b/src/password-crypt.h -@@ -30,6 +30,7 @@ typedef struct { - - #define PASSWORD_CRYPT_SIZE sizeof(pw_crypt_t) - -+#define MD5_B64_LENGTH 22 - #define SHA256_B64_LENGTH 43 - #define SHA512_B64_LENGTH 86 - --- -1.7.10.4 - - -From 472dbeefd87085e4164369110e0ba3d8bf05a964 Mon Sep 17 00:00:00 2001 -From: Gary Ching-Pang Lin -Date: Tue, 29 Jan 2013 13:59:36 +0800 -Subject: [PATCH 7/9] Fix SHA256/SHA512 parsing on hashes with no salt - ---- - src/password-crypt.c | 60 +++++++++++++++++++++++++++----------------------- - 1 file changed, 32 insertions(+), 28 deletions(-) - -diff --git a/src/password-crypt.c b/src/password-crypt.c -index e435ad3..de15193 100644 ---- a/src/password-crypt.c -+++ b/src/password-crypt.c -@@ -109,7 +109,7 @@ decode_sha256_pass (const char *string, pw_crypt_t *pw_crypt) - { - /* Expected string: (rounds=[0-9]{1,9}\$)?([./0-9A-Za-z]{1,16})?\$[./0-9A-Za-z]{43} */ - char *tmp, *ptr = (char *)string; -- char *b64_hash; -+ char b64_hash[SHA256_B64_LENGTH + 1]; - int count = 0; - - /* get rounds */ -@@ -127,30 +127,32 @@ decode_sha256_pass (const char *string, pw_crypt_t *pw_crypt) - } - - /* get salt */ -- for (tmp = ptr; *tmp != '$'; tmp++) { -- if (tmp == '\0') -- return -1; -- count++; -+ tmp = ptr; -+ if (strlen (ptr) > SHA256_B64_LENGTH) { -+ while (*tmp != '$') { -+ if (tmp == '\0') -+ return -1; -+ count++; -+ tmp++; -+ } -+ -+ count = MIN(count, SHA256_SALT_MAX); -+ memcpy (pw_crypt->salt, ptr, count); -+ pw_crypt->salt_size = count; -+ ptr = tmp + 1; -+ } else { -+ pw_crypt->salt_size = 0; - } -- count = MIN(count, SHA256_SALT_MAX); -- memcpy (pw_crypt->salt, ptr, count); -- pw_crypt->salt_size = count; -- ptr = tmp + 1; - - /* get hash */ - if (strlen(ptr) < SHA256_B64_LENGTH) - return -1; -- b64_hash = malloc (SHA256_B64_LENGTH + 1); -- if (!b64_hash) -- return -1; - memcpy (b64_hash, ptr, SHA256_B64_LENGTH); - b64_hash[SHA256_B64_LENGTH] = '\0'; - - if (restore_sha256_array (b64_hash, pw_crypt->hash) < 0) - return -1; - -- free (b64_hash); -- - return 0; - } - -@@ -159,7 +161,7 @@ decode_sha512_pass (const char *string, pw_crypt_t *pw_crypt) - { - /* Expected string: (rounds=[0-9]{1,9}\$)?([./0-9A-Za-z]{1,16})?\$[./0-9A-Za-z]{86} */ - char *tmp, *ptr = (char *)string; -- char *b64_hash; -+ char b64_hash[SHA512_B64_LENGTH + 1]; - int count = 0; - - /* get rounds */ -@@ -177,30 +179,32 @@ decode_sha512_pass (const char *string, pw_crypt_t *pw_crypt) - } - - /* get salt */ -- for (tmp = ptr; *tmp != '$'; tmp++) { -- if (tmp == '\0') -- return -1; -- count++; -+ tmp = ptr; -+ if (strlen (ptr) > SHA512_B64_LENGTH) { -+ while (*tmp != '$') { -+ if (tmp == '\0') -+ return -1; -+ count++; -+ tmp++; -+ } -+ -+ count = MIN(count, SHA512_SALT_MAX); -+ memcpy (pw_crypt->salt, ptr, count); -+ pw_crypt->salt_size = count; -+ ptr = tmp + 1; -+ } else { -+ pw_crypt->salt_size = 0; - } -- count = MIN(count, SHA512_SALT_MAX); -- memcpy (pw_crypt->salt, ptr, count); -- pw_crypt->salt_size = count; -- ptr = tmp + 1; - - /* get hash */ - if (strlen(ptr) < SHA512_B64_LENGTH) - return -1; -- b64_hash = malloc (SHA512_B64_LENGTH + 1); -- if (!b64_hash) -- return -1; - memcpy (b64_hash, ptr, SHA512_B64_LENGTH); - b64_hash[SHA512_B64_LENGTH] = '\0'; - - if (restore_sha512_array (b64_hash, pw_crypt->hash) < 0) - return -1; - -- free (b64_hash); -- - return 0; - } - --- -1.7.10.4 - - -From ddd501071734325a213fe994471dac269c69153a Mon Sep 17 00:00:00 2001 -From: Gary Ching-Pang Lin -Date: Tue, 29 Jan 2013 16:34:59 +0800 -Subject: [PATCH 8/9] Just use crypt() to generate hashes - ---- - src/mokutil.c | 7 ++----- - 1 file changed, 2 insertions(+), 5 deletions(-) - -diff --git a/src/mokutil.c b/src/mokutil.c -index ecf9e00..27ebf09 100644 ---- a/src/mokutil.c -+++ b/src/mokutil.c -@@ -12,7 +12,6 @@ - #include - #include - --#define __USE_GNU - #include - - #include "efi.h" -@@ -389,7 +388,6 @@ static int - generate_hash (pw_crypt_t *pw_crypt, char *password, int pw_len) - { - pw_crypt_t new_crypt; -- struct crypt_data data; - char settings[SETTINGS_LEN]; - char *crypt_string; - const char *prefix; -@@ -412,7 +410,7 @@ generate_hash (pw_crypt_t *pw_crypt, char *password, int pw_len) - pw_crypt->salt_size); - settings[pw_crypt->salt_size + prefix_len] = '\0'; - -- crypt_string = crypt_r (password, settings, &data); -+ crypt_string = crypt (password, settings); - if (!crypt_string) - return -1; - -@@ -1068,7 +1066,6 @@ reset_moks (const char *hash_file, const int root_pw) - static int - generate_pw_hash (const char *input_pw) - { -- struct crypt_data data; - char settings[SETTINGS_LEN]; - char *password = NULL; - char *crypt_string; -@@ -1106,7 +1103,7 @@ generate_pw_hash (const char *input_pw) - DEFAULT_SALT_SIZE, DEFAULT_SALT_SIZE); - settings[DEFAULT_SALT_SIZE + prefix_len] = '\0'; - -- crypt_string = crypt_r (password, settings, &data); -+ crypt_string = crypt (password, settings); - if (!crypt_string) { - fprintf (stderr, "Failed to generate hash\n"); - goto error; --- -1.7.10.4 - - -From f944da88acfffe80279de37c4181c9c19ff9a864 Mon Sep 17 00:00:00 2001 -From: Gary Ching-Pang Lin -Date: Tue, 29 Jan 2013 16:35:30 +0800 -Subject: [PATCH 9/9] Support Traditional DES hash - ---- - src/password-crypt.c | 29 +++++++++++++++++++++++++---- - src/password-crypt.h | 2 +- - 2 files changed, 26 insertions(+), 5 deletions(-) - -diff --git a/src/password-crypt.c b/src/password-crypt.c -index de15193..95bb687 100644 ---- a/src/password-crypt.c -+++ b/src/password-crypt.c -@@ -6,6 +6,8 @@ - - #define MIN(a,b) ((a)<(b)?(a):(b)) - -+#define TRAD_DES_HASH_SIZE 13 /* (64/6+1) + (12/6) */ -+#define BSDI_DES_HASH_SIZE 20 /* (64/6+1) + (24/6) + 4 + 1 */ - #define BLOWFISH_HASH_SIZE 31 /* 184 / 6 + 1 */ - - #define SHA256_DEFAULT_ROUNDS 5000 -@@ -33,10 +35,10 @@ int - get_hash_size (int method) - { - switch (method) { -- case TRANDITIONAL_DES: -- return 64 / 8; /* per "man crypt" */ -+ case TRADITIONAL_DES: -+ return TRAD_DES_HASH_SIZE; - case EXTEND_BSDI_DES: -- return 64 / 8; /* per "man crypt" */ -+ return BSDI_DES_HASH_SIZE; - case MD5_BASED: - return MD5_DIGEST_LENGTH; - case SHA256_BASED: -@@ -54,7 +56,7 @@ const char * - get_crypt_prefix (int method) - { - switch (method) { -- case TRANDITIONAL_DES: -+ case TRADITIONAL_DES: - return ""; /* per "man crypt" */ - case EXTEND_BSDI_DES: - return "_"; /* per "man crypt" */ -@@ -72,6 +74,20 @@ get_crypt_prefix (int method) - } - - static int -+decode_trad_des_pass (const char *string, pw_crypt_t *pw_crypt) -+{ -+ /* Expected string: [./0-9A-Za-z]{13} */ -+ pw_crypt->iter_count = 25; -+ pw_crypt->salt_size = 2; -+ memcpy (pw_crypt->salt, string, 2); -+ pw_crypt->salt[2] = '\0'; -+ memcpy (pw_crypt->hash, string, TRAD_DES_HASH_SIZE); -+ pw_crypt->hash[TRAD_DES_HASH_SIZE] = '\0'; -+ -+ return 0; -+} -+ -+static int - decode_md5_pass (const char *string, pw_crypt_t *pw_crypt) - { - /* Expected string: [./0-9A-Za-z]{1,8}\$[./0-9A-Za-z]{22} */ -@@ -267,6 +283,11 @@ decode_pass (const char *crypt_pass, pw_crypt_t *pw_crypt) - return decode_blowfish_pass (crypt_pass, pw_crypt); - } - -+ if (strlen (crypt_pass) == TRAD_DES_HASH_SIZE) { -+ pw_crypt->method = TRADITIONAL_DES; -+ return decode_trad_des_pass (crypt_pass, pw_crypt); -+ } -+ - return -1; - } - -diff --git a/src/password-crypt.h b/src/password-crypt.h -index aba6975..92338ad 100644 ---- a/src/password-crypt.h -+++ b/src/password-crypt.h -@@ -12,7 +12,7 @@ - #define BLOWFISH_SALT_MAX 22 - - enum HashMethod { -- TRANDITIONAL_DES = 0, -+ TRADITIONAL_DES = 0, - EXTEND_BSDI_DES, - MD5_BASED, - SHA256_BASED, --- -1.7.10.4 - diff --git a/mokutil-support-delete-keys.patch b/mokutil-support-delete-keys.patch deleted file mode 100644 index 20d03c4..0000000 --- a/mokutil-support-delete-keys.patch +++ /dev/null @@ -1,835 +0,0 @@ -From 36241509b1c96c3103becae75dc6df72d794cce7 Mon Sep 17 00:00:00 2001 -From: Gary Ching-Pang Lin -Date: Thu, 13 Dec 2012 17:09:34 +0800 -Subject: [PATCH 1/7] Move fail check to get_password() - ---- - src/mokutil.c | 83 ++++++++++++++++++++++++++++++++------------------------- - 1 file changed, 46 insertions(+), 37 deletions(-) - -diff --git a/src/mokutil.c b/src/mokutil.c -index aba1cfb..eea2b6c 100644 ---- a/src/mokutil.c -+++ b/src/mokutil.c -@@ -297,39 +297,60 @@ static int - get_password (char **password, int *len, int min, int max) - { - char *password_1, *password_2; -- int len_1, len_2; -+ int len_1, len_2, fail, ret = -1; - size_t n; - - password_1 = password_2 = NULL; - -- printf ("input password (%d~%d characters): ", min, max); -- len_1 = read_hidden_line (&password_1, &n); -- printf ("\n"); -+ fail = 0; - -- if (len_1 > max || len_1 < min) { -- free (password_1); -- fprintf (stderr, "password should be %d~%d characters\n", -- min, max); -- return -1; -+ while (fail < 3) { -+ printf ("input password (%d~%d characters): ", min, max); -+ len_1 = read_hidden_line (&password_1, &n); -+ printf ("\n"); -+ -+ if (len_1 > max || len_1 < min) { -+ fail++; -+ fprintf (stderr, "password should be %d~%d characters\n", -+ min, max); -+ } else { -+ break; -+ } - } - -- printf ("input password again: "); -- len_2 = read_hidden_line (&password_2, &n); -- printf ("\n"); -+ if (fail >= 3) { -+ if (password_1) -+ free (password_1); -+ goto error; -+ } - -- if (len_1 != len_2 || strcmp (password_1, password_2) != 0) { -- free (password_1); -- free (password_2); -- fprintf (stderr, "password doesn't match\n"); -- return -1; -+ fail = 0; -+ -+ while (fail < 3) { -+ printf ("input password again: "); -+ len_2 = read_hidden_line (&password_2, &n); -+ printf ("\n"); -+ -+ if (len_1 != len_2 || strcmp (password_1, password_2) != 0) { -+ fail++; -+ fprintf (stderr, "password doesn't match\n"); -+ } else { -+ break; -+ } - } - -+ if (fail >= 3) -+ goto error; -+ - *password = password_1; - *len = len_1; - -- free (password_2); -+ ret = 0; -+error: -+ if (password_2) -+ free (password_2); - -- return 0; -+ return ret; - } - - static int -@@ -364,14 +385,10 @@ update_request (void *new_list, int list_len) - efi_variable_t var; - uint8_t auth[SHA256_DIGEST_LENGTH]; - char *password = NULL; -- int pw_len, fail = 0; -+ int pw_len; - int ret = -1; - -- while (fail < 3 && -- get_password (&password, &pw_len, PASSWORD_MIN, PASSWORD_MAX) < 0) -- fail++; -- -- if (fail >= 3) { -+ if (get_password (&password, &pw_len, PASSWORD_MIN, PASSWORD_MAX) < 0) { - fprintf (stderr, "Abort\n"); - goto error; - } -@@ -745,14 +762,10 @@ set_password () - efi_variable_t var; - uint8_t auth[SHA256_DIGEST_LENGTH]; - char *password = NULL; -- int pw_len, fail = 0; -+ int pw_len; - int ret = -1; - -- while (fail < 3 && -- get_password (&password, &pw_len, PASSWORD_MIN, PASSWORD_MAX) < 0) -- fail++; -- -- if (fail >= 3) { -+ while (get_password (&password, &pw_len, PASSWORD_MIN, PASSWORD_MAX) < 0) { - fprintf (stderr, "Abort\n"); - goto error; - } -@@ -789,15 +802,11 @@ set_validation (uint32_t state) - efi_variable_t var; - MokSBVar sbvar; - char *password = NULL; -- int pw_len, fail = 0; -+ int pw_len; - efi_char16_t efichar_pass[PASSWORD_MAX]; - int ret = -1; - -- while (fail < 3 && -- get_password (&password, &pw_len, PASSWORD_MIN, PASSWORD_MAX) < 0) -- fail++; -- -- if (fail >= 3) { -+ while (get_password (&password, &pw_len, PASSWORD_MIN, PASSWORD_MAX) < 0) { - fprintf (stderr, "Abort\n"); - goto error; - } --- -1.7.10.4 - - -From 2649dde769b563f55a85ea68eb1fc9ce5bc7c984 Mon Sep 17 00:00:00 2001 -From: Gary Ching-Pang Lin -Date: Mon, 17 Dec 2012 16:22:41 +0800 -Subject: [PATCH 2/7] Add "--test-key" to test if the key is enrolled or not - ---- - src/mokutil.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 65 insertions(+) - -diff --git a/src/mokutil.c b/src/mokutil.c -index eea2b6c..68a25bc 100644 ---- a/src/mokutil.c -+++ b/src/mokutil.c -@@ -41,6 +41,7 @@ enum Command { - COMMAND_DISABLE_VALIDATION, - COMMAND_ENABLE_VALIDATION, - COMMAND_SB_STATE, -+ COMMAND_TEST_KEY, - }; - - static void -@@ -76,6 +77,9 @@ print_help () - - printf("SecureBoot State:\n"); - printf(" mokutil --sb-state\n\n"); -+ -+ printf("Test if the key is enrolled or not:\n"); -+ printf(" mokutil --test-key\n\n"); - } - - static int -@@ -882,10 +886,57 @@ sb_state () - return 0; - } - -+static int -+test_key (const char *key_file) -+{ -+ struct stat buf; -+ void *key = NULL; -+ ssize_t read_size; -+ int fd, ret = -1; -+ -+ if (stat (key_file, &buf) != 0) { -+ fprintf (stderr, "Failed to get file status, %s\n", key_file); -+ return -1; -+ } -+ -+ key = malloc (buf.st_size); -+ -+ fd = open (key_file, O_RDONLY); -+ if (fd < 0) { -+ fprintf (stderr, "Failed to open %s\n", key_file); -+ goto error; -+ } -+ -+ read_size = read (fd, key, buf.st_size); -+ if (read_size < 0 || read_size != buf.st_size) { -+ fprintf (stderr, "Failed to read %s\n", key_file); -+ goto error; -+ } -+ -+ if (!is_duplicate (key, read_size, "PK", EFI_GLOBAL_VARIABLE) && -+ !is_duplicate (key, read_size, "KEK", EFI_GLOBAL_VARIABLE) && -+ !is_duplicate (key, read_size, "db", EFI_GLOBAL_VARIABLE) && -+ !is_duplicate (key, read_size, "MokListRT", SHIM_LOCK_GUID) && -+ !is_duplicate (key, read_size, "MokNew", SHIM_LOCK_GUID)) { -+ printf ("%s is not enrolled\n", key_file); -+ ret = 0; -+ } else { -+ printf ("%s is already enrolled\n", key_file); -+ ret = 1; -+ } -+ -+error: -+ if (key) -+ free (key); -+ -+ return ret; -+} -+ - int - main (int argc, char *argv[]) - { - char **files = NULL; -+ char *key_file = NULL; - int i, total; - int command; - -@@ -962,6 +1013,17 @@ main (int argc, char *argv[]) - - command = COMMAND_SB_STATE; - -+ } else if (strcmp (argv[1], "--test-key") == 0) { -+ -+ if (argc < 3) { -+ print_help (); -+ return -1; -+ } -+ -+ key_file = argv[2]; -+ -+ command = COMMAND_TEST_KEY; -+ - } else { - fprintf (stderr, "Unknown argument: %s\n\n", argv[1]); - print_help (); -@@ -999,6 +1061,9 @@ main (int argc, char *argv[]) - case COMMAND_SB_STATE: - sb_state (); - break; -+ case COMMAND_TEST_KEY: -+ test_key (key_file); -+ break; - default: - fprintf (stderr, "Unknown command\n"); - break; --- -1.7.10.4 - - -From bba82fceec875ccf0d92eae1e9c7db54e92bcec9 Mon Sep 17 00:00:00 2001 -From: Gary Ching-Pang Lin -Date: Mon, 17 Dec 2012 16:33:59 +0800 -Subject: [PATCH 3/7] Handle the return values - ---- - src/mokutil.c | 25 +++++++++++++------------ - 1 file changed, 13 insertions(+), 12 deletions(-) - -diff --git a/src/mokutil.c b/src/mokutil.c -index 68a25bc..13ef69d 100644 ---- a/src/mokutil.c -+++ b/src/mokutil.c -@@ -939,6 +939,7 @@ main (int argc, char *argv[]) - char *key_file = NULL; - int i, total; - int command; -+ int ret = -1; - - if (argc < 2) { - print_help (); -@@ -1032,37 +1033,37 @@ main (int argc, char *argv[]) - - switch (command) { - case COMMAND_LIST_ENROLLED: -- list_enrolled_keys (); -+ ret = list_enrolled_keys (); - break; - case COMMAND_LIST_NEW: -- list_new_keys (); -+ ret = list_new_keys (); - break; - case COMMAND_IMPORT: -- import_moks (files, total); -+ ret = import_moks (files, total); - break; - case COMMAND_DELETE: -- delete_all (); -+ ret = delete_all (); - break; - case COMMAND_REVOKE: -- revoke_request (); -+ ret = revoke_request (); - break; - case COMMAND_EXPORT: -- export_moks (); -+ ret = export_moks (); - break; - case COMMAND_PASSWORD: -- set_password (); -+ ret = set_password (); - break; - case COMMAND_DISABLE_VALIDATION: -- disable_validation (); -+ ret = disable_validation (); - break; - case COMMAND_ENABLE_VALIDATION: -- enable_validation (); -+ ret = enable_validation (); - break; - case COMMAND_SB_STATE: -- sb_state (); -+ ret = sb_state (); - break; - case COMMAND_TEST_KEY: -- test_key (key_file); -+ ret = test_key (key_file); - break; - default: - fprintf (stderr, "Unknown command\n"); -@@ -1072,5 +1073,5 @@ main (int argc, char *argv[]) - if (files) - free (files); - -- return 0; -+ return ret; - } --- -1.7.10.4 - - -From fee5db0bd74fd7239832d435cdc653ade426c61c Mon Sep 17 00:00:00 2001 -From: Gary Ching-Pang Lin -Date: Mon, 24 Dec 2012 16:35:37 +0800 -Subject: [PATCH 4/7] Correct the GUID of "db" - ---- - src/efi.h | 2 ++ - src/mokutil.c | 2 +- - 2 files changed, 3 insertions(+), 1 deletion(-) - -diff --git a/src/efi.h b/src/efi.h -index 7185179..d2640b4 100644 ---- a/src/efi.h -+++ b/src/efi.h -@@ -86,6 +86,8 @@ EFI_GUID( 0x47c7b225, 0xc42a, 0x11d2, 0x8e, 0x57, 0x00, 0xa0, 0xc9, 0x69, 0x72, - EFI_GUID( 0x47c7b227, 0xc42a, 0x11d2, 0x8e, 0x57, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b) - #define ESP_UNKNOWN_GUID \ - EFI_GUID( 0x47c7b226, 0xc42a, 0x11d2, 0x8e, 0x57, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b) -+#define EFI_IMAGE_SECURITY_DATABASE_GUID \ -+EFI_GUID( 0xd719b2cb, 0x3d3a, 0x4596, 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f) - - static inline int - efi_guidcmp(efi_guid_t left, efi_guid_t right) -diff --git a/src/mokutil.c b/src/mokutil.c -index 13ef69d..6af5a9c 100644 ---- a/src/mokutil.c -+++ b/src/mokutil.c -@@ -636,7 +636,7 @@ import_moks (char **files, uint32_t total) - /* whether this key is already enrolled... */ - if (!is_duplicate (ptr, sizes[i], "PK", EFI_GLOBAL_VARIABLE) && - !is_duplicate (ptr, sizes[i], "KEK", EFI_GLOBAL_VARIABLE) && -- !is_duplicate (ptr, sizes[i], "db", EFI_GLOBAL_VARIABLE) && -+ !is_duplicate (ptr, sizes[i], "db", EFI_IMAGE_SECURITY_DATABASE_GUID) && - !is_duplicate (ptr, sizes[i], "MokListRT", SHIM_LOCK_GUID) && - !is_duplicate (ptr, sizes[i], "MokNew", SHIM_LOCK_GUID)) { - ptr += sizes[i]; --- -1.7.10.4 - - -From b1a6476307909b4c391b5cc632c0535ea43b08b1 Mon Sep 17 00:00:00 2001 -From: Gary Ching-Pang Lin -Date: Mon, 24 Dec 2012 18:12:48 +0800 -Subject: [PATCH 5/7] Initialize password array - ---- - src/mokutil.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/mokutil.c b/src/mokutil.c -index 6af5a9c..3d00df0 100644 ---- a/src/mokutil.c -+++ b/src/mokutil.c -@@ -509,7 +509,7 @@ verify_mok_new (void *mok_new, unsigned long mok_new_size) - { - efi_variable_t mok_auth; - uint8_t auth[SHA256_DIGEST_LENGTH]; -- char *password; -+ char *password = NULL; - int pw_len, fail = 0; - size_t n; - int ret = 0; --- -1.7.10.4 - - -From e772f72f23b4cf13c033292b55570a861281b71b Mon Sep 17 00:00:00 2001 -From: Gary Ching-Pang Lin -Date: Tue, 25 Dec 2012 15:53:56 +0800 -Subject: [PATCH 6/7] Add support for deleting specific keys - ---- - src/mokutil.c | 179 +++++++++++++++++++++++++++++++++++++++++---------------- - 1 file changed, 128 insertions(+), 51 deletions(-) - -diff --git a/src/mokutil.c b/src/mokutil.c -index 3d00df0..e6807da 100644 ---- a/src/mokutil.c -+++ b/src/mokutil.c -@@ -42,6 +42,7 @@ enum Command { - COMMAND_ENABLE_VALIDATION, - COMMAND_SB_STATE, - COMMAND_TEST_KEY, -+ COMMAND_RESET, - }; - - static void -@@ -57,8 +58,8 @@ print_help () - printf("Import keys:\n"); - printf(" mokutil --import ...\n\n"); - -- printf("Request to delete all keys\n"); -- printf(" mokutil --delete-all\n\n"); -+ printf("Request to delete specific keys\n"); -+ printf(" mokutil --delete ...\n\n"); - - printf("Revoke the request:\n"); - printf(" mokutil --revoke\n\n"); -@@ -80,6 +81,9 @@ print_help () - - printf("Test if the key is enrolled or not:\n"); - printf(" mokutil --test-key\n\n"); -+ -+ printf("Reset MOK list:\n"); -+ printf(" mokutil --reset\n\n"); - } - - static int -@@ -384,14 +388,23 @@ generate_auth (void *new_list, unsigned long list_len, char *password, - } - - static int --update_request (void *new_list, int list_len) -+update_request (void *new_list, int list_len, uint8_t import) - { - efi_variable_t var; -+ const char *req_name, *auth_name; - uint8_t auth[SHA256_DIGEST_LENGTH]; - char *password = NULL; - int pw_len; - int ret = -1; - -+ if (import) { -+ req_name = "MokNew"; -+ auth_name = "MokAuth"; -+ } else { -+ req_name = "MokDel"; -+ auth_name = "MokDelAuth"; -+ } -+ - if (get_password (&password, &pw_len, PASSWORD_MIN, PASSWORD_MAX) < 0) { - fprintf (stderr, "Abort\n"); - goto error; -@@ -403,7 +416,7 @@ update_request (void *new_list, int list_len) - /* Write MokNew*/ - var.Data = new_list; - var.DataSize = list_len; -- var.VariableName = "MokNew"; -+ var.VariableName = req_name; - - var.VendorGuid = SHIM_LOCK_GUID; - var.Attributes = EFI_VARIABLE_NON_VOLATILE -@@ -411,17 +424,18 @@ update_request (void *new_list, int list_len) - | EFI_VARIABLE_RUNTIME_ACCESS; - - if (edit_variable (&var) != EFI_SUCCESS) { -- fprintf (stderr, "Failed to enroll new keys\n"); -+ fprintf (stderr, "Failed to %s keys\n", -+ import ? "enroll new" : "delete"); - goto error; - } - } else { -- test_and_delete_var ("MokNew"); -+ test_and_delete_var (req_name); - } - - /* Write MokAuth */ - var.Data = auth; - var.DataSize = SHA256_DIGEST_LENGTH; -- var.VariableName = "MokAuth"; -+ var.VariableName = auth_name; - - var.VendorGuid = SHIM_LOCK_GUID; - var.Attributes = EFI_VARIABLE_NON_VOLATILE -@@ -429,8 +443,8 @@ update_request (void *new_list, int list_len) - | EFI_VARIABLE_RUNTIME_ACCESS; - - if (edit_variable (&var) != EFI_SUCCESS) { -- fprintf (stderr, "Failed to write MokAuth\n"); -- test_and_delete_var ("MokNew"); -+ fprintf (stderr, "Failed to write %s\n", auth_name); -+ test_and_delete_var (req_name); - goto error; - } - -@@ -505,20 +519,47 @@ done: - } - - static int --verify_mok_new (void *mok_new, unsigned long mok_new_size) -+is_valid_request (void *mok, uint32_t mok_size, uint8_t import) - { -- efi_variable_t mok_auth; -+ if (import) { -+ if (is_duplicate (mok, mok_size, "PK", EFI_GLOBAL_VARIABLE) || -+ is_duplicate (mok, mok_size, "KEK", EFI_GLOBAL_VARIABLE) || -+ is_duplicate (mok, mok_size, "db", EFI_IMAGE_SECURITY_DATABASE_GUID) || -+ is_duplicate (mok, mok_size, "MokListRT", SHIM_LOCK_GUID) || -+ is_duplicate (mok, mok_size, "MokNew", SHIM_LOCK_GUID)) { -+ return 0; -+ } -+ } else { -+ if (!is_duplicate (mok, mok_size, "MokListRT", SHIM_LOCK_GUID) || -+ is_duplicate (mok, mok_size, "MokDel", SHIM_LOCK_GUID)) { -+ return 0; -+ } -+ } -+ -+ return 1; -+} -+ -+static int -+verify_old_req (void *old_req, unsigned long old_req_size, uint8_t import) -+{ -+ efi_variable_t req_auth; -+ const char *auth_name; - uint8_t auth[SHA256_DIGEST_LENGTH]; - char *password = NULL; - int pw_len, fail = 0; - size_t n; - int ret = 0; - -- memset (&mok_auth, 0, sizeof(mok_auth)); -- mok_auth.VariableName = "MokAuth"; -- mok_auth.VendorGuid = SHIM_LOCK_GUID; -- if (read_variable (&mok_auth) != EFI_SUCCESS) { -- fprintf (stderr, "Failed to read MokAuth\n"); -+ if (import) -+ auth_name = "MokAuth"; -+ else -+ auth_name = "MokDelAuth"; -+ -+ memset (&req_auth, 0, sizeof(req_auth)); -+ req_auth.VariableName = auth_name; -+ req_auth.VendorGuid = SHIM_LOCK_GUID; -+ if (read_variable (&req_auth) != EFI_SUCCESS) { -+ fprintf (stderr, "Failed to read %s\n", auth_name); - return 0; - } - -@@ -534,8 +575,8 @@ verify_mok_new (void *mok_new, unsigned long mok_new_size) - continue; - } - -- generate_auth (mok_new, mok_new_size, password, pw_len, auth); -- if (memcmp (auth, mok_auth.Data, SHA256_DIGEST_LENGTH) == 0) { -+ generate_auth (old_req, old_req_size, password, pw_len, auth); -+ if (memcmp (auth, req_auth.Data, SHA256_DIGEST_LENGTH) == 0) { - ret = 1; - break; - } -@@ -543,16 +584,17 @@ verify_mok_new (void *mok_new, unsigned long mok_new_size) - fail++; - } - -- if (mok_auth.Data) -- free (mok_auth.Data); -+ if (req_auth.Data) -+ free (req_auth.Data); - - return ret; - } - - static int --import_moks (char **files, uint32_t total) -+issue_mok_request (char **files, uint32_t total, uint8_t import) - { -- efi_variable_t mok_new; -+ efi_variable_t old_req; -+ const char *req_name; - void *new_list = NULL; - void *ptr; - struct stat buf; -@@ -568,6 +610,11 @@ import_moks (char **files, uint32_t total) - if (!files) - return -1; - -+ if (import) -+ req_name = "MokNew"; -+ else -+ req_name = "MokDel"; -+ - sizes = malloc (total * sizeof(uint32_t)); - - if (!sizes) { -@@ -589,15 +636,15 @@ import_moks (char **files, uint32_t total) - list_size += sizeof(EFI_SIGNATURE_LIST) * total; - list_size += sizeof(efi_guid_t) * total; - -- memset (&mok_new, 0, sizeof(mok_new)); -- mok_new.VariableName = "MokNew"; -- mok_new.VendorGuid = SHIM_LOCK_GUID; -- if (read_variable (&mok_new) == EFI_SUCCESS) -- list_size += mok_new.DataSize; -+ memset (&old_req, 0, sizeof(old_req)); -+ old_req.VariableName = req_name; -+ old_req.VendorGuid = SHIM_LOCK_GUID; -+ if (read_variable (&old_req) == EFI_SUCCESS) -+ list_size += old_req.DataSize; - - new_list = malloc (list_size); - if (!new_list) { -- fprintf (stderr, "Failed to allocate space for MokNew\n"); -+ fprintf (stderr, "Failed to allocate space for %s\n", req_name); - goto error; - } - ptr = new_list; -@@ -633,15 +680,11 @@ import_moks (char **files, uint32_t total) - files[i]); - } - -- /* whether this key is already enrolled... */ -- if (!is_duplicate (ptr, sizes[i], "PK", EFI_GLOBAL_VARIABLE) && -- !is_duplicate (ptr, sizes[i], "KEK", EFI_GLOBAL_VARIABLE) && -- !is_duplicate (ptr, sizes[i], "db", EFI_IMAGE_SECURITY_DATABASE_GUID) && -- !is_duplicate (ptr, sizes[i], "MokListRT", SHIM_LOCK_GUID) && -- !is_duplicate (ptr, sizes[i], "MokNew", SHIM_LOCK_GUID)) { -+ if (is_valid_request (ptr, sizes[i], import)) { - ptr += sizes[i]; - real_size += sizes[i] + sizeof(EFI_SIGNATURE_LIST) + sizeof(efi_guid_t); - } else { -+ printf ("Skip %s\n", files[i]); - ptr -= sizeof(EFI_SIGNATURE_LIST) + sizeof(efi_guid_t); - } - -@@ -654,25 +697,25 @@ import_moks (char **files, uint32_t total) - goto error; - } - -- /* append the keys in MokNew */ -- if (mok_new.Data) { -+ /* append the keys to the previous request */ -+ if (old_req.Data) { - /* request the previous password to verify the keys */ -- if (!verify_mok_new (mok_new.Data, mok_new.DataSize)) { -+ if (!verify_old_req (old_req.Data, old_req.DataSize, import)) { - goto error; - } - -- memcpy (new_list + real_size, mok_new.Data, mok_new.DataSize); -- real_size += mok_new.DataSize; -+ memcpy (new_list + real_size, old_req.Data, old_req.DataSize); -+ real_size += old_req.DataSize; - } - -- if (update_request (new_list, real_size) < 0) { -+ if (update_request (new_list, real_size, import) < 0) { - goto error; - } - - ret = 0; - error: -- if (mok_new.Data) -- free (mok_new.Data); -+ if (old_req.Data) -+ free (old_req.Data); - if (sizes) - free (sizes); - if (new_list) -@@ -682,14 +725,15 @@ error: - } - - static int --delete_all () -+import_moks (char **files, uint32_t total) - { -- if (update_request (NULL, 0)) { -- fprintf (stderr, "Failed to issue an delete request\n"); -- return -1; -- } -+ return issue_mok_request (files, total, 1); -+} - -- return 0; -+static int -+delete_moks (char **files, uint32_t total) -+{ -+ return issue_mok_request (files, total, 0); - } - - static int -@@ -932,6 +976,17 @@ error: - return ret; - } - -+static int -+reset_moks () -+{ -+ if (update_request (NULL, 0, 1)) { -+ fprintf (stderr, "Failed to issue a reset request\n"); -+ return -1; -+ } -+ -+ return 0; -+} -+ - int - main (int argc, char *argv[]) - { -@@ -982,8 +1037,23 @@ main (int argc, char *argv[]) - - command = COMMAND_IMPORT; - -- } else if (strcmp (argv[1], "-D") == 0 || -- strcmp (argv[1], "--delete-all") == 0) { -+ } else if (strcmp (argv[1], "-d") == 0 || -+ strcmp (argv[1], "--delete") == 0) { -+ -+ if (argc < 3) { -+ print_help (); -+ return -1; -+ } -+ total = argc - 2; -+ -+ files = malloc (total * sizeof(char *)); -+ if (!files) { -+ fprintf (stderr, "Failed to allocate file list\n"); -+ return -1; -+ } -+ -+ for (i = 0; i < total; i++) -+ files[i] = argv[i+2]; - - command = COMMAND_DELETE; - -@@ -1025,6 +1095,10 @@ main (int argc, char *argv[]) - - command = COMMAND_TEST_KEY; - -+ } else if (strcmp (argv[1], "--reset") == 0) { -+ -+ command = COMMAND_RESET; -+ - } else { - fprintf (stderr, "Unknown argument: %s\n\n", argv[1]); - print_help (); -@@ -1042,7 +1116,7 @@ main (int argc, char *argv[]) - ret = import_moks (files, total); - break; - case COMMAND_DELETE: -- ret = delete_all (); -+ ret = delete_moks (files, total); - break; - case COMMAND_REVOKE: - ret = revoke_request (); -@@ -1065,6 +1139,9 @@ main (int argc, char *argv[]) - case COMMAND_TEST_KEY: - ret = test_key (key_file); - break; -+ case COMMAND_RESET: -+ ret = reset_moks (); -+ break; - default: - fprintf (stderr, "Unknown command\n"); - break; --- -1.7.10.4 - - -From 799d37815f470739ed079e2fea49077decaee3d3 Mon Sep 17 00:00:00 2001 -From: Gary Ching-Pang Lin -Date: Wed, 2 Jan 2013 17:09:35 +0800 -Subject: [PATCH 7/7] Initialize the variable to prevent a potential crash - -In issue_mok_request(), old_req.Data must be intialized before -"goto error", or the process would segfault when freeing old_req.Data. ---- - src/mokutil.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/src/mokutil.c b/src/mokutil.c -index e6807da..a99e355 100644 ---- a/src/mokutil.c -+++ b/src/mokutil.c -@@ -617,6 +617,8 @@ issue_mok_request (char **files, uint32_t total, uint8_t import) - - sizes = malloc (total * sizeof(uint32_t)); - -+ memset (&old_req, 0, sizeof(old_req)); -+ - if (!sizes) { - fprintf (stderr, "Failed to allocate space for sizes\n"); - goto error; -@@ -636,7 +638,6 @@ issue_mok_request (char **files, uint32_t total, uint8_t import) - list_size += sizeof(EFI_SIGNATURE_LIST) * total; - list_size += sizeof(efi_guid_t) * total; - -- memset (&old_req, 0, sizeof(old_req)); - old_req.VariableName = req_name; - old_req.VendorGuid = SHIM_LOCK_GUID; - if (read_variable (&old_req) == EFI_SUCCESS) --- -1.7.10.4 - diff --git a/mokutil-support-new-pw-hash.patch b/mokutil-support-new-pw-hash.patch deleted file mode 100644 index 82702e2..0000000 --- a/mokutil-support-new-pw-hash.patch +++ /dev/null @@ -1,1342 +0,0 @@ -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 - ---- - src/mokutil.c | 259 +++++++++++++++++++++++++++------------------------------ - 1 file changed, 124 insertions(+), 135 deletions(-) - -diff --git a/src/mokutil.c b/src/mokutil.c -index ea8481a..2ab005c 100644 ---- a/src/mokutil.c -+++ b/src/mokutil.c -@@ -6,6 +6,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -19,6 +20,20 @@ EFI_GUID (0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, - #define PASSWORD_MAX 16 - #define PASSWORD_MIN 8 - -+#define HELP 0x1 -+#define LIST_ENROLLED 0x2 -+#define LIST_NEW 0x4 -+#define IMPORT 0x8 -+#define DELETE 0x10 -+#define REVOKE 0x20 -+#define EXPORT 0x40 -+#define PASSWORD 0x80 -+#define DISABLE_VALIDATION 0x100 -+#define ENABLE_VALIDATION 0x200 -+#define SB_STATE 0x400 -+#define TEST_KEY 0x800 -+#define RESET 0x1000 -+ - typedef struct { - uint32_t mok_size; - void *mok; -@@ -30,21 +45,6 @@ typedef struct { - uint16_t password[PASSWORD_MAX]; - } MokSBVar; - --enum Command { -- COMMAND_LIST_ENROLLED, -- COMMAND_LIST_NEW, -- COMMAND_IMPORT, -- COMMAND_DELETE, -- COMMAND_REVOKE, -- COMMAND_EXPORT, -- COMMAND_PASSWORD, -- COMMAND_DISABLE_VALIDATION, -- COMMAND_ENABLE_VALIDATION, -- COMMAND_SB_STATE, -- COMMAND_TEST_KEY, -- COMMAND_RESET, --}; -- - static void - print_help () - { -@@ -80,7 +80,7 @@ print_help () - printf(" mokutil --sb-state\n\n"); - - printf("Test if the key is enrolled or not:\n"); -- printf(" mokutil --test-key\n\n"); -+ printf(" mokutil --test-key \n\n"); - - printf("Reset MOK list:\n"); - printf(" mokutil --reset\n\n"); -@@ -998,163 +998,152 @@ main (int argc, char *argv[]) - { - char **files = NULL; - char *key_file = NULL; -- int i, total; -- int command; -+ const char *option; -+ int c, i, f_ind, total = 0; -+ unsigned int command = 0; - int ret = -1; - -- if (argc < 2) { -- print_help (); -- return 0; -- } -- -- if (strcmp (argv[1], "-h") == 0 || -- strcmp (argv[1], "--help") == 0) { -- -- print_help (); -- return 0; -- -- } else if (strcmp (argv[1], "-le") == 0 || -- strcmp (argv[1], "--list-enrolled") == 0) { -- -- command = COMMAND_LIST_ENROLLED; -- -- } else if (strcmp (argv[1], "-ln") == 0 || -- strcmp (argv[1], "--list-new") == 0) { -- -- command = COMMAND_LIST_NEW; -- -- } else if (strcmp (argv[1], "-i") == 0 || -- strcmp (argv[1], "--import") == 0) { -- -- if (argc < 3) { -- print_help (); -- return -1; -- } -- total = argc - 2; -- -- files = malloc (total * sizeof(char *)); -- if (!files) { -- fprintf (stderr, "Failed to allocate file list\n"); -- return -1; -- } -- -- for (i = 0; i < total; i++) -- files[i] = argv[i+2]; -- -- command = COMMAND_IMPORT; -- -- } else if (strcmp (argv[1], "-d") == 0 || -- strcmp (argv[1], "--delete") == 0) { -- -- if (argc < 3) { -- print_help (); -- return -1; -- } -- total = argc - 2; -- -- files = malloc (total * sizeof(char *)); -- if (!files) { -- fprintf (stderr, "Failed to allocate file list\n"); -- return -1; -- } -- -- for (i = 0; i < total; i++) -- files[i] = argv[i+2]; -- -- command = COMMAND_DELETE; -- -- } else if (strcmp (argv[1], "-r") == 0 || -- strcmp (argv[1], "--revoke") == 0) { -- -- command = COMMAND_REVOKE; -- -- } else if (strcmp (argv[1], "-x") == 0 || -- strcmp (argv[1], "--export") == 0) { -- -- command = COMMAND_EXPORT; -- -- } else if (strcmp (argv[1], "-p") == 0 || -- strcmp (argv[1], "--password") == 0) { -- -- command = COMMAND_PASSWORD; -- -- } else if (strcmp (argv[1], "--disable-validation") == 0) { -- -- command = COMMAND_DISABLE_VALIDATION; -- -- } else if (strcmp (argv[1], "--enable-validation") == 0) { -- -- command = COMMAND_ENABLE_VALIDATION; -- -- } else if (strcmp (argv[1], "--sb-state") == 0) { -+ while (1) { -+ static struct option long_options[] = { -+ {"help", no_argument, 0, 'h'}, -+ {"list-enrolled", no_argument, 0, 0 }, -+ {"list-new", no_argument, 0, 0 }, -+ {"import", required_argument, 0, 'i'}, -+ {"delete", required_argument, 0, 'd'}, -+ {"revoke", no_argument, 0, 0 }, -+ {"export", no_argument, 0, 'x'}, -+ {"password", no_argument, 0, 'p'}, -+ {"disable-validation", no_argument, 0, 0 }, -+ {"enable-validation", no_argument, 0, 0 }, -+ {"sb-state", no_argument, 0, 0 }, -+ {"test-key", required_argument, 0, 't'}, -+ {"reset", no_argument, 0, 0 }, -+ {0, 0, 0, 0} -+ }; -+ -+ int option_index = 0; -+ c = getopt_long (argc, argv, "d:hi:pt:x", -+ long_options, &option_index); -+ -+ if (c == -1) -+ break; - -- command = COMMAND_SB_STATE; -+ switch (c) { -+ case 0: -+ option = long_options[option_index].name; -+ if (strcmp (option, "list-enrolled") == 0) { -+ command |= LIST_ENROLLED; -+ } else if (strcmp (option, "list-new") == 0) { -+ command |= LIST_NEW; -+ } else if (strcmp (option, "revoke") == 0) { -+ command |= REVOKE; -+ } else if (strcmp (option, "disable-validation") == 0) { -+ command |= DISABLE_VALIDATION; -+ } else if (strcmp (option, "enable-validation") == 0) { -+ command |= ENABLE_VALIDATION; -+ } else if (strcmp (option, "sb-state") == 0) { -+ command |= SB_STATE; -+ } else if (strcmp (option, "reset") == 0) { -+ command |= RESET; -+ } -+ break; -+ case 'd': -+ case 'i': -+ if (c == 'd') -+ command |= DELETE; -+ else -+ command |= IMPORT; -+ -+ if (files) { -+ command |= HELP; -+ break; -+ } -+ -+ total = 0; -+ for (f_ind = optind - 1; -+ f_ind < argc && *argv[f_ind] != '-'; -+ f_ind++) { -+ total++; -+ } -+ -+ files = malloc (total * sizeof (char *)); -+ for (i = 0; i < total; i++) { -+ f_ind = i + optind - 1; -+ files[i] = malloc (strlen(argv[f_ind]) + 1); -+ strcpy (files[i], argv[f_ind]); -+ } - -- } else if (strcmp (argv[1], "--test-key") == 0) { -+ break; -+ case 'p': -+ command |= PASSWORD; -+ break; -+ case 't': -+ key_file = strdup (optarg); - -- if (argc < 3) { -- print_help (); -- return -1; -+ command |= TEST_KEY; -+ break; -+ case 'x': -+ command |= EXPORT; -+ break; -+ case 'h': -+ case '?': -+ command |= HELP; -+ break; -+ default: -+ abort (); - } -- -- key_file = argv[2]; -- -- command = COMMAND_TEST_KEY; -- -- } else if (strcmp (argv[1], "--reset") == 0) { -- -- command = COMMAND_RESET; -- -- } else { -- fprintf (stderr, "Unknown argument: %s\n\n", argv[1]); -- print_help (); -- return -1; - } - - switch (command) { -- case COMMAND_LIST_ENROLLED: -+ case LIST_ENROLLED: - ret = list_enrolled_keys (); - break; -- case COMMAND_LIST_NEW: -+ case LIST_NEW: - ret = list_new_keys (); - break; -- case COMMAND_IMPORT: -+ case IMPORT: - ret = import_moks (files, total); - break; -- case COMMAND_DELETE: -+ case DELETE: - ret = delete_moks (files, total); - break; -- case COMMAND_REVOKE: -+ case REVOKE: - ret = revoke_request (); - break; -- case COMMAND_EXPORT: -+ case EXPORT: - ret = export_moks (); - break; -- case COMMAND_PASSWORD: -+ case PASSWORD: - ret = set_password (); - break; -- case COMMAND_DISABLE_VALIDATION: -+ case DISABLE_VALIDATION: - ret = disable_validation (); - break; -- case COMMAND_ENABLE_VALIDATION: -+ case ENABLE_VALIDATION: - ret = enable_validation (); - break; -- case COMMAND_SB_STATE: -+ case SB_STATE: - ret = sb_state (); - break; -- case COMMAND_TEST_KEY: -+ case TEST_KEY: - ret = test_key (key_file); - break; -- case COMMAND_RESET: -+ case RESET: - ret = reset_moks (); - break; - default: -- fprintf (stderr, "Unknown command\n"); -+ print_help (); - break; - } - -- if (files) -+ if (files) { -+ for (i = 0; i < total; i++) -+ free (files[i]); - free (files); -+ } -+ -+ if (key_file) -+ free (key_file); - - return ret; - } --- -1.7.10.4 - - -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 - -old format: MokNew + sha256sum(MokNew + password) -new format: salt + sha256sum(salt + password) -The new format makes a preset hash possible. ---- - src/mokutil.c | 102 ++++++++++++++++++++------------------------------------- - 1 file changed, 35 insertions(+), 67 deletions(-) - -diff --git a/src/mokutil.c b/src/mokutil.c -index 2ab005c..61c432d 100644 ---- a/src/mokutil.c -+++ b/src/mokutil.c -@@ -20,6 +20,8 @@ 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 -@@ -366,8 +368,19 @@ error: - return ret; - } - -+static void -+generate_salt (uint8_t salt[], unsigned int salt_len) -+{ -+ int i; -+ -+ srand (time (NULL)); -+ -+ for (i = 0; i < salt_len; i++) -+ salt[i] = rand() % 256; -+} -+ - static int --generate_auth (void *new_list, unsigned long list_len, char *password, -+generate_hash (void *salt, unsigned int salt_len, char *password, - int pw_len, uint8_t *auth) - { - efi_char16_t efichar_pass[PASSWORD_MAX+1]; -@@ -382,8 +395,8 @@ generate_auth (void *new_list, unsigned long list_len, char *password, - - SHA256_Init (&ctx); - -- if (new_list) -- SHA256_Update (&ctx, new_list, list_len); -+ if (salt) -+ SHA256_Update (&ctx, salt, salt_len); - - SHA256_Update (&ctx, efichar_pass, efichar_len); - -@@ -397,7 +410,9 @@ update_request (void *new_list, int list_len, uint8_t import) - { - efi_variable_t var; - const char *req_name, *auth_name; -- uint8_t auth[SHA256_DIGEST_LENGTH]; -+ uint8_t salt[SALT_SIZE]; -+ uint8_t hash[SHA256_DIGEST_LENGTH]; -+ uint8_t auth[SALT_SIZE + SHA256_DIGEST_LENGTH]; - char *password = NULL; - int pw_len; - int ret = -1; -@@ -415,7 +430,13 @@ update_request (void *new_list, int list_len, uint8_t import) - goto error; - } - -- generate_auth (new_list, list_len, password, pw_len, auth); -+ generate_salt (salt, SALT_SIZE); -+ if (generate_hash (salt, SALT_SIZE, password, pw_len, 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*/ -@@ -439,7 +460,7 @@ update_request (void *new_list, int list_len, uint8_t import) - - /* Write MokAuth */ - var.Data = auth; -- var.DataSize = SHA256_DIGEST_LENGTH; -+ var.DataSize = SHA256_DIGEST_LENGTH + SALT_SIZE; - var.VariableName = auth_name; - - var.VendorGuid = SHIM_LOCK_GUID; -@@ -545,57 +566,6 @@ is_valid_request (void *mok, uint32_t mok_size, uint8_t import) - } - - static int --verify_old_req (void *old_req, unsigned long old_req_size, uint8_t import) --{ -- efi_variable_t req_auth; -- const char *auth_name; -- uint8_t auth[SHA256_DIGEST_LENGTH]; -- char *password = NULL; -- int pw_len, fail = 0; -- size_t n; -- int ret = 0; -- -- if (import) -- auth_name = "MokAuth"; -- else -- auth_name = "MokDelAuth"; -- -- memset (&req_auth, 0, sizeof(req_auth)); -- req_auth.VariableName = auth_name; -- req_auth.VendorGuid = SHIM_LOCK_GUID; -- if (read_variable (&req_auth) != EFI_SUCCESS) { -- fprintf (stderr, "Failed to read %s\n", auth_name); -- return 0; -- } -- -- while (fail < 3) { -- printf ("input old password: "); -- pw_len = read_hidden_line (&password, &n); -- printf ("\n"); -- -- if (pw_len > PASSWORD_MAX || pw_len < PASSWORD_MIN) { -- free (password); -- fprintf (stderr, "invalid password\n"); -- fail++; -- continue; -- } -- -- generate_auth (old_req, old_req_size, password, pw_len, auth); -- if (memcmp (auth, req_auth.Data, SHA256_DIGEST_LENGTH) == 0) { -- ret = 1; -- break; -- } -- -- fail++; -- } -- -- if (req_auth.Data) -- free (req_auth.Data); -- -- return ret; --} -- --static int - issue_mok_request (char **files, uint32_t total, uint8_t import) - { - efi_variable_t old_req; -@@ -705,11 +675,6 @@ issue_mok_request (char **files, uint32_t total, uint8_t import) - - /* append the keys to the previous request */ - if (old_req.Data) { -- /* request the previous password to verify the keys */ -- if (!verify_old_req (old_req.Data, old_req.DataSize, import)) { -- goto error; -- } -- - memcpy (new_list + real_size, old_req.Data, old_req.DataSize); - real_size += old_req.DataSize; - } -@@ -745,8 +710,6 @@ delete_moks (char **files, uint32_t total) - static int - revoke_request () - { -- /* TODO request the old password? */ -- - if (test_and_delete_var ("MokNew") < 0) - return -1; - -@@ -814,7 +777,9 @@ static int - set_password () - { - efi_variable_t var; -- uint8_t auth[SHA256_DIGEST_LENGTH]; -+ uint8_t salt[SALT_SIZE]; -+ uint8_t hash[SHA256_DIGEST_LENGTH]; -+ uint8_t auth[SHA256_DIGEST_LENGTH + SALT_SIZE]; - char *password = NULL; - int pw_len; - int ret = -1; -@@ -824,13 +789,16 @@ set_password () - goto error; - } - -- if (generate_auth (NULL, 0, password, pw_len, auth) < 0) { -+ generate_salt (salt, SALT_SIZE); -+ if (generate_hash (salt, SALT_SIZE, password, pw_len, 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; -+ var.DataSize = SHA256_DIGEST_LENGTH + SALT_SIZE; - var.VariableName = "MokPW"; - - var.VendorGuid = SHIM_LOCK_GUID; --- -1.7.10.4 - - -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 - ---- - src/mokutil.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/src/mokutil.c b/src/mokutil.c -index 61c432d..86d5328 100644 ---- a/src/mokutil.c -+++ b/src/mokutil.c -@@ -947,6 +947,8 @@ error: - if (key) - free (key); - -+ close (fd); -+ - return ret; - } - --- -1.7.10.4 - - -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 - ---- - src/mokutil.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/mokutil.c b/src/mokutil.c -index 86d5328..36783cb 100644 ---- a/src/mokutil.c -+++ b/src/mokutil.c -@@ -784,7 +784,7 @@ set_password () - int pw_len; - int ret = -1; - -- while (get_password (&password, &pw_len, PASSWORD_MIN, PASSWORD_MAX) < 0) { -+ if (get_password (&password, &pw_len, PASSWORD_MIN, PASSWORD_MAX) < 0) { - fprintf (stderr, "Abort\n"); - goto error; - } -@@ -828,7 +828,7 @@ set_validation (uint32_t state) - efi_char16_t efichar_pass[PASSWORD_MAX]; - int ret = -1; - -- while (get_password (&password, &pw_len, PASSWORD_MIN, PASSWORD_MAX) < 0) { -+ if (get_password (&password, &pw_len, PASSWORD_MIN, PASSWORD_MAX) < 0) { - fprintf (stderr, "Abort\n"); - goto error; - } --- -1.7.10.4 - - -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 - ---- - src/mokutil.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++----------- - 1 file changed, 127 insertions(+), 31 deletions(-) - -diff --git a/src/mokutil.c b/src/mokutil.c -index 36783cb..4b9002e 100644 ---- a/src/mokutil.c -+++ b/src/mokutil.c -@@ -35,6 +35,7 @@ EFI_GUID (0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, - #define SB_STATE 0x400 - #define TEST_KEY 0x800 - #define RESET 0x1000 -+#define HASH_FILE 0x2000 - - typedef struct { - uint32_t mok_size; -@@ -406,7 +407,73 @@ generate_hash (void *salt, unsigned int salt_len, char *password, - } - - static int --update_request (void *new_list, int list_len, uint8_t import) -+char_to_int (const char c) -+{ -+ if (c >= '0' && c <= '9') -+ return (c - '0'); -+ -+ if (c >= 'A' && c <= 'F') -+ return (c - 'A' + 10); -+ -+ if (c >= 'a' && c <= 'f') -+ return (c - 'a' + 10); -+ -+ return -1; -+} -+ -+static int -+read_hex_array (const char *string, char *out, int len) -+{ -+ int i, digit_1, digit_2; -+ -+ for (i = 0; i < len; i++) { -+ digit_1 = char_to_int (string[2*i]); -+ digit_2 = char_to_int (string[2*i + 1]); -+ if (digit_1 < 0 || digit_2 < 0) -+ return -1; -+ -+ out[i] = (char)digit_1 * 16 + (char)digit_2; -+ } -+ -+ return 0; -+} -+ -+static int -+get_hash_from_file (const char *file, void *salt, void *hash) -+{ -+ FILE *fptr; -+ char salt_string[2*SALT_SIZE]; -+ char hash_string[2*SHA256_DIGEST_LENGTH]; -+ -+ fptr = fopen (file, "r"); -+ if (fptr == NULL) { -+ fprintf (stderr, "Failed to open %s\n", file); -+ return -1; -+ } -+ -+ memset (salt_string, 0, 2*SALT_SIZE); -+ memset (hash_string, 0, 2*SHA256_DIGEST_LENGTH); -+ -+ fscanf (fptr, "%32c.%64c", salt_string, hash_string); -+ -+ fclose (fptr); -+ -+ if (read_hex_array (salt_string, salt, SALT_SIZE) < 0) { -+ fprintf (stderr, "Corrupted salt\n"); -+ return -1; -+ } -+ -+ if (read_hex_array (hash_string, hash, SHA256_DIGEST_LENGTH) < 0) { -+ fprintf (stderr, "Corrupted hash\n"); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static int -+update_request (void *new_list, int list_len, uint8_t import, -+ const char *hash_file) - { - efi_variable_t var; - const char *req_name, *auth_name; -@@ -425,15 +492,22 @@ update_request (void *new_list, int list_len, uint8_t import) - auth_name = "MokDelAuth"; - } - -- if (get_password (&password, &pw_len, PASSWORD_MIN, PASSWORD_MAX) < 0) { -- fprintf (stderr, "Abort\n"); -- goto error; -- } -+ if (hash_file) { -+ if (get_hash_from_file (hash_file, salt, hash) < 0) { -+ fprintf (stderr, "Failed to read hash\n"); -+ goto error; -+ } -+ } else { -+ if (get_password (&password, &pw_len, PASSWORD_MIN, PASSWORD_MAX) < 0) { -+ fprintf (stderr, "Abort\n"); -+ goto error; -+ } - -- generate_salt (salt, SALT_SIZE); -- if (generate_hash (salt, SALT_SIZE, password, pw_len, hash) < 0) { -- fprintf (stderr, "Couldn't generate hash\n"); -- goto error; -+ generate_salt (salt, SALT_SIZE); -+ if (generate_hash (salt, SALT_SIZE, password, pw_len, hash) < 0) { -+ fprintf (stderr, "Couldn't generate hash\n"); -+ goto error; -+ } - } - memcpy (auth, salt, SALT_SIZE); - memcpy (auth + SALT_SIZE, hash, SHA256_DIGEST_LENGTH); -@@ -566,7 +640,8 @@ is_valid_request (void *mok, uint32_t mok_size, uint8_t import) - } - - static int --issue_mok_request (char **files, uint32_t total, uint8_t import) -+issue_mok_request (char **files, uint32_t total, uint8_t import, -+ const char *hash_file) - { - efi_variable_t old_req; - const char *req_name; -@@ -679,7 +754,7 @@ issue_mok_request (char **files, uint32_t total, uint8_t import) - real_size += old_req.DataSize; - } - -- if (update_request (new_list, real_size, import) < 0) { -+ if (update_request (new_list, real_size, import, hash_file) < 0) { - goto error; - } - -@@ -696,15 +771,15 @@ error: - } - - static int --import_moks (char **files, uint32_t total) -+import_moks (char **files, uint32_t total, const char *hash_file) - { -- return issue_mok_request (files, total, 1); -+ return issue_mok_request (files, total, 1, hash_file); - } - - static int --delete_moks (char **files, uint32_t total) -+delete_moks (char **files, uint32_t total, const char *hash_file) - { -- return issue_mok_request (files, total, 0); -+ return issue_mok_request (files, total, 0, hash_file); - } - - static int -@@ -774,7 +849,7 @@ error: - } - - static int --set_password () -+set_password (const char *hash_file) - { - efi_variable_t var; - uint8_t salt[SALT_SIZE]; -@@ -784,15 +859,22 @@ set_password () - int pw_len; - int ret = -1; - -- if (get_password (&password, &pw_len, PASSWORD_MIN, PASSWORD_MAX) < 0) { -- fprintf (stderr, "Abort\n"); -- goto error; -- } -+ if (hash_file) { -+ if (get_hash_from_file (hash_file, salt, hash) < 0) { -+ fprintf (stderr, "Failed to read hash\n"); -+ goto error; -+ } -+ } else { -+ if (get_password (&password, &pw_len, PASSWORD_MIN, PASSWORD_MAX) < 0) { -+ fprintf (stderr, "Abort\n"); -+ goto error; -+ } - -- generate_salt (salt, SALT_SIZE); -- if (generate_hash (salt, SALT_SIZE, password, pw_len, hash) < 0) { -- fprintf (stderr, "Couldn't generate hash\n"); -- goto error; -+ generate_salt (salt, SALT_SIZE); -+ if (generate_hash (salt, SALT_SIZE, password, pw_len, hash) < 0) { -+ fprintf (stderr, "Couldn't generate hash\n"); -+ goto error; -+ } - } - memcpy (auth, salt, SALT_SIZE); - memcpy (auth + SALT_SIZE, hash, SHA256_DIGEST_LENGTH); -@@ -953,9 +1035,9 @@ error: - } - - static int --reset_moks () -+reset_moks (const char *hash_file) - { -- if (update_request (NULL, 0, 1)) { -+ if (update_request (NULL, 0, 1, hash_file)) { - fprintf (stderr, "Failed to issue a reset request\n"); - return -1; - } -@@ -968,6 +1050,7 @@ main (int argc, char *argv[]) - { - char **files = NULL; - char *key_file = NULL; -+ char *hash_file = NULL; - const char *option; - int c, i, f_ind, total = 0; - unsigned int command = 0; -@@ -988,11 +1071,12 @@ main (int argc, char *argv[]) - {"sb-state", no_argument, 0, 0 }, - {"test-key", required_argument, 0, 't'}, - {"reset", no_argument, 0, 0 }, -+ {"hash-file", required_argument, 0, 'f'}, - {0, 0, 0, 0} - }; - - int option_index = 0; -- c = getopt_long (argc, argv, "d:hi:pt:x", -+ c = getopt_long (argc, argv, "d:f:hi:pt:x", - long_options, &option_index); - - if (c == -1) -@@ -1044,6 +1128,11 @@ main (int argc, char *argv[]) - } - - break; -+ case 'f': -+ hash_file = strdup (optarg); -+ -+ command |= HASH_FILE; -+ break; - case 'p': - command |= PASSWORD; - break; -@@ -1072,10 +1161,12 @@ main (int argc, char *argv[]) - ret = list_new_keys (); - break; - case IMPORT: -- ret = import_moks (files, total); -+ case IMPORT | HASH_FILE: -+ ret = import_moks (files, total, hash_file); - break; - case DELETE: -- ret = delete_moks (files, total); -+ case DELETE | HASH_FILE: -+ ret = delete_moks (files, total, hash_file); - break; - case REVOKE: - ret = revoke_request (); -@@ -1084,7 +1175,8 @@ main (int argc, char *argv[]) - ret = export_moks (); - break; - case PASSWORD: -- ret = set_password (); -+ case PASSWORD | HASH_FILE: -+ ret = set_password (hash_file); - break; - case DISABLE_VALIDATION: - ret = disable_validation (); -@@ -1099,7 +1191,8 @@ main (int argc, char *argv[]) - ret = test_key (key_file); - break; - case RESET: -- ret = reset_moks (); -+ case RESET | HASH_FILE: -+ ret = reset_moks (hash_file); - break; - default: - print_help (); -@@ -1115,5 +1208,8 @@ main (int argc, char *argv[]) - if (key_file) - free (key_file); - -+ if (hash_file) -+ free (hash_file); -+ - return ret; - } --- -1.7.10.4 - - -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 - ---- - src/mokutil.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 68 insertions(+), 1 deletion(-) - -diff --git a/src/mokutil.c b/src/mokutil.c -index 4b9002e..fdb1a2b 100644 ---- a/src/mokutil.c -+++ b/src/mokutil.c -@@ -36,6 +36,7 @@ EFI_GUID (0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, - #define TEST_KEY 0x800 - #define RESET 0x1000 - #define HASH_FILE 0x2000 -+#define GENERATE_PW_HASH 0x4000 - - typedef struct { - uint32_t mok_size; -@@ -1045,12 +1046,65 @@ reset_moks (const char *hash_file) - return 0; - } - -+static int -+generate_pw_hash (const char *input_pw) -+{ -+ uint8_t salt[SALT_SIZE]; -+ uint8_t hash[SHA256_DIGEST_LENGTH]; -+ char *password = NULL; -+ int pw_len, i, ret = -1; -+ -+ if (input_pw) { -+ pw_len = strlen (input_pw); -+ if (pw_len > PASSWORD_MAX || pw_len < PASSWORD_MIN) { -+ fprintf (stderr, "password should be %d~%d characters\n", -+ PASSWORD_MIN, PASSWORD_MAX); -+ return -1; -+ } -+ -+ password = strdup (input_pw); -+ -+ if (!password) { -+ fprintf (stderr, "Failed to duplicate string\n"); -+ return -1; -+ } -+ } else { -+ if (get_password (&password, &pw_len, PASSWORD_MIN, PASSWORD_MAX) < 0) { -+ fprintf (stderr, "Abort\n"); -+ return -1; -+ } -+ } -+ -+ generate_salt (salt, SALT_SIZE); -+ if (generate_hash (salt, SALT_SIZE, password, pw_len, 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); -+ } -+ putchar ('.'); -+ for (i = 0; i < SHA256_DIGEST_LENGTH; i++) -+ printf ("%x%x", hash[i]/16, hash[i]%16); -+ putchar ('\n'); -+ -+ ret = 0; -+error: -+ if (password) -+ free (password); -+ -+ return ret; -+} -+ - int - main (int argc, char *argv[]) - { - char **files = NULL; - char *key_file = NULL; - char *hash_file = NULL; -+ char *input_pw = NULL; - const char *option; - int c, i, f_ind, total = 0; - unsigned int command = 0; -@@ -1072,11 +1126,12 @@ main (int argc, char *argv[]) - {"test-key", required_argument, 0, 't'}, - {"reset", no_argument, 0, 0 }, - {"hash-file", required_argument, 0, 'f'}, -+ {"generate-hash", optional_argument, 0, 'g'}, - {0, 0, 0, 0} - }; - - int option_index = 0; -- c = getopt_long (argc, argv, "d:f:hi:pt:x", -+ c = getopt_long (argc, argv, "d:f:g::hi:pt:x", - long_options, &option_index); - - if (c == -1) -@@ -1133,6 +1188,12 @@ main (int argc, char *argv[]) - - command |= HASH_FILE; - break; -+ case 'g': -+ if (optarg) -+ input_pw = strdup (optarg); -+ -+ command |= GENERATE_PW_HASH; -+ break; - case 'p': - command |= PASSWORD; - break; -@@ -1194,6 +1255,9 @@ main (int argc, char *argv[]) - case RESET | HASH_FILE: - ret = reset_moks (hash_file); - break; -+ case GENERATE_PW_HASH: -+ ret = generate_pw_hash (input_pw); -+ break; - default: - print_help (); - break; -@@ -1211,5 +1275,8 @@ main (int argc, char *argv[]) - if (hash_file) - free (hash_file); - -+ if (input_pw) -+ free (input_pw); -+ - return ret; - } --- -1.7.10.4 - - -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 - ---- - src/mokutil.c | 59 ++++++++++++++++++++++----------------------------------- - 1 file changed, 23 insertions(+), 36 deletions(-) - -diff --git a/src/mokutil.c b/src/mokutil.c -index fdb1a2b..72a651a 100644 ---- a/src/mokutil.c -+++ b/src/mokutil.c -@@ -52,42 +52,29 @@ typedef struct { - static void - print_help () - { -- printf("Usage:\n"); -- printf("List the enrolled keys:\n"); -- printf(" mokutil --list-enrolled\n\n"); -- -- printf("List the keys to be enrolled:\n"); -- printf(" mokutil --list-new\n\n"); -- -- printf("Import keys:\n"); -- printf(" mokutil --import ...\n\n"); -- -- printf("Request to delete specific keys\n"); -- printf(" mokutil --delete ...\n\n"); -- -- printf("Revoke the request:\n"); -- printf(" mokutil --revoke\n\n"); -- -- printf("Export enrolled keys to files:\n"); -- printf(" mokutil --export\n\n"); -- -- printf("Set MOK password:\n"); -- printf(" mokutil --password\n\n"); -- -- printf("Disable signature validation:\n"); -- printf(" mokutil --disable-validation\n\n"); -- -- printf("Enable signature validation:\n"); -- printf(" mokutil --enable-validation\n\n"); -- -- printf("SecureBoot State:\n"); -- printf(" mokutil --sb-state\n\n"); -- -- printf("Test if the key is enrolled or not:\n"); -- printf(" mokutil --test-key \n\n"); -- -- printf("Reset MOK list:\n"); -- printf(" mokutil --reset\n\n"); -+ printf ("Usage:\n"); -+ printf (" mokutil OPTIONS [ARGS...]\n"); -+ printf ("\n"); -+ printf ("Options:\n"); -+ printf (" --help\t\t\t\tShow help\n"); -+ printf (" --list-enrolled\t\t\tList the enrolled keys\n"); -+ printf (" --list-new\t\t\t\tList the keys to be enrolled\n"); -+ printf (" --import \t\tImport keys\n"); -+ printf (" --delete \t\tDelete specific keys\n"); -+ printf (" --revoke\t\t\t\tRevoke the import request\n"); -+ printf (" --export\t\t\t\tExport enrolled keys to files\n"); -+ printf (" --password\t\t\t\tSet MOK password\n"); -+ printf (" --disable-validation\t\t\tDisable signature validation\n"); -+ printf (" --enable-validation\t\t\tEnable signature validation\n"); -+ printf (" --sb-state\t\t\t\tShow SecureBoot State\n"); -+ printf (" --test-key \t\t\tTest if the key is enrolled or not\n"); -+ printf (" --reset\t\t\t\tReset MOK list\n"); -+ printf (" --generate-hash[=password]\t\tGenerate the password hash\n"); -+ printf ("\n"); -+ printf ("Suboptions:\n"); -+ printf (" --hash-file \t\tUse the specific password hash\n"); -+ printf (" \t\t(Only valid with --import, --delete,\n"); -+ printf (" \t\t --password, and --reset)\n"); - } - - static int --- -1.7.10.4 - - -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 - ---- - src/mokutil.c | 58 +++++++++++++++++++++++++++++++++++---------------------- - 1 file changed, 36 insertions(+), 22 deletions(-) - -diff --git a/src/mokutil.c b/src/mokutil.c -index 72a651a..7392845 100644 ---- a/src/mokutil.c -+++ b/src/mokutil.c -@@ -27,16 +27,17 @@ EFI_GUID (0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, - #define LIST_NEW 0x4 - #define IMPORT 0x8 - #define DELETE 0x10 --#define REVOKE 0x20 --#define EXPORT 0x40 --#define PASSWORD 0x80 --#define DISABLE_VALIDATION 0x100 --#define ENABLE_VALIDATION 0x200 --#define SB_STATE 0x400 --#define TEST_KEY 0x800 --#define RESET 0x1000 --#define HASH_FILE 0x2000 --#define GENERATE_PW_HASH 0x4000 -+#define REVOKE_IMPORT 0x20 -+#define REVOKE_DELETE 0x40 -+#define EXPORT 0x80 -+#define PASSWORD 0x100 -+#define DISABLE_VALIDATION 0x200 -+#define ENABLE_VALIDATION 0x400 -+#define SB_STATE 0x800 -+#define TEST_KEY 0x1000 -+#define RESET 0x2000 -+#define HASH_FILE 0x4000 -+#define GENERATE_PW_HASH 0x8000 - - typedef struct { - uint32_t mok_size; -@@ -61,7 +62,8 @@ print_help () - printf (" --list-new\t\t\t\tList the keys to be enrolled\n"); - printf (" --import \t\tImport keys\n"); - printf (" --delete \t\tDelete specific keys\n"); -- printf (" --revoke\t\t\t\tRevoke the import request\n"); -+ printf (" --revoke-import\t\t\tRevoke the import request\n"); -+ printf (" --revoke-delete\t\t\tRevoke the delete request\n"); - printf (" --export\t\t\t\tExport enrolled keys to files\n"); - printf (" --password\t\t\t\tSet MOK password\n"); - printf (" --disable-validation\t\t\tDisable signature validation\n"); -@@ -771,13 +773,19 @@ delete_moks (char **files, uint32_t total, const char *hash_file) - } - - static int --revoke_request () -+revoke_request (uint8_t import) - { -- if (test_and_delete_var ("MokNew") < 0) -- return -1; -- -- if (test_and_delete_var ("MokAuth") < 0) -- return -1; -+ if (import == 1) { -+ if (test_and_delete_var ("MokNew") < 0) -+ return -1; -+ if (test_and_delete_var ("MokAuth") < 0) -+ return -1; -+ } else { -+ if (test_and_delete_var ("MokDel") < 0) -+ return -1; -+ if (test_and_delete_var ("MokDelAuth") < 0) -+ return -1; -+ } - - return 0; - } -@@ -1104,7 +1112,8 @@ main (int argc, char *argv[]) - {"list-new", no_argument, 0, 0 }, - {"import", required_argument, 0, 'i'}, - {"delete", required_argument, 0, 'd'}, -- {"revoke", no_argument, 0, 0 }, -+ {"revoke-import", no_argument, 0, 0 }, -+ {"revoke-delete", no_argument, 0, 0 }, - {"export", no_argument, 0, 'x'}, - {"password", no_argument, 0, 'p'}, - {"disable-validation", no_argument, 0, 0 }, -@@ -1131,8 +1140,10 @@ main (int argc, char *argv[]) - command |= LIST_ENROLLED; - } else if (strcmp (option, "list-new") == 0) { - command |= LIST_NEW; -- } else if (strcmp (option, "revoke") == 0) { -- command |= REVOKE; -+ } else if (strcmp (option, "revoke-import") == 0) { -+ command |= REVOKE_IMPORT; -+ } else if (strcmp (option, "revoke-delete") == 0) { -+ command |= REVOKE_DELETE; - } else if (strcmp (option, "disable-validation") == 0) { - command |= DISABLE_VALIDATION; - } else if (strcmp (option, "enable-validation") == 0) { -@@ -1216,8 +1227,11 @@ main (int argc, char *argv[]) - case DELETE | HASH_FILE: - ret = delete_moks (files, total, hash_file); - break; -- case REVOKE: -- ret = revoke_request (); -+ case REVOKE_IMPORT: -+ ret = revoke_request (1); -+ break; -+ case REVOKE_DELETE: -+ ret = revoke_request (0); - break; - case EXPORT: - ret = export_moks (); --- -1.7.10.4 - - -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 - -The UEFI variables which contain the password or the password hash -should not be accessed by normal users. ---- - src/efi.h | 1 + - src/efilib.c | 22 ++++++++++++++++++++++ - src/mokutil.c | 6 +++--- - 3 files changed, 26 insertions(+), 3 deletions(-) - -diff --git a/src/efi.h b/src/efi.h -index d2640b4..ceed6c2 100644 ---- a/src/efi.h -+++ b/src/efi.h -@@ -360,6 +360,7 @@ extern efi_status_t test_variable (efi_variable_t *var); - extern efi_status_t read_variable (efi_variable_t *var); - extern efi_status_t edit_variable (efi_variable_t *var); - extern efi_status_t delete_variable (efi_variable_t *var); -+extern efi_status_t edit_protected_variable (efi_variable_t *var); - - extern int efichar_strlen (const efi_char16_t *p, int max); - extern unsigned long efichar_from_char (efi_char16_t *dest, const char *src, size_t dest_len); -diff --git a/src/efilib.c b/src/efilib.c -index f192c1a..cb1aca6 100644 ---- a/src/efilib.c -+++ b/src/efilib.c -@@ -215,3 +215,25 @@ delete_variable(efi_variable_t *var) - - return EFI_OUT_OF_RESOURCES; - } -+ -+efi_status_t -+edit_protected_variable (efi_variable_t *var) -+{ -+ char name[PATH_MAX]; -+ char filename[PATH_MAX]; -+ int ret; -+ if (!var) -+ return EFI_INVALID_PARAMETER; -+ -+ variable_to_name(var, name); -+ -+ snprintf(filename, PATH_MAX-1, "%s/%s", SYSFS_DIR_EFI_VARS, name); -+ ret = write_variable (filename, var); -+ if (ret != EFI_SUCCESS) -+ return ret; -+ -+ if (chmod (filename, S_IRUSR | S_IWUSR) < 0) -+ return EFI_UNSUPPORTED; -+ -+ return EFI_SUCCESS; -+} -diff --git a/src/mokutil.c b/src/mokutil.c -index 7392845..c1a0ffc 100644 ---- a/src/mokutil.c -+++ b/src/mokutil.c -@@ -532,7 +532,7 @@ update_request (void *new_list, int list_len, uint8_t import, - | EFI_VARIABLE_BOOTSERVICE_ACCESS - | EFI_VARIABLE_RUNTIME_ACCESS; - -- if (edit_variable (&var) != EFI_SUCCESS) { -+ if (edit_protected_variable (&var) != EFI_SUCCESS) { - fprintf (stderr, "Failed to write %s\n", auth_name); - test_and_delete_var (req_name); - goto error; -@@ -884,7 +884,7 @@ set_password (const char *hash_file) - | EFI_VARIABLE_BOOTSERVICE_ACCESS - | EFI_VARIABLE_RUNTIME_ACCESS; - -- if (edit_variable (&var) != EFI_SUCCESS) { -+ if (edit_protected_variable (&var) != EFI_SUCCESS) { - fprintf (stderr, "Failed to write MokPW\n"); - goto error; - } -@@ -929,7 +929,7 @@ set_validation (uint32_t state) - | EFI_VARIABLE_BOOTSERVICE_ACCESS - | EFI_VARIABLE_RUNTIME_ACCESS; - -- if (edit_variable (&var) != EFI_SUCCESS) { -+ if (edit_protected_variable (&var) != EFI_SUCCESS) { - fprintf (stderr, "Failed to request new SB state\n"); - goto error; - } --- -1.7.10.4 - diff --git a/mokutil-update-man-page.patch b/mokutil-update-man-page.patch deleted file mode 100644 index 22e5cee..0000000 --- a/mokutil-update-man-page.patch +++ /dev/null @@ -1,124 +0,0 @@ -From 53a40965390cfa3b99d636874c6b9d968380f312 Mon Sep 17 00:00:00 2001 -From: Gary Ching-Pang Lin -Date: Wed, 30 Jan 2013 14:16:16 +0800 -Subject: [PATCH] Update man page - ---- - man/mokutil.1 | 59 +++++++++++++++++++++++++++++++++++++++++---------------- - 1 file changed, 43 insertions(+), 16 deletions(-) - -diff --git a/man/mokutil.1 b/man/mokutil.1 -index 7a70d3e..fabd7a9 100644 ---- a/man/mokutil.1 -+++ b/man/mokutil.1 -@@ -1,27 +1,41 @@ --.TH MOKUTIL 1 "Wed Nov 07 2012" -+.TH MOKUTIL 1 "Wed Jan 30 2013" - .SH NAME - - mokutil \- utility to manipulate machine owner keys - - .SH SYNOPSIS --\fBmokutil\fR [--list-enrolled | -le] -+\fBmokutil\fR [--list-enrolled] - .br --\fBmokutil\fR [--list-new | -ln] -+\fBmokutil\fR [--list-new] - .br --\fBmokutil\fR [--import | -i] ... -+\fBmokutil\fR [--import \fIkeylist\fR| -i \fIkeylist\fR] -+ ([--hash-file \fIhashfile\fR | -f \fIhashfile\fR] | [--root-pw | -P]) - .br --\fBmokutil\fR [--delete-all | -D] -+\fBmokutil\fR [--delete \fIkeylist\fR | -d \fIkeylist\fR] -+ ([--hash-file \fIhashfile\fR | -f \fIhashfile\fR] | [--root-pw | -P]) - .br --\fBmokutil\fR [--revoke | -r] -+\fBmokutil\fR [--revoke-import] -+.br -+\fBmokutil\fR [--revoke-delete] - .br - \fBmokutil\fR [--export | -x] - .br - \fBmokutil\fR [--password | -p] -+ ([--hash-file \fIhashfile\fR | -f \fIhashfile\fR] | [--root-pw | -P]) - .br - \fBmokutil\fR [--disable-validation] - .br - \fBmokutil\fR [--enable-validation] - .br -+\fBmokutil\fR [--sb-state] -+.br -+\fBmokutil\fR [--test-key | -t] ... -+.br -+\fBmokutil\fR [--reset] -+ ([--hash-file \fIhashfile\fR | -f \fIhashfile\fR] | [--root-pw | -P]) -+.br -+\fBmokutil\fR [--generate-hash=\fIpassword\fR | -g\fIpassword\fR] -+.br - - .SH DESCRIPTION - \fBmokutil\fR is a tool to import or delete the machines owner keys -@@ -31,36 +45,49 @@ mokutil \- utility to manipulate machine owner keys - .TP - \fB--list-enrolled\fR - List the keys the already stored in the database -- - .TP - \fB--list-new\fR - List the keys to be enrolled -- - .TP - \fB--import\fR - Collect the followed files and form a request to shim. The files must be in DER - format. -- - .TP - \fB--delete-all\fR - Request shim to delete all stored keys -- - .TP --\fB--revoke\fR --Revoke the current request -- -+\fB--revoke-import\fR -+Revoke the current import request (MokNew) -+.TP -+\fB--revoke-delete\fR -+Revoke the current delete request (MokDel) - .TP - \fB--export\fR - Export the keys stored in MokListRT -- - .TP - \fB--password\fR - Setup the password for MokManager -- - .TP - \fB--disable-validation\fR - Disable the validation process in shim -- - .TP - \fB--enrolled-validation\fR - Enable the validation process in shim -+.TP -+\fB--sb-state\fR -+Show SecureBoot State -+.TP -+\fB--test-key\fR -+Test if the key is enrolled or not -+.TP -+\fB--reset\fR -+Reset MOK list -+.TP -+\fB--generate-hash\fR -+Generate the password hash -+.TP -+\fB--hash-file\fR -+Use the password hash from a specific file -+.TP -+\fB--root-pw\fR -+Use the root password hash from /etc/shadow --- -1.7.10.4 - diff --git a/mokutil.changes b/mokutil.changes index 86e9262..fc649fd 100644 --- a/mokutil.changes +++ b/mokutil.changes @@ -1,3 +1,23 @@ +------------------------------------------------------------------- +Thu Jul 25 09:13:44 UTC 2013 - glin@suse.com + +- Update to 0.2.0 + + Generate the password hash with crypt() by default instead of + the original sha256 password hash + + Add an option to import the root password hash + + Amend error messages, help, and man page +- Drop upstreamed patches + + mokutil-lcrypt-ldflag.patch + + mokutil-probe-secure-boot-state.patch + + mokutil-allow-password-from-pipe.patch + + mokutil-bnc809703-check-pending-request.patch + + mokutil-support-delete-keys.patch + + mokutil-support-crypt-hash-methods.patch + + mokutil-update-man-page.patch + + mokutil-bnc809215-improve-wording.patch + + mokutil-support-new-pw-hash.patch + + mokutil-no-duplicate-keys-imported.patch + ------------------------------------------------------------------- Tue Apr 2 04:43:59 UTC 2013 - glin@suse.com diff --git a/mokutil.spec b/mokutil.spec index 4d04c14..3c6c8c4 100644 --- a/mokutil.spec +++ b/mokutil.spec @@ -17,33 +17,13 @@ Name: mokutil -Version: 0.1.0 +Version: 0.2.0 Release: 0 Summary: Tools for manipulating machine owner keys License: GPL-3.0 Group: Productivity/Security Url: https://github.com/lcp/mokutil Source: %{name}-%{version}.tar.bz2 -# PATCH-FIX-UPSTREAM mokutil-probe-secure-boot-state.patch glin@suse.com -- Probe the state of secure boot -Patch1: mokutil-probe-secure-boot-state.patch -# PATCH-FIX-UPSTREAM mokutil-no-duplicate-keys-imported.patch glin@suse.com -- Do not import duplicate keys -Patch2: mokutil-no-duplicate-keys-imported.patch -# PATCH-FIX-UPSTREAM mokutil-accept-password-from-pipe.patch glin@suse.com -- Allow the password to be sent through pipeline -Patch3: mokutil-allow-password-from-pipe.patch -# PATCH-FIX-UPSTREAM mokutil-support-delete-keys.patch glin@suse.com -- Add support for deleting specific keys -Patch4: mokutil-support-delete-keys.patch -# PATCH-FIX-UPSTREAM mokutil-support-new-pw-hash.patch glin@suse.com -- Support the new password hash format -Patch5: mokutil-support-new-pw-hash.patch -# PATCH-FIX-UPSTREAM mokutil-support-crypt-hash-methods.patch glin@suse.com -- Support the hash methods used for /etc/shadow -Patch6: mokutil-support-crypt-hash-methods.patch -# PATCH-FIX-UPSTREAM mokutil-update-man-page.patch glin@suse.com -- Update man page -Patch7: mokutil-update-man-page.patch -# PATCH-FIX-UPSTREAM mokutil-lcrypt-ldflag.patch glin@suse.com -- Add -lcrpyt correctly -Patch8: mokutil-lcrypt-ldflag.patch -# PATCH-FIX-UPSTREAM mokutil-bnc809215-improve-wording.patch bnc#809215 glin@suse.com -- Improve the wording of error messages -Patch9: mokutil-bnc809215-improve-wording.patch -# PATCH-FIX-UPSTREAM mokutil-bnc809703-check-pending-request.patch bnc#809703 glin@suse.com -- Remove the key from the pending requests if necessary -Patch10: mokutil-bnc809703-check-pending-request.patch BuildRequires: autoconf BuildRequires: automake BuildRequires: libopenssl-devel >= 0.9.8 @@ -63,19 +43,8 @@ Authors: %prep %setup -q -%patch1 -p1 -%patch2 -p1 -%patch3 -p1 -%patch4 -p1 -%patch5 -p1 -%patch6 -p1 -%patch7 -p1 -%patch8 -p1 -%patch9 -p1 -%patch10 -p1 %build -autoreconf -i -f %configure make