Coverage Report

Created: 2026-10-28 07:07

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cryptsetup/lib/luks2/luks2_disk_metadata.c
Line
Count
Source
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
 * LUKS - Linux Unified Key Setup v2
4
 *
5
 * Copyright (C) 2015-2026 Red Hat, Inc. All rights reserved.
6
 * Copyright (C) 2015-2026 Milan Broz
7
 */
8
9
#include "luks2_internal.h"
10
11
/*
12
 * Helper functions
13
 */
14
static json_object *parse_json_len(struct crypt_device *cd, const char *json_area,
15
          uint64_t max_length, int *json_len)
16
7.17k
{
17
7.17k
  json_object *jobj;
18
7.17k
  json_tokener *jtok;
19
20
   /* INT32_MAX is internal (json-c) json_tokener_parse_ex() limit */
21
7.17k
  if (!json_area || max_length > INT32_MAX)
22
0
    return NULL;
23
24
7.17k
  jtok = json_tokener_new();
25
7.17k
  if (!jtok) {
26
0
    log_dbg(cd, "ERROR: Failed to init json tokener");
27
0
    return NULL;
28
0
  }
29
30
7.17k
  jobj = json_tokener_parse_ex(jtok, json_area, max_length);
31
7.17k
  if (!jobj)
32
412
    log_dbg(cd, "ERROR: Failed to parse json data (%d): %s",
33
7.17k
      json_tokener_get_error(jtok),
34
7.17k
      json_tokener_error_desc(json_tokener_get_error(jtok)));
35
6.76k
  else
36
6.76k
    *json_len = jtok->char_offset;
37
38
7.17k
  json_tokener_free(jtok);
39
40
7.17k
  return jobj;
41
7.17k
}
42
43
static void log_dbg_checksum(struct crypt_device *cd,
44
           const uint8_t *csum, const char *csum_alg, const char *info)
45
17.9k
{
46
17.9k
  char csum_txt[2*LUKS2_CHECKSUM_L+1];
47
17.9k
  int i;
48
49
830k
  for (i = 0; i < crypt_hash_size(csum_alg); i++)
50
812k
    if (snprintf(&csum_txt[i*2], 3, "%02hhx", (const char)csum[i]) != 2)
51
0
      return;
52
53
17.9k
  log_dbg(cd, "Checksum:%s (%s)", &csum_txt[0], info);
54
17.9k
}
55
56
/*
57
 * Calculate hash (checksum) of |LUKS2_bin|LUKS2_JSON_area| from in-memory structs.
58
 * LUKS2 on-disk header contains uniques salt both for primary and secondary header.
59
 * Checksum is always calculated with zeroed checksum field in binary header.
60
 */
61
static int hdr_checksum_calculate(const char *alg, struct luks2_hdr_disk *hdr_disk,
62
          const char *json_area, size_t json_len)
63
10.0k
{
64
10.0k
  struct crypt_hash *hd = NULL;
65
10.0k
  int hash_size, r;
66
67
10.0k
  hash_size = crypt_hash_size(alg);
68
10.0k
  if (hash_size <= 0 || crypt_hash_init(&hd, alg))
69
0
    return -EINVAL;
70
71
  /* Binary header, csum zeroed. */
72
10.0k
  r = crypt_hash_write(hd, (char*)hdr_disk, LUKS2_HDR_BIN_LEN);
73
74
  /* JSON area (including unused space) */
75
10.0k
  if (!r)
76
10.0k
    r = crypt_hash_write(hd, json_area, json_len);
77
78
10.0k
  if (!r)
79
10.0k
    r = crypt_hash_final(hd, (char*)hdr_disk->csum, (size_t)hash_size);
80
81
10.0k
  crypt_hash_destroy(hd);
82
10.0k
  return r;
83
10.0k
}
84
85
/*
86
 * Compare hash (checksum) of on-disk and in-memory header.
87
 */
88
static int hdr_checksum_check(struct crypt_device *cd,
89
            const char *alg, struct luks2_hdr_disk *hdr_disk,
90
            const char *json_area, size_t json_len)
91
8.33k
{
92
8.33k
  struct luks2_hdr_disk hdr_tmp;
93
8.33k
  int hash_size, r;
94
95
8.33k
  hash_size = crypt_hash_size(alg);
96
8.33k
  if (hash_size <= 0)
97
470
    return -EINVAL;
98
99
  /* Copy header and zero checksum. */
100
7.86k
  memcpy(&hdr_tmp, hdr_disk, LUKS2_HDR_BIN_LEN);
101
7.86k
  memset(&hdr_tmp.csum, 0, sizeof(hdr_tmp.csum));
102
103
7.86k
  r = hdr_checksum_calculate(alg, &hdr_tmp, json_area, json_len);
104
7.86k
  if (r < 0)
105
0
    return r;
106
107
7.86k
  log_dbg_checksum(cd, hdr_disk->csum, alg, "on-disk");
108
7.86k
  log_dbg_checksum(cd, hdr_tmp.csum, alg, "in-memory");
109
110
7.86k
  if (memcmp(hdr_tmp.csum, hdr_disk->csum, (size_t)hash_size))
111
686
    return -EINVAL;
112
113
7.17k
  return 0;
114
7.86k
}
115
116
/*
117
 * Convert header from on-disk format to in-memory struct
118
 */
