Coverage Report

Created: 2026-06-08 06:07

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cryptsetup/lib/luks2/luks2_token.c
Line
Count
Source
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
 * LUKS - Linux Unified Key Setup v2, token handling
4
 *
5
 * Copyright (C) 2016-2025 Red Hat, Inc. All rights reserved.
6
 * Copyright (C) 2016-2025 Milan Broz
7
 */
8
9
#include <ctype.h>
10
11
#include "luks2_internal.h"
12
13
#if USE_EXTERNAL_TOKENS
14
#include <dlfcn.h>
15
#define TOKENS_PATH_MAX PATH_MAX
16
static bool external_tokens_enabled = true;
17
static char external_tokens_path[TOKENS_PATH_MAX] = EXTERNAL_LUKS2_TOKENS_PATH;
18
#else
19
static bool external_tokens_enabled = false;
20
#endif
21
22
static struct crypt_token_handler_internal token_handlers[LUKS2_TOKENS_MAX] = {
23
  /* keyring builtin token */
24
  {
25
    .version = 1,
26
    .u = {
27
      .v1 = { .name = LUKS2_TOKEN_KEYRING,
28
        .open = keyring_open,
29
        .buffer_free = keyring_buffer_free,
30
        .validate = keyring_validate,
31
        .dump = keyring_dump }
32
         }
33
  }
34
};
35
36
void crypt_token_external_disable(void)
37
0
{
38
0
  external_tokens_enabled = false;
39
0
}
40
41
const char *crypt_token_external_path(void)
42
0
{
43
0
#if USE_EXTERNAL_TOKENS
44
0
  return external_tokens_enabled ? external_tokens_path : NULL;
45
#else
46
  return NULL;
47
#endif
48
0
}
49
50
#if USE_EXTERNAL_TOKENS
51
int crypt_token_set_external_path(const char *path)
52
0
{
53
0
  int r;
54
0
  char tokens_path[TOKENS_PATH_MAX];
55
56
0
  if (!path)
57
0
    path = EXTERNAL_LUKS2_TOKENS_PATH;
58
0
  else if (*path != '/')
59
0
    return -EINVAL;
60
61
0
  r = snprintf(tokens_path, sizeof(tokens_path), "%s", path);
62
0
  if (r < 0 || (size_t)r >= sizeof(tokens_path))
63
0
    return -EINVAL;
64
65
0
  (void)strcpy(external_tokens_path, tokens_path);
66
67
0
  return 0;
68
0
}
69
#else
70
#pragma GCC diagnostic ignored "-Wunused-parameter"
71
int crypt_token_set_external_path(const char *path)
72
{
73
  return -ENOTSUP;
74
}
75
#endif
76
77
static bool token_validate_v1(struct crypt_device *cd, const crypt_token_handler *h)
78
0
{
79
0
  if (!h)
80
0
    return false;
81
82
0
  if (!h->name) {
83
0
    log_dbg(cd, "Error: token handler does not provide name attribute.");
84
0
    return false;
85
0
  }
86
87
0
  if (!h->open) {
88
0
    log_dbg(cd, "Error: token handler does not provide open function.");
89
0
    return false;
90
0
  }
91
92
0
  return true;
93
0
}
94
95
#if USE_EXTERNAL_TOKENS
96
static void *token_dlvsym(struct crypt_device *cd,
97
    void *handle,
98
    const char *symbol,
99
    const char *version)
