2 * FVAULT2 (FileVault2-compatible) volume handling
4 * Copyright (C) 2021-2022 Pavel Tobias
6 * This file is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This file is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this file; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 #include <uuid/uuid.h>
29 /* Core Storage signature/magic; "CS" big-endian */
30 #define FVAULT2_CORE_STORAGE_MAGIC 0x4353
32 /* size of the physical volume header in bytes */
33 #define FVAULT2_VOL_HEADER_SIZE 512
35 /* size of a single metadata block in bytes */
36 #define FVAULT2_MD_BLOCK_SIZE 8192
38 /* maximal offset to read metadata block */
39 #define FVAULT2_MAX_OFF 1024*1024*1024
41 /* encrypted metadata parsing progress flags (see _read_encrypted_metadata) */
42 #define FVAULT2_ENC_MD_PARSED_0x0019 0b001
43 #define FVAULT2_ENC_MD_PARSED_0x001A 0b010
44 #define FVAULT2_ENC_MD_PARSED_0x0305 0b100
45 #define FVAULT2_ENC_MD_PARSED_NONE 0b000
46 #define FVAULT2_ENC_MD_PARSED_ALL 0b111
48 /* sizes of decoded PassphraseWrappedKEKStruct and KEKWrappedVolumeKeyStruct */
49 #define FVAULT2_PWK_SIZE 284
50 #define FVAULT2_KWVK_SIZE 256
52 /* size of an AES-128 key */
53 #define FVAULT2_AES_KEY_SIZE 16
55 /* size of the volume key and the encrypted metadata decryption key */
56 #define FVAULT2_XTS_KEY_SIZE (FVAULT2_AES_KEY_SIZE * 2)
58 /* size of an XTS tweak value */
59 #define FVAULT2_XTS_TWEAK_SIZE 16
61 /* size of a binary representation of a UUID */
62 #define FVAULT2_UUID_BIN_SIZE 16
64 struct crc32_checksum {
67 } __attribute__((packed));
69 struct volume_header {
70 struct crc32_checksum checksum;
77 uint32_t checksum_algo;
80 uint32_t metadata_size;
81 uint64_t disklbl_blkoff;
82 uint64_t other_md_blkoffs[3];
84 uint32_t key_data_size;
86 uint8_t key_data[FVAULT2_AES_KEY_SIZE];
87 uint8_t unknown5[112];
88 uint8_t ph_vol_uuid[FVAULT2_UUID_BIN_SIZE];
89 uint8_t unknown6[192];
90 } __attribute__((packed));
92 struct volume_groups_descriptor {
94 uint64_t enc_md_blocks_n;
96 uint64_t enc_md_blkoff;
97 } __attribute__((packed));
99 struct metadata_block_header {
100 struct crc32_checksum checksum;
103 uint8_t unknown1[20];
107 uint8_t unknown3[12];
108 } __attribute__((packed));
110 struct metadata_block_0x0011 {
111 struct metadata_block_header header;
114 struct crc32_checksum checksum;
115 uint8_t unknown2[140];
116 uint32_t vol_gr_des_off;
117 } __attribute__((packed));
119 struct metadata_block_0x0019 {
120 struct metadata_block_header header;
121 uint8_t unknown1[40];
122 uint32_t xml_comp_size;
123 uint32_t xml_uncomp_size;
126 } __attribute__((packed));
128 struct metadata_block_0x001a {
129 struct metadata_block_header header;
130 uint8_t unknown1[64];
133 } __attribute__((packed));
135 struct metadata_block_0x0305 {
136 struct metadata_block_header header;
138 uint8_t unknown1[36];
139 uint32_t log_vol_blkoff;
140 } __attribute__((packed));
142 struct passphrase_wrapped_kek {
143 uint32_t pbkdf2_salt_type;
144 uint32_t pbkdf2_salt_size;
145 uint8_t pbkdf2_salt[FVAULT2_PBKDF2_SALT_SIZE];
146 uint32_t wrapped_kek_type;
147 uint32_t wrapped_kek_size;
148 uint8_t wrapped_kek[FVAULT2_WRAPPED_KEY_SIZE];
149 uint8_t unknown1[112];
150 uint32_t pbkdf2_iters;
151 } __attribute__((packed));
153 struct kek_wrapped_volume_key {
154 uint32_t wrapped_vk_type;
155 uint32_t wrapped_vk_size;
156 uint8_t wrapped_vk[FVAULT2_WRAPPED_KEY_SIZE];
157 } __attribute__((packed));
160 * Test whether all bytes of a chunk of memory are equal to a constant value.
161 * @param[in] value the value all bytes should be equal to
162 * @param[in] data the tested chunk of memory
163 * @param[in] data_size byte-size of the chunk of memory
165 static bool _filled_with(
170 const uint8_t *data_bytes = data;
173 for (i = 0; i < data_size; i++)
174 if (data_bytes[i] != value)
181 * Assert the validity of the CRC checksum of a chunk of memory.
182 * @param[in] data a chunk of memory starting with a crc32_checksum struct
183 * @param[in] data_size the size of the chunk of memory in bytes
185 static int _check_crc(
189 const size_t crc_size = sizeof(struct crc32_checksum);
193 assert(data_size >= crc_size);
195 value = le32_to_cpu(((const struct crc32_checksum *)data)->value);
196 seed = le32_to_cpu(((const struct crc32_checksum *)data)->seed);
197 if (seed != 0xffffffff)
200 if (crypt_crc32c(seed, (const uint8_t *)data + crc_size,
201 data_size - crc_size) != value)
208 * Unwrap an AES-wrapped key.
209 * @param[in] kek the KEK with which the key has been wrapped
210 * @param[in] kek_size the size of the KEK in bytes
211 * @param[in] key_wrapped the wrapped key
212 * @param[in] key_wrapped_size the size of the wrapped key in bytes
213 * @param[out] key_buf key an output buffer for the unwrapped key
214 * @param[in] key_buf_size the size of the output buffer in bytes
216 static int _unwrap_key(
219 const void *key_wrapped,
220 size_t key_wrapped_size,
224 /* Algorithm and notation taken from NIST Special Publication 800-38F:
225 https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf
227 This implementation supports only 128-bit KEKs and wrapped keys. */
230 struct crypt_cipher *cipher = NULL;
231 void *cipher_in = NULL;
232 void *cipher_out = NULL;
239 assert(kek_size == 16 && key_wrapped_size == 24 && key_buf_size == 16);
241 r = crypt_cipher_init(&cipher, "aes", "ecb", kek, kek_size);
245 cipher_in = malloc(16);
246 if (cipher_in == NULL) {
251 cipher_out = malloc(16);
252 if (cipher_out == NULL) {
257 /* CHAPTER 6.1, ALGORITHM 2: W^-1(C) */
259 /* initialize variables */
260 a = ((const uint64_t *)key_wrapped)[0]; /* A = C_1 (see step 1c) */
261 r2 = ((const uint64_t *)key_wrapped)[1]; /* R_1 = C_2 (see step 1d) */
262 r3 = ((const uint64_t *)key_wrapped)[2]; /* R_2 = C_3 (see step 1d) */
264 /* calculate intermediate values for each t = s, ..., 1 (see step 2),
265 where s = 6 * (n - 1) (see step 1a) */
266 for (t = 6 * (3 - 1); t > 0; t--) {
267 /* store current R2 for later assignment (see step 2c) */
270 /* prepare input for CIPH^{-1}_K (see steps 2a, 2b) */
271 ((uint64_t *)cipher_in)[0] = a ^ cpu_to_be64(t);
272 ((uint64_t *)cipher_in)[1] = r3;
274 /* A||R2 = CIPH^{-1}_K(...) (see steps 2a, 2b) */
275 r = crypt_cipher_decrypt(cipher, cipher_in, cipher_out, 16, NULL, 0);
278 a = ((uint64_t *)cipher_out)[0];
279 r2 = ((uint64_t *)cipher_out)[1];
281 /* assign previous R2 (see step 2c) */
285 /* note that A||R_1||R_2 holds the result S (see step 3) */
287 /* CHAPTER 6.2, ALGORITHM 4: KW-AD(C) */
289 /* check whether MSB_{64}(S) (= A) matches ICV1 (see step 3) */
290 if (a != 0xA6A6A6A6A6A6A6A6) {
295 /* return LSB_{128}(S) (= R_1||R_2) (see step 4) */
296 ((uint64_t *)key_buf)[0] = r2;
297 ((uint64_t *)key_buf)[1] = r3;
302 crypt_cipher_destroy(cipher);
307 * Search XML plist data for a property and return its value.
308 * @param[in] xml a 0-terminated string containing the XML plist data
309 * @param[in] prop_key a 0-terminated string with the seeked property's key
310 * @param[in] prop_type a 0-terminated string with the seeked property's type
311 * @param[out] value a 0-terminated string with the found property's value
313 static int _search_xml(
315 const char *prop_key,
316 const char *prop_type,
320 char *pattern = NULL;
321 bool regex_ready = false;
324 const char *value_start;
327 if (asprintf(&pattern, "<key>%s</key><%s[^>]*>([^<]+)</%s>",
328 prop_key, prop_type, prop_type) < 0) {
333 if (regcomp(®ex, pattern, REG_EXTENDED) != 0) {
340 if (regexec(®ex, xml, 2, match, 0) != 0) {
345 value_start = xml + match[1].rm_so;
346 value_len = match[1].rm_eo - match[1].rm_so;
348 *value = calloc(value_len + 1, 1);
349 if (*value == NULL) {
354 memcpy(*value, value_start, value_len);
363 * Extract relevant info from a metadata block of type 0x0019.
364 * @param[in] md_block the pre-read and decrypted metadata block
365 * @param[out] pbkdf2_iters number of PBKDF2 iterations
366 * @param[out] pbkdf2_salt PBKDF2 salt (intermt. key derivation from passphrase)
367 * @param[out] wrapped_kek KEK AES-wrapped with passphrase-derived key
368 * @param[out] wrapped_vk volume key AES-wrapped with KEK
370 static int _parse_metadata_block_0x0019(
371 const struct metadata_block_0x0019 *md_block,
372 uint32_t *pbkdf2_iters,
373 uint8_t *pbkdf2_salt,
374 uint8_t *wrapped_kek,
379 char *pwk_base64 = NULL;
380 char *kwvk_base64 = NULL;
381 struct passphrase_wrapped_kek *pwk = NULL;
382 struct kek_wrapped_volume_key *kwvk = NULL;
384 uint32_t xml_off = le32_to_cpu(md_block->xml_off);
385 uint32_t xml_size = le32_to_cpu(md_block->xml_size);
387 if (xml_off + xml_size > FVAULT2_MD_BLOCK_SIZE)
390 xml = strndup((const char *)md_block + xml_off, xml_size);
394 r = _search_xml(xml, "PassphraseWrappedKEKStruct", "data", &pwk_base64);
397 r = crypt_base64_decode((char **)&pwk, &decoded_size, pwk_base64, strlen(pwk_base64));
400 if (decoded_size != FVAULT2_PWK_SIZE) {
405 r = _search_xml(xml, "KEKWrappedVolumeKeyStruct", "data", &kwvk_base64);
408 r = crypt_base64_decode((char **)&kwvk, &decoded_size, kwvk_base64, strlen(kwvk_base64));
411 if (decoded_size != FVAULT2_KWVK_SIZE) {
416 *pbkdf2_iters = le32_to_cpu(pwk->pbkdf2_iters);
417 memcpy(pbkdf2_salt, pwk->pbkdf2_salt, FVAULT2_PBKDF2_SALT_SIZE);
418 memcpy(wrapped_kek, pwk->wrapped_kek, FVAULT2_WRAPPED_KEY_SIZE);
419 memcpy(wrapped_vk, kwvk->wrapped_vk, FVAULT2_WRAPPED_KEY_SIZE);
430 * Validate a UUID string and reformat it to match system defaults.
431 * @param[in] uuid_in the original UUID string
432 * @param[out] uuid_out the reformatted UUID string
434 static int _reformat_uuid(
438 uint8_t uuid_bin[FVAULT2_UUID_LEN];
441 r = uuid_parse(uuid_in, uuid_bin);
445 uuid_unparse(uuid_bin, uuid_out);
450 * Extract relevant info from a metadata block of type 0x001A.
451 * @param[in] md_block the pre-read and decrypted metadata block
452 * @param[out] log_vol_size encrypted logical volume size in bytes
453 * @param[out] family_uuid logical volume family UUID
455 static int _parse_metadata_block_0x001a(
456 const struct metadata_block_0x001a *md_block,
457 uint64_t *log_vol_size,
462 char *log_vol_size_str = NULL;
463 char *family_uuid_str = NULL;
464 uint32_t xml_off = le32_to_cpu(md_block->xml_off);
465 uint32_t xml_size = le32_to_cpu(md_block->xml_size);
467 if (xml_off + xml_size > FVAULT2_MD_BLOCK_SIZE)
470 xml = strndup((const char *)md_block + xml_off, xml_size);
474 r = _search_xml(xml, "com.apple.corestorage.lv.size", "integer", &log_vol_size_str);
477 *log_vol_size = strtoull(log_vol_size_str, NULL, 16);
478 if (*log_vol_size == 0 || *log_vol_size == ULLONG_MAX) {
483 r = _search_xml(xml, "com.apple.corestorage.lv.familyUUID", "string", &family_uuid_str);
486 r = _reformat_uuid(family_uuid_str, family_uuid);
491 free(log_vol_size_str);
492 free(family_uuid_str);
497 * Extract relevant info from a metadata block of type 0x0305.
498 * @param[in] md_block the pre-read and decrypted metadata block
499 * @param[out] log_vol_blkoff block-offset of the encrypted logical volume
501 static int _parse_metadata_block_0x0305(
502 const struct metadata_block_0x0305 *md_block,
503 uint32_t *log_vol_blkoff)
505 *log_vol_blkoff = le32_to_cpu(md_block->log_vol_blkoff);
510 * Extract relevant info from the physical volume header.
511 * @param[in] devfd opened device file descriptor
512 * @param[in] cd crypt_device passed into FVAULT2_read_metadata
513 * @param[out] block_size used to compute byte-offsets from block-offsets
514 * @param[out] disklbl_blkoff block-offset of the disk label block
515 * @param[out] ph_vol_uuid physical volume UUID
516 * @param[out] enc_md_key AES-XTS key used to decrypt the encrypted metadata
518 static int _read_volume_header(
520 struct crypt_device *cd,
521 uint64_t *block_size,
522 uint64_t *disklbl_blkoff,
524 struct volume_key **enc_md_key)
527 struct device *dev = crypt_metadata_device(cd);
528 struct volume_header *vol_header = NULL;
530 assert(sizeof(*vol_header) == FVAULT2_VOL_HEADER_SIZE);
532 vol_header = malloc(FVAULT2_VOL_HEADER_SIZE);
533 if (vol_header == NULL) {
538 log_dbg(cd, "Reading FVAULT2 volume header of size %u bytes.", FVAULT2_VOL_HEADER_SIZE);
539 if (read_blockwise(devfd, device_block_size(cd, dev),
540 device_alignment(dev), vol_header,
541 FVAULT2_VOL_HEADER_SIZE) != FVAULT2_VOL_HEADER_SIZE) {
542 log_err(cd, _("Could not read %u bytes of volume header."), FVAULT2_VOL_HEADER_SIZE);
547 r = _check_crc(vol_header, FVAULT2_VOL_HEADER_SIZE);
549 log_dbg(cd, "CRC mismatch.");
553 if (le16_to_cpu(vol_header->version) != 1) {
554 log_err(cd, _("Unsupported FVAULT2 version %" PRIu16 "."),
555 le16_to_cpu(vol_header->version));
560 if (be16_to_cpu(vol_header->magic) != FVAULT2_CORE_STORAGE_MAGIC) {
561 log_dbg(cd, "Invalid Core Storage magic bytes.");
566 if (le32_to_cpu(vol_header->key_data_size) != FVAULT2_AES_KEY_SIZE) {
567 log_dbg(cd, "Unsupported AES key size: %" PRIu32 " bytes.",
568 le32_to_cpu(vol_header->key_data_size));
573 *enc_md_key = crypt_alloc_volume_key(FVAULT2_XTS_KEY_SIZE, NULL);
574 if (*enc_md_key == NULL) {
579 *block_size = le32_to_cpu(vol_header->block_size);
580 *disklbl_blkoff = le64_to_cpu(vol_header->disklbl_blkoff);
581 uuid_unparse(vol_header->ph_vol_uuid, ph_vol_uuid);
582 memcpy((*enc_md_key)->key, vol_header->key_data, FVAULT2_AES_KEY_SIZE);
583 memcpy((*enc_md_key)->key + FVAULT2_AES_KEY_SIZE,
584 vol_header->ph_vol_uuid, FVAULT2_AES_KEY_SIZE);
591 * Extract info from the disk label block and the volume groups descriptor.
592 * @param[in] devfd opened device file descriptor
593 * @param[in] cd crypt_device passed into FVAULT2_read_metadata
594 * @param[in] block_size used to compute byte-offsets from block-offsets
595 * @param[in] disklbl_blkoff block-offset of the disk label block
596 * @param[out] enc_md_blkoff block-offset of the encrypted metadata
597 * @param[out] enc_md_blocks_n total count of encrypted metadata blocks
599 static int _read_disklabel(
601 struct crypt_device *cd,
603 uint64_t disklbl_blkoff,
604 uint64_t *enc_md_blkoff,
605 uint64_t *enc_md_blocks_n)
610 void *md_block = NULL;
611 struct metadata_block_0x0011 *md_block_11;
612 struct volume_groups_descriptor *vol_gr_des = NULL;
613 struct device *dev = crypt_metadata_device(cd);
615 md_block = malloc(FVAULT2_MD_BLOCK_SIZE);
616 if (md_block == NULL) {
621 if (uint64_mult_overflow(&off, disklbl_blkoff, block_size) ||
622 off > FVAULT2_MAX_OFF) {
623 log_dbg(cd, "Device offset overflow.");
627 size = FVAULT2_MD_BLOCK_SIZE;
628 log_dbg(cd, "Reading FVAULT2 disk label header of size %zu bytes.", size);
629 if (read_lseek_blockwise(devfd, device_block_size(cd, dev),
630 device_alignment(dev), md_block, size, off) != size) {
635 r = _check_crc(md_block, FVAULT2_MD_BLOCK_SIZE);
637 log_dbg(cd, "CRC mismatch.");
641 vol_gr_des = malloc(sizeof(*vol_gr_des));
642 if (vol_gr_des == NULL) {
647 md_block_11 = md_block;
648 off += le32_to_cpu(md_block_11->vol_gr_des_off);
649 if (off > FVAULT2_MAX_OFF) {
650 log_dbg(cd, "Device offset overflow.");
654 size = sizeof(struct volume_groups_descriptor);
655 log_dbg(cd, "Reading FVAULT2 volume groups descriptor of size %zu bytes.", size);
656 if (read_lseek_blockwise(devfd, device_block_size(cd, dev),
657 device_alignment(dev), vol_gr_des, size, off) != size) {
662 *enc_md_blkoff = le64_to_cpu(vol_gr_des->enc_md_blkoff);
663 *enc_md_blocks_n = le64_to_cpu(vol_gr_des->enc_md_blocks_n);
671 * Extract info from relevant encrypted metadata blocks.
672 * @param[in] devfd opened device file descriptor
673 * @param[in] cd crypt_device passed into FVAULT2_read_metadata
674 * @param[in] block_size used to compute byte-offsets from block-offsets
675 * @param[in] start_blkoff block-offset of the start of the encrypted metadata
676 * @param[in] blocks_n total count of encrypted metadata blocks
677 * @param[in] key AES-XTS key for decryption
678 * @param[out] params decryption parameters struct to fill
680 static int _read_encrypted_metadata(
682 struct crypt_device *cd,
684 uint64_t start_blkoff,
686 const struct volume_key *key,
687 struct fvault2_params *params)
690 int status = FVAULT2_ENC_MD_PARSED_NONE;
691 struct device *dev = crypt_metadata_device(cd);
692 struct crypt_cipher *cipher = NULL;
694 void *md_block_enc = NULL;
695 void *md_block = NULL;
696 struct metadata_block_header *md_block_header;
697 uint32_t log_vol_blkoff;
698 uint64_t i, start_off;
700 unsigned int block_type;
702 tweak = calloc(FVAULT2_XTS_TWEAK_SIZE, 1);
708 md_block_enc = malloc(FVAULT2_MD_BLOCK_SIZE);
709 if (md_block_enc == NULL) {
714 md_block = malloc(FVAULT2_MD_BLOCK_SIZE);
715 if (md_block == NULL) {
720 r = crypt_cipher_init(&cipher, "aes", "xts", key->key, FVAULT2_XTS_KEY_SIZE);
724 if (uint64_mult_overflow(&start_off, start_blkoff, block_size) ||
725 start_off > FVAULT2_MAX_OFF) {
726 log_dbg(cd, "Device offset overflow.");
731 log_dbg(cd, "Reading FVAULT2 encrypted metadata blocks.");
732 for (i = 0; i < blocks_n; i++) {
733 off = start_off + i * FVAULT2_MD_BLOCK_SIZE;
734 if (off > FVAULT2_MAX_OFF) {
735 log_dbg(cd, "Device offset overflow.");
739 if (read_lseek_blockwise(devfd, device_block_size(cd, dev),
740 device_alignment(dev), md_block_enc,
741 FVAULT2_MD_BLOCK_SIZE, off)
742 != FVAULT2_MD_BLOCK_SIZE) {
747 if (_filled_with(0, md_block_enc, FVAULT2_MD_BLOCK_SIZE))
750 *(uint64_t *)tweak = cpu_to_le64(i);
751 r = crypt_cipher_decrypt(cipher, md_block_enc, md_block,
752 FVAULT2_MD_BLOCK_SIZE, tweak, FVAULT2_XTS_TWEAK_SIZE);
756 r = _check_crc(md_block, FVAULT2_MD_BLOCK_SIZE);
758 log_dbg(cd, "CRC mismatch.");
762 md_block_header = md_block;
763 block_type = le16_to_cpu(md_block_header->block_type);
764 switch (block_type) {
766 log_dbg(cd, "Get FVAULT2 metadata block %" PRIu64 " type 0x0019.", i);
767 r = _parse_metadata_block_0x0019(md_block,
768 ¶ms->pbkdf2_iters,
769 (uint8_t *)params->pbkdf2_salt,
770 (uint8_t *)params->wrapped_kek,
771 (uint8_t *)params->wrapped_vk);
774 status |= FVAULT2_ENC_MD_PARSED_0x0019;
778 log_dbg(cd, "Get FVAULT2 metadata block %" PRIu64 " type 0x001A.", i);
779 r = _parse_metadata_block_0x001a(md_block,
780 ¶ms->log_vol_size,
781 params->family_uuid);
784 status |= FVAULT2_ENC_MD_PARSED_0x001A;
788 log_dbg(cd, "Get FVAULT2 metadata block %" PRIu64 " type 0x0305.", i);
789 r = _parse_metadata_block_0x0305(md_block,
793 if (uint64_mult_overflow(¶ms->log_vol_off,
794 log_vol_blkoff, block_size)) {
795 log_dbg(cd, "Device offset overflow.");
799 status |= FVAULT2_ENC_MD_PARSED_0x0305;
804 if (status != FVAULT2_ENC_MD_PARSED_ALL) {
805 log_dbg(cd, "Necessary FVAULT2 metadata blocks not found.");
814 crypt_cipher_destroy(cipher);
820 * @param[in] cd crypt_device struct passed into FVAULT2_activate_by_*
821 * @param[in] name name of the mapped device
822 * @param[in] vol_key the pre-derived AES-XTS volume key
823 * @param[in] params logical volume decryption parameters
824 * @param[in] flags flags assigned to the crypt_dm_active_device struct
826 static int _activate(
827 struct crypt_device *cd,
829 struct volume_key *vol_key,
830 const struct fvault2_params *params,
835 struct crypt_dm_active_device dm_dev = {
837 .size = params->log_vol_size / SECTOR_SIZE
840 r = device_block_adjust(cd, crypt_data_device(cd), DEV_EXCL,
841 crypt_get_data_offset(cd), &dm_dev.size, &dm_dev.flags);
845 if (asprintf(&cipher, "%s-%s", params->cipher, params->cipher_mode) < 0)
848 r = dm_crypt_target_set(&dm_dev.segment, 0, dm_dev.size,
849 crypt_data_device(cd), vol_key, cipher,
850 crypt_get_iv_offset(cd), crypt_get_data_offset(cd),
851 crypt_get_integrity(cd), crypt_get_integrity_tag_size(cd),
852 crypt_get_sector_size(cd));
855 r = dm_create_device(cd, name, CRYPT_FVAULT2, &dm_dev);
857 dm_targets_free(cd, &dm_dev);
862 int FVAULT2_read_metadata(
863 struct crypt_device *cd,
864 struct fvault2_params *params)
869 uint64_t disklbl_blkoff;
870 uint64_t enc_md_blkoff;
871 uint64_t enc_md_blocks_n;
872 struct volume_key *enc_md_key = NULL;
873 struct device *device = crypt_metadata_device(cd);
875 devfd = device_open(cd, device, O_RDONLY);
877 log_err(cd, _("Cannot open device %s."), device_path(device));
881 r = _read_volume_header(devfd, cd, &block_size, &disklbl_blkoff,
882 params->ph_vol_uuid, &enc_md_key);
886 r = _read_disklabel(devfd, cd, block_size, disklbl_blkoff,
887 &enc_md_blkoff, &enc_md_blocks_n);
891 r = _read_encrypted_metadata(devfd, cd, block_size, enc_md_blkoff,
892 enc_md_blocks_n, enc_md_key, params);
896 params->cipher = "aes";
897 params->cipher_mode = "xts-plain64";
898 params->key_size = FVAULT2_XTS_KEY_SIZE;
900 crypt_free_volume_key(enc_md_key);
904 int FVAULT2_get_volume_key(
905 struct crypt_device *cd,
906 const char *passphrase,
907 size_t passphrase_len,
908 const struct fvault2_params *params,
909 struct volume_key **vol_key)
912 uint8_t family_uuid_bin[FVAULT2_UUID_BIN_SIZE];
913 struct volume_key *passphrase_key = NULL;
914 struct volume_key *kek = NULL;
915 struct crypt_hash *hash = NULL;
919 if (uuid_parse(params->family_uuid, family_uuid_bin) < 0) {
920 log_dbg(cd, "Could not parse logical volume family UUID: %s.",
921 params->family_uuid);
926 passphrase_key = crypt_alloc_volume_key(FVAULT2_AES_KEY_SIZE, NULL);
927 if (passphrase_key == NULL) {
932 r = crypt_pbkdf("pbkdf2", "sha256", passphrase, passphrase_len,
933 params->pbkdf2_salt, FVAULT2_PBKDF2_SALT_SIZE, passphrase_key->key,
934 FVAULT2_AES_KEY_SIZE, params->pbkdf2_iters, 0, 0);
938 kek = crypt_alloc_volume_key(FVAULT2_AES_KEY_SIZE, NULL);
944 r = _unwrap_key(passphrase_key->key, FVAULT2_AES_KEY_SIZE, params->wrapped_kek,
945 FVAULT2_WRAPPED_KEY_SIZE, kek->key, FVAULT2_AES_KEY_SIZE);
949 *vol_key = crypt_alloc_volume_key(FVAULT2_XTS_KEY_SIZE, NULL);
950 if (*vol_key == NULL) {
955 r = _unwrap_key(kek->key, FVAULT2_AES_KEY_SIZE, params->wrapped_vk,
956 FVAULT2_WRAPPED_KEY_SIZE, (*vol_key)->key, FVAULT2_AES_KEY_SIZE);
960 r = crypt_hash_init(&hash, "sha256");
963 r = crypt_hash_write(hash, (*vol_key)->key, FVAULT2_AES_KEY_SIZE);
966 r = crypt_hash_write(hash, (char *)family_uuid_bin,
967 FVAULT2_UUID_BIN_SIZE);
970 r = crypt_hash_final(hash, (*vol_key)->key + FVAULT2_AES_KEY_SIZE,
971 FVAULT2_AES_KEY_SIZE);
975 crypt_free_volume_key(passphrase_key);
976 crypt_free_volume_key(kek);
978 crypt_free_volume_key(*vol_key);
982 crypt_hash_destroy(hash);
987 struct crypt_device *cd,
988 struct device *device,
989 const struct fvault2_params *params)
991 log_std(cd, "Header information for FVAULT2 device %s.\n", device_path(device));
993 log_std(cd, "Physical volume UUID: \t%s\n", params->ph_vol_uuid);
994 log_std(cd, "Family UUID: \t%s\n", params->family_uuid);
996 log_std(cd, "Logical volume offset:\t%" PRIu64 " [bytes]\n", params->log_vol_off);
998 log_std(cd, "Logical volume size: \t%" PRIu64 " [bytes]\n",
999 params->log_vol_size);
1001 log_std(cd, "Cipher: \t%s\n", params->cipher);
1002 log_std(cd, "Cipher mode: \t%s\n", params->cipher_mode);
1004 log_std(cd, "PBKDF2 iterations: \t%" PRIu32 "\n", params->pbkdf2_iters);
1006 log_std(cd, "PBKDF2 salt: \t");
1007 crypt_log_hex(cd, params->pbkdf2_salt, FVAULT2_PBKDF2_SALT_SIZE, " ", 0, NULL);
1013 int FVAULT2_activate_by_passphrase(
1014 struct crypt_device *cd,
1016 const char *passphrase,
1017 size_t passphrase_len,
1018 const struct fvault2_params *params,
1022 struct volume_key *vol_key = NULL;
1024 r = FVAULT2_get_volume_key(cd, passphrase, passphrase_len, params, &vol_key);
1029 r = _activate(cd, name, vol_key, params, flags);
1031 crypt_free_volume_key(vol_key);
1035 int FVAULT2_activate_by_volume_key(
1036 struct crypt_device *cd,
1040 const struct fvault2_params *params,
1044 struct volume_key *vol_key = NULL;
1046 if (key_size != FVAULT2_XTS_KEY_SIZE)
1049 vol_key = crypt_alloc_volume_key(FVAULT2_XTS_KEY_SIZE, key);
1050 if (vol_key == NULL)
1053 r = _activate(cd, name, vol_key, params, flags);
1055 crypt_free_volume_key(vol_key);