2 * LUKS - Linux Unified Key Setup v2, reencryption digest helpers
4 * Copyright (C) 2022-2023 Red Hat, Inc. All rights reserved.
5 * Copyright (C) 2022-2023 Ondrej Kozina
6 * Copyright (C) 2022-2023 Milan Broz
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include "luks2_internal.h"
28 enum { JNONE = 0, JSTR, JU64, JX64, JU32 } type;
33 static size_t sr(struct jtype *j, uint8_t *ptr)
40 if (!json_object_is_type(j->jobj, json_type_object))
43 if (!json_object_object_get_ex(j->jobj, j->id, &jobj))
47 case JSTR: /* JSON string */
48 if (!json_object_is_type(jobj, json_type_string))
50 len = strlen(json_object_get_string(jobj));
54 memcpy(ptr, json_object_get_string(jobj), len);
56 case JU64: /* Unsigned 64bit integer stored as string */
57 if (!json_object_is_type(jobj, json_type_string))
61 u64 = cpu_to_be64(crypt_jobj_get_uint64(jobj));
62 memcpy(ptr, &u64, len);
65 case JX64: /* Unsigned 64bit segment size (allows "dynamic") */
66 if (!json_object_is_type(jobj, json_type_string))
68 if (!strcmp(json_object_get_string(jobj), "dynamic")) {
69 len = strlen("dynamic");
71 memcpy(ptr, json_object_get_string(jobj), len);
74 u64 = cpu_to_be64(crypt_jobj_get_uint64(jobj));
76 memcpy(ptr, &u64, len);
79 case JU32: /* Unsigned 32bit integer, stored as JSON int */
80 if (!json_object_is_type(jobj, json_type_int))
84 u32 = cpu_to_be32(crypt_jobj_get_uint32(jobj));
85 memcpy(ptr, &u32, len);
95 static size_t srs(struct jtype j[], uint8_t *ptr)
111 static size_t segment_linear_serialize(json_object *jobj_segment, uint8_t *buffer)
114 { JSTR, jobj_segment, "type" },
115 { JU64, jobj_segment, "offset" },
116 { JX64, jobj_segment, "size" },
119 return srs(j, buffer);
122 static size_t segment_crypt_serialize(json_object *jobj_segment, uint8_t *buffer)
125 { JSTR, jobj_segment, "type" },
126 { JU64, jobj_segment, "offset" },
127 { JX64, jobj_segment, "size" },
128 { JU64, jobj_segment, "iv_tweak" },
129 { JSTR, jobj_segment, "encryption" },
130 { JU32, jobj_segment, "sector_size" },
133 return srs(j, buffer);
136 static size_t segment_serialize(json_object *jobj_segment, uint8_t *buffer)
138 json_object *jobj_type;
139 const char *segment_type;
141 if (!json_object_object_get_ex(jobj_segment, "type", &jobj_type))
144 if (!(segment_type = json_object_get_string(jobj_type)))
147 if (!strcmp(segment_type, "crypt"))
148 return segment_crypt_serialize(jobj_segment, buffer);
149 else if (!strcmp(segment_type, "linear"))
150 return segment_linear_serialize(jobj_segment, buffer);
155 static size_t backup_segments_serialize(struct luks2_hdr *hdr, uint8_t *buffer)
157 json_object *jobj_segment;
160 jobj_segment = LUKS2_get_segment_by_flag(hdr, "backup-previous");
161 if (!jobj_segment || !(l = segment_serialize(jobj_segment, buffer)))
167 jobj_segment = LUKS2_get_segment_by_flag(hdr, "backup-final");
168 if (!jobj_segment || !(l = segment_serialize(jobj_segment, buffer)))
174 jobj_segment = LUKS2_get_segment_by_flag(hdr, "backup-moved-segment");
176 if (!(l = segment_serialize(jobj_segment, buffer)))
184 static size_t reenc_keyslot_serialize(struct luks2_hdr *hdr, uint8_t *buffer)
186 json_object *jobj_keyslot, *jobj_area, *jobj_type;
187 const char *area_type;
188 int keyslot_reencrypt;
190 keyslot_reencrypt = LUKS2_find_keyslot(hdr, "reencrypt");
191 if (keyslot_reencrypt < 0)
194 if (!(jobj_keyslot = LUKS2_get_keyslot_jobj(hdr, keyslot_reencrypt)))
197 if (!json_object_object_get_ex(jobj_keyslot, "area", &jobj_area))
200 if (!json_object_object_get_ex(jobj_area, "type", &jobj_type))
203 if (!(area_type = json_object_get_string(jobj_type)))
207 { JSTR, jobj_keyslot, "mode" },
208 { JSTR, jobj_keyslot, "direction" },
209 { JSTR, jobj_area, "type" },
210 { JU64, jobj_area, "offset" },
211 { JU64, jobj_area, "size" },
214 struct jtype j_datashift[] = {
215 { JSTR, jobj_keyslot, "mode" },
216 { JSTR, jobj_keyslot, "direction" },
217 { JSTR, jobj_area, "type" },
218 { JU64, jobj_area, "offset" },
219 { JU64, jobj_area, "size" },
220 { JU64, jobj_area, "shift_size" },
223 struct jtype j_checksum[] = {
224 { JSTR, jobj_keyslot, "mode" },
225 { JSTR, jobj_keyslot, "direction" },
226 { JSTR, jobj_area, "type" },
227 { JU64, jobj_area, "offset" },
228 { JU64, jobj_area, "size" },
229 { JSTR, jobj_area, "hash" },
230 { JU32, jobj_area, "sector_size" },
233 struct jtype j_datashift_checksum[] = {
234 { JSTR, jobj_keyslot, "mode" },
235 { JSTR, jobj_keyslot, "direction" },
236 { JSTR, jobj_area, "type" },
237 { JU64, jobj_area, "offset" },
238 { JU64, jobj_area, "size" },
239 { JSTR, jobj_area, "hash" },
240 { JU32, jobj_area, "sector_size" },
241 { JU64, jobj_area, "shift_size" },
245 if (!strcmp(area_type, "datashift-checksum"))
246 return srs(j_datashift_checksum, buffer);
247 else if (!strcmp(area_type, "datashift") ||
248 !strcmp(area_type, "datashift-journal"))
249 return srs(j_datashift, buffer);
250 else if (!strcmp(area_type, "checksum"))
251 return srs(j_checksum, buffer);
253 return srs(j, buffer);
256 static size_t blob_serialize(void *blob, size_t length, uint8_t *buffer)
259 memcpy(buffer, blob, length);
264 static int reencrypt_assembly_verification_data(struct crypt_device *cd,
265 struct luks2_hdr *hdr,
266 struct volume_key *vks,
268 struct volume_key **verification_data)
271 int digest_new, digest_old;
272 struct volume_key *data = NULL, *vk_old = NULL, *vk_new = NULL;
273 size_t keyslot_data_len, segments_data_len, data_len = 2;
276 * This works up to (including) version v207.
278 assert(version < (UINT8_MAX - 0x2F));
280 /* Keys - calculate length */
281 digest_new = LUKS2_reencrypt_digest_new(hdr);
282 digest_old = LUKS2_reencrypt_digest_old(hdr);
284 if (digest_old >= 0) {
285 vk_old = crypt_volume_key_by_id(vks, digest_old);
287 log_dbg(cd, "Key (digest id %d) required but not unlocked.", digest_old);
290 data_len += blob_serialize(vk_old->key, vk_old->keylength, NULL);
293 if (digest_new >= 0 && digest_old != digest_new) {
294 vk_new = crypt_volume_key_by_id(vks, digest_new);
296 log_dbg(cd, "Key (digest id %d) required but not unlocked.", digest_new);
299 data_len += blob_serialize(vk_new->key, vk_new->keylength, NULL);
305 /* Metadata - calculate length */
306 if (!(keyslot_data_len = reenc_keyslot_serialize(hdr, NULL)))
308 data_len += keyslot_data_len;
310 if (!(segments_data_len = backup_segments_serialize(hdr, NULL)))
312 data_len += segments_data_len;
314 /* Alloc and fill serialization data */
315 data = crypt_alloc_volume_key(data_len, NULL);
319 ptr = (uint8_t*)data->key;
322 *ptr++ = 0x30 + version;
325 ptr += blob_serialize(vk_old->key, vk_old->keylength, ptr);
328 ptr += blob_serialize(vk_new->key, vk_new->keylength, ptr);
330 if (!reenc_keyslot_serialize(hdr, ptr))
332 ptr += keyslot_data_len;
334 if (!backup_segments_serialize(hdr, ptr))
336 ptr += segments_data_len;
338 assert((size_t)(ptr - (uint8_t*)data->key) == data_len);
340 *verification_data = data;
344 crypt_free_volume_key(data);
348 int LUKS2_keyslot_reencrypt_digest_create(struct crypt_device *cd,
349 struct luks2_hdr *hdr,
351 struct volume_key *vks)
353 int digest_reencrypt, keyslot_reencrypt, r;
354 struct volume_key *data;
356 keyslot_reencrypt = LUKS2_find_keyslot(hdr, "reencrypt");
357 if (keyslot_reencrypt < 0)
358 return keyslot_reencrypt;
360 r = reencrypt_assembly_verification_data(cd, hdr, vks, version, &data);
364 r = LUKS2_digest_create(cd, "pbkdf2", hdr, data);
365 crypt_free_volume_key(data);
369 digest_reencrypt = r;
371 r = LUKS2_digest_assign(cd, hdr, keyslot_reencrypt, CRYPT_ANY_DIGEST, 0, 0);
375 return LUKS2_digest_assign(cd, hdr, keyslot_reencrypt, digest_reencrypt, 1, 0);
378 int LUKS2_reencrypt_digest_verify(struct crypt_device *cd,
379 struct luks2_hdr *hdr,
380 struct volume_key *vks)
382 int r, keyslot_reencrypt;
383 struct volume_key *data;
386 log_dbg(cd, "Verifying reencryption metadata.");
388 keyslot_reencrypt = LUKS2_find_keyslot(hdr, "reencrypt");
389 if (keyslot_reencrypt < 0)
390 return keyslot_reencrypt;
392 if (LUKS2_config_get_reencrypt_version(hdr, &version))
395 r = reencrypt_assembly_verification_data(cd, hdr, vks, version, &data);
399 r = LUKS2_digest_verify(cd, hdr, data, keyslot_reencrypt);
400 crypt_free_volume_key(data);
404 log_dbg(cd, "Reencryption digest is missing.");
405 log_err(cd, _("Reencryption metadata is invalid."));
407 log_dbg(cd, "Reencryption metadata verified.");