100
0
{
101
0
  char *error;
102
0
  void *sym;
103
104
0
#if HAVE_DLVSYM
105
0
  log_dbg(cd, "Loading symbol %s@%s.", symbol, version);
106
0
  sym = dlvsym(handle, symbol, version);
107
#else
108
  UNUSED(version);
109
  log_dbg(cd, "Loading default version of symbol %s.", symbol);
110
  sym = dlsym(handle, symbol);
111
#endif
112
0
  error = dlerror();
113
114
0
  if (error)
115
0
    log_dbg(cd, "%s", error);
116
117
0
  return sym;
118
0
}
119
120
static bool token_validate_v2(struct crypt_device *cd, const struct crypt_token_handler_internal *h)
121
0
{
122
0
  if (!h)
123
0
    return false;
124
125
0
  if (!token_validate_v1(cd, &h->u.v1))
126
0
    return false;
127
128
0
  if (!h->u.v2.version) {
129
0
    log_dbg(cd, "Error: token handler does not provide " CRYPT_TOKEN_ABI_VERSION " function.");
130
0
    return false;
131
0
  }
132
133
0
  return true;
134
0
}
135
136
static bool external_token_name_valid(const char *name)
137
0
{
138
0
  if (!*name || strlen(name) > LUKS2_TOKEN_NAME_MAX)
139
0
    return false;
140
141
0
  while (*name) {
142
0
    if (!isalnum(*name) && *name != '-' && *name != '_')
143
0
      return false;
144
0
    name++;
145
0
  }
146
147
0
  return true;
148
0
}
149
150
static int
151
crypt_token_load_external(struct crypt_device *cd, const char *name, struct crypt_token_handler_internal *ret)
152
0
{
153
0
  struct crypt_token_handler_v2 *token;
154
0
  void *h;
155
0
  char buf[PATH_MAX];
156
0
  int r;
157
158
0
  if (!external_tokens_enabled)
159
0
    return -ENOTSUP;
160
161
0
  if (!ret || !name)
162
0
    return -EINVAL;
163
164
0
  if (!external_token_name_valid(name)) {
165
0
    log_dbg(cd, "External token name (%.*s) invalid.", LUKS2_TOKEN_NAME_MAX, name);
166
0
    return -EINVAL;
167
0
  }
168
169
0
  token = &ret->u.v2;
170
171
0
  r = snprintf(buf, sizeof(buf), "%s/libcryptsetup-token-%s.so", crypt_token_external_path(), name);
172
0
  if (r < 0 || (size_t)r >= sizeof(buf))
173
0
    return -EINVAL;
174
175
0
  assert(*buf == '/');
176
177
0
  log_dbg(cd, "Trying to load %s.", buf);
178
179
0
  h = dlopen(buf, RTLD_LAZY);
180
0
  if (!h) {
181
0
    log_dbg(cd, "%s", dlerror());
182
0
    return -EINVAL;
183
0
  }
184
0
  dlerror();
185
186
0
  token->name = strdup(name);
187
0
  if (!token->name) {
188
0
    dlclose(h);
189
0
    memset(token, 0, sizeof(*token));
190
0
    return -ENOMEM;
191
0
  }
192
193
0
  token->open = token_dlvsym(cd, h, CRYPT_TOKEN_ABI_OPEN, CRYPT_TOKEN_ABI_VERSION1);
194
0
  token->buffer_free = token_dlvsym(cd, h, CRYPT_TOKEN_ABI_BUFFER_FREE, CRYPT_TOKEN_ABI_VERSION1);
195
0
  token->validate = token_dlvsym(cd, h, CRYPT_TOKEN_ABI_VALIDATE, CRYPT_TOKEN_ABI_VERSION1);
196
0
  token->dump = token_dlvsym(cd, h, CRYPT_TOKEN_ABI_DUMP, CRYPT_TOKEN_ABI_VERSION1);
197
0
  token->open_pin = token_dlvsym(cd, h, CRYPT_TOKEN_ABI_OPEN_PIN, CRYPT_TOKEN_ABI_VERSION1);
198
0
  token->version = token_dlvsym(cd, h, CRYPT_TOKEN_ABI_VERSION, CRYPT_TOKEN_ABI_VERSION1);
199
200
0
  if (!token_validate_v2(cd, ret)) {
201
0
    free(CONST_CAST(void *)token->name);
202
0
    dlclose(h);
203
0
    memset(token, 0, sizeof(*token));
204
0
    return -EINVAL;
205
0
  }
206
207
  /* Token loaded, possible error here means only debug message fail and can be ignored */
208
0
  r = snprintf(buf, sizeof(buf), "%s", token->version() ?: "");
209
0
  if (r < 0 || (size_t)r >= sizeof(buf))
210
0
    *buf = '\0';
211
212
0
  log_dbg(cd, "Token handler %s-%s loaded successfully.", token->name, buf);
213
214
0
  token->dlhandle = h;
215
0
  ret->version = 2;
216
217
0
  return 0;
218
0
}
219
220
void crypt_token_unload_external_all(struct crypt_device *cd)
221
0
{
222
0
  struct crypt_token_handler_v2 *token;
223
0
  int i;
224
225
0
  for (i = LUKS2_TOKENS_MAX - 1; i >= 0; i--) {
226
0
    if (token_handlers[i].version < 2)
227
0
      continue;
228
229
0
    token = &token_handlers[i].u.v2;
230
231
0
    log_dbg(cd, "Unloading %s token handler.", token->name);
232
233
0
    free(CONST_CAST(void *)token->name);
234
235
0
    if (dlclose(token->dlhandle))
236
0
      log_dbg(cd, "%s", dlerror());
237
238
0
    memset(token, 0, sizeof(*token));
239
0
    token_handlers[i].version = 0;
240
0
  }
241
0
}
242
243
#else /* USE_EXTERNAL_TOKENS */
244
245
static int crypt_token_load_external(struct crypt_device *cd __attribute__((unused)),
246
             const char *name __attribute__((unused)),
247
             struct crypt_token_handler_internal *ret __attribute__((unused)))
