summaryrefslogtreecommitdiffstats
path: root/lib/luks2/luks2_internal.h
blob: b564a4811b3957474d1ffdecd53f9d0e46fcd8bc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
/*
 * LUKS - Linux Unified Key Setup v2
 *
 * Copyright (C) 2015-2023 Red Hat, Inc. All rights reserved.
 * Copyright (C) 2015-2023 Milan Broz
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#ifndef _CRYPTSETUP_LUKS2_INTERNAL_H
#define _CRYPTSETUP_LUKS2_INTERNAL_H

#include <stdio.h>
#include <errno.h>
#include <json-c/json.h>

#include "internal.h"
#include "luks2.h"

/* override useless forward slash escape when supported by json-c */
#ifndef JSON_C_TO_STRING_NOSLASHESCAPE
#define JSON_C_TO_STRING_NOSLASHESCAPE 0
#endif

/*
 * On-disk access function prototypes
 */
int LUKS2_disk_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr,
			struct device *device, int do_recovery, int do_blkprobe);
int LUKS2_disk_hdr_write(struct crypt_device *cd, struct luks2_hdr *hdr,
			 struct device *device, bool seqid_check);
int LUKS2_device_write_lock(struct crypt_device *cd,
	struct luks2_hdr *hdr, struct device *device);

/*
 * JSON struct access helpers
 */
json_object *LUKS2_get_keyslot_jobj(struct luks2_hdr *hdr, int keyslot);
json_object *LUKS2_get_token_jobj(struct luks2_hdr *hdr, int token);
json_object *LUKS2_get_digest_jobj(struct luks2_hdr *hdr, int digest);
json_object *LUKS2_get_segment_jobj(struct luks2_hdr *hdr, int segment);
json_object *LUKS2_get_tokens_jobj(struct luks2_hdr *hdr);
json_object *LUKS2_get_segments_jobj(struct luks2_hdr *hdr);

void hexprint_base64(struct crypt_device *cd, json_object *jobj,
		     const char *sep, const char *line_sep);

uint64_t crypt_jobj_get_uint64(json_object *jobj);
uint32_t crypt_jobj_get_uint32(json_object *jobj);
json_object *crypt_jobj_new_uint64(uint64_t value);

int json_object_object_add_by_uint(json_object *jobj, unsigned key, json_object *jobj_val);
void json_object_object_del_by_uint(json_object *jobj, unsigned key);
int json_object_copy(json_object *jobj_src, json_object **jobj_dst);

void JSON_DBG(struct crypt_device *cd, json_object *jobj, const char *desc);

/*
 * LUKS2 JSON validation
 */

/* validation helper */
bool validate_json_uint32(json_object *jobj);
json_object *json_contains(struct crypt_device *cd, json_object *jobj, const char *name,
			   const char *section, const char *key, json_type type);
json_object *json_contains_string(struct crypt_device *cd, json_object *jobj,
				  const char *name, const char *section, const char *key);

int LUKS2_hdr_validate(struct crypt_device *cd, json_object *hdr_jobj, uint64_t json_size);
int LUKS2_check_json_size(struct crypt_device *cd, const struct luks2_hdr *hdr);
int LUKS2_token_validate(struct crypt_device *cd, json_object *hdr_jobj,
			 json_object *jobj_token, const char *key);
void LUKS2_token_dump(struct crypt_device *cd, int token);

/*
 * LUKS2 JSON repair for known glitches
 */
void LUKS2_hdr_repair(struct crypt_device *cd, json_object *jobj_hdr);
void LUKS2_keyslots_repair(struct crypt_device *cd, json_object *jobj_hdr);

/*
 * JSON array helpers
 */
json_object *LUKS2_array_jobj(json_object *array, const char *num);
json_object *LUKS2_array_remove(json_object *array, const char *num);

/*
 * Plugins API
 */

/**
 * LUKS2 keyslots handlers (EXPERIMENTAL)
 */
typedef int (*keyslot_alloc_func)(struct crypt_device *cd, int keyslot,
				  size_t volume_key_len,
				  const struct luks2_keyslot_params *params);
typedef int (*keyslot_update_func)(struct crypt_device *cd, int keyslot,
				   const struct luks2_keyslot_params *params);
typedef int (*keyslot_open_func) (struct crypt_device *cd, int keyslot,
				  const char *password, size_t password_len,
				  char *volume_key, size_t volume_key_len);
typedef int (*keyslot_store_func)(struct crypt_device *cd, int keyslot,
				  const char *password, size_t password_len,
				  const char *volume_key, size_t volume_key_len);
typedef int (*keyslot_wipe_func) (struct crypt_device *cd, int keyslot);
typedef int (*keyslot_dump_func) (struct crypt_device *cd, int keyslot);
typedef int (*keyslot_validate_func) (struct crypt_device *cd, json_object *jobj_keyslot);
typedef void(*keyslot_repair_func) (json_object *jobj_keyslot);

