Coverage Report

Created: 2025-11-07 06:58

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cryptsetup/lib/luks2/luks2_keyslot_luks2.c
Line
Count
Source
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
 * LUKS - Linux Unified Key Setup v2, LUKS2 type keyslot handler
4
 *
5
 * Copyright (C) 2015-2025 Red Hat, Inc. All rights reserved.
6
 * Copyright (C) 2015-2025 Milan Broz
7
 */
8
9
#include <limits.h>
10
#include "luks2_internal.h"
11
12
/* FIXME: move keyslot encryption to crypto backend */
13
#include "../luks1/af.h"
14
15
0
#define LUKS_SALTSIZE 32
16
#define LUKS_SLOT_ITERATIONS_MIN 1000
17
18
/* Serialize memory-hard keyslot access: optional workaround for parallel processing */
19
0
#define MIN_MEMORY_FOR_SERIALIZE_LOCK_KB 32*1024 /* 32MB */
20
21
/* coverity[ -taint_source : arg-0 ] */
22
static int luks2_encrypt_to_storage(char *src, size_t srcLength,
23
  const char *cipher, const char *cipher_mode,
24
  struct volume_key *vk, unsigned int sector,
25
  struct crypt_device *cd)
26
0
{
27
#if !ENABLE_AF_ALG /* Support for old kernel without Crypto API */
28
  return LUKS_encrypt_to_storage(src, srcLength, cipher, cipher_mode, vk, sector, cd);
29
#else
30
0
  struct crypt_storage *s;
31
0
  int devfd, r;
32
0
  struct device *device = crypt_metadata_device(cd);
33
34
  /* Only whole sector writes supported */
35
0
  if (MISALIGNED_512(srcLength))
36
0
    return -EINVAL;
37
38
  /* Encrypt buffer */
39
0
  r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode,
40
0
             crypt_volume_key_get_key(vk), crypt_volume_key_length(vk), false);
41
0
  if (r) {
42
0
    log_err(cd, _("Cannot use %s-%s cipher for keyslot encryption."), cipher, cipher_mode);
43
0
    return r;
44
0
  }
45
46
0
  r = crypt_storage_encrypt(s, 0, srcLength, src);
47
0
  crypt_storage_destroy(s);
48
0
  if (r) {
49
0
    log_err(cd, _("IO error while encrypting keyslot."));
50
0
    return r;
51
0
  }
52
53
0
  devfd = device_open_locked(cd, device, O_RDWR);
54
0
  if (devfd >= 0) {
55
0
    if (write_lseek_blockwise(devfd, device_block_size(cd, device),
56
0
            device_alignment(device), src,
57
0
            srcLength, sector * SECTOR_SIZE) < 0)
58
0
      r = -EIO;
59
0
    else
60
0
      r = 0;
61
62
0
    device_sync(cd, device);
63
0
  } else
64
0
    r = -EIO;
65
66
0
  if (r)
67
0
    log_err(cd, _("IO error while encrypting keyslot."));
68
69
0
  return r;
70
0
#endif
71
0
}
72
73
static int luks2_decrypt_from_storage(char *dst, size_t dstLength,
74
  const char *cipher, const char *cipher_mode, struct volume_key *vk,
75
  unsigned int sector, struct crypt_device *cd)
76
0
{
77
0
  struct device *device = crypt_metadata_device(cd);
78
#if !ENABLE_AF_ALG /* Support for old kernel without Crypto API */
79
  int r = device_read_lock(cd, device);
80
  if (r) {
81
    log_err(cd, _("Failed to acquire read lock on device %s."), device_path(device));
82
    return r;
83
  }
84
  r = LUKS_decrypt_from_storage(dst, dstLength, cipher, cipher_mode, vk, sector, cd);
85
  device_read_unlock(cd, crypt_metadata_device(cd));
86
  return r;
87
#else
88
0
  struct crypt_storage *s;
89
0
  int devfd, r;
90
91
  /* Only whole sector writes supported */
92
0
  if (MISALIGNED_512(dstLength))
93
0
    return -EINVAL;
94
95
0
  r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode,
96
0
             crypt_volume_key_get_key(vk),
97
0
             crypt_volume_key_length(vk), false);
98
0
  if (r) {
99
0
    log_err(cd, _("Cannot use %s-%s cipher for keyslot encryption."), cipher, cipher_mode);
100
0
    return r;
101
0
  }
102
103
0
  r = device_read_lock(cd, device);
104
0
  if (r) {
105
0
    log_err(cd, _("Failed to acquire read lock on device %s."),
106
0
      device_path(device));
107
0
    crypt_storage_destroy(s);
108
0
    return r;
109
0
  }
110
111
0
  devfd = device_open_locked(cd, device, O_RDONLY);
112
0
  if (devfd >= 0) {
113
0
    if (read_lseek_blockwise(devfd, device_block_size(cd, device),
114
0
           device_alignment(device), dst,
115
0
           dstLength, sector * SECTOR_SIZE) < 0)
116
0
      r = -EIO;
117
0
    else
118
0
      r = 0;
119
0
  } else
120
0
    r = -EIO;
121
122
0
  device_read_unlock(cd, device);
123
124
  /* Decrypt buffer */
125
0
  if (!r)
126
0
    r = crypt_storage_decrypt(s, 0, dstLength, dst);
127
0
  else
128
0
    log_err(cd, _("IO error while decrypting keyslot."));
129
130
0
  crypt_storage_destroy(s);
131
0
  return r;
132
0
#endif
133
0
}
134
135
static int luks2_keyslot_get_pbkdf_params(json_object *jobj_keyslot,
136
                    struct crypt_pbkdf_type *pbkdf, char **salt)
137
0
{
138
0
  json_object *jobj_kdf, *jobj1, *jobj2;
139
0
  size_t salt_len;
140
0
  int r;
141
142
0
  if (!jobj_keyslot || !pbkdf)
143
0
    return -EINVAL;
144
145
0
  memset(pbkdf, 0, sizeof(*pbkdf));
146
147
0
  if (!json_object_object_get_ex(jobj_keyslot, "kdf", &jobj_kdf))
148
0
    return -EINVAL;
149
150
0
  if (!json_object_object_get_ex(jobj_kdf, "type", &jobj1))
151
0
    return -EINVAL;
152
0
  pbkdf->type = json_object_get_string(jobj1);
153
0
  if (!strcmp(pbkdf->type, CRYPT_KDF_PBKDF2)) {
154
0
    if (!json_object_object_get_ex(jobj_kdf, "hash", &jobj2))
155
0
      return -EINVAL;
156
0
    pbkdf->hash = json_object_get_string(jobj2);
157
0
    if (!json_object_object_get_ex(jobj_kdf, "iterations", &jobj2))
158
0
      return -EINVAL;
159
0
    pbkdf->iterations = json_object_get_int(jobj2);
160
0
    pbkdf->max_memory_kb = 0;
161
0
    pbkdf->parallel_threads = 0;
162
0
  } else {
163
0
    if (!json_object_object_get_ex(jobj_kdf, "time", &jobj2))
164
0
      return -EINVAL;
165
0
    pbkdf->iterations = json_object_get_int(jobj2);
166
0
    if (!json_object_object_get_ex(jobj_kdf, "memory", &jobj2))
167
0
      return -EINVAL;
168
0
    pbkdf->max_memory_kb = json_object_get_int(jobj2);
169
0
    if (!json_object_object_get_ex(jobj_kdf, "cpus", &jobj2))
170
0
      return -EINVAL;
171
0
    pbkdf->parallel_threads = json_object_get_int(jobj2);
172
0
  }
173
174
0
  if (!json_object_object_get_ex(jobj_kdf, "salt", &jobj2))
175
0
    return -EINVAL;
176
177
0
  r = crypt_base64_decode(salt, &salt_len, json_object_get_string(jobj2),
178
0
        json_object_get_string_len(jobj2));
179
0
  if (r < 0)
180
0
    return r;
181
182
0
  if (salt_len != LUKS_SALTSIZE) {
183
0
    free(*salt);
184
0
    return -EINVAL;
185
0
  }
186
187
0
  return 0;
188
0
}
189
190
static int luks2_keyslot_set_key(struct crypt_device *cd,
191
  json_object *jobj_keyslot,
192
  const char *password, size_t passwordLen,
193
  const char *volume_key, size_t volume_key_len)