248
{
249
  return -ENOTSUP;
250
}
251
252
void crypt_token_unload_external_all(struct crypt_device *cd __attribute__((unused)))
253
{
254
}
255
256
#endif
257
258
static int is_builtin_candidate(const char *type)
259
0
{
260
0
  return !strncmp(type, LUKS2_BUILTIN_TOKEN_PREFIX, LUKS2_BUILTIN_TOKEN_PREFIX_LEN);
261
0
}
262
263
static int crypt_token_find_free(struct crypt_device *cd, const char *name, int *index)
264
0
{
265
0
  int i;
266
267
0
  if (is_builtin_candidate(name)) {
268
0
    log_dbg(cd, "'" LUKS2_BUILTIN_TOKEN_PREFIX "' is reserved prefix for builtin tokens.");
269
0
    return -EINVAL;
270
0
  }
271
272
0
  for (i = 0; i < LUKS2_TOKENS_MAX && token_handlers[i].u.v1.name; i++) {
273
0
    if (!strcmp(token_handlers[i].u.v1.name, name)) {
274
0
      log_dbg(cd, "Keyslot handler %s is already registered.", name);
275
0
      return -EINVAL;
276
0
    }
277
0
  }
278
279
0
  if (i == LUKS2_TOKENS_MAX)
280
0
    return -EINVAL;
281
282
0
  if (index)
283
0
    *index = i;
284
285
0
  return 0;
286
0
}
287
288
int crypt_token_register(const crypt_token_handler *handler)
289
0
{
290
0
  int i, r;
291
292
0
  if (!token_validate_v1(NULL, handler))
293
0
    return -EINVAL;
294
295
0
  r = crypt_token_find_free(NULL, handler->name, &i);
296
0
  if (r < 0)
297
0
    return r;
298
299
0
  token_handlers[i].version = 1;
300
0
  token_handlers[i].u.v1 = *handler;
301
0
  return 0;
302
0
}
303
304
static const void
305
*LUKS2_token_handler_type(struct crypt_device *cd, const char *type)
306
0
{
307
0
  int i;
308
309
0
  for (i = 0; i < LUKS2_TOKENS_MAX && token_handlers[i].u.v1.name; i++)
310
0
    if (!strcmp(token_handlers[i].u.v1.name, type))
311
0
      return &token_handlers[i].u;
312
313
0
  if (i >= LUKS2_TOKENS_MAX)
314
0
    return NULL;
315
316
0
  if (is_builtin_candidate(type))
317
0
    return NULL;
318
319
0
  if (crypt_token_load_external(cd, type, &token_handlers[i]))
320
0
    return NULL;
321
322
0
  return &token_handlers[i].u;
323
0
}
324
325
static const void
326
*LUKS2_token_handler(struct crypt_device *cd, int token)
327
0
{
328
0
  struct luks2_hdr *hdr;
329
0
  json_object *jobj1, *jobj2;
330
331
0
  if (token < 0)
332
0
    return NULL;
333
334
0
  if (!(hdr = crypt_get_hdr(cd, CRYPT_LUKS2)))
335
0
    return NULL;
336
337
0
  if (!(jobj1 = LUKS2_get_token_jobj(hdr, token)))
338
0
    return NULL;
339
340
0
  if (!json_object_object_get_ex(jobj1, "type", &jobj2))
341
0
    return NULL;
342
343
0
  return LUKS2_token_handler_type(cd, json_object_get_string(jobj2));
344
0
}
345
346
static int LUKS2_token_find_free(struct luks2_hdr *hdr)
347
0
{
348
0
  int i;
349
350
0
  for (i = 0; i < LUKS2_TOKENS_MAX; i++)
351
0
    if (!LUKS2_get_token_jobj(hdr, i))
352
0
      return i;
353
354
0
  return -EINVAL;
355
0
}
356
357
int LUKS2_token_create(struct crypt_device *cd,
358
  struct luks2_hdr *hdr,
359
  int token,
360
  const char *json,
361
  int commit)
362
0
{
363
0
  const crypt_token_handler *h;
364
0
  json_object *jobj_tokens, *jobj_type, *jobj;
365
0
  enum json_tokener_error jerr;
366
0
  char num[16];
367
368
0
  if (token == CRYPT_ANY_TOKEN) {
369
0
    if (!json)
370
0
      return -EINVAL;
371
0
    token = LUKS2_token_find_free(hdr);
372
0
  }
373
374
0
  if (token < 0 || token >= LUKS2_TOKENS_MAX)
375
0
    return -EINVAL;
376
377
0
  if (!json_object_object_get_ex(hdr->jobj, "tokens", &jobj_tokens))
378
0
    return -EINVAL;
379
380
0
  if (snprintf(num, sizeof(num), "%d", token) < 0)
381
0
    return -EINVAL;
382
383
  /* Remove token */
384
0
  if (!json)
385
0
    json_object_object_del(jobj_tokens, num);
386
0
  else {
387
388
0
    jobj = json_tokener_parse_verbose(json, &jerr);
389
0
    if (!jobj) {
390
0
      log_dbg(cd, "Token JSON parse failed.");
391
0
      return -EINVAL;
392
0
    }
393
394
0
    if (LUKS2_token_validate(cd, hdr->jobj, jobj, num)) {
395
0
      json_object_put(jobj);
396
0
      return -EINVAL;
397
0
    }
398
399
0
    json_object_object_get_ex(jobj, "type", &jobj_type);
400
0
    h = LUKS2_token_handler_type(cd, json_object_get_string(jobj_type));
401
402
0
    if (is_builtin_candidate(json_object_get_string(jobj_type)) && !h) {
403
0
      log_dbg(cd, "%s is builtin token candidate with missing handler",
404
0
        json_object_get_string(jobj_type));
405
0
      json_object_put(jobj);
406
0
      return -EINVAL;
407
0
    }
408
409
0
    if (h && h->validate && h->validate(cd, json)) {
410
0
      json_object_put(jobj);
411
0
      log_dbg(cd, "Token type %s validation failed.", h->name);
412
0
      return -EINVAL;
413
0
    }
414
415
0
    json_object_object_add(jobj_tokens, num, jobj);
416
0
    if (LUKS2_check_json_size(cd, hdr)) {
417
0
      log_dbg(cd, "Not enough space in header json area for new token.");
418
0
      json_object_object_del(jobj_tokens, num);
419
0
      return -ENOSPC;
420
0
    }
421
0
  }
422
423
0
  if (commit)
424
0
    return LUKS2_hdr_write(cd, hdr) ?: token;
425
426
0
  return token;
427
0
}
428
429
crypt_token_info LUKS2_token_status(struct crypt_device *cd,
430
  struct luks2_hdr *hdr,
431
  int token,
432
  const char **type)
