"Fossies" - the Fresh Open Source Software Archive

Member "cryptsetup-2.4.3/lib/libdevmapper.c" (13 Jan 2022, 85399 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 "libdevmapper.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  * libdevmapper - device-mapper backend for cryptsetup
    3  *
    4  * Copyright (C) 2004 Jana Saout <jana@saout.de>
    5  * Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
    6  * Copyright (C) 2009-2021 Red Hat, Inc. All rights reserved.
    7  * Copyright (C) 2009-2021 Milan Broz
    8  *
    9  * This program is free software; you can redistribute it and/or
   10  * modify it under the terms of the GNU General Public License
   11  * as published by the Free Software Foundation; either version 2
   12  * of the License, or (at your option) any later version.
   13  *
   14  * This program is distributed in the hope that it will be useful,
   15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   17  * GNU General Public License for more details.
   18  *
   19  * You should have received a copy of the GNU General Public License
   20  * along with this program; if not, write to the Free Software
   21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   22  */
   23 
   24 #include <stdio.h>
   25 #include <stdbool.h>
   26 #include <ctype.h>
   27 #include <errno.h>
   28 #include <libdevmapper.h>
   29 #include <uuid/uuid.h>
   30 #include <sys/stat.h>
   31 #ifdef HAVE_SYS_SYSMACROS_H
   32 # include <sys/sysmacros.h>     /* for major, minor */
   33 #endif
   34 #include <assert.h>
   35 #include "internal.h"
   36 
   37 #define DM_CRYPT_TARGET     "crypt"
   38 #define DM_VERITY_TARGET    "verity"
   39 #define DM_INTEGRITY_TARGET "integrity"
   40 #define DM_LINEAR_TARGET    "linear"
   41 #define DM_ERROR_TARGET         "error"
   42 #define DM_ZERO_TARGET      "zero"
   43 #define RETRY_COUNT     5
   44 
   45 /* Set if DM target versions were probed */
   46 static bool _dm_ioctl_checked = false;
   47 static bool _dm_crypt_checked = false;
   48 static bool _dm_verity_checked = false;
   49 static bool _dm_integrity_checked = false;
   50 
   51 static int _quiet_log = 0;
   52 static uint32_t _dm_flags = 0;
   53 
   54 static struct crypt_device *_context = NULL;
   55 static int _dm_use_count = 0;
   56 
   57 /* Check if we have DM flag to instruct kernel to force wipe buffers */
   58 #if !HAVE_DECL_DM_TASK_SECURE_DATA
   59 static int dm_task_secure_data(struct dm_task *dmt) { return 1; }
   60 #endif
   61 
   62 /* Compatibility for old device-mapper without udev support */
   63 #if HAVE_DECL_DM_UDEV_DISABLE_DISK_RULES_FLAG
   64 #define CRYPT_TEMP_UDEV_FLAGS   DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG | \
   65                 DM_UDEV_DISABLE_DISK_RULES_FLAG | \
   66                 DM_UDEV_DISABLE_OTHER_RULES_FLAG
   67 #define _dm_task_set_cookie dm_task_set_cookie
   68 #define _dm_udev_wait       dm_udev_wait
   69 #else
   70 #define CRYPT_TEMP_UDEV_FLAGS   0
   71 static int _dm_task_set_cookie(struct dm_task *dmt, uint32_t *cookie, uint16_t flags) { return 0; }
   72 static int _dm_udev_wait(uint32_t cookie) { return 0; };
   73 #endif
   74 
   75 static int _dm_use_udev(void)
   76 {
   77 #ifdef USE_UDEV /* cannot be enabled if devmapper is too old */
   78     return dm_udev_get_sync_support();
   79 #else
   80     return 0;
   81 #endif
   82 }
   83 
   84 __attribute__((format(printf, 4, 5)))
   85 static void set_dm_error(int level,
   86              const char *file __attribute__((unused)),
   87              int line __attribute__((unused)),
   88              const char *f, ...)
   89 {
   90     char *msg = NULL;
   91     va_list va;
   92 
   93     va_start(va, f);
   94     if (vasprintf(&msg, f, va) > 0) {
   95         if (level < 4 && !_quiet_log) {
   96             log_err(_context, "%s", msg);
   97         } else {
   98             /* We do not use DM visual stack backtrace here */
   99             if (strncmp(msg, "<backtrace>", 11))
  100                 log_dbg(_context, "%s", msg);
  101         }
  102     }
  103     free(msg);
  104     va_end(va);
  105 }
  106 
  107 static int _dm_satisfies_version(unsigned target_maj, unsigned target_min, unsigned target_patch,
  108                  unsigned actual_maj, unsigned actual_min, unsigned actual_patch)
  109 {
  110     if (actual_maj > target_maj)
  111         return 1;
  112 
  113     if (actual_maj == target_maj && actual_min > target_min)
  114         return 1;
  115 
  116     if (actual_maj == target_maj && actual_min == target_min && actual_patch >= target_patch)
  117         return 1;
  118 
  119     return 0;
  120 }
  121 
  122 static void _dm_set_crypt_compat(struct crypt_device *cd,
  123                  unsigned crypt_maj,
  124                  unsigned crypt_min,
  125                  unsigned crypt_patch)
  126 {
  127     if (_dm_crypt_checked || crypt_maj == 0)
  128         return;
  129 
  130     log_dbg(cd, "Detected dm-crypt version %i.%i.%i.",
  131         crypt_maj, crypt_min, crypt_patch);
  132 
  133     if (_dm_satisfies_version(1, 2, 0, crypt_maj, crypt_min, crypt_patch))
  134         _dm_flags |= DM_KEY_WIPE_SUPPORTED;
  135     else
  136         log_dbg(cd, "Suspend and resume disabled, no wipe key support.");
  137 
  138     if (_dm_satisfies_version(1, 10, 0, crypt_maj, crypt_min, crypt_patch))
  139         _dm_flags |= DM_LMK_SUPPORTED;
  140 
  141     /* not perfect, 2.6.33 supports with 1.7.0 */
  142     if (_dm_satisfies_version(1, 8, 0, crypt_maj, crypt_min, crypt_patch))
  143         _dm_flags |= DM_PLAIN64_SUPPORTED;
  144 
  145     if (_dm_satisfies_version(1, 11, 0, crypt_maj, crypt_min, crypt_patch))
  146         _dm_flags |= DM_DISCARDS_SUPPORTED;
  147 
  148     if (_dm_satisfies_version(1, 13, 0, crypt_maj, crypt_min, crypt_patch))
  149         _dm_flags |= DM_TCW_SUPPORTED;
  150 
  151     if (_dm_satisfies_version(1, 14, 0, crypt_maj, crypt_min, crypt_patch)) {
  152         _dm_flags |= DM_SAME_CPU_CRYPT_SUPPORTED;
  153         _dm_flags |= DM_SUBMIT_FROM_CRYPT_CPUS_SUPPORTED;
  154     }
  155 
  156     if (_dm_satisfies_version(1, 18, 1, crypt_maj, crypt_min, crypt_patch))
  157         _dm_flags |= DM_KERNEL_KEYRING_SUPPORTED;
  158 
  159     if (_dm_satisfies_version(1, 17, 0, crypt_maj, crypt_min, crypt_patch)) {
  160         _dm_flags |= DM_SECTOR_SIZE_SUPPORTED;
  161         _dm_flags |= DM_CAPI_STRING_SUPPORTED;
  162     }
  163 
  164     if (_dm_satisfies_version(1, 19, 0, crypt_maj, crypt_min, crypt_patch))
  165         _dm_flags |= DM_BITLK_EBOIV_SUPPORTED;
  166 
  167     if (_dm_satisfies_version(1, 20, 0, crypt_maj, crypt_min, crypt_patch))
  168         _dm_flags |= DM_BITLK_ELEPHANT_SUPPORTED;
  169 
  170     if (_dm_satisfies_version(1, 22, 0, crypt_maj, crypt_min, crypt_patch))
  171         _dm_flags |= DM_CRYPT_NO_WORKQUEUE_SUPPORTED;
  172 
  173     _dm_crypt_checked = true;
  174 }
  175 
  176 static void _dm_set_verity_compat(struct crypt_device *cd,
  177                   unsigned verity_maj,
  178                   unsigned verity_min,
  179                   unsigned verity_patch)
  180 {
  181     if (_dm_verity_checked || verity_maj == 0)
  182         return;
  183 
  184     log_dbg(cd, "Detected dm-verity version %i.%i.%i.",
  185         verity_maj, verity_min, verity_patch);
  186 
  187     _dm_flags |= DM_VERITY_SUPPORTED;
  188 
  189     /*
  190      * ignore_corruption, restart_on corruption is available since 1.2 (kernel 4.1)
  191      * ignore_zero_blocks since 1.3 (kernel 4.5)
  192      * (but some dm-verity targets 1.2 don't support it)
  193      * FEC is added in 1.3 as well.
  194      * Check at most once is added in 1.4 (kernel 4.17).
  195      */
  196     if (_dm_satisfies_version(1, 3, 0, verity_maj, verity_min, verity_patch)) {
  197         _dm_flags |= DM_VERITY_ON_CORRUPTION_SUPPORTED;
  198         _dm_flags |= DM_VERITY_FEC_SUPPORTED;
  199     }
  200 
  201     if (_dm_satisfies_version(1, 5, 0, verity_maj, verity_min, verity_patch))
  202         _dm_flags |= DM_VERITY_SIGNATURE_SUPPORTED;
  203 
  204     if (_dm_satisfies_version(1, 7, 0, verity_maj, verity_min, verity_patch))
  205         _dm_flags |= DM_VERITY_PANIC_CORRUPTION_SUPPORTED;
  206 
  207     _dm_verity_checked = true;
  208 }
  209 
  210 static void _dm_set_integrity_compat(struct crypt_device *cd,
  211                      unsigned integrity_maj,
  212                      unsigned integrity_min,
  213                      unsigned integrity_patch)
  214 {
  215     if (_dm_integrity_checked || integrity_maj == 0)
  216         return;
  217 
  218     log_dbg(cd, "Detected dm-integrity version %i.%i.%i.",
  219         integrity_maj, integrity_min, integrity_patch);
  220 
  221     _dm_flags |= DM_INTEGRITY_SUPPORTED;
  222 
  223     if (_dm_satisfies_version(1, 2, 0, integrity_maj, integrity_min, integrity_patch))
  224         _dm_flags |= DM_INTEGRITY_RECALC_SUPPORTED;
  225 
  226     if (_dm_satisfies_version(1, 3, 0, integrity_maj, integrity_min, integrity_patch))
  227         _dm_flags |= DM_INTEGRITY_BITMAP_SUPPORTED;
  228 
  229     if (_dm_satisfies_version(1, 4, 0, integrity_maj, integrity_min, integrity_patch))
  230         _dm_flags |= DM_INTEGRITY_FIX_PADDING_SUPPORTED;
  231 
  232     if (_dm_satisfies_version(1, 6, 0, integrity_maj, integrity_min, integrity_patch))
  233         _dm_flags |= DM_INTEGRITY_DISCARDS_SUPPORTED;
  234 
  235     if (_dm_satisfies_version(1, 7, 0, integrity_maj, integrity_min, integrity_patch))
  236         _dm_flags |= DM_INTEGRITY_FIX_HMAC_SUPPORTED;
  237 
  238     if (_dm_satisfies_version(1, 8, 0, integrity_maj, integrity_min, integrity_patch))
  239         _dm_flags |= DM_INTEGRITY_RESET_RECALC_SUPPORTED;
  240 
  241     _dm_integrity_checked = true;
  242 }
  243 
  244 /* We use this for loading target module */
  245 static void _dm_check_target(dm_target_type target_type)
  246 {
  247 #if HAVE_DECL_DM_DEVICE_GET_TARGET_VERSION
  248     struct dm_task *dmt;
  249     const char *target_name = NULL;
  250 
  251     if (!(_dm_flags & DM_GET_TARGET_VERSION_SUPPORTED))
  252         return;
  253 
  254     if (target_type == DM_CRYPT)
  255         target_name = DM_CRYPT_TARGET;
  256     else if (target_type == DM_VERITY)
  257         target_name = DM_VERITY_TARGET;
  258     else if (target_type == DM_INTEGRITY)
  259         target_name = DM_INTEGRITY_TARGET;
  260     else
  261         return;
  262 
  263     if (!(dmt = dm_task_create(DM_DEVICE_GET_TARGET_VERSION)))
  264         return;
  265 
  266     if (dm_task_set_name(dmt, target_name))
  267         dm_task_run(dmt);
  268 
  269     dm_task_destroy(dmt);
  270 #endif
  271 }
  272 
  273 static int _dm_check_versions(struct crypt_device *cd, dm_target_type target_type)
  274 {
  275     struct dm_task *dmt;
  276     struct dm_versions *target, *last_target;
  277     char dm_version[16];
  278     unsigned dm_maj, dm_min, dm_patch;
  279     int r = 0;
  280 
  281     if ((target_type == DM_CRYPT     && _dm_crypt_checked) ||
  282         (target_type == DM_VERITY    && _dm_verity_checked) ||
  283         (target_type == DM_INTEGRITY && _dm_integrity_checked) ||
  284         (target_type == DM_LINEAR) || (target_type == DM_ZERO) ||
  285         (_dm_crypt_checked && _dm_verity_checked && _dm_integrity_checked))
  286         return 1;
  287 
  288     /* Shut up DM while checking */
  289     _quiet_log = 1;
  290 
  291     _dm_check_target(target_type);
  292 
  293     if (!(dmt = dm_task_create(DM_DEVICE_LIST_VERSIONS)))
  294         goto out;
  295 
  296     if (!dm_task_run(dmt))
  297         goto out;
  298 
  299     if (!dm_task_get_driver_version(dmt, dm_version, sizeof(dm_version)))
  300         goto out;
  301 
  302     if (!_dm_ioctl_checked) {
  303         if (sscanf(dm_version, "%u.%u.%u", &dm_maj, &dm_min, &dm_patch) != 3)
  304             goto out;
  305         log_dbg(cd, "Detected dm-ioctl version %u.%u.%u.", dm_maj, dm_min, dm_patch);
  306 
  307         if (_dm_satisfies_version(4, 20, 0, dm_maj, dm_min, dm_patch))
  308             _dm_flags |= DM_SECURE_SUPPORTED;
  309 #if HAVE_DECL_DM_TASK_DEFERRED_REMOVE
  310         if (_dm_satisfies_version(4, 27, 0, dm_maj, dm_min, dm_patch))
  311             _dm_flags |= DM_DEFERRED_SUPPORTED;
  312 #endif
  313 #if HAVE_DECL_DM_DEVICE_GET_TARGET_VERSION
  314         if (_dm_satisfies_version(4, 41, 0, dm_maj, dm_min, dm_patch))
  315             _dm_flags |= DM_GET_TARGET_VERSION_SUPPORTED;
  316 #endif
  317     }
  318 
  319     target = dm_task_get_versions(dmt);
  320     do {
  321         last_target = target;
  322         if (!strcmp(DM_CRYPT_TARGET, target->name)) {
  323             _dm_set_crypt_compat(cd, (unsigned)target->version[0],
  324                          (unsigned)target->version[1],
  325                          (unsigned)target->version[2]);
  326         } else if (!strcmp(DM_VERITY_TARGET, target->name)) {
  327             _dm_set_verity_compat(cd, (unsigned)target->version[0],
  328                           (unsigned)target->version[1],
  329                           (unsigned)target->version[2]);
  330         } else if (!strcmp(DM_INTEGRITY_TARGET, target->name)) {
  331             _dm_set_integrity_compat(cd, (unsigned)target->version[0],
  332                          (unsigned)target->version[1],
  333                          (unsigned)target->version[2]);
  334         }
  335         target = (struct dm_versions *)((char *) target + target->next);
  336     } while (last_target != target);
  337 
  338     r = 1;
  339     if (!_dm_ioctl_checked)
  340         log_dbg(cd, "Device-mapper backend running with UDEV support %sabled.",
  341             _dm_use_udev() ? "en" : "dis");
  342 
  343     _dm_ioctl_checked = true;
  344 out:
  345     if (dmt)
  346         dm_task_destroy(dmt);
  347 
  348     _quiet_log = 0;
  349     return r;
  350 }
  351 
  352 int dm_flags(struct crypt_device *cd, dm_target_type target, uint32_t *flags)
  353 {
  354     _dm_check_versions(cd, target);
  355     *flags = _dm_flags;
  356 
  357     if (target == DM_UNKNOWN &&
  358         _dm_crypt_checked && _dm_verity_checked && _dm_integrity_checked)
  359         return 0;
  360 
  361     if ((target == DM_CRYPT     && _dm_crypt_checked) ||
  362         (target == DM_VERITY    && _dm_verity_checked) ||
  363         (target == DM_INTEGRITY && _dm_integrity_checked) ||
  364         (target == DM_LINEAR) || (target == DM_ZERO)) /* nothing to check */
  365         return 0;
  366 
  367     return -ENODEV;
  368 }
  369 
  370 /* This doesn't run any kernel checks, just set up userspace libdevmapper */
  371 void dm_backend_init(struct crypt_device *cd)
  372 {
  373     if (!_dm_use_count++) {
  374         log_dbg(cd, "Initialising device-mapper backend library.");
  375         dm_log_init(set_dm_error);
  376         dm_log_init_verbose(10);
  377     }
  378 }
  379 
  380 void dm_backend_exit(struct crypt_device *cd)
  381 {
  382     if (_dm_use_count && (!--_dm_use_count)) {
  383         log_dbg(cd, "Releasing device-mapper backend.");
  384         dm_log_init_verbose(0);
  385         dm_log_init(NULL);
  386         dm_lib_release();
  387     }
  388 }
  389 
  390 /* libdevmapper is not context friendly, switch context on every DM call. */
  391 static int dm_init_context(struct crypt_device *cd, dm_target_type target)
  392 {
  393     _context = cd;
  394     if (!_dm_check_versions(cd, target)) {
  395         if (getuid() || geteuid())
  396             log_err(cd, _("Cannot initialize device-mapper, "
  397                       "running as non-root user."));
  398         else
  399             log_err(cd, _("Cannot initialize device-mapper. "
  400                       "Is dm_mod kernel module loaded?"));
  401         _context = NULL;
  402         return -ENOTSUP;
  403     }
  404     return 0;
  405 }
  406 static void dm_exit_context(void)
  407 {
  408     _context = NULL;
  409 }
  410 
  411 /* Return path to DM device */
  412 char *dm_device_path(const char *prefix, int major, int minor)
  413 {
  414     struct dm_task *dmt;
  415     const char *name;
  416     char path[PATH_MAX];
  417 
  418     if (!(dmt = dm_task_create(DM_DEVICE_STATUS)))
  419         return NULL;
  420     if (!dm_task_set_minor(dmt, minor) ||
  421         !dm_task_set_major(dmt, major) ||
  422         !dm_task_no_flush(dmt) ||
  423         !dm_task_run(dmt) ||
  424         !(name = dm_task_get_name(dmt))) {
  425         dm_task_destroy(dmt);
  426         return NULL;
  427     }
  428 
  429     if (snprintf(path, sizeof(path), "%s%s", prefix ?: "", name) < 0)
  430         path[0] = '\0';
  431 
  432     dm_task_destroy(dmt);
  433 
  434     return strdup(path);
  435 }
  436 
  437 char *dm_device_name(const char *path)
  438 {
  439     struct stat st;
  440 
  441     if (stat(path, &st) < 0 || !S_ISBLK(st.st_mode))
  442         return NULL;
  443 
  444     return dm_device_path(NULL, major(st.st_rdev), minor(st.st_rdev));
  445 }
  446 
  447 static void hex_key(char *hexkey, size_t key_size, const char *key)
  448 {
  449     unsigned i;
  450 
  451     for(i = 0; i < key_size; i++)
  452         sprintf(&hexkey[i * 2], "%02x", (unsigned char)key[i]);
  453 }
  454 
  455 static size_t int_log10(uint64_t x)
  456 {
  457     uint64_t r = 0;
  458     for (x /= 10; x > 0; x /= 10)
  459         r++;
  460     return r;
  461 }
  462 
  463 #define CLEN    64   /* 2*MAX_CIPHER_LEN */
  464 #define CLENS  "63"  /* for sscanf length + '\0' */
  465 #define CAPIL  144   /* should be enough to fit whole capi string */
  466 #define CAPIS "143"  /* for sscanf of crypto API string + 16  + \0 */
  467 
  468 static int cipher_c2dm(const char *org_c, const char *org_i, unsigned tag_size,
  469                char *c_dm, int c_dm_size,
  470                char *i_dm, int i_dm_size)
  471 {
  472     int c_size = 0, i_size = 0, i;
  473     char cipher[CLEN], mode[CLEN], iv[CLEN+1], tmp[CLEN];
  474     char capi[CAPIL];
  475 
  476     if (!c_dm || !c_dm_size || !i_dm || !i_dm_size)
  477         return -EINVAL;
  478 
  479     i = sscanf(org_c, "%" CLENS "[^-]-%" CLENS "s", cipher, tmp);
  480     if (i != 2)
  481         return -EINVAL;
  482 
  483     i = sscanf(tmp, "%" CLENS "[^-]-%" CLENS "s", mode, iv);
  484     if (i == 1) {
  485         memset(iv, 0, sizeof(iv));
  486         strncpy(iv, mode, sizeof(iv)-1);
  487         *mode = '\0';
  488         if (snprintf(capi, sizeof(capi), "%s", cipher) < 0)
  489             return -EINVAL;
  490     } else if (i == 2) {
  491         if (snprintf(capi, sizeof(capi), "%s(%s)", mode, cipher) < 0)
  492             return -EINVAL;
  493     } else
  494         return -EINVAL;
  495 
  496     if (!org_i) {
  497         /* legacy mode: CIPHER-MODE-IV*/
  498         i_size = snprintf(i_dm, i_dm_size, "%s", "");
  499         c_size = snprintf(c_dm, c_dm_size, "%s", org_c);
  500     } else if (!strcmp(org_i, "none")) {
  501         /* IV only: capi:MODE(CIPHER)-IV */
  502         i_size = snprintf(i_dm, i_dm_size, " integrity:%u:none", tag_size);
  503         c_size = snprintf(c_dm, c_dm_size, "capi:%s-%s", capi, iv);
  504     } else if (!strcmp(org_i, "aead") && !strcmp(mode, "ccm")) {
  505         /* CCM AEAD: capi:rfc4309(MODE(CIPHER))-IV */
  506         i_size = snprintf(i_dm, i_dm_size, " integrity:%u:aead", tag_size);
  507         c_size = snprintf(c_dm, c_dm_size, "capi:rfc4309(%s)-%s", capi, iv);
  508     } else if (!strcmp(org_i, "aead")) {
  509         /* AEAD: capi:MODE(CIPHER))-IV */
  510         i_size = snprintf(i_dm, i_dm_size, " integrity:%u:aead", tag_size);
  511         c_size = snprintf(c_dm, c_dm_size, "capi:%s-%s", capi, iv);
  512     } else if (!strcmp(org_i, "poly1305")) {
  513         /* POLY1305 AEAD: capi:rfc7539(MODE(CIPHER),POLY1305)-IV */
  514         i_size = snprintf(i_dm, i_dm_size, " integrity:%u:aead", tag_size);
  515         c_size = snprintf(c_dm, c_dm_size, "capi:rfc7539(%s,poly1305)-%s", capi, iv);
  516     } else {
  517         /* other AEAD: capi:authenc(<AUTH>,MODE(CIPHER))-IV */
  518         i_size = snprintf(i_dm, i_dm_size, " integrity:%u:aead", tag_size);
  519         c_size = snprintf(c_dm, c_dm_size, "capi:authenc(%s,%s)-%s", org_i, capi, iv);
  520     }
  521 
  522     if (c_size < 0 || c_size == c_dm_size)
  523         return -EINVAL;
  524     if (i_size < 0 || i_size == i_dm_size)
  525         return -EINVAL;
  526 
  527     return 0;
  528 }
  529 
  530 static int cipher_dm2c(char **org_c, char **org_i, const char *c_dm, const char *i_dm)
  531 {
  532     char cipher[CLEN], mode[CLEN], iv[CLEN], auth[CLEN];
  533     char tmp[CAPIL], dmcrypt_tmp[CAPIL*2], capi[CAPIL+1];
  534     size_t len;
  535     int i;
  536 
  537     if (!c_dm)
  538         return -EINVAL;
  539 
  540     /* legacy mode */
  541     if (strncmp(c_dm, "capi:", 4)) {
  542         if (!(*org_c = strdup(c_dm)))
  543             return -ENOMEM;
  544         *org_i = NULL;
  545         return 0;
  546     }
  547 
  548     /* modes with capi: prefix */
  549     i = sscanf(c_dm, "capi:%" CAPIS "[^-]-%" CLENS "s", tmp, iv);
  550     if (i != 2)
  551         return -EINVAL;
  552 
  553     len = strlen(tmp);
  554     if (len < 2)
  555         return -EINVAL;
  556 
  557     if (tmp[len-1] == ')')
  558         tmp[len-1] = '\0';
  559 
  560     if (sscanf(tmp, "rfc4309(%" CAPIS "s", capi) == 1) {
  561         if (!(*org_i = strdup("aead")))
  562             return -ENOMEM;
  563     } else if (sscanf(tmp, "rfc7539(%" CAPIS "[^,],%" CLENS "s", capi, auth) == 2) {
  564         if (!(*org_i = strdup(auth)))
  565             return -ENOMEM;
  566     } else if (sscanf(tmp, "authenc(%" CLENS "[^,],%" CAPIS "s", auth, capi) == 2) {
  567         if (!(*org_i = strdup(auth)))
  568             return -ENOMEM;
  569     } else {
  570         if (i_dm) {
  571             if (!(*org_i = strdup(i_dm)))
  572                 return -ENOMEM;
  573         } else
  574             *org_i = NULL;
  575         memset(capi, 0, sizeof(capi));
  576         strncpy(capi, tmp, sizeof(capi)-1);
  577     }
  578 
  579     i = sscanf(capi, "%" CLENS "[^(](%" CLENS "[^)])", mode, cipher);
  580     if (i == 2)
  581         i = snprintf(dmcrypt_tmp, sizeof(dmcrypt_tmp), "%s-%s-%s", cipher, mode, iv);
  582     else
  583         i = snprintf(dmcrypt_tmp, sizeof(dmcrypt_tmp), "%s-%s", capi, iv);
  584     if (i < 0 || (size_t)i >= sizeof(dmcrypt_tmp)) {
  585         free(*org_i);
  586         *org_i = NULL;
  587         return -EINVAL;
  588     }
  589 
  590     if (!(*org_c = strdup(dmcrypt_tmp))) {
  591         free(*org_i);
  592         *org_i = NULL;
  593         return -ENOMEM;
  594     }
  595 
  596     return 0;
  597 }
  598 
  599 static char *_uf(char *buf, size_t buf_size, const char *s, unsigned u)
  600 {
  601     size_t r = snprintf(buf, buf_size, " %s:%u", s, u);
  602     assert(r > 0 && r < buf_size);
  603     return buf;
  604 }
  605 
  606 /* https://gitlab.com/cryptsetup/cryptsetup/wikis/DMCrypt */
  607 static char *get_dm_crypt_params(const struct dm_target *tgt, uint32_t flags)
  608 {
  609     int r, max_size, null_cipher = 0, num_options = 0, keystr_len = 0;
  610     char *params = NULL, *hexkey = NULL;
  611     char sector_feature[32], features[512], integrity_dm[256], cipher_dm[256];
  612 
  613     if (!tgt)
  614         return NULL;
  615 
  616     r = cipher_c2dm(tgt->u.crypt.cipher, tgt->u.crypt.integrity, tgt->u.crypt.tag_size,
  617             cipher_dm, sizeof(cipher_dm), integrity_dm, sizeof(integrity_dm));
  618     if (r < 0)
  619         return NULL;
  620 
  621     if (flags & CRYPT_ACTIVATE_ALLOW_DISCARDS)
  622         num_options++;
  623     if (flags & CRYPT_ACTIVATE_SAME_CPU_CRYPT)
  624         num_options++;
  625     if (flags & CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS)
  626         num_options++;
  627     if (flags & CRYPT_ACTIVATE_NO_READ_WORKQUEUE)
  628         num_options++;
  629     if (flags & CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE)
  630         num_options++;
  631     if (flags & CRYPT_ACTIVATE_IV_LARGE_SECTORS)
  632         num_options++;
  633     if (tgt->u.crypt.integrity)
  634         num_options++;
  635     if (tgt->u.crypt.sector_size != SECTOR_SIZE)
  636         num_options++;
  637 
  638     if (num_options) { /* MAX length  int32 + 15 + 15 + 23 + 18 + 19 + 17 + 13 + int32 + integrity_str */
  639         r = snprintf(features, sizeof(features), " %d%s%s%s%s%s%s%s%s", num_options,
  640         (flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) ? " allow_discards" : "",
  641         (flags & CRYPT_ACTIVATE_SAME_CPU_CRYPT) ? " same_cpu_crypt" : "",
  642         (flags & CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS) ? " submit_from_crypt_cpus" : "",
  643         (flags & CRYPT_ACTIVATE_NO_READ_WORKQUEUE) ? " no_read_workqueue" : "",
  644         (flags & CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE) ? " no_write_workqueue" : "",
  645         (flags & CRYPT_ACTIVATE_IV_LARGE_SECTORS) ? " iv_large_sectors" : "",
  646         (tgt->u.crypt.sector_size != SECTOR_SIZE) ?
  647             _uf(sector_feature, sizeof(sector_feature), "sector_size", tgt->u.crypt.sector_size) : "",
  648         integrity_dm);
  649         if (r < 0 || (size_t)r >= sizeof(features))
  650             goto out;
  651     } else
  652         *features = '\0';
  653 
  654     if (crypt_is_cipher_null(cipher_dm))
  655         null_cipher = 1;
  656 
  657     if (null_cipher)
  658         hexkey = crypt_safe_alloc(2);
  659     else if (flags & CRYPT_ACTIVATE_KEYRING_KEY) {
  660         keystr_len = strlen(tgt->u.crypt.vk->key_description) + int_log10(tgt->u.crypt.vk->keylength) + 10;
  661         hexkey = crypt_safe_alloc(keystr_len);
  662     } else
  663         hexkey = crypt_safe_alloc(tgt->u.crypt.vk->keylength * 2 + 1);
  664 
  665     if (!hexkey)
  666         goto out;
  667 
  668     if (null_cipher)
  669         strncpy(hexkey, "-", 2);
  670     else if (flags & CRYPT_ACTIVATE_KEYRING_KEY) {
  671         r = snprintf(hexkey, keystr_len, ":%zu:logon:%s", tgt->u.crypt.vk->keylength, tgt->u.crypt.vk->key_description);
  672         if (r < 0 || r >= keystr_len)
  673             goto out;
  674     } else
  675         hex_key(hexkey, tgt->u.crypt.vk->keylength, tgt->u.crypt.vk->key);
  676 
  677     max_size = strlen(hexkey) + strlen(cipher_dm) +
  678            strlen(device_block_path(tgt->data_device)) +
  679            strlen(features) + 64;
  680     params = crypt_safe_alloc(max_size);
  681     if (!params)
  682         goto out;
  683 
  684     r = snprintf(params, max_size, "%s %s %" PRIu64 " %s %" PRIu64 "%s",
  685              cipher_dm, hexkey, tgt->u.crypt.iv_offset,
  686              device_block_path(tgt->data_device), tgt->u.crypt.offset,
  687              features);
  688     if (r < 0 || r >= max_size) {
  689         crypt_safe_free(params);
  690         params = NULL;
  691     }
  692 out:
  693     crypt_safe_free(hexkey);
  694     return params;
  695 }
  696 
  697 /* https://gitlab.com/cryptsetup/cryptsetup/wikis/DMVerity */
  698 static char *get_dm_verity_params(const struct dm_target *tgt, uint32_t flags)
  699 {
  700     int max_size, max_fec_size, max_verify_size, r, num_options = 0;
  701     struct crypt_params_verity *vp;
  702     char *params = NULL, *hexroot = NULL, *hexsalt = NULL;
  703     char features[256], *fec_features = NULL, *verity_verify_args = NULL;
  704 
  705     if (!tgt || !tgt->u.verity.vp)
  706         return NULL;
  707 
  708     vp = tgt->u.verity.vp;
  709 
  710     /* These flags are not compatible */
  711     if ((flags & CRYPT_ACTIVATE_RESTART_ON_CORRUPTION) &&
  712         (flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION))
  713         flags &= ~CRYPT_ACTIVATE_RESTART_ON_CORRUPTION;
  714     if ((flags & CRYPT_ACTIVATE_IGNORE_CORRUPTION) &&
  715         (flags & (CRYPT_ACTIVATE_RESTART_ON_CORRUPTION|CRYPT_ACTIVATE_PANIC_ON_CORRUPTION)))
  716         flags &= ~CRYPT_ACTIVATE_IGNORE_CORRUPTION;
  717 
  718     if (flags & CRYPT_ACTIVATE_IGNORE_CORRUPTION)
  719         num_options++;
  720     if (flags & CRYPT_ACTIVATE_RESTART_ON_CORRUPTION)
  721         num_options++;
  722     if (flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION)
  723         num_options++;
  724     if (flags & CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS)
  725         num_options++;
  726     if (flags & CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE)
  727         num_options++;
  728 
  729     max_fec_size = (tgt->u.verity.fec_device ? strlen(device_block_path(tgt->u.verity.fec_device)) : 0) + 256;
  730     fec_features = crypt_safe_alloc(max_fec_size);
  731     if (!fec_features)
  732         goto out;
  733 
  734     if (tgt->u.verity.fec_device) {  /* MAX length 21 + path + 11 + int64 + 12 + int64 + 11 + int32 */
  735         num_options += 8;
  736         r = snprintf(fec_features, max_fec_size,
  737              " use_fec_from_device %s fec_start %" PRIu64 " fec_blocks %" PRIu64 " fec_roots %" PRIu32,
  738              device_block_path(tgt->u.verity.fec_device), tgt->u.verity.fec_offset,
  739              tgt->u.verity.fec_blocks, vp->fec_roots);
  740         if (r < 0 || r >= max_fec_size)
  741             goto out;
  742     } else
  743         *fec_features = '\0';
  744 
  745     max_verify_size = (tgt->u.verity.root_hash_sig_key_desc ? strlen(tgt->u.verity.root_hash_sig_key_desc) : 0) + 32;
  746     verity_verify_args = crypt_safe_alloc(max_verify_size);
  747     if (!verity_verify_args)
  748         goto out;
  749     if (tgt->u.verity.root_hash_sig_key_desc) {  /* MAX length 24 + key_str */
  750         num_options += 2;
  751         r = snprintf(verity_verify_args, max_verify_size,
  752                 " root_hash_sig_key_desc %s", tgt->u.verity.root_hash_sig_key_desc);
  753         if (r < 0 || r >= max_verify_size)
  754             goto out;
  755     } else
  756         *verity_verify_args = '\0';
  757 
  758     if (num_options) {  /* MAX length int32 + 18 + 22 + 20 + 19 + 19 */
  759         r = snprintf(features, sizeof(features), " %d%s%s%s%s%s", num_options,
  760         (flags & CRYPT_ACTIVATE_IGNORE_CORRUPTION) ? " ignore_corruption" : "",
  761         (flags & CRYPT_ACTIVATE_RESTART_ON_CORRUPTION) ? " restart_on_corruption" : "",
  762         (flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION) ? " panic_on_corruption" : "",
  763         (flags & CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS) ? " ignore_zero_blocks" : "",
  764         (flags & CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE) ? " check_at_most_once" : "");
  765         if (r < 0 || (size_t)r >= sizeof(features))
  766             goto out;
  767     } else
  768         *features = '\0';
  769 
  770     hexroot = crypt_safe_alloc(tgt->u.verity.root_hash_size * 2 + 1);
  771     if (!hexroot)
  772         goto out;
  773     hex_key(hexroot, tgt->u.verity.root_hash_size, tgt->u.verity.root_hash);
  774 
  775     hexsalt = crypt_safe_alloc(vp->salt_size ? vp->salt_size * 2 + 1 : 2);
  776     if (!hexsalt)
  777         goto out;
  778     if (vp->salt_size)
  779         hex_key(hexsalt, vp->salt_size, vp->salt);
  780     else
  781         strncpy(hexsalt, "-", 2);
  782 
  783     max_size = strlen(hexroot) + strlen(hexsalt) +
  784            strlen(device_block_path(tgt->data_device)) +
  785            strlen(device_block_path(tgt->u.verity.hash_device)) +
  786            strlen(vp->hash_name) + strlen(features) + strlen(fec_features) + 128 +
  787            strlen(verity_verify_args);
  788 
  789     params = crypt_safe_alloc(max_size);
  790     if (!params)
  791         goto out;
  792 
  793     r = snprintf(params, max_size,
  794              "%u %s %s %u %u %" PRIu64 " %" PRIu64 " %s %s %s%s%s%s",
  795              vp->hash_type, device_block_path(tgt->data_device),
  796              device_block_path(tgt->u.verity.hash_device),
  797              vp->data_block_size, vp->hash_block_size,
  798              vp->data_size, tgt->u.verity.hash_offset,
  799              vp->hash_name, hexroot, hexsalt, features, fec_features,
  800              verity_verify_args);
  801     if (r < 0 || r >= max_size) {
  802         crypt_safe_free(params);
  803         params = NULL;
  804     }
  805 out:
  806     crypt_safe_free(fec_features);
  807     crypt_safe_free(verity_verify_args);
  808     crypt_safe_free(hexroot);
  809     crypt_safe_free(hexsalt);
  810     return params;
  811 }
  812 
  813 static char *get_dm_integrity_params(const struct dm_target *tgt, uint32_t flags)
  814 {
  815     int r, max_size, max_integrity, max_journal_integrity, max_journal_crypt, num_options = 0;
  816     char *params_out = NULL, *params, *hexkey, mode, feature[6][32];
  817     char *features, *integrity, *journal_integrity, *journal_crypt;
  818 
  819     if (!tgt)
  820         return NULL;
  821 
  822     max_integrity = (tgt->u.integrity.integrity && tgt->u.integrity.vk ? tgt->u.integrity.vk->keylength * 2 : 0) +
  823         (tgt->u.integrity.integrity ? strlen(tgt->u.integrity.integrity) : 0) + 32;
  824     max_journal_integrity = (tgt->u.integrity.journal_integrity && tgt->u.integrity.journal_integrity_key ?
  825         tgt->u.integrity.journal_integrity_key->keylength * 2 : 0) +
  826         (tgt->u.integrity.journal_integrity ? strlen(tgt->u.integrity.journal_integrity) : 0) + 32;
  827     max_journal_crypt = (tgt->u.integrity.journal_crypt && tgt->u.integrity.journal_crypt_key ?
  828         tgt->u.integrity.journal_crypt_key->keylength * 2 : 0) +
  829         (tgt->u.integrity.journal_crypt ? strlen(tgt->u.integrity.journal_crypt) : 0) + 32;
  830     max_size = strlen(device_block_path(tgt->data_device)) +
  831         (tgt->u.integrity.meta_device ? strlen(device_block_path(tgt->u.integrity.meta_device)) : 0) +
  832         max_integrity + max_journal_integrity + max_journal_crypt + 512;
  833 
  834     params = crypt_safe_alloc(max_size);
  835     features = crypt_safe_alloc(max_size);
  836     integrity = crypt_safe_alloc(max_integrity);
  837     journal_integrity = crypt_safe_alloc(max_journal_integrity);
  838     journal_crypt = crypt_safe_alloc(max_journal_crypt);
  839     if (!params || !features || !integrity || !journal_integrity || !journal_crypt)
  840         goto out;
  841 
  842     if (tgt->u.integrity.integrity) { /* MAX length 16 + str_integrity +  str_key */
  843         num_options++;
  844 
  845         if (tgt->u.integrity.vk) {
  846             hexkey = crypt_safe_alloc(tgt->u.integrity.vk->keylength * 2 + 1);
  847             if (!hexkey)
  848                 goto out;
  849             hex_key(hexkey, tgt->u.integrity.vk->keylength, tgt->u.integrity.vk->key);
  850         } else
  851             hexkey = NULL;
  852 
  853         r = snprintf(integrity, max_integrity, " internal_hash:%s%s%s",
  854              tgt->u.integrity.integrity, hexkey ? ":" : "", hexkey ?: "");
  855         crypt_safe_free(hexkey);
  856         if (r < 0 || r >= max_integrity)
  857             goto out;
  858     }
  859 
  860     if (tgt->u.integrity.journal_integrity) { /* MAX length 14 + str_journal_integrity + str_key */
  861         num_options++;
  862 
  863         if (tgt->u.integrity.journal_integrity_key) {
  864             hexkey = crypt_safe_alloc(tgt->u.integrity.journal_integrity_key->keylength * 2 + 1);
  865             if (!hexkey)
  866                 goto out;
  867             hex_key(hexkey, tgt->u.integrity.journal_integrity_key->keylength,
  868                 tgt->u.integrity.journal_integrity_key->key);
  869         } else
  870             hexkey = NULL;
  871 
  872         r = snprintf(journal_integrity, max_journal_integrity, " journal_mac:%s%s%s",
  873              tgt->u.integrity.journal_integrity, hexkey ? ":" : "", hexkey ?: "");
  874         crypt_safe_free(hexkey);
  875         if (r < 0 || r >= max_journal_integrity)
  876             goto out;
  877     }
  878 
  879     if (tgt->u.integrity.journal_crypt) { /* MAX length 15 + str_journal_crypt + str_key */
  880         num_options++;
  881 
  882         if (tgt->u.integrity.journal_crypt_key) {
  883             hexkey = crypt_safe_alloc(tgt->u.integrity.journal_crypt_key->keylength * 2 + 1);
  884             if (!hexkey)
  885                 goto out;
  886             hex_key(hexkey, tgt->u.integrity.journal_crypt_key->keylength,
  887                 tgt->u.integrity.journal_crypt_key->key);
  888         } else
  889             hexkey = NULL;
  890 
  891         r = snprintf(journal_crypt, max_journal_crypt, " journal_crypt:%s%s%s",
  892              tgt->u.integrity.journal_crypt, hexkey ? ":" : "", hexkey ?: "");
  893         crypt_safe_free(hexkey);
  894         if (r < 0 || r >= max_journal_crypt)
  895             goto out;
  896     }
  897 
  898     if (tgt->u.integrity.journal_size)
  899         num_options++;
  900     if (tgt->u.integrity.journal_watermark)
  901         num_options++;
  902     if (tgt->u.integrity.journal_commit_time)
  903         num_options++;
  904     if (tgt->u.integrity.interleave_sectors)
  905         num_options++;
  906     if (tgt->u.integrity.sector_size)
  907         num_options++;
  908     if (tgt->u.integrity.buffer_sectors)
  909         num_options++;
  910     if (tgt->u.integrity.fix_padding)
  911         num_options++;
  912     if (tgt->u.integrity.fix_hmac)
  913         num_options++;
  914     if (tgt->u.integrity.legacy_recalc)
  915         num_options++;
  916     if (tgt->u.integrity.meta_device)
  917         num_options++;
  918     if (flags & CRYPT_ACTIVATE_RECALCULATE)
  919         num_options++;
  920     if (flags & CRYPT_ACTIVATE_RECALCULATE_RESET)
  921         num_options++;
  922     if (flags & CRYPT_ACTIVATE_ALLOW_DISCARDS)
  923         num_options++;
  924 
  925     r = snprintf(features, max_size, "%d%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", num_options,
  926         tgt->u.integrity.journal_size ? _uf(feature[0], sizeof(feature[0]), /* MAX length 17 + int32 */
  927             "journal_sectors", (unsigned)(tgt->u.integrity.journal_size / SECTOR_SIZE)) : "",
  928         tgt->u.integrity.journal_watermark ? _uf(feature[1], sizeof(feature[1]), /* MAX length 19 + int32 */
  929              /* bitmap overloaded values */
  930              (flags & CRYPT_ACTIVATE_NO_JOURNAL_BITMAP) ? "sectors_per_bit" : "journal_watermark",
  931              tgt->u.integrity.journal_watermark) : "",
  932         tgt->u.integrity.journal_commit_time ? _uf(feature[2], sizeof(feature[2]), /* MAX length 23 + int32 */
  933              /* bitmap overloaded values */
  934              (flags & CRYPT_ACTIVATE_NO_JOURNAL_BITMAP) ? "bitmap_flush_interval" : "commit_time",
  935              tgt->u.integrity.journal_commit_time) : "",
  936         tgt->u.integrity.interleave_sectors ? _uf(feature[3], sizeof(feature[3]), /* MAX length 20 + int32 */
  937             "interleave_sectors", tgt->u.integrity.interleave_sectors) : "",
  938         tgt->u.integrity.sector_size ? _uf(feature[4], sizeof(feature[4]), /* MAX length 12 + int32 */
  939             "block_size", tgt->u.integrity.sector_size) : "",
  940         tgt->u.integrity.buffer_sectors ? _uf(feature[5], sizeof(feature[5]), /* MAX length 16 + int32 */
  941             "buffer_sectors", tgt->u.integrity.buffer_sectors) : "",
  942         tgt->u.integrity.integrity ? integrity : "",
  943         tgt->u.integrity.journal_integrity ? journal_integrity : "",
  944         tgt->u.integrity.journal_crypt ? journal_crypt : "",
  945         tgt->u.integrity.fix_padding ?  " fix_padding" : "", /* MAX length 12 */
  946         tgt->u.integrity.fix_hmac ?  " fix_hmac" : "", /* MAX length 9 */
  947         tgt->u.integrity.legacy_recalc ? " legacy_recalculate" : "", /* MAX length 19 */
  948         flags & CRYPT_ACTIVATE_RECALCULATE ? " recalculate" : "", /* MAX length 12 */
  949         flags & CRYPT_ACTIVATE_RECALCULATE_RESET ? " reset_recalculate" : "", /* MAX length 18 */
  950         flags & CRYPT_ACTIVATE_ALLOW_DISCARDS ? " allow_discards" : "", /* MAX length 15 */
  951         tgt->u.integrity.meta_device ? " meta_device:" : "", /* MAX length 13 + str_device */
  952         tgt->u.integrity.meta_device ? device_block_path(tgt->u.integrity.meta_device) : "");
  953     if (r < 0 || r >= max_size)
  954         goto out;
  955 
  956     if (flags & CRYPT_ACTIVATE_NO_JOURNAL_BITMAP)
  957         mode = 'B';
  958     else if (flags & CRYPT_ACTIVATE_RECOVERY)
  959         mode = 'R';
  960     else if (flags & CRYPT_ACTIVATE_NO_JOURNAL)
  961         mode = 'D';
  962     else
  963         mode = 'J';
  964 
  965     r = snprintf(params, max_size, "%s %" PRIu64 " %d %c %s",
  966              device_block_path(tgt->data_device), tgt->u.integrity.offset,
  967              tgt->u.integrity.tag_size, mode, features);
  968     if (r < 0 || r >= max_size)
  969         goto out;
  970 
  971     params_out = params;
  972 out:
  973     crypt_safe_free(features);
  974     crypt_safe_free(integrity);
  975     crypt_safe_free(journal_integrity);
  976     crypt_safe_free(journal_crypt);
  977     if (!params_out)
  978         crypt_safe_free(params);
  979 
  980     return params_out;
  981 }
  982 
  983 static char *get_dm_linear_params(const struct dm_target *tgt, uint32_t flags __attribute__((unused)))
  984 {
  985     char *params;
  986     int r;
  987     int max_size = strlen(device_block_path(tgt->data_device)) + int_log10(tgt->u.linear.offset) + 3;
  988 
  989     params = crypt_safe_alloc(max_size);
  990     if (!params)
  991         return NULL;
  992 
  993     r = snprintf(params, max_size, "%s %" PRIu64,
  994              device_block_path(tgt->data_device), tgt->u.linear.offset);
  995 
  996     if (r < 0 || r >= max_size) {
  997         crypt_safe_free(params);
  998         params = NULL;
  999     }
 1000 
 1001     return params;
 1002 }
 1003 
 1004 static char *get_dm_zero_params(const struct dm_target *tgt __attribute__((unused)), uint32_t flags __attribute__((unused)))
 1005 {
 1006     char *params = crypt_safe_alloc(1);
 1007     if (!params)
 1008         return NULL;
 1009 
 1010     params[0] = 0;
 1011     return params;
 1012 }
 1013 
 1014 /* DM helpers */
 1015 static int _dm_remove(const char *name, int udev_wait, int deferred)
 1016 {
 1017     int r = 0;
 1018     struct dm_task *dmt;
 1019     uint32_t cookie = 0;
 1020 
 1021     if (!_dm_use_udev())
 1022         udev_wait = 0;
 1023 
 1024     if (!(dmt = dm_task_create(DM_DEVICE_REMOVE)))
 1025         return 0;
 1026 
 1027     if (!dm_task_set_name(dmt, name))
 1028         goto out;
 1029 
 1030 #if HAVE_DECL_DM_TASK_RETRY_REMOVE
 1031     if (!dm_task_retry_remove(dmt))
 1032         goto out;
 1033 #endif
 1034 #if HAVE_DECL_DM_TASK_DEFERRED_REMOVE
 1035     if (deferred && !dm_task_deferred_remove(dmt))
 1036         goto out;
 1037 #endif
 1038     if (udev_wait && !_dm_task_set_cookie(dmt, &cookie, DM_UDEV_DISABLE_LIBRARY_FALLBACK))
 1039         goto out;
 1040 
 1041     r = dm_task_run(dmt);
 1042 
 1043     if (udev_wait)
 1044         (void)_dm_udev_wait(cookie);
 1045 out:
 1046     dm_task_destroy(dmt);
 1047     return r;
 1048 }
 1049 
 1050 static int _dm_simple(int task, const char *name, uint32_t dmflags)
 1051 {
 1052     int r = 0;
 1053     struct dm_task *dmt;
 1054 
 1055     if (!(dmt = dm_task_create(task)))
 1056         return 0;
 1057 
 1058     if (name && !dm_task_set_name(dmt, name))
 1059         goto out;
 1060 
 1061     if (task == DM_DEVICE_SUSPEND &&
 1062         (dmflags & DM_SUSPEND_SKIP_LOCKFS) && !dm_task_skip_lockfs(dmt))
 1063         goto out;
 1064 
 1065     if (task == DM_DEVICE_SUSPEND &&
 1066         (dmflags & DM_SUSPEND_NOFLUSH) && !dm_task_no_flush(dmt))
 1067         goto out;
 1068 
 1069     r = dm_task_run(dmt);
 1070 out:
 1071     dm_task_destroy(dmt);
 1072     return r;
 1073 }
 1074 
 1075 static int _dm_resume_device(const char *name, uint32_t flags);
 1076 
 1077 static int _error_device(const char *name, size_t size)
 1078 {
 1079     struct dm_task *dmt;
 1080     int r = 0;
 1081 
 1082     if (!(dmt = dm_task_create(DM_DEVICE_RELOAD)))
 1083         return 0;
 1084 
 1085     if (!dm_task_set_name(dmt, name))
 1086         goto out;
 1087 
 1088     if (!dm_task_add_target(dmt, UINT64_C(0), size, "error", ""))
 1089         goto out;
 1090 
 1091     if (!dm_task_set_ro(dmt))
 1092         goto out;
 1093 
 1094     if (!dm_task_no_open_count(dmt))
 1095         goto out;
 1096 
 1097     if (!dm_task_run(dmt))
 1098         goto out;
 1099 
 1100     if (_dm_resume_device(name, 0)) {
 1101         _dm_simple(DM_DEVICE_CLEAR, name, 0);
 1102         goto out;
 1103     }
 1104 
 1105     r = 1;
 1106 out:
 1107     dm_task_destroy(dmt);
 1108     return r;
 1109 }
 1110 
 1111 int dm_error_device(struct crypt_device *cd, const char *name)
 1112 {
 1113     int r;
 1114     struct crypt_dm_active_device dmd;
 1115 
 1116     if (!name)
 1117         return -EINVAL;
 1118 
 1119     if (dm_init_context(cd, DM_UNKNOWN))
 1120         return -ENOTSUP;
 1121 
 1122     if ((dm_query_device(cd, name, 0, &dmd) >= 0) && _error_device(name, dmd.size))
 1123         r = 0;
 1124     else
 1125         r = -EINVAL;
 1126 
 1127     dm_targets_free(cd, &dmd);
 1128 
 1129     dm_exit_context();
 1130 
 1131     return r;
 1132 }
 1133 
 1134 int dm_clear_device(struct crypt_device *cd, const char *name)
 1135 {
 1136     int r;
 1137 
 1138     if (!name)
 1139         return -EINVAL;
 1140 
 1141     if (dm_init_context(cd, DM_UNKNOWN))
 1142         return -ENOTSUP;
 1143 
 1144     if (_dm_simple(DM_DEVICE_CLEAR, name, 0))
 1145         r = 0;
 1146     else
 1147         r = -EINVAL;
 1148 
 1149     dm_exit_context();
 1150 
 1151     return r;
 1152 }
 1153 
 1154 int dm_remove_device(struct crypt_device *cd, const char *name, uint32_t flags)
 1155 {
 1156     struct crypt_dm_active_device dmd = {};
 1157     int r = -EINVAL;
 1158     int retries = (flags & CRYPT_DEACTIVATE_FORCE) ? RETRY_COUNT : 1;
 1159     int deferred = (flags & CRYPT_DEACTIVATE_DEFERRED) ? 1 : 0;
 1160     int error_target = 0;
 1161     uint32_t dmt_flags;
 1162 
 1163     if (!name)
 1164         return -EINVAL;
 1165 
 1166     if (dm_init_context(cd, DM_UNKNOWN))
 1167         return -ENOTSUP;
 1168 
 1169     if (deferred && !dm_flags(cd, DM_UNKNOWN, &dmt_flags) && !(dmt_flags & DM_DEFERRED_SUPPORTED)) {
 1170         log_err(cd, _("Requested deferred flag is not supported."));
 1171         dm_exit_context();
 1172         return -ENOTSUP;
 1173     }
 1174 
 1175     do {
 1176         r = _dm_remove(name, 1, deferred) ? 0 : -EINVAL;
 1177         if (--retries && r) {
 1178             log_dbg(cd, "WARNING: other process locked internal device %s, %s.",
 1179                 name, retries ? "retrying remove" : "giving up");
 1180             sleep(1);
 1181             if ((flags & CRYPT_DEACTIVATE_FORCE) && !error_target) {
 1182                 /* If force flag is set, replace device with error, read-only target.
 1183                  * it should stop processes from reading it and also removed underlying
 1184                  * device from mapping, so it is usable again.
 1185                  * Anyway, if some process try to read temporary cryptsetup device,
 1186                  * it is bug - no other process should try touch it (e.g. udev).
 1187                  */
 1188                 if (!dm_query_device(cd, name, 0, &dmd)) {
 1189                     _error_device(name, dmd.size);
 1190                     error_target = 1;
 1191                 }
 1192             }
 1193         }
 1194     } while (r == -EINVAL && retries);
 1195 
 1196     dm_task_update_nodes();
 1197     dm_exit_context();
 1198 
 1199     return r;
 1200 }
 1201 
 1202 #define UUID_LEN 37 /* 36 + \0, libuuid ... */
 1203 /*
 1204  * UUID has format: CRYPT-<devicetype>-[<uuid>-]<device name>
 1205  * CRYPT-PLAIN-name
 1206  * CRYPT-LUKS1-00000000000000000000000000000000-name
 1207  * CRYPT-TEMP-name
 1208  */
 1209 static int dm_prepare_uuid(struct crypt_device *cd, const char *name, const char *type,
 1210                 const char *uuid, char *buf, size_t buflen)
 1211 {
 1212     char *ptr, uuid2[UUID_LEN] = {0};
 1213     uuid_t uu;
 1214     int i = 0;
 1215 
 1216     /* Remove '-' chars */
 1217     if (uuid) {
 1218         if (uuid_parse(uuid, uu) < 0) {
 1219             log_dbg(cd, "Requested UUID %s has invalid format.", uuid);
 1220             return 0;
 1221         }
 1222 
 1223         for (ptr = uuid2, i = 0; i < UUID_LEN; i++)
 1224             if (uuid[i] != '-') {
 1225                 *ptr = uuid[i];
 1226                 ptr++;
 1227             }
 1228     }
 1229 
 1230     i = snprintf(buf, buflen, DM_UUID_PREFIX "%s%s%s%s%s",
 1231         type ?: "", type ? "-" : "",
 1232         uuid2[0] ? uuid2 : "", uuid2[0] ? "-" : "",
 1233         name);
 1234     if (i < 0)
 1235         return 0;
 1236 
 1237     log_dbg(cd, "DM-UUID is %s", buf);
 1238     if ((size_t)i >= buflen)
 1239         log_err(cd, _("DM-UUID for device %s was truncated."), name);
 1240 
 1241     return 1;
 1242 }
 1243 
 1244 int lookup_dm_dev_by_uuid(struct crypt_device *cd, const char *uuid, const char *type)
 1245 {
 1246     int r_udev, r;
 1247     char *c;
 1248     char dev_uuid[DM_UUID_LEN + DM_BY_ID_PREFIX_LEN] = DM_BY_ID_PREFIX;
 1249 
 1250     if (!dm_prepare_uuid(cd, "", type, uuid, dev_uuid + DM_BY_ID_PREFIX_LEN, DM_UUID_LEN))
 1251         return -EINVAL;
 1252 
 1253     c = strrchr(dev_uuid, '-');
 1254     if (!c)
 1255         return -EINVAL;
 1256 
 1257     /* cut of dm name */
 1258     *c = '\0';
 1259 
 1260     /* Either udev or sysfs can report that device is active. */
 1261     r = lookup_by_disk_id(dev_uuid);
 1262     if (r > 0)
 1263         return r;
 1264 
 1265     r_udev = r;
 1266     if (r_udev <= 0)
 1267         r = lookup_by_sysfs_uuid_field(dev_uuid + DM_BY_ID_PREFIX_LEN);
 1268 
 1269     return r == -ENOENT ? r_udev : r;
 1270 }
 1271 
 1272 static int _add_dm_targets(struct dm_task *dmt, struct crypt_dm_active_device *dmd)
 1273 {
 1274     const char *target;
 1275     struct dm_target *tgt = &dmd->segment;
 1276 
 1277     do {
 1278         switch (tgt->type) {
 1279         case DM_CRYPT:
 1280             target = DM_CRYPT_TARGET;
 1281             break;
 1282         case DM_VERITY:
 1283             target = DM_VERITY_TARGET;
 1284             break;
 1285         case DM_INTEGRITY:
 1286             target = DM_INTEGRITY_TARGET;
 1287             break;
 1288         case DM_LINEAR:
 1289             target = DM_LINEAR_TARGET;
 1290             break;
 1291         case DM_ZERO:
 1292             target = DM_ZERO_TARGET;
 1293             break;
 1294         default:
 1295             return -ENOTSUP;
 1296         }
 1297 
 1298         if (!dm_task_add_target(dmt, tgt->offset, tgt->size, target, tgt->params))
 1299             return -EINVAL;
 1300 
 1301         tgt = tgt->next;
 1302     } while (tgt);
 1303 
 1304     return 0;
 1305 }
 1306 
 1307 static void _destroy_dm_targets_params(struct crypt_dm_active_device *dmd)
 1308 {
 1309     struct dm_target *t = &dmd->segment;
 1310 
 1311     do {
 1312         crypt_safe_free(t->params);
 1313         t->params = NULL;
 1314         t = t->next;
 1315     } while (t);
 1316 }
 1317 
 1318 static int _create_dm_targets_params(struct crypt_dm_active_device *dmd)
 1319 {
 1320     int r;
 1321     struct dm_target *tgt = &dmd->segment;
 1322 
 1323     do {
 1324         if (tgt->type == DM_CRYPT)
 1325             tgt->params = get_dm_crypt_params(tgt, dmd->flags);
 1326         else if (tgt->type == DM_VERITY)
 1327             tgt->params = get_dm_verity_params(tgt, dmd->flags);
 1328         else if (tgt->type == DM_INTEGRITY)
 1329             tgt->params = get_dm_integrity_params(tgt, dmd->flags);
 1330         else if (tgt->type == DM_LINEAR)
 1331             tgt->params = get_dm_linear_params(tgt, dmd->flags);
 1332         else if (tgt->type == DM_ZERO)
 1333             tgt->params = get_dm_zero_params(tgt, dmd->flags);
 1334         else {
 1335             r = -ENOTSUP;
 1336             goto err;
 1337         }
 1338 
 1339         if (!tgt->params) {
 1340             r = -EINVAL;
 1341             goto err;
 1342         }
 1343         tgt = tgt->next;
 1344     } while (tgt);
 1345 
 1346     return 0;
 1347 err:
 1348     _destroy_dm_targets_params(dmd);
 1349     return r;
 1350 }
 1351 
 1352 static int _dm_create_device(struct crypt_device *cd, const char *name, const char *type,
 1353                  struct crypt_dm_active_device *dmd)
 1354 {
 1355     struct dm_task *dmt = NULL;
 1356     struct dm_info dmi;
 1357     char dev_uuid[DM_UUID_LEN] = {0};
 1358     int r = -EINVAL;
 1359     uint32_t cookie = 0, read_ahead = 0;
 1360     uint16_t udev_flags = DM_UDEV_DISABLE_LIBRARY_FALLBACK;
 1361 
 1362     if (dmd->flags & CRYPT_ACTIVATE_PRIVATE)
 1363         udev_flags |= CRYPT_TEMP_UDEV_FLAGS;
 1364 
 1365     /* All devices must have DM_UUID, only resize on old device is exception */
 1366     if (!dm_prepare_uuid(cd, name, type, dmd->uuid, dev_uuid, sizeof(dev_uuid)))
 1367         goto out;
 1368 
 1369     if (!(dmt = dm_task_create(DM_DEVICE_CREATE)))
 1370         goto out;
 1371 
 1372     if (!dm_task_set_name(dmt, name))
 1373         goto out;
 1374 
 1375     if (!dm_task_set_uuid(dmt, dev_uuid))
 1376         goto out;
 1377 
 1378     if (!dm_task_secure_data(dmt))
 1379         goto out;
 1380     if ((dmd->flags & CRYPT_ACTIVATE_READONLY) && !dm_task_set_ro(dmt))
 1381         goto out;
 1382 
 1383     r = _create_dm_targets_params(dmd);
 1384     if (r)
 1385         goto out;
 1386 
 1387     r = _add_dm_targets(dmt, dmd);
 1388     if (r)
 1389         goto out;
 1390 
 1391     r = -EINVAL;
 1392 
 1393 #ifdef DM_READ_AHEAD_MINIMUM_FLAG
 1394     if (device_read_ahead(dmd->segment.data_device, &read_ahead) &&
 1395         !dm_task_set_read_ahead(dmt, read_ahead, DM_READ_AHEAD_MINIMUM_FLAG))
 1396         goto out;
 1397 #endif
 1398     if (_dm_use_udev() && !_dm_task_set_cookie(dmt, &cookie, udev_flags))
 1399         goto out;
 1400 
 1401     if (!dm_task_run(dmt)) {
 1402         r = dm_status_device(cd, name);;
 1403         if (r >= 0)
 1404             r = -EEXIST;
 1405         if (r != -EEXIST && r != -ENODEV)
 1406             r = -EINVAL;
 1407         goto out;
 1408     }
 1409 
 1410     if (dm_task_get_info(dmt, &dmi))
 1411         r = 0;
 1412 
 1413     if (_dm_use_udev()) {
 1414         (void)_dm_udev_wait(cookie);
 1415         cookie = 0;
 1416     }
 1417 
 1418     if (r < 0)
 1419         _dm_remove(name, 1, 0);
 1420 
 1421 out:
 1422     if (cookie && _dm_use_udev())
 1423         (void)_dm_udev_wait(cookie);
 1424 
 1425     if (dmt)
 1426         dm_task_destroy(dmt);
 1427 
 1428     dm_task_update_nodes();
 1429 
 1430     /* If code just loaded target module, update versions */
 1431     _dm_check_versions(cd, dmd->segment.type);
 1432 
 1433     _destroy_dm_targets_params(dmd);
 1434 
 1435     return r;
 1436 }
 1437 
 1438 static int _dm_resume_device(const char *name, uint32_t dmflags)
 1439 {
 1440     struct dm_task *dmt;
 1441     int r = -EINVAL;
 1442     uint32_t cookie = 0;
 1443     uint16_t udev_flags = DM_UDEV_DISABLE_LIBRARY_FALLBACK;
 1444 
 1445     if (dmflags & DM_RESUME_PRIVATE)
 1446         udev_flags |= CRYPT_TEMP_UDEV_FLAGS;
 1447 
 1448     if (!(dmt = dm_task_create(DM_DEVICE_RESUME)))
 1449         return r;
 1450 
 1451     if (!dm_task_set_name(dmt, name))
 1452         goto out;
 1453 
 1454     if ((dmflags & DM_SUSPEND_SKIP_LOCKFS) && !dm_task_skip_lockfs(dmt))
 1455         goto out;
 1456 
 1457     if ((dmflags & DM_SUSPEND_NOFLUSH) && !dm_task_no_flush(dmt))
 1458         goto out;
 1459 
 1460     if (_dm_use_udev() && !_dm_task_set_cookie(dmt, &cookie, udev_flags))
 1461         goto out;
 1462 
 1463     if (dm_task_run(dmt))
 1464         r = 0;
 1465 out:
 1466     if (cookie && _dm_use_udev())
 1467         (void)_dm_udev_wait(cookie);
 1468 
 1469     dm_task_destroy(dmt);
 1470 
 1471     dm_task_update_nodes();
 1472 
 1473     return r;
 1474 }
 1475 
 1476 static int _dm_reload_device(struct crypt_device *cd, const char *name,
 1477                  struct crypt_dm_active_device *dmd)
 1478 {
 1479     int r = -EINVAL;
 1480     struct dm_task *dmt = NULL;
 1481     uint32_t read_ahead = 0;
 1482 
 1483     /* All devices must have DM_UUID, only resize on old device is exception */
 1484     if (!(dmt = dm_task_create(DM_DEVICE_RELOAD)))
 1485         goto out;
 1486 
 1487     if (!dm_task_set_name(dmt, name))
 1488         goto out;
 1489 
 1490     if (!dm_task_secure_data(dmt))
 1491         goto out;
 1492     if ((dmd->flags & CRYPT_ACTIVATE_READONLY) && !dm_task_set_ro(dmt))
 1493         goto out;
 1494 
 1495     r = _create_dm_targets_params(dmd);
 1496     if (r)
 1497         goto out;
 1498 
 1499     r = _add_dm_targets(dmt, dmd);
 1500     if (r)
 1501         goto out;
 1502 
 1503     r = -EINVAL;
 1504 
 1505 #ifdef DM_READ_AHEAD_MINIMUM_FLAG
 1506     if (device_read_ahead(dmd->segment.data_device, &read_ahead) &&
 1507         !dm_task_set_read_ahead(dmt, read_ahead, DM_READ_AHEAD_MINIMUM_FLAG))
 1508         goto out;
 1509 #endif
 1510 
 1511     if (dm_task_run(dmt))
 1512         r = 0;
 1513 out:
 1514     if (dmt)
 1515         dm_task_destroy(dmt);
 1516 
 1517     /* If code just loaded target module, update versions */
 1518     _dm_check_versions(cd, dmd->segment.type);
 1519 
 1520     _destroy_dm_targets_params(dmd);
 1521 
 1522     return r;
 1523 }
 1524 
 1525 static void crypt_free_verity_params(struct crypt_params_verity *vp)
 1526 {
 1527     if (!vp)
 1528         return;
 1529 
 1530     free(CONST_CAST(void*)vp->hash_name);
 1531     free(CONST_CAST(void*)vp->data_device);
 1532     free(CONST_CAST(void*)vp->hash_device);
 1533     free(CONST_CAST(void*)vp->fec_device);
 1534     free(CONST_CAST(void*)vp->salt);
 1535     free(vp);
 1536 }
 1537 
 1538 static void _dm_target_free_query_path(struct crypt_device *cd, struct dm_target *tgt)
 1539 {
 1540     switch(tgt->type) {
 1541     case DM_CRYPT:
 1542         crypt_free_volume_key(tgt->u.crypt.vk);
 1543         free(CONST_CAST(void*)tgt->u.crypt.cipher);
 1544         break;
 1545     case DM_INTEGRITY:
 1546         free(CONST_CAST(void*)tgt->u.integrity.integrity);
 1547         crypt_free_volume_key(tgt->u.integrity.vk);
 1548 
 1549         free(CONST_CAST(void*)tgt->u.integrity.journal_integrity);
 1550         crypt_free_volume_key(tgt->u.integrity.journal_integrity_key);
 1551 
 1552         free(CONST_CAST(void*)tgt->u.integrity.journal_crypt);
 1553         crypt_free_volume_key(tgt->u.integrity.journal_crypt_key);
 1554 
 1555         device_free(cd, tgt->u.integrity.meta_device);
 1556         break;
 1557     case DM_VERITY:
 1558         crypt_free_verity_params(tgt->u.verity.vp);
 1559         device_free(cd, tgt->u.verity.hash_device);
 1560         free(CONST_CAST(void*)tgt->u.verity.root_hash);
 1561         free(CONST_CAST(void*)tgt->u.verity.root_hash_sig_key_desc);
 1562         /* fall through */
 1563     case DM_LINEAR:
 1564         /* fall through */
 1565     case DM_ERROR:
 1566         /* fall through */
 1567     case DM_ZERO:
 1568         break;
 1569     default:
 1570         log_err(cd, _("Unknown dm target type."));
 1571         return;
 1572     }
 1573 
 1574     device_free(cd, tgt->data_device);
 1575 }
 1576 
 1577 static void _dm_target_erase(struct crypt_device *cd, struct dm_target *tgt)
 1578 {
 1579     if (tgt->direction == TARGET_QUERY)
 1580         _dm_target_free_query_path(cd, tgt);
 1581 
 1582     if (tgt->type == DM_CRYPT)
 1583         free(CONST_CAST(void*)tgt->u.crypt.integrity);
 1584 }
 1585 
 1586 void dm_targets_free(struct crypt_device *cd, struct crypt_dm_active_device *dmd)
 1587 {
 1588     struct dm_target *t = &dmd->segment, *next = t->next;
 1589 
 1590     _dm_target_erase(cd, t);
 1591 
 1592     while (next) {
 1593         t = next;
 1594         next = t->next;
 1595         _dm_target_erase(cd, t);
 1596         free(t);
 1597     }
 1598 
 1599     memset(&dmd->segment, 0, sizeof(dmd->segment));
 1600 }
 1601 
 1602 int dm_targets_allocate(struct dm_target *first, unsigned count)
 1603 {
 1604     if (!first || first->next || !count)
 1605         return -EINVAL;
 1606 
 1607     while (--count) {
 1608         first->next = crypt_zalloc(sizeof(*first));
 1609         if (!first->next)
 1610             return -ENOMEM;
 1611         first = first->next;
 1612     }
 1613 
 1614     return 0;
 1615 }
 1616 
 1617 static int check_retry(struct crypt_device *cd, uint32_t *dmd_flags, uint32_t dmt_flags)
 1618 {
 1619     int ret = 0;
 1620 
 1621     /* If discard not supported try to load without discard */
 1622     if ((*dmd_flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) &&
 1623         !(dmt_flags & DM_DISCARDS_SUPPORTED)) {
 1624         log_dbg(cd, "Discard/TRIM is not supported");
 1625         *dmd_flags = *dmd_flags & ~CRYPT_ACTIVATE_ALLOW_DISCARDS;
 1626         ret = 1;
 1627     }
 1628 
 1629     /* If kernel keyring is not supported load key directly in dm-crypt */
 1630     if ((*dmd_flags & CRYPT_ACTIVATE_KEYRING_KEY) &&
 1631         !(dmt_flags & DM_KERNEL_KEYRING_SUPPORTED)) {
 1632         log_dbg(cd, "dm-crypt does not support kernel keyring");
 1633         *dmd_flags = *dmd_flags & ~CRYPT_ACTIVATE_KEYRING_KEY;
 1634         ret = 1;
 1635     }
 1636 
 1637     /* Drop performance options if not supported */
 1638     if ((*dmd_flags & (CRYPT_ACTIVATE_SAME_CPU_CRYPT | CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS)) &&
 1639         !(dmt_flags & (DM_SAME_CPU_CRYPT_SUPPORTED | DM_SUBMIT_FROM_CRYPT_CPUS_SUPPORTED))) {
 1640         log_dbg(cd, "dm-crypt does not support performance options");
 1641         *dmd_flags = *dmd_flags & ~(CRYPT_ACTIVATE_SAME_CPU_CRYPT | CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS);
 1642         ret = 1;
 1643     }
 1644 
 1645     /* Drop no workqueue options if not supported */
 1646     if ((*dmd_flags & (CRYPT_ACTIVATE_NO_READ_WORKQUEUE | CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE)) &&
 1647         !(dmt_flags & DM_CRYPT_NO_WORKQUEUE_SUPPORTED)) {
 1648         log_dbg(cd, "dm-crypt does not support performance options");
 1649         *dmd_flags = *dmd_flags & ~(CRYPT_ACTIVATE_NO_READ_WORKQUEUE | CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE);
 1650         ret = 1;
 1651     }
 1652 
 1653     return ret;
 1654 }
 1655 
 1656 int dm_create_device(struct crypt_device *cd, const char *name,
 1657              const char *type,
 1658              struct crypt_dm_active_device *dmd)
 1659 {
 1660     uint32_t dmt_flags = 0;
 1661     int r = -EINVAL;
 1662 
 1663     if (!type || !dmd)
 1664         return -EINVAL;
 1665 
 1666     if (dm_init_context(cd, dmd->segment.type))
 1667         return -ENOTSUP;
 1668 
 1669     r = _dm_create_device(cd, name, type, dmd);
 1670 
 1671     if (r < 0 && dm_flags(cd, dmd->segment.type, &dmt_flags))
 1672         goto out;
 1673 
 1674     if (r && (dmd->segment.type == DM_CRYPT || dmd->segment.type == DM_LINEAR || dmd->segment.type == DM_ZERO) &&
 1675         check_retry(cd, &dmd->flags, dmt_flags)) {
 1676         log_dbg(cd, "Retrying open without incompatible options.");
 1677         r = _dm_create_device(cd, name, type, dmd);
 1678     }
 1679 
 1680     /*
 1681      * Print warning if activating dm-crypt cipher_null device unless it's reencryption helper or
 1682      * keyslot encryption helper device (LUKS1 cipher_null devices).
 1683      */
 1684     if (!r && !(dmd->flags & CRYPT_ACTIVATE_PRIVATE) && single_segment(dmd) && dmd->segment.type == DM_CRYPT &&
 1685         crypt_is_cipher_null(dmd->segment.u.crypt.cipher))
 1686         log_dbg(cd, "Activated dm-crypt device with cipher_null. Device is not encrypted.");
 1687 
 1688     if (r == -EINVAL &&
 1689         dmd->flags & (CRYPT_ACTIVATE_SAME_CPU_CRYPT|CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS) &&
 1690         !(dmt_flags & (DM_SAME_CPU_CRYPT_SUPPORTED|DM_SUBMIT_FROM_CRYPT_CPUS_SUPPORTED)))
 1691         log_err(cd, _("Requested dm-crypt performance options are not supported."));
 1692 
 1693     if (r == -EINVAL &&
 1694         dmd->flags & (CRYPT_ACTIVATE_NO_READ_WORKQUEUE | CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE) &&
 1695         !(dmt_flags & DM_CRYPT_NO_WORKQUEUE_SUPPORTED))
 1696         log_err(cd, _("Requested dm-crypt performance options are not supported."));
 1697 
 1698     if (r == -EINVAL && dmd->flags & (CRYPT_ACTIVATE_IGNORE_CORRUPTION|
 1699                       CRYPT_ACTIVATE_RESTART_ON_CORRUPTION|
 1700                       CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS|
 1701                       CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE) &&
 1702         !(dmt_flags & DM_VERITY_ON_CORRUPTION_SUPPORTED))
 1703         log_err(cd, _("Requested dm-verity data corruption handling options are not supported."));
 1704 
 1705     if (r == -EINVAL && dmd->flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION &&
 1706         !(dmt_flags & DM_VERITY_PANIC_CORRUPTION_SUPPORTED))
 1707         log_err(cd, _("Requested dm-verity data corruption handling options are not supported."));
 1708 
 1709     if (r == -EINVAL && dmd->segment.type == DM_VERITY &&
 1710         dmd->segment.u.verity.fec_device && !(dmt_flags & DM_VERITY_FEC_SUPPORTED))
 1711         log_err(cd, _("Requested dm-verity FEC options are not supported."));
 1712 
 1713     if (r == -EINVAL && dmd->segment.type == DM_CRYPT) {
 1714         if (dmd->segment.u.crypt.integrity && !(dmt_flags & DM_INTEGRITY_SUPPORTED))
 1715             log_err(cd, _("Requested data integrity options are not supported."));
 1716         if (dmd->segment.u.crypt.sector_size != SECTOR_SIZE && !(dmt_flags & DM_SECTOR_SIZE_SUPPORTED))
 1717             log_err(cd, _("Requested sector_size option is not supported."));
 1718     }
 1719 
 1720     if (r == -EINVAL && dmd->segment.type == DM_INTEGRITY && (dmd->flags & CRYPT_ACTIVATE_RECALCULATE) &&
 1721         !(dmt_flags & DM_INTEGRITY_RECALC_SUPPORTED))
 1722         log_err(cd, _("Requested automatic recalculation of integrity tags is not supported."));
 1723 
 1724     if (r == -EINVAL && dmd->segment.type == DM_INTEGRITY && (dmd->flags & CRYPT_ACTIVATE_RECALCULATE_RESET) &&
 1725         !(dmt_flags & DM_INTEGRITY_RESET_RECALC_SUPPORTED))
 1726         log_err(cd, _("Requested automatic recalculation of integrity tags is not supported."));
 1727 
 1728     if (r == -EINVAL && dmd->segment.type == DM_INTEGRITY && (dmd->flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) &&
 1729         !(dmt_flags & DM_INTEGRITY_DISCARDS_SUPPORTED))
 1730         log_err(cd, _("Discard/TRIM is not supported."));
 1731 
 1732     if (r == -EINVAL && dmd->segment.type == DM_INTEGRITY && (dmd->flags & CRYPT_ACTIVATE_NO_JOURNAL_BITMAP) &&
 1733         !(dmt_flags & DM_INTEGRITY_BITMAP_SUPPORTED))
 1734         log_err(cd, _("Requested dm-integrity bitmap mode is not supported."));
 1735 out:
 1736     dm_exit_context();
 1737     return r;
 1738 }
 1739 
 1740 int dm_reload_device(struct crypt_device *cd, const char *name,
 1741              struct crypt_dm_active_device *dmd, uint32_t dmflags, unsigned resume)
 1742 {
 1743     int r;
 1744     uint32_t dmt_flags;
 1745 
 1746     if (!dmd)
 1747         return -EINVAL;
 1748 
 1749     if (dm_init_context(cd, dmd->segment.type))
 1750         return -ENOTSUP;
 1751 
 1752     if (dm_flags(cd, DM_INTEGRITY, &dmt_flags) || !(dmt_flags & DM_INTEGRITY_RECALC_SUPPORTED))
 1753         dmd->flags &= ~CRYPT_ACTIVATE_RECALCULATE;
 1754 
 1755     r = _dm_reload_device(cd, name, dmd);
 1756 
 1757     if (r == -EINVAL && (dmd->segment.type == DM_CRYPT || dmd->segment.type == DM_LINEAR)) {
 1758         if ((dmd->flags & (CRYPT_ACTIVATE_SAME_CPU_CRYPT|CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS)) &&
 1759             !dm_flags(cd, DM_CRYPT, &dmt_flags) && !(dmt_flags & (DM_SAME_CPU_CRYPT_SUPPORTED | DM_SUBMIT_FROM_CRYPT_CPUS_SUPPORTED)))
 1760             log_err(cd, _("Requested dm-crypt performance options are not supported."));
 1761         if ((dmd->flags & (CRYPT_ACTIVATE_NO_READ_WORKQUEUE | CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE)) &&
 1762             !dm_flags(cd, DM_CRYPT, &dmt_flags) && !(dmt_flags & DM_CRYPT_NO_WORKQUEUE_SUPPORTED))
 1763             log_err(cd, _("Requested dm-crypt performance options are not supported."));
 1764         if ((dmd->flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) &&
 1765             !dm_flags(cd, DM_CRYPT, &dmt_flags) && !(dmt_flags & DM_DISCARDS_SUPPORTED))
 1766             log_err(cd, _("Discard/TRIM is not supported."));
 1767         if ((dmd->flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) &&
 1768             !dm_flags(cd, DM_INTEGRITY, &dmt_flags) && !(dmt_flags & DM_INTEGRITY_DISCARDS_SUPPORTED))
 1769             log_err(cd, _("Discard/TRIM is not supported."));
 1770     }
 1771 
 1772     if (!r && resume)
 1773         r = _dm_resume_device(name, dmflags | act2dmflags(dmd->flags));
 1774 
 1775     dm_exit_context();
 1776     return r;
 1777 }
 1778 
 1779 static int dm_status_dmi(const char *name, struct dm_info *dmi,
 1780               const char *target, char **status_line)
 1781 {
 1782     struct dm_task *dmt;
 1783     uint64_t start, length;
 1784     char *target_type, *params = NULL;
 1785     int r = -EINVAL;
 1786 
 1787     if (!(dmt = dm_task_create(DM_DEVICE_STATUS)))
 1788         return r;
 1789 
 1790     if (!dm_task_no_flush(dmt))
 1791         goto out;
 1792 
 1793     if (!dm_task_set_name(dmt, name))
 1794         goto out;
 1795 
 1796     if (!dm_task_run(dmt))
 1797         goto out;
 1798 
 1799     if (!dm_task_get_info(dmt, dmi))
 1800         goto out;
 1801 
 1802     if (!dmi->exists) {
 1803         r = -ENODEV;
 1804         goto out;
 1805     }
 1806 
 1807     r = -EEXIST;
 1808     dm_get_next_target(dmt, NULL, &start, &length,
 1809                &target_type, &params);
 1810 
 1811     if (!target_type || start != 0)
 1812         goto out;
 1813 
 1814     if (target && strcmp(target_type, target))
 1815         goto out;
 1816 
 1817     /* for target == NULL check all supported */
 1818     if (!target && (strcmp(target_type, DM_CRYPT_TARGET) &&
 1819             strcmp(target_type, DM_VERITY_TARGET) &&
 1820             strcmp(target_type, DM_INTEGRITY_TARGET) &&
 1821             strcmp(target_type, DM_LINEAR_TARGET) &&
 1822             strcmp(target_type, DM_ZERO_TARGET) &&
 1823             strcmp(target_type, DM_ERROR_TARGET)))
 1824         goto out;
 1825     r = 0;
 1826 out:
 1827     if (!r && status_line && !(*status_line = strdup(params)))
 1828         r = -ENOMEM;
 1829 
 1830     dm_task_destroy(dmt);
 1831 
 1832     return r;
 1833 }
 1834 
 1835 int dm_status_device(struct crypt_device *cd, const char *name)
 1836 {
 1837     int r;
 1838     struct dm_info dmi;
 1839     struct stat st;
 1840 
 1841     /* libdevmapper is too clever and handles
 1842      * path argument differently with error.
 1843      * Fail early here if parameter is non-existent path.
 1844      */
 1845     if (strchr(name, '/') && stat(name, &st) < 0)
 1846         return -ENODEV;
 1847 
 1848     if (dm_init_context(cd, DM_UNKNOWN))
 1849         return -ENOTSUP;
 1850     r = dm_status_dmi(name, &dmi, NULL, NULL);
 1851     dm_exit_context();
 1852 
 1853     if (r < 0)
 1854         return r;
 1855 
 1856     return (dmi.open_count > 0) ? 1 : 0;
 1857 }
 1858 
 1859 int dm_status_suspended(struct crypt_device *cd, const char *name)
 1860 {
 1861     int r;
 1862     struct dm_info dmi;
 1863 
 1864     if (dm_init_context(cd, DM_UNKNOWN))
 1865         return -ENOTSUP;
 1866     r = dm_status_dmi(name, &dmi, NULL, NULL);
 1867     dm_exit_context();
 1868 
 1869     if (r < 0)
 1870         return r;
 1871 
 1872     return dmi.suspended ? 1 : 0;
 1873 }
 1874 
 1875 static int _dm_status_verity_ok(struct crypt_device *cd, const char *name)
 1876 {
 1877     int r;
 1878     struct dm_info dmi;
 1879     char *status_line = NULL;
 1880 
 1881     r = dm_status_dmi(name, &dmi, DM_VERITY_TARGET, &status_line);
 1882     if (r < 0 || !status_line) {
 1883         free(status_line);
 1884         return r;
 1885     }
 1886 
 1887     log_dbg(cd, "Verity volume %s status is %s.", name, status_line ?: "");
 1888     r = status_line[0] == 'V' ? 1 : 0;
 1889     free(status_line);
 1890 
 1891     return r;
 1892 }
 1893 
 1894 int dm_status_verity_ok(struct crypt_device *cd, const char *name)
 1895 {
 1896     int r;
 1897 
 1898     if (dm_init_context(cd, DM_VERITY))
 1899         return -ENOTSUP;
 1900     r = _dm_status_verity_ok(cd, name);
 1901     dm_exit_context();
 1902     return r;
 1903 }
 1904 
 1905 int dm_status_integrity_failures(struct crypt_device *cd, const char *name, uint64_t *count)
 1906 {
 1907     int r;
 1908     struct dm_info dmi;
 1909     char *status_line = NULL;
 1910 
 1911     if (dm_init_context(cd, DM_INTEGRITY))
 1912         return -ENOTSUP;
 1913 
 1914     r = dm_status_dmi(name, &dmi, DM_INTEGRITY_TARGET, &status_line);
 1915     if (r < 0 || !status_line) {
 1916         free(status_line);
 1917         dm_exit_context();
 1918         return r;
 1919     }
 1920 
 1921     log_dbg(cd, "Integrity volume %s failure status is %s.", name, status_line ?: "");
 1922     *count = strtoull(status_line, NULL, 10);
 1923     free(status_line);
 1924     dm_exit_context();
 1925 
 1926     return 0;
 1927 }
 1928 
 1929 /* FIXME use hex wrapper, user val wrappers for line parsing */
 1930 static int _dm_target_query_crypt(struct crypt_device *cd, uint32_t get_flags,
 1931                   char *params, struct dm_target *tgt,
 1932                   uint32_t *act_flags)
 1933 {
 1934     uint64_t val64;
 1935     char *rcipher, *rintegrity, *key_, *rdevice, *endp, buffer[3], *arg, *key_desc;
 1936     unsigned int i, val;
 1937     int r;
 1938     size_t key_size;
 1939     struct device *data_device = NULL;
 1940     char *cipher = NULL, *integrity = NULL;
 1941     struct volume_key *vk = NULL;
 1942 
 1943     tgt->type = DM_CRYPT;
 1944     tgt->direction = TARGET_QUERY;
 1945     tgt->u.crypt.sector_size = SECTOR_SIZE;
 1946 
 1947     r = -EINVAL;
 1948 
 1949     rcipher = strsep(&params, " ");
 1950     rintegrity = NULL;
 1951 
 1952     /* skip */
 1953     key_ = strsep(&params, " ");
 1954     if (!params)
 1955         goto err;
 1956     val64 = strtoull(params, &params, 10);
 1957     if (*params != ' ')
 1958         goto err;
 1959     params++;
 1960 
 1961     tgt->u.crypt.iv_offset = val64;
 1962 
 1963     /* device */
 1964     rdevice = strsep(&params, " ");
 1965     if (get_flags & DM_ACTIVE_DEVICE) {
 1966         arg = crypt_lookup_dev(rdevice);
 1967         r = device_alloc(cd, &data_device, arg);
 1968         free(arg);
 1969         if (r < 0 && r != -ENOTBLK)
 1970             goto err;
 1971     }
 1972 
 1973     r = -EINVAL;
 1974 
 1975     /*offset */
 1976     if (!params)
 1977         goto err;
 1978     val64 = strtoull(params, &params, 10);
 1979     tgt->u.crypt.offset = val64;
 1980 
 1981     tgt->u.crypt.tag_size = 0;
 1982 
 1983     /* Features section, available since crypt target version 1.11 */
 1984     if (*params) {
 1985         if (*params != ' ')
 1986             goto err;
 1987         params++;
 1988 
 1989         /* Number of arguments */
 1990         val64 = strtoull(params, &params, 10);
 1991         if (*params != ' ')
 1992             goto err;
 1993         params++;
 1994 
 1995         for (i = 0; i < val64; i++) {
 1996             if (!params)
 1997                 goto err;
 1998             arg = strsep(&params, " ");
 1999             if (!strcasecmp(arg, "allow_discards"))
 2000                 *act_flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
 2001             else if (!strcasecmp(arg, "same_cpu_crypt"))
 2002                 *act_flags |= CRYPT_ACTIVATE_SAME_CPU_CRYPT;
 2003             else if (!strcasecmp(arg, "submit_from_crypt_cpus"))
 2004                 *act_flags |= CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS;
 2005             else if (!strcasecmp(arg, "no_read_workqueue"))
 2006                 *act_flags |= CRYPT_ACTIVATE_NO_READ_WORKQUEUE;
 2007             else if (!strcasecmp(arg, "no_write_workqueue"))
 2008                 *act_flags |= CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE;
 2009             else if (!strcasecmp(arg, "iv_large_sectors"))
 2010                 *act_flags |= CRYPT_ACTIVATE_IV_LARGE_SECTORS;
 2011             else if (sscanf(arg, "integrity:%u:", &val) == 1) {
 2012                 tgt->u.crypt.tag_size = val;
 2013                 rintegrity = strchr(arg + strlen("integrity:"), ':');
 2014                 if (!rintegrity)
 2015                     goto err;
 2016                 rintegrity++;
 2017             } else if (sscanf(arg, "sector_size:%u", &val) == 1) {
 2018                 tgt->u.crypt.sector_size = val;
 2019             } else /* unknown option */
 2020                 goto err;
 2021         }
 2022 
 2023         /* All parameters should be processed */
 2024         if (params)
 2025             goto err;
 2026     }
 2027 
 2028     /* cipher */
 2029     if (get_flags & DM_ACTIVE_CRYPT_CIPHER) {
 2030         r = cipher_dm2c(CONST_CAST(char**)&cipher,
 2031                 CONST_CAST(char**)&integrity,
 2032                 rcipher, rintegrity);
 2033         if (r < 0)
 2034             goto err;
 2035     }
 2036 
 2037     r = -EINVAL;
 2038 
 2039     if (key_[0] == ':')
 2040         *act_flags |= CRYPT_ACTIVATE_KEYRING_KEY;
 2041 
 2042     if (get_flags & DM_ACTIVE_CRYPT_KEYSIZE) {
 2043         /* we will trust kernel the key_string is in expected format */
 2044         if (key_[0] == ':') {
 2045             if (sscanf(key_ + 1, "%zu", &key_size) != 1)
 2046                 goto err;
 2047         } else
 2048             key_size = strlen(key_) / 2;
 2049 
 2050         vk = crypt_alloc_volume_key(key_size, NULL);
 2051         if (!vk) {
 2052             r = -ENOMEM;
 2053             goto err;
 2054         }
 2055 
 2056         if (get_flags & DM_ACTIVE_CRYPT_KEY) {
 2057             if (key_[0] == ':') {
 2058                 /* :<key_size>:<key_type>:<key_description> */
 2059                 key_desc = NULL;
 2060                 endp = strpbrk(key_ + 1, ":");
 2061                 if (endp)
 2062                     key_desc = strpbrk(endp + 1, ":");
 2063                 if (!key_desc) {
 2064                     r = -ENOMEM;
 2065                     goto err;
 2066                 }
 2067                 key_desc++;
 2068                 crypt_volume_key_set_description(vk, key_desc);
 2069             } else {
 2070                 buffer[2] = '\0';
 2071                 for(i = 0; i < vk->keylength; i++) {
 2072                     memcpy(buffer, &key_[i * 2], 2);
 2073                     vk->key[i] = strtoul(buffer, &endp, 16);
 2074                     if (endp != &buffer[2]) {
 2075                         r = -EINVAL;
 2076                         goto err;
 2077                     }
 2078                 }
 2079             }
 2080         }
 2081     }
 2082     memset(key_, 0, strlen(key_));
 2083 
 2084     if (cipher)
 2085         tgt->u.crypt.cipher = cipher;
 2086     if (integrity)
 2087         tgt->u.crypt.integrity = integrity;
 2088     if (data_device)
 2089         tgt->data_device = data_device;
 2090     if (vk)
 2091         tgt->u.crypt.vk = vk;
 2092     return 0;
 2093 err:
 2094     free(cipher);
 2095     free(integrity);
 2096     device_free(cd, data_device);
 2097     crypt_free_volume_key(vk);
 2098     return r;
 2099 }
 2100 
 2101 static int _dm_target_query_verity(struct crypt_device *cd,
 2102                    uint32_t get_flags,
 2103                        char *params,
 2104                        struct dm_target *tgt,
 2105                    uint32_t *act_flags)
 2106 {
 2107     struct crypt_params_verity *vp = NULL;
 2108     uint32_t val32;
 2109     uint64_t val64;
 2110     ssize_t len;
 2111     char *str, *str2, *arg;
 2112     unsigned int i, features;
 2113     int r;
 2114     struct device *data_device = NULL, *hash_device = NULL, *fec_device = NULL;
 2115     char *hash_name = NULL, *root_hash = NULL, *salt = NULL, *fec_dev_str = NULL;
 2116     char *root_hash_sig_key_desc = NULL;
 2117 
 2118     if (get_flags & DM_ACTIVE_VERITY_PARAMS) {
 2119         vp = crypt_zalloc(sizeof(*vp));
 2120         if (!vp)
 2121             return -ENOMEM;
 2122     }
 2123 
 2124     tgt->type = DM_VERITY;
 2125     tgt->direction = TARGET_QUERY;
 2126     tgt->u.verity.vp = vp;
 2127 
 2128     /* version */
 2129     val32 = strtoul(params, &params, 10);
 2130     if (*params != ' ')
 2131         return -EINVAL;
 2132     if (vp)
 2133         vp->hash_type = val32;
 2134     params++;
 2135 
 2136     /* data device */
 2137     str = strsep(&params, " ");
 2138     if (!params)
 2139         return -EINVAL;
 2140     if (get_flags & DM_ACTIVE_DEVICE) {
 2141         str2 = crypt_lookup_dev(str);
 2142         r = device_alloc(cd, &data_device, str2);
 2143         free(str2);
 2144         if (r < 0 && r != -ENOTBLK)
 2145             return r;
 2146     }
 2147 
 2148     r = -EINVAL;
 2149 
 2150     /* hash device */
 2151     str = strsep(&params, " ");
 2152     if (!params)
 2153         goto err;
 2154     if (get_flags & DM_ACTIVE_VERITY_HASH_DEVICE) {
 2155         str2 = crypt_lookup_dev(str);
 2156         r = device_alloc(cd, &hash_device, str2);
 2157         free(str2);
 2158         if (r < 0 && r != -ENOTBLK)
 2159             goto err;
 2160     }
 2161 
 2162     r = -EINVAL;
 2163 
 2164     /* data block size*/
 2165     val32 = strtoul(params, &params, 10);
 2166     if (*params != ' ')
 2167         goto err;
 2168     if (vp)
 2169         vp->data_block_size = val32;
 2170     params++;
 2171 
 2172     /* hash block size */
 2173     val32 = strtoul(params, &params, 10);
 2174     if (*params != ' ')
 2175         goto err;
 2176     if (vp)
 2177         vp->hash_block_size = val32;
 2178     params++;
 2179 
 2180     /* data blocks */
 2181     val64 = strtoull(params, &params, 10);
 2182     if (*params != ' ')
 2183         goto err;
 2184     if (vp)
 2185         vp->data_size = val64;
 2186     params++;
 2187 
 2188     /* hash start */
 2189     val64 = strtoull(params, &params, 10);
 2190     if (*params != ' ')
 2191         goto err;
 2192     tgt->u.verity.hash_offset = val64;
 2193     params++;
 2194 
 2195     /* hash algorithm */
 2196     str = strsep(&params, " ");
 2197     if (!params)
 2198         goto err;
 2199     if (vp) {
 2200         hash_name = strdup(str);
 2201         if (!hash_name) {
 2202             r = -ENOMEM;
 2203             goto err;
 2204         }
 2205     }
 2206 
 2207     /* root digest */
 2208     str = strsep(&params, " ");
 2209     if (!params)
 2210         goto err;
 2211     len = crypt_hex_to_bytes(str, &str2, 0);
 2212     if (len < 0) {
 2213         r = len;
 2214         goto err;
 2215     }
 2216     tgt->u.verity.root_hash_size = len;
 2217     if (get_flags & DM_ACTIVE_VERITY_ROOT_HASH)
 2218         root_hash = str2;
 2219     else
 2220         free(str2);
 2221 
 2222     /* salt */
 2223     str = strsep(&params, " ");
 2224     if (vp) {
 2225         if (!strcmp(str, "-")) {
 2226             vp->salt_size = 0;
 2227             vp->salt = NULL;
 2228         } else {
 2229             len = crypt_hex_to_bytes(str, &str2, 0);
 2230             if (len < 0) {
 2231                 r = len;
 2232                 goto err;
 2233             }
 2234             vp->salt_size = len;
 2235             salt = str2;
 2236         }
 2237     }
 2238 
 2239     r = -EINVAL;
 2240 
 2241     /* Features section, available since verity target version 1.3 */
 2242     if (params) {
 2243         /* Number of arguments */
 2244         val64 = strtoull(params, &params, 10);
 2245         if (*params != ' ')
 2246             goto err;
 2247         params++;
 2248 
 2249         features = (int)val64;
 2250         for (i = 0; i < features; i++) {
 2251             r = -EINVAL;
 2252             if (!params)
 2253                 goto err;
 2254             arg = strsep(&params, " ");
 2255             if (!strcasecmp(arg, "ignore_corruption"))
 2256                 *act_flags |= CRYPT_ACTIVATE_IGNORE_CORRUPTION;
 2257             else if (!strcasecmp(arg, "restart_on_corruption"))
 2258                 *act_flags |= CRYPT_ACTIVATE_RESTART_ON_CORRUPTION;
 2259             else if (!strcasecmp(arg, "panic_on_corruption"))
 2260                 *act_flags |= CRYPT_ACTIVATE_PANIC_ON_CORRUPTION;
 2261             else if (!strcasecmp(arg, "ignore_zero_blocks"))
 2262                 *act_flags |= CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS;
 2263             else if (!strcasecmp(arg, "check_at_most_once"))
 2264                 *act_flags |= CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE;
 2265             else if (!strcasecmp(arg, "use_fec_from_device")) {
 2266                 str = strsep(&params, " ");
 2267                 str2 = crypt_lookup_dev(str);
 2268                 if (get_flags & DM_ACTIVE_VERITY_HASH_DEVICE) {
 2269                     r = device_alloc(cd, &fec_device, str2);
 2270                     if (r < 0 && r != -ENOTBLK) {
 2271                         free(str2);
 2272                         goto err;
 2273                     }
 2274                 }
 2275                 if (vp) {
 2276                     free(fec_dev_str);
 2277                     fec_dev_str = str2;
 2278                 } else
 2279                     free(str2);
 2280                 i++;
 2281             } else if (!strcasecmp(arg, "fec_start")) {
 2282                 val64 = strtoull(params, &params, 10);
 2283                 if (*params)
 2284                     params++;
 2285                 tgt->u.verity.fec_offset = val64;
 2286                 if (vp)
 2287                     vp->fec_area_offset = val64 * vp->hash_block_size;
 2288                 i++;
 2289             } else if (!strcasecmp(arg, "fec_blocks")) {
 2290                 val64 = strtoull(params, &params, 10);
 2291                 if (*params)
 2292                     params++;
 2293                 tgt->u.verity.fec_blocks = val64;
 2294                 i++;
 2295             } else if (!strcasecmp(arg, "fec_roots")) {
 2296                 val32 = strtoul(params, &params, 10);
 2297                 if (*params)
 2298                     params++;
 2299                 if (vp)
 2300                     vp->fec_roots = val32;
 2301                 i++;
 2302             } else if (!strcasecmp(arg, "root_hash_sig_key_desc")) {
 2303                 str = strsep(&params, " ");
 2304                 if (!str)
 2305                     goto err;
 2306                 if (vp && !root_hash_sig_key_desc) {
 2307                     root_hash_sig_key_desc = strdup(str);
 2308                     if (!root_hash_sig_key_desc) {
 2309                         r = -ENOMEM;
 2310                         goto err;
 2311                     }
 2312                     /* not stored in params, but cannot be used without vp */
 2313                     vp->flags |= CRYPT_VERITY_ROOT_HASH_SIGNATURE;
 2314                 }
 2315                 i++;
 2316             } else /* unknown option */
 2317                 goto err;
 2318         }
 2319 
 2320         /* All parameters should be processed */
 2321         if (params && *params) {
 2322             r = -EINVAL;
 2323             goto err;
 2324         }
 2325     }
 2326 
 2327     if (data_device)
 2328         tgt->data_device = data_device;
 2329     if (hash_device)
 2330         tgt->u.verity.hash_device = hash_device;
 2331     if (fec_device)
 2332         tgt->u.verity.fec_device = fec_device;
 2333     if (root_hash)
 2334         tgt->u.verity.root_hash = root_hash;
 2335     if (vp && hash_name)
 2336         vp->hash_name = hash_name;
 2337     if (vp && salt)
 2338         vp->salt = salt;
 2339     if (vp && fec_dev_str)
 2340         vp->fec_device = fec_dev_str;
 2341     if (root_hash_sig_key_desc)
 2342         tgt->u.verity.root_hash_sig_key_desc = root_hash_sig_key_desc;
 2343 
 2344     return 0;
 2345 err:
 2346     device_free(cd, data_device);
 2347     device_free(cd, hash_device);
 2348     device_free(cd, fec_device);
 2349     free(root_hash_sig_key_desc);
 2350     free(root_hash);
 2351     free(hash_name);
 2352     free(salt);
 2353     free(fec_dev_str);
 2354     free(vp);
 2355     return r;
 2356 }
 2357 
 2358 static int _dm_target_query_integrity(struct crypt_device *cd,
 2359                  uint32_t get_flags,
 2360                  char *params,
 2361                  struct dm_target *tgt,
 2362                  uint32_t *act_flags)
 2363 {
 2364     uint32_t val32;
 2365     uint64_t val64;
 2366     char c, *str, *str2, *arg;
 2367     unsigned int i, features, val;
 2368     ssize_t len;
 2369     int r;
 2370     struct device *data_device = NULL, *meta_device = NULL;
 2371     char *integrity = NULL, *journal_crypt = NULL, *journal_integrity = NULL;
 2372     struct volume_key *vk = NULL;
 2373 
 2374     tgt->type = DM_INTEGRITY;
 2375     tgt->direction = TARGET_QUERY;
 2376 
 2377     /* data device */
 2378     str = strsep(&params, " ");
 2379     if (get_flags & DM_ACTIVE_DEVICE) {
 2380         str2 = crypt_lookup_dev(str);
 2381         r = device_alloc(cd, &data_device, str2);
 2382         free(str2);
 2383         if (r < 0 && r != -ENOTBLK)
 2384             return r;
 2385     }
 2386 
 2387     r = -EINVAL;
 2388 
 2389     /*offset */
 2390     if (!params)
 2391         goto err;
 2392     val64 = strtoull(params, &params, 10);
 2393     if (!*params || *params != ' ')
 2394         goto err;
 2395     tgt->u.integrity.offset = val64;
 2396 
 2397     /* tag size*/
 2398     val32 = strtoul(params, &params, 10);
 2399     tgt->u.integrity.tag_size = val32;
 2400     if (!*params || *params != ' ')
 2401         goto err;
 2402 
 2403     /* journal */
 2404     c = toupper(*(++params));
 2405     if (!*params || *(++params) != ' ' || (c != 'D' && c != 'J' && c != 'R' && c != 'B'))
 2406         goto err;
 2407     if (c == 'D')
 2408         *act_flags |= CRYPT_ACTIVATE_NO_JOURNAL;
 2409     if (c == 'R')
 2410         *act_flags |= CRYPT_ACTIVATE_RECOVERY;
 2411     if (c == 'B') {
 2412         *act_flags |= CRYPT_ACTIVATE_NO_JOURNAL;
 2413         *act_flags |= CRYPT_ACTIVATE_NO_JOURNAL_BITMAP;
 2414     }
 2415 
 2416     tgt->u.integrity.sector_size = SECTOR_SIZE;
 2417 
 2418     /* Features section */
 2419     if (params) {
 2420         /* Number of arguments */
 2421         val64 = strtoull(params, &params, 10);
 2422         if (*params != ' ')
 2423             goto err;
 2424         params++;
 2425 
 2426         features = (int)val64;
 2427         for (i = 0; i < features; i++) {
 2428             r = -EINVAL;
 2429             if (!params)
 2430                 goto err;
 2431             arg = strsep(&params, " ");
 2432             if (sscanf(arg, "journal_sectors:%u", &val) == 1)
 2433                 tgt->u.integrity.journal_size = val * SECTOR_SIZE;
 2434             else if (sscanf(arg, "journal_watermark:%u", &val) == 1)
 2435                 tgt->u.integrity.journal_watermark = val;
 2436             else if (sscanf(arg, "sectors_per_bit:%" PRIu64, &val64) == 1) {
 2437                 if (val64 > UINT_MAX)
 2438                     goto err;
 2439                 /* overloaded value for bitmap mode */
 2440                 tgt->u.integrity.journal_watermark = (unsigned int)val64;
 2441             } else if (sscanf(arg, "commit_time:%u", &val) == 1)
 2442                 tgt->u.integrity.journal_commit_time = val;
 2443             else if (sscanf(arg, "bitmap_flush_interval:%u", &val) == 1)
 2444                 /* overloaded value for bitmap mode */
 2445                 tgt->u.integrity.journal_commit_time = val;
 2446             else if (sscanf(arg, "interleave_sectors:%u", &val) == 1)
 2447                 tgt->u.integrity.interleave_sectors = val;
 2448             else if (sscanf(arg, "block_size:%u", &val) == 1)
 2449                 tgt->u.integrity.sector_size = val;
 2450             else if (sscanf(arg, "buffer_sectors:%u", &val) == 1)
 2451                 tgt->u.integrity.buffer_sectors = val;
 2452             else if (!strncmp(arg, "internal_hash:", 14) && !integrity) {
 2453                 str = &arg[14];
 2454                 arg = strsep(&str, ":");
 2455                 if (get_flags & DM_ACTIVE_INTEGRITY_PARAMS) {
 2456                     integrity = strdup(arg);
 2457                     if (!integrity) {
 2458                         r = -ENOMEM;
 2459                         goto err;
 2460                     }
 2461                 }
 2462 
 2463                 if (str) {
 2464                     len = crypt_hex_to_bytes(str, &str2, 1);
 2465                     if (len < 0) {
 2466                         r = len;
 2467                         goto err;
 2468                     }
 2469 
 2470                     r = 0;
 2471                     if (get_flags & DM_ACTIVE_CRYPT_KEY) {
 2472                         vk = crypt_alloc_volume_key(len, str2);
 2473                         if (!vk)
 2474                             r = -ENOMEM;
 2475                     } else if (get_flags & DM_ACTIVE_CRYPT_KEYSIZE) {
 2476                         vk = crypt_alloc_volume_key(len, NULL);
 2477                         if (!vk)
 2478                             r = -ENOMEM;
 2479                     }
 2480                     crypt_safe_free(str2);
 2481                     if (r < 0)
 2482                         goto err;
 2483                 }
 2484             } else if (!strncmp(arg, "meta_device:", 12) && !meta_device) {
 2485                 if (get_flags & DM_ACTIVE_DEVICE) {
 2486                     str = crypt_lookup_dev(&arg[12]);
 2487                     r = device_alloc(cd, &meta_device, str);
 2488                     free(str);
 2489                     if (r < 0 && r != -ENOTBLK)
 2490                         goto err;
 2491                 }
 2492             } else if (!strncmp(arg, "journal_crypt:", 14) && !journal_crypt) {
 2493                 str = &arg[14];
 2494                 arg = strsep(&str, ":");
 2495                 if (get_flags & DM_ACTIVE_INTEGRITY_PARAMS) {
 2496                     journal_crypt = strdup(arg);
 2497                     if (!journal_crypt) {
 2498                         r = -ENOMEM;
 2499                         goto err;
 2500                     }
 2501                 }
 2502             } else if (!strncmp(arg, "journal_mac:", 12) && !journal_integrity) {
 2503                 str = &arg[12];
 2504                 arg = strsep(&str, ":");
 2505                 if (get_flags & DM_ACTIVE_INTEGRITY_PARAMS) {
 2506                     journal_integrity = strdup(arg);
 2507                     if (!journal_integrity) {
 2508                         r = -ENOMEM;
 2509                         goto err;
 2510                     }
 2511                 }
 2512             } else if (!strcmp(arg, "recalculate")) {
 2513                 *act_flags |= CRYPT_ACTIVATE_RECALCULATE;
 2514             } else if (!strcmp(arg, "reset_recalculate")) {
 2515                 *act_flags |= CRYPT_ACTIVATE_RECALCULATE_RESET;
 2516             } else if (!strcmp(arg, "fix_padding")) {
 2517                 tgt->u.integrity.fix_padding = true;
 2518             } else if (!strcmp(arg, "fix_hmac")) {
 2519                 tgt->u.integrity.fix_hmac = true;
 2520             } else if (!strcmp(arg, "legacy_recalculate")) {
 2521                 tgt->u.integrity.legacy_recalc = true;
 2522             } else if (!strcmp(arg, "allow_discards")) {
 2523                 *act_flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
 2524             } else /* unknown option */
 2525                 goto err;
 2526         }
 2527 
 2528         /* All parameters should be processed */
 2529         if (params && *params) {
 2530             r = -EINVAL;
 2531             goto err;
 2532         }
 2533     }
 2534 
 2535     if (data_device)
 2536         tgt->data_device = data_device;
 2537     if (meta_device)
 2538         tgt->u.integrity.meta_device = meta_device;
 2539     if (integrity)
 2540         tgt->u.integrity.integrity = integrity;
 2541     if (journal_crypt)
 2542         tgt->u.integrity.journal_crypt = journal_crypt;
 2543     if (journal_integrity)
 2544         tgt->u.integrity.journal_integrity = journal_integrity;
 2545     if (vk)
 2546         tgt->u.integrity.vk = vk;
 2547     return 0;
 2548 err:
 2549     device_free(cd, data_device);
 2550     device_free(cd, meta_device);
 2551     free(integrity);
 2552     free(journal_crypt);
 2553     free(journal_integrity);
 2554     crypt_free_volume_key(vk);
 2555     return r;
 2556 }
 2557 
 2558 static int _dm_target_query_linear(struct crypt_device *cd, struct dm_target *tgt,
 2559                    uint32_t get_flags, char *params)
 2560 {
 2561     uint64_t val64;
 2562     char *rdevice, *arg;
 2563     int r;
 2564     struct device *device = NULL;
 2565 
 2566     /* device */
 2567     rdevice = strsep(&params, " ");
 2568     if (get_flags & DM_ACTIVE_DEVICE) {
 2569         arg = crypt_lookup_dev(rdevice);
 2570         r = device_alloc(cd, &device, arg);
 2571         free(arg);
 2572         if (r < 0 && r != -ENOTBLK)
 2573             return r;
 2574     }
 2575 
 2576     r = -EINVAL;
 2577 
 2578     /*offset */
 2579     if (!params)
 2580         goto err;
 2581     val64 = strtoull(params, &params, 10);
 2582 
 2583     /* params should be empty now */
 2584     if (*params)
 2585         goto err;
 2586 
 2587     tgt->type = DM_LINEAR;
 2588     tgt->direction = TARGET_QUERY;
 2589     tgt->data_device = device;
 2590     tgt->u.linear.offset = val64;
 2591 
 2592     return 0;
 2593 err:
 2594     device_free(cd, device);
 2595     return r;
 2596 }
 2597 
 2598 static int _dm_target_query_error(struct crypt_device *cd __attribute__((unused)), struct dm_target *tgt)
 2599 {
 2600     tgt->type = DM_ERROR;
 2601     tgt->direction = TARGET_QUERY;
 2602 
 2603     return 0;
 2604 }
 2605 
 2606 static int _dm_target_query_zero(struct crypt_device *cd __attribute__((unused)), struct dm_target *tgt)
 2607 {
 2608     tgt->type = DM_ZERO;
 2609     tgt->direction = TARGET_QUERY;
 2610 
 2611     return 0;
 2612 }
 2613 
 2614 /*
 2615  * on error retval has to be negative
 2616  *
 2617  * also currently any _dm_target_query fn does not perform cleanup on error
 2618  */
 2619 static int dm_target_query(struct crypt_device *cd, struct dm_target *tgt, const uint64_t *start,
 2620             const uint64_t *length, const char *target_type,
 2621             char *params, uint32_t get_flags, uint32_t *act_flags)
 2622 {
 2623     int r = -ENOTSUP;
 2624 
 2625     if (!strcmp(target_type, DM_CRYPT_TARGET))
 2626         r = _dm_target_query_crypt(cd, get_flags, params, tgt, act_flags);
 2627     else if (!strcmp(target_type, DM_VERITY_TARGET))
 2628         r = _dm_target_query_verity(cd, get_flags, params, tgt, act_flags);
 2629     else if (!strcmp(target_type, DM_INTEGRITY_TARGET))
 2630         r = _dm_target_query_integrity(cd, get_flags, params, tgt, act_flags);
 2631     else if (!strcmp(target_type, DM_LINEAR_TARGET))
 2632         r = _dm_target_query_linear(cd, tgt, get_flags, params);
 2633     else if (!strcmp(target_type, DM_ERROR_TARGET))
 2634         r = _dm_target_query_error(cd, tgt);
 2635     else if (!strcmp(target_type, DM_ZERO_TARGET))
 2636         r = _dm_target_query_zero(cd, tgt);
 2637 
 2638     if (!r) {
 2639         tgt->offset = *start;
 2640         tgt->size = *length;
 2641     }
 2642 
 2643     return r;
 2644 }
 2645 
 2646 static int _dm_query_device(struct crypt_device *cd, const char *name,
 2647             uint32_t get_flags, struct crypt_dm_active_device *dmd)
 2648 {
 2649     struct dm_target *t;
 2650     struct dm_task *dmt;
 2651     struct dm_info dmi;
 2652     uint64_t start, length;
 2653     char *target_type, *params;
 2654     const char *tmp_uuid;
 2655     void *next = NULL;
 2656     int r = -EINVAL;
 2657 
 2658     t = &dmd->segment;
 2659 
 2660     if (!(dmt = dm_task_create(DM_DEVICE_TABLE)))
 2661         return r;
 2662     if (!dm_task_secure_data(dmt))
 2663         goto out;
 2664     if (!dm_task_set_name(dmt, name))
 2665         goto out;
 2666     r = -ENODEV;
 2667     if (!dm_task_run(dmt))
 2668         goto out;
 2669 
 2670     r = -EINVAL;
 2671     if (!dm_task_get_info(dmt, &dmi))
 2672         goto out;
 2673 
 2674     if (!dmi.exists) {
 2675         r = -ENODEV;
 2676         goto out;
 2677     }
 2678 
 2679     if (dmi.target_count <= 0) {
 2680         r = -EINVAL;
 2681         goto out;
 2682     }
 2683 
 2684     /* Never allow to return empty key */
 2685     if ((get_flags & DM_ACTIVE_CRYPT_KEY) && dmi.suspended) {
 2686         log_dbg(cd, "Cannot read volume key while suspended.");
 2687         r = -EINVAL;
 2688         goto out;
 2689     }
 2690 
 2691     r = dm_targets_allocate(&dmd->segment, dmi.target_count);
 2692     if (r)
 2693         goto out;
 2694 
 2695     do {
 2696         next = dm_get_next_target(dmt, next, &start, &length,
 2697                                       &target_type, &params);
 2698 
 2699         r = dm_target_query(cd, t, &start, &length, target_type, params, get_flags, &dmd->flags);
 2700         if (!r && t->type == DM_VERITY) {
 2701             r = _dm_status_verity_ok(cd, name);
 2702             if (r == 0)
 2703                 dmd->flags |= CRYPT_ACTIVATE_CORRUPTED;
 2704         }
 2705 
 2706         if (r < 0) {
 2707             if (r != -ENOTSUP)
 2708                 log_err(cd, _("Failed to query dm-%s segment."), target_type);
 2709             goto out;
 2710         }
 2711 
 2712         dmd->size += length;
 2713         t = t->next;
 2714     } while (next && t);
 2715 
 2716     if (dmi.read_only)
 2717         dmd->flags |= CRYPT_ACTIVATE_READONLY;
 2718 
 2719     if (dmi.suspended)
 2720         dmd->flags |= CRYPT_ACTIVATE_SUSPENDED;
 2721 
 2722     tmp_uuid = dm_task_get_uuid(dmt);
 2723     if (!tmp_uuid)
 2724         dmd->flags |= CRYPT_ACTIVATE_NO_UUID;
 2725     else if (get_flags & DM_ACTIVE_UUID) {
 2726         if (!strncmp(tmp_uuid, DM_UUID_PREFIX, DM_UUID_PREFIX_LEN))
 2727             dmd->uuid = strdup(tmp_uuid + DM_UUID_PREFIX_LEN);
 2728     }
 2729 
 2730     dmd->holders = 0;
 2731 #if (HAVE_DECL_DM_DEVICE_HAS_HOLDERS && HAVE_DECL_DM_DEVICE_HAS_MOUNTED_FS)
 2732     if (get_flags & DM_ACTIVE_HOLDERS)
 2733         dmd->holders = (dm_device_has_mounted_fs(dmi.major, dmi.minor) ||
 2734                 dm_device_has_holders(dmi.major, dmi.minor));
 2735 #endif
 2736 
 2737     r = (dmi.open_count > 0);
 2738 out:
 2739     dm_task_destroy(dmt);
 2740 
 2741     if (r < 0)
 2742         dm_targets_free(cd, dmd);
 2743 
 2744     return r;
 2745 }
 2746 
 2747 int dm_query_device(struct crypt_device *cd, const char *name,
 2748             uint32_t get_flags, struct crypt_dm_active_device *dmd)
 2749 {
 2750     int r;
 2751 
 2752     if (!dmd)
 2753         return -EINVAL;
 2754 
 2755     memset(dmd, 0, sizeof(*dmd));
 2756 
 2757     if (dm_init_context(cd, DM_UNKNOWN))
 2758         return -ENOTSUP;
 2759 
 2760     r = _dm_query_device(cd, name, get_flags, dmd);
 2761 
 2762     dm_exit_context();
 2763     return r;
 2764 }
 2765 
 2766 static int _process_deps(struct crypt_device *cd, const char *prefix, struct dm_deps *deps, char **names, size_t names_offset, size_t names_length)
 2767 {
 2768 #if HAVE_DECL_DM_DEVICE_GET_NAME
 2769     struct crypt_dm_active_device dmd;
 2770     char dmname[PATH_MAX];
 2771     unsigned i;
 2772     int r, major, minor, count = 0;
 2773 
 2774     if (!prefix || !deps)
 2775         return -EINVAL;
 2776 
 2777     for (i = 0; i < deps->count; i++) {
 2778         major = major(deps->device[i]);
 2779         if (!dm_is_dm_major(major))
 2780             continue;
 2781 
 2782         minor = minor(deps->device[i]);
 2783         if (!dm_device_get_name(major, minor, 0, dmname, PATH_MAX))
 2784             return -EINVAL;
 2785 
 2786         memset(&dmd, 0, sizeof(dmd));
 2787         r = _dm_query_device(cd, dmname, DM_ACTIVE_UUID, &dmd);
 2788         if (r < 0)
 2789             continue;
 2790 
 2791         if (!dmd.uuid ||
 2792             strncmp(prefix, dmd.uuid, strlen(prefix)) ||
 2793             crypt_string_in(dmname, names, names_length))
 2794             *dmname = '\0';
 2795 
 2796         dm_targets_free(cd, &dmd);
 2797         free(CONST_CAST(void*)dmd.uuid);
 2798 
 2799         if ((size_t)count >= (names_length - names_offset))
 2800             return -ENOMEM;
 2801 
 2802         if (*dmname && !(names[names_offset + count++] = strdup(dmname)))
 2803             return -ENOMEM;
 2804     }
 2805 
 2806     return count;
 2807 #else
 2808     return -EINVAL;
 2809 #endif
 2810 }
 2811 
 2812 int dm_device_deps(struct crypt_device *cd, const char *name, const char *prefix, char **names, size_t names_length)
 2813 {
 2814     struct dm_task *dmt;
 2815     struct dm_info dmi;
 2816     struct dm_deps *deps;
 2817     int r = -EINVAL;
 2818     size_t i, last = 0, offset = 0;
 2819 
 2820     if (!name || !names_length || !names)
 2821         return -EINVAL;
 2822 
 2823     if (dm_init_context(cd, DM_UNKNOWN))
 2824         return -ENOTSUP;
 2825 
 2826     while (name) {
 2827         if (!(dmt = dm_task_create(DM_DEVICE_DEPS)))
 2828             goto out;
 2829         if (!dm_task_set_name(dmt, name))
 2830             goto out;
 2831 
 2832         r = -ENODEV;
 2833         if (!dm_task_run(dmt))
 2834             goto out;
 2835 
 2836         r = -EINVAL;
 2837         if (!dm_task_get_info(dmt, &dmi))
 2838             goto out;
 2839         if (!(deps = dm_task_get_deps(dmt)))
 2840             goto out;
 2841 
 2842         r = -ENODEV;
 2843         if (!dmi.exists)
 2844             goto out;
 2845 
 2846         r = _process_deps(cd, prefix, deps, names, offset, names_length - 1);
 2847         if (r < 0)
 2848             goto out;
 2849 
 2850         dm_task_destroy(dmt);
 2851         dmt = NULL;
 2852 
 2853         offset += r;
 2854         name = names[last++];
 2855     }
 2856 
 2857     r = 0;
 2858 out:
 2859     if (r < 0) {
 2860         for (i = 0; i < names_length - 1; i++)
 2861             free(names[i]);
 2862         *names = NULL;
 2863     }
 2864 
 2865     if (dmt)
 2866         dm_task_destroy(dmt);
 2867 
 2868     dm_exit_context();
 2869     return r;
 2870 }
 2871 
 2872 static int _dm_message(const char *name, const char *msg)
 2873 {
 2874     int r = 0;
 2875     struct dm_task *dmt;
 2876 
 2877     if (!(dmt = dm_task_create(DM_DEVICE_TARGET_MSG)))
 2878         return 0;
 2879 
 2880     if (!dm_task_secure_data(dmt))
 2881         goto out;
 2882 
 2883     if (name && !dm_task_set_name(dmt, name))
 2884         goto out;
 2885 
 2886     if (!dm_task_set_sector(dmt, (uint64_t) 0))
 2887         goto out;
 2888 
 2889     if (!dm_task_set_message(dmt, msg))
 2890         goto out;
 2891 
 2892     r = dm_task_run(dmt);
 2893 out:
 2894     dm_task_destroy(dmt);
 2895     return r;
 2896 }
 2897 
 2898 int dm_suspend_device(struct crypt_device *cd, const char *name, uint32_t dmflags)
 2899 {
 2900     uint32_t dmt_flags;
 2901     int r = -ENOTSUP;
 2902 
 2903     if (dm_init_context(cd, DM_UNKNOWN))
 2904         return r;
 2905 
 2906     if (dmflags & DM_SUSPEND_WIPE_KEY) {
 2907         if (dm_flags(cd, DM_CRYPT, &dmt_flags))
 2908             goto out;
 2909 
 2910         if (!(dmt_flags & DM_KEY_WIPE_SUPPORTED))
 2911             goto out;
 2912     }
 2913 
 2914     r = -EINVAL;
 2915 
 2916     if (!_dm_simple(DM_DEVICE_SUSPEND, name, dmflags))
 2917         goto out;
 2918 
 2919     if (dmflags & DM_SUSPEND_WIPE_KEY) {
 2920         if (!_dm_message(name, "key wipe")) {
 2921             _dm_resume_device(name, 0);
 2922             goto out;
 2923         }
 2924     }
 2925 
 2926     r = 0;
 2927 out:
 2928     dm_exit_context();
 2929     return r;
 2930 }
 2931 
 2932 int dm_resume_device(struct crypt_device *cd, const char *name, uint32_t dmflags)
 2933 {
 2934     int r;
 2935 
 2936     if (dm_init_context(cd, DM_UNKNOWN))
 2937         return -ENOTSUP;
 2938 
 2939     r = _dm_resume_device(name, dmflags);
 2940 
 2941     dm_exit_context();
 2942 
 2943     return r;
 2944 }
 2945 
 2946 int dm_resume_and_reinstate_key(struct crypt_device *cd, const char *name,
 2947                 const struct volume_key *vk)
 2948 {
 2949     uint32_t dmt_flags;
 2950     int msg_size;
 2951     char *msg = NULL;
 2952     int r = -ENOTSUP;
 2953 
 2954     if (dm_init_context(cd, DM_CRYPT) || dm_flags(cd, DM_CRYPT, &dmt_flags))
 2955         return -ENOTSUP;
 2956 
 2957     if (!(dmt_flags & DM_KEY_WIPE_SUPPORTED))
 2958         goto out;
 2959 
 2960     if (!vk->keylength)
 2961         msg_size = 11; // key set -
 2962     else if (vk->key_description)
 2963         msg_size = strlen(vk->key_description) + int_log10(vk->keylength) + 18;
 2964     else
 2965         msg_size = vk->keylength * 2 + 10; // key set <key>
 2966 
 2967     msg = crypt_safe_alloc(msg_size);
 2968     if (!msg) {
 2969         r = -ENOMEM;
 2970         goto out;
 2971     }
 2972 
 2973     strcpy(msg, "key set ");
 2974     if (!vk->keylength)
 2975         snprintf(msg + 8, msg_size - 8, "-");
 2976     else if (vk->key_description)
 2977         snprintf(msg + 8, msg_size - 8, ":%zu:logon:%s", vk->keylength, vk->key_description);
 2978     else
 2979         hex_key(&msg[8], vk->keylength, vk->key);
 2980 
 2981     if (!_dm_message(name, msg) ||
 2982         _dm_resume_device(name, 0)) {
 2983         r = -EINVAL;
 2984         goto out;
 2985     }
 2986     r = 0;
 2987 out:
 2988     crypt_safe_free(msg);
 2989     dm_exit_context();
 2990     return r;
 2991 }
 2992 
 2993 int dm_cancel_deferred_removal(const char *name)
 2994 {
 2995     return _dm_message(name, "@cancel_deferred_remove") ? 0 : -ENOTSUP;
 2996 }
 2997 
 2998 const char *dm_get_dir(void)
 2999 {
 3000     return dm_dir();
 3001 }
 3002 
 3003 int dm_is_dm_device(int major)
 3004 {
 3005     return dm_is_dm_major((uint32_t)major);
 3006 }
 3007 
 3008 int dm_is_dm_kernel_name(const char *name)
 3009 {
 3010     return strncmp(name, "dm-", 3) ? 0 : 1;
 3011 }
 3012 
 3013 int dm_crypt_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
 3014     struct device *data_device, struct volume_key *vk, const char *cipher,
 3015     uint64_t iv_offset, uint64_t data_offset, const char *integrity, uint32_t tag_size,
 3016     uint32_t sector_size)
 3017 {
 3018     char *dm_integrity = NULL;
 3019 
 3020     if (tag_size) {
 3021         /* Space for IV metadata only */
 3022         dm_integrity = strdup(integrity ?: "none");
 3023         if (!dm_integrity)
 3024             return -ENOMEM;
 3025     }
 3026 
 3027     tgt->data_device = data_device;
 3028 
 3029     tgt->type = DM_CRYPT;
 3030     tgt->direction = TARGET_SET;
 3031     tgt->u.crypt.vk = vk;
 3032     tgt->offset = seg_offset;
 3033     tgt->size = seg_size;
 3034 
 3035     tgt->u.crypt.cipher = cipher;
 3036     tgt->u.crypt.integrity = dm_integrity;
 3037     tgt->u.crypt.iv_offset = iv_offset;
 3038     tgt->u.crypt.offset = data_offset;
 3039     tgt->u.crypt.tag_size = tag_size;
 3040     tgt->u.crypt.sector_size = sector_size;
 3041 
 3042     return 0;
 3043 }
 3044 
 3045 int dm_verity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
 3046     struct device *data_device, struct device *hash_device, struct device *fec_device,
 3047     const char *root_hash, uint32_t root_hash_size, const char* root_hash_sig_key_desc,
 3048     uint64_t hash_offset_block, uint64_t fec_blocks, struct crypt_params_verity *vp)
 3049 {
 3050     if (!data_device || !hash_device || !vp)
 3051         return -EINVAL;
 3052 
 3053     tgt->type = DM_VERITY;
 3054     tgt->direction = TARGET_SET;
 3055     tgt->offset = seg_offset;
 3056     tgt->size = seg_size;
 3057     tgt->data_device = data_device;
 3058 
 3059     tgt->u.verity.hash_device = hash_device;
 3060     tgt->u.verity.fec_device = fec_device;
 3061     tgt->u.verity.root_hash = root_hash;
 3062     tgt->u.verity.root_hash_size = root_hash_size;
 3063     tgt->u.verity.root_hash_sig_key_desc = root_hash_sig_key_desc;
 3064     tgt->u.verity.hash_offset = hash_offset_block;
 3065     tgt->u.verity.fec_offset = vp->fec_area_offset / vp->hash_block_size;
 3066     tgt->u.verity.fec_blocks = fec_blocks;
 3067     tgt->u.verity.vp = vp;
 3068 
 3069     return 0;
 3070 }
 3071 
 3072 int dm_integrity_target_set(struct crypt_device *cd,
 3073             struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
 3074             struct device *meta_device,
 3075                 struct device *data_device, uint64_t tag_size, uint64_t offset,
 3076             uint32_t sector_size, struct volume_key *vk,
 3077             struct volume_key *journal_crypt_key, struct volume_key *journal_mac_key,
 3078             const struct crypt_params_integrity *ip)
 3079 {
 3080     uint32_t dmi_flags;
 3081 
 3082     if (!data_device)
 3083         return -EINVAL;
 3084 
 3085     _dm_check_versions(cd, DM_INTEGRITY);
 3086 
 3087     tgt->type = DM_INTEGRITY;
 3088     tgt->direction = TARGET_SET;
 3089     tgt->offset = seg_offset;
 3090     tgt->size = seg_size;
 3091     tgt->data_device = data_device;
 3092     if (meta_device != data_device)
 3093         tgt->u.integrity.meta_device = meta_device;
 3094     tgt->u.integrity.tag_size = tag_size;
 3095     tgt->u.integrity.offset = offset;
 3096     tgt->u.integrity.sector_size = sector_size;
 3097 
 3098     tgt->u.integrity.vk = vk;
 3099     tgt->u.integrity.journal_crypt_key = journal_crypt_key;
 3100     tgt->u.integrity.journal_integrity_key = journal_mac_key;
 3101 
 3102     if (!dm_flags(cd, DM_INTEGRITY, &dmi_flags) &&
 3103         (dmi_flags & DM_INTEGRITY_FIX_PADDING_SUPPORTED) &&
 3104         !(crypt_get_compatibility(cd) & CRYPT_COMPAT_LEGACY_INTEGRITY_PADDING))
 3105         tgt->u.integrity.fix_padding = true;
 3106 
 3107     if (!dm_flags(cd, DM_INTEGRITY, &dmi_flags) &&
 3108         (dmi_flags & DM_INTEGRITY_FIX_HMAC_SUPPORTED) &&
 3109         !(crypt_get_compatibility(cd) & CRYPT_COMPAT_LEGACY_INTEGRITY_HMAC))
 3110         tgt->u.integrity.fix_hmac = true;
 3111 
 3112     /* This flag can be backported, just try to set it always */
 3113     if (crypt_get_compatibility(cd) & CRYPT_COMPAT_LEGACY_INTEGRITY_RECALC)
 3114         tgt->u.integrity.legacy_recalc = true;
 3115 
 3116     if (ip) {
 3117         tgt->u.integrity.journal_size = ip->journal_size;
 3118         tgt->u.integrity.journal_watermark = ip->journal_watermark;
 3119         tgt->u.integrity.journal_commit_time = ip->journal_commit_time;
 3120         tgt->u.integrity.interleave_sectors = ip->interleave_sectors;
 3121         tgt->u.integrity.buffer_sectors = ip->buffer_sectors;
 3122         tgt->u.integrity.journal_integrity = ip->journal_integrity;
 3123         tgt->u.integrity.journal_crypt = ip->journal_crypt;
 3124         tgt->u.integrity.integrity = ip->integrity;
 3125     }
 3126 
 3127     return 0;
 3128 }
 3129 
 3130 int dm_linear_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
 3131     struct device *data_device, uint64_t data_offset)
 3132 {
 3133     if (!data_device)
 3134         return -EINVAL;
 3135 
 3136     tgt->type = DM_LINEAR;
 3137     tgt->direction = TARGET_SET;
 3138     tgt->offset = seg_offset;
 3139     tgt->size = seg_size;
 3140     tgt->data_device = data_device;
 3141 
 3142     tgt->u.linear.offset = data_offset;
 3143 
 3144     return 0;
 3145 }
 3146 
 3147 int dm_zero_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size)
 3148 {
 3149     tgt->type = DM_ZERO;
 3150     tgt->direction = TARGET_SET;
 3151     tgt->offset = seg_offset;
 3152     tgt->size = seg_size;
 3153 
 3154     return 0;
 3155 }