From 62c481c64ae8d4e239e0262cc2dd06e03c706925 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Guzm=C3=A1n?= <ark@switnet.org> Date: Sat, 11 Dec 2021 05:23:03 +0000 Subject: [PATCH] Grub2 unsigned 10.0 --- ...tomount-support-LUKS-detached-header.patch | 253 +++++++ .../0002-Cryptomount-support-key-files.patch | 211 ++++++ ...s-allow-multiple-passphrase-attempts.patch | 335 +++++++++ ...4-Cryptomount-support-plain-dm-crypt.patch | 650 ++++++++++++++++++ ...ptomount-support-for-hyphens-in-UUID.patch | 128 ++++ ...rt-for-using-whole-device-as-keyfile.patch | 114 +++ helpers/make-grub2-unsigned | 67 ++ 7 files changed, 1758 insertions(+) create mode 100644 helpers/DATA/grub2-unsigned/0001-Cryptomount-support-LUKS-detached-header.patch create mode 100644 helpers/DATA/grub2-unsigned/0002-Cryptomount-support-key-files.patch create mode 100644 helpers/DATA/grub2-unsigned/0003-Cryptomount-luks-allow-multiple-passphrase-attempts.patch create mode 100644 helpers/DATA/grub2-unsigned/0004-Cryptomount-support-plain-dm-crypt.patch create mode 100644 helpers/DATA/grub2-unsigned/0005-Cryptomount-support-for-hyphens-in-UUID.patch create mode 100644 helpers/DATA/grub2-unsigned/0006-Cryptomount-support-for-using-whole-device-as-keyfile.patch create mode 100644 helpers/make-grub2-unsigned diff --git a/helpers/DATA/grub2-unsigned/0001-Cryptomount-support-LUKS-detached-header.patch b/helpers/DATA/grub2-unsigned/0001-Cryptomount-support-LUKS-detached-header.patch new file mode 100644 index 00000000..5d6bd237 --- /dev/null +++ b/helpers/DATA/grub2-unsigned/0001-Cryptomount-support-LUKS-detached-header.patch @@ -0,0 +1,253 @@ +diff --git a/0001-Cryptomount-support-LUKS-detached-header.patch b/0001-Cryptomount-support-LUKS-detached-header.patch +new file mode 100644 +index 00000000000..65943f41b8c +--- /dev/null ++++ b/0001-Cryptomount-support-LUKS-detached-header.patch +@@ -0,0 +1,247 @@ ++From 2008e08c0a511da5d454664363f452a9e26c734f Mon Sep 17 00:00:00 2001 ++From: John Lane <john@lane.uk.net> ++Date: Tue, 23 Jun 2015 11:16:30 +0100 ++Subject: [PATCH 1/7] Cryptomount support LUKS detached header ++ ++--- ++ grub-core/disk/cryptodisk.c | 22 ++++++++++++++++++---- ++ grub-core/disk/geli.c | 7 +++++-- ++ grub-core/disk/luks.c | 45 +++++++++++++++++++++++++++++++++++++-------- ++ include/grub/cryptodisk.h | 5 +++-- ++ 4 files changed, 63 insertions(+), 16 deletions(-) ++ ++diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c ++index bd60a66b3..5230a5a9a 100644 ++--- a/grub-core/disk/cryptodisk.c +++++ b/grub-core/disk/cryptodisk.c ++@@ -41,6 +41,7 @@ static const struct grub_arg_option options[] = ++ /* TRANSLATORS: It's still restricted to cryptodisks only. */ ++ {"all", 'a', 0, N_("Mount all."), 0, 0}, ++ {"boot", 'b', 0, N_("Mount all volumes with `boot' flag set."), 0, 0}, +++ {"header", 'H', 0, N_("Read LUKS header from file"), 0, ARG_TYPE_STRING}, ++ {0, 0, 0, 0, 0, 0} ++ }; ++ ++@@ -809,6 +810,7 @@ grub_util_cryptodisk_get_uuid (grub_disk_t disk) ++ ++ static int check_boot, have_it; ++ static char *search_uuid; +++static grub_file_t hdr; ++ ++ static void ++ cryptodisk_close (grub_cryptodisk_t dev) ++@@ -833,13 +835,13 @@ grub_cryptodisk_scan_device_real (const char *name, grub_disk_t source) ++ ++ FOR_CRYPTODISK_DEVS (cr) ++ { ++- dev = cr->scan (source, search_uuid, check_boot); +++ dev = cr->scan (source, search_uuid, check_boot, hdr); ++ if (grub_errno) ++ return grub_errno; ++ if (!dev) ++ continue; ++ ++- err = cr->recover_key (source, dev); +++ err = cr->recover_key (source, dev, hdr); ++ if (err) ++ { ++ cryptodisk_close (dev); ++@@ -880,7 +882,7 @@ grub_cryptodisk_cheat_mount (const char *sourcedev, const char *cheat) ++ ++ FOR_CRYPTODISK_DEVS (cr) ++ { ++- dev = cr->scan (source, search_uuid, check_boot); +++ dev = cr->scan (source, search_uuid, check_boot,0); ++ if (grub_errno) ++ return grub_errno; ++ if (!dev) ++@@ -934,6 +936,18 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) ++ if (argc < 1 && !state[1].set && !state[2].set) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required"); ++ +++ if (state[3].set) /* LUKS detached header */ +++ { +++ if (state[0].set) /* Cannot use UUID lookup with detached header */ +++ return GRUB_ERR_BAD_ARGUMENT; +++ +++ hdr = grub_file_open (state[3].arg, GRUB_FILE_TYPE_NONE); +++ if (!hdr) +++ return grub_errno; +++ } +++ else +++ hdr = NULL; +++ ++ have_it = 0; ++ if (state[0].set) ++ { ++@@ -1141,7 +1155,7 @@ GRUB_MOD_INIT (cryptodisk) ++ { ++ grub_disk_dev_register (&grub_cryptodisk_dev); ++ cmd = grub_register_extcmd ("cryptomount", grub_cmd_cryptomount, 0, ++- N_("SOURCE|-u UUID|-a|-b"), +++ N_("SOURCE|-u UUID|-a|-b|-H file"), ++ N_("Mount a crypto device."), options); ++ grub_procfs_register ("luks_script", &luks_script); ++ } ++diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c ++index e9d23299a..f4394eb42 100644 ++--- a/grub-core/disk/geli.c +++++ b/grub-core/disk/geli.c ++@@ -52,6 +52,7 @@ ++ #include <grub/dl.h> ++ #include <grub/err.h> ++ #include <grub/disk.h> +++#include <grub/file.h> ++ #include <grub/crypto.h> ++ #include <grub/partition.h> ++ #include <grub/i18n.h> ++@@ -243,7 +244,8 @@ grub_util_get_geli_uuid (const char *dev) ++ ++ static grub_cryptodisk_t ++ configure_ciphers (grub_disk_t disk, const char *check_uuid, ++- int boot_only) +++ int boot_only, +++ grub_file_t hdr __attribute__ ((unused)) ) ++ { ++ grub_cryptodisk_t newdev; ++ struct grub_geli_phdr header; ++@@ -398,7 +400,8 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, ++ } ++ ++ static grub_err_t ++-recover_key (grub_disk_t source, grub_cryptodisk_t dev) +++recover_key (grub_disk_t source, grub_cryptodisk_t dev, +++ grub_file_t hdr __attribute__ ((unused)) ) ++ { ++ grub_size_t keysize; ++ grub_uint8_t digest[GRUB_CRYPTO_MAX_MDLEN]; ++diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c ++index 86c50c612..66e64c0e0 100644 ++--- a/grub-core/disk/luks.c +++++ b/grub-core/disk/luks.c ++@@ -23,6 +23,7 @@ ++ #include <grub/dl.h> ++ #include <grub/err.h> ++ #include <grub/disk.h> +++#include <grub/file.h> ++ #include <grub/crypto.h> ++ #include <grub/partition.h> ++ #include <grub/i18n.h> ++@@ -66,7 +67,7 @@ gcry_err_code_t AF_merge (const gcry_md_spec_t * hash, grub_uint8_t * src, ++ ++ static grub_cryptodisk_t ++ configure_ciphers (grub_disk_t disk, const char *check_uuid, ++- int check_boot) +++ int check_boot, grub_file_t hdr) ++ { ++ grub_cryptodisk_t newdev; ++ const char *iptr; ++@@ -86,11 +87,21 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, ++ int benbi_log = 0; ++ grub_err_t err; ++ +++ err = GRUB_ERR_NONE; +++ ++ if (check_boot) ++ return NULL; ++ ++ /* Read the LUKS header. */ ++- err = grub_disk_read (disk, 0, 0, sizeof (header), &header); +++ if (hdr) +++ { +++ grub_file_seek (hdr, 0); +++ if (grub_file_read (hdr, &header, sizeof (header)) != sizeof (header)) +++ err = GRUB_ERR_READ_ERROR; +++ } +++ else +++ err = grub_disk_read (disk, 0, 0, sizeof (header), &header); +++ ++ if (err) ++ { ++ if (err == GRUB_ERR_OUT_OF_RANGE) ++@@ -304,12 +315,14 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, ++ grub_memcpy (newdev->uuid, uuid, sizeof (newdev->uuid)); ++ newdev->modname = "luks"; ++ COMPILE_TIME_ASSERT (sizeof (newdev->uuid) >= sizeof (uuid)); +++ ++ return newdev; ++ } ++ ++ static grub_err_t ++ luks_recover_key (grub_disk_t source, ++- grub_cryptodisk_t dev) +++ grub_cryptodisk_t dev, +++ grub_file_t hdr) ++ { ++ struct grub_luks_phdr header; ++ grub_size_t keysize; ++@@ -321,8 +334,19 @@ luks_recover_key (grub_disk_t source, ++ grub_err_t err; ++ grub_size_t max_stripes = 1; ++ char *tmp; +++ grub_uint32_t sector; +++ +++ err = GRUB_ERR_NONE; +++ +++ if (hdr) +++ { +++ grub_file_seek (hdr, 0); +++ if (grub_file_read (hdr, &header, sizeof (header)) != sizeof (header)) +++ err = GRUB_ERR_READ_ERROR; +++ } +++ else +++ err = grub_disk_read (source, 0, 0, sizeof (header), &header); ++ ++- err = grub_disk_read (source, 0, 0, sizeof (header), &header); ++ if (err) ++ return err; ++ ++@@ -391,13 +415,18 @@ luks_recover_key (grub_disk_t source, ++ return grub_crypto_gcry_error (gcry_err); ++ } ++ +++ sector = grub_be_to_cpu32 (header.keyblock[i].keyMaterialOffset); ++ length = (keysize * grub_be_to_cpu32 (header.keyblock[i].stripes)); ++ ++ /* Read and decrypt the key material from the disk. */ ++- err = grub_disk_read (source, ++- grub_be_to_cpu32 (header.keyblock ++- [i].keyMaterialOffset), 0, ++- length, split_key); +++ if (hdr) +++ { +++ grub_file_seek (hdr, sector * 512); +++ if (grub_file_read (hdr, split_key, length) != (grub_ssize_t)length) +++ err = GRUB_ERR_READ_ERROR; +++ } +++ else +++ err = grub_disk_read (source, sector, 0, length, split_key); ++ if (err) ++ { ++ grub_free (split_key); ++diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h ++index 32f564ae0..4e6e89a93 100644 ++--- a/include/grub/cryptodisk.h +++++ b/include/grub/cryptodisk.h ++@@ -20,6 +20,7 @@ ++ #define GRUB_CRYPTODISK_HEADER 1 ++ ++ #include <grub/disk.h> +++#include <grub/file.h> ++ #include <grub/crypto.h> ++ #include <grub/list.h> ++ #ifdef GRUB_UTIL ++@@ -107,8 +108,8 @@ struct grub_cryptodisk_dev ++ struct grub_cryptodisk_dev **prev; ++ ++ grub_cryptodisk_t (*scan) (grub_disk_t disk, const char *check_uuid, ++- int boot_only); ++- grub_err_t (*recover_key) (grub_disk_t disk, grub_cryptodisk_t dev); +++ int boot_only, grub_file_t hdr); +++ grub_err_t (*recover_key) (grub_disk_t disk, grub_cryptodisk_t dev, grub_file_t hdr); ++ }; ++ typedef struct grub_cryptodisk_dev *grub_cryptodisk_dev_t; ++ ++-- ++2.16.2 ++ diff --git a/helpers/DATA/grub2-unsigned/0002-Cryptomount-support-key-files.patch b/helpers/DATA/grub2-unsigned/0002-Cryptomount-support-key-files.patch new file mode 100644 index 00000000..31063013 --- /dev/null +++ b/helpers/DATA/grub2-unsigned/0002-Cryptomount-support-key-files.patch @@ -0,0 +1,211 @@ +diff --git a/0002-Cryptomount-support-key-files.patch b/0002-Cryptomount-support-key-files.patch +new file mode 100644 +index 00000000000..43af5ff3cbf +--- /dev/null ++++ b/0002-Cryptomount-support-key-files.patch +@@ -0,0 +1,205 @@ ++From df3aa34cc68b128c5441ee25ef092e6c2c87392e Mon Sep 17 00:00:00 2001 ++From: John Lane <john@lane.uk.net> ++Date: Fri, 26 Jun 2015 13:37:10 +0100 ++Subject: [PATCH 2/7] Cryptomount support key files ++ ++--- ++ grub-core/disk/cryptodisk.c | 46 ++++++++++++++++++++++++++++++++++++++++++++- ++ grub-core/disk/geli.c | 4 +++- ++ grub-core/disk/luks.c | 44 +++++++++++++++++++++++++++++-------------- ++ include/grub/cryptodisk.h | 5 ++++- ++ 4 files changed, 82 insertions(+), 17 deletions(-) ++ ++diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c ++index 5230a5a9a..5261af547 100644 ++--- a/grub-core/disk/cryptodisk.c +++++ b/grub-core/disk/cryptodisk.c ++@@ -42,6 +42,9 @@ static const struct grub_arg_option options[] = ++ {"all", 'a', 0, N_("Mount all."), 0, 0}, ++ {"boot", 'b', 0, N_("Mount all volumes with `boot' flag set."), 0, 0}, ++ {"header", 'H', 0, N_("Read LUKS header from file"), 0, ARG_TYPE_STRING}, +++ {"keyfile", 'k', 0, N_("Key file"), 0, ARG_TYPE_STRING}, +++ {"keyfile-offset", 'O', 0, N_("Key file offset (bytes)"), 0, ARG_TYPE_INT}, +++ {"keyfile-size", 'S', 0, N_("Key file data size (bytes)"), 0, ARG_TYPE_INT}, ++ {0, 0, 0, 0, 0, 0} ++ }; ++ ++@@ -811,6 +814,8 @@ grub_util_cryptodisk_get_uuid (grub_disk_t disk) ++ static int check_boot, have_it; ++ static char *search_uuid; ++ static grub_file_t hdr; +++static grub_uint8_t *key, keyfile_buffer[GRUB_CRYPTODISK_MAX_KEYFILE_SIZE]; +++static grub_size_t keyfile_size; ++ ++ static void ++ cryptodisk_close (grub_cryptodisk_t dev) ++@@ -841,7 +846,7 @@ grub_cryptodisk_scan_device_real (const char *name, grub_disk_t source) ++ if (!dev) ++ continue; ++ ++- err = cr->recover_key (source, dev, hdr); +++ err = cr->recover_key (source, dev, hdr, key, keyfile_size); ++ if (err) ++ { ++ cryptodisk_close (dev); ++@@ -949,6 +954,45 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) ++ hdr = NULL; ++ ++ have_it = 0; +++ key = NULL; +++ +++ if (state[4].set) /* Key file; fails back to passphrase entry */ +++ { +++ grub_file_t keyfile; +++ int keyfile_offset; +++ grub_size_t requested_keyfile_size; +++ +++ requested_keyfile_size = state[6].set ? grub_strtoul(state[6].arg, 0, 0) : 0; +++ +++ if (requested_keyfile_size > GRUB_CRYPTODISK_MAX_KEYFILE_SIZE) +++ grub_printf (N_("Key file size exceeds maximum (%llu)\n"), \ +++ (unsigned long long) GRUB_CRYPTODISK_MAX_KEYFILE_SIZE); +++ else +++ { +++ keyfile_offset = state[5].set ? grub_strtoul (state[5].arg, 0, 0) : 0; +++ keyfile_size = requested_keyfile_size ? requested_keyfile_size : \ +++ GRUB_CRYPTODISK_MAX_KEYFILE_SIZE; +++ +++ keyfile = grub_file_open (state[4].arg, GRUB_FILE_TYPE_NONE); +++ if (!keyfile) +++ grub_printf (N_("Unable to open key file %s\n"), state[4].arg); +++ else if (grub_file_seek (keyfile, keyfile_offset) == (grub_off_t)-1) +++ grub_printf (N_("Unable to seek to offset %d in key file\n"), keyfile_offset); +++ else +++ { +++ keyfile_size = grub_file_read (keyfile, keyfile_buffer, keyfile_size); +++ if (keyfile_size == (grub_size_t)-1) +++ grub_printf (N_("Error reading key file\n")); +++ else if (requested_keyfile_size && (keyfile_size != requested_keyfile_size)) +++ grub_printf (N_("Cannot read %llu bytes for key file (read %llu bytes)\n"), +++ (unsigned long long) requested_keyfile_size, +++ (unsigned long long) keyfile_size); +++ else +++ key = keyfile_buffer; +++ } +++ } +++ } +++ ++ if (state[0].set) ++ { ++ grub_cryptodisk_t dev; ++diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c ++index f4394eb42..da6aa6a63 100644 ++--- a/grub-core/disk/geli.c +++++ b/grub-core/disk/geli.c ++@@ -401,7 +401,9 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, ++ ++ static grub_err_t ++ recover_key (grub_disk_t source, grub_cryptodisk_t dev, ++- grub_file_t hdr __attribute__ ((unused)) ) +++ grub_file_t hdr __attribute__ ((unused)), +++ grub_uint8_t *key __attribute__ ((unused)), +++ grub_size_t keyfile_size __attribute__ ((unused)) ) ++ { ++ grub_size_t keysize; ++ grub_uint8_t digest[GRUB_CRYPTO_MAX_MDLEN]; ++diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c ++index 66e64c0e0..588236888 100644 ++--- a/grub-core/disk/luks.c +++++ b/grub-core/disk/luks.c ++@@ -322,12 +322,16 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, ++ static grub_err_t ++ luks_recover_key (grub_disk_t source, ++ grub_cryptodisk_t dev, ++- grub_file_t hdr) +++ grub_file_t hdr, +++ grub_uint8_t *keyfile_bytes, +++ grub_size_t keyfile_bytes_size) ++ { ++ struct grub_luks_phdr header; ++ grub_size_t keysize; ++ grub_uint8_t *split_key = NULL; ++- char passphrase[MAX_PASSPHRASE] = ""; +++ char interactive_passphrase[MAX_PASSPHRASE] = ""; +++ grub_uint8_t *passphrase; +++ grub_size_t passphrase_length; ++ grub_uint8_t candidate_digest[sizeof (header.mkDigest)]; ++ unsigned i; ++ grub_size_t length; ++@@ -364,18 +368,30 @@ luks_recover_key (grub_disk_t source, ++ if (!split_key) ++ return grub_errno; ++ ++- /* Get the passphrase from the user. */ ++- tmp = NULL; ++- if (source->partition) ++- tmp = grub_partition_get_name (source->partition); ++- grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name, ++- source->partition ? "," : "", tmp ? : "", ++- dev->uuid); ++- grub_free (tmp); ++- if (!grub_password_get (passphrase, MAX_PASSPHRASE)) +++ if (keyfile_bytes) ++ { ++- grub_free (split_key); ++- return grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied"); +++ /* Use bytestring from key file as passphrase */ +++ passphrase = keyfile_bytes; +++ passphrase_length = keyfile_bytes_size; +++ } +++ else +++ { +++ /* Get the passphrase from the user. */ +++ tmp = NULL; +++ if (source->partition) +++ tmp = grub_partition_get_name (source->partition); +++ grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name, +++ source->partition ? "," : "", tmp ? : "", dev->uuid); +++ grub_free (tmp); +++ if (!grub_password_get (interactive_passphrase, MAX_PASSPHRASE)) +++ { +++ grub_free (split_key); +++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied"); +++ } +++ +++ passphrase = (grub_uint8_t *)interactive_passphrase; +++ passphrase_length = grub_strlen (interactive_passphrase); +++ ++ } ++ ++ /* Try to recover master key from each active keyslot. */ ++@@ -393,7 +409,7 @@ luks_recover_key (grub_disk_t source, ++ ++ /* Calculate the PBKDF2 of the user supplied passphrase. */ ++ gcry_err = grub_crypto_pbkdf2 (dev->hash, (grub_uint8_t *) passphrase, ++- grub_strlen (passphrase), +++ passphrase_length, ++ header.keyblock[i].passwordSalt, ++ sizeof (header.keyblock[i].passwordSalt), ++ grub_be_to_cpu32 (header.keyblock[i]. ++diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h ++index 4e6e89a93..67f6b0b59 100644 ++--- a/include/grub/cryptodisk.h +++++ b/include/grub/cryptodisk.h ++@@ -55,6 +55,8 @@ typedef enum ++ #define GRUB_CRYPTODISK_GF_BYTES (1U << GRUB_CRYPTODISK_GF_LOG_BYTES) ++ #define GRUB_CRYPTODISK_MAX_KEYLEN 128 ++ +++#define GRUB_CRYPTODISK_MAX_KEYFILE_SIZE 8192 +++ ++ struct grub_cryptodisk; ++ ++ typedef gcry_err_code_t ++@@ -109,7 +111,8 @@ struct grub_cryptodisk_dev ++ ++ grub_cryptodisk_t (*scan) (grub_disk_t disk, const char *check_uuid, ++ int boot_only, grub_file_t hdr); ++- grub_err_t (*recover_key) (grub_disk_t disk, grub_cryptodisk_t dev, grub_file_t hdr); +++ grub_err_t (*recover_key) (grub_disk_t disk, grub_cryptodisk_t dev, +++ grub_file_t hdr, grub_uint8_t *key, grub_size_t keyfile_size); ++ }; ++ typedef struct grub_cryptodisk_dev *grub_cryptodisk_dev_t; ++ ++-- ++2.16.2 ++ diff --git a/helpers/DATA/grub2-unsigned/0003-Cryptomount-luks-allow-multiple-passphrase-attempts.patch b/helpers/DATA/grub2-unsigned/0003-Cryptomount-luks-allow-multiple-passphrase-attempts.patch new file mode 100644 index 00000000..f6df2745 --- /dev/null +++ b/helpers/DATA/grub2-unsigned/0003-Cryptomount-luks-allow-multiple-passphrase-attempts.patch @@ -0,0 +1,335 @@ +diff --git a/0003-Cryptomount-luks-allow-multiple-passphrase-attempts.patch b/0003-Cryptomount-luks-allow-multiple-passphrase-attempts.patch +new file mode 100644 +index 00000000000..19ffed89ca8 +--- /dev/null ++++ b/0003-Cryptomount-luks-allow-multiple-passphrase-attempts.patch +@@ -0,0 +1,329 @@ ++From d055c1e314fa37957f169e08bea9d19c4417ed21 Mon Sep 17 00:00:00 2001 ++From: John Lane <john@lane.uk.net> ++Date: Fri, 26 Jun 2015 13:49:58 +0100 ++Subject: [PATCH 3/7] cryptomount luks allow multiple passphrase attempts ++ ++--- ++ grub-core/disk/luks.c | 278 ++++++++++++++++++++++++++------------------------ ++ 1 file changed, 143 insertions(+), 135 deletions(-) ++ ++diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c ++index 588236888..11e437edb 100644 ++--- a/grub-core/disk/luks.c +++++ b/grub-core/disk/luks.c ++@@ -321,10 +321,10 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, ++ ++ static grub_err_t ++ luks_recover_key (grub_disk_t source, ++- grub_cryptodisk_t dev, ++- grub_file_t hdr, ++- grub_uint8_t *keyfile_bytes, ++- grub_size_t keyfile_bytes_size) +++ grub_cryptodisk_t dev, +++ grub_file_t hdr, +++ grub_uint8_t *keyfile_bytes, +++ grub_size_t keyfile_bytes_size) ++ { ++ struct grub_luks_phdr header; ++ grub_size_t keysize; ++@@ -339,6 +339,7 @@ luks_recover_key (grub_disk_t source, ++ grub_size_t max_stripes = 1; ++ char *tmp; ++ grub_uint32_t sector; +++ unsigned attempts = 2; ++ ++ err = GRUB_ERR_NONE; ++ ++@@ -361,151 +362,158 @@ luks_recover_key (grub_disk_t source, ++ ++ for (i = 0; i < ARRAY_SIZE (header.keyblock); i++) ++ if (grub_be_to_cpu32 (header.keyblock[i].active) == LUKS_KEY_ENABLED ++- && grub_be_to_cpu32 (header.keyblock[i].stripes) > max_stripes) +++ && grub_be_to_cpu32 (header.keyblock[i].stripes) > max_stripes) ++ max_stripes = grub_be_to_cpu32 (header.keyblock[i].stripes); ++ ++ split_key = grub_malloc (keysize * max_stripes); ++ if (!split_key) ++ return grub_errno; ++ ++- if (keyfile_bytes) +++ while (attempts) ++ { ++- /* Use bytestring from key file as passphrase */ ++- passphrase = keyfile_bytes; ++- passphrase_length = keyfile_bytes_size; ++- } ++- else ++- { ++- /* Get the passphrase from the user. */ ++- tmp = NULL; ++- if (source->partition) ++- tmp = grub_partition_get_name (source->partition); ++- grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name, ++- source->partition ? "," : "", tmp ? : "", dev->uuid); ++- grub_free (tmp); ++- if (!grub_password_get (interactive_passphrase, MAX_PASSPHRASE)) +++ if (keyfile_bytes) ++ { ++- grub_free (split_key); ++- return grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied"); ++- } ++- ++- passphrase = (grub_uint8_t *)interactive_passphrase; ++- passphrase_length = grub_strlen (interactive_passphrase); ++- ++- } ++- ++- /* Try to recover master key from each active keyslot. */ ++- for (i = 0; i < ARRAY_SIZE (header.keyblock); i++) ++- { ++- gcry_err_code_t gcry_err; ++- grub_uint8_t candidate_key[GRUB_CRYPTODISK_MAX_KEYLEN]; ++- grub_uint8_t digest[GRUB_CRYPTODISK_MAX_KEYLEN]; ++- ++- /* Check if keyslot is enabled. */ ++- if (grub_be_to_cpu32 (header.keyblock[i].active) != LUKS_KEY_ENABLED) ++- continue; ++- ++- grub_dprintf ("luks", "Trying keyslot %d\n", i); ++- ++- /* Calculate the PBKDF2 of the user supplied passphrase. */ ++- gcry_err = grub_crypto_pbkdf2 (dev->hash, (grub_uint8_t *) passphrase, ++- passphrase_length, ++- header.keyblock[i].passwordSalt, ++- sizeof (header.keyblock[i].passwordSalt), ++- grub_be_to_cpu32 (header.keyblock[i]. ++- passwordIterations), ++- digest, keysize); ++- ++- if (gcry_err) ++- { ++- grub_free (split_key); ++- return grub_crypto_gcry_error (gcry_err); ++- } ++- ++- grub_dprintf ("luks", "PBKDF2 done\n"); ++- ++- gcry_err = grub_cryptodisk_setkey (dev, digest, keysize); ++- if (gcry_err) ++- { ++- grub_free (split_key); ++- return grub_crypto_gcry_error (gcry_err); ++- } ++- ++- sector = grub_be_to_cpu32 (header.keyblock[i].keyMaterialOffset); ++- length = (keysize * grub_be_to_cpu32 (header.keyblock[i].stripes)); ++- ++- /* Read and decrypt the key material from the disk. */ ++- if (hdr) ++- { ++- grub_file_seek (hdr, sector * 512); ++- if (grub_file_read (hdr, split_key, length) != (grub_ssize_t)length) ++- err = GRUB_ERR_READ_ERROR; +++ /* Use bytestring from key file as passphrase */ +++ passphrase = keyfile_bytes; +++ passphrase_length = keyfile_bytes_size; +++ keyfile_bytes = NULL; /* use it only once */ ++ } ++ else ++- err = grub_disk_read (source, sector, 0, length, split_key); ++- if (err) ++- { ++- grub_free (split_key); ++- return err; ++- } ++- ++- gcry_err = grub_cryptodisk_decrypt (dev, split_key, length, 0); ++- if (gcry_err) ++- { ++- grub_free (split_key); ++- return grub_crypto_gcry_error (gcry_err); ++- } ++- ++- /* Merge the decrypted key material to get the candidate master key. */ ++- gcry_err = AF_merge (dev->hash, split_key, candidate_key, keysize, ++- grub_be_to_cpu32 (header.keyblock[i].stripes)); ++- if (gcry_err) ++- { ++- grub_free (split_key); ++- return grub_crypto_gcry_error (gcry_err); ++- } ++- ++- grub_dprintf ("luks", "candidate key recovered\n"); ++- ++- /* Calculate the PBKDF2 of the candidate master key. */ ++- gcry_err = grub_crypto_pbkdf2 (dev->hash, candidate_key, ++- grub_be_to_cpu32 (header.keyBytes), ++- header.mkDigestSalt, ++- sizeof (header.mkDigestSalt), ++- grub_be_to_cpu32 ++- (header.mkDigestIterations), ++- candidate_digest, ++- sizeof (candidate_digest)); ++- if (gcry_err) ++- { ++- grub_free (split_key); ++- return grub_crypto_gcry_error (gcry_err); ++- } ++- ++- /* Compare the calculated PBKDF2 to the digest stored ++- in the header to see if it's correct. */ ++- if (grub_memcmp (candidate_digest, header.mkDigest, ++- sizeof (header.mkDigest)) != 0) ++- { ++- grub_dprintf ("luks", "bad digest\n"); ++- continue; ++- } +++ { +++ /* Get the passphrase from the user. */ +++ tmp = NULL; +++ if (source->partition) +++ tmp = grub_partition_get_name (source->partition); +++ grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name, +++ source->partition ? "," : "", tmp ? : "", dev->uuid); +++ grub_free (tmp); +++ if (!grub_password_get (interactive_passphrase, MAX_PASSPHRASE)) +++ { +++ grub_free (split_key); +++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied"); +++ } +++ +++ passphrase = (grub_uint8_t *)interactive_passphrase; +++ passphrase_length = grub_strlen (interactive_passphrase); ++ ++- /* TRANSLATORS: It's a cryptographic key slot: one element of an array ++- where each element is either empty or holds a key. */ ++- grub_printf_ (N_("Slot %d opened\n"), i); +++ } ++ ++- /* Set the master key. */ ++- gcry_err = grub_cryptodisk_setkey (dev, candidate_key, keysize); ++- if (gcry_err) ++- { ++- grub_free (split_key); ++- return grub_crypto_gcry_error (gcry_err); ++- } +++ /* Try to recover master key from each active keyslot. */ +++ for (i = 0; i < ARRAY_SIZE (header.keyblock); i++) +++ { +++ gcry_err_code_t gcry_err; +++ grub_uint8_t candidate_key[GRUB_CRYPTODISK_MAX_KEYLEN]; +++ grub_uint8_t digest[GRUB_CRYPTODISK_MAX_KEYLEN]; +++ +++ /* Check if keyslot is enabled. */ +++ if (grub_be_to_cpu32 (header.keyblock[i].active) != LUKS_KEY_ENABLED) +++ continue; +++ +++ grub_dprintf ("luks", "Trying keyslot %d\n", i); +++ +++ /* Calculate the PBKDF2 of the user supplied passphrase. */ +++ gcry_err = grub_crypto_pbkdf2 (dev->hash, (grub_uint8_t *) passphrase, +++ passphrase_length, +++ header.keyblock[i].passwordSalt, +++ sizeof (header.keyblock[i].passwordSalt), +++ grub_be_to_cpu32 (header.keyblock[i]. +++ passwordIterations), +++ digest, keysize); +++ +++ if (gcry_err) +++ { +++ grub_free (split_key); +++ return grub_crypto_gcry_error (gcry_err); +++ } +++ +++ grub_dprintf ("luks", "PBKDF2 done\n"); +++ +++ gcry_err = grub_cryptodisk_setkey (dev, digest, keysize); +++ if (gcry_err) +++ { +++ grub_free (split_key); +++ return grub_crypto_gcry_error (gcry_err); +++ } +++ +++ sector = grub_be_to_cpu32 (header.keyblock[i].keyMaterialOffset); +++ length = (keysize * grub_be_to_cpu32 (header.keyblock[i].stripes)); +++ +++ /* Read and decrypt the key material from the disk. */ +++ if (hdr) +++ { +++ grub_file_seek (hdr, sector * 512); +++ if (grub_file_read (hdr, split_key, length) != (grub_ssize_t)length) +++ err = GRUB_ERR_READ_ERROR; +++ } +++ else +++ err = grub_disk_read (source, sector, 0, length, split_key); +++ if (err) +++ { +++ grub_free (split_key); +++ return err; +++ } +++ +++ gcry_err = grub_cryptodisk_decrypt (dev, split_key, length, 0); +++ if (gcry_err) +++ { +++ grub_free (split_key); +++ return grub_crypto_gcry_error (gcry_err); +++ } +++ +++ /* Merge the decrypted key material to get the candidate master key. */ +++ gcry_err = AF_merge (dev->hash, split_key, candidate_key, keysize, +++ grub_be_to_cpu32 (header.keyblock[i].stripes)); +++ if (gcry_err) +++ { +++ grub_free (split_key); +++ return grub_crypto_gcry_error (gcry_err); +++ } +++ +++ grub_dprintf ("luks", "candidate key recovered\n"); +++ +++ /* Calculate the PBKDF2 of the candidate master key. */ +++ gcry_err = grub_crypto_pbkdf2 (dev->hash, candidate_key, +++ grub_be_to_cpu32 (header.keyBytes), +++ header.mkDigestSalt, +++ sizeof (header.mkDigestSalt), +++ grub_be_to_cpu32 +++ (header.mkDigestIterations), +++ candidate_digest, +++ sizeof (candidate_digest)); +++ if (gcry_err) +++ { +++ grub_free (split_key); +++ return grub_crypto_gcry_error (gcry_err); +++ } +++ +++ /* Compare the calculated PBKDF2 to the digest stored +++ in the header to see if it's correct. */ +++ if (grub_memcmp (candidate_digest, header.mkDigest, +++ sizeof (header.mkDigest)) != 0) +++ { +++ grub_dprintf ("luks", "bad digest\n"); +++ continue; +++ } +++ +++ /* TRANSLATORS: It's a cryptographic key slot: one element of an array +++ where each element is either empty or holds a key. */ +++ grub_printf_ (N_("Slot %d opened\n"), i); +++ +++ /* Set the master key. */ +++ gcry_err = grub_cryptodisk_setkey (dev, candidate_key, keysize); +++ if (gcry_err) +++ { +++ grub_free (split_key); +++ return grub_crypto_gcry_error (gcry_err); +++ } ++ ++- grub_free (split_key); +++ grub_free (split_key); ++ ++- return GRUB_ERR_NONE; +++ return GRUB_ERR_NONE; +++ } +++ grub_printf_ (N_("Failed to decrypt master key.\n")); +++ if (--attempts) grub_printf_ (N_("%u attempt%s remaining.\n"), attempts, +++ (attempts==1) ? "" : "s"); ++ } ++ ++ grub_free (split_key); ++-- ++2.16.2 ++ diff --git a/helpers/DATA/grub2-unsigned/0004-Cryptomount-support-plain-dm-crypt.patch b/helpers/DATA/grub2-unsigned/0004-Cryptomount-support-plain-dm-crypt.patch new file mode 100644 index 00000000..325186e0 --- /dev/null +++ b/helpers/DATA/grub2-unsigned/0004-Cryptomount-support-plain-dm-crypt.patch @@ -0,0 +1,650 @@ +diff --git a/0004-Cryptomount-support-plain-dm-crypt.patch b/0004-Cryptomount-support-plain-dm-crypt.patch +new file mode 100644 +index 00000000000..34c10d7216b +--- /dev/null ++++ b/0004-Cryptomount-support-plain-dm-crypt.patch +@@ -0,0 +1,644 @@ ++From a8f9e3dcece89c179e89414abe89985c7ab1e03f Mon Sep 17 00:00:00 2001 ++From: John Lane <john@lane.uk.net> ++Date: Fri, 26 Jun 2015 22:09:52 +0100 ++Subject: [PATCH 4/7] Cryptomount support plain dm-crypt ++ ++Patch modified to take into account a change to context ++brought about by c93d3e694713b8230fa2cf88414fabe005b56782 ++ ++grub-core/disk/cryptodisk.c ++142c142 ++< if (disklast) ++--- ++> ++--- ++ grub-core/disk/cryptodisk.c | 298 +++++++++++++++++++++++++++++++++++++++++++- ++ grub-core/disk/luks.c | 195 +---------------------------- ++ include/grub/cryptodisk.h | 8 ++ ++ 3 files changed, 310 insertions(+), 191 deletions(-) ++ ++diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c ++index 5261af547..7f656f75c 100644 ++--- a/grub-core/disk/cryptodisk.c +++++ b/grub-core/disk/cryptodisk.c ++@@ -45,6 +45,12 @@ static const struct grub_arg_option options[] = ++ {"keyfile", 'k', 0, N_("Key file"), 0, ARG_TYPE_STRING}, ++ {"keyfile-offset", 'O', 0, N_("Key file offset (bytes)"), 0, ARG_TYPE_INT}, ++ {"keyfile-size", 'S', 0, N_("Key file data size (bytes)"), 0, ARG_TYPE_INT}, +++ {"plain", 'p', 0, N_("Plain (no LUKS header)"), 0, ARG_TYPE_NONE}, +++ {"cipher", 'c', 0, N_("Plain mode cipher"), 0, ARG_TYPE_STRING}, +++ {"digest", 'd', 0, N_("Plain mode passphrase digest (hash)"), 0, ARG_TYPE_STRING}, +++ {"offset", 'o', 0, N_("Plain mode data sector offset"), 0, ARG_TYPE_INT}, +++ {"size", 's', 0, N_("Size of raw device (sectors, defaults to whole device)"), 0, ARG_TYPE_INT}, +++ {"key-size", 'K', 0, N_("Set key size (bits)"), 0, ARG_TYPE_INT}, ++ {0, 0, 0, 0, 0, 0} ++ }; ++ ++@@ -933,6 +939,48 @@ grub_cryptodisk_scan_device (const char *name, ++ return have_it && search_uuid ? 1 : 0; ++ } ++ +++/* Hashes a passphrase into a key and stores it with cipher. */ +++static gcry_err_code_t +++set_passphrase (grub_cryptodisk_t dev, grub_size_t keysize, const char *passphrase) +++{ +++ grub_uint8_t derived_hash[GRUB_CRYPTODISK_MAX_KEYLEN * 2], *dh = derived_hash; +++ char *p; +++ unsigned int round, i; +++ unsigned int len, size; +++ +++ /* Need no passphrase if there's no key */ +++ if (keysize == 0) +++ return GPG_ERR_INV_KEYLEN; +++ +++ /* Hack to support the "none" hash */ +++ if (dev->hash) +++ len = dev->hash->mdlen; +++ else +++ len = grub_strlen (passphrase); +++ +++ if (keysize > GRUB_CRYPTODISK_MAX_KEYLEN || len > GRUB_CRYPTODISK_MAX_KEYLEN) +++ return GPG_ERR_INV_KEYLEN; +++ +++ p = grub_malloc (grub_strlen (passphrase) + 2 + keysize / len); +++ if (!p) +++ return grub_errno; +++ +++ for (round = 0, size = keysize; size; round++, dh += len, size -= len) +++ { +++ for (i = 0; i < round; i++) +++ p[i] = 'A'; +++ +++ grub_strcpy (p + i, passphrase); +++ +++ if (len > size) +++ len = size; +++ +++ grub_crypto_hash (dev->hash, dh, p, grub_strlen (p)); +++ } +++ +++ return grub_cryptodisk_setkey (dev, derived_hash, keysize); +++} +++ ++ static grub_err_t ++ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) ++ { ++@@ -1060,7 +1108,63 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) ++ return GRUB_ERR_NONE; ++ } ++ ++- err = grub_cryptodisk_scan_device_real (diskname, disk); +++ if (state[7].set) /* Plain mode */ +++ { +++ char *cipher; +++ char *mode; +++ char *digest; +++ int offset, size, key_size; +++ +++ cipher = grub_strdup (state[8].set ? state[8].arg : GRUB_CRYPTODISK_PLAIN_CIPHER); +++ digest = grub_strdup (state[9].set ? state[9].arg : GRUB_CRYPTODISK_PLAIN_DIGEST); +++ offset = state[10].set ? grub_strtoul (state[10].arg, 0, 0) : 0; +++ size = state[11].set ? grub_strtoul (state[11].arg, 0, 0) : 0; +++ key_size = ( state[12].set ? grub_strtoul (state[12].arg, 0, 0) \ +++ : GRUB_CRYPTODISK_PLAIN_KEYSIZE ) / 8; +++ +++ /* no strtok, do it manually */ +++ mode = grub_strchr(cipher,'-'); +++ if (!mode) +++ return GRUB_ERR_BAD_ARGUMENT; +++ else +++ *mode++ = 0; +++ +++ dev = grub_cryptodisk_create (disk, NULL, cipher, mode, digest); +++ +++ dev->offset = offset; +++ if (size) dev->total_length = size; +++ +++ if (key) +++ { +++ err = grub_cryptodisk_setkey (dev, key, key_size); +++ if (err) +++ return err; +++ } +++ else +++ { +++ char passphrase[GRUB_CRYPTODISK_MAX_PASSPHRASE] = ""; +++ +++ grub_printf_ (N_("Enter passphrase for %s: "), diskname); +++ if (!grub_password_get (passphrase, GRUB_CRYPTODISK_MAX_PASSPHRASE)) +++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied"); +++ +++ err = set_passphrase (dev, key_size, passphrase); +++ if (err) +++ { +++ grub_crypto_cipher_close (dev->cipher); +++ return err; +++ } +++ } +++ +++ grub_cryptodisk_insert (dev, diskname, disk); +++ +++ grub_free (cipher); +++ grub_free (digest); +++ +++ err = GRUB_ERR_NONE; +++ } +++ else +++ err = grub_cryptodisk_scan_device_real (diskname, disk); ++ ++ grub_disk_close (disk); ++ if (disklast) ++@@ -1193,13 +1297,203 @@ struct grub_procfs_entry luks_script = ++ .get_contents = luks_script_get ++ }; ++ +++grub_cryptodisk_t +++grub_cryptodisk_create (grub_disk_t disk, char *uuid, +++ char *ciphername, char *ciphermode, char *hashspec) +++{ +++ grub_cryptodisk_t newdev; +++ char *cipheriv = NULL; +++ grub_crypto_cipher_handle_t cipher = NULL, secondary_cipher = NULL; +++ grub_crypto_cipher_handle_t essiv_cipher = NULL; +++ const gcry_md_spec_t *hash = NULL, *essiv_hash = NULL; +++ const struct gcry_cipher_spec *ciph; +++ grub_cryptodisk_mode_t mode; +++ grub_cryptodisk_mode_iv_t mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN64; +++ int benbi_log = 0; +++ +++ if (!uuid) +++ uuid = (char*)"00000000000000000000000000000000"; +++ +++ ciph = grub_crypto_lookup_cipher_by_name (ciphername); +++ if (!ciph) +++ { +++ grub_error (GRUB_ERR_FILE_NOT_FOUND, "Cipher %s isn't available", +++ ciphername); +++ return NULL; +++ } +++ +++ /* Configure the cipher used for the bulk data. */ +++ cipher = grub_crypto_cipher_open (ciph); +++ if (!cipher) +++ return NULL; +++ +++ /* Configure the cipher mode. */ +++ if (grub_strcmp (ciphermode, "ecb") == 0) +++ { +++ mode = GRUB_CRYPTODISK_MODE_ECB; +++ mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN; +++ cipheriv = NULL; +++ } +++ else if (grub_strcmp (ciphermode, "plain") == 0) +++ { +++ mode = GRUB_CRYPTODISK_MODE_CBC; +++ mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN; +++ cipheriv = NULL; +++ } +++ else if (grub_memcmp (ciphermode, "cbc-", sizeof ("cbc-") - 1) == 0) +++ { +++ mode = GRUB_CRYPTODISK_MODE_CBC; +++ cipheriv = ciphermode + sizeof ("cbc-") - 1; +++ } +++ else if (grub_memcmp (ciphermode, "pcbc-", sizeof ("pcbc-") - 1) == 0) +++ { +++ mode = GRUB_CRYPTODISK_MODE_PCBC; +++ cipheriv = ciphermode + sizeof ("pcbc-") - 1; +++ } +++ else if (grub_memcmp (ciphermode, "xts-", sizeof ("xts-") - 1) == 0) +++ { +++ mode = GRUB_CRYPTODISK_MODE_XTS; +++ cipheriv = ciphermode + sizeof ("xts-") - 1; +++ secondary_cipher = grub_crypto_cipher_open (ciph); +++ if (!secondary_cipher) +++ { +++ grub_crypto_cipher_close (cipher); +++ return NULL; +++ } +++ if (cipher->cipher->blocksize != GRUB_CRYPTODISK_GF_BYTES) +++ { +++ grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported XTS block size: %d", +++ cipher->cipher->blocksize); +++ grub_crypto_cipher_close (cipher); +++ grub_crypto_cipher_close (secondary_cipher); +++ return NULL; +++ } +++ if (secondary_cipher->cipher->blocksize != GRUB_CRYPTODISK_GF_BYTES) +++ { +++ grub_crypto_cipher_close (cipher); +++ grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported XTS block size: %d", +++ secondary_cipher->cipher->blocksize); +++ grub_crypto_cipher_close (secondary_cipher); +++ return NULL; +++ } +++ } +++ else if (grub_memcmp (ciphermode, "lrw-", sizeof ("lrw-") - 1) == 0) +++ { +++ mode = GRUB_CRYPTODISK_MODE_LRW; +++ cipheriv = ciphermode + sizeof ("lrw-") - 1; +++ if (cipher->cipher->blocksize != GRUB_CRYPTODISK_GF_BYTES) +++ { +++ grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported LRW block size: %d", +++ cipher->cipher->blocksize); +++ grub_crypto_cipher_close (cipher); +++ return NULL; +++ } +++ } +++ else +++ { +++ grub_crypto_cipher_close (cipher); +++ grub_error (GRUB_ERR_BAD_ARGUMENT, "Unknown cipher mode: %s", +++ ciphermode); +++ return NULL; +++ } +++ +++ if (cipheriv == NULL); +++ else if (grub_memcmp (cipheriv, "plain", sizeof ("plain") - 1) == 0) +++ mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN; +++ else if (grub_memcmp (cipheriv, "plain64", sizeof ("plain64") - 1) == 0) +++ mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN64; +++ else if (grub_memcmp (cipheriv, "benbi", sizeof ("benbi") - 1) == 0) +++ { +++ if (cipher->cipher->blocksize & (cipher->cipher->blocksize - 1) +++ || cipher->cipher->blocksize == 0) +++ grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported benbi blocksize: %d", +++ cipher->cipher->blocksize); +++ /* FIXME should we return an error here? */ +++ for (benbi_log = 0; +++ (cipher->cipher->blocksize << benbi_log) < GRUB_DISK_SECTOR_SIZE; +++ benbi_log++); +++ mode_iv = GRUB_CRYPTODISK_MODE_IV_BENBI; +++ } +++ else if (grub_memcmp (cipheriv, "null", sizeof ("null") - 1) == 0) +++ mode_iv = GRUB_CRYPTODISK_MODE_IV_NULL; +++ else if (grub_memcmp (cipheriv, "essiv:", sizeof ("essiv:") - 1) == 0) +++ { +++ char *hash_str = cipheriv + 6; +++ +++ mode_iv = GRUB_CRYPTODISK_MODE_IV_ESSIV; +++ +++ /* Configure the hash and cipher used for ESSIV. */ +++ essiv_hash = grub_crypto_lookup_md_by_name (hash_str); +++ if (!essiv_hash) +++ { +++ grub_crypto_cipher_close (cipher); +++ grub_crypto_cipher_close (secondary_cipher); +++ grub_error (GRUB_ERR_FILE_NOT_FOUND, +++ "Couldn't load %s hash", hash_str); +++ return NULL; +++ } +++ essiv_cipher = grub_crypto_cipher_open (ciph); +++ if (!essiv_cipher) +++ { +++ grub_crypto_cipher_close (cipher); +++ grub_crypto_cipher_close (secondary_cipher); +++ return NULL; +++ } +++ } +++ else +++ { +++ grub_crypto_cipher_close (cipher); +++ grub_crypto_cipher_close (secondary_cipher); +++ grub_error (GRUB_ERR_BAD_ARGUMENT, "Unknown IV mode: %s", +++ cipheriv); +++ return NULL; +++ } +++ +++ /* Configure the passphrase hash (LUKS also uses AF splitter and HMAC). */ +++ hash = grub_crypto_lookup_md_by_name (hashspec); +++ if (!hash) +++ { +++ grub_crypto_cipher_close (cipher); +++ grub_crypto_cipher_close (essiv_cipher); +++ grub_crypto_cipher_close (secondary_cipher); +++ grub_error (GRUB_ERR_FILE_NOT_FOUND, "Couldn't load %s hash", +++ hashspec); +++ return NULL; +++ } +++ +++ newdev = grub_zalloc (sizeof (struct grub_cryptodisk)); +++ if (!newdev) +++ { +++ grub_crypto_cipher_close (cipher); +++ grub_crypto_cipher_close (essiv_cipher); +++ grub_crypto_cipher_close (secondary_cipher); +++ return NULL; +++ } +++ newdev->cipher = cipher; +++ newdev->offset = 0; +++ newdev->source_disk = NULL; +++ newdev->benbi_log = benbi_log; +++ newdev->mode = mode; +++ newdev->mode_iv = mode_iv; +++ newdev->secondary_cipher = secondary_cipher; +++ newdev->essiv_cipher = essiv_cipher; +++ newdev->essiv_hash = essiv_hash; +++ newdev->hash = hash; +++ newdev->log_sector_size = 9; +++ newdev->total_length = grub_disk_get_size (disk) - newdev->offset; +++ grub_memcpy (newdev->uuid, uuid, sizeof (newdev->uuid)); +++ COMPILE_TIME_ASSERT (sizeof (newdev->uuid) >= sizeof (uuid)); +++ +++ return newdev; +++} +++ ++ static grub_extcmd_t cmd; ++ ++ GRUB_MOD_INIT (cryptodisk) ++ { ++ grub_disk_dev_register (&grub_cryptodisk_dev); ++ cmd = grub_register_extcmd ("cryptomount", grub_cmd_cryptomount, 0, ++- N_("SOURCE|-u UUID|-a|-b|-H file"), +++ N_("SOURCE|-u UUID|-a|-b|-H file|-p -c cipher -d digest"), ++ N_("Mount a crypto device."), options); ++ grub_procfs_register ("luks_script", &luks_script); ++ } ++diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c ++index 11e437edb..4ebe21b4e 100644 ++--- a/grub-core/disk/luks.c +++++ b/grub-core/disk/luks.c ++@@ -30,8 +30,6 @@ ++ ++ GRUB_MOD_LICENSE ("GPLv3+"); ++ ++-#define MAX_PASSPHRASE 256 ++- ++ #define LUKS_KEY_ENABLED 0x00AC71F3 ++ ++ /* On disk LUKS header */ ++@@ -76,15 +74,7 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, ++ char uuid[sizeof (header.uuid) + 1]; ++ char ciphername[sizeof (header.cipherName) + 1]; ++ char ciphermode[sizeof (header.cipherMode) + 1]; ++- char *cipheriv = NULL; ++ char hashspec[sizeof (header.hashSpec) + 1]; ++- grub_crypto_cipher_handle_t cipher = NULL, secondary_cipher = NULL; ++- grub_crypto_cipher_handle_t essiv_cipher = NULL; ++- const gcry_md_spec_t *hash = NULL, *essiv_hash = NULL; ++- const struct gcry_cipher_spec *ciph; ++- grub_cryptodisk_mode_t mode; ++- grub_cryptodisk_mode_iv_t mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN64; ++- int benbi_log = 0; ++ grub_err_t err; ++ ++ err = GRUB_ERR_NONE; ++@@ -119,7 +109,7 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, ++ iptr++) ++ { ++ if (*iptr != '-') ++- *optr++ = *iptr; +++ *optr++ = *iptr; ++ } ++ *optr = 0; ++ ++@@ -129,6 +119,7 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, ++ return NULL; ++ } ++ +++ ++ /* Make sure that strings are null terminated. */ ++ grub_memcpy (ciphername, header.cipherName, sizeof (header.cipherName)); ++ ciphername[sizeof (header.cipherName)] = 0; ++@@ -137,184 +128,10 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, ++ grub_memcpy (hashspec, header.hashSpec, sizeof (header.hashSpec)); ++ hashspec[sizeof (header.hashSpec)] = 0; ++ ++- ciph = grub_crypto_lookup_cipher_by_name (ciphername); ++- if (!ciph) ++- { ++- grub_error (GRUB_ERR_FILE_NOT_FOUND, "Cipher %s isn't available", ++- ciphername); ++- return NULL; ++- } ++- ++- /* Configure the cipher used for the bulk data. */ ++- cipher = grub_crypto_cipher_open (ciph); ++- if (!cipher) ++- return NULL; ++- ++- if (grub_be_to_cpu32 (header.keyBytes) > 1024) ++- { ++- grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid keysize %d", ++- grub_be_to_cpu32 (header.keyBytes)); ++- grub_crypto_cipher_close (cipher); ++- return NULL; ++- } ++- ++- /* Configure the cipher mode. */ ++- if (grub_strcmp (ciphermode, "ecb") == 0) ++- { ++- mode = GRUB_CRYPTODISK_MODE_ECB; ++- mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN; ++- cipheriv = NULL; ++- } ++- else if (grub_strcmp (ciphermode, "plain") == 0) ++- { ++- mode = GRUB_CRYPTODISK_MODE_CBC; ++- mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN; ++- cipheriv = NULL; ++- } ++- else if (grub_memcmp (ciphermode, "cbc-", sizeof ("cbc-") - 1) == 0) ++- { ++- mode = GRUB_CRYPTODISK_MODE_CBC; ++- cipheriv = ciphermode + sizeof ("cbc-") - 1; ++- } ++- else if (grub_memcmp (ciphermode, "pcbc-", sizeof ("pcbc-") - 1) == 0) ++- { ++- mode = GRUB_CRYPTODISK_MODE_PCBC; ++- cipheriv = ciphermode + sizeof ("pcbc-") - 1; ++- } ++- else if (grub_memcmp (ciphermode, "xts-", sizeof ("xts-") - 1) == 0) ++- { ++- mode = GRUB_CRYPTODISK_MODE_XTS; ++- cipheriv = ciphermode + sizeof ("xts-") - 1; ++- secondary_cipher = grub_crypto_cipher_open (ciph); ++- if (!secondary_cipher) ++- { ++- grub_crypto_cipher_close (cipher); ++- return NULL; ++- } ++- if (cipher->cipher->blocksize != GRUB_CRYPTODISK_GF_BYTES) ++- { ++- grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported XTS block size: %d", ++- cipher->cipher->blocksize); ++- grub_crypto_cipher_close (cipher); ++- grub_crypto_cipher_close (secondary_cipher); ++- return NULL; ++- } ++- if (secondary_cipher->cipher->blocksize != GRUB_CRYPTODISK_GF_BYTES) ++- { ++- grub_crypto_cipher_close (cipher); ++- grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported XTS block size: %d", ++- secondary_cipher->cipher->blocksize); ++- grub_crypto_cipher_close (secondary_cipher); ++- return NULL; ++- } ++- } ++- else if (grub_memcmp (ciphermode, "lrw-", sizeof ("lrw-") - 1) == 0) ++- { ++- mode = GRUB_CRYPTODISK_MODE_LRW; ++- cipheriv = ciphermode + sizeof ("lrw-") - 1; ++- if (cipher->cipher->blocksize != GRUB_CRYPTODISK_GF_BYTES) ++- { ++- grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported LRW block size: %d", ++- cipher->cipher->blocksize); ++- grub_crypto_cipher_close (cipher); ++- return NULL; ++- } ++- } ++- else ++- { ++- grub_crypto_cipher_close (cipher); ++- grub_error (GRUB_ERR_BAD_ARGUMENT, "Unknown cipher mode: %s", ++- ciphermode); ++- return NULL; ++- } ++- ++- if (cipheriv == NULL); ++- else if (grub_memcmp (cipheriv, "plain", sizeof ("plain") - 1) == 0) ++- mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN; ++- else if (grub_memcmp (cipheriv, "plain64", sizeof ("plain64") - 1) == 0) ++- mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN64; ++- else if (grub_memcmp (cipheriv, "benbi", sizeof ("benbi") - 1) == 0) ++- { ++- if (cipher->cipher->blocksize & (cipher->cipher->blocksize - 1) ++- || cipher->cipher->blocksize == 0) ++- grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported benbi blocksize: %d", ++- cipher->cipher->blocksize); ++- /* FIXME should we return an error here? */ ++- for (benbi_log = 0; ++- (cipher->cipher->blocksize << benbi_log) < GRUB_DISK_SECTOR_SIZE; ++- benbi_log++); ++- mode_iv = GRUB_CRYPTODISK_MODE_IV_BENBI; ++- } ++- else if (grub_memcmp (cipheriv, "null", sizeof ("null") - 1) == 0) ++- mode_iv = GRUB_CRYPTODISK_MODE_IV_NULL; ++- else if (grub_memcmp (cipheriv, "essiv:", sizeof ("essiv:") - 1) == 0) ++- { ++- char *hash_str = cipheriv + 6; ++- ++- mode_iv = GRUB_CRYPTODISK_MODE_IV_ESSIV; ++- ++- /* Configure the hash and cipher used for ESSIV. */ ++- essiv_hash = grub_crypto_lookup_md_by_name (hash_str); ++- if (!essiv_hash) ++- { ++- grub_crypto_cipher_close (cipher); ++- grub_crypto_cipher_close (secondary_cipher); ++- grub_error (GRUB_ERR_FILE_NOT_FOUND, ++- "Couldn't load %s hash", hash_str); ++- return NULL; ++- } ++- essiv_cipher = grub_crypto_cipher_open (ciph); ++- if (!essiv_cipher) ++- { ++- grub_crypto_cipher_close (cipher); ++- grub_crypto_cipher_close (secondary_cipher); ++- return NULL; ++- } ++- } ++- else ++- { ++- grub_crypto_cipher_close (cipher); ++- grub_crypto_cipher_close (secondary_cipher); ++- grub_error (GRUB_ERR_BAD_ARGUMENT, "Unknown IV mode: %s", ++- cipheriv); ++- return NULL; ++- } ++- ++- /* Configure the hash used for the AF splitter and HMAC. */ ++- hash = grub_crypto_lookup_md_by_name (hashspec); ++- if (!hash) ++- { ++- grub_crypto_cipher_close (cipher); ++- grub_crypto_cipher_close (essiv_cipher); ++- grub_crypto_cipher_close (secondary_cipher); ++- grub_error (GRUB_ERR_FILE_NOT_FOUND, "Couldn't load %s hash", ++- hashspec); ++- return NULL; ++- } +++ newdev = grub_cryptodisk_create (disk, uuid, ciphername, ciphermode, hashspec); ++ ++- newdev = grub_zalloc (sizeof (struct grub_cryptodisk)); ++- if (!newdev) ++- { ++- grub_crypto_cipher_close (cipher); ++- grub_crypto_cipher_close (essiv_cipher); ++- grub_crypto_cipher_close (secondary_cipher); ++- return NULL; ++- } ++- newdev->cipher = cipher; ++ newdev->offset = grub_be_to_cpu32 (header.payloadOffset); ++- newdev->source_disk = NULL; ++- newdev->benbi_log = benbi_log; ++- newdev->mode = mode; ++- newdev->mode_iv = mode_iv; ++- newdev->secondary_cipher = secondary_cipher; ++- newdev->essiv_cipher = essiv_cipher; ++- newdev->essiv_hash = essiv_hash; ++- newdev->hash = hash; ++- newdev->log_sector_size = 9; ++- newdev->total_length = grub_disk_get_size (disk) - newdev->offset; ++- grub_memcpy (newdev->uuid, uuid, sizeof (newdev->uuid)); ++ newdev->modname = "luks"; ++- COMPILE_TIME_ASSERT (sizeof (newdev->uuid) >= sizeof (uuid)); ++ ++ return newdev; ++ } ++@@ -329,7 +146,7 @@ luks_recover_key (grub_disk_t source, ++ struct grub_luks_phdr header; ++ grub_size_t keysize; ++ grub_uint8_t *split_key = NULL; ++- char interactive_passphrase[MAX_PASSPHRASE] = ""; +++ char interactive_passphrase[GRUB_CRYPTODISK_MAX_PASSPHRASE] = ""; ++ grub_uint8_t *passphrase; ++ grub_size_t passphrase_length; ++ grub_uint8_t candidate_digest[sizeof (header.mkDigest)]; ++@@ -376,7 +193,7 @@ luks_recover_key (grub_disk_t source, ++ /* Use bytestring from key file as passphrase */ ++ passphrase = keyfile_bytes; ++ passphrase_length = keyfile_bytes_size; ++- keyfile_bytes = NULL; /* use it only once */ +++ keyfile_bytes = NULL; /* use it only once */ ++ } ++ else ++ { ++@@ -387,7 +204,7 @@ luks_recover_key (grub_disk_t source, ++ grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name, ++ source->partition ? "," : "", tmp ? : "", dev->uuid); ++ grub_free (tmp); ++- if (!grub_password_get (interactive_passphrase, MAX_PASSPHRASE)) +++ if (!grub_password_get (interactive_passphrase, GRUB_CRYPTODISK_MAX_PASSPHRASE)) ++ { ++ grub_free (split_key); ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied"); ++diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h ++index 67f6b0b59..bb25ab730 100644 ++--- a/include/grub/cryptodisk.h +++++ b/include/grub/cryptodisk.h ++@@ -54,9 +54,14 @@ typedef enum ++ #define GRUB_CRYPTODISK_GF_LOG_BYTES (GRUB_CRYPTODISK_GF_LOG_SIZE - 3) ++ #define GRUB_CRYPTODISK_GF_BYTES (1U << GRUB_CRYPTODISK_GF_LOG_BYTES) ++ #define GRUB_CRYPTODISK_MAX_KEYLEN 128 +++#define GRUB_CRYPTODISK_MAX_PASSPHRASE 256 ++ ++ #define GRUB_CRYPTODISK_MAX_KEYFILE_SIZE 8192 ++ +++#define GRUB_CRYPTODISK_PLAIN_CIPHER "aes-cbc-essiv:sha256" +++#define GRUB_CRYPTODISK_PLAIN_DIGEST "ripemd160" +++#define GRUB_CRYPTODISK_PLAIN_KEYSIZE 256 +++ ++ struct grub_cryptodisk; ++ ++ typedef gcry_err_code_t ++@@ -160,4 +165,7 @@ grub_util_get_geli_uuid (const char *dev); ++ grub_cryptodisk_t grub_cryptodisk_get_by_uuid (const char *uuid); ++ grub_cryptodisk_t grub_cryptodisk_get_by_source_disk (grub_disk_t disk); ++ +++grub_cryptodisk_t grub_cryptodisk_create (grub_disk_t disk, char *uuid, +++ char *ciphername, char *ciphermode, char *digest); +++ ++ #endif ++-- ++2.16.2 ++ diff --git a/helpers/DATA/grub2-unsigned/0005-Cryptomount-support-for-hyphens-in-UUID.patch b/helpers/DATA/grub2-unsigned/0005-Cryptomount-support-for-hyphens-in-UUID.patch new file mode 100644 index 00000000..a70086ff --- /dev/null +++ b/helpers/DATA/grub2-unsigned/0005-Cryptomount-support-for-hyphens-in-UUID.patch @@ -0,0 +1,128 @@ +diff --git a/0005-Cryptomount-support-for-hyphens-in-UUID.patch b/0005-Cryptomount-support-for-hyphens-in-UUID.patch +new file mode 100644 +index 00000000000..f6ed18a66d7 +--- /dev/null ++++ b/0005-Cryptomount-support-for-hyphens-in-UUID.patch +@@ -0,0 +1,122 @@ ++From 0939fef502c4b97d1facc7972a54d5dfeba4ab71 Mon Sep 17 00:00:00 2001 ++From: John Lane <john@lane.uk.net> ++Date: Fri, 26 Jun 2015 22:48:03 +0100 ++Subject: [PATCH 5/7] Cryptomount support for hyphens in UUID ++ ++--- ++ grub-core/disk/cryptodisk.c | 20 +++++++++++++++++--- ++ grub-core/disk/luks.c | 26 ++++++++------------------ ++ include/grub/cryptodisk.h | 2 ++ ++ 3 files changed, 27 insertions(+), 21 deletions(-) ++ ++diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c ++index 7f656f75c..c442d3a34 100644 ++--- a/grub-core/disk/cryptodisk.c +++++ b/grub-core/disk/cryptodisk.c ++@@ -114,6 +114,20 @@ gf_mul_be (grub_uint8_t *o, const grub_uint8_t *a, const grub_uint8_t *b) ++ } ++ } ++ +++int +++grub_cryptodisk_uuidcmp(char *uuid_a, char *uuid_b) +++{ +++ while ((*uuid_a != '\0') && (*uuid_b != '\0')) +++ { +++ while (*uuid_a == '-') uuid_a++; +++ while (*uuid_b == '-') uuid_b++; +++ if (grub_toupper(*uuid_a) != grub_toupper(*uuid_b)) break; +++ uuid_a++; +++ uuid_b++; +++ } +++ return (*uuid_a == '\0') && (*uuid_b == '\0'); +++} +++ ++ static gcry_err_code_t ++ grub_crypto_pcbc_decrypt (grub_crypto_cipher_handle_t cipher, ++ void *out, void *in, grub_size_t size, ++@@ -509,8 +523,8 @@ grub_cryptodisk_open (const char *name, grub_disk_t disk) ++ if (grub_memcmp (name, "cryptouuid/", sizeof ("cryptouuid/") - 1) == 0) ++ { ++ for (dev = cryptodisk_list; dev != NULL; dev = dev->next) ++- if (grub_strcasecmp (name + sizeof ("cryptouuid/") - 1, dev->uuid) == 0) ++- break; +++ if (grub_cryptodisk_uuidcmp(name + sizeof ("cryptouuid/") - 1, dev->uuid)) +++ break; ++ } ++ else ++ { ++@@ -742,7 +756,7 @@ grub_cryptodisk_get_by_uuid (const char *uuid) ++ { ++ grub_cryptodisk_t dev; ++ for (dev = cryptodisk_list; dev != NULL; dev = dev->next) ++- if (grub_strcasecmp (dev->uuid, uuid) == 0) +++ if (grub_cryptodisk_uuidcmp(dev->uuid, uuid)) ++ return dev; ++ return NULL; ++ } ++diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c ++index 4ebe21b4e..80a760670 100644 ++--- a/grub-core/disk/luks.c +++++ b/grub-core/disk/luks.c ++@@ -68,9 +68,7 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, ++ int check_boot, grub_file_t hdr) ++ { ++ grub_cryptodisk_t newdev; ++- const char *iptr; ++ struct grub_luks_phdr header; ++- char *optr; ++ char uuid[sizeof (header.uuid) + 1]; ++ char ciphername[sizeof (header.cipherName) + 1]; ++ char ciphermode[sizeof (header.cipherMode) + 1]; ++@@ -104,22 +102,6 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, ++ || grub_be_to_cpu16 (header.version) != 1) ++ return NULL; ++ ++- optr = uuid; ++- for (iptr = header.uuid; iptr < &header.uuid[ARRAY_SIZE (header.uuid)]; ++- iptr++) ++- { ++- if (*iptr != '-') ++- *optr++ = *iptr; ++- } ++- *optr = 0; ++- ++- if (check_uuid && grub_strcasecmp (check_uuid, uuid) != 0) ++- { ++- grub_dprintf ("luks", "%s != %s\n", uuid, check_uuid); ++- return NULL; ++- } ++- ++- ++ /* Make sure that strings are null terminated. */ ++ grub_memcpy (ciphername, header.cipherName, sizeof (header.cipherName)); ++ ciphername[sizeof (header.cipherName)] = 0; ++@@ -127,6 +109,14 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, ++ ciphermode[sizeof (header.cipherMode)] = 0; ++ grub_memcpy (hashspec, header.hashSpec, sizeof (header.hashSpec)); ++ hashspec[sizeof (header.hashSpec)] = 0; +++ grub_memcpy (uuid, header.uuid, sizeof (header.uuid)); +++ uuid[sizeof (header.uuid)] = 0; +++ +++ if ( check_uuid && ! grub_cryptodisk_uuidcmp(check_uuid, uuid)) +++ { +++ grub_dprintf ("luks", "%s != %s\n", uuid, check_uuid); +++ return NULL; +++ } ++ ++ newdev = grub_cryptodisk_create (disk, uuid, ciphername, ciphermode, hashspec); ++ ++diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h ++index bb25ab730..01c02696e 100644 ++--- a/include/grub/cryptodisk.h +++++ b/include/grub/cryptodisk.h ++@@ -168,4 +168,6 @@ grub_cryptodisk_t grub_cryptodisk_get_by_source_disk (grub_disk_t disk); ++ grub_cryptodisk_t grub_cryptodisk_create (grub_disk_t disk, char *uuid, ++ char *ciphername, char *ciphermode, char *digest); ++ +++int +++grub_cryptodisk_uuidcmp(char *uuid_a, char *uuid_b); ++ #endif ++-- ++2.16.2 ++ diff --git a/helpers/DATA/grub2-unsigned/0006-Cryptomount-support-for-using-whole-device-as-keyfile.patch b/helpers/DATA/grub2-unsigned/0006-Cryptomount-support-for-using-whole-device-as-keyfile.patch new file mode 100644 index 00000000..09f876d2 --- /dev/null +++ b/helpers/DATA/grub2-unsigned/0006-Cryptomount-support-for-using-whole-device-as-keyfile.patch @@ -0,0 +1,114 @@ +diff --git a/0006-Cryptomount-support-for-using-whole-device-as-keyfile.patch b/0006-Cryptomount-support-for-using-whole-device-as-keyfile.patch +new file mode 100644 +index 00000000000..49750f84aca +--- /dev/null ++++ b/0006-Cryptomount-support-for-using-whole-device-as-keyfile.patch +@@ -0,0 +1,108 @@ ++From 908f4282cc934422923ff59836a835e63d6a7117 Mon Sep 17 00:00:00 2001 ++From: Paul Gideon Dann <pdgiddie@gmail.com> ++Date: Tue, 19 Jul 2016 12:36:37 +0100 ++Subject: [PATCH] Add support for using a whole device as a keyfile ++ ++--- ++ grub-core/disk/cryptodisk.c | 86 +++++++++++++++++++++++++++++-------- ++ 1 file changed, 68 insertions(+), 18 deletions(-) ++ ++diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c ++index d0388c6d1..c5d8021ba 100644 ++--- a/grub-core/disk/cryptodisk.c +++++ b/grub-core/disk/cryptodisk.c ++@@ -1031,26 +1031,76 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) ++ else ++ { ++ keyfile_offset = state[5].set ? grub_strtoul (state[5].arg, 0, 0) : 0; ++- keyfile_size = requested_keyfile_size ? requested_keyfile_size : \ ++- GRUB_CRYPTODISK_MAX_KEYFILE_SIZE; ++- ++- keyfile = grub_file_open (state[4].arg, GRUB_FILE_TYPE_NONE); ++- if (!keyfile) ++- grub_printf (N_("Unable to open key file %s\n"), state[4].arg); ++- else if (grub_file_seek (keyfile, keyfile_offset) == (grub_off_t)-1) ++- grub_printf (N_("Unable to seek to offset %d in key file\n"), keyfile_offset); ++- else +++ +++ if (grub_strchr (state[4].arg, '/')) ++ { ++- keyfile_size = grub_file_read (keyfile, keyfile_buffer, keyfile_size); ++- if (keyfile_size == (grub_size_t)-1) ++- grub_printf (N_("Error reading key file\n")); ++- else if (requested_keyfile_size && (keyfile_size != requested_keyfile_size)) ++- grub_printf (N_("Cannot read %llu bytes for key file (read %llu bytes)\n"), ++- (unsigned long long) requested_keyfile_size, ++- (unsigned long long) keyfile_size); +++ keyfile_size = requested_keyfile_size ? requested_keyfile_size : \ +++ GRUB_CRYPTODISK_MAX_KEYFILE_SIZE; +++ keyfile = grub_file_open (state[4].arg, GRUB_FILE_TYPE_NONE); +++ if (!keyfile) +++ grub_printf (N_("Unable to open key file %s\n"), state[4].arg); +++ else if (grub_file_seek (keyfile, keyfile_offset) == (grub_off_t)-1) +++ grub_printf (N_("Unable to seek to offset %d in key file\n"), keyfile_offset); ++ else ++- key = keyfile_buffer; ++- } +++ { +++ keyfile_size = grub_file_read (keyfile, keyfile_buffer, keyfile_size); +++ if (keyfile_size == (grub_size_t)-1) +++ grub_printf (N_("Error reading key file\n")); +++ else if (requested_keyfile_size && (keyfile_size != requested_keyfile_size)) +++ grub_printf (N_("Cannot read %llu bytes for key file (read %llu bytes)\n"), +++ (unsigned long long) requested_keyfile_size, +++ (unsigned long long) keyfile_size); +++ else +++ key = keyfile_buffer; +++ } +++ } +++ else +++ { +++ grub_disk_t keydisk; +++ char* keydisk_name; +++ grub_err_t err; +++ grub_uint64_t total_sectors; +++ +++ keydisk_name = grub_file_get_device_name(state[4].arg); +++ keydisk = grub_disk_open (keydisk_name); +++ if (!keydisk) +++ { +++ grub_printf (N_("Unable to open disk %s\n"), keydisk_name); +++ goto cleanup_keydisk_name; +++ } +++ +++ total_sectors = grub_disk_get_size (keydisk); +++ if (total_sectors == GRUB_DISK_SIZE_UNKNOWN) +++ { +++ grub_printf (N_("Unable to determine size of disk %s\n"), keydisk_name); +++ goto cleanup_keydisk; +++ } +++ +++ keyfile_size = (total_sectors << GRUB_DISK_SECTOR_BITS); +++ if (requested_keyfile_size > 0 && requested_keyfile_size < keyfile_size) +++ keyfile_size = requested_keyfile_size; +++ if (keyfile_size > GRUB_CRYPTODISK_MAX_KEYFILE_SIZE) +++ { +++ grub_printf (N_("Key file size exceeds maximum (%llu)\n"), \ +++ (unsigned long long) GRUB_CRYPTODISK_MAX_KEYFILE_SIZE); +++ goto cleanup_keydisk; +++ } +++ +++ err = grub_disk_read (keydisk, 0, keyfile_offset, keyfile_size, keyfile_buffer); +++ if (err != GRUB_ERR_NONE) +++ { +++ grub_printf (N_("Failed to read from disk %s\n"), keydisk_name); +++ keyfile_size = 0; +++ goto cleanup_keydisk; +++ } +++ +++ key = keyfile_buffer; +++ +++ cleanup_keydisk: +++ grub_disk_close (keydisk); +++ cleanup_keydisk_name: +++ grub_free (keydisk_name); +++ } ++ } ++ } ++ diff --git a/helpers/make-grub2-unsigned b/helpers/make-grub2-unsigned new file mode 100644 index 00000000..5f343a11 --- /dev/null +++ b/helpers/make-grub2-unsigned @@ -0,0 +1,67 @@ +#!/bin/sh +# +# Copyright (C) 2011-2017 Ruben Rodriguez <ruben@trisquel.info> +# Copyright (C) 2019 Mason Hock <mason@masonhock.com> +# Copyright (C) 2021 Luis Guzman <ark@switnet.org> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# + +################################################################################################# +# This helper and DATA folder are a copy of the grub2 package, please track changes accordingly. +# The only change is the FIXED_VER variable that needs to be empty or removed. +# Please keep this note on the helper until a new change or approach solves this state. +################################################################################################# + +VERSION=5 +FIXED_VER='' #Keep FIXED_VER empty or delete it. +COMPONENT=main + +. ./config + +# http://grub.johnlane.ie/ +## updated to 2.04-1 on https://aur.archlinux.org/packages/grub-luks-keyfile/ +for i in $DATA/*.patch; do +echo Applying patch $i +patch -p1 < $i +done + +#apt-get remove -y --force-yes dosfstools +#sed '/dosfstools/d' -i debian/control +sed '/mkfs.minix/s/-B $BLKSIZE//g' -i tests/util/grub-fs-tester.in + +for i in install-efi-ubuntu-flavours.patch mkconfig-ubuntu-distributor.patch; do + rm debian/patches/$i + sed /$i/d debian/patches/series -i +done + +#Allow passwords https://bugs.launchpad.net/ubuntu/+source/grub2/+bug/1311302 +/bin/sed '/CLASS=/s/class os/class os --unrestricted/' -i util/grub.d/* debian/patches/mkconfig-other-inits.patch + +replace "with Linux" "with Linux-Libre" util +replace "with Linux" "with Linux-Libre" debian +replace "Linux" "Linux-Libre" po +replace Ubuntu Trisquel . +replace ubuntu trisquel . +find |grep ubuntu|xargs rename s/ubuntu/trisquel/ + +# Allow Windows and MacOX entries to boot without a password +sed 's/class osx/class osx --unrestricted/; s/class windows/class osx --unrestricted/;' -i ./util/grub.d/30_os-prober.in + +sed -i '/set -e/aexit 77' tests/grub_cmd_set_date.in + +changelog "skip test grub_cmd_set_date.in" + +compile -- GitLab