/src/cryptsetup/lib/luks2/luks2_internal.h
Line | Count | Source |
1 | | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | | /* |
3 | | * LUKS - Linux Unified Key Setup v2 (with JSON internals) |
4 | | * |
5 | | * Copyright (C) 2015-2025 Red Hat, Inc. All rights reserved. |
6 | | * Copyright (C) 2015-2025 Milan Broz |
7 | | */ |
8 | | |
9 | | #ifndef _CRYPTSETUP_LUKS2_INTERNAL_H |
10 | | #define _CRYPTSETUP_LUKS2_INTERNAL_H |
11 | | |
12 | | #include <stdio.h> |
13 | | #include <errno.h> |
14 | | #include <json-c/json.h> |
15 | | |
16 | | #include "internal.h" |
17 | | #include "luks2.h" |
18 | | |
19 | | /* override useless forward slash escape when supported by json-c */ |
20 | | #ifndef JSON_C_TO_STRING_NOSLASHESCAPE |
21 | | #define JSON_C_TO_STRING_NOSLASHESCAPE 0 |
22 | | #endif |
23 | | |
24 | | /* |
25 | | * On-disk access function prototypes |
26 | | */ |
27 | | int LUKS2_disk_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr, |
28 | | struct device *device, int do_recovery, int do_blkprobe); |
29 | | int LUKS2_disk_hdr_write(struct crypt_device *cd, struct luks2_hdr *hdr, |
30 | | struct device *device, bool seqid_check); |
31 | | int LUKS2_device_write_lock(struct crypt_device *cd, |
32 | | struct luks2_hdr *hdr, struct device *device); |
33 | | |
34 | | /* |
35 | | * JSON struct access helpers |
36 | | */ |
37 | | json_object *LUKS2_get_keyslot_jobj(struct luks2_hdr *hdr, int keyslot); |
38 | | json_object *LUKS2_get_token_jobj(struct luks2_hdr *hdr, int token); |
39 | | json_object *LUKS2_get_digest_jobj(struct luks2_hdr *hdr, int digest); |
40 | | json_object *LUKS2_get_segment_jobj(struct luks2_hdr *hdr, int segment); |
41 | | json_object *LUKS2_get_tokens_jobj(struct luks2_hdr *hdr); |
42 | | json_object *LUKS2_get_segments_jobj(struct luks2_hdr *hdr); |
43 | | |
44 | | void hexprint_base64(struct crypt_device *cd, json_object *jobj, |
45 | | const char *sep, const char *line_sep); |
46 | | |
47 | | uint64_t crypt_jobj_get_uint64(json_object *jobj); |
48 | | uint32_t crypt_jobj_get_uint32(json_object *jobj); |
49 | | json_object *crypt_jobj_new_uint64(uint64_t value); |
50 | | |
51 | | /* |
52 | | * Generate json format string representation libcryptsetup uses |
53 | | * to store json metadata on disk. |
54 | | */ |
55 | | static inline const char *crypt_jobj_to_string_on_disk(json_object *jobj) |
56 | 6.19k | { |
57 | 6.19k | return json_object_to_json_string_ext(jobj, |
58 | 6.19k | JSON_C_TO_STRING_PLAIN | JSON_C_TO_STRING_NOSLASHESCAPE); |
59 | 6.19k | } Unexecuted instantiation: utils_wipe.c:crypt_jobj_to_string_on_disk Unexecuted instantiation: luks2_disk_metadata.c:crypt_jobj_to_string_on_disk Unexecuted instantiation: luks2_json_format.c:crypt_jobj_to_string_on_disk luks2_json_metadata.c:crypt_jobj_to_string_on_disk Line | Count | Source | 56 | 6.19k | { | 57 | 6.19k | return json_object_to_json_string_ext(jobj, | 58 | 6.19k | JSON_C_TO_STRING_PLAIN | JSON_C_TO_STRING_NOSLASHESCAPE); | 59 | 6.19k | } |
Unexecuted instantiation: luks2_luks1_convert.c:crypt_jobj_to_string_on_disk Unexecuted instantiation: luks2_digest.c:crypt_jobj_to_string_on_disk Unexecuted instantiation: luks2_digest_pbkdf2.c:crypt_jobj_to_string_on_disk Unexecuted instantiation: luks2_keyslot.c:crypt_jobj_to_string_on_disk Unexecuted instantiation: luks2_keyslot_luks2.c:crypt_jobj_to_string_on_disk Unexecuted instantiation: luks2_keyslot_reenc.c:crypt_jobj_to_string_on_disk Unexecuted instantiation: luks2_reencrypt.c:crypt_jobj_to_string_on_disk Unexecuted instantiation: luks2_reencrypt_digest.c:crypt_jobj_to_string_on_disk Unexecuted instantiation: luks2_segment.c:crypt_jobj_to_string_on_disk Unexecuted instantiation: luks2_token_keyring.c:crypt_jobj_to_string_on_disk Unexecuted instantiation: luks2_token.c:crypt_jobj_to_string_on_disk |
60 | | |
61 | | int json_object_object_add_by_uint(json_object *jobj, unsigned key, json_object *jobj_val); |
62 | | int json_object_object_add_by_uint_by_ref(json_object *jobj, unsigned key, json_object **jobj_val_ref); |
63 | | void json_object_object_del_by_uint(json_object *jobj, unsigned key); |
64 | | int json_object_copy(json_object *jobj_src, json_object **jobj_dst); |
65 | | |
66 | | void JSON_DBG(struct crypt_device *cd, json_object *jobj, const char *desc); |
67 | | |
68 | | /* |
69 | | * LUKS2 JSON validation |
70 | | */ |
71 | | |
72 | | /* validation helper */ |
73 | | bool validate_json_uint32(json_object *jobj); |
74 | | json_object *json_contains(struct crypt_device *cd, json_object *jobj, const char *name, |
75 | | const char *section, const char *key, json_type type); |
76 | | json_object *json_contains_string(struct crypt_device *cd, json_object *jobj, |
77 | | const char *name, const char *section, const char *key); |
78 | | |
79 | | int LUKS2_hdr_validate(struct crypt_device *cd, json_object *hdr_jobj, uint64_t json_size); |
80 | | int LUKS2_check_json_size(struct crypt_device *cd, const struct luks2_hdr *hdr); |
81 | | int LUKS2_token_validate(struct crypt_device *cd, json_object *hdr_jobj, |
82 | | json_object *jobj_token, const char *key); |
83 | | void LUKS2_token_dump(struct crypt_device *cd, int token); |
84 | | |
85 | | /* |
86 | | * LUKS2 JSON repair for known glitches |
87 | | */ |
88 | | void LUKS2_hdr_repair(struct crypt_device *cd, json_object *jobj_hdr); |
89 | | void LUKS2_keyslots_repair(struct crypt_device *cd, json_object *jobj_hdr); |
90 | | |
91 | | /* |
92 | | * JSON array helpers |
93 | | */ |
94 | | json_object *LUKS2_array_jobj(json_object *array, const char *num); |
95 | | json_object *LUKS2_array_remove(json_object *array, const char *num); |
96 | | |
97 | | /* |
98 | | * Plugins API |
99 | | */ |
100 | | |
101 | | /** |
102 | | * LUKS2 keyslots handlers |
103 | | */ |
104 | | typedef int (*keyslot_alloc_func)(struct crypt_device *cd, int keyslot, |
105 | | size_t volume_key_len, |
106 | | const struct luks2_keyslot_params *params); |
107 | | typedef int (*keyslot_update_func)(struct crypt_device *cd, int keyslot, |
108 | | const struct luks2_keyslot_params *params); |
109 | | typedef int (*keyslot_open_func) (struct crypt_device *cd, int keyslot, |
110 | | const char *password, size_t password_len, |
111 | | char *volume_key, size_t volume_key_len); |
112 | | typedef int (*keyslot_store_func)(struct crypt_device *cd, int keyslot, |
113 | | const char *password, size_t password_len, |
114 | | const char *volume_key, size_t volume_key_len); |
115 | | typedef int (*keyslot_wipe_func) (struct crypt_device *cd, int keyslot); |
116 | | typedef int (*keyslot_dump_func) (struct crypt_device *cd, int keyslot); |
117 | | typedef int (*keyslot_validate_func) (struct crypt_device *cd, json_object *jobj_keyslot); |
118 | | typedef void(*keyslot_repair_func) (json_object *jobj_keyslot); |
119 | | |
120 | | /* see LUKS2_luks2_to_luks1 */ |
121 | | int placeholder_keyslot_alloc(struct crypt_device *cd, |
122 | | int keyslot, |
123 | | uint64_t area_offset, |
124 | | uint64_t area_length); |
125 | | |
126 | | /* validate all keyslot implementations in hdr json */ |
127 | | int LUKS2_keyslots_validate(struct crypt_device *cd, json_object *hdr_jobj); |
128 | | |
129 | | typedef struct { |
130 | | const char *name; |
131 | | keyslot_alloc_func alloc; |
132 | | keyslot_update_func update; |
133 | | keyslot_open_func open; |
134 | | keyslot_store_func store; |
135 | | keyslot_wipe_func wipe; |
136 | | keyslot_dump_func dump; |
137 | | keyslot_validate_func validate; |
138 | | keyslot_repair_func repair; |
139 | | } keyslot_handler; |
140 | | |
141 | | struct reenc_protection { |
142 | | enum { REENC_PROTECTION_NOT_SET = 0, |
143 | | REENC_PROTECTION_NONE, |
144 | | REENC_PROTECTION_CHECKSUM, |
145 | | REENC_PROTECTION_JOURNAL, |
146 | | REENC_PROTECTION_DATASHIFT } type; |
147 | | |
148 | | union { |
149 | | struct { |
150 | | char hash[LUKS2_CHECKSUM_ALG_L]; |
151 | | struct crypt_hash *ch; |
152 | | size_t hash_size; |
153 | | /* buffer for checksums */ |
154 | | void *checksums; |
155 | | size_t checksums_len; |
156 | | size_t block_size; |
157 | | } csum; |
158 | | struct { |
159 | | uint64_t data_shift; |
160 | | } ds; |
161 | | } p; |
162 | | }; |
163 | | |
164 | | /** |
165 | | * LUKS2 digest handlers |
166 | | */ |
167 | | typedef int (*digest_verify_func)(struct crypt_device *cd, int digest, |
168 | | const char *volume_key, size_t volume_key_len); |
169 | | typedef int (*digest_store_func) (struct crypt_device *cd, int digest, |
170 | | const char *volume_key, size_t volume_key_len); |
171 | | typedef int (*digest_dump_func) (struct crypt_device *cd, int digest); |
172 | | |
173 | | typedef struct { |
174 | | const char *name; |
175 | | digest_verify_func verify; |
176 | | digest_store_func store; |
177 | | digest_dump_func dump; |
178 | | } digest_handler; |
179 | | |
180 | | int keyring_open(struct crypt_device *cd, |
181 | | int token, |
182 | | char **buffer, |
183 | | size_t *buffer_len, |
184 | | void *usrptr); |
185 | | |
186 | | void keyring_dump(struct crypt_device *cd, const char *json); |
187 | | |
188 | | int keyring_validate(struct crypt_device *cd, const char *json); |
189 | | |
190 | | void keyring_buffer_free(void *buffer, size_t buffer_size); |
191 | | |
192 | | struct crypt_token_handler_v2 { |
193 | | const char *name; |
194 | | crypt_token_open_func open; |
195 | | crypt_token_buffer_free_func buffer_free; |
196 | | crypt_token_validate_func validate; |
197 | | crypt_token_dump_func dump; |
198 | | |
199 | | /* here ends v1. Do not touch anything above */ |
200 | | |
201 | | crypt_token_open_pin_func open_pin; |
202 | | crypt_token_version_func version; |
203 | | |
204 | | void *dlhandle; |
205 | | }; |
206 | | |
207 | | /* |
208 | | * Initial sequence of structure members in union 'u' must be always |
209 | | * identical. Version 4 must fully contain version 3 which must |
210 | | * subsequently fully contain version 2, etc. |
211 | | * |
212 | | * See C standard, section 6.5.2.3, item 5. |
213 | | */ |
214 | | struct crypt_token_handler_internal { |
215 | | uint32_t version; |
216 | | union { |
217 | | crypt_token_handler v1; /* deprecated public structure */ |
218 | | struct crypt_token_handler_v2 v2; /* internal helper v2 structure */ |
219 | | } u; |
220 | | }; |
221 | | |
222 | | int LUKS2_find_area_gap(struct crypt_device *cd, struct luks2_hdr *hdr, |
223 | | size_t keylength, uint64_t *area_offset, uint64_t *area_length); |
224 | | int LUKS2_find_area_max_gap(struct crypt_device *cd, struct luks2_hdr *hdr, |
225 | | uint64_t *area_offset, uint64_t *area_length); |
226 | | |
227 | | uint64_t LUKS2_hdr_and_areas_size_jobj(json_object *jobj); |
228 | | |
229 | | int LUKS2_check_cipher(struct crypt_device *cd, |
230 | | size_t keylength, |
231 | | const char *cipher, |
232 | | const char *cipher_mode); |
233 | | |
234 | | static inline const char *crypt_reencrypt_mode_to_str(crypt_reencrypt_mode_info mi) |
235 | 0 | { |
236 | 0 | if (mi == CRYPT_REENCRYPT_REENCRYPT) |
237 | 0 | return "reencrypt"; |
238 | 0 | if (mi == CRYPT_REENCRYPT_ENCRYPT) |
239 | 0 | return "encrypt"; |
240 | 0 | if (mi == CRYPT_REENCRYPT_DECRYPT) |
241 | 0 | return "decrypt"; |
242 | 0 | return "<unknown>"; |
243 | 0 | } Unexecuted instantiation: utils_wipe.c:crypt_reencrypt_mode_to_str Unexecuted instantiation: luks2_disk_metadata.c:crypt_reencrypt_mode_to_str Unexecuted instantiation: luks2_json_format.c:crypt_reencrypt_mode_to_str Unexecuted instantiation: luks2_json_metadata.c:crypt_reencrypt_mode_to_str Unexecuted instantiation: luks2_luks1_convert.c:crypt_reencrypt_mode_to_str Unexecuted instantiation: luks2_digest.c:crypt_reencrypt_mode_to_str Unexecuted instantiation: luks2_digest_pbkdf2.c:crypt_reencrypt_mode_to_str Unexecuted instantiation: luks2_keyslot.c:crypt_reencrypt_mode_to_str Unexecuted instantiation: luks2_keyslot_luks2.c:crypt_reencrypt_mode_to_str Unexecuted instantiation: luks2_keyslot_reenc.c:crypt_reencrypt_mode_to_str Unexecuted instantiation: luks2_reencrypt.c:crypt_reencrypt_mode_to_str Unexecuted instantiation: luks2_reencrypt_digest.c:crypt_reencrypt_mode_to_str Unexecuted instantiation: luks2_segment.c:crypt_reencrypt_mode_to_str Unexecuted instantiation: luks2_token_keyring.c:crypt_reencrypt_mode_to_str Unexecuted instantiation: luks2_token.c:crypt_reencrypt_mode_to_str |
244 | | |
245 | | /* |
246 | | * Generic LUKS2 keyslot |
247 | | */ |
248 | | int LUKS2_keyslot_reencrypt_store(struct crypt_device *cd, |
249 | | struct luks2_hdr *hdr, |
250 | | int keyslot, |
251 | | const void *buffer, |
252 | | size_t buffer_length); |
253 | | |
254 | | int LUKS2_keyslot_reencrypt_allocate(struct crypt_device *cd, |
255 | | struct luks2_hdr *hdr, |
256 | | int keyslot, |
257 | | const struct crypt_params_reencrypt *params, |
258 | | size_t alignment); |
259 | | |
260 | | int LUKS2_keyslot_reencrypt_update_needed(struct crypt_device *cd, |
261 | | struct luks2_hdr *hdr, |
262 | | int keyslot, |
263 | | const struct crypt_params_reencrypt *params, |
264 | | size_t alignment); |
265 | | |
266 | | int LUKS2_keyslot_reencrypt_update(struct crypt_device *cd, |
267 | | struct luks2_hdr *hdr, |
268 | | int keyslot, |
269 | | const struct crypt_params_reencrypt *params, |
270 | | size_t alignment, |
271 | | struct volume_key *vks); |
272 | | |
273 | | int LUKS2_keyslot_reencrypt_load(struct crypt_device *cd, |
274 | | struct luks2_hdr *hdr, |
275 | | int keyslot, |
276 | | struct reenc_protection *rp, |
277 | | bool primary); |
278 | | |
279 | | int LUKS2_keyslot_reencrypt_digest_create(struct crypt_device *cd, |
280 | | struct luks2_hdr *hdr, |
281 | | uint8_t version, |
282 | | struct volume_key *vks); |
283 | | |
284 | | int LUKS2_keyslot_dump(struct crypt_device *cd, |
285 | | int keyslot); |
286 | | |
287 | | int LUKS2_keyslot_jobj_area(json_object *jobj_keyslot, uint64_t *offset, uint64_t *length); |
288 | | |
289 | | /* JSON helpers */ |
290 | | uint64_t json_segment_get_offset(json_object *jobj_segment, unsigned blockwise); |
291 | | const char *json_segment_type(json_object *jobj_segment); |
292 | | uint64_t json_segment_get_iv_offset(json_object *jobj_segment); |
293 | | uint64_t json_segment_get_size(json_object *jobj_segment, unsigned blockwise); |
294 | | const char *json_segment_get_cipher(json_object *jobj_segment); |
295 | | uint32_t json_segment_get_sector_size(json_object *jobj_segment); |
296 | | int json_segment_get_opal_segment_id(json_object *jobj_segment, uint32_t *ret_opal_segment_id); |
297 | | int json_segment_get_opal_key_size(json_object *jobj_segment, size_t *ret_key_size); |
298 | | bool json_segment_is_backup(json_object *jobj_segment); |
299 | | json_object *json_segments_get_segment(json_object *jobj_segments, int segment); |
300 | | unsigned json_segments_count(json_object *jobj_segments); |
301 | | void json_segment_remove_flag(json_object *jobj_segment, const char *flag); |
302 | | uint64_t json_segments_get_minimal_offset(json_object *jobj_segments, unsigned blockwise); |
303 | | json_object *json_segment_create_linear(uint64_t offset, const uint64_t *length, unsigned reencryption); |
304 | | json_object *json_segment_create_crypt(uint64_t offset, uint64_t iv_offset, const uint64_t *length, |
305 | | const char *cipher, const char *integrity, uint32_t integrity_key_size, |
306 | | uint32_t sector_size, unsigned reencryption); |
307 | | json_object *json_segment_create_opal(uint64_t offset, const uint64_t *length, |
308 | | uint32_t segment_number, uint32_t key_size); |
309 | | json_object *json_segment_create_opal_crypt(uint64_t offset, const uint64_t *length, |
310 | | uint32_t segment_number, uint32_t key_size, |
311 | | uint64_t iv_offset, const char *cipher, |
312 | | const char *integrity, uint32_t sector_size, |
313 | | unsigned reencryption); |
314 | | int json_segments_segment_in_reencrypt(json_object *jobj_segments); |
315 | | bool json_segment_cmp(json_object *jobj_segment_1, json_object *jobj_segment_2); |
316 | | bool json_segment_contains_flag(json_object *jobj_segment, const char *flag_str, size_t len); |
317 | | |
318 | | int LUKS2_assembly_multisegment_dmd(struct crypt_device *cd, |
319 | | struct luks2_hdr *hdr, |
320 | | struct volume_key *vks, |
321 | | json_object *jobj_segments, |
322 | | struct crypt_dm_active_device *dmd); |
323 | | |
324 | | /* |
325 | | * Generic LUKS2 segment |
326 | | */ |
327 | | int LUKS2_segments_count(struct luks2_hdr *hdr); |
328 | | |
329 | | int LUKS2_segment_first_unused_id(struct luks2_hdr *hdr); |
330 | | |
331 | | int LUKS2_segment_set_flag(json_object *jobj_segment, const char *flag); |
332 | | |
333 | | json_object *LUKS2_get_segment_by_flag(struct luks2_hdr *hdr, const char *flag); |
334 | | |
335 | | int LUKS2_get_segment_id_by_flag(struct luks2_hdr *hdr, const char *flag); |
336 | | |
337 | | int LUKS2_segments_set(struct crypt_device *cd, |
338 | | struct luks2_hdr *hdr, |
339 | | json_object *jobj_segments, |
340 | | int commit); |
341 | | |
342 | | uint64_t LUKS2_segment_offset(struct luks2_hdr *hdr, |
343 | | int segment, |
344 | | unsigned blockwise); |
345 | | |
346 | | uint64_t LUKS2_segment_size(struct luks2_hdr *hdr, |
347 | | int segment, |
348 | | unsigned blockwise); |
349 | | |
350 | | uint64_t LUKS2_opal_segment_size(struct luks2_hdr *hdr, |
351 | | int segment, |
352 | | unsigned blockwise); |
353 | | |
354 | | int LUKS2_segment_is_type(struct luks2_hdr *hdr, |
355 | | int segment, |
356 | | const char *type); |
357 | | |
358 | | int LUKS2_segment_by_type(struct luks2_hdr *hdr, |
359 | | const char *type); |
360 | | |
361 | | int LUKS2_last_segment_by_type(struct luks2_hdr *hdr, |
362 | | const char *type); |
363 | | |
364 | | int LUKS2_get_default_segment(struct luks2_hdr *hdr); |
365 | | |
366 | | int LUKS2_reencrypt_digest_new(struct luks2_hdr *hdr); |
367 | | int LUKS2_reencrypt_digest_old(struct luks2_hdr *hdr); |
368 | | int LUKS2_reencrypt_segment_new(struct luks2_hdr *hdr); |
369 | | int LUKS2_reencrypt_segment_old(struct luks2_hdr *hdr); |
370 | | int LUKS2_reencrypt_data_offset(struct luks2_hdr *hdr, bool blockwise); |
371 | | |
372 | | int LUKS2_reencrypt_max_hotzone_size(struct crypt_device *cd, |
373 | | struct luks2_hdr *hdr, |
374 | | const struct reenc_protection *rp, |
375 | | int reencrypt_keyslot, |
376 | | uint64_t *r_length); |
377 | | |
378 | | void LUKS2_reencrypt_protection_erase(struct reenc_protection *rp); |
379 | | |
380 | | /* |
381 | | * Generic LUKS2 digest |
382 | | */ |
383 | | int LUKS2_digest_verify_by_digest(struct crypt_device *cd, |
384 | | int digest, |
385 | | const struct volume_key *vk); |
386 | | |
387 | | void LUKS2_digests_erase_unused(struct crypt_device *cd, |
388 | | struct luks2_hdr *hdr); |
389 | | |
390 | | int LUKS2_digest_dump(struct crypt_device *cd, |
391 | | int digest); |
392 | | |
393 | | /* |
394 | | * Generic LUKS2 token |
395 | | */ |
396 | | int LUKS2_tokens_count(struct luks2_hdr *hdr); |
397 | | |
398 | | /* |
399 | | * LUKS2 generic |
400 | | */ |
401 | | int LUKS2_reload(struct crypt_device *cd, |
402 | | const char *name, |
403 | | struct volume_key *vks, |
404 | | uint64_t device_size, |
405 | | uint32_t flags); |
406 | | |
407 | | int LUKS2_keyslot_for_segment(struct luks2_hdr *hdr, int keyslot, int segment); |
408 | | int LUKS2_find_keyslot(struct luks2_hdr *hdr, const char *type); |
409 | | int LUKS2_set_keyslots_size(struct luks2_hdr *hdr, uint64_t data_offset); |
410 | | |
411 | | #endif |