433
0
{
434
0
  const char *tmp;
435
0
  const crypt_token_handler *th;
436
0
  json_object *jobj_type, *jobj_token;
437
438
0
  if (token < 0 || token >= LUKS2_TOKENS_MAX)
439
0
    return CRYPT_TOKEN_INVALID;
440
441
0
  if (!(jobj_token = LUKS2_get_token_jobj(hdr, token)))
442
0
    return CRYPT_TOKEN_INACTIVE;
443
444
0
  json_object_object_get_ex(jobj_token, "type", &jobj_type);
445
0
  tmp = json_object_get_string(jobj_type);
446
447
0
  if ((th = LUKS2_token_handler_type(cd, tmp))) {
448
0
    if (type)
449
0
      *type = th->name;
450
0
    return is_builtin_candidate(tmp) ? CRYPT_TOKEN_INTERNAL : CRYPT_TOKEN_EXTERNAL;
451
0
  }
452
453
0
  if (type)
454
0
    *type = tmp;
455
456
0
  return is_builtin_candidate(tmp) ? CRYPT_TOKEN_INTERNAL_UNKNOWN : CRYPT_TOKEN_EXTERNAL_UNKNOWN;
457
0
}
458
459
static int token_is_usable(struct luks2_hdr *hdr, json_object *jobj_token, int keyslot, int segment,
460
         crypt_keyslot_priority minimal_priority, bool requires_keyslot)
461
0
{
462
0
  crypt_keyslot_priority keyslot_priority;
463
0
  json_object *jobj_array;
464
0
  int i, slot, len, r = -ENOENT;
465
466
0
  if (!jobj_token)
467
0
    return -EINVAL;
468
469
0
  if (!json_object_object_get_ex(jobj_token, "keyslots", &jobj_array))
470
0
    return -EINVAL;
471
472
0
  if (segment < 0 && segment != CRYPT_ANY_SEGMENT)
473
0
    return -EINVAL;
474
475
  /* no assigned keyslot returns -ENOENT even for CRYPT_ANY_SEGMENT */
476
0
  len = json_object_array_length(jobj_array);
477
0
  if (len < 0)
478
0
    return -ENOENT;
479
480
0
  if (!requires_keyslot)
481
0
    return 0;
482
483
0
  if (!len)
484
0
    return -ENOENT;
485
486
0
  for (i = 0; i < len; i++) {
487
0
    slot = atoi(json_object_get_string(json_object_array_get_idx(jobj_array, i)));
488
489
0
    if (keyslot != CRYPT_ANY_SLOT && slot != keyslot)
490
0
      continue;
491
492
0
    keyslot_priority = LUKS2_keyslot_priority_get(hdr, slot);
493
0
    if (keyslot_priority == CRYPT_SLOT_PRIORITY_INVALID)
494
0
      return -EINVAL;
495
496
0
    if (keyslot_priority < minimal_priority)
497
0
      continue;
498
499
0
    r = LUKS2_keyslot_for_segment(hdr, slot, segment);
500
0
    if (r != -ENOENT)
501
0
      return r;
502
0
  }
503
504
0
  return r;
505
0
}
506
507
static int translate_errno(struct crypt_device *cd, int ret_val, const char *type)
508
0
{
509
0
  if ((ret_val > 0 || ret_val == -EINVAL || ret_val == -EPERM) && !is_builtin_candidate(type)) {
510
0
    log_dbg(cd, "%s token handler returned %d. Changing to %d.", type, ret_val, -ENOENT);
511
0
    ret_val = -ENOENT;
512
0
  }
513
514
0
  return ret_val;
515
0
}
516
517
static int token_open(struct crypt_device *cd,
518
  struct luks2_hdr *hdr,
519
  int keyslot,
520
  int token,
521
  json_object *jobj_token,
522
  const char *type,
523
  int segment,
524
  crypt_keyslot_priority priority,
525
  const char *pin,
526
  size_t pin_size,
527
  char **buffer,
528
  size_t *buffer_len,
529
  void *usrptr,
530
  bool requires_keyslot)
531
0
{
532
0
  const struct crypt_token_handler_v2 *h;
533
0
  json_object *jobj_type;
534
0
  int r;
535
536
0
  assert(token >= 0);
537
0
  assert(jobj_token);
538
0
  assert(priority >= 0);
539
540
0
  if (type) {
541
0
    if (!json_object_object_get_ex(jobj_token, "type", &jobj_type))
542
0
      return -EINVAL;
543
0
    if (strcmp(type, json_object_get_string(jobj_type)))
544
0
      return -ENOENT;
545
0
  }
546
547
0
  r = token_is_usable(hdr, jobj_token, keyslot, segment, priority, requires_keyslot);
548
0
  if (r < 0) {
549
0
    if (r == -ENOENT)
550
0
      log_dbg(cd, "Token %d unusable for segment %d with desired keyslot priority %d.",
551
0
        token, segment, priority);
552
0
    return r;
553
0
  }
554
555
0
  if (!(h = LUKS2_token_handler(cd, token)))
556
0
    return -ENOENT;
557
558
0
  if (h->validate && h->validate(cd, crypt_jobj_to_string_on_disk(jobj_token))) {
559
0
    log_dbg(cd, "Token %d (%s) validation failed.", token, h->name);
560
0
    return -ENOENT;
561
0
  }
562
563
0
  if (pin && !h->open_pin)
564
0
    r = -ENOENT;
565
0
  else if (pin)
566
0
    r = translate_errno(cd, h->open_pin(cd, token, pin, pin_size, buffer, buffer_len, usrptr), h->name);
567
0
  else
568
0
    r = translate_errno(cd, h->open(cd, token, buffer, buffer_len, usrptr), h->name);
569
0
  if (r < 0)
570
0
    log_dbg(cd, "Token %d (%s) open failed with %d.", token, h->name, r);
571
572
0
  return r;
573
0
}
574
575
static void LUKS2_token_buffer_free(struct crypt_device *cd,
576
    int token,
577
    void *buffer,
578
    size_t buffer_len)
