Coverage Report

Created: 2025-12-10 06:24

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cryptsetup/lib/bitlk/bitlk.c
Line
Count
Source
1
// SPDX-License-Identifier: LGPL-2.1-or-later
2
/*
3
 * BITLK (BitLocker-compatible) volume handling
4
 *
5
 * Copyright (C) 2019-2025 Red Hat, Inc. All rights reserved.
6
 * Copyright (C) 2019-2025 Milan Broz
7
 * Copyright (C) 2019-2025 Vojtech Trefny
8
 */
9
10
#include <errno.h>
11
#include <string.h>
12
#include <uuid/uuid.h>
13
#include <time.h>
14
#include <limits.h>
15
16
#include "bitlk.h"
17
#include "internal.h"
18
19
577
#define BITLK_BOOTCODE_V1 "\xeb\x52\x90"
20
576
#define BITLK_BOOTCODE_V2 "\xeb\x58\x90"
21
2.50k
#define BITLK_SIGNATURE "-FVE-FS-"
22
871
#define BITLK_SIGNATURE_TOGO "MSWIN4.1"
23
561
#define BITLK_HEADER_METADATA_OFFSET 160
24
16
#define BITLK_HEADER_METADATA_OFFSET_TOGO 424
25
26
/* FVE metadata header is split into two parts */
27
0
#define BITLK_FVE_METADATA_BLOCK_HEADER_LEN 64
28
0
#define BITLK_FVE_METADATA_HEADER_LEN 48
29
0
#define BITLK_FVE_METADATA_HEADERS_LEN BITLK_FVE_METADATA_BLOCK_HEADER_LEN + BITLK_FVE_METADATA_HEADER_LEN
30
31
/* total size of the FVE area (64 KiB) */
32
676
#define BITLK_FVE_METADATA_SIZE 64 * 1024
33
34
0
#define BITLK_ENTRY_HEADER_LEN 8
35
0
#define BITLK_VMK_HEADER_LEN 28
36
37
0
#define BITLK_OPEN_KEY_METADATA_LEN 12
38
39
0
#define BITLK_RECOVERY_KEY_LEN 55
40
#define BITLK_RECOVERY_PARTS 8
41
0
#define BITLK_RECOVERY_PART_LEN 6
42
43
0
#define BITLK_BEK_FILE_HEADER_LEN 48
44
0
#define BITLK_STARTUP_KEY_HEADER_LEN 24
45
46
0
#define BITLK_KDF_HASH "sha256"
47
0
#define BITLK_KDF_ITERATION_COUNT 0x100000
48
49
/* maximum number of segments for the DM device */
50
#define MAX_BITLK_SEGMENTS 10
51
52
/* January 1, 1970 as MS file time */
53
0
#define EPOCH_AS_FILETIME 116444736000000000
54
0
#define HUNDREDS_OF_NANOSECONDS 10000000
55
56
/* not available in older version of libuuid */
57
#ifndef UUID_STR_LEN
58
#define UUID_STR_LEN  37
59
#endif
60
61
/* known types of GUIDs from the BITLK superblock */
62
const uint8_t BITLK_GUID_NORMAL[16] = { 0x3b, 0xd6, 0x67, 0x49, 0x29, 0x2e, 0xd8, 0x4a,
63
          0x83, 0x99, 0xf6, 0xa3, 0x39, 0xe3, 0xd0, 0x01 };
64
const uint8_t BITLK_GUID_EOW[16] = { 0x3b, 0x4d, 0xa8, 0x92, 0x80, 0xdd, 0x0e, 0x4d,
65
             0x9e, 0x4e, 0xb1, 0xe3, 0x28, 0x4e, 0xae, 0xd8 };
