Imported Upstream version 2.6.1
[platform/upstream/cryptsetup.git] / lib / libdevmapper.c
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-2023 Red Hat, Inc. All rights reserved.
7  * Copyright (C) 2009-2023 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 "internal.h"
35
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"
42 #define RETRY_COUNT             5
43
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;
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         if (_dm_satisfies_version(1, 9, 0, verity_maj, verity_min, verity_patch))
208                 _dm_flags |= DM_VERITY_TASKLETS_SUPPORTED;
209
210         _dm_verity_checked = true;
211 }
212
213 static void _dm_set_integrity_compat(struct crypt_device *cd,
214                                      unsigned integrity_maj,
215                                      unsigned integrity_min,
216                                      unsigned integrity_patch)
217 {
218         if (_dm_integrity_checked || integrity_maj == 0)
219                 return;
220
221         log_dbg(cd, "Detected dm-integrity version %i.%i.%i.",
222                 integrity_maj, integrity_min, integrity_patch);
223
224         _dm_flags |= DM_INTEGRITY_SUPPORTED;
225
226         if (_dm_satisfies_version(1, 2, 0, integrity_maj, integrity_min, integrity_patch))
227                 _dm_flags |= DM_INTEGRITY_RECALC_SUPPORTED;
228
229         if (_dm_satisfies_version(1, 3, 0, integrity_maj, integrity_min, integrity_patch))
230                 _dm_flags |= DM_INTEGRITY_BITMAP_SUPPORTED;
231
232         if (_dm_satisfies_version(1, 4, 0, integrity_maj, integrity_min, integrity_patch))
233                 _dm_flags |= DM_INTEGRITY_FIX_PADDING_SUPPORTED;
234
235         if (_dm_satisfies_version(1, 6, 0, integrity_maj, integrity_min, integrity_patch))
236                 _dm_flags |= DM_INTEGRITY_DISCARDS_SUPPORTED;
237
238         if (_dm_satisfies_version(1, 7, 0, integrity_maj, integrity_min, integrity_patch))
239                 _dm_flags |= DM_INTEGRITY_FIX_HMAC_SUPPORTED;
240
241         if (_dm_satisfies_version(1, 8, 0, integrity_maj, integrity_min, integrity_patch))
242                 _dm_flags |= DM_INTEGRITY_RESET_RECALC_SUPPORTED;
243
244         _dm_integrity_checked = true;
245 }
246
247 static void _dm_set_zero_compat(struct crypt_device *cd,
248                                 unsigned zero_maj,
249                                 unsigned zero_min,
250                                 unsigned zero_patch)
251 {
252         if (_dm_zero_checked || zero_maj == 0)
253                 return;
254
255         log_dbg(cd, "Detected dm-zero version %i.%i.%i.",
256                 zero_maj, zero_min, zero_patch);
257
258         _dm_zero_checked = true;
259 }
260
261 /* We use this for loading target module */
262 static void _dm_check_target(dm_target_type target_type)
263 {
264 #if HAVE_DECL_DM_DEVICE_GET_TARGET_VERSION
265         struct dm_task *dmt;
266         const char *target_name = NULL;
267
268         if (!(_dm_flags & DM_GET_TARGET_VERSION_SUPPORTED))
269                 return;
270
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;
277         else
278                 return;
279
280         if (!(dmt = dm_task_create(DM_DEVICE_GET_TARGET_VERSION)))
281                 return;
282
283         if (dm_task_set_name(dmt, target_name))
284                 dm_task_run(dmt);
285
286         dm_task_destroy(dmt);
287 #endif
288 }
289
290 static int _dm_check_versions(struct crypt_device *cd, dm_target_type target_type)
291 {
292         struct dm_task *dmt;
293         struct dm_versions *target, *last_target;
294         char dm_version[16];
295         unsigned dm_maj, dm_min, dm_patch;
296         int r = 0;
297
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))
304                 return 1;
305
306         /* Shut up DM while checking */
307         _quiet_log = 1;
308
309         _dm_check_target(target_type);
310
311         if (!(dmt = dm_task_create(DM_DEVICE_LIST_VERSIONS)))
312                 goto out;
313
314         if (!dm_task_run(dmt))
315                 goto out;
316
317         if (!dm_task_get_driver_version(dmt, dm_version, sizeof(dm_version)))
318                 goto out;
319
320         if (!_dm_ioctl_checked) {
321                 if (sscanf(dm_version, "%u.%u.%u", &dm_maj, &dm_min, &dm_patch) != 3)
322                         goto out;
323                 log_dbg(cd, "Detected dm-ioctl version %u.%u.%u.", dm_maj, dm_min, dm_patch);
324
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;
330 #endif
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;
334 #endif
335         }
336
337         target = dm_task_get_versions(dmt);
338         do {
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]);
356                 }
357                 target = VOIDP_CAST(struct dm_versions *)((char *) target + target->next);
358         } while (last_target != target);
359
360         r = 1;
361         if (!_dm_ioctl_checked)
362                 log_dbg(cd, "Device-mapper backend running with UDEV support %sabled.",
363                         _dm_use_udev() ? "en" : "dis");
364
365         _dm_ioctl_checked = true;
366 out:
367         if (dmt)
368                 dm_task_destroy(dmt);
369
370         _quiet_log = 0;
371         return r;
372 }
373
374 int dm_flags(struct crypt_device *cd, dm_target_type target, uint32_t *flags)
375 {
376         _dm_check_versions(cd, target);
377         *flags = _dm_flags;
378
379         if (target == DM_UNKNOWN &&
380             _dm_crypt_checked && _dm_verity_checked && _dm_integrity_checked && _dm_zero_checked)
381                 return 0;
382
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 */
388                 return 0;
389
390         return -ENODEV;
391 }
392
393 /* This doesn't run any kernel checks, just set up userspace libdevmapper */
394 void dm_backend_init(struct crypt_device *cd)
395 {
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);
400         }
401 }
402
403 void dm_backend_exit(struct crypt_device *cd)
404 {
405         if (_dm_use_count && (!--_dm_use_count)) {
406                 log_dbg(cd, "Releasing device-mapper backend.");
407                 dm_log_init_verbose(0);
408                 dm_log_init(NULL);
409                 dm_lib_release();
410         }
411 }
412
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)
415 {
416         _context = cd;
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."));
421                 else
422                         log_err(cd, _("Cannot initialize device-mapper. "
423                                       "Is dm_mod kernel module loaded?"));
424                 _context = NULL;
425                 return -ENOTSUP;
426         }
427         return 0;
428 }
429 static void dm_exit_context(void)
430 {
431         _context = NULL;
432 }
433
434 /* Return path to DM device */
435 char *dm_device_path(const char *prefix, int major, int minor)
436 {
437         struct dm_task *dmt;
438         const char *name;
439         char path[PATH_MAX];
440
441         if (!(dmt = dm_task_create(DM_DEVICE_STATUS)))
442                 return NULL;
443         if (!dm_task_set_minor(dmt, minor) ||
444             !dm_task_set_major(dmt, major) ||
445             !dm_task_no_flush(dmt) ||
446             !dm_task_run(dmt) ||
447             !(name = dm_task_get_name(dmt))) {
448                 dm_task_destroy(dmt);
449                 return NULL;
450         }
451
452         if (snprintf(path, sizeof(path), "%s%s", prefix ?: "", name) < 0)
453                 path[0] = '\0';
454
455         dm_task_destroy(dmt);
456
457         return strdup(path);
458 }
459
460 char *dm_device_name(const char *path)
461 {
462         struct stat st;
463
464         if (stat(path, &st) < 0 || !S_ISBLK(st.st_mode))
465                 return NULL;
466
467         return dm_device_path(NULL, major(st.st_rdev), minor(st.st_rdev));
468 }
469
470 static size_t int_log10(uint64_t x)
471 {
472         uint64_t r = 0;
473         for (x /= 10; x > 0; x /= 10)
474                 r++;
475         return r;
476 }
477
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)
481 {
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];
485
486         if (!c_dm || !c_dm_size || !i_dm || !i_dm_size)
487                 return -EINVAL;
488
489         i = sscanf(org_c, "%" MAX_CAPI_ONE_LEN_STR "[^-]-%" MAX_CAPI_ONE_LEN_STR "s", cipher, tmp);
490         if (i != 2)
491                 return -EINVAL;
492
493         i = sscanf(tmp, "%" MAX_CAPI_ONE_LEN_STR "[^-]-%" MAX_CAPI_ONE_LEN_STR "s", mode, iv);
494         if (i == 1) {
495                 memset(iv, 0, sizeof(iv));
496                 strncpy(iv, mode, sizeof(iv)-1);
497                 *mode = '\0';
498                 if (snprintf(capi, sizeof(capi), "%s", cipher) < 0)
499                         return -EINVAL;
500         } else if (i == 2) {
501                 if (snprintf(capi, sizeof(capi), "%s(%s)", mode, cipher) < 0)
502                         return -EINVAL;
503         } else
504                 return -EINVAL;
505
506         if (!org_i) {
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);
526         } else {
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);
530         }
531
532         if (c_size < 0 || c_size == c_dm_size)
533                 return -EINVAL;
534         if (i_size < 0 || i_size == i_dm_size)
535                 return -EINVAL;
536
537         return 0;
538 }
539
540 static char *_uf(char *buf, size_t buf_size, const char *s, unsigned u)
541 {
542         size_t r = snprintf(buf, buf_size, " %s:%u", s, u);
543         assert(r > 0 && r < buf_size);
544         return buf;
545 }
546
547 /* https://gitlab.com/cryptsetup/cryptsetup/wikis/DMCrypt */
548 static char *get_dm_crypt_params(const struct dm_target *tgt, uint32_t flags)
549 {
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];
553
554         if (!tgt)
555                 return NULL;
556
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));
559         if (r < 0)
560                 return NULL;
561
562         if (flags & CRYPT_ACTIVATE_ALLOW_DISCARDS)
563                 num_options++;
564         if (flags & CRYPT_ACTIVATE_SAME_CPU_CRYPT)
565                 num_options++;
566         if (flags & CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS)
567                 num_options++;
568         if (flags & CRYPT_ACTIVATE_NO_READ_WORKQUEUE)
569                 num_options++;
570         if (flags & CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE)
571                 num_options++;
572         if (flags & CRYPT_ACTIVATE_IV_LARGE_SECTORS)
573                 num_options++;
574         if (tgt->u.crypt.integrity)
575                 num_options++;
576         if (tgt->u.crypt.sector_size != SECTOR_SIZE)
577                 num_options++;
578
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) : "",
589                 integrity_dm);
590                 if (r < 0 || (size_t)r >= sizeof(features))
591                         goto out;
592         } else
593                 *features = '\0';
594
595         if (crypt_is_cipher_null(cipher_dm))
596                 null_cipher = 1;
597
598         if (null_cipher)
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);
603                 if (!hexkey)
604                         goto out;
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)
607                         goto out;
608         } else
609                 hexkey = crypt_bytes_to_hex(tgt->u.crypt.vk->keylength, tgt->u.crypt.vk->key);
610
611         if (!hexkey)
612                 goto out;
613
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);
618         if (!params)
619                 goto out;
620
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,
624                      features);
625         if (r < 0 || r >= max_size) {
626                 crypt_safe_free(params);
627                 params = NULL;
628         }
629 out:
630         crypt_safe_free(hexkey);
631         return params;
632 }
633
634 /* https://gitlab.com/cryptsetup/cryptsetup/wikis/DMVerity */
635 static char *get_dm_verity_params(const struct dm_target *tgt, uint32_t flags)
636 {
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;
641
642         if (!tgt || !tgt->u.verity.vp)
643                 return NULL;
644
645         vp = tgt->u.verity.vp;
646
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;
654
655         if (flags & CRYPT_ACTIVATE_IGNORE_CORRUPTION)
656                 num_options++;
657         if (flags & CRYPT_ACTIVATE_RESTART_ON_CORRUPTION)
658                 num_options++;
659         if (flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION)
660                 num_options++;
661         if (flags & CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS)
662                 num_options++;
663         if (flags & CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE)
664                 num_options++;
665         if (flags & CRYPT_ACTIVATE_TASKLETS)
666                 num_options++;
667
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);
670         if (!fec_features)
671                 goto out;
672
673         if (tgt->u.verity.fec_device) {  /* MAX length 21 + path + 11 + int64 + 12 + int64 + 11 + int32 */
674                 num_options += 8;
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)
680                         goto out;
681         } else
682                 *fec_features = '\0';
683
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)
687                 goto out;
688         if (tgt->u.verity.root_hash_sig_key_desc) {  /* MAX length 24 + key_str */
689                 num_options += 2;
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)
693                         goto out;
694         } else
695                 *verity_verify_args = '\0';
696
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))
706                         goto out;
707         } else
708                 *features = '\0';
709
710         hexroot = crypt_bytes_to_hex(tgt->u.verity.root_hash_size, tgt->u.verity.root_hash);
711         if (!hexroot)
712                 goto out;
713
714         hexsalt = crypt_bytes_to_hex(vp->salt_size, vp->salt);
715         if (!hexsalt)
716                 goto out;
717
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);
723
724         params = crypt_safe_alloc(max_size);
725         if (!params)
726                 goto out;
727
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,
735                      verity_verify_args);
736         if (r < 0 || r >= max_size) {
737                 crypt_safe_free(params);
738                 params = NULL;
739         }
740 out:
741         crypt_safe_free(fec_features);
742         crypt_safe_free(verity_verify_args);
743         crypt_safe_free(hexroot);
744         crypt_safe_free(hexsalt);
745         return params;
746 }
747
748 static char *get_dm_integrity_params(const struct dm_target *tgt, uint32_t flags)
749 {
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;
753
754         if (!tgt)
755                 return NULL;
756
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;
768
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)
775                 goto out;
776
777         if (tgt->u.integrity.integrity) { /* MAX length 16 + str_integrity +  str_key */
778                 num_options++;
779
780                 if (tgt->u.integrity.vk) {
781                         hexkey = crypt_bytes_to_hex(tgt->u.integrity.vk->keylength, tgt->u.integrity.vk->key);
782                         if (!hexkey)
783                                 goto out;
784                 } else
785                         hexkey = NULL;
786
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)
791                         goto out;
792         }
793
794         if (tgt->u.integrity.journal_integrity) { /* MAX length 14 + str_journal_integrity + str_key */
795                 num_options++;
796
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);
800                         if (!hexkey)
801                                 goto out;
802                 } else
803                         hexkey = NULL;
804
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)
809                         goto out;
810         }
811
812         if (tgt->u.integrity.journal_crypt) { /* MAX length 15 + str_journal_crypt + str_key */
813                 num_options++;
814
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);
818                         if (!hexkey)
819                                 goto out;
820                 } else
821                         hexkey = NULL;
822
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)
827                         goto out;
828         }
829
830         if (tgt->u.integrity.journal_size)
831                 num_options++;
832         if (tgt->u.integrity.journal_watermark)
833                 num_options++;
834         if (tgt->u.integrity.journal_commit_time)
835                 num_options++;
836         if (tgt->u.integrity.interleave_sectors)
837                 num_options++;
838         if (tgt->u.integrity.sector_size)
839                 num_options++;
840         if (tgt->u.integrity.buffer_sectors)
841                 num_options++;
842         if (tgt->u.integrity.fix_padding)
843                 num_options++;
844         if (tgt->u.integrity.fix_hmac)
845                 num_options++;
846         if (tgt->u.integrity.legacy_recalc)
847                 num_options++;
848         if (tgt->u.integrity.meta_device)
849                 num_options++;
850         if (flags & CRYPT_ACTIVATE_RECALCULATE)
851                 num_options++;
852         if (flags & CRYPT_ACTIVATE_RECALCULATE_RESET)
853                 num_options++;
854         if (flags & CRYPT_ACTIVATE_ALLOW_DISCARDS)
855                 num_options++;
856
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)
886                 goto out;
887
888         if (flags & CRYPT_ACTIVATE_NO_JOURNAL_BITMAP)
889                 mode = 'B';
890         else if (flags & CRYPT_ACTIVATE_RECOVERY)
891                 mode = 'R';
892         else if (flags & CRYPT_ACTIVATE_NO_JOURNAL)
893                 mode = 'D';
894         else
895                 mode = 'J';
896
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)
901                 goto out;
902
903         params_out = params;
904 out:
905         crypt_safe_free(features);
906         crypt_safe_free(integrity);
907         crypt_safe_free(journal_integrity);
908         crypt_safe_free(journal_crypt);
909         if (!params_out)
910                 crypt_safe_free(params);
911
912         return params_out;
913 }
914
915 static char *get_dm_linear_params(const struct dm_target *tgt)
916 {
917         char *params;
918         int r;
919         int max_size = strlen(device_block_path(tgt->data_device)) + int_log10(tgt->u.linear.offset) + 3;
920
921         params = crypt_safe_alloc(max_size);
922         if (!params)
923                 return NULL;
924
925         r = snprintf(params, max_size, "%s %" PRIu64,
926                      device_block_path(tgt->data_device), tgt->u.linear.offset);
927
928         if (r < 0 || r >= max_size) {
929                 crypt_safe_free(params);
930                 params = NULL;
931         }
932
933         return params;
934 }
935
936 static char *get_dm_zero_params(void)
937 {
938         char *params = crypt_safe_alloc(1);
939         if (!params)
940                 return NULL;
941
942         params[0] = 0;
943         return params;
944 }
945
946 /* DM helpers */
947 static int _dm_remove(const char *name, int udev_wait, int deferred)
948 {
949         int r = 0;
950         struct dm_task *dmt;
951         uint32_t cookie = 0;
952
953         if (!_dm_use_udev())
954                 udev_wait = 0;
955
956         if (!(dmt = dm_task_create(DM_DEVICE_REMOVE)))
957                 return 0;
958
959         if (!dm_task_set_name(dmt, name))
960                 goto out;
961
962 #if HAVE_DECL_DM_TASK_RETRY_REMOVE
963         if (!dm_task_retry_remove(dmt))
964                 goto out;
965 #endif
966 #if HAVE_DECL_DM_TASK_DEFERRED_REMOVE
967         if (deferred && !dm_task_deferred_remove(dmt))
968                 goto out;
969 #endif
970         if (udev_wait && !_dm_task_set_cookie(dmt, &cookie, DM_UDEV_DISABLE_LIBRARY_FALLBACK))
971                 goto out;
972
973         r = dm_task_run(dmt);
974
975         if (udev_wait)
976                 (void)_dm_udev_wait(cookie);
977 out:
978         dm_task_destroy(dmt);
979         return r;
980 }
981
982 static int _dm_simple(int task, const char *name, uint32_t dmflags)
983 {
984         int r = 0;
985         struct dm_task *dmt;
986
987         if (!(dmt = dm_task_create(task)))
988                 return 0;
989
990         if (name && !dm_task_set_name(dmt, name))
991                 goto out;
992
993         if (task == DM_DEVICE_SUSPEND &&
994             (dmflags & DM_SUSPEND_SKIP_LOCKFS) && !dm_task_skip_lockfs(dmt))
995                 goto out;
996
997         if (task == DM_DEVICE_SUSPEND &&
998             (dmflags & DM_SUSPEND_NOFLUSH) && !dm_task_no_flush(dmt))
999                 goto out;
1000
1001         r = dm_task_run(dmt);
1002 out:
1003         dm_task_destroy(dmt);
1004         return r;
1005 }
1006
1007 static int _dm_resume_device(const char *name, uint32_t flags);
1008
1009 static int _error_device(const char *name, size_t size)
1010 {
1011         struct dm_task *dmt;
1012         int r = 0;
1013
1014         if (!(dmt = dm_task_create(DM_DEVICE_RELOAD)))
1015                 return 0;
1016
1017         if (!dm_task_set_name(dmt, name))
1018                 goto out;
1019
1020         if (!dm_task_add_target(dmt, UINT64_C(0), size, "error", ""))
1021                 goto out;
1022
1023         if (!dm_task_set_ro(dmt))
1024                 goto out;
1025
1026         if (!dm_task_no_open_count(dmt))
1027                 goto out;
1028
1029         if (!dm_task_run(dmt))
1030                 goto out;
1031
1032         if (_dm_resume_device(name, 0)) {
1033                 _dm_simple(DM_DEVICE_CLEAR, name, 0);
1034                 goto out;
1035         }
1036
1037         r = 1;
1038 out:
1039         dm_task_destroy(dmt);
1040         return r;
1041 }
1042
1043 int dm_error_device(struct crypt_device *cd, const char *name)
1044 {
1045         int r;
1046         struct crypt_dm_active_device dmd;
1047
1048         if (!name)
1049                 return -EINVAL;
1050
1051         if (dm_init_context(cd, DM_UNKNOWN))
1052                 return -ENOTSUP;
1053
1054         if ((dm_query_device(cd, name, 0, &dmd) >= 0) && _error_device(name, dmd.size))
1055                 r = 0;
1056         else
1057                 r = -EINVAL;
1058
1059         dm_targets_free(cd, &dmd);
1060
1061         dm_exit_context();
1062
1063         return r;
1064 }
1065
1066 int dm_clear_device(struct crypt_device *cd, const char *name)
1067 {
1068         int r;
1069
1070         if (!name)
1071                 return -EINVAL;
1072
1073         if (dm_init_context(cd, DM_UNKNOWN))
1074                 return -ENOTSUP;
1075
1076         if (_dm_simple(DM_DEVICE_CLEAR, name, 0))
1077                 r = 0;
1078         else
1079                 r = -EINVAL;
1080
1081         dm_exit_context();
1082
1083         return r;
1084 }
1085
1086 int dm_remove_device(struct crypt_device *cd, const char *name, uint32_t flags)
1087 {
1088         struct crypt_dm_active_device dmd = {};
1089         int r = -EINVAL;
1090         int retries = (flags & CRYPT_DEACTIVATE_FORCE) ? RETRY_COUNT : 1;
1091         int deferred = (flags & CRYPT_DEACTIVATE_DEFERRED) ? 1 : 0;
1092         int error_target = 0;
1093         uint32_t dmt_flags;
1094
1095         if (!name)
1096                 return -EINVAL;
1097
1098         if (dm_init_context(cd, DM_UNKNOWN))
1099                 return -ENOTSUP;
1100
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."));
1103                 dm_exit_context();
1104                 return -ENOTSUP;
1105         }
1106
1107         do {
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");
1112                         sleep(1);
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).
1119                                  */
1120                                 if (!dm_query_device(cd, name, 0, &dmd)) {
1121                                         _error_device(name, dmd.size);
1122                                         error_target = 1;
1123                                 }
1124                         }
1125                 }
1126         } while (r == -EINVAL && retries);
1127
1128         dm_task_update_nodes();
1129         dm_exit_context();
1130
1131         return r;
1132 }
1133
1134 #define UUID_LEN 37 /* 36 + \0, libuuid ... */
1135 /*
1136  * UUID has format: CRYPT-<devicetype>-[<uuid>-]<device name>
1137  * CRYPT-PLAIN-name
1138  * CRYPT-LUKS1-00000000000000000000000000000000-name
1139  * CRYPT-TEMP-name
1140  */
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)
1143 {
1144         char *ptr, uuid2[UUID_LEN] = {0};
1145         uuid_t uu;
1146         int i = 0;
1147
1148         /* Remove '-' chars */
1149         if (uuid) {
1150                 if (uuid_parse(uuid, uu) < 0) {
1151                         log_dbg(cd, "Requested UUID %s has invalid format.", uuid);
1152                         return 0;
1153                 }
1154
1155                 for (ptr = uuid2, i = 0; i < UUID_LEN; i++)
1156                         if (uuid[i] != '-') {
1157                                 *ptr = uuid[i];
1158                                 ptr++;
1159                         }
1160         }
1161
1162         i = snprintf(buf, buflen, DM_UUID_PREFIX "%s%s%s%s%s",
1163                 type ?: "", type ? "-" : "",
1164                 uuid2[0] ? uuid2 : "", uuid2[0] ? "-" : "",
1165                 name);
1166         if (i < 0)
1167                 return 0;
1168
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);
1172
1173         return 1;
1174 }
1175
1176 int lookup_dm_dev_by_uuid(struct crypt_device *cd, const char *uuid, const char *type)
1177 {
1178         int r_udev, r;
1179         char *c;
1180         char dev_uuid[DM_UUID_LEN + DM_BY_ID_PREFIX_LEN] = DM_BY_ID_PREFIX;
1181
1182         if (!dm_prepare_uuid(cd, "", type, uuid, dev_uuid + DM_BY_ID_PREFIX_LEN, DM_UUID_LEN))
1183                 return -EINVAL;
1184
1185         c = strrchr(dev_uuid, '-');
1186         if (!c)
1187                 return -EINVAL;
1188
1189         /* cut of dm name */
1190         *c = '\0';
1191
1192         /* Either udev or sysfs can report that device is active. */
1193         r = lookup_by_disk_id(dev_uuid);
1194         if (r > 0)
1195                 return r;
1196
1197         r_udev = r;
1198         r = lookup_by_sysfs_uuid_field(dev_uuid + DM_BY_ID_PREFIX_LEN);
1199
1200         return r == -ENOENT ? r_udev : r;
1201 }
1202
1203 static int _add_dm_targets(struct dm_task *dmt, struct crypt_dm_active_device *dmd)
1204 {
1205         const char *target;
1206         struct dm_target *tgt = &dmd->segment;
1207
1208         do {
1209                 switch (tgt->type) {
1210                 case DM_CRYPT:
1211                         target = DM_CRYPT_TARGET;
1212                         break;
1213                 case DM_VERITY:
1214                         target = DM_VERITY_TARGET;
1215                         break;
1216                 case DM_INTEGRITY:
1217                         target = DM_INTEGRITY_TARGET;
1218                         break;
1219                 case DM_LINEAR:
1220                         target = DM_LINEAR_TARGET;
1221                         break;
1222                 case DM_ZERO:
1223                         target = DM_ZERO_TARGET;
1224                         break;
1225                 default:
1226                         return -ENOTSUP;
1227                 }
1228
1229                 if (!dm_task_add_target(dmt, tgt->offset, tgt->size, target, tgt->params))
1230                         return -EINVAL;
1231
1232                 tgt = tgt->next;
1233         } while (tgt);
1234
1235         return 0;
1236 }
1237
1238 static void _destroy_dm_targets_params(struct crypt_dm_active_device *dmd)
1239 {
1240         struct dm_target *t = &dmd->segment;
1241
1242         do {
1243                 crypt_safe_free(t->params);
1244                 t->params = NULL;
1245                 t = t->next;
1246         } while (t);
1247 }
1248
1249 static int _create_dm_targets_params(struct crypt_dm_active_device *dmd)
1250 {
1251         int r;
1252         struct dm_target *tgt = &dmd->segment;
1253
1254         do {
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();
1265                 else {
1266                         r = -ENOTSUP;
1267                         goto err;
1268                 }
1269
1270                 if (!tgt->params) {
1271                         r = -EINVAL;
1272                         goto err;
1273                 }
1274                 tgt = tgt->next;
1275         } while (tgt);
1276
1277         return 0;
1278 err:
1279         _destroy_dm_targets_params(dmd);
1280         return r;
1281 }
1282
1283 static int _dm_create_device(struct crypt_device *cd, const char *name, const char *type,
1284                              struct crypt_dm_active_device *dmd)
1285 {
1286         struct dm_task *dmt = NULL;
1287         struct dm_info dmi;
1288         char dev_uuid[DM_UUID_LEN] = {0};
1289         int r = -EINVAL;
1290         uint32_t cookie = 0, read_ahead = 0;
1291         uint16_t udev_flags = DM_UDEV_DISABLE_LIBRARY_FALLBACK;
1292
1293         if (dmd->flags & CRYPT_ACTIVATE_PRIVATE)
1294                 udev_flags |= CRYPT_TEMP_UDEV_FLAGS;
1295
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)))
1298                 goto out;
1299
1300         if (!(dmt = dm_task_create(DM_DEVICE_CREATE)))
1301                 goto out;
1302
1303         if (!dm_task_set_name(dmt, name))
1304                 goto out;
1305
1306         if (!dm_task_set_uuid(dmt, dev_uuid))
1307                 goto out;
1308
1309         if (!dm_task_secure_data(dmt))
1310                 goto out;
1311         if ((dmd->flags & CRYPT_ACTIVATE_READONLY) && !dm_task_set_ro(dmt))
1312                 goto out;
1313
1314         r = _create_dm_targets_params(dmd);
1315         if (r)
1316                 goto out;
1317
1318         r = _add_dm_targets(dmt, dmd);
1319         if (r)
1320                 goto out;
1321
1322         r = -EINVAL;
1323
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))
1327                 goto out;
1328 #endif
1329         if (_dm_use_udev() && !_dm_task_set_cookie(dmt, &cookie, udev_flags))
1330                 goto out;
1331
1332         if (!dm_task_run(dmt)) {
1333                 r = dm_status_device(cd, name);;
1334                 if (r >= 0)
1335                         r = -EEXIST;
1336                 if (r != -EEXIST && r != -ENODEV)
1337                         r = -EINVAL;
1338                 goto out;
1339         }
1340
1341         if (dm_task_get_info(dmt, &dmi))
1342                 r = 0;
1343
1344         if (_dm_use_udev()) {
1345                 (void)_dm_udev_wait(cookie);
1346                 cookie = 0;
1347         }
1348
1349         if (r < 0)
1350                 _dm_remove(name, 1, 0);
1351
1352 out:
1353         if (cookie && _dm_use_udev())
1354                 (void)_dm_udev_wait(cookie);
1355
1356         if (dmt)
1357                 dm_task_destroy(dmt);
1358
1359         dm_task_update_nodes();
1360
1361         /* If code just loaded target module, update versions */
1362         _dm_check_versions(cd, dmd->segment.type);
1363
1364         _destroy_dm_targets_params(dmd);
1365
1366         return r;
1367 }
1368
1369 static int _dm_resume_device(const char *name, uint32_t dmflags)
1370 {
1371         struct dm_task *dmt;
1372         int r = -EINVAL;
1373         uint32_t cookie = 0;
1374         uint16_t udev_flags = DM_UDEV_DISABLE_LIBRARY_FALLBACK;
1375
1376         if (dmflags & DM_RESUME_PRIVATE)
1377                 udev_flags |= CRYPT_TEMP_UDEV_FLAGS;
1378
1379         if (!(dmt = dm_task_create(DM_DEVICE_RESUME)))
1380                 return r;
1381
1382         if (!dm_task_set_name(dmt, name))
1383                 goto out;
1384
1385         if ((dmflags & DM_SUSPEND_SKIP_LOCKFS) && !dm_task_skip_lockfs(dmt))
1386                 goto out;
1387
1388         if ((dmflags & DM_SUSPEND_NOFLUSH) && !dm_task_no_flush(dmt))
1389                 goto out;
1390
1391         if (_dm_use_udev() && !_dm_task_set_cookie(dmt, &cookie, udev_flags))
1392                 goto out;
1393
1394         if (dm_task_run(dmt))
1395                 r = 0;
1396 out:
1397         if (cookie && _dm_use_udev())
1398                 (void)_dm_udev_wait(cookie);
1399
1400         dm_task_destroy(dmt);
1401
1402         dm_task_update_nodes();
1403
1404         return r;
1405 }
1406
1407 static int _dm_reload_device(struct crypt_device *cd, const char *name,
1408                              struct crypt_dm_active_device *dmd)
1409 {
1410         int r = -EINVAL;
1411         struct dm_task *dmt = NULL;
1412         uint32_t read_ahead = 0;
1413
1414         /* All devices must have DM_UUID, only resize on old device is exception */
1415         if (!(dmt = dm_task_create(DM_DEVICE_RELOAD)))
1416                 goto out;
1417
1418         if (!dm_task_set_name(dmt, name))
1419                 goto out;
1420
1421         if (!dm_task_secure_data(dmt))
1422                 goto out;
1423         if ((dmd->flags & CRYPT_ACTIVATE_READONLY) && !dm_task_set_ro(dmt))
1424                 goto out;
1425
1426         r = _create_dm_targets_params(dmd);
1427         if (r)
1428                 goto out;
1429
1430         r = _add_dm_targets(dmt, dmd);
1431         if (r)
1432                 goto out;
1433
1434         r = -EINVAL;
1435
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))
1439                 goto out;
1440 #endif
1441
1442         if (dm_task_run(dmt))
1443                 r = 0;
1444 out:
1445         if (dmt)
1446                 dm_task_destroy(dmt);
1447
1448         /* If code just loaded target module, update versions */
1449         _dm_check_versions(cd, dmd->segment.type);
1450
1451         _destroy_dm_targets_params(dmd);
1452
1453         return r;
1454 }
1455
1456 static void crypt_free_verity_params(struct crypt_params_verity *vp)
1457 {
1458         if (!vp)
1459                 return;
1460
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);
1466         free(vp);
1467 }
1468
1469 static void _dm_target_free_query_path(struct crypt_device *cd, struct dm_target *tgt)
1470 {
1471         switch(tgt->type) {
1472         case DM_CRYPT:
1473                 crypt_free_volume_key(tgt->u.crypt.vk);
1474                 free(CONST_CAST(void*)tgt->u.crypt.cipher);
1475                 break;
1476         case DM_INTEGRITY:
1477                 free(CONST_CAST(void*)tgt->u.integrity.integrity);
1478                 crypt_free_volume_key(tgt->u.integrity.vk);
1479
1480                 free(CONST_CAST(void*)tgt->u.integrity.journal_integrity);
1481                 crypt_free_volume_key(tgt->u.integrity.journal_integrity_key);
1482
1483                 free(CONST_CAST(void*)tgt->u.integrity.journal_crypt);
1484                 crypt_free_volume_key(tgt->u.integrity.journal_crypt_key);
1485
1486                 device_free(cd, tgt->u.integrity.meta_device);
1487                 break;
1488         case DM_VERITY:
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);
1493                 /* fall through */
1494         case DM_LINEAR:
1495                 /* fall through */
1496         case DM_ERROR:
1497                 /* fall through */
1498         case DM_ZERO:
1499                 break;
1500         default:
1501                 log_err(cd, _("Unknown dm target type."));
1502                 return;
1503         }
1504
1505         device_free(cd, tgt->data_device);
1506 }
1507
1508 static void _dm_target_erase(struct crypt_device *cd, struct dm_target *tgt)
1509 {
1510         if (tgt->direction == TARGET_EMPTY)
1511                 return;
1512
1513         if (tgt->direction == TARGET_QUERY)
1514                 _dm_target_free_query_path(cd, tgt);
1515
1516         if (tgt->type == DM_CRYPT)
1517                 free(CONST_CAST(void*)tgt->u.crypt.integrity);
1518 }
1519
1520 void dm_targets_free(struct crypt_device *cd, struct crypt_dm_active_device *dmd)
1521 {
1522         struct dm_target *t = &dmd->segment, *next = t->next;
1523
1524         _dm_target_erase(cd, t);
1525
1526         while (next) {
1527                 t = next;
1528                 next = t->next;
1529                 _dm_target_erase(cd, t);
1530                 free(t);
1531         }
1532
1533         memset(&dmd->segment, 0, sizeof(dmd->segment));
1534 }
1535
1536 int dm_targets_allocate(struct dm_target *first, unsigned count)
1537 {
1538         if (!first || first->next || !count)
1539                 return -EINVAL;
1540
1541         while (--count) {
1542                 first->next = crypt_zalloc(sizeof(*first));
1543                 if (!first->next)
1544                         return -ENOMEM;
1545                 first = first->next;
1546         }
1547
1548         return 0;
1549 }
1550
1551 static int check_retry(struct crypt_device *cd, uint32_t *dmd_flags, uint32_t dmt_flags)
1552 {
1553         int ret = 0;
1554
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;
1560                 ret = 1;
1561         }
1562
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;
1568                 ret = 1;
1569         }
1570
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);
1576                 ret = 1;
1577         }
1578
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);
1584                 ret = 1;
1585         }
1586
1587         return ret;
1588 }
1589
1590 int dm_create_device(struct crypt_device *cd, const char *name,
1591                      const char *type,
1592                      struct crypt_dm_active_device *dmd)
1593 {
1594         uint32_t dmt_flags = 0;
1595         int r = -EINVAL;
1596
1597         if (!type || !dmd)
1598                 return -EINVAL;
1599
1600         if (dm_init_context(cd, dmd->segment.type))
1601                 return -ENOTSUP;
1602
1603         r = _dm_create_device(cd, name, type, dmd);
1604         if (!r || r == -EEXIST)
1605                 goto out;
1606
1607         if (dm_flags(cd, dmd->segment.type, &dmt_flags))
1608                 goto out;
1609
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)
1615                         goto out;
1616         }
1617
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."));
1621                 r = -EINVAL;
1622         }
1623
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."));
1627                 r = -EINVAL;
1628         }
1629
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."));
1636                 r = -EINVAL;
1637         }
1638
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."));
1642                 r = -EINVAL;
1643         }
1644
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."));
1648                 r = -EINVAL;
1649         }
1650
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."));
1654                 r = -EINVAL;
1655         }
1656
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."));
1660                         r = -EINVAL;
1661                 }
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."));
1664                         r = -EINVAL;
1665                 }
1666         }
1667
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."));
1671                 r = -EINVAL;
1672         }
1673
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."));
1677                 r = -EINVAL;
1678         }
1679
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."));
1683                 r = -EINVAL;
1684         }
1685
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."));
1689                 r = -EINVAL;
1690         }
1691 out:
1692         /*
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).
1695          */
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.");
1699
1700         dm_exit_context();
1701         return r;
1702 }
1703
1704 int dm_reload_device(struct crypt_device *cd, const char *name,
1705                      struct crypt_dm_active_device *dmd, uint32_t dmflags, unsigned resume)
1706 {
1707         int r;
1708         uint32_t dmt_flags;
1709
1710         if (!dmd)
1711                 return -EINVAL;
1712
1713         if (dm_init_context(cd, dmd->segment.type))
1714                 return -ENOTSUP;
1715
1716         if (dm_flags(cd, DM_INTEGRITY, &dmt_flags) || !(dmt_flags & DM_INTEGRITY_RECALC_SUPPORTED))
1717                 dmd->flags &= ~CRYPT_ACTIVATE_RECALCULATE;
1718
1719         r = _dm_reload_device(cd, name, dmd);
1720
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."));
1734         }
1735
1736         if (!r && resume)
1737                 r = _dm_resume_device(name, dmflags | act2dmflags(dmd->flags));
1738
1739         dm_exit_context();
1740         return r;
1741 }
1742
1743 static int dm_status_dmi(const char *name, struct dm_info *dmi,
1744                           const char *target, char **status_line)
1745 {
1746         struct dm_task *dmt;
1747         uint64_t start, length;
1748         char *target_type, *params = NULL;
1749         int r = -EINVAL;
1750
1751         if (!(dmt = dm_task_create(DM_DEVICE_STATUS)))
1752                 return r;
1753
1754         if (!dm_task_no_flush(dmt))
1755                 goto out;
1756
1757         if (!dm_task_set_name(dmt, name))
1758                 goto out;
1759
1760         if (!dm_task_run(dmt))
1761                 goto out;
1762
1763         if (!dm_task_get_info(dmt, dmi))
1764                 goto out;
1765
1766         if (!dmi->exists) {
1767                 r = -ENODEV;
1768                 goto out;
1769         }
1770
1771         r = -EEXIST;
1772         dm_get_next_target(dmt, NULL, &start, &length,
1773                            &target_type, &params);
1774
1775         if (!target_type || start != 0)
1776                 goto out;
1777
1778         if (target && strcmp(target_type, target))
1779                 goto out;
1780
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)))
1788                 goto out;
1789         r = 0;
1790 out:
1791         if (!r && status_line && !(*status_line = strdup(params)))
1792                 r = -ENOMEM;
1793
1794         dm_task_destroy(dmt);
1795
1796         return r;
1797 }
1798
1799 int dm_status_device(struct crypt_device *cd, const char *name)
1800 {
1801         int r;
1802         struct dm_info dmi;
1803         struct stat st;
1804
1805         /* libdevmapper is too clever and handles
1806          * path argument differently with error.
1807          * Fail early here if parameter is non-existent path.
1808          */
1809         if (strchr(name, '/') && stat(name, &st) < 0)
1810                 return -ENODEV;
1811
1812         if (dm_init_context(cd, DM_UNKNOWN))
1813                 return -ENOTSUP;
1814         r = dm_status_dmi(name, &dmi, NULL, NULL);
1815         dm_exit_context();
1816
1817         if (r < 0)
1818                 return r;
1819
1820         return (dmi.open_count > 0) ? 1 : 0;
1821 }
1822
1823 int dm_status_suspended(struct crypt_device *cd, const char *name)
1824 {
1825         int r;
1826         struct dm_info dmi;
1827
1828         if (dm_init_context(cd, DM_UNKNOWN))
1829                 return -ENOTSUP;
1830         r = dm_status_dmi(name, &dmi, NULL, NULL);
1831         dm_exit_context();
1832
1833         if (r < 0)
1834                 return r;
1835
1836         return dmi.suspended ? 1 : 0;
1837 }
1838
1839 static int _dm_status_verity_ok(struct crypt_device *cd, const char *name)
1840 {
1841         int r;
1842         struct dm_info dmi;
1843         char *status_line = NULL;
1844
1845         r = dm_status_dmi(name, &dmi, DM_VERITY_TARGET, &status_line);
1846         if (r < 0 || !status_line) {
1847                 free(status_line);
1848                 return r;
1849         }
1850
1851         log_dbg(cd, "Verity volume %s status is %s.", name, status_line ?: "");
1852         r = status_line[0] == 'V' ? 1 : 0;
1853         free(status_line);
1854
1855         return r;
1856 }
1857
1858 int dm_status_verity_ok(struct crypt_device *cd, const char *name)
1859 {
1860         int r;
1861
1862         if (dm_init_context(cd, DM_VERITY))
1863                 return -ENOTSUP;
1864         r = _dm_status_verity_ok(cd, name);
1865         dm_exit_context();
1866         return r;
1867 }
1868
1869 int dm_status_integrity_failures(struct crypt_device *cd, const char *name, uint64_t *count)
1870 {
1871         int r;
1872         struct dm_info dmi;
1873         char *status_line = NULL;
1874
1875         if (dm_init_context(cd, DM_INTEGRITY))
1876                 return -ENOTSUP;
1877
1878         r = dm_status_dmi(name, &dmi, DM_INTEGRITY_TARGET, &status_line);
1879         if (r < 0 || !status_line) {
1880                 free(status_line);
1881                 dm_exit_context();
1882                 return r;
1883         }
1884
1885         log_dbg(cd, "Integrity volume %s failure status is %s.", name, status_line ?: "");
1886         *count = strtoull(status_line, NULL, 10);
1887         free(status_line);
1888         dm_exit_context();
1889
1890         return 0;
1891 }
1892
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)
1897 {
1898         uint64_t val64;
1899         char *rcipher, *rintegrity, *key_, *rdevice, *endp, buffer[3], *arg, *key_desc;
1900         unsigned int i, val;
1901         int r;
1902         size_t key_size;
1903         struct device *data_device = NULL;
1904         char *cipher = NULL, *integrity = NULL;
1905         struct volume_key *vk = NULL;
1906
1907         tgt->type = DM_CRYPT;
1908         tgt->direction = TARGET_QUERY;
1909         tgt->u.crypt.sector_size = SECTOR_SIZE;
1910
1911         r = -EINVAL;
1912
1913         rcipher = strsep(&params, " ");
1914         rintegrity = NULL;
1915
1916         /* skip */
1917         key_ = strsep(&params, " ");
1918         if (!params)
1919                 goto err;
1920         val64 = strtoull(params, &params, 10);
1921         if (*params != ' ')
1922                 goto err;
1923         params++;
1924
1925         tgt->u.crypt.iv_offset = val64;
1926
1927         /* device */
1928         rdevice = strsep(&params, " ");
1929         if (get_flags & DM_ACTIVE_DEVICE) {
1930                 arg = crypt_lookup_dev(rdevice);
1931                 r = device_alloc(cd, &data_device, arg);
1932                 free(arg);
1933                 if (r < 0 && r != -ENOTBLK)
1934                         goto err;
1935         }
1936
1937         r = -EINVAL;
1938
1939         /*offset */
1940         if (!params)
1941                 goto err;
1942         val64 = strtoull(params, &params, 10);
1943         tgt->u.crypt.offset = val64;
1944
1945         tgt->u.crypt.tag_size = 0;
1946
1947         /* Features section, available since crypt target version 1.11 */
1948         if (*params) {
1949                 if (*params != ' ')
1950                         goto err;
1951                 params++;
1952
1953                 /* Number of arguments */
1954                 val64 = strtoull(params, &params, 10);
1955                 if (*params != ' ')
1956                         goto err;
1957                 params++;
1958
1959                 for (i = 0; i < val64; i++) {
1960                         if (!params)
1961                                 goto err;
1962                         arg = strsep(&params, " ");
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:"), ':');
1978                                 if (!rintegrity)
1979                                         goto err;
1980                                 rintegrity++;
1981                         } else if (sscanf(arg, "sector_size:%u", &val) == 1) {
1982                                 tgt->u.crypt.sector_size = val;
1983                         } else /* unknown option */
1984                                 goto err;
1985                 }
1986
1987                 /* All parameters should be processed */
1988                 if (params)
1989                         goto err;
1990         }
1991
1992         /* cipher */
1993         if (get_flags & DM_ACTIVE_CRYPT_CIPHER) {
1994                 r = crypt_capi_to_cipher(&cipher, &integrity, rcipher, rintegrity);
1995                 if (r < 0)
1996                         goto err;
1997         }
1998
1999         r = -EINVAL;
2000
2001         if (key_[0] == ':')
2002                 *act_flags |= CRYPT_ACTIVATE_KEYRING_KEY;
2003
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)
2008                                 goto err;
2009                 } else
2010                         key_size = strlen(key_) / 2;
2011
2012                 vk = crypt_alloc_volume_key(key_size, NULL);
2013                 if (!vk) {
2014                         r = -ENOMEM;
2015                         goto err;
2016                 }
2017
2018                 if (get_flags & DM_ACTIVE_CRYPT_KEY) {
2019                         if (key_[0] == ':') {
2020                                 /* :<key_size>:<key_type>:<key_description> */
2021                                 key_desc = NULL;
2022                                 endp = strpbrk(key_ + 1, ":");
2023                                 if (endp)
2024                                         key_desc = strpbrk(endp + 1, ":");
2025                                 if (!key_desc) {
2026                                         r = -ENOMEM;
2027                                         goto err;
2028                                 }
2029                                 key_desc++;
2030                                 crypt_volume_key_set_description(vk, key_desc);
2031                         } else {
2032                                 buffer[2] = '\0';
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]) {
2037                                                 r = -EINVAL;
2038                                                 goto err;
2039                                         }
2040                                 }
2041                         }
2042                 }
2043         }
2044         memset(key_, 0, strlen(key_));
2045
2046         if (cipher)
2047                 tgt->u.crypt.cipher = cipher;
2048         if (integrity)
2049                 tgt->u.crypt.integrity = integrity;
2050         if (data_device)
2051                 tgt->data_device = data_device;
2052         if (vk)
2053                 tgt->u.crypt.vk = vk;
2054         return 0;
2055 err:
2056         free(cipher);
2057         free(integrity);
2058         device_free(cd, data_device);
2059         crypt_free_volume_key(vk);
2060         return r;
2061 }
2062
2063 static int _dm_target_query_verity(struct crypt_device *cd,
2064                                    uint32_t get_flags,
2065                                    char *params,
2066                                    struct dm_target *tgt,
2067                                    uint32_t *act_flags)
2068 {
2069         struct crypt_params_verity *vp = NULL;
2070         uint32_t val32;
2071         uint64_t val64;
2072         ssize_t len;
2073         char *str, *str2, *arg;
2074         unsigned int i, features;
2075         int r;
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;
2079
2080         if (get_flags & DM_ACTIVE_VERITY_PARAMS) {
2081                 vp = crypt_zalloc(sizeof(*vp));
2082                 if (!vp)
2083                         return -ENOMEM;
2084         }
2085
2086         tgt->type = DM_VERITY;
2087         tgt->direction = TARGET_QUERY;
2088         tgt->u.verity.vp = vp;
2089
2090         /* version */
2091         val32 = strtoul(params, &params, 10);
2092         if (*params != ' ')
2093                 return -EINVAL;
2094         if (vp)
2095                 vp->hash_type = val32;
2096         params++;
2097
2098         /* data device */
2099         str = strsep(&params, " ");
2100         if (!params)
2101                 return -EINVAL;
2102         if (get_flags & DM_ACTIVE_DEVICE) {
2103                 str2 = crypt_lookup_dev(str);
2104                 r = device_alloc(cd, &data_device, str2);
2105                 free(str2);
2106                 if (r < 0 && r != -ENOTBLK)
2107                         return r;
2108         }
2109
2110         r = -EINVAL;
2111
2112         /* hash device */
2113         str = strsep(&params, " ");
2114         if (!params)
2115                 goto err;
2116         if (get_flags & DM_ACTIVE_VERITY_HASH_DEVICE) {
2117                 str2 = crypt_lookup_dev(str);
2118                 r = device_alloc(cd, &hash_device, str2);
2119                 free(str2);
2120                 if (r < 0 && r != -ENOTBLK)
2121                         goto err;
2122         }
2123
2124         r = -EINVAL;
2125
2126         /* data block size*/
2127         val32 = strtoul(params, &params, 10);
2128         if (*params != ' ')
2129                 goto err;
2130         if (vp)
2131                 vp->data_block_size = val32;
2132         params++;
2133
2134         /* hash block size */
2135         val32 = strtoul(params, &params, 10);
2136         if (*params != ' ')
2137                 goto err;
2138         if (vp)
2139                 vp->hash_block_size = val32;
2140         params++;
2141
2142         /* data blocks */
2143         val64 = strtoull(params, &params, 10);
2144         if (*params != ' ')
2145                 goto err;
2146         if (vp)
2147                 vp->data_size = val64;
2148         params++;
2149
2150         /* hash start */
2151         val64 = strtoull(params, &params, 10);
2152         if (*params != ' ')
2153                 goto err;
2154         tgt->u.verity.hash_offset = val64;
2155         params++;
2156
2157         /* hash algorithm */
2158         str = strsep(&params, " ");
2159         if (!params)
2160                 goto err;
2161         if (vp) {
2162                 hash_name = strdup(str);
2163                 if (!hash_name) {
2164                         r = -ENOMEM;
2165                         goto err;
2166                 }
2167         }
2168
2169         /* root digest */
2170         str = strsep(&params, " ");
2171         if (!params)
2172                 goto err;
2173         len = crypt_hex_to_bytes(str, &str2, 0);
2174         if (len < 0) {
2175                 r = len;
2176                 goto err;
2177         }
2178         tgt->u.verity.root_hash_size = len;
2179         if (get_flags & DM_ACTIVE_VERITY_ROOT_HASH)
2180                 root_hash = str2;
2181         else
2182                 free(str2);
2183
2184         /* salt */
2185         str = strsep(&params, " ");
2186         if (vp) {
2187                 if (!strcmp(str, "-")) {
2188                         vp->salt_size = 0;
2189                         vp->salt = NULL;
2190                 } else {
2191                         len = crypt_hex_to_bytes(str, &str2, 0);
2192                         if (len < 0) {
2193                                 r = len;
2194                                 goto err;
2195                         }
2196                         vp->salt_size = len;
2197                         salt = str2;
2198                 }
2199         }
2200
2201         r = -EINVAL;
2202
2203         /* Features section, available since verity target version 1.3 */
2204         if (params) {
2205                 /* Number of arguments */
2206                 val64 = strtoull(params, &params, 10);
2207                 if (*params != ' ')
2208                         goto err;
2209                 params++;
2210
2211                 features = (int)val64;
2212                 for (i = 0; i < features; i++) {
2213                         r = -EINVAL;
2214                         if (!params)
2215                                 goto err;
2216                         arg = strsep(&params, " ");
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(&params, " ");
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) {
2235                                                 free(str2);
2236                                                 goto err;
2237                                         }
2238                                 }
2239                                 if (vp) {
2240                                         free(fec_dev_str);
2241                                         fec_dev_str = str2;
2242                                 } else
2243                                         free(str2);
2244                                 i++;
2245                         } else if (!strcasecmp(arg, "fec_start")) {
2246                                 val64 = strtoull(params, &params, 10);
2247                                 if (*params)
2248                                         params++;
2249                                 tgt->u.verity.fec_offset = val64;
2250                                 if (vp)
2251                                         vp->fec_area_offset = val64 * vp->hash_block_size;
2252                                 i++;
2253                         } else if (!strcasecmp(arg, "fec_blocks")) {
2254                                 val64 = strtoull(params, &params, 10);
2255                                 if (*params)
2256                                         params++;
2257                                 tgt->u.verity.fec_blocks = val64;
2258                                 i++;
2259                         } else if (!strcasecmp(arg, "fec_roots")) {
2260                                 val32 = strtoul(params, &params, 10);
2261                                 if (*params)
2262                                         params++;
2263                                 if (vp)
2264                                         vp->fec_roots = val32;
2265                                 i++;
2266                         } else if (!strcasecmp(arg, "root_hash_sig_key_desc")) {
2267                                 str = strsep(&params, " ");
2268                                 if (!str)
2269                                         goto err;
2270                                 if (vp && !root_hash_sig_key_desc) {
2271                                         root_hash_sig_key_desc = strdup(str);
2272                                         if (!root_hash_sig_key_desc) {
2273                                                 r = -ENOMEM;
2274                                                 goto err;
2275                                         }
2276                                         /* not stored in params, but cannot be used without vp */
2277                                         vp->flags |= CRYPT_VERITY_ROOT_HASH_SIGNATURE;
2278                                 }
2279                                 i++;
2280                         } else /* unknown option */
2281                                 goto err;
2282                 }
2283
2284                 /* All parameters should be processed */
2285                 if (params && *params) {
2286                         r = -EINVAL;
2287                         goto err;
2288                 }
2289         }
2290
2291         if (data_device)
2292                 tgt->data_device = data_device;
2293         if (hash_device)
2294                 tgt->u.verity.hash_device = hash_device;
2295         if (fec_device)
2296                 tgt->u.verity.fec_device = fec_device;
2297         if (root_hash)
2298                 tgt->u.verity.root_hash = root_hash;
2299         if (vp && hash_name)
2300                 vp->hash_name = hash_name;
2301         if (vp && salt)
2302                 vp->salt = salt;
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;
2307
2308         return 0;
2309 err:
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);
2314         free(root_hash);
2315         free(hash_name);
2316         free(salt);
2317         free(fec_dev_str);
2318         free(vp);
2319         return r;
2320 }
2321
2322 static int _dm_target_query_integrity(struct crypt_device *cd,
2323                              uint32_t get_flags,
2324                              char *params,
2325                              struct dm_target *tgt,
2326                              uint32_t *act_flags)
2327 {
2328         uint32_t val32;
2329         uint64_t val64;
2330         char c, *str, *str2, *arg;
2331         unsigned int i, features, val;
2332         ssize_t len;
2333         int r;
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;
2339
2340         tgt->type = DM_INTEGRITY;
2341         tgt->direction = TARGET_QUERY;
2342
2343         /* data device */
2344         str = strsep(&params, " ");
2345         if (get_flags & DM_ACTIVE_DEVICE) {
2346                 str2 = crypt_lookup_dev(str);
2347                 r = device_alloc(cd, &data_device, str2);
2348                 free(str2);
2349                 if (r < 0 && r != -ENOTBLK)
2350                         return r;
2351         }
2352
2353         r = -EINVAL;
2354
2355         /*offset */
2356         if (!params)
2357                 goto err;
2358         val64 = strtoull(params, &params, 10);
2359         if (!*params || *params != ' ')
2360                 goto err;
2361         tgt->u.integrity.offset = val64;
2362
2363         /* tag size*/
2364         val32 = strtoul(params, &params, 10);
2365         tgt->u.integrity.tag_size = val32;
2366         if (!*params || *params != ' ')
2367                 goto err;
2368
2369         /* journal */
2370         c = toupper(*(++params));
2371         if (!*params || *(++params) != ' ' || (c != 'D' && c != 'J' && c != 'R' && c != 'B'))
2372                 goto err;
2373         if (c == 'D')
2374                 *act_flags |= CRYPT_ACTIVATE_NO_JOURNAL;
2375         if (c == 'R')
2376                 *act_flags |= CRYPT_ACTIVATE_RECOVERY;
2377         if (c == 'B') {
2378                 *act_flags |= CRYPT_ACTIVATE_NO_JOURNAL;
2379                 *act_flags |= CRYPT_ACTIVATE_NO_JOURNAL_BITMAP;
2380         }
2381
2382         tgt->u.integrity.sector_size = SECTOR_SIZE;
2383
2384         /* Features section */
2385         if (params) {
2386                 /* Number of arguments */
2387                 val64 = strtoull(params, &params, 10);
2388                 if (*params != ' ')
2389                         goto err;
2390                 params++;
2391
2392                 features = (int)val64;
2393                 for (i = 0; i < features; i++) {
2394                         r = -EINVAL;
2395                         if (!params)
2396                                 goto err;
2397                         arg = strsep(&params, " ");
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)
2404                                         goto err;
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) {
2419                                 str = &arg[14];
2420                                 arg = strsep(&str, ":");
2421                                 if (get_flags & DM_ACTIVE_INTEGRITY_PARAMS) {
2422                                         integrity = strdup(arg);
2423                                         if (!integrity) {
2424                                                 r = -ENOMEM;
2425                                                 goto err;
2426                                         }
2427                                 }
2428
2429                                 if (str) {
2430                                         len = crypt_hex_to_bytes(str, &str2, 1);
2431                                         if (len < 0) {
2432                                                 r = len;
2433                                                 goto err;
2434                                         }
2435
2436                                         r = 0;
2437                                         if (get_flags & DM_ACTIVE_CRYPT_KEY) {
2438                                                 vk = crypt_alloc_volume_key(len, str2);
2439                                                 if (!vk)
2440                                                         r = -ENOMEM;
2441                                         } else if (get_flags & DM_ACTIVE_CRYPT_KEYSIZE) {
2442                                                 vk = crypt_alloc_volume_key(len, NULL);
2443                                                 if (!vk)
2444                                                         r = -ENOMEM;
2445                                         }
2446                                         crypt_safe_free(str2);
2447                                         if (r < 0)
2448                                                 goto err;
2449                                 }
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);
2454                                         free(str);
2455                                         if (r < 0 && r != -ENOTBLK)
2456                                                 goto err;
2457                                 }
2458                         } else if (!strncmp(arg, "journal_crypt:", 14) && !journal_crypt) {
2459                                 str = &arg[14];
2460                                 arg = strsep(&str, ":");
2461                                 if (get_flags & DM_ACTIVE_INTEGRITY_PARAMS) {
2462                                         journal_crypt = strdup(arg);
2463                                         if (!journal_crypt) {
2464                                                 r = -ENOMEM;
2465                                                 goto err;
2466                                         }
2467                                 }
2468
2469                                 if (str) {
2470                                         len = crypt_hex_to_bytes(str, &str2, 1);
2471                                         if (len < 0) {
2472                                                 r = len;
2473                                                 goto err;
2474                                         }
2475
2476                                         r = 0;
2477                                         if (get_flags & DM_ACTIVE_JOURNAL_CRYPT_KEY) {
2478                                                 journal_crypt_key = crypt_alloc_volume_key(len, str2);
2479                                                 if (!journal_crypt_key)
2480                                                         r = -ENOMEM;
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)
2484                                                         r = -ENOMEM;
2485                                         }
2486                                         crypt_safe_free(str2);
2487                                         if (r < 0)
2488                                                 goto err;
2489                                 }
2490                         } else if (!strncmp(arg, "journal_mac:", 12) && !journal_integrity) {
2491                                 str = &arg[12];
2492                                 arg = strsep(&str, ":");
2493                                 if (get_flags & DM_ACTIVE_INTEGRITY_PARAMS) {
2494                                         journal_integrity = strdup(arg);
2495                                         if (!journal_integrity) {
2496                                                 r = -ENOMEM;
2497                                                 goto err;
2498                                         }
2499                                 }
2500
2501                                 if (str) {
2502                                         len = crypt_hex_to_bytes(str, &str2, 1);
2503                                         if (len < 0) {
2504                                                 r = len;
2505                                                 goto err;
2506                                         }
2507
2508                                         r = 0;
2509                                         if (get_flags & DM_ACTIVE_JOURNAL_MAC_KEY) {
2510                                                 journal_integrity_key = crypt_alloc_volume_key(len, str2);
2511                                                 if (!journal_integrity_key)
2512                                                         r = -ENOMEM;
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)
2516                                                         r = -ENOMEM;
2517                                         }
2518                                         crypt_safe_free(str2);
2519                                         if (r < 0)
2520                                                 goto err;
2521                                 }
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 */
2535                                 goto err;
2536                 }
2537
2538                 /* All parameters should be processed */
2539                 if (params && *params) {
2540                         r = -EINVAL;
2541                         goto err;
2542                 }
2543         }
2544
2545         if (data_device)
2546                 tgt->data_device = data_device;
2547         if (meta_device)
2548                 tgt->u.integrity.meta_device = meta_device;
2549         if (integrity)
2550                 tgt->u.integrity.integrity = integrity;
2551         if (journal_crypt)
2552                 tgt->u.integrity.journal_crypt = journal_crypt;
2553         if (journal_integrity)
2554                 tgt->u.integrity.journal_integrity = journal_integrity;
2555         if (vk)
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;
2561         return 0;
2562 err:
2563         device_free(cd, data_device);
2564         device_free(cd, meta_device);
2565         free(integrity);
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);
2571         return r;
2572 }
2573
2574 static int _dm_target_query_linear(struct crypt_device *cd, struct dm_target *tgt,
2575                                    uint32_t get_flags, char *params)
2576 {
2577         uint64_t val64;
2578         char *rdevice, *arg;
2579         int r;
2580         struct device *device = NULL;
2581
2582         /* device */
2583         rdevice = strsep(&params, " ");
2584         if (get_flags & DM_ACTIVE_DEVICE) {
2585                 arg = crypt_lookup_dev(rdevice);
2586                 r = device_alloc(cd, &device, arg);
2587                 free(arg);
2588                 if (r < 0 && r != -ENOTBLK)
2589                         return r;
2590         }
2591
2592         r = -EINVAL;
2593
2594         /*offset */
2595         if (!params)
2596                 goto err;
2597         val64 = strtoull(params, &params, 10);
2598
2599         /* params should be empty now */
2600         if (*params)
2601                 goto err;
2602
2603         tgt->type = DM_LINEAR;
2604         tgt->direction = TARGET_QUERY;
2605         tgt->data_device = device;
2606         tgt->u.linear.offset = val64;
2607
2608         return 0;
2609 err:
2610         device_free(cd, device);
2611         return r;
2612 }
2613
2614 static int _dm_target_query_error(struct dm_target *tgt)
2615 {
2616         tgt->type = DM_ERROR;
2617         tgt->direction = TARGET_QUERY;
2618
2619         return 0;
2620 }
2621
2622 static int _dm_target_query_zero(struct dm_target *tgt)
2623 {
2624         tgt->type = DM_ZERO;
2625         tgt->direction = TARGET_QUERY;
2626
2627         return 0;
2628 }
2629
2630 /*
2631  * on error retval has to be negative
2632  *
2633  * also currently any _dm_target_query fn does not perform cleanup on error
2634  */
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)
2638 {
2639         int r = -ENOTSUP;
2640
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);
2653
2654         if (!r) {
2655                 tgt->offset = *start;
2656                 tgt->size = *length;
2657         }
2658
2659         return r;
2660 }
2661
2662 static int _dm_query_device(struct crypt_device *cd, const char *name,
2663                     uint32_t get_flags, struct crypt_dm_active_device *dmd)
2664 {
2665         struct dm_target *t;
2666         struct dm_task *dmt;
2667         struct dm_info dmi;
2668         uint64_t start, length;
2669         char *target_type, *params;
2670         const char *tmp_uuid;
2671         void *next = NULL;
2672         int r = -EINVAL;
2673
2674         t = &dmd->segment;
2675
2676         if (!(dmt = dm_task_create(DM_DEVICE_TABLE)))
2677                 return r;
2678         if (!dm_task_secure_data(dmt))
2679                 goto out;
2680         if (!dm_task_set_name(dmt, name))
2681                 goto out;
2682         r = -ENODEV;
2683         if (!dm_task_run(dmt))
2684                 goto out;
2685
2686         r = -EINVAL;
2687         if (!dm_task_get_info(dmt, &dmi))
2688                 goto out;
2689
2690         if (!dmi.exists) {
2691                 r = -ENODEV;
2692                 goto out;
2693         }
2694
2695         if (dmi.target_count <= 0) {
2696                 r = -EINVAL;
2697                 goto out;
2698         }
2699
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.");
2703                 r = -EINVAL;
2704                 goto out;
2705         }
2706
2707         r = dm_targets_allocate(&dmd->segment, dmi.target_count);
2708         if (r)
2709                 goto out;
2710
2711         do {
2712                 next = dm_get_next_target(dmt, next, &start, &length,
2713                                           &target_type, &params);
2714
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);
2718                         if (r == 0)
2719                                 dmd->flags |= CRYPT_ACTIVATE_CORRUPTED;
2720                 }
2721
2722                 if (r < 0) {
2723                         if (r != -ENOTSUP)
2724                                 log_err(cd, _("Failed to query dm-%s segment."), target_type);
2725                         goto out;
2726                 }
2727
2728                 dmd->size += length;
2729                 t = t->next;
2730         } while (next && t);
2731
2732         if (dmi.read_only)
2733                 dmd->flags |= CRYPT_ACTIVATE_READONLY;
2734
2735         if (dmi.suspended)
2736                 dmd->flags |= CRYPT_ACTIVATE_SUSPENDED;
2737
2738         tmp_uuid = dm_task_get_uuid(dmt);
2739         if (!tmp_uuid)
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);
2744         }
2745
2746         dmd->holders = 0;
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));
2751 #endif
2752
2753         r = (dmi.open_count > 0);
2754 out:
2755         dm_task_destroy(dmt);
2756
2757         if (r < 0)
2758                 dm_targets_free(cd, dmd);
2759
2760         return r;
2761 }
2762
2763 int dm_query_device(struct crypt_device *cd, const char *name,
2764                     uint32_t get_flags, struct crypt_dm_active_device *dmd)
2765 {
2766         int r;
2767
2768         if (!dmd)
2769                 return -EINVAL;
2770
2771         memset(dmd, 0, sizeof(*dmd));
2772
2773         if (dm_init_context(cd, DM_UNKNOWN))
2774                 return -ENOTSUP;
2775
2776         r = _dm_query_device(cd, name, get_flags, dmd);
2777
2778         dm_exit_context();
2779         return r;
2780 }
2781
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)
2784 {
2785 #if HAVE_DECL_DM_DEVICE_GET_NAME
2786         struct crypt_dm_active_device dmd;
2787         char dmname[PATH_MAX];
2788         unsigned i;
2789         int r, major, minor, count = 0;
2790
2791         if (!prefix || !deps)
2792                 return -EINVAL;
2793
2794         for (i = 0; i < deps->count; i++) {
2795                 major = major(deps->device[i]);
2796                 if (!dm_is_dm_major(major))
2797                         continue;
2798
2799                 minor = minor(deps->device[i]);
2800                 if (!dm_device_get_name(major, minor, 0, dmname, PATH_MAX))
2801                         return -EINVAL;
2802
2803                 memset(&dmd, 0, sizeof(dmd));
2804                 r = _dm_query_device(cd, dmname, DM_ACTIVE_UUID, &dmd);
2805                 if (r < 0)
2806                         continue;
2807
2808                 if (!dmd.uuid ||
2809                     strncmp(prefix, dmd.uuid, strlen(prefix)) ||
2810                     crypt_string_in(dmname, names, names_length))
2811                         *dmname = '\0';
2812
2813                 dm_targets_free(cd, &dmd);
2814                 free(CONST_CAST(void*)dmd.uuid);
2815
2816                 if ((size_t)count >= (names_length - names_offset))
2817                         return -ENOMEM;
2818
2819                 if (*dmname && !(names[names_offset + count++] = strdup(dmname)))
2820                         return -ENOMEM;
2821         }
2822
2823         return count;
2824 #else
2825         return -EINVAL;
2826 #endif
2827 }
2828
2829 int dm_device_deps(struct crypt_device *cd, const char *name, const char *prefix,
2830                    char **names, size_t names_length)
2831 {
2832         struct dm_task *dmt;
2833         struct dm_info dmi;
2834         struct dm_deps *deps;
2835         int r = -EINVAL;
2836         size_t i, last = 0, offset = 0;
2837
2838         if (!name || !names_length || !names)
2839                 return -EINVAL;
2840
2841         if (dm_init_context(cd, DM_UNKNOWN))
2842                 return -ENOTSUP;
2843
2844         while (name) {
2845                 if (!(dmt = dm_task_create(DM_DEVICE_DEPS)))
2846                         goto out;
2847                 if (!dm_task_set_name(dmt, name))
2848                         goto out;
2849
2850                 r = -ENODEV;
2851                 if (!dm_task_run(dmt))
2852                         goto out;
2853
2854                 r = -EINVAL;
2855                 if (!dm_task_get_info(dmt, &dmi))
2856                         goto out;
2857                 if (!(deps = dm_task_get_deps(dmt)))
2858                         goto out;
2859
2860                 r = -ENODEV;
2861                 if (!dmi.exists)
2862                         goto out;
2863
2864                 r = _process_deps(cd, prefix, deps, names, offset, names_length - 1);
2865                 if (r < 0)
2866                         goto out;
2867
2868                 dm_task_destroy(dmt);
2869                 dmt = NULL;
2870
2871                 offset += r;
2872                 name = names[last++];
2873         }
2874
2875         r = 0;
2876 out:
2877         if (r < 0) {
2878                 for (i = 0; i < names_length - 1; i++)
2879                         free(names[i]);
2880                 *names = NULL;
2881         }
2882
2883         if (dmt)
2884                 dm_task_destroy(dmt);
2885
2886         dm_exit_context();
2887         return r;
2888 }
2889
2890 static int _dm_message(const char *name, const char *msg)
2891 {
2892         int r = 0;
2893         struct dm_task *dmt;
2894
2895         if (!(dmt = dm_task_create(DM_DEVICE_TARGET_MSG)))
2896                 return 0;
2897
2898         if (!dm_task_secure_data(dmt))
2899                 goto out;
2900
2901         if (name && !dm_task_set_name(dmt, name))
2902                 goto out;
2903
2904         if (!dm_task_set_sector(dmt, (uint64_t) 0))
2905                 goto out;
2906
2907         if (!dm_task_set_message(dmt, msg))
2908                 goto out;
2909
2910         r = dm_task_run(dmt);
2911 out:
2912         dm_task_destroy(dmt);
2913         return r;
2914 }
2915
2916 int dm_suspend_device(struct crypt_device *cd, const char *name, uint32_t dmflags)
2917 {
2918         uint32_t dmt_flags;
2919         int r = -ENOTSUP;
2920
2921         if (dm_init_context(cd, DM_UNKNOWN))
2922                 return r;
2923
2924         if (dmflags & DM_SUSPEND_WIPE_KEY) {
2925                 if (dm_flags(cd, DM_CRYPT, &dmt_flags))
2926                         goto out;
2927
2928                 if (!(dmt_flags & DM_KEY_WIPE_SUPPORTED))
2929                         goto out;
2930         }
2931
2932         r = -EINVAL;
2933
2934         if (!_dm_simple(DM_DEVICE_SUSPEND, name, dmflags))
2935                 goto out;
2936
2937         if (dmflags & DM_SUSPEND_WIPE_KEY) {
2938                 if (!_dm_message(name, "key wipe")) {
2939                         _dm_resume_device(name, 0);
2940                         goto out;
2941                 }
2942         }
2943
2944         r = 0;
2945 out:
2946         dm_exit_context();
2947         return r;
2948 }
2949
2950 int dm_resume_device(struct crypt_device *cd, const char *name, uint32_t dmflags)
2951 {
2952         int r;
2953
2954         if (dm_init_context(cd, DM_UNKNOWN))
2955                 return -ENOTSUP;
2956
2957         r = _dm_resume_device(name, dmflags);
2958
2959         dm_exit_context();
2960
2961         return r;
2962 }
2963
2964 int dm_resume_and_reinstate_key(struct crypt_device *cd, const char *name,
2965                                 const struct volume_key *vk)
2966 {
2967         uint32_t dmt_flags;
2968         int msg_size;
2969         char *msg = NULL, *key = NULL;
2970         int r = -ENOTSUP;
2971
2972         if (dm_init_context(cd, DM_CRYPT) || dm_flags(cd, DM_CRYPT, &dmt_flags))
2973                 return -ENOTSUP;
2974
2975         if (!(dmt_flags & DM_KEY_WIPE_SUPPORTED))
2976                 goto out;
2977
2978         if (!vk->keylength)
2979                 msg_size = 11; // key set -
2980         else if (vk->key_description)
2981                 msg_size = strlen(vk->key_description) + int_log10(vk->keylength) + 18;
2982         else
2983                 msg_size = vk->keylength * 2 + 10; // key set <key>
2984
2985         msg = crypt_safe_alloc(msg_size);
2986         if (!msg) {
2987                 r = -ENOMEM;
2988                 goto out;
2989         }
2990
2991         if (vk->key_description) {
2992                 r = snprintf(msg, msg_size, "key set :%zu:logon:%s", vk->keylength, vk->key_description);
2993         } else  {
2994                 key = crypt_bytes_to_hex(vk->keylength, vk->key);
2995                 if (!key) {
2996                         r = -ENOMEM;
2997                         goto out;
2998                 }
2999
3000                 r = snprintf(msg, msg_size, "key set %s", key);
3001         }
3002         if (r < 0 || r >= msg_size) {
3003                 r = -EINVAL;
3004                 goto out;
3005         }
3006         if (!_dm_message(name, msg) ||
3007             _dm_resume_device(name, 0)) {
3008                 r = -EINVAL;
3009                 goto out;
3010         }
3011         r = 0;
3012 out:
3013         crypt_safe_free(msg);
3014         crypt_safe_free(key);
3015         dm_exit_context();
3016         return r;
3017 }
3018
3019 int dm_cancel_deferred_removal(const char *name)
3020 {
3021         return _dm_message(name, "@cancel_deferred_remove") ? 0 : -ENOTSUP;
3022 }
3023
3024 const char *dm_get_dir(void)
3025 {
3026         return dm_dir();
3027 }
3028
3029 int dm_is_dm_device(int major)
3030 {
3031         return dm_is_dm_major((uint32_t)major);
3032 }
3033
3034 int dm_is_dm_kernel_name(const char *name)
3035 {
3036         return strncmp(name, "dm-", 3) ? 0 : 1;
3037 }
3038
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)
3043 {
3044         char *dm_integrity = NULL;
3045
3046         if (tag_size) {
3047                 /* Space for IV metadata only */
3048                 dm_integrity = strdup(integrity ?: "none");
3049                 if (!dm_integrity)
3050                         return -ENOMEM;
3051         }
3052
3053         tgt->data_device = data_device;
3054
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;
3060
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;
3067
3068         return 0;
3069 }
3070
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)
3075 {
3076         if (!data_device || !hash_device || !vp)
3077                 return -EINVAL;
3078
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;
3084
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;
3094
3095         return 0;
3096 }
3097
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)
3105 {
3106         uint32_t dmi_flags;
3107
3108         if (!data_device)
3109                 return -EINVAL;
3110
3111         _dm_check_versions(cd, DM_INTEGRITY);
3112
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;
3123
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;
3127
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;
3132
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;
3137
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;
3141
3142         if (ip) {
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;
3151         }
3152
3153         return 0;
3154 }
3155
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)
3158 {
3159         if (!data_device)
3160                 return -EINVAL;
3161
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;
3167
3168         tgt->u.linear.offset = data_offset;
3169
3170         return 0;
3171 }
3172
3173 int dm_zero_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size)
3174 {
3175         tgt->type = DM_ZERO;
3176         tgt->direction = TARGET_SET;
3177         tgt->offset = seg_offset;
3178         tgt->size = seg_size;
3179
3180         return 0;
3181 }