2 * LUKS - Linux Unified Key Setup v2, reencryption digest helpers
4 * Copyright (C) 2022, Red Hat, Inc. All rights reserved.
5 * Copyright (C) 2022, Ondrej Kozina
6 * Copyright (C) 2022, 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"
29 enum { JNONE = 0, JSTR, JU64, JX64, JU32 } type;
34 static size_t sr(struct jtype *j, uint8_t *ptr)
41 if (!json_object_is_type(j->jobj, json_type_object))
44 if (!json_object_object_get_ex(j->jobj, j->id, &jobj))
48 case JSTR: /* JSON string */
49 if (!json_object_is_type(jobj, json_type_string))
51 len = strlen(json_object_get_string(jobj));
55 memcpy(ptr, json_object_get_string(jobj), len);
57 case JU64: /* Unsigned 64bit integer stored as string */
58 if (!json_object_is_type(jobj, json_type_string))
62 u64 = cpu_to_be64(crypt_jobj_get_uint64(jobj));
63 memcpy(ptr, &u64, len);
66 case JX64: /* Unsigned 64bit segment size (allows "dynamic") */
67 if (!json_object_is_type(jobj, json_type_string))
69 if (!strcmp(json_object_get_string(jobj), "dynamic")) {
70 len = strlen("dynamic");
72 memcpy(ptr, json_object_get_string(jobj), len);
75 u64 = cpu_to_be64(crypt_jobj_get_uint64(jobj));
77 memcpy(ptr, &u64, len);
80 case JU32: /* Unsigned 32bit integer, stored as JSON int */
81 if (!json_object_is_type(jobj, json_type_int))
85 u32 = cpu_to_be32(crypt_jobj_get_uint32(jobj));
86 memcpy(ptr, &u32, len);
96 static size_t srs(struct jtype j[], uint8_t *ptr)
112 static size_t segment_linear_serialize(json_object *jobj_segment, uint8_t *buffer)
115 { JSTR, jobj_segment, "type" },
116 { JU64, jobj_segment, "offset" },
117 { JX64, jobj_segment, "size" },
120 return srs(j, buffer);
123 static size_t segment_crypt_serialize(json_object *jobj_segment, uint8_t *buffer)
126 { JSTR, jobj_segment, "type" },
127 { JU64, jobj_segment, "offset" },
128 { JX64, jobj_segment, "size" },
129 { JU64, jobj_segment, "iv_tweak" },
130 { JSTR, jobj_segment, "encryption" },
131 { JU32, jobj_segment, "sector_size" },
134 return srs(j, buffer);
137 static size_t segment_serialize(json_object *jobj_segment, uint8_t *buffer)
139 json_object *jobj_type;
140 const char *segment_type;
142 if (!json_object_object_get_ex(jobj_segment, "type", &jobj_type))
145 if (!(segment_type = json_object_get_string(jobj_type)))
148 if (!strcmp(segment_type, "crypt"))
149 return segment_crypt_serialize(jobj_segment, buffer);
150 else if (!strcmp(segment_type, "linear"))
151 return segment_linear_serialize(jobj_segment, buffer);
156 static size_t backup_segments_serialize(struct luks2_hdr *hdr, uint8_t *buffer)
158 json_object *jobj_segment;
161 jobj_segment = LUKS2_get_segment_by_flag(hdr, "backup-previous");
162 if (!jobj_segment || !(l = segment_serialize(jobj_segment, buffer)))
168 jobj_segment = LUKS2_get_segment_by_flag(hdr, "backup-final");
169 if (!jobj_segment || !(l = segment_serialize(jobj_segment, buffer)))
175 jobj_segment = LUKS2_get_segment_by_flag(hdr, "backup-moved-segment");
177 if (!(l = segment_serialize(jobj_segment, buffer)))
185 static size_t reenc_keyslot_serialize(struct luks2_hdr *hdr, uint8_t *buffer)
187 json_object *jobj_keyslot, *jobj_area, *jobj_type;
188 const char *area_type;
189 int keyslot_reencrypt;
191 keyslot_reencrypt = LUKS2_find_keyslot(hdr, "reencrypt");
192 if (keyslot_reencrypt < 0)
195 if (!(jobj_keyslot = LUKS2_get_keyslot_jobj(hdr, keyslot_reencrypt)))
198 if (!json_object_object_get_ex(jobj_keyslot, "area", &jobj_area))
201 if (!json_object_object_get_ex(jobj_area, "type", &jobj_type))
204 if (!(area_type = json_object_get_string(jobj_type)))
208 { JSTR, jobj_keyslot, "mode" },
209 { JSTR, jobj_keyslot, "direction" },
210 { JSTR, jobj_area, "type" },
211 { JU64, jobj_area, "offset" },
212 { JU64, jobj_area, "size" },
215 struct jtype j_datashift[] = {
216 { JSTR, jobj_keyslot, "mode" },
217 { JSTR, jobj_keyslot, "direction" },
218 { JSTR, jobj_area, "type" },
219 { JU64, jobj_area, "offset" },
220 { JU64, jobj_area, "size" },
221 { JU64, jobj_area, "shift_size" },
224 struct jtype j_checksum[] = {
225 { JSTR, jobj_keyslot, "mode" },
226 { JSTR, jobj_keyslot, "direction" },
227 { JSTR, jobj_area, "type" },
228 { JU64, jobj_area, "offset" },
229 { JU64, jobj_area, "size" },
230 { JSTR, jobj_area, "hash" },
231 { JU32, jobj_area, "sector_size" },
235 if (!strcmp(area_type, "datashift"))
236 return srs(j_datashift, buffer);
237 else if (!strcmp(area_type, "checksum"))
238 return srs(j_checksum, buffer);
240 return srs(j, buffer);
243 static size_t blob_serialize(void *blob, size_t length, uint8_t *buffer)
246 memcpy(buffer, blob, length);
251 static int reencrypt_assembly_verification_data(struct crypt_device *cd,
252 struct luks2_hdr *hdr,
253 struct volume_key *vks,
254 struct volume_key **verification_data)
257 int digest_new, digest_old;
258 struct volume_key *data = NULL, *vk_old = NULL, *vk_new = NULL;
259 size_t keyslot_data_len, segments_data_len, data_len = 2;
261 /* Keys - calculate length */
262 digest_new = LUKS2_reencrypt_digest_new(hdr);
263 digest_old = LUKS2_reencrypt_digest_old(hdr);
265 if (digest_old >= 0) {
266 vk_old = crypt_volume_key_by_id(vks, digest_old);
269 data_len += blob_serialize(vk_old->key, vk_old->keylength, NULL);
272 if (digest_new >= 0 && digest_old != digest_new) {
273 vk_new = crypt_volume_key_by_id(vks, digest_new);
276 data_len += blob_serialize(vk_new->key, vk_new->keylength, NULL);
282 /* Metadata - calculate length */
283 if (!(keyslot_data_len = reenc_keyslot_serialize(hdr, NULL)))
285 data_len += keyslot_data_len;
287 if (!(segments_data_len = backup_segments_serialize(hdr, NULL)))
289 data_len += segments_data_len;
291 /* Alloc and fill serialization data */
292 data = crypt_alloc_volume_key(data_len, NULL);
296 ptr = (uint8_t*)data->key;
303 ptr += blob_serialize(vk_old->key, vk_old->keylength, ptr);
306 ptr += blob_serialize(vk_new->key, vk_new->keylength, ptr);
308 if (!reenc_keyslot_serialize(hdr, ptr))
310 ptr += keyslot_data_len;
312 if (!backup_segments_serialize(hdr, ptr))
314 ptr += segments_data_len;
316 assert((size_t)(ptr - (uint8_t*)data->key) == data_len);
318 *verification_data = data;
322 crypt_free_volume_key(data);
326 int LUKS2_keyslot_reencrypt_digest_create(struct crypt_device *cd,
327 struct luks2_hdr *hdr,
328 struct volume_key *vks)
330 int digest_reencrypt, keyslot_reencrypt, r;
331 struct volume_key *data;
333 keyslot_reencrypt = LUKS2_find_keyslot(hdr, "reencrypt");
334 if (keyslot_reencrypt < 0)
335 return keyslot_reencrypt;
337 r = reencrypt_assembly_verification_data(cd, hdr, vks, &data);
341 r = LUKS2_digest_create(cd, "pbkdf2", hdr, data);
342 crypt_free_volume_key(data);
346 digest_reencrypt = r;
348 r = LUKS2_digest_assign(cd, hdr, keyslot_reencrypt, CRYPT_ANY_DIGEST, 0, 0);
352 return LUKS2_digest_assign(cd, hdr, keyslot_reencrypt, digest_reencrypt, 1, 0);
355 int LUKS2_reencrypt_digest_verify(struct crypt_device *cd,
356 struct luks2_hdr *hdr,
357 struct volume_key *vks)
359 int r, keyslot_reencrypt;
360 struct volume_key *data;
362 keyslot_reencrypt = LUKS2_find_keyslot(hdr, "reencrypt");
363 if (keyslot_reencrypt < 0)
364 return keyslot_reencrypt;
366 r = reencrypt_assembly_verification_data(cd, hdr, vks, &data);
370 r = LUKS2_digest_verify(cd, hdr, data, keyslot_reencrypt);
371 crypt_free_volume_key(data);
375 log_dbg(cd, "Reencryption digest is missing.");
376 log_err(cd, _("Reencryption metadata is invalid."));
378 log_dbg(cd, "Reencryption metadata verified.");