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 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411
|
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* LUKS - Linux Unified Key Setup v2 (with JSON internals)
*
* Copyright (C) 2015-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2025 Milan Broz
*/
#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);
/*
* Generate json format string representation libcryptsetup uses
* to store json metadata on disk.
*/
static inline const char *crypt_jobj_to_string_on_disk(json_object *jobj)
{
return json_object_to_json_string_ext(jobj,
JSON_C_TO_STRING_PLAIN | JSON_C_TO_STRING_NOSLASHESCAPE);
}
int json_object_object_add_by_uint(json_object *jobj, unsigned key, json_object *jobj_val);
int json_object_object_add_by_uint_by_ref(json_object *jobj, unsigned key, json_object **jobj_val_ref);
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
*/
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
*/
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);
int json_segment_get_opal_segment_id(json_object *jobj_segment, uint32_t *ret_opal_segment_id);
int json_segment_get_opal_key_size(json_object *jobj_segment, size_t *ret_key_size);
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, const char *integrity, uint32_t integrity_key_size,
uint32_t sector_size, unsigned reencryption);
json_object *json_segment_create_opal(uint64_t offset, const uint64_t *length,
uint32_t segment_number, uint32_t key_size);
json_object *json_segment_create_opal_crypt(uint64_t offset, const uint64_t *length,
uint32_t segment_number, uint32_t key_size,
uint64_t iv_offset, const char *cipher,
const char *integrity, 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);
uint64_t LUKS2_opal_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_segment_new(struct luks2_hdr *hdr);
int LUKS2_reencrypt_segment_old(struct luks2_hdr *hdr);
int LUKS2_reencrypt_data_offset(struct luks2_hdr *hdr, bool blockwise);
int LUKS2_reencrypt_max_hotzone_size(struct crypt_device *cd,
struct luks2_hdr *hdr,
const struct reenc_protection *rp,
int reencrypt_keyslot,
uint64_t *r_length);
void LUKS2_reencrypt_protection_erase(struct reenc_protection *rp);
/*
* 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
|