119
static void hdr_from_disk(struct luks2_hdr_disk *hdr_disk1,
120
        struct luks2_hdr_disk *hdr_disk2,
121
        struct luks2_hdr *hdr,
122
        int secondary)
123
6.64k
{
124
6.64k
  hdr->version  = be16_to_cpu(hdr_disk1->version);
125
6.64k
  hdr->hdr_size = be64_to_cpu(hdr_disk1->hdr_size);
126
6.64k
  hdr->seqid    = be64_to_cpu(hdr_disk1->seqid);
127
128
6.64k
  memcpy(hdr->label, hdr_disk1->label, LUKS2_LABEL_L);
129
6.64k
  hdr->label[LUKS2_LABEL_L - 1] = '\0';
130
6.64k
  memcpy(hdr->subsystem, hdr_disk1->subsystem, LUKS2_LABEL_L);
131
6.64k
  hdr->subsystem[LUKS2_LABEL_L - 1] = '\0';
132
6.64k
  memcpy(hdr->checksum_alg, hdr_disk1->checksum_alg, LUKS2_CHECKSUM_ALG_L);
133
6.64k
  hdr->checksum_alg[LUKS2_CHECKSUM_ALG_L - 1] = '\0';
134
6.64k
  memcpy(hdr->uuid, hdr_disk1->uuid, LUKS2_UUID_L);
135
6.64k
  hdr->uuid[LUKS2_UUID_L - 1] = '\0';
136
137
6.64k
  if (secondary) {
138
5.71k
    memcpy(hdr->salt1, hdr_disk2->salt, LUKS2_SALT_L);
139
5.71k
    memcpy(hdr->salt2, hdr_disk1->salt, LUKS2_SALT_L);
140
5.71k
  } else {
141
930
    memcpy(hdr->salt1, hdr_disk1->salt, LUKS2_SALT_L);
142
930
    memcpy(hdr->salt2, hdr_disk2->salt, LUKS2_SALT_L);
143
930
  }
144
6.64k
}
145
146
/*
147
 * Convert header from in-memory struct to on-disk format
148
 */
149
static void hdr_to_disk(struct luks2_hdr *hdr,
150
      struct luks2_hdr_disk *hdr_disk,
151
      int secondary, uint64_t offset)
152
2.21k
{
153
2.21k
  assert(((char*)&(hdr_disk->_padding4096) - (char*)&(hdr_disk->magic)) == 512);
154
155
2.21k
  memset(hdr_disk, 0, LUKS2_HDR_BIN_LEN);
156
157
2.21k
  memcpy(&hdr_disk->magic, secondary ? LUKS2_MAGIC_2ND : LUKS2_MAGIC_1ST, LUKS2_MAGIC_L);
158
2.21k
  hdr_disk->version     = cpu_to_be16(hdr->version);
159
2.21k
  hdr_disk->hdr_size    = cpu_to_be64(hdr->hdr_size);
160
2.21k
  hdr_disk->hdr_offset  = cpu_to_be64(offset);
161
2.21k
  hdr_disk->seqid       = cpu_to_be64(hdr->seqid);
162
163
2.21k
  memcpy(hdr_disk->label, hdr->label, MIN(strlen(hdr->label), LUKS2_LABEL_L));
164
2.21k
  hdr_disk->label[LUKS2_LABEL_L - 1] = '\0';
165
2.21k
  memcpy(hdr_disk->subsystem, hdr->subsystem, MIN(strlen(hdr->subsystem), LUKS2_LABEL_L));
166
2.21k
  hdr_disk->subsystem[LUKS2_LABEL_L - 1] = '\0';
167
2.21k
  memcpy(hdr_disk->checksum_alg, hdr->checksum_alg, MIN(strlen(hdr->checksum_alg), LUKS2_CHECKSUM_ALG_L));
168
2.21k
  hdr_disk->checksum_alg[LUKS2_CHECKSUM_ALG_L - 1] = '\0';
169
2.21k
  memcpy(hdr_disk->uuid, hdr->uuid, MIN(strlen(hdr->uuid), LUKS2_UUID_L));
170
2.21k
  hdr_disk->uuid[LUKS2_UUID_L - 1] = '\0';
171
172
2.21k
  memcpy(hdr_disk->salt, secondary ? hdr->salt2 : hdr->salt1, LUKS2_SALT_L);
173
2.21k
}
174
175
/*
176
 * Sanity checks before checksum is validated
177
 */
178
static int hdr_disk_sanity_check_pre(struct crypt_device *cd,
179
             struct luks2_hdr_disk *hdr,
180
             size_t *hdr_json_size, int secondary,
181
             uint64_t offset)
