2 * libdevmapper - device-mapper backend for cryptsetup
4 * Copyright (C) 2004 Jana Saout <jana@saout.de>
5 * Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
6 * Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved.
7 * Copyright (C) 2009-2023 Milan Broz
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.
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.
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.
28 #include <libdevmapper.h>
29 #include <uuid/uuid.h>
31 #ifdef HAVE_SYS_SYSMACROS_H
32 # include <sys/sysmacros.h> /* for major, minor */
36 #define DM_CRYPT_TARGET "crypt"
37 #define DM_VERITY_TARGET "verity"
38 #define DM_INTEGRITY_TARGET "integrity"
39 #define DM_LINEAR_TARGET "linear"
40 #define DM_ERROR_TARGET "error"
41 #define DM_ZERO_TARGET "zero"
44 /* Set if DM target versions were probed */
45 static bool _dm_ioctl_checked = false;
46 static bool _dm_crypt_checked = false;
47 static bool _dm_verity_checked = false;
48 static bool _dm_integrity_checked = false;
49 static bool _dm_zero_checked = false;
51 static int _quiet_log = 0;
52 static uint32_t _dm_flags = 0;
54 static struct crypt_device *_context = NULL;
55 static int _dm_use_count = 0;
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; }
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
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; };
75 static int _dm_use_udev(void)
77 #ifdef USE_UDEV /* cannot be enabled if devmapper is too old */
78 return dm_udev_get_sync_support();
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)),
94 if (vasprintf(&msg, f, va) > 0) {
95 if (level < 4 && !_quiet_log) {
96 log_err(_context, "%s", msg);
98 /* We do not use DM visual stack backtrace here */
99 if (strncmp(msg, "<backtrace>", 11))
100 log_dbg(_context, "%s", msg);
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)
110 if (actual_maj > target_maj)
113 if (actual_maj == target_maj && actual_min > target_min)
116 if (actual_maj == target_maj && actual_min == target_min && actual_patch >= target_patch)
122 static void _dm_set_crypt_compat(struct crypt_device *cd,
125 unsigned crypt_patch)
127 if (_dm_crypt_checked || crypt_maj == 0)
130 log_dbg(cd, "Detected dm-crypt version %i.%i.%i.",
131 crypt_maj, crypt_min, crypt_patch);
133 if (_dm_satisfies_version(1, 2, 0, crypt_maj, crypt_min, crypt_patch))
134 _dm_flags |= DM_KEY_WIPE_SUPPORTED;
136 log_dbg(cd, "Suspend and resume disabled, no wipe key support.");
138 if (_dm_satisfies_version(1, 10, 0, crypt_maj, crypt_min, crypt_patch))
139 _dm_flags |= DM_LMK_SUPPORTED;
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;
145 if (_dm_satisfies_version(1, 11, 0, crypt_maj, crypt_min, crypt_patch))
146 _dm_flags |= DM_DISCARDS_SUPPORTED;
148 if (_dm_satisfies_version(1, 13, 0, crypt_maj, crypt_min, crypt_patch))
149 _dm_flags |= DM_TCW_SUPPORTED;
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;
156 if (_dm_satisfies_version(1, 18, 1, crypt_maj, crypt_min, crypt_patch))
157 _dm_flags |= DM_KERNEL_KEYRING_SUPPORTED;
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;
164 if (_dm_satisfies_version(1, 19, 0, crypt_maj, crypt_min, crypt_patch))
165 _dm_flags |= DM_BITLK_EBOIV_SUPPORTED;
167 if (_dm_satisfies_version(1, 20, 0, crypt_maj, crypt_min, crypt_patch))
168 _dm_flags |= DM_BITLK_ELEPHANT_SUPPORTED;
170 if (_dm_satisfies_version(1, 22, 0, crypt_maj, crypt_min, crypt_patch))
171 _dm_flags |= DM_CRYPT_NO_WORKQUEUE_SUPPORTED;
173 _dm_crypt_checked = true;
176 static void _dm_set_verity_compat(struct crypt_device *cd,
179 unsigned verity_patch)
181 if (_dm_verity_checked || verity_maj == 0)
184 log_dbg(cd, "Detected dm-verity version %i.%i.%i.",
185 verity_maj, verity_min, verity_patch);
187 _dm_flags |= DM_VERITY_SUPPORTED;
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).
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;
201 if (_dm_satisfies_version(1, 5, 0, verity_maj, verity_min, verity_patch))
202 _dm_flags |= DM_VERITY_SIGNATURE_SUPPORTED;
204 if (_dm_satisfies_version(1, 7, 0, verity_maj, verity_min, verity_patch))
205 _dm_flags |= DM_VERITY_PANIC_CORRUPTION_SUPPORTED;
207 if (_dm_satisfies_version(1, 9, 0, verity_maj, verity_min, verity_patch))
208 _dm_flags |= DM_VERITY_TASKLETS_SUPPORTED;
210 _dm_verity_checked = true;
213 static void _dm_set_integrity_compat(struct crypt_device *cd,
214 unsigned integrity_maj,
215 unsigned integrity_min,
216 unsigned integrity_patch)
218 if (_dm_integrity_checked || integrity_maj == 0)
221 log_dbg(cd, "Detected dm-integrity version %i.%i.%i.",
222 integrity_maj, integrity_min, integrity_patch);
224 _dm_flags |= DM_INTEGRITY_SUPPORTED;
226 if (_dm_satisfies_version(1, 2, 0, integrity_maj, integrity_min, integrity_patch))
227 _dm_flags |= DM_INTEGRITY_RECALC_SUPPORTED;
229 if (_dm_satisfies_version(1, 3, 0, integrity_maj, integrity_min, integrity_patch))
230 _dm_flags |= DM_INTEGRITY_BITMAP_SUPPORTED;
232 if (_dm_satisfies_version(1, 4, 0, integrity_maj, integrity_min, integrity_patch))
233 _dm_flags |= DM_INTEGRITY_FIX_PADDING_SUPPORTED;
235 if (_dm_satisfies_version(1, 6, 0, integrity_maj, integrity_min, integrity_patch))
236 _dm_flags |= DM_INTEGRITY_DISCARDS_SUPPORTED;
238 if (_dm_satisfies_version(1, 7, 0, integrity_maj, integrity_min, integrity_patch))
239 _dm_flags |= DM_INTEGRITY_FIX_HMAC_SUPPORTED;
241 if (_dm_satisfies_version(1, 8, 0, integrity_maj, integrity_min, integrity_patch))
242 _dm_flags |= DM_INTEGRITY_RESET_RECALC_SUPPORTED;
244 _dm_integrity_checked = true;
247 static void _dm_set_zero_compat(struct crypt_device *cd,
252 if (_dm_zero_checked || zero_maj == 0)
255 log_dbg(cd, "Detected dm-zero version %i.%i.%i.",
256 zero_maj, zero_min, zero_patch);
258 _dm_zero_checked = true;
261 /* We use this for loading target module */
262 static void _dm_check_target(dm_target_type target_type)
264 #if HAVE_DECL_DM_DEVICE_GET_TARGET_VERSION
266 const char *target_name = NULL;
268 if (!(_dm_flags & DM_GET_TARGET_VERSION_SUPPORTED))
271 if (target_type == DM_CRYPT)
272 target_name = DM_CRYPT_TARGET;
273 else if (target_type == DM_VERITY)
274 target_name = DM_VERITY_TARGET;
275 else if (target_type == DM_INTEGRITY)
276 target_name = DM_INTEGRITY_TARGET;
280 if (!(dmt = dm_task_create(DM_DEVICE_GET_TARGET_VERSION)))
283 if (dm_task_set_name(dmt, target_name))
286 dm_task_destroy(dmt);
290 static int _dm_check_versions(struct crypt_device *cd, dm_target_type target_type)
293 struct dm_versions *target, *last_target;
295 unsigned dm_maj, dm_min, dm_patch;
298 if ((target_type == DM_CRYPT && _dm_crypt_checked) ||
299 (target_type == DM_VERITY && _dm_verity_checked) ||
300 (target_type == DM_INTEGRITY && _dm_integrity_checked) ||
301 (target_type == DM_ZERO && _dm_zero_checked) ||
302 (target_type == DM_LINEAR) ||
303 (_dm_crypt_checked && _dm_verity_checked && _dm_integrity_checked && _dm_zero_checked))
306 /* Shut up DM while checking */
309 _dm_check_target(target_type);
311 if (!(dmt = dm_task_create(DM_DEVICE_LIST_VERSIONS)))
314 if (!dm_task_run(dmt))
317 if (!dm_task_get_driver_version(dmt, dm_version, sizeof(dm_version)))
320 if (!_dm_ioctl_checked) {
321 if (sscanf(dm_version, "%u.%u.%u", &dm_maj, &dm_min, &dm_patch) != 3)
323 log_dbg(cd, "Detected dm-ioctl version %u.%u.%u.", dm_maj, dm_min, dm_patch);
325 if (_dm_satisfies_version(4, 20, 0, dm_maj, dm_min, dm_patch))
326 _dm_flags |= DM_SECURE_SUPPORTED;
327 #if HAVE_DECL_DM_TASK_DEFERRED_REMOVE
328 if (_dm_satisfies_version(4, 27, 0, dm_maj, dm_min, dm_patch))
329 _dm_flags |= DM_DEFERRED_SUPPORTED;
331 #if HAVE_DECL_DM_DEVICE_GET_TARGET_VERSION
332 if (_dm_satisfies_version(4, 41, 0, dm_maj, dm_min, dm_patch))
333 _dm_flags |= DM_GET_TARGET_VERSION_SUPPORTED;
337 target = dm_task_get_versions(dmt);
339 last_target = target;
340 if (!strcmp(DM_CRYPT_TARGET, target->name)) {
341 _dm_set_crypt_compat(cd, (unsigned)target->version[0],
342 (unsigned)target->version[1],
343 (unsigned)target->version[2]);
344 } else if (!strcmp(DM_VERITY_TARGET, target->name)) {
345 _dm_set_verity_compat(cd, (unsigned)target->version[0],
346 (unsigned)target->version[1],
347 (unsigned)target->version[2]);
348 } else if (!strcmp(DM_INTEGRITY_TARGET, target->name)) {
349 _dm_set_integrity_compat(cd, (unsigned)target->version[0],
350 (unsigned)target->version[1],
351 (unsigned)target->version[2]);
352 } else if (!strcmp(DM_ZERO_TARGET, target->name)) {
353 _dm_set_zero_compat(cd, (unsigned)target->version[0],
354 (unsigned)target->version[1],
355 (unsigned)target->version[2]);
357 target = VOIDP_CAST(struct dm_versions *)((char *) target + target->next);
358 } while (last_target != target);
361 if (!_dm_ioctl_checked)
362 log_dbg(cd, "Device-mapper backend running with UDEV support %sabled.",
363 _dm_use_udev() ? "en" : "dis");
365 _dm_ioctl_checked = true;
368 dm_task_destroy(dmt);
374 int dm_flags(struct crypt_device *cd, dm_target_type target, uint32_t *flags)
376 _dm_check_versions(cd, target);
379 if (target == DM_UNKNOWN &&
380 _dm_crypt_checked && _dm_verity_checked && _dm_integrity_checked && _dm_zero_checked)
383 if ((target == DM_CRYPT && _dm_crypt_checked) ||
384 (target == DM_VERITY && _dm_verity_checked) ||
385 (target == DM_INTEGRITY && _dm_integrity_checked) ||
386 (target == DM_ZERO && _dm_zero_checked) ||
387 (target == DM_LINEAR)) /* nothing to check */
393 /* This doesn't run any kernel checks, just set up userspace libdevmapper */
394 void dm_backend_init(struct crypt_device *cd)
396 if (!_dm_use_count++) {
397 log_dbg(cd, "Initialising device-mapper backend library.");
398 dm_log_init(set_dm_error);
399 dm_log_init_verbose(10);
403 void dm_backend_exit(struct crypt_device *cd)
405 if (_dm_use_count && (!--_dm_use_count)) {
406 log_dbg(cd, "Releasing device-mapper backend.");
407 dm_log_init_verbose(0);
413 /* libdevmapper is not context friendly, switch context on every DM call. */
414 static int dm_init_context(struct crypt_device *cd, dm_target_type target)
417 if (!_dm_check_versions(cd, target)) {
418 if (getuid() || geteuid())
419 log_err(cd, _("Cannot initialize device-mapper, "
420 "running as non-root user."));
422 log_err(cd, _("Cannot initialize device-mapper. "
423 "Is dm_mod kernel module loaded?"));
429 static void dm_exit_context(void)
434 /* Return path to DM device */
435 char *dm_device_path(const char *prefix, int major, int minor)
441 if (!(dmt = dm_task_create(DM_DEVICE_STATUS)))
443 if (!dm_task_set_minor(dmt, minor) ||
444 !dm_task_set_major(dmt, major) ||
445 !dm_task_no_flush(dmt) ||
447 !(name = dm_task_get_name(dmt))) {
448 dm_task_destroy(dmt);
452 if (snprintf(path, sizeof(path), "%s%s", prefix ?: "", name) < 0)
455 dm_task_destroy(dmt);
460 char *dm_device_name(const char *path)
464 if (stat(path, &st) < 0 || !S_ISBLK(st.st_mode))
467 return dm_device_path(NULL, major(st.st_rdev), minor(st.st_rdev));
470 static size_t int_log10(uint64_t x)
473 for (x /= 10; x > 0; x /= 10)
478 static int cipher_dm2c(const char *org_c, const char *org_i, unsigned tag_size,
479 char *c_dm, int c_dm_size,
480 char *i_dm, int i_dm_size)
482 int c_size = 0, i_size = 0, i;
483 char cipher[MAX_CAPI_ONE_LEN], mode[MAX_CAPI_ONE_LEN], iv[MAX_CAPI_ONE_LEN+1],
484 tmp[MAX_CAPI_ONE_LEN], capi[MAX_CAPI_LEN];
486 if (!c_dm || !c_dm_size || !i_dm || !i_dm_size)
489 i = sscanf(org_c, "%" MAX_CAPI_ONE_LEN_STR "[^-]-%" MAX_CAPI_ONE_LEN_STR "s", cipher, tmp);
493 i = sscanf(tmp, "%" MAX_CAPI_ONE_LEN_STR "[^-]-%" MAX_CAPI_ONE_LEN_STR "s", mode, iv);
495 memset(iv, 0, sizeof(iv));
496 strncpy(iv, mode, sizeof(iv)-1);
498 if (snprintf(capi, sizeof(capi), "%s", cipher) < 0)
501 if (snprintf(capi, sizeof(capi), "%s(%s)", mode, cipher) < 0)
507 /* legacy mode: CIPHER-MODE-IV*/
508 i_size = snprintf(i_dm, i_dm_size, "%s", "");
509 c_size = snprintf(c_dm, c_dm_size, "%s", org_c);
510 } else if (!strcmp(org_i, "none")) {
511 /* IV only: capi:MODE(CIPHER)-IV */
512 i_size = snprintf(i_dm, i_dm_size, " integrity:%u:none", tag_size);
513 c_size = snprintf(c_dm, c_dm_size, "capi:%s-%s", capi, iv);
514 } else if (!strcmp(org_i, "aead") && !strcmp(mode, "ccm")) {
515 /* CCM AEAD: capi:rfc4309(MODE(CIPHER))-IV */
516 i_size = snprintf(i_dm, i_dm_size, " integrity:%u:aead", tag_size);
517 c_size = snprintf(c_dm, c_dm_size, "capi:rfc4309(%s)-%s", capi, iv);
518 } else if (!strcmp(org_i, "aead")) {
519 /* AEAD: capi:MODE(CIPHER))-IV */
520 i_size = snprintf(i_dm, i_dm_size, " integrity:%u:aead", tag_size);
521 c_size = snprintf(c_dm, c_dm_size, "capi:%s-%s", capi, iv);
522 } else if (!strcmp(org_i, "poly1305")) {
523 /* POLY1305 AEAD: capi:rfc7539(MODE(CIPHER),POLY1305)-IV */
524 i_size = snprintf(i_dm, i_dm_size, " integrity:%u:aead", tag_size);
525 c_size = snprintf(c_dm, c_dm_size, "capi:rfc7539(%s,poly1305)-%s", capi, iv);
527 /* other AEAD: capi:authenc(<AUTH>,MODE(CIPHER))-IV */
528 i_size = snprintf(i_dm, i_dm_size, " integrity:%u:aead", tag_size);
529 c_size = snprintf(c_dm, c_dm_size, "capi:authenc(%s,%s)-%s", org_i, capi, iv);
532 if (c_size < 0 || c_size == c_dm_size)
534 if (i_size < 0 || i_size == i_dm_size)
540 static char *_uf(char *buf, size_t buf_size, const char *s, unsigned u)
542 size_t r = snprintf(buf, buf_size, " %s:%u", s, u);
543 assert(r > 0 && r < buf_size);
547 /* https://gitlab.com/cryptsetup/cryptsetup/wikis/DMCrypt */
548 static char *get_dm_crypt_params(const struct dm_target *tgt, uint32_t flags)
550 int r, max_size, null_cipher = 0, num_options = 0, keystr_len = 0;
551 char *params = NULL, *hexkey = NULL;
552 char sector_feature[32], features[512], integrity_dm[256], cipher_dm[256];
557 r = cipher_dm2c(tgt->u.crypt.cipher, tgt->u.crypt.integrity, tgt->u.crypt.tag_size,
558 cipher_dm, sizeof(cipher_dm), integrity_dm, sizeof(integrity_dm));
562 if (flags & CRYPT_ACTIVATE_ALLOW_DISCARDS)
564 if (flags & CRYPT_ACTIVATE_SAME_CPU_CRYPT)
566 if (flags & CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS)
568 if (flags & CRYPT_ACTIVATE_NO_READ_WORKQUEUE)
570 if (flags & CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE)
572 if (flags & CRYPT_ACTIVATE_IV_LARGE_SECTORS)
574 if (tgt->u.crypt.integrity)
576 if (tgt->u.crypt.sector_size != SECTOR_SIZE)
579 if (num_options) { /* MAX length int32 + 15 + 15 + 23 + 18 + 19 + 17 + 13 + int32 + integrity_str */
580 r = snprintf(features, sizeof(features), " %d%s%s%s%s%s%s%s%s", num_options,
581 (flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) ? " allow_discards" : "",
582 (flags & CRYPT_ACTIVATE_SAME_CPU_CRYPT) ? " same_cpu_crypt" : "",
583 (flags & CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS) ? " submit_from_crypt_cpus" : "",
584 (flags & CRYPT_ACTIVATE_NO_READ_WORKQUEUE) ? " no_read_workqueue" : "",
585 (flags & CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE) ? " no_write_workqueue" : "",
586 (flags & CRYPT_ACTIVATE_IV_LARGE_SECTORS) ? " iv_large_sectors" : "",
587 (tgt->u.crypt.sector_size != SECTOR_SIZE) ?
588 _uf(sector_feature, sizeof(sector_feature), "sector_size", tgt->u.crypt.sector_size) : "",
590 if (r < 0 || (size_t)r >= sizeof(features))
595 if (crypt_is_cipher_null(cipher_dm))
599 hexkey = crypt_bytes_to_hex(0, NULL);
600 else if (flags & CRYPT_ACTIVATE_KEYRING_KEY) {
601 keystr_len = strlen(tgt->u.crypt.vk->key_description) + int_log10(tgt->u.crypt.vk->keylength) + 10;
602 hexkey = crypt_safe_alloc(keystr_len);
605 r = snprintf(hexkey, keystr_len, ":%zu:logon:%s", tgt->u.crypt.vk->keylength, tgt->u.crypt.vk->key_description);
606 if (r < 0 || r >= keystr_len)
609 hexkey = crypt_bytes_to_hex(tgt->u.crypt.vk->keylength, tgt->u.crypt.vk->key);
614 max_size = strlen(hexkey) + strlen(cipher_dm) +
615 strlen(device_block_path(tgt->data_device)) +
616 strlen(features) + 64;
617 params = crypt_safe_alloc(max_size);
621 r = snprintf(params, max_size, "%s %s %" PRIu64 " %s %" PRIu64 "%s",
622 cipher_dm, hexkey, tgt->u.crypt.iv_offset,
623 device_block_path(tgt->data_device), tgt->u.crypt.offset,
625 if (r < 0 || r >= max_size) {
626 crypt_safe_free(params);
630 crypt_safe_free(hexkey);
634 /* https://gitlab.com/cryptsetup/cryptsetup/wikis/DMVerity */
635 static char *get_dm_verity_params(const struct dm_target *tgt, uint32_t flags)
637 int max_size, max_fec_size, max_verify_size, r, num_options = 0;
638 struct crypt_params_verity *vp;
639 char *params = NULL, *hexroot = NULL, *hexsalt = NULL;
640 char features[256], *fec_features = NULL, *verity_verify_args = NULL;
642 if (!tgt || !tgt->u.verity.vp)
645 vp = tgt->u.verity.vp;
647 /* These flags are not compatible */
648 if ((flags & CRYPT_ACTIVATE_RESTART_ON_CORRUPTION) &&
649 (flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION))
650 flags &= ~CRYPT_ACTIVATE_RESTART_ON_CORRUPTION;
651 if ((flags & CRYPT_ACTIVATE_IGNORE_CORRUPTION) &&
652 (flags & (CRYPT_ACTIVATE_RESTART_ON_CORRUPTION|CRYPT_ACTIVATE_PANIC_ON_CORRUPTION)))
653 flags &= ~CRYPT_ACTIVATE_IGNORE_CORRUPTION;
655 if (flags & CRYPT_ACTIVATE_IGNORE_CORRUPTION)
657 if (flags & CRYPT_ACTIVATE_RESTART_ON_CORRUPTION)
659 if (flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION)
661 if (flags & CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS)
663 if (flags & CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE)
665 if (flags & CRYPT_ACTIVATE_TASKLETS)
668 max_fec_size = (tgt->u.verity.fec_device ? strlen(device_block_path(tgt->u.verity.fec_device)) : 0) + 256;
669 fec_features = crypt_safe_alloc(max_fec_size);
673 if (tgt->u.verity.fec_device) { /* MAX length 21 + path + 11 + int64 + 12 + int64 + 11 + int32 */
675 r = snprintf(fec_features, max_fec_size,
676 " use_fec_from_device %s fec_start %" PRIu64 " fec_blocks %" PRIu64 " fec_roots %" PRIu32,
677 device_block_path(tgt->u.verity.fec_device), tgt->u.verity.fec_offset,
678 tgt->u.verity.fec_blocks, vp->fec_roots);
679 if (r < 0 || r >= max_fec_size)
682 *fec_features = '\0';
684 max_verify_size = (tgt->u.verity.root_hash_sig_key_desc ? strlen(tgt->u.verity.root_hash_sig_key_desc) : 0) + 32;
685 verity_verify_args = crypt_safe_alloc(max_verify_size);
686 if (!verity_verify_args)
688 if (tgt->u.verity.root_hash_sig_key_desc) { /* MAX length 24 + key_str */
690 r = snprintf(verity_verify_args, max_verify_size,
691 " root_hash_sig_key_desc %s", tgt->u.verity.root_hash_sig_key_desc);
692 if (r < 0 || r >= max_verify_size)
695 *verity_verify_args = '\0';
697 if (num_options) { /* MAX length int32 + 18 + 22 + 20 + 19 + 19 + 22 */
698 r = snprintf(features, sizeof(features), " %d%s%s%s%s%s%s", num_options,
699 (flags & CRYPT_ACTIVATE_IGNORE_CORRUPTION) ? " ignore_corruption" : "",
700 (flags & CRYPT_ACTIVATE_RESTART_ON_CORRUPTION) ? " restart_on_corruption" : "",
701 (flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION) ? " panic_on_corruption" : "",
702 (flags & CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS) ? " ignore_zero_blocks" : "",
703 (flags & CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE) ? " check_at_most_once" : "",
704 (flags & CRYPT_ACTIVATE_TASKLETS) ? " try_verify_in_tasklet" : "");
705 if (r < 0 || (size_t)r >= sizeof(features))
710 hexroot = crypt_bytes_to_hex(tgt->u.verity.root_hash_size, tgt->u.verity.root_hash);
714 hexsalt = crypt_bytes_to_hex(vp->salt_size, vp->salt);
718 max_size = strlen(hexroot) + strlen(hexsalt) +
719 strlen(device_block_path(tgt->data_device)) +
720 strlen(device_block_path(tgt->u.verity.hash_device)) +
721 strlen(vp->hash_name) + strlen(features) + strlen(fec_features) + 128 +
722 strlen(verity_verify_args);
724 params = crypt_safe_alloc(max_size);
728 r = snprintf(params, max_size,
729 "%u %s %s %u %u %" PRIu64 " %" PRIu64 " %s %s %s%s%s%s",
730 vp->hash_type, device_block_path(tgt->data_device),
731 device_block_path(tgt->u.verity.hash_device),
732 vp->data_block_size, vp->hash_block_size,
733 vp->data_size, tgt->u.verity.hash_offset,
734 vp->hash_name, hexroot, hexsalt, features, fec_features,
736 if (r < 0 || r >= max_size) {
737 crypt_safe_free(params);
741 crypt_safe_free(fec_features);
742 crypt_safe_free(verity_verify_args);
743 crypt_safe_free(hexroot);
744 crypt_safe_free(hexsalt);
748 static char *get_dm_integrity_params(const struct dm_target *tgt, uint32_t flags)
750 int r, max_size, max_integrity, max_journal_integrity, max_journal_crypt, num_options = 0;
751 char *params_out = NULL, *params, *hexkey, mode, feature[6][32];
752 char *features, *integrity, *journal_integrity, *journal_crypt;
757 max_integrity = (tgt->u.integrity.integrity && tgt->u.integrity.vk ? tgt->u.integrity.vk->keylength * 2 : 0) +
758 (tgt->u.integrity.integrity ? strlen(tgt->u.integrity.integrity) : 0) + 32;
759 max_journal_integrity = (tgt->u.integrity.journal_integrity && tgt->u.integrity.journal_integrity_key ?
760 tgt->u.integrity.journal_integrity_key->keylength * 2 : 0) +
761 (tgt->u.integrity.journal_integrity ? strlen(tgt->u.integrity.journal_integrity) : 0) + 32;
762 max_journal_crypt = (tgt->u.integrity.journal_crypt && tgt->u.integrity.journal_crypt_key ?
763 tgt->u.integrity.journal_crypt_key->keylength * 2 : 0) +
764 (tgt->u.integrity.journal_crypt ? strlen(tgt->u.integrity.journal_crypt) : 0) + 32;
765 max_size = strlen(device_block_path(tgt->data_device)) +
766 (tgt->u.integrity.meta_device ? strlen(device_block_path(tgt->u.integrity.meta_device)) : 0) +
767 max_integrity + max_journal_integrity + max_journal_crypt + 512;
769 params = crypt_safe_alloc(max_size);
770 features = crypt_safe_alloc(max_size);
771 integrity = crypt_safe_alloc(max_integrity);
772 journal_integrity = crypt_safe_alloc(max_journal_integrity);
773 journal_crypt = crypt_safe_alloc(max_journal_crypt);
774 if (!params || !features || !integrity || !journal_integrity || !journal_crypt)
777 if (tgt->u.integrity.integrity) { /* MAX length 16 + str_integrity + str_key */
780 if (tgt->u.integrity.vk) {
781 hexkey = crypt_bytes_to_hex(tgt->u.integrity.vk->keylength, tgt->u.integrity.vk->key);
787 r = snprintf(integrity, max_integrity, " internal_hash:%s%s%s",
788 tgt->u.integrity.integrity, hexkey ? ":" : "", hexkey ?: "");
789 crypt_safe_free(hexkey);
790 if (r < 0 || r >= max_integrity)
794 if (tgt->u.integrity.journal_integrity) { /* MAX length 14 + str_journal_integrity + str_key */
797 if (tgt->u.integrity.journal_integrity_key) {
798 hexkey = crypt_bytes_to_hex( tgt->u.integrity.journal_integrity_key->keylength,
799 tgt->u.integrity.journal_integrity_key->key);
805 r = snprintf(journal_integrity, max_journal_integrity, " journal_mac:%s%s%s",
806 tgt->u.integrity.journal_integrity, hexkey ? ":" : "", hexkey ?: "");
807 crypt_safe_free(hexkey);
808 if (r < 0 || r >= max_journal_integrity)
812 if (tgt->u.integrity.journal_crypt) { /* MAX length 15 + str_journal_crypt + str_key */
815 if (tgt->u.integrity.journal_crypt_key) {
816 hexkey = crypt_bytes_to_hex(tgt->u.integrity.journal_crypt_key->keylength,
817 tgt->u.integrity.journal_crypt_key->key);
823 r = snprintf(journal_crypt, max_journal_crypt, " journal_crypt:%s%s%s",
824 tgt->u.integrity.journal_crypt, hexkey ? ":" : "", hexkey ?: "");
825 crypt_safe_free(hexkey);
826 if (r < 0 || r >= max_journal_crypt)
830 if (tgt->u.integrity.journal_size)
832 if (tgt->u.integrity.journal_watermark)
834 if (tgt->u.integrity.journal_commit_time)
836 if (tgt->u.integrity.interleave_sectors)
838 if (tgt->u.integrity.sector_size)
840 if (tgt->u.integrity.buffer_sectors)
842 if (tgt->u.integrity.fix_padding)
844 if (tgt->u.integrity.fix_hmac)
846 if (tgt->u.integrity.legacy_recalc)
848 if (tgt->u.integrity.meta_device)
850 if (flags & CRYPT_ACTIVATE_RECALCULATE)
852 if (flags & CRYPT_ACTIVATE_RECALCULATE_RESET)
854 if (flags & CRYPT_ACTIVATE_ALLOW_DISCARDS)
857 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,
858 tgt->u.integrity.journal_size ? _uf(feature[0], sizeof(feature[0]), /* MAX length 17 + int32 */
859 "journal_sectors", (unsigned)(tgt->u.integrity.journal_size / SECTOR_SIZE)) : "",
860 tgt->u.integrity.journal_watermark ? _uf(feature[1], sizeof(feature[1]), /* MAX length 19 + int32 */
861 /* bitmap overloaded values */
862 (flags & CRYPT_ACTIVATE_NO_JOURNAL_BITMAP) ? "sectors_per_bit" : "journal_watermark",
863 tgt->u.integrity.journal_watermark) : "",
864 tgt->u.integrity.journal_commit_time ? _uf(feature[2], sizeof(feature[2]), /* MAX length 23 + int32 */
865 /* bitmap overloaded values */
866 (flags & CRYPT_ACTIVATE_NO_JOURNAL_BITMAP) ? "bitmap_flush_interval" : "commit_time",
867 tgt->u.integrity.journal_commit_time) : "",
868 tgt->u.integrity.interleave_sectors ? _uf(feature[3], sizeof(feature[3]), /* MAX length 20 + int32 */
869 "interleave_sectors", tgt->u.integrity.interleave_sectors) : "",
870 tgt->u.integrity.sector_size ? _uf(feature[4], sizeof(feature[4]), /* MAX length 12 + int32 */
871 "block_size", tgt->u.integrity.sector_size) : "",
872 tgt->u.integrity.buffer_sectors ? _uf(feature[5], sizeof(feature[5]), /* MAX length 16 + int32 */
873 "buffer_sectors", tgt->u.integrity.buffer_sectors) : "",
874 tgt->u.integrity.integrity ? integrity : "",
875 tgt->u.integrity.journal_integrity ? journal_integrity : "",
876 tgt->u.integrity.journal_crypt ? journal_crypt : "",
877 tgt->u.integrity.fix_padding ? " fix_padding" : "", /* MAX length 12 */
878 tgt->u.integrity.fix_hmac ? " fix_hmac" : "", /* MAX length 9 */
879 tgt->u.integrity.legacy_recalc ? " legacy_recalculate" : "", /* MAX length 19 */
880 flags & CRYPT_ACTIVATE_RECALCULATE ? " recalculate" : "", /* MAX length 12 */
881 flags & CRYPT_ACTIVATE_RECALCULATE_RESET ? " reset_recalculate" : "", /* MAX length 18 */
882 flags & CRYPT_ACTIVATE_ALLOW_DISCARDS ? " allow_discards" : "", /* MAX length 15 */
883 tgt->u.integrity.meta_device ? " meta_device:" : "", /* MAX length 13 + str_device */
884 tgt->u.integrity.meta_device ? device_block_path(tgt->u.integrity.meta_device) : "");
885 if (r < 0 || r >= max_size)
888 if (flags & CRYPT_ACTIVATE_NO_JOURNAL_BITMAP)
890 else if (flags & CRYPT_ACTIVATE_RECOVERY)
892 else if (flags & CRYPT_ACTIVATE_NO_JOURNAL)
897 r = snprintf(params, max_size, "%s %" PRIu64 " %d %c %s",
898 device_block_path(tgt->data_device), tgt->u.integrity.offset,
899 tgt->u.integrity.tag_size, mode, features);
900 if (r < 0 || r >= max_size)
905 crypt_safe_free(features);
906 crypt_safe_free(integrity);
907 crypt_safe_free(journal_integrity);
908 crypt_safe_free(journal_crypt);
910 crypt_safe_free(params);
915 static char *get_dm_linear_params(const struct dm_target *tgt)
919 int max_size = strlen(device_block_path(tgt->data_device)) + int_log10(tgt->u.linear.offset) + 3;
921 params = crypt_safe_alloc(max_size);
925 r = snprintf(params, max_size, "%s %" PRIu64,
926 device_block_path(tgt->data_device), tgt->u.linear.offset);
928 if (r < 0 || r >= max_size) {
929 crypt_safe_free(params);
936 static char *get_dm_zero_params(void)
938 char *params = crypt_safe_alloc(1);
947 static int _dm_remove(const char *name, int udev_wait, int deferred)
956 if (!(dmt = dm_task_create(DM_DEVICE_REMOVE)))
959 if (!dm_task_set_name(dmt, name))
962 #if HAVE_DECL_DM_TASK_RETRY_REMOVE
963 if (!dm_task_retry_remove(dmt))
966 #if HAVE_DECL_DM_TASK_DEFERRED_REMOVE
967 if (deferred && !dm_task_deferred_remove(dmt))
970 if (udev_wait && !_dm_task_set_cookie(dmt, &cookie, DM_UDEV_DISABLE_LIBRARY_FALLBACK))
973 r = dm_task_run(dmt);
976 (void)_dm_udev_wait(cookie);
978 dm_task_destroy(dmt);
982 static int _dm_simple(int task, const char *name, uint32_t dmflags)
987 if (!(dmt = dm_task_create(task)))
990 if (name && !dm_task_set_name(dmt, name))
993 if (task == DM_DEVICE_SUSPEND &&
994 (dmflags & DM_SUSPEND_SKIP_LOCKFS) && !dm_task_skip_lockfs(dmt))
997 if (task == DM_DEVICE_SUSPEND &&
998 (dmflags & DM_SUSPEND_NOFLUSH) && !dm_task_no_flush(dmt))
1001 r = dm_task_run(dmt);
1003 dm_task_destroy(dmt);
1007 static int _dm_resume_device(const char *name, uint32_t flags);
1009 static int _error_device(const char *name, size_t size)
1011 struct dm_task *dmt;
1014 if (!(dmt = dm_task_create(DM_DEVICE_RELOAD)))
1017 if (!dm_task_set_name(dmt, name))
1020 if (!dm_task_add_target(dmt, UINT64_C(0), size, "error", ""))
1023 if (!dm_task_set_ro(dmt))
1026 if (!dm_task_no_open_count(dmt))
1029 if (!dm_task_run(dmt))
1032 if (_dm_resume_device(name, 0)) {
1033 _dm_simple(DM_DEVICE_CLEAR, name, 0);
1039 dm_task_destroy(dmt);
1043 int dm_error_device(struct crypt_device *cd, const char *name)
1046 struct crypt_dm_active_device dmd;
1051 if (dm_init_context(cd, DM_UNKNOWN))
1054 if ((dm_query_device(cd, name, 0, &dmd) >= 0) && _error_device(name, dmd.size))
1059 dm_targets_free(cd, &dmd);
1066 int dm_clear_device(struct crypt_device *cd, const char *name)
1073 if (dm_init_context(cd, DM_UNKNOWN))
1076 if (_dm_simple(DM_DEVICE_CLEAR, name, 0))
1086 int dm_remove_device(struct crypt_device *cd, const char *name, uint32_t flags)
1088 struct crypt_dm_active_device dmd = {};
1090 int retries = (flags & CRYPT_DEACTIVATE_FORCE) ? RETRY_COUNT : 1;
1091 int deferred = (flags & CRYPT_DEACTIVATE_DEFERRED) ? 1 : 0;
1092 int error_target = 0;
1098 if (dm_init_context(cd, DM_UNKNOWN))
1101 if (deferred && !dm_flags(cd, DM_UNKNOWN, &dmt_flags) && !(dmt_flags & DM_DEFERRED_SUPPORTED)) {
1102 log_err(cd, _("Requested deferred flag is not supported."));
1108 r = _dm_remove(name, 1, deferred) ? 0 : -EINVAL;
1109 if (--retries && r) {
1110 log_dbg(cd, "WARNING: other process locked internal device %s, %s.",
1111 name, retries ? "retrying remove" : "giving up");
1113 if ((flags & CRYPT_DEACTIVATE_FORCE) && !error_target) {
1114 /* If force flag is set, replace device with error, read-only target.
1115 * it should stop processes from reading it and also removed underlying
1116 * device from mapping, so it is usable again.
1117 * Anyway, if some process try to read temporary cryptsetup device,
1118 * it is bug - no other process should try touch it (e.g. udev).
1120 if (!dm_query_device(cd, name, 0, &dmd)) {
1121 _error_device(name, dmd.size);
1126 } while (r == -EINVAL && retries);
1128 dm_task_update_nodes();
1134 #define UUID_LEN 37 /* 36 + \0, libuuid ... */
1136 * UUID has format: CRYPT-<devicetype>-[<uuid>-]<device name>
1138 * CRYPT-LUKS1-00000000000000000000000000000000-name
1141 static int dm_prepare_uuid(struct crypt_device *cd, const char *name, const char *type,
1142 const char *uuid, char *buf, size_t buflen)
1144 char *ptr, uuid2[UUID_LEN] = {0};
1148 /* Remove '-' chars */
1150 if (uuid_parse(uuid, uu) < 0) {
1151 log_dbg(cd, "Requested UUID %s has invalid format.", uuid);
1155 for (ptr = uuid2, i = 0; i < UUID_LEN; i++)
1156 if (uuid[i] != '-') {
1162 i = snprintf(buf, buflen, DM_UUID_PREFIX "%s%s%s%s%s",
1163 type ?: "", type ? "-" : "",
1164 uuid2[0] ? uuid2 : "", uuid2[0] ? "-" : "",
1169 log_dbg(cd, "DM-UUID is %s", buf);
1170 if ((size_t)i >= buflen)
1171 log_err(cd, _("DM-UUID for device %s was truncated."), name);
1176 int lookup_dm_dev_by_uuid(struct crypt_device *cd, const char *uuid, const char *type)
1180 char dev_uuid[DM_UUID_LEN + DM_BY_ID_PREFIX_LEN] = DM_BY_ID_PREFIX;
1182 if (!dm_prepare_uuid(cd, "", type, uuid, dev_uuid + DM_BY_ID_PREFIX_LEN, DM_UUID_LEN))
1185 c = strrchr(dev_uuid, '-');
1189 /* cut of dm name */
1192 /* Either udev or sysfs can report that device is active. */
1193 r = lookup_by_disk_id(dev_uuid);
1198 r = lookup_by_sysfs_uuid_field(dev_uuid + DM_BY_ID_PREFIX_LEN);
1200 return r == -ENOENT ? r_udev : r;
1203 static int _add_dm_targets(struct dm_task *dmt, struct crypt_dm_active_device *dmd)
1206 struct dm_target *tgt = &dmd->segment;
1209 switch (tgt->type) {
1211 target = DM_CRYPT_TARGET;
1214 target = DM_VERITY_TARGET;
1217 target = DM_INTEGRITY_TARGET;
1220 target = DM_LINEAR_TARGET;
1223 target = DM_ZERO_TARGET;
1229 if (!dm_task_add_target(dmt, tgt->offset, tgt->size, target, tgt->params))
1238 static void _destroy_dm_targets_params(struct crypt_dm_active_device *dmd)
1240 struct dm_target *t = &dmd->segment;
1243 crypt_safe_free(t->params);
1249 static int _create_dm_targets_params(struct crypt_dm_active_device *dmd)
1252 struct dm_target *tgt = &dmd->segment;
1255 if (tgt->type == DM_CRYPT)
1256 tgt->params = get_dm_crypt_params(tgt, dmd->flags);
1257 else if (tgt->type == DM_VERITY)
1258 tgt->params = get_dm_verity_params(tgt, dmd->flags);
1259 else if (tgt->type == DM_INTEGRITY)
1260 tgt->params = get_dm_integrity_params(tgt, dmd->flags);
1261 else if (tgt->type == DM_LINEAR)
1262 tgt->params = get_dm_linear_params(tgt);
1263 else if (tgt->type == DM_ZERO)
1264 tgt->params = get_dm_zero_params();
1279 _destroy_dm_targets_params(dmd);
1283 static int _dm_create_device(struct crypt_device *cd, const char *name, const char *type,
1284 struct crypt_dm_active_device *dmd)
1286 struct dm_task *dmt = NULL;
1288 char dev_uuid[DM_UUID_LEN] = {0};
1290 uint32_t cookie = 0, read_ahead = 0;
1291 uint16_t udev_flags = DM_UDEV_DISABLE_LIBRARY_FALLBACK;
1293 if (dmd->flags & CRYPT_ACTIVATE_PRIVATE)
1294 udev_flags |= CRYPT_TEMP_UDEV_FLAGS;
1296 /* All devices must have DM_UUID, only resize on old device is exception */
1297 if (!dm_prepare_uuid(cd, name, type, dmd->uuid, dev_uuid, sizeof(dev_uuid)))
1300 if (!(dmt = dm_task_create(DM_DEVICE_CREATE)))
1303 if (!dm_task_set_name(dmt, name))
1306 if (!dm_task_set_uuid(dmt, dev_uuid))
1309 if (!dm_task_secure_data(dmt))
1311 if ((dmd->flags & CRYPT_ACTIVATE_READONLY) && !dm_task_set_ro(dmt))
1314 r = _create_dm_targets_params(dmd);
1318 r = _add_dm_targets(dmt, dmd);
1324 #ifdef DM_READ_AHEAD_MINIMUM_FLAG
1325 if (device_read_ahead(dmd->segment.data_device, &read_ahead) &&
1326 !dm_task_set_read_ahead(dmt, read_ahead, DM_READ_AHEAD_MINIMUM_FLAG))
1329 if (_dm_use_udev() && !_dm_task_set_cookie(dmt, &cookie, udev_flags))
1332 if (!dm_task_run(dmt)) {
1333 r = dm_status_device(cd, name);;
1336 if (r != -EEXIST && r != -ENODEV)
1341 if (dm_task_get_info(dmt, &dmi))
1344 if (_dm_use_udev()) {
1345 (void)_dm_udev_wait(cookie);
1350 _dm_remove(name, 1, 0);
1353 if (cookie && _dm_use_udev())
1354 (void)_dm_udev_wait(cookie);
1357 dm_task_destroy(dmt);
1359 dm_task_update_nodes();
1361 /* If code just loaded target module, update versions */
1362 _dm_check_versions(cd, dmd->segment.type);
1364 _destroy_dm_targets_params(dmd);
1369 static int _dm_resume_device(const char *name, uint32_t dmflags)
1371 struct dm_task *dmt;
1373 uint32_t cookie = 0;
1374 uint16_t udev_flags = DM_UDEV_DISABLE_LIBRARY_FALLBACK;
1376 if (dmflags & DM_RESUME_PRIVATE)
1377 udev_flags |= CRYPT_TEMP_UDEV_FLAGS;
1379 if (!(dmt = dm_task_create(DM_DEVICE_RESUME)))
1382 if (!dm_task_set_name(dmt, name))
1385 if ((dmflags & DM_SUSPEND_SKIP_LOCKFS) && !dm_task_skip_lockfs(dmt))
1388 if ((dmflags & DM_SUSPEND_NOFLUSH) && !dm_task_no_flush(dmt))
1391 if (_dm_use_udev() && !_dm_task_set_cookie(dmt, &cookie, udev_flags))
1394 if (dm_task_run(dmt))
1397 if (cookie && _dm_use_udev())
1398 (void)_dm_udev_wait(cookie);
1400 dm_task_destroy(dmt);
1402 dm_task_update_nodes();
1407 static int _dm_reload_device(struct crypt_device *cd, const char *name,
1408 struct crypt_dm_active_device *dmd)
1411 struct dm_task *dmt = NULL;
1412 uint32_t read_ahead = 0;
1414 /* All devices must have DM_UUID, only resize on old device is exception */
1415 if (!(dmt = dm_task_create(DM_DEVICE_RELOAD)))
1418 if (!dm_task_set_name(dmt, name))
1421 if (!dm_task_secure_data(dmt))
1423 if ((dmd->flags & CRYPT_ACTIVATE_READONLY) && !dm_task_set_ro(dmt))
1426 r = _create_dm_targets_params(dmd);
1430 r = _add_dm_targets(dmt, dmd);
1436 #ifdef DM_READ_AHEAD_MINIMUM_FLAG
1437 if (device_read_ahead(dmd->segment.data_device, &read_ahead) &&
1438 !dm_task_set_read_ahead(dmt, read_ahead, DM_READ_AHEAD_MINIMUM_FLAG))
1442 if (dm_task_run(dmt))
1446 dm_task_destroy(dmt);
1448 /* If code just loaded target module, update versions */
1449 _dm_check_versions(cd, dmd->segment.type);
1451 _destroy_dm_targets_params(dmd);
1456 static void crypt_free_verity_params(struct crypt_params_verity *vp)
1461 free(CONST_CAST(void*)vp->hash_name);
1462 free(CONST_CAST(void*)vp->data_device);
1463 free(CONST_CAST(void*)vp->hash_device);
1464 free(CONST_CAST(void*)vp->fec_device);
1465 free(CONST_CAST(void*)vp->salt);
1469 static void _dm_target_free_query_path(struct crypt_device *cd, struct dm_target *tgt)
1473 crypt_free_volume_key(tgt->u.crypt.vk);
1474 free(CONST_CAST(void*)tgt->u.crypt.cipher);
1477 free(CONST_CAST(void*)tgt->u.integrity.integrity);
1478 crypt_free_volume_key(tgt->u.integrity.vk);
1480 free(CONST_CAST(void*)tgt->u.integrity.journal_integrity);
1481 crypt_free_volume_key(tgt->u.integrity.journal_integrity_key);
1483 free(CONST_CAST(void*)tgt->u.integrity.journal_crypt);
1484 crypt_free_volume_key(tgt->u.integrity.journal_crypt_key);
1486 device_free(cd, tgt->u.integrity.meta_device);
1489 crypt_free_verity_params(tgt->u.verity.vp);
1490 device_free(cd, tgt->u.verity.hash_device);
1491 free(CONST_CAST(void*)tgt->u.verity.root_hash);
1492 free(CONST_CAST(void*)tgt->u.verity.root_hash_sig_key_desc);
1501 log_err(cd, _("Unknown dm target type."));
1505 device_free(cd, tgt->data_device);
1508 static void _dm_target_erase(struct crypt_device *cd, struct dm_target *tgt)
1510 if (tgt->direction == TARGET_EMPTY)
1513 if (tgt->direction == TARGET_QUERY)
1514 _dm_target_free_query_path(cd, tgt);
1516 if (tgt->type == DM_CRYPT)
1517 free(CONST_CAST(void*)tgt->u.crypt.integrity);
1520 void dm_targets_free(struct crypt_device *cd, struct crypt_dm_active_device *dmd)
1522 struct dm_target *t = &dmd->segment, *next = t->next;
1524 _dm_target_erase(cd, t);
1529 _dm_target_erase(cd, t);
1533 memset(&dmd->segment, 0, sizeof(dmd->segment));
1536 int dm_targets_allocate(struct dm_target *first, unsigned count)
1538 if (!first || first->next || !count)
1542 first->next = crypt_zalloc(sizeof(*first));
1545 first = first->next;
1551 static int check_retry(struct crypt_device *cd, uint32_t *dmd_flags, uint32_t dmt_flags)
1555 /* If discard not supported try to load without discard */
1556 if ((*dmd_flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) &&
1557 !(dmt_flags & DM_DISCARDS_SUPPORTED)) {
1558 log_dbg(cd, "Discard/TRIM is not supported");
1559 *dmd_flags = *dmd_flags & ~CRYPT_ACTIVATE_ALLOW_DISCARDS;
1563 /* If kernel keyring is not supported load key directly in dm-crypt */
1564 if ((*dmd_flags & CRYPT_ACTIVATE_KEYRING_KEY) &&
1565 !(dmt_flags & DM_KERNEL_KEYRING_SUPPORTED)) {
1566 log_dbg(cd, "dm-crypt does not support kernel keyring");
1567 *dmd_flags = *dmd_flags & ~CRYPT_ACTIVATE_KEYRING_KEY;
1571 /* Drop performance options if not supported */
1572 if ((*dmd_flags & (CRYPT_ACTIVATE_SAME_CPU_CRYPT | CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS)) &&
1573 !(dmt_flags & (DM_SAME_CPU_CRYPT_SUPPORTED | DM_SUBMIT_FROM_CRYPT_CPUS_SUPPORTED))) {
1574 log_dbg(cd, "dm-crypt does not support performance options");
1575 *dmd_flags = *dmd_flags & ~(CRYPT_ACTIVATE_SAME_CPU_CRYPT | CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS);
1579 /* Drop no workqueue options if not supported */
1580 if ((*dmd_flags & (CRYPT_ACTIVATE_NO_READ_WORKQUEUE | CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE)) &&
1581 !(dmt_flags & DM_CRYPT_NO_WORKQUEUE_SUPPORTED)) {
1582 log_dbg(cd, "dm-crypt does not support performance options");
1583 *dmd_flags = *dmd_flags & ~(CRYPT_ACTIVATE_NO_READ_WORKQUEUE | CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE);
1590 int dm_create_device(struct crypt_device *cd, const char *name,
1592 struct crypt_dm_active_device *dmd)
1594 uint32_t dmt_flags = 0;
1600 if (dm_init_context(cd, dmd->segment.type))
1603 r = _dm_create_device(cd, name, type, dmd);
1604 if (!r || r == -EEXIST)
1607 if (dm_flags(cd, dmd->segment.type, &dmt_flags))
1610 if ((dmd->segment.type == DM_CRYPT || dmd->segment.type == DM_LINEAR || dmd->segment.type == DM_ZERO) &&
1611 check_retry(cd, &dmd->flags, dmt_flags)) {
1612 log_dbg(cd, "Retrying open without incompatible options.");
1613 r = _dm_create_device(cd, name, type, dmd);
1614 if (!r || r == -EEXIST)
1618 if (dmd->flags & (CRYPT_ACTIVATE_SAME_CPU_CRYPT|CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS) &&
1619 !(dmt_flags & (DM_SAME_CPU_CRYPT_SUPPORTED|DM_SUBMIT_FROM_CRYPT_CPUS_SUPPORTED))) {
1620 log_err(cd, _("Requested dm-crypt performance options are not supported."));
1624 if (dmd->flags & (CRYPT_ACTIVATE_NO_READ_WORKQUEUE | CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE) &&
1625 !(dmt_flags & DM_CRYPT_NO_WORKQUEUE_SUPPORTED)) {
1626 log_err(cd, _("Requested dm-crypt performance options are not supported."));
1630 if (dmd->flags & (CRYPT_ACTIVATE_IGNORE_CORRUPTION|
1631 CRYPT_ACTIVATE_RESTART_ON_CORRUPTION|
1632 CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS|
1633 CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE) &&
1634 !(dmt_flags & DM_VERITY_ON_CORRUPTION_SUPPORTED)) {
1635 log_err(cd, _("Requested dm-verity data corruption handling options are not supported."));
1639 if (dmd->flags & CRYPT_ACTIVATE_TASKLETS &&
1640 !(dmt_flags & DM_VERITY_TASKLETS_SUPPORTED)) {
1641 log_err(cd, _("Requested dm-verity tasklets option is not supported."));
1645 if (dmd->flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION &&
1646 !(dmt_flags & DM_VERITY_PANIC_CORRUPTION_SUPPORTED)) {
1647 log_err(cd, _("Requested dm-verity data corruption handling options are not supported."));
1651 if (dmd->segment.type == DM_VERITY &&
1652 dmd->segment.u.verity.fec_device && !(dmt_flags & DM_VERITY_FEC_SUPPORTED)) {
1653 log_err(cd, _("Requested dm-verity FEC options are not supported."));
1657 if (dmd->segment.type == DM_CRYPT) {
1658 if (dmd->segment.u.crypt.integrity && !(dmt_flags & DM_INTEGRITY_SUPPORTED)) {
1659 log_err(cd, _("Requested data integrity options are not supported."));
1662 if (dmd->segment.u.crypt.sector_size != SECTOR_SIZE && !(dmt_flags & DM_SECTOR_SIZE_SUPPORTED)) {
1663 log_err(cd, _("Requested sector_size option is not supported."));
1668 if (dmd->segment.type == DM_INTEGRITY && (dmd->flags & CRYPT_ACTIVATE_RECALCULATE) &&
1669 !(dmt_flags & DM_INTEGRITY_RECALC_SUPPORTED)) {
1670 log_err(cd, _("Requested automatic recalculation of integrity tags is not supported."));
1674 if (dmd->segment.type == DM_INTEGRITY && (dmd->flags & CRYPT_ACTIVATE_RECALCULATE_RESET) &&
1675 !(dmt_flags & DM_INTEGRITY_RESET_RECALC_SUPPORTED)) {
1676 log_err(cd, _("Requested automatic recalculation of integrity tags is not supported."));
1680 if (dmd->segment.type == DM_INTEGRITY && (dmd->flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) &&
1681 !(dmt_flags & DM_INTEGRITY_DISCARDS_SUPPORTED)) {
1682 log_err(cd, _("Discard/TRIM is not supported."));
1686 if (dmd->segment.type == DM_INTEGRITY && (dmd->flags & CRYPT_ACTIVATE_NO_JOURNAL_BITMAP) &&
1687 !(dmt_flags & DM_INTEGRITY_BITMAP_SUPPORTED)) {
1688 log_err(cd, _("Requested dm-integrity bitmap mode is not supported."));
1693 * Print warning if activating dm-crypt cipher_null device unless it's reencryption helper or
1694 * keyslot encryption helper device (LUKS1 cipher_null devices).
1696 if (!r && !(dmd->flags & CRYPT_ACTIVATE_PRIVATE) && single_segment(dmd) && dmd->segment.type == DM_CRYPT &&
1697 crypt_is_cipher_null(dmd->segment.u.crypt.cipher))
1698 log_dbg(cd, "Activated dm-crypt device with cipher_null. Device is not encrypted.");
1704 int dm_reload_device(struct crypt_device *cd, const char *name,
1705 struct crypt_dm_active_device *dmd, uint32_t dmflags, unsigned resume)
1713 if (dm_init_context(cd, dmd->segment.type))
1716 if (dm_flags(cd, DM_INTEGRITY, &dmt_flags) || !(dmt_flags & DM_INTEGRITY_RECALC_SUPPORTED))
1717 dmd->flags &= ~CRYPT_ACTIVATE_RECALCULATE;
1719 r = _dm_reload_device(cd, name, dmd);
1721 if (r == -EINVAL && (dmd->segment.type == DM_CRYPT || dmd->segment.type == DM_LINEAR)) {
1722 if ((dmd->flags & (CRYPT_ACTIVATE_SAME_CPU_CRYPT|CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS)) &&
1723 !dm_flags(cd, DM_CRYPT, &dmt_flags) && !(dmt_flags & (DM_SAME_CPU_CRYPT_SUPPORTED | DM_SUBMIT_FROM_CRYPT_CPUS_SUPPORTED)))
1724 log_err(cd, _("Requested dm-crypt performance options are not supported."));
1725 if ((dmd->flags & (CRYPT_ACTIVATE_NO_READ_WORKQUEUE | CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE)) &&
1726 !dm_flags(cd, DM_CRYPT, &dmt_flags) && !(dmt_flags & DM_CRYPT_NO_WORKQUEUE_SUPPORTED))
1727 log_err(cd, _("Requested dm-crypt performance options are not supported."));
1728 if ((dmd->flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) &&
1729 !dm_flags(cd, DM_CRYPT, &dmt_flags) && !(dmt_flags & DM_DISCARDS_SUPPORTED))
1730 log_err(cd, _("Discard/TRIM is not supported."));
1731 if ((dmd->flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) &&
1732 !dm_flags(cd, DM_INTEGRITY, &dmt_flags) && !(dmt_flags & DM_INTEGRITY_DISCARDS_SUPPORTED))
1733 log_err(cd, _("Discard/TRIM is not supported."));
1737 r = _dm_resume_device(name, dmflags | act2dmflags(dmd->flags));
1743 static int dm_status_dmi(const char *name, struct dm_info *dmi,
1744 const char *target, char **status_line)
1746 struct dm_task *dmt;
1747 uint64_t start, length;
1748 char *target_type, *params = NULL;
1751 if (!(dmt = dm_task_create(DM_DEVICE_STATUS)))
1754 if (!dm_task_no_flush(dmt))
1757 if (!dm_task_set_name(dmt, name))
1760 if (!dm_task_run(dmt))
1763 if (!dm_task_get_info(dmt, dmi))
1772 dm_get_next_target(dmt, NULL, &start, &length,
1773 &target_type, ¶ms);
1775 if (!target_type || start != 0)
1778 if (target && strcmp(target_type, target))
1781 /* for target == NULL check all supported */
1782 if (!target && (strcmp(target_type, DM_CRYPT_TARGET) &&
1783 strcmp(target_type, DM_VERITY_TARGET) &&
1784 strcmp(target_type, DM_INTEGRITY_TARGET) &&
1785 strcmp(target_type, DM_LINEAR_TARGET) &&
1786 strcmp(target_type, DM_ZERO_TARGET) &&
1787 strcmp(target_type, DM_ERROR_TARGET)))
1791 if (!r && status_line && !(*status_line = strdup(params)))
1794 dm_task_destroy(dmt);
1799 int dm_status_device(struct crypt_device *cd, const char *name)
1805 /* libdevmapper is too clever and handles
1806 * path argument differently with error.
1807 * Fail early here if parameter is non-existent path.
1809 if (strchr(name, '/') && stat(name, &st) < 0)
1812 if (dm_init_context(cd, DM_UNKNOWN))
1814 r = dm_status_dmi(name, &dmi, NULL, NULL);
1820 return (dmi.open_count > 0) ? 1 : 0;
1823 int dm_status_suspended(struct crypt_device *cd, const char *name)
1828 if (dm_init_context(cd, DM_UNKNOWN))
1830 r = dm_status_dmi(name, &dmi, NULL, NULL);
1836 return dmi.suspended ? 1 : 0;
1839 static int _dm_status_verity_ok(struct crypt_device *cd, const char *name)
1843 char *status_line = NULL;
1845 r = dm_status_dmi(name, &dmi, DM_VERITY_TARGET, &status_line);
1846 if (r < 0 || !status_line) {
1851 log_dbg(cd, "Verity volume %s status is %s.", name, status_line ?: "");
1852 r = status_line[0] == 'V' ? 1 : 0;
1858 int dm_status_verity_ok(struct crypt_device *cd, const char *name)
1862 if (dm_init_context(cd, DM_VERITY))
1864 r = _dm_status_verity_ok(cd, name);
1869 int dm_status_integrity_failures(struct crypt_device *cd, const char *name, uint64_t *count)
1873 char *status_line = NULL;
1875 if (dm_init_context(cd, DM_INTEGRITY))
1878 r = dm_status_dmi(name, &dmi, DM_INTEGRITY_TARGET, &status_line);
1879 if (r < 0 || !status_line) {
1885 log_dbg(cd, "Integrity volume %s failure status is %s.", name, status_line ?: "");
1886 *count = strtoull(status_line, NULL, 10);
1893 /* FIXME use hex wrapper, user val wrappers for line parsing */
1894 static int _dm_target_query_crypt(struct crypt_device *cd, uint32_t get_flags,
1895 char *params, struct dm_target *tgt,
1896 uint32_t *act_flags)
1899 char *rcipher, *rintegrity, *key_, *rdevice, *endp, buffer[3], *arg, *key_desc;
1900 unsigned int i, val;
1903 struct device *data_device = NULL;
1904 char *cipher = NULL, *integrity = NULL;
1905 struct volume_key *vk = NULL;
1907 tgt->type = DM_CRYPT;
1908 tgt->direction = TARGET_QUERY;
1909 tgt->u.crypt.sector_size = SECTOR_SIZE;
1913 rcipher = strsep(¶ms, " ");
1917 key_ = strsep(¶ms, " ");
1920 val64 = strtoull(params, ¶ms, 10);
1925 tgt->u.crypt.iv_offset = val64;
1928 rdevice = strsep(¶ms, " ");
1929 if (get_flags & DM_ACTIVE_DEVICE) {
1930 arg = crypt_lookup_dev(rdevice);
1931 r = device_alloc(cd, &data_device, arg);
1933 if (r < 0 && r != -ENOTBLK)
1942 val64 = strtoull(params, ¶ms, 10);
1943 tgt->u.crypt.offset = val64;
1945 tgt->u.crypt.tag_size = 0;
1947 /* Features section, available since crypt target version 1.11 */
1953 /* Number of arguments */
1954 val64 = strtoull(params, ¶ms, 10);
1959 for (i = 0; i < val64; i++) {
1962 arg = strsep(¶ms, " ");
1963 if (!strcasecmp(arg, "allow_discards"))
1964 *act_flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
1965 else if (!strcasecmp(arg, "same_cpu_crypt"))
1966 *act_flags |= CRYPT_ACTIVATE_SAME_CPU_CRYPT;
1967 else if (!strcasecmp(arg, "submit_from_crypt_cpus"))
1968 *act_flags |= CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS;
1969 else if (!strcasecmp(arg, "no_read_workqueue"))
1970 *act_flags |= CRYPT_ACTIVATE_NO_READ_WORKQUEUE;
1971 else if (!strcasecmp(arg, "no_write_workqueue"))
1972 *act_flags |= CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE;
1973 else if (!strcasecmp(arg, "iv_large_sectors"))
1974 *act_flags |= CRYPT_ACTIVATE_IV_LARGE_SECTORS;
1975 else if (sscanf(arg, "integrity:%u:", &val) == 1) {
1976 tgt->u.crypt.tag_size = val;
1977 rintegrity = strchr(arg + strlen("integrity:"), ':');
1981 } else if (sscanf(arg, "sector_size:%u", &val) == 1) {
1982 tgt->u.crypt.sector_size = val;
1983 } else /* unknown option */
1987 /* All parameters should be processed */
1993 if (get_flags & DM_ACTIVE_CRYPT_CIPHER) {
1994 r = crypt_capi_to_cipher(&cipher, &integrity, rcipher, rintegrity);
2002 *act_flags |= CRYPT_ACTIVATE_KEYRING_KEY;
2004 if (get_flags & DM_ACTIVE_CRYPT_KEYSIZE) {
2005 /* we will trust kernel the key_string is in expected format */
2006 if (key_[0] == ':') {
2007 if (sscanf(key_ + 1, "%zu", &key_size) != 1)
2010 key_size = strlen(key_) / 2;
2012 vk = crypt_alloc_volume_key(key_size, NULL);
2018 if (get_flags & DM_ACTIVE_CRYPT_KEY) {
2019 if (key_[0] == ':') {
2020 /* :<key_size>:<key_type>:<key_description> */
2022 endp = strpbrk(key_ + 1, ":");
2024 key_desc = strpbrk(endp + 1, ":");
2030 crypt_volume_key_set_description(vk, key_desc);
2033 for(i = 0; i < vk->keylength; i++) {
2034 memcpy(buffer, &key_[i * 2], 2);
2035 vk->key[i] = strtoul(buffer, &endp, 16);
2036 if (endp != &buffer[2]) {
2044 memset(key_, 0, strlen(key_));
2047 tgt->u.crypt.cipher = cipher;
2049 tgt->u.crypt.integrity = integrity;
2051 tgt->data_device = data_device;
2053 tgt->u.crypt.vk = vk;
2058 device_free(cd, data_device);
2059 crypt_free_volume_key(vk);
2063 static int _dm_target_query_verity(struct crypt_device *cd,
2066 struct dm_target *tgt,
2067 uint32_t *act_flags)
2069 struct crypt_params_verity *vp = NULL;
2073 char *str, *str2, *arg;
2074 unsigned int i, features;
2076 struct device *data_device = NULL, *hash_device = NULL, *fec_device = NULL;
2077 char *hash_name = NULL, *root_hash = NULL, *salt = NULL, *fec_dev_str = NULL;
2078 char *root_hash_sig_key_desc = NULL;
2080 if (get_flags & DM_ACTIVE_VERITY_PARAMS) {
2081 vp = crypt_zalloc(sizeof(*vp));
2086 tgt->type = DM_VERITY;
2087 tgt->direction = TARGET_QUERY;
2088 tgt->u.verity.vp = vp;
2091 val32 = strtoul(params, ¶ms, 10);
2095 vp->hash_type = val32;
2099 str = strsep(¶ms, " ");
2102 if (get_flags & DM_ACTIVE_DEVICE) {
2103 str2 = crypt_lookup_dev(str);
2104 r = device_alloc(cd, &data_device, str2);
2106 if (r < 0 && r != -ENOTBLK)
2113 str = strsep(¶ms, " ");
2116 if (get_flags & DM_ACTIVE_VERITY_HASH_DEVICE) {
2117 str2 = crypt_lookup_dev(str);
2118 r = device_alloc(cd, &hash_device, str2);
2120 if (r < 0 && r != -ENOTBLK)
2126 /* data block size*/
2127 val32 = strtoul(params, ¶ms, 10);
2131 vp->data_block_size = val32;
2134 /* hash block size */
2135 val32 = strtoul(params, ¶ms, 10);
2139 vp->hash_block_size = val32;
2143 val64 = strtoull(params, ¶ms, 10);
2147 vp->data_size = val64;
2151 val64 = strtoull(params, ¶ms, 10);
2154 tgt->u.verity.hash_offset = val64;
2157 /* hash algorithm */
2158 str = strsep(¶ms, " ");
2162 hash_name = strdup(str);
2170 str = strsep(¶ms, " ");
2173 len = crypt_hex_to_bytes(str, &str2, 0);
2178 tgt->u.verity.root_hash_size = len;
2179 if (get_flags & DM_ACTIVE_VERITY_ROOT_HASH)
2185 str = strsep(¶ms, " ");
2187 if (!strcmp(str, "-")) {
2191 len = crypt_hex_to_bytes(str, &str2, 0);
2196 vp->salt_size = len;
2203 /* Features section, available since verity target version 1.3 */
2205 /* Number of arguments */
2206 val64 = strtoull(params, ¶ms, 10);
2211 features = (int)val64;
2212 for (i = 0; i < features; i++) {
2216 arg = strsep(¶ms, " ");
2217 if (!strcasecmp(arg, "ignore_corruption"))
2218 *act_flags |= CRYPT_ACTIVATE_IGNORE_CORRUPTION;
2219 else if (!strcasecmp(arg, "restart_on_corruption"))
2220 *act_flags |= CRYPT_ACTIVATE_RESTART_ON_CORRUPTION;
2221 else if (!strcasecmp(arg, "panic_on_corruption"))
2222 *act_flags |= CRYPT_ACTIVATE_PANIC_ON_CORRUPTION;
2223 else if (!strcasecmp(arg, "ignore_zero_blocks"))
2224 *act_flags |= CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS;
2225 else if (!strcasecmp(arg, "check_at_most_once"))
2226 *act_flags |= CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE;
2227 else if (!strcasecmp(arg, "try_verify_in_tasklet"))
2228 *act_flags |= CRYPT_ACTIVATE_TASKLETS;
2229 else if (!strcasecmp(arg, "use_fec_from_device")) {
2230 str = strsep(¶ms, " ");
2231 str2 = crypt_lookup_dev(str);
2232 if (get_flags & DM_ACTIVE_VERITY_HASH_DEVICE) {
2233 r = device_alloc(cd, &fec_device, str2);
2234 if (r < 0 && r != -ENOTBLK) {
2245 } else if (!strcasecmp(arg, "fec_start")) {
2246 val64 = strtoull(params, ¶ms, 10);
2249 tgt->u.verity.fec_offset = val64;
2251 vp->fec_area_offset = val64 * vp->hash_block_size;
2253 } else if (!strcasecmp(arg, "fec_blocks")) {
2254 val64 = strtoull(params, ¶ms, 10);
2257 tgt->u.verity.fec_blocks = val64;
2259 } else if (!strcasecmp(arg, "fec_roots")) {
2260 val32 = strtoul(params, ¶ms, 10);
2264 vp->fec_roots = val32;
2266 } else if (!strcasecmp(arg, "root_hash_sig_key_desc")) {
2267 str = strsep(¶ms, " ");
2270 if (vp && !root_hash_sig_key_desc) {
2271 root_hash_sig_key_desc = strdup(str);
2272 if (!root_hash_sig_key_desc) {
2276 /* not stored in params, but cannot be used without vp */
2277 vp->flags |= CRYPT_VERITY_ROOT_HASH_SIGNATURE;
2280 } else /* unknown option */
2284 /* All parameters should be processed */
2285 if (params && *params) {
2292 tgt->data_device = data_device;
2294 tgt->u.verity.hash_device = hash_device;
2296 tgt->u.verity.fec_device = fec_device;
2298 tgt->u.verity.root_hash = root_hash;
2299 if (vp && hash_name)
2300 vp->hash_name = hash_name;
2303 if (vp && fec_dev_str)
2304 vp->fec_device = fec_dev_str;
2305 if (root_hash_sig_key_desc)
2306 tgt->u.verity.root_hash_sig_key_desc = root_hash_sig_key_desc;
2310 device_free(cd, data_device);
2311 device_free(cd, hash_device);
2312 device_free(cd, fec_device);
2313 free(root_hash_sig_key_desc);
2322 static int _dm_target_query_integrity(struct crypt_device *cd,
2325 struct dm_target *tgt,
2326 uint32_t *act_flags)
2330 char c, *str, *str2, *arg;
2331 unsigned int i, features, val;
2334 struct device *data_device = NULL, *meta_device = NULL;
2335 char *integrity = NULL, *journal_crypt = NULL, *journal_integrity = NULL;
2336 struct volume_key *vk = NULL;
2337 struct volume_key *journal_integrity_key = NULL;
2338 struct volume_key *journal_crypt_key = NULL;
2340 tgt->type = DM_INTEGRITY;
2341 tgt->direction = TARGET_QUERY;
2344 str = strsep(¶ms, " ");
2345 if (get_flags & DM_ACTIVE_DEVICE) {
2346 str2 = crypt_lookup_dev(str);
2347 r = device_alloc(cd, &data_device, str2);
2349 if (r < 0 && r != -ENOTBLK)
2358 val64 = strtoull(params, ¶ms, 10);
2359 if (!*params || *params != ' ')
2361 tgt->u.integrity.offset = val64;
2364 val32 = strtoul(params, ¶ms, 10);
2365 tgt->u.integrity.tag_size = val32;
2366 if (!*params || *params != ' ')
2370 c = toupper(*(++params));
2371 if (!*params || *(++params) != ' ' || (c != 'D' && c != 'J' && c != 'R' && c != 'B'))
2374 *act_flags |= CRYPT_ACTIVATE_NO_JOURNAL;
2376 *act_flags |= CRYPT_ACTIVATE_RECOVERY;
2378 *act_flags |= CRYPT_ACTIVATE_NO_JOURNAL;
2379 *act_flags |= CRYPT_ACTIVATE_NO_JOURNAL_BITMAP;
2382 tgt->u.integrity.sector_size = SECTOR_SIZE;
2384 /* Features section */
2386 /* Number of arguments */
2387 val64 = strtoull(params, ¶ms, 10);
2392 features = (int)val64;
2393 for (i = 0; i < features; i++) {
2397 arg = strsep(¶ms, " ");
2398 if (sscanf(arg, "journal_sectors:%u", &val) == 1)
2399 tgt->u.integrity.journal_size = val * SECTOR_SIZE;
2400 else if (sscanf(arg, "journal_watermark:%u", &val) == 1)
2401 tgt->u.integrity.journal_watermark = val;
2402 else if (sscanf(arg, "sectors_per_bit:%" PRIu64, &val64) == 1) {
2403 if (val64 > UINT_MAX)
2405 /* overloaded value for bitmap mode */
2406 tgt->u.integrity.journal_watermark = (unsigned int)val64;
2407 } else if (sscanf(arg, "commit_time:%u", &val) == 1)
2408 tgt->u.integrity.journal_commit_time = val;
2409 else if (sscanf(arg, "bitmap_flush_interval:%u", &val) == 1)
2410 /* overloaded value for bitmap mode */
2411 tgt->u.integrity.journal_commit_time = val;
2412 else if (sscanf(arg, "interleave_sectors:%u", &val) == 1)
2413 tgt->u.integrity.interleave_sectors = val;
2414 else if (sscanf(arg, "block_size:%u", &val) == 1)
2415 tgt->u.integrity.sector_size = val;
2416 else if (sscanf(arg, "buffer_sectors:%u", &val) == 1)
2417 tgt->u.integrity.buffer_sectors = val;
2418 else if (!strncmp(arg, "internal_hash:", 14) && !integrity) {
2420 arg = strsep(&str, ":");
2421 if (get_flags & DM_ACTIVE_INTEGRITY_PARAMS) {
2422 integrity = strdup(arg);
2430 len = crypt_hex_to_bytes(str, &str2, 1);
2437 if (get_flags & DM_ACTIVE_CRYPT_KEY) {
2438 vk = crypt_alloc_volume_key(len, str2);
2441 } else if (get_flags & DM_ACTIVE_CRYPT_KEYSIZE) {
2442 vk = crypt_alloc_volume_key(len, NULL);
2446 crypt_safe_free(str2);
2450 } else if (!strncmp(arg, "meta_device:", 12) && !meta_device) {
2451 if (get_flags & DM_ACTIVE_DEVICE) {
2452 str = crypt_lookup_dev(&arg[12]);
2453 r = device_alloc(cd, &meta_device, str);
2455 if (r < 0 && r != -ENOTBLK)
2458 } else if (!strncmp(arg, "journal_crypt:", 14) && !journal_crypt) {
2460 arg = strsep(&str, ":");
2461 if (get_flags & DM_ACTIVE_INTEGRITY_PARAMS) {
2462 journal_crypt = strdup(arg);
2463 if (!journal_crypt) {
2470 len = crypt_hex_to_bytes(str, &str2, 1);
2477 if (get_flags & DM_ACTIVE_JOURNAL_CRYPT_KEY) {
2478 journal_crypt_key = crypt_alloc_volume_key(len, str2);
2479 if (!journal_crypt_key)
2481 } else if (get_flags & DM_ACTIVE_JOURNAL_CRYPT_KEYSIZE) {
2482 journal_crypt_key = crypt_alloc_volume_key(len, NULL);
2483 if (!journal_crypt_key)
2486 crypt_safe_free(str2);
2490 } else if (!strncmp(arg, "journal_mac:", 12) && !journal_integrity) {
2492 arg = strsep(&str, ":");
2493 if (get_flags & DM_ACTIVE_INTEGRITY_PARAMS) {
2494 journal_integrity = strdup(arg);
2495 if (!journal_integrity) {
2502 len = crypt_hex_to_bytes(str, &str2, 1);
2509 if (get_flags & DM_ACTIVE_JOURNAL_MAC_KEY) {
2510 journal_integrity_key = crypt_alloc_volume_key(len, str2);
2511 if (!journal_integrity_key)
2513 } else if (get_flags & DM_ACTIVE_JOURNAL_MAC_KEYSIZE) {
2514 journal_integrity_key = crypt_alloc_volume_key(len, NULL);
2515 if (!journal_integrity_key)
2518 crypt_safe_free(str2);
2522 } else if (!strcmp(arg, "recalculate")) {
2523 *act_flags |= CRYPT_ACTIVATE_RECALCULATE;
2524 } else if (!strcmp(arg, "reset_recalculate")) {
2525 *act_flags |= CRYPT_ACTIVATE_RECALCULATE_RESET;
2526 } else if (!strcmp(arg, "fix_padding")) {
2527 tgt->u.integrity.fix_padding = true;
2528 } else if (!strcmp(arg, "fix_hmac")) {
2529 tgt->u.integrity.fix_hmac = true;
2530 } else if (!strcmp(arg, "legacy_recalculate")) {
2531 tgt->u.integrity.legacy_recalc = true;
2532 } else if (!strcmp(arg, "allow_discards")) {
2533 *act_flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
2534 } else /* unknown option */
2538 /* All parameters should be processed */
2539 if (params && *params) {
2546 tgt->data_device = data_device;
2548 tgt->u.integrity.meta_device = meta_device;
2550 tgt->u.integrity.integrity = integrity;
2552 tgt->u.integrity.journal_crypt = journal_crypt;
2553 if (journal_integrity)
2554 tgt->u.integrity.journal_integrity = journal_integrity;
2556 tgt->u.integrity.vk = vk;
2557 if (journal_integrity_key)
2558 tgt->u.integrity.journal_integrity_key = journal_integrity_key;
2559 if (journal_crypt_key)
2560 tgt->u.integrity.journal_crypt_key = journal_crypt_key;
2563 device_free(cd, data_device);
2564 device_free(cd, meta_device);
2566 free(journal_crypt);
2567 free(journal_integrity);
2568 crypt_free_volume_key(vk);
2569 crypt_free_volume_key(journal_integrity_key);
2570 crypt_free_volume_key(journal_crypt_key);
2574 static int _dm_target_query_linear(struct crypt_device *cd, struct dm_target *tgt,
2575 uint32_t get_flags, char *params)
2578 char *rdevice, *arg;
2580 struct device *device = NULL;
2583 rdevice = strsep(¶ms, " ");
2584 if (get_flags & DM_ACTIVE_DEVICE) {
2585 arg = crypt_lookup_dev(rdevice);
2586 r = device_alloc(cd, &device, arg);
2588 if (r < 0 && r != -ENOTBLK)
2597 val64 = strtoull(params, ¶ms, 10);
2599 /* params should be empty now */
2603 tgt->type = DM_LINEAR;
2604 tgt->direction = TARGET_QUERY;
2605 tgt->data_device = device;
2606 tgt->u.linear.offset = val64;
2610 device_free(cd, device);
2614 static int _dm_target_query_error(struct dm_target *tgt)
2616 tgt->type = DM_ERROR;
2617 tgt->direction = TARGET_QUERY;
2622 static int _dm_target_query_zero(struct dm_target *tgt)
2624 tgt->type = DM_ZERO;
2625 tgt->direction = TARGET_QUERY;
2631 * on error retval has to be negative
2633 * also currently any _dm_target_query fn does not perform cleanup on error
2635 static int dm_target_query(struct crypt_device *cd, struct dm_target *tgt, const uint64_t *start,
2636 const uint64_t *length, const char *target_type,
2637 char *params, uint32_t get_flags, uint32_t *act_flags)
2641 if (!strcmp(target_type, DM_CRYPT_TARGET))
2642 r = _dm_target_query_crypt(cd, get_flags, params, tgt, act_flags);
2643 else if (!strcmp(target_type, DM_VERITY_TARGET))
2644 r = _dm_target_query_verity(cd, get_flags, params, tgt, act_flags);
2645 else if (!strcmp(target_type, DM_INTEGRITY_TARGET))
2646 r = _dm_target_query_integrity(cd, get_flags, params, tgt, act_flags);
2647 else if (!strcmp(target_type, DM_LINEAR_TARGET))
2648 r = _dm_target_query_linear(cd, tgt, get_flags, params);
2649 else if (!strcmp(target_type, DM_ERROR_TARGET))
2650 r = _dm_target_query_error(tgt);
2651 else if (!strcmp(target_type, DM_ZERO_TARGET))
2652 r = _dm_target_query_zero(tgt);
2655 tgt->offset = *start;
2656 tgt->size = *length;
2662 static int _dm_query_device(struct crypt_device *cd, const char *name,
2663 uint32_t get_flags, struct crypt_dm_active_device *dmd)
2665 struct dm_target *t;
2666 struct dm_task *dmt;
2668 uint64_t start, length;
2669 char *target_type, *params;
2670 const char *tmp_uuid;
2676 if (!(dmt = dm_task_create(DM_DEVICE_TABLE)))
2678 if (!dm_task_secure_data(dmt))
2680 if (!dm_task_set_name(dmt, name))
2683 if (!dm_task_run(dmt))
2687 if (!dm_task_get_info(dmt, &dmi))
2695 if (dmi.target_count <= 0) {
2700 /* Never allow one to return empty key */
2701 if ((get_flags & DM_ACTIVE_CRYPT_KEY) && dmi.suspended) {
2702 log_dbg(cd, "Cannot read volume key while suspended.");
2707 r = dm_targets_allocate(&dmd->segment, dmi.target_count);
2712 next = dm_get_next_target(dmt, next, &start, &length,
2713 &target_type, ¶ms);
2715 r = dm_target_query(cd, t, &start, &length, target_type, params, get_flags, &dmd->flags);
2716 if (!r && t->type == DM_VERITY) {
2717 r = _dm_status_verity_ok(cd, name);
2719 dmd->flags |= CRYPT_ACTIVATE_CORRUPTED;
2724 log_err(cd, _("Failed to query dm-%s segment."), target_type);
2728 dmd->size += length;
2730 } while (next && t);
2733 dmd->flags |= CRYPT_ACTIVATE_READONLY;
2736 dmd->flags |= CRYPT_ACTIVATE_SUSPENDED;
2738 tmp_uuid = dm_task_get_uuid(dmt);
2740 dmd->flags |= CRYPT_ACTIVATE_NO_UUID;
2741 else if (get_flags & DM_ACTIVE_UUID) {
2742 if (!strncmp(tmp_uuid, DM_UUID_PREFIX, DM_UUID_PREFIX_LEN))
2743 dmd->uuid = strdup(tmp_uuid + DM_UUID_PREFIX_LEN);
2747 #if (HAVE_DECL_DM_DEVICE_HAS_HOLDERS && HAVE_DECL_DM_DEVICE_HAS_MOUNTED_FS)
2748 if (get_flags & DM_ACTIVE_HOLDERS)
2749 dmd->holders = (dm_device_has_mounted_fs(dmi.major, dmi.minor) ||
2750 dm_device_has_holders(dmi.major, dmi.minor));
2753 r = (dmi.open_count > 0);
2755 dm_task_destroy(dmt);
2758 dm_targets_free(cd, dmd);
2763 int dm_query_device(struct crypt_device *cd, const char *name,
2764 uint32_t get_flags, struct crypt_dm_active_device *dmd)
2771 memset(dmd, 0, sizeof(*dmd));
2773 if (dm_init_context(cd, DM_UNKNOWN))
2776 r = _dm_query_device(cd, name, get_flags, dmd);
2782 static int _process_deps(struct crypt_device *cd, const char *prefix, struct dm_deps *deps,
2783 char **names, size_t names_offset, size_t names_length)
2785 #if HAVE_DECL_DM_DEVICE_GET_NAME
2786 struct crypt_dm_active_device dmd;
2787 char dmname[PATH_MAX];
2789 int r, major, minor, count = 0;
2791 if (!prefix || !deps)
2794 for (i = 0; i < deps->count; i++) {
2795 major = major(deps->device[i]);
2796 if (!dm_is_dm_major(major))
2799 minor = minor(deps->device[i]);
2800 if (!dm_device_get_name(major, minor, 0, dmname, PATH_MAX))
2803 memset(&dmd, 0, sizeof(dmd));
2804 r = _dm_query_device(cd, dmname, DM_ACTIVE_UUID, &dmd);
2809 strncmp(prefix, dmd.uuid, strlen(prefix)) ||
2810 crypt_string_in(dmname, names, names_length))
2813 dm_targets_free(cd, &dmd);
2814 free(CONST_CAST(void*)dmd.uuid);
2816 if ((size_t)count >= (names_length - names_offset))
2819 if (*dmname && !(names[names_offset + count++] = strdup(dmname)))
2829 int dm_device_deps(struct crypt_device *cd, const char *name, const char *prefix,
2830 char **names, size_t names_length)
2832 struct dm_task *dmt;
2834 struct dm_deps *deps;
2836 size_t i, last = 0, offset = 0;
2838 if (!name || !names_length || !names)
2841 if (dm_init_context(cd, DM_UNKNOWN))
2845 if (!(dmt = dm_task_create(DM_DEVICE_DEPS)))
2847 if (!dm_task_set_name(dmt, name))
2851 if (!dm_task_run(dmt))
2855 if (!dm_task_get_info(dmt, &dmi))
2857 if (!(deps = dm_task_get_deps(dmt)))
2864 r = _process_deps(cd, prefix, deps, names, offset, names_length - 1);
2868 dm_task_destroy(dmt);
2872 name = names[last++];
2878 for (i = 0; i < names_length - 1; i++)
2884 dm_task_destroy(dmt);
2890 static int _dm_message(const char *name, const char *msg)
2893 struct dm_task *dmt;
2895 if (!(dmt = dm_task_create(DM_DEVICE_TARGET_MSG)))
2898 if (!dm_task_secure_data(dmt))
2901 if (name && !dm_task_set_name(dmt, name))
2904 if (!dm_task_set_sector(dmt, (uint64_t) 0))
2907 if (!dm_task_set_message(dmt, msg))
2910 r = dm_task_run(dmt);
2912 dm_task_destroy(dmt);
2916 int dm_suspend_device(struct crypt_device *cd, const char *name, uint32_t dmflags)
2921 if (dm_init_context(cd, DM_UNKNOWN))
2924 if (dmflags & DM_SUSPEND_WIPE_KEY) {
2925 if (dm_flags(cd, DM_CRYPT, &dmt_flags))
2928 if (!(dmt_flags & DM_KEY_WIPE_SUPPORTED))
2934 if (!_dm_simple(DM_DEVICE_SUSPEND, name, dmflags))
2937 if (dmflags & DM_SUSPEND_WIPE_KEY) {
2938 if (!_dm_message(name, "key wipe")) {
2939 _dm_resume_device(name, 0);
2950 int dm_resume_device(struct crypt_device *cd, const char *name, uint32_t dmflags)
2954 if (dm_init_context(cd, DM_UNKNOWN))
2957 r = _dm_resume_device(name, dmflags);
2964 int dm_resume_and_reinstate_key(struct crypt_device *cd, const char *name,
2965 const struct volume_key *vk)
2969 char *msg = NULL, *key = NULL;
2972 if (dm_init_context(cd, DM_CRYPT) || dm_flags(cd, DM_CRYPT, &dmt_flags))
2975 if (!(dmt_flags & DM_KEY_WIPE_SUPPORTED))
2979 msg_size = 11; // key set -
2980 else if (vk->key_description)
2981 msg_size = strlen(vk->key_description) + int_log10(vk->keylength) + 18;
2983 msg_size = vk->keylength * 2 + 10; // key set <key>
2985 msg = crypt_safe_alloc(msg_size);
2991 if (vk->key_description) {
2992 r = snprintf(msg, msg_size, "key set :%zu:logon:%s", vk->keylength, vk->key_description);
2994 key = crypt_bytes_to_hex(vk->keylength, vk->key);
3000 r = snprintf(msg, msg_size, "key set %s", key);
3002 if (r < 0 || r >= msg_size) {
3006 if (!_dm_message(name, msg) ||
3007 _dm_resume_device(name, 0)) {
3013 crypt_safe_free(msg);
3014 crypt_safe_free(key);
3019 int dm_cancel_deferred_removal(const char *name)
3021 return _dm_message(name, "@cancel_deferred_remove") ? 0 : -ENOTSUP;
3024 const char *dm_get_dir(void)
3029 int dm_is_dm_device(int major)
3031 return dm_is_dm_major((uint32_t)major);
3034 int dm_is_dm_kernel_name(const char *name)
3036 return strncmp(name, "dm-", 3) ? 0 : 1;
3039 int dm_crypt_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
3040 struct device *data_device, struct volume_key *vk, const char *cipher,
3041 uint64_t iv_offset, uint64_t data_offset, const char *integrity, uint32_t tag_size,
3042 uint32_t sector_size)
3044 char *dm_integrity = NULL;
3047 /* Space for IV metadata only */
3048 dm_integrity = strdup(integrity ?: "none");
3053 tgt->data_device = data_device;
3055 tgt->type = DM_CRYPT;
3056 tgt->direction = TARGET_SET;
3057 tgt->u.crypt.vk = vk;
3058 tgt->offset = seg_offset;
3059 tgt->size = seg_size;
3061 tgt->u.crypt.cipher = cipher;
3062 tgt->u.crypt.integrity = dm_integrity;
3063 tgt->u.crypt.iv_offset = iv_offset;
3064 tgt->u.crypt.offset = data_offset;
3065 tgt->u.crypt.tag_size = tag_size;
3066 tgt->u.crypt.sector_size = sector_size;
3071 int dm_verity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
3072 struct device *data_device, struct device *hash_device, struct device *fec_device,
3073 const char *root_hash, uint32_t root_hash_size, const char* root_hash_sig_key_desc,
3074 uint64_t hash_offset_block, uint64_t fec_blocks, struct crypt_params_verity *vp)
3076 if (!data_device || !hash_device || !vp)
3079 tgt->type = DM_VERITY;
3080 tgt->direction = TARGET_SET;
3081 tgt->offset = seg_offset;
3082 tgt->size = seg_size;
3083 tgt->data_device = data_device;
3085 tgt->u.verity.hash_device = hash_device;
3086 tgt->u.verity.fec_device = fec_device;
3087 tgt->u.verity.root_hash = root_hash;
3088 tgt->u.verity.root_hash_size = root_hash_size;
3089 tgt->u.verity.root_hash_sig_key_desc = root_hash_sig_key_desc;
3090 tgt->u.verity.hash_offset = hash_offset_block;
3091 tgt->u.verity.fec_offset = vp->fec_area_offset / vp->hash_block_size;
3092 tgt->u.verity.fec_blocks = fec_blocks;
3093 tgt->u.verity.vp = vp;
3098 int dm_integrity_target_set(struct crypt_device *cd,
3099 struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
3100 struct device *meta_device,
3101 struct device *data_device, uint64_t tag_size, uint64_t offset,
3102 uint32_t sector_size, struct volume_key *vk,
3103 struct volume_key *journal_crypt_key, struct volume_key *journal_mac_key,
3104 const struct crypt_params_integrity *ip)
3111 _dm_check_versions(cd, DM_INTEGRITY);
3113 tgt->type = DM_INTEGRITY;
3114 tgt->direction = TARGET_SET;
3115 tgt->offset = seg_offset;
3116 tgt->size = seg_size;
3117 tgt->data_device = data_device;
3118 if (meta_device != data_device)
3119 tgt->u.integrity.meta_device = meta_device;
3120 tgt->u.integrity.tag_size = tag_size;
3121 tgt->u.integrity.offset = offset;
3122 tgt->u.integrity.sector_size = sector_size;
3124 tgt->u.integrity.vk = vk;
3125 tgt->u.integrity.journal_crypt_key = journal_crypt_key;
3126 tgt->u.integrity.journal_integrity_key = journal_mac_key;
3128 if (!dm_flags(cd, DM_INTEGRITY, &dmi_flags) &&
3129 (dmi_flags & DM_INTEGRITY_FIX_PADDING_SUPPORTED) &&
3130 !(crypt_get_compatibility(cd) & CRYPT_COMPAT_LEGACY_INTEGRITY_PADDING))
3131 tgt->u.integrity.fix_padding = true;
3133 if (!dm_flags(cd, DM_INTEGRITY, &dmi_flags) &&
3134 (dmi_flags & DM_INTEGRITY_FIX_HMAC_SUPPORTED) &&
3135 !(crypt_get_compatibility(cd) & CRYPT_COMPAT_LEGACY_INTEGRITY_HMAC))
3136 tgt->u.integrity.fix_hmac = true;
3138 /* This flag can be backported, just try to set it always */
3139 if (crypt_get_compatibility(cd) & CRYPT_COMPAT_LEGACY_INTEGRITY_RECALC)
3140 tgt->u.integrity.legacy_recalc = true;
3143 tgt->u.integrity.journal_size = ip->journal_size;
3144 tgt->u.integrity.journal_watermark = ip->journal_watermark;
3145 tgt->u.integrity.journal_commit_time = ip->journal_commit_time;
3146 tgt->u.integrity.interleave_sectors = ip->interleave_sectors;
3147 tgt->u.integrity.buffer_sectors = ip->buffer_sectors;
3148 tgt->u.integrity.journal_integrity = ip->journal_integrity;
3149 tgt->u.integrity.journal_crypt = ip->journal_crypt;
3150 tgt->u.integrity.integrity = ip->integrity;
3156 int dm_linear_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
3157 struct device *data_device, uint64_t data_offset)
3162 tgt->type = DM_LINEAR;
3163 tgt->direction = TARGET_SET;
3164 tgt->offset = seg_offset;
3165 tgt->size = seg_size;
3166 tgt->data_device = data_device;
3168 tgt->u.linear.offset = data_offset;
3173 int dm_zero_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size)
3175 tgt->type = DM_ZERO;
3176 tgt->direction = TARGET_SET;
3177 tgt->offset = seg_offset;
3178 tgt->size = seg_size;