2 * LUKS - Linux Unified Key Setup v2, reencryption keyslot handler
4 * Copyright (C) 2016-2023 Red Hat, Inc. All rights reserved.
5 * Copyright (C) 2016-2023 Ondrej Kozina
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include "luks2_internal.h"
24 static int reenc_keyslot_open(struct crypt_device *cd __attribute__((unused)),
25 int keyslot __attribute__((unused)),
26 const char *password __attribute__((unused)),
27 size_t password_len __attribute__((unused)),
28 char *volume_key __attribute__((unused)),
29 size_t volume_key_len __attribute__((unused)))
34 static json_object *reencrypt_keyslot_area_jobj(struct crypt_device *cd,
35 const struct crypt_params_reencrypt *params,
40 json_object *jobj_area = json_object_new_object();
42 if (!jobj_area || !params || !params->resilience)
45 json_object_object_add(jobj_area, "offset", crypt_jobj_new_uint64(area_offset));
46 json_object_object_add(jobj_area, "size", crypt_jobj_new_uint64(area_length));
47 json_object_object_add(jobj_area, "type", json_object_new_string(params->resilience));
49 if (!strcmp(params->resilience, "checksum")) {
50 log_dbg(cd, "Setting reencrypt keyslot for checksum protection.");
51 json_object_object_add(jobj_area, "hash", json_object_new_string(params->hash));
52 json_object_object_add(jobj_area, "sector_size", json_object_new_int64(alignment));
53 } else if (!strcmp(params->resilience, "journal")) {
54 log_dbg(cd, "Setting reencrypt keyslot for journal protection.");
55 } else if (!strcmp(params->resilience, "none")) {
56 log_dbg(cd, "Setting reencrypt keyslot for none protection.");
57 } else if (!strcmp(params->resilience, "datashift")) {
58 log_dbg(cd, "Setting reencrypt keyslot for datashift protection.");
59 json_object_object_add(jobj_area, "shift_size",
60 crypt_jobj_new_uint64(params->data_shift << SECTOR_SHIFT));
61 } else if (!strcmp(params->resilience, "datashift-checksum")) {
62 log_dbg(cd, "Setting reencrypt keyslot for datashift and checksum protection.");
63 json_object_object_add(jobj_area, "hash", json_object_new_string(params->hash));
64 json_object_object_add(jobj_area, "sector_size", json_object_new_int64(alignment));
65 json_object_object_add(jobj_area, "shift_size",
66 crypt_jobj_new_uint64(params->data_shift << SECTOR_SHIFT));
67 } else if (!strcmp(params->resilience, "datashift-journal")) {
68 log_dbg(cd, "Setting reencrypt keyslot for datashift and journal protection.");
69 json_object_object_add(jobj_area, "shift_size",
70 crypt_jobj_new_uint64(params->data_shift << SECTOR_SHIFT));
72 json_object_put(jobj_area);
79 static json_object *reencrypt_keyslot_area_jobj_update_block_size(struct crypt_device *cd,
80 json_object *jobj_area, size_t alignment)
82 json_object *jobj_type, *jobj_area_new = NULL;
85 !json_object_object_get_ex(jobj_area, "type", &jobj_type) ||
86 (strcmp(json_object_get_string(jobj_type), "checksum") &&
87 strcmp(json_object_get_string(jobj_type), "datashift-checksum")))
90 if (json_object_copy(jobj_area, &jobj_area_new))
93 log_dbg(cd, "Updating reencrypt resilience checksum block size.");
95 json_object_object_add(jobj_area_new, "sector_size", json_object_new_int64(alignment));
100 static int reenc_keyslot_alloc(struct crypt_device *cd,
101 struct luks2_hdr *hdr,
103 const struct crypt_params_reencrypt *params,
107 json_object *jobj_keyslots, *jobj_keyslot, *jobj_area;
108 uint64_t area_offset, area_length;
110 log_dbg(cd, "Allocating reencrypt keyslot %d.", keyslot);
112 if (!params || !params->resilience || params->direction > CRYPT_REENCRYPT_BACKWARD)
115 if (keyslot < 0 || keyslot >= LUKS2_KEYSLOTS_MAX)
118 if (!json_object_object_get_ex(hdr->jobj, "keyslots", &jobj_keyslots))
121 /* only plain datashift resilience mode does not require additional storage */
122 if (!strcmp(params->resilience, "datashift"))
123 r = LUKS2_find_area_gap(cd, hdr, 1, &area_offset, &area_length);
125 r = LUKS2_find_area_max_gap(cd, hdr, &area_offset, &area_length);
129 jobj_area = reencrypt_keyslot_area_jobj(cd, params, alignment, area_offset, area_length);
133 jobj_keyslot = json_object_new_object();
135 json_object_put(jobj_area);
138 json_object_object_add(jobj_keyslot, "area", jobj_area);
140 json_object_object_add(jobj_keyslot, "type", json_object_new_string("reencrypt"));
141 json_object_object_add(jobj_keyslot, "key_size", json_object_new_int(1)); /* useless but mandatory */
142 json_object_object_add(jobj_keyslot, "mode", json_object_new_string(crypt_reencrypt_mode_to_str(params->mode)));
143 if (params->direction == CRYPT_REENCRYPT_FORWARD)
144 json_object_object_add(jobj_keyslot, "direction", json_object_new_string("forward"));
146 json_object_object_add(jobj_keyslot, "direction", json_object_new_string("backward"));
148 json_object_object_add_by_uint(jobj_keyslots, keyslot, jobj_keyslot);
149 if (LUKS2_check_json_size(cd, hdr)) {
150 log_dbg(cd, "New keyslot too large to fit in free metadata space.");
151 json_object_object_del_by_uint(jobj_keyslots, keyslot);
155 JSON_DBG(cd, hdr->jobj, "JSON:");
160 static int reenc_keyslot_store_data(struct crypt_device *cd,
161 json_object *jobj_keyslot,
162 const void *buffer, size_t buffer_len)
165 json_object *jobj_area, *jobj_offset, *jobj_length;
166 uint64_t area_offset, area_length;
167 struct device *device = crypt_metadata_device(cd);
169 if (!json_object_object_get_ex(jobj_keyslot, "area", &jobj_area) ||
170 !json_object_object_get_ex(jobj_area, "offset", &jobj_offset) ||
171 !json_object_object_get_ex(jobj_area, "size", &jobj_length))
174 area_offset = crypt_jobj_get_uint64(jobj_offset);
175 area_length = crypt_jobj_get_uint64(jobj_length);
177 if (!area_offset || !area_length || ((uint64_t)buffer_len > area_length))
180 devfd = device_open_locked(cd, device, O_RDWR);
182 if (write_lseek_blockwise(devfd, device_block_size(cd, device),
183 device_alignment(device), CONST_CAST(void *)buffer,
184 buffer_len, area_offset) < 0)
192 log_err(cd, _("IO error while encrypting keyslot."));
197 static int reenc_keyslot_store(struct crypt_device *cd,
199 const char *password __attribute__((unused)),
200 size_t password_len __attribute__((unused)),
204 struct luks2_hdr *hdr;
205 json_object *jobj_keyslot;
208 if (!cd || !buffer || !buffer_len)
211 if (!(hdr = crypt_get_hdr(cd, CRYPT_LUKS2)))
214 log_dbg(cd, "Reencrypt keyslot %d store.", keyslot);
216 jobj_keyslot = LUKS2_get_keyslot_jobj(hdr, keyslot);
220 r = LUKS2_device_write_lock(cd, hdr, crypt_metadata_device(cd));
224 r = reenc_keyslot_store_data(cd, jobj_keyslot, buffer, buffer_len);
226 device_write_unlock(cd, crypt_metadata_device(cd));
230 r = LUKS2_hdr_write(cd, hdr);
232 device_write_unlock(cd, crypt_metadata_device(cd));
234 return r < 0 ? r : keyslot;
237 static int reenc_keyslot_wipe(struct crypt_device *cd,
240 struct luks2_hdr *hdr;
242 if (!(hdr = crypt_get_hdr(cd, CRYPT_LUKS2)))
245 /* remove reencryption verification data */
246 LUKS2_digest_assign(cd, hdr, keyslot, CRYPT_ANY_DIGEST, 0, 0);
251 static int reenc_keyslot_dump(struct crypt_device *cd, int keyslot)
253 json_object *jobj_keyslot, *jobj_area, *jobj_direction, *jobj_mode, *jobj_resilience,
256 jobj_keyslot = LUKS2_get_keyslot_jobj(crypt_get_hdr(cd, CRYPT_LUKS2), keyslot);
260 if (!json_object_object_get_ex(jobj_keyslot, "direction", &jobj_direction) ||
261 !json_object_object_get_ex(jobj_keyslot, "mode", &jobj_mode) ||
262 !json_object_object_get_ex(jobj_keyslot, "area", &jobj_area) ||
263 !json_object_object_get_ex(jobj_area, "type", &jobj_resilience))
266 log_std(cd, "\t%-12s%s\n", "Mode:", json_object_get_string(jobj_mode));
267 log_std(cd, "\t%-12s%s\n", "Direction:", json_object_get_string(jobj_direction));
268 log_std(cd, "\t%-12s%s\n", "Resilience:", json_object_get_string(jobj_resilience));
270 if (!strcmp(json_object_get_string(jobj_resilience), "checksum")) {
271 json_object_object_get_ex(jobj_area, "hash", &jobj1);
272 log_std(cd, "\t%-12s%s\n", "Hash:", json_object_get_string(jobj1));
273 json_object_object_get_ex(jobj_area, "sector_size", &jobj1);
274 log_std(cd, "\t%-12s%d [bytes]\n", "Hash data:", json_object_get_int(jobj1));
275 } else if (!strcmp(json_object_get_string(jobj_resilience), "datashift")) {
276 json_object_object_get_ex(jobj_area, "shift_size", &jobj1);
277 log_std(cd, "\t%-12s%" PRIu64 "[bytes]\n", "Shift size:", crypt_jobj_get_uint64(jobj1));
280 json_object_object_get_ex(jobj_area, "offset", &jobj1);
281 log_std(cd, "\tArea offset:%" PRIu64 " [bytes]\n", crypt_jobj_get_uint64(jobj1));
283 json_object_object_get_ex(jobj_area, "size", &jobj1);
284 log_std(cd, "\tArea length:%" PRIu64 " [bytes]\n", crypt_jobj_get_uint64(jobj1));
289 static int reenc_keyslot_validate(struct crypt_device *cd, json_object *jobj_keyslot)
291 json_object *jobj_mode, *jobj_area, *jobj_type, *jobj_shift_size, *jobj_hash,
292 *jobj_sector_size, *jobj_direction, *jobj_key_size;
293 const char *mode, *type, *direction;
294 uint32_t sector_size;
297 /* mode (string: encrypt,reencrypt,decrypt)
298 * direction (string:)
300 * type: (string: datashift, journal, checksum, none, datashift-journal, datashift-checksum)
301 * hash: (string: checksum and datashift-checksum types)
302 * sector_size (uint32: checksum and datashift-checksum types)
303 * shift_size (uint64: all datashift based types)
307 /* area and area type are validated in general validation code */
308 if (!jobj_keyslot || !json_object_object_get_ex(jobj_keyslot, "area", &jobj_area) ||
309 !json_object_object_get_ex(jobj_area, "type", &jobj_type))
312 jobj_key_size = json_contains(cd, jobj_keyslot, "", "reencrypt keyslot", "key_size", json_type_int);
313 jobj_mode = json_contains_string(cd, jobj_keyslot, "", "reencrypt keyslot", "mode");
314 jobj_direction = json_contains_string(cd, jobj_keyslot, "", "reencrypt keyslot", "direction");
316 if (!jobj_mode || !jobj_direction || !jobj_key_size)
319 if (!validate_json_uint32(jobj_key_size) || crypt_jobj_get_uint32(jobj_key_size) != 1) {
320 log_dbg(cd, "Illegal reencrypt key size.");
324 mode = json_object_get_string(jobj_mode);
325 type = json_object_get_string(jobj_type);
326 direction = json_object_get_string(jobj_direction);
328 if (strcmp(mode, "reencrypt") && strcmp(mode, "encrypt") &&
329 strcmp(mode, "decrypt")) {
330 log_dbg(cd, "Illegal reencrypt mode %s.", mode);
334 if (strcmp(direction, "forward") && strcmp(direction, "backward")) {
335 log_dbg(cd, "Illegal reencrypt direction %s.", direction);
339 if (!strcmp(type, "checksum") || !strcmp(type, "datashift-checksum")) {
340 jobj_hash = json_contains_string(cd, jobj_area, "type:checksum",
341 "Keyslot area", "hash");
342 jobj_sector_size = json_contains(cd, jobj_area, "type:checksum",
343 "Keyslot area", "sector_size", json_type_int);
344 if (!jobj_hash || !jobj_sector_size)
346 if (!validate_json_uint32(jobj_sector_size))
348 sector_size = crypt_jobj_get_uint32(jobj_sector_size);
349 if (sector_size < SECTOR_SIZE || NOTPOW2(sector_size)) {
350 log_dbg(cd, "Invalid sector_size (%" PRIu32 ") for checksum resilience mode.",
354 } else if (!strcmp(type, "datashift") ||
355 !strcmp(type, "datashift-checksum") ||
356 !strcmp(type, "datashift-journal")) {
357 if (!(jobj_shift_size = json_contains_string(cd, jobj_area, "type:datashift",
358 "Keyslot area", "shift_size")))
361 shift_size = crypt_jobj_get_uint64(jobj_shift_size);
365 if (MISALIGNED_512(shift_size)) {
366 log_dbg(cd, "Shift size field has to be aligned to 512 bytes.");
374 static int reenc_keyslot_update_needed(struct crypt_device *cd,
375 json_object *jobj_keyslot,
376 const struct crypt_params_reencrypt *params,
380 json_object *jobj_area, *jobj_type, *jobj;
382 if (!json_object_object_get_ex(jobj_keyslot, "area", &jobj_area) ||
383 !json_object_object_get_ex(jobj_area, "type", &jobj_type) ||
384 !(type = json_object_get_string(jobj_type)))
388 * If no resilience mode change is requested and effective
389 * resilience mode is 'checksum' then check alignment matches
390 * stored checksum block size.
392 if (!params || !params->resilience) {
393 if (!strcmp(json_object_get_string(jobj_type), "checksum") ||
394 !strcmp(json_object_get_string(jobj_type), "datashift-checksum"))
395 return (json_object_object_get_ex(jobj_area, "sector_size", &jobj) ||
396 alignment != crypt_jobj_get_uint32(jobj));
400 if (strcmp(params->resilience, type))
403 if (!strcmp(type, "checksum") ||
404 !strcmp(type, "datashift-checksum")) {
407 if (!json_object_object_get_ex(jobj_area, "hash", &jobj) ||
408 strcmp(json_object_get_string(jobj), params->hash) ||
409 !json_object_object_get_ex(jobj_area, "sector_size", &jobj) ||
410 crypt_jobj_get_uint32(jobj) != alignment)
414 if (!strncmp(type, "datashift", 9)) {
415 if (!json_object_object_get_ex(jobj_area, "shift_size", &jobj))
417 if ((params->data_shift << SECTOR_SHIFT) != crypt_jobj_get_uint64(jobj))
421 /* nothing to compare with 'none' and 'journal' */
425 static int load_checksum_protection(struct crypt_device *cd,
426 json_object *jobj_area,
427 uint64_t area_length,
428 struct reenc_protection *rp)
431 json_object *jobj_hash, *jobj_block_size;
433 if (!jobj_area || !rp ||
434 !json_object_object_get_ex(jobj_area, "hash", &jobj_hash) ||
435 !json_object_object_get_ex(jobj_area, "sector_size", &jobj_block_size))
438 r = snprintf(rp->p.csum.hash, sizeof(rp->p.csum.hash), "%s", json_object_get_string(jobj_hash));
439 if (r < 0 || (size_t)r >= sizeof(rp->p.csum.hash))
442 if (crypt_hash_init(&rp->p.csum.ch, rp->p.csum.hash)) {
443 log_err(cd, _("Hash algorithm %s is not available."), rp->p.csum.hash);
447 r = crypt_hash_size(rp->p.csum.hash);
449 crypt_hash_destroy(rp->p.csum.ch);
450 rp->p.csum.ch = NULL;
451 log_dbg(cd, "Invalid hash size");
455 rp->p.csum.hash_size = r;
456 rp->p.csum.block_size = crypt_jobj_get_uint32(jobj_block_size);
457 rp->p.csum.checksums_len = area_length;
459 rp->type = REENC_PROTECTION_CHECKSUM;
463 static int reenc_keyslot_load_resilience_primary(struct crypt_device *cd,
465 json_object *jobj_area,
466 uint64_t area_length,
467 struct reenc_protection *rp)
471 if (!strcmp(type, "checksum")) {
472 log_dbg(cd, "Initializing checksum resilience mode.");
473 return load_checksum_protection(cd, jobj_area, area_length, rp);
474 } else if (!strcmp(type, "journal")) {
475 log_dbg(cd, "Initializing journal resilience mode.");
476 rp->type = REENC_PROTECTION_JOURNAL;
477 } else if (!strcmp(type, "none")) {
478 log_dbg(cd, "Initializing none resilience mode.");
479 rp->type = REENC_PROTECTION_NONE;
480 } else if (!strcmp(type, "datashift") ||
481 !strcmp(type, "datashift-checksum") ||
482 !strcmp(type, "datashift-journal")) {
483 log_dbg(cd, "Initializing datashift resilience mode.");
484 if (!json_object_object_get_ex(jobj_area, "shift_size", &jobj))
486 rp->type = REENC_PROTECTION_DATASHIFT;
487 rp->p.ds.data_shift = crypt_jobj_get_uint64(jobj);
494 static int reenc_keyslot_load_resilience_secondary(struct crypt_device *cd,
496 json_object *jobj_area,
497 uint64_t area_length,
498 struct reenc_protection *rp)
500 if (!strcmp(type, "datashift-checksum")) {
501 log_dbg(cd, "Initializing checksum resilience mode.");
502 return load_checksum_protection(cd, jobj_area, area_length, rp);
503 } else if (!strcmp(type, "datashift-journal")) {
504 log_dbg(cd, "Initializing journal resilience mode.");
505 rp->type = REENC_PROTECTION_JOURNAL;
507 rp->type = REENC_PROTECTION_NOT_SET;
512 static int reenc_keyslot_load_resilience(struct crypt_device *cd,
513 json_object *jobj_keyslot,
514 struct reenc_protection *rp,
519 json_object *jobj_area, *jobj_type;
520 uint64_t dummy, area_length;
522 if (!rp || !json_object_object_get_ex(jobj_keyslot, "area", &jobj_area) ||
523 !json_object_object_get_ex(jobj_area, "type", &jobj_type))
526 r = LUKS2_keyslot_jobj_area(jobj_keyslot, &dummy, &area_length);
530 type = json_object_get_string(jobj_type);
535 return reenc_keyslot_load_resilience_primary(cd, type, jobj_area, area_length, rp);
537 return reenc_keyslot_load_resilience_secondary(cd, type, jobj_area, area_length, rp);
540 static bool reenc_keyslot_update_is_valid(struct crypt_device *cd,
541 json_object *jobj_area,
542 const struct crypt_params_reencrypt *params)
545 json_object *jobj_type, *jobj;
547 if (!json_object_object_get_ex(jobj_area, "type", &jobj_type) ||
548 !(type = json_object_get_string(jobj_type)))
551 /* do not allow switch to/away from datashift resilience type */
552 if ((strcmp(params->resilience, "datashift") && !strcmp(type, "datashift")) ||
553 (!strcmp(params->resilience, "datashift") && strcmp(type, "datashift")))
556 /* do not allow switch to/away from datashift- resilience subvariants */
557 if ((strncmp(params->resilience, "datashift-", 10) &&
558 !strncmp(type, "datashift-", 10)) ||
559 (!strncmp(params->resilience, "datashift-", 10) &&
560 strncmp(type, "datashift-", 10)))
563 /* datashift value is also immutable */
564 if (!strncmp(type, "datashift", 9)) {
565 if (!json_object_object_get_ex(jobj_area, "shift_size", &jobj))
567 return (params->data_shift << SECTOR_SHIFT) == crypt_jobj_get_uint64(jobj);
573 static int reenc_keyslot_update(struct crypt_device *cd,
574 json_object *jobj_keyslot,
575 const struct crypt_params_reencrypt *params,
579 json_object *jobj_area, *jobj_area_new;
580 uint64_t area_offset, area_length;
582 if (!json_object_object_get_ex(jobj_keyslot, "area", &jobj_area))
585 r = LUKS2_keyslot_jobj_area(jobj_keyslot, &area_offset, &area_length);
589 if (!params || !params->resilience)
590 jobj_area_new = reencrypt_keyslot_area_jobj_update_block_size(cd, jobj_area, alignment);
592 if (!reenc_keyslot_update_is_valid(cd, jobj_area, params)) {
593 log_err(cd, _("Invalid reencryption resilience mode change requested."));
597 jobj_area_new = reencrypt_keyslot_area_jobj(cd, params, alignment,
598 area_offset, area_length);
604 /* increase refcount for validation purposes */
605 json_object_get(jobj_area);
607 json_object_object_add(jobj_keyslot, "area", jobj_area_new);
609 r = reenc_keyslot_validate(cd, jobj_keyslot);
611 /* replace invalid object with previous valid one */
612 json_object_object_add(jobj_keyslot, "area", jobj_area);
616 /* previous area object is no longer needed */
617 json_object_put(jobj_area);
622 int LUKS2_keyslot_reencrypt_allocate(struct crypt_device *cd,
623 struct luks2_hdr *hdr,
625 const struct crypt_params_reencrypt *params,
630 if (keyslot == CRYPT_ANY_SLOT)
633 r = reenc_keyslot_alloc(cd, hdr, keyslot, params, alignment);
637 r = LUKS2_keyslot_priority_set(cd, hdr, keyslot, CRYPT_SLOT_PRIORITY_IGNORE, 0);
641 r = reenc_keyslot_validate(cd, LUKS2_get_keyslot_jobj(hdr, keyslot));
643 log_dbg(cd, "Keyslot validation failed.");
650 int LUKS2_keyslot_reencrypt_update_needed(struct crypt_device *cd,
651 struct luks2_hdr *hdr,
653 const struct crypt_params_reencrypt *params,
657 json_object *jobj_type, *jobj_keyslot = LUKS2_get_keyslot_jobj(hdr, keyslot);
660 !json_object_object_get_ex(jobj_keyslot, "type", &jobj_type) ||
661 strcmp(json_object_get_string(jobj_type), "reencrypt"))
664 r = reenc_keyslot_update_needed(cd, jobj_keyslot, params, alignment);
666 log_dbg(cd, "No update of reencrypt keyslot needed.");
671 int LUKS2_keyslot_reencrypt_update(struct crypt_device *cd,
672 struct luks2_hdr *hdr,
674 const struct crypt_params_reencrypt *params,
676 struct volume_key *vks)
680 uint64_t max_size, moved_segment_size;
681 json_object *jobj_type, *jobj_keyslot = LUKS2_get_keyslot_jobj(hdr, keyslot);
682 struct reenc_protection check_rp = {};
685 !json_object_object_get_ex(jobj_keyslot, "type", &jobj_type) ||
686 strcmp(json_object_get_string(jobj_type), "reencrypt"))
689 if (LUKS2_config_get_reencrypt_version(hdr, &version))
692 /* verify existing reencryption metadata before updating */
693 r = LUKS2_reencrypt_digest_verify(cd, hdr, vks);
697 r = reenc_keyslot_update(cd, jobj_keyslot, params, alignment);
701 r = reenc_keyslot_load_resilience(cd, jobj_keyslot, &check_rp, false);
705 if (check_rp.type != REENC_PROTECTION_NOT_SET) {
706 r = LUKS2_reencrypt_max_hotzone_size(cd, hdr, &check_rp, keyslot, &max_size);
707 LUKS2_reencrypt_protection_erase(&check_rp);
710 moved_segment_size = json_segment_get_size(LUKS2_get_segment_by_flag(hdr, "backup-moved-segment"), 0);
711 if (!moved_segment_size)
713 if (moved_segment_size > max_size) {
714 log_err(cd, _("Can not update resilience type. "
715 "New type only provides %" PRIu64 " bytes, "
716 "required space is: %" PRIu64 " bytes."),
717 max_size, moved_segment_size);
722 r = LUKS2_keyslot_reencrypt_digest_create(cd, hdr, version, vks);
724 log_err(cd, _("Failed to refresh reencryption verification digest."));
726 return r ?: LUKS2_hdr_write(cd, hdr);
729 int LUKS2_keyslot_reencrypt_load(struct crypt_device *cd,
730 struct luks2_hdr *hdr,
732 struct reenc_protection *rp,
735 json_object *jobj_type, *jobj_keyslot = LUKS2_get_keyslot_jobj(hdr, keyslot);
738 !json_object_object_get_ex(jobj_keyslot, "type", &jobj_type) ||
739 strcmp(json_object_get_string(jobj_type), "reencrypt"))
742 return reenc_keyslot_load_resilience(cd, jobj_keyslot, rp, primary);
745 const keyslot_handler reenc_keyslot = {
747 .open = reenc_keyslot_open,
748 .store = reenc_keyslot_store, /* initialization only or also per every chunk write */
749 .wipe = reenc_keyslot_wipe,
750 .dump = reenc_keyslot_dump,
751 .validate = reenc_keyslot_validate