66
67
/* taken from libfdisk gpt.c -- TODO: this is a good candidate for adding to libuuid */
68
struct bitlk_guid {
69
  uint32_t   time_low;
70
  uint16_t   time_mid;
71
  uint16_t   time_hi_and_version;
72
  uint8_t    clock_seq_hi;
73
  uint8_t    clock_seq_low;
74
  uint8_t    node[6];
75
} __attribute__ ((packed));
76
77
0
static void swap_guid(struct bitlk_guid *guid) {
78
0
  guid->time_low = swab32(guid->time_low);
79
0
  guid->time_mid = swab16(guid->time_mid);
80
0
  guid->time_hi_and_version = swab16(guid->time_hi_and_version);
81
0
}
82
83
0
static void guid_to_string(struct bitlk_guid *guid, char *out) {
84
0
  swap_guid(guid);
85
0
  uuid_unparse((unsigned char *) guid, out);
86
0
}
87
88
typedef enum {
89
  BITLK_SEGTYPE_CRYPT,
90
  BITLK_SEGTYPE_ZERO,
91
} BitlkSegmentType;
92
93
struct segment {
94
  uint64_t offset;
95
  uint64_t length;
96
  uint64_t iv_offset;
97
  BitlkSegmentType type;
98
};
99
100
struct bitlk_signature {
101
  uint8_t boot_code[3];
102
  uint8_t signature[8];
103
  uint16_t sector_size;
104
} __attribute__ ((packed));
105
106
struct bitlk_superblock {
107
  struct bitlk_guid guid;
108
  uint64_t fve_offset[3];
109
} __attribute__ ((packed));
110
111
struct bitlk_fve_metadata {
112
  /* FVE metadata block header */
113
  uint8_t signature[8];
114
  /* size of this block (in 16-byte units) */
115
  uint16_t fve_size;
116
  uint16_t fve_version;
117
  uint16_t curr_state;
118
  uint16_t next_state;
119
  uint64_t volume_size;
120
  uint32_t unknown2;
121
  uint32_t volume_header_size;
122
  uint64_t fve_offset[3];
123
  uint64_t volume_header_offset;
124
  /* FVE metadata header */
125
  uint32_t metadata_size;
126
  uint32_t metadata_version;
127
  uint32_t metadata_header_size;
128
  uint32_t metada_size_copy;
129
  struct bitlk_guid guid;
130
  uint32_t next_nonce;
131
  uint16_t encryption;
132
  uint16_t unknown3;
133
  uint64_t creation_time;
134
} __attribute__ ((packed));
135
136
struct bitlk_validation_hash {
137
  uint16_t size;
138
  uint16_t role;
139
  uint16_t type;
140
  uint16_t flags;
141
  /* likely a hash type code, anything other than 0x2005 isn't supported */
142
  uint16_t hash_type;
143
  uint16_t unknown1;
144
  /* SHA-256 */
145
  uint8_t hash[32];
146
} __attribute__ ((packed));
147
148
struct bitlk_fve_metadata_validation {
149
  /* FVE metadata validation block header */
150
  uint16_t validation_size;
151
  uint16_t validation_version;
152
  uint32_t fve_crc32;
153
  /* this is a single nested structure's header defined here for simplicity */
154
  uint16_t nested_struct_size;
155
  uint16_t nested_struct_role;
156
  uint16_t nested_struct_type;
157
  uint16_t nested_struct_flags;
158
  /* datum containing a similar nested structure (encrypted using VMK) with hash (SHA256) */
159
  uint8_t nested_struct_data[BITLK_VALIDATION_VMK_DATA_SIZE];
160
} __attribute__ ((packed));
161
162
struct bitlk_entry_header_block {
163
  uint64_t offset;
164
  uint64_t size;
165
} __attribute__ ((packed));
166
167
struct bitlk_entry_vmk {
168
  struct bitlk_guid guid;
169
  uint8_t modified[8];
170
  uint16_t _unknown;
171
  uint16_t protection;
172
} __attribute__ ((packed));
173
174
struct bitlk_kdf_data {
175
  char last_sha256[32];
176
  char initial_sha256[32];
177
  char salt[16];
178
  uint64_t count;
179
};
180
181
struct bitlk_bek_header {
182
  uint32_t metadata_size;
183
  uint32_t metadata_version;
184
  uint32_t metadata_header_size;
185
  uint32_t metada_size_copy;
186
  struct bitlk_guid guid;
187
  uint32_t next_nonce;
188
  uint16_t encryption;
189
  uint16_t unknown;
190
  uint64_t creation_time;
191
} __attribute__ ((packed));
192
193
static BITLKVMKProtection get_vmk_protection(uint16_t protection)
194
0
{
195
0
  switch (protection) {
196
0
  case 0x0000:
197
0
    return BITLK_PROTECTION_CLEAR_KEY;
198
0
  case 0x0100:
199
0
    return BITLK_PROTECTION_TPM;
200
0
  case 0x0200:
201
0
    return BITLK_PROTECTION_STARTUP_KEY;
202
0
  case 0x0500:
203
0
    return BITLK_PROTECTION_TPM_PIN;
204
0
  case 0x0800:
205
0
    return BITLK_PROTECTION_RECOVERY_PASSPHRASE;
206
0
  case 0x1000:
207
0
    return BITLK_PROTECTION_SMART_CARD;
208
0
  case 0x2000:
209
0
    return BITLK_PROTECTION_PASSPHRASE;
210
0
  default:
211
0
    return BITLK_PROTECTION_UNKNOWN;
212
0
  }
213
0
}
214
215
static const char* get_vmk_protection_string(BITLKVMKProtection protection)
216
0
{
217
0
  switch (protection) {
218
0
  case BITLK_PROTECTION_CLEAR_KEY:
219
0
    return "VMK protected with clear key";
220
0
  case BITLK_PROTECTION_TPM:
221
0
    return "VMK protected with TPM";
222
0
  case BITLK_PROTECTION_STARTUP_KEY:
223
0
    return "VMK protected with startup key";
224
0
  case BITLK_PROTECTION_TPM_PIN:
225
0
    return "VMK protected with TPM and PIN";
226
0
  case BITLK_PROTECTION_PASSPHRASE:
227
0
    return "VMK protected with passphrase";
228
0
  case BITLK_PROTECTION_RECOVERY_PASSPHRASE:
229
0
    return "VMK protected with recovery passphrase";
230
0
  case BITLK_PROTECTION_SMART_CARD:
231
0
    return "VMK protected with smart card";
232
0
  default:
233
0
    return "VMK with unknown protection";
234
0
  }
235
0
}
236
237
static const char* get_bitlk_type_string(BITLKEncryptionType type)
238
472
{
239
472
  switch (type)
240
472
  {
241
2
  case BITLK_ENCRYPTION_TYPE_NORMAL:
242
2
    return "normal";
243
3
  case BITLK_ENCRYPTION_TYPE_EOW:
244
3
    return "encrypt-on-write";
245
467
  default:
246
467
    return "unknown";
247
472
  }
248
472
}
249
250
static uint64_t filetime_to_unixtime(uint64_t time)
251
0
{
252
0
  return (time - EPOCH_AS_FILETIME) / HUNDREDS_OF_NANOSECONDS;
253
0
}
254
255
static int parse_vmk_entry(struct crypt_device *cd, uint8_t *data, int start, int end, struct bitlk_vmk **vmk)
256
0
{
257
0
  uint16_t key_entry_size = 0;
258
0
  uint16_t key_entry_type = 0;
259
0
  uint16_t key_entry_value = 0;
260
0
  size_t key_size = 0;
261
0
  char *string = NULL;
262
0
  const char *key = NULL;
263
0
  struct volume_key *vk = NULL;
264
0
  bool supported = false;
265
0
  int r = 0;
266
267
  /* only passphrase, recovery passphrase, startup key and clearkey vmks are supported (can be used to activate) */
268
0
  supported = (*vmk)->protection == BITLK_PROTECTION_PASSPHRASE ||
269
0
        (*vmk)->protection == BITLK_PROTECTION_RECOVERY_PASSPHRASE ||
270
0
        (*vmk)->protection == BITLK_PROTECTION_STARTUP_KEY ||
271
0
        (*vmk)->protection == BITLK_PROTECTION_CLEAR_KEY;
272
273
0
  while ((end - start) >= (ssize_t)(sizeof(key_entry_size) + sizeof(key_entry_type) + sizeof(key_entry_value))) {
274
    /* size of this entry */
275
0
    memcpy(&key_entry_size, data + start, sizeof(key_entry_size));
276
0
    key_entry_size = le16_to_cpu(key_entry_size);
277
0
    if (key_entry_size == 0)
278
0
      break;
279
280
0
    if (key_entry_size > (end - start))
281
0
      return -EINVAL;
282
283
    /* type and value of this entry */
284
0
    memcpy(&key_entry_type, data + start + sizeof(key_entry_size), sizeof(key_entry_type));
285
0
    memcpy(&key_entry_value,
286
0
           data + start + sizeof(key_entry_size) + sizeof(key_entry_type),
287
0
           sizeof(key_entry_value));
288
0
    key_entry_type = le16_to_cpu(key_entry_type);
289
0
    key_entry_value = le16_to_cpu(key_entry_value);
290
291
0
    if (key_entry_type != BITLK_ENTRY_TYPE_PROPERTY) {
292
0
      if (supported) {
293
0
        log_err(cd, _("Unexpected metadata entry type '%u' found when parsing supported Volume Master Key."), key_entry_type);
294
0
        return -EINVAL;
295
0
      } else {
296
0
        log_dbg(cd, "Unexpected metadata entry type '%u' found when parsing unsupported VMK.", key_entry_type);
297
0
      }
298
0
    }
299
300
    /* stretch key with salt, skip 4 B (encryption method of the stretch key) */
301
0
    if (key_entry_value == BITLK_ENTRY_VALUE_STRETCH_KEY) {
302
0
      if ((end - start) < (BITLK_ENTRY_HEADER_LEN + BITLK_SALT_SIZE + 4))
303
0
        return -EINVAL;
304
0
      memcpy((*vmk)->salt,
305
0
             data + start + BITLK_ENTRY_HEADER_LEN + 4,
306
0
             BITLK_SALT_SIZE);
307
    /* AES-CCM encrypted key */
308
0
    } else if (key_entry_value == BITLK_ENTRY_VALUE_ENCRYPTED_KEY) {
309
0
      if (key_entry_size < (BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE + BITLK_VMK_MAC_TAG_SIZE))
310
0
        return -EINVAL;
311
      /* nonce */
312
0
      memcpy((*vmk)->nonce,
313
0
             data + start + BITLK_ENTRY_HEADER_LEN,
314
0
             BITLK_NONCE_SIZE);
315
      /* MAC tag */
316
0
      memcpy((*vmk)->mac_tag,
317
0
             data + start + BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE,
318
0
             BITLK_VMK_MAC_TAG_SIZE);
319
      /* AES-CCM encrypted key */
320
0
      key_size = key_entry_size - (BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE + BITLK_VMK_MAC_TAG_SIZE);
321
0
      key = (const char *) data + start + BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE + BITLK_VMK_MAC_TAG_SIZE;
322
0
      vk = crypt_alloc_volume_key(key_size, key);
323
0
      if (vk == NULL)
324
0
        return -ENOMEM;
325
0
      crypt_volume_key_add_next(&((*vmk)->vk), vk);
326
    /* clear key for a partially decrypted volume */
327
0
    } else if (key_entry_value == BITLK_ENTRY_VALUE_KEY) {
328
      /* For clearkey protection, we need to store this key */
329
0
      key_size = key_entry_size - (BITLK_ENTRY_HEADER_LEN + 4);
330
0
      key = (const char *) data + start + BITLK_ENTRY_HEADER_LEN + 4;
331
0
      vk = crypt_alloc_volume_key(key_size, key);
332
0
      if (vk == NULL)
333
0
        return -ENOMEM;
334
0
      crypt_volume_key_add_next(&((*vmk)->vk), vk);
335
    /* unknown timestamps in recovery protected VMK */
336
0
    } else if (key_entry_value == BITLK_ENTRY_VALUE_RECOVERY_TIME) {
337
0
      ;
338
    /* optional hint (?) string (masked email?), we can safely ignore it */
339
0
    } else if (key_entry_value == BITLK_ENTRY_VALUE_HINT) {
340
0
      ;
341
0
    } else if (key_entry_value == BITLK_ENTRY_VALUE_STRING) {
342
0
      if (key_entry_size < BITLK_ENTRY_HEADER_LEN)
343
0
        return -EINVAL;
344
0
      string = malloc((key_entry_size - BITLK_ENTRY_HEADER_LEN) * 2 + 1);
345
0
      if (!string)
346
0
        return -ENOMEM;
347
0
      r = crypt_utf16_to_utf8(&string, CONST_CAST(char16_t *)(data + start + BITLK_ENTRY_HEADER_LEN),
348
0
                 key_entry_size - BITLK_ENTRY_HEADER_LEN);
349
0
      if (r < 0 || !string) {
350
0
        free(string);
351
0
        log_err(cd, _("Invalid string found when parsing Volume Master Key."));
352
0
        return -EINVAL;
353
0
      } else if ((*vmk)->name != NULL) {
354
0
        if (supported) {
355
0
          log_err(cd, _("Unexpected string ('%s') found when parsing supported Volume Master Key."), string);
356
0
          free(string);
357
0
          return -EINVAL;
358
0
        }
359
0
        log_dbg(cd, "Unexpected string ('%s') found when parsing unsupported VMK.", string);
360
0
        free(string);
361
0
        string = NULL;
362
0
      } else {
363
        /* Assume that strings in VMK are the name of the VMK */
364
0
        (*vmk)->name = string;
365
0
        string = NULL;
366
0
      }
367
    /* no idea what this is, lets hope it's not important */
368
0
    } else if (key_entry_value == BITLK_ENTRY_VALUE_USE_KEY && (*vmk)->protection == BITLK_PROTECTION_STARTUP_KEY) {
369
0
      ;
370
    /* quietly ignore unsupported TPM key */
371
0
    } else if (key_entry_value == BITLK_ENTRY_VALUE_TPM_KEY && (*vmk)->protection == BITLK_PROTECTION_TPM) {
372
0
      ;
373
0
    } else {
374
0
      if (supported) {
375
0
        log_err(cd, _("Unexpected metadata entry value '%u' found when parsing supported Volume Master Key."), key_entry_value);
376
0
        return -EINVAL;
377
0
      } else {
378
0
        log_dbg(cd, "Unexpected metadata entry value '%u' found when parsing unsupported VMK.", key_entry_value);
379
0
      }
380
0
    }
381
382
0
    start += key_entry_size;
383
0
  }
384
385
0
  return 0;
386
0
}
387
388
static bool check_fve_metadata(struct bitlk_fve_metadata *fve)
389
1.06k
{
390
1.06k
  if (memcmp(fve->signature, BITLK_SIGNATURE, sizeof(fve->signature)) || le16_to_cpu(fve->fve_version) != 2 ||
391
204
    (fve->fve_size << 4) > BITLK_FVE_METADATA_SIZE)
392
877
    return false;
393
394
191
  return true;
395
1.06k
}
396
397
static bool check_fve_metadata_validation(struct bitlk_fve_metadata_validation *validation)
398
191
{
399
  /* only check if there is room for CRC-32, the actual size must be larger */
400
191
  if (le16_to_cpu(validation->validation_size) < 8 || le16_to_cpu(validation->validation_version > 2))
401
71
    return false;
402
403
120
  return true;
404
191
}
405
406
static bool parse_fve_metadata_validation(struct bitlk_metadata *params, struct bitlk_fve_metadata_validation *validation)
407
0
{
408
  /* extra checks for a nested structure (MAC) and BITLK FVE metadata */
409
410
0
  if (le16_to_cpu(validation->validation_size) < sizeof(struct bitlk_fve_metadata_validation))
411
0
    return false;
412
413
0
  if (le16_to_cpu(validation->nested_struct_size != BITLK_VALIDATION_VMK_HEADER_SIZE + BITLK_VALIDATION_VMK_DATA_SIZE) ||
414
0
    le16_to_cpu(validation->nested_struct_role) != 0 ||
415
0
    le16_to_cpu(validation->nested_struct_type) != 5)
416
0
    return false;
417
418
  /* nonce */
419
0
  memcpy(params->validation->nonce,
420
0
    validation->nested_struct_data,
421
0
    BITLK_NONCE_SIZE);
422
423
  /* MAC tag */
424
0
  memcpy(params->validation->mac_tag,
425
0
    validation->nested_struct_data + BITLK_NONCE_SIZE,
426
0
    BITLK_VMK_MAC_TAG_SIZE);
427
428
  /* AES-CCM encrypted datum with SHA256 hash */
429
0
  memcpy(params->validation->enc_datum,
430
0
    validation->nested_struct_data + BITLK_NONCE_SIZE + BITLK_VMK_MAC_TAG_SIZE,
431
0
    BITLK_VALIDATION_VMK_DATA_SIZE - BITLK_NONCE_SIZE - BITLK_VMK_MAC_TAG_SIZE);
432
433
0
  return true;
434
0
}
435
436
void BITLK_bitlk_fvek_free(struct bitlk_fvek *fvek)
437
1.43k
{
438
1.43k
  if (!fvek)
439
1.43k
    return;
440
441
0
  crypt_free_volume_key(fvek->vk);
442
0
  free(fvek);
443
0
}
444
445
void BITLK_bitlk_vmk_free(struct bitlk_vmk *vmk)
446
1.43k
{
447
1.43k
  struct bitlk_vmk *vmk_next = NULL;
448
449
1.43k
  while (vmk) {
450
0
    free(vmk->guid);
451
0
    free(vmk->name);
452
0
    crypt_free_volume_key(vmk->vk);
453
0
    vmk_next = vmk->next;
454
0
    free(vmk);
455
0
    vmk = vmk_next;
456
0
  }
457
1.43k
}
458
459
void BITLK_bitlk_metadata_free(struct bitlk_metadata *metadata)
460
1.43k
{
461
1.43k
  if (!metadata)
462
0
    return;
463
464
1.43k
  free(metadata->guid);
465
1.43k
  free(metadata->description);
466
1.43k
  free(metadata->validation);
467
1.43k
  BITLK_bitlk_vmk_free(metadata->vmks);
468
1.43k
  BITLK_bitlk_fvek_free(metadata->fvek);
469
1.43k
}
470
471
int BITLK_read_sb(struct crypt_device *cd, struct bitlk_metadata *params)
472
1.43k
{
473
1.43k
  int devfd;
474
1.43k
  struct device *device = crypt_metadata_device(cd);
475
1.43k
  struct bitlk_signature sig = {};
476
1.43k
  struct bitlk_superblock sb = {};
477
1.43k
  struct bitlk_fve_metadata fve = {};
478
1.43k
  struct bitlk_fve_metadata_validation validation = {};
479
1.43k
  struct bitlk_entry_vmk entry_vmk = {};
480
1.43k
  uint8_t *fve_entries = NULL;
481
1.43k
  uint8_t *fve_validated_block = NULL;
482
1.43k
  size_t fve_entries_size = 0;
483
1.43k
  uint32_t fve_metadata_size = 0;
484
1.43k
  uint32_t fve_size_real = 0;
485
1.43k
  int fve_offset = 0;
486
1.43k
  char guid_buf[UUID_STR_LEN] = {0};
487
1.43k
  uint16_t entry_size = 0;
488
1.43k
  uint16_t entry_type = 0;
489
1.43k
  int i = 0;
490
1.43k
  int r = 0;
491
1.43k
  int valid_fve_metadata_idx = -1;
492
1.43k
  int start = 0;
493
1.43k
  size_t key_size = 0;
494
1.43k
  const char *key = NULL;
495
1.43k
  char *description = NULL;
496
1.43k
  struct crypt_hash *hash;
497
498
1.43k
  struct bitlk_vmk *vmk = NULL;
499
1.43k
  struct bitlk_vmk *vmk_p = params->vmks;
500
501
1.43k
  devfd = device_open(cd, crypt_data_device(cd), O_RDONLY);
502
1.43k
  if (devfd < 0) {
503
0
    r = -EINVAL;
504
0
    goto out;
505
0
  }
506
507
  /* read and check the signature */
508
1.43k
  if (read_lseek_blockwise(devfd, device_block_size(cd, device),
509
1.43k
    device_alignment(device), &sig, sizeof(sig), 0) != sizeof(sig)) {
510
0
    log_dbg(cd, "Failed to read BITLK signature from %s.", device_path(device));
511
0
    r = -EIO;
512
0
    goto out;
513
0
  }
514
515
1.43k
  if (memcmp(sig.signature, BITLK_SIGNATURE, sizeof(sig.signature)) == 0) {
516
561
    params->togo = false;
517
561
    fve_offset = BITLK_HEADER_METADATA_OFFSET;
518
871
  } else if (memcmp(sig.signature, BITLK_SIGNATURE_TOGO, sizeof(sig.signature)) == 0) {
519
16
    params->togo = true;
520
16
    fve_offset = BITLK_HEADER_METADATA_OFFSET_TOGO;
521
855
  } else {
522
855
    log_dbg(cd, "Invalid or unknown signature for BITLK device.");
523
855
    r = -EINVAL;
524
855
    goto out;
525
855
  }
526
527
577
  if (memcmp(sig.boot_code, BITLK_BOOTCODE_V1, sizeof(sig.boot_code)) == 0) {
528
1
    log_err(cd, _("BITLK version 1 is currently not supported."));
529
1
    r = -ENOTSUP;
530
1
    goto out;
531
576
  } else if (memcmp(sig.boot_code, BITLK_BOOTCODE_V2, sizeof(sig.boot_code)) == 0)
532
506
    ;
533
70
  else {
534
70
    log_err(cd, _("Invalid or unknown boot signature for BITLK device."));
535
70
    r = -EINVAL;
536
70
    goto out;
537
70
  }
538
539
506
  params->sector_size = le16_to_cpu(sig.sector_size);
540
506
  if (params->sector_size == 0) {
541
60
    log_dbg(cd, "Got sector size 0, assuming 512.");
542
60
    params->sector_size = SECTOR_SIZE;
543
60
  }
544
545
506
  if (!(params->sector_size == 512 || params->sector_size == 4096)) {
546
34
    log_err(cd, _("Unsupported sector size %" PRIu16 "."), params->sector_size);
547
34
    r = -EINVAL;
548
34
    goto out;
549
34
  }
550
551
  /* read GUID and FVE metadata offsets */
552
472
  if (read_lseek_blockwise(devfd, device_block_size(cd, device),
553
472
    device_alignment(device), &sb, sizeof(sb), fve_offset) != sizeof(sb)) {
554
0
    log_err(cd, _("Failed to read BITLK header from %s."), device_path(device));
555
0
    r = -EINVAL;
556
0
    goto out;
557
0
  }
558
559
  /* get encryption "type" based on the GUID from BITLK superblock */
560
472
  if (memcmp(&sb.guid, BITLK_GUID_NORMAL, 16) == 0)
561
2
    params->type = BITLK_ENCRYPTION_TYPE_NORMAL;
562
470
  else if (memcmp(&sb.guid, BITLK_GUID_EOW, 16) == 0)
563
3
    params->type = BITLK_ENCRYPTION_TYPE_EOW;
564
467
  else
565
467
    params->type = BITLK_ENCRYPTION_TYPE_UNKNOWN;
566
472
  log_dbg(cd, "BITLK type from GUID: %s.", get_bitlk_type_string(params->type));
567
568
1.88k
  for (i = 0; i < 3; i++)
569
1.41k
    params->metadata_offset[i] = le64_to_cpu(sb.fve_offset[i]);
570
571
472
  fve_validated_block = malloc(BITLK_FVE_METADATA_SIZE);
572
472
  if (fve_validated_block == NULL) {
573
0
    r = -ENOMEM;
574
0
    goto out;
575
0
  }
576
577
1.80k
  for (i = 0; i < 3; i++) {
578
    /* iterate over FVE metadata copies and pick the valid one */
579
1.36k
    log_dbg(cd, "Reading BITLK FVE metadata copy #%d of size %zu on device %s, offset %" PRIu64 ".",
580
1.36k
      i, sizeof(fve), device_path(device), params->metadata_offset[i]);
581
582
1.36k
    if (read_lseek_blockwise(devfd, device_block_size(cd, device),
583
1.36k
      device_alignment(device), &fve, sizeof(fve), params->metadata_offset[i]) != sizeof(fve) ||
584
1.06k
      !check_fve_metadata(&fve) ||
585
191
      (fve_size_real = le16_to_cpu(fve.fve_size) << 4, read_lseek_blockwise(devfd, device_block_size(cd, device),
586
191
      device_alignment(device), &validation, sizeof(validation), params->metadata_offset[i] + fve_size_real) != sizeof(validation)) ||
587
191
      !check_fve_metadata_validation(&validation) ||
588
      /* double-fetch is here, but we aren't validating MAC */
589
120
      read_lseek_blockwise(devfd, device_block_size(cd, device), device_alignment(device), fve_validated_block, fve_size_real,
590
120
      params->metadata_offset[i]) != fve_size_real ||
591
1.33k
      (crypt_crc32(~0, fve_validated_block, fve_size_real) ^ ~0) != le32_to_cpu(validation.fve_crc32)) {
592
      /* found an invalid FVE metadata copy, log and skip */
593
1.33k
      log_dbg(cd, _("Failed to read or validate BITLK FVE metadata copy #%d from %s."), i, device_path(device));
594
1.33k
    } else {
595
      /* found a valid FVE metadata copy, use it */
596
36
      valid_fve_metadata_idx = i;
597
36
      break;
598
36
    }
599
1.36k
  }
600
601
472
  if (valid_fve_metadata_idx < 0) {
602
    /* all FVE metadata copies are invalid, fail */
603
436
    log_err(cd, _("Failed to read and validate BITLK FVE metadata from %s."), device_path(device));
604
436
    r = -EINVAL;
605
436
    goto out;
606
436
  }
607
608
  /* check that a valid FVE metadata block is in its expected location */
609
36
  if (params->metadata_offset[valid_fve_metadata_idx] != le64_to_cpu(fve.fve_offset[valid_fve_metadata_idx])) {
610
36
    log_err(cd, _("Failed to validate the location of BITLK FVE metadata from %s."), device_path(device));
611
36
    r = -EINVAL;
612
36
    goto out;
613
36
  }
614
615
  /* update offsets from a valid FVE metadata copy */
616
0
  for (i = 0; i < 3; i++)
617
0
    params->metadata_offset[i] = le64_to_cpu(fve.fve_offset[i]);
618
619
  /* check that the FVE metadata hasn't changed between reads, because we are preparing for the MAC check */
620
0
  if (memcmp(&fve, fve_validated_block, sizeof(fve)) != 0) {
621
0
    log_err(cd, _("BITLK FVE metadata changed between reads from %s."), device_path(device));
622
0
    r = -EINVAL;
623
0
    goto out;
624
0
  }
625
626
0
  crypt_backend_memzero(&params->sha256_fve, 32);
627
0
  if (crypt_hash_init(&hash, "sha256")) {
628
0
    log_err(cd, _("Failed to hash BITLK FVE metadata read from %s."), device_path(device));
629
0
    r = -EINVAL;
630
0
    goto out;
631
0
  }
632
0
  crypt_hash_write(hash, (const char *)fve_validated_block, fve_size_real);
633
0
  crypt_hash_final(hash, (char *)&params->sha256_fve, 32);
634
0
  crypt_hash_destroy(hash);
635
636
  /* do some extended checks against FVE metadata, but not including MAC verification */
637
0
  params->validation = malloc(sizeof(struct bitlk_validation));
638
0
  if (!params->validation) {
639
0
    r = -ENOMEM;
640
0
    goto out;
641
0
  }
642
643
0
  if (!parse_fve_metadata_validation(params, &validation)) {
644
0
    log_err(cd, _("Failed to parse BITLK FVE validation metadata from %s."), device_path(device));
645
0
    r = -EINVAL;
646
0
    goto out;
647
0
  }
648
649
  /* check encryption state for the device */
650
0
  params->state = true;
651
0
  if (le16_to_cpu(fve.curr_state) != BITLK_STATE_NORMAL || le16_to_cpu(fve.next_state) != BITLK_STATE_NORMAL) {
652
0
    params->state = false;
653
0
    log_dbg(cd, "Unknown/unsupported state detected. Current state: %"PRIu16", next state: %"PRIu16".",
654
0
      le16_to_cpu(fve.curr_state), le16_to_cpu(fve.next_state));
655
0
  }
656
657
0
  params->volume_size = le64_to_cpu(fve.volume_size);
658
0
  params->metadata_version = le16_to_cpu(fve.fve_version);
659
660
0
  switch (le16_to_cpu(fve.encryption)) {
661
  /* AES-CBC with Elephant difuser */
662
0
  case 0x8000:
663
0
    params->key_size = 256;
664
0
    params->cipher = "aes";
665
0
    params->cipher_mode = "cbc-elephant";
666
0
    break;
667
0
  case 0x8001:
668
0
    params->key_size = 512;
669
0
    params->cipher = "aes";
670
0
    params->cipher_mode = "cbc-elephant";
671
0
    break;
672
  /* AES-CBC */
673
0
  case 0x8002:
674
0
    params->key_size = 128;
675
0
    params->cipher = "aes";
676
0
    params->cipher_mode = "cbc-eboiv";
677
0
    break;
678
0
  case 0x8003:
679
0
    params->key_size = 256;
680
0
    params->cipher = "aes";
681
0
    params->cipher_mode = "cbc-eboiv";
682
0
    break;
683
  /* AES-XTS */
684
0
  case 0x8004:
685
0
    params->key_size = 256;
686
0
    params->cipher = "aes";
687
0
    params->cipher_mode = "xts-plain64";
688
0
    break;
689
0
  case 0x8005:
690
0
    params->key_size = 512;
691
0
    params->cipher = "aes";
692
0
    params->cipher_mode = "xts-plain64";
693
0
    break;
694
0
  default:
695
0
    log_err(cd, _("Unknown or unsupported encryption type."));
696
0
    params->key_size = 0;
697
0
    params->cipher = NULL;
698
0
    params->cipher_mode = NULL;
699
0
    r = -ENOTSUP;
700
0
    goto out;
701
0
  };
702
703
  /* device GUID */
704
0
  guid_to_string(&fve.guid, guid_buf);
705
0
  params->guid = strdup(guid_buf);
706
0
  if (!params->guid) {
707
0
    r = -ENOMEM;
708
0
    goto out;
709
0
  }
710
711
0
  params->creation_time = filetime_to_unixtime(le64_to_cpu(fve.creation_time));
712
713
0
  fve_metadata_size = le32_to_cpu(fve.metadata_size);
714
0
  if (fve_metadata_size < (BITLK_FVE_METADATA_HEADER_LEN + sizeof(entry_size) + sizeof(entry_type)) ||
715
0
      fve_metadata_size > BITLK_FVE_METADATA_SIZE) {
716
0
    r = -EINVAL;
717
0
    goto out;
718
0
  }
719
0
  fve_entries_size = fve_metadata_size - BITLK_FVE_METADATA_HEADER_LEN;
720
721
  /* read and parse all FVE metadata entries */
722
0
  fve_entries = malloc(fve_entries_size);
723
0
  if (!fve_entries) {
724
0
    r = -ENOMEM;
725
0
    goto out;
726
0
  }
727
0
  memset(fve_entries, 0, fve_entries_size);
728
729
0
  log_dbg(cd, "Getting BITLK FVE metadata entries of size %zu on device %s, offset %" PRIu64 ".",
730
0
    fve_entries_size, device_path(device), params->metadata_offset[valid_fve_metadata_idx] + BITLK_FVE_METADATA_HEADERS_LEN);
731
732
0
  if (BITLK_FVE_METADATA_HEADERS_LEN + fve_entries_size > fve_size_real) {
733
0
    log_err(cd, _("Failed to check BITLK metadata entries previously read from %s."), device_path(device));
734
0
    r = -EINVAL;
735
0
    goto out;
736
0
  }
737
738
  /* fetch these entries from validated buffer to avoid double-fetch */
739
0
  memcpy(fve_entries, fve_validated_block + BITLK_FVE_METADATA_HEADERS_LEN, fve_entries_size);
740
741
0
  while ((fve_entries_size - start) >= (sizeof(entry_size) + sizeof(entry_type))) {
742
743
    /* size of this entry */
744
0
    memcpy(&entry_size, fve_entries + start, sizeof(entry_size));
745
0
    entry_size = le16_to_cpu(entry_size);
746
0
    if (entry_size == 0)
747
0
      break;
748
749
0
    if (entry_size > (fve_entries_size - start)) {
750
0
      r = -EINVAL;
751
0
      goto out;
752
0
    }
753
754
    /* type of this entry */
755
0
    memcpy(&entry_type, fve_entries + start + sizeof(entry_size), sizeof(entry_type));
756
0
    entry_type = le16_to_cpu(entry_type);
757
758
    /* VMK */
759
0
    if (entry_type == BITLK_ENTRY_TYPE_VMK) {
760
0
      if (entry_size < (BITLK_ENTRY_HEADER_LEN + sizeof(entry_vmk))) {
761
0
        r = -EINVAL;
762
0
        goto out;
763
0
      }
764
      /* skip first four variables in the entry (entry size, type, value and version) */
765
0
      memcpy(&entry_vmk,
766
0
             fve_entries + start + BITLK_ENTRY_HEADER_LEN,
767
0
             sizeof(entry_vmk));
768
769
0
      vmk = malloc(sizeof(struct bitlk_vmk));
770
0
      if (!vmk) {
771
0
        r = -ENOMEM;
772
0
        goto out;
773
0
      }
774
0
      memset(vmk, 0, sizeof(struct bitlk_vmk));
775
776
0
      guid_to_string(&entry_vmk.guid, guid_buf);
777
0
      vmk->guid = strdup (guid_buf);
778
779
0
      vmk->name = NULL;
780
781
0
      vmk->protection = get_vmk_protection(le16_to_cpu(entry_vmk.protection));
782
783
      /* more data in another entry list */
784
0
      r = parse_vmk_entry(cd, fve_entries,
785
0
                            start + BITLK_ENTRY_HEADER_LEN + BITLK_VMK_HEADER_LEN,
786
0
                start + entry_size, &vmk);
787
0
      if (r < 0) {
788
0
        BITLK_bitlk_vmk_free(vmk);
789
0
        goto out;
790
0
      }
791
792
0
      if (params->vmks == NULL)
793
0
        params->vmks = vmk;
794
0
      else
795
0
        vmk_p->next = vmk;
796
797
0
      vmk_p = vmk;
798
0
      vmk = vmk->next;
799
    /* FVEK */
800
0
    } else if (entry_type == BITLK_ENTRY_TYPE_FVEK && !params->fvek) {
801
0
      if (entry_size < (BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE + BITLK_VMK_MAC_TAG_SIZE)) {
802
0
        r = -EINVAL;
803
0
        goto out;
804
0
      }
805
0
      params->fvek = malloc(sizeof(struct bitlk_fvek));
806
0
      if (!params->fvek) {
807
0
        r = -ENOMEM;
808
0
        goto out;
809
0
      }
810
0
      memcpy(params->fvek->nonce,
811
0
             fve_entries + start + BITLK_ENTRY_HEADER_LEN,
812
0
             BITLK_NONCE_SIZE);
813
      /* MAC tag */
814
0
      memcpy(params->fvek->mac_tag,
815
0
             fve_entries + start + BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE,
816
0
             BITLK_VMK_MAC_TAG_SIZE);
817
      /* AES-CCM encrypted key */
818
0
      key_size = entry_size - (BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE + BITLK_VMK_MAC_TAG_SIZE);
819
0
      key = (const char *) fve_entries + start + BITLK_ENTRY_HEADER_LEN + BITLK_NONCE_SIZE + BITLK_VMK_MAC_TAG_SIZE;
820
0
      params->fvek->vk = crypt_alloc_volume_key(key_size, key);
821
0
      if (params->fvek->vk == NULL) {
822
0
        r = -ENOMEM;
823
0
        goto out;
824
0
      }
825
    /* volume header info (location and size) */
826
0
    } else if (entry_type == BITLK_ENTRY_TYPE_VOLUME_HEADER) {
827
0
      struct bitlk_entry_header_block entry_header;
828
0
      if ((fve_entries_size - start) < (BITLK_ENTRY_HEADER_LEN + sizeof(entry_header))) {
829
0
        r = -EINVAL;
830
0
        goto out;
831
0
      }
832
0
      memcpy(&entry_header,
833
0
             fve_entries + start + BITLK_ENTRY_HEADER_LEN,
834
0
             sizeof(entry_header));
835
0
      params->volume_header_offset = le64_to_cpu(entry_header.offset);
836
0
      params->volume_header_size = le64_to_cpu(entry_header.size);
837
    /* volume description (utf-16 string) */
838
0
    } else if (entry_type == BITLK_ENTRY_TYPE_DESCRIPTION && !params->description) {
839
0
      if (entry_size < BITLK_ENTRY_HEADER_LEN) {
840
0
        r = -EINVAL;
841
0
        goto out;
842
0
      }
843
0
      description = malloc((entry_size - BITLK_ENTRY_HEADER_LEN) * 2 + 1);
844
0
      if (!description) {
845
0
        r = -ENOMEM;
846
0
        goto out;
847
0
      }
848
0
      r = crypt_utf16_to_utf8(&description, CONST_CAST(char16_t *)(fve_entries + start + BITLK_ENTRY_HEADER_LEN),
849
0
                            entry_size - BITLK_ENTRY_HEADER_LEN);
850
0
      if (r < 0) {
851
0
        free(description);
852
0
        BITLK_bitlk_vmk_free(vmk);
853
0
        log_err(cd, _("Failed to convert BITLK volume description"));
854
0
        goto out;
855
0
      }
856
0
      params->description = description;
857
0
    }
858
859
0
    start += entry_size;
860
0
  }
861
1.43k
out:
862
1.43k
  free(fve_entries);
863
1.43k
  free(fve_validated_block);
864
865
1.43k
  return r;
866
0
}
867
868
int BITLK_dump(struct crypt_device *cd, struct device *device, struct bitlk_metadata *params)
869
0
{
870
0
  struct volume_key *vk_p;
871
0
  struct bitlk_vmk *vmk_p;
872
0
  char time[32];
873
0
  int next_id = 0;
874
0
  int i = 0;
875
876
0
  log_std(cd, "Info for BITLK%s device %s.\n", params->togo ? " To Go" : "", device_path(device));
877
0
  log_std(cd, "Version:      \t%u\n", params->metadata_version);
878
0
  log_std(cd, "GUID:         \t%s\n", params->guid);
879
0
  log_std(cd, "Sector size:  \t%u [bytes]\n", params->sector_size);
880
0
  log_std(cd, "Volume size:  \t%" PRIu64 " [bytes]\n", params->volume_size);
881
0
  if (ctime_r((time_t *)&params->creation_time, time))
882
0
    log_std(cd, "Created:      \t%s", time);
883
0
  log_std(cd, "Description:  \t%s\n", params->description);
884
0
  log_std(cd, "Cipher name:  \t%s\n", params->cipher);
885
0
  log_std(cd, "Cipher mode:  \t%s\n", params->cipher_mode);
886
0
  log_std(cd, "Cipher key:   \t%u [bits]\n", params->key_size);
887
888
0
  log_std(cd, "\n");
889
890
0
  log_std(cd, "Keyslots:\n");
891
0
  vmk_p = params->vmks;
892
0
  while (vmk_p) {
893
0
    log_std(cd, " %d: VMK\n", next_id);
894
0
    if (vmk_p->name != NULL) {
895
0
      log_std(cd, "\tName:       \t%s\n", vmk_p->name);
896
0
    }
897
0
    log_std(cd, "\tGUID:       \t%s\n", vmk_p->guid);
898
0
    log_std(cd, "\tProtection: \t%s\n", get_vmk_protection_string (vmk_p->protection));
899
0
    log_std(cd, "\tSalt:       \t");
900
0
    crypt_log_hex(cd, (const char *) vmk_p->salt, 16, "", 0, NULL);
901
0
    log_std(cd, "\n");
902
903
0
    vk_p = vmk_p->vk;
904
0
    while (vk_p) {
905
0
      log_std(cd, "\tKey data size:\t%zu [bytes]\n", crypt_volume_key_length(vk_p));
906
0
      vk_p = crypt_volume_key_next(vk_p);
907
0
    }
908
0
    vmk_p = vmk_p->next;
909
0
    next_id++;
910
0
  }
911
912
0
  log_std(cd, " %d: FVEK\n", next_id);
913
0
  log_std(cd, "\tKey data size:\t%zu [bytes]\n", crypt_volume_key_length(params->fvek->vk));
914
915
0
  log_std(cd, "\n");
916
917
0
  log_std(cd, "Metadata segments:\n");
918
919
0
  for (i = 0; i < 3; i++) {
920
0
    log_std(cd, " %d: FVE metadata area\n", i);
921
0
    log_std(cd, "\tOffset: \t%" PRIu64 " [bytes]\n", params->metadata_offset[i]);
922
0
    log_std(cd, "\tSize:   \t%d [bytes]\n", BITLK_FVE_METADATA_SIZE);
923
0
  }
924
925
0
  log_std(cd, " %d: Volume header\n", i);
926
0
  log_std(cd, "\tOffset: \t%" PRIu64 " [bytes]\n", params->volume_header_offset);
927
0
  log_std(cd, "\tSize:   \t%" PRIu64 " [bytes]\n", params->volume_header_size);
928
0
  log_std(cd, "\tCipher: \t%s-%s\n", params->cipher, params->cipher_mode);
929
930
0
  return 0;
931
0
}
932
933
/* check if given passphrase can be a recovery key (has right format) and convert it */
934
static int get_recovery_key(struct crypt_device *cd,
935
          const char *password,
936
          size_t passwordLen,
937
          struct volume_key **rc_key)