579
0
{
580
0
  const crypt_token_handler *h = LUKS2_token_handler(cd, token);
581
582
0
  if (h && h->buffer_free)
583
0
    h->buffer_free(buffer, buffer_len);
584
0
  else {
585
0
    crypt_safe_memzero(buffer, buffer_len);
586
0
    free(buffer);
587
0
  }
588
0
}
589
590
static bool break_loop_retval(int r)
591
0
{
592
0
  if (r == -ENOENT || r == -EPERM || r == -EAGAIN || r == -ENOANO)
593
0
    return false;
594
0
  return true;
595
0
}
596
597
static void update_return_errno(int r, int *stored)
598
0
{
599
0
  if (*stored == -ENOANO)
600
0
    return;
601
0
  else if (r == -ENOANO)
602
0
    *stored = r;
603
0
  else if (r == -EAGAIN && *stored != -ENOANO)
604
0
    *stored = r;
605
0
  else if (r == -EPERM && (*stored != -ENOANO && *stored != -EAGAIN))
606
0
    *stored = r;
607
0
}
608
609
static int try_token_keyslot_unlock(struct crypt_device *cd,
610
  struct luks2_hdr *hdr,
611
  const char *type,
612
  json_object *jobj_token_keyslots,
613
  int token,
614
  int segment,
615
  crypt_keyslot_priority priority,
616
  const char *buffer,
617
  size_t buffer_len,
618
  struct volume_key **r_vk)
619
0
{
620
0
  json_object *jobj;
621
0
  crypt_keyslot_priority keyslot_priority;
622
0
  int i, r = -ENOENT, stored_retval = -ENOENT;
623
0
  unsigned int num = 0;
624
625
0
  for (i = 0; i < (int) json_object_array_length(jobj_token_keyslots) && r < 0; i++) {
626
0
    jobj = json_object_array_get_idx(jobj_token_keyslots, i);
627
0
    num = atoi(json_object_get_string(jobj));
628
0
    keyslot_priority = LUKS2_keyslot_priority_get(hdr, num);
629
0
    if (keyslot_priority == CRYPT_SLOT_PRIORITY_INVALID)
630
0
      return -EINVAL;
631
0
    if (keyslot_priority < priority)
632
0
      continue;
633
0
    log_dbg(cd, "Trying to open keyslot %u with token %d (type %s).",
634
0
      num, token, type);
635
0
    r = LUKS2_keyslot_open(cd, num, segment, buffer, buffer_len, r_vk);
636
    /* short circuit on fatal error */
637
0
    if (r < 0 && r != -EPERM && r != -ENOENT)
638
0
      return r;
639
    /* save -EPERM in case no other keyslot is usable */
640
0
    if (r == -EPERM)
641
0
      stored_retval = r;
642
0
  }
643
644
0
  if (r < 0)
645
0
    return stored_retval;
646
647
0
  return num;
648
0
}
649
650
static int LUKS2_keyslot_open_by_token(struct crypt_device *cd,
651
  struct luks2_hdr *hdr,
652
  int keyslot,
653
  int token,
654
  int segment,
655
  crypt_keyslot_priority min_priority,
656
  const char *buffer,
657
  size_t buffer_len,
658
  struct volume_key **vk)
659
0
{
660
0
  json_object *jobj_token, *jobj_token_keyslots, *jobj_type;
661
0
  crypt_keyslot_priority priority = CRYPT_SLOT_PRIORITY_PREFER;
662
0
  int r = -ENOENT, stored_retval = -ENOENT;
663
664
0
  jobj_token = LUKS2_get_token_jobj(hdr, token);
665
0
  if (!jobj_token)
666
0
    return -EINVAL;
667
668
0
  if (!json_object_object_get_ex(jobj_token, "type", &jobj_type))
669
0
    return -EINVAL;
670
671
0
  json_object_object_get_ex(jobj_token, "keyslots", &jobj_token_keyslots);
672
0
  if (!jobj_token_keyslots)
673
0
    return -EINVAL;
674
675
  /* with specific keyslot just ignore priorities and unlock */
676
0
  if (keyslot != CRYPT_ANY_SLOT) {
677
0
    log_dbg(cd, "Trying to open keyslot %u with token %d (type %s).",
678
0
      keyslot, token, json_object_get_string(jobj_type));
679
0
    return LUKS2_keyslot_open(cd, keyslot, segment, buffer, buffer_len, vk);
680
0
  }
681
682
  /* Try to open keyslot referenced in token */
683
0
  while (priority >= min_priority) {
684
0
    r = try_token_keyslot_unlock(cd, hdr, json_object_get_string(jobj_type),
685
0
               jobj_token_keyslots, token, segment,
686
0
               priority, buffer, buffer_len, vk);
687
0
    if (r == -EINVAL || r >= 0)
688
0
      return r;
689
0
    if (r == -EPERM)
690
0
      stored_retval = r;
691
0
    priority--;
692
0
  }
693
694
0
  return stored_retval;
695
0
}
696
697
static bool token_is_blocked(int token, uint32_t *block_list)
698
0
{
699
  /* it is safe now, but have assert in case LUKS2_TOKENS_MAX grows */
700
0
  assert(token >= 0 && (size_t)token < BITFIELD_SIZE(block_list));
701
702
0
  return (*block_list & (UINT32_C(1) << token));
703
0
}
704
705
static void token_block(int token, uint32_t *block_list)
706
0
{
707
  /* it is safe now, but have assert in case LUKS2_TOKENS_MAX grows */
708
0
  assert(token >= 0 && (size_t)token < BITFIELD_SIZE(block_list));
709
710
0
  *block_list |= (UINT32_C(1) << token);
711
0
}
712
713
static int token_open_priority(struct crypt_device *cd,
714
  struct luks2_hdr *hdr,
715
  json_object *jobj_tokens,
716
  const char *type,
717
  int keyslot,
718
  int segment,
719
  crypt_keyslot_priority priority,
720
  const char *pin,
721
  size_t pin_size,
722
  void *usrptr,
723
  int *stored_retval,
724
  uint32_t *block_list,
725
  struct volume_key **vk)
