mirror of
https://git.savannah.gnu.org/git/grub.git
synced 2026-10-20 22:48:22 +00:00
cryptodisk: Support key protectors
Add a new parameter to cryptomount to support the key protectors framework: -P. The parameter is used to automatically retrieve a key from specified key protectors. The parameter may be repeated to specify any number of key protectors. These are tried in order until one provides a usable key for any given disk. Signed-off-by: Hernan Gatta <hegatta@linux.microsoft.com> Signed-off-by: Michael Chang <mchang@suse.com> Signed-off-by: Gary Lin <glin@suse.com> Reviewed-by: Glenn Washburn <development@efficientek.com> Reviewed-by: Stefan Berger <stefanb@linux.ibm.com> Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> Tested-by: Stefan Berger <stefanb@linux.ibm.com>
This commit is contained in:
1 parent
48e230c317
commit
ad0c52784a
4 files changed
+212
-78
No files matched your search
@@ -40,6 +40,7 @@ library = {
|
|||||||
common = grub-core/disk/luks.c;
|
common = grub-core/disk/luks.c;
|
||||||
common = grub-core/disk/luks2.c;
|
common = grub-core/disk/luks2.c;
|
||||||
common = grub-core/disk/geli.c;
|
common = grub-core/disk/geli.c;
|
||||||
|
common = grub-core/disk/key_protector.c;
|
||||||
common = grub-core/disk/cryptodisk.c;
|
common = grub-core/disk/cryptodisk.c;
|
||||||
common = grub-core/disk/AFSplitter.c;
|
common = grub-core/disk/AFSplitter.c;
|
||||||
common = grub-core/lib/pbkdf2.c;
|
common = grub-core/lib/pbkdf2.c;
|
||||||
|
|||||||
+7
-5
@@ -6683,16 +6683,18 @@ Alias for @code{hashsum --hash crc32 arg @dots{}}. See command @command{hashsum}
|
|||||||
@node cryptomount
|
@node cryptomount
|
||||||
@subsection cryptomount
|
@subsection cryptomount
|
||||||
|
|
||||||
@deffn Command cryptomount [ [@option{-p} password] | [@option{-k} keyfile [@option{-O} keyoffset] [@option{-S} keysize] ] ] [@option{-H} file] device|@option{-u} uuid|@option{-a}|@option{-b}
|
@deffn Command cryptomount [ [@option{-p} password] | [@option{-k} keyfile [@option{-O} keyoffset] [@option{-S} keysize] ] | [@option{-P} protector] ] [@option{-H} file] device|@option{-u} uuid|@option{-a}|@option{-b}
|
||||||
Setup access to encrypted device. A passphrase will be requested interactively,
|
Setup access to encrypted device. A passphrase will be requested interactively,
|
||||||
if neither the @option{-p} nor @option{-k} options are given. The option
|
if neither the @option{-p} nor @option{-k} options are given. The option
|
||||||
@option{-p} can be used to supply a passphrase (useful for scripts).
|
@option{-p} can be used to supply a passphrase (useful for scripts).
|
||||||
Alternatively the @option{-k} option can be used to supply a keyfile with
|
Alternatively the @option{-k} option can be used to supply a keyfile with
|
||||||
options @option{-O} and @option{-S} optionally supplying the offset and size,
|
options @option{-O} and @option{-S} optionally supplying the offset and size,
|
||||||
respectively, of the key data in the given key file. The @option{-H} options can
|
respectively, of the key data in the given key file. Besides the keyfile,
|
||||||
be used to supply cryptomount backends with an alternative header file (aka
|
the key can be stored in a key protector, and option @option{-P} configures
|
||||||
detached header). Not all backends have headers nor support alternative header
|
specific key protector, e.g. tpm2, to retrieve the key from.
|
||||||
files (currently only LUKS1 and LUKS2 support them).
|
The @option{-H} options can be used to supply cryptomount backends with an
|
||||||
|
alternative header file (aka detached header). Not all backends have headers
|
||||||
|
nor support alternative header files (currently only LUKS1 and LUKS2 support them).
|
||||||
Argument @var{device} configures specific grub device
|
Argument @var{device} configures specific grub device
|
||||||
(@pxref{Naming convention}); option @option{-u} @var{uuid} configures device
|
(@pxref{Naming convention}); option @option{-u} @var{uuid} configures device
|
||||||
with specified @var{uuid}; option @option{-a} configures all detected encrypted
|
with specified @var{uuid}; option @option{-a} configures all detected encrypted
|
||||||
|
|||||||
+188
-73
@@ -27,6 +27,7 @@
|
|||||||
#include <grub/file.h>
|
#include <grub/file.h>
|
||||||
#include <grub/procfs.h>
|
#include <grub/procfs.h>
|
||||||
#include <grub/partition.h>
|
#include <grub/partition.h>
|
||||||
|
#include <grub/key_protector.h>
|
||||||
|
|
||||||
#ifdef GRUB_UTIL
|
#ifdef GRUB_UTIL
|
||||||
#include <grub/emu/hostdisk.h>
|
#include <grub/emu/hostdisk.h>
|
||||||
@@ -45,7 +46,8 @@ enum
|
|||||||
OPTION_KEYFILE,
|
OPTION_KEYFILE,
|
||||||
OPTION_KEYFILE_OFFSET,
|
OPTION_KEYFILE_OFFSET,
|
||||||
OPTION_KEYFILE_SIZE,
|
OPTION_KEYFILE_SIZE,
|
||||||
OPTION_HEADER
|
OPTION_HEADER,
|
||||||
|
OPTION_PROTECTOR
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct grub_arg_option options[] =
|
static const struct grub_arg_option options[] =
|
||||||
@@ -59,6 +61,8 @@ static const struct grub_arg_option options[] =
|
|||||||
{"keyfile-offset", 'O', 0, N_("Key file offset (bytes)"), 0, ARG_TYPE_INT},
|
{"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},
|
{"keyfile-size", 'S', 0, N_("Key file data size (bytes)"), 0, ARG_TYPE_INT},
|
||||||
{"header", 'H', 0, N_("Read header from file"), 0, ARG_TYPE_STRING},
|
{"header", 'H', 0, N_("Read header from file"), 0, ARG_TYPE_STRING},
|
||||||
|
{"protector", 'P', GRUB_ARG_OPTION_REPEATABLE,
|
||||||
|
N_("Unlock volume(s) using key protector(s)."), 0, ARG_TYPE_STRING},
|
||||||
{0, 0, 0, 0, 0, 0}
|
{0, 0, 0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1062,6 +1066,7 @@ grub_cryptodisk_scan_device_real (const char *name,
|
|||||||
grub_err_t ret = GRUB_ERR_NONE;
|
grub_err_t ret = GRUB_ERR_NONE;
|
||||||
grub_cryptodisk_t dev;
|
grub_cryptodisk_t dev;
|
||||||
grub_cryptodisk_dev_t cr;
|
grub_cryptodisk_dev_t cr;
|
||||||
|
int i;
|
||||||
struct cryptodisk_read_hook_ctx read_hook_data = {0};
|
struct cryptodisk_read_hook_ctx read_hook_data = {0};
|
||||||
int askpass = 0;
|
int askpass = 0;
|
||||||
char *part = NULL;
|
char *part = NULL;
|
||||||
@@ -1114,79 +1119,151 @@ grub_cryptodisk_scan_device_real (const char *name,
|
|||||||
goto error_no_close;
|
goto error_no_close;
|
||||||
if (!dev)
|
if (!dev)
|
||||||
continue;
|
continue;
|
||||||
|
break;
|
||||||
if (cargs->key_len)
|
|
||||||
{
|
|
||||||
ret = cr->recover_key (source, dev, cargs);
|
|
||||||
if (ret != GRUB_ERR_NONE)
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Get the passphrase from the user, if no key data. */
|
|
||||||
unsigned long tries = 3;
|
|
||||||
const char *tries_env;
|
|
||||||
|
|
||||||
askpass = 1;
|
|
||||||
cargs->key_data = grub_malloc (GRUB_CRYPTODISK_MAX_PASSPHRASE);
|
|
||||||
if (cargs->key_data == NULL)
|
|
||||||
goto error_no_close;
|
|
||||||
|
|
||||||
tries_env = grub_env_get ("cryptodisk_passphrase_tries");
|
|
||||||
if (tries_env != NULL && tries_env[0] != '\0')
|
|
||||||
{
|
|
||||||
unsigned long tries_env_val;
|
|
||||||
const char *p;
|
|
||||||
|
|
||||||
tries_env_val = grub_strtoul (tries_env, &p, 0);
|
|
||||||
if (*p == '\0' && tries_env_val != ~0UL)
|
|
||||||
tries = tries_env_val;
|
|
||||||
else
|
|
||||||
grub_printf_ (N_("Invalid cryptodisk_passphrase_tries value `%s'. Defaulting to %lu.\n"),
|
|
||||||
tries_env,
|
|
||||||
tries);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; tries > 0; tries--)
|
|
||||||
{
|
|
||||||
part = grub_partition_get_name (source->partition);
|
|
||||||
grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name,
|
|
||||||
source->partition != NULL ? "," : "",
|
|
||||||
part != NULL ? part : N_("UNKNOWN"),
|
|
||||||
dev->uuid);
|
|
||||||
grub_free (part);
|
|
||||||
|
|
||||||
if (!grub_password_get ((char *) cargs->key_data, GRUB_CRYPTODISK_MAX_PASSPHRASE))
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_BAD_ARGUMENT, "passphrase not supplied");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
cargs->key_len = grub_strlen ((char *) cargs->key_data);
|
|
||||||
|
|
||||||
ret = cr->recover_key (source, dev, cargs);
|
|
||||||
if (ret == GRUB_ERR_NONE)
|
|
||||||
break;
|
|
||||||
if (ret != GRUB_ERR_ACCESS_DENIED || tries == 1)
|
|
||||||
goto error;
|
|
||||||
grub_puts_ (N_("Invalid passphrase."));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Since recover_key() calls a function that returns grub_errno,
|
|
||||||
* a leftover error value from a previously rejected passphrase
|
|
||||||
* will trigger a phantom failure. We therefore clear it before
|
|
||||||
* trying a new passphrase.
|
|
||||||
*/
|
|
||||||
grub_errno = GRUB_ERR_NONE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = grub_cryptodisk_insert (dev, name, source);
|
|
||||||
if (ret != GRUB_ERR_NONE)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
goto cleanup;
|
|
||||||
}
|
}
|
||||||
grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk module can handle this device");
|
|
||||||
|
if (dev == NULL)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_BAD_MODULE,
|
||||||
|
"no cryptodisk module can handle this device");
|
||||||
|
goto error_no_close;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cargs->protectors)
|
||||||
|
{
|
||||||
|
for (i = 0; cargs->protectors[i]; i++)
|
||||||
|
{
|
||||||
|
if (cargs->key_cache[i].invalid)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (cargs->key_cache[i].key == NULL)
|
||||||
|
{
|
||||||
|
ret = grub_key_protector_recover_key (cargs->protectors[i],
|
||||||
|
&cargs->key_cache[i].key,
|
||||||
|
&cargs->key_cache[i].key_len);
|
||||||
|
if (ret != GRUB_ERR_NONE)
|
||||||
|
{
|
||||||
|
if (grub_errno)
|
||||||
|
{
|
||||||
|
grub_print_error ();
|
||||||
|
grub_errno = GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_dprintf ("cryptodisk",
|
||||||
|
"failed to recover a key from key protector "
|
||||||
|
"%s, will not try it again for any other "
|
||||||
|
"disks, if any, during this invocation of "
|
||||||
|
"cryptomount\n",
|
||||||
|
cargs->protectors[i]);
|
||||||
|
|
||||||
|
cargs->key_cache[i].invalid = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cargs->key_data = cargs->key_cache[i].key;
|
||||||
|
cargs->key_len = cargs->key_cache[i].key_len;
|
||||||
|
|
||||||
|
ret = cr->recover_key (source, dev, cargs);
|
||||||
|
if (ret != GRUB_ERR_NONE)
|
||||||
|
{
|
||||||
|
part = grub_partition_get_name (source->partition);
|
||||||
|
grub_dprintf ("cryptodisk",
|
||||||
|
"recovered a key from key protector %s but it "
|
||||||
|
"failed to unlock %s%s%s (%s)\n",
|
||||||
|
cargs->protectors[i], source->name,
|
||||||
|
source->partition != NULL ? "," : "",
|
||||||
|
part != NULL ? part : N_("UNKNOWN"), dev->uuid);
|
||||||
|
grub_free (part);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = grub_cryptodisk_insert (dev, name, source);
|
||||||
|
if (ret != GRUB_ERR_NONE)
|
||||||
|
goto error;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
part = grub_partition_get_name (source->partition);
|
||||||
|
grub_error (GRUB_ERR_ACCESS_DENIED,
|
||||||
|
N_("no key protector provided a usable key for %s%s%s (%s)"),
|
||||||
|
source->name, source->partition != NULL ? "," : "",
|
||||||
|
part != NULL ? part : N_("UNKNOWN"), dev->uuid);
|
||||||
|
grub_free (part);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cargs->key_len)
|
||||||
|
{
|
||||||
|
ret = cr->recover_key (source, dev, cargs);
|
||||||
|
if (ret != GRUB_ERR_NONE)
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Get the passphrase from the user, if no key data. */
|
||||||
|
unsigned long tries = 3;
|
||||||
|
const char *tries_env;
|
||||||
|
|
||||||
|
askpass = 1;
|
||||||
|
cargs->key_data = grub_malloc (GRUB_CRYPTODISK_MAX_PASSPHRASE);
|
||||||
|
if (cargs->key_data == NULL)
|
||||||
|
goto error_no_close;
|
||||||
|
|
||||||
|
tries_env = grub_env_get ("cryptodisk_passphrase_tries");
|
||||||
|
if (tries_env != NULL && tries_env[0] != '\0')
|
||||||
|
{
|
||||||
|
unsigned long tries_env_val;
|
||||||
|
const char *p;
|
||||||
|
|
||||||
|
tries_env_val = grub_strtoul (tries_env, &p, 0);
|
||||||
|
if (*p == '\0' && tries_env_val != ~0UL)
|
||||||
|
tries = tries_env_val;
|
||||||
|
else
|
||||||
|
grub_printf_ (N_("Invalid cryptodisk_passphrase_tries value `%s'. Defaulting to %lu.\n"),
|
||||||
|
tries_env,
|
||||||
|
tries);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; tries > 0; tries--)
|
||||||
|
{
|
||||||
|
part = grub_partition_get_name (source->partition);
|
||||||
|
grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name,
|
||||||
|
source->partition != NULL ? "," : "",
|
||||||
|
part != NULL ? part : N_("UNKNOWN"),
|
||||||
|
dev->uuid);
|
||||||
|
grub_free (part);
|
||||||
|
|
||||||
|
if (!grub_password_get ((char *) cargs->key_data, GRUB_CRYPTODISK_MAX_PASSPHRASE))
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_BAD_ARGUMENT, "passphrase not supplied");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
cargs->key_len = grub_strlen ((char *) cargs->key_data);
|
||||||
|
|
||||||
|
ret = cr->recover_key (source, dev, cargs);
|
||||||
|
if (ret == GRUB_ERR_NONE)
|
||||||
|
break;
|
||||||
|
if (ret != GRUB_ERR_ACCESS_DENIED || tries == 1)
|
||||||
|
goto error;
|
||||||
|
grub_puts_ (N_("Invalid passphrase."));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Since recover_key() calls a function that returns grub_errno,
|
||||||
|
* a leftover error value from a previously rejected passphrase
|
||||||
|
* will trigger a phantom failure. We therefore clear it before
|
||||||
|
* trying a new passphrase.
|
||||||
|
*/
|
||||||
|
grub_errno = GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = grub_cryptodisk_insert (dev, name, source);
|
||||||
|
if (ret != GRUB_ERR_NONE)
|
||||||
|
goto error;
|
||||||
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
@@ -1298,6 +1375,20 @@ grub_cryptodisk_scan_device (const char *name,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
grub_cryptodisk_clear_key_cache (struct grub_cryptomount_args *cargs)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (cargs->key_cache == NULL || cargs->protectors == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; cargs->protectors[i]; i++)
|
||||||
|
grub_free (cargs->key_cache[i].key);
|
||||||
|
|
||||||
|
grub_free (cargs->key_cache);
|
||||||
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||||
{
|
{
|
||||||
@@ -1310,6 +1401,14 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
|||||||
if (grub_cryptodisk_list == NULL)
|
if (grub_cryptodisk_list == NULL)
|
||||||
return grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk modules loaded");
|
return grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk modules loaded");
|
||||||
|
|
||||||
|
if (state[OPTION_PASSWORD].set && state[OPTION_PROTECTOR].set) /* password and key protector */
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||||
|
"a password and a key protector cannot both be set");
|
||||||
|
|
||||||
|
if (state[OPTION_KEYFILE].set && state[OPTION_PROTECTOR].set) /* key file and key protector */
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||||
|
"a key file and a key protector cannot both be set");
|
||||||
|
|
||||||
if (state[OPTION_PASSWORD].set) /* password */
|
if (state[OPTION_PASSWORD].set) /* password */
|
||||||
{
|
{
|
||||||
cargs.key_data = (grub_uint8_t *) state[OPTION_PASSWORD].arg;
|
cargs.key_data = (grub_uint8_t *) state[OPTION_PASSWORD].arg;
|
||||||
@@ -1402,6 +1501,15 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
|||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (state[OPTION_PROTECTOR].set) /* key protector(s) */
|
||||||
|
{
|
||||||
|
cargs.key_cache = grub_zalloc (state[OPTION_PROTECTOR].set * sizeof (*cargs.key_cache));
|
||||||
|
if (cargs.key_cache == NULL)
|
||||||
|
return grub_error (GRUB_ERR_OUT_OF_MEMORY,
|
||||||
|
"no memory for key protector key cache");
|
||||||
|
cargs.protectors = state[OPTION_PROTECTOR].args;
|
||||||
|
}
|
||||||
|
|
||||||
if (state[OPTION_UUID].set) /* uuid */
|
if (state[OPTION_UUID].set) /* uuid */
|
||||||
{
|
{
|
||||||
int found_uuid;
|
int found_uuid;
|
||||||
@@ -1410,6 +1518,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
|||||||
dev = grub_cryptodisk_get_by_uuid (args[0]);
|
dev = grub_cryptodisk_get_by_uuid (args[0]);
|
||||||
if (dev)
|
if (dev)
|
||||||
{
|
{
|
||||||
|
grub_cryptodisk_clear_key_cache (&cargs);
|
||||||
grub_dprintf ("cryptodisk",
|
grub_dprintf ("cryptodisk",
|
||||||
"already mounted as crypto%lu\n", dev->id);
|
"already mounted as crypto%lu\n", dev->id);
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
@@ -1418,6 +1527,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
|||||||
cargs.check_boot = state[OPTION_BOOT].set;
|
cargs.check_boot = state[OPTION_BOOT].set;
|
||||||
cargs.search_uuid = args[0];
|
cargs.search_uuid = args[0];
|
||||||
found_uuid = grub_device_iterate (&grub_cryptodisk_scan_device, &cargs);
|
found_uuid = grub_device_iterate (&grub_cryptodisk_scan_device, &cargs);
|
||||||
|
grub_cryptodisk_clear_key_cache (&cargs);
|
||||||
|
|
||||||
if (found_uuid)
|
if (found_uuid)
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
@@ -1437,6 +1547,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
|||||||
{
|
{
|
||||||
cargs.check_boot = state[OPTION_BOOT].set;
|
cargs.check_boot = state[OPTION_BOOT].set;
|
||||||
grub_device_iterate (&grub_cryptodisk_scan_device, &cargs);
|
grub_device_iterate (&grub_cryptodisk_scan_device, &cargs);
|
||||||
|
grub_cryptodisk_clear_key_cache (&cargs);
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1460,6 +1571,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
|||||||
disk = grub_disk_open (diskname);
|
disk = grub_disk_open (diskname);
|
||||||
if (!disk)
|
if (!disk)
|
||||||
{
|
{
|
||||||
|
grub_cryptodisk_clear_key_cache (&cargs);
|
||||||
if (disklast)
|
if (disklast)
|
||||||
*disklast = ')';
|
*disklast = ')';
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
@@ -1470,12 +1582,14 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
|||||||
{
|
{
|
||||||
grub_dprintf ("cryptodisk", "already mounted as crypto%lu\n", dev->id);
|
grub_dprintf ("cryptodisk", "already mounted as crypto%lu\n", dev->id);
|
||||||
grub_disk_close (disk);
|
grub_disk_close (disk);
|
||||||
|
grub_cryptodisk_clear_key_cache (&cargs);
|
||||||
if (disklast)
|
if (disklast)
|
||||||
*disklast = ')';
|
*disklast = ')';
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev = grub_cryptodisk_scan_device_real (diskname, disk, &cargs);
|
dev = grub_cryptodisk_scan_device_real (diskname, disk, &cargs);
|
||||||
|
grub_cryptodisk_clear_key_cache (&cargs);
|
||||||
|
|
||||||
grub_disk_close (disk);
|
grub_disk_close (disk);
|
||||||
if (disklast)
|
if (disklast)
|
||||||
@@ -1629,6 +1743,7 @@ GRUB_MOD_INIT (cryptodisk)
|
|||||||
cmd = grub_register_extcmd ("cryptomount", grub_cmd_cryptomount, 0,
|
cmd = grub_register_extcmd ("cryptomount", grub_cmd_cryptomount, 0,
|
||||||
N_("[ [-p password] | [-k keyfile"
|
N_("[ [-p password] | [-k keyfile"
|
||||||
" [-O keyoffset] [-S keysize] ] ] [-H file]"
|
" [-O keyoffset] [-S keysize] ] ] [-H file]"
|
||||||
|
" [-P protector [-P protector ...]]"
|
||||||
" <SOURCE|-u UUID|-a|-b>"),
|
" <SOURCE|-u UUID|-a|-b>"),
|
||||||
N_("Mount a crypto device."), options);
|
N_("Mount a crypto device."), options);
|
||||||
grub_procfs_register ("luks_script", &luks_script);
|
grub_procfs_register ("luks_script", &luks_script);
|
||||||
|
|||||||
@@ -70,6 +70,18 @@ typedef gcry_err_code_t
|
|||||||
(*grub_cryptodisk_rekey_func_t) (struct grub_cryptodisk *dev,
|
(*grub_cryptodisk_rekey_func_t) (struct grub_cryptodisk *dev,
|
||||||
grub_uint64_t zoneno);
|
grub_uint64_t zoneno);
|
||||||
|
|
||||||
|
struct grub_cryptomount_cached_key
|
||||||
|
{
|
||||||
|
grub_uint8_t *key;
|
||||||
|
grub_size_t key_len;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The key protector associated with this cache entry failed, so avoid it
|
||||||
|
* even if the cached entry (an instance of this structure) is empty.
|
||||||
|
*/
|
||||||
|
bool invalid;
|
||||||
|
};
|
||||||
|
|
||||||
struct grub_cryptomount_args
|
struct grub_cryptomount_args
|
||||||
{
|
{
|
||||||
/* scan: Flag to indicate that only bootable volumes should be decrypted */
|
/* scan: Flag to indicate that only bootable volumes should be decrypted */
|
||||||
@@ -81,6 +93,10 @@ struct grub_cryptomount_args
|
|||||||
/* recover_key: Length of key_data */
|
/* recover_key: Length of key_data */
|
||||||
grub_size_t key_len;
|
grub_size_t key_len;
|
||||||
grub_file_t hdr_file;
|
grub_file_t hdr_file;
|
||||||
|
/* recover_key: Names of the key protectors to use (NULL-terminated) */
|
||||||
|
char **protectors;
|
||||||
|
/* recover_key: Key cache to avoid invoking the same key protector twice */
|
||||||
|
struct grub_cryptomount_cached_key *key_cache;
|
||||||
};
|
};
|
||||||
typedef struct grub_cryptomount_args *grub_cryptomount_args_t;
|
typedef struct grub_cryptomount_args *grub_cryptomount_args_t;
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user