"Fossies" - the Fresh Open Source Software Archive

Member "cryptsetup-2.4.3/lib/luks2/luks2_token.c" (13 Jan 2022, 23857 Bytes) of package /linux/misc/cryptsetup-2.4.3.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "luks2_token.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 2.4.1_vs_2.4.2.

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