726
0
{
727
0
  char *buffer;
728
0
  size_t buffer_size;
729
0
  int token, r;
730
731
0
  assert(stored_retval);
732
0
  assert(block_list);
733
734
0
  json_object_object_foreach(jobj_tokens, slot, val) {
735
0
    token = atoi(slot);
736
0
    if (token_is_blocked(token, block_list))
737
0
      continue;
738
0
    r = token_open(cd, hdr, keyslot, token, val, type, segment, priority, pin, pin_size,
739
0
             &buffer, &buffer_size, usrptr, true);
740
0
    if (!r) {
741
0
      r = LUKS2_keyslot_open_by_token(cd, hdr, keyslot, token, segment, priority,
742
0
              buffer, buffer_size, vk);
743
0
      LUKS2_token_buffer_free(cd, token, buffer, buffer_size);
744
0
    }
745
746
0
    if (r == -ENOANO)
747
0
      token_block(token, block_list);
748
749
0
    if (break_loop_retval(r))
750
0
      return r;
751
752
0
    update_return_errno(r, stored_retval);
753
0
  }
754
755
0
  return *stored_retval;
756
0
}
757
758
static int token_open_any(struct crypt_device *cd, struct luks2_hdr *hdr, const char *type,
759
        int keyslot, int segment, const char *pin, size_t pin_size, void *usrptr,
760
        struct volume_key **vk)
761
0
{
762
0
  json_object *jobj_tokens;
763
0
  int r, retval = -ENOENT;
764
0
  uint32_t blocked = 0; /* bitmap with tokens blocked from loop by returning -ENOANO (wrong/missing pin) */
765
766
0
  json_object_object_get_ex(hdr->jobj, "tokens", &jobj_tokens);
767
768
  /* passing usrptr for CRYPT_ANY_TOKEN does not make sense without specific type */
769
0
  if (!type)
770
0
    usrptr = NULL;
771
772
0
  if (keyslot != CRYPT_ANY_SLOT)
773
0
    return token_open_priority(cd, hdr, jobj_tokens, type, keyslot, segment, CRYPT_SLOT_PRIORITY_IGNORE,
774
0
        pin, pin_size, usrptr, &retval, &blocked, vk);
775
776
0
  r = token_open_priority(cd, hdr, jobj_tokens, type, keyslot, segment, CRYPT_SLOT_PRIORITY_PREFER,
777
0
        pin, pin_size, usrptr, &retval, &blocked, vk);
778
0
  if (break_loop_retval(r))
779
0
    return r;
780
781
0
  return token_open_priority(cd, hdr, jobj_tokens, type, keyslot, segment, CRYPT_SLOT_PRIORITY_NORMAL,
782
0
           pin, pin_size, usrptr, &retval, &blocked, vk);
783
0
}
784
785
int LUKS2_token_unlock_key(struct crypt_device *cd,
786
  struct luks2_hdr *hdr,
787
  int keyslot,
788
  int token,
789
  const char *type,
790
  const char *pin,
791
  size_t pin_size,
792
  int segment,
793
  void *usrptr,
794
  struct volume_key **vk)
795
0
{
796
0
  char *buffer;
797
0
  size_t buffer_size;
798
0
  json_object *jobj_token;
799
0
  crypt_keyslot_priority min_priority;
800
0
  int r = -ENOENT;
801
802
0
  assert(vk);
803
804
0
  if (segment == CRYPT_DEFAULT_SEGMENT)
805
0
    segment = LUKS2_get_default_segment(hdr);
806
807
0
  if (segment < 0 && segment != CRYPT_ANY_SEGMENT)
808
0
    return -EINVAL;
809
810
0
  if (keyslot != CRYPT_ANY_SLOT || token != CRYPT_ANY_TOKEN)
811
0
    min_priority = CRYPT_SLOT_PRIORITY_IGNORE;
812
0
  else
813
0
    min_priority = CRYPT_SLOT_PRIORITY_NORMAL;
814
815
0
  if (keyslot != CRYPT_ANY_SLOT) {
816
0
    r = LUKS2_keyslot_for_segment(hdr, keyslot, segment);
817
0
    if (r < 0) {
818
0
      if (r == -ENOENT)
819
0
        log_dbg(cd, "Keyslot %d unusable for segment %d.", keyslot, segment);
820
0
      return r;
821
0
    }
822
0
  }
823
824
0
  if (token >= 0 && token < LUKS2_TOKENS_MAX) {
825
0
    if ((jobj_token = LUKS2_get_token_jobj(hdr, token))) {
826
0
      r = token_open(cd, hdr, keyslot, token, jobj_token, type, segment, min_priority,
827
0
               pin, pin_size, &buffer, &buffer_size, usrptr, true);
828
0
      if (!r) {
829
0
        r = LUKS2_keyslot_open_by_token(cd, hdr, keyslot, token, segment,
830
0
                min_priority, buffer, buffer_size, vk);
831
0
        LUKS2_token_buffer_free(cd, token, buffer, buffer_size);
832
0
      }
833
0
    }
834
0
  } else if (token == CRYPT_ANY_TOKEN)
835
    /*
836
     * return priorities (ordered form least to most significant):
837
     * ENOENT - unusable for activation (no token handler, invalid token metadata, not assigned to volume segment, etc)
838
     * EPERM  - usable but token provided passphrase did not unlock any assigned keyslot
839
     * EAGAIN - usable but not ready (token HW is missing)
840
     * ENOANO - ready, but token pin is wrong or missing
841
     *
842
     * success (>= 0) or any other negative errno short-circuits token activation loop
843
     * immediately
844
     */
845
0
    r = token_open_any(cd, hdr, type, keyslot, segment, pin, pin_size, usrptr, vk);
846
0
  else
847
0
    r = -EINVAL;
848
849
0
  return r;
850
0
}
851
852
void LUKS2_token_dump(struct crypt_device *cd, int token)
853
0
{
854
0
  const crypt_token_handler *h;
855
0
  json_object *jobj_token;
856
857
0
  h = LUKS2_token_handler(cd, token);
858
0
  if (h && h->dump) {
859
0
    jobj_token = LUKS2_get_token_jobj(crypt_get_hdr(cd, CRYPT_LUKS2), token);
860
0
    if (jobj_token)
861
0
      h->dump(cd, crypt_jobj_to_string_on_disk(jobj_token));
862
0
  }
863
0
}
864
865
int LUKS2_token_json_get(struct luks2_hdr *hdr, int token, const char **json)
866
0
{
867
0
  json_object *jobj_token;
868
869
0
  jobj_token = LUKS2_get_token_jobj(hdr, token);
870
0
  if (!jobj_token)
871
0
    return -EINVAL;
872
873
0
  *json = crypt_jobj_to_string_on_disk(jobj_token);
874
0
  return 0;
875
0
}
876
877
static int assign_one_keyslot(struct crypt_device *cd, struct luks2_hdr *hdr,
878
            int token, int keyslot, int assign)
