Imported Upstream version 2.6.1
[platform/upstream/cryptsetup.git] / lib / fvault2 / fvault2.c
1 /*
2  * FVAULT2 (FileVault2-compatible) volume handling
3  *
4  * Copyright (C) 2021-2022 Pavel Tobias
5  *
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.
10  *
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.
15  *
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.
19  */
20
21 #include <errno.h>
22 #include <regex.h>
23 #include <stdio.h>
24 #include <uuid/uuid.h>
25
26 #include "internal.h"
27 #include "fvault2.h"
28
29 /* Core Storage signature/magic; "CS" big-endian */
30 #define FVAULT2_CORE_STORAGE_MAGIC 0x4353
31
32 /* size of the physical volume header in bytes */
33 #define FVAULT2_VOL_HEADER_SIZE 512
34
35 /* size of a single metadata block in bytes */
36 #define FVAULT2_MD_BLOCK_SIZE 8192
37
38 /* maximal offset to read metadata block */
39 #define FVAULT2_MAX_OFF 1024*1024*1024
40
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
47
48 /* sizes of decoded PassphraseWrappedKEKStruct and KEKWrappedVolumeKeyStruct */
49 #define FVAULT2_PWK_SIZE 284
50 #define FVAULT2_KWVK_SIZE 256
51
52 /* size of an AES-128 key */
53 #define FVAULT2_AES_KEY_SIZE 16
54
55 /* size of the volume key and the encrypted metadata decryption key */
56 #define FVAULT2_XTS_KEY_SIZE (FVAULT2_AES_KEY_SIZE * 2)
57
58 /* size of an XTS tweak value */
59 #define FVAULT2_XTS_TWEAK_SIZE 16
60
61 /* size of a binary representation of a UUID */
62 #define FVAULT2_UUID_BIN_SIZE 16
63
64 struct crc32_checksum {
65         uint32_t value;
66         uint32_t seed;
67 } __attribute__((packed));
68
69 struct volume_header {
70         struct crc32_checksum checksum;
71         uint16_t version;
72         uint16_t block_type;
73         uint8_t unknown1[52];
74         uint64_t ph_vol_size;
75         uint8_t unknown2[16];
76         uint16_t magic;
77         uint32_t checksum_algo;
78         uint8_t unknown3[2];
79         uint32_t block_size;
80         uint32_t metadata_size;
81         uint64_t disklbl_blkoff;
82         uint64_t other_md_blkoffs[3];
83         uint8_t unknown4[32];
84         uint32_t key_data_size;
85         uint32_t cipher;
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));
91
92 struct volume_groups_descriptor {
93         uint8_t unknown1[8];
94         uint64_t enc_md_blocks_n;
95         uint8_t unknown2[16];
96         uint64_t enc_md_blkoff;
97 } __attribute__((packed));
98
99 struct metadata_block_header {
100         struct crc32_checksum checksum;
101         uint16_t version;
102         uint16_t block_type;
103         uint8_t unknown1[20];
104         uint64_t block_num;
105         uint8_t unknown2[8];
106         uint32_t block_size;
107         uint8_t unknown3[12];
108 } __attribute__((packed));
109
110 struct metadata_block_0x0011 {
111         struct metadata_block_header header;
112         uint32_t md_size;
113         uint8_t unknown1[4];
114         struct crc32_checksum checksum;
115         uint8_t unknown2[140];
116         uint32_t vol_gr_des_off;
117 } __attribute__((packed));
118
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;
124         uint32_t xml_off;
125         uint32_t xml_size;
126 } __attribute__((packed));
127
128 struct metadata_block_0x001a {
129         struct metadata_block_header header;
130         uint8_t unknown1[64];
131         uint32_t xml_off;
132         uint32_t xml_size;
133 } __attribute__((packed));
134
135 struct metadata_block_0x0305 {
136         struct metadata_block_header header;
137         uint32_t entries_n;
138         uint8_t unknown1[36];
139         uint32_t log_vol_blkoff;
140 } __attribute__((packed));
141
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));
152
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));
158
159 /**
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
164  */
165 static bool _filled_with(
166         uint8_t value,
167         const void *data,
168         size_t data_size)
169 {
170         const uint8_t *data_bytes = data;
171         size_t i;
172
173         for (i = 0; i < data_size; i++)
174                 if (data_bytes[i] != value)
175                         return false;
176
177         return true;
178 }
179
180 /**
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
184  */
185 static int _check_crc(
186         const void *data,
187         size_t data_size)
188 {
189         const size_t crc_size = sizeof(struct crc32_checksum);
190         uint32_t seed;
191         uint32_t value;
192
193         assert(data_size >= crc_size);
194
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)
198                 return -EINVAL;
199
200         if (crypt_crc32c(seed, (const uint8_t *)data + crc_size,
201                         data_size - crc_size) != value)
202                 return -EINVAL;
203
204         return 0;
205 }
206
207 /**
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
215  */
216 static int _unwrap_key(
217         const void *kek,
218         size_t kek_size,
219         const void *key_wrapped,
220         size_t key_wrapped_size,
221         void *key_buf,
222         size_t key_buf_size)
223 {
224         /* Algorithm and notation taken from NIST Special Publication 800-38F:
225         https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf
226
227         This implementation supports only 128-bit KEKs and wrapped keys. */
228
229         int r = 0;
230         struct crypt_cipher *cipher = NULL;
231         void *cipher_in = NULL;
232         void *cipher_out = NULL;
233         uint64_t a;
234         uint64_t r2;
235         uint64_t r3;
236         uint64_t t;
237         uint64_t r2_prev;
238
239         assert(kek_size == 16 && key_wrapped_size == 24 && key_buf_size == 16);
240
241         r = crypt_cipher_init(&cipher, "aes", "ecb", kek, kek_size);
242         if (r < 0)
243                 goto out;
244
245         cipher_in = malloc(16);
246         if (cipher_in == NULL) {
247                 r = -ENOMEM;
248                 goto out;
249         }
250
251         cipher_out = malloc(16);
252         if (cipher_out == NULL) {
253                 r = -ENOMEM;
254                 goto out;
255         }
256
257         /* CHAPTER 6.1, ALGORITHM 2: W^-1(C) */
258
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) */
263
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) */
268                 r2_prev = r2;
269
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;
273
274                 /* A||R2 = CIPH^{-1}_K(...) (see steps 2a, 2b) */
275                 r = crypt_cipher_decrypt(cipher, cipher_in, cipher_out, 16, NULL, 0);
276                 if (r < 0)
277                         goto out;
278                 a = ((uint64_t *)cipher_out)[0];
279                 r2 = ((uint64_t *)cipher_out)[1];
280
281                 /* assign previous R2 (see step 2c) */
282                 r3 = r2_prev;
283         }
284
285         /* note that A||R_1||R_2 holds the result S (see step 3) */
286
287         /* CHAPTER 6.2, ALGORITHM 4: KW-AD(C) */
288
289         /* check whether MSB_{64}(S) (= A) matches ICV1 (see step 3) */
290         if (a != 0xA6A6A6A6A6A6A6A6) {
291                 r = -EPERM;
292                 goto out;
293         }
294
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;
298 out:
299         free(cipher_in);
300         free(cipher_out);
301         if (cipher != NULL)
302                 crypt_cipher_destroy(cipher);
303         return r;
304 }
305
306 /**
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
312  */
313 static int _search_xml(
314         const char *xml,
315         const char *prop_key,
316         const char *prop_type,
317         char **value)
318 {
319         int r = 0;
320         char *pattern = NULL;
321         bool regex_ready = false;
322         regex_t regex;
323         regmatch_t match[2];
324         const char *value_start;
325         size_t value_len;
326
327         if (asprintf(&pattern, "<key>%s</key><%s[^>]*>([^<]+)</%s>",
328                         prop_key, prop_type, prop_type) < 0) {
329                 r = -ENOMEM;
330                 goto out;
331         }
332
333         if (regcomp(&regex, pattern, REG_EXTENDED) != 0) {
334                 r = -EINVAL;
335                 goto out;
336         }
337
338         regex_ready = true;
339
340         if (regexec(&regex, xml, 2, match, 0) != 0) {
341                 r = -EINVAL;
342                 goto out;
343         }
344
345         value_start = xml + match[1].rm_so;
346         value_len = match[1].rm_eo - match[1].rm_so;
347
348         *value = calloc(value_len + 1, 1);
349         if (*value == NULL) {
350                 r = -ENOMEM;
351                 goto out;
352         }
353
354         memcpy(*value, value_start, value_len);
355 out:
356         free(pattern);
357         if (regex_ready)
358                 regfree(&regex);
359         return r;
360 }
361
362 /**
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
369  */
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,
375         uint8_t *wrapped_vk)
376 {
377         int r = 0;
378         char *xml = NULL;
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;
383         size_t decoded_size;
384         uint32_t xml_off = le32_to_cpu(md_block->xml_off);
385         uint32_t xml_size = le32_to_cpu(md_block->xml_size);
386
387         if (xml_off + xml_size > FVAULT2_MD_BLOCK_SIZE)
388                 return -EINVAL;
389
390         xml = strndup((const char *)md_block + xml_off, xml_size);
391         if (xml == NULL)
392                 return -ENOMEM;
393
394         r = _search_xml(xml, "PassphraseWrappedKEKStruct", "data", &pwk_base64);
395         if (r < 0)
396                 goto out;
397         r = crypt_base64_decode((char **)&pwk, &decoded_size, pwk_base64, strlen(pwk_base64));
398         if (r < 0)
399                 goto out;
400         if (decoded_size != FVAULT2_PWK_SIZE) {
401                 r = -EINVAL;
402                 goto out;
403         }
404
405         r = _search_xml(xml, "KEKWrappedVolumeKeyStruct", "data", &kwvk_base64);
406         if (r < 0)
407                 goto out;
408         r = crypt_base64_decode((char **)&kwvk, &decoded_size, kwvk_base64, strlen(kwvk_base64));
409         if (r < 0)
410                 goto out;
411         if (decoded_size != FVAULT2_KWVK_SIZE) {
412                 r = -EINVAL;
413                 goto out;
414         }
415
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);
420 out:
421         free(xml);
422         free(pwk_base64);
423         free(kwvk_base64);
424         free(pwk);
425         free(kwvk);
426         return r;
427 }
428
429 /**
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
433  */
434 static int _reformat_uuid(
435         const char *uuid_in,
436         char *uuid_out)
437 {
438         uint8_t uuid_bin[FVAULT2_UUID_LEN];
439         int r;
440
441         r = uuid_parse(uuid_in, uuid_bin);
442         if (r < 0)
443                 return -EINVAL;
444
445         uuid_unparse(uuid_bin, uuid_out);
446         return 0;
447 }
448
449 /**
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
454  */
455 static int _parse_metadata_block_0x001a(
456         const struct metadata_block_0x001a *md_block,
457         uint64_t *log_vol_size,
458         char *family_uuid)
459 {
460         int r = 0;
461         char *xml = NULL;
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);
466
467         if (xml_off + xml_size > FVAULT2_MD_BLOCK_SIZE)
468                 return -EINVAL;
469
470         xml = strndup((const char *)md_block + xml_off, xml_size);
471         if (xml == NULL)
472                 return -ENOMEM;
473
474         r = _search_xml(xml, "com.apple.corestorage.lv.size", "integer", &log_vol_size_str);
475         if (r < 0)
476                 goto out;
477         *log_vol_size = strtoull(log_vol_size_str, NULL, 16);
478         if (*log_vol_size == 0 || *log_vol_size == ULLONG_MAX) {
479                 r = -EINVAL;
480                 goto out;
481         }
482
483         r = _search_xml(xml, "com.apple.corestorage.lv.familyUUID", "string", &family_uuid_str);
484         if (r < 0)
485                 goto out;
486         r = _reformat_uuid(family_uuid_str, family_uuid);
487         if (r < 0)
488                 goto out;
489 out:
490         free(xml);
491         free(log_vol_size_str);
492         free(family_uuid_str);
493         return r;
494 }
495
496 /**
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
500  */
501 static int _parse_metadata_block_0x0305(
502         const struct metadata_block_0x0305 *md_block,
503         uint32_t *log_vol_blkoff)
504 {
505         *log_vol_blkoff = le32_to_cpu(md_block->log_vol_blkoff);
506         return 0;
507 }
508
509 /**
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
517  */
518 static int _read_volume_header(
519         int devfd,
520         struct crypt_device *cd,
521         uint64_t *block_size,
522         uint64_t *disklbl_blkoff,
523         char *ph_vol_uuid,
524         struct volume_key **enc_md_key)
525 {
526         int r = 0;
527         struct device *dev = crypt_metadata_device(cd);
528         struct volume_header *vol_header = NULL;
529
530         assert(sizeof(*vol_header) == FVAULT2_VOL_HEADER_SIZE);
531
532         vol_header = malloc(FVAULT2_VOL_HEADER_SIZE);
533         if (vol_header == NULL) {
534                 r = -ENOMEM;
535                 goto out;
536         }
537
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);
543                 r = -EIO;
544                 goto out;
545         }
546
547         r = _check_crc(vol_header, FVAULT2_VOL_HEADER_SIZE);
548         if (r < 0) {
549                 log_dbg(cd, "CRC mismatch.");
550                 goto out;
551         }
552
553         if (le16_to_cpu(vol_header->version) != 1) {
554                 log_err(cd, _("Unsupported FVAULT2 version %" PRIu16 "."),
555                         le16_to_cpu(vol_header->version));
556                 r = -EINVAL;
557                 goto out;
558         }
559
560         if (be16_to_cpu(vol_header->magic) != FVAULT2_CORE_STORAGE_MAGIC) {
561                 log_dbg(cd, "Invalid Core Storage magic bytes.");
562                 r = -EINVAL;
563                 goto out;
564         }
565
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));
569                 r = -EINVAL;
570                 goto out;
571         }
572
573         *enc_md_key = crypt_alloc_volume_key(FVAULT2_XTS_KEY_SIZE, NULL);
574         if (*enc_md_key == NULL) {
575                 r = -ENOMEM;
576                 goto out;
577         }
578
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);
585 out:
586         free(vol_header);
587         return r;
588 }
589
590 /**
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
598  */
599 static int _read_disklabel(
600         int devfd,
601         struct crypt_device *cd,
602         uint64_t block_size,
603         uint64_t disklbl_blkoff,
604         uint64_t *enc_md_blkoff,
605         uint64_t *enc_md_blocks_n)
606 {
607         int r = 0;
608         uint64_t off;
609         ssize_t size;
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);
614
615         md_block = malloc(FVAULT2_MD_BLOCK_SIZE);
616         if (md_block == NULL) {
617                 r = -ENOMEM;
618                 goto out;
619         }
620
621         if (uint64_mult_overflow(&off, disklbl_blkoff, block_size) ||
622             off > FVAULT2_MAX_OFF) {
623                 log_dbg(cd, "Device offset overflow.");
624                 r = -EINVAL;
625                 goto out;
626         }
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) {
631                 r = -EIO;
632                 goto out;
633         }
634
635         r = _check_crc(md_block, FVAULT2_MD_BLOCK_SIZE);
636         if (r < 0) {
637                 log_dbg(cd, "CRC mismatch.");
638                 goto out;
639         }
640
641         vol_gr_des = malloc(sizeof(*vol_gr_des));
642         if (vol_gr_des == NULL) {
643                 r = -ENOMEM;
644                 goto out;
645         }
646
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.");
651                 r = -EINVAL;
652                 goto out;
653         }
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) {
658                 r = -EIO;
659                 goto out;
660         }
661
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);
664 out:
665         free(md_block);
666         free(vol_gr_des);
667         return r;
668 }
669
670 /**
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
679  */
680 static int _read_encrypted_metadata(
681         int devfd,
682         struct crypt_device *cd,
683         uint64_t block_size,
684         uint64_t start_blkoff,
685         uint64_t blocks_n,
686         const struct volume_key *key,
687         struct fvault2_params *params)
688 {
689         int r = 0;
690         int status = FVAULT2_ENC_MD_PARSED_NONE;
691         struct device *dev = crypt_metadata_device(cd);
692         struct crypt_cipher *cipher = NULL;
693         void *tweak;
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;
699         off_t off;
700         unsigned int block_type;
701
702         tweak = calloc(FVAULT2_XTS_TWEAK_SIZE, 1);
703         if (tweak == NULL) {
704                 r = -ENOMEM;
705                 goto out;
706         }
707
708         md_block_enc = malloc(FVAULT2_MD_BLOCK_SIZE);
709         if (md_block_enc == NULL) {
710                 r = -ENOMEM;
711                 goto out;
712         }
713
714         md_block = malloc(FVAULT2_MD_BLOCK_SIZE);
715         if (md_block == NULL) {
716                 r = -ENOMEM;
717                 goto out;
718         }
719
720         r = crypt_cipher_init(&cipher, "aes", "xts", key->key, FVAULT2_XTS_KEY_SIZE);
721         if (r < 0)
722                 goto out;
723
724         if (uint64_mult_overflow(&start_off, start_blkoff, block_size) ||
725             start_off > FVAULT2_MAX_OFF) {
726                 log_dbg(cd, "Device offset overflow.");
727                 r = -EINVAL;
728                 goto out;
729         }
730
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.");
736                         r = -EINVAL;
737                         goto out;
738                 }
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) {
743                         r = -EIO;
744                         goto out;
745                 }
746
747                 if (_filled_with(0, md_block_enc, FVAULT2_MD_BLOCK_SIZE))
748                         break;
749
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);
753                 if (r < 0)
754                         goto out;
755
756                 r = _check_crc(md_block, FVAULT2_MD_BLOCK_SIZE);
757                 if (r < 0) {
758                         log_dbg(cd, "CRC mismatch.");
759                         goto out;
760                 }
761
762                 md_block_header = md_block;
763                 block_type = le16_to_cpu(md_block_header->block_type);
764                 switch (block_type) {
765                 case 0x0019:
766                         log_dbg(cd, "Get FVAULT2 metadata block %" PRIu64 " type 0x0019.", i);
767                         r = _parse_metadata_block_0x0019(md_block,
768                                 &params->pbkdf2_iters,
769                                 (uint8_t *)params->pbkdf2_salt,
770                                 (uint8_t *)params->wrapped_kek,
771                                 (uint8_t *)params->wrapped_vk);
772                         if (r < 0)
773                                 goto out;
774                         status |= FVAULT2_ENC_MD_PARSED_0x0019;
775                         break;
776
777                 case 0x001A:
778                         log_dbg(cd, "Get FVAULT2 metadata block %" PRIu64 " type 0x001A.", i);
779                         r = _parse_metadata_block_0x001a(md_block,
780                                 &params->log_vol_size,
781                                 params->family_uuid);
782                         if (r < 0)
783                                 goto out;
784                         status |= FVAULT2_ENC_MD_PARSED_0x001A;
785                         break;
786
787                 case 0x0305:
788                         log_dbg(cd, "Get FVAULT2 metadata block %" PRIu64 " type 0x0305.", i);
789                         r = _parse_metadata_block_0x0305(md_block,
790                                 &log_vol_blkoff);
791                         if (r < 0)
792                                 goto out;
793                         if (uint64_mult_overflow(&params->log_vol_off,
794                             log_vol_blkoff, block_size)) {
795                                 log_dbg(cd, "Device offset overflow.");
796                                 r = -EINVAL;
797                                 goto out;
798                         }
799                         status |= FVAULT2_ENC_MD_PARSED_0x0305;
800                         break;
801                 }
802         }
803
804         if (status != FVAULT2_ENC_MD_PARSED_ALL) {
805                 log_dbg(cd, "Necessary FVAULT2 metadata blocks not found.");
806                 r = -EINVAL;
807                 goto out;
808         }
809 out:
810         free(tweak);
811         free(md_block_enc);
812         free(md_block);
813         if (cipher != NULL)
814                 crypt_cipher_destroy(cipher);
815         return r;
816 }
817
818 /**
819  * Activate device.
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
825  */
826 static int _activate(
827         struct crypt_device *cd,
828         const char *name,
829         struct volume_key *vol_key,
830         const struct fvault2_params *params,
831         uint32_t flags)
832 {
833         int r = 0;
834         char *cipher = NULL;
835         struct crypt_dm_active_device dm_dev = {
836                 .flags = flags,
837                 .size = params->log_vol_size / SECTOR_SIZE
838         };
839
840         r = device_block_adjust(cd, crypt_data_device(cd), DEV_EXCL,
841                 crypt_get_data_offset(cd), &dm_dev.size, &dm_dev.flags);
842         if (r)
843                 return r;
844
845         if (asprintf(&cipher, "%s-%s", params->cipher, params->cipher_mode) < 0)
846                 return -ENOMEM;
847
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));
853
854         if (!r)
855                 r = dm_create_device(cd, name, CRYPT_FVAULT2, &dm_dev);
856
857         dm_targets_free(cd, &dm_dev);
858         free(cipher);
859         return r;
860 }
861
862 int FVAULT2_read_metadata(
863         struct crypt_device *cd,
864         struct fvault2_params *params)
865 {
866         int r = 0;
867         int devfd;
868         uint64_t block_size;
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);
874
875         devfd = device_open(cd, device, O_RDONLY);
876         if (devfd < 0) {
877                 log_err(cd, _("Cannot open device %s."), device_path(device));
878                 return -EIO;
879         }
880
881         r = _read_volume_header(devfd, cd, &block_size, &disklbl_blkoff,
882                 params->ph_vol_uuid, &enc_md_key);
883         if (r < 0)
884                 goto out;
885
886         r = _read_disklabel(devfd, cd, block_size, disklbl_blkoff,
887                 &enc_md_blkoff, &enc_md_blocks_n);
888         if (r < 0)
889                 goto out;
890
891         r = _read_encrypted_metadata(devfd, cd, block_size, enc_md_blkoff,
892                 enc_md_blocks_n, enc_md_key, params);
893         if (r < 0)
894                 goto out;
895
896         params->cipher = "aes";
897         params->cipher_mode = "xts-plain64";
898         params->key_size = FVAULT2_XTS_KEY_SIZE;
899 out:
900         crypt_free_volume_key(enc_md_key);
901         return r;
902 }
903
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)
910 {
911         int r = 0;
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;
916
917         *vol_key = NULL;
918
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);
922                 r = -EINVAL;
923                 goto out;
924         }
925
926         passphrase_key = crypt_alloc_volume_key(FVAULT2_AES_KEY_SIZE, NULL);
927         if (passphrase_key == NULL) {
928                 r = -ENOMEM;
929                 goto out;
930         }
931
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);
935         if (r < 0)
936                 goto out;
937
938         kek = crypt_alloc_volume_key(FVAULT2_AES_KEY_SIZE, NULL);
939         if (kek == NULL) {
940                 r = -ENOMEM;
941                 goto out;
942         }
943
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);
946         if (r < 0)
947                 goto out;
948
949         *vol_key = crypt_alloc_volume_key(FVAULT2_XTS_KEY_SIZE, NULL);
950         if (*vol_key == NULL) {
951                 r = -ENOMEM;
952                 goto out;
953         }
954
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);
957         if (r < 0)
958                 goto out;
959
960         r = crypt_hash_init(&hash, "sha256");
961         if (r < 0)
962                 goto out;
963         r = crypt_hash_write(hash, (*vol_key)->key, FVAULT2_AES_KEY_SIZE);
964         if (r < 0)
965                 goto out;
966         r = crypt_hash_write(hash, (char *)family_uuid_bin,
967                 FVAULT2_UUID_BIN_SIZE);
968         if (r < 0)
969                 goto out;
970         r = crypt_hash_final(hash, (*vol_key)->key + FVAULT2_AES_KEY_SIZE,
971                 FVAULT2_AES_KEY_SIZE);
972         if (r < 0)
973                 goto out;
974 out:
975         crypt_free_volume_key(passphrase_key);
976         crypt_free_volume_key(kek);
977         if (r < 0) {
978                 crypt_free_volume_key(*vol_key);
979                 *vol_key = NULL;
980         }
981         if (hash != NULL)
982                 crypt_hash_destroy(hash);
983         return r;
984 }
985
986 int FVAULT2_dump(
987         struct crypt_device *cd,
988         struct device *device,
989         const struct fvault2_params *params)
990 {
991         log_std(cd, "Header information for FVAULT2 device %s.\n", device_path(device));
992
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);
995
996         log_std(cd, "Logical volume offset:\t%" PRIu64 " [bytes]\n", params->log_vol_off);
997
998         log_std(cd, "Logical volume size:  \t%" PRIu64 " [bytes]\n",
999                 params->log_vol_size);
1000
1001         log_std(cd, "Cipher:               \t%s\n", params->cipher);
1002         log_std(cd, "Cipher mode:          \t%s\n", params->cipher_mode);
1003
1004         log_std(cd, "PBKDF2 iterations:    \t%" PRIu32 "\n", params->pbkdf2_iters);
1005
1006         log_std(cd, "PBKDF2 salt:          \t");
1007         crypt_log_hex(cd, params->pbkdf2_salt, FVAULT2_PBKDF2_SALT_SIZE, " ", 0, NULL);
1008         log_std(cd, "\n");
1009
1010         return 0;
1011 }
1012
1013 int FVAULT2_activate_by_passphrase(
1014         struct crypt_device *cd,
1015         const char *name,
1016         const char *passphrase,
1017         size_t passphrase_len,
1018         const struct fvault2_params *params,
1019         uint32_t flags)
1020 {
1021         int r;
1022         struct volume_key *vol_key = NULL;
1023
1024         r = FVAULT2_get_volume_key(cd, passphrase, passphrase_len, params, &vol_key);
1025         if (r < 0)
1026                 return r;
1027
1028         if (name)
1029             r = _activate(cd, name, vol_key, params, flags);
1030
1031         crypt_free_volume_key(vol_key);
1032         return r;
1033 }
1034
1035 int FVAULT2_activate_by_volume_key(
1036         struct crypt_device *cd,
1037         const char *name,
1038         const char *key,
1039         size_t key_size,
1040         const struct fvault2_params *params,
1041         uint32_t flags)
1042 {
1043         int r = 0;
1044         struct volume_key *vol_key = NULL;
1045
1046         if (key_size != FVAULT2_XTS_KEY_SIZE)
1047                 return -EINVAL;
1048
1049         vol_key = crypt_alloc_volume_key(FVAULT2_XTS_KEY_SIZE, key);
1050         if (vol_key == NULL)
1051                 return -ENOMEM;
1052
1053         r = _activate(cd, name, vol_key, params, flags);
1054
1055         crypt_free_volume_key(vol_key);
1056         return r;
1057 }