2 * BITLK (BitLocker-compatible) volume handling
4 * Copyright (C) 2019-2023 Red Hat, Inc. All rights reserved.
5 * Copyright (C) 2019-2023 Milan Broz
6 * Copyright (C) 2019-2023 Vojtech Trefny
8 * This file is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This file is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this file; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 #include <uuid/uuid.h>
32 #define BITLK_BOOTCODE_V1 "\xeb\x52\x90"
33 #define BITLK_BOOTCODE_V2 "\xeb\x58\x90"
34 #define BITLK_SIGNATURE "-FVE-FS-"
35 #define BITLK_SIGNATURE_TOGO "MSWIN4.1"
36 #define BITLK_HEADER_METADATA_OFFSET 160
37 #define BITLK_HEADER_METADATA_OFFSET_TOGO 424
39 /* FVE metadata header is split into two parts */
40 #define BITLK_FVE_METADATA_BLOCK_HEADER_LEN 64
41 #define BITLK_FVE_METADATA_HEADER_LEN 48
42 #define BITLK_FVE_METADATA_HEADERS_LEN BITLK_FVE_METADATA_BLOCK_HEADER_LEN + BITLK_FVE_METADATA_HEADER_LEN
44 /* total size of the FVE area (64 KiB) */
45 #define BITLK_FVE_METADATA_SIZE 64 * 1024
47 #define BITLK_ENTRY_HEADER_LEN 8
48 #define BITLK_VMK_HEADER_LEN 28
50 #define BITLK_OPEN_KEY_METADATA_LEN 12
52 #define BITLK_RECOVERY_KEY_LEN 55
53 #define BITLK_RECOVERY_PARTS 8
54 #define BITLK_RECOVERY_PART_LEN 6
56 #define BITLK_BEK_FILE_HEADER_LEN 48
57 #define BITLK_STARTUP_KEY_HEADER_LEN 24
59 #define BITLK_KDF_HASH "sha256"
60 #define BITLK_KDF_ITERATION_COUNT 0x100000
62 /* maximum number of segments for the DM device */
63 #define MAX_BITLK_SEGMENTS 10
65 /* January 1, 1970 as MS file time */
66 #define EPOCH_AS_FILETIME 116444736000000000
67 #define HUNDREDS_OF_NANOSECONDS 10000000
69 /* not available in older version of libuuid */
71 #define UUID_STR_LEN 37
74 /* known types of GUIDs from the BITLK superblock */
75 const uint8_t BITLK_GUID_NORMAL[16] = { 0x3b, 0xd6, 0x67, 0x49, 0x29, 0x2e, 0xd8, 0x4a,
76 0x83, 0x99, 0xf6, 0xa3, 0x39, 0xe3, 0xd0, 0x01 };
77 const uint8_t BITLK_GUID_EOW[16] = { 0x3b, 0x4d, 0xa8, 0x92, 0x80, 0xdd, 0x0e, 0x4d,
78 0x9e, 0x4e, 0xb1, 0xe3, 0x28, 0x4e, 0xae, 0xd8 };
80 /* taken from libfdisk gpt.c -- TODO: this is a good candidate for adding to libuuid */
84 uint16_t time_hi_and_version;
86 uint8_t clock_seq_low;
88 } __attribute__ ((packed));
90 static void swap_guid(struct bitlk_guid *guid) {
91 guid->time_low = swab32(guid->time_low);
92 guid->time_mid = swab16(guid->time_mid);
93 guid->time_hi_and_version = swab16(guid->time_hi_and_version);
96 static void guid_to_string(struct bitlk_guid *guid, char *out) {
98 uuid_unparse((unsigned char *) guid, out);
110 BitlkSegmentType type;
113 struct bitlk_signature {
114 uint8_t boot_code[3];
115 uint8_t signature[8];
116 uint16_t sector_size;
117 } __attribute__ ((packed));
119 struct bitlk_superblock {
120 struct bitlk_guid guid;
121 uint64_t fve_offset[3];
122 } __attribute__ ((packed));
124 struct bitlk_fve_metadata {
125 /* FVE metadata block header */
126 uint8_t signature[8];
128 uint16_t fve_version;
131 uint64_t volume_size;
133 uint32_t volume_header_size;
134 uint64_t fve_offset[3];
135 uint64_t volume_header_offset;
136 /* FVE metadata header */
137 uint32_t metadata_size;
138 uint32_t metadata_version;
139 uint32_t metadata_header_size;
140 uint32_t metada_size_copy;
141 struct bitlk_guid guid;
145 uint64_t creation_time;
146 } __attribute__ ((packed));
148 struct bitlk_entry_header_block {
151 } __attribute__ ((packed));
153 struct bitlk_entry_vmk {
154 struct bitlk_guid guid;
158 } __attribute__ ((packed));
160 struct bitlk_kdf_data {
161 char last_sha256[32];
162 char initial_sha256[32];
167 struct bitlk_bek_header {
168 uint32_t metadata_size;
169 uint32_t metadata_version;
170 uint32_t metadata_header_size;
171 uint32_t metada_size_copy;
172 struct bitlk_guid guid;
176 uint64_t creation_time;
177 } __attribute__ ((packed));
179 static BITLKVMKProtection get_vmk_protection(uint16_t protection)
181 switch (protection) {
183 return BITLK_PROTECTION_CLEAR_KEY;
185 return BITLK_PROTECTION_TPM;
187 return BITLK_PROTECTION_STARTUP_KEY;
189 return BITLK_PROTECTION_TPM_PIN;
191 return BITLK_PROTECTION_RECOVERY_PASSPHRASE;
193 return BITLK_PROTECTION_SMART_CARD;
195 return BITLK_PROTECTION_PASSPHRASE;
197 return BITLK_PROTECTION_UNKNOWN;
201 static const char* get_vmk_protection_string(BITLKVMKProtection protection)
203 switch (protection) {
204 case BITLK_PROTECTION_CLEAR_KEY:
205 return "VMK protected with clear key";
206 case BITLK_PROTECTION_TPM:
207 return "VMK protected with TPM";
208 case BITLK_PROTECTION_STARTUP_KEY:
209 return "VMK protected with startup key";
210 case BITLK_PROTECTION_TPM_PIN:
211 return "VMK protected with TPM and PIN";
212 case BITLK_PROTECTION_PASSPHRASE:
213 return "VMK protected with passphrase";
214 case BITLK_PROTECTION_RECOVERY_PASSPHRASE:
215 return "VMK protected with recovery passphrase";
216 case BITLK_PROTECTION_SMART_CARD:
217 return "VMK protected with smart card";
219 return "VMK with unknown protection";
223 static const char* get_bitlk_type_string(BITLKEncryptionType type)
227 case BITLK_ENCRYPTION_TYPE_NORMAL:
229 case BITLK_ENCRYPTION_TYPE_EOW:
230 return "encrypt-on-write";
236 static uint64_t filetime_to_unixtime(uint64_t time)
238 return (time - EPOCH_AS_FILETIME) / HUNDREDS_OF_NANOSECONDS;
241 static int parse_vmk_entry(struct crypt_device *cd, uint8_t *data, int start, int end, struct bitlk_vmk **vmk)
243 uint16_t key_entry_size = 0;
244 uint16_t key_entry_type = 0;
245 uint16_t key_entry_value = 0;
248 const char *key = NULL;
249 struct volume_key *vk = NULL;
250 bool supported = false;
253 /* only passphrase or recovery passphrase vmks are supported (can be used to activate) */
254 supported = (*vmk)->protection == BITLK_PROTECTION_PASSPHRASE ||
255 (*vmk)->protection == BITLK_PROTECTION_RECOVERY_PASSPHRASE ||
256 (*vmk)->protection == BITLK_PROTECTION_STARTUP_KEY;
258 while ((end - start) >= (ssize_t)(sizeof(key_entry_size) + sizeof(key_entry_type) + sizeof(key_entry_value))) {
259 /* size of this entry */
260 memcpy(&key_entry_size, data + start, sizeof(key_entry_size));
261 key_entry_size = le16_to_cpu(key_entry_size);
262 if (key_entry_size == 0)
265 if (key_entry_size > (end - start))
268 /* type and value of this entry */
269 memcpy(&key_entry_type, data + start + sizeof(key_entry_size), sizeof(key_entry_type));
270 memcpy(&key_entry_value,
271 data + start + sizeof(key_entry_size) + sizeof(key_entry_type),
272 sizeof(key_entry_value));
273 key_entry_type = le16_to_cpu(key_entry_type);
274 key_entry_value = le16_to_cpu(key_entry_value);
276 if (key_entry_type != BITLK_ENTRY_TYPE_PROPERTY) {
278 log_err(cd, _("Unexpected metadata entry type '%u' found when parsing supported Volume Master Key."), key_entry_type);
281 log_dbg(cd, "Unexpected metadata entry type '%u' found when parsing unsupported VMK.", key_entry_type);
285 /* stretch key with salt, skip 4 B (encryption method of the stretch key) */
286 if (key_entry_value == BITLK_ENTRY_VALUE_STRETCH_KEY) {
287 if ((end - start) < (BITLK_ENTRY_HEADER_LEN + BITLK_SALT_SIZE + 4))
290 data + start + BITLK_ENTRY_HEADER_LEN + 4,
292 /* AES-CCM encrypted key */
293 } else if (key_entry_value == BITLK_ENTRY_VALUE_ENCRYPTED_KEY) {
294 if (key_entry_size < (BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE + BITLK_VMK_MAC_TAG_SIZE))
297 memcpy((*vmk)->nonce,
298 data + start + BITLK_ENTRY_HEADER_LEN,
301 memcpy((*vmk)->mac_tag,
302 data + start + BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE,
303 BITLK_VMK_MAC_TAG_SIZE);
304 /* AES-CCM encrypted key */
305 key_size = key_entry_size - (BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE + BITLK_VMK_MAC_TAG_SIZE);
306 key = (const char *) data + start + BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE + BITLK_VMK_MAC_TAG_SIZE;
307 vk = crypt_alloc_volume_key(key_size, key);
310 crypt_volume_key_add_next(&((*vmk)->vk), vk);
311 /* clear key for a partially decrypted volume */
312 } else if (key_entry_value == BITLK_ENTRY_VALUE_KEY) {
313 /* We currently don't want to support opening a partially decrypted
314 * device so we don't need to store this key.
316 * key_size = key_entry_size - (BITLK_ENTRY_HEADER_LEN + 4);
317 * key = (const char *) data + start + BITLK_ENTRY_HEADER_LEN + 4;
318 * vk = crypt_alloc_volume_key(key_size, key);
321 * crypt_volume_key_add_next(&((*vmk)->vk), vk);
323 log_dbg(cd, "Skipping clear key metadata entry.");
324 /* unknown timestamps in recovery protected VMK */
325 } else if (key_entry_value == BITLK_ENTRY_VALUE_RECOVERY_TIME) {
327 } else if (key_entry_value == BITLK_ENTRY_VALUE_STRING) {
328 if (key_entry_size < BITLK_ENTRY_HEADER_LEN)
330 string = malloc((key_entry_size - BITLK_ENTRY_HEADER_LEN) * 2 + 1);
333 r = crypt_utf16_to_utf8(&string, CONST_CAST(char16_t *)(data + start + BITLK_ENTRY_HEADER_LEN),
334 key_entry_size - BITLK_ENTRY_HEADER_LEN);
335 if (r < 0 || !string) {
337 log_err(cd, _("Invalid string found when parsing Volume Master Key."));
339 } else if ((*vmk)->name != NULL) {
341 log_err(cd, _("Unexpected string ('%s') found when parsing supported Volume Master Key."), string);
345 log_dbg(cd, "Unexpected string ('%s') found when parsing unsupported VMK.", string);
349 /* Assume that strings in VMK are the name of the VMK */
350 (*vmk)->name = string;
353 /* no idea what this is, lets hope it's not important */
354 } else if (key_entry_value == BITLK_ENTRY_VALUE_USE_KEY && (*vmk)->protection == BITLK_PROTECTION_STARTUP_KEY) {
358 log_err(cd, _("Unexpected metadata entry value '%u' found when parsing supported Volume Master Key."), key_entry_value);
361 log_dbg(cd, "Unexpected metadata entry value '%u' found when parsing unsupported VMK.", key_entry_value);
365 start += key_entry_size;
371 void BITLK_bitlk_fvek_free(struct bitlk_fvek *fvek)
376 crypt_free_volume_key(fvek->vk);
380 void BITLK_bitlk_vmk_free(struct bitlk_vmk *vmk)
382 struct bitlk_vmk *vmk_next = NULL;
389 crypt_free_volume_key(vmk->vk);
390 vmk_next = vmk->next;
396 void BITLK_bitlk_metadata_free(struct bitlk_metadata *metadata)
401 free(metadata->guid);
402 if (metadata->description)
403 free(metadata->description);
404 BITLK_bitlk_vmk_free(metadata->vmks);
405 BITLK_bitlk_fvek_free(metadata->fvek);
408 int BITLK_read_sb(struct crypt_device *cd, struct bitlk_metadata *params)
411 struct device *device = crypt_metadata_device(cd);
412 struct bitlk_signature sig = {};
413 struct bitlk_superblock sb = {};
414 struct bitlk_fve_metadata fve = {};
415 struct bitlk_entry_vmk entry_vmk = {};
416 uint8_t *fve_entries = NULL;
417 size_t fve_entries_size = 0;
418 uint32_t fve_metadata_size = 0;
420 char guid_buf[UUID_STR_LEN] = {0};
421 uint16_t entry_size = 0;
422 uint16_t entry_type = 0;
427 const char *key = NULL;
428 char *description = NULL;
430 struct bitlk_vmk *vmk = NULL;
431 struct bitlk_vmk *vmk_p = params->vmks;
433 devfd = device_open(cd, crypt_data_device(cd), O_RDONLY);
439 /* read and check the signature */
440 if (read_lseek_blockwise(devfd, device_block_size(cd, device),
441 device_alignment(device), &sig, sizeof(sig), 0) != sizeof(sig)) {
442 log_dbg(cd, "Failed to read BITLK signature from %s.", device_path(device));
447 if (memcmp(sig.signature, BITLK_SIGNATURE, sizeof(sig.signature)) == 0) {
448 params->togo = false;
449 fve_offset = BITLK_HEADER_METADATA_OFFSET;
450 } else if (memcmp(sig.signature, BITLK_SIGNATURE_TOGO, sizeof(sig.signature)) == 0) {
452 fve_offset = BITLK_HEADER_METADATA_OFFSET_TOGO;
454 log_dbg(cd, "Invalid or unknown signature for BITLK device.");
459 if (memcmp(sig.boot_code, BITLK_BOOTCODE_V1, sizeof(sig.boot_code)) == 0) {
460 log_err(cd, _("BITLK version 1 is currently not supported."));
463 } else if (memcmp(sig.boot_code, BITLK_BOOTCODE_V2, sizeof(sig.boot_code)) == 0)
466 log_err(cd, _("Invalid or unknown boot signature for BITLK device."));
471 params->sector_size = le16_to_cpu(sig.sector_size);
472 if (params->sector_size == 0) {
473 log_dbg(cd, "Got sector size 0, assuming 512.");
474 params->sector_size = SECTOR_SIZE;
477 if (!(params->sector_size == 512 || params->sector_size == 4096)) {
478 log_err(cd, _("Unsupported sector size %" PRIu16 "."), params->sector_size);
483 /* read GUID and FVE metadata offsets */
484 if (read_lseek_blockwise(devfd, device_block_size(cd, device),
485 device_alignment(device), &sb, sizeof(sb), fve_offset) != sizeof(sb)) {
486 log_err(cd, _("Failed to read BITLK header from %s."), device_path(device));
491 /* get encryption "type" based on the GUID from BITLK superblock */
492 if (memcmp(&sb.guid, BITLK_GUID_NORMAL, 16) == 0)
493 params->type = BITLK_ENCRYPTION_TYPE_NORMAL;
494 else if (memcmp(&sb.guid, BITLK_GUID_EOW, 16) == 0)
495 params->type = BITLK_ENCRYPTION_TYPE_EOW;
497 params->type = BITLK_ENCRYPTION_TYPE_UNKNOWN;
498 log_dbg(cd, "BITLK type from GUID: %s.", get_bitlk_type_string(params->type));
500 for (i = 0; i < 3; i++)
501 params->metadata_offset[i] = le64_to_cpu(sb.fve_offset[i]);
503 log_dbg(cd, "Reading BITLK FVE metadata of size %zu on device %s, offset %" PRIu64 ".",
504 sizeof(fve), device_path(device), params->metadata_offset[0]);
506 /* read FVE metadata from the first metadata area */
507 if (read_lseek_blockwise(devfd, device_block_size(cd, device),
508 device_alignment(device), &fve, sizeof(fve), params->metadata_offset[0]) != sizeof(fve) ||
509 memcmp(fve.signature, BITLK_SIGNATURE, sizeof(fve.signature)) ||
510 le16_to_cpu(fve.fve_version) != 2) {
511 log_err(cd, _("Failed to read BITLK FVE metadata from %s."), device_path(device));
516 /* check encryption state for the device */
517 params->state = true;
518 if (le16_to_cpu(fve.curr_state) != BITLK_STATE_NORMAL || le16_to_cpu(fve.next_state) != BITLK_STATE_NORMAL) {
519 params->state = false;
520 log_dbg(cd, "Unknown/unsupported state detected. Current state: %"PRIu16", next state: %"PRIu16".",
521 le16_to_cpu(fve.curr_state), le16_to_cpu(fve.next_state));
524 params->volume_size = le64_to_cpu(fve.volume_size);
525 params->metadata_version = le16_to_cpu(fve.fve_version);
527 switch (le16_to_cpu(fve.encryption)) {
528 /* AES-CBC with Elephant difuser */
530 params->key_size = 256;
531 params->cipher = "aes";
532 params->cipher_mode = "cbc-elephant";
535 params->key_size = 512;
536 params->cipher = "aes";
537 params->cipher_mode = "cbc-elephant";
541 params->key_size = 128;
542 params->cipher = "aes";
543 params->cipher_mode = "cbc-eboiv";
546 params->key_size = 256;
547 params->cipher = "aes";
548 params->cipher_mode = "cbc-eboiv";
552 params->key_size = 256;
553 params->cipher = "aes";
554 params->cipher_mode = "xts-plain64";
557 params->key_size = 512;
558 params->cipher = "aes";
559 params->cipher_mode = "xts-plain64";
562 log_err(cd, _("Unknown or unsupported encryption type."));
563 params->key_size = 0;
564 params->cipher = NULL;
565 params->cipher_mode = NULL;
571 guid_to_string(&fve.guid, guid_buf);
572 params->guid = strdup(guid_buf);
578 params->creation_time = filetime_to_unixtime(le64_to_cpu(fve.creation_time));
580 fve_metadata_size = le32_to_cpu(fve.metadata_size);
581 if (fve_metadata_size < (BITLK_FVE_METADATA_HEADER_LEN + sizeof(entry_size) + sizeof(entry_type)) ||
582 fve_metadata_size > BITLK_FVE_METADATA_SIZE) {
586 fve_entries_size = fve_metadata_size - BITLK_FVE_METADATA_HEADER_LEN;
588 /* read and parse all FVE metadata entries */
589 fve_entries = malloc(fve_entries_size);
594 memset(fve_entries, 0, fve_entries_size);
596 log_dbg(cd, "Reading BITLK FVE metadata entries of size %zu on device %s, offset %" PRIu64 ".",
597 fve_entries_size, device_path(device), params->metadata_offset[0] + BITLK_FVE_METADATA_HEADERS_LEN);
599 if (read_lseek_blockwise(devfd, device_block_size(cd, device),
600 device_alignment(device), fve_entries, fve_entries_size,
601 params->metadata_offset[0] + BITLK_FVE_METADATA_HEADERS_LEN) != (ssize_t)fve_entries_size) {
602 log_err(cd, _("Failed to read BITLK metadata entries from %s."), device_path(device));
607 while ((fve_entries_size - start) >= (sizeof(entry_size) + sizeof(entry_type))) {
609 /* size of this entry */
610 memcpy(&entry_size, fve_entries + start, sizeof(entry_size));
611 entry_size = le16_to_cpu(entry_size);
615 if (entry_size > (fve_entries_size - start)) {
620 /* type of this entry */
621 memcpy(&entry_type, fve_entries + start + sizeof(entry_size), sizeof(entry_type));
622 entry_type = le16_to_cpu(entry_type);
625 if (entry_type == BITLK_ENTRY_TYPE_VMK) {
626 if (entry_size < (BITLK_ENTRY_HEADER_LEN + sizeof(entry_vmk))) {
630 /* skip first four variables in the entry (entry size, type, value and version) */
632 fve_entries + start + BITLK_ENTRY_HEADER_LEN,
635 vmk = malloc(sizeof(struct bitlk_vmk));
640 memset(vmk, 0, sizeof(struct bitlk_vmk));
642 guid_to_string(&entry_vmk.guid, guid_buf);
643 vmk->guid = strdup (guid_buf);
647 vmk->protection = get_vmk_protection(le16_to_cpu(entry_vmk.protection));
649 /* more data in another entry list */
650 r = parse_vmk_entry(cd, fve_entries,
651 start + BITLK_ENTRY_HEADER_LEN + BITLK_VMK_HEADER_LEN,
652 start + entry_size, &vmk);
654 BITLK_bitlk_vmk_free(vmk);
658 if (params->vmks == NULL)
666 } else if (entry_type == BITLK_ENTRY_TYPE_FVEK && !params->fvek) {
667 if (entry_size < (BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE + BITLK_VMK_MAC_TAG_SIZE)) {
671 params->fvek = malloc(sizeof(struct bitlk_fvek));
676 memcpy(params->fvek->nonce,
677 fve_entries + start + BITLK_ENTRY_HEADER_LEN,
680 memcpy(params->fvek->mac_tag,
681 fve_entries + start + BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE,
682 BITLK_VMK_MAC_TAG_SIZE);
683 /* AES-CCM encrypted key */
684 key_size = entry_size - (BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE + BITLK_VMK_MAC_TAG_SIZE);
685 key = (const char *) fve_entries + start + BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE + BITLK_VMK_MAC_TAG_SIZE;
686 params->fvek->vk = crypt_alloc_volume_key(key_size, key);
687 if (params->fvek->vk == NULL) {
691 /* volume header info (location and size) */
692 } else if (entry_type == BITLK_ENTRY_TYPE_VOLUME_HEADER) {
693 struct bitlk_entry_header_block entry_header;
694 if ((fve_entries_size - start) < (BITLK_ENTRY_HEADER_LEN + sizeof(entry_header))) {
698 memcpy(&entry_header,
699 fve_entries + start + BITLK_ENTRY_HEADER_LEN,
700 sizeof(entry_header));
701 params->volume_header_offset = le64_to_cpu(entry_header.offset);
702 params->volume_header_size = le64_to_cpu(entry_header.size);
703 /* volume description (utf-16 string) */
704 } else if (entry_type == BITLK_ENTRY_TYPE_DESCRIPTION && !params->description) {
705 if (entry_size < BITLK_ENTRY_HEADER_LEN) {
709 description = malloc((entry_size - BITLK_ENTRY_HEADER_LEN) * 2 + 1);
714 r = crypt_utf16_to_utf8(&description, CONST_CAST(char16_t *)(fve_entries + start + BITLK_ENTRY_HEADER_LEN),
715 entry_size - BITLK_ENTRY_HEADER_LEN);
718 BITLK_bitlk_vmk_free(vmk);
719 log_err(cd, _("Failed to convert BITLK volume description"));
722 params->description = description;
734 int BITLK_dump(struct crypt_device *cd, struct device *device, struct bitlk_metadata *params)
736 struct volume_key *vk_p;
737 struct bitlk_vmk *vmk_p;
741 log_std(cd, "Info for BITLK%s device %s.\n", params->togo ? " To Go" : "", device_path(device));
742 log_std(cd, "Version: \t%u\n", params->metadata_version);
743 log_std(cd, "GUID: \t%s\n", params->guid);
744 log_std(cd, "Sector size: \t%u [bytes]\n", params->sector_size);
745 log_std(cd, "Volume size: \t%" PRIu64 " [bytes]\n", params->volume_size);
746 log_std(cd, "Created: \t%s", ctime((time_t *)&(params->creation_time)));
747 log_std(cd, "Description: \t%s\n", params->description);
748 log_std(cd, "Cipher name: \t%s\n", params->cipher);
749 log_std(cd, "Cipher mode: \t%s\n", params->cipher_mode);
750 log_std(cd, "Cipher key: \t%u bits\n", params->key_size);
754 log_std(cd, "Keyslots:\n");
755 vmk_p = params->vmks;
757 log_std(cd, " %d: VMK\n", next_id);
758 if (vmk_p->name != NULL) {
759 log_std(cd, "\tName: \t%s\n", vmk_p->name);
761 log_std(cd, "\tGUID: \t%s\n", vmk_p->guid);
762 log_std(cd, "\tProtection: \t%s\n", get_vmk_protection_string (vmk_p->protection));
763 log_std(cd, "\tSalt: \t");
764 crypt_log_hex(cd, (const char *) vmk_p->salt, 16, "", 0, NULL);
769 log_std(cd, "\tKey data size:\t%zu [bytes]\n", vk_p->keylength);
776 log_std(cd, " %d: FVEK\n", next_id);
777 log_std(cd, "\tKey data size:\t%zu [bytes]\n", params->fvek->vk->keylength);
781 log_std(cd, "Metadata segments:\n");
783 for (i = 0; i < 3; i++) {
784 log_std(cd, " %d: FVE metadata area\n", i);
785 log_std(cd, "\tOffset: \t%" PRIu64 " [bytes]\n", params->metadata_offset[i]);
786 log_std(cd, "\tSize: \t%d [bytes]\n", BITLK_FVE_METADATA_SIZE);
789 log_std(cd, " %d: Volume header\n", i);
790 log_std(cd, "\tOffset: \t%" PRIu64 " [bytes]\n", params->volume_header_offset);
791 log_std(cd, "\tSize: \t%" PRIu64 " [bytes]\n", params->volume_header_size);
792 log_std(cd, "\tCipher: \t%s-%s\n", params->cipher, params->cipher_mode);
797 /* check if given passphrase can be a recovery key (has right format) and convert it */
798 static int get_recovery_key(struct crypt_device *cd,
799 const char *password,
801 struct volume_key **rc_key)
803 unsigned int i, j = 0;
804 uint16_t parts[BITLK_RECOVERY_PARTS] = {0};
805 char part_str[BITLK_RECOVERY_PART_LEN + 1] = {0};
808 /* check the passphrase it should be:
810 - 8 groups of 6 divided by '-'
811 - each part is a number dividable by 11
813 if (passwordLen != BITLK_RECOVERY_KEY_LEN) {
814 if (passwordLen == BITLK_RECOVERY_KEY_LEN + 1 && password[passwordLen - 1] == '\n') {
815 /* looks like a recovery key with an extra newline, possibly from a key file */
817 log_dbg(cd, "Possible extra EOL stripped from the recovery key.");
822 for (i = BITLK_RECOVERY_PART_LEN; i < passwordLen; i += BITLK_RECOVERY_PART_LEN + 1) {
823 if (password[i] != '-')
827 for (i = 0, j = 0; i < passwordLen; i += BITLK_RECOVERY_PART_LEN + 1, j++) {
828 strncpy(part_str, password + i, BITLK_RECOVERY_PART_LEN);
831 part_num = strtol(part_str, NULL, 10);
832 if ((errno == ERANGE && (part_num == LONG_MAX || part_num == LONG_MIN)) ||
833 (errno != 0 && part_num == 0))
836 if (part_num % 11 != 0)
838 parts[j] = cpu_to_le16(part_num / 11);
841 *rc_key = crypt_alloc_volume_key(16, (const char*) parts);
848 static int parse_external_key_entry(struct crypt_device *cd,
852 struct volume_key **vk,
853 const struct bitlk_metadata *params)
855 uint16_t key_entry_size = 0;
856 uint16_t key_entry_type = 0;
857 uint16_t key_entry_value = 0;
859 const char *key = NULL;
860 struct bitlk_guid guid;
861 char guid_buf[UUID_STR_LEN] = {0};
863 while ((end - start) >= (ssize_t)(sizeof(key_entry_size) + sizeof(key_entry_type) + sizeof(key_entry_value))) {
864 /* size of this entry */
865 memcpy(&key_entry_size, data + start, sizeof(key_entry_size));
866 key_entry_size = le16_to_cpu(key_entry_size);
867 if (key_entry_size == 0)
870 if (key_entry_size > (end - start))
873 /* type and value of this entry */
874 memcpy(&key_entry_type, data + start + sizeof(key_entry_size), sizeof(key_entry_type));
875 memcpy(&key_entry_value,
876 data + start + sizeof(key_entry_size) + sizeof(key_entry_type),
877 sizeof(key_entry_value));
878 key_entry_type = le16_to_cpu(key_entry_type);
879 key_entry_value = le16_to_cpu(key_entry_value);
881 if (key_entry_type != BITLK_ENTRY_TYPE_PROPERTY && key_entry_type != BITLK_ENTRY_TYPE_VOLUME_GUID) {
882 log_err(cd, _("Unexpected metadata entry type '%u' found when parsing external key."), key_entry_type);
886 if (key_entry_value == BITLK_ENTRY_VALUE_KEY) {
887 if (key_entry_size < (BITLK_ENTRY_HEADER_LEN + 4))
889 key_size = key_entry_size - (BITLK_ENTRY_HEADER_LEN + 4);
890 key = (const char *) data + start + BITLK_ENTRY_HEADER_LEN + 4;
891 *vk = crypt_alloc_volume_key(key_size, key);
895 /* optional "ExternalKey" string, we can safely ignore it */
896 } else if (key_entry_value == BITLK_ENTRY_VALUE_STRING)
898 /* GUID of the BitLocker device we are trying to open with this key */
899 else if (key_entry_value == BITLK_ENTRY_VALUE_GUID) {
900 if ((end - start) < (ssize_t)(BITLK_ENTRY_HEADER_LEN + sizeof(struct bitlk_guid)))
902 memcpy(&guid, data + start + BITLK_ENTRY_HEADER_LEN, sizeof(struct bitlk_guid));
903 guid_to_string(&guid, guid_buf);
904 if (strcmp(guid_buf, params->guid) != 0) {
905 log_err(cd, _("BEK file GUID '%s' does not match GUID of the volume."), guid_buf);
909 log_err(cd, _("Unexpected metadata entry value '%u' found when parsing external key."), key_entry_value);
913 start += key_entry_size;
916 /* if we got here we failed to parse the metadata */
920 /* check if given passphrase can be a startup key (has right format) and convert it */
921 static int get_startup_key(struct crypt_device *cd,
922 const char *password,
924 const struct bitlk_vmk *vmk,
925 struct volume_key **su_key,
926 const struct bitlk_metadata *params)
928 struct bitlk_bek_header bek_header = {0};
929 char guid_buf[UUID_STR_LEN] = {0};
931 uint16_t key_entry_size = 0;
932 uint16_t key_entry_type = 0;
933 uint16_t key_entry_value = 0;
935 if (passwordLen < (BITLK_BEK_FILE_HEADER_LEN + sizeof(key_entry_size) + sizeof(key_entry_type) + sizeof(key_entry_value)))
938 memcpy(&bek_header, password, BITLK_BEK_FILE_HEADER_LEN);
940 /* metadata should contain GUID of the VMK this startup key is used for */
941 guid_to_string(&bek_header.guid, guid_buf);
942 if (strcmp(guid_buf, vmk->guid) == 0)
943 log_dbg(cd, "Found matching startup key for VMK %s", vmk->guid);
947 if (le32_to_cpu(bek_header.metadata_version) != 1) {
948 log_err(cd, _("Unsupported BEK metadata version %" PRIu32), le32_to_cpu(bek_header.metadata_version));
952 if (le32_to_cpu(bek_header.metadata_size) != passwordLen) {
953 log_err(cd, _("Unexpected BEK metadata size %" PRIu32 " does not match BEK file length"),
954 le32_to_cpu(bek_header.metadata_size));
958 /* we are expecting exactly one metadata entry starting immediately after the header */
959 memcpy(&key_entry_size, password + BITLK_BEK_FILE_HEADER_LEN, sizeof(key_entry_size));
960 key_entry_size = le16_to_cpu(key_entry_size);
961 if (key_entry_size < BITLK_ENTRY_HEADER_LEN) {
962 log_dbg(cd, "Unexpected metadata entry size %" PRIu16 " when parsing BEK file", key_entry_size);
966 /* type and value of this entry */
967 memcpy(&key_entry_type, password + BITLK_BEK_FILE_HEADER_LEN + sizeof(key_entry_size), sizeof(key_entry_type));
968 memcpy(&key_entry_value,
969 password + BITLK_BEK_FILE_HEADER_LEN + sizeof(key_entry_size) + sizeof(key_entry_type),
970 sizeof(key_entry_value));
971 key_entry_type = le16_to_cpu(key_entry_type);
972 key_entry_value = le16_to_cpu(key_entry_value);
974 if (key_entry_type == BITLK_ENTRY_TYPE_STARTUP_KEY && key_entry_value == BITLK_ENTRY_VALUE_EXTERNAL_KEY) {
975 return parse_external_key_entry(cd, password,
976 BITLK_BEK_FILE_HEADER_LEN + BITLK_ENTRY_HEADER_LEN + BITLK_STARTUP_KEY_HEADER_LEN,
977 passwordLen, su_key, params);
979 log_err(cd, _("Unexpected metadata entry found when parsing startup key."));
980 log_dbg(cd, "Entry type: %u, entry value: %u", key_entry_type, key_entry_value);
985 static int bitlk_kdf(struct crypt_device *cd,
986 const char *password,
990 struct volume_key **vk)
992 struct bitlk_kdf_data kdf = {};
993 struct crypt_hash *hd = NULL;
995 char16_t *utf16Password = NULL;
999 memcpy(kdf.salt, salt, 16);
1001 r = crypt_hash_init(&hd, BITLK_KDF_HASH);
1004 len = crypt_hash_size(BITLK_KDF_HASH);
1006 crypt_hash_destroy(hd);
1011 /* passphrase: convert to UTF-16 first, then sha256(sha256(pw)) */
1012 utf16Password = crypt_safe_alloc(sizeof(char16_t) * (passwordLen + 1));
1013 if (!utf16Password) {
1017 r = crypt_utf8_to_utf16(&utf16Password, CONST_CAST(char*)password, passwordLen);
1021 crypt_hash_write(hd, (char*)utf16Password, passwordLen * 2);
1022 r = crypt_hash_final(hd, kdf.initial_sha256, len);
1026 crypt_hash_write(hd, kdf.initial_sha256, len);
1027 r = crypt_hash_final(hd, kdf.initial_sha256, len);
1031 /* recovery passphrase: already converted in #get_recovery_key, now just sha256(rpw) */
1032 crypt_hash_write(hd, password, passwordLen);
1033 r = crypt_hash_final(hd, kdf.initial_sha256, len);
1038 for (i = 0; i < BITLK_KDF_ITERATION_COUNT; i++) {
1039 crypt_hash_write(hd, (const char*) &kdf, sizeof(kdf));
1040 r = crypt_hash_final(hd, kdf.last_sha256, len);
1043 kdf.count = cpu_to_le64(le64_to_cpu(kdf.count) + 1);
1046 *vk = crypt_alloc_volume_key(len, kdf.last_sha256);
1049 crypt_safe_free(utf16Password);
1051 crypt_hash_destroy(hd);
1055 static int decrypt_key(struct crypt_device *cd,
1056 struct volume_key **vk,
1057 struct volume_key *enc_key,
1058 struct volume_key *key,
1059 const uint8_t *tag, size_t tag_size,
1060 const uint8_t *iv, size_t iv_size,
1065 uint16_t key_size = 0;
1067 outbuf = crypt_safe_alloc(enc_key->keylength);
1071 r = crypt_bitlk_decrypt_key(key->key, key->keylength, enc_key->key, outbuf, enc_key->keylength,
1072 (const char*)iv, iv_size, (const char*)tag, tag_size);
1075 log_err(cd, _("This operation is not supported."));
1079 /* key_data has it's size as part of the metadata */
1080 memcpy(&key_size, outbuf, 2);
1081 key_size = le16_to_cpu(key_size);
1082 if (enc_key->keylength != key_size) {
1083 log_err(cd, _("Unexpected key data size."));
1084 log_dbg(cd, "Expected key data size: %zu, got %" PRIu16 "", enc_key->keylength, key_size);
1090 if (is_fvek && strcmp(crypt_get_cipher_mode(cd), "cbc-elephant") == 0 &&
1091 crypt_get_volume_key_size(cd) == 32) {
1092 /* 128bit AES-CBC with Elephant -- key size is 256 bit (2 keys) but key data is 512 bits,
1093 data: 16B CBC key, 16B empty, 16B elephant key, 16B empty */
1094 memcpy(outbuf + 16 + BITLK_OPEN_KEY_METADATA_LEN,
1095 outbuf + 2 * 16 + BITLK_OPEN_KEY_METADATA_LEN, 16);
1096 key_size = 32 + BITLK_OPEN_KEY_METADATA_LEN;
1100 *vk = crypt_alloc_volume_key(key_size - BITLK_OPEN_KEY_METADATA_LEN,
1101 (const char *)(outbuf + BITLK_OPEN_KEY_METADATA_LEN));
1102 r = *vk ? 0 : -ENOMEM;
1104 crypt_safe_free(outbuf);
1108 int BITLK_get_volume_key(struct crypt_device *cd,
1109 const char *password,
1111 const struct bitlk_metadata *params,
1112 struct volume_key **open_fvek_key)
1115 struct volume_key *open_vmk_key = NULL;
1116 struct volume_key *vmk_dec_key = NULL;
1117 struct volume_key *recovery_key = NULL;
1118 const struct bitlk_vmk *next_vmk = NULL;
1120 next_vmk = params->vmks;
1122 if (next_vmk->protection == BITLK_PROTECTION_PASSPHRASE) {
1123 r = bitlk_kdf(cd, password, passwordLen, false, next_vmk->salt, &vmk_dec_key);
1125 /* something wrong happened, but we still want to check other key slots */
1126 next_vmk = next_vmk->next;
1129 } else if (next_vmk->protection == BITLK_PROTECTION_RECOVERY_PASSPHRASE) {
1130 r = get_recovery_key(cd, password, passwordLen, &recovery_key);
1132 /* something wrong happened, but we still want to check other key slots */
1133 next_vmk = next_vmk->next;
1136 if (recovery_key == NULL) {
1137 /* r = 0 but no key -> given passphrase is not a recovery passphrase */
1139 next_vmk = next_vmk->next;
1142 log_dbg(cd, "Trying to use given password as a recovery key.");
1143 r = bitlk_kdf(cd, recovery_key->key, recovery_key->keylength,
1144 true, next_vmk->salt, &vmk_dec_key);
1145 crypt_free_volume_key(recovery_key);
1148 } else if (next_vmk->protection == BITLK_PROTECTION_STARTUP_KEY) {
1149 r = get_startup_key(cd, password, passwordLen, next_vmk, &vmk_dec_key, params);
1151 next_vmk = next_vmk->next;
1154 log_dbg(cd, "Trying to use external key found in provided password.");
1156 /* only passphrase, recovery passphrase and startup key VMKs supported right now */
1157 log_dbg(cd, "Skipping %s", get_vmk_protection_string(next_vmk->protection));
1158 next_vmk = next_vmk->next;
1160 /* we need to set error code in case we have only unsupported VMKs */
1165 log_dbg(cd, "Trying to decrypt %s.", get_vmk_protection_string(next_vmk->protection));
1166 r = decrypt_key(cd, &open_vmk_key, next_vmk->vk, vmk_dec_key,
1167 next_vmk->mac_tag, BITLK_VMK_MAC_TAG_SIZE,
1168 next_vmk->nonce, BITLK_NONCE_SIZE, false);
1170 log_dbg(cd, "Failed to decrypt VMK using provided passphrase.");
1171 crypt_free_volume_key(vmk_dec_key);
1174 next_vmk = next_vmk->next;
1177 crypt_free_volume_key(vmk_dec_key);
1179 r = decrypt_key(cd, open_fvek_key, params->fvek->vk, open_vmk_key,
1180 params->fvek->mac_tag, BITLK_VMK_MAC_TAG_SIZE,
1181 params->fvek->nonce, BITLK_NONCE_SIZE, true);
1183 log_dbg(cd, "Failed to decrypt FVEK using VMK.");
1184 crypt_free_volume_key(open_vmk_key);
1188 crypt_free_volume_key(open_vmk_key);
1192 next_vmk = next_vmk->next;
1196 log_dbg(cd, "No more VMKs to try.");
1203 static int _activate_check(struct crypt_device *cd,
1204 const struct bitlk_metadata *params)
1206 const struct bitlk_vmk *next_vmk = NULL;
1208 if (!params->state) {
1209 log_err(cd, _("This BITLK device is in an unsupported state and cannot be activated."));
1213 if (params->type != BITLK_ENCRYPTION_TYPE_NORMAL) {
1214 log_err(cd, _("BITLK devices with type '%s' cannot be activated."), get_bitlk_type_string(params->type));
1218 next_vmk = params->vmks;
1220 if (next_vmk->protection == BITLK_PROTECTION_CLEAR_KEY) {
1221 log_err(cd, _("Activation of partially decrypted BITLK device is not supported."));
1224 next_vmk = next_vmk->next;
1230 static int _activate(struct crypt_device *cd,
1232 struct volume_key *open_fvek_key,
1233 const struct bitlk_metadata *params,
1240 int num_segments = 0;
1241 struct crypt_dm_active_device dmd = {
1244 struct dm_target *next_segment = NULL;
1245 struct segment segments[MAX_BITLK_SEGMENTS] = {};
1246 struct segment temp;
1247 uint64_t next_start = 0;
1248 uint64_t next_end = 0;
1249 uint64_t last_segment = 0;
1250 uint32_t dmt_flags = 0;
1252 r = _activate_check(cd, params);
1256 r = device_block_adjust(cd, crypt_data_device(cd), DEV_EXCL,
1257 0, &dmd.size, &dmd.flags);
1261 if (dmd.size * SECTOR_SIZE != params->volume_size)
1262 log_std(cd, _("WARNING: BitLocker volume size %" PRIu64 " does not match the underlying device size %" PRIu64 ""),
1263 params->volume_size,
1264 dmd.size * SECTOR_SIZE);
1266 /* there will be always 4 dm-zero segments: 3x metadata, 1x FS header */
1267 for (i = 0; i < 3; i++) {
1268 segments[num_segments].offset = params->metadata_offset[i] / SECTOR_SIZE;
1269 segments[num_segments].length = BITLK_FVE_METADATA_SIZE / SECTOR_SIZE;
1270 segments[num_segments].iv_offset = 0;
1271 segments[num_segments].type = BITLK_SEGTYPE_ZERO;
1274 segments[num_segments].offset = params->volume_header_offset / SECTOR_SIZE;
1275 segments[num_segments].length = params->volume_header_size / SECTOR_SIZE;
1276 segments[num_segments].iv_offset = 0;
1277 segments[num_segments].type = BITLK_SEGTYPE_ZERO;
1280 /* filesystem header (moved from the special location) */
1281 segments[num_segments].offset = 0;
1282 segments[num_segments].length = params->volume_header_size / SECTOR_SIZE;
1283 segments[num_segments].iv_offset = params->volume_header_offset / SECTOR_SIZE;
1284 segments[num_segments].type = BITLK_SEGTYPE_CRYPT;
1287 /* now fill gaps between the dm-zero segments with dm-crypt */
1288 last_segment = params->volume_header_size / SECTOR_SIZE;
1290 next_start = dmd.size;
1291 next_end = dmd.size;
1293 /* start of the next segment: end of the first existing segment after the last added */
1294 for (i = 0; i < num_segments; i++)
1295 if (segments[i].offset + segments[i].length < next_start && segments[i].offset + segments[i].length >= last_segment)
1296 next_start = segments[i].offset + segments[i].length;
1298 /* end of the next segment: start of the next segment after start we found above */
1299 for (i = 0; i < num_segments; i++)
1300 if (segments[i].offset < next_end && segments[i].offset >= next_start)
1301 next_end = segments[i].offset;
1303 /* two zero segments next to each other, just bump the last_segment
1304 so the algorithm moves */
1305 if (next_end - next_start == 0) {
1306 last_segment = next_end + 1;
1310 segments[num_segments].offset = next_start;
1311 segments[num_segments].length = next_end - next_start;
1312 segments[num_segments].iv_offset = next_start;
1313 segments[num_segments].type = BITLK_SEGTYPE_CRYPT;
1314 last_segment = next_end;
1317 if (next_end == dmd.size)
1320 if (num_segments == 10) {
1321 log_dbg(cd, "Failed to calculate number of dm-crypt segments for open.");
1327 /* device mapper needs the segment sorted */
1328 for (i = 0; i < num_segments - 1; i++) {
1330 for (j = i + 1; j < num_segments; j++)
1331 if (segments[j].offset < segments[min].offset)
1335 temp.offset = segments[min].offset;
1336 temp.length = segments[min].length;
1337 temp.iv_offset = segments[min].iv_offset;
1338 temp.type = segments[min].type;
1340 segments[min].offset = segments[i].offset;
1341 segments[min].length = segments[i].length;
1342 segments[min].iv_offset = segments[i].iv_offset;
1343 segments[min].type = segments[i].type;
1345 segments[i].offset = temp.offset;
1346 segments[i].length = temp.length;
1347 segments[i].iv_offset = temp.iv_offset;
1348 segments[i].type = temp.type;
1352 if (params->sector_size != SECTOR_SIZE)
1353 dmd.flags |= CRYPT_ACTIVATE_IV_LARGE_SECTORS;
1355 r = dm_targets_allocate(&dmd.segment, num_segments);
1358 next_segment = &dmd.segment;
1360 for (i = 0; i < num_segments; i++) {
1361 if (segments[i].type == BITLK_SEGTYPE_ZERO)
1362 r = dm_zero_target_set(next_segment,
1364 segments[i].length);
1365 else if (segments[i].type == BITLK_SEGTYPE_CRYPT)
1366 r = dm_crypt_target_set(next_segment,
1369 crypt_data_device(cd),
1371 crypt_get_cipher_spec(cd),
1372 segments[i].iv_offset,
1373 segments[i].iv_offset,
1375 params->sector_size);
1379 next_segment = next_segment->next;
1382 log_dbg(cd, "Trying to activate BITLK on device %s%s%s.",
1383 device_path(crypt_data_device(cd)), name ? " with name " :"", name ?: "");
1385 r = dm_create_device(cd, name, CRYPT_BITLK, &dmd);
1387 dm_flags(cd, DM_CRYPT, &dmt_flags);
1388 if (!strcmp(params->cipher_mode, "cbc-eboiv") && !(dmt_flags & DM_BITLK_EBOIV_SUPPORTED)) {
1389 log_err(cd, _("Cannot activate device, kernel dm-crypt is missing support for BITLK IV."));
1392 if (!strcmp(params->cipher_mode, "cbc-elephant") && !(dmt_flags & DM_BITLK_ELEPHANT_SUPPORTED)) {
1393 log_err(cd, _("Cannot activate device, kernel dm-crypt is missing support for BITLK Elephant diffuser."));
1396 if ((dmd.flags & CRYPT_ACTIVATE_IV_LARGE_SECTORS) && !(dmt_flags & DM_SECTOR_SIZE_SUPPORTED)) {
1397 log_err(cd, _("Cannot activate device, kernel dm-crypt is missing support for large sector size."));
1400 if (dm_flags(cd, DM_ZERO, &dmt_flags) < 0) {
1401 log_err(cd, _("Cannot activate device, kernel dm-zero module is missing."));
1406 dm_targets_free(cd, &dmd);
1410 int BITLK_activate_by_passphrase(struct crypt_device *cd,
1412 const char *password,
1414 const struct bitlk_metadata *params,
1418 struct volume_key *open_fvek_key = NULL;
1420 r = _activate_check(cd, params);
1424 r = BITLK_get_volume_key(cd, password, passwordLen, params, &open_fvek_key);
1428 /* Password verify only */
1432 r = _activate(cd, name, open_fvek_key, params, flags);
1434 crypt_free_volume_key(open_fvek_key);
1438 int BITLK_activate_by_volume_key(struct crypt_device *cd,
1440 const char *volume_key,
1441 size_t volume_key_size,
1442 const struct bitlk_metadata *params,
1446 struct volume_key *open_fvek_key = NULL;
1448 r = _activate_check(cd, params);
1452 open_fvek_key = crypt_alloc_volume_key(volume_key_size, volume_key);
1456 r = _activate(cd, name, open_fvek_key, params, flags);
1458 crypt_free_volume_key(open_fvek_key);