879
0
{
880
0
  json_object *jobj1, *jobj_token, *jobj_token_keyslots;
881
0
  char num[16];
882
883
0
  log_dbg(cd, "Keyslot %i %s token %i.", keyslot, assign ? "assigned to" : "unassigned from", token);
884
885
0
  jobj_token = LUKS2_get_token_jobj(hdr, token);
886
0
  if (!jobj_token)
887
0
    return -EINVAL;
888
889
0
  json_object_object_get_ex(jobj_token, "keyslots", &jobj_token_keyslots);
890
0
  if (!jobj_token_keyslots)
891
0
    return -EINVAL;
892
893
0
  if (snprintf(num, sizeof(num), "%d", keyslot) < 0)
894
0
    return -EINVAL;
895
896
0
  if (assign) {
897
0
    jobj1 = LUKS2_array_jobj(jobj_token_keyslots, num);
898
0
    if (!jobj1)
899
0
      json_object_array_add(jobj_token_keyslots, json_object_new_string(num));
900
0
  } else {
901
0
    jobj1 = LUKS2_array_remove(jobj_token_keyslots, num);
902
0
    if (jobj1)
903
0
      json_object_object_add(jobj_token, "keyslots", jobj1);
904
0
  }
905
906
0
  return 0;
907
0
}
908
909
static int assign_one_token(struct crypt_device *cd, struct luks2_hdr *hdr,
910
          int keyslot, int token, int assign)
911
0
{
912
0
  json_object *jobj_keyslots;
913
0
  int r = 0;
914
915
0
  if (!LUKS2_get_token_jobj(hdr, token))
916
0
    return -EINVAL;
917
918
0
  if (keyslot == CRYPT_ANY_SLOT) {
919
0
    json_object_object_get_ex(hdr->jobj, "keyslots", &jobj_keyslots);
920
921
0
    json_object_object_foreach(jobj_keyslots, key, val) {
922
0
      UNUSED(val);
923
0
      r = assign_one_keyslot(cd, hdr, token, atoi(key), assign);
924
0
      if (r < 0)
925
0
        break;
926
0
    }
927
0
  } else
928
0
    r = assign_one_keyslot(cd, hdr, token, keyslot, assign);
929
930
0
  return r;
931
0
}
932
933
int LUKS2_token_assign(struct crypt_device *cd, struct luks2_hdr *hdr,
934
      int keyslot, int token, int assign, int commit)