/* see LUKS2_luks2_to_luks1 */
int placeholder_keyslot_alloc(struct crypt_device *cd,
	int keyslot,
	uint64_t area_offset,
	uint64_t area_length);

/* validate all keyslot implementations in hdr json */
int LUKS2_keyslots_validate(struct crypt_device *cd, json_object *hdr_jobj);

typedef struct  {
	const char *name;
	keyslot_alloc_func alloc;
	keyslot_update_func update;
	keyslot_open_func  open;
	keyslot_store_func store;
	keyslot_wipe_func  wipe;
	keyslot_dump_func  dump;
	keyslot_validate_func validate;
	keyslot_repair_func repair;
} keyslot_handler;

struct reenc_protection {
	enum { REENC_PROTECTION_NOT_SET = 0,
	       REENC_PROTECTION_NONE,
	       REENC_PROTECTION_CHECKSUM,
	       REENC_PROTECTION_JOURNAL,
	       REENC_PROTECTION_DATASHIFT } type;

	union {
	struct {
		char hash[LUKS2_CHECKSUM_ALG_L];
		struct crypt_hash *ch;
		size_t hash_size;
		/* buffer for checksums */
		void *checksums;
		size_t checksums_len;
		size_t block_size;
	} csum;
	struct {
		uint64_t data_shift;
	} ds;
	} p;
};

/**
 * LUKS2 digest handlers (EXPERIMENTAL)
 */
typedef int (*digest_verify_func)(struct crypt_device *cd, int digest,
				  const char *volume_key, size_t volume_key_len);
typedef int (*digest_store_func) (struct crypt_device *cd, int digest,
				  const char *volume_key, size_t volume_key_len);
typedef int (*digest_dump_func)  (struct crypt_device *cd, int digest);

typedef struct  {
	const char *name;
	digest_verify_func verify;
	digest_store_func  store;
	digest_dump_func   dump;
} digest_handler;

int keyring_open(struct crypt_device *cd,
	int token,
	char **buffer,
	size_t *buffer_len,
	void *usrptr);

void keyring_dump(struct crypt_device *cd, const char *json);

int keyring_validate(struct crypt_device *cd, const char *json);

void keyring_buffer_free(void *buffer, size_t buffer_size);

struct crypt_token_handler_v2 {
	const char *name;
	crypt_token_open_func open;
	crypt_token_buffer_free_func buffer_free;
	crypt_token_validate_func validate;
	crypt_token_dump_func dump;

	/* here ends v1. Do not touch anything above */

	crypt_token_open_pin_func open_pin;
	crypt_token_version_func version;

	void *dlhandle;
};

/*
 * Initial sequence of structure members in union 'u' must be always
 * identical. Version 4 must fully contain version 3 which must
 * subsequently fully contain version 2, etc.
 *
 * See C standard, section 6.5.2.3, item 5.
 */
struct crypt_token_handler_internal {
	uint32_t version;
	union {
		crypt_token_handler v1; /* deprecated public structure */
		struct crypt_token_handler_v2 v2; /* internal helper v2 structure */
	} u;
};

int LUKS2_find_area_gap(struct crypt_device *cd, struct luks2_hdr *hdr,
			size_t keylength, uint64_t *area_offset, uint64_t *area_length);
int LUKS2_find_area_max_gap(struct crypt_device *cd, struct luks2_hdr *hdr,
			    uint64_t *area_offset, uint64_t *area_length);

uint64_t LUKS2_hdr_and_areas_size_jobj(json_object *jobj);

int LUKS2_check_cipher(struct crypt_device *cd,
		      size_t keylength,
		      const char *cipher,
		      const char *cipher_mode);

static inline const char *crypt_reencrypt_mode_to_str(crypt_reencrypt_mode_info mi)
{
	if (mi == CRYPT_REENCRYPT_REENCRYPT)
		return "reencrypt";
	if (mi == CRYPT_REENCRYPT_ENCRYPT)
		return "encrypt";
	if (mi == CRYPT_REENCRYPT_DECRYPT)
		return "decrypt";
	return "<unknown>";
}

/*
 * Generic LUKS2 keyslot
 */
int LUKS2_keyslot_reencrypt_store(struct crypt_device *cd,
	struct luks2_hdr *hdr,
	int keyslot,
	const void *buffer,
	size_t buffer_length);

int LUKS2_keyslot_reencrypt_allocate(struct crypt_device *cd,
	struct luks2_hdr *hdr,
	int keyslot,
	const struct crypt_params_reencrypt *params,
	size_t alignment);

int LUKS2_keyslot_reencrypt_update_needed(struct crypt_device *cd,
	struct luks2_hdr *hdr,
	int keyslot,
	const struct crypt_params_reencrypt *params,
	size_t alignment);