938
0
{
939
0
  unsigned int i, j = 0;
940
0
  uint16_t parts[BITLK_RECOVERY_PARTS] = {0};
941
0
  char part_str[BITLK_RECOVERY_PART_LEN + 1] = {0};
942
0
  long part_num = 0;
943
944
  /* check the passphrase it should be:
945
      - 55 characters
946
      - 8 groups of 6 divided by '-'
947
      - each part is a number dividable by 11
948
  */
949
0
  if (passwordLen != BITLK_RECOVERY_KEY_LEN) {
950
0
    if (passwordLen == BITLK_RECOVERY_KEY_LEN + 1 && password[passwordLen - 1] == '\n') {
951
      /* looks like a recovery key with an extra newline, possibly from a key file */
952
0
      passwordLen--;
953
0
      log_dbg(cd, "Possible extra EOL stripped from the recovery key.");
954
0
    } else
955
0
      return 0;
956
0
  }
957
958
0
  for (i = BITLK_RECOVERY_PART_LEN; i < passwordLen; i += BITLK_RECOVERY_PART_LEN + 1) {
959
0
    if (password[i] != '-')
960
0
      return 0;
961
0
  }
962
963
0
  for (i = 0, j = 0; i < passwordLen; i += BITLK_RECOVERY_PART_LEN + 1, j++) {
964
0
    strncpy(part_str, password + i, BITLK_RECOVERY_PART_LEN);
965
966
0
    errno = 0;
967
0
    part_num = strtol(part_str, NULL, 10);
968
0
    if ((errno == ERANGE && (part_num == LONG_MAX || part_num == LONG_MIN)) ||
969
0
        (errno != 0 && part_num == 0))
970
0
      return -errno;
971
972
0
    if (part_num % 11 != 0)
973
0
      return 0;
974
0
    parts[j] = cpu_to_le16(part_num / 11);
975
0
  }
976
977
0
  *rc_key = crypt_alloc_volume_key(16, (const char*) parts);
978
0
  if (*rc_key == NULL)
979
0
    return -ENOMEM;
980
981
0
  return 0;
982
0
}
983
984
static int parse_external_key_entry(struct crypt_device *cd,
985
            const char *data,
986
            int start,
987
            int end,
988
            struct volume_key **vk,
989
            const struct bitlk_metadata *params)
