diff options
Diffstat (limited to 'lib/luks2/luks2_internal.h')
-rw-r--r-- | lib/luks2/luks2_internal.h | 388 |
1 files changed, 388 insertions, 0 deletions
diff --git a/lib/luks2/luks2_internal.h b/lib/luks2/luks2_internal.h new file mode 100644 index 0000000..b564a48 --- /dev/null +++ b/lib/luks2/luks2_internal.h @@ -0,0 +1,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 |