182
38.1k
{
183
38.1k
  uint64_t hdr_size;
184
185
38.1k
  if (memcmp(hdr->magic, secondary ? LUKS2_MAGIC_2ND : LUKS2_MAGIC_1ST, LUKS2_MAGIC_L))
186
29.4k
    return -EINVAL;
187
188
8.74k
  if (be16_to_cpu(hdr->version) != 2) {
189
94
    log_dbg(cd, "Unsupported LUKS2 header version %u.", be16_to_cpu(hdr->version));
190
94
    return -EINVAL;
191
94
  }
192
193
8.64k
  if (offset != be64_to_cpu(hdr->hdr_offset)) {
194
158
    log_dbg(cd, "LUKS2 offset 0x%04" PRIx64 " on device differs to expected offset 0x%04" PRIx64 ".",
195
158
      be64_to_cpu(hdr->hdr_offset), offset);
196
158
    return -EINVAL;
197
158
  }
198
199
8.48k
  hdr_size = be64_to_cpu(hdr->hdr_size);
200
201
8.48k
  if (hdr_size < LUKS2_HDR_16K_LEN || hdr_size > LUKS2_HDR_OFFSET_MAX) {
202
140
    log_dbg(cd, "LUKS2 header has bogus size 0x%04" PRIx64 ".", hdr_size);
203
140
    return -EINVAL;
204
140
  }
205
206
8.34k
  if (secondary && (offset != hdr_size)) {
207
17
    log_dbg(cd, "LUKS2 offset 0x%04" PRIx64 " in secondary header does not match size 0x%04" PRIx64 ".",
208
17
      offset, hdr_size);
209
17
    return -EINVAL;
210
17
  }
211
212
  /* FIXME: sanity check checksum alg. */
213
214
8.33k
  log_dbg(cd, "LUKS2 header version %u of size %" PRIu64 " bytes, checksum %s.",
215
8.33k
    be16_to_cpu(hdr->version), hdr_size,
216
8.33k
    hdr->checksum_alg);
217
218
8.33k
  *hdr_json_size = hdr_size - LUKS2_HDR_BIN_LEN;
219
8.33k
  return 0;
220
8.34k
}
221
222
/*
223
 * Read LUKS2 header from disk at specific offset.
224
 */
225
static int hdr_read_disk(struct crypt_device *cd,
226
       struct device *device, struct luks2_hdr_disk *hdr_disk,
227
       char **json_area, uint64_t offset, int secondary)
228
38.1k
{
229
38.1k
  size_t hdr_json_size = 0;
230
38.1k
  int devfd, r;
231
232
38.1k
  log_dbg(cd, "Trying to read %s LUKS2 header at offset 0x%" PRIx64 ".",
233
38.1k
    secondary ? "secondary" : "primary", offset);
234
235
38.1k
  devfd = device_open_locked(cd, device, O_RDONLY);
236
38.1k
  if (devfd < 0)
237
0
    return devfd == -1 ? -EIO : devfd;
238
239
  /*
240
   * Read binary header and run sanity check before reading
241
   * JSON area and validating checksum.
242
   */
243
38.1k
  if (read_lseek_blockwise(devfd, device_block_size(cd, device),
244
38.1k
         device_alignment(device), hdr_disk,
245
38.1k
         LUKS2_HDR_BIN_LEN, offset) != LUKS2_HDR_BIN_LEN) {
246
0
    memset(hdr_disk, 0, LUKS2_HDR_BIN_LEN);
247
0
    return -EIO;
248
0
  }
249
250
  /*
251
   * hdr_json_size is validated if this call succeeds
252
   */
253
38.1k
  r = hdr_disk_sanity_check_pre(cd, hdr_disk, &hdr_json_size, secondary, offset);
254
38.1k
  if (r < 0)
255
29.8k
    return r;
256
257
  /*
258
   * Allocate and read JSON area. Always the whole area must be read.
259
   */
260
8.33k
  *json_area = malloc(hdr_json_size);
261
8.33k
  if (!*json_area)
262
0
    return -ENOMEM;
263
264
8.33k
  if (read_lseek_blockwise(devfd, device_block_size(cd, device),
265
8.33k
         device_alignment(device), *json_area, hdr_json_size,
266
8.33k
         offset + LUKS2_HDR_BIN_LEN) != (ssize_t)hdr_json_size) {
267
0
    free(*json_area);
268
0
    *json_area = NULL;
269
0
    return -EIO;
270
0
  }
271
272
  /*
273
   * Calculate and validate checksum and zero it afterwards.
274
   */
275
8.33k
  if (hdr_checksum_check(cd, hdr_disk->checksum_alg, hdr_disk,
276
8.33k
        *json_area, hdr_json_size)) {
277
1.15k
    log_dbg(cd, "LUKS2 header checksum error (offset %" PRIu64 ").", offset);
278
1.15k
    free(*json_area);
279
1.15k
    *json_area = NULL;
280
1.15k
    r = -EINVAL;
281
1.15k
  }
282
8.33k
  memset(hdr_disk->csum, 0, LUKS2_CHECKSUM_L);
283
284
8.33k
  return r;
285
8.33k
}
286
287
/*
288
 * Write LUKS2 header to disk at specific offset.
289
 */
290
static int hdr_write_disk(struct crypt_device *cd,
291
        struct device *device, struct luks2_hdr *hdr,
292
        const char *json_area, size_t write_area_len,
293
        int secondary)