194
0
{
195
0
  char *salt = NULL, cipher[MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN];
196
0
  char *AfKey = NULL;
197
0
  const char *af_hash = NULL;
198
0
  size_t AFEKSize, keyslot_key_len;
199
0
  json_object *jobj2, *jobj_kdf, *jobj_af, *jobj_area;
200
0
  uint64_t area_offset;
201
0
  struct crypt_pbkdf_type pbkdf;
202
0
  int r;
203
0
  struct volume_key *derived_vk = NULL;
204
0
  void *derived_key = NULL;
205
206
0
  if (!json_object_object_get_ex(jobj_keyslot, "kdf", &jobj_kdf) ||
207
0
      !json_object_object_get_ex(jobj_keyslot, "af", &jobj_af) ||
208
0
      !json_object_object_get_ex(jobj_keyslot, "area", &jobj_area))
209
0
    return -EINVAL;
210
211
  /* prevent accidental volume key size change after allocation */
212
0
  if (!json_object_object_get_ex(jobj_keyslot, "key_size", &jobj2))
213
0
    return -EINVAL;
214
0
  if (json_object_get_int(jobj2) != (int)volume_key_len)
215
0
    return -EINVAL;
216
217
0
  if (!json_object_object_get_ex(jobj_area, "offset", &jobj2))
218
0
    return -EINVAL;
219
0
  area_offset = crypt_jobj_get_uint64(jobj2);
220
221
0
  if (!json_object_object_get_ex(jobj_area, "encryption", &jobj2))
222
0
    return -EINVAL;
223
0
  r = crypt_parse_name_and_mode(json_object_get_string(jobj2), cipher, NULL, cipher_mode);
224
0
  if (r < 0)
225
0
    return r;
226
227
0
  if (!json_object_object_get_ex(jobj_area, "key_size", &jobj2))
228
0
    return -EINVAL;
229
0
  keyslot_key_len = json_object_get_int(jobj2);
230
231
0
  if (!json_object_object_get_ex(jobj_af, "hash", &jobj2))
232
0
    return -EINVAL;
233
0
  af_hash = json_object_get_string(jobj2);
234
235
0
  r = luks2_keyslot_get_pbkdf_params(jobj_keyslot, &pbkdf, &salt);
236
0
  if (r < 0)
237
0
    return r;
238
239
  /*
240
   * Allocate derived key storage.
241
   */
242
0
  derived_key = crypt_safe_alloc(keyslot_key_len);
243
0
  if (!derived_key) {
244
0
    free(salt);
245
0
    return -ENOMEM;
246
0
  }
247
  /*
248
   * Calculate keyslot content, split and store it to keyslot area.
249
   */
250
0
  log_dbg(cd, "Running keyslot key derivation.");
251
0
  r = crypt_pbkdf(pbkdf.type, pbkdf.hash, password, passwordLen,
252
0
      salt, LUKS_SALTSIZE,
253
0
      derived_key, keyslot_key_len,
254
0
      pbkdf.iterations, pbkdf.max_memory_kb,
255
0
      pbkdf.parallel_threads);
256
0
  free(salt);
257
0
  if (r < 0) {
258
0
    if ((crypt_backend_flags() & CRYPT_BACKEND_PBKDF2_INT) &&
259
0
         pbkdf.iterations > INT_MAX)
260
0
      log_err(cd, _("PBKDF2 iteration value overflow."));
261
0
    if (r == -ENOMEM)
262
0
      log_err(cd, _("Not enough memory for keyslot key derivation."));
263
0
    goto out;
264
0
  }
265
266
  // FIXME: verity key_size to AFEKSize
267
0
  AFEKSize = AF_split_sectors(volume_key_len, LUKS_STRIPES) * SECTOR_SIZE;
268
0
  AfKey = crypt_safe_alloc(AFEKSize);
269
0
  if (!AfKey) {
270
0
    r = -ENOMEM;
271
0
    goto out;
272
0
  }
273
274
0
  r = crypt_hash_size(af_hash);
275
0
  if (r < 0)
276
0
    log_err(cd, _("Hash algorithm %s is not available."), af_hash);
277
0
  else
278
0
    r = AF_split(cd, volume_key, AfKey, volume_key_len, LUKS_STRIPES, af_hash);
279
280
0
  if (r < 0)
281
0
    goto out;
282
283
0
  derived_vk = crypt_alloc_volume_key_by_safe_alloc(&derived_key);
284
0
  if (!derived_vk) {
285
0
    r = -ENOMEM;
286
0
    goto out;
287
0
  }
288
289
0
  log_dbg(cd, "Updating keyslot area [0x%04" PRIx64 "].", area_offset);
290
  /* FIXME: sector_offset should be size_t, fix LUKS_encrypt... accordingly */
291
0
  r = luks2_encrypt_to_storage(AfKey, AFEKSize, cipher, cipher_mode,
292
0
          derived_vk, (unsigned)(area_offset / SECTOR_SIZE), cd);
293
0
out:
294
0
  crypt_safe_free(AfKey);
295
0
  crypt_safe_free(derived_key);
296
0
  crypt_free_volume_key(derived_vk);
297
0
  if (r < 0)
298
0
    return r;
299
300
0
  return 0;
301
0
}
302
303
static int luks2_keyslot_get_key(struct crypt_device *cd,
304
  json_object *jobj_keyslot,
305
  const char *password, size_t passwordLen,
306
  char *volume_key, size_t volume_key_len)
307
0
{
308
0
  struct crypt_pbkdf_type pbkdf;
309
0
  char *AfKey = NULL;
310
0
  size_t AFEKSize;
311
0
  const char *af_hash = NULL;
312
0
  char *salt = NULL, cipher[MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN];
313
0
  json_object *jobj2, *jobj_af, *jobj_area;
314
0
  uint64_t area_offset;
315
0
  size_t keyslot_key_len;
316
0
  bool try_serialize_lock = false;
317
0
  int r;
318
0
  struct volume_key *derived_vk = NULL;
319
0
  void *derived_key = NULL;
320
321
0
  if (!json_object_object_get_ex(jobj_keyslot, "af", &jobj_af) ||
322
0
      !json_object_object_get_ex(jobj_keyslot, "area", &jobj_area))
323
0
    return -EINVAL;
324
325
0
  if (!json_object_object_get_ex(jobj_af, "hash", &jobj2))
326
0
    return -EINVAL;
327
0
  af_hash = json_object_get_string(jobj2);
328
329
0
  if (!json_object_object_get_ex(jobj_area, "offset", &jobj2))
330
0
    return -EINVAL;
331
0
  area_offset = crypt_jobj_get_uint64(jobj2);
332
333
0
  if (!json_object_object_get_ex(jobj_area, "encryption", &jobj2))
334
0
    return -EINVAL;
335
0
  r = crypt_parse_name_and_mode(json_object_get_string(jobj2), cipher, NULL, cipher_mode);
336
0
  if (r < 0)
337
0
    return r;
338
339
  /* Allow only empty passphrase with null cipher */
340
0
  if (crypt_is_cipher_null(cipher) && passwordLen)
341
0
    return -EPERM;
342
343
0
  if (!json_object_object_get_ex(jobj_area, "key_size", &jobj2))
344
0
    return -EINVAL;
345
0
  keyslot_key_len = json_object_get_int(jobj2);
346
347
0
  r = luks2_keyslot_get_pbkdf_params(jobj_keyslot, &pbkdf, &salt);
348
0
  if (r < 0)
349
0
    return r;
350
351
  /*
352
   * Allocate derived key storage space.
353
   */
354
0
  derived_key = crypt_safe_alloc(keyslot_key_len);
355
0
  if (!derived_key) {
356
0
    r = -ENOMEM;
357
0
    goto out;
358
0
  }
359
360
0
  AFEKSize = AF_split_sectors(volume_key_len, LUKS_STRIPES) * SECTOR_SIZE;
361
0
  AfKey = crypt_safe_alloc(AFEKSize);
362
0
  if (!AfKey) {
363
0
    r = -ENOMEM;
364
0
    goto out;
365
0
  }
366
367
  /*
368
   * If requested, serialize unlocking for memory-hard KDF. Usually NOOP.
369
   */
370
0
  if (pbkdf.max_memory_kb > MIN_MEMORY_FOR_SERIALIZE_LOCK_KB)
371
0
    try_serialize_lock = true;
372
0
  if (try_serialize_lock && (r = crypt_serialize_lock(cd)))
373
0
    goto out;
374
375
  /*
376
   * Calculate derived key, decrypt keyslot content and merge it.
377
   */
378
0
  log_dbg(cd, "Running keyslot key derivation.");
379
0
  r = crypt_pbkdf(pbkdf.type, pbkdf.hash, password, passwordLen,
380
0
      salt, LUKS_SALTSIZE,
381
0
      derived_key, keyslot_key_len,
382
0
      pbkdf.iterations, pbkdf.max_memory_kb,
383
0
      pbkdf.parallel_threads);
384
385
0
  if (try_serialize_lock)
386
0
    crypt_serialize_unlock(cd);
387
388
0
  if (r < 0)
389
0
    goto out;
390
391
0
  derived_vk = crypt_alloc_volume_key_by_safe_alloc(&derived_key);
392
0
  if (!derived_vk) {
393
0
    r = -ENOMEM;
394
0
    goto out;
395
0
  }
396
397
0
  log_dbg(cd, "Reading keyslot area [0x%04" PRIx64 "].", area_offset);
398
  /* FIXME: sector_offset should be size_t, fix LUKS_decrypt... accordingly */
399
0
  r = luks2_decrypt_from_storage(AfKey, AFEKSize, cipher, cipher_mode,
400
0
            derived_vk, (unsigned)(area_offset / SECTOR_SIZE), cd);
401
402
0
  if (r == 0) {
403
0
    r = crypt_hash_size(af_hash);
404
0
    if (r < 0)
405
0
      log_err(cd, _("Hash algorithm %s is not available."), af_hash);
406
0
    else
407
0
      r = AF_merge(AfKey, volume_key, volume_key_len, LUKS_STRIPES, af_hash);
408
0
  }
409
0
out:
410
0
  free(salt);
411
0
  crypt_free_volume_key(derived_vk);
412
0
  crypt_safe_free(AfKey);
413
0
  crypt_safe_free(derived_key);
414
415
0
  return r;
416
0
}
417
418
/*
419
 * currently we support update of only:
420
 *
421
 * - af hash function
422
 * - kdf params
423
 */
424
static int luks2_keyslot_update_json(struct crypt_device *cd,
425
  json_object *jobj_keyslot,
426
  const struct luks2_keyslot_params *params)
427
0
{
428
0
  const struct crypt_pbkdf_type *pbkdf;
429
0
  json_object *jobj_af, *jobj_area, *jobj_kdf;
430
0
  char salt[LUKS_SALTSIZE], *salt_base64 = NULL;
431
0
  int r;
432
433
  /* jobj_keyslot is not yet validated */
434
435
0
  if (!json_object_object_get_ex(jobj_keyslot, "af", &jobj_af) ||
436
0
      !json_object_object_get_ex(jobj_keyslot, "area", &jobj_area))
437
0
    return -EINVAL;
438
439
  /* update area encryption parameters */
440
0
  json_object_object_add(jobj_area, "encryption", json_object_new_string(params->area.raw.encryption));
441
0
  json_object_object_add(jobj_area, "key_size", json_object_new_int(params->area.raw.key_size));
442
443
0
  pbkdf = crypt_get_pbkdf_type(cd);
444
0
  if (!pbkdf)
445
0
    return -EINVAL;
446
447
0
  r = crypt_benchmark_pbkdf_internal(cd, CONST_CAST(struct crypt_pbkdf_type *)pbkdf, params->area.raw.key_size);
448
0
  if (r < 0)
449
0
    return r;
450
451
  /* refresh whole 'kdf' object */
452
0
  jobj_kdf = json_object_new_object();
453
0
  if (!jobj_kdf)
454
0
    return -ENOMEM;
455
0
  json_object_object_add(jobj_kdf, "type", json_object_new_string(pbkdf->type));
456
0
  if (!strcmp(pbkdf->type, CRYPT_KDF_PBKDF2)) {
457
0
    json_object_object_add(jobj_kdf, "hash", json_object_new_string(pbkdf->hash));
458
0
    json_object_object_add(jobj_kdf, "iterations", json_object_new_int(pbkdf->iterations));
459
0
  } else {
460
0
    json_object_object_add(jobj_kdf, "time", json_object_new_int(pbkdf->iterations));
461
0
    json_object_object_add(jobj_kdf, "memory", json_object_new_int(pbkdf->max_memory_kb));
462
0
    json_object_object_add(jobj_kdf, "cpus", json_object_new_int(pbkdf->parallel_threads));
463
0
  }
464
0
  json_object_object_add(jobj_keyslot, "kdf", jobj_kdf);
465
466
  /*
467
   * Regenerate salt and add it in 'kdf' object
468
   */
469
0
  r = crypt_random_get(cd, salt, LUKS_SALTSIZE, CRYPT_RND_SALT);
470
0
  if (r < 0)
471
0
    return r;
472
0
  r = crypt_base64_encode(&salt_base64, NULL, salt, LUKS_SALTSIZE);
473
0
  if (r < 0)
474
0
    return r;
475
0
  json_object_object_add(jobj_kdf, "salt", json_object_new_string(salt_base64));
476
0
  free(salt_base64);
477
478
  /* update 'af' hash */
479
0
  json_object_object_add(jobj_af, "hash", json_object_new_string(params->af.luks1.hash));
480
481
0
  JSON_DBG(cd, jobj_keyslot, "Keyslot JSON:");
482
0
  return 0;
483
0
}
484
485
static int luks2_keyslot_alloc(struct crypt_device *cd,
486
  int keyslot,
487
  size_t volume_key_len,
488
  const struct luks2_keyslot_params *params)
489
0
{
490
0
  struct luks2_hdr *hdr;
491
0
  uint64_t area_offset, area_length;
492
0
  json_object *jobj_keyslots, *jobj_keyslot, *jobj_af, *jobj_area;
493
0
  int r;
494
495
0
  log_dbg(cd, "Trying to allocate LUKS2 keyslot %d.", keyslot);
496
497
0
  if (!params || params->area_type != LUKS2_KEYSLOT_AREA_RAW ||
498
0
      params->af_type != LUKS2_KEYSLOT_AF_LUKS1) {
499
0
    log_dbg(cd, "Invalid LUKS2 keyslot parameters.");
500
0
    return -EINVAL;
501
0
  }
502
503
0
  if (!(hdr = crypt_get_hdr(cd, CRYPT_LUKS2)))
504
0
    return -EINVAL;
505
506
0
  if (keyslot == CRYPT_ANY_SLOT)
507
0
    keyslot = LUKS2_keyslot_find_empty(cd, hdr, 0);
508
509
0
  if (keyslot < 0 || keyslot >= LUKS2_KEYSLOTS_MAX)
510
0
    return -ENOMEM;
511
512
0
  if (LUKS2_get_keyslot_jobj(hdr, keyslot)) {
513
0
    log_dbg(cd, "Cannot modify already active keyslot %d.", keyslot);
514
0
    return -EINVAL;
515
0
  }
516
517
0
  if (!json_object_object_get_ex(hdr->jobj, "keyslots", &jobj_keyslots))
518
0
    return -EINVAL;
519
520
0
  r = LUKS2_find_area_gap(cd, hdr, volume_key_len, &area_offset, &area_length);
521
0
  if (r < 0) {
522
0
    log_err(cd, _("No space for new keyslot."));
523
0
    return r;
524
0
  }
525
526
0
  jobj_keyslot = json_object_new_object();
527
0
  if (!jobj_keyslot) {
528
0
    r = -ENOMEM;
529
0
    goto err;
530
0
  }
531
532
0
  json_object_object_add(jobj_keyslot, "type", json_object_new_string("luks2"));
533
0
  json_object_object_add(jobj_keyslot, "key_size", json_object_new_int(volume_key_len));
534
535
  /* AF object */
536
0
  jobj_af = json_object_new_object();
537
0
  if (!jobj_af) {
538
0
    r = -ENOMEM;
539
0
    goto err;
540
0
  }
541
542
0
  json_object_object_add(jobj_af, "type", json_object_new_string("luks1"));
543
0
  json_object_object_add(jobj_af, "stripes", json_object_new_int(params->af.luks1.stripes));
544
0
  json_object_object_add(jobj_keyslot, "af", jobj_af);
545
546
  /* Area object */
547
0
  jobj_area = json_object_new_object();
548
0
  if (!jobj_area) {
549
0
    r = -ENOMEM;
550
0
    goto err;
551
0
  }
552
553
0
  json_object_object_add(jobj_area, "type", json_object_new_string("raw"));
554
0
  json_object_object_add(jobj_area, "offset", crypt_jobj_new_uint64(area_offset));
555
0
  json_object_object_add(jobj_area, "size", crypt_jobj_new_uint64(area_length));
556
0
  json_object_object_add(jobj_keyslot, "area", jobj_area);
557
558
0
  r = json_object_object_add_by_uint(jobj_keyslots, keyslot, jobj_keyslot);
559
0
  if (r) {
560
0
    json_object_put(jobj_keyslot);
561
0
    return r;
562
0
  }
563
564
0
  r = luks2_keyslot_update_json(cd, jobj_keyslot, params);
565
566
0
  if (!r && LUKS2_check_json_size(cd, hdr)) {
567
0
    log_dbg(cd, "Not enough space in header json area for new keyslot.");
568
0
    r = -ENOSPC;
569
0
  }
570
571
0
  if (r)
572
0
    json_object_object_del_by_uint(jobj_keyslots, keyslot);
573
574
0
  return r;
575
0
err:
576
0
  json_object_put(jobj_keyslot);
577
0
  return r;
578
0
}
579
580
static int luks2_keyslot_open(struct crypt_device *cd,
581
  int keyslot,
582
  const char *password,
583
  size_t password_len,
584
  char *volume_key,
585
  size_t volume_key_len)
