Add --unbound keyslot option to cryptsetup.

An unbound keyslot is slot not assigned to a segment;
such a keyslot cannot be used to activate LUKS device, but
can be used for an arbitrary key store.

This patch adds --unboud option for luksAddKey cryptsetup command.
This commit is contained in:
Ondrej Kozina
2018-04-16 16:09:36 +02:00
committed by Milan Broz
parent 103fa8fa2c
commit 38d83c27b4
2 changed files with 89 additions and 5 deletions

View File

@@ -270,15 +270,22 @@ Prompts interactively for a passphrase if \-\-key-file is not given.
.PP .PP
\fIluksAddKey\fR <device> [<key file with new key>] \fIluksAddKey\fR <device> [<key file with new key>]
.IP .IP
adds a new passphrase. An existing passphrase must be supplied Adds a new passphrase. An existing passphrase must be supplied
interactively or via \-\-key-file. interactively or via \-\-key-file.
The new passphrase to be added can be specified interactively The new passphrase to be added can be specified interactively
or read from the file given as positional argument. or read from the file given as positional argument.
\fBNOTE:\fR with \-\-unbound option the action creates new unbound
LUKS2 keyslot. The keyslot cannot be used for device activation.
If you don't pass new key via \-\-master\-key\-file option,
new random key is generated. Existing passphrase for any active keyslot
is not required.
\fB<options>\fR can be [\-\-key\-file, \-\-keyfile\-offset, \fB<options>\fR can be [\-\-key\-file, \-\-keyfile\-offset,
\-\-keyfile\-size, \-\-new\-keyfile\-offset, \-\-keyfile\-size, \-\-new\-keyfile\-offset,
\-\-new\-keyfile\-size, \-\-key\-slot, \-\-master\-key\-file, \-\-new\-keyfile\-size, \-\-key\-slot, \-\-master\-key\-file,
\-\-iter\-time, \-\-force\-password, \-\-header, \-\-disable\-locks]. \-\-iter\-time, \-\-force\-password, \-\-header, \-\-disable\-locks,
\-\-unbound].
.PP .PP
\fIluksRemoveKey\fR <device> [<key file with passphrase to be removed>] \fIluksRemoveKey\fR <device> [<key file with passphrase to be removed>]
.IP .IP
@@ -1166,6 +1173,11 @@ to the sector.
aligned to page size and page-cache initiates read of a sector with invalid aligned to page size and page-cache initiates read of a sector with invalid
integrity tag. integrity tag.
.TP .TP
.B "\-\-unbound"
Creates new LUKS2 unbound keyslot. See \fIluksAddKey\fR action for more
details.
.TP
.B "\-\-tcrypt\-hidden" .B "\-\-tcrypt\-hidden"
.B "\-\-tcrypt\-system" .B "\-\-tcrypt\-system"
.B "\-\-tcrypt\-backup" .B "\-\-tcrypt\-backup"

View File

