diff --git a/lib/luks2/luks2.h b/lib/luks2/luks2.h index 95a8a02d..7852b5b6 100644 --- a/lib/luks2/luks2.h +++ b/lib/luks2/luks2.h @@ -328,6 +328,7 @@ int LUKS2_keyslot_params_default(struct crypt_device *cd, struct luks2_hdr *hdr, size_t key_size, struct luks2_keyslot_params *params); int LUKS2_get_keyslot_params(struct luks2_hdr *hdr, int keyslot, struct luks2_keyslot_params *params); +unsigned LUKS2_get_keyslot_digests_count(struct luks2_hdr *hdr, int keyslot); int LUKS2_get_volume_key_size(struct luks2_hdr *hdr, int segment); int LUKS2_get_keyslot_key_size(struct luks2_hdr *hdr, int keyslot); int LUKS2_keyslot_find_empty(struct luks2_hdr *hdr, const char *type); diff --git a/lib/luks2/luks2_json_metadata.c b/lib/luks2/luks2_json_metadata.c index d5235fc6..590a2047 100644 --- a/lib/luks2/luks2_json_metadata.c +++ b/lib/luks2/luks2_json_metadata.c @@ -335,6 +335,28 @@ static json_bool validate_segments_array(json_object *jarr, json_object *jobj_se return TRUE; } +unsigned LUKS2_get_keyslot_digests_count(struct luks2_hdr *hdr, int keyslot) +{ + char num[16]; + json_object *jobj_digests, *jobj_keyslots; + unsigned count = 0; + + if (!json_object_object_get_ex(hdr->jobj, "digests", &jobj_digests)) + return 0; + + if (snprintf(num, sizeof(num), "%u", keyslot) < 0) + return 0; + + json_object_object_foreach(jobj_digests, key, val) { + UNUSED(key); + json_object_object_get_ex(val, "keyslots", &jobj_keyslots); + if (LUKS2_array_jobj(jobj_keyslots, num)) + count++; + } + + return count; +} + static json_bool segment_has_digest(const char *segment_name, json_object *jobj_digests) { json_object *jobj_segments; @@ -586,11 +608,9 @@ static int hdr_validate_areas(json_object *hdr_jobj) int length, ret, i = 0; uint64_t first_offset; - /* keyslots should already be validated */ if (!json_object_object_get_ex(hdr_jobj, "keyslots", &jobj_keyslots)) return 1; - /* segments should already be validated */ if (!json_object_object_get_ex(hdr_jobj, "segments", &jobj_segments)) return 1; diff --git a/lib/luks2/luks2_keyslot_luks2.c b/lib/luks2/luks2_keyslot_luks2.c index a363bef2..ac2466e9 100644 --- a/lib/luks2/luks2_keyslot_luks2.c +++ b/lib/luks2/luks2_keyslot_luks2.c @@ -609,6 +609,7 @@ static int luks2_keyslot_validate(struct crypt_device *cd, int keyslot) struct luks2_hdr *hdr; json_object *jobj_keyslot, *jobj_kdf, *jobj_af, *jobj_area, *jobj1; char num[16]; + unsigned count; hdr = crypt_get_hdr(cd, CRYPT_LUKS2); @@ -662,6 +663,13 @@ static int luks2_keyslot_validate(struct crypt_device *cd, int keyslot) } else return -EINVAL; + /* luks2 keyslot must have exactly one digest */ + count = LUKS2_get_keyslot_digests_count(hdr, keyslot); + if (count != 1) { + log_dbg("Keyslot %d is assigned to %u digest(s). Expected value is 1.", keyslot, count); + return -EINVAL; + } + return 0; }