294
4.43k
{
295
4.43k
  struct luks2_hdr_disk hdr_disk;
296
4.43k
  uint64_t offset = secondary ? hdr->hdr_size : 0;
297
4.43k
  size_t hdr_json_len;
298
4.43k
  int devfd, r;
299
300
4.43k
  hdr_json_len = hdr->hdr_size - LUKS2_HDR_BIN_LEN;
301
302
4.43k
  assert(write_area_len <= hdr_json_len);
303
304
4.43k
  log_dbg(cd, "Trying to write LUKS2 header (%zu bytes) at offset %" PRIu64 ".",
305
4.43k
    write_area_len, offset);
306
307
4.43k
  devfd = device_open_locked(cd, device, O_RDWR);
308
4.43k
  if (devfd < 0)
309
2.21k
    return devfd == -1 ? -EINVAL : devfd;
310
311
2.21k
  hdr_to_disk(hdr, &hdr_disk, secondary, offset);
312
313
  /*
314
   * Write header without checksum but with proper seqid.
315
   */
316
2.21k
  if (write_lseek_blockwise(devfd, device_block_size(cd, device),
317
2.21k
          device_alignment(device), (char *)&hdr_disk,
318
2.21k
          LUKS2_HDR_BIN_LEN, offset) < (ssize_t)LUKS2_HDR_BIN_LEN) {
319
0
    return -EIO;
320
0
  }
321
322
  /*
323
   * Write json area.
324
   */
325
2.21k
  if (write_lseek_blockwise(devfd, device_block_size(cd, device),
326
2.21k
          device_alignment(device),
327
2.21k
          CONST_CAST(char*)json_area, write_area_len,
328
2.21k
          LUKS2_HDR_BIN_LEN + offset) < (ssize_t)write_area_len) {
329
0
    return -EIO;
330
0
  }
331
332
  /*
333
   * Calculate checksum and write header with checksum.
334
   */
335
2.21k
  r = hdr_checksum_calculate(hdr_disk.checksum_alg, &hdr_disk,
336
2.21k
           json_area, hdr_json_len);
337
2.21k
  if (r < 0) {
338
0
    return r;
339
0
  }
340
2.21k
  log_dbg_checksum(cd, hdr_disk.csum, hdr_disk.checksum_alg, "in-memory");
341
342
2.21k
  if (write_lseek_blockwise(devfd, device_block_size(cd, device),
343
2.21k
          device_alignment(device), (char *)&hdr_disk,
344
2.21k
          LUKS2_HDR_BIN_LEN, offset) < (ssize_t)LUKS2_HDR_BIN_LEN)
345
0
    r = -EIO;
346
347
2.21k
  device_sync(cd, device);
348
2.21k
  return r;
349
2.21k
}
350
351
static int LUKS2_check_sequence_id(struct crypt_device *cd, struct luks2_hdr *hdr, struct device *device)
352
0
{
353
0
  int devfd;
354
0
  struct luks2_hdr_disk dhdr;
355
356
0
  if (!hdr)
357
0
    return -EINVAL;
358
359
0
  devfd = device_open_locked(cd, device, O_RDONLY);
360
0
  if (devfd < 0)
361
0
    return devfd == -1 ? -EINVAL : devfd;
362
363
  /* we need only first 512 bytes, see luks2_hdr_disk structure */
364
0
  if ((read_lseek_blockwise(devfd, device_block_size(cd, device),
365
0
       device_alignment(device), &dhdr, 512, 0) != 512))
366
0
    return -EIO;
367
368
  /* there's nothing to check if there's no LUKS2 header */
369
0
  if ((be16_to_cpu(dhdr.version) != 2) ||
370
0
      memcmp(dhdr.magic, LUKS2_MAGIC_1ST, LUKS2_MAGIC_L) ||
371
0
      strcmp(dhdr.uuid, hdr->uuid))
372
0
    return 0;
373
374
0
  return hdr->seqid != be64_to_cpu(dhdr.seqid);
375
0
}
376
377
int LUKS2_device_write_lock(struct crypt_device *cd, struct luks2_hdr *hdr, struct device *device)
378
0
{
379
0
  int r = device_write_lock(cd, device);
380
381
0
  if (r < 0) {
382
0
    log_err(cd, _("Failed to acquire write lock on device %s."), device_path(device));
383
0
    return r;
384
0
  }
385
386
  /* run sequence id check only on first write lock (r == 1) and w/o LUKS2 reencryption in-progress */
387
0
  if (r == 1 && !crypt_get_luks2_reencrypt(cd)) {
388
0
    log_dbg(cd, "Checking context sequence id matches value stored on disk.");
389
0
    if (LUKS2_check_sequence_id(cd, hdr, device)) {
390
0
      device_write_unlock(cd, device);
391
0
      log_err(cd, _("Detected attempt for concurrent LUKS2 metadata update. Aborting operation."));
392
0
      return -EINVAL;
393
0
    }
394
0
  }
395
396
0
  return 0;
397
0
}
398
399
/*
400
 * Convert in-memory LUKS2 header and write it to disk.
401
 * This will increase sequence id, write both header copies and calculate checksum.
402
 */