990
0
{
991
0
  uint16_t key_entry_size = 0;
992
0
  uint16_t key_entry_type = 0;
993
0
  uint16_t key_entry_value = 0;
994
0
  size_t key_size = 0;
995
0
  const char *key = NULL;
996
0
  struct bitlk_guid guid;
997
0
  char guid_buf[UUID_STR_LEN] = {0};
998
999
0
  while ((end - start) >= (ssize_t)(sizeof(key_entry_size) + sizeof(key_entry_type) + sizeof(key_entry_value))) {
1000
    /* size of this entry */
1001
0
    memcpy(&key_entry_size, data + start, sizeof(key_entry_size));
1002
0
    key_entry_size = le16_to_cpu(key_entry_size);
1003
0
    if (key_entry_size == 0)
1004
0
      break;
1005
1006
0
    if (key_entry_size > (end - start))
1007
0
      return -EINVAL;
1008
1009
    /* type and value of this entry */
1010
0
    memcpy(&key_entry_type, data + start + sizeof(key_entry_size), sizeof(key_entry_type));
1011
0
    memcpy(&key_entry_value,
1012
0
           data + start + sizeof(key_entry_size) + sizeof(key_entry_type),
1013
0
           sizeof(key_entry_value));
1014
0
    key_entry_type = le16_to_cpu(key_entry_type);
1015
0
    key_entry_value = le16_to_cpu(key_entry_value);
1016
1017
0
    if (key_entry_type != BITLK_ENTRY_TYPE_PROPERTY && key_entry_type != BITLK_ENTRY_TYPE_VOLUME_GUID) {
1018
0
      log_err(cd, _("Unexpected metadata entry type '%u' found when parsing external key."), key_entry_type);
1019
0
      return -EINVAL;
1020
0
    }
1021
1022
0
    if (key_entry_value == BITLK_ENTRY_VALUE_KEY) {
1023
0
      if (key_entry_size < (BITLK_ENTRY_HEADER_LEN + 4))
1024
0
        return -EINVAL;
1025
0
      key_size = key_entry_size - (BITLK_ENTRY_HEADER_LEN + 4);
1026
0
      key = (const char *) data + start + BITLK_ENTRY_HEADER_LEN + 4;
1027
0
      *vk = crypt_alloc_volume_key(key_size, key);
1028
0
      if (*vk == NULL)
1029
0
        return -ENOMEM;
1030
0
      return 0;
1031
    /* optional "ExternalKey" string, we can safely ignore it */
1032
0
    } else if (key_entry_value == BITLK_ENTRY_VALUE_STRING)
1033
0
      ;
1034
    /* GUID of the BitLocker device we are trying to open with this key */
1035
0
    else if (key_entry_value == BITLK_ENTRY_VALUE_GUID) {
1036
0
      if ((end - start) < (ssize_t)(BITLK_ENTRY_HEADER_LEN + sizeof(struct bitlk_guid)))
1037
0
        return -EINVAL;
1038
0
      memcpy(&guid, data + start + BITLK_ENTRY_HEADER_LEN, sizeof(struct bitlk_guid));
1039
0
      guid_to_string(&guid, guid_buf);
1040
0
      if (strcmp(guid_buf, params->guid) != 0) {
1041
0
        log_err(cd, _("BEK file GUID '%s' does not match GUID of the volume."), guid_buf);
1042
0
        return -EINVAL;
1043
0
      }
1044
0
    } else {
1045
0
      log_err(cd, _("Unexpected metadata entry value '%u' found when parsing external key."), key_entry_value);
1046
0
      return -EINVAL;
1047
0
    }
1048
1049
0
    start += key_entry_size;
1050
0
  }
1051
1052
  /* if we got here we failed to parse the metadata */
1053
0
  return -EINVAL;
1054
0
}
1055
1056
/* check if given passphrase can be a startup key (has right format) and convert it */
1057
static int get_startup_key(struct crypt_device *cd,
1058
         const char *password,
1059
         size_t passwordLen,
1060
         const struct bitlk_vmk *vmk,
1061
         struct volume_key **su_key,
1062
         const struct bitlk_metadata *params)
1063
0
{
1064
0
  struct bitlk_bek_header bek_header = {0};
1065
0
  char guid_buf[UUID_STR_LEN] = {0};
1066
1067
0
  uint16_t key_entry_size = 0;
1068
0
  uint16_t key_entry_type = 0;
1069
0
  uint16_t key_entry_value = 0;
1070
1071
0
  if (passwordLen < (BITLK_BEK_FILE_HEADER_LEN + sizeof(key_entry_size) + sizeof(key_entry_type) + sizeof(key_entry_value)))
1072
0
    return -EPERM;
1073
1074
0
  memcpy(&bek_header, password, BITLK_BEK_FILE_HEADER_LEN);
1075
1076
  /* metadata should contain GUID of the VMK this startup key is used for */
1077
0
  guid_to_string(&bek_header.guid, guid_buf);
1078
0
  if (strcmp(guid_buf, vmk->guid) == 0)
1079
0
    log_dbg(cd, "Found matching startup key for VMK %s", vmk->guid);
1080
0
  else
1081
0
    return -EPERM;
1082
1083
0
  if (le32_to_cpu(bek_header.metadata_version) != 1) {
1084
0
    log_err(cd, _("Unsupported BEK metadata version %" PRIu32), le32_to_cpu(bek_header.metadata_version));
1085
0
    return -ENOTSUP;
1086
0
  }
1087
1088
0
  if (le32_to_cpu(bek_header.metadata_size) != passwordLen) {
1089
0
    log_err(cd, _("Unexpected BEK metadata size %" PRIu32 " does not match BEK file length"),
1090
0
      le32_to_cpu(bek_header.metadata_size));
1091
0
    return -EINVAL;
1092
0
  }
1093
1094
  /* we are expecting exactly one metadata entry starting immediately after the header */
1095
0
  memcpy(&key_entry_size, password + BITLK_BEK_FILE_HEADER_LEN, sizeof(key_entry_size));
1096
0
  key_entry_size = le16_to_cpu(key_entry_size);
1097
0
  if (key_entry_size < BITLK_ENTRY_HEADER_LEN) {
1098
0
    log_dbg(cd, "Unexpected metadata entry size %" PRIu16 " when parsing BEK file", key_entry_size);
1099
0
    return -EINVAL;
1100
0
  }
1101
1102
  /* type and value of this entry */
1103
0
  memcpy(&key_entry_type, password + BITLK_BEK_FILE_HEADER_LEN + sizeof(key_entry_size), sizeof(key_entry_type));
1104
0
  memcpy(&key_entry_value,
1105
0
         password + BITLK_BEK_FILE_HEADER_LEN + sizeof(key_entry_size) + sizeof(key_entry_type),
1106
0
         sizeof(key_entry_value));
1107
0
  key_entry_type = le16_to_cpu(key_entry_type);
1108
0
  key_entry_value = le16_to_cpu(key_entry_value);
1109
1110
0
  if (key_entry_type == BITLK_ENTRY_TYPE_STARTUP_KEY && key_entry_value == BITLK_ENTRY_VALUE_EXTERNAL_KEY) {
1111
0
    return parse_external_key_entry(cd, password,
1112
0
            BITLK_BEK_FILE_HEADER_LEN + BITLK_ENTRY_HEADER_LEN + BITLK_STARTUP_KEY_HEADER_LEN,
1113
0
            passwordLen, su_key, params);
1114
0
  } else {
1115
0
    log_err(cd, _("Unexpected metadata entry found when parsing startup key."));
1116
0
    log_dbg(cd, "Entry type: %u, entry value: %u", key_entry_type, key_entry_value);
1117
0
    return -EINVAL;
1118
0
  }
1119
0
}
1120
1121
static int bitlk_kdf(const char *password,
1122
         size_t passwordLen,
1123
         bool recovery,
1124
         const uint8_t *salt,
1125
         struct volume_key **vk)
1126
0
{
1127
0
  struct bitlk_kdf_data kdf = {};
1128
0
  struct crypt_hash *hd = NULL;
1129
0
  int len = 0;
1130
0
  char16_t *utf16Password = NULL;
1131
0
  size_t utf16Len = 0;
1132
0
  int i = 0;
1133
0
  int r = 0;
1134
1135
0
  if (!password)
1136
0
    return -EINVAL;
1137
1138
0
  memcpy(kdf.salt, salt, 16);
1139
1140
0
  r = crypt_hash_init(&hd, BITLK_KDF_HASH);
1141
0
  if (r < 0)
1142
0
    return r;
1143
0
  len = crypt_hash_size(BITLK_KDF_HASH);
1144
0
  if (len < 0) {
1145
0
    crypt_hash_destroy(hd);
1146
0
    return len;
1147
0
  }
1148
1149
0
  if (!recovery) {
1150
    /* passphrase: convert to UTF-16 first, then sha256(sha256(pw)) */
1151
0
    utf16Password = crypt_safe_alloc(sizeof(char16_t) * (passwordLen + 1));
1152
0
    if (!utf16Password) {
1153
0
      r = -ENOMEM;
1154
0
      goto out;
1155
0
    }
1156
0
    r = crypt_utf8_to_utf16(&utf16Password, CONST_CAST(char*)password, passwordLen);
1157
0
    if (r < 0)
1158
0
      goto out;
1159
1160
0
    utf16Len = crypt_char16_strlen(utf16Password);
1161
0
    crypt_hash_write(hd, (char*)utf16Password, utf16Len * 2);
1162
0
    r = crypt_hash_final(hd, kdf.initial_sha256, len);
1163
0
    if (r < 0)
1164
0
      goto out;
1165
1166
0
    crypt_hash_write(hd, kdf.initial_sha256, len);
1167
0
    r = crypt_hash_final(hd, kdf.initial_sha256, len);
1168
0
    if (r < 0)
1169
0
      goto out;
1170
0
  } else {
1171
    /* recovery passphrase: already converted in #get_recovery_key, now just sha256(rpw) */
1172
0
    crypt_hash_write(hd, password, passwordLen);
1173
0
    r = crypt_hash_final(hd, kdf.initial_sha256, len);
1174
0
    if (r < 0)
1175
0
      goto out;
1176
0
  }
1177
1178
0
  for (i = 0; i < BITLK_KDF_ITERATION_COUNT; i++) {
1179
0
    crypt_hash_write(hd, (const char*) &kdf, sizeof(kdf));
1180
0
    r = crypt_hash_final(hd, kdf.last_sha256, len);
1181
0
    if (r < 0)
1182
0
      goto out;
1183
0
    kdf.count = cpu_to_le64(le64_to_cpu(kdf.count) + 1);
1184
0
  }
1185
1186
0
  *vk = crypt_alloc_volume_key(len, kdf.last_sha256);
1187
1188
0
out:
1189
0
  crypt_safe_free(utf16Password);
1190
0
  if (hd)
1191
0
    crypt_hash_destroy(hd);
1192
0
  return r;
1193
0
}
1194
1195
static int decrypt_key(struct crypt_device *cd,
1196
           struct volume_key **vk,
1197
           struct volume_key *enc_key,
1198
           struct volume_key *key,
1199
           const uint8_t *tag, size_t tag_size,
1200
           const uint8_t *iv, size_t iv_size,
1201
           bool is_fvek)
1202
0
{
1203
0
  char *outbuf;
1204
0
  int r;
1205
0
  uint16_t key_size = 0;
1206
1207
0
  outbuf = crypt_safe_alloc(crypt_volume_key_length(enc_key));
1208
0
  if (!outbuf)
1209
0
    return -ENOMEM;
1210
1211
0
  r = crypt_bitlk_decrypt_key(crypt_volume_key_get_key(key),
1212
0
        crypt_volume_key_length(key),
1213
0
        crypt_volume_key_get_key(enc_key), outbuf,
1214
0
        crypt_volume_key_length(enc_key),
1215
0
        (const char*)iv, iv_size, (const char*)tag, tag_size);
1216
0
  if (r < 0) {
1217
0
    if (r == -ENOTSUP)
1218
0
      log_err(cd, _("This operation is not supported."));
1219
0
    goto out;
1220
0
  }
1221
1222
  /* key_data has it's size as part of the metadata */
1223
0
  memcpy(&key_size, outbuf, 2);
1224
0
  key_size = le16_to_cpu(key_size);
1225
0
  if (crypt_volume_key_length(enc_key) != key_size) {
1226
0
    log_err(cd, _("Unexpected key data size."));
1227
0
    log_dbg(cd, "Expected key data size: %zu, got %" PRIu16 "",
1228
0
          crypt_volume_key_length(enc_key), key_size);
1229
1230
0
    r = -EINVAL;
1231
0
    goto out;
1232
0
  }
1233
1234
0
  if (is_fvek && strcmp(crypt_get_cipher_mode(cd), "cbc-elephant") == 0 &&
1235
0
    crypt_get_volume_key_size(cd) == 32) {
1236
    /* 128bit AES-CBC with Elephant -- key size is 256 bit (2 keys) but key data is 512 bits,
1237
       data: 16B CBC key, 16B empty, 16B elephant key, 16B empty */
1238
0
    crypt_safe_memcpy(outbuf + 16 + BITLK_OPEN_KEY_METADATA_LEN,
1239
0
      outbuf + 2 * 16 + BITLK_OPEN_KEY_METADATA_LEN, 16);
1240
0
    key_size = 32 + BITLK_OPEN_KEY_METADATA_LEN;
1241
0
  }
1242
1243
1244
0
  *vk = crypt_alloc_volume_key(key_size - BITLK_OPEN_KEY_METADATA_LEN,
1245
0
          (const char *)(outbuf + BITLK_OPEN_KEY_METADATA_LEN));
1246
0
  r = *vk ? 0 : -ENOMEM;
1247
0
out:
1248
0
  crypt_safe_free(outbuf);
1249
0
  return r;
1250
0
}
1251
1252
static int get_clear_key(struct crypt_device *cd, const struct bitlk_vmk *vmk, struct volume_key **vmk_dec_key)
1253
0
{
1254
0
  struct volume_key *nested_key = vmk->vk;
1255
1256
0
  if (!nested_key) {
1257
0
    log_dbg(cd, "Clearkey VMK structure incomplete - missing nested key");
1258
0
    return -ENOTSUP;
1259
0
  }
1260
1261
0
  struct volume_key *encrypted_vmk = crypt_volume_key_next(nested_key);
1262
1263
0
  if (!encrypted_vmk) {
1264
0
    log_dbg(cd, "Clearkey VMK structure incomplete - missing encrypted VMK");
1265
0
    return -ENOTSUP;
1266
0
  }
1267
1268
  /**
1269
   *  For clearkey protection, we need to decrypt the encrypted VMK using the nested key
1270
   *  and return the decrypted VMK as vmk_dec_key
1271
   */
1272
0
  struct volume_key *decrypted_vmk = NULL;
1273
0
  int r = decrypt_key(cd, &decrypted_vmk, encrypted_vmk, nested_key,
1274
0
      vmk->mac_tag, BITLK_VMK_MAC_TAG_SIZE,
1275
0
      vmk->nonce, BITLK_NONCE_SIZE, false);
1276
1277
0
  if (r == 0 && decrypted_vmk) {
1278
0
    log_dbg(cd, "Successfully decrypted VMK using nested key");
1279
0
    *vmk_dec_key = decrypted_vmk;
1280
0
    return 0;
1281
0
  } else {
1282
0
    log_dbg(cd, "Failed to decrypt VMK using nested key (error: %d)", r);
1283
0
    return r;
1284
0
  }
1285
0
}
1286
1287
int BITLK_get_volume_key(struct crypt_device *cd,
1288
       const char *password,
1289
       size_t passwordLen,
1290
       const struct bitlk_metadata *params,
1291
       struct volume_key **open_fvek_key)
1292
0
{
1293
0
  int r = 0;
1294
0
  struct volume_key *open_vmk_key = NULL;
1295
0
  struct volume_key *vmk_dec_key = NULL;
1296
0
  struct volume_key *recovery_key = NULL;
1297
0
  struct bitlk_validation_hash dec_hash = {};
1298
0
  const struct bitlk_vmk *next_vmk = NULL;
1299
1300
0
  next_vmk = params->vmks;
1301
0
  while (next_vmk) {
1302
0
    bool is_decrypted = false;
1303
0
    if (next_vmk->protection == BITLK_PROTECTION_PASSPHRASE) {
1304
0
      r = bitlk_kdf(password, passwordLen, false, next_vmk->salt, &vmk_dec_key);
1305
0
      if (r) {
1306
        /* something wrong happened, but we still want to check other key slots */
1307
0
        next_vmk = next_vmk->next;
1308
0
        continue;
1309
0
      }
1310
0
    } else if (next_vmk->protection == BITLK_PROTECTION_RECOVERY_PASSPHRASE) {
1311
0
      r = get_recovery_key(cd, password, passwordLen, &recovery_key);
1312
0
      if (r) {
1313
        /* something wrong happened, but we still want to check other key slots */
1314
0
        next_vmk = next_vmk->next;
1315
0
        continue;
1316
0
      }
1317
0
      if (recovery_key == NULL) {
1318
        /* r = 0 but no key -> given passphrase is not a recovery passphrase */
1319
0
        r = -EPERM;
1320
0
        next_vmk = next_vmk->next;
1321
0
        continue;
1322
0
      }
1323
0
      log_dbg(cd, "Trying to use given password as a recovery key.");
1324
0
      r = bitlk_kdf(crypt_volume_key_get_key(recovery_key),
1325
0
              crypt_volume_key_length(recovery_key),
1326
0
              true, next_vmk->salt, &vmk_dec_key);
1327
0
      crypt_free_volume_key(recovery_key);
1328
0
      if (r)
1329
0
        return r;
1330
0
    } else if (next_vmk->protection == BITLK_PROTECTION_STARTUP_KEY) {
1331
0
      r = get_startup_key(cd, password, passwordLen, next_vmk, &vmk_dec_key, params);
1332
0
      if (r) {
1333
0
        next_vmk = next_vmk->next;
1334
0
        continue;
1335
0
      }
1336
0
      log_dbg(cd, "Trying to use external key found in provided password.");
1337
0
    } else if (next_vmk->protection == BITLK_PROTECTION_CLEAR_KEY) {
1338
0
      r = get_clear_key(cd, next_vmk, &vmk_dec_key);
1339
0
      if (r) {
1340
        /* something wrong happened, but we still want to check other key slots */
1341
0
        next_vmk = next_vmk->next;
1342
0
        continue;
1343
0
      }
1344
0
      is_decrypted = true;
1345
0
      open_vmk_key = vmk_dec_key;
1346
0
      log_dbg(cd, "Extracted VMK using clearkey.");
1347
0
    } else {
1348
      /* only passphrase, recovery passphrase, startup key and clearkey VMKs supported right now */
1349
0
      log_dbg(cd, "Skipping %s", get_vmk_protection_string(next_vmk->protection));
1350
0
      next_vmk = next_vmk->next;
1351
0
      if (r == 0)
1352
        /* we need to set error code in case we have only unsupported VMKs */
1353
0
        r = -ENOTSUP;
1354
0
      continue;
1355
0
    }
1356
1357
0
    if (!is_decrypted) {
1358
0
      r = decrypt_key(cd, &open_vmk_key, next_vmk->vk, vmk_dec_key,
1359
0
          next_vmk->mac_tag, BITLK_VMK_MAC_TAG_SIZE,
1360
0
          next_vmk->nonce, BITLK_NONCE_SIZE, false);
1361
1362
0
      crypt_free_volume_key(vmk_dec_key);
1363
0
    }
1364
0
    if (r < 0) {
1365
0
      log_dbg(cd, "Failed to decrypt VMK using provided passphrase.");
1366
1367
0
      if (r == -ENOTSUP)
1368
0
        return r;
1369
0
      next_vmk = next_vmk->next;
1370
0
      continue;
1371
0
    }
1372
1373
0
    log_dbg(cd, "Trying to decrypt validation metadata using VMK.");
1374
0
    r = crypt_bitlk_decrypt_key(crypt_volume_key_get_key(open_vmk_key),
1375
0
      crypt_volume_key_length(open_vmk_key),
1376
0
      (const char*)params->validation->enc_datum,
1377
0
      (char *)&dec_hash,
1378
0
      BITLK_VALIDATION_VMK_DATA_SIZE - BITLK_NONCE_SIZE - BITLK_VMK_MAC_TAG_SIZE,
1379
0
      (const char*)params->validation->nonce, BITLK_NONCE_SIZE,
1380
0
      (const char*)params->validation->mac_tag, BITLK_VMK_MAC_TAG_SIZE);
1381
0
    if (r < 0) {
1382
0
      log_dbg(cd, "Failed to decrypt validation metadata using VMK.");
1383
0
      crypt_free_volume_key(open_vmk_key);
1384
0
      if (r == -ENOTSUP)
1385
0
        return r;
1386
0
      break;
1387
0
    }
1388
1389
    /* now, do the MAC validation */
1390
0
    if (le16_to_cpu(dec_hash.role) != 0 ||le16_to_cpu(dec_hash.type) != 1 ||
1391
0
      (le16_to_cpu(dec_hash.hash_type) != 0x2005)) {
1392
0
      log_dbg(cd, "Failed to parse decrypted validation metadata.");
1393
0
      crypt_free_volume_key(open_vmk_key);
1394
0
      return -ENOTSUP;
1395
0
    }
1396
1397
0
    if (memcmp(dec_hash.hash, params->sha256_fve, sizeof(dec_hash.hash)) != 0) {
1398
0
      log_dbg(cd, "Failed MAC validation of BITLK FVE metadata.");
1399
0
      crypt_free_volume_key(open_vmk_key);
1400
0
      return -EINVAL;
1401
0
    }
1402
1403
0
    r = decrypt_key(cd, open_fvek_key, params->fvek->vk, open_vmk_key,
1404
0
        params->fvek->mac_tag, BITLK_VMK_MAC_TAG_SIZE,
1405
0
        params->fvek->nonce, BITLK_NONCE_SIZE, true);
1406
0
    if (r < 0) {
1407
0
      log_dbg(cd, "Failed to decrypt FVEK using VMK.");
1408
0
      crypt_free_volume_key(open_vmk_key);
1409
0
      if (r == -ENOTSUP)
1410
0
        return r;
1411
0
    } else {
1412
0
      crypt_free_volume_key(open_vmk_key);
1413
0
      break;
1414
0
    }
1415
1416
0
    next_vmk = next_vmk->next;
1417
0
  }
1418
1419
0
  if (r) {
1420
0
    log_dbg(cd, "No more VMKs to try.");
1421
0
    return r;
1422
0
  }
1423
1424
0
  return 0;
1425
0
}
1426
1427
static int _activate_check(struct crypt_device *cd,
1428
               const struct bitlk_metadata *params)
