]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
support UUID for geli
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sun, 24 Apr 2011 19:11:14 +0000 (21:11 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sun, 24 Apr 2011 19:11:14 +0000 (21:11 +0200)
grub-core/disk/geli.c
grub-core/disk/luks.c
include/grub/cryptodisk.h

index b86e363c76e9a4aa5733a03edc24b63369a65eb0..10420054627c1d72d8caeaa10a7b25f3b97b3ffc 100644 (file)
@@ -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
+  gcry_err = grub_crypto_hmac_buffer (GRUB_MD_SHA256,
+                                     header->salt, sizeof (header->salt),
+                                     "uuid", sizeof ("uuid") - 1, uuidbin);
+  if (gcry_err)
+    {
+      grub_crypto_gcry_error (gcry_err);
+      return NULL;
+    }
   optr = uuid;
-  for (iptr = header->uuid; iptr < &header->uuid[ARRAY_SIZE (header->uuid)];
-       iptr++)
+  for (iptr = uuidbin; iptr < &uuidbin[ARRAY_SIZE (uuidbin)]; iptr++)
     {
-      if (*iptr != '-')
-       *optr++ = *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;
 }
 
index 3f98dfc87c1ec17637e1317b8e0f26981b02c6e0..a94b3cc527f61c28bf68221642128f9985e47ef6 100644 (file)
@@ -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;
 }
 
index 1911c04be3b98c01b391bfb458bd90ba1e9635fa..169fb119de6866c99a7767fc9ad216c8aae43a9d 100644 (file)
@@ -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)