From 908f4282cc934422923ff59836a835e63d6a7117 Mon Sep 17 00:00:00 2001 From: Paul Gideon Dann Date: Tue, 19 Jul 2016 12:36:37 +0100 Subject: [PATCH] Add support for using a whole device as a keyfile --- grub-core/disk/cryptodisk.c | 86 +++++++++++++++++++++++++++++-------- 1 file changed, 68 insertions(+), 18 deletions(-) diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c index d0388c6d1..c5d8021ba 100644 --- a/grub-core/disk/cryptodisk.c +++ b/grub-core/disk/cryptodisk.c @@ -1031,26 +1031,76 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) 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, GRUB_FILE_TYPE_NONE); - 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 + + if (grub_strchr (state[4].arg, '/')) { - 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); + keyfile_size = requested_keyfile_size ? requested_keyfile_size : \ + GRUB_CRYPTODISK_MAX_KEYFILE_SIZE; + keyfile = grub_file_open (state[4].arg, GRUB_FILE_TYPE_NONE); + 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 - key = keyfile_buffer; - } + { + 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; + } + } + else + { + grub_disk_t keydisk; + char* keydisk_name; + grub_err_t err; + grub_uint64_t total_sectors; + + keydisk_name = grub_file_get_device_name(state[4].arg); + keydisk = grub_disk_open (keydisk_name); + if (!keydisk) + { + grub_printf (N_("Unable to open disk %s\n"), keydisk_name); + goto cleanup_keydisk_name; + } + + total_sectors = grub_disk_native_sectors (keydisk); + if (total_sectors == GRUB_DISK_SIZE_UNKNOWN) + { + grub_printf (N_("Unable to determine size of disk %s\n"), keydisk_name); + goto cleanup_keydisk; + } + + keyfile_size = (total_sectors << GRUB_DISK_SECTOR_BITS); + if (requested_keyfile_size > 0 && requested_keyfile_size < keyfile_size) + keyfile_size = requested_keyfile_size; + if (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); + goto cleanup_keydisk; + } + + err = grub_disk_read (keydisk, 0, keyfile_offset, keyfile_size, keyfile_buffer); + if (err != GRUB_ERR_NONE) + { + grub_printf (N_("Failed to read from disk %s\n"), keydisk_name); + keyfile_size = 0; + goto cleanup_keydisk; + } + + key = keyfile_buffer; + + cleanup_keydisk: + grub_disk_close (keydisk); + cleanup_keydisk_name: + grub_free (keydisk_name); + } } }