1429
0
{
1430
0
  if (!params->state) {
1431
0
    log_err(cd, _("This BITLK device is in an unsupported state and cannot be activated."));
1432
0
    return -ENOTSUP;
1433
0
  }
1434
1435
0
  if (params->type != BITLK_ENCRYPTION_TYPE_NORMAL) {
1436
0
    log_err(cd, _("BITLK devices with type '%s' cannot be activated."), get_bitlk_type_string(params->type));
1437
0
    return -ENOTSUP;
1438
0
  }
1439
1440
0
  return 0;
1441
0
}
1442
1443
static int _activate(struct crypt_device *cd,
1444
         const char *name,
1445
         struct volume_key *open_fvek_key,
1446
         const struct bitlk_metadata *params,
1447
         uint32_t flags)
1448
0
{
1449
0
  int r = 0;
1450
0
  int i = 0;
1451
0
  int j = 0;
1452
0
  int min = 0;
1453
0
  int num_segments = 0;
1454
0
  struct crypt_dm_active_device dmd = {
1455
0
    .flags = flags,
1456
0
  };
1457
0
  struct dm_target *next_segment = NULL;
1458
0
  struct segment segments[MAX_BITLK_SEGMENTS] = {};
1459
0
  struct segment temp;
1460
0
  uint64_t next_start = 0;
1461
0
  uint64_t next_end = 0;
1462
0
  uint64_t last_segment = 0;
1463
0
  uint64_t dmt_flags = 0;
1464
1465
0
  r = _activate_check(cd, params);
1466
0
  if (r)
1467
0
    return r;
1468
1469
0
  r = device_block_adjust(cd, crypt_data_device(cd), DEV_EXCL,
1470
0
        0, &dmd.size, &dmd.flags);
1471
0
  if (r)
1472
0
    return r;
1473
1474
0
  if (dmd.size * SECTOR_SIZE != params->volume_size)
1475
0
    log_std(cd, _("WARNING: BitLocker volume size %" PRIu64 " does not match the underlying device size %" PRIu64 ""),
1476
0
      params->volume_size,
1477
0
      dmd.size * SECTOR_SIZE);
1478
1479
  /* there will be always 4 dm-zero segments: 3x metadata, 1x FS header */
1480
0
  for (i = 0; i < 3; i++) {
1481
0
    segments[num_segments].offset = params->metadata_offset[i] / SECTOR_SIZE;
1482
0
    segments[num_segments].length = BITLK_FVE_METADATA_SIZE / SECTOR_SIZE;
1483
0
    segments[num_segments].iv_offset = 0;
1484
0
    segments[num_segments].type = BITLK_SEGTYPE_ZERO;
1485
0
    num_segments++;
1486
0
  }
1487
0
  segments[num_segments].offset = params->volume_header_offset / SECTOR_SIZE;
1488
0
  segments[num_segments].length = params->volume_header_size / SECTOR_SIZE;
1489
0
  segments[num_segments].iv_offset = 0;
1490
0
  segments[num_segments].type = BITLK_SEGTYPE_ZERO;
1491
0
  num_segments++;
1492
1493
  /* filesystem header (moved from the special location) */
1494
0
  segments[num_segments].offset = 0;
1495
0
  segments[num_segments].length = params->volume_header_size / SECTOR_SIZE;
1496
0
  segments[num_segments].iv_offset = params->volume_header_offset / SECTOR_SIZE;
1497
0
  segments[num_segments].type = BITLK_SEGTYPE_CRYPT;
1498
0
  num_segments++;
1499
1500
  /* now fill gaps between the dm-zero segments with dm-crypt */
1501
0
  last_segment = params->volume_header_size / SECTOR_SIZE;
1502
0
  while (true) {
1503
0
    next_start = dmd.size;
1504
0
    next_end = dmd.size;
1505
1506
    /* start of the next segment: end of the first existing segment after the last added */
1507
0
    for (i = 0; i < num_segments; i++)
1508
0
      if (segments[i].offset + segments[i].length < next_start && segments[i].offset + segments[i].length >= last_segment)
1509
0
        next_start = segments[i].offset + segments[i].length;
1510
1511
    /* end of the next segment: start of the next segment after start we found above */
1512
0
    for (i = 0; i < num_segments; i++)
1513
0
      if (segments[i].offset < next_end && segments[i].offset >= next_start)
1514
0
        next_end = segments[i].offset;
1515
1516
    /* two zero segments next to each other, just bump the last_segment
1517
       so the algorithm moves */
1518
0
    if (next_end - next_start == 0) {
1519
0
      last_segment = next_end + 1;
1520
0
      continue;
1521
0
    }
1522
1523
0
    segments[num_segments].offset = next_start;
1524
0
    segments[num_segments].length = next_end - next_start;
1525
0
    segments[num_segments].iv_offset = next_start;
1526
0
    segments[num_segments].type = BITLK_SEGTYPE_CRYPT;
1527
0
    last_segment = next_end;
1528
0
    num_segments++;
1529
1530
0
    if (next_end == dmd.size)
1531
0
      break;
1532
1533
0
    if (num_segments == 10) {
1534
0
      log_dbg(cd, "Failed to calculate number of dm-crypt segments for open.");
1535
0
      r = -EINVAL;
1536
0
      goto out;
1537
0
    }
1538
0
  }
1539
1540
  /* device mapper needs the segment sorted */
1541
0
  for (i = 0; i < num_segments - 1; i++) {
1542
0
    min = i;
1543
0
    for (j = i + 1; j < num_segments; j++)
1544
0
      if (segments[j].offset < segments[min].offset)
1545
0
        min = j;
1546
1547
0
    if (min != i) {
1548
0
      temp.offset = segments[min].offset;
1549
0
      temp.length = segments[min].length;
1550
0
      temp.iv_offset = segments[min].iv_offset;
1551
0
      temp.type = segments[min].type;
1552
1553
0
      segments[min].offset = segments[i].offset;
1554
0
      segments[min].length = segments[i].length;
1555
0
      segments[min].iv_offset = segments[i].iv_offset;
1556
0
      segments[min].type = segments[i].type;
1557
1558
0
      segments[i].offset = temp.offset;
1559
0
      segments[i].length = temp.length;
1560
0
      segments[i].iv_offset = temp.iv_offset;
1561
0
      segments[i].type = temp.type;
1562
0
    }
1563
0
  }
1564
1565
0
  if (params->sector_size != SECTOR_SIZE)
1566
0
    dmd.flags |= CRYPT_ACTIVATE_IV_LARGE_SECTORS;
1567
1568
0
  r = dm_targets_allocate(&dmd.segment, num_segments);
1569
0
  if (r)
1570
0
    goto out;
1571
0
  next_segment = &dmd.segment;
1572
1573
0
  for (i = 0; i < num_segments; i++) {
1574
0
    if (segments[i].type == BITLK_SEGTYPE_ZERO)
1575
0
      r = dm_zero_target_set(next_segment,
1576
0
                 segments[i].offset,
1577
0
                 segments[i].length);
1578
0
    else if (segments[i].type == BITLK_SEGTYPE_CRYPT)
1579
0
      r = dm_crypt_target_set(next_segment,
1580
0
            segments[i].offset,
1581
0
            segments[i].length,
1582
0
            crypt_data_device(cd),
1583
0
            open_fvek_key,
1584
0
            crypt_get_cipher_spec(cd),
1585
0
            segments[i].iv_offset,
1586
0
            segments[i].iv_offset,
1587
0
            NULL, 0, 0,
1588
0
            params->sector_size);
1589
0
    if (r)
1590
0
      goto out;
1591
1592
0
    next_segment = next_segment->next;
1593
0
  }
1594
1595
0
  log_dbg(cd, "Trying to activate BITLK on device %s%s%s.",
1596
0
    device_path(crypt_data_device(cd)), name ? " with name " :"", name ?: "");
1597
1598
0
  r = dm_create_device(cd, name, CRYPT_BITLK, &dmd);
1599
0
  if (r < 0) {
1600
0
    dm_flags(cd, DM_CRYPT, &dmt_flags);
1601
0
    if (!strcmp(params->cipher_mode, "cbc-eboiv") && !(dmt_flags & DM_BITLK_EBOIV_SUPPORTED)) {
1602
0
      log_err(cd, _("Cannot activate device, kernel dm-crypt is missing support for BITLK IV."));
1603
0
      r = -ENOTSUP;
1604
0
    }
1605
0
    if (!strcmp(params->cipher_mode, "cbc-elephant") && !(dmt_flags & DM_BITLK_ELEPHANT_SUPPORTED)) {
1606
0
      log_err(cd, _("Cannot activate device, kernel dm-crypt is missing support for BITLK Elephant diffuser."));
1607
0
      r = -ENOTSUP;
1608
0
    }
1609
0
    if ((dmd.flags & CRYPT_ACTIVATE_IV_LARGE_SECTORS) && !(dmt_flags & DM_SECTOR_SIZE_SUPPORTED)) {
1610
0
      log_err(cd, _("Cannot activate device, kernel dm-crypt is missing support for large sector size."));
1611
0
      r = -ENOTSUP;
1612
0
    }
1613
0
    if (dm_flags(cd, DM_ZERO, &dmt_flags) < 0) {
1614
0
      log_err(cd, _("Cannot activate device, kernel dm-zero module is missing."));
1615
0
      r = -ENOTSUP;
1616
0
    }
1617
0
  }
1618
0
out:
1619
0
  dm_targets_free(cd, &dmd);
1620
0
  return r;
1621
0
}
1622
1623
int BITLK_activate_by_volume_key(struct crypt_device *cd,
1624
         const char *name,
1625
         struct volume_key *vk,
1626
         const struct bitlk_metadata *params,
1627
         uint32_t flags)
1628
0
{
1629
0
  int r;
1630
1631
0
  r = _activate_check(cd, params);
1632
0
  if (r)
1633
0
    return r;
1634
1635
0
  return _activate(cd, name, vk, params, flags);
1636
0
}