403
int LUKS2_disk_hdr_write(struct crypt_device *cd, struct luks2_hdr *hdr, struct device *device, bool seqid_check)
404
0
{
405
0
  char *json_area;
406
0
  const char *json_text;
407
0
  size_t json_data_len, json_area_len, json_area_write_len;
408
0
  int r;
409
410
0
  if (hdr->version != 2) {
411
0
    log_dbg(cd, "Unsupported LUKS2 header version (%u).", hdr->version);
412
0
    return -EINVAL;
413
0
  }
414
415
0
  r = device_check_size(cd, crypt_metadata_device(cd), LUKS2_hdr_and_areas_size(hdr), 1);
416
0
  if (r)
417
0
    return r;
418
419
  /*
420
   * Generate text space-efficient JSON representation to json area.
421
   */
422
0
  json_text = crypt_jobj_to_string_on_disk(hdr->jobj);
423
0
  if (!json_text || !*json_text) {
424
0
    log_dbg(cd, "Cannot parse JSON object to text representation.");
425
0
    return -ENOMEM;
426
0
  }
427
428
0
  json_area_len = hdr->hdr_size - LUKS2_HDR_BIN_LEN;
429
0
  json_area_write_len = json_data_len = strlen(json_text);
430
431
0
  if (json_data_len > (json_area_len - 1)) {
432
0
    log_dbg(cd, "JSON is too large (%zu > %zu).", json_data_len, json_area_len - 1);
433
0
    return -EINVAL;
434
0
  }
435
436
  /*
437
   * Allocate and zero JSON area (of proper header size).
438
   */
439
0
  json_area = crypt_zalloc(json_area_len);
440
0
  if (!json_area)
441
0
    return -ENOMEM;
442
443
  /*
444
   * If the metadata in 'json_area' buffer is smaller than last on-disk
445
   * metadata we also have to erase the remaining bytes between the tail
446
   * of current metadata and the on-disk metadata end pointer. Set write
447
   * area length large enough to overwrite it.
448
   *
449
   * If seqid_check is turned off (during LUKS2 format) write entire
450
   * LUKS2 metadata size instead.
451
   *
452
   * Turn off the optimization also during metadata upconversion
453
   * (hdr->on_disk_json_end_offset == 0).
454
   */
455
0
  if (seqid_check && (json_data_len < hdr->on_disk_json_end_offset))
456
0
    json_area_write_len = hdr->on_disk_json_end_offset;
457
0
  else if (!seqid_check || !hdr->on_disk_json_end_offset)
458
0
    json_area_write_len = json_area_len;
459
460
0
  strncpy(json_area, json_text, json_area_len);
461
462
0
  if (seqid_check)
463
0
    r = LUKS2_device_write_lock(cd, hdr, device);
464
0
  else
465
0
    r = device_write_lock(cd, device);
466
0
  if (r < 0) {
467
0
    free(json_area);
468
0
    return r;
469
0
  }
470
471
  /* Increase sequence id before writing it to disk. */
472
0
  hdr->seqid++;
473
474
  /* Write primary and secondary header */
475
0
  r = hdr_write_disk(cd, device, hdr, json_area, json_area_write_len, 0);
476
0
  if (!r)
477
0
    r = hdr_write_disk(cd, device, hdr, json_area, json_area_write_len, 1);
478
479
0
  if (r)
480
0
    log_dbg(cd, "LUKS2 header write failed (%d).", r);
481
482
  /* store new json end pointer or reset it on error */
483
0
  hdr->on_disk_json_end_offset = r ? 0 : json_data_len;
484
485
0
  device_write_unlock(cd, device);
486
487
0
  free(json_area);
488
0
  return r;
489
0
}
490
static int validate_json_area(struct crypt_device *cd, const char *json_area,
491
            uint64_t json_len, uint64_t max_length)
492
6.76k
{
493
6.76k
  char c;
494
495
  /* Enforce there are no needless opening bytes */
496
6.76k
  if (*json_area != '{') {
497
104
    log_dbg(cd, "ERROR: Opening character must be left curly bracket: '{'.");
498
104
    return -EINVAL;
499
104
  }
500
501
6.66k
  if (json_len >= max_length) {
502
0
    log_dbg(cd, "ERROR: Missing trailing null byte beyond parsed json data string.");
503
0
    return -EINVAL;
504
0
  }
505
506
  /*
507
   * TODO:
508
   *  validate there are legal json format characters between
509
   *  'json_area' and 'json_area + json_len'
510
   */
511
512
399M
  do {
513
399M
    c = *(json_area + json_len);
514
399M
    if (c != '\0') {
515
11
      log_dbg(cd, "ERROR: Forbidden ascii code 0x%02hhx found beyond json data string at offset %" PRIu64,
516
11
        c, json_len);
517
11
      return -EINVAL;
518
11
    }
519
399M
  } while (++json_len < max_length);
520
521
6.64k
  return 0;
522
6.66k
}
523
524
static int validate_luks2_json_object(struct crypt_device *cd, json_object *jobj_hdr, uint64_t length)
525
6.64k
{
526
6.64k
  int r;
527
528
  /* we require top level object to be of json_type_object */
529
6.64k
  r = !json_object_is_type(jobj_hdr, json_type_object);
530
6.64k
  if (r) {
531
2
    log_dbg(cd, "ERROR: Resulting object is not a json object type");
532
2
    return r;
533
2
  }
534
535
6.64k
  r = LUKS2_hdr_validate(cd, jobj_hdr, length);
536
6.64k
  if (r) {
537
268
    log_dbg(cd, "Repairing JSON metadata.");
538
    /* try to correct known glitches */
539
268
    LUKS2_hdr_repair(cd, jobj_hdr);
540
541
    /* run validation again */
542
268
    r = LUKS2_hdr_validate(cd, jobj_hdr, length);
543
268
  }
544
545
6.64k
  if (r)
546
268
    log_dbg(cd, "ERROR: LUKS2 validation failed");
547
548
6.64k
  return r;
549
6.64k
}
550
551
static json_object *parse_and_validate_json(struct crypt_device *cd,
552
              const char *json_area, uint64_t hdr_size,
553
              uint64_t *json_area_end)
554
7.17k
{
555
7.17k
  int json_len, r;
556
7.17k
  json_object *jobj;
557
7.17k
  uint64_t max_length;
558
559
7.17k
  assert(json_area_end);
560
561
7.17k
  if (hdr_size <= LUKS2_HDR_BIN_LEN || hdr_size > LUKS2_HDR_OFFSET_MAX) {
562
0
    log_dbg(cd, "LUKS2 header JSON has bogus size 0x%04" PRIx64 ".", hdr_size);
563
0
    return NULL;
564
0
  }
565
566
7.17k
  max_length = hdr_size - LUKS2_HDR_BIN_LEN;
567
568
7.17k
  jobj = parse_json_len(cd, json_area, max_length, &json_len);
569
7.17k
  if (!jobj)
570
412
    return NULL;
571
572
  /* successful parse_json_len must not return offset <= 0 */
573
7.17k
  assert(json_len > 0);
574
575
6.76k
  r = validate_json_area(cd, json_area, json_len, max_length);
576
6.76k
  if (!r)
577
6.64k
    r = validate_luks2_json_object(cd, jobj, max_length);
578
579
6.76k
  if (r) {
580
385
    json_object_put(jobj);
581
385
    jobj = NULL;
582
385
  }
583
584
6.76k
  *json_area_end = json_len;
585
586
6.76k
  return jobj;
587
6.76k
}
588
589
static int detect_device_signatures(struct crypt_device *cd, const char *path)
590
6.37k
{
591
6.37k
  blk_probe_status prb_state;
592
6.37k
  int r;
593
6.37k
  struct blkid_handle *h;
594
595
6.37k
  if (!blk_supported()) {
596
0
    log_dbg(cd, "Blkid probing of device signatures disabled.");
597
0
    return 0;
598
0
  }
599
600
6.37k
  if ((r = blk_init_by_path(&h, path))) {
601
0
    log_dbg(cd, "Failed to initialize blkid_handle by path.");
602
0
    return -EINVAL;
603
0
  }
604
605
  /* We don't care about details. Be fast. */
606
6.37k
  blk_set_chains_for_fast_detection(h);
607
608
  /* Filter out crypto_LUKS. we don't care now */
609
6.37k
  blk_superblocks_filter_luks(h);
610
611
6.37k
  prb_state = blk_safeprobe(h);
612
613
6.37k
  switch (prb_state) {
614
0
  case PRB_AMBIGUOUS:
615
0
    log_dbg(cd, "Blkid probe couldn't decide device type unambiguously.");
616
    /* fall through */
617
515
  case PRB_FAIL:
618
515
    log_dbg(cd, "Blkid probe failed.");
619
515
    r = -EINVAL;
620
515
    break;
621
1.43k
  case PRB_OK: /* crypto_LUKS type is filtered out */
622
1.43k
    r = -EINVAL;
623
624
1.43k
    if (blk_is_partition(h))
625
510
      log_dbg(cd, "Blkid probe detected partition type '%s'", blk_get_partition_type(h));
626
923
    else if (blk_is_superblock(h))
627
923
      log_dbg(cd, "blkid probe detected superblock type '%s'", blk_get_superblock_type(h));
628
1.43k
    break;
629
4.43k
  case PRB_EMPTY:
630
4.43k
    log_dbg(cd, "Blkid probe detected no foreign device signature.");
631
6.37k
  }
632
6.37k
  blk_free(h);
633
6.37k
  return r;
634
6.37k
}
635
636
/*
637
 * Read and convert on-disk LUKS2 header to in-memory representation..
638
 * Try to do recovery if on-disk state is not consistent.
639
 */
640
int LUKS2_disk_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr,
641
      struct device *device, int do_recovery, int do_blkprobe)
642
8.40k
{
643
8.40k
  enum { HDR_OK, HDR_OBSOLETE, HDR_FAIL, HDR_FAIL_IO } state_hdr1, state_hdr2;
644
8.40k
  struct luks2_hdr_disk hdr_disk1, hdr_disk2;
645
8.40k
  char *json_area1 = NULL, *json_area2 = NULL;
646
8.40k
  json_object *jobj_hdr1 = NULL, *jobj_hdr2 = NULL;
647
8.40k
  unsigned int i;
648
8.40k
  int r;
649
8.40k
  uint64_t hdr_size, json_area_end1 = 0, json_area_end2 = 0;
650
8.40k
  uint64_t hdr2_offsets[] = LUKS2_HDR2_OFFSETS;
651
652
  /* Skip auto-recovery if locks are disabled and we're not doing LUKS2 explicit repair */
653
8.40k
  if (do_recovery && do_blkprobe && !crypt_metadata_locking_enabled()) {
654
0
    do_recovery = 0;
655
0
    log_dbg(cd, "Disabling header auto-recovery due to locking being disabled.");
656
0
  }
657
658
  /*
659
   * Read primary LUKS2 header (offset 0).
660
   */
661
8.40k
  state_hdr1 = HDR_FAIL;
662
8.40k
  r = hdr_read_disk(cd, device, &hdr_disk1, &json_area1, 0, 0);
663
8.40k
  if (r == 0) {
664
1.43k
    jobj_hdr1 = parse_and_validate_json(cd, json_area1, be64_to_cpu(hdr_disk1.hdr_size), &json_area_end1);
665
1.43k
    state_hdr1 = jobj_hdr1 ? HDR_OK : HDR_OBSOLETE;
666
6.97k
  } else if (r == -EIO)
667
0
    state_hdr1 = HDR_FAIL_IO;
668
669
  /*
670
   * Read secondary LUKS2 header (follows primary).
671
   */
672
8.40k
  state_hdr2 = HDR_FAIL;
673
8.40k
  if (state_hdr1 != HDR_FAIL && state_hdr1 != HDR_FAIL_IO) {
674
1.43k
    r = hdr_read_disk(cd, device, &hdr_disk2, &json_area2, be64_to_cpu(hdr_disk1.hdr_size), 1);
675
1.43k
    if (r == 0) {
676
0
      jobj_hdr2 = parse_and_validate_json(cd, json_area2, be64_to_cpu(hdr_disk2.hdr_size), &json_area_end2);
677
0
      state_hdr2 = jobj_hdr2 ? HDR_OK : HDR_OBSOLETE;
678
1.43k
    } else if (r == -EIO)
679
0
      state_hdr2 = HDR_FAIL_IO;
680
6.97k
  } else {
681
    /*
682
     * No header size, check all known offsets.
683
     */
684
6.97k
    hdr_disk2.hdr_size = 0;
685
35.2k
    for (r = -EINVAL,i = 0; r < 0 && i < ARRAY_SIZE(hdr2_offsets); i++)
686
28.3k
      r = hdr_read_disk(cd, device, &hdr_disk2, &json_area2, hdr2_offsets[i], 1);
687
688
6.97k
    if (r == 0) {
689
5.74k
      jobj_hdr2 = parse_and_validate_json(cd, json_area2, be64_to_cpu(hdr_disk2.hdr_size), &json_area_end2);
690
5.74k
      state_hdr2 = jobj_hdr2 ? HDR_OK : HDR_OBSOLETE;
691
5.74k
    } else if (r == -EIO)
692
0
      state_hdr2 = HDR_FAIL_IO;
693
6.97k
  }
694
695
  /*
696
   * Check sequence id if both headers are read correctly.
697
   */
698
8.40k
  if (state_hdr1 == HDR_OK && state_hdr2 == HDR_OK) {
699
0
    if (be64_to_cpu(hdr_disk1.seqid) > be64_to_cpu(hdr_disk2.seqid))
700
0
      state_hdr2 = HDR_OBSOLETE;
701
0
    else if (be64_to_cpu(hdr_disk1.seqid) < be64_to_cpu(hdr_disk2.seqid))
702
0
      state_hdr1 = HDR_OBSOLETE;
703
0
  }
704
705
  /* check header with keyslots to fit the device */
706
8.40k
  if (state_hdr1 == HDR_OK)
707
646
    hdr_size = LUKS2_hdr_and_areas_size_jobj(jobj_hdr1);
708
7.76k
  else if (state_hdr2 == HDR_OK)
709
5.73k
    hdr_size = LUKS2_hdr_and_areas_size_jobj(jobj_hdr2);
710
2.02k
  else {
711
2.02k
    r = (state_hdr1 == HDR_FAIL_IO && state_hdr2 == HDR_FAIL_IO) ? -EIO : -EINVAL;
712
2.02k
    goto err;
713
2.02k
  }
714
715
6.37k
  r = device_check_size(cd, device, hdr_size, 0);
716
6.37k
  if (r)
717
1
    goto err;
718
719
  /*
720
   * Try to rewrite (recover) bad header. Always regenerate salt for bad header.
721
   */
722
6.37k
  if (state_hdr1 == HDR_OK && state_hdr2 != HDR_OK) {
723
645
    log_dbg(cd, "Secondary LUKS2 header requires recovery.");
724
725
645
    if (do_blkprobe && (r = detect_device_signatures(cd, device_path(device)))) {
726
25
      log_err(cd, _("Device contains ambiguous signatures, cannot auto-recover LUKS2.\n"
727
25
              "Please run \"cryptsetup repair\" for recovery."));
728
25
      goto err;
729
25
    }
730
731
620
    if (do_recovery) {
732
620
      memcpy(&hdr_disk2, &hdr_disk1, LUKS2_HDR_BIN_LEN);
733
620
      r = crypt_random_get(cd, (char*)hdr_disk2.salt, sizeof(hdr_disk2.salt), CRYPT_RND_SALT);
734
620
      if (r)
735
0
        log_dbg(cd, "Cannot generate header salt.");
736
620
      else {
737
620
        hdr_from_disk(&hdr_disk1, &hdr_disk2, hdr, 0);
738
620
        r = hdr_write_disk(cd, device, hdr, json_area1, hdr->hdr_size - LUKS2_HDR_BIN_LEN, 1);
739
620
      }
740
620
      if (r)
741
310
        log_dbg(cd, "Secondary LUKS2 header recovery failed.");
742
620
    }
743
5.73k
  } else if (state_hdr1 != HDR_OK && state_hdr2 == HDR_OK) {
744
5.73k
    log_dbg(cd, "Primary LUKS2 header requires recovery.");
745
746
5.73k
    if (do_blkprobe && (r = detect_device_signatures(cd, device_path(device)))) {
747
1.92k
      log_err(cd, _("Device contains ambiguous signatures, cannot auto-recover LUKS2.\n"
748
1.92k
              "Please run \"cryptsetup repair\" for recovery."));
749
1.92k
      goto err;
750
1.92k
    }
751
752
3.81k
    if (do_recovery) {
753
3.81k
      memcpy(&hdr_disk1, &hdr_disk2, LUKS2_HDR_BIN_LEN);
754
3.81k
      r = crypt_random_get(cd, (char*)hdr_disk1.salt, sizeof(hdr_disk1.salt), CRYPT_RND_SALT);
755
3.81k
      if (r)
756
0
        log_dbg(cd, "Cannot generate header salt.");
757
3.81k
      else {
758
3.81k
        hdr_from_disk(&hdr_disk2, &hdr_disk1, hdr, 1);
759
3.81k
        r = hdr_write_disk(cd, device, hdr, json_area2, hdr->hdr_size - LUKS2_HDR_BIN_LEN, 0);
760
3.81k
      }
761
3.81k
      if (r)
762
1.90k
        log_dbg(cd, "Primary LUKS2 header recovery failed.");
763
3.81k
    }
764
3.81k
  }
765
766
4.43k
  free(json_area1);
767
4.43k
  json_area1 = NULL;
768
4.43k
  free(json_area2);
769
4.43k
  json_area2 = NULL;
770
771
  /* wrong lock for write mode during recovery attempt */
772
4.43k
  if (r == -EAGAIN)
773
2.21k
    goto err;
774
775
  /*
776
   * Even if status is failed, the second header includes salt.
777
   */
778
2.21k
  if (state_hdr1 == HDR_OK) {
779
310
    hdr_from_disk(&hdr_disk1, &hdr_disk2, hdr, 0);
780
310
    hdr->jobj = jobj_hdr1;
781
310
    json_object_put(jobj_hdr2);
782
1.90k
  } else if (state_hdr2 == HDR_OK) {
783
1.90k
    hdr_from_disk(&hdr_disk2, &hdr_disk1, hdr, 1);
784
1.90k
    hdr->jobj = jobj_hdr2;
785
1.90k
    json_object_put(jobj_hdr1);
786
1.90k
  }
787
788
2.21k
  if (json_area_end1 > json_area_end2)
789
310
    hdr->on_disk_json_end_offset = json_area_end1;
790
1.90k
  else
791
1.90k
    hdr->on_disk_json_end_offset = json_area_end2;
792
793
  /*
794
   * FIXME: should this fail? At least one header was read correctly.
795
   * r = (state_hdr1 == HDR_FAIL_IO || state_hdr2 == HDR_FAIL_IO) ? -EIO : -EINVAL;
796
   */
797
2.21k
  return 0;
798
6.19k
err:
799
6.19k
  log_dbg(cd, "LUKS2 header read failed (%d).", r);
800
801
6.19k
  free(json_area1);
802
6.19k
  free(json_area2);
803
6.19k
  json_object_put(jobj_hdr1);
804
6.19k
  json_object_put(jobj_hdr2);
805
6.19k
  hdr->jobj = NULL;
806
6.19k
  return r;
807
4.43k
}
808
809
int LUKS2_hdr_version_unlocked(struct crypt_device *cd, struct device *device)
810
8.03k
{
811
8.03k
  struct {
812
8.03k
    char magic[LUKS2_MAGIC_L];
813
8.03k
    uint16_t version;
814
8.03k
  }  __attribute__ ((packed)) hdr;
815
8.03k
  int r = 0, devfd, flags = O_RDONLY;
816
817
8.03k
  assert(cd);
818
8.03k
  assert(device);
819
820
8.03k
  if (device_direct_io(device))
821
8.03k
    flags |= O_DIRECT;
822
823
8.03k
  devfd = device_open(cd, device, flags);
824
8.03k
  if (devfd != -1 && (read_lseek_blockwise(devfd, device_block_size(cd, device),
825
8.03k
       device_alignment(device), &hdr, sizeof(hdr), 0) == sizeof(hdr)) &&
826
8.03k
      !memcmp(hdr.magic, LUKS2_MAGIC_1ST, LUKS2_MAGIC_L))
827
2.98k
    r = (int)be16_to_cpu(hdr.version);
828
829
8.03k
  return r;
830
8.03k
}