* [PATCH 0/2] Bitlocker: Support clearkey
@ 2025-10-04 0:35 Kfir Kahanov
2025-10-04 0:35 ` [PATCH 1/2] bitlocker: " Kfir Kahanov
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Kfir Kahanov @ 2025-10-04 0:35 UTC (permalink / raw)
To: cryptsetup; +Cc: Kfir Kahanov
This code enable support for clearkey bitlocker protection.
Closes: #962
Kfir Kahanov (2):
bitlocker: Support clearkey
bitlocker: Add clearkey option
lib/bitlk/bitlk.c | 106 +++++++++++++++++++++++++-------------
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 +
10 files changed, 234 insertions(+), 44 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [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
* Re: [PATCH 0/2] Bitlocker: Support clearkey
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 ` [PATCH 2/2] bitlocker: Add clearkey option Kfir Kahanov
@ 2025-10-04 18:17 ` Milan Broz
2025-10-04 19:28 ` Kfir Ka
2 siblings, 1 reply; 6+ messages in thread
From: Milan Broz @ 2025-10-04 18:17 UTC (permalink / raw)
To: Kfir Kahanov, cryptsetup; +Cc: Vojtech Trefny
On 10/4/25 2:35 AM, Kfir Kahanov wrote:
> This code enable support for clearkey bitlocker protection.
> Closes: #962
Hi,
as this is not trivial feature, please submit it through
merge request through GitLab project page.
You already have issue there, so it should not be a problem.
This way it can go through CI and all discussion and changes
will be there. Also it need to include some tests.
For the patch - we planned support for Bitlocker clearkey,
so it is definitely something that I would lite to merge.
However, I do not understand why you need to touch API
and other formats. The whole implementation should be embedded
in BITLK format support only.
IMO if Bitlocker header contains CLEARKEY, it should be used
directly. I know it will be a little bit tricky to support
it through existing calls, but I definitely do not want new activation
API call and commandline option for it.
Anyway, this discussion should happen on Gitlab, we can
discuss there possible options for integration.
Thanks!
Milan
>
>
> Kfir Kahanov (2):
> bitlocker: Support clearkey
> bitlocker: Add clearkey option
>
> lib/bitlk/bitlk.c | 106 +++++++++++++++++++++++++-------------
> 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 +
> 10 files changed, 234 insertions(+), 44 deletions(-)
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 0/2] Bitlocker: Support clearkey
2025-10-04 18:17 ` [PATCH 0/2] Bitlocker: Support clearkey Milan Broz
@ 2025-10-04 19:28 ` Kfir Ka
2025-10-04 19:46 ` Milan Broz
0 siblings, 1 reply; 6+ messages in thread
From: Kfir Ka @ 2025-10-04 19:28 UTC (permalink / raw)
To: Milan Broz; +Cc: cryptsetup, Vojtech Trefny
I would like to create a Merge request but unfortunately I do not have
the permissions to do so.
It seems that you will need to add me as a developer in the gitlab project.
בתאריך שבת, 4 באוק׳ 2025 ב-21:17 מאת Milan Broz <gmazyland@gmail.com>:
>
> On 10/4/25 2:35 AM, Kfir Kahanov wrote:
> > This code enable support for clearkey bitlocker protection.
> > Closes: #962
>
> Hi,
>
> as this is not trivial feature, please submit it through
> merge request through GitLab project page.
> You already have issue there, so it should not be a problem.
>
> This way it can go through CI and all discussion and changes
> will be there. Also it need to include some tests.
>
> For the patch - we planned support for Bitlocker clearkey,
> so it is definitely something that I would lite to merge.
>
> However, I do not understand why you need to touch API
> and other formats. The whole implementation should be embedded
> in BITLK format support only.
> IMO if Bitlocker header contains CLEARKEY, it should be used
> directly. I know it will be a little bit tricky to support
> it through existing calls, but I definitely do not want new activation
> API call and commandline option for it.
>
> Anyway, this discussion should happen on Gitlab, we can
> discuss there possible options for integration.
>
> Thanks!
> Milan
>
>
> >
> >
> > Kfir Kahanov (2):
> > bitlocker: Support clearkey
> > bitlocker: Add clearkey option
> >
> > lib/bitlk/bitlk.c | 106 +++++++++++++++++++++++++-------------
> > 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 +
> > 10 files changed, 234 insertions(+), 44 deletions(-)
> >
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 0/2] Bitlocker: Support clearkey
2025-10-04 19:28 ` Kfir Ka
@ 2025-10-04 19:46 ` Milan Broz
0 siblings, 0 replies; 6+ messages in thread
From: Milan Broz @ 2025-10-04 19:46 UTC (permalink / raw)
To: Kfir Ka; +Cc: cryptsetup, Vojtech Trefny
On 10/4/25 9:28 PM, Kfir Ka wrote:
> I would like to create a Merge request but unfortunately I do not have
> the permissions to do so.
> It seems that you will need to add me as a developer in the gitlab project.
No, you can definitely create MR from your git tree and branch.
Please do so and if there is any problem, send me a mail.
Milan
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2025-10-04 19:46 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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 ` [PATCH 2/2] bitlocker: Add clearkey option Kfir Kahanov
2025-10-04 18:17 ` [PATCH 0/2] Bitlocker: Support clearkey Milan Broz
2025-10-04 19:28 ` Kfir Ka
2025-10-04 19:46 ` Milan Broz
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox