This lets a LUKS2 cryptodisk have all the cipher, hash, and sizes filled out, otherwise they wouldn't be initialized if cheat mounted. --- grub-core/osdep/devmapper/getroot.c | 51 ++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-)
diff --git a/grub-core/osdep/devmapper/getroot.c b/grub-core/osdep/devmapper/getroot.c index ad1daf9c8..574d07a20 100644 --- a/grub-core/osdep/devmapper/getroot.c +++ b/grub-core/osdep/devmapper/getroot.c @@ -51,6 +51,8 @@ #include <grub/emu/misc.h> #include <grub/emu/hostdisk.h> +#include <grub/cryptodisk.h> + static int grub_util_open_dm (const char *os_dev, struct dm_tree **tree, struct dm_tree_node **node) @@ -183,7 +185,6 @@ grub_util_pull_devmapper (const char *os_dev) && lastsubdev) { char *grdev = grub_util_get_grub_dev (lastsubdev); - dm_tree_free (tree); if (grdev) { grub_err_t err; @@ -191,7 +192,55 @@ grub_util_pull_devmapper (const char *os_dev) if (err) grub_util_error (_("can't mount encrypted volume `%s': %s"), lastsubdev, grub_errmsg); + if (strncmp (uuid, "CRYPT-LUKS2-", sizeof ("CRYPT-LUKS2-") - 1) == 0) + { + /* set LUKS2 cipher and size from dm parameter, since it is not + possible to determine the correct ones without unlocking, as + there might be multiple segments. */ + grub_disk_t source = grub_disk_open (grdev); + grub_cryptodisk_t cryptodisk = grub_cryptodisk_get_by_source_disk (source); + grub_disk_close (source); + grub_addr_t start, length; + char *target_type = NULL; + char *params; + const char *name = dm_tree_node_get_name (node); + char *cipher, *cipher_mode; + struct dm_task *dmt; + grub_util_info ("creating dm task for `%s'", name); + if (!(dmt = dm_task_create (DM_DEVICE_TABLE))) + grub_util_error (_("can't create dm task DM_DEVICE_TABLE")); + if (!dm_task_set_name (dmt, name)) + grub_util_error (_("can't set dm task name to `%s'"), name); + if (!dm_task_run (dmt)) + grub_util_error (_("can't run dm task for `%s'"), name); + dm_get_next_target (dmt, NULL, &start, &length, + &target_type, ¶ms); + if (strncmp (target_type, "crypt", sizeof ("crypt")) != 0) + grub_util_error (_("dm target is not `crypt'")); + + cryptodisk->total_sectors = length; + cryptodisk->log_sector_size = GRUB_LUKS1_LOG_SECTOR_SIZE; + + char *seek_head, *c; + c = params; + if (!(seek_head = grub_memchr (c, '-', grub_strlen (c)))) + grub_util_error (_("can't get cipher from dm task")); + cipher = grub_strndup (c, seek_head - c); + + c = seek_head + 1; + if (!(seek_head = grub_memchr (c, ' ', grub_strlen (c)))) + grub_util_error (_("can't get cipher mode from dm task")); + cipher_mode = grub_strndup (c, seek_head - c); + + grub_cryptodisk_setcipher (cryptodisk, cipher, cipher_mode); + + /* This is the only hash usable by PBKDF2, so set it as such */ + cryptodisk->hash = grub_crypto_lookup_md_by_name ("sha256"); + + dm_task_destroy (dmt); + } } + dm_tree_free (tree); grub_free (grdev); } else -- 2.34.0 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel