From 23432f6542506794cbcf1d3b75b1e9d3fe284ad4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 24 Apr 2011 21:11:14 +0200 Subject: [PATCH] support UUID for geli --- grub-core/disk/geli.c | 41 +++++++++++++++++++++++++++++---------- grub-core/disk/luks.c | 1 + include/grub/cryptodisk.h | 2 +- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c index b86e363c7..104200546 100644 --- a/grub-core/disk/geli.c +++ b/grub-core/disk/geli.c @@ -84,7 +84,6 @@ struct grub_geli_phdr /* FIXME: support big-endian pre-version-4 volumes. */ /* FIXME: support for keyfiles. */ /* FIXME: support for HMAC. */ -/* FIXME: support for UUID. */ /* FIXME: support for mounting all boot volumes. */ const char *algorithms[] = { [0x01] = "des", @@ -132,6 +131,18 @@ geli_rekey (struct grub_cryptodisk *dev, grub_uint64_t zoneno) dev->rekey_derived_size); } +static inline int +ascii2hex (char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + return 0; +} + static grub_cryptodisk_t configure_ciphers (const struct grub_geli_phdr *header) { @@ -139,6 +150,11 @@ configure_ciphers (const struct grub_geli_phdr *header) grub_crypto_cipher_handle_t cipher = NULL, secondary_cipher = NULL; const struct gcry_cipher_spec *ciph; const char *ciphername = NULL; + char uuid[GRUB_MD_SHA256->mdlen * 2 + 1]; + grub_uint8_t uuidbin[GRUB_MD_SHA256->mdlen]; + grub_uint8_t *iptr; + char *optr; + gcry_err_code_t gcry_err; /* Look for GELI magic sequence. */ if (grub_memcmp (header->magic, GELI_MAGIC, sizeof (GELI_MAGIC)) @@ -157,13 +173,19 @@ configure_ciphers (const struct grub_geli_phdr *header) return NULL; } -#if 0 - optr = uuid; - for (iptr = header->uuid; iptr < &header->uuid[ARRAY_SIZE (header->uuid)]; - iptr++) + gcry_err = grub_crypto_hmac_buffer (GRUB_MD_SHA256, + header->salt, sizeof (header->salt), + "uuid", sizeof ("uuid") - 1, uuidbin); + if (gcry_err) { - if (*iptr != '-') - *optr++ = *iptr; + grub_crypto_gcry_error (gcry_err); + return NULL; + } + optr = uuid; + for (iptr = uuidbin; iptr < &uuidbin[ARRAY_SIZE (uuidbin)]; iptr++) + { + grub_snprintf (optr, 3, "%02x", *iptr); + optr += 2; } *optr = 0; @@ -172,7 +194,6 @@ configure_ciphers (const struct grub_geli_phdr *header) grub_dprintf ("luks", "%s != %s", uuid, search_uuid); return NULL; } -#endif if (grub_le_to_cpu16 (header->alg) >= ARRAY_SIZE (algorithms) || algorithms[grub_le_to_cpu16 (header->alg)] == NULL) @@ -242,9 +263,9 @@ configure_ciphers (const struct grub_geli_phdr *header) newdev->rekey = geli_rekey; newdev->rekey_shift = 20; } -#if 0 + grub_memcpy (newdev->uuid, uuid, sizeof (newdev->uuid)); -#endif + COMPILE_TIME_ASSERT (sizeof (newdev->uuid) >= 32 * 2 + 1); return newdev; } diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c index 3f98dfc87..a94b3cc52 100644 --- a/grub-core/disk/luks.c +++ b/grub-core/disk/luks.c @@ -284,6 +284,7 @@ configure_ciphers (const struct grub_luks_phdr *header) newdev->hash = hash; newdev->log_sector_size = 9; grub_memcpy (newdev->uuid, uuid, sizeof (newdev->uuid)); + COMPILE_TIME_ASSERT (sizeof (newdev->uuid) >= sizeof (uuid)); return newdev; } diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h index 1911c04be..169fb119d 100644 --- a/include/grub/cryptodisk.h +++ b/include/grub/cryptodisk.h @@ -42,7 +42,7 @@ typedef enum GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64_HASH } grub_cryptodisk_mode_iv_t; -#define GRUB_CRYPTODISK_MAX_UUID_LENGTH 63 +#define GRUB_CRYPTODISK_MAX_UUID_LENGTH 71 #define GRUB_CRYPTODISK_GF_LOG_SIZE 7 #define GRUB_CRYPTODISK_GF_SIZE (1U << GRUB_CRYPTODISK_GF_LOG_SIZE)