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