586
0
{
587
0
  struct luks2_hdr *hdr;
588
0
  json_object *jobj_keyslot;
589
590
0
  log_dbg(cd, "Trying to open LUKS2 keyslot %d.", keyslot);
591
592
0
  if (!(hdr = crypt_get_hdr(cd, CRYPT_LUKS2)))
593
0
    return -EINVAL;
594
595
0
  jobj_keyslot = LUKS2_get_keyslot_jobj(hdr, keyslot);
596
0
  if (!jobj_keyslot)
597
0
    return -EINVAL;
598
599
0
  return luks2_keyslot_get_key(cd, jobj_keyslot,
600
0
             password, password_len,
601
0
             volume_key, volume_key_len);
602
0
}
603
604
/*
605
 * This function must not modify json.
606
 * It's called after luks2 keyslot validation.
607
 */
608
static int luks2_keyslot_store(struct crypt_device *cd,
609
  int keyslot,
610
  const char *password,
611
  size_t password_len,
612
  const char *volume_key,
613
  size_t volume_key_len)
614
0
{
615
0
  struct luks2_hdr *hdr;
616
0
  json_object *jobj_keyslot;
617
0
  int r;
618
619
0
  log_dbg(cd, "Calculating attributes for LUKS2 keyslot %d.", keyslot);
620
621
0
  if (!(hdr = crypt_get_hdr(cd, CRYPT_LUKS2)))
622
0
    return -EINVAL;
623
624
0
  jobj_keyslot = LUKS2_get_keyslot_jobj(hdr, keyslot);
625
0
  if (!jobj_keyslot)
626
0
    return -EINVAL;
627
628
0
  r = LUKS2_device_write_lock(cd, hdr, crypt_metadata_device(cd));
629
0
  if(r)
630
0
    return r;
631
632
0
  r = luks2_keyslot_set_key(cd, jobj_keyslot,
633
0
          password, password_len,
634
0
          volume_key, volume_key_len);
635
0
  if (!r)
636
0
    r = LUKS2_hdr_write(cd, hdr);
637
638
0
  device_write_unlock(cd, crypt_metadata_device(cd));
639
640
0
  return r < 0 ? r : keyslot;
641
0
}
642
643
static int luks2_keyslot_wipe(struct crypt_device *cd, int keyslot)
644
0
{
645
0
  struct luks2_hdr *hdr;
646
647
0
  if (!(hdr = crypt_get_hdr(cd, CRYPT_LUKS2)))
648
0
    return -EINVAL;
649
650
  /* Remove any reference of deleted keyslot from digests and tokens */
651
0
  LUKS2_digest_assign(cd, hdr, keyslot, CRYPT_ANY_DIGEST, 0, 0);
652
0
  LUKS2_token_assign(cd, hdr, keyslot, CRYPT_ANY_TOKEN, 0, 0);
653
654
0
  return 0;
655
0
}
656
657
static int luks2_keyslot_dump(struct crypt_device *cd, int keyslot)
658
0
{
659
0
  json_object *jobj_keyslot, *jobj1, *jobj_kdf, *jobj_af, *jobj_area;
660
661
0
  jobj_keyslot = LUKS2_get_keyslot_jobj(crypt_get_hdr(cd, CRYPT_LUKS2), keyslot);
662
0
  if (!jobj_keyslot)
663
0
    return -EINVAL;
664
665
0
  if (!json_object_object_get_ex(jobj_keyslot, "kdf", &jobj_kdf) ||
666
0
      !json_object_object_get_ex(jobj_keyslot, "af", &jobj_af) ||
667
0
      !json_object_object_get_ex(jobj_keyslot, "area", &jobj_area))
668
0
    return -EINVAL;
669
670
0
  json_object_object_get_ex(jobj_area, "encryption", &jobj1);
671
0
  log_std(cd, "\tCipher:     %s\n", json_object_get_string(jobj1));
672
673
0
  json_object_object_get_ex(jobj_area, "key_size", &jobj1);
674
0
  log_std(cd, "\tCipher key: %u bits\n", crypt_jobj_get_uint32(jobj1) * 8);
675
676
0
  json_object_object_get_ex(jobj_kdf, "type", &jobj1);
677
0
  log_std(cd, "\tPBKDF:      %s\n", json_object_get_string(jobj1));
678
679
0
  if (!strcmp(json_object_get_string(jobj1), CRYPT_KDF_PBKDF2)) {
680
0
    json_object_object_get_ex(jobj_kdf, "hash", &jobj1);
681
0
    log_std(cd, "\tHash:       %s\n", json_object_get_string(jobj1));
682
683
0
    json_object_object_get_ex(jobj_kdf, "iterations", &jobj1);
684
0
    log_std(cd, "\tIterations: %" PRIu64 "\n", crypt_jobj_get_uint64(jobj1));
685
0
  } else {
686
0
    json_object_object_get_ex(jobj_kdf, "time", &jobj1);
687
0
    log_std(cd, "\tTime cost:  %" PRIu64 "\n", json_object_get_int64(jobj1));
688
689
0
    json_object_object_get_ex(jobj_kdf, "memory", &jobj1);
690
0
    log_std(cd, "\tMemory:     %" PRIu64 "\n", json_object_get_int64(jobj1));
691
692
0
    json_object_object_get_ex(jobj_kdf, "cpus", &jobj1);
693
0
    log_std(cd, "\tThreads:    %" PRIu64 "\n", json_object_get_int64(jobj1));
694
0
  }
695
0
  json_object_object_get_ex(jobj_kdf, "salt", &jobj1);
696
0
  log_std(cd, "\tSalt:       ");
697
0
  hexprint_base64(cd, jobj1, " ", "            ");
698
699
700
0
  json_object_object_get_ex(jobj_af, "stripes", &jobj1);
701
0
  log_std(cd, "\tAF stripes: %u\n", json_object_get_int(jobj1));
702
703
0
  json_object_object_get_ex(jobj_af, "hash", &jobj1);
704
0
  log_std(cd, "\tAF hash:    %s\n", json_object_get_string(jobj1));
705
706
0
  json_object_object_get_ex(jobj_area, "offset", &jobj1);
707
0
  log_std(cd, "\tArea offset:%" PRIu64 " [bytes]\n", crypt_jobj_get_uint64(jobj1));
708
709
0
  json_object_object_get_ex(jobj_area, "size", &jobj1);
710
0
  log_std(cd, "\tArea length:%" PRIu64 " [bytes]\n", crypt_jobj_get_uint64(jobj1));
711
712
0
  return 0;
713
0
}
714
715
static int luks2_keyslot_validate(struct crypt_device *cd, json_object *jobj_keyslot)
716
0
{
717
0
  json_object *jobj_kdf, *jobj_af, *jobj_area, *jobj1;
718
0
  const char *type;
719
0
  int count;
720
721
0
  if (!jobj_keyslot)
722
0
    return -EINVAL;
723
724
0
  if (!(jobj_kdf = json_contains(cd, jobj_keyslot, "", "keyslot", "kdf", json_type_object)) ||
725
0
      !(jobj_af = json_contains(cd, jobj_keyslot, "", "keyslot", "af", json_type_object)) ||
726
0
      !(jobj_area = json_contains(cd, jobj_keyslot, "", "keyslot", "area", json_type_object)))
727
0
    return -EINVAL;
728
729
0
  count = json_object_object_length(jobj_kdf);
730
731
0
  jobj1 = json_contains_string(cd, jobj_kdf, "", "kdf section", "type");
732
0
  if (!jobj1)
733
0
    return -EINVAL;
734
0
  type = json_object_get_string(jobj1);
735
736
0
  if (!strcmp(type, CRYPT_KDF_PBKDF2)) {
737
0
    if (count != 4 || /* type, salt, hash, iterations only */
738
0
        !json_contains_string(cd, jobj_kdf, "kdf type", type, "hash") ||
739
0
        !json_contains(cd, jobj_kdf, "kdf type", type, "iterations", json_type_int) ||
740
0
        !json_contains_string(cd, jobj_kdf, "kdf type", type, "salt"))
741
0
      return -EINVAL;
742
0
  } else if (!strcmp(type, CRYPT_KDF_ARGON2I) || !strcmp(type, CRYPT_KDF_ARGON2ID)) {
743
0
    if (count != 5 || /* type, salt, time, memory, cpus only */
744
0
        !json_contains(cd, jobj_kdf, "kdf type", type, "time", json_type_int) ||
745
0
        !json_contains(cd, jobj_kdf, "kdf type", type, "memory", json_type_int) ||
746
0
        !json_contains(cd, jobj_kdf, "kdf type", type, "cpus", json_type_int) ||
747
0
        !json_contains_string(cd, jobj_kdf, "kdf type", type, "salt"))
748
0
      return -EINVAL;
749
0
  }
750
751
0
  jobj1 = json_contains_string(cd, jobj_af, "", "af section", "type");
752
0
  if (!jobj1)
753
0
    return -EINVAL;
754
0
  type = json_object_get_string(jobj1);
755
756
0
  if (!strcmp(type, "luks1")) {
757
0
    if (!json_contains_string(cd, jobj_af, "", "luks1 af", "hash") ||
758
0
        !json_contains(cd, jobj_af, "", "luks1 af", "stripes", json_type_int))
759
0
      return -EINVAL;
760
0
  } else
761
0
    return -EINVAL;
762
763
  // FIXME check numbered
764
0
  jobj1 = json_contains_string(cd, jobj_area, "", "area section", "type");
765
0
  if (!jobj1)
766
0
    return -EINVAL;
767
0
  type = json_object_get_string(jobj1);
768
769
0
  if (!strcmp(type, "raw")) {
770
0
    if (!json_contains_string(cd, jobj_area, "area", "raw type", "encryption") ||
771
0
        !json_contains(cd, jobj_area, "area", "raw type", "key_size", json_type_int) ||
772
0
        !json_contains_string(cd, jobj_area, "area", "raw type", "offset") ||
773
0
        !json_contains_string(cd, jobj_area, "area", "raw type", "size"))
774
0
      return -EINVAL;
775
0
  } else
776
0
    return -EINVAL;
777
778
0
  return 0;
779
0
}
780
781
static int luks2_keyslot_update(struct crypt_device *cd,
782
  int keyslot,
783
  const struct luks2_keyslot_params *params)
