Introduce CRYPT_SLOT_UNBOUND keyslot status for LUKS2.

A keyslot not bound to any segment can store any key for any purpose.

To easily check slot status, new enum value is introduced.
This status is valid only for LUKS2, so the functions are backward compatible
with LUKS1.
This commit is contained in:
Milan Broz
2018-04-19 15:22:28 +02:00
parent 879403a172
commit aa1551c6e8
12 changed files with 145 additions and 54 deletions

View File

@@ -175,6 +175,7 @@ int LUKS2_digest_verify_by_segment(struct crypt_device *cd,
return digest;
}
/* FIXME: segment can have more digests */
int LUKS2_digest_by_segment(struct crypt_device *cd,
struct luks2_hdr *hdr,
int segment)

View File

@@ -882,17 +882,11 @@ int LUKS2_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr)
return r;
}
/* NOTE: is called before LUKS2 validation routines */
static void LUKS2_hdr_free_unused_objects(struct crypt_device *cd, struct luks2_hdr *hdr)
{
/* erase unused digests (no assigned keyslot or segment) */
LUKS2_digests_erase_unused(cd, hdr);
}
int LUKS2_hdr_write(struct crypt_device *cd, struct luks2_hdr *hdr)
{
/* FIXME: we risk to hide future internal implementation bugs with this */
LUKS2_hdr_free_unused_objects(cd, hdr);
/* NOTE: is called before LUKS2 validation routines */
/* erase unused digests (no assigned keyslot or segment) */
LUKS2_digests_erase_unused(cd, hdr);
if (LUKS2_hdr_validate(hdr->jobj))
return -EINVAL;

View File

@@ -63,14 +63,6 @@ static const keyslot_handler
return LUKS2_keyslot_handler_type(cd, json_object_get_string(jobj2));
}
static crypt_keyslot_info LUKS2_keyslot_active(struct luks2_hdr *hdr, int keyslot)
{
if (keyslot >= LUKS2_KEYSLOTS_MAX)
return CRYPT_SLOT_INVALID;
return LUKS2_get_keyslot_jobj(hdr, keyslot) ? CRYPT_SLOT_ACTIVE : CRYPT_SLOT_INACTIVE;
}
int LUKS2_keyslot_find_empty(struct luks2_hdr *hdr, const char *type)
{
int i;
@@ -82,6 +74,7 @@ int LUKS2_keyslot_find_empty(struct luks2_hdr *hdr, const char *type)
return -EINVAL;
}
/* Check if a keyslot is asssigned to specific segment */
int LUKS2_keyslot_for_segment(struct luks2_hdr *hdr, int keyslot, int segment)
{
int keyslot_digest, segment_digest;
@@ -101,6 +94,7 @@ int LUKS2_keyslot_for_segment(struct luks2_hdr *hdr, int keyslot, int segment)
return segment_digest == keyslot_digest ? 0 : -ENOENT;
}
/* Number of keyslots assigned to a segment or all keyslots for CRYPT_ANY_SEGMENT */
int LUKS2_keyslot_active_count(struct luks2_hdr *hdr, int segment)
{
int num = 0;
@@ -176,18 +170,38 @@ int LUKS2_keyslot_params_default(struct crypt_device *cd, struct luks2_hdr *hdr,
return 0;
}
static int LUKS2_keyslot_unbound(struct luks2_hdr *hdr, int keyslot)
{
json_object *jobj_digest, *jobj_segments;
int digest = LUKS2_digest_by_keyslot(NULL, hdr, keyslot);
if (digest < 0)
return 0;
if (!(jobj_digest = LUKS2_get_digest_jobj(hdr, digest)))
return 0;
json_object_object_get_ex(jobj_digest, "segments", &jobj_segments);
if (!jobj_segments || !json_object_is_type(jobj_segments, json_type_array) ||
json_object_array_length(jobj_segments) == 0)
return 1;
return 0;
}
crypt_keyslot_info LUKS2_keyslot_info(struct luks2_hdr *hdr, int keyslot)
{
crypt_keyslot_info ki;
if(keyslot >= LUKS2_KEYSLOTS_MAX || keyslot < 0)
return CRYPT_SLOT_INVALID;
ki = LUKS2_keyslot_active(hdr, keyslot);
if (ki != CRYPT_SLOT_ACTIVE)
return ki;
if (!LUKS2_get_keyslot_jobj(hdr, keyslot))
return CRYPT_SLOT_INACTIVE;
if (LUKS2_keyslot_active_count(hdr, CRYPT_DEFAULT_SEGMENT) == 1 && !LUKS2_keyslot_for_segment(hdr, keyslot, CRYPT_DEFAULT_SEGMENT))
if (LUKS2_keyslot_unbound(hdr, keyslot))
return CRYPT_SLOT_UNBOUND;
if (LUKS2_keyslot_active_count(hdr, CRYPT_DEFAULT_SEGMENT) == 1 &&
!LUKS2_keyslot_for_segment(hdr, keyslot, CRYPT_DEFAULT_SEGMENT))
return CRYPT_SLOT_ACTIVE_LAST;
return CRYPT_SLOT_ACTIVE;

View File

@@ -397,7 +397,8 @@ int LUKS2_token_open_and_activate(struct crypt_device *cd,
return r;
r = LUKS2_keyslot_open_by_token(cd, hdr, token,
name ? CRYPT_DEFAULT_SEGMENT : CRYPT_ANY_SEGMENT,
(flags & CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY) ?
CRYPT_ANY_SEGMENT : CRYPT_DEFAULT_SEGMENT,
buffer, buffer_len, &vk);
LUKS2_token_buffer_free(cd, token, buffer, buffer_len);
@@ -442,7 +443,8 @@ int LUKS2_token_open_and_activate_any(struct crypt_device *cd,
continue;
r = LUKS2_keyslot_open_by_token(cd, hdr, token,
name ? CRYPT_DEFAULT_SEGMENT : CRYPT_ANY_SEGMENT,
(flags & CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY) ?
CRYPT_ANY_SEGMENT : CRYPT_DEFAULT_SEGMENT,
buffer, buffer_len, &vk);
LUKS2_token_buffer_free(cd, token, buffer, buffer_len);
if (r >= 0)