Hi, I'd like to first say thanks to the additions you made to cryptomount. I
came across your patches 2-3 months ago when I was looking to do FDE including
/boot for LVM on LUKS. I created a few patches outlined with their features
below. I would have messaged sooner but I didn't know about these posts on
grub-help until after finding the link from your github. After also coming
across the problem of having no way to reliably predict what a device
(hd0,msdos1) will map to, I ended up creating an add-on command, that uses the
partition UUID/GUID, to search (--pt-uuid) and an accompanying module
search.pt_uuid. These two commands mirror the search --fs-uuid and
search.fs_uuid where given a uuid it will return the device. When given a
disk/partition UUID/GUID that corresponds to a disk that is either a biosdisk
or efidisk, or a partition with a partmap name of either "msdos" or "gpt" on
one of the previous disks it will return that device.
Patch 1 stops search from printing same device twice if called multiple times.
Patch 2 allows this--->Added module search_pt_uuid. When given a disk/part
UUID/GUID it will return the associated device.
On a biosdisk/mbr it will return the same value for the device
(hd0)/(hd0,msdos1) as lsblk -o PARTUUID returns. This should be the same as the
NT disk signature located at mbr.code[440] for 4 bytes in little endian format
plus the partition number appended if applicable xxxxxxxx-yy. On an efidisk/gpt
it will return the same value for the device (hd0)/(hd0,gpt1) as lsblk -o
PARTUUID returns. This will be the disk/partition UUID/GUID.
An example of using this command inside load.cfg or directly on the grub
command line. This example is for a detached header LUKS volume on (hdX,msdosY)
which corresponds to a partuuid of 12345678-01 with the header file stored on a
plain text partition either on the same device or a different one with a
fs_uuid=5432-7654.
From your site this would look like
cryptomount -H (hd0,1)/header hd1,1
But with my patch it would be.
search.fs_uuid 5432-7654 header_file_device ----Line for setting (hd0,1)
search.pt_uuid 12345678-01 cryptodevice ----Line for setting (hd1,1)
cryptomount ($cryptodevice) --header=($header_file_device)/header.bin
Or if the header file is in a separate encrypted LUKS volume. LUKS volume UUID
is 12345678-1234-1234-1234-1234567890ab. When the LUKS volume is open the
mounted fs_uuid is 11112222-3333-4444-5555-123456654321 for a ext4 partition.
cryptomount -u 12345678-1234-1234-1234-1234567890ab ----Line for opening the
LUKS volume with the header file in it.
search.fs_uuid 11112222-3333-4444-5555-123456654321 header_file_device ----Line
for setting (hd0,1)
search.pt_uuid 12345678-01 cryptodevice ----Line for setting (hd1,1)
cryptomount ($cryptodevice) --header=($header_file_device)/header.bin ----Line
for opening LUKS volume with /boot
Patch 3 allows this---->Inclusion of altered "load.cfg" to
grub-install/mkconfig.
mattle_opts (More Advanced Than Traditional LUKS Encryption Options). Added
mattle_opts.cfg file which allows the user to customize load.cfg to allow for
extra options for cryptomount. mattle_opts.cfg is located in user-defined/etc/
folder. Same folder as crypttab and fstab. Only affects cryptomount options in
load.cfg and only if GRUB_ENABLE_CRYPTODISK_MATTLE_OPTS=y is set in grub.cfg.
If not set then normal 'cryptomount -u $uuid' is printed to load.cfg. I altered
grub-install and grub-mkconfig to allow it to have essentially an alternate
load.cfg (mattle_opts.cfg) to be easily editted by the user prior to running
grub-install to allow grub-install to then read from this file and then fprint
this alternate files contents into load.cfg to allow your alternate cryptomount
commands to be run during boot up. This does not interfere with any of
grub-install's other actions with load.cfg it merely replaces the normal
'cryptomount -u $uuid' that is printed from grub-install into load.cfg. This
makes it so you don't have to do grub-mkimage and the associated commands. Also
added command line options for grub-install/mkconfig to allow an alternate
mattle_opts.cfg to allow the user to quickly install grub to another device
without having to modify the default mattle_opts.cfg.
Patch 4 allows this----> grub-install and grub-mkconfig magic for /boot on a
detached header LUKS volume
Added grub-install magic for a crypto-device that is on a disk with either an
msdos or gpt partition table and either on a biosdisk or efidisk. Grub-install
magic works with grub-mkconfig for booting a detached header LUKS volume when
used with --crypto-device and --crypto-header. By reading the actual header
file that corresponds to that partitcular LUKS volume this allows
grub-install/mkconfig to have the proper modules loaded by grub. The
grub-install command for /boot located on /dev/sda1 where /dev/sda1 is a
detached header LUKS volume and the header is located on the root / directory
and we are installing to /dev/sda.
grub-install --boot-directory=/boot --crypto-device=/dev/sda1
--crypto-header=/header.bin /dev/sda
grub-mkconfig -o /boot/grub/grub.cfg
For above patch 4 grub-install needs to be run prior to grub-mkconfig so the
proper *.cfg files are created and configured to allow cryptodisk.c and luk.c
to create a cryptodisk based off the stated crypto-device.
A few notes: mattle_opts.cfg is read only by grub-install/mkconfig and must be
edited outside of grub using nano/text editor.
The command line options for grub-install do not alter mattle_opts.cfg so if
installing to two different devices i.e a usb stick and a hard drive,
mattle_opts.cfg may need to be edited. i.e. depending on where header/key files
are stored.
The easiest setup seems to be /boot/grub on the rootfs and only have the
applicable header/key files on the usb either in plain text or in an encrypted
partition, and have the boot.img and core.img installed to the usb as well.
The changes to luks.c should only be in effect for grub utils and not in effect
during booting.
I've also included your first 3 LUKS patches as they would apply after my
patches. These patches are based off of grub-2.02-rc2. I tested these to work
on x64 version of Ubuntu 16.04 LTS running bios. For the efi with gpt it was
tested on a virtual machine x64 Ubuntu 16.04 LTS.
Best regards,
Matt
From a8271b1a4ba07cbf1af4406b67ea802f8584d6ed Mon Sep 17 00:00:00 2001
From: matt <[email protected]>
Date: Sat, 8 Apr 2017 08:26:26 -0400
Subject: [PATCH 4/7] Added grub-install/mkconfig magic for detached header
LUKS
---
grub-core/disk/luks.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++
util/grub-install.c | 84 +++++++++++++++++++++++++++++++++-
2 files changed, 207 insertions(+), 1 deletion(-)
diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c
index 86c50c6..ab07ba9 100644
--- a/grub-core/disk/luks.c
+++ b/grub-core/disk/luks.c
@@ -91,6 +91,130 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
/* Read the LUKS header. */
err = grub_disk_read (disk, 0, 0, sizeof (header), &header);
+
+
+#ifdef GRUB_UTIL
+
+ int have_crypto_device = 0;
+ if (disk->partition)
+ {
+ char *partuuid = 0;
+ char *crypto_device_name = 0;
+ crypto_device_name = grub_xasprintf ("%s,%s%d",disk->name, disk->partition->partmap->name,disk->partition->number + 1);
+
+ /* Obtain the partition table from the root device. */
+ grub_partition_t crypto_p = disk->partition;
+ if (crypto_p && (grub_strcmp (crypto_p->partmap->name, "msdos") == 0 || grub_strcmp (crypto_p->partmap->name, "gpt") == 0 ))
+ {
+ if (disk->partition->number + 1)
+ {
+ partuuid = grub_strdup (crypto_p->partuuid);
+ if (partuuid)
+ {
+ static FILE *fpcrypto_ptuuid_f; /*file pointer to be used as the local program name for crypto device ptuuid */
+ static char *crypto_ptuuid_name; /*absolute path for crypto_ptuuid file*/
+ crypto_ptuuid_name = grub_util_path_concat (2, GRUB_SYSCONFDIR, "crypto_ptuuid.cfg");
+ static char fpcrypto_contents[256];
+ static char fpcrypto_contents_2[256];
+ int i = 0;
+ int k = 0;
+ fpcrypto_ptuuid_f = fopen (crypto_ptuuid_name, "r");
+
+ if (fpcrypto_ptuuid_f)
+ {
+ while(1)
+ {
+ k = fgetc(fpcrypto_ptuuid_f);
+ fpcrypto_contents[i] = k;
+ if ((k == '\n') || feof(fpcrypto_ptuuid_f))
+ break;
+ i++;
+ }
+ fpcrypto_contents[i] = '\0';
+ i = 0;
+ if (!feof(fpcrypto_ptuuid_f))
+ while(1)
+ {
+ k = fgetc(fpcrypto_ptuuid_f);
+ fpcrypto_contents_2[i] = k;
+ if ((k == '\n') || feof(fpcrypto_ptuuid_f))
+ break;
+ i++;
+ }
+ fpcrypto_contents_2[i] = '\0';
+ if (grub_strcmp (partuuid, fpcrypto_contents) == 0)
+ if (grub_strcmp (crypto_device_name, fpcrypto_contents_2) == 0)
+ {
+ have_crypto_device = 1;
+ }
+ }
+ fclose (fpcrypto_ptuuid_f); /*closing file*/
+ grub_free (crypto_ptuuid_name); /*freeing crypto_ptuuid_name*/
+ }
+ }
+ }
+ grub_free (partuuid);
+ grub_free (crypto_device_name);
+ }
+ if (have_crypto_device)
+ {
+ /*If no header file is given with grub-install then we
+ use a dummy header file. This does not write data to
+ the disk. It is only used to make grub-install think this
+ is a cryptodisk. Since it really is but without a header
+ grub-install does not know this.*/
+ grub_uint8_t num[6] = {'L','U','K','S',0xba,0xbe};
+ grub_memcpy (header.magic, num, sizeof(num));
+ header.version = 0x0100;
+ grub_strcpy (header.cipherName, "aes");
+ grub_strcpy (header.cipherMode, "xts-plain64");
+ grub_strcpy (header.hashSpec, "sha1");
+ header.payloadOffset = 0x10000000;
+ header.keyBytes = 0x20000000;
+ grub_uint32_t alter_mkDigest[5] = {0x00,0x00,0x00,0x00,0x00};
+ grub_memcpy (header.mkDigest,alter_mkDigest, sizeof(alter_mkDigest));
+ grub_uint64_t alter_mkDigestSalt[4] = {0x00,0x00,0x00,0x00};
+ grub_memcpy (header.mkDigestSalt,alter_mkDigestSalt, sizeof(alter_mkDigestSalt));
+ header.mkDigestIterations = 0x0020;
+ grub_strcpy (header.uuid, "01234567-1234-1234-1234-0123456789ab");
+
+ /*This is for reading a header file in from grub-install for a detached header cryptodisk*/
+ static FILE *fpcrypto_header_f; /*file pointer to be used as the local program name for crypto device ptuuid */
+ static char *crypto_header_name; /*absolute path for crypto_ptuuid file*/
+ crypto_header_name = grub_util_path_concat (2, GRUB_SYSCONFDIR, "crypto_header.cfg");
+ fpcrypto_header_f = fopen (crypto_header_name, "r");
+
+ if (fpcrypto_header_f)
+ {
+ static char header_file_name[256]; /*Length of the header file name including path */
+ int i = 0;
+ int k = 0;
+ static FILE *fpcrypto_detached_header_f;
+
+ while(1)
+ {
+ k = fgetc(fpcrypto_header_f);
+ header_file_name[i] = k;
+ if ((k == '\n') || feof(fpcrypto_header_f))
+ break;
+ i++;
+ }
+ header_file_name[i] = '\0';
+ if (header_file_name[0] != '\0') /*In case the file is opened but empty. If empty then use above dummy header. */
+ {
+ fpcrypto_detached_header_f = fopen (header_file_name, "r");
+ if (fread (&header, 1, sizeof (header), fpcrypto_detached_header_f) != sizeof (header))
+ err = GRUB_ERR_READ_ERROR;
+ fclose (fpcrypto_detached_header_f);
+ }
+ }
+ fclose (fpcrypto_header_f);
+ if (crypto_header_name)
+ grub_free (crypto_header_name);
+ }
+#endif
+
+
if (err)
{
if (err == GRUB_ERR_OUT_OF_RANGE)
diff --git a/util/grub-install.c b/util/grub-install.c
index 109a4e2..4e8803e 100644
--- a/util/grub-install.c
+++ b/util/grub-install.c
@@ -80,6 +80,8 @@ static char *label_bgcolor;
static char *product_version;
static int add_rs_codes = 1;
static char *mattle_opts_file = NULL;
+static char *crypto_device = NULL;
+static char *crypto_header = NULL;
enum
{
@@ -111,7 +113,9 @@ enum
OPTION_LABEL_COLOR,
OPTION_LABEL_BGCOLOR,
OPTION_PRODUCT_VERSION,
- OPTION_MATTLE_OPTS_FILE
+ OPTION_MATTLE_OPTS_FILE,
+ OPTION_CRYPTO_DEVICE,
+ OPTION_CRYPTO_HEADER
};
static int fs_probe = 1;
@@ -246,6 +250,16 @@ argp_parser (int key, char *arg, struct argp_state *state)
mattle_opts_file = xstrdup (arg);
return 0;
+ case OPTION_CRYPTO_DEVICE:
+ free (crypto_device);
+ crypto_device = xstrdup (arg);
+ return 0;
+
+ case OPTION_CRYPTO_HEADER:
+ free (crypto_header);
+ crypto_header = xstrdup (arg);
+ return 0;
+
default:
return ARGP_ERR_UNKNOWN;
}
@@ -311,6 +325,12 @@ static struct argp_option options[] = {
{"product-version", OPTION_PRODUCT_VERSION, N_("STRING"), 0, N_("use STRING as product version"), 2},
{"mattle-opts-file", OPTION_MATTLE_OPTS_FILE, N_("FILE"), 0,
N_("use FILE instead of using %smattle_opts.cfg "), 2},
+ {"crypto-device", OPTION_CRYPTO_DEVICE, N_("DEVICE"), 0, N_("DEVICE is the LUKS crypto "
+ "volume with a detached header that the root filesystem is on. i.e."
+ " LUKS volume is on /dev/sda1 -> /dev/mapper/luks-volume and /boot may be on that device. "
+ "Usage --crypto-device=/dev/sdXY"), 2},
+ {"crypto-header", OPTION_CRYPTO_HEADER, N_("FILE"), 0, N_("FILE is the detached LUKS header file for --crypto-device=DEVICE."
+ " A copy of FILE needs to be stored on a different device and must be accessible in order to boot the DEVICE."), 2},
{0, 0, 0, 0, 0, 0}
};
@@ -1188,6 +1208,68 @@ main (int argc, char *argv[])
grub_install_mkdir_p (efidir);
}
+ /*Here is the start to adding code for ability to do grub-install on a detached header
+ LUKS volume i.e --boot-directory=/boot and /boot resides on detached header
+ LUKS volume. This is placed outside the if (crypto_device) to clear file from
+ seperate grub-install calls. If placed inside then from each call crypto_ptuuid file will
+ retain the info and luks.c will access it even if --crypto-device is not called.*/
+ static FILE *fpcrypto_ptuuid_f; /*file pointer to be used as the local program name for crypto device uuid*/
+ static char *crypto_ptuuid_name; /*absolute path for crypto_ptuuid file*/
+ crypto_ptuuid_name = grub_util_path_concat (2, GRUB_SYSCONFDIR, "crypto_ptuuid.cfg");
+ fpcrypto_ptuuid_f = grub_util_fopen (crypto_ptuuid_name, "wb");
+
+ if (crypto_device)
+ {
+ grub_device_t crypto_dev = NULL;
+ char *crypto_grub_devname;
+ crypto_grub_devname = grub_util_get_grub_dev (crypto_device);
+ if (crypto_grub_devname)
+ {
+ char *partuuid = 0;
+ crypto_dev = grub_device_open (crypto_grub_devname);
+ if (crypto_dev && crypto_dev->disk)
+ {
+ grub_disk_t crypto_disk = crypto_dev->disk;
+ grub_partition_t crypto_p = crypto_disk->partition;
+ if (crypto_disk->partition)
+ {
+ /*This means that it wont find devices like /dev/sdX only /dev/sdXY
+ And only if /dev/sdXY is an msdos or gpt type partition*/
+ if (crypto_p && (grub_strcmp (crypto_p->partmap->name, "msdos") == 0 || grub_strcmp (crypto_p->partmap->name, "gpt") == 0 ))
+ {
+ if (crypto_disk->partition->number + 1)
+ {
+ partuuid = grub_strdup (crypto_p->partuuid);
+ if (partuuid)
+ {
+ fprintf (fpcrypto_ptuuid_f, "%s\n%s", partuuid, crypto_grub_devname);
+ static FILE *fpcrypto_header_f; /*file pointer to be used as the local program name for crypto device uuid*/
+ static char *crypto_header_name; /*absolute path for crypto_ptuuid file*/
+ crypto_header_name = grub_util_path_concat (2, GRUB_SYSCONFDIR, "crypto_header.cfg");
+ fpcrypto_header_f = grub_util_fopen (crypto_header_name, "wb");
+ if (crypto_header)
+ {
+ fprintf (fpcrypto_header_f, "%s\n", crypto_header);
+ }
+
+ fclose (fpcrypto_header_f); /*closing file*/
+ free (crypto_header_name); /*freeing crypto_ptuuid_name*/
+ }
+ grub_free (partuuid);
+ }
+ }
+ }
+ }
+ }
+ grub_free (crypto_grub_devname);
+ if (crypto_dev)
+ grub_device_close (crypto_dev);
+ }
+
+ fclose (fpcrypto_ptuuid_f); /*closing file*/
+ free (crypto_ptuuid_name); /*freeing crypto_ptuuid_name*/
+
+
if (platform == GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275)
{
int is_guess = 0;
--
2.7.4
From c2b0e32591e8bcb6358a93318f99698ad62f61c9 Mon Sep 17 00:00:00 2001
From: matt <[email protected]>
Date: Sat, 8 Apr 2017 08:56:21 -0400
Subject: [PATCH 7/7] Added LUKS patch 3
---
grub-core/disk/luks.c | 258 ++++++++++++++++++++++++++------------------------
1 file changed, 133 insertions(+), 125 deletions(-)
diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c
index a4f2311..c776261 100644
--- a/grub-core/disk/luks.c
+++ b/grub-core/disk/luks.c
@@ -445,10 +445,10 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
static grub_err_t
luks_recover_key (grub_disk_t source,
- grub_cryptodisk_t dev,
- grub_file_t hdr,
- grub_uint8_t *keyfile_bytes,
- grub_size_t keyfile_bytes_size)
+ grub_cryptodisk_t dev,
+ grub_file_t hdr,
+ grub_uint8_t *keyfile_bytes,
+ grub_size_t keyfile_bytes_size)
{
struct grub_luks_phdr header;
grub_size_t keysize;
@@ -463,6 +463,7 @@ luks_recover_key (grub_disk_t source,
grub_size_t max_stripes = 1;
char *tmp;
grub_uint32_t sector;
+ unsigned attempts = 2;
err = GRUB_ERR_NONE;
@@ -485,151 +486,158 @@ luks_recover_key (grub_disk_t source,
for (i = 0; i < ARRAY_SIZE (header.keyblock); i++)
if (grub_be_to_cpu32 (header.keyblock[i].active) == LUKS_KEY_ENABLED
- && grub_be_to_cpu32 (header.keyblock[i].stripes) > max_stripes)
+ && grub_be_to_cpu32 (header.keyblock[i].stripes) > max_stripes)
max_stripes = grub_be_to_cpu32 (header.keyblock[i].stripes);
split_key = grub_malloc (keysize * max_stripes);
if (!split_key)
return grub_errno;
- if (keyfile_bytes)
+ while (attempts)
{
- /* Use bytestring from key file as passphrase */
- passphrase = keyfile_bytes;
- passphrase_length = keyfile_bytes_size;
- }
- else
- {
- /* Get the passphrase from the user. */
- tmp = NULL;
- if (source->partition)
- tmp = grub_partition_get_name (source->partition);
- grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name,
- source->partition ? "," : "", tmp ? : "", dev->uuid);
- grub_free (tmp);
- if (!grub_password_get (interactive_passphrase, MAX_PASSPHRASE))
+ if (keyfile_bytes)
{
- grub_free (split_key);
- return grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied");
+ /* Use bytestring from key file as passphrase */
+ passphrase = keyfile_bytes;
+ passphrase_length = keyfile_bytes_size;
+ keyfile_bytes = NULL; /* use it only once */
}
+ else
+ {
+ /* Get the passphrase from the user. */
+ tmp = NULL;
+ if (source->partition)
+ tmp = grub_partition_get_name (source->partition);
+ grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name,
+ source->partition ? "," : "", tmp ? : "", dev->uuid);
+ grub_free (tmp);
+ if (!grub_password_get (interactive_passphrase, MAX_PASSPHRASE))
+ {
+ grub_free (split_key);
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied");
+ }
- passphrase = (grub_uint8_t *)interactive_passphrase;
- passphrase_length = grub_strlen (interactive_passphrase);
+ passphrase = (grub_uint8_t *)interactive_passphrase;
+ passphrase_length = grub_strlen (interactive_passphrase);
- }
+ }
- /* Try to recover master key from each active keyslot. */
- for (i = 0; i < ARRAY_SIZE (header.keyblock); i++)
- {
- gcry_err_code_t gcry_err;
- grub_uint8_t candidate_key[GRUB_CRYPTODISK_MAX_KEYLEN];
- grub_uint8_t digest[GRUB_CRYPTODISK_MAX_KEYLEN];
-
- /* Check if keyslot is enabled. */
- if (grub_be_to_cpu32 (header.keyblock[i].active) != LUKS_KEY_ENABLED)
- continue;
-
- grub_dprintf ("luks", "Trying keyslot %d\n", i);
-
- /* Calculate the PBKDF2 of the user supplied passphrase. */
- gcry_err = grub_crypto_pbkdf2 (dev->hash, (grub_uint8_t *) passphrase,
- passphrase_length,
- header.keyblock[i].passwordSalt,
- sizeof (header.keyblock[i].passwordSalt),
- grub_be_to_cpu32 (header.keyblock[i].
- passwordIterations),
- digest, keysize);
-
- if (gcry_err)
- {
- grub_free (split_key);
- return grub_crypto_gcry_error (gcry_err);
- }
+ /* Try to recover master key from each active keyslot. */
+ for (i = 0; i < ARRAY_SIZE (header.keyblock); i++)
+ {
+ gcry_err_code_t gcry_err;
+ grub_uint8_t candidate_key[GRUB_CRYPTODISK_MAX_KEYLEN];
+ grub_uint8_t digest[GRUB_CRYPTODISK_MAX_KEYLEN];
+
+ /* Check if keyslot is enabled. */
+ if (grub_be_to_cpu32 (header.keyblock[i].active) != LUKS_KEY_ENABLED)
+ continue;
+
+ grub_dprintf ("luks", "Trying keyslot %d\n", i);
+
+ /* Calculate the PBKDF2 of the user supplied passphrase. */
+ gcry_err = grub_crypto_pbkdf2 (dev->hash, (grub_uint8_t *) passphrase,
+ passphrase_length,
+ header.keyblock[i].passwordSalt,
+ sizeof (header.keyblock[i].passwordSalt),
+ grub_be_to_cpu32 (header.keyblock[i].
+ passwordIterations),
+ digest, keysize);
+
+ if (gcry_err)
+ {
+ grub_free (split_key);
+ return grub_crypto_gcry_error (gcry_err);
+ }
- grub_dprintf ("luks", "PBKDF2 done\n");
+ grub_dprintf ("luks", "PBKDF2 done\n");
- gcry_err = grub_cryptodisk_setkey (dev, digest, keysize);
- if (gcry_err)
- {
- grub_free (split_key);
- return grub_crypto_gcry_error (gcry_err);
- }
+ gcry_err = grub_cryptodisk_setkey (dev, digest, keysize);
+ if (gcry_err)
+ {
+ grub_free (split_key);
+ return grub_crypto_gcry_error (gcry_err);
+ }
- sector = grub_be_to_cpu32 (header.keyblock[i].keyMaterialOffset);
- length = (keysize * grub_be_to_cpu32 (header.keyblock[i].stripes));
+ sector = grub_be_to_cpu32 (header.keyblock[i].keyMaterialOffset);
+ length = (keysize * grub_be_to_cpu32 (header.keyblock[i].stripes));
- /* Read and decrypt the key material from the disk. */
- if (hdr)
- {
- grub_file_seek (hdr, sector * 512);
- if (grub_file_read (hdr, split_key, length) != (grub_ssize_t)length)
- err = GRUB_ERR_READ_ERROR;
- }
- else
- err = grub_disk_read (source, sector, 0, length, split_key);
- if (err)
- {
- grub_free (split_key);
- return err;
- }
+ /* Read and decrypt the key material from the disk. */
+ if (hdr)
+ {
+ grub_file_seek (hdr, sector * 512);
+ if (grub_file_read (hdr, split_key, length) != (grub_ssize_t)length)
+ err = GRUB_ERR_READ_ERROR;
+ }
+ else
+ err = grub_disk_read (source, sector, 0, length, split_key);
+ if (err)
+ {
+ grub_free (split_key);
+ return err;
+ }
- gcry_err = grub_cryptodisk_decrypt (dev, split_key, length, 0);
- if (gcry_err)
- {
- grub_free (split_key);
- return grub_crypto_gcry_error (gcry_err);
- }
+ gcry_err = grub_cryptodisk_decrypt (dev, split_key, length, 0);
+ if (gcry_err)
+ {
+ grub_free (split_key);
+ return grub_crypto_gcry_error (gcry_err);
+ }
- /* Merge the decrypted key material to get the candidate master key. */
- gcry_err = AF_merge (dev->hash, split_key, candidate_key, keysize,
- grub_be_to_cpu32 (header.keyblock[i].stripes));
- if (gcry_err)
- {
- grub_free (split_key);
- return grub_crypto_gcry_error (gcry_err);
- }
+ /* Merge the decrypted key material to get the candidate master key. */
+ gcry_err = AF_merge (dev->hash, split_key, candidate_key, keysize,
+ grub_be_to_cpu32 (header.keyblock[i].stripes));
+ if (gcry_err)
+ {
+ grub_free (split_key);
+ return grub_crypto_gcry_error (gcry_err);
+ }
- grub_dprintf ("luks", "candidate key recovered\n");
-
- /* Calculate the PBKDF2 of the candidate master key. */
- gcry_err = grub_crypto_pbkdf2 (dev->hash, candidate_key,
- grub_be_to_cpu32 (header.keyBytes),
- header.mkDigestSalt,
- sizeof (header.mkDigestSalt),
- grub_be_to_cpu32
- (header.mkDigestIterations),
- candidate_digest,
- sizeof (candidate_digest));
- if (gcry_err)
- {
- grub_free (split_key);
- return grub_crypto_gcry_error (gcry_err);
- }
+ grub_dprintf ("luks", "candidate key recovered\n");
+
+ /* Calculate the PBKDF2 of the candidate master key. */
+ gcry_err = grub_crypto_pbkdf2 (dev->hash, candidate_key,
+ grub_be_to_cpu32 (header.keyBytes),
+ header.mkDigestSalt,
+ sizeof (header.mkDigestSalt),
+ grub_be_to_cpu32
+ (header.mkDigestIterations),
+ candidate_digest,
+ sizeof (candidate_digest));
+ if (gcry_err)
+ {
+ grub_free (split_key);
+ return grub_crypto_gcry_error (gcry_err);
+ }
- /* Compare the calculated PBKDF2 to the digest stored
- in the header to see if it's correct. */
- if (grub_memcmp (candidate_digest, header.mkDigest,
- sizeof (header.mkDigest)) != 0)
- {
- grub_dprintf ("luks", "bad digest\n");
- continue;
- }
+ /* Compare the calculated PBKDF2 to the digest stored
+ in the header to see if it's correct. */
+ if (grub_memcmp (candidate_digest, header.mkDigest,
+ sizeof (header.mkDigest)) != 0)
+ {
+ grub_dprintf ("luks", "bad digest\n");
+ continue;
+ }
- /* TRANSLATORS: It's a cryptographic key slot: one element of an array
- where each element is either empty or holds a key. */
- grub_printf_ (N_("Slot %d opened\n"), i);
+ /* TRANSLATORS: It's a cryptographic key slot: one element of an array
+ where each element is either empty or holds a key. */
+ grub_printf_ (N_("Slot %d opened\n"), i);
- /* Set the master key. */
- gcry_err = grub_cryptodisk_setkey (dev, candidate_key, keysize);
- if (gcry_err)
- {
- grub_free (split_key);
- return grub_crypto_gcry_error (gcry_err);
- }
+ /* Set the master key. */
+ gcry_err = grub_cryptodisk_setkey (dev, candidate_key, keysize);
+ if (gcry_err)
+ {
+ grub_free (split_key);
+ return grub_crypto_gcry_error (gcry_err);
+ }
- grub_free (split_key);
+ grub_free (split_key);
- return GRUB_ERR_NONE;
+ return GRUB_ERR_NONE;
+ }
+ grub_printf_ (N_("Failed to decrypt master key.\n"));
+ if (--attempts) grub_printf_ (N_("%u attempt%s remaining.\n"), attempts,
+ (attempts==1) ? "" : "s");
}
grub_free (split_key);
--
2.7.4
From 2313466ce3ab7b3777db46180367ff8010962748 Mon Sep 17 00:00:00 2001
From: matt <[email protected]>
Date: Sat, 8 Apr 2017 08:50:45 -0400
Subject: [PATCH 5/7] Added LUKS patch 1
---
grub-core/disk/cryptodisk.c | 22 ++++++++++++++++++----
grub-core/disk/geli.c | 7 +++++--
grub-core/disk/luks.c | 45 +++++++++++++++++++++++++++++++++++++--------
include/grub/cryptodisk.h | 5 +++--
4 files changed, 63 insertions(+), 16 deletions(-)
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
index 1e03a09..dd8870d 100644
--- a/grub-core/disk/cryptodisk.c
+++ b/grub-core/disk/cryptodisk.c
@@ -41,6 +41,7 @@ static const struct grub_arg_option options[] =
/* TRANSLATORS: It's still restricted to cryptodisks only. */
{"all", 'a', 0, N_("Mount all."), 0, 0},
{"boot", 'b', 0, N_("Mount all volumes with `boot' flag set."), 0, 0},
+ {"header", 'H', 0, N_("Read LUKS header from file"), 0, ARG_TYPE_STRING},
{0, 0, 0, 0, 0, 0}
};
@@ -808,6 +809,7 @@ grub_util_cryptodisk_get_uuid (grub_disk_t disk)
static int check_boot, have_it;
static char *search_uuid;
+static grub_file_t hdr;
static void
cryptodisk_close (grub_cryptodisk_t dev)
@@ -832,13 +834,13 @@ grub_cryptodisk_scan_device_real (const char *name, grub_disk_t source)
FOR_CRYPTODISK_DEVS (cr)
{
- dev = cr->scan (source, search_uuid, check_boot);
+ dev = cr->scan (source, search_uuid, check_boot, hdr);
if (grub_errno)
return grub_errno;
if (!dev)
continue;
- err = cr->recover_key (source, dev);
+ err = cr->recover_key (source, dev, hdr);
if (err)
{
cryptodisk_close (dev);
@@ -879,7 +881,7 @@ grub_cryptodisk_cheat_mount (const char *sourcedev, const char *cheat)
FOR_CRYPTODISK_DEVS (cr)
{
- dev = cr->scan (source, search_uuid, check_boot);
+ dev = cr->scan (source, search_uuid, check_boot,0);
if (grub_errno)
return grub_errno;
if (!dev)
@@ -933,6 +935,18 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
if (argc < 1 && !state[1].set && !state[2].set)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");
+ if (state[3].set) /* LUKS detached header */
+ {
+ if (state[0].set) /* Cannot use UUID lookup with detached header */
+ return GRUB_ERR_BAD_ARGUMENT;
+
+ hdr = grub_file_open (state[3].arg);
+ if (!hdr)
+ return grub_errno;
+ }
+ else
+ hdr = NULL;
+
have_it = 0;
if (state[0].set)
{
@@ -1140,7 +1154,7 @@ GRUB_MOD_INIT (cryptodisk)
{
grub_disk_dev_register (&grub_cryptodisk_dev);
cmd = grub_register_extcmd ("cryptomount", grub_cmd_cryptomount, 0,
- N_("SOURCE|-u UUID|-a|-b"),
+ N_("SOURCE|-u UUID|-a|-b|-H file"),
N_("Mount a crypto device."), options);
grub_procfs_register ("luks_script", &luks_script);
}
diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c
index e9d2329..f4394eb 100644
--- a/grub-core/disk/geli.c
+++ b/grub-core/disk/geli.c
@@ -52,6 +52,7 @@
#include <grub/dl.h>
#include <grub/err.h>
#include <grub/disk.h>
+#include <grub/file.h>
#include <grub/crypto.h>
#include <grub/partition.h>
#include <grub/i18n.h>
@@ -243,7 +244,8 @@ grub_util_get_geli_uuid (const char *dev)
static grub_cryptodisk_t
configure_ciphers (grub_disk_t disk, const char *check_uuid,
- int boot_only)
+ int boot_only,
+ grub_file_t hdr __attribute__ ((unused)) )
{
grub_cryptodisk_t newdev;
struct grub_geli_phdr header;
@@ -398,7 +400,8 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
}
static grub_err_t
-recover_key (grub_disk_t source, grub_cryptodisk_t dev)
+recover_key (grub_disk_t source, grub_cryptodisk_t dev,
+ grub_file_t hdr __attribute__ ((unused)) )
{
grub_size_t keysize;
grub_uint8_t digest[GRUB_CRYPTO_MAX_MDLEN];
diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c
index ab07ba9..9a39fb5 100644
--- a/grub-core/disk/luks.c
+++ b/grub-core/disk/luks.c
@@ -23,6 +23,7 @@
#include <grub/dl.h>
#include <grub/err.h>
#include <grub/disk.h>
+#include <grub/file.h>
#include <grub/crypto.h>
#include <grub/partition.h>
#include <grub/i18n.h>
@@ -66,7 +67,7 @@ gcry_err_code_t AF_merge (const gcry_md_spec_t * hash, grub_uint8_t * src,
static grub_cryptodisk_t
configure_ciphers (grub_disk_t disk, const char *check_uuid,
- int check_boot)
+ int check_boot, grub_file_t hdr)
{
grub_cryptodisk_t newdev;
const char *iptr;
@@ -86,11 +87,21 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
int benbi_log = 0;
grub_err_t err;
+ err = GRUB_ERR_NONE;
+
if (check_boot)
return NULL;
/* Read the LUKS header. */
- err = grub_disk_read (disk, 0, 0, sizeof (header), &header);
+ if (hdr)
+ {
+ grub_file_seek (hdr, 0);
+ if (grub_file_read (hdr, &header, sizeof (header)) != sizeof (header))
+ err = GRUB_ERR_READ_ERROR;
+ }
+ else
+ err = grub_disk_read (disk, 0, 0, sizeof (header), &header);
+
#ifdef GRUB_UTIL
@@ -428,12 +439,14 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
grub_memcpy (newdev->uuid, uuid, sizeof (newdev->uuid));
newdev->modname = "luks";
COMPILE_TIME_ASSERT (sizeof (newdev->uuid) >= sizeof (uuid));
+
return newdev;
}
static grub_err_t
luks_recover_key (grub_disk_t source,
- grub_cryptodisk_t dev)
+ grub_cryptodisk_t dev,
+ grub_file_t hdr)
{
struct grub_luks_phdr header;
grub_size_t keysize;
@@ -445,8 +458,19 @@ luks_recover_key (grub_disk_t source,
grub_err_t err;
grub_size_t max_stripes = 1;
char *tmp;
+ grub_uint32_t sector;
+
+ err = GRUB_ERR_NONE;
+
+ if (hdr)
+ {
+ grub_file_seek (hdr, 0);
+ if (grub_file_read (hdr, &header, sizeof (header)) != sizeof (header))
+ err = GRUB_ERR_READ_ERROR;
+ }
+ else
+ err = grub_disk_read (source, 0, 0, sizeof (header), &header);
- err = grub_disk_read (source, 0, 0, sizeof (header), &header);
if (err)
return err;
@@ -515,13 +539,18 @@ luks_recover_key (grub_disk_t source,
return grub_crypto_gcry_error (gcry_err);
}
+ sector = grub_be_to_cpu32 (header.keyblock[i].keyMaterialOffset);
length = (keysize * grub_be_to_cpu32 (header.keyblock[i].stripes));
/* Read and decrypt the key material from the disk. */
- err = grub_disk_read (source,
- grub_be_to_cpu32 (header.keyblock
- [i].keyMaterialOffset), 0,
- length, split_key);
+ if (hdr)
+ {
+ grub_file_seek (hdr, sector * 512);
+ if (grub_file_read (hdr, split_key, length) != (grub_ssize_t)length)
+ err = GRUB_ERR_READ_ERROR;
+ }
+ else
+ err = grub_disk_read (source, sector, 0, length, split_key);
if (err)
{
grub_free (split_key);
diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h
index 32f564a..4e6e89a 100644
--- a/include/grub/cryptodisk.h
+++ b/include/grub/cryptodisk.h
@@ -20,6 +20,7 @@
#define GRUB_CRYPTODISK_HEADER 1
#include <grub/disk.h>
+#include <grub/file.h>
#include <grub/crypto.h>
#include <grub/list.h>
#ifdef GRUB_UTIL
@@ -107,8 +108,8 @@ struct grub_cryptodisk_dev
struct grub_cryptodisk_dev **prev;
grub_cryptodisk_t (*scan) (grub_disk_t disk, const char *check_uuid,
- int boot_only);
- grub_err_t (*recover_key) (grub_disk_t disk, grub_cryptodisk_t dev);
+ int boot_only, grub_file_t hdr);
+ grub_err_t (*recover_key) (grub_disk_t disk, grub_cryptodisk_t dev, grub_file_t hdr);
};
typedef struct grub_cryptodisk_dev *grub_cryptodisk_dev_t;
--
2.7.4
From b80afb1f4c68eb027c48463c5e051255614bf2ff Mon Sep 17 00:00:00 2001
From: matt <[email protected]>
Date: Sat, 8 Apr 2017 08:54:20 -0400
Subject: [PATCH 6/7] Added LUKS patch 2
---
grub-core/disk/cryptodisk.c | 46 ++++++++++++++++++++++++++++++++++++++++++++-
grub-core/disk/geli.c | 4 +++-
grub-core/disk/luks.c | 44 +++++++++++++++++++++++++++++--------------
include/grub/cryptodisk.h | 5 ++++-
4 files changed, 82 insertions(+), 17 deletions(-)
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
index dd8870d..0e7ced8 100644
--- a/grub-core/disk/cryptodisk.c
+++ b/grub-core/disk/cryptodisk.c
@@ -42,6 +42,9 @@ static const struct grub_arg_option options[] =
{"all", 'a', 0, N_("Mount all."), 0, 0},
{"boot", 'b', 0, N_("Mount all volumes with `boot' flag set."), 0, 0},
{"header", 'H', 0, N_("Read LUKS header from file"), 0, ARG_TYPE_STRING},
+ {"keyfile", 'k', 0, N_("Key file"), 0, ARG_TYPE_STRING},
+ {"keyfile-offset", 'O', 0, N_("Key file offset (bytes)"), 0, ARG_TYPE_INT},
+ {"keyfile-size", 'S', 0, N_("Key file data size (bytes)"), 0, ARG_TYPE_INT},
{0, 0, 0, 0, 0, 0}
};
@@ -810,6 +813,8 @@ grub_util_cryptodisk_get_uuid (grub_disk_t disk)
static int check_boot, have_it;
static char *search_uuid;
static grub_file_t hdr;
+static grub_uint8_t *key, keyfile_buffer[GRUB_CRYPTODISK_MAX_KEYFILE_SIZE];
+static grub_size_t keyfile_size;
static void
cryptodisk_close (grub_cryptodisk_t dev)
@@ -840,7 +845,7 @@ grub_cryptodisk_scan_device_real (const char *name, grub_disk_t source)
if (!dev)
continue;
- err = cr->recover_key (source, dev, hdr);
+ err = cr->recover_key (source, dev, hdr, key, keyfile_size);
if (err)
{
cryptodisk_close (dev);
@@ -948,6 +953,45 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
hdr = NULL;
have_it = 0;
+ key = NULL;
+
+ if (state[4].set) /* Key file; fails back to passphrase entry */
+ {
+ grub_file_t keyfile;
+ int keyfile_offset;
+ grub_size_t requested_keyfile_size;
+
+ requested_keyfile_size = state[6].set ? grub_strtoul(state[6].arg, 0, 0) : 0;
+
+ if (requested_keyfile_size > GRUB_CRYPTODISK_MAX_KEYFILE_SIZE)
+ grub_printf (N_("Key file size exceeds maximum (%llu)\n"), \
+ (unsigned long long) GRUB_CRYPTODISK_MAX_KEYFILE_SIZE);
+ else
+ {
+ keyfile_offset = state[5].set ? grub_strtoul (state[5].arg, 0, 0) : 0;
+ keyfile_size = requested_keyfile_size ? requested_keyfile_size : \
+ GRUB_CRYPTODISK_MAX_KEYFILE_SIZE;
+
+ keyfile = grub_file_open (state[4].arg);
+ if (!keyfile)
+ grub_printf (N_("Unable to open key file %s\n"), state[4].arg);
+ else if (grub_file_seek (keyfile, keyfile_offset) == (grub_off_t)-1)
+ grub_printf (N_("Unable to seek to offset %d in key file\n"), keyfile_offset);
+ else
+ {
+ keyfile_size = grub_file_read (keyfile, keyfile_buffer, keyfile_size);
+ if (keyfile_size == (grub_size_t)-1)
+ grub_printf (N_("Error reading key file\n"));
+ else if (requested_keyfile_size && (keyfile_size != requested_keyfile_size))
+ grub_printf (N_("Cannot read %llu bytes for key file (read %llu bytes)\n"),
+ (unsigned long long) requested_keyfile_size,
+ (unsigned long long) keyfile_size);
+ else
+ key = keyfile_buffer;
+ }
+ }
+ }
+
if (state[0].set)
{
grub_cryptodisk_t dev;
diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c
index f4394eb..da6aa6a 100644
--- a/grub-core/disk/geli.c
+++ b/grub-core/disk/geli.c
@@ -401,7 +401,9 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
static grub_err_t
recover_key (grub_disk_t source, grub_cryptodisk_t dev,
- grub_file_t hdr __attribute__ ((unused)) )
+ grub_file_t hdr __attribute__ ((unused)),
+ grub_uint8_t *key __attribute__ ((unused)),
+ grub_size_t keyfile_size __attribute__ ((unused)) )
{
grub_size_t keysize;
grub_uint8_t digest[GRUB_CRYPTO_MAX_MDLEN];
diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c
index 9a39fb5..a4f2311 100644
--- a/grub-core/disk/luks.c
+++ b/grub-core/disk/luks.c
@@ -446,12 +446,16 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
static grub_err_t
luks_recover_key (grub_disk_t source,
grub_cryptodisk_t dev,
- grub_file_t hdr)
+ grub_file_t hdr,
+ grub_uint8_t *keyfile_bytes,
+ grub_size_t keyfile_bytes_size)
{
struct grub_luks_phdr header;
grub_size_t keysize;
grub_uint8_t *split_key = NULL;
- char passphrase[MAX_PASSPHRASE] = "";
+ char interactive_passphrase[MAX_PASSPHRASE] = "";
+ grub_uint8_t *passphrase;
+ grub_size_t passphrase_length;
grub_uint8_t candidate_digest[sizeof (header.mkDigest)];
unsigned i;
grub_size_t length;
@@ -488,18 +492,30 @@ luks_recover_key (grub_disk_t source,
if (!split_key)
return grub_errno;
- /* Get the passphrase from the user. */
- tmp = NULL;
- if (source->partition)
- tmp = grub_partition_get_name (source->partition);
- grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name,
- source->partition ? "," : "", tmp ? : "",
- dev->uuid);
- grub_free (tmp);
- if (!grub_password_get (passphrase, MAX_PASSPHRASE))
+ if (keyfile_bytes)
{
- grub_free (split_key);
- return grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied");
+ /* Use bytestring from key file as passphrase */
+ passphrase = keyfile_bytes;
+ passphrase_length = keyfile_bytes_size;
+ }
+ else
+ {
+ /* Get the passphrase from the user. */
+ tmp = NULL;
+ if (source->partition)
+ tmp = grub_partition_get_name (source->partition);
+ grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name,
+ source->partition ? "," : "", tmp ? : "", dev->uuid);
+ grub_free (tmp);
+ if (!grub_password_get (interactive_passphrase, MAX_PASSPHRASE))
+ {
+ grub_free (split_key);
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied");
+ }
+
+ passphrase = (grub_uint8_t *)interactive_passphrase;
+ passphrase_length = grub_strlen (interactive_passphrase);
+
}
/* Try to recover master key from each active keyslot. */
@@ -517,7 +533,7 @@ luks_recover_key (grub_disk_t source,
/* Calculate the PBKDF2 of the user supplied passphrase. */
gcry_err = grub_crypto_pbkdf2 (dev->hash, (grub_uint8_t *) passphrase,
- grub_strlen (passphrase),
+ passphrase_length,
header.keyblock[i].passwordSalt,
sizeof (header.keyblock[i].passwordSalt),
grub_be_to_cpu32 (header.keyblock[i].
diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h
index 4e6e89a..67f6b0b 100644
--- a/include/grub/cryptodisk.h
+++ b/include/grub/cryptodisk.h
@@ -55,6 +55,8 @@ typedef enum
#define GRUB_CRYPTODISK_GF_BYTES (1U << GRUB_CRYPTODISK_GF_LOG_BYTES)
#define GRUB_CRYPTODISK_MAX_KEYLEN 128
+#define GRUB_CRYPTODISK_MAX_KEYFILE_SIZE 8192
+
struct grub_cryptodisk;
typedef gcry_err_code_t
@@ -109,7 +111,8 @@ struct grub_cryptodisk_dev
grub_cryptodisk_t (*scan) (grub_disk_t disk, const char *check_uuid,
int boot_only, grub_file_t hdr);
- grub_err_t (*recover_key) (grub_disk_t disk, grub_cryptodisk_t dev, grub_file_t hdr);
+ grub_err_t (*recover_key) (grub_disk_t disk, grub_cryptodisk_t dev,
+ grub_file_t hdr, grub_uint8_t *key, grub_size_t keyfile_size);
};
typedef struct grub_cryptodisk_dev *grub_cryptodisk_dev_t;
--
2.7.4
From f4b95bb1a5f96011c7bb4016dc9d6927ddc592dd Mon Sep 17 00:00:00 2001
From: matt <[email protected]>
Date: Wed, 5 Apr 2017 06:08:09 -0400
Subject: [PATCH 3/7] Added mattle_opts.cfg
---
grub-core/osdep/unix/config.c | 8 +++++--
include/grub/emu/config.h | 1 +
util/config.c | 10 ++++++++
util/grub-install.c | 55 +++++++++++++++++++++++++++++++++++++++----
util/grub-mkconfig.in | 10 +++++++-
util/grub-mkconfig_lib.in | 23 +++++++++++++++---
6 files changed, 96 insertions(+), 11 deletions(-)
diff --git a/grub-core/osdep/unix/config.c b/grub-core/osdep/unix/config.c
index 65effa9..360b3d6 100644
--- a/grub-core/osdep/unix/config.c
+++ b/grub-core/osdep/unix/config.c
@@ -78,6 +78,10 @@ grub_util_load_config (struct grub_util_config *cfg)
if (v && v[0] == 'y' && v[1] == '\0')
cfg->is_cryptodisk_enabled = 1;
+ v = getenv ("GRUB_ENABLE_CRYPTODISK_MATTLE_OPTS");
+ if (v && v[0] == 'y' && v[1] == '\0')
+ cfg->is_cryptodisk_enabled_mattle_opts = 1;
+
v = getenv ("GRUB_DISTRIBUTOR");
if (v)
cfg->grub_distributor = xstrdup (v);
@@ -105,8 +109,8 @@ grub_util_load_config (struct grub_util_config *cfg)
*ptr++ = *iptr;
}
- strcpy (ptr, "'; printf \"GRUB_ENABLE_CRYPTODISK=%s\\nGRUB_DISTRIBUTOR=%s\\n\" "
- "\"$GRUB_ENABLE_CRYPTODISK\" \"$GRUB_DISTRIBUTOR\"");
+ strcpy (ptr, "'; printf \"GRUB_ENABLE_CRYPTODISK=%s\\nGRUB_ENABLE_CRYPTODISK_MATTLE_OPTS=%s\\nGRUB_DISTRIBUTOR=%s\\n\" "
+ "\"$GRUB_ENABLE_CRYPTODISK\" \"$GRUB_ENABLE_CRYPTODISK_MATTLE_OPTS\" \"$GRUB_DISTRIBUTOR\"");
argv[2] = script;
argv[3] = '\0';
diff --git a/include/grub/emu/config.h b/include/grub/emu/config.h
index 875d589..f761005 100644
--- a/include/grub/emu/config.h
+++ b/include/grub/emu/config.h
@@ -36,6 +36,7 @@ grub_util_get_localedir (void);
struct grub_util_config
{
int is_cryptodisk_enabled;
+ int is_cryptodisk_enabled_mattle_opts;
char *grub_distributor;
};
diff --git a/util/config.c b/util/config.c
index ebcdd8f..ec429fd 100644
--- a/util/config.c
+++ b/util/config.c
@@ -42,6 +42,16 @@ grub_util_parse_config (FILE *f, struct grub_util_config *cfg, int simple)
cfg->is_cryptodisk_enabled = 1;
continue;
}
+ if (grub_strncmp (ptr, "GRUB_ENABLE_CRYPTODISK_MATTLE_OPTS=",
+ sizeof ("GRUB_ENABLE_CRYPTODISK_MATTLE_OPTS=") - 1) == 0)
+ {
+ ptr += sizeof ("GRUB_ENABLE_CRYPTODISK_MATTLE_OPTS=") - 1;
+ if (*ptr == '"' || *ptr == '\'')
+ ptr++;
+ if (*ptr == 'y')
+ cfg->is_cryptodisk_enabled_mattle_opts = 1;
+ continue;
+ }
if (grub_strncmp (ptr, "GRUB_DISTRIBUTOR=",
sizeof ("GRUB_DISTRIBUTOR=") - 1) == 0)
{
diff --git a/util/grub-install.c b/util/grub-install.c
index 6c89c2b..109a4e2 100644
--- a/util/grub-install.c
+++ b/util/grub-install.c
@@ -79,6 +79,7 @@ static char *label_color;
static char *label_bgcolor;
static char *product_version;
static int add_rs_codes = 1;
+static char *mattle_opts_file = NULL;
enum
{
@@ -109,7 +110,8 @@ enum
OPTION_LABEL_FONT,
OPTION_LABEL_COLOR,
OPTION_LABEL_BGCOLOR,
- OPTION_PRODUCT_VERSION
+ OPTION_PRODUCT_VERSION,
+ OPTION_MATTLE_OPTS_FILE
};
static int fs_probe = 1;
@@ -239,6 +241,11 @@ argp_parser (int key, char *arg, struct argp_state *state)
install_device = xstrdup (arg);
return 0;
+ case OPTION_MATTLE_OPTS_FILE:
+ free (mattle_opts_file);
+ mattle_opts_file = xstrdup (arg);
+ return 0;
+
default:
return ARGP_ERR_UNKNOWN;
}
@@ -302,6 +309,8 @@ static struct argp_option options[] = {
{"label-color", OPTION_LABEL_COLOR, N_("COLOR"), 0, N_("use COLOR for label"), 2},
{"label-bgcolor", OPTION_LABEL_BGCOLOR, N_("COLOR"), 0, N_("use COLOR for label background"), 2},
{"product-version", OPTION_PRODUCT_VERSION, N_("STRING"), 0, N_("use STRING as product version"), 2},
+ {"mattle-opts-file", OPTION_MATTLE_OPTS_FILE, N_("FILE"), 0,
+ N_("use FILE instead of using %smattle_opts.cfg "), 2},
{0, 0, 0, 0, 0, 0}
};
@@ -346,6 +355,8 @@ help_filter (int key, const char *text, void *input __attribute__ ((unused)))
free (plats);
return ret;
}
+ case OPTION_MATTLE_OPTS_FILE:
+ return xasprintf (text, GRUB_SYSCONFDIR "/");
case ARGP_KEY_HELP_POST_DOC:
return xasprintf (text, program_name, GRUB_BOOT_DIR_NAME "/" GRUB_DIR_NAME);
default:
@@ -523,16 +534,50 @@ probe_cryptodisk_uuid (grub_disk_t disk)
}
if (disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID)
{
+ static struct grub_util_config config;
+ grub_util_load_config (&config);
const char *uuid = grub_util_cryptodisk_get_uuid (disk);
+ char *mattle_opts_name; /*absolute path for mattle_opts.cfg */
+ static FILE *fpmattle; /*file pointer to be used as the local program name for mattle_opts.cfg */
+ int k = 0;
if (!load_cfg_f)
- load_cfg_f = grub_util_fopen (load_cfg, "wb");
+ load_cfg_f = grub_util_fopen (load_cfg, "wb");
have_load_cfg = 1;
-
- fprintf (load_cfg_f, "cryptomount -u %s\n",
- uuid);
+ if (config.is_cryptodisk_enabled_mattle_opts)
+ {
+ if (mattle_opts_file != '\0')
+ mattle_opts_name = grub_strdup (mattle_opts_file);
+ else
+ mattle_opts_name = grub_util_path_concat (2, GRUB_SYSCONFDIR, "mattle_opts.cfg");
+ fpmattle = grub_util_fopen (mattle_opts_name, "r");
+ if (!fpmattle)
+ {
+ grub_util_error (_("cannot open `%s': %s, check to make sure %s has been created"), mattle_opts_name,
+ strerror (errno), mattle_opts_name);
+ }
+ while(1)
+ {
+ k = fgetc(fpmattle);
+ if (feof(fpmattle))
+ break;
+ fprintf (load_cfg_f, "%c", k);
+ }
+ fclose (fpmattle);
+ free (mattle_opts_name);
+ if (mattle_opts_file)
+ free (mattle_opts_file);
+ grub_install_push_module ("exfat");
+ grub_install_push_module ("fat");
+ grub_install_push_module ("search_pt_uuid");
+ grub_install_push_module ("search_fs_uuid");
+ grub_install_push_module ("part_gpt");
+ }
+ else
+ fprintf (load_cfg_f, "cryptomount -u %s\n ", uuid); /*This is to keep it like the original unaltered settings*/
}
}
+
static int
is_same_disk (const char *a, const char *b)
{
diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in
index f8496d2..33a0dbf 100644
--- a/util/grub-mkconfig.in
+++ b/util/grub-mkconfig.in
@@ -60,6 +60,7 @@ usage () {
print_option_help "-o, --output=$(gettext FILE)" "$(gettext "output generated config to FILE [default=stdout]")"
print_option_help "-h, --help" "$(gettext "print this message and exit")"
print_option_help "-v, --version" "$(gettext "print the version information and exit")"
+ print_option_help "-m, --mattle-opts-file=$(gettext FILE)" "$(gettext "alternate mattle_opts.cfg FILE")"
echo
gettext "Report bugs to <[email protected]>."; echo
}
@@ -93,6 +94,11 @@ do
--output=*)
grub_cfg=`echo "$option" | sed 's/--output=//'`
;;
+ -m | --mattle-opts-file)
+ GRUB_ALT_OPTS_FILE=`argument $option "$@"`; shift;;
+ --mattle-opts-file=*)
+ GRUB_ALT_OPTS_FILE=`echo "$option" | sed 's/--mattle-opts-file=//'`
+ ;;
-*)
gettext_printf "Unrecognized option \`%s'\n" "$option" 1>&2
usage
@@ -187,7 +193,8 @@ export GRUB_DEVICE \
GRUB_FS \
GRUB_FONT \
GRUB_PRELOAD_MODULES \
- GRUB_ACTUAL_DEFAULT
+ GRUB_ACTUAL_DEFAULT \
+ GRUB_ALT_OPTS_FILE
# These are optional, user-defined variables.
export GRUB_DEFAULT \
@@ -225,6 +232,7 @@ export GRUB_DEFAULT \
GRUB_INIT_TUNE \
GRUB_SAVEDEFAULT \
GRUB_ENABLE_CRYPTODISK \
+ GRUB_ENABLE_CRYPTODISK_MATTLE_OPTS \
GRUB_BADRAM \
GRUB_OS_PROBER_SKIP_LIST \
GRUB_DISABLE_SUBMENU
diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in
index 60b31ca..45c9eaa 100644
--- a/util/grub-mkconfig_lib.in
+++ b/util/grub-mkconfig_lib.in
@@ -145,9 +145,26 @@ prepare_grub_to_access_device ()
done
if [ x$GRUB_ENABLE_CRYPTODISK = xy ]; then
- for uuid in `"${grub_probe}" --device $@ --target=cryptodisk_uuid`; do
- echo "cryptomount -u $uuid"
- done
+ if [ x$GRUB_ENABLE_CRYPTODISK_MATTLE_OPTS = xy ]; then
+ if test -n "$GRUB_ALT_OPTS_FILE"; then
+ if test -f "$GRUB_ALT_OPTS_FILE"; then
+ #echo "tested good"
+ while read -r WHOLE_FILE; do echo "$WHOLE_FILE" ; done < $GRUB_ALT_OPTS_FILE
+ else
+ gettext_printf "Error: cannot open %s\n" "$GRUB_ALT_OPTS_FILE" 1>&2
+ exit 1
+ fi
+ elif test -f "${prefix}/etc/mattle_opts.cfg"; then
+ while read -r WHOLE_FILE; do echo "$WHOLE_FILE" ; done < ${prefix}/etc/mattle_opts.cfg
+ else
+ gettext_printf "Error: cannot open %s\n" "${prefix}/etc/mattle_opts.cfg" 1>&2
+ exit 1
+ fi
+ else
+ for uuid in `"${grub_probe}" --device $@ --target=cryptodisk_uuid`; do
+ echo "cryptomount -u $uuid"
+ done
+ fi
fi
# If there's a filesystem UUID that GRUB is capable of identifying, use it;
--
2.7.4
From d35b67005f7281668221cd335f0b19b3d68a225d Mon Sep 17 00:00:00 2001
From: matt <[email protected]>
Date: Wed, 5 Apr 2017 04:16:07 -0400
Subject: [PATCH 2/7] Added search_pt_uuid module
---
grub-core/Makefile.core.def | 5 ++++
grub-core/commands/search.c | 56 ++++++++++++++++++++++++++++++++++
grub-core/commands/search_ptuuid.c | 5 ++++
grub-core/commands/search_wrap.c | 12 ++++++--
grub-core/disk/efi/efidisk.c | 61 +++++++++++++++++++++++++++++++++++++-
grub-core/disk/i386/pc/biosdisk.c | 27 ++++++++++++++++-
grub-core/partmap/gpt.c | 4 +++
grub-core/partmap/msdos.c | 12 +++++---
include/grub/disk.h | 5 ++++
include/grub/misc.h | 22 ++++++++++++++
include/grub/partition.h | 3 ++
include/grub/search.h | 2 ++
12 files changed, 205 insertions(+), 9 deletions(-)
create mode 100644 grub-core/commands/search_ptuuid.c
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 2dfa22a..91d5a82 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -994,6 +994,11 @@ module = {
};
module = {
+ name = search_pt_uuid;
+ common = commands/search_ptuuid.c;
+};
+
+module = {
name = search_label;
common = commands/search_label.c;
};
diff --git a/grub-core/commands/search.c b/grub-core/commands/search.c
index 2fea001..d0c26c9 100644
--- a/grub-core/commands/search.c
+++ b/grub-core/commands/search.c
@@ -73,6 +73,8 @@ if(grub_strcmp (ctx->print_once, name) != 0)
#ifdef DO_SEARCH_FS_UUID
#define compare_fn grub_strcasecmp
+#elif defined (DO_SEARCH_PT_UUID)
+#define compare_fn grub_strcasecmp
#else
#define compare_fn grub_strcmp
#endif
@@ -95,6 +97,56 @@ if(grub_strcmp (ctx->print_once, name) != 0)
}
grub_free (buf);
}
+#elif defined (DO_SEARCH_PT_UUID)
+ {
+
+ /* Obtain the partition table from the root device. */
+ grub_device_t dev;
+ char *partuuid = 0;
+ dev = grub_device_open (name);
+ if (dev && dev->disk)
+ {
+ grub_disk_t disk = dev->disk;
+ grub_partition_t p = disk->partition;
+ /*Read the disk UUID/GUID*/
+ if (grub_strlen(name) == 3 && name[0] == 'h' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9')
+ {
+ if (disk->dev->partuuid)
+ {
+ disk->dev->partuuid (dev, &partuuid);
+ if (grub_errno == GRUB_ERR_NONE && partuuid)
+ {
+ if (compare_fn (partuuid, ctx->key) == 0)
+ {
+ found = 1;
+ }
+ grub_free (partuuid);
+ }
+ }
+ }
+ /*Read the partition UUID/GUID*/
+ else if (disk)
+ {
+ if (p && (grub_strcmp (p->partmap->name, "msdos") == 0 || grub_strcmp (p->partmap->name, "gpt") == 0 ))
+ {
+ if (disk->partition->number + 1)
+ {
+ partuuid = grub_strdup (p->partuuid);
+ if (grub_errno == GRUB_ERR_NONE && partuuid)
+ {
+ if (compare_fn (partuuid, ctx->key) == 0)
+ {
+ found = 1;
+ }
+ grub_free (partuuid);
+ }
+ }
+ }
+ }
+ }
+ if (dev)
+ grub_device_close (dev);
+ }
#else
{
/* SEARCH_FS_UUID or SEARCH_LABEL */
@@ -326,6 +378,8 @@ static grub_command_t cmd;
GRUB_MOD_INIT(search_fs_file)
#elif defined (DO_SEARCH_FS_UUID)
GRUB_MOD_INIT(search_fs_uuid)
+#elif defined (DO_SEARCH_PT_UUID)
+GRUB_MOD_INIT(search_pt_uuid)
#else
GRUB_MOD_INIT(search_label)
#endif
@@ -340,6 +394,8 @@ GRUB_MOD_INIT(search_label)
GRUB_MOD_FINI(search_fs_file)
#elif defined (DO_SEARCH_FS_UUID)
GRUB_MOD_FINI(search_fs_uuid)
+#elif defined (DO_SEARCH_PT_UUID)
+GRUB_MOD_FINI(search_pt_uuid)
#else
GRUB_MOD_FINI(search_label)
#endif
diff --git a/grub-core/commands/search_ptuuid.c b/grub-core/commands/search_ptuuid.c
new file mode 100644
index 0000000..06f8391
--- /dev/null
+++ b/grub-core/commands/search_ptuuid.c
@@ -0,0 +1,5 @@
+#define DO_SEARCH_PT_UUID 1
+#define FUNC_NAME grub_search_pt_uuid
+#define COMMAND_NAME "search.pt_uuid"
+#define HELP_MESSAGE N_("Search devices by disk/partition UUID/GUID. If VARIABLE is specified, the first device found is set to a variable.")
+#include "search.c"
diff --git a/grub-core/commands/search_wrap.c b/grub-core/commands/search_wrap.c
index d7fd26b..85f35d2 100644
--- a/grub-core/commands/search_wrap.c
+++ b/grub-core/commands/search_wrap.c
@@ -36,6 +36,8 @@ static const struct grub_arg_option options[] =
0, 0},
{"fs-uuid", 'u', 0, N_("Search devices by a filesystem UUID."),
0, 0},
+ {"pt-uuid", 'p', 0, N_("Search devices by a disk/partition UUID/GUID."),
+ 0, 0},
{"set", 's', GRUB_ARG_OPTION_OPTIONAL,
N_("Set a variable to the first device found."), N_("VARNAME"),
ARG_TYPE_STRING},
@@ -71,6 +73,7 @@ enum options
SEARCH_FILE,
SEARCH_LABEL,
SEARCH_FS_UUID,
+ SEARCH_PT_UUID,
SEARCH_SET,
SEARCH_NO_FLOPPY,
SEARCH_HINT,
@@ -186,6 +189,9 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args)
else if (state[SEARCH_FS_UUID].set)
grub_search_fs_uuid (id, var, state[SEARCH_NO_FLOPPY].set,
hints, nhints);
+ else if (state[SEARCH_PT_UUID].set)
+ grub_search_pt_uuid (id, var, state[SEARCH_NO_FLOPPY].set,
+ hints, nhints);
else if (state[SEARCH_FILE].set)
grub_search_fs_file (id, var, state[SEARCH_NO_FLOPPY].set,
hints, nhints);
@@ -204,10 +210,10 @@ GRUB_MOD_INIT(search)
cmd =
grub_register_extcmd ("search", grub_cmd_search,
GRUB_COMMAND_FLAG_EXTRACTOR | GRUB_COMMAND_ACCEPT_DASH,
- N_("[-f|-l|-u|-s|-n] [--hint HINT [--hint HINT] ...]"
+ N_("[-f|-l|-u|-p|-s|-n] [--hint HINT [--hint HINT] ...]"
" NAME"),
- N_("Search devices by file, filesystem label"
- " or filesystem UUID."
+ N_("Search devices by file, filesystem label,"
+ " filesystem UUID or disk/partition UUID/GUID."
" If --set is specified, the first device found is"
" set to a variable. If no variable name is"
" specified, `root' is used."),
diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c
index e66b35d..dfeb685 100644
--- a/grub-core/disk/efi/efidisk.c
+++ b/grub-core/disk/efi/efidisk.c
@@ -18,6 +18,8 @@
#include <grub/disk.h>
#include <grub/partition.h>
+#include <grub/gpt_partition.h>
+#include <grub/msdos_partition.h>
#include <grub/mm.h>
#include <grub/types.h>
#include <grub/misc.h>
@@ -622,6 +624,62 @@ grub_efidisk_write (struct grub_disk *disk, grub_disk_addr_t sector,
return GRUB_ERR_NONE;
}
+static grub_uint8_t grub_gpt_magic[8] =
+ {
+ 0x45, 0x46, 0x49, 0x20, 0x50, 0x41, 0x52, 0x54
+ };
+
+/* 512 << 7 = 65536 byte sectors. */
+#define MAX_SECTOR_LOG 7
+
+static grub_err_t
+grub_efidisk_uuid (grub_device_t device, char **partuuid)
+{
+ grub_disk_t disk = device->disk;
+ unsigned int mbr_sig = 0xaa55;
+ struct grub_gpt_header gpt;
+ struct grub_msdos_partition_mbr mbr;
+ unsigned int i;
+ int sector_log = 0;
+ if (grub_strlen(disk->name) == 3 && disk->name[0] == 'h' && disk->name[1] == 'd' && disk->name[2] >= '0' && disk->name[2] <= '9')
+ {
+ /* Read the protective MBR. */
+ if (grub_disk_read (disk, 0, 0, sizeof (mbr), &mbr) == GRUB_ERR_NONE)
+ if (mbr.signature == mbr_sig)
+ {
+ for (i = 0; i < 4; i++)
+ if (mbr.entries[i].type == GRUB_PC_PARTITION_TYPE_GPT_DISK)
+ break;
+ /* Read the GPT header. */
+ if (mbr.entries[i].type == GRUB_PC_PARTITION_TYPE_GPT_DISK)
+ {
+ if (i < 4)
+ {
+ for (sector_log = 0; sector_log < MAX_SECTOR_LOG; sector_log++)
+ {
+ if (grub_disk_read (disk, 1 << sector_log, 0, sizeof (gpt), &gpt) == GRUB_ERR_NONE)
+ {
+ if (grub_memcmp (gpt.magic, grub_gpt_magic, sizeof (grub_gpt_magic)) == 0)
+ {
+ if (disk->dev && gpt.guid)
+ {
+ *partuuid = grub_xasprintf ("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ gpt.guid[3],gpt.guid[2],gpt.guid[1],gpt.guid[0],gpt.guid[5],gpt.guid[4],gpt.guid[7],gpt.guid[6],
+ gpt.guid[8],gpt.guid[9],gpt.guid[10],gpt.guid[11],gpt.guid[12],gpt.guid[13],gpt.guid[14],
+ gpt.guid[15]);
+ }
+ else
+ *partuuid = NULL;
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+return grub_errno;
+}
static struct grub_disk_dev grub_efidisk_dev =
{
@@ -632,7 +690,8 @@ static struct grub_disk_dev grub_efidisk_dev =
.close = grub_efidisk_close,
.read = grub_efidisk_read,
.write = grub_efidisk_write,
- .next = 0
+ .next = 0,
+ .partuuid = grub_efidisk_uuid
};
void
diff --git a/grub-core/disk/i386/pc/biosdisk.c b/grub-core/disk/i386/pc/biosdisk.c
index f0aadd1..53a24a9 100644
--- a/grub-core/disk/i386/pc/biosdisk.c
+++ b/grub-core/disk/i386/pc/biosdisk.c
@@ -633,6 +633,30 @@ grub_biosdisk_write (grub_disk_t disk, grub_disk_addr_t sector,
return grub_errno;
}
+static grub_err_t
+grub_biosdisk_uuid (grub_device_t device, char **partuuid)
+{
+ grub_disk_t disk = device->disk;
+ grub_uint8_t mbr_buf[512];
+ unsigned int mbr_id = 0;
+ unsigned int mbr_sig = 0xaa55;
+ if (grub_strlen(disk->name) == 3 && disk->name[0] == 'h' && disk->name[1] == 'd' && disk->name[2] >= '0' && disk->name[2] <= '9')
+ {
+ if (grub_disk_read (disk, 0, 0, sizeof (mbr_buf), &mbr_buf) == GRUB_ERR_NONE)
+ if (mbr_get_sig (mbr_buf) == mbr_sig)
+ {
+ mbr_id = mbr_get_id (mbr_buf);
+ if (disk->dev)
+ {
+ *partuuid = grub_xasprintf ("%08x", mbr_id);
+ }
+ else
+ *partuuid = NULL;
+ }
+ }
+return grub_errno;
+}
+
static struct grub_disk_dev grub_biosdisk_dev =
{
.name = "biosdisk",
@@ -642,7 +666,8 @@ static struct grub_disk_dev grub_biosdisk_dev =
.close = grub_biosdisk_close,
.read = grub_biosdisk_read,
.write = grub_biosdisk_write,
- .next = 0
+ .next = 0,
+ .partuuid = grub_biosdisk_uuid
};
static void
diff --git a/grub-core/partmap/gpt.c b/grub-core/partmap/gpt.c
index 83bcba7..0012204 100644
--- a/grub-core/partmap/gpt.c
+++ b/grub-core/partmap/gpt.c
@@ -108,6 +108,10 @@ grub_gpt_partition_map_iterate (grub_disk_t disk,
part.index = last_offset;
part.partmap = &grub_gpt_partition_map;
part.parent = disk->partition;
+ part.partuuid = grub_xasprintf ("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ entry.guid[3],entry.guid[2],entry.guid[1],entry.guid[0],entry.guid[5],entry.guid[4],entry.guid[7],
+ entry.guid[6],entry.guid[8],entry.guid[9],entry.guid[10],entry.guid[11],entry.guid[12],
+ entry.guid[13],entry.guid[14],entry.guid[15]);
grub_dprintf ("gpt", "GPT entry %d: start=%lld, length=%lld\n", i,
(unsigned long long) part.start,
diff --git a/grub-core/partmap/msdos.c b/grub-core/partmap/msdos.c
index 6d4b455..acde247 100644
--- a/grub-core/partmap/msdos.c
+++ b/grub-core/partmap/msdos.c
@@ -113,6 +113,7 @@ grub_partition_msdos_iterate (grub_disk_t disk,
struct grub_partition p;
struct grub_msdos_partition_mbr mbr;
int labeln = 0;
+ unsigned int mbr_id = 0;
grub_disk_addr_t lastaddr;
grub_disk_addr_t ext_offset;
grub_disk_addr_t delta = 0;
@@ -180,12 +181,15 @@ grub_partition_msdos_iterate (grub_disk_t disk,
p.len = grub_le_to_cpu32 (e->length)
<< (disk->log_sector_size - GRUB_DISK_SECTOR_BITS);
p.msdostype = e->type;
-
- grub_dprintf ("partition",
- "partition %d: flag 0x%x, type 0x%x, start 0x%llx, len 0x%llx\n",
+ if (p.offset == 0) /*allows for the correct mbr to be read when extended/logical partitions are read.*/
+ mbr_id = mbr_get_id(mbr.code);
+ p.partuuid = grub_xasprintf ("%08x-%02x", mbr_id, p.number + 2);/*2 since it starts off number = -1*/
+ grub_dprintf ("partition",
+ "partition %d: flag 0x%x, type 0x%x, start 0x%llx, len 0x%llx, PARTUUID 0x%s\n",
p.index, e->flag, e->type,
(unsigned long long) p.start,
- (unsigned long long) p.len);
+ (unsigned long long) p.len,
+ p.partuuid);
/* If this partition is a normal one, call the hook. */
if (! grub_msdos_partition_is_empty (e->type)
diff --git a/include/grub/disk.h b/include/grub/disk.h
index b385af8..dd9dd67 100644
--- a/include/grub/disk.h
+++ b/include/grub/disk.h
@@ -100,6 +100,11 @@ struct grub_disk_dev
/* The next disk device. */
struct grub_disk_dev *next;
+
+ /* Return the partuuid (disk/partition UUID/GUID) of the device DEVICE in PARTUUID. The partuuid is
+ returned in a grub_malloc'ed buffer and should be freed by the
+ caller. */
+ grub_err_t (*partuuid) (grub_device_t device, char **partuuid);
};
typedef struct grub_disk_dev *grub_disk_dev_t;
diff --git a/include/grub/misc.h b/include/grub/misc.h
index 2a9f87c..a559654 100644
--- a/include/grub/misc.h
+++ b/include/grub/misc.h
@@ -51,6 +51,28 @@ grub_strncpy (char *dest, const char *src, int c)
return dest;
}
+static inline unsigned int grub_assemble_32le(const unsigned char *p)
+{
+ return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
+}
+
+static inline unsigned int mbr_get_id(const unsigned char *mbr)
+{
+ return grub_assemble_32le(&mbr[440]);
+}
+
+static inline unsigned int grub_assemble_16le(const unsigned char *p)
+{
+ return p[0] | (p[1] << 8);
+}
+
+static inline unsigned int mbr_get_sig(const unsigned char *mbr)
+{
+ return grub_assemble_16le(&mbr[510]);
+}
+
+
+
static inline char *
grub_stpcpy (char *dest, const char *src)
{
diff --git a/include/grub/partition.h b/include/grub/partition.h
index 7adb7ec..68c4128 100644
--- a/include/grub/partition.h
+++ b/include/grub/partition.h
@@ -87,6 +87,9 @@ struct grub_partition
/* The type of partition whne it's on MSDOS.
Used for embedding detection. */
grub_uint8_t msdostype;
+
+ /*Partition UUID/GUID*/
+ const char *partuuid;
};
grub_partition_t EXPORT_FUNC(grub_partition_probe) (struct grub_disk *disk,
diff --git a/include/grub/search.h b/include/grub/search.h
index d80347d..69cbad0 100644
--- a/include/grub/search.h
+++ b/include/grub/search.h
@@ -23,6 +23,8 @@ void grub_search_fs_file (const char *key, const char *var, int no_floppy,
char **hints, unsigned nhints);
void grub_search_fs_uuid (const char *key, const char *var, int no_floppy,
char **hints, unsigned nhints);
+void grub_search_pt_uuid (const char *key, const char *var, int no_floppy,
+ char **hints, unsigned nhints);
void grub_search_label (const char *key, const char *var, int no_floppy,
char **hints, unsigned nhints);
--
2.7.4
From 8c0c70536fcfc92ff0639481bcfb7c3ae9445ec6 Mon Sep 17 00:00:00 2001
From: matt <[email protected]>
Date: Wed, 5 Apr 2017 01:57:15 -0400
Subject: [PATCH 1/7] Search bug fix stop duplicate printing of cache device
---
grub-core/commands/search.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/grub-core/commands/search.c b/grub-core/commands/search.c
index 7dd32e4..2fea001 100644
--- a/grub-core/commands/search.c
+++ b/grub-core/commands/search.c
@@ -52,6 +52,7 @@ struct search_ctx
unsigned nhints;
int count;
int is_cache;
+ const char *print_once;
};
/* Helper for FUNC_NAME. */
@@ -60,6 +61,10 @@ iterate_device (const char *name, void *data)
{
struct search_ctx *ctx = data;
int found = 0;
+/*This is to skip over re-iterating device if the device info was just cached
+ on an earlier iteration. So it does not print the same device name twice*/
+if(grub_strcmp (ctx->print_once, name) != 0)
+{
/* Skip floppy drives when requested. */
if (ctx->no_floppy &&
@@ -157,9 +162,15 @@ iterate_device (const char *name, void *data)
if (ctx->var)
grub_env_set (ctx->var, name);
else
+ {
+ if(ctx->is_cache)
+ {
+ ctx->print_once = grub_strdup (name);
+ }
grub_printf (" %s", name);
+ }
}
-
+}
grub_errno = GRUB_ERR_NONE;
return (found && ctx->var);
}
--
2.7.4
_______________________________________________
Help-grub mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/help-grub