diff --git a/lib/bitlk/bitlk.c b/lib/bitlk/bitlk.c index c09eff304..7b6fb23bb 100644 --- a/lib/bitlk/bitlk.c +++ b/lib/bitlk/bitlk.c @@ -1401,34 +1401,6 @@ static int _activate(struct crypt_device *cd, return r; } -int BITLK_activate_by_passphrase(struct crypt_device *cd, - const char *name, - const char *password, - size_t passwordLen, - const struct bitlk_metadata *params, - uint32_t flags) -{ - int r = 0; - struct volume_key *open_fvek_key = NULL; - - r = _activate_check(cd, params); - if (r) - return r; - - r = BITLK_get_volume_key(cd, password, passwordLen, params, &open_fvek_key); - if (r < 0) - goto out; - - /* Password verify only */ - if (!name) - goto out; - - r = _activate(cd, name, open_fvek_key, params, flags); -out: - crypt_free_volume_key(open_fvek_key); - return r; -} - int BITLK_activate_by_volume_key(struct crypt_device *cd, const char *name, struct volume_key *vk, diff --git a/lib/bitlk/bitlk.h b/lib/bitlk/bitlk.h index 82a89d94e..d95e01d71 100644 --- a/lib/bitlk/bitlk.h +++ b/lib/bitlk/bitlk.h @@ -115,13 +115,6 @@ int BITLK_get_volume_key(struct crypt_device *cd, const struct bitlk_metadata *params, struct volume_key **open_fvek_key); -int BITLK_activate_by_passphrase(struct crypt_device *cd, - const char *name, - const char *password, - size_t passwordLen, - const struct bitlk_metadata *params, - uint32_t flags); - int BITLK_activate_by_volume_key(struct crypt_device *cd, const char *name, struct volume_key *vk, diff --git a/lib/fvault2/fvault2.c b/lib/fvault2/fvault2.c index cdd3d1b46..3df23f6ee 100644 --- a/lib/fvault2/fvault2.c +++ b/lib/fvault2/fvault2.c @@ -997,28 +997,6 @@ int FVAULT2_dump( return 0; } -int FVAULT2_activate_by_passphrase( - struct crypt_device *cd, - const char *name, - const char *passphrase, - size_t passphrase_len, - const struct fvault2_params *params, - uint32_t flags) -{ - int r; - struct volume_key *vol_key = NULL; - - r = FVAULT2_get_volume_key(cd, passphrase, passphrase_len, params, &vol_key); - if (r < 0) - return r; - - if (name) - r = _activate(cd, name, vol_key, params, flags); - - crypt_free_volume_key(vol_key); - return r; -} - int FVAULT2_activate_by_volume_key( struct crypt_device *cd, const char *name, diff --git a/lib/fvault2/fvault2.h b/lib/fvault2/fvault2.h index d80259877..fb842cdcb 100644 --- a/lib/fvault2/fvault2.h +++ b/lib/fvault2/fvault2.h @@ -48,14 +48,6 @@ int FVAULT2_dump( struct device *device, const struct fvault2_params *params); -int FVAULT2_activate_by_passphrase( - struct crypt_device *cd, - const char *name, - const char *passphrase, - size_t passphrase_len, - const struct fvault2_params *params, - uint32_t flags); - int FVAULT2_activate_by_volume_key( struct crypt_device *cd, const char *name, diff --git a/lib/keyslot_context.c b/lib/keyslot_context.c index b26f95512..a3abafe50 100644 --- a/lib/keyslot_context.c +++ b/lib/keyslot_context.c @@ -8,6 +8,8 @@ #include +#include "bitlk/bitlk.h" +#include "fvault2/fvault2.h" #include "luks1/luks.h" #include "luks2/luks2.h" #include "keyslot_context.h" @@ -58,6 +60,44 @@ static int get_luks2_volume_key_by_passphrase(struct crypt_device *cd, return get_luks2_key_by_passphrase(cd, kc, keyslot, CRYPT_DEFAULT_SEGMENT, r_vk); } +static int get_bitlk_volume_key_by_passphrase(struct crypt_device *cd, + struct crypt_keyslot_context *kc, + const struct bitlk_metadata *params, + struct volume_key **r_vk) +{ + int r; + + assert(cd); + assert(kc && kc->type == CRYPT_KC_TYPE_PASSPHRASE); + assert(params); + assert(r_vk); + + r = BITLK_get_volume_key(cd, kc->u.p.passphrase, kc->u.p.passphrase_size, params, r_vk); + if (r < 0) + kc->error = r; + + return r; +} + +static int get_fvault2_volume_key_by_passphrase(struct crypt_device *cd, + struct crypt_keyslot_context *kc, + const struct fvault2_params *params, + struct volume_key **r_vk) +{ + int r; + + assert(cd); + assert(kc && kc->type == CRYPT_KC_TYPE_PASSPHRASE); + assert(params); + assert(r_vk); + + r = FVAULT2_get_volume_key(cd, kc->u.p.passphrase, kc->u.p.passphrase_size, params, r_vk); + if (r < 0) + kc->error = r; + + return r; +} + static int get_passphrase_by_passphrase(struct crypt_device *cd, struct crypt_keyslot_context *kc, const char **r_passphrase, @@ -160,6 +200,56 @@ static int get_luks1_volume_key_by_keyfile(struct crypt_device *cd, return r; } +static int get_bitlk_volume_key_by_keyfile(struct crypt_device *cd, + struct crypt_keyslot_context *kc, + const struct bitlk_metadata *params, + struct volume_key **r_vk) +{ + int r; + const char *passphrase; + size_t passphrase_size; + + assert(cd); + assert(kc && kc->type == CRYPT_KC_TYPE_KEYFILE); + assert(params); + assert(r_vk); + + r = get_passphrase_by_keyfile(cd, kc, &passphrase, &passphrase_size); + if (r < 0) + return r; + + r = BITLK_get_volume_key(cd, passphrase, passphrase_size, params, r_vk); + if (r < 0) + kc->error = r; + + return r; +} + +static int get_fvault2_volume_key_by_keyfile(struct crypt_device *cd, + struct crypt_keyslot_context *kc, + const struct fvault2_params *params, + struct volume_key **r_vk) +{ + int r; + const char *passphrase; + size_t passphrase_size; + + assert(cd); + assert(kc && kc->type == CRYPT_KC_TYPE_KEYFILE); + assert(params); + assert(r_vk); + + r = get_passphrase_by_keyfile(cd, kc, &passphrase, &passphrase_size); + if (r < 0) + return r; + + r = FVAULT2_get_volume_key(cd, passphrase, passphrase_size, params, r_vk); + if (r < 0) + kc->error = r; + + return r; +} + static int get_key_by_key(struct crypt_device *cd __attribute__((unused)), struct crypt_keyslot_context *kc, int keyslot __attribute__((unused)), @@ -198,6 +288,22 @@ static int get_generic_volume_key_by_key(struct crypt_device *cd, return get_key_by_key(cd, kc, -2 /* unused */, -2 /* unused */, r_vk); } +static int get_bitlk_volume_key_by_key(struct crypt_device *cd, + struct crypt_keyslot_context *kc, + const struct bitlk_metadata *params __attribute__((unused)), + struct volume_key **r_vk) +{ + return get_key_by_key(cd, kc, -2 /* unused */, -2 /* unused */, r_vk); +} + +static int get_fvault2_volume_key_by_key(struct crypt_device *cd, + struct crypt_keyslot_context *kc, + const struct fvault2_params *params __attribute__((unused)), + struct volume_key **r_vk) +{ + return get_key_by_key(cd, kc, -2 /* unused */, -2 /* unused */, r_vk); +} + static int get_generic_signed_key_by_key(struct crypt_device *cd, struct crypt_keyslot_context *kc, struct volume_key **r_vk, @@ -486,8 +592,8 @@ void crypt_keyslot_context_init_by_key_internal(struct crypt_keyslot_context *kc kc->get_luks1_volume_key = get_volume_key_by_key; kc->get_luks2_volume_key = get_volume_key_by_key; kc->get_plain_volume_key = get_generic_volume_key_by_key; - kc->get_bitlk_volume_key = get_generic_volume_key_by_key; - kc->get_fvault2_volume_key = get_generic_volume_key_by_key; + kc->get_bitlk_volume_key = get_bitlk_volume_key_by_key; + kc->get_fvault2_volume_key = get_fvault2_volume_key_by_key; kc->get_verity_volume_key = get_generic_signed_key_by_key; kc->get_integrity_volume_key = get_generic_volume_key_by_key; kc->context_free = key_context_free; @@ -530,9 +636,12 @@ void crypt_keyslot_context_init_by_passphrase_internal(struct crypt_keyslot_cont kc->type = CRYPT_KC_TYPE_PASSPHRASE; kc->u.p.passphrase = passphrase; kc->u.p.passphrase_size = passphrase_size; + kc->get_luks2_key = get_luks2_key_by_passphrase; kc->get_luks1_volume_key = get_luks1_volume_key_by_passphrase; kc->get_luks2_volume_key = get_luks2_volume_key_by_passphrase; + kc->get_bitlk_volume_key = get_bitlk_volume_key_by_passphrase; + kc->get_fvault2_volume_key = get_fvault2_volume_key_by_passphrase; kc->get_passphrase = get_passphrase_by_passphrase; crypt_keyslot_context_init_common(kc); } @@ -559,6 +668,8 @@ void crypt_keyslot_context_init_by_keyfile_internal(struct crypt_keyslot_context kc->get_luks2_key = get_luks2_key_by_keyfile; kc->get_luks1_volume_key = get_luks1_volume_key_by_keyfile; kc->get_luks2_volume_key = get_luks2_volume_key_by_keyfile; + kc->get_bitlk_volume_key = get_bitlk_volume_key_by_keyfile; + kc->get_fvault2_volume_key = get_fvault2_volume_key_by_keyfile; kc->get_passphrase = get_passphrase_by_keyfile; kc->context_free = keyfile_context_free; crypt_keyslot_context_init_common(kc); @@ -602,20 +713,6 @@ static void vk_in_keyring_context_free(struct crypt_keyslot_context *kc) free(kc->u.vk_kr.i_key_description); } -void crypt_keyslot_context_init_by_vk_in_keyring_internal(struct crypt_keyslot_context *kc, - const char *key_description) -{ - assert(kc); - - kc->type = CRYPT_KC_TYPE_VK_KEYRING; - kc->u.vk_kr.key_description = key_description; - - kc->get_luks2_key = get_key_by_vk_in_keyring; - kc->get_luks2_volume_key = get_volume_key_by_vk_in_keyring; - kc->context_free = vk_in_keyring_context_free; - crypt_keyslot_context_init_common(kc); -} - void crypt_keyslot_context_destroy_internal(struct crypt_keyslot_context *kc) { if (!kc) @@ -1033,7 +1130,13 @@ static int _crypt_keyslot_context_init_by_vk_in_keyring(const char *key_descript key_description = i_key_description; } - crypt_keyslot_context_init_by_vk_in_keyring_internal(tmp, key_description); + tmp->type = CRYPT_KC_TYPE_VK_KEYRING; + tmp->u.vk_kr.key_description = key_description; + + tmp->get_luks2_key = get_key_by_vk_in_keyring; + tmp->get_luks2_volume_key = get_volume_key_by_vk_in_keyring; + tmp->context_free = vk_in_keyring_context_free; + crypt_keyslot_context_init_common(tmp); if (self_contained) { tmp->u.vk_kr.i_key_description = i_key_description; diff --git a/lib/keyslot_context.h b/lib/keyslot_context.h index df40becac..50e96e0b1 100644 --- a/lib/keyslot_context.h +++ b/lib/keyslot_context.h @@ -14,6 +14,9 @@ #include "internal.h" +struct bitlk_metadata; +struct fvault2_params; + typedef int (*keyslot_context_get_key) ( struct crypt_device *cd, struct crypt_keyslot_context *kc, @@ -32,6 +35,19 @@ typedef int (*keyslot_context_get_generic_volume_key) ( struct crypt_keyslot_context *kc, struct volume_key **r_vk); +typedef int (*keyslot_context_get_bitlk_volume_key) ( + struct crypt_device *cd, + struct crypt_keyslot_context *kc, + const struct bitlk_metadata *params, + struct volume_key **r_vk); + +typedef int (*keyslot_context_get_fvault2_volume_key) ( + struct crypt_device *cd, + struct crypt_keyslot_context *kc, + const struct fvault2_params *params, + struct volume_key **r_vk); + + typedef int (*keyslot_context_get_generic_signed_key) ( struct crypt_device *cd, struct crypt_keyslot_context *kc, @@ -113,8 +129,8 @@ struct crypt_keyslot_context { keyslot_context_get_volume_key get_luks1_volume_key; keyslot_context_get_volume_key get_luks2_volume_key; keyslot_context_get_generic_volume_key get_plain_volume_key; - keyslot_context_get_generic_volume_key get_bitlk_volume_key; - keyslot_context_get_generic_volume_key get_fvault2_volume_key; + keyslot_context_get_bitlk_volume_key get_bitlk_volume_key; + keyslot_context_get_fvault2_volume_key get_fvault2_volume_key; keyslot_context_get_generic_signed_key get_verity_volume_key; keyslot_context_get_generic_volume_key get_integrity_volume_key; keyslot_context_get_passphrase get_passphrase; @@ -152,9 +168,6 @@ void crypt_keyslot_context_init_by_token_internal(struct crypt_keyslot_context * void crypt_keyslot_context_init_by_keyring_internal(struct crypt_keyslot_context *kc, const char *key_description); -void crypt_keyslot_context_init_by_vk_in_keyring_internal(struct crypt_keyslot_context *kc, - const char *key_description); - const char *keyslot_context_type_string(const struct crypt_keyslot_context *kc); #endif /* KEYSLOT_CONTEXT_H */ diff --git a/lib/luks2/luks2.h b/lib/luks2/luks2.h index 206f48842..742d22a74 100644 --- a/lib/luks2/luks2.h +++ b/lib/luks2/luks2.h @@ -196,13 +196,6 @@ int LUKS2_keyslot_open(struct crypt_device *cd, size_t password_len, struct volume_key **vk); -int LUKS2_keyslot_open_all_segments(struct crypt_device *cd, - int keyslot_old, - int keyslot_new, - const char *password, - size_t password_len, - struct volume_key **vks); - int LUKS2_keyslot_context_open_all_segments(struct crypt_device *cd, int keyslot_old, int keyslot_new, @@ -270,17 +263,6 @@ crypt_token_info LUKS2_token_status(struct crypt_device *cd, int token, const char **type); -int LUKS2_token_open_and_activate(struct crypt_device *cd, - struct luks2_hdr *hdr, - int keyslot, - int token, - const char *name, - const char *type, - const char *pin, - size_t pin_size, - uint32_t flags, - void *usrptr); - int LUKS2_token_unlock_key(struct crypt_device *cd, struct luks2_hdr *hdr, int keyslot, @@ -445,8 +427,6 @@ int LUKS2_unmet_requirements(struct crypt_device *cd, struct luks2_hdr *hdr, uin int LUKS2_key_description_by_segment(struct crypt_device *cd, struct luks2_hdr *hdr, struct volume_key *vk, int segment); -int LUKS2_volume_key_load_in_keyring_by_keyslot(struct crypt_device *cd, - struct luks2_hdr *hdr, struct volume_key *vk, int keyslot); int LUKS2_volume_key_load_in_keyring_by_digest(struct crypt_device *cd, struct volume_key *vk, int digest); @@ -460,13 +440,6 @@ int LUKS2_luks2_to_luks1(struct crypt_device *cd, /* * LUKS2 reencryption */ -int LUKS2_reencrypt_locked_recovery_by_passphrase(struct crypt_device *cd, - int keyslot_old, - int keyslot_new, - const char *passphrase, - size_t passphrase_size, - struct volume_key **vks); - int LUKS2_reencrypt_locked_recovery_by_vks(struct crypt_device *cd, struct volume_key *vks); @@ -495,10 +468,6 @@ int LUKS2_reencrypt_check_device_size(struct crypt_device *cd, bool device_exclusive_check, bool dynamic); -void LUKS2_reencrypt_lookup_key_ids(struct crypt_device *cd, - struct luks2_hdr *hdr, - struct volume_key *vk); - int LUKS2_reencrypt_digest_verify(struct crypt_device *cd, struct luks2_hdr *hdr, struct volume_key *vks); diff --git a/lib/luks2/luks2_digest.c b/lib/luks2/luks2_digest.c index bf9b9bdae..fac4cc3f4 100644 --- a/lib/luks2/luks2_digest.c +++ b/lib/luks2/luks2_digest.c @@ -424,20 +424,6 @@ int LUKS2_key_description_by_segment(struct crypt_device *cd, return r; } -int LUKS2_volume_key_load_in_keyring_by_keyslot(struct crypt_device *cd, - struct luks2_hdr *hdr, struct volume_key *vk, int keyslot) -{ - char *desc = get_key_description_by_digest(cd, LUKS2_digest_by_keyslot(hdr, keyslot)); - int r; - - r = crypt_volume_key_set_description(vk, desc); - if (!r) - r = crypt_volume_key_load_in_keyring(cd, vk); - - free(desc); - return r; -} - int LUKS2_volume_key_load_in_keyring_by_digest(struct crypt_device *cd, struct volume_key *vk, int digest) { diff --git a/lib/luks2/luks2_keyslot.c b/lib/luks2/luks2_keyslot.c index f41fb3ffe..ba8ca4df9 100644 --- a/lib/luks2/luks2_keyslot.c +++ b/lib/luks2/luks2_keyslot.c @@ -124,16 +124,6 @@ static int _keyslot_for_segment(struct luks2_hdr *hdr, int keyslot, int segment) return count; } -static int _keyslot_for_digest(struct luks2_hdr *hdr, int keyslot, int digest) -{ - int r = -EINVAL; - - r = LUKS2_digest_by_keyslot(hdr, keyslot); - if (r < 0) - return r; - return r == digest ? 0 : -ENOENT; -} - int LUKS2_keyslot_for_segment(struct luks2_hdr *hdr, int keyslot, int segment) { int r = -EINVAL; @@ -376,36 +366,6 @@ static int _open_and_verify(struct crypt_device *cd, return r < 0 ? r : keyslot; } -static int LUKS2_open_and_verify_by_digest(struct crypt_device *cd, - struct luks2_hdr *hdr, - int keyslot, - int digest, - const char *password, - size_t password_len, - struct volume_key **vk) -{ - const keyslot_handler *h; - int r; - - if (!(h = LUKS2_keyslot_handler(cd, keyslot))) - return -ENOENT; - - r = h->validate(cd, LUKS2_get_keyslot_jobj(hdr, keyslot)); - if (r) { - log_dbg(cd, "Keyslot %d validation failed.", keyslot); - return r; - } - - r = _keyslot_for_digest(hdr, keyslot, digest); - if (r) { - if (r == -ENOENT) - log_dbg(cd, "Keyslot %d unusable for digest %d.", keyslot, digest); - return r; - } - - return _open_and_verify(cd, hdr, h, keyslot, password, password_len, vk); -} - static int LUKS2_open_and_verify(struct crypt_device *cd, struct luks2_hdr *hdr, int keyslot, @@ -436,49 +396,6 @@ static int LUKS2_open_and_verify(struct crypt_device *cd, return _open_and_verify(cd, hdr, h, keyslot, password, password_len, vk); } -static int LUKS2_keyslot_open_priority_digest(struct crypt_device *cd, - struct luks2_hdr *hdr, - crypt_keyslot_priority priority, - const char *password, - size_t password_len, - int digest, - struct volume_key **vk) -{ - json_object *jobj_keyslots, *jobj; - crypt_keyslot_priority slot_priority; - int keyslot, r = -ENOENT, r_old; - - json_object_object_get_ex(hdr->jobj, "keyslots", &jobj_keyslots); - - json_object_object_foreach(jobj_keyslots, slot, val) { - r_old = r; - - if (!json_object_object_get_ex(val, "priority", &jobj)) - slot_priority = CRYPT_SLOT_PRIORITY_NORMAL; - else - slot_priority = json_object_get_int(jobj); - - keyslot = atoi(slot); - if (slot_priority != priority) { - log_dbg(cd, "Keyslot %d priority %d != %d (required), skipped.", - keyslot, slot_priority, priority); - continue; - } - - r = LUKS2_open_and_verify_by_digest(cd, hdr, keyslot, digest, password, password_len, vk); - - /* Do not retry for errors that are no -EPERM or -ENOENT, - former meaning password wrong, latter key slot unusable for segment */ - if ((r != -EPERM) && (r != -ENOENT)) - break; - /* If a previous keyslot failed with EPERM (bad password) prefer it */ - if (r_old == -EPERM && r == -ENOENT) - r = -EPERM; - } - - return r; -} - static int LUKS2_keyslot_open_priority(struct crypt_device *cd, struct luks2_hdr *hdr, crypt_keyslot_priority priority, @@ -522,38 +439,6 @@ static int LUKS2_keyslot_open_priority(struct crypt_device *cd, return r; } -static int LUKS2_keyslot_open_by_digest(struct crypt_device *cd, - struct luks2_hdr *hdr, - int keyslot, - int digest, - const char *password, - size_t password_len, - struct volume_key **vk) -{ - int r_prio, r = -EINVAL; - - if (digest < 0) - return r; - - if (keyslot == CRYPT_ANY_SLOT) { - r_prio = LUKS2_keyslot_open_priority_digest(cd, hdr, CRYPT_SLOT_PRIORITY_PREFER, - password, password_len, digest, vk); - if (r_prio >= 0) - r = r_prio; - else if (r_prio != -EPERM && r_prio != -ENOENT) - r = r_prio; - else - r = LUKS2_keyslot_open_priority_digest(cd, hdr, CRYPT_SLOT_PRIORITY_NORMAL, - password, password_len, digest, vk); - /* Prefer password wrong to no entry from priority slot */ - if (r_prio == -EPERM && r == -ENOENT) - r = r_prio; - } else - r = LUKS2_open_and_verify_by_digest(cd, hdr, keyslot, digest, password, password_len, vk); - - return r; -} - static int keyslot_context_open_all_segments(struct crypt_device *cd, int keyslot_old, int keyslot_new, @@ -653,47 +538,6 @@ int LUKS2_keyslot_context_open_all_segments(struct crypt_device *cd, return r; } -int LUKS2_keyslot_open_all_segments(struct crypt_device *cd, - int keyslot_old, - int keyslot_new, - const char *password, - size_t password_len, - struct volume_key **vks) -{ - struct volume_key *vk = NULL; - int digest_old, digest_new, r = -EINVAL; - struct luks2_hdr *hdr = crypt_get_hdr(cd, CRYPT_LUKS2); - - digest_old = LUKS2_reencrypt_digest_old(hdr); - if (digest_old >= 0) { - log_dbg(cd, "Trying to unlock volume key (digest: %d) using keyslot %d.", digest_old, keyslot_old); - r = LUKS2_keyslot_open_by_digest(cd, hdr, keyslot_old, digest_old, password, password_len, &vk); - if (r < 0) - goto out; - crypt_volume_key_add_next(vks, vk); - } - - digest_new = LUKS2_reencrypt_digest_new(hdr); - if (digest_new >= 0 && digest_old != digest_new) { - log_dbg(cd, "Trying to unlock volume key (digest: %d) using keyslot %d.", digest_new, keyslot_new); - r = LUKS2_keyslot_open_by_digest(cd, hdr, keyslot_new, digest_new, password, password_len, &vk); - if (r < 0) - goto out; - crypt_volume_key_add_next(vks, vk); - } -out: - if (r < 0) { - crypt_free_volume_key(*vks); - *vks = NULL; - - if (r == -ENOMEM) - log_err(cd, _("Not enough available memory to open a keyslot.")); - else if (r != -EPERM && r != -ENOENT) - log_err(cd, _("Keyslot open failed.")); - } - return r; -} - int LUKS2_keyslot_open(struct crypt_device *cd, int keyslot, int segment, diff --git a/lib/luks2/luks2_reencrypt.c b/lib/luks2/luks2_reencrypt.c index f8f0abcdc..ec647bad4 100644 --- a/lib/luks2/luks2_reencrypt.c +++ b/lib/luks2/luks2_reencrypt.c @@ -4452,54 +4452,6 @@ int LUKS2_reencrypt_check_device_size(struct crypt_device *cd, struct luks2_hdr } #if USE_LUKS2_REENCRYPTION /* returns keyslot number on success (>= 0) or negative errnor otherwise */ -int LUKS2_reencrypt_locked_recovery_by_passphrase(struct crypt_device *cd, - int keyslot_old, - int keyslot_new, - const char *passphrase, - size_t passphrase_size, - struct volume_key **vks) -{ - uint64_t minimal_size, device_size; - int keyslot, r = -EINVAL; - struct luks2_hdr *hdr = crypt_get_hdr(cd, CRYPT_LUKS2); - struct volume_key *vk = NULL, *_vks = NULL; - - log_dbg(cd, "Entering reencryption crash recovery."); - - if (LUKS2_get_data_size(hdr, &minimal_size, NULL)) - return r; - - r = LUKS2_keyslot_open_all_segments(cd, keyslot_old, keyslot_new, - passphrase, passphrase_size, &_vks); - if (r < 0) - goto out; - keyslot = r; - - if (crypt_use_keyring_for_vk(cd)) - vk = _vks; - - while (vk) { - r = LUKS2_volume_key_load_in_keyring_by_digest(cd, vk, crypt_volume_key_get_id(vk)); - if (r < 0) - goto out; - vk = crypt_volume_key_next(vk); - } - - if (LUKS2_reencrypt_check_device_size(cd, hdr, minimal_size, &device_size, true, false)) - goto out; - - r = reencrypt_recovery(cd, hdr, device_size, _vks); - - if (!r && vks) - MOVE_REF(*vks, _vks); -out: - if (r < 0) - crypt_drop_keyring_key(cd, _vks); - crypt_free_volume_key(_vks); - - return r < 0 ? r : keyslot; -} - int LUKS2_reencrypt_locked_recovery_by_vks(struct crypt_device *cd, struct volume_key *vks) { diff --git a/lib/luks2/luks2_reencrypt_digest.c b/lib/luks2/luks2_reencrypt_digest.c index 52f22e327..1dda8a268 100644 --- a/lib/luks2/luks2_reencrypt_digest.c +++ b/lib/luks2/luks2_reencrypt_digest.c @@ -362,22 +362,6 @@ int LUKS2_keyslot_reencrypt_digest_create(struct crypt_device *cd, return LUKS2_digest_assign(cd, hdr, keyslot_reencrypt, digest_reencrypt, 1, 0); } -void LUKS2_reencrypt_lookup_key_ids(struct crypt_device *cd, struct luks2_hdr *hdr, struct volume_key *vk) -{ - int digest_old, digest_new; - - digest_old = LUKS2_reencrypt_digest_old(hdr); - digest_new = LUKS2_reencrypt_digest_new(hdr); - - while (vk) { - if (digest_old >= 0 && LUKS2_digest_verify_by_digest(cd, digest_old, vk) == digest_old) - crypt_volume_key_set_id(vk, digest_old); - if (digest_new >= 0 && LUKS2_digest_verify_by_digest(cd, digest_new, vk) == digest_new) - crypt_volume_key_set_id(vk, digest_new); - vk = vk->next; - } -} - int LUKS2_reencrypt_digest_verify(struct crypt_device *cd, struct luks2_hdr *hdr, struct volume_key *vks) diff --git a/lib/luks2/luks2_token.c b/lib/luks2/luks2_token.c index 4014a2658..8bd953f73 100644 --- a/lib/luks2/luks2_token.c +++ b/lib/luks2/luks2_token.c @@ -842,71 +842,6 @@ int LUKS2_token_unlock_key(struct crypt_device *cd, return r; } -int LUKS2_token_open_and_activate(struct crypt_device *cd, - struct luks2_hdr *hdr, - int keyslot, - int token, - const char *name, - const char *type, - const char *pin, - size_t pin_size, - uint32_t flags, - void *usrptr) -{ - bool use_keyring; - int r, segment; - struct volume_key *p_crypt, *p_opal, *crypt_key = NULL, *opal_key = NULL, *vk = NULL; - - if (flags & CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY) - segment = CRYPT_ANY_SEGMENT; - else - segment = CRYPT_DEFAULT_SEGMENT; - - r = LUKS2_token_unlock_key(cd, hdr, keyslot, token, type, pin, pin_size, segment, usrptr, &vk); - if (r < 0) - return r; - - assert(vk); - - keyslot = r; - - if (LUKS2_segment_is_hw_opal(hdr, CRYPT_DEFAULT_SEGMENT)) { - r = LUKS2_split_crypt_and_opal_keys(cd, hdr, vk, &crypt_key, &opal_key); - if (r < 0) { - crypt_free_volume_key(vk); - return r; - } - - p_crypt = crypt_key; - p_opal = opal_key ?: vk; - } else { - p_crypt = vk; - p_opal = NULL; - } - - if (!crypt_use_keyring_for_vk(cd) || !p_crypt) - use_keyring = false; - else - use_keyring = ((name && !crypt_is_cipher_null(crypt_get_cipher(cd))) || - (flags & CRYPT_ACTIVATE_KEYRING_KEY)); - - if (use_keyring) { - if (!(r = LUKS2_volume_key_load_in_keyring_by_keyslot(cd, hdr, p_crypt, keyslot))) - flags |= CRYPT_ACTIVATE_KEYRING_KEY; - } - - if (r >= 0 && name) - r = LUKS2_activate(cd, name, p_crypt, p_opal, flags); - - if (r < 0) - crypt_drop_keyring_key(cd, p_crypt); - crypt_free_volume_key(vk); - crypt_free_volume_key(crypt_key); - crypt_free_volume_key(opal_key); - - return r < 0 ? r : keyslot; -} - void LUKS2_token_dump(struct crypt_device *cd, int token) { const crypt_token_handler *h; diff --git a/lib/setup.c b/lib/setup.c index f0b640503..482f5c605 100644 --- a/lib/setup.c +++ b/lib/setup.c @@ -4919,85 +4919,6 @@ int create_or_reload_device_with_integrity(struct crypt_device *cd, const char * return r; } -static int _open_and_activate(struct crypt_device *cd, - int keyslot, - const char *name, - const char *passphrase, - size_t passphrase_size, - uint32_t flags) -{ - bool use_keyring; - int r; - struct volume_key *p_crypt = NULL, *p_opal = NULL, *crypt_key = NULL, *opal_key = NULL, *vk = NULL; - key_serial_t kid1 = 0, kid2 = 0; - - r = LUKS2_keyslot_open(cd, keyslot, - (flags & CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY) ? - CRYPT_ANY_SEGMENT : CRYPT_DEFAULT_SEGMENT, - passphrase, passphrase_size, &vk); - if (r < 0) - return r; - keyslot = r; - - /* split the key only if we do activation */ - if (name && LUKS2_segment_is_hw_opal(&cd->u.luks2.hdr, CRYPT_DEFAULT_SEGMENT)) { - r = LUKS2_split_crypt_and_opal_keys(cd, &cd->u.luks2.hdr, - vk, &crypt_key, - &opal_key); - if (r < 0) - goto out; - - /* copy volume key digest id in crypt subkey */ - crypt_volume_key_set_id(crypt_key, crypt_volume_key_get_id(vk)); - - p_crypt = crypt_key; - p_opal = opal_key ?: vk; - } else - p_crypt = vk; - - if (!crypt_use_keyring_for_vk(cd)) - use_keyring = false; - else - use_keyring = ((name && !crypt_is_cipher_null(crypt_get_cipher(cd))) || - (flags & CRYPT_ACTIVATE_KEYRING_KEY)); - - if (use_keyring) { - /* upload dm-crypt part of volume key in thread keyring if requested */ - if (p_crypt) { - r = LUKS2_volume_key_load_in_keyring_by_digest(cd, p_crypt, - crypt_volume_key_get_id(p_crypt)); - if (r < 0) - goto out; - flags |= CRYPT_ACTIVATE_KEYRING_KEY; - } - - /* upload the volume key in custom user keyring if requested */ - if (cd->link_vk_to_keyring) { - r = crypt_volume_key_load_in_user_keyring(cd, vk, &kid1, &kid2); - if (r < 0) { - log_err(cd, _("Failed to link volume key in user defined keyring.")); - goto out; - } - } - } - - if (name) - r = LUKS2_activate(cd, name, p_crypt, p_opal, flags); -out: - if (r < 0) { - crypt_drop_keyring_key(cd, p_crypt); - if (cd->link_vk_to_keyring && kid1) - crypt_unlink_key_from_custom_keyring(cd, kid1); - if (cd->link_vk_to_keyring && kid2) - crypt_unlink_key_from_custom_keyring(cd, kid2); - } - crypt_free_volume_key(vk); - crypt_free_volume_key(crypt_key); - crypt_free_volume_key(opal_key); - - return r < 0 ? r : keyslot; -} - static int load_all_keys(struct crypt_device *cd, struct volume_key *vks) { int r; @@ -5014,54 +4935,6 @@ static int load_all_keys(struct crypt_device *cd, struct volume_key *vks) } #if USE_LUKS2_REENCRYPTION -static int _open_all_keys(struct crypt_device *cd, - struct luks2_hdr *hdr, - int keyslot, - const char *passphrase, - size_t passphrase_size, - uint32_t flags, - struct volume_key **vks) -{ - int r, segment; - struct volume_key *_vks = NULL; - crypt_reencrypt_info ri = LUKS2_reencrypt_status(hdr); - - segment = (flags & CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY) ? CRYPT_ANY_SEGMENT : CRYPT_DEFAULT_SEGMENT; - - switch (ri) { - case CRYPT_REENCRYPT_NONE: - r = LUKS2_keyslot_open(cd, keyslot, segment, passphrase, passphrase_size, &_vks); - break; - case CRYPT_REENCRYPT_CLEAN: - case CRYPT_REENCRYPT_CRASH: - if (segment == CRYPT_ANY_SEGMENT) - r = LUKS2_keyslot_open(cd, keyslot, segment, passphrase, - passphrase_size, &_vks); - else - r = LUKS2_keyslot_open_all_segments(cd, keyslot, - keyslot, passphrase, passphrase_size, - &_vks); - break; - default: - r = -EINVAL; - } - - if (keyslot == CRYPT_ANY_SLOT) - keyslot = r; - - if (r >= 0 && (flags & CRYPT_ACTIVATE_KEYRING_KEY)) - r = load_all_keys(cd, _vks); - - if (r >= 0 && vks) - MOVE_REF(*vks, _vks); - - if (r < 0) - crypt_drop_keyring_key(cd, _vks); - crypt_free_volume_key(_vks); - - return r < 0 ? r : keyslot; -} - static int _activate_reencrypt_device_by_vk(struct crypt_device *cd, struct luks2_hdr *hdr, const char *name, @@ -5150,152 +5023,9 @@ static int _activate_reencrypt_device_by_vk(struct crypt_device *cd, return r; } -static int _open_and_activate_reencrypt_device(struct crypt_device *cd, - struct luks2_hdr *hdr, - int keyslot, - const char *name, - const char *passphrase, - size_t passphrase_size, - uint32_t flags) -{ - bool dynamic_size; - crypt_reencrypt_info ri; - uint64_t minimal_size, device_size; - struct volume_key *vks = NULL; - int r = 0; - struct crypt_lock_handle *reencrypt_lock = NULL; - key_serial_t kid1 = 0, kid2 = 0; - - if (crypt_use_keyring_for_vk(cd)) - flags |= CRYPT_ACTIVATE_KEYRING_KEY; - - r = LUKS2_reencrypt_lock(cd, &reencrypt_lock); - if (r) { - if (r == -EBUSY) - log_err(cd, _("Reencryption in-progress. Cannot activate device.")); - else - log_err(cd, _("Failed to get reencryption lock.")); - return r; - } - - if ((r = crypt_load(cd, CRYPT_LUKS2, NULL))) - goto out; - - ri = LUKS2_reencrypt_status(hdr); - - if (ri == CRYPT_REENCRYPT_CRASH) { - r = LUKS2_reencrypt_locked_recovery_by_passphrase(cd, keyslot, - keyslot, passphrase, passphrase_size, &vks); - if (r < 0) { - log_err(cd, _("LUKS2 reencryption recovery failed.")); - goto out; - } - keyslot = r; - - ri = LUKS2_reencrypt_status(hdr); - } - - /* recovery finished reencryption or it's already finished */ - if (ri == CRYPT_REENCRYPT_NONE) { - crypt_drop_keyring_key(cd, vks); - crypt_free_volume_key(vks); - LUKS2_reencrypt_unlock(cd, reencrypt_lock); - return _open_and_activate(cd, keyslot, name, passphrase, passphrase_size, flags); - } - - if (ri > CRYPT_REENCRYPT_CLEAN) { - r = -EINVAL; - goto out; - } - - if (LUKS2_get_data_size(hdr, &minimal_size, &dynamic_size)) - goto out; - - if (!vks) { - r = _open_all_keys(cd, hdr, keyslot, passphrase, passphrase_size, flags, &vks); - if (r >= 0) - keyslot = r; - } - - if (r >= 0) { - r = LUKS2_reencrypt_digest_verify(cd, hdr, vks); - if (r < 0) - goto out; - } - - log_dbg(cd, "Entering clean reencryption state mode."); - - if (cd->link_vk_to_keyring) { - r = crypt_volume_key_load_in_user_keyring(cd, vks, &kid1, &kid2); - if (r < 0) { - log_err(cd, _("Failed to link volume keys in user defined keyring.")); - goto out; - } - } - - if (r >= 0) - r = LUKS2_reencrypt_check_device_size(cd, hdr, minimal_size, &device_size, - !(flags & CRYPT_ACTIVATE_SHARED), - dynamic_size); - - if (r >= 0) - r = LUKS2_activate_multi(cd, name, vks, device_size >> SECTOR_SHIFT, flags); -out: - LUKS2_reencrypt_unlock(cd, reencrypt_lock); - if (r < 0) { - crypt_drop_keyring_key(cd, vks); - if (cd->link_vk_to_keyring && kid1) - crypt_unlink_key_from_custom_keyring(cd, kid1); - if (cd->link_vk_to_keyring && kid2) - crypt_unlink_key_from_custom_keyring(cd, kid2); - } - - crypt_free_volume_key(vks); - - return r < 0 ? r : keyslot; -} - /* * Activation/deactivation of a device */ -static int _open_and_activate_luks2(struct crypt_device *cd, - int keyslot, - const char *name, - const char *passphrase, - size_t passphrase_size, - uint32_t flags) -{ - crypt_reencrypt_info ri; - int r, rv; - struct luks2_hdr *hdr = &cd->u.luks2.hdr; - struct volume_key *vks = NULL; - - ri = LUKS2_reencrypt_status(hdr); - if (ri == CRYPT_REENCRYPT_INVALID) - return -EINVAL; - - if (ri > CRYPT_REENCRYPT_NONE) { - if (name) - r = _open_and_activate_reencrypt_device(cd, hdr, keyslot, name, passphrase, - passphrase_size, flags); - else { - r = _open_all_keys(cd, hdr, keyslot, passphrase, - passphrase_size, flags, &vks); - if (r < 0) - return r; - - rv = LUKS2_reencrypt_digest_verify(cd, hdr, vks); - crypt_free_volume_key(vks); - if (rv < 0) - return rv; - } - } else - r = _open_and_activate(cd, keyslot, name, passphrase, - passphrase_size, flags); - - return r; -} - static int _activate_luks2_by_volume_key(struct crypt_device *cd, const char *name, struct volume_key *vk, @@ -5320,27 +5050,6 @@ static int _activate_luks2_by_volume_key(struct crypt_device *cd, return r; } #else -static int _open_and_activate_luks2(struct crypt_device *cd, - int keyslot, - const char *name, - const char *passphrase, - size_t passphrase_size, - uint32_t flags) -{ - crypt_reencrypt_info ri; - - ri = LUKS2_reencrypt_status(&cd->u.luks2.hdr); - if (ri == CRYPT_REENCRYPT_INVALID) - return -EINVAL; - - if (ri > CRYPT_REENCRYPT_NONE) { - log_err(cd, _("This operation is not supported for this device type.")); - return -ENOTSUP; - } - - return _open_and_activate(cd, keyslot, name, passphrase, passphrase_size, flags); -} - static int _activate_luks2_by_volume_key(struct crypt_device *cd, const char *name, struct volume_key *vk, @@ -5365,76 +5074,6 @@ static int _activate_luks2_by_volume_key(struct crypt_device *cd, } #endif -static int _activate_by_passphrase(struct crypt_device *cd, - const char *name, - int keyslot, - const char *passphrase, - size_t passphrase_size, - uint32_t flags) -{ - int r; - struct volume_key *vk = NULL; - - if ((flags & CRYPT_ACTIVATE_KEYRING_KEY) && !crypt_use_keyring_for_vk(cd)) - return -EINVAL; - - if ((flags & CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY) && name) - return -EINVAL; - - r = _check_header_data_overlap(cd, name); - if (r < 0) - return r; - - if (flags & CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF) - cd->memory_hard_pbkdf_lock_enabled = true; - - /* plain, use hashed passphrase */ - if (isPLAIN(cd->type)) { - r = -EINVAL; - if (!name) - goto out; - - r = process_key(cd, cd->u.plain.hdr.hash, - cd->u.plain.key_size, - passphrase, passphrase_size, &vk); - if (r < 0) - goto out; - - r = PLAIN_activate(cd, name, vk, cd->u.plain.hdr.size, flags); - keyslot = 0; - } else if (isLUKS1(cd->type)) { - r = LUKS_open_key_with_hdr(keyslot, passphrase, - passphrase_size, &cd->u.luks1.hdr, &vk, cd); - if (r >= 0) { - keyslot = r; - if (name) - r = LUKS1_activate(cd, name, vk, flags); - } - } else if (isLUKS2(cd->type)) { - r = _open_and_activate_luks2(cd, keyslot, name, passphrase, passphrase_size, flags); - keyslot = r; - } else if (isBITLK(cd->type)) { - r = BITLK_activate_by_passphrase(cd, name, passphrase, passphrase_size, - &cd->u.bitlk.params, flags); - keyslot = 0; - } else if (isFVAULT2(cd->type)) { - r = FVAULT2_activate_by_passphrase(cd, name, passphrase, passphrase_size, - &cd->u.fvault2.params, flags); - keyslot = 0; - } else { - log_err(cd, _("Device type is not properly initialized.")); - r = -EINVAL; - } -out: - if (r < 0) - crypt_drop_keyring_key(cd, vk); - crypt_free_volume_key(vk); - - cd->memory_hard_pbkdf_lock_enabled = false; - - return r < 0 ? r : keyslot; -} - static int _activate_loopaes(struct crypt_device *cd, const char *name, const char *buffer, @@ -5598,6 +5237,7 @@ static int _activate_by_volume_key(struct crypt_device *cd, cd->u.integrity.sb_flags); } else if (isBITLK(cd->type)) { assert(!external_key); + assert(crypt_volume_key_get_id(vk) == KEY_VERIFIED); r = BITLK_activate_by_volume_key(cd, name, vk, &cd->u.bitlk.params, flags); } else if (isFVAULT2(cd->type)) { assert(!external_key); @@ -5656,23 +5296,14 @@ int crypt_activate_by_keyslot_context(struct crypt_device *cd, if (r < 0) return r; - /* for TCRYPT and token skip passphrase activation */ if (kc->get_passphrase && kc->type != CRYPT_KC_TYPE_TOKEN && - !isTCRYPT(cd->type) && !isLUKS(cd->type)) { + isLOOPAES(cd->type)) { r = kc->get_passphrase(cd, kc, &passphrase, &passphrase_size); if (r < 0) return r; - /* TODO: Only loopaes should by activated by passphrase method */ - if (passphrase) { - if (isLOOPAES(cd->type)) - return _activate_loopaes(cd, name, passphrase, passphrase_size, flags); - else - return _activate_by_passphrase(cd, name, keyslot, passphrase, passphrase_size, flags); - } + + return _activate_loopaes(cd, name, passphrase, passphrase_size, flags); } - /* only passphrase unlock is supported with loopaes */ - if (isLOOPAES(cd->type)) - return -EINVAL; /* aquire the volume key(s) */ r = -EINVAL; @@ -5701,14 +5332,21 @@ int crypt_activate_by_keyslot_context(struct crypt_device *cd, } else if (isTCRYPT(cd->type)) { r = 0; } else if (name && isPLAIN(cd->type)) { - if (kc->get_plain_volume_key) + if (kc->get_passphrase && kc->type != CRYPT_KC_TYPE_TOKEN) { + r = kc->get_passphrase(cd, kc, &passphrase, &passphrase_size); + if (r < 0) + return r; + r = process_key(cd, cd->u.plain.hdr.hash, + cd->u.plain.key_size, + passphrase, passphrase_size, &vk); + } else if (kc->get_plain_volume_key) r = kc->get_plain_volume_key(cd, kc, &vk); - } else if (name && isBITLK(cd->type)) { - if (kc->get_bitlk_volume_key) - r = kc->get_bitlk_volume_key(cd, kc, &vk); + } else if (isBITLK(cd->type)) { + if (kc->get_bitlk_volume_key && (name || kc->type != CRYPT_KC_TYPE_KEY)) + r = kc->get_bitlk_volume_key(cd, kc, &cd->u.bitlk.params, &vk); } else if (isFVAULT2(cd->type)) { if (kc->get_fvault2_volume_key) - r = kc->get_fvault2_volume_key(cd, kc, &vk); + r = kc->get_fvault2_volume_key(cd, kc, &cd->u.fvault2.params, &vk); } else if (isVERITY(cd->type) && (name || kc->type != CRYPT_KC_TYPE_SIGNED_KEY)) { if (kc->get_verity_volume_key) r = kc->get_verity_volume_key(cd, kc, &vk, &vk_sign); @@ -6148,12 +5786,6 @@ int crypt_volume_key_get_by_keyslot_context(struct crypt_device *cd, if (kc && (!kc->get_passphrase || kc->type == CRYPT_KC_TYPE_KEY)) return -EINVAL; - if (kc) { - r = kc->get_passphrase(cd, kc, &passphrase, &passphrase_size); - if (r < 0) - return r; - } - r = -EINVAL; if (isLUKS2(cd->type)) { @@ -6172,10 +5804,14 @@ int crypt_volume_key_get_by_keyslot_context(struct crypt_device *cd, r = -ENOENT; else r = kc->get_luks1_volume_key(cd, kc, keyslot, &vk); - } else if (isPLAIN(cd->type)) { - if (passphrase && cd->u.plain.hdr.hash) + } else if (isPLAIN(cd->type) && cd->u.plain.hdr.hash) { + if (kc && kc->get_passphrase && kc->type != CRYPT_KC_TYPE_TOKEN) { + r = kc->get_passphrase(cd, kc, &passphrase, &passphrase_size); + if (r < 0) + return r; r = process_key(cd, cd->u.plain.hdr.hash, key_len, passphrase, passphrase_size, &vk); + } if (r < 0) log_err(cd, _("Cannot retrieve volume key for plain device.")); } else if (isVERITY(cd->type)) { @@ -6189,13 +5825,13 @@ int crypt_volume_key_get_by_keyslot_context(struct crypt_device *cd, } else if (isTCRYPT(cd->type)) { r = TCRYPT_get_volume_key(cd, &cd->u.tcrypt.hdr, &cd->u.tcrypt.params, &vk); } else if (isBITLK(cd->type)) { - if (passphrase) - r = BITLK_get_volume_key(cd, passphrase, passphrase_size, &cd->u.bitlk.params, &vk); + if (kc && kc->get_bitlk_volume_key) + r = kc->get_bitlk_volume_key(cd, kc, &cd->u.bitlk.params, &vk); if (r < 0) log_err(cd, _("Cannot retrieve volume key for BITLK device.")); } else if (isFVAULT2(cd->type)) { - if (passphrase) - r = FVAULT2_get_volume_key(cd, passphrase, passphrase_size, &cd->u.fvault2.params, &vk); + if (kc && kc->get_fvault2_volume_key) + r = kc->get_fvault2_volume_key(cd, kc, &cd->u.fvault2.params, &vk); if (r < 0) log_err(cd, _("Cannot retrieve volume key for FVAULT2 device.")); } else