diff --git a/lib/bitlk/bitlk.c b/lib/bitlk/bitlk.c index 181a90d7..965c7692 100644 --- a/lib/bitlk/bitlk.c +++ b/lib/bitlk/bitlk.c @@ -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; diff --git a/lib/bitlk/bitlk.h b/lib/bitlk/bitlk.h index 57ba92e3..ccf99a72 100644 --- a/lib/bitlk/bitlk.h +++ b/lib/bitlk/bitlk.h @@ -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 { diff --git a/tests/bitlk-images.tar.xz b/tests/bitlk-images.tar.xz index eea33ed2..845e9de3 100644 Binary files a/tests/bitlk-images.tar.xz and b/tests/bitlk-images.tar.xz differ