commit dc5510d0af424e753ab6fb12639b7ddcdcb7d6fa Author: CentOS Sources Date: Thu Nov 4 00:58:35 2021 -0400 import mokutil-0.4.0-8.el9 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..af35945 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/0.4.0.tar.gz diff --git a/.mokutil.metadata b/.mokutil.metadata new file mode 100644 index 0000000..032d179 --- /dev/null +++ b/.mokutil.metadata @@ -0,0 +1 @@ +42d6c1551535386cba63265a6ed7172d11c88b97 SOURCES/0.4.0.tar.gz diff --git a/SOURCES/0001-Avoid-taking-pointer-to-packed-struct.patch b/SOURCES/0001-Avoid-taking-pointer-to-packed-struct.patch new file mode 100644 index 0000000..67d946e --- /dev/null +++ b/SOURCES/0001-Avoid-taking-pointer-to-packed-struct.patch @@ -0,0 +1,117 @@ +From 19e8c9071b3d9306ca7b7329b313b31f86c2936d Mon Sep 17 00:00:00 2001 +From: Harry Youd +Date: Wed, 31 Jul 2019 19:44:53 +0100 +Subject: [PATCH] Avoid taking pointer to packed struct +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Fixes: +error: taking address of packed member of ‘struct ’ may result in an unaligned pointer value [-Werror=address-of-packed-member] +--- + src/mokutil.c | 38 ++++++++++++++++++++++---------------- + 1 file changed, 22 insertions(+), 16 deletions(-) + +diff --git a/src/mokutil.c b/src/mokutil.c +index e2d567d..8892613 100644 +--- a/src/mokutil.c ++++ b/src/mokutil.c +@@ -270,20 +270,22 @@ build_mok_list (void *data, unsigned long data_size, uint32_t *mok_num) + return NULL; + } + +- if ((efi_guid_cmp (&CertList->SignatureType, &efi_guid_x509_cert) != 0) && +- (efi_guid_cmp (&CertList->SignatureType, &efi_guid_sha1) != 0) && +- (efi_guid_cmp (&CertList->SignatureType, &efi_guid_sha224) != 0) && +- (efi_guid_cmp (&CertList->SignatureType, &efi_guid_sha256) != 0) && +- (efi_guid_cmp (&CertList->SignatureType, &efi_guid_sha384) != 0) && +- (efi_guid_cmp (&CertList->SignatureType, &efi_guid_sha512) != 0)) { ++ efi_guid_t sigtype = CertList->SignatureType; ++ ++ if ((efi_guid_cmp (&sigtype, &efi_guid_x509_cert) != 0) && ++ (efi_guid_cmp (&sigtype, &efi_guid_sha1) != 0) && ++ (efi_guid_cmp (&sigtype, &efi_guid_sha224) != 0) && ++ (efi_guid_cmp (&sigtype, &efi_guid_sha256) != 0) && ++ (efi_guid_cmp (&sigtype, &efi_guid_sha384) != 0) && ++ (efi_guid_cmp (&sigtype, &efi_guid_sha512) != 0)) { + dbsize -= CertList->SignatureListSize; + CertList = (EFI_SIGNATURE_LIST *)((uint8_t *) CertList + + CertList->SignatureListSize); + continue; + } + +- if ((efi_guid_cmp (&CertList->SignatureType, &efi_guid_x509_cert) != 0) && +- (CertList->SignatureSize != signature_size (&CertList->SignatureType))) { ++ if ((efi_guid_cmp (&sigtype, &efi_guid_x509_cert) != 0) && ++ (CertList->SignatureSize != signature_size (&sigtype))) { + dbsize -= CertList->SignatureListSize; + CertList = (EFI_SIGNATURE_LIST *)((uint8_t *) CertList + + CertList->SignatureListSize); +@@ -312,7 +314,7 @@ build_mok_list (void *data, unsigned long data_size, uint32_t *mok_num) + } + + list[count].header = CertList; +- if (efi_guid_cmp (&CertList->SignatureType, &efi_guid_x509_cert) == 0) { ++ if (efi_guid_cmp (&sigtype, &efi_guid_x509_cert) == 0) { + /* X509 certificate */ + list[count].mok_size = CertList->SignatureSize - + sizeof(efi_guid_t); +@@ -442,10 +444,11 @@ list_keys (uint8_t *data, size_t data_size) + + for (unsigned int i = 0; i < mok_num; i++) { + printf ("[key %d]\n", i+1); +- if (efi_guid_cmp (&list[i].header->SignatureType, &efi_guid_x509_cert) == 0) { ++ efi_guid_t sigtype = list[i].header->SignatureType; ++ if (efi_guid_cmp (&sigtype, &efi_guid_x509_cert) == 0) { + print_x509 ((char *)list[i].mok, list[i].mok_size); + } else { +- print_hash_array (&list[i].header->SignatureType, ++ print_hash_array (&sigtype, + list[i].mok, list[i].mok_size); + } + if (i < mok_num - 1) +@@ -523,7 +526,8 @@ delete_data_from_list (const efi_guid_t *var_guid, const char *var_name, + remain = total; + for (unsigned int i = 0; i < mok_num; i++) { + remain -= list[i].header->SignatureListSize; +- if (efi_guid_cmp (&list[i].header->SignatureType, type) != 0) ++ efi_guid_t sigtype = list[i].header->SignatureType; ++ if (efi_guid_cmp (&sigtype, type) != 0) + continue; + + sig_list_size = list[i].header->SignatureListSize; +@@ -1057,7 +1061,8 @@ is_duplicate (const efi_guid_t *type, const void *data, const uint32_t data_size + } + + for (unsigned int i = 0; i < node_num; i++) { +- if (efi_guid_cmp (&list[i].header->SignatureType, type) != 0) ++ efi_guid_t sigtype = list[i].header->SignatureType; ++ if (efi_guid_cmp (&sigtype, type) != 0) + continue; + + if (efi_guid_cmp (type, &efi_guid_x509_cert) == 0) { +@@ -1510,8 +1515,8 @@ issue_hash_request (const char *hash_str, MokRequest req, + goto error; + /* Check if there is a signature list with the same type */ + for (unsigned int i = 0; i < mok_num; i++) { +- if (efi_guid_cmp (&mok_list[i].header->SignatureType, +- &hash_type) == 0) { ++ efi_guid_t sigtype = mok_list[i].header->SignatureType; ++ if (efi_guid_cmp (&sigtype, &hash_type) == 0) { + merge_ind = i; + list_size -= sizeof(EFI_SIGNATURE_LIST); + break; +@@ -1678,8 +1683,9 @@ export_db_keys (const DBName db_name) + for (unsigned i = 0; i < mok_num; i++) { + off_t offset = 0; + ssize_t write_size; ++ efi_guid_t sigtype = list[i].header->SignatureType; + +- if (efi_guid_cmp (&list[i].header->SignatureType, &efi_guid_x509_cert) != 0) ++ if (efi_guid_cmp (&sigtype, &efi_guid_x509_cert) != 0) + continue; + + /* Dump X509 certificate to files */ +-- +2.21.0 + diff --git a/SOURCES/0002-Fix-a-integer-comparison-sign-issue.patch b/SOURCES/0002-Fix-a-integer-comparison-sign-issue.patch new file mode 100644 index 0000000..591a8d2 --- /dev/null +++ b/SOURCES/0002-Fix-a-integer-comparison-sign-issue.patch @@ -0,0 +1,33 @@ +From 9292352eb29a4fca41909448799efc524ee3c255 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Wed, 25 Jul 2018 10:27:34 -0400 +Subject: [PATCH] Fix a integer comparison sign issue. + +I introduced this, and it's stupid: + +mokutil.c: In function 'generate_pw_hash': +mokutil.c:1971:16: error: comparison of integer expressions of different signedness: 'unsigned int' and 'int' [-Werror=sign-compare] + if (salt_size > settings_len - (next - settings)) { + ^ + +Signed-off-by: Peter Jones +--- + src/mokutil.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/mokutil.c b/src/mokutil.c +index d03127abf54..068df0d109c 100644 +--- a/src/mokutil.c ++++ b/src/mokutil.c +@@ -1938,7 +1938,7 @@ generate_pw_hash (const char *input_pw) + char *password = NULL; + char *crypt_string; + const char *prefix; +- int settings_len = sizeof (settings) - 2; ++ unsigned int settings_len = sizeof (settings) - 2; + unsigned int pw_len, salt_size; + + if (input_pw) { +-- +2.23.0 + diff --git a/SOURCES/0003-mokutil-Add-option-to-print-the-UEFI-SBAT-variable-c.patch b/SOURCES/0003-mokutil-Add-option-to-print-the-UEFI-SBAT-variable-c.patch new file mode 100644 index 0000000..34f7fbc --- /dev/null +++ b/SOURCES/0003-mokutil-Add-option-to-print-the-UEFI-SBAT-variable-c.patch @@ -0,0 +1,124 @@ +From 698994102afcbbe16e65930a09e0df5248c4d200 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Wed, 17 Mar 2021 14:38:57 +0100 +Subject: [PATCH] mokutil: Add option to print the UEFI SBAT variable content + +This variable contains the descriptive form of all the components used by +the operating systems that ship signed shim binaries. Along with a minimum +generation number for each component. More information in can be found in +the UEFI Secure Boot Advanced Targeting (SBAT) specification: + + https://github.com/rhboot/shim/blob/main/SBAT.md + +Since a SBAT variable contains a set of Comma Separated Values (CSV) UTF-8 +encoded strings, the data could just be printed without the need to do any +previous processing. + +Signed-off-by: Javier Martinez Canillas +--- + man/mokutil.1 | 5 +++++ + src/mokutil.c | 33 +++++++++++++++++++++++++++++++++ + 2 files changed, 38 insertions(+) + +diff --git a/man/mokutil.1 b/man/mokutil.1 +index 25fe8b433da..446298763ad 100644 +--- a/man/mokutil.1 ++++ b/man/mokutil.1 +@@ -73,6 +73,8 @@ mokutil \- utility to manipulate machine owner keys + .br + \fBmokutil\fR [--dbx] + .br ++\fBmokutil\fR [--sbat] ++.br + + .SH DESCRIPTION + \fBmokutil\fR is a tool to import or delete the machines owner keys +@@ -173,3 +175,6 @@ List the keys in the secure boot signature store (db) + \fB--dbx\fR + List the keys in the secure boot blacklist signature store (dbx) + .TP ++\fB--sbat\fR ++List the entries in the Secure Boot Advanced Targeting store (SBAT) ++.TP +diff --git a/src/mokutil.c b/src/mokutil.c +index b66c1b8b5a7..0c25ae5033d 100644 +--- a/src/mokutil.c ++++ b/src/mokutil.c +@@ -84,6 +84,7 @@ + #define DELETE_HASH (1 << 22) + #define VERBOSITY (1 << 23) + #define TIMEOUT (1 << 24) ++#define LIST_SBAT (1 << 25) + + #define DEFAULT_CRYPT_METHOD SHA512_BASED + #define DEFAULT_SALT_SIZE SHA512_SALT_MAX +@@ -176,6 +177,7 @@ print_help () + printf (" --db\t\t\t\t\tList the keys in db\n"); + printf (" --dbx\t\t\t\t\tList the keys in dbx\n"); + printf (" --timeout <-1,0..0x7fff>\t\tSet the timeout for MOK prompt\n"); ++ printf (" --sbat\t\t\t\tList the entries in SBAT\n"); + printf ("\n"); + printf ("Supplimentary Options:\n"); + printf (" --hash-file \t\tUse the specific password hash\n"); +@@ -1598,6 +1600,31 @@ error: + return ret; + } + ++static int ++print_var_content (const char *var_name, const efi_guid_t guid) ++{ ++ uint8_t *data = NULL; ++ size_t data_size; ++ uint32_t attributes; ++ int ret; ++ ++ ret = efi_get_variable (guid, var_name, &data, &data_size, &attributes); ++ if (ret < 0) { ++ if (errno == ENOENT) { ++ printf ("%s is empty\n", var_name); ++ return 0; ++ } ++ ++ fprintf (stderr, "Failed to read %s: %m\n", var_name); ++ return -1; ++ } ++ ++ printf ("%s", data); ++ free (data); ++ ++ return ret; ++} ++ + static int + revoke_request (MokRequest req) + { +@@ -2187,6 +2214,7 @@ main (int argc, char *argv[]) + {"kek", no_argument, 0, 0 }, + {"db", no_argument, 0, 0 }, + {"dbx", no_argument, 0, 0 }, ++ {"sbat", no_argument, 0, 0 }, + {"timeout", required_argument, 0, 0 }, + {0, 0, 0, 0} + }; +@@ -2271,6 +2299,8 @@ main (int argc, char *argv[]) + } else { + db_name = DBX; + } ++ } else if (strcmp (option, "sbat") == 0) { ++ command |= LIST_SBAT; + } else if (strcmp (option, "timeout") == 0) { + command |= TIMEOUT; + timeout = strdup (optarg); +@@ -2543,6 +2573,9 @@ main (int argc, char *argv[]) + case TIMEOUT: + ret = set_timeout (timeout); + break; ++ case LIST_SBAT: ++ ret = print_var_content ("SBAT", efi_guid_shim); ++ break; + default: + print_help (); + break; +-- +2.29.2 + diff --git a/SOURCES/0004-mokutil-add-mok-variables-parsing-support.patch b/SOURCES/0004-mokutil-add-mok-variables-parsing-support.patch new file mode 100644 index 0000000..88ea983 --- /dev/null +++ b/SOURCES/0004-mokutil-add-mok-variables-parsing-support.patch @@ -0,0 +1,241 @@ +From 256639accc910e60496fffef96128dc1afd0fa3a Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Wed, 17 Mar 2021 14:49:21 +0100 +Subject: [PATCH] mokutil: add mok-variables parsing support + +his patch adds support for getting mok variables from +/sys/firmware/efi/mok-variables/$NAME , if they are present, as well as +for checking MokListRT, MokListRT1, MokListRT2, etc., for any of the mok +variables. + +Signed-off-by: Peter Jones +--- + src/mokutil.c | 175 +++++++++++++++++++++++++++++++++++++++++++------- + 1 file changed, 151 insertions(+), 24 deletions(-) + +diff --git a/src/mokutil.c b/src/mokutil.c +index 0c25ae5033d..252dc7a327f 100644 +--- a/src/mokutil.c ++++ b/src/mokutil.c +@@ -251,6 +251,63 @@ signature_size (const efi_guid_t *hash_type) + return 0; + } + ++static int ++mok_get_variable(const char *name, uint8_t **datap, size_t *data_sizep) ++{ ++ char filename[] = "/sys/firmware/efi/mok-variables/implausibly-long-mok-variable-name"; ++ size_t filename_sz = sizeof(filename); ++ int fd, rc; ++ struct stat sb = { 0, }; ++ uint8_t *buf; ++ size_t bufsz, pos = 0; ++ ssize_t ssz; ++ ++ *datap = 0; ++ *data_sizep = 0; ++ ++ snprintf(filename, filename_sz, "/sys/firmware/efi/mok-variables/%s", name); ++ ++ fd = open(filename, O_RDONLY); ++ if (fd < 0) ++ return fd; ++ ++ rc = fstat(fd, &sb); ++ if (rc < 0) { ++err_close: ++ close(fd); ++ return rc; ++ } ++ ++ if (sb.st_size == 0) { ++ errno = ENOENT; ++ rc = -1; ++ goto err_close; ++ } ++ ++ bufsz = sb.st_size; ++ buf = calloc(1, bufsz); ++ if (!buf) ++ goto err_close; ++ ++ while (pos < bufsz) { ++ ssz = read(fd, &buf[pos], bufsz - pos); ++ if (ssz < 0) { ++ if (errno == EAGAIN || ++ errno == EWOULDBLOCK || ++ errno == EINTR) ++ continue; ++ free(buf); ++ goto err_close; ++ } ++ ++ pos += ssz; ++ } ++ *datap = buf; ++ *data_sizep = pos; ++ ++ return 0; ++} ++ + static MokListNode* + build_mok_list (void *data, unsigned long data_size, uint32_t *mok_num) + { +@@ -622,25 +679,44 @@ static int + list_keys_in_var (const char *var_name, const efi_guid_t guid) + { + uint8_t *data = NULL; +- size_t data_size; ++ char varname[] = "implausibly-long-mok-variable-name"; ++ size_t data_sz, i, varname_sz = sizeof(varname); + uint32_t attributes; + int ret; + +- ret = efi_get_variable (guid, var_name, &data, &data_size, &attributes); +- if (ret < 0) { +- if (errno == ENOENT) { +- printf ("%s is empty\n", var_name); +- return 0; ++ ret = mok_get_variable(var_name, &data, &data_sz); ++ if (ret >= 0) { ++ ret = list_keys (data, data_sz); ++ free(data); ++ return ret; ++ } ++ ++ for (i = 0; i < SIZE_MAX; i++) { ++ if (i == 0) { ++ snprintf(varname, varname_sz, "%s", var_name); ++ } else { ++ snprintf(varname, varname_sz, "%s%zu", var_name, i); + } + +- fprintf (stderr, "Failed to read %s: %m\n", var_name); +- return -1; +- } ++ ret = efi_get_variable (guid, varname, &data, &data_sz, ++ &attributes); ++ if (ret < 0) ++ return 0; + +- ret = list_keys (data, data_size); +- free (data); ++ ret = list_keys (data, data_sz); ++ free(data); ++ /* ++ * If ret is < 0, the next one will error as well. ++ * If ret is 0, we need to test the next variable. ++ * If it's 1, that's a real answer. ++ */ ++ if (ret < 0) ++ return 0; ++ if (ret > 0) ++ return ret; ++ } + +- return ret; ++ return 0; + } + + static int +@@ -1039,22 +1115,15 @@ is_valid_cert (void *cert, uint32_t cert_size) + } + + static int +-is_duplicate (const efi_guid_t *type, const void *data, const uint32_t data_size, +- const efi_guid_t *vendor, const char *db_name) ++is_one_duplicate (const efi_guid_t *type, ++ const void *data, const uint32_t data_size, ++ uint8_t *var_data, size_t var_data_size) + { +- uint8_t *var_data; +- size_t var_data_size; +- uint32_t attributes; + uint32_t node_num; + MokListNode *list; + int ret = 0; + +- if (!data || data_size == 0 || !db_name) +- return 0; +- +- ret = efi_get_variable (*vendor, db_name, &var_data, &var_data_size, +- &attributes); +- if (ret < 0) ++ if (!data || data_size == 0) + return 0; + + list = build_mok_list (var_data, var_data_size, &node_num); +@@ -1087,11 +1156,69 @@ is_duplicate (const efi_guid_t *type, const void *data, const uint32_t data_size + done: + if (list) + free (list); +- free (var_data); + + return ret; + } + ++static int ++is_duplicate (const efi_guid_t *type, ++ const void *data, const uint32_t data_size, ++ const efi_guid_t *vendor, const char *db_name) ++{ ++ uint32_t attributes; ++ char varname[] = "implausibly-long-mok-variable-name"; ++ size_t varname_sz = sizeof(varname); ++ int ret = 0; ++ size_t i; ++ ++ if (!strncmp(db_name, "Mok", 3)) { ++ uint8_t *var_data = NULL; ++ size_t var_data_size = 0; ++ ret = mok_get_variable(db_name, &var_data, &var_data_size); ++ if (ret >= 0) { ++ ret = is_one_duplicate(type, data, data_size, ++ var_data, var_data_size); ++ if (ret >= 0) { ++ free (var_data); ++ return ret; ++ } ++ var_data = NULL; ++ var_data_size = 0; ++ } ++ } ++ ++ for (i = 0; i < SIZE_MAX; i++) { ++ uint8_t *var_data = NULL; ++ size_t var_data_size = 0; ++ if (i == 0) { ++ snprintf(varname, varname_sz, "%s", db_name); ++ } else { ++ snprintf(varname, varname_sz, "%s%zu", db_name, i); ++ } ++ ++ ret = efi_get_variable (*vendor, varname, ++ &var_data, &var_data_size, ++ &attributes); ++ if (ret < 0) ++ return 0; ++ ++ ret = is_one_duplicate(type, data, data_size, ++ var_data, var_data_size); ++ free (var_data); ++ /* ++ * If ret is < 0, the next one will error as well. ++ * If ret is 0, we need to test the next variable. ++ * If it's 1, that's a real answer. ++ */ ++ if (ret < 0) ++ return 0; ++ if (ret > 0) ++ return ret; ++ } ++ ++ return 0; ++} ++ + static int + is_valid_request (const efi_guid_t *type, void *mok, uint32_t mok_size, + MokRequest req) +-- +2.29.2 + diff --git a/SOURCES/0005-mokutil-remove-simple-hash.patch b/SOURCES/0005-mokutil-remove-simple-hash.patch new file mode 100644 index 0000000..f53791a --- /dev/null +++ b/SOURCES/0005-mokutil-remove-simple-hash.patch @@ -0,0 +1,260 @@ +From b7a6c0a7ee8e66c5daa377d2e6f59461ed34f3bf Mon Sep 17 00:00:00 2001 +From: Gary Lin +Date: Tue, 25 May 2021 12:46:03 +0200 +Subject: [PATCH] mokutil: remove "--simple-hash" + +The simple-hash password format is used by the very early MokManager and +not the default format anymore after we changed to password-crypt. +Remove the code to reduce the code size. + +Signed-off-by: Gary Lin +--- + src/mokutil.c | 87 +++++---------------------------------------------- + 1 file changed, 7 insertions(+), 80 deletions(-) + +diff --git a/src/mokutil.c b/src/mokutil.c +index 252dc7a327f..563e585979b 100644 +--- a/src/mokutil.c ++++ b/src/mokutil.c +@@ -76,7 +76,6 @@ + #define TEST_KEY (1 << 14) + #define RESET (1 << 15) + #define GENERATE_PW_HASH (1 << 16) +-#define SIMPLE_HASH (1 << 17) + #define IGNORE_DB (1 << 18) + #define USE_DB (1 << 19) + #define MOKX (1 << 20) +@@ -95,8 +94,6 @@ typedef unsigned long efi_status_t; + typedef uint8_t efi_bool_t; + typedef wchar_t efi_char16_t; /* UNICODE character */ + +-static int use_simple_hash; +- + typedef enum { + DELETE_MOK = 0, + ENROLL_MOK, +@@ -182,7 +179,6 @@ print_help () + printf ("Supplimentary Options:\n"); + printf (" --hash-file \t\tUse the specific password hash\n"); + printf (" --root-pw\t\t\t\tUse the root password\n"); +- printf (" --simple-hash\t\t\t\tUse the old password hash method\n"); + printf (" --mokx\t\t\t\tManipulate the MOK blacklist\n"); + } + +@@ -814,32 +810,6 @@ error: + return ret; + } + +-static int +-generate_auth (void *new_list, int list_len, char *password, +- unsigned int pw_len, uint8_t *auth) +-{ +- efi_char16_t efichar_pass[PASSWORD_MAX+1]; +- unsigned long efichar_len; +- SHA256_CTX ctx; +- +- if (!password || !auth) +- return -1; +- +- efichar_len = efichar_from_char (efichar_pass, password, +- pw_len * sizeof(efi_char16_t)); +- +- SHA256_Init (&ctx); +- +- if (new_list) +- SHA256_Update (&ctx, new_list, list_len); +- +- SHA256_Update (&ctx, efichar_pass, efichar_len); +- +- SHA256_Final (auth, &ctx); +- +- return 0; +-} +- + static void + generate_salt (char salt[], unsigned int salt_size) + { +@@ -979,7 +949,6 @@ update_request (void *new_list, int list_len, MokRequest req, + size_t data_size; + const char *req_name, *auth_name; + pw_crypt_t pw_crypt; +- uint8_t auth[SHA256_DIGEST_LENGTH]; + char *password = NULL; + unsigned int pw_len; + int auth_ret; +@@ -1028,12 +997,7 @@ update_request (void *new_list, int list_len, MokRequest req, + goto error; + } + +- if (!use_simple_hash) { +- auth_ret = generate_hash (&pw_crypt, password, pw_len); +- } else { +- auth_ret = generate_auth (new_list, list_len, password, +- pw_len, auth); +- } ++ auth_ret = generate_hash (&pw_crypt, password, pw_len); + if (auth_ret < 0) { + fprintf (stderr, "Couldn't generate hash\n"); + goto error; +@@ -1069,13 +1033,8 @@ update_request (void *new_list, int list_len, MokRequest req, + } + + /* Write MokAuth, MokDelAuth, MokXAuth, or MokXDelAuth */ +- if (!use_simple_hash) { +- data = (void *)&pw_crypt; +- data_size = PASSWORD_CRYPT_SIZE; +- } else { +- data = (void *)auth; +- data_size = SHA256_DIGEST_LENGTH; +- } ++ data = (void *)&pw_crypt; ++ data_size = PASSWORD_CRYPT_SIZE; + + if (efi_set_variable (efi_guid_shim, auth_name, data, data_size, + attributes, S_IRUSR | S_IWUSR) < 0) { +@@ -1904,26 +1863,16 @@ set_password (const char *hash_file, const int root_pw, const int clear) + goto error; + } + +- if (!use_simple_hash) { +- pw_crypt.method = DEFAULT_CRYPT_METHOD; +- auth_ret = generate_hash (&pw_crypt, password, pw_len); +- } else { +- auth_ret = generate_auth (NULL, 0, password, pw_len, +- auth); +- } ++ pw_crypt.method = DEFAULT_CRYPT_METHOD; ++ auth_ret = generate_hash (&pw_crypt, password, pw_len); + if (auth_ret < 0) { + fprintf (stderr, "Couldn't generate hash\n"); + goto error; + } + } + +- if (!use_simple_hash) { +- data = (void *)&pw_crypt; +- data_size = PASSWORD_CRYPT_SIZE; +- } else { +- data = (void *)auth; +- data_size = SHA256_DIGEST_LENGTH; +- } ++ data = (void *)auth; ++ data_size = SHA256_DIGEST_LENGTH; + uint32_t attributes = EFI_VARIABLE_NON_VOLATILE + | EFI_VARIABLE_BOOTSERVICE_ACCESS + | EFI_VARIABLE_RUNTIME_ACCESS; +@@ -2301,8 +2250,6 @@ main (int argc, char *argv[]) + DBName db_name = MOK_LIST_RT; + int ret = -1; + +- use_simple_hash = 0; +- + if (!efi_variables_supported ()) { + fprintf (stderr, "EFI variables are not supported on this system\n"); + exit (1); +@@ -2329,7 +2276,6 @@ main (int argc, char *argv[]) + {"hash-file", required_argument, 0, 'f'}, + {"generate-hash", optional_argument, 0, 'g'}, + {"root-pw", no_argument, 0, 'P'}, +- {"simple-hash", no_argument, 0, 's'}, + {"ignore-db", no_argument, 0, 0 }, + {"use-db", no_argument, 0, 0 }, + {"mok", no_argument, 0, 'm'}, +@@ -2531,10 +2477,6 @@ main (int argc, char *argv[]) + case 'x': + command |= EXPORT; + break; +- case 's': +- command |= SIMPLE_HASH; +- use_simple_hash = 1; +- break; + case 'm': + db_name = MOK_LIST_RT; + break; +@@ -2555,9 +2497,6 @@ main (int argc, char *argv[]) + } + } + +- if (use_root_pw == 1 && use_simple_hash == 1) +- use_simple_hash = 0; +- + if (hash_file && use_root_pw) + command |= HELP; + +@@ -2593,22 +2532,18 @@ main (int argc, char *argv[]) + ret = list_keys_in_var ("MokDel", efi_guid_shim); + break; + case IMPORT: +- case IMPORT | SIMPLE_HASH: + ret = issue_mok_request (files, total, ENROLL_MOK, + hash_file, use_root_pw); + break; + case DELETE: +- case DELETE | SIMPLE_HASH: + ret = issue_mok_request (files, total, DELETE_MOK, + hash_file, use_root_pw); + break; + case IMPORT_HASH: +- case IMPORT_HASH | SIMPLE_HASH: + ret = issue_hash_request (hash_str, ENROLL_MOK, + hash_file, use_root_pw); + break; + case DELETE_HASH: +- case DELETE_HASH | SIMPLE_HASH: + ret = issue_hash_request (hash_str, DELETE_MOK, + hash_file, use_root_pw); + break; +@@ -2623,11 +2558,9 @@ main (int argc, char *argv[]) + ret = export_db_keys (db_name); + break; + case PASSWORD: +- case PASSWORD | SIMPLE_HASH: + ret = set_password (hash_file, use_root_pw, 0); + break; + case CLEAR_PASSWORD: +- case CLEAR_PASSWORD | SIMPLE_HASH: + ret = set_password (NULL, 0, 1); + break; + case DISABLE_VALIDATION: +@@ -2643,7 +2576,6 @@ main (int argc, char *argv[]) + ret = test_key (ENROLL_MOK, key_file); + break; + case RESET: +- case RESET | SIMPLE_HASH: + ret = reset_moks (ENROLL_MOK, hash_file, use_root_pw); + break; + case GENERATE_PW_HASH: +@@ -2662,22 +2594,18 @@ main (int argc, char *argv[]) + ret = list_keys_in_var ("MokXDel", efi_guid_shim); + break; + case IMPORT | MOKX: +- case IMPORT | SIMPLE_HASH | MOKX: + ret = issue_mok_request (files, total, ENROLL_BLACKLIST, + hash_file, use_root_pw); + break; + case DELETE | MOKX: +- case DELETE | SIMPLE_HASH | MOKX: + ret = issue_mok_request (files, total, DELETE_BLACKLIST, + hash_file, use_root_pw); + break; + case IMPORT_HASH | MOKX: +- case IMPORT_HASH | SIMPLE_HASH | MOKX: + ret = issue_hash_request (hash_str, ENROLL_BLACKLIST, + hash_file, use_root_pw); + break; + case DELETE_HASH | MOKX: +- case DELETE_HASH | SIMPLE_HASH | MOKX: + ret = issue_hash_request (hash_str, DELETE_BLACKLIST, + hash_file, use_root_pw); + break; +@@ -2688,7 +2616,6 @@ main (int argc, char *argv[]) + ret = revoke_request (DELETE_BLACKLIST); + break; + case RESET | MOKX: +- case RESET | SIMPLE_HASH | MOKX: + ret = reset_moks (ENROLL_BLACKLIST, hash_file, use_root_pw); + break; + case TEST_KEY | MOKX: +-- +2.31.1 + diff --git a/SOURCES/0006-man-remove-simple-hash.patch b/SOURCES/0006-man-remove-simple-hash.patch new file mode 100644 index 0000000..4ae64a0 --- /dev/null +++ b/SOURCES/0006-man-remove-simple-hash.patch @@ -0,0 +1,81 @@ +From d944337820debcaa5e275ec6a3523702ee2d9dd7 Mon Sep 17 00:00:00 2001 +From: Gary Lin +Date: Thu, 27 Aug 2020 14:48:08 +0800 +Subject: [PATCH 2/2] man: remove "--simple-hash" + +Remove "--simple-hash" from the man page. + +Signed-off-by: Gary Lin +--- + man/mokutil.1 | 19 ++++++------------- + 1 file changed, 6 insertions(+), 13 deletions(-) + +diff --git a/man/mokutil.1 b/man/mokutil.1 +index 446298763ad..1f82ff1abed 100644 +--- a/man/mokutil.1 ++++ b/man/mokutil.1 +@@ -15,11 +15,11 @@ mokutil \- utility to manipulate machine owner keys + .br + \fBmokutil\fR [--import \fIkeylist\fR| -i \fIkeylist\fR] + ([--hash-file \fIhashfile\fR | -f \fIhashfile\fR] | [--root-pw | -P] | +- [--simple-hash | -s] | [--mokx | -X]) ++ [--mokx | -X]) + .br + \fBmokutil\fR [--delete \fIkeylist\fR | -d \fIkeylist\fR] + ([--hash-file \fIhashfile\fR | -f \fIhashfile\fR] | [--root-pw | -P] | +- [--simple-hash | -s] | [--mokx |- X]) ++ [--mokx |- X]) + .br + \fBmokutil\fR [--revoke-import] + ([--mokx | -X]) +@@ -30,11 +30,9 @@ mokutil \- utility to manipulate machine owner keys + \fBmokutil\fR [--export | -x] + .br + \fBmokutil\fR [--password | -p] +- ([--hash-file \fIhashfile\fR | -f \fIhashfile\fR] | [--root-pw | -P] | +- [--simple-hash | -s]) ++ ([--hash-file \fIhashfile\fR | -f \fIhashfile\fR] | [--root-pw | -P]) + .br + \fBmokutil\fR [--clear-password | -c] +- ([--simple-hash | -s]) + .br + \fBmokutil\fR [--disable-validation] + .br +@@ -47,7 +45,7 @@ mokutil \- utility to manipulate machine owner keys + .br + \fBmokutil\fR [--reset] + ([--hash-file \fIhashfile\fR | -f \fIhashfile\fR] | [--root-pw | -P] | +- [--simple-hash | -s] | [--mok | -X]) ++ [--mok | -X]) + .br + \fBmokutil\fR [--generate-hash=\fIpassword\fR | -g\fIpassword\fR] + .br +@@ -57,11 +55,11 @@ mokutil \- utility to manipulate machine owner keys + .br + \fBmokutil\fR [--import-hash \fIhash\fR] + ([--hash-file \fIhashfile\fR | -f \fIhashfile\fR] | [--root-pw | -P] | +- [--simple-hash | -s] | [--mokx | -X]) ++ [--mokx | -X]) + .br + \fBmokutil\fR [--delete-hash \fIhash\fR] + ([--hash-file \fIhashfile\fR | -f \fIhashfile\fR] | [--root-pw | -P] | +- [--simple-hash | -s] | [--mokx | -X]) ++ [--mokx | -X]) + .br + \fBmokutil\fR [--set-verbosity (\fItrue\fR | \fIfalse\fR)] + .br +@@ -138,11 +136,6 @@ Use the password hash from a specific file + \fB-P, --root-pw\fR + Use the root password hash from /etc/shadow + .TP +-\fB-s, --simple-hash\fR +-Use the old SHA256 password hash method to hash the password +-.br +-Note: --root-pw invalidates --simple-hash +-.TP + \fB--ignore-db\fR + Tell shim to not use the keys in db to verify EFI images + .TP +-- +2.31.1 + diff --git a/SOURCES/0007-mokutil-use-EVP_Digest-functions-instead-of-the-depr.patch b/SOURCES/0007-mokutil-use-EVP_Digest-functions-instead-of-the-depr.patch new file mode 100644 index 0000000..67bdff8 --- /dev/null +++ b/SOURCES/0007-mokutil-use-EVP_Digest-functions-instead-of-the-depr.patch @@ -0,0 +1,98 @@ +From f552d2bb570568673d293fcb2263a2ee8c3333de Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Tue, 25 May 2021 15:22:29 +0200 +Subject: [PATCH] mokutil: use EVP_Digest()* functions instead of the + deprecated SHA1_*() + +The SHA1_*() functions have been deprecated since OpenSSL 3.0, this leads +to compile errors when building with -Werror=deprecated-declarations, i.e: + +mokutil.c: In function 'print_x509': +mokutil.c:424:9: error: 'SHA1_Init' is deprecated: Since OpenSSL 3.0 [-Werror=deprecated-declarations] + 424 | SHA1_Init (&ctx); + | ^~~~~~~~~ +... + +instead, the EVP_Digest*() functions could be used. Port to them and avoid +these build failures with the latest OpenSSL 3.0 version. + +Signed-off-by: Javier Martinez Canillas +--- + src/mokutil.c | 44 ++++++++++++++++++++++++++++++++++++-------- + 1 file changed, 36 insertions(+), 8 deletions(-) + +diff --git a/src/mokutil.c b/src/mokutil.c +index 563e585979b..3fdc791af7f 100644 +--- a/src/mokutil.c ++++ b/src/mokutil.c +@@ -405,8 +405,10 @@ print_x509 (char *cert, int cert_size) + { + X509 *X509cert; + BIO *cert_bio; +- SHA_CTX ctx; +- uint8_t fingerprint[SHA_DIGEST_LENGTH]; ++ EVP_MD_CTX *ctx; ++ const EVP_MD *md; ++ unsigned int md_len; ++ unsigned char fingerprint[EVP_MAX_MD_SIZE]; + + cert_bio = BIO_new (BIO_s_mem ()); + BIO_write (cert_bio, cert, cert_size); +@@ -418,22 +420,48 @@ print_x509 (char *cert, int cert_size) + X509cert = d2i_X509_bio (cert_bio, NULL); + if (X509cert == NULL) { + fprintf (stderr, "Invalid X509 certificate\n"); +- return -1; ++ goto cleanup_bio; ++ } ++ ++ md = EVP_get_digestbyname ("SHA1"); ++ if(md == NULL) { ++ fprintf (stderr, "Failed to get SHA1 digest\n"); ++ goto cleanup_bio; ++ } ++ ++ ctx = EVP_MD_CTX_create (); ++ if (ctx == NULL) { ++ fprintf (stderr, "Failed to create digest context\n"); ++ goto cleanup_bio; + } + +- SHA1_Init (&ctx); +- SHA1_Update (&ctx, cert, cert_size); +- SHA1_Final (fingerprint, &ctx); ++ if (!EVP_DigestInit_ex (ctx, md, NULL)) { ++ fprintf (stderr, "Failed to initialize digest context\n"); ++ goto cleanup_ctx; ++ } ++ ++ if (!EVP_DigestUpdate (ctx, cert, cert_size)) { ++ fprintf (stderr, "Failed to hash into the digest context\n"); ++ goto cleanup_ctx; ++ } ++ ++ if (!EVP_DigestFinal_ex (ctx, fingerprint, &md_len)) { ++ fprintf (stderr, "Failed to get digest value\n"); ++ goto cleanup_ctx; ++ } + + printf ("SHA1 Fingerprint: "); +- for (unsigned int i = 0; i < SHA_DIGEST_LENGTH; i++) { ++ for (unsigned int i = 0; i < md_len; i++) { + printf ("%02x", fingerprint[i]); +- if (i < SHA_DIGEST_LENGTH - 1) ++ if (i < md_len - 1) + printf (":"); + } + printf ("\n"); + X509_print_fp (stdout, X509cert); + ++cleanup_ctx: ++ EVP_MD_CTX_destroy (ctx); ++cleanup_bio: + BIO_free (cert_bio); + + return 0; +-- +2.31.1 + diff --git a/SPECS/mokutil.spec b/SPECS/mokutil.spec new file mode 100644 index 0000000..a7a1378 --- /dev/null +++ b/SPECS/mokutil.spec @@ -0,0 +1,146 @@ +Name: mokutil +Version: 0.4.0 +Release: 8%{?dist} +Epoch: 2 +Summary: Tool to manage UEFI Secure Boot MoK Keys +License: GPLv3+ +URL: https://github.com/lcp/mokutil +ExclusiveArch: %{ix86} x86_64 aarch64 +BuildRequires: make +BuildRequires: gcc +BuildRequires: autoconf automake gnu-efi git openssl-devel openssl +BuildRequires: efivar-devel >= 31-1 +Source0: https://github.com/lcp/mokutil/archive/%{version}.tar.gz +Conflicts: shim < 0.8-1%{?dist} +Obsoletes: mokutil < 0.2.0 + +Patch0001: 0001-Avoid-taking-pointer-to-packed-struct.patch +Patch0002: 0002-Fix-a-integer-comparison-sign-issue.patch +Patch0003: 0003-mokutil-Add-option-to-print-the-UEFI-SBAT-variable-c.patch +Patch0004: 0004-mokutil-add-mok-variables-parsing-support.patch +Patch0005: 0005-mokutil-remove-simple-hash.patch +Patch0006: 0006-man-remove-simple-hash.patch +Patch0007: 0007-mokutil-use-EVP_Digest-functions-instead-of-the-depr.patch + +%description +mokutil provides a tool to manage keys for Secure Boot through the MoK +("Machine's Own Keys") mechanism. + +%prep +%setup -q -n %{name}-%{version} +git init +git config user.email "%{name}-owner@fedoraproject.org" +git config user.name "Fedora Ninjas" +git add . +git commit -a -q -m "%{version} baseline." +git am %{patches} - 2:0.4.0-8 +- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags + Related: rhbz#1991688 + +* Wed Jun 16 2021 Mohan Boddu - 2:0.4.0-7 +- Rebuilt for RHEL 9 BETA for openssl 3.0 + Related: rhbz#1971065 + +* Tue May 25 2021 Javier Martinez Canillas - 0.4.0-6 +- Port to OpenSSL 3.0 + Resolves: rhbz#1958040 + +* Fri Apr 16 2021 Mohan Boddu - 2:0.4.0-5 +- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937 + +* Wed Mar 17 2021 Javier Martinez Canillas - 0.4.0-4 +- Add SBAT and mok-variables support + +* Tue Jan 26 2021 Fedora Release Engineering - 2:0.4.0-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + +* Tue Jul 28 2020 Fedora Release Engineering - 2:0.4.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Thu Jun 11 2020 Javier Martinez Canillas - 0.4.0-1 +- Update to 0.4.0 release + +* Wed Jan 29 2020 Fedora Release Engineering - 2:0.3.0-15 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Tue Nov 12 2019 Peter Jones - 0.3.0-14 +- Pull one more upstream patch to keep this in sync with the f31 build. + +* Thu Oct 24 2019 Leigh Scott - 1:0.3.0-14 +- Apply upstream commits to fix FTBFS + +* Thu Jul 25 2019 Fedora Release Engineering - 1:0.3.0-13 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Fri Feb 01 2019 Fedora Release Engineering - 1:0.3.0-12 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Mon Jan 14 2019 Björn Esser - 1:0.3.0-11 +- Rebuilt for libcrypt.so.2 (#1666033) + +* Fri Jul 13 2018 Fedora Release Engineering - 1:0.3.0-10 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Thu Feb 08 2018 Fedora Release Engineering - 1:0.3.0-9 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Sat Jan 20 2018 Björn Esser - 1:0.3.0-8 +- Rebuilt for switch to libxcrypt + +* Thu Aug 03 2017 Fedora Release Engineering - 1:0.3.0-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Wed Jul 26 2017 Fedora Release Engineering - 1:0.3.0-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Sat Jul 08 2017 Peter Jones - 0.3.0-5 +- Rebuild for efivar-31-1.fc26 + Related: rhbz#1468841 + +* Fri Feb 10 2017 Fedora Release Engineering - 1:0.3.0-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Wed Aug 17 2016 Peter Jones - 0.3.0-3 +- Rebuild for newer efivar again. + +* Wed Aug 10 2016 Peter Jones - 0.3.0-2 +- Update for newer efivar. + +* Tue Jun 14 2016 Peter Jones - 0.3.0-1 +- Update to 0.3.0 release. + Resolves: rhbz#1334628 + +* Thu Feb 04 2016 Fedora Release Engineering - 1:0.2.0-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Wed Jun 17 2015 Fedora Release Engineering - 1:0.2.0-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Sat Feb 21 2015 Till Maas - 1:0.2.0-2 +- Rebuilt for Fedora 23 Change + https://fedoraproject.org/wiki/Changes/Harden_all_packages_with_position-independent_code + +* Mon Oct 06 2014 Peter Jones - 0.2.0-1 +- First independent package.