Remove unused digests handling code.

Remove code for handling multiple digests per single keyslot.
Same would apply to segments with the only exception of segment
in-reencryption. We need that exception so that we will not lose
old key digests too early.
This commit is contained in:
Ondrej Kozina
2017-12-19 09:50:31 +01:00
committed by Milan Broz
parent 982da4d20c
commit cc76f3746f
5 changed files with 87 additions and 223 deletions

View File

@@ -43,8 +43,6 @@
#define LUKS2_DIGEST_MAX 8
typedef int digests_t[LUKS2_DIGEST_MAX];
#define CRYPT_ANY_SEGMENT -1
#define CRYPT_DEFAULT_SEGMENT 0
#define CRYPT_DEFAULT_SEGMENT_STR "0"
@@ -227,16 +225,14 @@ int LUKS2_token_open_and_activate_any(struct crypt_device *cd,
/*
* Generic LUKS2 digest
*/
int LUKS2_digests_by_segment(struct crypt_device *cd,
int LUKS2_digest_by_segment(struct crypt_device *cd,
struct luks2_hdr *hdr,
int segment,
digests_t digests);
int segment);
int LUKS2_digests_verify_by_segment(struct crypt_device *cd,
int LUKS2_digest_verify_by_segment(struct crypt_device *cd,
struct luks2_hdr *hdr,
int segment,
const struct volume_key *vk,
digests_t digests);
const struct volume_key *vk);
void LUKS2_digests_erase_unused(struct crypt_device *cd,
struct luks2_hdr *hdr);
@@ -249,18 +245,6 @@ int LUKS2_digest_verify(struct crypt_device *cd,
int LUKS2_digest_dump(struct crypt_device *cd,
int digest);
int LUKS2_digest_json_set(struct crypt_device *cd,
struct luks2_hdr *hdr,
int digest,
const char *json);
int LUKS2_digests_assign(struct crypt_device *cd,
struct luks2_hdr *hdr,
int keyslot,
digests_t digests,
int assign,
int commit);
int LUKS2_digest_assign(struct crypt_device *cd,
struct luks2_hdr *hdr,
int keyslot,
@@ -275,10 +259,9 @@ int LUKS2_digest_segment_assign(struct crypt_device *cd,
int assign,
int commit);
int LUKS2_digests_by_keyslot(struct crypt_device *cd,
int LUKS2_digest_by_keyslot(struct crypt_device *cd,
struct luks2_hdr *hdr,
int keyslot,
digests_t digests);
int keyslot);
int LUKS2_digest_create(struct crypt_device *cd,
const char *type,

View File

@@ -28,22 +28,6 @@ static const digest_handler *digest_handlers[LUKS2_DIGEST_MAX] = {
NULL
};
int crypt_digest_register(const digest_handler *handler)
{
int i;
for (i = 0; i < LUKS2_DIGEST_MAX && digest_handlers[i]; i++) {
if (!strcmp(digest_handlers[i]->name, handler->name))
return -EINVAL;
}
if (i == LUKS2_DIGEST_MAX)
return -EINVAL;
digest_handlers[i] = handler;
return 0;
}
const digest_handler *LUKS2_digest_handler_type(struct crypt_device *cd, const char *type)
{
int i;
@@ -107,13 +91,11 @@ int LUKS2_digest_create(struct crypt_device *cd,
return dh->store(cd, digest, vk->key, vk->keylength) ?: digest;
}
int LUKS2_digests_by_keyslot(struct crypt_device *cd,
int LUKS2_digest_by_keyslot(struct crypt_device *cd,
struct luks2_hdr *hdr,
int keyslot,
digests_t digests)
int keyslot)
{
char keyslot_name[16];
int i = 0;
json_object *jobj_digests, *jobj_digest_keyslots;
if (snprintf(keyslot_name, sizeof(keyslot_name), "%u", keyslot) < 1)
@@ -124,13 +106,10 @@ int LUKS2_digests_by_keyslot(struct crypt_device *cd,
json_object_object_foreach(jobj_digests, key, val) {
json_object_object_get_ex(val, "keyslots", &jobj_digest_keyslots);
if (LUKS2_array_jobj(jobj_digest_keyslots, keyslot_name))
digests[i++] = atoi(key);
return atoi(key);
}
if (i < LUKS2_DIGEST_MAX)
digests[i] = -1;
return i ? 0 : -ENOENT;
return -ENOENT;
}
int LUKS2_digest_verify(struct crypt_device *cd,
@@ -139,28 +118,23 @@ int LUKS2_digest_verify(struct crypt_device *cd,
int keyslot)
{
const digest_handler *h;
digests_t digests;
int i, r;
int digest, r;
r = LUKS2_digests_by_keyslot(cd, hdr, keyslot, digests);
if (r == -ENOENT)
digest = LUKS2_digest_by_keyslot(cd, hdr, keyslot);
if (digest == -ENOENT)
return 0;
if (r < 0)
if (digest < 0)
return digest;
log_dbg("Verifying key from keyslot %d, digest %d.", keyslot, digest);
h = LUKS2_digest_handler(cd, digest);
if (!h)
return -EINVAL;
r = h->verify(cd, digest, vk->key, vk->keylength);
if (r < 0) {
log_dbg("Digest %d (%s) verify failed with %d.", digest, h->name, r);
return r;
for (i = 0; i < LUKS2_DIGEST_MAX && digests[i] != -1 ; i++) {
log_dbg("Verifying key from keyslot %d, digest %d.",
keyslot, digests[i]);
h = LUKS2_digest_handler(cd, digests[i]);
if (!h)
return -EINVAL;
r = h->verify(cd, digests[i], vk->key, vk->keylength);
if (r < 0) {
log_dbg("Digest %d (%s) verify failed with %d.",
digests[i], h->name, r);
return r;
}
}
return 0;
@@ -176,49 +150,39 @@ int LUKS2_digest_dump(struct crypt_device *cd, int digest)
return h->dump(cd, digest);
}
int LUKS2_digests_verify_by_segment(struct crypt_device *cd,
int LUKS2_digest_verify_by_segment(struct crypt_device *cd,
struct luks2_hdr *hdr,
int segment,
const struct volume_key *vk,
digests_t digests)
const struct volume_key *vk)
{
const digest_handler *h;
digests_t tmp;
int *digest, r, i = 0;
int digest, r;
digest = digests ? digests : tmp;
digest = LUKS2_digest_by_segment(cd, hdr, segment);
if (digest < 0)
return digest;
r = LUKS2_digests_by_segment(cd, hdr, segment, digest);
if (r)
log_dbg("Verifying key digest %d.", digest);
h = LUKS2_digest_handler(cd, digest);
if (!h)
return -EINVAL;
r = h->verify(cd, digest, vk->key, vk->keylength);
if (r < 0) {
log_dbg("Digest %d (%s) verify failed with %d.", digest, h->name, r);
return r;
while (i < LUKS2_DIGEST_MAX && digest[i] != -1) {
log_dbg("Verifying key digest %d.", digest[i]);
h = LUKS2_digest_handler(cd, digest[i]);
if (!h)
return -EINVAL;
r = h->verify(cd, digest[i], vk->key, vk->keylength);
if (r < 0) {
log_dbg("Digest %d (%s) verify failed with %d.", digest[i], h->name, r);
return r;
}
i++;
}
return 0;
}
int LUKS2_digests_by_segment(struct crypt_device *cd,
int LUKS2_digest_by_segment(struct crypt_device *cd,
struct luks2_hdr *hdr,
int segment,
digests_t digests)
int segment)
{
char segment_name[16];
json_object *jobj_digests, *jobj_digest_segments;
int i = 0;
json_object_object_get_ex(hdr->jobj, "digests", &jobj_digests);
@@ -230,13 +194,10 @@ int LUKS2_digests_by_segment(struct crypt_device *cd,
if (!LUKS2_array_jobj(jobj_digest_segments, segment_name))
continue;
digests[i++] = atoi(key);
return atoi(key);
}
if (i < LUKS2_DIGEST_MAX)
digests[i] = -1;
return i ? 0 : -ENOENT;
return -ENOENT;
}
static int assign_one_digest(struct crypt_device *cd, struct luks2_hdr *hdr,
@@ -269,20 +230,6 @@ static int assign_one_digest(struct crypt_device *cd, struct luks2_hdr *hdr,
return 0;
}
int LUKS2_digests_assign(struct crypt_device *cd, struct luks2_hdr *hdr,
int keyslot, digests_t digests, int assign, int commit)
{
int i, r;
for (i = 0; i < LUKS2_DIGEST_MAX && digests[i] != -1; i++) {
r = LUKS2_digest_assign(cd, hdr, keyslot, digests[i], assign, 0);
if (r < 0)
return r;
}
return commit ? LUKS2_hdr_write(cd, hdr) : 0;
}
int LUKS2_digest_assign(struct crypt_device *cd, struct luks2_hdr *hdr,
int keyslot, int digest, int assign, int commit)
{

View File

@@ -124,12 +124,9 @@ typedef struct {
digest_dump_func dump;
} digest_handler;
int crypt_digest_register(const digest_handler *handler);
const digest_handler *LUKS2_digest_handler_type(struct crypt_device *cd, const char *type);
#define CRYPT_ANY_DIGEST -1
int crypt_keyslot_assign_digest(struct crypt_device *cd, int keyslot, int digest);
int crypt_keyslot_unassign_digest(struct crypt_device *cd, int keyslot, int digest);
/**
* LUKS2 token handlers (internal use only)

View File

@@ -82,75 +82,23 @@ int LUKS2_keyslot_find_empty(struct luks2_hdr *hdr, const char *type)
return -EINVAL;
}
static int digests_by_segment(json_object *jobj_digests, const char *segment,
digests_t digests)
{
json_object *jobj_segs;
int i = 0;
json_object_object_foreach(jobj_digests, dig, val) {
json_object_object_get_ex(val, "segments", &jobj_segs);
if (LUKS2_array_jobj(jobj_segs, segment))
digests[i++] = atoi(dig);
}
if (i < LUKS2_DIGEST_MAX)
digests[i] = -1;
return i ? 0 : -ENOENT;
}
static int is_in(const int super[], int super_size, int elem)
{
int i;
for (i = 0; i < super_size && super[i] != -1; i++)
if (super[i] == elem)
return 1;
return 0;
}
static int is_subset(const int super[], const int sub[], int super_size)
{
int i;
for (i = 0; i < super_size && sub[i] != -1; i++)
if (!is_in(super, super_size, sub[i]))
return 0;
return 1;
}
int LUKS2_keyslot_for_segment(struct luks2_hdr *hdr, int keyslot, int segment)
{
char keyslot_name[16], segment_name[16];
digests_t keyslot_digests, segment_digests;
json_object *jobj_digests;
int r = -ENOENT;
int keyslot_digest, segment_digest;
/* no need to check anything */
if (segment == CRYPT_ANY_SEGMENT)
return 0;
if (snprintf(segment_name, sizeof(segment_name), "%u", segment) < 1 ||
snprintf(keyslot_name, sizeof(keyslot_name), "%u", keyslot) < 1)
keyslot_digest = LUKS2_digest_by_keyslot(NULL, hdr, keyslot);
if (keyslot_digest < 0)
return -EINVAL;
/* empty set is subset of any set and it'd be wrong */
json_object_object_get_ex(hdr->jobj, "digests", &jobj_digests);
r = LUKS2_digests_by_keyslot(NULL, hdr, keyslot, keyslot_digests);
if (r)
return r;
segment_digest = LUKS2_digest_by_segment(NULL, hdr, segment);
if (segment_digest < 0)
return -EINVAL;
/* empty set can't be superset of non-empty one */
if (digests_by_segment(jobj_digests, segment_name, segment_digests))
return r;
/*
* keyslot may activate segment if set of digests for keyslot
* is actually subset of set of digests for segment
*/
return is_subset(segment_digests, keyslot_digests, LUKS2_DIGEST_MAX) ? 0 : -ENOENT;
return segment_digest == keyslot_digest ? 0 : -ENOENT;
}
int LUKS2_keyslot_active_count(struct luks2_hdr *hdr, int segment)
@@ -160,7 +108,6 @@ int LUKS2_keyslot_active_count(struct luks2_hdr *hdr, int segment)
json_object_object_get_ex(hdr->jobj, "keyslots", &jobj_keyslots);
/* keyslot digests must be subset of segment digests */
json_object_object_foreach(jobj_keyslots, slot, val) {
UNUSED(val);
if (!LUKS2_keyslot_for_segment(hdr, atoi(slot), segment))