784
0
{
785
0
  struct luks2_hdr *hdr;
786
0
  json_object *jobj_keyslot;
787
0
  int r;
788
789
0
  log_dbg(cd, "Updating LUKS2 keyslot %d.", keyslot);
790
791
0
  if (!(hdr = crypt_get_hdr(cd, CRYPT_LUKS2)))
792
0
    return -EINVAL;
793
794
0
  jobj_keyslot = LUKS2_get_keyslot_jobj(hdr, keyslot);
795
0
  if (!jobj_keyslot)
796
0
    return -EINVAL;
797
798
0
  r = luks2_keyslot_update_json(cd, jobj_keyslot, params);
799
800
0
  if (!r && LUKS2_check_json_size(cd, hdr)) {
801
0
    log_dbg(cd, "Not enough space in header json area for updated keyslot %d.", keyslot);
802
0
    r = -ENOSPC;
803
0
  }
804
805
0
  return r;
806
0
}
807
808
static void luks2_keyslot_repair(json_object *jobj_keyslot)
809
232
{
810
232
  const char *type;
811
232
  json_object *jobj_kdf, *jobj_type;
812
813
232
  if (!json_object_object_get_ex(jobj_keyslot, "kdf", &jobj_kdf) ||
814
174
      !json_object_is_type(jobj_kdf, json_type_object))
815
58
    return;
816
817
174
  if (!json_object_object_get_ex(jobj_kdf, "type", &jobj_type) ||
818
160
      !json_object_is_type(jobj_type, json_type_string))
819
24
    return;
820
821
150
  type = json_object_get_string(jobj_type);
822
823
150
  if (!strcmp(type, CRYPT_KDF_PBKDF2)) {
824
    /* type, salt, hash, iterations only */
825
467
    json_object_object_foreach(jobj_kdf, key, val) {
826
467
      UNUSED(val);
827
467
      if (!strcmp(key, "type") || !strcmp(key, "salt") ||
828
361
          !strcmp(key, "hash") || !strcmp(key, "iterations"))
829
170
          continue;
830
297
      json_object_object_del(jobj_kdf, key);
831
297
    }
832
94
  } else if (!strcmp(type, CRYPT_KDF_ARGON2I) || !strcmp(type, CRYPT_KDF_ARGON2ID)) {
833
    /* type, salt, time, memory, cpus only */
834
461
    json_object_object_foreach(jobj_kdf, key, val) {
835
461
      UNUSED(val);
836
461
      if (!strcmp(key, "type") || !strcmp(key, "salt") ||
837
324
          !strcmp(key, "time") || !strcmp(key, "memory") ||
838
212
          !strcmp(key, "cpus"))
839
303
          continue;
840
158
      json_object_object_del(jobj_kdf, key);
841
158
    }
842
71
  }
843
150
}
844
845
const keyslot_handler luks2_keyslot = {
846
  .name  = "luks2",
847
  .alloc  = luks2_keyslot_alloc,
848
  .update = luks2_keyslot_update,
849
  .open  = luks2_keyslot_open,
850
  .store = luks2_keyslot_store,
851
  .wipe  = luks2_keyslot_wipe,
852
  .dump  = luks2_keyslot_dump,
853
  .validate = luks2_keyslot_validate,
854
  .repair = luks2_keyslot_repair
855
};