luks grub-probe support

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2011-04-22 23:39:36 +02:00
parent fe32915a5e
commit 50ad7d9cae
5 changed files with 116 additions and 84 deletions

View file

@ -863,6 +863,38 @@ grub_luks_write (grub_disk_t disk __attribute ((unused)),
return GRUB_ERR_NOT_IMPLEMENTED_YET; 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 static void
luks_cleanup (void) luks_cleanup (void)
{ {
@ -953,6 +985,9 @@ static struct grub_disk_dev grub_luks_dev = {
.close = grub_luks_close, .close = grub_luks_close,
.read = grub_luks_read, .read = grub_luks_read,
.write = grub_luks_write, .write = grub_luks_write,
#ifdef GRUB_UTIL
.memberlist = grub_luks_memberlist,
#endif
.next = 0 .next = 0
}; };

View file

@ -126,6 +126,9 @@ typedef struct gcry_cipher_spec
gcry_cipher_decrypt_t decrypt; gcry_cipher_decrypt_t decrypt;
gcry_cipher_stencrypt_t stencrypt; gcry_cipher_stencrypt_t stencrypt;
gcry_cipher_stdecrypt_t stdecrypt; gcry_cipher_stdecrypt_t stdecrypt;
#ifdef GRUB_UTIL
const char *modname;
#endif
struct gcry_cipher_spec *next; struct gcry_cipher_spec *next;
} gcry_cipher_spec_t; } gcry_cipher_spec_t;
@ -161,6 +164,9 @@ typedef struct gcry_md_spec
grub_size_t contextsize; /* allocate this amount of context */ grub_size_t contextsize; /* allocate this amount of context */
/* Block size, needed for HMAC. */ /* Block size, needed for HMAC. */
grub_size_t blocksize; grub_size_t blocksize;
#ifdef GRUB_UTIL
const char *modname;
#endif
struct gcry_md_spec *next; struct gcry_md_spec *next;
} gcry_md_spec_t; } gcry_md_spec_t;

View 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); ssize_t grub_util_fd_read (int fd, char *buf, size_t len);
grub_err_t grub_err_t
grub_luks_cheat_mount (const char *sourcedev, const char *cheat); 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 */ #endif /* ! GRUB_BIOSDISK_MACHINE_UTIL_HEADER */

View file

@ -34,6 +34,7 @@
#include <grub/env.h> #include <grub/env.h>
#include <grub/raid.h> #include <grub/raid.h>
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/crypto.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
@ -63,15 +64,28 @@ static void
probe_partmap (grub_disk_t disk) probe_partmap (grub_disk_t disk)
{ {
grub_partition_t part; grub_partition_t part;
grub_disk_memberlist_t list = NULL, tmp;
if (disk->partition == NULL) if (disk->partition == NULL)
{ {
grub_util_info ("no partition map found for %s", disk->name); grub_util_info ("no partition map found for %s", disk->name);
return;
} }
for (part = disk->partition; part; part = part->parent) 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 static int
@ -88,6 +102,45 @@ probe_raid_level (grub_disk_t disk)
return ((struct grub_raid_array *) disk->data)->level; 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 static void
probe (const char *path, char *device_name) probe (const char *path, char *device_name)
{ {
@ -136,91 +189,16 @@ probe (const char *path, char *device_name)
if (print == PRINT_ABSTRACTION) if (print == PRINT_ABSTRACTION)
{ {
grub_disk_memberlist_t list = NULL, tmp; probe_abstraction (dev->disk);
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 ");
printf ("\n"); printf ("\n");
goto end; goto end;
} }
if (print == PRINT_PARTMAP) if (print == PRINT_PARTMAP)
{ {
grub_disk_memberlist_t list = NULL, tmp;
/* Check if dev->disk itself is contained in a partmap. */ /* Check if dev->disk itself is contained in a partmap. */
probe_partmap (dev->disk); probe_partmap (dev->disk);
printf ("\n");
/* 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;
}
goto end; goto end;
} }

View file

@ -111,6 +111,7 @@ for cipher_file in cipher_files:
skip = False skip = False
skip2 = False skip2 = False
ismd = False ismd = False
iscipher = False
iscryptostart = False iscryptostart = False
iscomma = False iscomma = False
isglue = False isglue = False
@ -140,15 +141,22 @@ for cipher_file in cipher_files:
sg = s.groups()[0] sg = s.groups()[0]
cryptolist.write (("%s: %s\n") % (sg, modname)) cryptolist.write (("%s: %s\n") % (sg, modname))
iscryptostart = False iscryptostart = False
if ismd: if ismd or iscipher:
if not re.search (" *};", line) is None: 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: if not iscomma:
fw.write (" ,\n") 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 ismd = False
iscipher = False
iscomma = not re.search (",$", line) is None iscomma = not re.search (",$", line) is None
# Used only for selftests. # Used only for selftests.
m = re.match ("(static byte|static unsigned char) (weak_keys_chksum)\[[0-9]*\] =", line) 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 continue
m = re.match ("gcry_cipher_spec_t", line) m = re.match ("gcry_cipher_spec_t", line)
if isc and not m is None: if isc and not m is None:
assert (not iscryptostart)
assert (not iscipher)
assert (not iscryptostart) assert (not iscryptostart)
ciphername = line [len ("gcry_cipher_spec_t"):].strip () ciphername = line [len ("gcry_cipher_spec_t"):].strip ()
ciphername = re.match("[a-zA-Z0-9_]*",ciphername).group () ciphername = re.match("[a-zA-Z0-9_]*",ciphername).group ()
ciphernames.append (ciphername) ciphernames.append (ciphername)
iscipher = True
iscryptostart = True iscryptostart = True
m = re.match ("gcry_md_spec_t", line) m = re.match ("gcry_md_spec_t", line)
if isc and not m is None: if isc and not m is None:
assert (not ismd) assert (not ismd)
assert (not iscipher)
assert (not iscryptostart) assert (not iscryptostart)
mdname = line [len ("gcry_md_spec_t"):].strip () mdname = line [len ("gcry_md_spec_t"):].strip ()
mdname = re.match("[a-zA-Z0-9_]*",mdname).group () mdname = re.match("[a-zA-Z0-9_]*",mdname).group ()