mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-05 16:00:05 +01:00
bitlk: Fix support for startup key with new metadata entry
Windows 11 now includes the BitLocker volume GUID in the BEK file metadata entries. This was previously not included so cryptsetup refused to open the file because there was an unknown metadata entry in the startup key. Fixes: #690
This commit is contained in:
@@ -869,13 +869,20 @@ static int get_recovery_key(struct crypt_device *cd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_external_key_entry(struct crypt_device *cd, const char *data, int start, int end, struct volume_key **vk)
|
||||
static int parse_external_key_entry(struct crypt_device *cd,
|
||||
const char *data,
|
||||
int start,
|
||||
int end,
|
||||
struct volume_key **vk,
|
||||
const struct bitlk_metadata *params)
|
||||
{
|
||||
uint16_t key_entry_size = 0;
|
||||
uint16_t key_entry_type = 0;
|
||||
uint16_t key_entry_value = 0;
|
||||
size_t key_size = 0;
|
||||
const char *key = NULL;
|
||||
struct bitlk_guid guid;
|
||||
char guid_buf[UUID_STR_LEN] = {0};
|
||||
|
||||
while (end - start > 2) {
|
||||
/* size of this entry */
|
||||
@@ -892,8 +899,7 @@ static int parse_external_key_entry(struct crypt_device *cd, const char *data, i
|
||||
key_entry_type = le16_to_cpu(key_entry_type);
|
||||
key_entry_value = le16_to_cpu(key_entry_value);
|
||||
|
||||
/* only properties should be in this entry */
|
||||
if (key_entry_type != BITLK_ENTRY_TYPE_PROPERTY) {
|
||||
if (key_entry_type != BITLK_ENTRY_TYPE_PROPERTY && key_entry_type != BITLK_ENTRY_TYPE_VOLUME_GUID) {
|
||||
log_err(cd, _("Unexpected metadata entry type '%u' found when parsing external key."), key_entry_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -908,7 +914,15 @@ static int parse_external_key_entry(struct crypt_device *cd, const char *data, i
|
||||
/* optional "ExternalKey" string, we can safely ignore it */
|
||||
} else if (key_entry_value == BITLK_ENTRY_VALUE_STRING)
|
||||
;
|
||||
else {
|
||||
/* GUID of the BitLocker device we are trying to open with this key */
|
||||
else if (key_entry_value == BITLK_ENTRY_VALUE_GUID) {
|
||||
memcpy(&guid, data + start + BITLK_ENTRY_HEADER_LEN, sizeof(struct bitlk_guid));
|
||||
guid_to_string(&guid, guid_buf);
|
||||
if (strcmp(guid_buf, params->guid) != 0) {
|
||||
log_err(cd, _("BEK file GUID '%s' does not match GUID of the volume."), guid_buf);
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
log_err(cd, _("Unexpected metadata entry value '%u' found when parsing external key."), key_entry_value);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -925,7 +939,8 @@ static int get_startup_key(struct crypt_device *cd,
|
||||
const char *password,
|
||||
size_t passwordLen,
|
||||
const struct bitlk_vmk *vmk,
|
||||
struct volume_key **su_key)
|
||||
struct volume_key **su_key,
|
||||
const struct bitlk_metadata *params)
|
||||
{
|
||||
struct bitlk_bek_header bek_header = {0};
|
||||
char guid_buf[UUID_STR_LEN] = {0};
|
||||
@@ -975,7 +990,7 @@ static int get_startup_key(struct crypt_device *cd,
|
||||
if (key_entry_type == BITLK_ENTRY_TYPE_STARTUP_KEY && key_entry_value == BITLK_ENTRY_VALUE_EXTERNAL_KEY) {
|
||||
return parse_external_key_entry(cd, password,
|
||||
BITLK_BEK_FILE_HEADER_LEN + BITLK_ENTRY_HEADER_LEN + BITLK_STARTUP_KEY_HEADER_LEN,
|
||||
passwordLen, su_key);
|
||||
passwordLen, su_key, params);
|
||||
} else {
|
||||
log_err(cd, _("Unexpected metadata entry found when parsing startup key."));
|
||||
log_dbg(cd, "Entry type: %u, entry value: %u", key_entry_type, key_entry_value);
|
||||
@@ -1142,7 +1157,7 @@ int BITLK_get_volume_key(struct crypt_device *cd,
|
||||
if (r)
|
||||
return r;
|
||||
} else if (next_vmk->protection == BITLK_PROTECTION_STARTUP_KEY) {
|
||||
r = get_startup_key(cd, password, passwordLen, next_vmk, &vmk_dec_key);
|
||||
r = get_startup_key(cd, password, passwordLen, next_vmk, &vmk_dec_key, params);
|
||||
if (r) {
|
||||
next_vmk = next_vmk->next;
|
||||
continue;
|
||||
|
||||
@@ -61,6 +61,7 @@ typedef enum {
|
||||
BITLK_ENTRY_TYPE_STARTUP_KEY = 0x0006,
|
||||
BITLK_ENTRY_TYPE_DESCRIPTION = 0x0007,
|
||||
BITLK_ENTRY_TYPE_VOLUME_HEADER = 0x000f,
|
||||
BITLK_ENTRY_TYPE_VOLUME_GUID = 0x0019,
|
||||
} BITLKFVEEntryType;
|
||||
|
||||
typedef enum {
|
||||
@@ -76,6 +77,7 @@ typedef enum {
|
||||
BITLK_ENTRY_VALUE_EXTERNAL_KEY = 0x0009,
|
||||
BITLK_ENTRY_VALUE_OFFSET_SIZE = 0x000f,
|
||||
BITLK_ENTRY_VALUE_RECOVERY_TIME = 0x015,
|
||||
BITLK_ENTRY_VALUE_GUID = 0x0017,
|
||||
} BITLKFVEEntryValue;
|
||||
|
||||
struct bitlk_vmk {
|
||||
|
||||
Reference in New Issue
Block a user