935
0
{
936
0
  json_object *jobj_tokens;
937
0
  int r = 0;
938
939
0
  if ((keyslot < 0 && keyslot != CRYPT_ANY_SLOT) || keyslot >= LUKS2_KEYSLOTS_MAX ||
940
0
      (token < 0 && token != CRYPT_ANY_TOKEN) || token >= LUKS2_TOKENS_MAX)
941
0
    return -EINVAL;
942
943
0
  if (token == CRYPT_ANY_TOKEN) {
944
0
    json_object_object_get_ex(hdr->jobj, "tokens", &jobj_tokens);
945
946
0
    json_object_object_foreach(jobj_tokens, key, val) {
947
0
      UNUSED(val);
948
0
      r = assign_one_token(cd, hdr, keyslot, atoi(key), assign);
949
0
      if (r < 0)
950
0
        break;
951
0
    }
952
0
  } else
953
0
    r = assign_one_token(cd, hdr, keyslot, token, assign);
954
955
0
  if (r < 0)
956
0
    return r;
957
958
0
  if (commit)
959
0
    return LUKS2_hdr_write(cd, hdr) ?: token;
960
961
0
  return token;
962
0
}
963
964
static int token_is_assigned(struct luks2_hdr *hdr, int keyslot, int token)
965
0
{
966
0
  int i;
967
0
  json_object *jobj, *jobj_token_keyslots,
968
0
        *jobj_token = LUKS2_get_token_jobj(hdr, token);
969
970
0
  if (!jobj_token)
971
0
    return -ENOENT;
972
973
0
  json_object_object_get_ex(jobj_token, "keyslots", &jobj_token_keyslots);
974
975
0
  for (i = 0; i < (int) json_object_array_length(jobj_token_keyslots); i++) {
976
0
    jobj = json_object_array_get_idx(jobj_token_keyslots, i);
977
0
    if (keyslot == atoi(json_object_get_string(jobj)))
978
0
      return 0;
979
0
  }
980
981
0
  return -ENOENT;
982
0
}
983
984
int LUKS2_token_is_assigned(struct luks2_hdr *hdr, int keyslot, int token)
985
0
{
986
0
  if (keyslot < 0 || keyslot >= LUKS2_KEYSLOTS_MAX || token < 0 || token >= LUKS2_TOKENS_MAX)
987
0
    return -EINVAL;
988
989
0
  return token_is_assigned(hdr, keyslot, token);
990
0
}
991
992
int LUKS2_tokens_count(struct luks2_hdr *hdr)
993
0
{
994
0
  json_object *jobj_tokens = LUKS2_get_tokens_jobj(hdr);
995
0
  if (!jobj_tokens)
996
0
    return -EINVAL;
997
998
0
  return json_object_object_length(jobj_tokens);
999
0
}
1000
1001
int LUKS2_token_assignment_copy(struct crypt_device *cd,
1002
      struct luks2_hdr *hdr,
1003
      int keyslot_from,
1004
      int keyslot_to,
1005
      int commit)
1006
0
{
1007
0
  int i, r;
1008
1009
0
  if (keyslot_from < 0 || keyslot_from >= LUKS2_KEYSLOTS_MAX || keyslot_to < 0 || keyslot_to >= LUKS2_KEYSLOTS_MAX)
1010
0
    return -EINVAL;
1011
1012
0
  r = LUKS2_tokens_count(hdr);
1013
0
  if (r <= 0)
1014
0
    return r;
1015
1016
0
  for (i = 0; i < LUKS2_TOKENS_MAX; i++) {
1017
0
    if (!token_is_assigned(hdr, keyslot_from, i)) {
1018
0
      if ((r = assign_one_token(cd, hdr, keyslot_to, i, 1)))
1019
0
        return r;
1020
0
    }
1021
0
  }
1022
1023
0
  return commit ? LUKS2_hdr_write(cd, hdr) : 0;
1024
0
}
1025
1026
int LUKS2_token_unlock_passphrase(struct crypt_device *cd,
1027
  struct luks2_hdr *hdr,
1028
  int token,
1029
  const char *type,
1030
  const char *pin,
1031
  size_t pin_size,
1032
  void *usrptr,
1033
  char **passphrase,
1034
  size_t *passphrase_size)
1035
0
{
1036
0
  char *buffer;
1037
0
  size_t buffer_size;
1038
0
  json_object *jobj_token, *jobj_tokens;
1039
0
  int r = -ENOENT, retval = -ENOENT;
1040
1041
0
  if (!hdr)
1042
0
    return -EINVAL;
1043
1044
0
  if (token >= 0 && token < LUKS2_TOKENS_MAX) {
1045
0
    if ((jobj_token = LUKS2_get_token_jobj(hdr, token)))
1046
0
      r = token_open(cd, hdr, CRYPT_ANY_SLOT, token, jobj_token, type,
1047
0
               CRYPT_ANY_SEGMENT, CRYPT_SLOT_PRIORITY_IGNORE, pin, pin_size,
1048
0
               &buffer, &buffer_size, usrptr, false);
1049
0
  } else if (token == CRYPT_ANY_TOKEN) {
1050
0
    json_object_object_get_ex(hdr->jobj, "tokens", &jobj_tokens);
1051
1052
0
    if (!type)
1053
0
      usrptr = NULL;
1054
1055
0
    json_object_object_foreach(jobj_tokens, slot, val) {
1056
0
      token = atoi(slot);
1057
0
      r = token_open(cd, hdr, CRYPT_ANY_SLOT, token, val, type, CRYPT_ANY_SEGMENT, CRYPT_SLOT_PRIORITY_IGNORE,
1058
0
               pin, pin_size, &buffer, &buffer_size, usrptr, false);
1059
1060
      /*
1061
       * return priorities (ordered form least to most significant):
1062
       * ENOENT - unusable for activation (no token handler, invalid token metadata, etc)
1063
       * EAGAIN - usable but not ready (token HW is missing)
1064
       * ENOANO - ready, but token pin is wrong or missing
1065
       *
1066
       * success (>= 0) or any other negative errno short-circuits token activation loop
1067
       * immediately
1068
       */
1069
0
      if (break_loop_retval(r))
1070
0
        goto out;
1071
1072
0
      update_return_errno(r, &retval);
1073
0
    }
1074
0
    r = retval;
1075
0
  } else
1076
0
    r = -EINVAL;
1077
0
out:
1078
0
  if (!r) {
1079
0
    *passphrase = crypt_safe_alloc(buffer_size);
1080
0
    if (*passphrase) {
1081
0
      crypt_safe_memcpy(*passphrase, buffer, buffer_size);
1082
0
      *passphrase_size = buffer_size;
1083
0
    } else
1084
0
      r = -ENOMEM;
1085
0
    LUKS2_token_buffer_free(cd, token, buffer, buffer_size);
1086
0
  }
1087
1088
0
  if (!r)
1089
0
    return token;
1090
1091
0
  return r;
1092
0
}