]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
luks grub-probe support
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Fri, 22 Apr 2011 21:39:36 +0000 (23:39 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Fri, 22 Apr 2011 21:39:36 +0000 (23:39 +0200)
grub-core/disk/luks.c
include/grub/crypto.h
include/grub/emu/hostdisk.h
util/grub-probe.c
util/import_gcry.py

index 0098c9d497b208c7958ae3e9694eb01f65b7843b..ce1f1bfc6e0e0be7e33ea0f9bf93a6184d95ba97 100644 (file)
@@ -863,6 +863,38 @@ grub_luks_write (grub_disk_t disk __attribute ((unused)),
   return GRUB_ERR_NOT_IMPLEMENTED_YET;
 }
 
+#ifdef GRUB_UTIL
+static grub_disk_memberlist_t
+grub_luks_memberlist (grub_disk_t disk)
+{
+  grub_luks_t dev = (grub_luks_t) disk->data;
+  grub_disk_memberlist_t list = NULL;
+
+  list = grub_malloc (sizeof (*list));
+  if (list)
+    {
+      list->disk = dev->source_disk;
+      list->next = NULL;
+    }
+
+  return list;
+}
+
+void
+grub_util_luks_print_ciphers (grub_disk_t disk)
+{
+  grub_luks_t dev = (grub_luks_t) disk->data;
+  if (dev->cipher)
+    grub_printf ("%s ", dev->cipher->cipher->modname);
+  if (dev->secondary_cipher)
+    grub_printf ("%s ", dev->secondary_cipher->cipher->modname);
+  if (dev->hash)
+    grub_printf ("%s ", dev->hash->modname);
+  if (dev->essiv_hash)
+    grub_printf ("%s ", dev->essiv_hash->modname);
+}
+#endif
+
 static void
 luks_cleanup (void)
 {
@@ -953,6 +985,9 @@ static struct grub_disk_dev grub_luks_dev = {
   .close = grub_luks_close,
   .read = grub_luks_read,
   .write = grub_luks_write,
+#ifdef GRUB_UTIL
+  .memberlist = grub_luks_memberlist,
+#endif
   .next = 0
 };
 
index a8ca2106dc210932f6df11c5334b1e8c8959c549..62ed2015cba644bdd4728cf011492959ca59fce1 100644 (file)
@@ -126,6 +126,9 @@ typedef struct gcry_cipher_spec
   gcry_cipher_decrypt_t decrypt;
   gcry_cipher_stencrypt_t stencrypt;
   gcry_cipher_stdecrypt_t stdecrypt;
+#ifdef GRUB_UTIL
+  const char *modname;
+#endif
   struct gcry_cipher_spec *next;
 } gcry_cipher_spec_t;
 
@@ -161,6 +164,9 @@ typedef struct gcry_md_spec
   grub_size_t contextsize; /* allocate this amount of context */
   /* Block size, needed for HMAC.  */
   grub_size_t blocksize;
+#ifdef GRUB_UTIL
+  const char *modname;
+#endif
   struct gcry_md_spec *next;
 } gcry_md_spec_t;
 
index c7a794d68530e3c204b76f7543331d642ae818c5..2be24cc3fc2407c9e3aec7020dc401628d883982 100644 (file)
@@ -36,5 +36,6 @@ grub_util_fd_sector_seek (int fd, const char *name, grub_disk_addr_t sector);
 ssize_t grub_util_fd_read (int fd, char *buf, size_t len);
 grub_err_t
 grub_luks_cheat_mount (const char *sourcedev, const char *cheat);
+void grub_util_luks_print_ciphers (grub_disk_t disk);
 
 #endif /* ! GRUB_BIOSDISK_MACHINE_UTIL_HEADER */
index 6c6220b8b7b660e64f6a84502c9ba32fe5266d10..68d9b06f1d2e45f769eb393f11775979cee9af32 100644 (file)
@@ -34,6 +34,7 @@
 #include <grub/env.h>
 #include <grub/raid.h>
 #include <grub/i18n.h>
