From ba3031f9963dfc5416140ceebd16d8239e22b1e4 Mon Sep 17 00:00:00 2001 From: Kris Moore Date: Mon, 19 Jan 2015 21:56:41 +0300 Subject: [PATCH] Support GELI v6 and v7 --- ChangeLog | 4 ++++ grub-core/disk/geli.c | 26 ++++++++++++++++++++------ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index c38917bd9..854c008e1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2015-01-19 Kris Moore + + * grub-core/disk/geli.c: Support GELI v6 and v7. + 2014-12-09 Andrei Borzenkov * grub-core/term/serial.c (grub_cmd_serial): Fix --rtscts diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c index 17273416f..4ed07bb91 100644 --- a/grub-core/disk/geli.c +++ b/grub-core/disk/geli.c @@ -225,7 +225,7 @@ grub_util_get_geli_uuid (const char *dev) /* Look for GELI magic sequence. */ if (grub_memcmp (header->magic, GELI_MAGIC, sizeof (GELI_MAGIC)) - || grub_le_to_cpu32 (header->version) > 5 + || grub_le_to_cpu32 (header->version) > 7 || grub_le_to_cpu32 (header->version) < 1) grub_util_error ("%s", _("wrong ELI magic or version")); @@ -265,7 +265,7 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, /* Look for GELI magic sequence. */ if (grub_memcmp (header.magic, GELI_MAGIC, sizeof (GELI_MAGIC)) - || grub_le_to_cpu32 (header.version) > 5 + || grub_le_to_cpu32 (header.version) > 7 || grub_le_to_cpu32 (header.version) < 1) { grub_dprintf ("geli", "wrong magic %02x\n", header.magic[0]); @@ -401,6 +401,7 @@ recover_key (grub_disk_t source, grub_cryptodisk_t dev) grub_uint8_t geomkey[GRUB_CRYPTO_MAX_MDLEN]; grub_uint8_t verify_key[GRUB_CRYPTO_MAX_MDLEN]; grub_uint8_t zero[GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE]; + grub_uint8_t geli_cipher_key[64]; char passphrase[MAX_PASSPHRASE] = ""; unsigned i; gcry_err_code_t gcry_err; @@ -524,6 +525,19 @@ recover_key (grub_disk_t source, grub_cryptodisk_t dev) continue; grub_printf_ (N_("Slot %d opened\n"), i); + if (grub_le_to_cpu32 (header.version) >= 7) + { + /* GELI >=7 uses the cipher_key */ + grub_memcpy (geli_cipher_key, candidate_key.cipher_key, + sizeof (candidate_key.cipher_key)); + } + else + { + /* GELI <=6 uses the iv_key */ + grub_memcpy (geli_cipher_key, candidate_key.iv_key, + sizeof (candidate_key.iv_key)); + } + /* Set the master key. */ if (!dev->rekey) { @@ -540,13 +554,13 @@ recover_key (grub_disk_t source, grub_cryptodisk_t dev) grub_size_t real_keysize = keysize; if (grub_le_to_cpu16 (header.alg) == 0x16) real_keysize *= 2; - /* For a reason I don't know, the IV key is used in rekeying. */ - grub_memcpy (dev->rekey_key, candidate_key.iv_key, - sizeof (candidate_key.iv_key)); + + grub_memcpy (dev->rekey_key, geli_cipher_key, + sizeof (geli_cipher_key)); dev->rekey_derived_size = real_keysize; dev->last_rekey = -1; COMPILE_TIME_ASSERT (sizeof (dev->rekey_key) - >= sizeof (candidate_key.iv_key)); + >= sizeof (geli_cipher_key)); } dev->iv_prefix_len = sizeof (candidate_key.iv_key);