forked from pool/s390-tools
a7f8ed0265
Lots of features implemented for SLES15 SP1. OBS-URL: https://build.opensuse.org/request/show/648783 OBS-URL: https://build.opensuse.org/package/show/Base:System/s390-tools?expand=0&rev=57
1804 lines
61 KiB
Diff
1804 lines
61 KiB
Diff
Subject: zkey: Add volume-type property to support LUKS2 volumes
|
|
From: Ingo Franzki <ifranzki@linux.ibm.com>
|
|
|
|
Summary: zkey: Support CCA master key change with LUKS2 volumes using paes
|
|
Description: Support the usage of protected key crypto for dm-crypt disks in
|
|
LUKS2 format by providing a tool allowing to re-encipher a
|
|
secure LUKS2 volume key when the CCA master key is changed
|
|
Upstream-ID: 1f07a41d5a408c1650d20a688cf10bd02a8e7dd7
|
|
Problem-ID: SEC1424.1
|
|
|
|
Upstream-Description:
|
|
|
|
zkey: Add volume-type property to support LUKS2 volumes
|
|
|
|
Allow to specify a volume-type for a key. This applies to all
|
|
associated volumes. The volume type can be either 'plain' or
|
|
'luks2'. New keys created will default to 'luks2', but existing
|
|
keys that do not have a volume-type property default to 'plain'
|
|
for compatibility reasons.
|
|
|
|
The volume type 'luks2' is only available when the define
|
|
HAVE_LUKS2_SUPPORT is set in the makefile. This is set only
|
|
when libcryptsetup version 2.0.3 or newer is available
|
|
at build time. If the define is not set, the volume-type
|
|
option is not available to the user, and the volume-type of
|
|
a key defaults to 'plain'.
|
|
|
|
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
|
|
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
|
|
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
|
|
|
|
|
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
|
|
---
|
|
zkey/Makefile | 1
|
|
zkey/keystore.c | 423 +++++++++++++++++++++++++++++++++++++++++++++-----------
|
|
zkey/keystore.h | 15 +
|
|
zkey/zkey.1 | 292 ++++++++++++++++++++++++--------------
|
|
zkey/zkey.c | 100 +++++++++++--
|
|
5 files changed, 627 insertions(+), 204 deletions(-)
|
|
|
|
--- a/zkey/Makefile
|
|
+++ b/zkey/Makefile
|
|
@@ -12,6 +12,7 @@ ifneq (${HAVE_CRYPTSETUP2},0)
|
|
ifneq (${HAVE_JSONC},0)
|
|
BUILD_TARGETS += zkey-cryptsetup
|
|
INSTALL_TARGETS += install-zkey-cryptsetup
|
|
+ CPPFLAGS += -DHAVE_LUKS2_SUPPORT
|
|
else
|
|
BUILD_TARGETS += zkey-cryptsetup-skip-jsonc
|
|
INSTALL_TARGETS += zkey-cryptsetup-skip-jsonc
|
|
--- a/zkey/keystore.c
|
|
+++ b/zkey/keystore.c
|
|
@@ -59,6 +59,15 @@ struct key_filenames {
|
|
#define PROP_NAME_CHANGE_TIME "update-time"
|
|
#define PROP_NAME_REENC_TIME "reencipher-time"
|
|
#define PROP_NAME_KEY_VP "verification-pattern"
|
|
+#define PROP_NAME_VOLUME_TYPE "volume-type"
|
|
+
|
|
+#define VOLUME_TYPE_PLAIN "plain"
|
|
+#define VOLUME_TYPE_LUKS2 "luks2"
|
|
+#ifdef HAVE_LUKS2_SUPPORT
|
|
+ #define DEFAULT_VOLUME_TYPE VOLUME_TYPE_LUKS2
|
|
+#else
|
|
+ #define DEFAULT_VOLUME_TYPE VOLUME_TYPE_PLAIN
|
|
+#endif
|
|
|
|
#define IS_XTS(secure_key_size) (secure_key_size > SECURE_KEY_SIZE ? 1 : 0)
|
|
|
|
@@ -72,11 +81,12 @@ struct key_filenames {
|
|
#define REC_KEY_FILE "Key file name"
|
|
#define REC_SECTOR_SIZE "Sector size"
|
|
#define REC_STATUS "Status"
|
|
-#define REC_MASTERKEY "Encrypted with"
|
|
+#define REC_MASTERKEY "Enciphered with"
|
|
#define REC_CREATION_TIME "Created"
|
|
#define REC_CHANGE_TIME "Changed"
|
|
#define REC_REENC_TIME "Re-enciphered"
|
|
#define REC_KEY_VP "Verification pattern"
|
|
+#define REC_VOLUME_TYPE "Volume type"
|
|
|
|
#define pr_verbose(keystore, fmt...) do { \
|
|
if (keystore->verbose) \
|
|
@@ -280,6 +290,85 @@ static int _keystore_valid_sector_size(s
|
|
return 1;
|
|
}
|
|
|
|
+/**
|
|
+ * Checks if the volume type is supported.
|
|
+ *
|
|
+ * @param[in] volume_type the volume type
|
|
+ *
|
|
+ * @returns 1 if the volume type is valid, 0 otherwise
|
|
+ */
|
|
+static int _keystore_valid_volume_type(const char *volume_type)
|
|
+{
|
|
+ if (strcasecmp(volume_type, VOLUME_TYPE_PLAIN) == 0)
|
|
+ return 1;
|
|
+#ifdef HAVE_LUKS2_SUPPORT
|
|
+ if (strcasecmp(volume_type, VOLUME_TYPE_LUKS2) == 0)
|
|
+ return 1;
|
|
+#endif
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/**
|
|
+ * Returns the volume type contained in the properties. If no volume type
|
|
+ * property is contained, then 'plain' is assumed (for backward comatibility).
|
|
+ *
|
|
+ * @returns a string containing the volume type. Must be freed by the caller.
|
|
+ */
|
|
+static char *_keystore_get_volume_type(struct properties *properties)
|
|
+{
|
|
+ char *type;
|
|
+
|
|
+ type = properties_get(properties, PROP_NAME_VOLUME_TYPE);
|
|
+ if (type == NULL)
|
|
+ type = util_strdup(VOLUME_TYPE_PLAIN);
|
|
+
|
|
+ return type;
|
|
+}
|
|
+
|
|
+/**
|
|
+ * Prints a message followed by a list of associated volumes, if volumes are
|
|
+ * associated and the volume-type matches (if specified)
|
|
+ *
|
|
+ * @param[in] msg the message to display
|
|
+ * @param[in] properties the properties
|
|
+ * @param[in] volume_type the volume type to display the message for (or NULL)
|
|
+ *
|
|
+ * @returns always zero
|
|
+ */
|
|
+static int _keystore_msg_for_volumes(const char *msg,
|
|
+ struct properties *properties,
|
|
+ const char *volume_type)
|
|
+{
|
|
+ char *volumes = NULL;
|
|
+ char **volume_list;
|
|
+ char *type = NULL;
|
|
+ int i;
|
|
+
|
|
+ if (volume_type != NULL) {
|
|
+ type = _keystore_get_volume_type(properties);
|
|
+ if (strcasecmp(type, volume_type) != 0)
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ volumes = properties_get(properties, PROP_NAME_VOLUMES);
|
|
+ if (volumes != NULL && strlen(volumes) > 0) {
|
|
+ volume_list = str_list_split(volumes);
|
|
+
|
|
+ util_print_indented(msg, 0);
|
|
+ for (i = 0; volume_list[i] != NULL; i++)
|
|
+ printf(" %s\n", volume_list[i]);
|
|
+ str_list_free_string_array(volume_list);
|
|
+ }
|
|
+
|
|
+out:
|
|
+ if (volumes != NULL)
|
|
+ free(volumes);
|
|
+ if (type != NULL)
|
|
+ free(type);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
typedef int (*check_association_t)(const char *value, bool remove,
|
|
char **normalized, void *private);
|
|
|
|
@@ -712,6 +801,35 @@ static int _keystore_match_filter_proper
|
|
}
|
|
|
|
/**
|
|
+ * Checks if the volume type property matches the specified volume type.
|
|
+ * If the properties do not contain a volume type property, then the default
|
|
+ * volume type is assumed.
|
|
+ *
|
|
+ * @param[in] properties a properties object
|
|
+ * @param[in] volume_type the volume type to match. Can be NULL. In this case
|
|
+ * it always matches.
|
|
+ *
|
|
+ * @returns 1 for a match, 0 for not matched
|
|
+ */
|
|
+static int _keystore_match_volume_type_property(struct properties *properties,
|
|
+ const char *volume_type)
|
|
+{
|
|
+ char *type;
|
|
+ int rc = 0;
|
|
+
|
|
+ if (volume_type == NULL)
|
|
+ return 1;
|
|
+
|
|
+ type = _keystore_get_volume_type(properties);
|
|
+ if (strcasecmp(type, volume_type) == 0)
|
|
+ rc = 1;
|
|
+
|
|
+ free(type);
|
|
+ return rc;
|
|
+}
|
|
+
|
|
+
|
|
+/**
|
|
* Checks if a key name matches a name filter
|
|
*
|
|
* @param[in] name the name to check
|
|
@@ -774,6 +892,7 @@ typedef int (*process_key_t)(struct keys
|
|
* @param[in] apqn_filter the APQN filter. Can contain wild cards, and
|
|
* mutliple APQN filters separated by commas.
|
|
* NULL means no APQN filter.
|
|
+ * @param[in] volume_type If not NULL, specifies the volume type.
|
|
* @param[in] process_func the callback function called for a matching key
|
|
* @param[in/out] process_private private data passed to the process_func
|
|
*
|
|
@@ -785,6 +904,7 @@ static int _keystore_process_filtered(st
|
|
const char *name_filter,
|
|
const char *volume_filter,
|
|
const char *apqn_filter,
|
|
+ const char *volume_type,
|
|
process_key_t process_func,
|
|
void *process_private)
|
|
{
|
|
@@ -867,6 +987,15 @@ static int _keystore_process_filtered(st
|
|
goto free_prop;
|
|
}
|
|
|
|
+ rc = _keystore_match_volume_type_property(key_props,
|
|
+ volume_type);
|
|
+ if (rc == 0) {
|
|
+ pr_verbose(keystore,
|
|
+ "Key '%s' filtered out due to volume type",
|
|
+ name);
|
|
+ goto free_prop;
|
|
+ }
|
|
+
|
|
rc = process_func(keystore, name, key_props, &file_names,
|
|
process_private);
|
|
if (rc != 0) {
|
|
@@ -1122,8 +1251,8 @@ static int _keystore_volume_check(const
|
|
}
|
|
|
|
rc = _keystore_process_filtered(info->keystore, NULL, info->volume,
|
|
- NULL, _keystore_volume_check_process,
|
|
- info);
|
|
+ NULL, NULL,
|
|
+ _keystore_volume_check_process, info);
|
|
out:
|
|
free((void *)info->volume);
|
|
info->volume = NULL;
|
|
@@ -1418,13 +1547,15 @@ static int _keystore_set_default_propert
|
|
* of two and in range 512 - 4096 bytes. 0 means that
|
|
* the sector size is not specified and the system
|
|
* default is used.
|
|
+ * @param[in] volume_type the type of volume
|
|
*/
|
|
static int _keystore_create_info_file(struct keystore *keystore,
|
|
const char *name,
|
|
const struct key_filenames *filenames,
|
|
const char *description,
|
|
const char *volumes, const char *apqns,
|
|
- size_t sector_size)
|
|
+ size_t sector_size,
|
|
+ const char *volume_type)
|
|
{
|
|
struct volume_check vol_check = { .keystore = keystore, .name = name };
|
|
struct properties *key_props;
|
|
@@ -1469,6 +1600,19 @@ static int _keystore_create_info_file(st
|
|
goto out;
|
|
}
|
|
|
|
+ if (volume_type == NULL)
|
|
+ volume_type = DEFAULT_VOLUME_TYPE;
|
|
+ if (!_keystore_valid_volume_type(volume_type)) {
|
|
+ warnx("Invalid volume-type specified");
|
|
+ rc = -EINVAL;
|
|
+ goto out;
|
|
+ }
|
|
+ rc = properties_set(key_props, PROP_NAME_VOLUME_TYPE, volume_type);
|
|
+ if (rc != 0) {
|
|
+ warnx("Invalid characters in volume-type");
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
rc = _keystore_ensure_vp_exists(keystore, filenames, key_props);
|
|
if (rc != 0) {
|
|
warnx("Failed to generate the key verification pattern: %s",
|
|
@@ -1553,6 +1697,7 @@ out:
|
|
* @param[in] clear_key_file if not NULL the secure key is generated from the
|
|
* clear key contained in the file denoted here.
|
|
* if NULL, the secure key is generated by random.
|
|
+ * @param[in] volume_type the type of volume
|
|
* @param[in] pkey_fd the file descriptor of /dev/pkey
|
|
*
|
|
* @returns 0 for success or a negative errno in case of an error
|
|
@@ -1561,7 +1706,7 @@ int keystore_generate_key(struct keystor
|
|
const char *description, const char *volumes,
|
|
const char *apqns, size_t sector_size,
|
|
size_t keybits, bool xts, const char *clear_key_file,
|
|
- int pkey_fd)
|
|
+ const char *volume_type, int pkey_fd)
|
|
{
|
|
struct key_filenames file_names = { NULL, NULL, NULL };
|
|
struct properties *key_props = NULL;
|
|
@@ -1603,7 +1748,7 @@ int keystore_generate_key(struct keystor
|
|
|
|
rc = _keystore_create_info_file(keystore, name, &file_names,
|
|
description, volumes, apqns,
|
|
- sector_size);
|
|
+ sector_size, volume_type);
|
|
if (rc != 0)
|
|
goto out_free_props;
|
|
|
|
@@ -1640,14 +1785,15 @@ out_free_key_filenames:
|
|
* of two and in range 512 - 4096 bytes. 0 means that
|
|
* the sector size is not specified and the system
|
|
* default is used.
|
|
- * @param[in] import_file The name of a secure key containing the kley to import
|
|
+ * @param[in] import_file The name of a secure key containing the key to import
|
|
+ * @param[in] volume_type the type of volume
|
|
*
|
|
* @returns 0 for success or a negative errno in case of an error
|
|
*/
|
|
int keystore_import_key(struct keystore *keystore, const char *name,
|
|
const char *description, const char *volumes,
|
|
const char *apqns, size_t sector_size,
|
|
- const char *import_file)
|
|
+ const char *import_file, const char *volume_type)
|
|
{
|
|
struct key_filenames file_names = { NULL, NULL, NULL };
|
|
struct properties *key_props = NULL;
|
|
@@ -1686,7 +1832,7 @@ int keystore_import_key(struct keystore
|
|
|
|
rc = _keystore_create_info_file(keystore, name, &file_names,
|
|
description, volumes, apqns,
|
|
- sector_size);
|
|
+ sector_size, volume_type);
|
|
if (rc != 0)
|
|
goto out_free_props;
|
|
|
|
@@ -1722,25 +1868,28 @@ out_free_key_filenames:
|
|
* volumes are not changed.
|
|
* @param[in] apqns a comma separated list of APQNs associated with this
|
|
* key, or an APQN prefixed with '+' or '-' to add or
|
|
- * remove that APQN respectively. IfNULL then the APQNs
|
|
+ * remove that APQN respectively. If NULL then the APQNs
|
|
* are not changed.
|
|
* @param[in] sector_size the sector size to use with dm-crypt. It must be power
|
|
* of two and in range 512 - 4096 bytes. 0 means that
|
|
* the sector size is not specified and the system
|
|
* default is used. Specify -1 if this property should
|
|
* not be changed.
|
|
- *
|
|
+ * @param[in] volume_type the type of volume. If NULL then the volume type is
|
|
+ * not changed.
|
|
+ * *
|
|
* @returns 0 for success or a negative errno in case of an error
|
|
*
|
|
*/
|
|
int keystore_change_key(struct keystore *keystore, const char *name,
|
|
const char *description, const char *volumes,
|
|
- const char *apqns, long int sector_size)
|
|
+ const char *apqns, long int sector_size,
|
|
+ const char *volume_type)
|
|
{
|
|
struct volume_check vol_check = { .keystore = keystore, .name = name };
|
|
struct key_filenames file_names = { NULL, NULL, NULL };
|
|
struct properties *key_props = NULL;
|
|
- char temp[10];
|
|
+ char temp[30];
|
|
int rc;
|
|
|
|
util_assert(keystore != NULL, "Internal error: keystore is NULL");
|
|
@@ -1803,6 +1952,21 @@ int keystore_change_key(struct keystore
|
|
}
|
|
}
|
|
|
|
+ if (volume_type != NULL) {
|
|
+ if (!_keystore_valid_volume_type(volume_type)) {
|
|
+ warnx("Invalid volume-type specified");
|
|
+ rc = -EINVAL;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ rc = properties_set(key_props, PROP_NAME_VOLUME_TYPE,
|
|
+ volume_type);
|
|
+ if (rc != 0) {
|
|
+ warnx("Invalid characters in volume-type");
|
|
+ goto out;
|
|
+ }
|
|
+ }
|
|
+
|
|
rc = _keystore_ensure_vp_exists(keystore, &file_names, key_props);
|
|
/* ignore return code, vp generation might fail if key is not valid */
|
|
|
|
@@ -1849,6 +2013,8 @@ int keystore_rename_key(struct keystore
|
|
{
|
|
struct key_filenames file_names = { NULL, NULL, NULL };
|
|
struct key_filenames new_names = { NULL, NULL, NULL };
|
|
+ struct properties *key_props = NULL;
|
|
+ char *msg;
|
|
int rc;
|
|
|
|
util_assert(keystore != NULL, "Internal error: keystore is NULL");
|
|
@@ -1896,12 +2062,28 @@ int keystore_rename_key(struct keystore
|
|
}
|
|
}
|
|
|
|
+ key_props = properties_new();
|
|
+ rc = properties_load(key_props, new_names.info_filename, 1);
|
|
+ if (rc != 0) {
|
|
+ warnx("Key '%s' does not exist or is invalid", newname);
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ util_asprintf(&msg, "The following volumes are associated with the "
|
|
+ "renamed key '%s'. You should adjust the corresponding "
|
|
+ "crypttab entries and 'cryptsetup plainOpen' commands to "
|
|
+ "use the new name.", newname);
|
|
+ _keystore_msg_for_volumes(msg, key_props, VOLUME_TYPE_PLAIN);
|
|
+ free(msg);
|
|
+
|
|
pr_verbose(keystore, "Successfully renamed key '%s' to '%s'", name,
|
|
newname);
|
|
|
|
out:
|
|
_keystore_free_key_filenames(&file_names);
|
|
_keystore_free_key_filenames(&new_names);
|
|
+ if (key_props != NULL)
|
|
+ properties_free(key_props);
|
|
|
|
if (rc != 0)
|
|
pr_verbose(keystore, "Failed to rename key '%s'to '%s': %s",
|
|
@@ -1941,6 +2123,8 @@ static struct util_rec *_keystore_setup_
|
|
util_rec_def(rec, REC_KEY_FILE, UTIL_REC_ALIGN_LEFT, 54, REC_KEY_FILE);
|
|
util_rec_def(rec, REC_SECTOR_SIZE, UTIL_REC_ALIGN_LEFT, 54,
|
|
REC_SECTOR_SIZE);
|
|
+ util_rec_def(rec, REC_VOLUME_TYPE, UTIL_REC_ALIGN_LEFT, 54,
|
|
+ REC_VOLUME_TYPE);
|
|
util_rec_def(rec, REC_KEY_VP, UTIL_REC_ALIGN_LEFT, 54, REC_KEY_VP);
|
|
util_rec_def(rec, REC_CREATION_TIME, UTIL_REC_ALIGN_LEFT, 54,
|
|
REC_CREATION_TIME);
|
|
@@ -1967,6 +2151,7 @@ static void _keystore_print_record(struc
|
|
size_t sector_size = 0;
|
|
size_t apqns_argz_len;
|
|
char *description;
|
|
+ char *volume_type;
|
|
char *reencipher;
|
|
char *creation;
|
|
char *volumes;
|
|
@@ -2001,6 +2186,7 @@ static void _keystore_print_record(struc
|
|
change = properties_get(properties, PROP_NAME_CHANGE_TIME);
|
|
reencipher = properties_get(properties, PROP_NAME_REENC_TIME);
|
|
vp = properties_get(properties, PROP_NAME_KEY_VP);
|
|
+ volume_type = _keystore_get_volume_type(properties);
|
|
|
|
util_rec_set(rec, REC_KEY, name);
|
|
if (validation)
|
|
@@ -2039,6 +2225,7 @@ static void _keystore_print_record(struc
|
|
else
|
|
util_rec_set(rec, REC_SECTOR_SIZE, "%lu bytes",
|
|
sector_size);
|
|
+ util_rec_set(rec, REC_VOLUME_TYPE, volume_type);
|
|
if (vp != NULL) {
|
|
len = sprintf(temp_vp, "%.*s%c%.*s",
|
|
VERIFICATION_PATTERN_LEN / 2, vp,
|
|
@@ -2075,6 +2262,8 @@ static void _keystore_print_record(struc
|
|
free(reencipher);
|
|
if (vp != NULL)
|
|
free(vp);
|
|
+ if (volume_type != NULL)
|
|
+ free(volume_type);
|
|
}
|
|
|
|
struct validate_info {
|
|
@@ -2227,10 +2416,10 @@ static int _keystore_process_validate(st
|
|
|
|
if (valid && is_old_mk) {
|
|
util_print_indented("WARNING: The secure key is currently "
|
|
- "enciphered with the OLD CCA master key "
|
|
- "and should be re-enciphered with the "
|
|
- "CURRENT CCA master key as soon as "
|
|
- "possible to avoid data loss\n", 0);
|
|
+ "enciphered with the OLD CCA master key. "
|
|
+ "To mitigate the danger of data loss "
|
|
+ "re-encipher it with the CURRENT CCA "
|
|
+ "master key\n", 0);
|
|
info->num_warnings++;
|
|
}
|
|
if (_keystore_display_apqn_status(properties, name) != 0)
|
|
@@ -2271,7 +2460,7 @@ int keystore_validate_key(struct keystor
|
|
info.num_warnings = 0;
|
|
|
|
rc = _keystore_process_filtered(keystore, name_filter, NULL,
|
|
- apqn_filter,
|
|
+ apqn_filter, NULL,
|
|
_keystore_process_validate, &info);
|
|
|
|
util_rec_free(rec);
|
|
@@ -2458,7 +2647,8 @@ static int _keystore_process_reencipher(
|
|
if (params.complete) {
|
|
warnx("Key '%s' is not valid, re-enciphering is not "
|
|
"completed", name);
|
|
- warnx("Possibly the CCA master key not yet been set?");
|
|
+ warnx("The new CCA master key might yet have to be set "
|
|
+ "as the CURRENT master key.");
|
|
} else {
|
|
warnx("Key '%s' is not valid, it is not re-enciphered",
|
|
name);
|
|
@@ -2526,6 +2716,14 @@ static int _keystore_process_reencipher(
|
|
file_names->info_filename);
|
|
if (rc != 0)
|
|
goto out;
|
|
+
|
|
+ util_asprintf(&temp, "The following LUKS2 volumes are "
|
|
+ "encrypted with key '%s'. You should also "
|
|
+ "re-encipher the volume key of those volumes "
|
|
+ "using command 'zkey-cryptsetup reencipher "
|
|
+ "<device>':", name);
|
|
+ _keystore_msg_for_volumes(temp, properties, VOLUME_TYPE_LUKS2);
|
|
+ free(temp);
|
|
}
|
|
|
|
if (params.complete ||
|
|
@@ -2539,12 +2737,11 @@ static int _keystore_process_reencipher(
|
|
}
|
|
|
|
if (params.inplace != 1) {
|
|
- util_asprintf(&temp, "Staged re-enciphering has completed for "
|
|
- "key '%s'. Run 'zkey reencipher' with option "
|
|
- "'--complete' when the NEW CCA master key has "
|
|
- "been set (moved to the CURRENT master key "
|
|
- "register) to complete the re-enciphering "
|
|
- "process", name);
|
|
+ util_asprintf(&temp, "Staged re-enciphering is initiated for "
|
|
+ "key '%s'. After the NEW CCA master key has been "
|
|
+ "set to become the CURRENT master key run "
|
|
+ "'zkey reencipher' with option '--complete' to "
|
|
+ "complete the re-enciphering process", name);
|
|
util_print_indented(temp, 0);
|
|
free(temp);
|
|
}
|
|
@@ -2613,7 +2810,7 @@ int keystore_reencipher_key(struct keyst
|
|
info.num_skipped = 0;
|
|
|
|
rc = _keystore_process_filtered(keystore, name_filter, NULL,
|
|
- apqn_filter,
|
|
+ apqn_filter, NULL,
|
|
_keystore_process_reencipher, &info);
|
|
|
|
if (rc != 0) {
|
|
@@ -2833,10 +3030,9 @@ static int _keystore_propmp_for_remove(s
|
|
struct key_filenames *file_names)
|
|
{
|
|
struct properties *key_prop;
|
|
- char *volumes = NULL;
|
|
- char **volume_list = NULL;
|
|
char str[20];
|
|
- int rc, i;
|
|
+ char *msg;
|
|
+ int rc;
|
|
|
|
key_prop = properties_new();
|
|
rc = properties_load(key_prop, file_names->info_filename, 1);
|
|
@@ -2845,15 +3041,10 @@ static int _keystore_propmp_for_remove(s
|
|
goto out;
|
|
}
|
|
|
|
- volumes = properties_get(key_prop, PROP_NAME_VOLUMES);
|
|
- if (volumes != NULL && strlen(volumes) > 0) {
|
|
- volume_list = str_list_split(volumes);
|
|
-
|
|
- warnx("When you remove key '%s' the following volumes will "
|
|
- "no longer be usable:", name);
|
|
- for (i = 0; volume_list[i] != NULL; i++)
|
|
- fprintf(stderr, "%s\n", volume_list[i]);
|
|
- }
|
|
+ util_asprintf(&msg, "When you remove key '%s' the following volumes "
|
|
+ "will no longer be usable:", name);
|
|
+ _keystore_msg_for_volumes(msg, key_prop, VOLUME_TYPE_PLAIN);
|
|
+ free(msg);
|
|
|
|
printf("%s: Remove key '%s'? ", program_invocation_short_name, name);
|
|
if (fgets(str, sizeof(str), stdin) == NULL) {
|
|
@@ -2870,9 +3061,6 @@ static int _keystore_propmp_for_remove(s
|
|
|
|
out:
|
|
properties_free(key_prop);
|
|
- if (volume_list != NULL)
|
|
- str_list_free_string_array(volume_list);
|
|
-
|
|
return rc;
|
|
}
|
|
|
|
@@ -3000,22 +3188,30 @@ out:
|
|
* @param[in] apqn_filter the APQN filter. Can contain wild cards, and
|
|
* mutliple APQN filters separated by commas.
|
|
* NULL means no APQN filter.
|
|
+ * @param[in] volume_type The volume type. NULL means no volume type filter.
|
|
*
|
|
* @returns 0 for success or a negative errno in case of an error
|
|
*/
|
|
int keystore_list_keys(struct keystore *keystore, const char *name_filter,
|
|
- const char *volume_filter, const char *apqn_filter)
|
|
+ const char *volume_filter, const char *apqn_filter,
|
|
+ const char *volume_type)
|
|
{
|
|
struct util_rec *rec;
|
|
int rc;
|
|
|
|
util_assert(keystore != NULL, "Internal error: keystore is NULL");
|
|
|
|
+ if (volume_type != NULL &&
|
|
+ !_keystore_valid_volume_type(volume_type)) {
|
|
+ warnx("Invalid volume-type specified");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
rec = _keystore_setup_record(0);
|
|
|
|
rc = _keystore_process_filtered(keystore, name_filter, volume_filter,
|
|
- apqn_filter, _keystore_display_key,
|
|
- rec);
|
|
+ apqn_filter, volume_type,
|
|
+ _keystore_display_key, rec);
|
|
util_rec_free(rec);
|
|
|
|
if (rc != 0)
|
|
@@ -3067,6 +3263,7 @@ struct crypt_info {
|
|
const char *key_file_name,
|
|
size_t key_file_size,
|
|
size_t sector_size,
|
|
+ const char *volume_type,
|
|
struct crypt_info *info);
|
|
};
|
|
|
|
@@ -3080,7 +3277,8 @@ struct crypt_info {
|
|
* @param[in] cipher_spec the cipher specification
|
|
* @param[in] key_file_name the key file name
|
|
* @param[in] key_file_size the size of the key file in bytes
|
|
- * @param sector_size the sector size in bytes or 0 if not specified
|
|
+ * @param[in] sector_size the sector size in bytes or 0 if not specified
|
|
+ * @param[in] volume_type the volume type
|
|
* @param[in] info processing info
|
|
*
|
|
* @returns 0 if successful, a negative errno value otherwise
|
|
@@ -3092,6 +3290,7 @@ static int _keystore_process_cryptsetup(
|
|
const char *key_file_name,
|
|
size_t key_file_size,
|
|
size_t sector_size,
|
|
+ const char *volume_type,
|
|
struct crypt_info *info)
|
|
{
|
|
char temp[100];
|
|
@@ -3099,18 +3298,53 @@ static int _keystore_process_cryptsetup(
|
|
char *cmd;
|
|
|
|
sprintf(temp, "--sector-size %lu ", sector_size);
|
|
- util_asprintf(&cmd,
|
|
- "cryptsetup plainOpen %s--key-file '%s' --key-size %lu "
|
|
- "--cipher %s %s%s %s",
|
|
- keystore->verbose ? "-v " : "", key_file_name,
|
|
- key_file_size * 8, cipher_spec,
|
|
- sector_size > 0 ? temp : "", volume, dmname);
|
|
-
|
|
- if (info->execute) {
|
|
- printf("Executing: %s\n", cmd);
|
|
- rc = _keystore_execute_cmd(cmd, "cryptsetup");
|
|
+
|
|
+ if (strcasecmp(volume_type, VOLUME_TYPE_PLAIN) == 0) {
|
|
+ util_asprintf(&cmd,
|
|
+ "cryptsetup plainOpen %s--key-file '%s' "
|
|
+ "--key-size %lu --cipher %s %s%s %s",
|
|
+ keystore->verbose ? "-v " : "", key_file_name,
|
|
+ key_file_size * 8, cipher_spec,
|
|
+ sector_size > 0 ? temp : "", volume, dmname);
|
|
+
|
|
+ if (info->execute) {
|
|
+ printf("Executing: %s\n", cmd);
|
|
+ rc = _keystore_execute_cmd(cmd, "cryptsetup");
|
|
+ } else {
|
|
+ printf("%s\n", cmd);
|
|
+ }
|
|
+ } else if (strcasecmp(volume_type, VOLUME_TYPE_LUKS2) == 0) {
|
|
+ util_asprintf(&cmd,
|
|
+ "cryptsetup luksFormat %s--type luks2 "
|
|
+ "--master-key-file '%s' --key-size %lu "
|
|
+ "--cipher %s %s%s",
|
|
+ keystore->verbose ? "-v " : "", key_file_name,
|
|
+ key_file_size * 8, cipher_spec,
|
|
+ sector_size > 0 ? temp : "", volume);
|
|
+
|
|
+ if (info->execute) {
|
|
+ printf("Executing: %s\n", cmd);
|
|
+ rc = _keystore_execute_cmd(cmd, "cryptsetup");
|
|
+ } else {
|
|
+ printf("%s\n", cmd);
|
|
+ }
|
|
+
|
|
+ free(cmd);
|
|
+ if (rc != 0)
|
|
+ return rc;
|
|
+
|
|
+ util_asprintf(&cmd,
|
|
+ "zkey-cryptsetup setvp %s%s", volume,
|
|
+ keystore->verbose ? " -V " : "");
|
|
+
|
|
+ if (info->execute) {
|
|
+ printf("Executing: %s\n", cmd);
|
|
+ rc = _keystore_execute_cmd(cmd, "zkey-cryptsetup");
|
|
+ } else {
|
|
+ printf("%s\n", cmd);
|
|
+ }
|
|
} else {
|
|
- printf("%s\n", cmd);
|
|
+ return -EINVAL;
|
|
}
|
|
|
|
free(cmd);
|
|
@@ -3127,7 +3361,8 @@ static int _keystore_process_cryptsetup(
|
|
* @param[in] cipher_spec the cipher specification
|
|
* @param[in] key_file_name the key file name
|
|
* @param[in] key_file_size the size of the key file in bytes
|
|
- * @param sector_size the sector size in bytes or 0 if not specified
|
|
+ * @param[in] sector_size the sector size in bytes or 0 if not specified
|
|
+ * @param[in] volume_type the volume type
|
|
* @param[in] info processing info (not used here)
|
|
*
|
|
* @returns 0 if successful, a negative errno value otherwise
|
|
@@ -3140,26 +3375,35 @@ static int _keystore_process_crypttab(st
|
|
const char *key_file_name,
|
|
size_t key_file_size,
|
|
size_t sector_size,
|
|
+ const char *volume_type,
|
|
struct crypt_info *UNUSED(info))
|
|
{
|
|
char temp[1000];
|
|
|
|
- if (sector_size > 0) {
|
|
- sprintf(temp,
|
|
- "WARNING: volume '%s' is using a sector size of %lu. "
|
|
- "At the time this utility was developed, systemd's "
|
|
- "support of crypttab did not support to specify a "
|
|
- "sector size with plain dm-crypt devices. The generated "
|
|
- "crypttab entry might or might not work, and might need "
|
|
- "manual adoptions.", volume, sector_size);
|
|
- util_print_indented(temp, 0);
|
|
+ if (strcasecmp(volume_type, VOLUME_TYPE_PLAIN) == 0) {
|
|
+ if (sector_size > 0) {
|
|
+ sprintf(temp,
|
|
+ "WARNING: volume '%s' is using a sector size "
|
|
+ "of %lu. At the time this utility was "
|
|
+ "developed, systemd's support of crypttab did "
|
|
+ "not support to specify a sector size with "
|
|
+ "plain dm-crypt devices. The generated "
|
|
+ "crypttab entry might or might not work, and "
|
|
+ "might need manual adoptions.", volume,
|
|
+ sector_size);
|
|
+ util_print_indented(temp, 0);
|
|
+ }
|
|
+
|
|
+ sprintf(temp, ",sector-size=%lu", sector_size);
|
|
+ printf("%s\t%s\t%s\tplain,cipher=%s,size=%lu,hash=plain%s\n",
|
|
+ dmname, volume, key_file_name, cipher_spec,
|
|
+ key_file_size * 8, sector_size > 0 ? temp : "");
|
|
+ } else if (strcasecmp(volume_type, VOLUME_TYPE_LUKS2) == 0) {
|
|
+ printf("%s\t%s\n", dmname, volume);
|
|
+ } else {
|
|
+ return -EINVAL;
|
|
}
|
|
|
|
- sprintf(temp, ",sector-size=%lu", sector_size);
|
|
- printf("%s\t%s\t%s\tplain,cipher=%s,size=%lu,hash=plain%s\n",
|
|
- dmname, volume, key_file_name, cipher_spec, key_file_size * 8,
|
|
- sector_size > 0 ? temp : "");
|
|
-
|
|
return 0;
|
|
}
|
|
|
|
@@ -3251,6 +3495,7 @@ static int _keystore_process_crypt(struc
|
|
struct crypt_info *info = (struct crypt_info *)private;
|
|
char **volume_list = NULL;
|
|
char *cipher_spec = NULL;
|
|
+ char *volume_type = NULL;
|
|
size_t secure_key_size;
|
|
size_t sector_size = 0;
|
|
char *volumes = NULL;
|
|
@@ -3290,6 +3535,8 @@ static int _keystore_process_crypt(struc
|
|
free(temp);
|
|
}
|
|
|
|
+ volume_type = _keystore_get_volume_type(properties);
|
|
+
|
|
for (i = 0; volume_list[i] != NULL && rc == 0; i++) {
|
|
vol = volume_list[i];
|
|
if (_keystore_match_filter(vol, info->volume_filter,
|
|
@@ -3306,7 +3553,8 @@ static int _keystore_process_crypt(struc
|
|
|
|
rc = info->process_func(keystore, vol, dmname,
|
|
cipher_spec, file_names->skey_filename,
|
|
- secure_key_size, sector_size, info);
|
|
+ secure_key_size, sector_size,
|
|
+ volume_type, info);
|
|
if (rc != 0)
|
|
break;
|
|
}
|
|
@@ -3319,6 +3567,8 @@ out:
|
|
str_list_free_string_array(volume_list);
|
|
if (cipher_spec != NULL)
|
|
free(cipher_spec);
|
|
+ if (volume_type != NULL)
|
|
+ free(volume_type);
|
|
return rc;
|
|
}
|
|
|
|
@@ -3333,11 +3583,12 @@ out:
|
|
* checks the volume part only.
|
|
* @param[in] execute If TRUE the cryptsetup command is executed,
|
|
* otherwise it is printed to stdout
|
|
- *
|
|
+ * @param[in] volume_type the type of volume to generate cryptsetup cmds for
|
|
+ * *
|
|
* @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)
|
|
+ bool execute, const char *volume_type)
|
|
{
|
|
struct crypt_info info = { 0 };
|
|
int rc;
|
|
@@ -3346,12 +3597,20 @@ int keystore_cryptsetup(struct keystore
|
|
|
|
if (volume_filter == NULL)
|
|
volume_filter = "*";
|
|
+
|
|
+ if (volume_type != NULL &&
|
|
+ !_keystore_valid_volume_type(volume_type)) {
|
|
+ warnx("Invalid volume-type specified");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
info.execute = execute;
|
|
info.volume_filter = str_list_split(volume_filter);
|
|
info.process_func = _keystore_process_cryptsetup;
|
|
|
|
rc = _keystore_process_filtered(keystore, NULL, volume_filter, NULL,
|
|
- _keystore_process_crypt, &info);
|
|
+ volume_type, _keystore_process_crypt,
|
|
+ &info);
|
|
|
|
str_list_free_string_array(info.volume_filter);
|
|
|
|
@@ -3376,10 +3635,12 @@ int keystore_cryptsetup(struct keystore
|
|
* The ':dm-name' part of the volume is optional
|
|
* for the volume filter. If not specified, the filter
|
|
* checks the volume part only.
|
|
+ * @param[in] volume_type the type of volume to generate crypttab entries for
|
|
*
|
|
* @returns 0 for success or a negative errno in case of an error
|
|
*/
|
|
-int keystore_crypttab(struct keystore *keystore, const char *volume_filter)
|
|
+int keystore_crypttab(struct keystore *keystore, const char *volume_filter,
|
|
+ const char *volume_type)
|
|
{
|
|
struct crypt_info info = { 0 };
|
|
int rc;
|
|
@@ -3388,11 +3649,19 @@ int keystore_crypttab(struct keystore *k
|
|
|
|
if (volume_filter == NULL)
|
|
volume_filter = "*";
|
|
+
|
|
+ if (volume_type != NULL &&
|
|
+ !_keystore_valid_volume_type(volume_type)) {
|
|
+ warnx("Invalid volume-type specified");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
info.volume_filter = str_list_split(volume_filter);
|
|
info.process_func = _keystore_process_crypttab;
|
|
|
|
rc = _keystore_process_filtered(keystore, NULL, volume_filter, NULL,
|
|
- _keystore_process_crypt, &info);
|
|
+ volume_type, _keystore_process_crypt,
|
|
+ &info);
|
|
|
|
str_list_free_string_array(info.volume_filter);
|
|
|
|
--- a/zkey/keystore.h
|
|
+++ b/zkey/keystore.h
|
|
@@ -30,16 +30,17 @@ int keystore_generate_key(struct keystor
|
|
const char *description, const char *volumes,
|
|
const char *apqns, size_t sector_size,
|
|
size_t keybits, bool xts, const char *clear_key_file,
|
|
- int pkey_fd);
|
|
+ const char *volume_type, int pkey_fd);
|
|
|
|
int keystore_import_key(struct keystore *keystore, const char *name,
|
|
const char *description, const char *volumes,
|
|
const char *apqns, size_t sector_size,
|
|
- const char *import_file);
|
|
+ const char *import_file, const char *volume_type);
|
|
|
|
int keystore_change_key(struct keystore *keystore, const char *name,
|
|
const char *description, const char *volumes,
|
|
- const char *apqns, long int sector_size);
|
|
+ const char *apqns, long int sector_size,
|
|
+ const char *volume_type);
|
|
|
|
int keystore_rename_key(struct keystore *keystore, const char *name,
|
|
const char *newname);
|
|
@@ -63,12 +64,14 @@ int keystore_remove_key(struct keystore
|
|
bool quiet);
|
|
|
|
int keystore_list_keys(struct keystore *keystore, const char *name_filter,
|
|
- const char *volume_filter, const char *apqn_filter);
|
|
+ const char *volume_filter, const char *apqn_filter,
|
|
+ const char *volume_type);
|
|
|
|
int keystore_cryptsetup(struct keystore *keystore, const char *volume_filter,
|
|
- bool execute);
|
|
+ bool execute, const char *volume_type);
|
|
|
|
-int keystore_crypttab(struct keystore *keystore, const char *volume_filter);
|
|
+int keystore_crypttab(struct keystore *keystore, const char *volume_filter,
|
|
+ const char *volume_type);
|
|
|
|
void keystore_free(struct keystore *keystore);
|
|
|
|
--- a/zkey/zkey.1
|
|
+++ b/zkey/zkey.1
|
|
@@ -75,30 +75,32 @@ key repository.
|
|
.BR generate | gen
|
|
.I secure\-key\-file
|
|
.RB [ \-\-keybits | \-k
|
|
-.IB size ]
|
|
+.IR size ]
|
|
.RB [ \-\-xts | \-x ]
|
|
.RB [ \-\-clearkey | \-c
|
|
-.IB clear\-key\-file ]
|
|
+.IR clear\-key\-file ]
|
|
.RB [ \-\-verbose | \-V ]
|
|
.
|
|
.PP
|
|
.B zkey
|
|
.BR generate | gen
|
|
.B \-\-name | \-N
|
|
-.IB key-name
|
|
+.IR key-name
|
|
.RB [ \-\-description | \-d
|
|
-.IB description ]
|
|
+.IR description ]
|
|
.RB [ \-\-volumes | \-l
|
|
-.IB volume1:dmname1[,volume2:dmname2[,...]] ]
|
|
+.IR volume1:dmname1[,volume2:dmname2[,...]] ]
|
|
.RB [ \-\-apqns | \-a
|
|
-.IB card1.domain1[,card2.domain2[,...]] ]
|
|
+.IR card1.domain1[,card2.domain2[,...]] ]
|
|
.RB [ \-\-sector-size | \-S
|
|
-.IB bytes ]
|
|
+.IR bytes ]
|
|
+.RB [ \-\-volume-type | \-t
|
|
+.IR type ]
|
|
.RB [ \-\-keybits | \-k
|
|
-.IB size ]
|
|
+.IR size ]
|
|
.RB [ \-\-xts | \-x ]
|
|
.RB [ \-\-clearkey | \-c
|
|
-.IB clear\-key\-file ]
|
|
+.IR clear\-key\-file ]
|
|
.RB [ \-\-verbose | \-V ]
|
|
.PP
|
|
Use the
|
|
@@ -115,16 +117,16 @@ The generated secure key can either be s
|
|
or in the secure key repository. To store the generated secure key in a
|
|
file, specify the file name with option \fIsecure\-key\-file\fP. To store the
|
|
secure key in the secure key repository, specify the name of the key using the
|
|
-.B --name
|
|
+.B \-\-name
|
|
option. When storing the secure key in a key repository,
|
|
additional information can be associated with a secure key using the
|
|
-.B --description
|
|
+.B \-\-description
|
|
,
|
|
-.B --volumes
|
|
+.B \-\-volumes
|
|
,
|
|
-.B --apqns
|
|
+.B \-\-apqns
|
|
, or the
|
|
-.B --sector-size
|
|
+.B \-\-sector-size
|
|
options.
|
|
.
|
|
.SS "Validating secure AES keys"
|
|
@@ -138,7 +140,7 @@ options.
|
|
.B zkey
|
|
.BR validate | val
|
|
.RB [ \-\-name | \-N
|
|
-.IB key-name ]
|
|
+.IR key-name ]
|
|
.RB [ \-\-verbose | \-V ]
|
|
.PP
|
|
Use the
|
|
@@ -156,10 +158,10 @@ secure key repository. To validate a sec
|
|
the file name with option \fIsecure\-key\-file\fP. To validate secure keys
|
|
contained in the secure key repository, specify the name of the key
|
|
or a pattern containing wildcards using the
|
|
-.B --name
|
|
+.B \-\-name
|
|
option. When wildcards are used you must quote the value.
|
|
If neither option \fIsecure\-key\-file\fP nor option
|
|
-.B --name
|
|
+.B \-\-name
|
|
are specified, then all secure keys contained in the key repository
|
|
are validated.
|
|
.
|
|
@@ -171,15 +173,15 @@ are validated.
|
|
.RB [ \-\-to\-new | \-n ]
|
|
.RB [ \-\-from\-old | \-o ]
|
|
.RB [ \-\-output | \-f
|
|
-.IB output\-file ]
|
|
+.IR output\-file ]
|
|
.RB [ \-\-verbose | \-V ]
|
|
.PP
|
|
.B zkey
|
|
.BR reencipher | re
|
|
.RB [ \-\-name | \-N
|
|
-.IB key-name ]
|
|
+.IR key-name ]
|
|
.RB [ \-\-apqns | \-a
|
|
-.IB card1.domain1[,card2.domain2[,...]] ]
|
|
+.IR card1.domain1[,card2.domain2[,...]] ]
|
|
.RB [ \-\-to\-new | \-n ]
|
|
.RB [ \-\-from\-old | \-o ]
|
|
.RB [ \-\-in-place | \-i ]
|
|
@@ -190,7 +192,7 @@ are validated.
|
|
Use the
|
|
.B reencipher
|
|
command to re-encipher an existing secure key with a new master key.
|
|
-A secure key bust be re-enciphered when the master key of the CCA
|
|
+A secure key must be re-enciphered when the master key of the CCA
|
|
cryptographic adapter changes.
|
|
.PP
|
|
The CCA cryptographic adapter has three different registers to store
|
|
@@ -243,18 +245,18 @@ secure key repository. To re-encipher a
|
|
specify the file name with option \fIsecure\-key\-file\fP. To re-encipher
|
|
secure keys contained in the secure key repository, specify the name of the key
|
|
or a pattern containing wildcards using the
|
|
-.B --name
|
|
+.B \-\-name
|
|
option. When wildcards are used you must quote the value.
|
|
You can also specify the
|
|
-.B --apqns
|
|
+.B \-\-apqns
|
|
option to re-encipher those secure
|
|
keys which are associated with the specified cryptographic adapters (APQNs).
|
|
You can use wildcards for the APQN specification.
|
|
When wildcards are used you must quote the value.
|
|
If both option
|
|
-.B --name
|
|
+.B \-\-name
|
|
and option
|
|
-.B --apqns
|
|
+.B \-\-apqns
|
|
are specified then all secure keys
|
|
contained in the key repository that match both patterns are re-enciphered.
|
|
If all both options are omitted, then all secure keys contained in the key
|
|
@@ -265,7 +267,7 @@ performed \fBin-place\fP, or in \fBstage
|
|
.PP
|
|
\fB"In-place"\fP immediately replaces the secure key in the repository with
|
|
the re-enciphered secure key. Re-enciphering from \fBOLD\fP to \fBCURRENT\fP is
|
|
-performed in-place per default. You can use option \fB--in-place\fP to force an
|
|
+performed in-place per default. You can use option \fB\-\-in-place\fP to force an
|
|
in-place re-enciphering for the \fBCURRENT\fP to \fBNEW\fP case. Be aware that
|
|
a secure key that was re-enciphered in-place from \fBCURRENT\fP to \fBNEW\fP
|
|
is no longer valid, until the new CCA master key has been made the current one.
|
|
@@ -273,9 +275,9 @@ is no longer valid, until the new CCA ma
|
|
\fBStaged\fP mode means that the re-enciphered secure key is stored in a
|
|
separate file in the secure key repository. Thus the current secure key is still
|
|
valid at this point. Once the new CCA master key has been set (made active), you
|
|
-must rerun the reencipher command with option \fB--complete\fP to complete the
|
|
+must rerun the reencipher command with option \fB\-\-complete\fP to complete the
|
|
staged re-enciphering. Re-enciphering from \fBCURRENT\fP to \fBNEW\fP is
|
|
-performed in staged mode per default. You can use option \fB--staged\fP to force
|
|
+performed in staged mode per default. You can use option \fB\-\-staged\fP to force
|
|
a staged re-enciphering for the \fBOLD\fP to \fBCURRENT\fP case.
|
|
.PP
|
|
.B Note:
|
|
@@ -288,15 +290,17 @@ to be installed.
|
|
.BR import | im
|
|
.I secure\-key\-file
|
|
.B \-\-name | \-N
|
|
-.IB key-name
|
|
+.IR key-name
|
|
.RB [ \-\-description | \-d
|
|
-.IB description ]
|
|
+.IR description ]
|
|
.RB [ \-\-volumes | \-l
|
|
-.IB volume1:dmname1[,volume2:dmname2[,...]] ]
|
|
+.IR volume1:dmname1[,volume2:dmname2[,...]] ]
|
|
.RB [ \-\-apqns | \-a
|
|
-.IB card1.domain1[,card2.domain2[,...]] ]
|
|
+.IR card1.domain1[,card2.domain2[,...]] ]
|
|
.RB [ \-\-sector-size | \-S
|
|
-.IB bytes ]
|
|
+.IR bytes ]
|
|
+.RB [ \-\-volume-type | \-t
|
|
+.IR type ]
|
|
.RB [ \-\-verbose | \-V ]
|
|
.
|
|
.PP
|
|
@@ -305,13 +309,13 @@ Use the
|
|
command to import an existing secure key contained in a file into the the
|
|
secure key repository. When importing a secure key in a key repository,
|
|
additional information can be associated with a secure key using the
|
|
-.B --description
|
|
+.B \-\-description
|
|
,
|
|
-.B --volumes
|
|
+.B \-\-volumes
|
|
,
|
|
-.B --apqns
|
|
+.B \-\-apqns
|
|
, or the
|
|
-.B --sector-size
|
|
+.B \-\-sector-size
|
|
options.
|
|
.
|
|
.SS "Export AES secure keys from the secure key repository"
|
|
@@ -320,7 +324,7 @@ options.
|
|
.BR export | ex
|
|
.I secure\-key\-file
|
|
.B \-\-name | \-N
|
|
-.IB key-name
|
|
+.IR key-name
|
|
.RB [ \-\-verbose | \-V ]
|
|
.
|
|
.PP
|
|
@@ -329,7 +333,7 @@ Use the
|
|
command to export an existing secure key contained in the secure key repository
|
|
to a file in the file system. Specify the name of the key that is to be exported
|
|
using the
|
|
-.B --name
|
|
+.B \-\-name
|
|
option. You cannot use wildcards.
|
|
When wildcards are used you must quote the value.
|
|
The exported secure key also remains in the secure key repository.
|
|
@@ -339,20 +343,22 @@ The exported secure key also remains in
|
|
.B zkey
|
|
.BR list | li
|
|
.RB [ \-\-name | \-N
|
|
-.IB key-name ]
|
|
+.IR key-name ]
|
|
.RB [ \-\-volumes | \-l
|
|
-.IB volume1[:dmname1][,volume2[:dmname2][,...]] ]
|
|
+.IR volume1[:dmname1][,volume2[:dmname2][,...]] ]
|
|
.RB [ \-\-apqns | \-a
|
|
-.IB card1.domain1[,card2.domain2[,...]] ]
|
|
+.IR card1.domain1[,card2.domain2[,...]] ]
|
|
+.RB [ \-\-volume-type | \-t
|
|
+.IR type ]
|
|
.RB [ \-\-verbose | \-V ]
|
|
.
|
|
.PP
|
|
Use the
|
|
.B list
|
|
command to display a list of secure keys contained in the secure key repository.
|
|
-You can filter the displayed list by key name, associated volumes, and
|
|
-associated cryptographic adapters (APQNs). You can use wildcards for the key
|
|
-name, associated APQNs, and associated volumes. The device-mapper name of an
|
|
+You can filter the displayed list by key name, associated volumes, associated
|
|
+cryptographic adapters (APQNs), and volume type. You can use wildcards for the
|
|
+key name, associated APQNs, and associated volumes. The device-mapper name of an
|
|
associated volume can be omitted; if it is specified then only those keys are
|
|
listed that are associated with the specified volume and device-mapper name.
|
|
.PP
|
|
@@ -369,7 +375,7 @@ modification and last re-encipherment.
|
|
.B zkey
|
|
.BR remove | rem
|
|
.B \-\-name | \-N
|
|
-.IB key-name
|
|
+.IR key-name
|
|
.RB [ \-\-force | \-F ]
|
|
.RB [ \-\-verbose | \-V ]
|
|
.
|
|
@@ -378,10 +384,10 @@ Use the
|
|
.B remove
|
|
command to remove an existing secure key from the secure key repository.
|
|
Specify the name of the key that is to be removed using the
|
|
-.B --name
|
|
+.B \-\-name
|
|
option. You cannot use wildcards. The remove command prompts for
|
|
a confirmation, unless you specify the
|
|
-.B --force
|
|
+.B \-\-force
|
|
option.
|
|
.PP
|
|
.B Note:
|
|
@@ -395,43 +401,45 @@ secure key.
|
|
.B zkey
|
|
.BR change | ch
|
|
.B \-\-name | \-N
|
|
-.IB key-name
|
|
+.IR key-name
|
|
.RB [ \-\-description | \-d
|
|
-.IB description ]
|
|
+.IR description ]
|
|
.RB [ \-\-volumes | \-l
|
|
-.IB [+|-]volume1:dmname1[,volume2:dmname2[,...]] ]
|
|
+.IR [+|-]volume1:dmname1[,volume2:dmname2[,...]] ]
|
|
.RB [ \-\-apqns | \-a
|
|
-.IB [+|-]card1.domain1[,card2.domain2[,...]] ]
|
|
+.IR [+|-]card1.domain1[,card2.domain2[,...]] ]
|
|
.RB [ \-\-sector-size | \-S
|
|
-.IB bytes ]
|
|
+.IR bytes ]
|
|
+.RB [ \-\-volume-type | \-t
|
|
+.IR type ]
|
|
.RB [ \-\-verbose | \-V ]
|
|
.
|
|
.PP
|
|
Use the
|
|
.B change
|
|
command to change the description, the associated volumes, the associated
|
|
-cryptographic adapters (APQNs), and the sector size of a secure key contained
|
|
-in the secure key repository. Specify the name of the key that is to be changed
|
|
-using the
|
|
-.B --name
|
|
+cryptographic adapters (APQNs), the sector size, and the volume type of a secure
|
|
+key contained in the secure key repository. Specify the name of the key that is
|
|
+to be changed using the
|
|
+.B \-\-name
|
|
option. You cannot use wildcards.
|
|
.PP
|
|
You can set (replace), add, or
|
|
remove volume and cryptographic adapters (APQN) associations. To set
|
|
(replace) an association, specify the association with the
|
|
-.B --volumes
|
|
+.B \-\-volumes
|
|
or the
|
|
-.B --apqns
|
|
+.B \-\-apqns
|
|
options. To add an association,
|
|
specify the new association prefixed with a \fI+\fP with the
|
|
-.B --volumes
|
|
+.B \-\-volumes
|
|
or the
|
|
-.B --apqns
|
|
+.B \-\-apqns
|
|
options. To remove an association,
|
|
specify the association to remove prefixed with a \fI-\fP with the
|
|
-.B --volumes
|
|
+.B \-\-volumes
|
|
or the
|
|
-.B --apqns
|
|
+.B \-\-apqns
|
|
options. You cannot mix \fI+\fP and
|
|
\fI-\fP in one specification. You can either add or remove (or set) the
|
|
associations with one command.
|
|
@@ -447,9 +455,9 @@ command.
|
|
.B zkey
|
|
.BR rename | ren
|
|
.B \-\-name | \-N
|
|
-.IB key-name
|
|
+.IR key-name
|
|
.B \-\-new-name | \-w
|
|
-.IB new-key-name
|
|
+.IR new-key-name
|
|
.RB [ \-\-verbose | \-V ]
|
|
.
|
|
.PP
|
|
@@ -457,9 +465,9 @@ Use the
|
|
.B rename
|
|
command to rename an existing secure key in the secure key repository.
|
|
Specify the name of the key that is to be renamed using the
|
|
-.B --name
|
|
+.B \-\-name
|
|
option and the new name using the
|
|
-.B --new-name
|
|
+.B \-\-new-name
|
|
option. You cannot use wildcards.
|
|
.
|
|
.SS "Copy (duplicate) existing AES secure keys in the secure key repository"
|
|
@@ -467,11 +475,11 @@ option. You cannot use wildcards.
|
|
.B zkey
|
|
.B copy | co
|
|
.RB \-\-name | \-N
|
|
-.IB key-name
|
|
+.IR key-name
|
|
.B \-\-new-key-name | \-w
|
|
-.IB new-name
|
|
+.IR new-name
|
|
.RB [ \-\-volumes | \-l
|
|
-.IB volume1:dmname1[,volume2:dmname2[,...]] ]
|
|
+.IR volume1:dmname1[,volume2:dmname2[,...]] ]
|
|
.RB [ \-\-verbose | \-V ]
|
|
.
|
|
.PP
|
|
@@ -479,15 +487,15 @@ Use the
|
|
.B copy
|
|
command to copy (duplicate) an existing secure key in the secure key repository.
|
|
Specify the name of the key that is to be copied using the
|
|
-.B --name
|
|
+.B \-\-name
|
|
option and the name of the copied key using the
|
|
-.B --new-name
|
|
+.B \-\-new-name
|
|
option. You cannot use wildcards.
|
|
.PP
|
|
.B Note:
|
|
When copying a secure key, the volume associations are not copied, because
|
|
a specific volume can only be associated with a single secure key. Specify the
|
|
-.B --volumes
|
|
+.B \-\-volumes
|
|
option to associate different
|
|
volumes with the copied secure key, or use the \fBchange\fP command to associate
|
|
volumes afterwards.
|
|
@@ -497,45 +505,56 @@ volumes afterwards.
|
|
.B zkey
|
|
.BR crypttab | cryptt
|
|
.RB [ \-\-volumes | \-l
|
|
-.IB volume1[:dmname1][,volume2[:dmname2][,...]] ]
|
|
+.IR volume1[:dmname1][,volume2[:dmname2][,...]] ]
|
|
+.RB [ \-\-volume-type | \-t
|
|
+.IR type ]
|
|
.RB [ \-\-verbose | \-V ]
|
|
.
|
|
.PP
|
|
Use the
|
|
.B crypttab
|
|
-command to generate crypttab entries using the \fBplain\fP dm-crypt mode
|
|
-for volumes that are associated with secure keys contained in the secure key
|
|
-repository. Specify the
|
|
-.B --volumes
|
|
+command to generate crypttab entries using the \fBplain\fP or \fBLUKS2\fP
|
|
+dm-crypt mode 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 crypttab entries are generated for. You can use wildcards.
|
|
When wildcards are used you must quote the value.
|
|
The device-mapper name of an associated volume can be omitted; if it is
|
|
specified then only those volumes with the specified volume and device-mapper
|
|
name are selected.
|
|
+Specify the
|
|
+.B \-\-volume-type
|
|
+option to generate crypttab entries for the specified volume type only.
|
|
.
|
|
.SS "Generate cryptsetup commands for volumes associated with secure AES keys"
|
|
.
|
|
.B zkey
|
|
.BR cryptsetup | crypts
|
|
.RB [ \-\-volumes | \-l
|
|
-.IB volume1[:dmname1][,volume2[:dmname2][,...]] ]
|
|
+.IR volume1[:dmname1][,volume2[:dmname2][,...]] ]
|
|
+.RB [ \-\-volume-type | \-t
|
|
+.IR type ]
|
|
.RB [ \-\-run | \-r ]
|
|
.RB [ \-\-verbose | \-V ]
|
|
.
|
|
.PP
|
|
Use the
|
|
.B cryptsetup
|
|
-command to generate \fBcryptsetup plainOpen\fP commands for volumes that are
|
|
-associated with secure keys contained in the secure key repository. Specify the
|
|
-.B --volumes
|
|
+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
|
|
+.B \-\-volumes
|
|
option to limit the list
|
|
of volumes where cryptsetup commands are generated for. You can use wildcards.
|
|
When wildcards are used you must quote the value.
|
|
The device-mapper name of an associated volume can be omitted; if it is
|
|
specified then only those volumes with the specified volume and device-mapper
|
|
name are selected. Specify the
|
|
-.B --run
|
|
+.B \-\-volume-type
|
|
+option to generate cryptsetup commands for the specified volume type only.
|
|
+Specify the
|
|
+.B \-\-run
|
|
option to run the generated cryptsetup commands.
|
|
.
|
|
.
|
|
@@ -589,8 +608,17 @@ This option is only used for secure keys
|
|
.TP
|
|
.BR \-S ", " \-\-sector-size\~\fIbytes\fP
|
|
Specifies the sector size in bytes used with dm-crypt. It must be a power of two
|
|
-and in the range 512 - 4096 bytes. If omitted, the system default sector size
|
|
-is used.
|
|
+and in the range of 512 to 4096 bytes. If omitted, the system default sector
|
|
+size is used.
|
|
+This option is only used for secure keys contained in the secure key repository.
|
|
+.TP
|
|
+.BR \-t ", " \-\-volume-type\~\fItype\fP
|
|
+Specifies the volume type of the associated volumes used with dm-crypt. Possible
|
|
+values are \fBplain\fP and \fBluks2\fP. If omitted, \fBluks2\fP is used.
|
|
+This option is only available if
|
|
+.B zkey
|
|
+has been compiled with LUKS2 support enabled. If LUKS2 support is not enabled,
|
|
+the default volume type is \fBplain\fP.
|
|
This option is only used for secure keys contained in the secure key repository.
|
|
.
|
|
.
|
|
@@ -650,7 +678,7 @@ repository is performed in staged mode.
|
|
secure key is stored in a separate file in the secure key repository. Thus the
|
|
current secure key is still valid at this point. Once the new CCA master key has
|
|
been set (made active), you must rerun the reencipher command with option
|
|
-\fB--complete\fP to complete the staged re-enciphering.
|
|
+\fB\-\-complete\fP to complete the staged re-enciphering.
|
|
Re-enciphering from CURRENT to NEW is performed in staged mode per default.
|
|
This option is only used for secure keys contained in the secure key repository.
|
|
.TP
|
|
@@ -690,8 +718,17 @@ This option is only used for secure keys
|
|
.TP
|
|
.BR \-S ", " \-\-sector-size\~\fIbytes\fP
|
|
Specifies the sector size in bytes used with dm-crypt. It must be a power of two
|
|
-and in the range 512 - 4096 bytes. If omitted, the system default sector size
|
|
-is used.
|
|
+and in the range of 512 to 4096 bytes. If omitted, the system default sector
|
|
+size is used.
|
|
+This option is only used for secure keys contained in the secure key repository.
|
|
+.TP
|
|
+.BR \-t ", " \-\-volume-type\~\fItype\fP
|
|
+Specifies the volume type of the associated volumes used with dm-crypt. Possible
|
|
+values are \fBplain\fP and \fBluks2\fP. If omitted, \fBluks2\fP is used.
|
|
+This option is only available if
|
|
+.B zkey
|
|
+has been compiled with LUKS2 support enabled. If LUKS2 support is not enabled,
|
|
+the default volume type is \fBplain\fP.
|
|
This option is only used for secure keys contained in the secure key repository.
|
|
.
|
|
.
|
|
@@ -734,6 +771,15 @@ APQNs. Each APQN association specifies a
|
|
by a period (like lszcrypt displays it). You can use wildcards in the APQN
|
|
specification.
|
|
This option is only used for secure keys contained in the secure key repository.
|
|
+.TP
|
|
+.BR \-t ", " \-\-volume-type\~\fItype\fP
|
|
+Specifies the volume type of the associated volumes used with dm-crypt. Possible
|
|
+values are \fBplain\fP and \fBluks2\fP. Only keys with the specified volume
|
|
+type are listed.
|
|
+This option is only available if
|
|
+.B zkey
|
|
+has been compiled with LUKS2 support enabled.
|
|
+This option is only used for secure keys contained in the secure key repository.
|
|
.
|
|
.
|
|
.
|
|
@@ -791,9 +837,16 @@ This option is only used for secure keys
|
|
.TP
|
|
.BR \-S ", " \-\-sector-size\~\fIbytes\fP
|
|
Specifies the sector size in bytes used with dm-crypt. It must be a power of two
|
|
-and in the range 512 - 4096 bytes. If omitted, the system default sector size
|
|
-is used. Specify \fI0\fP to un-set the sector size so that the system default
|
|
-is used.
|
|
+and in the range of 512 to 4096 bytes. Specify \fI0\fP to set the sector size
|
|
+to the system default.
|
|
+This option is only used for secure keys contained in the secure key repository.
|
|
+.TP
|
|
+.BR \-t ", " \-\-volume-type\~\fItype\fP
|
|
+Specifies the volume type of the associated volumes used with dm-crypt. Possible
|
|
+values are \fBplain\fP and \fBluks2\fP.
|
|
+This option is only available if
|
|
+.B zkey
|
|
+has been compiled with LUKS2 support enabled.
|
|
This option is only used for secure keys contained in the secure key repository.
|
|
.
|
|
.
|
|
@@ -845,6 +898,15 @@ specified volume and device-mapper name.
|
|
the volumes and device-mapper names.
|
|
When wildcards are used you must quote the value.
|
|
This option is only used for secure keys contained in the secure key repository.
|
|
+.TP
|
|
+.BR \-t ", " \-\-volume-type\~\fItype\fP
|
|
+Specifies the volume type of the associated volumes used with dm-crypt. Possible
|
|
+values are \fBplain\fP and \fBluks2\fP. Only keys with the specified volume
|
|
+type are selected to generate crypttab entries for.
|
|
+This option is only available if
|
|
+.B zkey
|
|
+has been compiled with LUKS2 support enabled.
|
|
+This option is only used for secure keys contained in the secure key repository.
|
|
.
|
|
.
|
|
.
|
|
@@ -861,10 +923,18 @@ the volumes and device-mapper names.
|
|
When wildcards are used you must quote the value.
|
|
This option is only used for secure keys contained in the secure key repository.
|
|
.TP
|
|
-.BR \-r ", " \-\-run\fP
|
|
-Runs the generated cryptsetup commands. When an execution of a cryptsetup
|
|
-command fails, no further cryptsetup commands are executed, and zkey ends
|
|
-with an error.
|
|
+.BR \-t ", " \-\-volume-type\~\fItype\fP
|
|
+Specifies the volume type of the associated volumes used with dm-crypt. Possible
|
|
+values are \fBplain\fP and \fBluks2\fP. Only keys with the specified volume
|
|
+type are selected to generate cryptsetup commands for.
|
|
+This option is only available if
|
|
+.B zkey
|
|
+has been compiled with LUKS2 support enabled.
|
|
+This option is only used for secure keys contained in the secure key repository.
|
|
+.TP
|
|
+.BR \-r ", " \-\-run
|
|
+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.
|
|
.
|
|
.
|
|
@@ -895,15 +965,20 @@ in file 'seckey.bin'.
|
|
Generates a secure AES key from the clear key in file 'clearkey.bin' and
|
|
stores it in file 'seckey.bin'.
|
|
.TP
|
|
-.B zkey generate --name seckey
|
|
+.B zkey generate \-\-name seckey
|
|
Generates a random 256-bit secure AES key and stores it in the secure key
|
|
-repository under the name 'seckey'.
|
|
+repository using the name 'seckey'.
|
|
.TP
|
|
-.B zkey generate --name seckey --volumes /dev/dasdc1:encvol --apqns 03.004c
|
|
+.B zkey generate \-\-name seckey \-\-volumes /dev/dasdc1:encvol \-\-apqns 03.004c
|
|
Generates a random 256-bit secure AES key and stores it in the secure key
|
|
-repository under the name 'seckey' and associates it with block
|
|
+repository using the name 'seckey' and associates it with block
|
|
device '/dev/dasdc1' and device-mapper name 'encvol', and APQN '03.004c'.
|
|
.TP
|
|
+.B zkey generate \-\-name seckey \-\-volumes /dev/dasdc1:encvol \-\-volume-type luks2
|
|
+Generates a random 256-bit secure AES key and stores it in the secure key
|
|
+repository using the name 'seckey' and associates it with block
|
|
+device '/dev/dasdc1' and device-mapper name 'encvol', and a volume type of luks2.
|
|
+.TP
|
|
.B zkey reencipher seckey.bin \-\-from\-old
|
|
Re-enciphers the secure key in file 'seckey.bin' which is currently enciphered
|
|
with the master key in the OLD register with the master key in the CURRENT
|
|
@@ -915,17 +990,17 @@ Re-enciphers the secure key in file 'sec
|
|
with the master key in the CURRENT register with the master key in the NEW
|
|
register, and saves the re-enciphered secure key to file 'seckey2.bin'.
|
|
.TP
|
|
-.B zkey reencipher --name seckey
|
|
+.B zkey reencipher \-\-name seckey
|
|
Re-enciphers the secure key 'seckey' in the secure key repository.
|
|
.TP
|
|
-.B zkey reencipher --apqns 03.004c
|
|
+.B zkey reencipher \-\-apqns 03.004c
|
|
Re-enciphers all secure keys contained in the secure key repository that are
|
|
associated with APQN '03.004c'.
|
|
.TP
|
|
.B zkey validate seckey.bin
|
|
Validates the secure key in file 'seckey.bin' and displays its attributes.
|
|
.TP
|
|
-.B zkey validate --name seckey
|
|
+.B zkey validate \-\-name seckey
|
|
Validates the secure key 'seckey' in the secure key repository and displays its
|
|
attributes.
|
|
.TP
|
|
@@ -933,25 +1008,28 @@ attributes.
|
|
Lists all secure keys in the secure key repository and displays its
|
|
attributes.
|
|
.TP
|
|
-.B zkey list --name '*key'
|
|
+.B zkey list \-\-name '*key'
|
|
Lists all secure keys in the secure key repository with names ending with 'key'
|
|
and displays its attributes.
|
|
.TP
|
|
-.B zkey change --name seckey --volumes +/dev/dasdc2:encvol2
|
|
+.B zkey change \-\-name seckey \-\-volumes +/dev/dasdc2:encvol2
|
|
Changes the secure key 'seckey' in the secure key repository and adds
|
|
volume '/dev/dasdc2' with device-mapper name 'encvol2' to the list of associated
|
|
volumes of this secure key.
|
|
.TP
|
|
-.B zkey change --name seckey --apqns -03.004c
|
|
+.B zkey change \-\-name seckey \-\-apqns -03.004c
|
|
Changes the secure key 'seckey' in the secure key repository and removes
|
|
APQN '03.004c' from the list of associated APQNs of this secure key.
|
|
.TP
|
|
-.B zkey crypttab --volumes '/dev/dasdc*'
|
|
+.B zkey crypttab \-\-volumes '/dev/dasdc*'
|
|
Generates crypttab entries for all volumes that match the pattern '/dev/dasdc*'.
|
|
.TP
|
|
-.B zkey cryptsetup --volumes '*:enc_dasd'
|
|
+.B zkey cryptsetup \-\-volumes '*:enc_dasd'
|
|
Generates cryptsetup commands for the volumes that uses the device-mapper
|
|
name 'enc_dasd'.
|
|
+.TP
|
|
+.B zkey cryptsetup \-\-volume-type luks2
|
|
+Generates cryptsetup commands for all volumes of type luks2.
|
|
.
|
|
.SH ENVIRONMENT
|
|
.TP
|
|
--- a/zkey/zkey.c
|
|
+++ b/zkey/zkey.c
|
|
@@ -68,6 +68,7 @@ static struct zkey_globals {
|
|
char *volumes;
|
|
char *apqns;
|
|
long int sector_size;
|
|
+ char *volume_type;
|
|
char *newname;
|
|
bool run;
|
|
bool force;
|
|
@@ -180,6 +181,16 @@ static struct util_opt opt_vec[] = {
|
|
"used",
|
|
.command = COMMAND_GENERATE,
|
|
},
|
|
+#ifdef HAVE_LUKS2_SUPPORT
|
|
+ {
|
|
+ .option = { "volume-type", required_argument, NULL, 't'},
|
|
+ .argument = "type",
|
|
+ .desc = "The type of the associated volume(s). Possible values "
|
|
+ "are 'plain' and 'luks2'. When this option is omitted, "
|
|
+ "the default is 'luks2'",
|
|
+ .command = COMMAND_GENERATE,
|
|
+ },
|
|
+#endif
|
|
/***********************************************************/
|
|
{
|
|
.flags = UTIL_OPT_FLAG_SECTION,
|
|
@@ -211,19 +222,23 @@ static struct util_opt opt_vec[] = {
|
|
},
|
|
{
|
|
.option = {"complete", 0, NULL, 'p'},
|
|
- .desc = "Completes a pending re-enciphering of a secure AES "
|
|
- "key that was re-enciphered with the master key in the "
|
|
- "NEW register",
|
|
+ .desc = "Completes a staged re-enciphering. Use this option "
|
|
+ "after the new CCA master key has been set (made "
|
|
+ "active)",
|
|
.command = COMMAND_REENCIPHER,
|
|
},
|
|
{
|
|
.option = {"in-place", 0, NULL, 'i'},
|
|
- .desc = "Forces an in-place re-enchipering of a secure AES key",
|
|
+ .desc = "Forces an in-place re-enchipering of a secure AES "
|
|
+ "key. Re-enciphering from OLD to CURRENT is performed "
|
|
+ "in-place per default",
|
|
.command = COMMAND_REENCIPHER,
|
|
},
|
|
{
|
|
.option = {"staged", 0, NULL, 's'},
|
|
- .desc = "Forces a staged re-enchipering of a secure AES key",
|
|
+ .desc = "Forces that the re-enciphering of a secure AES key is "
|
|
+ "performed in staged mode. Re-enciphering from CURRENT "
|
|
+ "to NEW is performed in staged mode per default",
|
|
.command = COMMAND_REENCIPHER,
|
|
},
|
|
{
|
|
@@ -310,6 +325,16 @@ static struct util_opt opt_vec[] = {
|
|
"used",
|
|
.command = COMMAND_IMPORT,
|
|
},
|
|
+#ifdef HAVE_LUKS2_SUPPORT
|
|
+ {
|
|
+ .option = { "volume-type", required_argument, NULL, 't'},
|
|
+ .argument = "type",
|
|
+ .desc = "The type of the associated volume(s). Possible values "
|
|
+ "are 'plain' and 'luks2'. When this option is omitted, "
|
|
+ "the default is 'luks2'",
|
|
+ .command = COMMAND_IMPORT,
|
|
+ },
|
|
+#endif
|
|
/***********************************************************/
|
|
{
|
|
.flags = UTIL_OPT_FLAG_SECTION,
|
|
@@ -358,6 +383,16 @@ static struct util_opt opt_vec[] = {
|
|
"associated with specific crypto cards",
|
|
.command = COMMAND_LIST,
|
|
},
|
|
+#ifdef HAVE_LUKS2_SUPPORT
|
|
+ {
|
|
+ .option = { "volume-type", required_argument, NULL, 't'},
|
|
+ .argument = "type",
|
|
+ .desc = "The type of the associated volume(s). Possible values "
|
|
+ "are 'plain' and 'luks2'. Use this option to list all "
|
|
+ "keys with the specified volumes type.",
|
|
+ .command = COMMAND_LIST,
|
|
+ },
|
|
+#endif
|
|
/***********************************************************/
|
|
{
|
|
.flags = UTIL_OPT_FLAG_SECTION,
|
|
@@ -422,11 +457,19 @@ static struct util_opt opt_vec[] = {
|
|
.option = { "sector-size", required_argument, NULL, 'S'},
|
|
.argument = "0|512|4096",
|
|
.desc = "The sector size used with dm-crypt. It must be power "
|
|
- "of two and in range 512 - 4096 bytes. If this option "
|
|
- "is omitted, the system default sector size (512) is "
|
|
- "used",
|
|
+ "of two and in range 512 - 4096 bytes. Specify 0 to "
|
|
+ "use the system default sector size (512)",
|
|
+ .command = COMMAND_CHANGE,
|
|
+ },
|
|
+#ifdef HAVE_LUKS2_SUPPORT
|
|
+ {
|
|
+ .option = { "volume-type", required_argument, NULL, 't'},
|
|
+ .argument = "type",
|
|
+ .desc = "The type of the associated volume(s). Possible values "
|
|
+ "are 'plain' and 'luks2'",
|
|
.command = COMMAND_CHANGE,
|
|
},
|
|
+#endif
|
|
/***********************************************************/
|
|
{
|
|
.flags = UTIL_OPT_FLAG_SECTION,
|
|
@@ -494,6 +537,17 @@ static struct util_opt opt_vec[] = {
|
|
"volume and the device-mapper name matches",
|
|
.command = COMMAND_CRYPTTAB,
|
|
},
|
|
+#ifdef HAVE_LUKS2_SUPPORT
|
|
+ {
|
|
+ .option = { "volume-type", required_argument, NULL, 't'},
|
|
+ .argument = "type",
|
|
+ .desc = "The type of the associated volume(s). Possible values "
|
|
+ "are 'plain' and 'luks2'. Use this option to select "
|
|
+ "the keys by its volume type for which a crypttab "
|
|
+ "entry is to be generated",
|
|
+ .command = COMMAND_CRYPTTAB,
|
|
+ },
|
|
+#endif
|
|
/***********************************************************/
|
|
{
|
|
.flags = UTIL_OPT_FLAG_SECTION,
|
|
@@ -512,6 +566,17 @@ static struct util_opt opt_vec[] = {
|
|
"both, the volume and the device-mapper name matches",
|
|
.command = COMMAND_CRYPTSETUP,
|
|
},
|
|
+#ifdef HAVE_LUKS2_SUPPORT
|
|
+ {
|
|
+ .option = { "volume-type", required_argument, NULL, 't'},
|
|
+ .argument = "type",
|
|
+ .desc = "The type of the associated volume(s). Possible values "
|
|
+ "are 'plain' and 'luks2'. Use this option to select "
|
|
+ "the keys by its volume type for which a crypttab "
|
|
+ "entry is to be generated",
|
|
+ .command = COMMAND_CRYPTSETUP,
|
|
+ },
|
|
+#endif
|
|
{
|
|
.option = {"run", 0, NULL, 'r'},
|
|
.desc = "Runs the generated cryptsetup command",
|
|
@@ -819,7 +884,7 @@ static int command_generate_repository(v
|
|
|
|
rc = keystore_generate_key(g.keystore, g.name, g.description, g.volumes,
|
|
g.apqns, g.sector_size, g.keybits, g.xts,
|
|
- g.clearkeyfile, g.pkey_fd);
|
|
+ g.clearkeyfile, g.volume_type, g.pkey_fd);
|
|
|
|
return rc != 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
|
}
|
|
@@ -1167,7 +1232,8 @@ static int command_import(void)
|
|
g.sector_size = 0;
|
|
|
|
rc = keystore_import_key(g.keystore, g.name, g.description, g.volumes,
|
|
- g.apqns, g.sector_size, g.pos_arg);
|
|
+ g.apqns, g.sector_size, g.pos_arg,
|
|
+ g.volume_type);
|
|
|
|
return rc != 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
|
}
|
|
@@ -1200,7 +1266,8 @@ static int command_list(void)
|
|
{
|
|
int rc;
|
|
|
|
- rc = keystore_list_keys(g.keystore, g.name, g.volumes, g.apqns);
|
|
+ rc = keystore_list_keys(g.keystore, g.name, g.volumes, g.apqns,
|
|
+ g.volume_type);
|
|
|
|
return rc != 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
|
}
|
|
@@ -1239,7 +1306,7 @@ static int command_change(void)
|
|
}
|
|
|
|
rc = keystore_change_key(g.keystore, g.name, g.description, g.volumes,
|
|
- g.apqns, g.sector_size);
|
|
+ g.apqns, g.sector_size, g.volume_type);
|
|
|
|
return rc != 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
|
}
|
|
@@ -1299,7 +1366,7 @@ static int command_crypttab(void)
|
|
{
|
|
int rc;
|
|
|
|
- rc = keystore_crypttab(g.keystore, g.volumes);
|
|
+ rc = keystore_crypttab(g.keystore, g.volumes, g.volume_type);
|
|
|
|
return rc != 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
|
}
|
|
@@ -1313,7 +1380,7 @@ static int command_cryptsetup(void)
|
|
{
|
|
int rc;
|
|
|
|
- rc = keystore_cryptsetup(g.keystore, g.volumes, g.run);
|
|
+ rc = keystore_cryptsetup(g.keystore, g.volumes, g.run, g.volume_type);
|
|
|
|
return rc != 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
|
}
|
|
@@ -1490,6 +1557,11 @@ int main(int argc, char *argv[])
|
|
return EXIT_FAILURE;
|
|
}
|
|
break;
|
|
+#ifdef HAVE_LUKS2_SUPPORT
|
|
+ case 't':
|
|
+ g.volume_type = optarg;
|
|
+ break;
|
|
+#endif
|
|
case 'w':
|
|
g.newname = optarg;
|
|
break;
|