+#include <grub/crypto.h>
 
 #include <stdio.h>
 #include <unistd.h>
@@ -63,15 +64,28 @@ static void
 probe_partmap (grub_disk_t disk)
 {
   grub_partition_t part;
+  grub_disk_memberlist_t list = NULL, tmp;
 
   if (disk->partition == NULL)
     {
       grub_util_info ("no partition map found for %s", disk->name);
-      return;
     }
 
   for (part = disk->partition; part; part = part->parent)
-    printf ("%s\n", part->partmap->name);
+    printf ("%s ", part->partmap->name);
+
+  /* In case of LVM/RAID, check the member devices as well.  */
+  if (disk->dev->memberlist)
+    {
+      list = disk->dev->memberlist (disk);
+    }
+  while (list)
+    {
+      probe_partmap (list->disk);
+      tmp = list->next;
+      free (list);
+      list = tmp;
+    }
 }
 
 static int
@@ -88,6 +102,45 @@ probe_raid_level (grub_disk_t disk)
   return ((struct grub_raid_array *) disk->data)->level;
 }
 
+static void
+probe_abstraction (grub_disk_t disk)
+{
+  grub_disk_memberlist_t list = NULL, tmp;
+  int raid_level;
+
+  if (disk->dev->memberlist)
+    list = disk->dev->memberlist (disk);
+  while (list)
+    {
+      probe_abstraction (list->disk);
+
+      tmp = list->next;
+      free (list);
+      list = tmp;
+    }
+
+  if (disk->dev->id == GRUB_DISK_DEVICE_LVM_ID)
+    printf ("lvm ");
+
+  if (disk->dev->id == GRUB_DISK_DEVICE_LUKS_ID)
+    {
+      printf ("luks ");
+      grub_util_luks_print_ciphers (disk);
+    }
+
+  raid_level = probe_raid_level (disk);
+  if (raid_level >= 0)
+    {
+      printf ("raid ");
+      if (disk->dev->raidname)
+       printf ("%s ", disk->dev->raidname (disk));
+    }
+  if (raid_level == 5)
+    printf ("raid5rec ");
+  if (raid_level == 6)
+    printf ("raid6rec ");
+}
+
 static void
 probe (const char *path, char *device_name)
 {
@@ -136,91 +189,16 @@ probe (const char *path, char *device_name)
 
   if (print == PRINT_ABSTRACTION)
     {
-      grub_disk_memberlist_t list = NULL, tmp;
-      const int is_lvm = (dev->disk->dev->id == GRUB_DISK_DEVICE_LVM_ID);
-      int is_raid = 0;
-      int is_raid5 = 0;
-      int is_raid6 = 0;
-      int raid_level;
-      grub_disk_t raid_disk;
-
-      raid_level = probe_raid_level (dev->disk);
-      if (raid_level >= 0)
-       {
-         is_raid = 1;
-         is_raid5 |= (raid_level == 5);
-         is_raid6 |= (raid_level == 6);
-         raid_disk = dev->disk;
-       }
-
-      if ((is_lvm) && (dev->disk->dev->memberlist))
-       list = dev->disk->dev->memberlist (dev->disk);
-      while (list)
-       {
-         raid_level = probe_raid_level (list->disk);
-         if (raid_level >= 0)
-           {
-             is_raid = 1;
-             is_raid5 |= (raid_level == 5);
-             is_raid6 |= (raid_level == 6);
-             raid_disk = list->disk;
-           }
-
-         tmp = list->next;
-         free (list);
-         list = tmp;
-       }
-
-      if (is_raid)
-       {
-         printf ("raid ");
-         if (is_raid5)
-           printf ("raid5rec ");
-         if (is_raid6)
-           printf ("raid6rec ");
-         if (raid_disk->dev->raidname)
-           printf ("%s ", raid_disk->dev->raidname (raid_disk));
-       }
-
-      if (is_lvm)
-       printf ("lvm ");
-
+      probe_abstraction (dev->disk);
       printf ("\n");
-
       goto end;
     }
 
   if (print == PRINT_PARTMAP)
     {
-      grub_disk_memberlist_t list = NULL, tmp;
-
       /* Check if dev->disk itself is contained in a partmap.  */
       probe_partmap (dev->disk);
-
-      /* In case of LVM/RAID, check the member devices as well.  */
-      if (dev->disk->dev->memberlist)
-       list = dev->disk->dev->memberlist (dev->disk);
-      while (list)
-       {
-         probe_partmap (list->disk);
-         /* LVM on RAID  */
-         if (list->disk->dev->memberlist)
-           {
-             grub_disk_memberlist_t sub_list;
-
-             sub_list = list->disk->dev->memberlist (list->disk);
-             while (sub_list)
-               {
-                 probe_partmap (sub_list->disk);
-                 tmp = sub_list->next;
-                 free (sub_list);
-                 sub_list = tmp;
-               }
-           }
-         tmp = list->next;
-         free (list);
-         list = tmp;
-       }
+      printf ("\n");
       goto end;
     }
 
index 3a110f0281d2ff5900c964fac04d671379a86b86..0ebfd1f567bafb880d99b0a898f2bdc41fcd1b55 100644 (file)
@@ -111,6 +111,7 @@ for cipher_file in cipher_files:
         skip = False
         skip2 = False
         ismd = False
+        iscipher = False
         iscryptostart = False
         iscomma = False
         isglue = False
@@ -140,15 +141,22 @@ for cipher_file in cipher_files:
                     sg = s.groups()[0]
                     cryptolist.write (("%s: %s\n") % (sg, modname))
                     iscryptostart = False
-            if ismd:
+            if ismd or iscipher:
                 if not re.search (" *};", line) is None:
-                    if not mdblocksizes.has_key (mdname):
-                        print ("ERROR: Unknown digest blocksize: %s\n" % mdname)
-                        exit (1)
                     if not iscomma:
                         fw.write ("    ,\n")
-                    fw.write ("    .blocksize = %s\n" % mdblocksizes [mdname])
+                    fw.write ("#ifdef GRUB_UTIL\n");
+                    fw.write ("    .modname = \"%s\",\n" % modname);
+                    fw.write ("#endif\n");
+                    if ismd:
+                        if not mdblocksizes.has_key (mdname):
+                            print ("ERROR: Unknown digest blocksize: %s\n"
+                                   % mdname)
+                            exit (1)
+                            fw.write ("    .blocksize = %s\n"
+                                      % mdblocksizes [mdname])
                     ismd = False
+                    iscipher = False
                 iscomma = not re.search (",$", line) is None
             # Used only for selftests.
             m = re.match ("(static byte|static unsigned char) (weak_keys_chksum)\[[0-9]*\] =", line)
@@ -189,14 +197,18 @@ for cipher_file in cipher_files:
                 continue
             m = re.match ("gcry_cipher_spec_t", line)
             if isc and not m is None:
+                assert (not iscryptostart)
+                assert (not iscipher)
                 assert (not iscryptostart)
                 ciphername = line [len ("gcry_cipher_spec_t"):].strip ()
                 ciphername = re.match("[a-zA-Z0-9_]*",ciphername).group ()
                 ciphernames.append (ciphername)
+                iscipher = True
                 iscryptostart = True
             m = re.match ("gcry_md_spec_t", line)
             if isc and not m is None:
                 assert (not ismd)
+                assert (not iscipher)
                 assert (not iscryptostart)
                 mdname = line [len ("gcry_md_spec_t"):].strip ()
                 mdname = re.match("[a-zA-Z0-9_]*",mdname).group ()