@@ -87,6 +87,7 @@ static int opt_sector_size = SECTOR_SIZE;
static int opt_persistent = 0; static int opt_persistent = 0;
static const char *opt_label = NULL; static const char *opt_label = NULL;
static const char *opt_subsystem = NULL; static const char *opt_subsystem = NULL;
static int opt_unbound = 0;
static const char **action_argv; static const char **action_argv;
static int action_argc; static int action_argc;
@@ -1280,6 +1281,61 @@ out:
return r; return r;
} }
static int luksAddUnboundKey(void)
{
int r = -EINVAL, keysize = 0;
char *key = NULL;
const char *opt_new_key_file = (action_argc > 1 ? action_argv[1] : NULL);
char *password_new = NULL;
size_t password_new_size = 0;
struct crypt_device *cd = NULL;
if ((r = crypt_init(&cd, uuid_or_device_header(NULL))))
goto out;
crypt_set_confirm_callback(cd, yesDialog, NULL);
if ((r = crypt_load(cd, CRYPT_LUKS2, NULL)))
goto out;
/* Never call pwquality if using null cipher */
if (tools_is_cipher_null(crypt_get_cipher(cd)))
opt_force_password = 1;
keysize = opt_key_size / 8;
r = set_pbkdf_params(cd, crypt_get_type(cd));
if (r) {
log_err(_("Failed to set pbkdf parameters.\n"));
goto out;
}
if (opt_master_key_file) {
r = tools_read_mk(opt_master_key_file, &key, keysize);
if (r < 0)
goto out;
check_signal(&r);
if (r < 0)
goto out;
}
r = tools_get_key(_("Enter new passphrase for key slot: "),
&password_new, &password_new_size,
opt_new_keyfile_offset, opt_new_keyfile_size,
opt_new_key_file, opt_timeout,
_verify_passphrase(1), 1, cd);
if (r < 0)
goto out;
r = crypt_keyslot_add_by_key(cd, opt_key_slot, key, keysize,
password_new, password_new_size, CRYPT_VOLUME_KEY_NO_SEGMENT);
out:
crypt_safe_free(password_new);
crypt_safe_free(key);
crypt_free(cd);
return r;
}
static int action_luksAddKey(void) static int action_luksAddKey(void)
{ {
int r = -EINVAL, keysize = 0; int r = -EINVAL, keysize = 0;
@@ -1289,6 +1345,10 @@ static int action_luksAddKey(void)
size_t password_size = 0, password_new_size = 0; size_t password_size = 0, password_new_size = 0;
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
/* Unbound keyslot (no assigned data segment) is special case */
if (opt_unbound)
return luksAddUnboundKey();
if ((r = crypt_init(&cd, uuid_or_device_header(NULL)))) if ((r = crypt_init(&cd, uuid_or_device_header(NULL))))
goto out; goto out;
@@ -2132,6 +2192,7 @@ int main(int argc, const char **argv)
{ "persistent", '\0', POPT_ARG_NONE, &opt_persistent, 0, N_("Set activation flags persistent for device."), NULL }, { "persistent", '\0', POPT_ARG_NONE, &opt_persistent, 0, N_("Set activation flags persistent for device."), NULL },
{ "label", '\0', POPT_ARG_STRING, &opt_label, 0, N_("Set label for the LUKS2 device."), NULL }, { "label", '\0', POPT_ARG_STRING, &opt_label, 0, N_("Set label for the LUKS2 device."), NULL },
{ "subsystem", '\0', POPT_ARG_STRING, &opt_subsystem, 0, N_("Set subsystem label for the LUKS2 device."), NULL }, { "subsystem", '\0', POPT_ARG_STRING, &opt_subsystem, 0, N_("Set subsystem label for the LUKS2 device."), NULL },
{ "unbound", '\0', POPT_ARG_NONE, &opt_unbound, 0, N_("Create unbound (no assigned data segment) LUKS2 keyslot."), NULL },
POPT_TABLEEND POPT_TABLEEND
}; };
poptContext popt_context; poptContext popt_context;
@@ -2296,10 +2357,11 @@ int main(int argc, const char **argv)
if (opt_key_size && if (opt_key_size &&
strcmp(aname, "luksFormat") && strcmp(aname, "luksFormat") &&
strcmp(aname, "open") && strcmp(aname, "open") &&
strcmp(aname, "benchmark")) strcmp(aname, "benchmark") &&
(strcmp(aname, "luksAddKey") || !opt_unbound))
usage(popt_context, EXIT_FAILURE, usage(popt_context, EXIT_FAILURE,
_("Option --key-size is allowed only for luksFormat, open and benchmark.\n" _("Option --key-size is allowed only for luksFormat, luksAddKey (with --unbound),\n"
"To limit read from keyfile use --keyfile-size=(bytes)."), "open and benchmark actions. To limit read from keyfile use --keyfile-size=(bytes)."),
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
if (opt_integrity && strcmp(aname, "luksFormat")) if (opt_integrity && strcmp(aname, "luksFormat"))
@@ -2453,6 +2515,16 @@ int main(int argc, const char **argv)
_("Unsupported encryption sector size.\n"), _("Unsupported encryption sector size.\n"),
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
if (opt_unbound && !opt_key_size)
usage(popt_context, EXIT_FAILURE,
_("Key size is required with --unbound option.\n"),
poptGetInvocationName(popt_context));
if (opt_unbound && strcmp(aname, "luksAddKey"))
usage(popt_context, EXIT_FAILURE,
_("Option --unbound may be used only with luksAddKey action.\n"),
poptGetInvocationName(popt_context));
if (opt_debug) { if (opt_debug) {
opt_verbose = 1; opt_verbose = 1;
crypt_set_debug_level(-1); crypt_set_debug_level(-1);