zkey: Add open and format options to the cryptsetup command

For LUKS2 volumes the cryptsetup command currently generates
'cryptsetup luksFormat' commands, but for plain mode volumes it
generates 'cryptsetup plainOpen' commands.

With the --open option it can now also generate 'cryptsetup luksOpen'
commands for opening LUKS2 volumes. With the --format option you can
limit the generated commands to only generate 'cryptsetup luksFormat'
commands for LUKS2 volumes, and skip plain mode volumes.
The default behavior (i.e. if none of the two options specified),
remains the same as before.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
Ingo Franzki
2019-03-14 16:36:35 +01:00
committed by Jan Höppner
parent 3ed8ab4e2a
commit 11bfa1d3c8
4 changed files with 133 additions and 39 deletions

View File

@@ -3247,6 +3247,8 @@ struct crypt_info {
size_t keyfile_offset;
size_t keyfile_size;
size_t tries;
bool open;
bool format;
char **volume_filter;
int (*process_func)(struct keystore *keystore,
const char *volume,
@@ -3318,6 +3320,9 @@ static int _keystore_process_cryptsetup(struct keystore *keystore,
free(tries_opt);
if (strcasecmp(volume_type, VOLUME_TYPE_PLAIN) == 0) {
if (info->format)
return 0;
util_asprintf(&cmd,
"cryptsetup plainOpen %s%s--key-file '%s' "
"--key-size %lu --cipher %s %s%s %s",
@@ -3333,43 +3338,63 @@ static int _keystore_process_cryptsetup(struct keystore *keystore,
printf("%s\n", cmd);
}
} else if (strcasecmp(volume_type, VOLUME_TYPE_LUKS2) == 0) {
/*
* Use PBKDF2 as key derivation function for LUKS2 volumes.
* LUKS2 uses Argon2i as default, but this might cause
* out-of-memory errors when multiple LUKS2 volumes are opened
* automatically via /etc/crypttab
*/
util_asprintf(&cmd,
"cryptsetup luksFormat %s%s--type luks2 "
"--master-key-file '%s' --key-size %lu "
"--cipher %s --pbkdf pbkdf2 %s%s%s",
info->batch_mode ? "-q " : "",
keystore->verbose ? "-v " : "", key_file_name,
key_file_size * 8, cipher_spec,
common_len > 0 ? common_passphrase_options : "",
sector_size > 0 ? temp : "", volume);
if (info->open) {
util_asprintf(&cmd,
"cryptsetup luksOpen %s%s%s%s %s",
info->batch_mode ? "-q " : "",
keystore->verbose ? "-v " : "",
common_len > 0 ?
common_passphrase_options : "",
volume, dmname);
if (info->execute) {
printf("Executing: %s\n", cmd);
rc = _keystore_execute_cmd(cmd, "cryptsetup");
if (info->execute) {
printf("Executing: %s\n", cmd);
rc = _keystore_execute_cmd(cmd, "cryptsetup");
} else {
printf("%s\n", cmd);
}
} else {
printf("%s\n", cmd);
}
/*
* Use PBKDF2 as key derivation function for LUKS2
* volumes. LUKS2 uses Argon2i as default, but this
* might cause out-of-memory errors when multiple LUKS2
* volumes are opened automatically via /etc/crypttab
*/
util_asprintf(&cmd,
"cryptsetup luksFormat %s%s--type luks2 "
"--master-key-file '%s' --key-size %lu "
"--cipher %s --pbkdf pbkdf2 %s%s%s",
info->batch_mode ? "-q " : "",
keystore->verbose ? "-v " : "",
key_file_name, key_file_size * 8,
cipher_spec, common_len > 0 ?
common_passphrase_options : "",
sector_size > 0 ? temp : "", volume);
free(cmd);
if (rc != 0)
return rc;
if (info->execute) {
printf("Executing: %s\n", cmd);
rc = _keystore_execute_cmd(cmd, "cryptsetup");
} else {
printf("%s\n", cmd);
}
util_asprintf(&cmd,
"zkey-cryptsetup setvp %s %s%s", volume,
common_len > 0 ? common_passphrase_options : "",
keystore->verbose ? "-V" : "");
free(cmd);
if (rc != 0)
return rc;
if (info->execute) {
printf("Executing: %s\n", cmd);
rc = _keystore_execute_cmd(cmd, "zkey-cryptsetup");
} else {
printf("%s\n", cmd);
util_asprintf(&cmd,
"zkey-cryptsetup setvp %s %s%s", volume,
common_len > 0 ?
common_passphrase_options : "",
keystore->verbose ? "-V" : "");
if (info->execute) {
printf("Executing: %s\n", cmd);
rc = _keystore_execute_cmd(cmd,
"zkey-cryptsetup");
} else {
printf("%s\n", cmd);
}
}
} else {
return -EINVAL;
@@ -3630,12 +3655,15 @@ out:
* @param[in] keyfile_size the size in bytes for reading from keyfile
* @param[in] tries the number of tries for passphrase entry
* @param[in] batch_mode If TRUE, suppress cryptsetup confirmation questions
* @param[in] open If TRUE, generate luksOpen/plainOpen commands
* @param[in] format If TRUE, generate luksFormat commands
* @returns 0 for success or a negative errno in case of an error
*/
int keystore_cryptsetup(struct keystore *keystore, const char *volume_filter,
bool execute, const char *volume_type,
const char *keyfile, size_t keyfile_offset,
size_t keyfile_size, size_t tries, bool batch_mode)
size_t keyfile_size, size_t tries, bool batch_mode,
bool open, bool format)
{
struct crypt_info info = { 0 };
int rc;
@@ -3652,6 +3680,8 @@ int keystore_cryptsetup(struct keystore *keystore, const char *volume_filter,
}
info.execute = execute;
info.open = open;
info.format = format;
info.batch_mode = batch_mode;
info.keyfile = keyfile;
info.keyfile_offset = keyfile_offset;

View File

@@ -70,7 +70,8 @@ int keystore_list_keys(struct keystore *keystore, const char *name_filter,
int keystore_cryptsetup(struct keystore *keystore, const char *volume_filter,
bool execute, const char *volume_type,
const char *keyfile, size_t keyfile_offset,
size_t keyfile_size, size_t tries, bool batch_mode);
size_t keyfile_size, size_t tries, bool batch_mode,
bool open, bool format);
int keystore_crypttab(struct keystore *keystore, const char *volume_filter,
const char *volume_type, const char *keyfile,

View File

@@ -572,6 +572,8 @@ has been compiled with LUKS2 support enabled.
.RB [ \-\-volume-type | \-t
.IR type ]
.RB [ \-\-run | \-r ]
.RB [ \-\-open ]
.RB [ \-\-format ]
.RB [ \-\-key\-file
.IR file-name ]
.RB [ \-\-keyfile\-offset
@@ -585,9 +587,9 @@ has been compiled with LUKS2 support enabled.
.PP
Use the
.B cryptsetup
command to generate \fBcryptsetup plainOpen\fP or \fBcryptsetup luksFormat\fP
commands for volumes that are associated with secure keys contained in the
secure key repository. Specify the
command to generate \fBcryptsetup plainOpen\fP, \fBcryptsetup luksOpen\fP, or
\fBcryptsetup luksFormat\fP commands for volumes that are associated with
secure keys contained in the secure key repository. Specify the
.B \-\-volumes
option to limit the list
of volumes where cryptsetup commands are generated for. You can use wildcards.
@@ -599,7 +601,14 @@ name are selected. Specify the
option to generate cryptsetup commands for the specified volume type only.
Specify the
.B \-\-run
option to run the generated cryptsetup commands.
option to run the generated cryptsetup commands. Specify the
.B \-\-open
to generate \fBcryptsetup plainOpen\fP or \fBcryptsetup luksOpen\fP commands.
For the plain volume type, this is the default. Specify the
.B \-\-format
option to generate \fBcryptsetup luksFormat\fP commands. For the LUKS2 volume
type, this is the default. If specified for the plain volume type, then no
command is generated.
.P
For LUKS2 volumes, the generated \fBcryptsetup luksFormat\fP contains
option \fB\-\-pbkdf pbkdf2\fP to set \fBPBKDF2\fP as password based key
@@ -1051,6 +1060,24 @@ Runs the generated cryptsetup commands. When one of the cryptsetup command fail,
no further cryptsetup commands are run, and zkey ends with an error.
This option is only used for secure keys contained in the secure key repository.
.TP
.BR \-\-open
Generates \fBcryptsetup luksOpen\fP or \fBcryptsetup plainOpen\fP commands.
For a plain volume type, this is the default. This option can not be specified
together with the
.BR \-\-format
option, and is only available if
.B zkey
has been compiled with LUKS2 support enabled.
.TP
.BR \-\-format
Generates \fBcryptsetup luksFormat\fP commands. For a LUKS2 volume type, this
is the default. If specified for a plain volume type, then no command is
generated. This option can not be specified together with the
.BR \-\-open
option, and is only available if
.B zkey
has been compiled with LUKS2 support enabled.
.TP
.BR \-\-key\-file\~\fIfile\-name\fP
Reads the passphrase from the specified file. If this option is omitted,
or if the file\-name is \fI-\fP (a dash), then you are prompted to enter the

View File

@@ -77,6 +77,8 @@ static struct zkey_globals {
long long keyfile_size;
long long tries;
bool force;
bool open;
bool format;
void *lib_csulcca;
t_CSNBKTC dll_CSNBKTC;
int pkey_fd;
@@ -111,6 +113,8 @@ static struct zkey_globals {
#define OPT_CRYPTSETUP_KEYFILE_OFFSET 257
#define OPT_CRYPTSETUP_KEYFILE_SIZE 258
#define OPT_CRYPTSETUP_TRIES 259
#define OPT_CRYPTSETUP_OPEN 260
#define OPT_CRYPTSETUP_FORMAT 261
/*
* Configuration of command line options
@@ -691,6 +695,23 @@ static struct util_opt opt_vec[] = {
"command(s)",
.command = COMMAND_CRYPTSETUP,
},
#ifdef HAVE_LUKS2_SUPPORT
{
.option = {"open", 0, NULL, OPT_CRYPTSETUP_OPEN},
.desc = "Generates luksOpen or plainOpen commands. For the "
"plain volume type, this is the default",
.command = COMMAND_CRYPTSETUP,
.flags = UTIL_OPT_FLAG_NOSHORT,
},
{
.option = {"format", 0, NULL, OPT_CRYPTSETUP_FORMAT},
.desc = "Generates luksFormat commands. For the LUKS2 volume "
"type, this is the default. If specified for the "
"plain volume type, then no command is generated",
.command = COMMAND_CRYPTSETUP,
.flags = UTIL_OPT_FLAG_NOSHORT,
},
#endif
/***********************************************************/
{
.flags = UTIL_OPT_FLAG_SECTION,
@@ -1490,9 +1511,16 @@ static int command_cryptsetup(void)
{
int rc;
if (g.open && g.format) {
warnx("Either '--open' or '--format' can be specified, but "
"not both");
util_prg_print_parse_error();
return EXIT_FAILURE;
}
rc = keystore_cryptsetup(g.keystore, g.volumes, g.run, g.volume_type,
g.keyfile, g.keyfile_offset, g.keyfile_size,
g.tries, g.batch_mode);
g.tries, g.batch_mode, g.open, g.format);
return rc != 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
@@ -1728,6 +1756,14 @@ int main(int argc, char *argv[])
case 'q':
g.batch_mode = 1;
break;
#ifdef HAVE_LUKS2_SUPPORT
case OPT_CRYPTSETUP_OPEN:
g.open = 1;
break;
case OPT_CRYPTSETUP_FORMAT:
g.format = 1;
break;
#endif
case 'h':
print_help(command);
return EXIT_SUCCESS;