* [PATCH 1/2] bitlocker: Support clearkey
2025-10-04 0:35 [PATCH 0/2] Bitlocker: Support clearkey Kfir Kahanov
@ 2025-10-04 0:35 ` Kfir Kahanov
2025-10-04 0:35 ` [PATCH 2/2] bitlocker: Add clearkey option Kfir Kahanov
2025-10-04 18:17 ` [PATCH 0/2] Bitlocker: Support clearkey Milan Broz
2 siblings, 0 replies; 6+ messages in thread
From: Kfir Kahanov @ 2025-10-04 0:35 UTC (permalink / raw)
To: cryptsetup; +Cc: Kfir Kahanov
Clearkey does not mean partially encrypted, and may be on fully
encrypted volumes.
---
lib/bitlk/bitlk.c | 106 ++++++++++++++++++++++++++++++----------------
1 file changed, 69 insertions(+), 37 deletions(-)
diff --git a/lib/bitlk/bitlk.c b/lib/bitlk/bitlk.c
index bc3a55bb..11edd7d9 100644
--- a/lib/bitlk/bitlk.c
+++ b/lib/bitlk/bitlk.c
@@ -264,10 +264,11 @@ static int parse_vmk_entry(struct crypt_device *cd, uint8_t *data, int start, in
bool supported = false;
int r = 0;
- /* only passphrase or recovery passphrase vmks are supported (can be used to activate) */
+ /* only passphrase, recovery passphrase, startup key and clearkey vmks are supported (can be used to activate) */
supported = (*vmk)->protection == BITLK_PROTECTION_PASSPHRASE ||
(*vmk)->protection == BITLK_PROTECTION_RECOVERY_PASSPHRASE ||
- (*vmk)->protection == BITLK_PROTECTION_STARTUP_KEY;
+ (*vmk)->protection == BITLK_PROTECTION_STARTUP_KEY ||
+ (*vmk)->protection == BITLK_PROTECTION_CLEAR_KEY;
while ((end - start) >= (ssize_t)(sizeof(key_entry_size) + sizeof(key_entry_type) + sizeof(key_entry_value))) {
/* size of this entry */
@@ -324,17 +325,13 @@ static int parse_vmk_entry(struct crypt_device *cd, uint8_t *data, int start, in
crypt_volume_key_add_next(&((*vmk)->vk), vk);
/* clear key for a partially decrypted volume */
} else if (key_entry_value == BITLK_ENTRY_VALUE_KEY) {
- /* We currently don't want to support opening a partially decrypted
- * device so we don't need to store this key.
- *
- * key_size = key_entry_size - (BITLK_ENTRY_HEADER_LEN + 4);
- * key = (const char *) data + start + BITLK_ENTRY_HEADER_LEN + 4;
- * vk = crypt_alloc_volume_key(key_size, key);
- * if (vk == NULL)
- * return -ENOMEM;
- * crypt_volume_key_add_next(&((*vmk)->vk), vk);
- */
- log_dbg(cd, "Skipping clear key metadata entry.");
+ /* For clearkey protection, we need to store this key */
+ key_size = key_entry_size - (BITLK_ENTRY_HEADER_LEN + 4);
+ key = (const char *) data + start + BITLK_ENTRY_HEADER_LEN + 4;
+ vk = crypt_alloc_volume_key(key_size, key);
+ if (vk == NULL)
+ return -ENOMEM;
+ crypt_volume_key_add_next(&((*vmk)->vk), vk);
/* unknown timestamps in recovery protected VMK */
} else if (key_entry_value == BITLK_ENTRY_VALUE_RECOVERY_TIME) {
;
@@ -1249,6 +1246,43 @@ out:
return r;
}
+static int get_clear_key(struct crypt_device *cd, const struct bitlk_vmk *vmk, struct volume_key **vmk_dec_key)
+{
+ struct volume_key *nested_key = vmk->vk; // First key in chain
+
+ if (!nested_key) {
+ log_dbg(cd, "Clearkey VMK structure incomplete - missing nested key");
+ return -ENOTSUP;
+ }
+
+ struct volume_key *encrypted_vmk = crypt_volume_key_next(nested_key); // Second key in chain
+
+ if (!encrypted_vmk) {
+ log_dbg(cd, "Clearkey VMK structure incomplete - missing encrypted VMK");
+ return -ENOTSUP;
+ }
+
+ log_dbg(cd, "Clearkey VMK structure: nested_key=%zu bytes, encrypted_vmk=%zu bytes",
+ crypt_volume_key_length(nested_key),
+ crypt_volume_key_length(encrypted_vmk));
+
+ /* For clearkey protection, we need to decrypt the encrypted VMK using the nested key */
+ /* and return the decrypted VMK as vmk_dec_key */
+ struct volume_key *decrypted_vmk = NULL;
+ int r = decrypt_key(cd, &decrypted_vmk, encrypted_vmk, nested_key,
+ vmk->mac_tag, BITLK_VMK_MAC_TAG_SIZE,
+ vmk->nonce, BITLK_NONCE_SIZE, false);
+
+ if (r == 0 && decrypted_vmk) {
+ log_dbg(cd, "Successfully decrypted VMK using nested key");
+ *vmk_dec_key = decrypted_vmk;
+ return 0;
+ } else {
+ log_dbg(cd, "Failed to decrypt VMK using nested key (error: %d)", r);
+ return r;
+ }
+}
+
int BITLK_get_volume_key(struct crypt_device *cd,
const char *password,
size_t passwordLen,
@@ -1261,6 +1295,8 @@ int BITLK_get_volume_key(struct crypt_device *cd,
struct volume_key *recovery_key = NULL;
struct bitlk_validation_hash dec_hash = {};
const struct bitlk_vmk *next_vmk = NULL;
+ bool is_decrypted = false;
+
next_vmk = params->vmks;
while (next_vmk) {
@@ -1298,8 +1334,18 @@ int BITLK_get_volume_key(struct crypt_device *cd,
continue;
}
log_dbg(cd, "Trying to use external key found in provided password.");
+ } else if (next_vmk->protection == BITLK_PROTECTION_CLEAR_KEY) {
+ r = get_clear_key(cd, next_vmk, &vmk_dec_key);
+ if (r) {
+ /* something wrong happened, but we still want to check other key slots */
+ next_vmk = next_vmk->next;
+ continue;
+ }
+ is_decrypted = true;
+ open_vmk_key = vmk_dec_key;
+ log_dbg(cd, "Extracted VMK using clearkey.\n");
} else {
- /* only passphrase, recovery passphrase and startup key VMKs supported right now */
+ /* only passphrase, recovery passphrase, startup key and clearkey VMKs supported right now */
log_dbg(cd, "Skipping %s", get_vmk_protection_string(next_vmk->protection));
next_vmk = next_vmk->next;
if (r == 0)
@@ -1308,19 +1354,22 @@ int BITLK_get_volume_key(struct crypt_device *cd,
continue;
}
- log_dbg(cd, "Trying to decrypt %s.", get_vmk_protection_string(next_vmk->protection));
- r = decrypt_key(cd, &open_vmk_key, next_vmk->vk, vmk_dec_key,
- next_vmk->mac_tag, BITLK_VMK_MAC_TAG_SIZE,
- next_vmk->nonce, BITLK_NONCE_SIZE, false);
+ if (!is_decrypted) {
+ r = decrypt_key(cd, &open_vmk_key, next_vmk->vk, vmk_dec_key,
+ next_vmk->mac_tag, BITLK_VMK_MAC_TAG_SIZE,
+ next_vmk->nonce, BITLK_NONCE_SIZE, false);
+
+ crypt_free_volume_key(vmk_dec_key);
+ is_decrypted = true;
+ }
if (r < 0) {
log_dbg(cd, "Failed to decrypt VMK using provided passphrase.");
- crypt_free_volume_key(vmk_dec_key);
+
if (r == -ENOTSUP)
return r;
next_vmk = next_vmk->next;
continue;
}
- crypt_free_volume_key(vmk_dec_key);
log_dbg(cd, "Trying to decrypt validation metadata using VMK.");
r = crypt_bitlk_decrypt_key(crypt_volume_key_get_key(open_vmk_key),
@@ -1379,8 +1428,6 @@ int BITLK_get_volume_key(struct crypt_device *cd,
static int _activate_check(struct crypt_device *cd,
const struct bitlk_metadata *params)
{
- const struct bitlk_vmk *next_vmk = NULL;
-
if (!params->state) {
log_err(cd, _("This BITLK device is in an unsupported state and cannot be activated."));
return -ENOTSUP;
@@ -1391,15 +1438,6 @@ static int _activate_check(struct crypt_device *cd,
return -ENOTSUP;
}
- next_vmk = params->vmks;
- while (next_vmk) {
- if (next_vmk->protection == BITLK_PROTECTION_CLEAR_KEY) {
- log_err(cd, _("Activation of BITLK device with clear key protection is not supported."));
- return -ENOTSUP;
- }
- next_vmk = next_vmk->next;
- }
-
return 0;
}
@@ -1589,11 +1627,5 @@ int BITLK_activate_by_volume_key(struct crypt_device *cd,
const struct bitlk_metadata *params,
uint32_t flags)
{
- int r;
-
- r = _activate_check(cd, params);
- if (r)
- return r;
-
return _activate(cd, name, vk, params, flags);
}
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 2/2] bitlocker: Add clearkey option
2025-10-04 0:35 [PATCH 0/2] Bitlocker: Support clearkey Kfir Kahanov
2025-10-04 0:35 ` [PATCH 1/2] bitlocker: " Kfir Kahanov
@ 2025-10-04 0:35 ` Kfir Kahanov
2025-10-04 18:17 ` [PATCH 0/2] Bitlocker: Support clearkey Milan Broz
2 siblings, 0 replies; 6+ messages in thread
From: Kfir Kahanov @ 2025-10-04 0:35 UTC (permalink / raw)
To: cryptsetup; +Cc: Kfir Kahanov
In order to bypass getting the password.
---
lib/keyslot_context.c | 97 +++++++++++++++++++++++++++++++++++++++
lib/keyslot_context.h | 2 +
lib/libcryptsetup.h | 24 ++++++++++
lib/libcryptsetup.sym | 1 +
lib/setup.c | 24 +++++++++-
src/cryptsetup.c | 20 +++++---
src/cryptsetup_arg_list.h | 2 +
src/cryptsetup_args.h | 1 +
src/utils_arg_names.h | 1 +
9 files changed, 165 insertions(+), 7 deletions(-)
diff --git a/lib/keyslot_context.c b/lib/keyslot_context.c
index 1b137823..a6df53fb 100644
--- a/lib/keyslot_context.c
+++ b/lib/keyslot_context.c
@@ -304,6 +304,68 @@ static int get_fvault2_volume_key_by_key(struct crypt_device *cd,
return get_key_by_key(cd, kc, -2 /* unused */, -2 /* unused */, r_vk);
}
+/* Clearkey-specific functions */
+static int get_luks1_volume_key_by_clearkey(struct crypt_device *cd __attribute__((unused)),
+ struct crypt_keyslot_context *kc __attribute__((unused)),
+ int keyslot __attribute__((unused)),
+ struct volume_key **r_vk __attribute__((unused)))
+{
+ /* LUKS1 does not support clearkey protection */
+ return -ENOTSUP;
+}
+
+static int get_luks2_volume_key_by_clearkey(struct crypt_device *cd __attribute__((unused)),
+ struct crypt_keyslot_context *kc __attribute__((unused)),
+ int keyslot __attribute__((unused)),
+ struct volume_key **r_vk __attribute__((unused)))
+{
+ /* LUKS2 does not support clearkey protection */
+ return -ENOTSUP;
+}
+
+static int get_plain_volume_key_by_clearkey(struct crypt_device *cd __attribute__((unused)),
+ struct crypt_keyslot_context *kc __attribute__((unused)),
+ struct volume_key **r_vk __attribute__((unused)))
+{
+ /* Plain does not support clearkey protection */
+ return -ENOTSUP;
+}
+
+static int get_bitlk_volume_key_by_clearkey(struct crypt_device *cd,
+ struct crypt_keyslot_context *kc __attribute__((unused)),
+ const struct bitlk_metadata *params,
+ struct volume_key **r_vk)
+{
+ /* For BitLocker clearkey, call BITLK_get_volume_key without passphrase */
+ return BITLK_get_volume_key(cd, NULL, 0, params, r_vk);
+}
+
+static int get_fvault2_volume_key_by_clearkey(struct crypt_device *cd __attribute__((unused)),
+ struct crypt_keyslot_context *kc __attribute__((unused)),
+ const struct fvault2_params *params __attribute__((unused)),
+ struct volume_key **r_vk __attribute__((unused)))
+{
+ /* FVAULT2 does not support clearkey protection */
+ return -ENOTSUP;
+}
+
+static int get_verity_volume_key_by_clearkey(struct crypt_device *cd __attribute__((unused)),
+ struct crypt_keyslot_context *kc __attribute__((unused)),
+ struct volume_key **r_vk __attribute__((unused)),
+ struct volume_key **r_signature __attribute__((unused)))
+{
+ /* Verity does not support clearkey protection */
+ return -ENOTSUP;
+}
+
+static int get_integrity_volume_key_by_clearkey(struct crypt_device *cd __attribute__((unused)),
+ struct crypt_keyslot_context *kc __attribute__((unused)),
+ struct volume_key **r_vk __attribute__((unused)))
+{
+ /* Integrity does not support clearkey protection */
+ return -ENOTSUP;
+}
+
static int get_generic_signed_key_by_key(struct crypt_device *cd,
struct crypt_keyslot_context *kc,
struct volume_key **r_vk,
@@ -629,6 +691,26 @@ void crypt_keyslot_context_init_by_key_internal(struct crypt_keyslot_context *kc
crypt_keyslot_context_init_common(kc);
}
+void crypt_keyslot_context_init_by_clearkey_internal(struct crypt_keyslot_context *kc)
+{
+ assert(kc);
+
+ kc->type = CRYPT_KC_TYPE_KEY;
+
+ kc->get_luks1_volume_key = get_luks1_volume_key_by_clearkey;
+ kc->get_luks2_volume_key = get_luks2_volume_key_by_clearkey;
+ kc->get_plain_volume_key = get_plain_volume_key_by_clearkey;
+ kc->get_bitlk_volume_key = get_bitlk_volume_key_by_clearkey;
+ kc->get_fvault2_volume_key = get_fvault2_volume_key_by_clearkey;
+ kc->get_verity_volume_key = get_verity_volume_key_by_clearkey;
+ kc->get_integrity_volume_key = get_integrity_volume_key_by_clearkey;
+
+ kc->get_key_size = key_get_key_size;
+ kc->context_free = key_context_free;
+ crypt_keyslot_context_init_common(kc);
+}
+
+
static void signed_key_context_free(struct crypt_keyslot_context *kc)
{
assert(kc && kc->type == CRYPT_KC_TYPE_SIGNED_KEY);
@@ -1196,6 +1278,21 @@ CRYPT_SYMBOL_EXPORT_OLD(int, crypt_keyslot_context_init_by_vk_in_keyring, 2, 7,
return _crypt_keyslot_context_init_by_vk_in_keyring(key_description, kc, false);
}
+CRYPT_SYMBOL_EXPORT_NEW(int, crypt_keyslot_context_init_by_clearkey, 2, 8, struct crypt_device *cd,
+ struct crypt_keyslot_context **kc)
+{
+ if (!kc)
+ return -EINVAL;
+
+ *kc = crypt_zalloc(sizeof(**kc));
+ if (!*kc)
+ return -ENOMEM;
+
+ crypt_keyslot_context_init_by_clearkey_internal(*kc);
+
+ return 0;
+}
+
int crypt_keyslot_context_get_error(struct crypt_keyslot_context *kc)
{
return kc ? kc->error : -EINVAL;
diff --git a/lib/keyslot_context.h b/lib/keyslot_context.h
index a2e42b20..f373bf8d 100644
--- a/lib/keyslot_context.h
+++ b/lib/keyslot_context.h
@@ -175,6 +175,8 @@ void crypt_keyslot_context_init_by_token_internal(struct crypt_keyslot_context *
void crypt_keyslot_context_init_by_keyring_internal(struct crypt_keyslot_context *kc,
const char *key_description);
+void crypt_keyslot_context_init_by_clearkey_internal(struct crypt_keyslot_context *kc);
+
const char *keyslot_context_type_string(const struct crypt_keyslot_context *kc);
#endif /* KEYSLOT_CONTEXT_H */
diff --git a/lib/libcryptsetup.h b/lib/libcryptsetup.h
index 77eb29ef..07b18f70 100644
--- a/lib/libcryptsetup.h
+++ b/lib/libcryptsetup.h
@@ -1352,6 +1352,17 @@ int crypt_keyslot_context_init_by_vk_in_keyring(struct crypt_device *cd,
const char *key_description,
struct crypt_keyslot_context **kc);
+/**
+ * Initialize keyslot context for clear key.
+ *
+ * @param cd crypt device handle initialized to LUKS device context
+ * @param kc returns crypt keyslot context handle type CRYPT_KC_TYPE_KEY
+ *
+ * @return zero on success or negative errno otherwise.
+ */
+int crypt_keyslot_context_init_by_clearkey(struct crypt_device *cd,
+ struct crypt_keyslot_context **kc);
+
/**
* Get error code per keyslot context from last failed call.
*
@@ -1823,6 +1834,19 @@ int crypt_activate_by_keyring(struct crypt_device *cd,
int keyslot,
uint32_t flags);
+/**
+ * Activate BITLK device using clearkey.
+ *
+ * @param cd crypt device handle
+ * @param name name of device to create
+ * @param flags activation flags
+ *
+ * @return @e 0 on success or negative errno value otherwise.
+ */
+int crypt_activate_by_clearkey(struct crypt_device *cd,
+ const char *name,
+ uint32_t flags);
+
/** lazy deactivation - remove once last user releases it */
#define CRYPT_DEACTIVATE_DEFERRED (UINT32_C(1) << 0)
/** force deactivation - if the device is busy, it is replaced by error device */
diff --git a/lib/libcryptsetup.sym b/lib/libcryptsetup.sym
index 3a54431a..f6463af2 100644
--- a/lib/libcryptsetup.sym
+++ b/lib/libcryptsetup.sym
@@ -61,6 +61,7 @@ CRYPTSETUP_2.0 {
crypt_activate_by_volume_key;
crypt_activate_by_signed_key;
crypt_activate_by_keyring;
+ crypt_activate_by_clearkey;
crypt_deactivate;
crypt_deactivate_by_name;
crypt_volume_key_get;
diff --git a/lib/setup.c b/lib/setup.c
index 37e6f7d9..1be05cfe 100644
--- a/lib/setup.c
+++ b/lib/setup.c
@@ -5707,6 +5707,20 @@ int crypt_activate_by_signed_key(struct crypt_device *cd,
return r;
}
+int crypt_activate_by_clearkey(struct crypt_device *cd,
+ const char *name,
+ uint32_t flags)
+{
+ int r;
+ struct crypt_keyslot_context kc = {};
+
+ crypt_keyslot_context_init_by_clearkey_internal(&kc);
+ r = crypt_activate_by_keyslot_context(cd, name, CRYPT_ANY_SLOT /* unused */, &kc, CRYPT_ANY_SLOT, &kc, flags);
+ crypt_keyslot_context_destroy_internal(&kc);
+
+ return r;
+}
+
int crypt_deactivate_by_name(struct crypt_device *cd, const char *name, uint32_t flags)
{
struct crypt_device *fake_cd = NULL;
@@ -5917,7 +5931,7 @@ int crypt_volume_key_get_by_keyslot_context(struct crypt_device *cd,
struct volume_key *vk = NULL;
if (!cd || !volume_key || !volume_key_size ||
- (!kc && !isLUKS(cd->type) && !isTCRYPT(cd->type) && !isVERITY(cd->type)))
+ (!kc && !isLUKS(cd->type) && !isTCRYPT(cd->type) && !isVERITY(cd->type) && !isBITLK(cd->type)))
return -EINVAL;
if (isLUKS2(cd->type) && keyslot != CRYPT_ANY_SLOT)
@@ -5977,6 +5991,14 @@ int crypt_volume_key_get_by_keyslot_context(struct crypt_device *cd,
} else if (isBITLK(cd->type)) {
if (kc && kc->get_bitlk_volume_key)
r = kc->get_bitlk_volume_key(cd, kc, &cd->u.bitlk.params, &vk);
+ else if (!kc) {
+ struct crypt_keyslot_context *kc_clearkey = NULL;
+ r = crypt_keyslot_context_init_by_clearkey(cd, &kc_clearkey);
+ if (r >= 0) {
+ r = kc_clearkey->get_bitlk_volume_key(cd, kc_clearkey, &cd->u.bitlk.params, &vk);
+ }
+ crypt_keyslot_context_free(kc_clearkey);
+ }
if (r < 0)
log_err(cd, _("Cannot retrieve volume key for BITLK device."));
} else if (isFVAULT2(cd->type)) {
diff --git a/src/cryptsetup.c b/src/cryptsetup.c
index bd2ee780..134162c6 100644
--- a/src/cryptsetup.c
+++ b/src/cryptsetup.c
@@ -508,6 +508,11 @@ static int action_open_bitlk(void)
goto out;
r = crypt_activate_by_volume_key(cd, activated_name,
key, keysize, activate_flags);
+ } else if (ARG_SET(OPT_CLEARKEY_ID)) {
+ /* For clearkey, we don't need a passphrase - pass NULL to activate_by_passphrase */
+ r = crypt_activate_by_clearkey(cd, activated_name, activate_flags);
+ if (r < 0)
+ log_err(_("No clearkey protection found on BITLK device."));
} else {
tries = set_tries_tty(false);
do {
@@ -617,14 +622,17 @@ static int bitlkDump_with_volume_key(struct crypt_device *cd)
if (!vk)
return -ENOMEM;
- r = tools_get_key(NULL, &password, &passwordLen,
- ARG_UINT64(OPT_KEYFILE_OFFSET_ID), ARG_UINT32(OPT_KEYFILE_SIZE_ID), ARG_STR(OPT_KEY_FILE_ID),
- ARG_UINT32(OPT_TIMEOUT_ID), 0, 0, cd);
- if (r < 0)
- goto out;
+ if (!ARG_SET(OPT_CLEARKEY_ID)) {
+ r = tools_get_key(NULL, &password, &passwordLen,
+ ARG_UINT64(OPT_KEYFILE_OFFSET_ID), ARG_UINT32(OPT_KEYFILE_SIZE_ID), ARG_STR(OPT_KEY_FILE_ID),
+ ARG_UINT32(OPT_TIMEOUT_ID), 0, 0, cd);
+ if (r < 0)
+ goto out;
+ }
r = crypt_volume_key_get(cd, CRYPT_ANY_SLOT, vk, &vk_size,
- password, passwordLen);
+ password, passwordLen);
+
tools_passphrase_msg(r);
check_signal(&r);
if (r < 0)
diff --git a/src/cryptsetup_arg_list.h b/src/cryptsetup_arg_list.h
index 26652dd8..95b2c991 100644
--- a/src/cryptsetup_arg_list.h
+++ b/src/cryptsetup_arg_list.h
@@ -241,6 +241,8 @@ ARG(OPT_USE_DIRECTIO, '\0', POPT_ARG_NONE, N_("Use direct-io when accessing devi
ARG(OPT_USE_FSYNC, '\0', POPT_ARG_NONE, N_("Use fsync after each block"), NULL, CRYPT_ARG_BOOL, {}, {})
ARG(OPT_WRITE_LOG, '\0', POPT_ARG_NONE, N_("Update log file after every block"), NULL, CRYPT_ARG_BOOL, {}, {})
+
+ARG(OPT_CLEARKEY, '\0', POPT_ARG_NONE, N_("Open BITLK device using only clearkey protection"), NULL, CRYPT_ARG_BOOL, {}, {})
/* aliases */
diff --git a/src/cryptsetup_args.h b/src/cryptsetup_args.h
index 43926f99..3ef58b61 100644
--- a/src/cryptsetup_args.h
+++ b/src/cryptsetup_args.h
@@ -43,6 +43,7 @@
/* 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_CLEARKEY_ACTIONS { OPEN_ACTION, BITLKDUMP_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 }
diff --git a/src/utils_arg_names.h b/src/utils_arg_names.h
index a01419d3..f50c26dc 100644
--- a/src/utils_arg_names.h
+++ b/src/utils_arg_names.h
@@ -20,6 +20,7 @@
#define OPT_CANCEL_DEFERRED "cancel-deferred"
#define OPT_CHECK_AT_MOST_ONCE "check-at-most-once"
#define OPT_CIPHER "cipher"
+#define OPT_CLEARKEY "clearkey"
#define OPT_DATA_BLOCK_SIZE "data-block-size"
#define OPT_DATA_BLOCKS "data-blocks"
#define OPT_DATA_DEVICE "data-device"
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread