summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/cryptsetup.c637
-rw-r--r--src/cryptsetup.h4
-rw-r--r--src/cryptsetup_arg_list.h56
-rw-r--r--src/cryptsetup_args.h43
-rw-r--r--src/integritysetup.c30
-rw-r--r--src/integritysetup_arg_list.h34
-rw-r--r--src/integritysetup_args.h17
-rw-r--r--src/meson.build77
-rw-r--r--src/utils_arg_macros.h4
-rw-r--r--src/utils_arg_names.h11
-rw-r--r--src/utils_args.c4
-rw-r--r--src/utils_blockdev.c18
-rw-r--r--src/utils_luks.c9
-rw-r--r--src/utils_luks.h6
-rw-r--r--src/utils_password.c5
-rw-r--r--src/utils_progress.c4
-rw-r--r--src/utils_reencrypt.c43
-rw-r--r--src/utils_reencrypt_luks1.c4
-rw-r--r--src/utils_tools.c17
-rw-r--r--src/veritysetup.c7
-rw-r--r--src/veritysetup_arg_list.h4
-rw-r--r--src/veritysetup_args.h6
22 files changed, 839 insertions, 201 deletions
diff --git a/src/cryptsetup.c b/src/cryptsetup.c
index e387c1c..a46e2dd 100644
--- a/src/cryptsetup.c
+++ b/src/cryptsetup.c
@@ -3,8 +3,8 @@
*
* Copyright (C) 2004 Jana Saout <jana@saout.de>
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
- * Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved.
- * Copyright (C) 2009-2023 Milan Broz
+ * Copyright (C) 2009-2024 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2009-2024 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -28,9 +28,13 @@
#include "utils_luks.h"
static char *keyfiles[MAX_KEYFILES];
+static char *keyring_links[MAX_KEYRING_LINKS];
+static char *vks_in_keyring[MAX_VK_IN_KEYRING];
static char *keyfile_stdin = NULL;
static int keyfiles_count = 0;
+static int keyring_links_count = 0;
+static int vks_in_keyring_count = 0;
int64_t data_shift = 0;
const char *device_type = "luks";
@@ -57,6 +61,10 @@ void tools_cleanup(void)
while (keyfiles_count)
free(keyfiles[--keyfiles_count]);
+ while (keyring_links_count)
+ free(keyring_links[--keyring_links_count]);
+ while (vks_in_keyring_count)
+ free(vks_in_keyring[--vks_in_keyring_count]);
total_keyfiles = 0;
}
@@ -89,27 +97,49 @@ static int _set_keyslot_encryption_params(struct crypt_device *cd)
return crypt_keyslot_set_encryption(cd, ARG_STR(OPT_KEYSLOT_CIPHER_ID), ARG_UINT32(OPT_KEYSLOT_KEY_SIZE_ID) / 8);
}
-static int _try_token_pin_unlock(struct crypt_device *cd,
- int token_id,
- const char *activated_name,
- const char *token_type,
- uint32_t activate_flags,
- int tries,
- bool activation)
+static int _try_token_unlock(struct crypt_device *cd,
+ int keyslot,
+ int token_id,
+ const char *activated_name,
+ const char *token_type,
+ uint32_t activate_flags,
+ int tries,
+ bool activation,
+ bool token_only)
{
+ int r;
+ struct crypt_keyslot_context *kc;
size_t pin_len;
char msg[64], *pin = NULL;
- int r;
assert(tries >= 1);
assert(token_id >= 0 || token_id == CRYPT_ANY_TOKEN);
+ assert(keyslot >= 0 || keyslot == CRYPT_ANY_SLOT);
+
+ r = crypt_keyslot_context_init_by_token(cd, token_id, token_type, NULL, 0, NULL, &kc);
+ if (r < 0)
+ return r;
+
+ if (activation)
+ r = crypt_activate_by_keyslot_context(cd, activated_name, keyslot, kc, CRYPT_ANY_SLOT, NULL, activate_flags);
+ else
+ r = crypt_resume_by_keyslot_context(cd, activated_name, keyslot, kc);
+
+ tools_keyslot_msg(r, UNLOCKED);
+ tools_token_error_msg(r, token_type, token_id, false);
+
+ /* Token requires PIN (-ENOANO). Ask for it if there is evident preference for tokens */
+ if (r != -ENOANO || (!token_only && !token_type && token_id == CRYPT_ANY_TOKEN))
+ goto out;
if (token_id == CRYPT_ANY_TOKEN)
r = snprintf(msg, sizeof(msg), _("Enter token PIN: "));
else
r = snprintf(msg, sizeof(msg), _("Enter token %d PIN: "), token_id);
- if (r < 0 || (size_t)r >= sizeof(msg))
- return -EINVAL;
+ if (r < 0 || (size_t)r >= sizeof(msg)) {
+ r = -EINVAL;
+ goto out;
+ }
do {
r = tools_get_key(msg, &pin, &pin_len, 0, 0, NULL,
@@ -117,20 +147,26 @@ static int _try_token_pin_unlock(struct crypt_device *cd,
if (r < 0)
break;
+ r = crypt_keyslot_context_set_pin(cd, pin, pin_len, kc);
+ if (r < 0) {
+ crypt_safe_free(pin);
+ break;
+ }
+
if (activation)
- r = crypt_activate_by_token_pin(cd, activated_name, token_type,
- token_id, pin, pin_len, NULL,
- activate_flags);
+ r = crypt_activate_by_keyslot_context(cd, activated_name, keyslot,
+ kc, CRYPT_ANY_SLOT, NULL, activate_flags);
else
- r = crypt_resume_by_token_pin(cd, activated_name, token_type,
- token_id, pin, pin_len, NULL);
+ r = crypt_resume_by_keyslot_context(cd, activated_name, keyslot, kc);
+
crypt_safe_free(pin);
pin = NULL;
tools_keyslot_msg(r, UNLOCKED);
- tools_token_error_msg(r, ARG_STR(OPT_TOKEN_TYPE_ID), token_id, true);
+ tools_token_error_msg(r, token_type, token_id, true);
check_signal(&r);
} while (r == -ENOANO && (--tries > 0));
-
+out:
+ crypt_keyslot_context_free(kc);
return r;
}
@@ -151,6 +187,7 @@ static int action_open_plain(void)
size_t passwordLen, key_size_max, signatures = 0,
key_size = (ARG_UINT32(OPT_KEY_SIZE_ID) ?: DEFAULT_PLAIN_KEYBITS) / 8;
uint32_t activate_flags = 0;
+ bool compat_warning = false;
int r;
r = crypt_parse_name_and_mode(ARG_STR(OPT_CIPHER_ID) ?: DEFAULT_CIPHER(PLAIN),
@@ -160,6 +197,23 @@ static int action_open_plain(void)
goto out;
}
+ /*
+ * Warn user if no cipher options and passphrase hashing is not specified.
+ * For keyfile, password hashing is not used, no need to print warning for missing --hash.
+ * Keep this enabled even in batch mode to fix scripts and avoid data corruption.
+ */
+ if (!ARG_SET(OPT_CIPHER_ID) || !ARG_SET(OPT_KEY_SIZE_ID)) {
+ log_err(_("WARNING: Using default options for cipher (%s-%s, key size %u bits) that could be incompatible with older versions."),
+ cipher, cipher_mode, key_size * 8);
+ compat_warning = true;
+ }
+ if (!ARG_SET(OPT_HASH_ID) && !ARG_SET(OPT_KEY_FILE_ID)) {
+ log_err(_("WARNING: Using default options for hash (%s) that could be incompatible with older versions."), params.hash);
+ compat_warning = true;
+ }
+ if (compat_warning)
+ log_err(_("For plain mode, always use options --cipher, --key-size and if no keyfile is used, then also --hash."));
+
/* FIXME: temporary hack, no hashing for keyfiles in plain mode */
if (ARG_SET(OPT_KEY_FILE_ID) && !tools_is_stdin(ARG_STR(OPT_KEY_FILE_ID))) {
params.hash = NULL;
@@ -204,11 +258,14 @@ static int action_open_plain(void)
goto out;
/* Skip blkid scan when activating plain device with offset */
- if (!ARG_UINT64(OPT_OFFSET_ID)) {
+ if (!ARG_UINT64(OPT_OFFSET_ID) && !ARG_SET(OPT_DISABLE_BLKID_ID)) {
/* Print all present signatures in read-only mode */
r = tools_detect_signatures(action_argv[0], PRB_FILTER_NONE, &signatures, ARG_SET(OPT_BATCH_MODE_ID));
- if (r < 0)
+ if (r < 0) {
+ if (r == -EIO)
+ log_err(_("Blkid scan failed for %s."), action_argv[0]);
goto out;
+ }
}
if (signatures && !ARG_SET(OPT_BATCH_MODE_ID)) {
@@ -829,6 +886,15 @@ static int action_resize(void)
else if (ARG_SET(OPT_SIZE_ID))
dev_size = ARG_UINT64(OPT_SIZE_ID);
+ if (ARG_SET(OPT_EXTERNAL_TOKENS_PATH_ID)) {
+ r = crypt_token_set_external_path(ARG_STR(OPT_EXTERNAL_TOKENS_PATH_ID));
+ if (r < 0) {
+ log_err(_("Failed to set external tokens path %s."),
+ ARG_STR(OPT_EXTERNAL_TOKENS_PATH_ID));
+ goto out;
+ }
+ }
+
if (cad.flags & CRYPT_ACTIVATE_KEYRING_KEY) {
if (ARG_SET(OPT_DISABLE_KEYRING_ID)) {
r = -EINVAL;
@@ -838,16 +904,9 @@ static int action_resize(void)
}
/* try load VK in kernel keyring using token */
- r = crypt_activate_by_token_pin(cd, NULL, ARG_STR(OPT_TOKEN_TYPE_ID),
- ARG_INT32(OPT_TOKEN_ID_ID), NULL, 0, NULL,
- CRYPT_ACTIVATE_KEYRING_KEY);
- tools_keyslot_msg(r, UNLOCKED);
- tools_token_error_msg(r, ARG_STR(OPT_TOKEN_TYPE_ID), ARG_INT32(OPT_TOKEN_ID_ID), false);
-
- /* Token requires PIN. Ask if there is evident preference for tokens */
- if (r == -ENOANO && (ARG_SET(OPT_TOKEN_ONLY_ID) || ARG_SET(OPT_TOKEN_TYPE_ID) ||
- ARG_SET(OPT_TOKEN_ID_ID)))
- r = _try_token_pin_unlock(cd, ARG_INT32(OPT_TOKEN_ID_ID), NULL, ARG_STR(OPT_TOKEN_TYPE_ID), CRYPT_ACTIVATE_KEYRING_KEY, 1, true);
+ r = _try_token_unlock(cd, ARG_INT32(OPT_KEY_SLOT_ID), ARG_INT32(OPT_TOKEN_ID_ID),
+ NULL, ARG_STR(OPT_TOKEN_TYPE_ID), CRYPT_ACTIVATE_KEYRING_KEY,
+ 1, true, ARG_SET(OPT_TOKEN_ONLY_ID));
if (r >= 0 || quit || ARG_SET(OPT_TOKEN_ONLY_ID))
goto out;
@@ -883,7 +942,7 @@ static int action_status(void)
struct crypt_device *cd = NULL;
char *backing_file;
const char *device;
- int path = 0, r = 0;
+ int path = 0, r = 0, hw_enc;
/* perhaps a path, not a dm device name */
if (strchr(action_argv[0], '/'))
@@ -932,13 +991,33 @@ static int action_status(void)
if (r < 0 && r != -ENOTSUP)
goto out;
- log_std(" cipher: %s-%s\n", crypt_get_cipher(cd), crypt_get_cipher_mode(cd));
- log_std(" keysize: %d bits\n", crypt_get_volume_key_size(cd) * 8);
- log_std(" key location: %s\n", (cad.flags & CRYPT_ACTIVATE_KEYRING_KEY) ? "keyring" : "dm-crypt");
+ hw_enc = crypt_get_hw_encryption_type(cd);
+ if (hw_enc < 0) {
+ r = hw_enc;
+ goto out;
+ }
+
+ if (hw_enc == CRYPT_SW_ONLY) {
+ log_std(" cipher: %s-%s\n", crypt_get_cipher(cd), crypt_get_cipher_mode(cd));
+ log_std(" keysize: %d bits\n", crypt_get_volume_key_size(cd) * 8);
+ log_std(" key location: %s\n", (cad.flags & CRYPT_ACTIVATE_KEYRING_KEY) ? "keyring" : "dm-crypt");
+ } else if (hw_enc == CRYPT_OPAL_HW_ONLY) {
+ log_std(" encryption: HW OPAL only\n");
+ log_std(" OPAL keysize: %d bits\n", crypt_get_hw_encryption_key_size(cd) * 8);
+ } else if (hw_enc == CRYPT_SW_AND_OPAL_HW) {
+ log_std(" encryption: dm-crypt over HW OPAL\n");
+ log_std(" OPAL keysize: %d bits\n", crypt_get_hw_encryption_key_size(cd) * 8);
+ log_std(" cipher: %s-%s\n", crypt_get_cipher(cd), crypt_get_cipher_mode(cd));
+ log_std(" keysize: %d bits\n", (crypt_get_volume_key_size(cd) - crypt_get_hw_encryption_key_size(cd)) * 8);
+ log_std(" key location: %s\n", (cad.flags & CRYPT_ACTIVATE_KEYRING_KEY) ? "keyring" : "dm-crypt");
+ }
+
if (ip.integrity)
log_std(" integrity: %s\n", ip.integrity);
if (ip.integrity_key_size)
log_std(" integrity keysize: %d bits\n", ip.integrity_key_size * 8);
+ if (ip.tag_size)
+ log_std(" integrity tag size: %u bytes\n", ip.tag_size);
device = crypt_get_device_name(cd);
log_std(" device: %s\n", device);
if ((backing_file = crypt_loop_backing_file(device))) {
@@ -1282,9 +1361,14 @@ static int action_luksRepair(void)
goto out;
}
- r = tools_detect_signatures(action_argv[0], PRB_FILTER_LUKS, NULL, ARG_SET(OPT_BATCH_MODE_ID));
- if (r < 0)
- goto out;
+ if (!ARG_SET(OPT_DISABLE_BLKID_ID)) {
+ r = tools_detect_signatures(action_argv[0], PRB_FILTER_LUKS, NULL, ARG_SET(OPT_BATCH_MODE_ID));
+ if (r < 0) {
+ if (r == -EIO)
+ log_err(_("Blkid scan failed for %s."), action_argv[0]);
+ goto out;
+ }
+ }
if (!ARG_SET(OPT_BATCH_MODE_ID) &&
!yesDialog(_("Really try to repair LUKS device header?"),
@@ -1353,12 +1437,13 @@ static int strcmp_or_null(const char *str, const char *expected)
int luksFormat(struct crypt_device **r_cd, char **r_password, size_t *r_passwordLen)
{
- int r = -EINVAL, keysize, integrity_keysize = 0, fd, created = 0;
+ bool wipe_signatures = false;
+ int encrypt_type, r = -EINVAL, keysize, integrity_keysize = 0, fd, created = 0;
struct stat st;
const char *header_device, *type;
char *msg = NULL, *key = NULL, *password = NULL;
char cipher [MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN], integrity[MAX_CIPHER_LEN];
- size_t passwordLen, signatures;
+ size_t passwordLen, signatures = 0;
struct crypt_device *cd = NULL;
struct crypt_params_luks1 params1 = {
.hash = ARG_STR(OPT_HASH_ID) ?: DEFAULT_LUKS1_HASH,
@@ -1372,6 +1457,9 @@ int luksFormat(struct crypt_device **r_cd, char **r_password, size_t *r_password
.label = ARG_STR(OPT_LABEL_ID),
.subsystem = ARG_STR(OPT_SUBSYSTEM_ID)
};
+ struct crypt_params_hw_opal opal_params = {
+ .user_key_size = DEFAULT_LUKS1_KEYBITS / 8
+ };
void *params;
type = luksType(device_type);
@@ -1397,6 +1485,11 @@ int luksFormat(struct crypt_device **r_cd, char **r_password, size_t *r_password
log_err(_("Unsupported LUKS2 metadata size options."));
return -EINVAL;
}
+
+ if (ARG_SET(OPT_HW_OPAL_ID) || ARG_SET(OPT_HW_OPAL_ONLY_ID)) {
+ log_err(_("OPAL is supported only for LUKS2 format."));
+ return -EINVAL;
+ }
} else
return -EINVAL;
@@ -1466,9 +1559,14 @@ int luksFormat(struct crypt_device **r_cd, char **r_password, size_t *r_password
}
/* Print all present signatures in read-only mode */
- r = tools_detect_signatures(header_device, PRB_FILTER_NONE, &signatures, ARG_SET(OPT_BATCH_MODE_ID));
- if (r < 0)
- goto out;
+ if (!ARG_SET(OPT_DISABLE_BLKID_ID)) {
+ r = tools_detect_signatures(header_device, PRB_FILTER_NONE, &signatures, ARG_SET(OPT_BATCH_MODE_ID));
+ if (r < 0) {
+ if (r == -EIO)
+ log_err(_("Blkid scan failed for %s."), header_device);
+ goto out;
+ }
+ }
if (!created && !ARG_SET(OPT_BATCH_MODE_ID)) {
r = asprintf(&msg, _("This will overwrite data on %s irrevocably."), header_device);
@@ -1485,6 +1583,11 @@ int luksFormat(struct crypt_device **r_cd, char **r_password, size_t *r_password
keysize = get_adjusted_key_size(cipher_mode, DEFAULT_LUKS1_KEYBITS, integrity_keysize);
+ if (ARG_SET(OPT_HW_OPAL_ONLY_ID))
+ keysize = opal_params.user_key_size;
+ else if (ARG_SET(OPT_HW_OPAL_ID))
+ keysize += opal_params.user_key_size;
+
if (ARG_SET(OPT_USE_RANDOM_ID))
crypt_set_rng_type(cd, CRYPT_RNG_RANDOM);
else if (ARG_SET(OPT_USE_URANDOM_ID))
@@ -1496,6 +1599,19 @@ int luksFormat(struct crypt_device **r_cd, char **r_password, size_t *r_password
if (r < 0)
goto out;
+ if (ARG_SET(OPT_HW_OPAL_ID) || ARG_SET(OPT_HW_OPAL_ONLY_ID)) {
+ r = tools_get_key("Enter OPAL Admin password: ", CONST_CAST(char **)&opal_params.admin_key, &opal_params.admin_key_size,
+ 0, 0, NULL,
+ ARG_UINT32(OPT_TIMEOUT_ID), verify_passphrase(1), !ARG_SET(OPT_FORCE_PASSWORD_ID), cd);
+ if (r < 0)
+ goto out;
+ if (opal_params.admin_key_size == 0) {
+ log_err(_("OPAL Admin password cannot be empty."));
+ r = -EPERM;
+ goto out;
+ }
+ }
+
if (ARG_SET(OPT_VOLUME_KEY_FILE_ID)) {
r = tools_read_vk(ARG_STR(OPT_VOLUME_KEY_FILE_ID), &key, keysize);
if (r < 0)
@@ -1509,13 +1625,20 @@ int luksFormat(struct crypt_device **r_cd, char **r_password, size_t *r_password
}
/* Signature candidates found */
- if (signatures && ((r = tools_wipe_all_signatures(header_device, true, false)) < 0))
+ if (!ARG_SET(OPT_DISABLE_BLKID_ID) && signatures &&
+ ((r = tools_wipe_all_signatures(header_device, true, false)) < 0))
goto out;
if (ARG_SET(OPT_INTEGRITY_LEGACY_PADDING_ID))
crypt_set_compatibility(cd, CRYPT_COMPAT_LEGACY_INTEGRITY_PADDING);
- r = crypt_format(cd, type, cipher, cipher_mode,
+ if (ARG_SET(OPT_HW_OPAL_ID) || ARG_SET(OPT_HW_OPAL_ONLY_ID))
+ r = crypt_format_luks2_opal(cd,
+ ARG_SET(OPT_HW_OPAL_ONLY_ID) ? NULL : cipher,
+ ARG_SET(OPT_HW_OPAL_ONLY_ID) ? NULL : cipher_mode,
+ ARG_STR(OPT_UUID_ID), key, keysize, params, &opal_params);
+ else
+ r = crypt_format(cd, type, cipher, cipher_mode,
ARG_STR(OPT_UUID_ID), key, keysize, params);
check_signal(&r);
if (r < 0)
@@ -1529,25 +1652,44 @@ int luksFormat(struct crypt_device **r_cd, char **r_password, size_t *r_password
key, keysize,
password, passwordLen);
if (r < 0) {
- (void) tools_wipe_all_signatures(header_device, true, false);
+ wipe_signatures = true;
goto out;
}
tools_keyslot_msg(r, CREATED);
if (ARG_SET(OPT_INTEGRITY_ID) && !ARG_SET(OPT_INTEGRITY_NO_WIPE_ID) &&
- strcmp_or_null(params2.integrity, "none"))
+ strcmp_or_null(params2.integrity, "none")) {
r = _wipe_data_device(cd);
+ /* Interrupted wipe should not fail luksFormat action */
+ if (r == -EINTR)
+ r = 0;
+ }
out:
+ crypt_safe_free(key);
+
+ if (r < 0) {
+ encrypt_type = crypt_get_hw_encryption_type(cd);
+ if (encrypt_type == CRYPT_OPAL_HW_ONLY ||
+ encrypt_type == CRYPT_SW_AND_OPAL_HW) {
+ (void) crypt_wipe_hw_opal(cd, CRYPT_LUKS2_SEGMENT,
+ opal_params.admin_key, opal_params.admin_key_size,
+ 0);
+ }
+ if (wipe_signatures)
+ (void) tools_wipe_all_signatures(header_device, true, false);
+ }
+
+ crypt_safe_free(CONST_CAST(void *)opal_params.admin_key);
+
if (r >= 0 && r_cd && r_password && r_passwordLen) {
*r_cd = cd;
*r_password = password;
*r_passwordLen = passwordLen;
- } else {
- crypt_free(cd);
- crypt_safe_free(password);
+ return r;
}
- crypt_safe_free(key);
+ crypt_free(cd);
+ crypt_safe_free(password);
return r;
}
@@ -1557,17 +1699,166 @@ static int action_luksFormat(void)
return luksFormat(NULL, NULL, NULL);
}
+static int parse_vk_description(const char *key_description, char **ret_key_description)
+{
+ char *tmp;
+ int r;
+
+ assert(key_description);
+ assert(ret_key_description);
+
+ /* apply default key type */
+ if (*key_description != '%')
+ r = asprintf(&tmp, "%%user:%s", key_description) < 0 ? -EINVAL : 0;
+ else
+ r = (tmp = strdup(key_description)) ? 0 : -ENOMEM;
+ if (!r)
+ *ret_key_description = tmp;
+
+ return r;
+}
+
+static int parse_single_vk_and_keyring_description(
+ struct crypt_device *cd,
+ char *keyring_key_description, char **keyring_part_out, char
+ **key_part_out, char **type_part_out)
+{
+ int r = -EINVAL;
+ char *endp, *sep, *key_part, *type_part = NULL;
+ char *key_part_copy = NULL, *type_part_copy = NULL, *keyring_part = NULL;
+
+ if (!cd || !keyring_key_description)
+ return -EINVAL;
+
+ /* "::" is separator between keyring specification a key description */
+ key_part = strstr(keyring_key_description, "::");
+ if (!key_part)
+ goto out;
+
+ *key_part = '\0';
+ key_part = key_part + 2;
+
+ if (*key_part == '%') {
+ type_part = key_part + 1;
+ sep = strstr(type_part, ":");
+ if (!sep)
+ goto out;
+ *sep = '\0';
+
+ key_part = sep + 1;
+ }
+
+ if (*keyring_key_description == '%') {
+ keyring_key_description = strstr(keyring_key_description, ":");
+ if (!keyring_key_description)
+ goto out;
+ log_verbose(_("Type specification in --link-vk-to-keyring keyring specification is ignored."));
+ keyring_key_description++;
+ }
+
+ (void)strtol(keyring_key_description, &endp, 0);
+
+ r = 0;
+ if (*keyring_key_description == '@' || !*endp)
+ keyring_part = strdup(keyring_key_description);
+ else
+ r = asprintf(&keyring_part, "%%:%s", keyring_key_description);
+
+ if (!keyring_part || r < 0) {
+ r = -ENOMEM;
+ goto out;
+ }
+
+ if (!(key_part_copy = strdup(key_part))) {
+ r = -ENOMEM;
+ goto out;
+ }
+ if (type_part && !(type_part_copy = strdup(type_part)))
+ r = -ENOMEM;
+
+out:
+ if (r < 0) {
+ free(keyring_part);
+ free(key_part_copy);
+ free(type_part_copy);
+ } else {
+ *keyring_part_out = keyring_part;
+ *key_part_out = key_part_copy;
+ *type_part_out = type_part_copy;
+ }
+
+ return r;
+}
+
+static int parse_vk_and_keyring_description(
+ struct crypt_device *cd,
+ char **keyring_key_descriptions,
+ int keyring_key_links_count)
+{
+ int r = 0;
+
+ char *keyring_part_out1 = NULL, *key_part_out1 = NULL, *type_part_out1 = NULL;
+ char *keyring_part_out2 = NULL, *key_part_out2 = NULL, *type_part_out2 = NULL;
+
+ if (keyring_key_links_count > 0) {
+ r = parse_single_vk_and_keyring_description(cd,
+ keyring_key_descriptions[0],
+ &keyring_part_out1, &key_part_out1,
+ &type_part_out1);
+ if (r < 0)
+ goto out;
+ }
+ if (keyring_key_links_count > 1) {
+ r = parse_single_vk_and_keyring_description(cd,
+ keyring_key_descriptions[1],
+ &keyring_part_out2, &key_part_out2,
+ &type_part_out2);
+ if (r < 0)
+ goto out;
+
+ if ((type_part_out1 && type_part_out2) && strcmp(type_part_out1, type_part_out2)) {
+ log_err(_("Key types have to be the same for both volume keys."));
+ r = -EINVAL;
+ goto out;
+ }
+ if ((keyring_part_out1 && keyring_part_out2) && strcmp(keyring_part_out1, keyring_part_out2)) {
+ log_err(_("Both volume keys have to be linked to the same keyring."));
+ r = -EINVAL;
+ goto out;
+ }
+ }
+
+ if (keyring_key_links_count > 0) {
+ r = crypt_set_keyring_to_link(cd, key_part_out1, key_part_out2,
+ type_part_out1, keyring_part_out1);
+ if (r == -EAGAIN)
+ log_err(_("You need to supply more key names."));
+ }
+out:
+ if (r == -EINVAL)
+ log_err(_("Invalid --link-vk-to-keyring value."));
+ free(keyring_part_out1);
+ free(key_part_out1);
+ free(type_part_out1);
+ free(keyring_part_out2);
+ free(key_part_out2);
+ free(type_part_out2);
+
+ return r;
+}
+
static int action_open_luks(void)
{
struct crypt_active_device cad;
struct crypt_device *cd = NULL;
const char *data_device, *header_device, *activated_name;
- char *key = NULL;
+ char *key = NULL, *vk_description_activation1 = NULL, *vk_description_activation2 = NULL;
uint32_t activate_flags = 0;
int r, keysize, tries;
char *password = NULL;
size_t passwordLen;
struct stat st;
+ struct crypt_keyslot_context *kc1 = NULL, *kc2 = NULL;
if (ARG_SET(OPT_REFRESH_ID)) {
activated_name = action_argc > 1 ? action_argv[1] : action_argv[0];
@@ -1606,6 +1897,21 @@ static int action_open_luks(void)
set_activation_flags(&activate_flags);
+ if (ARG_SET(OPT_EXTERNAL_TOKENS_PATH_ID)) {
+ r = crypt_token_set_external_path(ARG_STR(OPT_EXTERNAL_TOKENS_PATH_ID));
+ if (r < 0) {
+ log_err(_("Failed to set external tokens path %s."),
+ ARG_STR(OPT_EXTERNAL_TOKENS_PATH_ID));
+ goto out;
+ }
+ }
+
+ if (ARG_SET(OPT_LINK_VK_TO_KEYRING_ID)) {
+ r = parse_vk_and_keyring_description(cd, keyring_links, keyring_links_count);
+ if (r < 0)
+ goto out;
+ }
+
if (ARG_SET(OPT_VOLUME_KEY_FILE_ID)) {
keysize = crypt_get_volume_key_size(cd);
if (!keysize && !ARG_SET(OPT_KEY_SIZE_ID)) {
@@ -1620,16 +1926,37 @@ static int action_open_luks(void)
goto out;
r = crypt_activate_by_volume_key(cd, activated_name,
key, keysize, activate_flags);
+ } else if (ARG_SET(OPT_VOLUME_KEY_KEYRING_ID)) {
+ if (vks_in_keyring_count == 1) {
+ r = parse_vk_description(vks_in_keyring[0], &vk_description_activation1);
+ if (r < 0)
+ goto out;
+ r = crypt_keyslot_context_init_by_vk_in_keyring(cd, vk_description_activation1, &kc1);
+ if (r)
+ goto out;
+ r = crypt_activate_by_keyslot_context(cd, activated_name, CRYPT_ANY_SLOT, kc1, CRYPT_ANY_SLOT, NULL, activate_flags);
+ } else if (vks_in_keyring_count == 2) {
+ r = parse_vk_description(vks_in_keyring[0], &vk_description_activation1);
+ if (r < 0)
+ goto out;
+ r = parse_vk_description(vks_in_keyring[1], &vk_description_activation2);
+ if (r < 0)
+ goto out;
+ r = crypt_keyslot_context_init_by_vk_in_keyring(cd, vk_description_activation1, &kc1);
+ if (r)
+ goto out;
+ r = crypt_keyslot_context_init_by_vk_in_keyring(cd, vk_description_activation2, &kc2);
+ if (r)
+ goto out;
+ r = crypt_activate_by_keyslot_context(cd, activated_name, CRYPT_ANY_SLOT, kc1, CRYPT_ANY_SLOT, kc2, activate_flags);
+ }
+ if (r)
+ goto out;
} else {
- r = crypt_activate_by_token_pin(cd, activated_name, ARG_STR(OPT_TOKEN_TYPE_ID),
- ARG_INT32(OPT_TOKEN_ID_ID), NULL, 0, NULL, activate_flags);
- tools_keyslot_msg(r, UNLOCKED);
- tools_token_error_msg(r, ARG_STR(OPT_TOKEN_TYPE_ID), ARG_INT32(OPT_TOKEN_ID_ID), false);
-
- /* Token requires PIN. Ask if there is evident preference for tokens */
- if (r == -ENOANO && (ARG_SET(OPT_TOKEN_ONLY_ID) || ARG_SET(OPT_TOKEN_TYPE_ID) ||
- ARG_SET(OPT_TOKEN_ID_ID)))
- r = _try_token_pin_unlock(cd, ARG_INT32(OPT_TOKEN_ID_ID), activated_name, ARG_STR(OPT_TOKEN_TYPE_ID), activate_flags, set_tries_tty(), true);
+ r = _try_token_unlock(cd, ARG_INT32(OPT_KEY_SLOT_ID),
+ ARG_INT32(OPT_TOKEN_ID_ID), activated_name,
+ ARG_STR(OPT_TOKEN_TYPE_ID), activate_flags,
+ set_tries_tty(), true, ARG_SET(OPT_TOKEN_ONLY_ID));
if (r >= 0 || r == -EEXIST || quit || ARG_SET(OPT_TOKEN_ONLY_ID))
goto out;
@@ -1657,9 +1984,14 @@ out:
crypt_persistent_flags_set(cd, CRYPT_FLAGS_ACTIVATION, cad.flags & activate_flags)))
log_err(_("Device activated but cannot make flags persistent."));
+ crypt_keyslot_context_free(kc1);
+ crypt_keyslot_context_free(kc2);
crypt_safe_free(key);
crypt_safe_free(password);
crypt_free(cd);
+ free(vk_description_activation1);
+ free(vk_description_activation2);
+
return r;
}
@@ -1839,6 +2171,15 @@ static int luksAddUnboundKey(void)
goto out;
}
+ if (ARG_SET(OPT_EXTERNAL_TOKENS_PATH_ID)) {
+ r = crypt_token_set_external_path(ARG_STR(OPT_EXTERNAL_TOKENS_PATH_ID));
+ if (r < 0) {
+ log_err(_("Failed to set external tokens path %s."),
+ ARG_STR(OPT_EXTERNAL_TOKENS_PATH_ID));
+ goto out;
+ }
+ }
+
r = _set_keyslot_encryption_params(cd);
if (r < 0)
goto out;
@@ -1943,7 +2284,8 @@ static int action_luksAddKey(void)
{
int keyslot_old, keyslot_new, keysize = 0, r = -EINVAL;
const char *new_key_file = (action_argc > 1 ? action_argv[1] : NULL);
- char *key = NULL, *password = NULL, *password_new = NULL, *pin = NULL, *pin_new = NULL;
+ char *key = NULL, *password = NULL, *password_new = NULL, *pin = NULL, *pin_new = NULL,
+ *vk_description = NULL;
size_t pin_size, pin_size_new, password_size = 0, password_new_size = 0;
struct crypt_device *cd = NULL;
struct crypt_keyslot_context *p_kc_new = NULL, *kc = NULL, *kc_new = NULL;
@@ -1983,6 +2325,15 @@ static int action_luksAddKey(void)
if (r < 0)
goto out;
+ if (ARG_SET(OPT_EXTERNAL_TOKENS_PATH_ID)) {
+ r = crypt_token_set_external_path(ARG_STR(OPT_EXTERNAL_TOKENS_PATH_ID));
+ if (r < 0) {
+ log_err(_("Failed to set external tokens path %s."),
+ ARG_STR(OPT_EXTERNAL_TOKENS_PATH_ID));
+ goto out;
+ }
+ }
+
/* Never call pwquality if using null cipher */
if (crypt_is_cipher_null(crypt_get_cipher(cd)))
ARG_SET_TRUE(OPT_FORCE_PASSWORD_ID);
@@ -2019,7 +2370,11 @@ static int action_luksAddKey(void)
ARG_UINT32(OPT_KEYFILE_SIZE_ID),
ARG_UINT64(OPT_KEYFILE_OFFSET_ID),
&kc);
- else if (ARG_SET(OPT_TOKEN_ID_ID) || ARG_SET(OPT_TOKEN_TYPE_ID) || ARG_SET(OPT_TOKEN_ONLY_ID)) {
+ else if (ARG_SET(OPT_VOLUME_KEY_KEYRING_ID)) {
+ r = parse_vk_description(ARG_STR(OPT_VOLUME_KEY_KEYRING_ID), &vk_description);
+ if (!r)
+ r = crypt_keyslot_context_init_by_vk_in_keyring(cd, vk_description, &kc);
+ } else if (ARG_SET(OPT_TOKEN_ID_ID) || ARG_SET(OPT_TOKEN_TYPE_ID) || ARG_SET(OPT_TOKEN_ONLY_ID)) {
r = crypt_keyslot_context_init_by_token(cd,
ARG_INT32(OPT_TOKEN_ID_ID),
ARG_STR(OPT_TOKEN_TYPE_ID),
@@ -2034,7 +2389,7 @@ static int action_luksAddKey(void)
goto out;
/* Check password before asking for new one */
- r = crypt_activate_by_passphrase(cd, NULL, CRYPT_ANY_SLOT,
+ r = crypt_activate_by_passphrase(cd, NULL, keyslot_old,
password, password_size, 0);
check_signal(&r);
tools_passphrase_msg(r);
@@ -2107,6 +2462,7 @@ static int action_luksAddKey(void)
}
out:
tools_keyslot_msg(r, CREATED);
+ free(vk_description);
crypt_keyslot_context_free(kc);
crypt_keyslot_context_free(kc_new);
crypt_safe_free(password);
@@ -2416,6 +2772,15 @@ static int action_luksDump(void)
goto out;
}
+ if (ARG_SET(OPT_EXTERNAL_TOKENS_PATH_ID)) {
+ r = crypt_token_set_external_path(ARG_STR(OPT_EXTERNAL_TOKENS_PATH_ID));
+ if (r < 0) {
+ log_err(_("Failed to set external tokens path %s."),
+ ARG_STR(OPT_EXTERNAL_TOKENS_PATH_ID));
+ goto out;
+ }
+ }
+
if (ARG_SET(OPT_DUMP_VOLUME_KEY_ID))
r = luksDump_with_volume_key(cd);
else if (ARG_SET(OPT_UNBOUND_ID))
@@ -2448,11 +2813,12 @@ static int action_luksSuspend(void)
static int action_luksResume(void)
{
struct crypt_device *cd = NULL;
- char *password = NULL;
+ char *password = NULL, *vk_description_activation = NULL;
size_t passwordLen;
int r, tries;
struct crypt_active_device cad;
const char *req_type = luksType(device_type);
+ struct crypt_keyslot_context *kc = NULL;
if (req_type && !isLUKS(req_type))
return -EINVAL;
@@ -2460,7 +2826,14 @@ static int action_luksResume(void)
if ((r = crypt_init_by_name_and_header(&cd, action_argv[0], uuid_or_device(ARG_STR(OPT_HEADER_ID)))))
return r;
+ if (ARG_SET(OPT_LINK_VK_TO_KEYRING_ID)) {
+ r = parse_vk_and_keyring_description(cd, keyring_links, keyring_links_count);
+ if (r < 0)
+ goto out;
+ }
+
r = -EINVAL;
+
if (!isLUKS(crypt_get_type(cd))) {
log_err(_("%s is not active LUKS device name or header is missing."), action_argv[0]);
goto out;
@@ -2481,20 +2854,34 @@ static int action_luksResume(void)
goto out;
}
- /* try to resume LUKS2 device by token first */
- r = crypt_resume_by_token_pin(cd, action_argv[0], ARG_STR(OPT_TOKEN_TYPE_ID),
- ARG_INT32(OPT_TOKEN_ID_ID), NULL, 0, NULL);
- tools_keyslot_msg(r, UNLOCKED);
- tools_token_error_msg(r, ARG_STR(OPT_TOKEN_TYPE_ID), ARG_INT32(OPT_TOKEN_ID_ID), false);
+ if (ARG_SET(OPT_EXTERNAL_TOKENS_PATH_ID)) {
+ r = crypt_token_set_external_path(ARG_STR(OPT_EXTERNAL_TOKENS_PATH_ID));
+ if (r < 0) {
+ log_err(_("Failed to set external tokens path %s."),
+ ARG_STR(OPT_EXTERNAL_TOKENS_PATH_ID));
+ goto out;
+ }
+ }
- /* Token requires PIN. Ask if there is evident preference for tokens */
- if (r == -ENOANO && (ARG_SET(OPT_TOKEN_ONLY_ID) || ARG_SET(OPT_TOKEN_TYPE_ID) ||
- ARG_SET(OPT_TOKEN_ID_ID)))
- r = _try_token_pin_unlock(cd, ARG_INT32(OPT_TOKEN_ID_ID), action_argv[0], ARG_STR(OPT_TOKEN_TYPE_ID), 0, set_tries_tty(), false);
+ /* try to resume LUKS2 device by token first */
+ r = _try_token_unlock(cd, ARG_INT32(OPT_KEY_SLOT_ID), ARG_INT32(OPT_TOKEN_ID_ID),
+ action_argv[0], ARG_STR(OPT_TOKEN_TYPE_ID), 0,
+ set_tries_tty(), false, ARG_SET(OPT_TOKEN_ONLY_ID));
if (r >= 0 || quit || ARG_SET(OPT_TOKEN_ONLY_ID))
goto out;
+ if (ARG_SET(OPT_VOLUME_KEY_KEYRING_ID)) {
+ r = parse_vk_description(ARG_STR(OPT_VOLUME_KEY_KEYRING_ID), &vk_description_activation);
+ if (r < 0)
+ goto out;
+ r = crypt_keyslot_context_init_by_vk_in_keyring(cd, vk_description_activation, &kc);
+ if (r)
+ goto out;
+ r = crypt_resume_by_keyslot_context(cd, action_argv[0], CRYPT_ANY_SLOT, kc);
+ goto out;
+ }
+
tries = set_tries_tty();
do {
r = tools_get_key(NULL, &password, &passwordLen,
@@ -2513,7 +2900,9 @@ static int action_luksResume(void)
password = NULL;
} while ((r == -EPERM || r == -ERANGE) && (--tries > 0));
out:
+ crypt_keyslot_context_free(kc);
crypt_safe_free(password);
+ free(vk_description_activation);
crypt_free(cd);
return r;
}
@@ -2642,15 +3031,48 @@ out:
return r;
}
+static int opal_erase(struct crypt_device *cd, bool factory_reset) {
+ char *password = NULL;
+ size_t password_size = 0;
+ int r;
+
+ r = tools_get_key(factory_reset ? _("Enter OPAL PSID: ") : _("Enter OPAL Admin password: "),
+ &password, &password_size, ARG_UINT64(OPT_KEYFILE_OFFSET_ID),
+ ARG_UINT32(OPT_KEYFILE_SIZE_ID), ARG_STR(OPT_KEY_FILE_ID),
+ ARG_UINT32(OPT_TIMEOUT_ID), verify_passphrase(0),
+ !ARG_SET(OPT_FORCE_PASSWORD_ID), cd);
+ if (r < 0)
+ return r;
+
+ if (factory_reset && !ARG_SET(OPT_BATCH_MODE_ID) &&
+ !yesDialog(_("WARNING: WHOLE disk will be factory reset and all data will be lost! Continue?"),
+ _("Operation aborted.\n"))) {
+ crypt_safe_free(password);
+ return -EPERM;
+ }
+
+ r = crypt_wipe_hw_opal(cd, factory_reset ? CRYPT_NO_SEGMENT : CRYPT_LUKS2_SEGMENT,
+ password, password_size, 0);
+
+ crypt_safe_free(password);
+ return r;
+}
+
static int action_luksErase(void)
{
struct crypt_device *cd = NULL;
crypt_keyslot_info ki;
char *msg = NULL;
- int i, max, r;
+ int i, max, r, hw_enc;
- if ((r = crypt_init(&cd, uuid_or_device_header(NULL))))
+ if ((r = crypt_init_data_device(&cd, uuid_or_device(ARG_STR(OPT_HEADER_ID) ?: action_argv[0]), action_argv[0])))
+ return r;
+
+ /* Allow factory reset even if there's no LUKS header, as long as OPAL is enabled on the device */
+ if (ARG_SET(OPT_HW_OPAL_FACTORY_RESET_ID)) {
+ r = opal_erase(cd, true);
goto out;
+ }
if ((r = crypt_load(cd, luksType(device_type), NULL))) {
log_err(_("Device %s is not a valid LUKS device."),
@@ -2658,7 +3080,15 @@ static int action_luksErase(void)
goto out;
}
- if(asprintf(&msg, _("This operation will erase all keyslots on device %s.\n"
+ hw_enc = crypt_get_hw_encryption_type(cd);
+ if (hw_enc < 0)
+ goto out;
+ if (hw_enc == CRYPT_OPAL_HW_ONLY || hw_enc == CRYPT_SW_AND_OPAL_HW) {
+ r = opal_erase(cd, false);
+ goto out;
+ }
+
+ if (asprintf(&msg, _("This operation will erase all keyslots on device %s.\n"
"Device will become unusable after this operation."),
uuid_or_device_header(NULL)) == -1) {
r = -ENOMEM;
@@ -2951,6 +3381,16 @@ static int action_token(void)
return r;
}
+ if (ARG_SET(OPT_EXTERNAL_TOKENS_PATH_ID)) {
+ r = crypt_token_set_external_path(ARG_STR(OPT_EXTERNAL_TOKENS_PATH_ID));
+ if (r < 0) {
+ log_err(_("Failed to set external tokens path %s."),
+ ARG_STR(OPT_EXTERNAL_TOKENS_PATH_ID));
+ crypt_free(cd);
+ return r;
+ }
+ }
+
r = -EINVAL;
if (!strcmp(action_argv[0], "add")) {
@@ -3063,7 +3503,7 @@ static const char *verify_resize(void)
static const char *verify_reencrypt(void)
{
if (ARG_SET(OPT_REDUCE_DEVICE_SIZE_ID) && ARG_SET(OPT_DEVICE_SIZE_ID))
- return _("Options --reduce-device-size and --data-size cannot be combined.");
+ return _("Options --reduce-device-size and --device-size cannot be combined.");
if (isLUKS1(luksType(device_type)) && ARG_SET(OPT_ACTIVE_NAME_ID))
return _("Option --active-name can be set only for LUKS2 device.");
@@ -3220,10 +3660,10 @@ static void help(poptContext popt_context,
path = crypt_token_external_path();
if (path) {
- log_std(_("\nLUKS2 external token plugin support is %s.\n"), _("compiled-in"));
+ log_std(_("\nLUKS2 external token plugin support is enabled.\n"));
log_std(_("LUKS2 external token plugin path: %s.\n"), path);
} else
- log_std(_("\nLUKS2 external token plugin support is %s.\n"), _("disabled"));
+ log_std(_("\nLUKS2 external token plugin support is disabled.\n"));
pbkdf_luks1 = crypt_get_pbkdf_default(CRYPT_LUKS1);
pbkdf_luks2 = crypt_get_pbkdf_default(CRYPT_LUKS2);
@@ -3315,6 +3755,7 @@ static void basic_options_cb(poptContext popt_context,
const char *arg,
void *data __attribute__((unused)))
{
+ char buf[128];
tools_parse_arg_value(popt_context, tool_core_args[key->val].type, tool_core_args + key->val, arg, key->val, needs_size_conversion);
/* special cases additional handling */
@@ -3366,6 +3807,29 @@ static void basic_options_cb(poptContext popt_context,
_("Key size must be a multiple of 8 bits"),
poptGetInvocationName(popt_context));
break;
+ case OPT_VOLUME_KEY_KEYRING_ID:
+ if (vks_in_keyring_count < MAX_VK_IN_KEYRING)
+ vks_in_keyring[vks_in_keyring_count++] = strdup(ARG_STR(OPT_VOLUME_KEY_KEYRING_ID));
+ else {
+ if (snprintf(buf, sizeof(buf), _("At most %d volume key specifications can be supplied."), MAX_KEYRING_LINKS) < 0)
+ buf[0] = '\0';
+ usage(popt_context, EXIT_FAILURE,
+ buf,
+ poptGetInvocationName(popt_context));
+ }
+ break;
+ case OPT_LINK_VK_TO_KEYRING_ID:
+ if (keyring_links_count < MAX_KEYRING_LINKS)
+ keyring_links[keyring_links_count++] = strdup(ARG_STR(OPT_LINK_VK_TO_KEYRING_ID));
+ else {
+
+ if (snprintf(buf, sizeof(buf), _("At most %d keyring link specifications can be supplied."), MAX_KEYRING_LINKS) < 0)
+ buf[0] = '\0';
+ usage(popt_context, EXIT_FAILURE,
+ buf,
+ poptGetInvocationName(popt_context));
+ }
+ break;
case OPT_REDUCE_DEVICE_SIZE_ID:
if (ARG_UINT64(OPT_REDUCE_DEVICE_SIZE_ID) > 1024 * 1024 * 1024)
usage(popt_context, EXIT_FAILURE, _("Maximum device reduce size is 1 GiB."),
@@ -3439,6 +3903,9 @@ int main(int argc, const char **argv)
textdomain(PACKAGE);
popt_context = poptGetContext(PACKAGE, argc, argv, popt_options, 0);
+ if (!popt_context)
+ exit(EXIT_FAILURE);
+
poptSetOtherOptionHelp(popt_context,
_("[OPTION...] <action> <action-specific>"));
@@ -3506,7 +3973,10 @@ int main(int argc, const char **argv)
aname = CLOSE_ACTION;
} else if (!strcmp(aname, "luksErase")) {
aname = ERASE_ACTION;
- device_type = "luks";
+ if (ARG_SET(OPT_TYPE_ID))
+ device_type = ARG_STR(OPT_TYPE_ID);
+ else
+ device_type = "luks";
} else if (!strcmp(aname, "luksConfig")) {
aname = CONFIG_ACTION;
device_type = "luks2";
@@ -3562,6 +4032,11 @@ int main(int argc, const char **argv)
_("PBKDF forced iterations cannot be combined with iteration time option."),
poptGetInvocationName(popt_context));
+ if (ARG_SET(OPT_DISABLE_KEYRING_ID) && ARG_SET(OPT_LINK_VK_TO_KEYRING_ID))
+ usage(popt_context, EXIT_FAILURE,
+ _("Cannot link volume key to a keyring when keyring is disabled."),
+ poptGetInvocationName(popt_context));
+
if (ARG_SET(OPT_DEBUG_ID) || ARG_SET(OPT_DEBUG_JSON_ID)) {
crypt_set_debug_level(ARG_SET(OPT_DEBUG_JSON_ID)? CRYPT_DEBUG_JSON : CRYPT_DEBUG_ALL);
dbg_version_and_cmd(argc, argv);
diff --git a/src/cryptsetup.h b/src/cryptsetup.h
index 011a669..8de8744 100644
--- a/src/cryptsetup.h
+++ b/src/cryptsetup.h
@@ -3,8 +3,8 @@
*
* Copyright (C) 2004 Jana Saout <jana@saout.de>
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
- * Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved.
- * Copyright (C) 2009-2023 Milan Broz
+ * Copyright (C) 2009-2024 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2009-2024 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/src/cryptsetup_arg_list.h b/src/cryptsetup_arg_list.h
index a7e5bb0..7496748 100644
--- a/src/cryptsetup_arg_list.h
+++ b/src/cryptsetup_arg_list.h
@@ -1,8 +1,8 @@
/*
* Cryptsetup command line arguments list
*
- * Copyright (C) 2020-2023 Red Hat, Inc. All rights reserved.
- * Copyright (C) 2020-2023 Ondrej Kozina
+ * Copyright (C) 2020-2024 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2020-2024 Ondrej Kozina
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -37,11 +37,13 @@ ARG(OPT_DEBUG, '\0', POPT_ARG_NONE, N_("Show debug messages"), NULL, CRYPT_ARG_B
ARG(OPT_DEBUG_JSON, '\0', POPT_ARG_NONE, N_("Show debug messages including JSON metadata"), NULL, CRYPT_ARG_BOOL, {}, {})
+ARG(OPT_DECRYPT, '\0', POPT_ARG_NONE, N_("Decrypt LUKS2 device (remove encryption)"), NULL, CRYPT_ARG_BOOL, {}, {})
+
ARG(OPT_DEFERRED, '\0', POPT_ARG_NONE, N_("Device removal is deferred until the last user closes it"), NULL, CRYPT_ARG_BOOL, {}, OPT_DEFERRED_ACTIONS)
-ARG(OPT_DEVICE_SIZE, '\0', POPT_ARG_STRING, N_("Use only specified device size (ignore rest of device). DANGEROUS!"), N_("bytes"), CRYPT_ARG_UINT64, {}, OPT_DEVICE_SIZE_ACTIONS)
+ARG(OPT_DEVICE_SIZE, '\0', POPT_ARG_STRING, N_("Use only specified device size (ignore rest of device), DANGEROUS!"), N_("bytes"), CRYPT_ARG_UINT64, {}, OPT_DEVICE_SIZE_ACTIONS)
-ARG(OPT_DECRYPT, '\0', POPT_ARG_NONE, N_("Decrypt LUKS2 device (remove encryption)."), NULL, CRYPT_ARG_BOOL, {}, {})
+ARG(OPT_DISABLE_BLKID, '\0', POPT_ARG_NONE, N_("Disable blkid on-disk signature detection and wiping"), NULL, CRYPT_ARG_BOOL, {}, OPT_DISABLE_BLKID_ACTIONS)
ARG(OPT_DISABLE_EXTERNAL_TOKENS, '\0', POPT_ARG_NONE, N_("Disable loading of external LUKS2 token plugins"), NULL, CRYPT_ARG_BOOL, {}, {})
@@ -55,11 +57,13 @@ ARG(OPT_DUMP_JSON, '\0', POPT_ARG_NONE, N_("Dump info in JSON format (LUKS2 only
ARG(OPT_DUMP_VOLUME_KEY, '\0', POPT_ARG_NONE, N_("Dump volume key instead of keyslots info"), NULL, CRYPT_ARG_BOOL, {}, {})
-ARG(OPT_ENCRYPT, '\0', POPT_ARG_NONE, N_("Encrypt LUKS2 device (in-place encryption)."), NULL, CRYPT_ARG_BOOL, {}, {})
+ARG(OPT_ENCRYPT, '\0', POPT_ARG_NONE, N_("Encrypt LUKS2 device (in-place encryption)"), NULL, CRYPT_ARG_BOOL, {}, {})
+
+ARG(OPT_EXTERNAL_TOKENS_PATH, '\0', POPT_ARG_STRING, N_("Path to directory with external token handlers (plugins)."), NULL, CRYPT_ARG_STRING, {}, OPT_EXTERNAL_TOKENS_PATH_ACTIONS)
ARG(OPT_FORCE_PASSWORD, '\0', POPT_ARG_NONE, N_("Disable password quality check (if enabled)"), NULL, CRYPT_ARG_BOOL, {}, {})
-ARG(OPT_FORCE_OFFLINE_REENCRYPT, '\0', POPT_ARG_NONE, N_("Force offline LUKS2 reencryption and bypass active device detection."), NULL, CRYPT_ARG_BOOL, {}, OPT_FORCE_OFFLINE_REENCRYPT_ACTIONS)
+ARG(OPT_FORCE_OFFLINE_REENCRYPT, '\0', POPT_ARG_NONE, N_("Force offline LUKS2 reencryption and bypass active device detection"), NULL, CRYPT_ARG_BOOL, {}, OPT_FORCE_OFFLINE_REENCRYPT_ACTIONS)
ARG(OPT_HASH, 'h', POPT_ARG_STRING, N_("The hash used to create the encryption key from the passphrase"), NULL, CRYPT_ARG_STRING, {}, {})
@@ -67,9 +71,15 @@ ARG(OPT_HEADER, '\0', POPT_ARG_STRING, N_("Device or file with separated LUKS he
ARG(OPT_HEADER_BACKUP_FILE, '\0', POPT_ARG_STRING, N_("File with LUKS header and keyslots backup"), NULL, CRYPT_ARG_STRING, {}, {})
-ARG(OPT_HOTZONE_SIZE, '\0', POPT_ARG_STRING, N_("Maximal reencryption hotzone size."), N_("bytes"), CRYPT_ARG_UINT64, {}, OPT_HOTZONE_SIZE_ACTIONS)
+ARG(OPT_HOTZONE_SIZE, '\0', POPT_ARG_STRING, N_("Maximal reencryption hotzone size"), N_("bytes"), CRYPT_ARG_UINT64, {}, OPT_HOTZONE_SIZE_ACTIONS)
+
+ARG(OPT_HW_OPAL, '\0', POPT_ARG_NONE, N_("Use HW OPAL encryption together with SW encryption"), NULL, CRYPT_ARG_BOOL, {}, OPT_HW_OPAL_ACTIONS)
+
+ARG(OPT_HW_OPAL_FACTORY_RESET, '\0', POPT_ARG_NONE, N_("Wipe WHOLE OPAL disk on luksErase"), NULL, CRYPT_ARG_BOOL, {}, OPT_ERASE_ACTIONS)
-ARG(OPT_INIT_ONLY, '\0', POPT_ARG_NONE, N_("Initialize LUKS2 reencryption in metadata only."), NULL, CRYPT_ARG_BOOL, {}, {})
+ARG(OPT_HW_OPAL_ONLY, '\0', POPT_ARG_NONE, N_("Use only HW OPAL encryption"), NULL, CRYPT_ARG_BOOL, {}, OPT_HW_OPAL_ONLY_ACTIONS)
+
+ARG(OPT_INIT_ONLY, '\0', POPT_ARG_NONE, N_("Initialize LUKS2 reencryption in metadata only"), NULL, CRYPT_ARG_BOOL, {}, {})
ARG(OPT_INTEGRITY, 'I', POPT_ARG_STRING, N_("Data integrity algorithm (LUKS2 only)"), NULL, CRYPT_ARG_STRING, {}, OPT_INTEGRITY_ACTIONS)
@@ -85,7 +95,7 @@ ARG(OPT_IV_LARGE_SECTORS, '\0', POPT_ARG_NONE, N_("Use IV counted in sector size
ARG(OPT_JSON_FILE, '\0', POPT_ARG_STRING, N_("Read or write the json from or to a file"), NULL, CRYPT_ARG_STRING, {}, {})
-ARG(OPT_KEEP_KEY, '\0', POPT_ARG_NONE, N_("Do not change volume key."), NULL, CRYPT_ARG_BOOL, {}, OPT_KEEP_KEY_ACTIONS)
+ARG(OPT_KEEP_KEY, '\0', POPT_ARG_NONE, N_("Do not change volume key"), NULL, CRYPT_ARG_BOOL, {}, OPT_KEEP_KEY_ACTIONS)
ARG(OPT_KEY_DESCRIPTION, '\0', POPT_ARG_STRING, N_("Key description"), NULL, CRYPT_ARG_STRING, {}, {})
@@ -105,20 +115,20 @@ ARG(OPT_KEYSLOT_KEY_SIZE, '\0', POPT_ARG_STRING, N_("LUKS2 keyslot: The size of
ARG(OPT_LABEL, '\0', POPT_ARG_STRING, N_("Set label for the LUKS2 device"), NULL, CRYPT_ARG_STRING, {}, OPT_LABEL_ACTIONS)
+ARG(OPT_LINK_VK_TO_KEYRING, '\0', POPT_ARG_STRING, N_("Set keyring where to link volume key"), NULL, CRYPT_ARG_STRING, {}, OPT_LINK_VK_TO_KEYRING_ACTIONS)
+
ARG(OPT_LUKS2_KEYSLOTS_SIZE, '\0', POPT_ARG_STRING, N_("LUKS2 header keyslots area size"), N_("bytes"), CRYPT_ARG_UINT64, {}, OPT_LUKS2_KEYSLOTS_SIZE_ACTIONS)
ARG(OPT_LUKS2_METADATA_SIZE, '\0', POPT_ARG_STRING, N_("LUKS2 header metadata area size"), N_("bytes"), CRYPT_ARG_UINT64, {}, OPT_LUKS2_METADATA_SIZE_ACTIONS)
-ARG(OPT_VOLUME_KEY_FILE, '\0', POPT_ARG_STRING, N_("Use the volume key from file."), NULL, CRYPT_ARG_STRING, {}, {})
-
ARG(OPT_NEW_KEYFILE, '\0', POPT_ARG_STRING, N_("Read the key for a new slot from a file"), NULL, CRYPT_ARG_STRING, {}, OPT_NEW_KEYFILE_ACTIONS)
-ARG(OPT_NEW_KEY_SLOT, '\0', POPT_ARG_STRING, N_("Slot number for new key (default is first free)"), "INT", CRYPT_ARG_INT32, { .i32_value = CRYPT_ANY_SLOT }, OPT_NEW_KEY_SLOT_ACTIONS)
-
ARG(OPT_NEW_KEYFILE_OFFSET , '\0', POPT_ARG_STRING, N_("Number of bytes to skip in newly added keyfile"), N_("bytes"), CRYPT_ARG_UINT64, {}, {})
ARG(OPT_NEW_KEYFILE_SIZE, '\0', POPT_ARG_STRING, N_("Limits the read from newly added keyfile"), N_("bytes"), CRYPT_ARG_UINT32, {}, {})
+ARG(OPT_NEW_KEY_SLOT, '\0', POPT_ARG_STRING, N_("Slot number for new key (default is first free)"), "INT", CRYPT_ARG_INT32, { .i32_value = CRYPT_ANY_SLOT }, OPT_NEW_KEY_SLOT_ACTIONS)
+
ARG(OPT_NEW_TOKEN_ID, '\0', POPT_ARG_STRING, N_("Token number (default: any)"), "INT", CRYPT_ARG_INT32, { .i32_value = CRYPT_ANY_TOKEN }, OPT_NEW_TOKEN_ID_ACTIONS)
ARG(OPT_OFFSET, 'o', POPT_ARG_STRING, N_("The start offset in the backend device"), N_("SECTORS"), CRYPT_ARG_UINT64, {}, OPT_OFFSET_ACTIONS)
@@ -149,7 +159,7 @@ ARG(OPT_PROGRESS_FREQUENCY, '\0', POPT_ARG_STRING, N_("Progress line update (in
ARG(OPT_READONLY, 'r', POPT_ARG_NONE, N_("Create a readonly mapping"), NULL, CRYPT_ARG_BOOL, {}, {})
-ARG(OPT_REDUCE_DEVICE_SIZE, '\0', POPT_ARG_STRING, N_("Reduce data device size (move data offset). DANGEROUS!"), N_("bytes"), CRYPT_ARG_UINT64, {}, {})
+ARG(OPT_REDUCE_DEVICE_SIZE, '\0', POPT_ARG_STRING, N_("Reduce data device size (move data offset), DANGEROUS!"), N_("bytes"), CRYPT_ARG_UINT64, {}, {})
ARG(OPT_REFRESH, '\0', POPT_ARG_NONE, N_("Refresh (reactivate) device with new parameters"), NULL, CRYPT_ARG_BOOL, {}, OPT_REFRESH_ACTIONS)
@@ -157,7 +167,7 @@ ARG(OPT_RESILIENCE, '\0', POPT_ARG_STRING, N_("Reencryption hotzone resilience t
ARG(OPT_RESILIENCE_HASH, '\0', POPT_ARG_STRING, N_("Reencryption hotzone checksums hash"), NULL, CRYPT_ARG_STRING, {}, {})
-ARG(OPT_RESUME_ONLY, '\0', POPT_ARG_NONE, N_("Resume initialized LUKS2 reencryption only."), NULL, CRYPT_ARG_BOOL, {}, {})
+ARG(OPT_RESUME_ONLY, '\0', POPT_ARG_NONE, N_("Resume initialized LUKS2 reencryption only"), NULL, CRYPT_ARG_BOOL, {}, {})
ARG(OPT_SECTOR_SIZE, '\0', POPT_ARG_STRING, N_("Encryption sector size (default: 512 bytes)"), "INT", CRYPT_ARG_UINT32, {}, OPT_SECTOR_SIZE_ACTIONS)
@@ -171,12 +181,6 @@ ARG(OPT_SKIP, 'p', POPT_ARG_STRING, N_("How many sectors of the encrypted data t
ARG(OPT_SUBSYSTEM, '\0', POPT_ARG_STRING, N_("Set subsystem label for the LUKS2 device"), NULL, CRYPT_ARG_STRING, {}, OPT_SUBSYSTEM_ACTIONS)
-ARG(OPT_TCRYPT_BACKUP, '\0', POPT_ARG_NONE, N_("Use backup (secondary) TCRYPT header"), NULL, CRYPT_ARG_BOOL, {}, OPT_TCRYPT_BACKUP_ACTIONS)
-
-ARG(OPT_TCRYPT_HIDDEN, '\0', POPT_ARG_NONE, N_("Use hidden header (hidden TCRYPT device)"), NULL, CRYPT_ARG_BOOL, {}, OPT_TCRYPT_HIDDEN_ACTIONS)
-
-ARG(OPT_TCRYPT_SYSTEM, '\0', POPT_ARG_NONE, N_("Device is system TCRYPT drive (with bootloader)"), NULL, CRYPT_ARG_BOOL, {}, OPT_TCRYPT_SYSTEM_ACTIONS)
-
ARG(OPT_TEST_ARGS, '\0', POPT_ARG_NONE, N_("Do not run action, just validate all command line parameters"), NULL, CRYPT_ARG_BOOL, {}, {})
ARG(OPT_TEST_PASSPHRASE, '\0', POPT_ARG_NONE, N_("Do not activate device, just check passphrase"), NULL, CRYPT_ARG_BOOL, {}, OPT_TEST_PASSPHRASE_ACTIONS)
@@ -191,6 +195,12 @@ ARG(OPT_TOKEN_REPLACE, '\0', POPT_ARG_NONE, N_("Replace the current token"), NUL
ARG(OPT_TOKEN_TYPE, '\0', POPT_ARG_STRING, N_("Restrict allowed token types used to retrieve LUKS2 key"), NULL, CRYPT_ARG_STRING, {}, {})
+ARG(OPT_TCRYPT_BACKUP, '\0', POPT_ARG_NONE, N_("Use backup (secondary) TCRYPT header"), NULL, CRYPT_ARG_BOOL, {}, OPT_TCRYPT_BACKUP_ACTIONS)
+
+ARG(OPT_TCRYPT_HIDDEN, '\0', POPT_ARG_NONE, N_("Use hidden header (hidden TCRYPT device)"), NULL, CRYPT_ARG_BOOL, {}, OPT_TCRYPT_HIDDEN_ACTIONS)
+
+ARG(OPT_TCRYPT_SYSTEM, '\0', POPT_ARG_NONE, N_("Device is system TCRYPT drive (with bootloader)"), NULL, CRYPT_ARG_BOOL, {}, OPT_TCRYPT_SYSTEM_ACTIONS)
+
ARG(OPT_TRIES, 'T', POPT_ARG_STRING, N_("How often the input of the passphrase can be retried"), "INT", CRYPT_ARG_UINT32, { .u32_value = 3 }, {})
ARG(OPT_TYPE, 'M', POPT_ARG_STRING, N_("Type of device metadata: luks, luks1, luks2, plain, loopaes, tcrypt, bitlk"), NULL, CRYPT_ARG_STRING, {}, {})
@@ -213,6 +223,10 @@ ARG(OPT_VERBOSE, 'v', POPT_ARG_NONE, N_("Shows more detailed error messages"), N
ARG(OPT_VERIFY_PASSPHRASE, 'y', POPT_ARG_NONE, N_("Verifies the passphrase by asking for it twice"), NULL, CRYPT_ARG_BOOL, {}, {})
+ARG(OPT_VOLUME_KEY_FILE, '\0', POPT_ARG_STRING, N_("Use the volume key from file"), NULL, CRYPT_ARG_STRING, {}, {})
+
+ARG(OPT_VOLUME_KEY_KEYRING, '\0', POPT_ARG_STRING, N_("Use the specified keyring key as a volume key"), NULL, CRYPT_ARG_STRING, {}, {})
+
/* added for reencryption */
ARG(OPT_BLOCK_SIZE, 'B', POPT_ARG_STRING, N_("Reencryption block size"), N_("MiB"), CRYPT_ARG_UINT32, { .u32_value = 4 }, {})
diff --git a/src/cryptsetup_args.h b/src/cryptsetup_args.h
index 63604a3..5df9e1e 100644
--- a/src/cryptsetup_args.h
+++ b/src/cryptsetup_args.h
@@ -1,8 +1,8 @@
/*
* Command line arguments helpers
*
- * Copyright (C) 2020-2023 Red Hat, Inc. All rights reserved.
- * Copyright (C) 2020-2023 Ondrej Kozina
+ * Copyright (C) 2020-2024 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2020-2024 Ondrej Kozina
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -25,57 +25,64 @@
#include "utils_arg_names.h"
#include "utils_arg_macros.h"
+#define ADDKEY_ACTION "luksAddKey"
#define BITLKDUMP_ACTION "bitlkDump"
#define BENCHMARK_ACTION "benchmark"
+#define CHANGEKEY_ACTION "luksChangeKey"
#define CLOSE_ACTION "close"
+#define CONVERTKEY_ACTION "luksConvertKey"
#define CONFIG_ACTION "config"
#define CONVERT_ACTION "convert"
#define ERASE_ACTION "erase"
-#define FVAULT2DUMP_ACTION "fvault2Dump"
-#define ISLUKS_ACTION "isLuks"
-#define ADDKEY_ACTION "luksAddKey"
-#define CHANGEKEY_ACTION "luksChangeKey"
-#define CONVERTKEY_ACTION "luksConvertKey"
-#define LUKSDUMP_ACTION "luksDump"
#define FORMAT_ACTION "luksFormat"
+#define FVAULT2DUMP_ACTION "fvault2Dump"
#define HEADERBACKUP_ACTION "luksHeaderBackup"
#define HEADERRESTORE_ACTION "luksHeaderRestore"
+#define ISLUKS_ACTION "isLuks"
#define KILLKEY_ACTION "luksKillSlot"
-#define REMOVEKEY_ACTION "luksRemoveKey"
-#define RESUME_ACTION "luksResume"
-#define SUSPEND_ACTION "luksSuspend"
-#define UUID_ACTION "luksUUID"
+#define LUKSDUMP_ACTION "luksDump"
#define OPEN_ACTION "open"
#define REENCRYPT_ACTION "reencrypt"
+#define REMOVEKEY_ACTION "luksRemoveKey"
#define REPAIR_ACTION "repair"
#define RESIZE_ACTION "resize"
+#define RESUME_ACTION "luksResume"
#define STATUS_ACTION "status"
+#define SUSPEND_ACTION "luksSuspend"
#define TCRYPTDUMP_ACTION "tcryptDump"
#define TOKEN_ACTION "token"
+#define UUID_ACTION "luksUUID"
/* avoid unshielded commas in ARG() macros later */
#define OPT_ALIGN_PAYLOAD_ACTIONS { FORMAT_ACTION, REENCRYPT_ACTION }
#define OPT_ALLOW_DISCARDS_ACTIONS { OPEN_ACTION }
#define OPT_DEFERRED_ACTIONS { CLOSE_ACTION }
#define OPT_DEVICE_SIZE_ACTIONS { OPEN_ACTION, RESIZE_ACTION, REENCRYPT_ACTION }
+#define OPT_DISABLE_BLKID_ACTIONS { FORMAT_ACTION, REENCRYPT_ACTION }
#define OPT_DISABLE_VERACRYPT_ACTIONS { OPEN_ACTION, TCRYPTDUMP_ACTION }
-#define OPT_HOTZONE_SIZE_ACTIONS { REENCRYPT_ACTION }
+#define OPT_ERASE_ACTIONS { ERASE_ACTION }
+#define OPT_EXTERNAL_TOKENS_PATH_ACTIONS { RESIZE_ACTION, OPEN_ACTION, ADDKEY_ACTION, LUKSDUMP_ACTION, RESUME_ACTION, TOKEN_ACTION }
#define OPT_FORCE_OFFLINE_REENCRYPT_ACTIONS { REENCRYPT_ACTION }
-#define OPT_INTEGRITY_ACTIONS { FORMAT_ACTION, REENCRYPT_ACTION }
-#define OPT_INTEGRITY_NO_WIPE_ACTIONS { FORMAT_ACTION, REENCRYPT_ACTION }
+#define OPT_HOTZONE_SIZE_ACTIONS { REENCRYPT_ACTION }
+#define OPT_HW_OPAL_ACTIONS { FORMAT_ACTION }
+#define OPT_HW_OPAL_ONLY_ACTIONS OPT_HW_OPAL_ACTIONS
+#define OPT_INTEGRITY_ACTIONS { FORMAT_ACTION }
+#define OPT_INTEGRITY_NO_WIPE_ACTIONS { FORMAT_ACTION }
#define OPT_ITER_TIME_ACTIONS { BENCHMARK_ACTION, FORMAT_ACTION, ADDKEY_ACTION, CHANGEKEY_ACTION, CONVERTKEY_ACTION, REENCRYPT_ACTION }
#define OPT_IV_LARGE_SECTORS_ACTIONS { OPEN_ACTION }
#define OPT_KEEP_KEY_ACTIONS { REENCRYPT_ACTION }
+#define OPT_KEY_DESCRIPTION_ACTIONS { TOKEN_ACTION }
#define OPT_KEY_SIZE_ACTIONS { OPEN_ACTION, BENCHMARK_ACTION, FORMAT_ACTION, REENCRYPT_ACTION, ADDKEY_ACTION }
#define OPT_KEY_SLOT_ACTIONS { OPEN_ACTION, REENCRYPT_ACTION, CONFIG_ACTION, FORMAT_ACTION, ADDKEY_ACTION, CHANGEKEY_ACTION, CONVERTKEY_ACTION, LUKSDUMP_ACTION, TOKEN_ACTION, RESUME_ACTION }
#define OPT_KEYSLOT_CIPHER_ACTIONS { FORMAT_ACTION, REENCRYPT_ACTION, ADDKEY_ACTION, CHANGEKEY_ACTION, CONVERTKEY_ACTION }
#define OPT_KEYSLOT_KEY_SIZE_ACTIONS OPT_KEYSLOT_CIPHER_ACTIONS
-#define OPT_NEW_KEYFILE_ACTIONS { ADDKEY_ACTION }
-#define OPT_NEW_KEY_SLOT_ACTIONS { ADDKEY_ACTION }
-#define OPT_NEW_TOKEN_ID_ACTIONS { ADDKEY_ACTION }
#define OPT_LABEL_ACTIONS { CONFIG_ACTION, FORMAT_ACTION, REENCRYPT_ACTION }
+#define OPT_LINK_VK_TO_KEYRING_ACTIONS { OPEN_ACTION, RESUME_ACTION }
#define OPT_LUKS2_KEYSLOTS_SIZE_ACTIONS { REENCRYPT_ACTION, FORMAT_ACTION }
#define OPT_LUKS2_METADATA_SIZE_ACTIONS { REENCRYPT_ACTION, FORMAT_ACTION }
+#define OPT_NEW_KEYFILE_ACTIONS { ADDKEY_ACTION }
+#define OPT_NEW_KEY_SLOT_ACTIONS { ADDKEY_ACTION }
+#define OPT_NEW_TOKEN_ID_ACTIONS { ADDKEY_ACTION }
#define OPT_OFFSET_ACTIONS { OPEN_ACTION, REENCRYPT_ACTION, FORMAT_ACTION }
#define OPT_PBKDF_ACTIONS { BENCHMARK_ACTION, FORMAT_ACTION, ADDKEY_ACTION, CHANGEKEY_ACTION, CONVERTKEY_ACTION, REENCRYPT_ACTION }
#define OPT_PBKDF_FORCE_ITERATIONS_ACTIONS { FORMAT_ACTION, ADDKEY_ACTION, CHANGEKEY_ACTION, CONVERTKEY_ACTION, REENCRYPT_ACTION }
diff --git a/src/integritysetup.c b/src/integritysetup.c
index eee6171..0e5d70f 100644
--- a/src/integritysetup.c
+++ b/src/integritysetup.c
@@ -1,8 +1,8 @@
/*
* integritysetup - setup integrity protected volumes for dm-integrity
*
- * Copyright (C) 2017-2023 Red Hat, Inc. All rights reserved.
- * Copyright (C) 2017-2023 Milan Broz
+ * Copyright (C) 2017-2024 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2017-2024 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -190,13 +190,18 @@ static int action_format(void)
goto out;
}
- r = tools_detect_signatures(action_argv[0], PRB_FILTER_NONE, &signatures, ARG_SET(OPT_BATCH_MODE_ID));
- if (r < 0)
- goto out;
+ if (!ARG_SET(OPT_DISABLE_BLKID_ID)) {
+ r = tools_detect_signatures(action_argv[0], PRB_FILTER_NONE, &signatures, ARG_SET(OPT_BATCH_MODE_ID));
+ if (r < 0) {
+ if (r == -EIO)
+ log_err(_("Blkid scan failed for %s."), action_argv[0]);
+ goto out;
+ }
- /* Signature candidates found */
- if (signatures && ((r = tools_wipe_all_signatures(action_argv[0], true, false)) < 0))
- goto out;
+ /* Signature candidates found */
+ if (signatures && ((r = tools_wipe_all_signatures(action_argv[0], true, false)) < 0))
+ goto out;
+ }
if (ARG_SET(OPT_INTEGRITY_LEGACY_PADDING_ID))
crypt_set_compatibility(cd, CRYPT_COMPAT_LEGACY_INTEGRITY_PADDING);
@@ -212,8 +217,12 @@ static int action_format(void)
log_std(_("Formatted with tag size %u, internal integrity %s.\n"),
params2.tag_size, params2.integrity);
- if (!ARG_SET(OPT_NO_WIPE_ID))
+ if (!ARG_SET(OPT_NO_WIPE_ID)) {
r = _wipe_data_device(cd, integrity_key);
+ /* Interrupted wipe should not fail format action */
+ if (r == -EINTR)
+ r = 0;
+ }
out:
crypt_safe_free(integrity_key);
crypt_safe_free(CONST_CAST(void*)params.journal_integrity_key);
@@ -660,6 +669,9 @@ int main(int argc, const char **argv)
textdomain(PACKAGE);
popt_context = poptGetContext("integrity", argc, argv, popt_options, 0);
+ if (!popt_context)
+ exit(EXIT_FAILURE);
+
poptSetOtherOptionHelp(popt_context,
_("[OPTION...] <action> <action-specific>"));
diff --git a/src/integritysetup_arg_list.h b/src/integritysetup_arg_list.h
index 39f2906..083184b 100644
--- a/src/integritysetup_arg_list.h
+++ b/src/integritysetup_arg_list.h
@@ -1,8 +1,8 @@
/*
* Integritysetup command line arguments list
*
- * Copyright (C) 2020-2023 Red Hat, Inc. All rights reserved.
- * Copyright (C) 2020-2023 Ondrej Kozina
+ * Copyright (C) 2020-2024 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2020-2024 Ondrej Kozina
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -29,7 +29,7 @@ ARG(OPT_BUFFER_SECTORS, '\0', POPT_ARG_STRING, N_("Buffers size"), N_("SECTORS")
ARG(OPT_BITMAP_FLUSH_TIME, '\0', POPT_ARG_STRING, N_("Bitmap mode flush time"), N_("ms"), CRYPT_ARG_UINT32, {}, {})
-ARG(OPT_BITMAP_SECTORS_PER_BIT, '\0', POPT_ARG_STRING, N_("Number of 512-byte sectors per bit (bitmap mode)."), "INT", CRYPT_ARG_UINT32, {}, {})
+ARG(OPT_BITMAP_SECTORS_PER_BIT, '\0', POPT_ARG_STRING, N_("Number of 512-byte sectors per bit (bitmap mode)"), "INT", CRYPT_ARG_UINT32, {}, {})
ARG(OPT_CANCEL_DEFERRED, '\0', POPT_ARG_NONE, N_("Cancel a previously set deferred device removal"), NULL, CRYPT_ARG_BOOL, {}, OPT_DEFERRED_ACTIONS)
@@ -39,8 +39,14 @@ ARG(OPT_DEBUG, '\0', POPT_ARG_NONE, N_("Show debug messages"), NULL, CRYPT_ARG_B
ARG(OPT_DEFERRED, '\0', POPT_ARG_NONE, N_("Device removal is deferred until the last user closes it"), NULL, CRYPT_ARG_BOOL, {}, OPT_DEFERRED_ACTIONS)
+ARG(OPT_DEVICE_SIZE, '\0', POPT_ARG_STRING, N_("Use only specified device size (ignore rest of device), DANGEROUS!"), N_("bytes"), CRYPT_ARG_UINT64, {}, OPT_DEVICE_SIZE_ACTIONS)
+
+ARG(OPT_DISABLE_BLKID, '\0', POPT_ARG_NONE, N_("Disable blkid on-disk signature detection and wiping"), NULL, CRYPT_ARG_BOOL, {}, OPT_DISABLE_BLKID_ACTIONS)
+
ARG(OPT_INTEGRITY, 'I', POPT_ARG_STRING, N_("Data integrity algorithm"), NULL, CRYPT_ARG_STRING, { .str_value = CONST_CAST(void *)DEFAULT_ALG_NAME }, {})
+ARG(OPT_INTEGRITY_BITMAP_MODE, 'B', POPT_ARG_NONE, N_("Use bitmap to track changes and disable journal for integrity device"), NULL, CRYPT_ARG_BOOL, {}, {})
+
ARG(OPT_INTEGRITY_KEY_FILE, '\0', POPT_ARG_STRING, N_("Read the integrity key from a file"), NULL, CRYPT_ARG_STRING, {}, {})
ARG(OPT_INTEGRITY_KEY_SIZE, '\0', POPT_ARG_STRING, N_("The size of the data integrity key"), N_("BITS"), CRYPT_ARG_UINT32, {}, {})
@@ -53,6 +59,12 @@ ARG(OPT_INTEGRITY_LEGACY_RECALC, '\0', POPT_ARG_NONE, N_("Allow recalculating of
ARG(OPT_INTEGRITY_NO_JOURNAL, 'D', POPT_ARG_NONE, N_("Disable journal for integrity device"), NULL, CRYPT_ARG_BOOL, {}, {})
+ARG(OPT_INTEGRITY_RECALCULATE, '\0', POPT_ARG_NONE, N_("Recalculate initial tags automatically"), NULL, CRYPT_ARG_BOOL, {}, OPT_INTEGRITY_RECALCULATE_ACTIONS)
+
+ARG(OPT_INTEGRITY_RECALCULATE_RESET, '\0', POPT_ARG_NONE, N_("Reset automatic recalculate position"), NULL, CRYPT_ARG_BOOL, {}, OPT_INTEGRITY_RECALCULATE_ACTIONS)
+
+ARG(OPT_INTEGRITY_RECOVERY_MODE, 'R', POPT_ARG_NONE, N_("Recovery mode (no journal, no tag checking)"), NULL, CRYPT_ARG_BOOL, {}, {})
+
ARG(OPT_INTERLEAVE_SECTORS, '\0', POPT_ARG_STRING, N_("Interleave sectors"), N_("SECTORS"), CRYPT_ARG_UINT32, {}, OPT_INTERLEAVE_SECTORS_ACTIONS)
ARG(OPT_JOURNAL_COMMIT_TIME, '\0', POPT_ARG_STRING, N_("Journal commit time"), N_("ms"), CRYPT_ARG_UINT32, {}, {})
@@ -75,26 +87,16 @@ ARG(OPT_JOURNAL_WATERMARK, '\0', POPT_ARG_STRING, N_("Journal watermark"), N_("p
ARG(OPT_NO_WIPE, '\0', POPT_ARG_NONE, N_("Do not wipe device after format"), NULL, CRYPT_ARG_BOOL, {}, OPT_NO_WIPE_ACTIONS)
-ARG(OPT_WIPE, '\0', POPT_ARG_NONE, N_("Wipe the end of the device after resize"), NULL, CRYPT_ARG_BOOL, {}, OPT_WIPE_ACTIONS)
-
ARG(OPT_PROGRESS_FREQUENCY, '\0', POPT_ARG_STRING, N_("Progress line update (in seconds)"), N_("secs"), CRYPT_ARG_UINT32, {}, {})
ARG(OPT_PROGRESS_JSON, '\0', POPT_ARG_NONE, N_("Print wipe progress data in json format (suitable for machine processing)"), NULL, CRYPT_ARG_BOOL, {}, OPT_PROGRESS_JSON_ACTIONS)
-ARG(OPT_INTEGRITY_BITMAP_MODE, 'B', POPT_ARG_NONE, N_("Use bitmap to track changes and disable journal for integrity device"), NULL, CRYPT_ARG_BOOL, {}, {})
-
-ARG(OPT_INTEGRITY_RECALCULATE, '\0', POPT_ARG_NONE, N_("Recalculate initial tags automatically."), NULL, CRYPT_ARG_BOOL, {}, OPT_INTEGRITY_RECALCULATE_ACTIONS)
-
-ARG(OPT_INTEGRITY_RECALCULATE_RESET, '\0', POPT_ARG_NONE, N_("Reset automatic recalculate position."), NULL, CRYPT_ARG_BOOL, {}, OPT_INTEGRITY_RECALCULATE_ACTIONS)
-
-ARG(OPT_INTEGRITY_RECOVERY_MODE, 'R', POPT_ARG_NONE, N_("Recovery mode (no journal, no tag checking)"), NULL, CRYPT_ARG_BOOL, {}, {})
-
ARG(OPT_SECTOR_SIZE, 's', POPT_ARG_STRING, N_("Sector size"), N_("bytes"), CRYPT_ARG_UINT32, { .u32_value = 512 }, OPT_SECTOR_SIZE_ACTIONS)
+ARG(OPT_SIZE, 'b', POPT_ARG_STRING, N_("The size of the device"), N_("SECTORS"), CRYPT_ARG_UINT64, {}, OPT_SIZE_ACTIONS)
+
ARG(OPT_TAG_SIZE, 't', POPT_ARG_STRING, N_("Tag size (per-sector)"), N_("bytes"), CRYPT_ARG_UINT32, {}, OPT_TAG_SIZE_ACTIONS)
ARG(OPT_VERBOSE, 'v', POPT_ARG_NONE, N_("Shows more detailed error messages"), NULL, CRYPT_ARG_BOOL, {}, {})
-ARG(OPT_DEVICE_SIZE, '\0', POPT_ARG_STRING, N_("Use only specified device size (ignore rest of device). DANGEROUS!"), N_("bytes"), CRYPT_ARG_UINT64, {}, OPT_DEVICE_SIZE_ACTIONS)
-
-ARG(OPT_SIZE, 'b', POPT_ARG_STRING, N_("The size of the device"), N_("SECTORS"), CRYPT_ARG_UINT64, {}, OPT_SIZE_ACTIONS)
+ARG(OPT_WIPE, '\0', POPT_ARG_NONE, N_("Wipe the end of the device after resize"), NULL, CRYPT_ARG_BOOL, {}, OPT_WIPE_ACTIONS)
diff --git a/src/integritysetup_args.h b/src/integritysetup_args.h
index 8241008..5595a84 100644
--- a/src/integritysetup_args.h
+++ b/src/integritysetup_args.h
@@ -1,8 +1,8 @@
/*
* Command line arguments helpers
*
- * Copyright (C) 2020-2023 Red Hat, Inc. All rights reserved.
- * Copyright (C) 2020-2023 Ondrej Kozina
+ * Copyright (C) 2020-2024 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2020-2024 Ondrej Kozina
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -25,24 +25,25 @@
#include "utils_arg_names.h"
#include "utils_arg_macros.h"
+#define DUMP_ACTION "dump"
#define FORMAT_ACTION "format"
-#define OPEN_ACTION "open"
#define CLOSE_ACTION "close"
-#define STATUS_ACTION "status"
-#define DUMP_ACTION "dump"
+#define OPEN_ACTION "open"
#define RESIZE_ACTION "resize"
+#define STATUS_ACTION "status"
#define OPT_ALLOW_DISCARDS_ACTIONS { OPEN_ACTION }
#define OPT_DEFERRED_ACTIONS { CLOSE_ACTION }
+#define OPT_DEVICE_SIZE_ACTIONS { RESIZE_ACTION }
+#define OPT_DISABLE_BLKID_ACTIONS { FORMAT_ACTION }
#define OPT_INTEGRITY_RECALCULATE_ACTIONS { OPEN_ACTION }
+#define OPT_INTERLEAVE_SECTORS_ACTIONS { FORMAT_ACTION }
#define OPT_JOURNAL_SIZE_ACTIONS { FORMAT_ACTION }
#define OPT_NO_WIPE_ACTIONS { FORMAT_ACTION }
-#define OPT_INTERLEAVE_SECTORS_ACTIONS { FORMAT_ACTION }
#define OPT_PROGRESS_JSON_ACTIONS { FORMAT_ACTION, RESIZE_ACTION }
#define OPT_SECTOR_SIZE_ACTIONS { FORMAT_ACTION }
-#define OPT_TAG_SIZE_ACTIONS { FORMAT_ACTION }
-#define OPT_DEVICE_SIZE_ACTIONS { RESIZE_ACTION }
#define OPT_SIZE_ACTIONS { RESIZE_ACTION }
+#define OPT_TAG_SIZE_ACTIONS { FORMAT_ACTION }
#define OPT_WIPE_ACTIONS { RESIZE_ACTION }
enum {
diff --git a/src/meson.build b/src/meson.build
new file mode 100644
index 0000000..3fd1ff5
--- /dev/null
+++ b/src/meson.build
@@ -0,0 +1,77 @@
+src_build_dir = meson.current_build_dir()
+
+if get_option('cryptsetup')
+ cryptsetup_files = files(
+ 'cryptsetup.c',
+ 'utils_args.c',
+ 'utils_blockdev.c',
+ 'utils_luks.c',
+ 'utils_password.c',
+ 'utils_progress.c',
+ 'utils_reencrypt.c',
+ 'utils_reencrypt_luks1.c',
+ 'utils_tools.c',
+ )
+ cryptsetup_files += lib_tools_files
+ cryptsetup_deps = [
+ popt,
+ pwquality,
+ passwdqc,
+ uuid,
+ blkid,
+ ]
+ cryptsetup = executable('cryptsetup',
+ cryptsetup_files,
+ dependencies: cryptsetup_deps,
+ link_with: libcryptsetup,
+ link_args: link_args,
+ include_directories: includes_tools)
+endif
+
+if get_option('veritysetup')
+ veritysetup_files = files(
+ 'utils_args.c',
+ 'utils_tools.c',
+ 'veritysetup.c',
+ )
+ veritysetup_files += lib_tools_files
+ veritysetup_deps = [
+ popt,
+ blkid,
+ ]
+
+ veritysetup = executable('veritysetup',
+ veritysetup_files,
+ dependencies: veritysetup_deps,
+ link_with: libcryptsetup,
+ link_args: link_args,
+ include_directories: includes_tools)
+endif
+
+if get_option('integritysetup')
+ integritysetup_files = files(
+ 'integritysetup.c',
+ 'utils_args.c',
+ 'utils_blockdev.c',
+ 'utils_progress.c',
+ 'utils_tools.c',
+ )
+ integritysetup_files += lib_tools_files
+ integritysetup_deps = [
+ popt,
+ uuid,
+ blkid,
+ ]
+
+ integritysetup = executable('integritysetup',
+ integritysetup_files,
+ dependencies: integritysetup_deps,
+ link_with: libcryptsetup,
+ link_args: link_args,
+ include_directories: includes_tools)
+endif
+
+src_ssh_token_files = files(
+ 'utils_password.c',
+ 'utils_tools.c',
+)
diff --git a/src/utils_arg_macros.h b/src/utils_arg_macros.h
index 901b3f4..eba0eca 100644
--- a/src/utils_arg_macros.h
+++ b/src/utils_arg_macros.h
@@ -1,8 +1,8 @@
/*
* Command line arguments parsing helpers
*
- * Copyright (C) 2020-2023 Red Hat, Inc. All rights reserved.
- * Copyright (C) 2020-2023 Ondrej Kozina
+ * Copyright (C) 2020-2024 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2020-2024 Ondrej Kozina
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/src/utils_arg_names.h b/src/utils_arg_names.h
index 66a59e8..4ec5510 100644
--- a/src/utils_arg_names.h
+++ b/src/utils_arg_names.h
@@ -1,8 +1,8 @@
/*
* Command line arguments name list
*
- * Copyright (C) 2020-2023 Red Hat, Inc. All rights reserved.
- * Copyright (C) 2020-2023 Ondrej Kozina
+ * Copyright (C) 2020-2024 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2020-2024 Ondrej Kozina
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -41,6 +41,7 @@
#define OPT_DEFERRED "deferred"
#define OPT_DEVICE_SIZE "device-size"
#define OPT_DECRYPT "decrypt"
+#define OPT_DISABLE_BLKID "disable-blkid"
#define OPT_DISABLE_EXTERNAL_TOKENS "disable-external-tokens"
#define OPT_DISABLE_KEYRING "disable-keyring"
#define OPT_DISABLE_LOCKS "disable-locks"
@@ -49,6 +50,7 @@
#define OPT_DUMP_MASTER_KEY "dump-master-key"
#define OPT_DUMP_VOLUME_KEY "dump-volume-key"
#define OPT_ENCRYPT "encrypt"
+#define OPT_EXTERNAL_TOKENS_PATH "external-tokens-path"
#define OPT_FEC_DEVICE "fec-device"
#define OPT_FEC_OFFSET "fec-offset"
#define OPT_FEC_ROOTS "fec-roots"
@@ -61,6 +63,9 @@
#define OPT_HEADER "header"
#define OPT_HEADER_BACKUP_FILE "header-backup-file"
#define OPT_HOTZONE_SIZE "hotzone-size"
+#define OPT_HW_OPAL "hw-opal"
+#define OPT_HW_OPAL_ONLY "hw-opal-only"
+#define OPT_HW_OPAL_FACTORY_RESET "hw-opal-factory-reset"
#define OPT_IGNORE_CORRUPTION "ignore-corruption"
#define OPT_IGNORE_ZERO_BLOCKS "ignore-zero-blocks"
#define OPT_INIT_ONLY "init-only"
@@ -102,10 +107,12 @@
#define OPT_NO_WIPE "no-wipe"
#define OPT_WIPE "wipe"
#define OPT_LABEL "label"
+#define OPT_LINK_VK_TO_KEYRING "link-vk-to-keyring"
#define OPT_LUKS2_KEYSLOTS_SIZE "luks2-keyslots-size"
#define OPT_LUKS2_METADATA_SIZE "luks2-metadata-size"
#define OPT_MASTER_KEY_FILE "master-key-file"
#define OPT_VOLUME_KEY_FILE "volume-key-file"
+#define OPT_VOLUME_KEY_KEYRING "volume-key-keyring"
#define OPT_NEW "new"
#define OPT_NEW_KEY_SLOT "new-key-slot"
#define OPT_NEW_KEYFILE "new-keyfile"
diff --git a/src/utils_args.c b/src/utils_args.c
index fda2350..47be0c3 100644
--- a/src/utils_args.c
+++ b/src/utils_args.c
@@ -1,8 +1,8 @@
/*
* Command line arguments parsing helpers
*
- * Copyright (C) 2020-2023 Red Hat, Inc. All rights reserved.
- * Copyright (C) 2020-2023 Ondrej Kozina
+ * Copyright (C) 2020-2024 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2020-2024 Ondrej Kozina
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/src/utils_blockdev.c b/src/utils_blockdev.c
index ae6dec4..c797cf4 100644
--- a/src/utils_blockdev.c
+++ b/src/utils_blockdev.c
@@ -1,8 +1,8 @@
/*
* Linux block devices helpers
*
- * Copyright (C) 2018-2023 Red Hat, Inc. All rights reserved.
- * Copyright (C) 2018-2023 Ondrej Kozina
+ * Copyright (C) 2018-2024 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2018-2024 Ondrej Kozina
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -222,17 +222,22 @@ int tools_detect_signatures(const char *device, tools_probe_filter_info filter,
switch (filter) {
case PRB_FILTER_LUKS:
+ log_dbg("Blkid check (filter LUKS).");
if (blk_superblocks_filter_luks(h)) {
r = -EINVAL;
+ log_dbg("Blkid filter LUKS probe failed.");
goto out;
}
/* fall-through */
case PRB_FILTER_NONE:
+ log_dbg("Blkid check (filter none).");
blk_set_chains_for_full_print(h);
break;
case PRB_ONLY_LUKS:
+ log_dbg("Blkid check (LUKS only).");
blk_set_chains_for_fast_detection(h);
if (blk_superblocks_only_luks(h)) {
+ log_dbg("Blkid only LUKS probe failed.");
r = -EINVAL;
goto out;
}
@@ -251,8 +256,11 @@ int tools_detect_signatures(const char *device, tools_probe_filter_info filter,
(*count)++;
}
- if (pr == PRB_FAIL)
- r = -EINVAL;
+ if (pr == PRB_FAIL) {
+ /* Expect device cannot be read */
+ r = -EIO;
+ log_dbg("Blkid probe failed.");
+ }
out:
blk_free(h);
return r;
@@ -302,6 +310,8 @@ int tools_wipe_all_signatures(const char *path, bool exclusive, bool only_luks)
goto out;
}
+ log_dbg("Blkid wipe.");
+
while ((pr = blk_probe(h)) < PRB_EMPTY) {
if (blk_is_partition(h))
log_verbose(_("Existing '%s' partition signature on device %s will be wiped."),
diff --git a/src/utils_luks.c b/src/utils_luks.c
index 6a10ab6..5007b3f 100644
--- a/src/utils_luks.c
+++ b/src/utils_luks.c
@@ -1,9 +1,9 @@
/*
* Helper utilities for LUKS2 features
*
- * Copyright (C) 2018-2023 Red Hat, Inc. All rights reserved.
- * Copyright (C) 2018-2023 Milan Broz
- * Copyright (C) 2018-2023 Ondrej Kozina
+ * Copyright (C) 2018-2024 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2018-2024 Milan Broz
+ * Copyright (C) 2018-2024 Ondrej Kozina
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -50,7 +50,8 @@ bool isLUKS1(const char *type)
bool isLUKS2(const char *type)
{
- return type && !strcmp(type, CRYPT_LUKS2);
+ /* OPAL just changes the driver, header format is identical, so overload */
+ return type && (!strcmp(type, CRYPT_LUKS2));
}
int verify_passphrase(int def)
diff --git a/src/utils_luks.h b/src/utils_luks.h
index 28220ab..6183b26 100644
--- a/src/utils_luks.h
+++ b/src/utils_luks.h
@@ -1,9 +1,9 @@
/*
* Helper utilities for LUKS in cryptsetup
*
- * Copyright (C) 2018-2023 Red Hat, Inc. All rights reserved.
- * Copyright (C) 2018-2023 Milan Broz
- * Copyright (C) 2018-2023 Ondrej Kozina
+ * Copyright (C) 2018-2024 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2018-2024 Milan Broz
+ * Copyright (C) 2018-2024 Ondrej Kozina
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/src/utils_password.c b/src/utils_password.c
index 3374e18..70da4b0 100644
--- a/src/utils_password.c
+++ b/src/utils_password.c
@@ -1,8 +1,8 @@
/*
* Password quality check wrapper
*
- * Copyright (C) 2012-2023 Red Hat, Inc. All rights reserved.
- * Copyright (C) 2012-2023 Milan Broz
+ * Copyright (C) 2012-2024 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2012-2024 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -98,6 +98,7 @@ static int tools_check_password(const char *password)
#elif defined ENABLE_PASSWDQC
return tools_check_passwdqc(password);
#else
+ UNUSED(password);
return 0;
#endif
}
diff --git a/src/utils_progress.c b/src/utils_progress.c
index 76b1818..3105bed 100644
--- a/src/utils_progress.c
+++ b/src/utils_progress.c
@@ -1,8 +1,8 @@
/*
* cryptsetup - progress output utilities
*
- * Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved.
- * Copyright (C) 2009-2023 Milan Broz
+ * Copyright (C) 2009-2024 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2009-2024 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/src/utils_reencrypt.c b/src/utils_reencrypt.c
index a78557c..7546811 100644
--- a/src/utils_reencrypt.c
+++ b/src/utils_reencrypt.c
@@ -1,9 +1,9 @@
/*
* cryptsetup - action re-encryption utilities
*
- * Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved.
- * Copyright (C) 2009-2023 Milan Broz
- * Copyright (C) 2021-2023 Ondrej Kozina
+ * Copyright (C) 2009-2024 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2009-2024 Milan Broz
+ * Copyright (C) 2021-2024 Ondrej Kozina
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -306,7 +306,7 @@ static int reencrypt_luks2_load(struct crypt_device *cd, const char *data_device
if (!ARG_SET(OPT_BATCH_MODE_ID) && !ARG_SET(OPT_RESUME_ONLY_ID)) {
r = asprintf(&msg, _("Device %s is already in LUKS2 reencryption. "
"Do you wish to resume previously initialised operation?"),
- crypt_get_metadata_device_name(cd) ?: data_device);
+ crypt_get_metadata_device_name(cd) ?: crypt_get_device_name(cd));
if (r < 0) {
r = -ENOMEM;
goto out;
@@ -349,11 +349,6 @@ static int luks2_reencrypt_in_progress(struct crypt_device *cd)
if (crypt_persistent_flags_get(cd, CRYPT_FLAGS_REQUIREMENTS, &flags))
return -EINVAL;
- if (flags & CRYPT_REQUIREMENT_OFFLINE_REENCRYPT) {
- log_err(_("Legacy LUKS2 reencryption is no longer supported."));
- return -EINVAL;
- }
-
return flags & CRYPT_REQUIREMENT_ONLINE_REENCRYPT;
}
@@ -411,14 +406,34 @@ static enum device_status_info load_luks(struct crypt_device **r_cd,
static bool luks2_reencrypt_eligible(struct crypt_device *cd)
{
+ uint32_t flags;
struct crypt_params_integrity ip = { 0 };
+ if (crypt_persistent_flags_get(cd, CRYPT_FLAGS_REQUIREMENTS, &flags))
+ return false;
+
+ if (flags & CRYPT_REQUIREMENT_OFFLINE_REENCRYPT) {
+ log_err(_("Legacy LUKS2 reencryption is no longer supported."));
+ return false;
+ }
+
+ if (flags & CRYPT_REQUIREMENT_OPAL) {
+ log_err(_("Can not reencrypt LUKS2 device configured to use OPAL."));
+ return false;
+ }
+
/* raw integrity info is available since 2.0 */
if (crypt_get_integrity_info(cd, &ip) || ip.tag_size) {
log_err(_("Reencryption of device with integrity profile is not supported."));
return false;
}
+ /* Check that cipher is in compatible format */
+ if (!crypt_get_cipher(cd)) {
+ log_err(_("No known cipher specification pattern detected in LUKS2 header."));
+ return false;
+ }
+
return true;
}
@@ -1322,9 +1337,15 @@ static int check_broken_luks_signature(const char *device)
int r;
size_t count;
+ if (ARG_SET(OPT_DISABLE_BLKID_ID))
+ return 0;
+
r = tools_detect_signatures(device, PRB_ONLY_LUKS, &count, ARG_SET(OPT_BATCH_MODE_ID));
- if (r < 0)
+ if (r < 0) {
+ if (r == -EIO)
+ log_err(_("Blkid scan failed for %s."), device);
return -EINVAL;
+ }
if (count) {
log_err(_("Device %s contains broken LUKS metadata. Aborting operation."), device);
return -EINVAL;
@@ -1449,6 +1470,8 @@ static int _decrypt(struct crypt_device **cd, enum device_status_info dev_st, co
if ((r = reencrypt_luks2_load(*cd, data_device)) < 0)
return r;
} else if (dev_st == DEVICE_LUKS2) {
+ if (!luks2_reencrypt_eligible(*cd))
+ return -EINVAL;
if (!ARG_SET(OPT_HEADER_ID)) {
log_err(_("LUKS2 decryption requires --header option."));
return -EINVAL;
diff --git a/src/utils_reencrypt_luks1.c b/src/utils_reencrypt_luks1.c
index ae849c0..1e36ad9 100644
--- a/src/utils_reencrypt_luks1.c
+++ b/src/utils_reencrypt_luks1.c
@@ -1,8 +1,8 @@
/*
* cryptsetup - LUKS1 utility for offline re-encryption
*
- * Copyright (C) 2012-2023 Red Hat, Inc. All rights reserved.
- * Copyright (C) 2012-2023 Milan Broz
+ * Copyright (C) 2012-2024 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2012-2024 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/src/utils_tools.c b/src/utils_tools.c
index a0e2ebc..5cfd9e6 100644
--- a/src/utils_tools.c
+++ b/src/utils_tools.c
@@ -3,8 +3,8 @@
*
* Copyright (C) 2004 Jana Saout <jana@saout.de>
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
- * Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved.
- * Copyright (C) 2009-2023 Milan Broz
+ * Copyright (C) 2009-2024 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2009-2024 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -435,8 +435,9 @@ int tools_write_mk(const char *file, const char *key, int keysize)
void tools_package_version(const char *name, bool use_pwlibs)
{
- bool udev = false, blkid = false, keyring = false, fips = false;
- bool kernel_capi = false, pwquality = false, passwdqc = false;
+ bool udev = false, blkid = false, keyring = false, fips = false,
+ kernel_capi = false, pwquality = false, passwdqc = false,
+ hw_opal = false;
#ifdef USE_UDEV
udev = true;
#endif
@@ -457,12 +458,16 @@ void tools_package_version(const char *name, bool use_pwlibs)
#elif defined(ENABLE_PASSWDQC)
passwdqc = true;
#endif
- log_std("%s %s flags: %s%s%s%s%s%s%s\n", name, PACKAGE_VERSION,
+#ifdef HAVE_HW_OPAL
+ hw_opal = true;
+#endif
+ log_std("%s %s flags: %s%s%s%s%s%s%s%s\n", name, PACKAGE_VERSION,
udev ? "UDEV " : "",
blkid ? "BLKID " : "",
keyring ? "KEYRING " : "",
fips ? "FIPS " : "",
kernel_capi ? "KERNEL_CAPI " : "",
pwquality && use_pwlibs ? "PWQUALITY " : "",
- passwdqc && use_pwlibs ? "PASSWDQC " : "");
+ passwdqc && use_pwlibs ? "PASSWDQC " : "",
+ hw_opal ? "HW_OPAL " : "");
}
diff --git a/src/veritysetup.c b/src/veritysetup.c
index 8be81cc..3fd90fc 100644
--- a/src/veritysetup.c
+++ b/src/veritysetup.c
@@ -1,8 +1,8 @@
/*
* veritysetup - setup cryptographic volumes for dm-verity
*
- * Copyright (C) 2012-2023 Red Hat, Inc. All rights reserved.
- * Copyright (C) 2012-2023 Milan Broz
+ * Copyright (C) 2012-2024 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2012-2024 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -599,6 +599,9 @@ int main(int argc, const char **argv)
textdomain(PACKAGE);
popt_context = poptGetContext("verity", argc, argv, popt_options, 0);
+ if (!popt_context)
+ exit(EXIT_FAILURE);
+
poptSetOtherOptionHelp(popt_context,
_("[OPTION...] <action> <action-specific>"));
diff --git a/src/veritysetup_arg_list.h b/src/veritysetup_arg_list.h
index 014273e..34002f3 100644
--- a/src/veritysetup_arg_list.h
+++ b/src/veritysetup_arg_list.h
@@ -1,8 +1,8 @@
/*
* Veritysetup command line arguments list
*
- * Copyright (C) 2020-2023 Red Hat, Inc. All rights reserved.
- * Copyright (C) 2020-2023 Ondrej Kozina
+ * Copyright (C) 2020-2024 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2020-2024 Ondrej Kozina
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/src/veritysetup_args.h b/src/veritysetup_args.h
index d47813d..43f4a23 100644
--- a/src/veritysetup_args.h
+++ b/src/veritysetup_args.h
@@ -1,8 +1,8 @@
/*
* Command line arguments helpers
*
- * Copyright (C) 2020-2023 Red Hat, Inc. All rights reserved.
- * Copyright (C) 2020-2023 Ondrej Kozina
+ * Copyright (C) 2020-2024 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2020-2024 Ondrej Kozina
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -35,8 +35,8 @@
#define OPT_DEFERRED_ACTIONS { CLOSE_ACTION }
#define OPT_IGNORE_CORRUPTION_ACTIONS { OPEN_ACTION }
#define OPT_IGNORE_ZERO_BLOCKS_ACTIONS { OPEN_ACTION }
-#define OPT_RESTART_ON_CORRUPTION_ACTIONS { OPEN_ACTION }
#define OPT_PANIC_ON_CORRUPTION_ACTIONS { OPEN_ACTION }
+#define OPT_RESTART_ON_CORRUPTION_ACTIONS { OPEN_ACTION }
#define OPT_ROOT_HASH_FILE_ACTIONS { FORMAT_ACTION, OPEN_ACTION, VERIFY_ACTION }
#define OPT_ROOT_HASH_SIGNATURE_ACTIONS { OPEN_ACTION }
#define OPT_USE_TASKLETS_ACTIONS { OPEN_ACTION }