int LUKS2_keyslot_reencrypt_update(struct crypt_device *cd,
	struct luks2_hdr *hdr,
	int keyslot,
	const struct crypt_params_reencrypt *params,
	size_t alignment,
	struct volume_key *vks);

int LUKS2_keyslot_reencrypt_load(struct crypt_device *cd,
	struct luks2_hdr *hdr,
	int keyslot,
	struct reenc_protection *rp,
	bool primary);

int LUKS2_keyslot_reencrypt_digest_create(struct crypt_device *cd,
	struct luks2_hdr *hdr,
	uint8_t version,
	struct volume_key *vks);

int LUKS2_keyslot_dump(struct crypt_device *cd,
	int keyslot);

int LUKS2_keyslot_jobj_area(json_object *jobj_keyslot, uint64_t *offset, uint64_t *length);

/* JSON helpers */
uint64_t json_segment_get_offset(json_object *jobj_segment, unsigned blockwise);
const char *json_segment_type(json_object *jobj_segment);
uint64_t json_segment_get_iv_offset(json_object *jobj_segment);
uint64_t json_segment_get_size(json_object *jobj_segment, unsigned blockwise);
const char *json_segment_get_cipher(json_object *jobj_segment);
uint32_t json_segment_get_sector_size(json_object *jobj_segment);
bool json_segment_is_backup(json_object *jobj_segment);
json_object *json_segments_get_segment(json_object *jobj_segments, int segment);
unsigned json_segments_count(json_object *jobj_segments);
void json_segment_remove_flag(json_object *jobj_segment, const char *flag);
uint64_t json_segments_get_minimal_offset(json_object *jobj_segments, unsigned blockwise);
json_object *json_segment_create_linear(uint64_t offset, const uint64_t *length, unsigned reencryption);
json_object *json_segment_create_crypt(uint64_t offset, uint64_t iv_offset, const uint64_t *length, const char *cipher, uint32_t sector_size, unsigned reencryption);
int json_segments_segment_in_reencrypt(json_object *jobj_segments);
bool json_segment_cmp(json_object *jobj_segment_1, json_object *jobj_segment_2);
bool json_segment_contains_flag(json_object *jobj_segment, const char *flag_str, size_t len);

int LUKS2_assembly_multisegment_dmd(struct crypt_device *cd,
	struct luks2_hdr *hdr,
	struct volume_key *vks,
	json_object *jobj_segments,
	struct crypt_dm_active_device *dmd);

/*
 * Generic LUKS2 segment
 */
int LUKS2_segments_count(struct luks2_hdr *hdr);

int LUKS2_segment_first_unused_id(struct luks2_hdr *hdr);

int LUKS2_segment_set_flag(json_object *jobj_segment, const char *flag);

json_object *LUKS2_get_segment_by_flag(struct luks2_hdr *hdr, const char *flag);

int LUKS2_get_segment_id_by_flag(struct luks2_hdr *hdr, const char *flag);

int LUKS2_segments_set(struct crypt_device *cd,
	struct luks2_hdr *hdr,
	json_object *jobj_segments,
	int commit);

uint64_t LUKS2_segment_offset(struct luks2_hdr *hdr,
	int segment,
	unsigned blockwise);

uint64_t LUKS2_segment_size(struct luks2_hdr *hdr,
	int segment,
	unsigned blockwise);

int LUKS2_segment_is_type(struct luks2_hdr *hdr,
	int segment,
	const char *type);

int LUKS2_segment_by_type(struct luks2_hdr *hdr,
	const char *type);

int LUKS2_last_segment_by_type(struct luks2_hdr *hdr,
	const char *type);

int LUKS2_get_default_segment(struct luks2_hdr *hdr);

int LUKS2_reencrypt_digest_new(struct luks2_hdr *hdr);
int LUKS2_reencrypt_digest_old(struct luks2_hdr *hdr);
int LUKS2_reencrypt_data_offset(struct luks2_hdr *hdr, bool blockwise);

/*
 * Generic LUKS2 digest
 */
int LUKS2_digest_verify_by_digest(struct crypt_device *cd,
	int digest,
	const struct volume_key *vk);

void LUKS2_digests_erase_unused(struct crypt_device *cd,
	struct luks2_hdr *hdr);

int LUKS2_digest_dump(struct crypt_device *cd,
	int digest);

/*
 * Generic LUKS2 token
 */
int LUKS2_tokens_count(struct luks2_hdr *hdr);

/*
 * LUKS2 generic
 */
int LUKS2_reload(struct crypt_device *cd,
	const char *name,
	struct volume_key *vks,
	uint64_t device_size,
	uint32_t flags);

int LUKS2_keyslot_for_segment(struct luks2_hdr *hdr, int keyslot, int segment);
int LUKS2_find_keyslot(struct luks2_hdr *hdr, const char *type);
int LUKS2_set_keyslots_size(struct luks2_hdr *hdr, uint64_t data_offset);

#endif