Commit 1ac353d2 authored by Milan Broz's avatar Milan Broz

Allocate key description in volume key.

The key description is now allocated by volume key wrappers.
parent d7686201
......@@ -64,8 +64,7 @@ struct volume_key {
struct volume_key *crypt_alloc_volume_key(size_t keylength, const char *key);
struct volume_key *crypt_generate_volume_key(struct crypt_device *cd, size_t keylength);
void crypt_free_volume_key(struct volume_key *vk);
void crypt_volume_key_set_description(struct volume_key *key, const char *key_description);
const char *crypt_volume_key_get_description(const struct volume_key *key);
int crypt_volume_key_set_description(struct volume_key *key, const char *key_description);
struct crypt_pbkdf_type *crypt_get_pbkdf(struct crypt_device *cd);
int init_pbkdf_type(struct crypt_device *cd,
......
......@@ -1482,7 +1482,7 @@ static int _dm_query_crypt(uint32_t get_flags,
if (get_flags & DM_ACTIVE_CRYPT_KEY) {
if (key_[0] == ':') {
key_desc = strdup(strpbrk(strpbrk(key_ + 1, ":") + 1, ":") + 1);
key_desc = strpbrk(strpbrk(key_ + 1, ":") + 1, ":") + 1;
if (!key_desc) {
r = -ENOMEM;
goto err;
......
......@@ -353,9 +353,8 @@ int LUKS2_config_set_requirements(struct crypt_device *cd, struct luks2_hdr *hdr
int LUKS2_unmet_requirements(struct crypt_device *cd, struct luks2_hdr *hdr, uint32_t reqs_mask, int quiet);
int crypt_use_keyring_for_vk(const struct crypt_device *cd);
int crypt_volume_key_load_in_keyring(struct crypt_device *cd, struct volume_key *vk);
int crypt_volume_key_load_in_keyring_by_keyslot(struct crypt_device *cd, struct volume_key *vk, int keyslot);
void crypt_drop_keyring_key(struct crypt_device *cd, const char *key_description);
const char *crypt_get_key_description_by_keyslot(struct crypt_device *cd, int keyslot);
int crypt_get_passphrase_from_keyring(const char *key_description,
char **passphrase, size_t *passphrase_len);
......
......@@ -403,16 +403,14 @@ int LUKS2_token_open_and_activate(struct crypt_device *cd,
keyslot = r;
if ((name || (flags & CRYPT_ACTIVATE_KEYRING_KEY)) && crypt_use_keyring_for_vk(cd)) {
crypt_volume_key_set_description(vk, crypt_get_key_description_by_keyslot(cd, keyslot));
r = crypt_volume_key_load_in_keyring(cd, vk);
}
if ((name || (flags & CRYPT_ACTIVATE_KEYRING_KEY)) && crypt_use_keyring_for_vk(cd))
r = crypt_volume_key_load_in_keyring_by_keyslot(cd, vk, keyslot);
if (r >= 0 && name)
r = LUKS2_activate(cd, name, vk, flags);
if (r < 0)
crypt_drop_keyring_key(cd, crypt_volume_key_get_description(vk));
if (r < 0 && vk)
crypt_drop_keyring_key(cd, vk->key_description);
crypt_free_volume_key(vk);
return r < 0 ? r : keyslot;
......@@ -449,16 +447,14 @@ int LUKS2_token_open_and_activate_any(struct crypt_device *cd,
keyslot = r;
if (r >= 0 && (name || (flags & CRYPT_ACTIVATE_KEYRING_KEY)) && crypt_use_keyring_for_vk(cd)) {
crypt_volume_key_set_description(vk, crypt_get_key_description_by_keyslot(cd, keyslot));
r = crypt_volume_key_load_in_keyring(cd, vk);
}
if (r >= 0 && (name || (flags & CRYPT_ACTIVATE_KEYRING_KEY)) && crypt_use_keyring_for_vk(cd))
r = crypt_volume_key_load_in_keyring_by_keyslot(cd, vk, keyslot);
if (r >= 0 && name)
r = LUKS2_activate(cd, name, vk, flags);
if (r < 0)
crypt_drop_keyring_key(cd, crypt_volume_key_get_description(vk));
if (r < 0 && vk)
crypt_drop_keyring_key(cd, vk->key_description);
crypt_free_volume_key(vk);
return r < 0 ? r : keyslot;
......
......@@ -2017,7 +2017,7 @@ int crypt_repair(struct crypt_device *cd,
return r;
}
static const char *crypt_get_key_description_by_digest(struct crypt_device *cd, int digest)
static char *crypt_get_key_description_by_digest(struct crypt_device *cd, int digest)
{
char *desc, digest_str[3];
int r;
......@@ -2046,15 +2046,52 @@ static const char *crypt_get_key_description_by_digest(struct crypt_device *cd,
return desc;
}
static const char *crypt_get_key_description_by_segment(struct crypt_device *cd, int segment)
static int crypt_set_key_description_by_segment(struct crypt_device *cd, struct volume_key *vk, int segment)
{
return crypt_get_key_description_by_digest(cd, LUKS2_digest_by_segment(cd, &cd->u.luks2.hdr, segment));
char *desc = crypt_get_key_description_by_digest(cd, LUKS2_digest_by_segment(cd, &cd->u.luks2.hdr, segment));
int r;
r = crypt_volume_key_set_description(vk, desc);
free(desc);
return r;
}
/* curently internal only (candidate for new API call) */
const char *crypt_get_key_description_by_keyslot(struct crypt_device *cd, int keyslot)
/* internal only */
static int crypt_volume_key_load_in_keyring(struct crypt_device *cd, struct volume_key *vk)
{
return crypt_get_key_description_by_digest(cd, LUKS2_digest_by_keyslot(cd, &cd->u.luks2.hdr, keyslot));
int r;
if (!vk || !cd)
return -EINVAL;
if (!vk->key_description) {
log_dbg("Invalid key description");
return -EINVAL;
}
log_dbg("Loading key (%zu bytes) in thread keyring.", vk->keylength);
r = keyring_add_key_in_thread_keyring(vk->key_description, vk->key, vk->keylength);
if (r) {
log_dbg("keyring_add_key_in_thread_keyring failed (error %d)", r);
log_err(cd, _("Failed to load key in kernel keyring.\n"));
} else
crypt_set_key_in_keyring(cd, 1);
return r;
}
int crypt_volume_key_load_in_keyring_by_keyslot(struct crypt_device *cd, struct volume_key *vk, int keyslot)
{
char *desc = crypt_get_key_description_by_digest(cd, LUKS2_digest_by_keyslot(cd, &cd->u.luks2.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 crypt_resize(struct crypt_device *cd, const char *name, uint64_t new_size)
......@@ -2096,8 +2133,7 @@ int crypt_resize(struct crypt_device *cd, const char *name, uint64_t new_size)
}
if (crypt_key_in_keyring(cd)) {
crypt_volume_key_set_description(dmd.u.crypt.vk, crypt_get_key_description_by_segment(cd, CRYPT_DEFAULT_SEGMENT));
r = crypt_volume_key_get_description(dmd.u.crypt.vk) ? 0 : -EINVAL;
r = crypt_set_key_description_by_segment(cd, dmd.u.crypt.vk, CRYPT_DEFAULT_SEGMENT);
if (r)
goto out;
......@@ -2320,7 +2356,7 @@ void crypt_drop_keyring_key(struct crypt_device *cd, const char *key_description
if (!key_description)
return;
log_dbg("Requesting keyring key %s for revoke and unlink.", key_description);
log_dbg("Requesting keyring key for revoke and unlink.");
r = keyring_revoke_and_unlink_key(key_description);
if (r)
......@@ -2337,8 +2373,8 @@ static char *crypt_get_device_key_description(const char *name)
return NULL;
if (dmd.target == DM_CRYPT) {
if (dmd.flags & CRYPT_ACTIVATE_KEYRING_KEY)
tmp = strdup(crypt_volume_key_get_description(dmd.u.crypt.vk));
if ((dmd.flags & CRYPT_ACTIVATE_KEYRING_KEY) && dmd.u.crypt.vk->key_description)
tmp = strdup(dmd.u.crypt.vk->key_description);
crypt_free_volume_key(dmd.u.crypt.vk);
} else if (dmd.target == DM_INTEGRITY) {
crypt_free_volume_key(dmd.u.integrity.vk);
......@@ -2447,8 +2483,7 @@ int crypt_resume_by_passphrase(struct crypt_device *cd,
keyslot = r;
if (crypt_use_keyring_for_vk(cd)) {
crypt_volume_key_set_description(vk, crypt_get_key_description_by_keyslot(cd, keyslot));
r = crypt_volume_key_load_in_keyring(cd, vk);
r = crypt_volume_key_load_in_keyring_by_keyslot(cd, vk, keyslot);
if (r < 0)
goto out;
}
......@@ -2460,8 +2495,8 @@ int crypt_resume_by_passphrase(struct crypt_device *cd,
else if (r)
log_err(cd, _("Error during resuming device %s.\n"), name);
out:
if (r < 0)
crypt_drop_keyring_key(cd, crypt_volume_key_get_description(vk));
if (r < 0 && vk)
crypt_drop_keyring_key(cd, vk->key_description);
crypt_free_volume_key(vk);
return r < 0 ? r : keyslot;
......@@ -2514,8 +2549,7 @@ int crypt_resume_by_keyfile_device_offset(struct crypt_device *cd,
keyslot = r;
if (crypt_use_keyring_for_vk(cd)) {
crypt_volume_key_set_description(vk, crypt_get_key_description_by_keyslot(cd, keyslot));
r = crypt_volume_key_load_in_keyring(cd, vk);
r = crypt_volume_key_load_in_keyring_by_keyslot(cd, vk, keyslot);
if (r < 0)
goto out;
}
......@@ -2525,8 +2559,8 @@ int crypt_resume_by_keyfile_device_offset(struct crypt_device *cd,
log_err(cd, _("Error during resuming device %s.\n"), name);
out:
crypt_safe_free(passphrase_read);
if (r < 0)
crypt_drop_keyring_key(cd, crypt_volume_key_get_description(vk));
if (r < 0 && vk)
crypt_drop_keyring_key(cd, vk->key_description);
crypt_free_volume_key(vk);
return r < 0 ? r : keyslot;
}
......@@ -2936,33 +2970,6 @@ int crypt_keyslot_destroy(struct crypt_device *cd, int keyslot)
return LUKS2_keyslot_wipe(cd, &cd->u.luks2.hdr, keyslot, 0);
}
/* internal only */
int crypt_volume_key_load_in_keyring(struct crypt_device *cd, struct volume_key *vk)
{
const char *key_desc;
int r;
if (!vk || !cd)
return -EINVAL;
key_desc = crypt_volume_key_get_description(vk);
if (!key_desc) {
log_dbg("Invalid key description");
return -EINVAL;
}
log_dbg("Loading key %s (%zu bytes) in thread keyring.", key_desc, vk->keylength);
r = keyring_add_key_in_thread_keyring(key_desc, vk->key, vk->keylength);
if (r) {
log_dbg("keyring_add_key_in_thread_keyring failed (error %d)", r);
log_err(cd, _("Failed to load key in kernel keyring.\n"));
} else
crypt_set_key_in_keyring(cd, 1);
return r;
}
/*
* Activation/deactivation of a device
*/
......@@ -3008,8 +3015,7 @@ static int _activate_by_passphrase(struct crypt_device *cd,
keyslot = r;
if ((name || (flags & CRYPT_ACTIVATE_KEYRING_KEY)) && crypt_use_keyring_for_vk(cd)) {
crypt_volume_key_set_description(vk, crypt_get_key_description_by_keyslot(cd, keyslot));
r = crypt_volume_key_load_in_keyring(cd, vk);
r = crypt_volume_key_load_in_keyring_by_keyslot(cd, vk, keyslot);
if (r < 0)
goto out;
flags |= CRYPT_ACTIVATE_KEYRING_KEY;
......@@ -3023,8 +3029,8 @@ static int _activate_by_passphrase(struct crypt_device *cd,
r = -EINVAL;
}
out:
if (r < 0)
crypt_drop_keyring_key(cd, crypt_volume_key_get_description(vk));
if (r < 0 && vk)
crypt_drop_keyring_key(cd, vk->key_description);
crypt_free_volume_key(vk);
return r < 0 ? r : keyslot;
......@@ -3147,8 +3153,7 @@ int crypt_activate_by_keyfile_device_offset(struct crypt_device *cd,
keyslot = r;
if ((name || (flags & CRYPT_ACTIVATE_KEYRING_KEY)) && crypt_use_keyring_for_vk(cd)) {
crypt_volume_key_set_description(vk, crypt_get_key_description_by_keyslot(cd, keyslot));
r = crypt_volume_key_load_in_keyring(cd, vk);
r = crypt_volume_key_load_in_keyring_by_keyslot(cd, vk, keyslot);
if (r < 0)
goto out;
flags |= CRYPT_ACTIVATE_KEYRING_KEY;
......@@ -3179,8 +3184,8 @@ int crypt_activate_by_keyfile_device_offset(struct crypt_device *cd,
}
out:
crypt_safe_free(passphrase_read);
if (r < 0)
crypt_drop_keyring_key(cd, crypt_volume_key_get_description(vk));
if (r < 0 && vk)
crypt_drop_keyring_key(cd, vk->key_description);
crypt_free_volume_key(vk);
return r;
......@@ -3285,8 +3290,9 @@ int crypt_activate_by_volume_key(struct crypt_device *cd,
log_err(cd, _("Volume key does not match the volume.\n"));
if (!r && (name || (flags & CRYPT_ACTIVATE_KEYRING_KEY)) && crypt_use_keyring_for_vk(cd)) {
crypt_volume_key_set_description(vk, crypt_get_key_description_by_segment(cd, CRYPT_DEFAULT_SEGMENT));
r = crypt_volume_key_load_in_keyring(cd, vk);
r = crypt_set_key_description_by_segment(cd, vk, CRYPT_DEFAULT_SEGMENT);
if (!r)
r = crypt_volume_key_load_in_keyring(cd, vk);
if (!r)
flags |= CRYPT_ACTIVATE_KEYRING_KEY;
}
......@@ -3334,8 +3340,8 @@ int crypt_activate_by_volume_key(struct crypt_device *cd,
r = -EINVAL;
}
if (r < 0)
crypt_drop_keyring_key(cd, crypt_volume_key_get_description(vk));
if (r < 0 && vk)
crypt_drop_keyring_key(cd, vk->key_description);
crypt_free_volume_key(vk);
return r;
......
......@@ -22,6 +22,7 @@
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <errno.h>
#include "internal.h"
......@@ -50,20 +51,17 @@ struct volume_key *crypt_alloc_volume_key(size_t keylength, const char *key)
return vk;
}
void crypt_volume_key_set_description(struct volume_key *vk, const char *key_description)
{
if (vk) {
free(CONST_CAST(void*)vk->key_description);
vk->key_description = key_description;
}
}
const char *crypt_volume_key_get_description(const struct volume_key *vk)
int crypt_volume_key_set_description(struct volume_key *vk, const char *key_description)
{
if (!vk)
return NULL;
return -EINVAL;
free(CONST_CAST(void*)vk->key_description);
vk->key_description = NULL;
if (key_description && !(vk->key_description = strdup(key_description)))
return -ENOMEM;
return vk->key_description;
return 0;
}
void crypt_free_volume_key(struct volume_key *vk)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment