diff --git a/zkey/keystore.c b/zkey/keystore.c index 603b0179..a2bb2972 100644 --- a/zkey/keystore.c +++ b/zkey/keystore.c @@ -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; diff --git a/zkey/keystore.h b/zkey/keystore.h index b3b846eb..180bf171 100644 --- a/zkey/keystore.h +++ b/zkey/keystore.h @@ -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, diff --git a/zkey/zkey.1 b/zkey/zkey.1 index 7c6b4979..fb7561bb 100644 --- a/zkey/zkey.1 +++ b/zkey/zkey.1 @@ -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 diff --git a/zkey/zkey.c b/zkey/zkey.c index 120bcce0..f682ab92 100644 --- a/zkey/zkey.c +++ b/zkey/zkey.c @@ -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;