Fixed the build error for riscv64 arch using gcc 13
[platform/upstream/cryptsetup.git] / lib / luks2 / luks2_token.c
1 /*
2  * LUKS - Linux Unified Key Setup v2, token handling
3  *
4  * Copyright (C) 2016-2021 Red Hat, Inc. All rights reserved.
5  * Copyright (C) 2016-2021 Milan Broz
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21
22 #include <assert.h>
23
24 #include "luks2_internal.h"
25
26 /* Builtin tokens */
27 extern const crypt_token_handler keyring_handler;
28
29 static token_handler token_handlers[LUKS2_TOKENS_MAX] = {
30         /* keyring builtin token */
31         {
32           .get = token_keyring_get,
33           .set = token_keyring_set,
34           .h = &keyring_handler
35         },
36 };
37
38 static int is_builtin_candidate(const char *type)
39 {
40         return !strncmp(type, LUKS2_BUILTIN_TOKEN_PREFIX, LUKS2_BUILTIN_TOKEN_PREFIX_LEN);
41 }
42
43 int crypt_token_register(const crypt_token_handler *handler)
44 {
45         int i;
46
47         if (is_builtin_candidate(handler->name)) {
48                 log_dbg(NULL, "'" LUKS2_BUILTIN_TOKEN_PREFIX "' is reserved prefix for builtin tokens.");
49                 return -EINVAL;
50         }
51
52         for (i = 0; i < LUKS2_TOKENS_MAX && token_handlers[i].h; i++) {
53                 if (!strcmp(token_handlers[i].h->name, handler->name)) {
54                         log_dbg(NULL, "Keyslot handler %s is already registered.", handler->name);
55                         return -EINVAL;
56                 }
57         }
58
59         if (i == LUKS2_TOKENS_MAX)
60                 return -EINVAL;
61
62         token_handlers[i].h = handler;
63         return 0;
64 }
65
66 static const token_handler
67 *LUKS2_token_handler_type_internal(struct crypt_device *cd, const char *type)
68 {
69         int i;
70
71         for (i = 0; i < LUKS2_TOKENS_MAX && token_handlers[i].h; i++)
72                 if (!strcmp(token_handlers[i].h->name, type))
73                         return token_handlers + i;
74
75         return NULL;
76 }
77
78 static const crypt_token_handler
79 *LUKS2_token_handler_type(struct crypt_device *cd, const char *type)
80 {
81         const token_handler *th = LUKS2_token_handler_type_internal(cd, type);
82
83         return th ? th->h : NULL;
84 }
85
86 static const token_handler
87 *LUKS2_token_handler_internal(struct crypt_device *cd, int token)
88 {
89         struct luks2_hdr *hdr;
90         json_object *jobj1, *jobj2;
91
92         if (token < 0)
93                 return NULL;
94
95         if (!(hdr = crypt_get_hdr(cd, CRYPT_LUKS2)))
96                 return NULL;
97
98         if (!(jobj1 = LUKS2_get_token_jobj(hdr, token)))
99                 return NULL;
100
101         if (!json_object_object_get_ex(jobj1, "type", &jobj2))
102                 return NULL;
103
104         return LUKS2_token_handler_type_internal(cd, json_object_get_string(jobj2));
105 }
106
107 static const crypt_token_handler
108 *LUKS2_token_handler(struct crypt_device *cd, int token)
109 {
110         const token_handler *th = LUKS2_token_handler_internal(cd, token);
111
112         return th ? th->h : NULL;
113 }
114
115 static int LUKS2_token_find_free(struct luks2_hdr *hdr)
116 {
117         int i;
118
119         for (i = 0; i < LUKS2_TOKENS_MAX; i++)
120                 if (!LUKS2_get_token_jobj(hdr, i))
121                         return i;
122
123         return -EINVAL;
124 }
125
126 int LUKS2_token_create(struct crypt_device *cd,
127         struct luks2_hdr *hdr,
128         int token,
129         const char *json,
130         int commit)
131 {
132         const crypt_token_handler *h;
133         const token_handler *th;
134         json_object *jobj_tokens, *jobj_type, *jobj;
135         enum json_tokener_error jerr;
136         char num[16];
137
138         if (token == CRYPT_ANY_TOKEN) {
139                 if (!json)
140                         return -EINVAL;
141                 token = LUKS2_token_find_free(hdr);
142         }
143
144         if (token < 0 || token >= LUKS2_TOKENS_MAX)
145                 return -EINVAL;
146
147         if (!json_object_object_get_ex(hdr->jobj, "tokens", &jobj_tokens))
148                 return -EINVAL;
149
150         if (snprintf(num, sizeof(num), "%d", token) < 0)
151                 return -EINVAL;
152
153         /* Remove token */
154         if (!json)
155                 json_object_object_del(jobj_tokens, num);
156         else {
157
158                 jobj = json_tokener_parse_verbose(json, &jerr);
159                 if (!jobj) {
160                         log_dbg(cd, "Token JSON parse failed.");
161                         return -EINVAL;
162                 }
163
164                 if (LUKS2_token_validate(cd, hdr->jobj, jobj, num)) {
165                         json_object_put(jobj);
166                         return -EINVAL;
167                 }
168
169                 json_object_object_get_ex(jobj, "type", &jobj_type);
170                 if (is_builtin_candidate(json_object_get_string(jobj_type))) {
171                         th = LUKS2_token_handler_type_internal(cd, json_object_get_string(jobj_type));
172                         if (!th || !th->set) {
173                                 log_dbg(cd, "%s is builtin token candidate with missing handler", json_object_get_string(jobj_type));
174                                 json_object_put(jobj);
175                                 return -EINVAL;
176                         }
177                         h = th->h;
178                 } else
179                         h = LUKS2_token_handler_type(cd, json_object_get_string(jobj_type));
180
181                 if (h && h->validate && h->validate(cd, json)) {
182                         json_object_put(jobj);
183                         log_dbg(cd, "Token type %s validation failed.", h->name);
184                         return -EINVAL;
185                 }
186
187                 json_object_object_add(jobj_tokens, num, jobj);
188                 if (LUKS2_check_json_size(cd, hdr)) {
189                         log_dbg(cd, "Not enough space in header json area for new token.");
190                         json_object_object_del(jobj_tokens, num);
191                         return -ENOSPC;
192                 }
193         }
194
195         if (commit)
196                 return LUKS2_hdr_write(cd, hdr) ?: token;
197
198         return token;
199 }
200
201 crypt_token_info LUKS2_token_status(struct crypt_device *cd,
202         struct luks2_hdr *hdr,
203         int token,
204         const char **type)
205 {
206         const char *tmp;
207         const token_handler *th;
208         json_object *jobj_type, *jobj_token;
209
210         if (token < 0 || token >= LUKS2_TOKENS_MAX)
211                 return CRYPT_TOKEN_INVALID;
212
213         if (!(jobj_token = LUKS2_get_token_jobj(hdr, token)))
214                 return CRYPT_TOKEN_INACTIVE;
215
216         json_object_object_get_ex(jobj_token, "type", &jobj_type);
217         tmp = json_object_get_string(jobj_type);
218
219         if ((th = LUKS2_token_handler_type_internal(cd, tmp))) {
220                 if (type)
221                         *type = th->h->name;
222                 return th->set ? CRYPT_TOKEN_INTERNAL : CRYPT_TOKEN_EXTERNAL;
223         }
224
225         if (type)
226                 *type = tmp;
227
228         return is_builtin_candidate(tmp) ? CRYPT_TOKEN_INTERNAL_UNKNOWN : CRYPT_TOKEN_EXTERNAL_UNKNOWN;
229 }
230
231 int LUKS2_builtin_token_get(struct crypt_device *cd,
232         struct luks2_hdr *hdr,
233         int token,
234         const char *type,
235         void *params)
236 {
237         const token_handler *th = LUKS2_token_handler_type_internal(cd, type);
238
239         // internal error
240         assert(th && th->get);
241
242         return th->get(LUKS2_get_token_jobj(hdr, token), params) ?: token;
243 }
244
245 int LUKS2_builtin_token_create(struct crypt_device *cd,
246         struct luks2_hdr *hdr,
247         int token,
248         const char *type,
249         const void *params,
250         int commit)
251 {
252         const token_handler *th;
253         int r;
254         json_object *jobj_token, *jobj_tokens;
255
256         th = LUKS2_token_handler_type_internal(cd, type);
257
258         // at this point all builtin handlers must exist and have validate fn defined
259         assert(th && th->set && th->h->validate);
260
261         if (token == CRYPT_ANY_TOKEN) {
262                 if ((token = LUKS2_token_find_free(hdr)) < 0)
263                         log_err(cd, _("No free token slot."));
264         }
265         if (token < 0 || token >= LUKS2_TOKENS_MAX)
266                 return -EINVAL;
267
268         r = th->set(&jobj_token, params);
269         if (r) {
270                 log_err(cd, _("Failed to create builtin token %s."), type);
271                 return r;
272         }
273
274         // builtin tokens must produce valid json
275         r = LUKS2_token_validate(cd, hdr->jobj, jobj_token, "new");
276         assert(!r);
277         r = th->h->validate(cd, json_object_to_json_string_ext(jobj_token,
278                 JSON_C_TO_STRING_PLAIN | JSON_C_TO_STRING_NOSLASHESCAPE));
279         assert(!r);
280
281         json_object_object_get_ex(hdr->jobj, "tokens", &jobj_tokens);
282         json_object_object_add_by_uint(jobj_tokens, token, jobj_token);
283         if (LUKS2_check_json_size(cd, hdr)) {
284                 log_dbg(cd, "Not enough space in header json area for new %s token.", type);
285                 json_object_object_del_by_uint(jobj_tokens, token);
286                 return -ENOSPC;
287         }
288
289         if (commit)
290                 return LUKS2_hdr_write(cd, hdr) ?: token;
291
292         return token;
293 }
294
295 static int LUKS2_token_open(struct crypt_device *cd,
296         struct luks2_hdr *hdr,
297         int token,
298         char **buffer,
299         size_t *buffer_len,
300         void *usrptr)
301 {
302         const char *json;
303         const crypt_token_handler *h;
304         int r;
305
306         if (!(h = LUKS2_token_handler(cd, token)))
307                 return -ENOENT;
308
309         if (h->validate) {
310                 if (LUKS2_token_json_get(cd, hdr, token, &json))
311                         return -EINVAL;
312
313                 if (h->validate(cd, json)) {
314                         log_dbg(cd, "Token %d (%s) validation failed.", token, h->name);
315                         return -EINVAL;
316                 }
317         }
318
319         r = h->open(cd, token, buffer, buffer_len, usrptr);
320         if (r < 0)
321                 log_dbg(cd, "Token %d (%s) open failed with %d.", token, h->name, r);
322
323         return r;
324 }
325
326 static void LUKS2_token_buffer_free(struct crypt_device *cd,
327                 int token,
328                 void *buffer,
329                 size_t buffer_len)
330 {
331         const crypt_token_handler *h = LUKS2_token_handler(cd, token);
332
333         if (h && h->buffer_free)
334                 h->buffer_free(buffer, buffer_len);
335         else {
336                 crypt_safe_memzero(buffer, buffer_len);
337                 free(buffer);
338         }
339 }
340
341 static int LUKS2_keyslot_open_by_token(struct crypt_device *cd,
342         struct luks2_hdr *hdr,
343         int token,
344         int segment,
345         const char *buffer,
346         size_t buffer_len,
347         struct volume_key **vk)
348 {
349         const crypt_token_handler *h;
350         json_object *jobj_token, *jobj_token_keyslots, *jobj;
351         unsigned int num = 0;
352         int i, r;
353
354         if (!(h = LUKS2_token_handler(cd, token)))
355                 return -ENOENT;
356
357         jobj_token = LUKS2_get_token_jobj(hdr, token);
358         if (!jobj_token)
359                 return -EINVAL;
360
361         json_object_object_get_ex(jobj_token, "keyslots", &jobj_token_keyslots);
362         if (!jobj_token_keyslots)
363                 return -EINVAL;
364
365         /* Try to open keyslot referenced in token */
366         r = -EINVAL;
367         for (i = 0; i < (int) json_object_array_length(jobj_token_keyslots) && r < 0; i++) {
368                 jobj = json_object_array_get_idx(jobj_token_keyslots, i);
369                 num = atoi(json_object_get_string(jobj));
370                 log_dbg(cd, "Trying to open keyslot %u with token %d (type %s).", num, token, h->name);
371                 r = LUKS2_keyslot_open(cd, num, segment, buffer, buffer_len, vk);
372         }
373
374         if (r < 0)
375                 return r;
376
377         return num;
378 }
379
380 int LUKS2_token_open_and_activate(struct crypt_device *cd,
381                 struct luks2_hdr *hdr,
382                 int token,
383                 const char *name,
384                 uint32_t flags,
385                 void *usrptr)
386 {
387         bool use_keyring;
388         int keyslot, r;
389         char *buffer;
390         size_t buffer_len;
391         struct volume_key *vk = NULL;
392
393         r = LUKS2_token_open(cd, hdr, token, &buffer, &buffer_len, usrptr);
394         if (r < 0)
395                 return r;
396
397         r = LUKS2_keyslot_open_by_token(cd, hdr, token,
398                                         (flags & CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY) ?
399                                         CRYPT_ANY_SEGMENT : CRYPT_DEFAULT_SEGMENT,
400                                         buffer, buffer_len, &vk);
401
402         LUKS2_token_buffer_free(cd, token, buffer, buffer_len);
403
404         if (r < 0)
405                 return r;
406
407         keyslot = r;
408
409         if (!crypt_use_keyring_for_vk(cd))
410                 use_keyring = false;
411         else
412                 use_keyring = ((name && !crypt_is_cipher_null(crypt_get_cipher(cd))) ||
413                                (flags & CRYPT_ACTIVATE_KEYRING_KEY));
414
415         if (use_keyring) {
416                 if (!(r = LUKS2_volume_key_load_in_keyring_by_keyslot(cd, hdr, vk, keyslot)))
417                         flags |= CRYPT_ACTIVATE_KEYRING_KEY;
418         }
419
420         if (r >= 0 && name)
421                 r = LUKS2_activate(cd, name, vk, flags);
422
423         if (r < 0)
424                 crypt_drop_keyring_key(cd, vk);
425         crypt_free_volume_key(vk);
426
427         return r < 0 ? r : keyslot;
428 }
429
430 int LUKS2_token_open_and_activate_any(struct crypt_device *cd,
431         struct luks2_hdr *hdr,
432         const char *name,
433         uint32_t flags)
434 {
435         char *buffer;
436         json_object *tokens_jobj;
437         size_t buffer_len;
438         int keyslot, token, r = -EINVAL;
439         struct volume_key *vk = NULL;
440
441         json_object_object_get_ex(hdr->jobj, "tokens", &tokens_jobj);
442
443         json_object_object_foreach(tokens_jobj, slot, val) {
444                 UNUSED(val);
445                 token = atoi(slot);
446
447                 r = LUKS2_token_open(cd, hdr, token, &buffer, &buffer_len, NULL);
448                 if (r < 0)
449                         continue;
450
451                 r = LUKS2_keyslot_open_by_token(cd, hdr, token,
452                                                 (flags & CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY) ?
453                                                 CRYPT_ANY_SEGMENT : CRYPT_DEFAULT_SEGMENT,
454                                                 buffer, buffer_len, &vk);
455                 LUKS2_token_buffer_free(cd, token, buffer, buffer_len);
456                 if (r >= 0)
457                         break;
458         }
459
460         keyslot = r;
461
462         if (r >= 0 && (name || (flags & CRYPT_ACTIVATE_KEYRING_KEY)) && crypt_use_keyring_for_vk(cd)) {
463                 if (!(r = LUKS2_volume_key_load_in_keyring_by_keyslot(cd, hdr, vk, keyslot)))
464                         flags |= CRYPT_ACTIVATE_KEYRING_KEY;
465         }
466
467         if (r >= 0 && name)
468                 r = LUKS2_activate(cd, name, vk, flags);
469
470         if (r < 0)
471                 crypt_drop_keyring_key(cd, vk);
472         crypt_free_volume_key(vk);
473
474         return r < 0 ? r : keyslot;
475 }
476
477 void LUKS2_token_dump(struct crypt_device *cd, int token)
478 {
479         const crypt_token_handler *h;
480         json_object *jobj_token;
481
482         h = LUKS2_token_handler(cd, token);
483         if (h && h->dump) {
484                 jobj_token = LUKS2_get_token_jobj(crypt_get_hdr(cd, CRYPT_LUKS2), token);
485                 if (jobj_token)
486                         h->dump(cd, json_object_to_json_string_ext(jobj_token,
487                                 JSON_C_TO_STRING_PLAIN | JSON_C_TO_STRING_NOSLASHESCAPE));
488         }
489 }
490
491 int LUKS2_token_json_get(struct crypt_device *cd, struct luks2_hdr *hdr,
492                            int token, const char **json)
493 {
494         json_object *jobj_token;
495
496         jobj_token = LUKS2_get_token_jobj(hdr, token);
497         if (!jobj_token)
498                 return -EINVAL;
499
500         *json = json_object_to_json_string_ext(jobj_token,
501                 JSON_C_TO_STRING_PLAIN | JSON_C_TO_STRING_NOSLASHESCAPE);
502         return 0;
503 }
504
505 static int assign_one_keyslot(struct crypt_device *cd, struct luks2_hdr *hdr,
506                               int token, int keyslot, int assign)
507 {
508         json_object *jobj1, *jobj_token, *jobj_token_keyslots;
509         char num[16];
510
511         log_dbg(cd, "Keyslot %i %s token %i.", keyslot, assign ? "assigned to" : "unassigned from", token);
512
513         jobj_token = LUKS2_get_token_jobj(hdr, token);
514         if (!jobj_token)
515                 return -EINVAL;
516
517         json_object_object_get_ex(jobj_token, "keyslots", &jobj_token_keyslots);
518         if (!jobj_token_keyslots)
519                 return -EINVAL;
520
521         if (snprintf(num, sizeof(num), "%d", keyslot) < 0)
522                 return -EINVAL;
523
524         if (assign) {
525                 jobj1 = LUKS2_array_jobj(jobj_token_keyslots, num);
526                 if (!jobj1)
527                         json_object_array_add(jobj_token_keyslots, json_object_new_string(num));
528         } else {
529                 jobj1 = LUKS2_array_remove(jobj_token_keyslots, num);
530                 if (jobj1)
531                         json_object_object_add(jobj_token, "keyslots", jobj1);
532         }
533
534         return 0;
535 }
536
537 static int assign_one_token(struct crypt_device *cd, struct luks2_hdr *hdr,
538                             int keyslot, int token, int assign)
539 {
540         json_object *jobj_keyslots;
541         int r = 0;
542
543         if (!LUKS2_get_token_jobj(hdr, token))
544                 return -EINVAL;
545
546         if (keyslot == CRYPT_ANY_SLOT) {
547                 json_object_object_get_ex(hdr->jobj, "keyslots", &jobj_keyslots);
548
549                 json_object_object_foreach(jobj_keyslots, key, val) {
550                         UNUSED(val);
551                         r = assign_one_keyslot(cd, hdr, token, atoi(key), assign);
552                         if (r < 0)
553                                 break;
554                 }
555         } else
556                 r = assign_one_keyslot(cd, hdr, token, keyslot, assign);
557
558         return r;
559 }
560
561 int LUKS2_token_assign(struct crypt_device *cd, struct luks2_hdr *hdr,
562                         int keyslot, int token, int assign, int commit)
563 {
564         json_object *jobj_tokens;
565         int r = 0;
566
567         if (token == CRYPT_ANY_TOKEN) {
568                 json_object_object_get_ex(hdr->jobj, "tokens", &jobj_tokens);
569
570                 json_object_object_foreach(jobj_tokens, key, val) {
571                         UNUSED(val);
572                         r = assign_one_token(cd, hdr, keyslot, atoi(key), assign);
573                         if (r < 0)
574                                 break;
575                 }
576         } else
577                 r = assign_one_token(cd, hdr, keyslot, token, assign);
578
579         if (r < 0)
580                 return r;
581
582         // FIXME: do not write header in nothing changed
583         if (commit)
584                 return LUKS2_hdr_write(cd, hdr) ?: token;
585
586         return token;
587 }
588
589 static int token_is_assigned(struct luks2_hdr *hdr, int keyslot, int token)
590 {
591         int i;
592         json_object *jobj, *jobj_token_keyslots,
593                     *jobj_token = LUKS2_get_token_jobj(hdr, token);
594
595         if (!jobj_token)
596                 return -ENOENT;
597
598         json_object_object_get_ex(jobj_token, "keyslots", &jobj_token_keyslots);
599
600         for (i = 0; i < (int) json_object_array_length(jobj_token_keyslots); i++) {
601                 jobj = json_object_array_get_idx(jobj_token_keyslots, i);
602                 if (keyslot == atoi(json_object_get_string(jobj)))
603                         return 0;
604         }
605
606         return -ENOENT;
607 }
608
609 int LUKS2_token_is_assigned(struct crypt_device *cd, struct luks2_hdr *hdr,
610                             int keyslot, int token)
611 {
612         if (keyslot < 0 || keyslot >= LUKS2_KEYSLOTS_MAX || token < 0 || token >= LUKS2_TOKENS_MAX)
613                 return -EINVAL;
614
615         return token_is_assigned(hdr, keyslot, token);
616 }
617
618 int LUKS2_tokens_count(struct luks2_hdr *hdr)
619 {
620         json_object *jobj_tokens = LUKS2_get_tokens_jobj(hdr);
621         if (!jobj_tokens)
622                 return -EINVAL;
623
624         return json_object_object_length(jobj_tokens);
625 }
626
627 int LUKS2_token_assignment_copy(struct crypt_device *cd,
628                         struct luks2_hdr *hdr,
629                         int keyslot_from,
630                         int keyslot_to,
631                         int commit)
632 {
633         int i, r;
634
635         if (keyslot_from < 0 || keyslot_from >= LUKS2_KEYSLOTS_MAX || keyslot_to < 0 || keyslot_to >= LUKS2_KEYSLOTS_MAX)
636                 return -EINVAL;
637
638         r = LUKS2_tokens_count(hdr);
639         if (r <= 0)
640                 return r;
641
642         for (i = 0; i < LUKS2_TOKENS_MAX; i++) {
643                 if (!token_is_assigned(hdr, keyslot_from, i)) {
644                         if ((r = assign_one_token(cd, hdr, keyslot_to, i, 1)))
645                                 return r;
646                 }
647         }
648
649         return commit ? LUKS2_hdr_write(cd, hdr) : 0;
650 }