2 * BITLK (BitLocker-compatible) volume handling
4 * Copyright (C) 2019-2021 Red Hat, Inc. All rights reserved.
5 * Copyright (C) 2019-2021 Milan Broz
6 * Copyright (C) 2019-2021 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>
33 #define BITLK_BOOTCODE_V1 "\xeb\x52\x90"
34 #define BITLK_BOOTCODE_V2 "\xeb\x58\x90"
35 #define BITLK_SIGNATURE "-FVE-FS-"
36 #define BITLK_SIGNATURE_TOGO "MSWIN4.1"
37 #define BITLK_HEADER_METADATA_OFFSET 160
38 #define BITLK_HEADER_METADATA_OFFSET_TOGO 424
40 /* FVE metadata header is split into two parts */
41 #define BITLK_FVE_METADATA_BLOCK_HEADER_LEN 64
42 #define BITLK_FVE_METADATA_HEADER_LEN 48
43 #define BITLK_FVE_METADATA_HEADERS_LEN BITLK_FVE_METADATA_BLOCK_HEADER_LEN + BITLK_FVE_METADATA_HEADER_LEN
45 /* total size of the FVE area (64 KiB) */
46 #define BITLK_FVE_METADATA_SIZE 64 * 1024
48 #define BITLK_ENTRY_HEADER_LEN 8
49 #define BITLK_VMK_HEADER_LEN 28
51 #define BITLK_OPEN_KEY_METADATA_LEN 12
53 #define BITLK_RECOVERY_KEY_LEN 55
54 #define BITLK_RECOVERY_PARTS 8
55 #define BITLK_RECOVERY_PART_LEN 6
57 #define BITLK_BEK_FILE_HEADER_LEN 48
58 #define BITLK_STARTUP_KEY_HEADER_LEN 24
60 #define BITLK_KDF_HASH "sha256"
61 #define BITLK_KDF_ITERATION_COUNT 0x100000
63 /* maximum number of segments for the DM device */
64 #define MAX_BITLK_SEGMENTS 10
66 /* January 1, 1970 as MS file time */
67 #define EPOCH_AS_FILETIME 116444736000000000
68 #define HUNDREDS_OF_NANOSECONDS 10000000
70 /* not available in older version of libuuid */
72 #define UUID_STR_LEN 37
75 /* known types of GUIDs from the BITLK superblock */
76 const uint8_t BITLK_GUID_NORMAL[16] = { 0x3b, 0xd6, 0x67, 0x49, 0x29, 0x2e, 0xd8, 0x4a,
77 0x83, 0x99, 0xf6, 0xa3, 0x39, 0xe3, 0xd0, 0x01 };
78 const uint8_t BITLK_GUID_EOW[16] = { 0x3b, 0x4d, 0xa8, 0x92, 0x80, 0xdd, 0x0e, 0x4d,
79 0x9e, 0x4e, 0xb1, 0xe3, 0x28, 0x4e, 0xae, 0xd8 };
81 /* taken from libfdisk gpt.c -- TODO: this is a good candidate for adding to libuuid */
85 uint16_t time_hi_and_version;
87 uint8_t clock_seq_low;
89 } __attribute__ ((packed));
91 static void swap_guid(struct bitlk_guid *guid) {
92 guid->time_low = swab32(guid->time_low);
93 guid->time_mid = swab16(guid->time_mid);
94 guid->time_hi_and_version = swab16(guid->time_hi_and_version);
97 static void guid_to_string(struct bitlk_guid *guid, char *out) {
99 uuid_unparse((unsigned char *) guid, out);
111 BitlkSegmentType type;
114 struct bitlk_signature {
115 uint8_t boot_code[3];
116 uint8_t signature[8];
117 uint16_t sector_size;
118 } __attribute__ ((packed));
120 struct bitlk_superblock {
121 struct bitlk_guid guid;
122 uint64_t fve_offset[3];
123 } __attribute__ ((packed));
125 struct bitlk_fve_metadata {
126 /* FVE metadata block header */
127 uint8_t signature[8];
129 uint16_t fve_version;
132 uint64_t volume_size;
134 uint32_t volume_header_size;
135 uint64_t fve_offset[3];
136 uint64_t volume_header_offset;
137 /* FVE metadata header */
138 uint32_t metadata_size;
139 uint32_t metadata_version;
140 uint32_t metadata_header_size;
141 uint32_t metada_size_copy;
142 struct bitlk_guid guid;
146 uint64_t creation_time;
147 } __attribute__ ((packed));
149 struct bitlk_entry_header_block {
152 } __attribute__ ((packed));
154 struct bitlk_entry_vmk {
155 struct bitlk_guid guid;
159 } __attribute__ ((packed));
161 struct bitlk_kdf_data {
162 char last_sha256[32];
163 char initial_sha256[32];
168 struct bitlk_bek_header {
169 uint32_t metadata_size;
170 uint32_t metadata_version;
171 uint32_t metadata_header_size;
172 uint32_t metada_size_copy;
173 struct bitlk_guid guid;
177 uint64_t creation_time;
178 } __attribute__ ((packed));
180 static BITLKVMKProtection get_vmk_protection(uint16_t protection)
182 switch (protection) {
184 return BITLK_PROTECTION_CLEAR_KEY;
186 return BITLK_PROTECTION_TPM;
188 return BITLK_PROTECTION_STARTUP_KEY;
190 return BITLK_PROTECTION_TPM_PIN;
192 return BITLK_PROTECTION_RECOVERY_PASSPHRASE;
194 return BITLK_PROTECTION_SMART_CARD;
196 return BITLK_PROTECTION_PASSPHRASE;
198 return BITLK_PROTECTION_UNKNOWN;
202 static const char* get_vmk_protection_string(BITLKVMKProtection protection)
204 switch (protection) {
205 case BITLK_PROTECTION_CLEAR_KEY:
206 return "VMK protected with clear key";
207 case BITLK_PROTECTION_TPM:
208 return "VMK protected with TPM";
209 case BITLK_PROTECTION_STARTUP_KEY:
210 return "VMK protected with startup key";
211 case BITLK_PROTECTION_TPM_PIN:
212 return "VMK protected with TPM and PIN";
213 case BITLK_PROTECTION_PASSPHRASE:
214 return "VMK protected with passphrase";
215 case BITLK_PROTECTION_RECOVERY_PASSPHRASE:
216 return "VMK protected with recovery passphrase";
217 case BITLK_PROTECTION_SMART_CARD:
218 return "VMK protected with smart card";
220 return "VMK with unknown protection";
224 static const char* get_bitlk_type_string(BITLKEncryptionType type)
228 case BITLK_ENCRYPTION_TYPE_NORMAL:
230 case BITLK_ENCRYPTION_TYPE_EOW:
231 return "encrypt-on-write";
237 /* TODO -- move to some utils file */
238 static void hexprint(struct crypt_device *cd, const char *d, int n, const char *sep)
241 for(i = 0; i < n; i++)
242 log_std(cd, "%02hhx%s", (const char)d[i], sep);
245 static uint64_t filetime_to_unixtime(uint64_t time)
247 return (time - EPOCH_AS_FILETIME) / HUNDREDS_OF_NANOSECONDS;
250 static int convert_to_utf8(struct crypt_device *cd, uint8_t *input, size_t inlen, char **out)
254 size_t ic_inlen = inlen;
255 size_t ic_outlen = inlen;
256 char *ic_outbuf = NULL;
259 outbuf = malloc(inlen);
263 memset(outbuf, 0, inlen);
266 ic = iconv_open("UTF-8", "UTF-16LE");
267 r = iconv(ic, (char **) &input, &ic_inlen, &ic_outbuf, &ic_outlen);
271 *out = strdup(outbuf);
274 log_dbg(cd, "Failed to convert volume description: %s", strerror(errno));
282 static int passphrase_to_utf16(struct crypt_device *cd, char *input, size_t inlen, char **out)
286 size_t ic_inlen = inlen;
287 size_t ic_outlen = inlen * 2;
288 char *ic_outbuf = NULL;
294 outbuf = crypt_safe_alloc(inlen * 2);
298 memset(outbuf, 0, inlen * 2);
301 ic = iconv_open("UTF-16LE", "UTF-8");
302 r = iconv(ic, &input, &ic_inlen, &ic_outbuf, &ic_outlen);
309 crypt_safe_free(outbuf);
310 log_dbg(cd, "Failed to convert passphrase: %s", strerror(errno));
317 static int parse_vmk_entry(struct crypt_device *cd, uint8_t *data, int start, int end, struct bitlk_vmk **vmk)
319 uint16_t key_entry_size = 0;
320 uint16_t key_entry_type = 0;
321 uint16_t key_entry_value = 0;
324 const char *key = NULL;
325 struct volume_key *vk = NULL;
326 bool supported = false;
328 /* only passphrase or recovery passphrase vmks are supported (can be used to activate) */
329 supported = (*vmk)->protection == BITLK_PROTECTION_PASSPHRASE ||
330 (*vmk)->protection == BITLK_PROTECTION_RECOVERY_PASSPHRASE ||
331 (*vmk)->protection == BITLK_PROTECTION_STARTUP_KEY;
333 while (end - start > 2) {
334 /* size of this entry */
335 memcpy(&key_entry_size, data + start, sizeof(key_entry_size));
336 key_entry_size = le16_to_cpu(key_entry_size);
337 if (key_entry_size == 0)
340 /* type and value of this entry */
341 memcpy(&key_entry_type, data + start + sizeof(key_entry_size), sizeof(key_entry_type));
342 memcpy(&key_entry_value,
343 data + start + sizeof(key_entry_size) + sizeof(key_entry_type),
344 sizeof(key_entry_value));
345 key_entry_type = le16_to_cpu(key_entry_type);
346 key_entry_value = le16_to_cpu(key_entry_value);
348 if (key_entry_type != BITLK_ENTRY_TYPE_PROPERTY) {
350 log_err(cd, _("Unexpected metadata entry type '%u' found when parsing supported Volume Master Key."), key_entry_type);
353 log_dbg(cd, "Unexpected metadata entry type '%u' found when parsing unsupported VMK.", key_entry_type);
357 /* stretch key with salt, skip 4 B (encryption method of the stretch key) */
358 if (key_entry_value == BITLK_ENTRY_VALUE_STRETCH_KEY)
360 data + start + BITLK_ENTRY_HEADER_LEN + 4,
361 sizeof((*vmk)->salt));
362 /* AES-CCM encrypted key */
363 else if (key_entry_value == BITLK_ENTRY_VALUE_ENCRYPTED_KEY) {
365 memcpy((*vmk)->nonce,
366 data + start + BITLK_ENTRY_HEADER_LEN,
367 sizeof((*vmk)->nonce));
369 memcpy((*vmk)->mac_tag,
370 data + start + BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE,
371 sizeof((*vmk)->mac_tag));
372 /* AES-CCM encrypted key */
373 key_size = key_entry_size - (BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE + BITLK_VMK_MAC_TAG_SIZE);
374 key = (const char *) data + start + BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE + BITLK_VMK_MAC_TAG_SIZE;
375 vk = crypt_alloc_volume_key(key_size, key);
378 crypt_volume_key_add_next(&((*vmk)->vk), vk);
379 /* clear key for a partially decrypted volume */
380 } else if (key_entry_value == BITLK_ENTRY_VALUE_KEY) {
381 /* We currently don't want to support opening a partially decrypted
382 * device so we don't need to store this key.
384 * key_size = key_entry_size - (BITLK_ENTRY_HEADER_LEN + 4);
385 * key = (const char *) data + start + BITLK_ENTRY_HEADER_LEN + 4;
386 * vk = crypt_alloc_volume_key(key_size, key);
389 * crypt_volume_key_add_next(&((*vmk)->vk), vk);
391 log_dbg(cd, "Skipping clear key metadata entry.");
392 /* unknown timestamps in recovery protected VMK */
393 } else if (key_entry_value == BITLK_ENTRY_VALUE_RECOVERY_TIME) {
395 } else if (key_entry_value == BITLK_ENTRY_VALUE_STRING) {
396 if (convert_to_utf8(cd, data + start + BITLK_ENTRY_HEADER_LEN, key_entry_size - BITLK_ENTRY_HEADER_LEN, &string) < 0) {
397 log_err(cd, _("Invalid string found when parsing Volume Master Key."));
400 } else if ((*vmk)->name != NULL) {
402 log_err(cd, _("Unexpected string ('%s') found when parsing supported Volume Master Key."), string);
406 log_dbg(cd, "Unexpected string ('%s') found when parsing unsupported VMK.", string);
410 /* Assume that strings in VMK are the name of the VMK */
411 (*vmk)->name = string;
414 /* no idea what this is, lets hope it's not important */
415 } else if (key_entry_value == BITLK_ENTRY_VALUE_USE_KEY && (*vmk)->protection == BITLK_PROTECTION_STARTUP_KEY) {
419 log_err(cd, _("Unexpected metadata entry value '%u' found when parsing supported Volume Master Key."), key_entry_value);
422 log_dbg(cd, "Unexpected metadata entry value '%u' found when parsing unsupported VMK.", key_entry_value);
426 start += key_entry_size;
432 void BITLK_bitlk_fvek_free(struct bitlk_fvek *fvek)
437 crypt_free_volume_key(fvek->vk);
441 void BITLK_bitlk_vmk_free(struct bitlk_vmk *vmk)
443 struct bitlk_vmk *vmk_next = NULL;
450 crypt_free_volume_key(vmk->vk);
451 vmk_next = vmk->next;
457 void BITLK_bitlk_metadata_free(struct bitlk_metadata *metadata)
462 free(metadata->guid);
463 if (metadata->description)
464 free(metadata->description);
465 BITLK_bitlk_vmk_free(metadata->vmks);
466 BITLK_bitlk_fvek_free(metadata->fvek);
469 int BITLK_read_sb(struct crypt_device *cd, struct bitlk_metadata *params)
472 struct device *device = crypt_metadata_device(cd);
473 struct bitlk_signature sig = {};
474 struct bitlk_superblock sb = {};
475 struct bitlk_fve_metadata fve = {};
476 struct bitlk_entry_vmk entry_vmk = {};
477 uint8_t *fve_entries = NULL;
478 uint32_t fve_metadata_size = 0;
480 char guid_buf[UUID_STR_LEN] = {0};
481 uint16_t entry_size = 0;
482 uint16_t entry_type = 0;
488 const char *key = NULL;
490 struct bitlk_vmk *vmk = NULL;
491 struct bitlk_vmk *vmk_p = params->vmks;
493 devfd = device_open(cd, crypt_data_device(cd), O_RDONLY);
499 /* read and check the signature */
500 if (read_lseek_blockwise(devfd, device_block_size(cd, device),
501 device_alignment(device), &sig, sizeof(sig), 0) != sizeof(sig)) {
502 log_err(cd, _("Failed to read BITLK signature from %s."), device_path(device));
507 if (memcmp(sig.signature, BITLK_SIGNATURE, sizeof(sig.signature)) == 0) {
508 params->togo = false;
509 fve_offset = BITLK_HEADER_METADATA_OFFSET;
510 } else if (memcmp(sig.signature, BITLK_SIGNATURE_TOGO, sizeof(sig.signature)) == 0) {
512 fve_offset = BITLK_HEADER_METADATA_OFFSET_TOGO;
514 log_err(cd, _("Invalid or unknown signature for BITLK device."));
519 if (memcmp(sig.boot_code, BITLK_BOOTCODE_V1, sizeof(sig.boot_code)) == 0) {
520 log_err(cd, _("BITLK version 1 is currently not supported."));
523 } else if (memcmp(sig.boot_code, BITLK_BOOTCODE_V2, sizeof(sig.boot_code)) == 0)
526 log_err(cd, _("Invalid or unknown boot signature for BITLK device."));
531 params->sector_size = le16_to_cpu(sig.sector_size);
532 if (params->sector_size == 0) {
533 log_dbg(cd, "Got sector size 0, assuming 512.");
534 params->sector_size = SECTOR_SIZE;
537 if (!(params->sector_size == 512 || params->sector_size == 4096)) {
538 log_err(cd, _("Unsupported sector size %" PRIu16 "."), params->sector_size);
543 /* read GUID and FVE metadata offsets */
544 if (read_lseek_blockwise(devfd, device_block_size(cd, device),
545 device_alignment(device), &sb, sizeof(sb), fve_offset) != sizeof(sb)) {
546 log_err(cd, _("Failed to read BITLK header from %s."), device_path(device));
551 /* get encryption "type" based on the GUID from BITLK superblock */
552 if (memcmp(&sb.guid, BITLK_GUID_NORMAL, 16) == 0)
553 params->type = BITLK_ENCRYPTION_TYPE_NORMAL;
554 else if (memcmp(&sb.guid, BITLK_GUID_EOW, 16) == 0)
555 params->type = BITLK_ENCRYPTION_TYPE_EOW;
557 params->type = BITLK_ENCRYPTION_TYPE_UNKNOWN;
558 log_dbg(cd, "BITLK type from GUID: %s.", get_bitlk_type_string(params->type));
560 for (i = 0; i < 3; i++)
561 params->metadata_offset[i] = le64_to_cpu(sb.fve_offset[i]);
563 log_dbg(cd, "Reading BITLK FVE metadata of size %zu on device %s, offset %" PRIu64 ".",
564 sizeof(fve), device_path(device), params->metadata_offset[0]);
566 /* read FVE metadata from the first metadata area */
567 if (read_lseek_blockwise(devfd, device_block_size(cd, device),
568 device_alignment(device), &fve, sizeof(fve), params->metadata_offset[0]) != sizeof(fve) ||
569 memcmp(fve.signature, BITLK_SIGNATURE, sizeof(fve.signature)) ||
570 le16_to_cpu(fve.fve_version) != 2) {
571 log_err(cd, _("Failed to read BITLK FVE metadata from %s."), device_path(device));
576 /* check encryption state for the device */
577 params->state = true;
578 if (le16_to_cpu(fve.curr_state) != BITLK_STATE_NORMAL || le16_to_cpu(fve.next_state) != BITLK_STATE_NORMAL) {
579 params->state = false;
580 log_dbg(cd, "Unknown/unsupported state detected. Current state: %"PRIu16", next state: %"PRIu16".",
581 le16_to_cpu(fve.curr_state), le16_to_cpu(fve.next_state));
584 params->metadata_version = le16_to_cpu(fve.fve_version);
585 fve_metadata_size = le32_to_cpu(fve.metadata_size);
587 switch (le16_to_cpu(fve.encryption)) {
588 /* AES-CBC with Elephant difuser */
590 params->key_size = 256;
591 params->cipher = "aes";
592 params->cipher_mode = "cbc-elephant";
595 params->key_size = 512;
596 params->cipher = "aes";
597 params->cipher_mode = "cbc-elephant";
601 params->key_size = 128;
602 params->cipher = "aes";
603 params->cipher_mode = "cbc-eboiv";
606 params->key_size = 256;
607 params->cipher = "aes";
608 params->cipher_mode = "cbc-eboiv";
612 params->key_size = 256;
613 params->cipher = "aes";
614 params->cipher_mode = "xts-plain64";
617 params->key_size = 512;
618 params->cipher = "aes";
619 params->cipher_mode = "xts-plain64";
622 log_err(cd, _("Unknown or unsupported encryption type."));
623 params->key_size = 0;
624 params->cipher = NULL;
625 params->cipher_mode = NULL;
631 guid_to_string(&fve.guid, guid_buf);
632 params->guid = strdup(guid_buf);
638 params->creation_time = filetime_to_unixtime(le64_to_cpu(fve.creation_time));
640 /* read and parse all FVE metadata entries */
641 fve_entries = malloc(fve_metadata_size - BITLK_FVE_METADATA_HEADER_LEN);
646 memset(fve_entries, 0, (fve_metadata_size - BITLK_FVE_METADATA_HEADER_LEN));
648 log_dbg(cd, "Reading BITLK FVE metadata entries of size %" PRIu32 " on device %s, offset %" PRIu64 ".",
649 fve_metadata_size - BITLK_FVE_METADATA_HEADER_LEN, device_path(device),
650 params->metadata_offset[0] + BITLK_FVE_METADATA_HEADERS_LEN);
652 if (read_lseek_blockwise(devfd, device_block_size(cd, device),
653 device_alignment(device), fve_entries, fve_metadata_size - BITLK_FVE_METADATA_HEADER_LEN,
654 params->metadata_offset[0] + BITLK_FVE_METADATA_HEADERS_LEN) != (ssize_t)(fve_metadata_size - BITLK_FVE_METADATA_HEADER_LEN)) {
655 log_err(cd, _("Failed to read BITLK metadata entries from %s."), device_path(device));
660 end = fve_metadata_size - BITLK_FVE_METADATA_HEADER_LEN;
661 while (end - start > 2) {
662 /* size of this entry */
663 memcpy(&entry_size, fve_entries + start, sizeof(entry_size));
664 entry_size = le16_to_cpu(entry_size);
668 /* type of this entry */
669 memcpy(&entry_type, fve_entries + start + sizeof(entry_size), sizeof(entry_type));
670 entry_type = le16_to_cpu(entry_type);
673 if (entry_type == BITLK_ENTRY_TYPE_VMK) {
674 /* skip first four variables in the entry (entry size, type, value and version) */
676 fve_entries + start + BITLK_ENTRY_HEADER_LEN,
679 vmk = malloc(sizeof(struct bitlk_vmk));
684 memset(vmk, 0, sizeof(struct bitlk_vmk));
686 guid_to_string(&entry_vmk.guid, guid_buf);
687 vmk->guid = strdup (guid_buf);
691 vmk->protection = get_vmk_protection(le16_to_cpu(entry_vmk.protection));
693 /* more data in another entry list */
694 r = parse_vmk_entry(cd, fve_entries,
695 start + BITLK_ENTRY_HEADER_LEN + BITLK_VMK_HEADER_LEN,
696 start + entry_size, &vmk);
698 BITLK_bitlk_vmk_free(vmk);
702 if (params->vmks == NULL)
710 } else if (entry_type == BITLK_ENTRY_TYPE_FVEK) {
711 params->fvek = malloc(sizeof(struct bitlk_fvek));
716 memcpy(params->fvek->nonce,
717 fve_entries + start + BITLK_ENTRY_HEADER_LEN,
718 sizeof(params->fvek->nonce));
720 memcpy(params->fvek->mac_tag,
721 fve_entries + start + BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE,
722 sizeof(params->fvek->mac_tag));
723 /* AES-CCM encrypted key */
724 key_size = entry_size - (BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE + BITLK_VMK_MAC_TAG_SIZE);
725 key = (const char *) fve_entries + start + BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE + BITLK_VMK_MAC_TAG_SIZE;
726 params->fvek->vk = crypt_alloc_volume_key(key_size, key);
727 if (params->fvek->vk == NULL) {
731 /* volume header info (location and size) */
732 } else if (entry_type == BITLK_ENTRY_TYPE_VOLUME_HEADER) {
733 struct bitlk_entry_header_block entry_header;
734 memcpy(&entry_header,
735 fve_entries + start + BITLK_ENTRY_HEADER_LEN,
736 sizeof(entry_header));
737 params->volume_header_offset = le64_to_cpu(entry_header.offset);
738 params->volume_header_size = le64_to_cpu(entry_header.size);
739 /* volume description (utf-16 string) */
740 } else if (entry_type == BITLK_ENTRY_TYPE_DESCRIPTION) {
741 r = convert_to_utf8(cd, fve_entries + start + BITLK_ENTRY_HEADER_LEN,
742 entry_size - BITLK_ENTRY_HEADER_LEN,
743 &(params->description));
745 BITLK_bitlk_vmk_free(vmk);
759 int BITLK_dump(struct crypt_device *cd, struct device *device, struct bitlk_metadata *params)
761 struct volume_key *vk_p;
762 struct bitlk_vmk *vmk_p;
766 log_std(cd, "Info for BITLK%s device %s.\n", params->togo ? " To Go" : "", device_path(device));
767 log_std(cd, "Version: \t%u\n", params->metadata_version);
768 log_std(cd, "GUID: \t%s\n", params->guid);
769 log_std(cd, "Sector size: \t%u [bytes]\n", params->sector_size);
770 log_std(cd, "Created: \t%s", ctime((time_t *)&(params->creation_time)));
771 log_std(cd, "Description: \t%s\n", params->description);
772 log_std(cd, "Cipher name: \t%s\n", params->cipher);
773 log_std(cd, "Cipher mode: \t%s\n", params->cipher_mode);
774 log_std(cd, "Cipher key: \t%u bits\n", params->key_size);
778 log_std(cd, "Keyslots:\n");
779 vmk_p = params->vmks;
781 log_std(cd, " %d: VMK\n", next_id);
782 if (vmk_p->name != NULL) {
783 log_std(cd, "\tName: \t%s\n", vmk_p->name);
785 log_std(cd, "\tGUID: \t%s\n", vmk_p->guid);
786 log_std(cd, "\tProtection: \t%s\n", get_vmk_protection_string (vmk_p->protection));
787 log_std(cd, "\tSalt: \t");
788 hexprint(cd, (const char *) vmk_p->salt, 16, "");
793 log_std(cd, "\tKey data size:\t%zu [bytes]\n", vk_p->keylength);
800 log_std(cd, " %d: FVEK\n", next_id);
801 log_std(cd, "\tKey data size:\t%zu [bytes]\n", params->fvek->vk->keylength);
805 log_std(cd, "Metadata segments:\n");
807 for (i = 0; i < 3; i++) {
808 log_std(cd, " %d: FVE metadata area\n", i);
809 log_std(cd, "\tOffset: \t%" PRIu64 " [bytes]\n", params->metadata_offset[i]);
810 log_std(cd, "\tSize: \t%d [bytes]\n", BITLK_FVE_METADATA_SIZE);
813 log_std(cd, " %d: Volume header\n", i);
814 log_std(cd, "\tOffset: \t%" PRIu64 " [bytes]\n", params->volume_header_offset);
815 log_std(cd, "\tSize: \t%" PRIu64 " [bytes]\n", params->volume_header_size);
816 log_std(cd, "\tCipher: \t%s-%s\n", params->cipher, params->cipher_mode);
821 /* check if given passphrase can be a recovery key (has right format) and convert it */
822 static int get_recovery_key(struct crypt_device *cd,
823 const char *password,
825 struct volume_key **rc_key)
827 unsigned int i, j = 0;
828 uint16_t parts[BITLK_RECOVERY_PARTS] = {0};
829 char part_str[BITLK_RECOVERY_PART_LEN + 1] = {0};
832 /* check the passphrase it should be:
834 - 8 groups of 6 divided by '-'
835 - each part is a number dividable by 11
837 if (passwordLen != BITLK_RECOVERY_KEY_LEN) {
838 if (passwordLen == BITLK_RECOVERY_KEY_LEN + 1 && password[passwordLen - 1] == '\n') {
839 /* looks like a recovery key with an extra newline, possibly from a key file */
841 log_dbg(cd, "Possible extra EOL stripped from the recovery key.");
846 for (i = BITLK_RECOVERY_PART_LEN; i < passwordLen; i += BITLK_RECOVERY_PART_LEN + 1) {
847 if (password[i] != '-')
851 for (i = 0, j = 0; i < passwordLen; i += BITLK_RECOVERY_PART_LEN + 1, j++) {
852 strncpy(part_str, password + i, BITLK_RECOVERY_PART_LEN);
855 part_num = strtol(part_str, NULL, 10);
856 if ((errno == ERANGE && (part_num == LONG_MAX || part_num == LONG_MIN)) ||
857 (errno != 0 && part_num == 0))
860 if (part_num % 11 != 0)
862 parts[j] = cpu_to_le16(part_num / 11);
865 *rc_key = crypt_alloc_volume_key(16, (const char*) parts);
872 static int parse_external_key_entry(struct crypt_device *cd, const char *data, int start, int end, struct volume_key **vk)
874 uint16_t key_entry_size = 0;
875 uint16_t key_entry_type = 0;
876 uint16_t key_entry_value = 0;
878 const char *key = NULL;
880 while (end - start > 2) {
881 /* size of this entry */
882 memcpy(&key_entry_size, data + start, sizeof(key_entry_size));
883 key_entry_size = le16_to_cpu(key_entry_size);
884 if (key_entry_size == 0)
887 /* type and value of this entry */
888 memcpy(&key_entry_type, data + start + sizeof(key_entry_size), sizeof(key_entry_type));
889 memcpy(&key_entry_value,
890 data + start + sizeof(key_entry_size) + sizeof(key_entry_type),
891 sizeof(key_entry_value));
892 key_entry_type = le16_to_cpu(key_entry_type);
893 key_entry_value = le16_to_cpu(key_entry_value);
895 /* only properties should be in this entry */
896 if (key_entry_type != BITLK_ENTRY_TYPE_PROPERTY) {
897 log_err(cd, _("Unexpected metadata entry type '%u' found when parsing external key."), key_entry_type);
901 if (key_entry_value == BITLK_ENTRY_VALUE_KEY) {
902 key_size = key_entry_size - (BITLK_ENTRY_HEADER_LEN + 4);
903 key = (const char *) data + start + BITLK_ENTRY_HEADER_LEN + 4;
904 *vk = crypt_alloc_volume_key(key_size, key);
908 /* optional "ExternalKey" string, we can safely ignore it */
909 } else if (key_entry_value == BITLK_ENTRY_VALUE_STRING)
912 log_err(cd, _("Unexpected metadata entry value '%u' found when parsing external key."), key_entry_value);
916 start += key_entry_size;
919 /* if we got here we failed to parse the metadata */
923 /* check if given passphrase can be a startup key (has right format) and convert it */
924 static int get_startup_key(struct crypt_device *cd,
925 const char *password,
927 const struct bitlk_vmk *vmk,
928 struct volume_key **su_key)
930 struct bitlk_bek_header bek_header = {0};
931 char guid_buf[UUID_STR_LEN] = {0};
933 uint16_t key_entry_size = 0;
934 uint16_t key_entry_type = 0;
935 uint16_t key_entry_value = 0;
937 if (passwordLen < BITLK_BEK_FILE_HEADER_LEN)
940 memcpy(&bek_header, password, BITLK_BEK_FILE_HEADER_LEN);
942 /* metadata should contain GUID of the VMK this startup key is used for */
943 guid_to_string(&bek_header.guid, guid_buf);
944 if (strcmp(guid_buf, vmk->guid) == 0)
945 log_dbg(cd, "Found matching startup key for VMK %s", vmk->guid);
949 if (bek_header.metadata_version != 1) {
950 log_err(cd, "Unsupported BEK metadata version %" PRIu32 "", bek_header.metadata_version);
954 if (bek_header.metadata_size != passwordLen) {
955 log_err(cd, "Unexpected BEK metadata size %" PRIu32 " does not match BEK file length", bek_header.metadata_size);
959 /* we are expecting exactly one metadata entry starting immediately after the header */
960 memcpy(&key_entry_size, password + BITLK_BEK_FILE_HEADER_LEN, sizeof(key_entry_size));
961 key_entry_size = le16_to_cpu(key_entry_size);
962 if (key_entry_size < BITLK_ENTRY_HEADER_LEN) {
963 log_dbg(cd, "Unexpected metadata entry size %" PRIu16 " when parsing BEK file", key_entry_size);
967 /* type and value of this entry */
968 memcpy(&key_entry_type, password + BITLK_BEK_FILE_HEADER_LEN + sizeof(key_entry_size), sizeof(key_entry_type));
969 memcpy(&key_entry_value,
970 password + BITLK_BEK_FILE_HEADER_LEN + sizeof(key_entry_size) + sizeof(key_entry_type),
971 sizeof(key_entry_value));
972 key_entry_type = le16_to_cpu(key_entry_type);
973 key_entry_value = le16_to_cpu(key_entry_value);
975 if (key_entry_type == BITLK_ENTRY_TYPE_STARTUP_KEY && key_entry_value == BITLK_ENTRY_VALUE_EXTERNAL_KEY) {
976 return parse_external_key_entry(cd, password,
977 BITLK_BEK_FILE_HEADER_LEN + BITLK_ENTRY_HEADER_LEN + BITLK_STARTUP_KEY_HEADER_LEN,
978 passwordLen, su_key);
980 log_err(cd, _("Unexpected metadata entry found when parsing startup key."));
981 log_dbg(cd, "Entry type: %u, entry value: %u", key_entry_type, key_entry_value);
986 static int bitlk_kdf(struct crypt_device *cd,
987 const char *password,
991 struct volume_key **vk)
993 struct bitlk_kdf_data kdf = {};
994 struct crypt_hash *hd = NULL;
996 char *utf16Password = NULL;
1000 memcpy(kdf.salt, salt, 16);
1002 r = crypt_hash_init(&hd, BITLK_KDF_HASH);
1005 len = crypt_hash_size(BITLK_KDF_HASH);
1007 crypt_hash_destroy(hd);
1012 /* passphrase: convert to UTF-16 first, then sha256(sha256(pw)) */
1013 r = passphrase_to_utf16(cd, CONST_CAST(char*)password, passwordLen, &utf16Password);
1017 crypt_hash_write(hd, utf16Password, passwordLen * 2);
1018 r = crypt_hash_final(hd, kdf.initial_sha256, len);
1022 crypt_hash_write(hd, kdf.initial_sha256, len);
1023 r = crypt_hash_final(hd, kdf.initial_sha256, len);
1027 /* recovery passphrase: already converted in #get_recovery_key, now just sha256(rpw) */
1028 crypt_hash_write(hd, password, passwordLen);
1029 r = crypt_hash_final(hd, kdf.initial_sha256, len);
1034 for (i = 0; i < BITLK_KDF_ITERATION_COUNT; i++) {
1035 crypt_hash_write(hd, (const char*) &kdf, sizeof(kdf));
1036 r = crypt_hash_final(hd, kdf.last_sha256, len);
1039 kdf.count = cpu_to_le64(le64_to_cpu(kdf.count) + 1);
1042 *vk = crypt_alloc_volume_key(len, kdf.last_sha256);
1045 crypt_safe_free(utf16Password);
1047 crypt_hash_destroy(hd);
1051 static int decrypt_key(struct crypt_device *cd,
1052 struct volume_key **vk,
1053 struct volume_key *enc_key,
1054 struct volume_key *key,
1055 const uint8_t *tag, size_t tag_size,
1056 const uint8_t *iv, size_t iv_size,
1061 uint16_t key_size = 0;
1063 outbuf = crypt_safe_alloc(enc_key->keylength);
1067 r = crypt_bitlk_decrypt_key(key->key, key->keylength, enc_key->key, outbuf, enc_key->keylength,
1068 (const char*)iv, iv_size, (const char*)tag, tag_size);
1071 log_err(cd, _("This operation is not supported."));
1075 /* key_data has it's size as part of the metadata */
1076 memcpy(&key_size, outbuf, 2);
1077 key_size = le16_to_cpu(key_size);
1078 if (enc_key->keylength != key_size) {
1079 log_err(cd, _("Unexpected key data size."));
1080 log_dbg(cd, "Expected key data size: %zu, got %" PRIu16 "", enc_key->keylength, key_size);
1086 if (is_fvek && strcmp(crypt_get_cipher_mode(cd), "cbc-elephant") == 0 &&
1087 crypt_get_volume_key_size(cd) == 32) {
1088 /* 128bit AES-CBC with Elephant -- key size is 256 bit (2 keys) but key data is 512 bits,
1089 data: 16B CBC key, 16B empty, 16B elephant key, 16B empty */
1090 memcpy(outbuf + 16 + BITLK_OPEN_KEY_METADATA_LEN,
1091 outbuf + 2 * 16 + BITLK_OPEN_KEY_METADATA_LEN, 16);
1092 key_size = 32 + BITLK_OPEN_KEY_METADATA_LEN;
1096 *vk = crypt_alloc_volume_key(key_size - BITLK_OPEN_KEY_METADATA_LEN,
1097 (const char *)(outbuf + BITLK_OPEN_KEY_METADATA_LEN));
1098 r = *vk ? 0 : -ENOMEM;
1100 crypt_safe_free(outbuf);
1104 int BITLK_activate(struct crypt_device *cd,
1106 const char *password,
1108 const struct bitlk_metadata *params,
1115 int num_segments = 0;
1116 struct crypt_dm_active_device dmd = {
1119 struct dm_target *next_segment = NULL;
1120 struct volume_key *open_vmk_key = NULL;
1121 struct volume_key *open_fvek_key = NULL;
1122 struct volume_key *vmk_dec_key = NULL;
1123 struct volume_key *recovery_key = NULL;
1124 const struct bitlk_vmk *next_vmk = NULL;
1125 struct segment segments[MAX_BITLK_SEGMENTS] = {};
1126 struct segment temp;
1127 uint64_t next_start = 0;
1128 uint64_t next_end = 0;
1129 uint64_t last_segment = 0;
1132 if (!params->state) {
1133 log_err(cd, _("This BITLK device is in an unsupported state and cannot be activated."));
1138 if (params->type != BITLK_ENCRYPTION_TYPE_NORMAL) {
1139 log_err(cd, _("BITLK devices with type '%s' cannot be activated."), get_bitlk_type_string(params->type));
1144 next_vmk = params->vmks;
1146 if (next_vmk->protection == BITLK_PROTECTION_PASSPHRASE) {
1147 r = bitlk_kdf(cd, password, passwordLen, false, next_vmk->salt, &vmk_dec_key);
1149 /* something wrong happened, but we still want to check other key slots */
1150 next_vmk = next_vmk->next;
1153 } else if (next_vmk->protection == BITLK_PROTECTION_RECOVERY_PASSPHRASE) {
1154 r = get_recovery_key(cd, password, passwordLen, &recovery_key);
1156 /* something wrong happened, but we still want to check other key slots */
1157 next_vmk = next_vmk->next;
1160 if (recovery_key == NULL) {
1161 /* r = 0 but no key -> given passphrase is not a recovery passphrase */
1163 next_vmk = next_vmk->next;
1166 log_dbg(cd, "Trying to use given password as a recovery key.");
1167 r = bitlk_kdf(cd, recovery_key->key, recovery_key->keylength,
1168 true, next_vmk->salt, &vmk_dec_key);
1169 crypt_free_volume_key(recovery_key);
1172 } else if (next_vmk->protection == BITLK_PROTECTION_STARTUP_KEY) {
1173 r = get_startup_key(cd, password, passwordLen, next_vmk, &vmk_dec_key);
1175 next_vmk = next_vmk->next;
1178 log_dbg(cd, "Trying to use external key found in provided password.");
1180 /* only passphrase, recovery passphrase and startup key VMKs supported right now */
1181 log_dbg(cd, "Skipping %s", get_vmk_protection_string(next_vmk->protection));
1182 next_vmk = next_vmk->next;
1184 /* we need to set error code in case we have only unsupported VMKs */
1189 log_dbg(cd, "Trying to decrypt %s.", get_vmk_protection_string(next_vmk->protection));
1190 r = decrypt_key(cd, &open_vmk_key, next_vmk->vk, vmk_dec_key,
1191 next_vmk->mac_tag, BITLK_VMK_MAC_TAG_SIZE,
1192 next_vmk->nonce, BITLK_NONCE_SIZE, false);
1194 log_dbg(cd, "Failed to decrypt VMK using provided passphrase.");
1195 crypt_free_volume_key(vmk_dec_key);
1198 next_vmk = next_vmk->next;
1201 crypt_free_volume_key(vmk_dec_key);
1203 r = decrypt_key(cd, &open_fvek_key, params->fvek->vk, open_vmk_key,
1204 params->fvek->mac_tag, BITLK_VMK_MAC_TAG_SIZE,
1205 params->fvek->nonce, BITLK_NONCE_SIZE, true);
1207 log_dbg(cd, "Failed to decrypt FVEK using VMK.");
1208 crypt_free_volume_key(open_vmk_key);
1212 crypt_free_volume_key(open_vmk_key);
1216 next_vmk = next_vmk->next;
1220 log_dbg(cd, "No more VMKs to try.");
1224 /* Password verify only */
1226 crypt_free_volume_key(open_fvek_key);
1230 next_vmk = params->vmks;
1232 if (next_vmk->protection == BITLK_PROTECTION_CLEAR_KEY) {
1233 crypt_free_volume_key(open_fvek_key);
1234 log_err(cd, _("Activation of partially decrypted BITLK device is not supported."));
1237 next_vmk = next_vmk->next;
1240 r = device_block_adjust(cd, crypt_data_device(cd), DEV_EXCL,
1241 0, &dmd.size, &dmd.flags);
1243 crypt_free_volume_key(open_fvek_key);
1247 /* there will be always 4 dm-zero segments: 3x metadata, 1x FS header */
1248 for (i = 0; i < 3; i++) {
1249 segments[num_segments].offset = params->metadata_offset[i] / SECTOR_SIZE;
1250 segments[num_segments].length = BITLK_FVE_METADATA_SIZE / SECTOR_SIZE;
1251 segments[num_segments].iv_offset = 0;
1252 segments[num_segments].type = BITLK_SEGTYPE_ZERO;
1255 segments[num_segments].offset = params->volume_header_offset / SECTOR_SIZE;
1256 segments[num_segments].length = params->volume_header_size / SECTOR_SIZE;
1257 segments[num_segments].iv_offset = 0;
1258 segments[num_segments].type = BITLK_SEGTYPE_ZERO;
1261 /* filesystem header (moved from the special location) */
1262 segments[num_segments].offset = 0;
1263 segments[num_segments].length = params->volume_header_size / SECTOR_SIZE;
1264 segments[num_segments].iv_offset = params->volume_header_offset / SECTOR_SIZE;
1265 segments[num_segments].type = BITLK_SEGTYPE_CRYPT;
1268 /* now fill gaps between the dm-zero segments with dm-crypt */
1269 last_segment = params->volume_header_size / SECTOR_SIZE;
1271 next_start = dmd.size;
1272 next_end = dmd.size;
1274 /* start of the next segment: end of the first existing segment after the last added */
1275 for (i = 0; i < num_segments; i++)
1276 if (segments[i].offset + segments[i].length < next_start && segments[i].offset + segments[i].length >= last_segment)
1277 next_start = segments[i].offset + segments[i].length;
1279 /* end of the next segment: start of the next segment after start we found above */
1280 for (i = 0; i < num_segments; i++)
1281 if (segments[i].offset < next_end && segments[i].offset >= next_start)
1282 next_end = segments[i].offset;
1284 /* two zero segments next to each other, just bump the last_segment
1285 so the algorithm moves */
1286 if (next_end - next_start == 0) {
1287 last_segment = next_end + 1;
1291 segments[num_segments].offset = next_start;
1292 segments[num_segments].length = next_end - next_start;
1293 segments[num_segments].iv_offset = next_start;
1294 segments[num_segments].type = BITLK_SEGTYPE_CRYPT;
1295 last_segment = next_end;
1298 if (next_end == dmd.size)
1301 if (num_segments == 10) {
1302 log_dbg(cd, "Failed to calculate number of dm-crypt segments for open.");
1308 /* device mapper needs the segment sorted */
1309 for (i = 0; i < num_segments - 1; i++) {
1311 for (j = i + 1; j < num_segments; j++)
1312 if (segments[j].offset < segments[min].offset)
1316 temp.offset = segments[min].offset;
1317 temp.length = segments[min].length;
1318 temp.iv_offset = segments[min].iv_offset;
1319 temp.type = segments[min].type;
1321 segments[min].offset = segments[i].offset;
1322 segments[min].length = segments[i].length;
1323 segments[min].iv_offset = segments[i].iv_offset;
1324 segments[min].type = segments[i].type;
1326 segments[i].offset = temp.offset;
1327 segments[i].length = temp.length;
1328 segments[i].iv_offset = temp.iv_offset;
1329 segments[i].type = temp.type;
1333 if (params->sector_size != SECTOR_SIZE)
1334 dmd.flags |= CRYPT_ACTIVATE_IV_LARGE_SECTORS;
1336 r = dm_targets_allocate(&dmd.segment, num_segments);
1339 next_segment = &dmd.segment;
1341 for (i = 0; i < num_segments; i++) {
1342 if (segments[i].type == BITLK_SEGTYPE_ZERO)
1343 r = dm_zero_target_set(next_segment,
1345 segments[i].length);
1346 else if (segments[i].type == BITLK_SEGTYPE_CRYPT)
1347 r = dm_crypt_target_set(next_segment,
1350 crypt_data_device(cd),
1352 crypt_get_cipher_spec(cd),
1353 segments[i].iv_offset,
1354 segments[i].iv_offset,
1356 params->sector_size);
1360 next_segment = next_segment->next;
1363 log_dbg(cd, "Trying to activate BITLK on device %s%s%s.",
1364 device_path(crypt_data_device(cd)), name ? " with name " :"", name ?: "");
1366 r = dm_create_device(cd, name, CRYPT_BITLK, &dmd);
1368 dm_flags(cd, DM_CRYPT, &dmt_flags);
1369 if (!strcmp(params->cipher_mode, "cbc-eboiv") && !(dmt_flags & DM_BITLK_EBOIV_SUPPORTED)) {
1370 log_err(cd, _("Cannot activate device, kernel dm-crypt is missing support for BITLK IV."));
1373 if (!strcmp(params->cipher_mode, "cbc-elephant") && !(dmt_flags & DM_BITLK_ELEPHANT_SUPPORTED)) {
1374 log_err(cd, _("Cannot activate device, kernel dm-crypt is missing support for BITLK Elephant diffuser."));
1379 dm_targets_free(cd, &dmd);
1380 crypt_free_volume_key(open_fvek_key);