Switch reencrypt --encrypt initialization to keyslot context.

This allows to simplify init_keyslot_context and we can only
pass single pointer from luksFormat routine.
This commit is contained in:
Ondrej Kozina
2025-04-25 18:06:05 +02:00
committed by Milan Broz
parent 9f0dd9cc4c
commit 4493d9ad3e
4 changed files with 67 additions and 68 deletions

View File

@@ -906,10 +906,8 @@ static int action_close(void)
static int action_resize(void) static int action_resize(void)
{ {
int r; int r;
size_t passwordLen;
struct crypt_active_device cad; struct crypt_active_device cad;
uint64_t dev_size = 0; uint64_t dev_size = 0;
char *password = NULL;
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
struct crypt_keyslot_context *kc = NULL; struct crypt_keyslot_context *kc = NULL;
@@ -953,9 +951,7 @@ static int action_resize(void)
if (r >= 0 || quit || ARG_SET(OPT_TOKEN_ONLY_ID)) if (r >= 0 || quit || ARG_SET(OPT_TOKEN_ONLY_ID))
goto out; goto out;
r = luks_init_keyslot_context(cd, NULL, &password, &passwordLen, r = luks_init_keyslot_context(cd, NULL, verify_passphrase(0), false, &kc);
verify_passphrase(0), false, false, &kc);
crypt_safe_free(password);
if (r < 0) if (r < 0)
goto out; goto out;
@@ -1491,15 +1487,15 @@ static int strcmp_or_null(const char *str, const char *expected)
return !str ? 0 : strcmp(str, expected); return !str ? 0 : strcmp(str, expected);
} }
int luksFormat(struct crypt_device **r_cd, char **r_password, size_t *r_passwordLen) int luksFormat(struct crypt_device **r_cd, struct crypt_keyslot_context **r_kc)
{ {
bool wipe_signatures = false; bool wipe_signatures = false;
int encrypt_type, r = -EINVAL, keysize, integrity_keysize = 0, required_integrity_key_size = 0, fd, created = 0; int encrypt_type, r = -EINVAL, integrity_keysize = 0, required_integrity_key_size = 0, fd, created = 0;
struct stat st; struct stat st;
const char *header_device, *type; const char *header_device, *type;
char *msg = NULL, *key = NULL, *password = NULL; char *msg = NULL, *key = NULL;
char cipher [MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN], integrity[MAX_CIPHER_LEN]; char cipher [MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN], integrity[MAX_CIPHER_LEN];
size_t passwordLen = 0, signatures = 0; size_t keysize, signatures = 0;
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
struct crypt_params_luks1 params1 = { struct crypt_params_luks1 params1 = {
.hash = ARG_STR(OPT_HASH_ID) ?: DEFAULT_LUKS1_HASH, .hash = ARG_STR(OPT_HASH_ID) ?: DEFAULT_LUKS1_HASH,
@@ -1666,9 +1662,8 @@ int luksFormat(struct crypt_device **r_cd, char **r_password, size_t *r_password
else if (ARG_SET(OPT_USE_URANDOM_ID)) else if (ARG_SET(OPT_USE_URANDOM_ID))
crypt_set_rng_type(cd, CRYPT_RNG_URANDOM); crypt_set_rng_type(cd, CRYPT_RNG_URANDOM);
r = luks_init_keyslot_context(cd, NULL, &password, &passwordLen, r = luks_init_keyslot_context(cd, NULL, verify_passphrase(1),
verify_passphrase(1), !ARG_SET(OPT_FORCE_PASSWORD_ID), !ARG_SET(OPT_FORCE_PASSWORD_ID), &new_kc);
r_password != NULL, &new_kc);
if (r < 0) if (r < 0)
goto out; goto out;
@@ -1721,10 +1716,25 @@ int luksFormat(struct crypt_device **r_cd, char **r_password, size_t *r_password
if (r < 0) if (r < 0)
goto out; goto out;
if (!key && r_kc) {
key = crypt_safe_alloc(keysize);
if (!key) {
r = -ENOMEM;
goto out;
}
/* Extract VK for LUKS2 encryption later */
r = crypt_volume_key_get_by_keyslot_context(cd, CRYPT_ANY_SLOT, key, &keysize, NULL);
if (r < 0)
goto out;
}
r = crypt_keyslot_context_init_by_volume_key(cd, key, keysize, &kc); r = crypt_keyslot_context_init_by_volume_key(cd, key, keysize, &kc);
if (r < 0) if (r < 0)
goto out; goto out;
crypt_safe_free(key);
key = NULL;
r = crypt_keyslot_add_by_keyslot_context(cd, CRYPT_ANY_SLOT, kc, r = crypt_keyslot_add_by_keyslot_context(cd, CRYPT_ANY_SLOT, kc,
ARG_INT32(OPT_KEY_SLOT_ID), new_kc, 0); ARG_INT32(OPT_KEY_SLOT_ID), new_kc, 0);
if (r < 0) { if (r < 0) {
@@ -1742,7 +1752,6 @@ int luksFormat(struct crypt_device **r_cd, char **r_password, size_t *r_password
} }
out: out:
crypt_safe_free(key); crypt_safe_free(key);
crypt_keyslot_context_free(kc);
crypt_keyslot_context_free(new_kc); crypt_keyslot_context_free(new_kc);
if (r < 0) { if (r < 0) {
@@ -1759,22 +1768,21 @@ out:
crypt_safe_free(CONST_CAST(void *)opal_params.admin_key); crypt_safe_free(CONST_CAST(void *)opal_params.admin_key);
if (r >= 0 && r_cd && r_password && r_passwordLen) { if (r >= 0 && r_cd && r_kc) {
*r_cd = cd; *r_cd = cd;
*r_password = password; *r_kc = kc;
*r_passwordLen = passwordLen;
return r; return r;
} }
crypt_keyslot_context_free(kc);
crypt_free(cd); crypt_free(cd);
crypt_safe_free(password);
return r; return r;
} }
static int action_luksFormat(void) static int action_luksFormat(void)
{ {
return luksFormat(NULL, NULL, NULL); return luksFormat(NULL, NULL);
} }
static int action_open_luks(void) static int action_open_luks(void)
@@ -1785,8 +1793,6 @@ static int action_open_luks(void)
char *key = NULL, *vk_description_activation1 = NULL, *vk_description_activation2 = NULL; char *key = NULL, *vk_description_activation1 = NULL, *vk_description_activation2 = NULL;
uint32_t activate_flags = 0; uint32_t activate_flags = 0;
int r, keysize, tries; int r, keysize, tries;
char *password = NULL;
size_t passwordLen;
struct stat st; struct stat st;
struct crypt_keyslot_context *kc = NULL, *kc1 = NULL, *kc2 = NULL; struct crypt_keyslot_context *kc = NULL, *kc1 = NULL, *kc2 = NULL;
@@ -1898,12 +1904,9 @@ static int action_open_luks(void)
tries = set_tries_tty(true); tries = set_tries_tty(true);
do { do {
r = luks_init_keyslot_context(cd, NULL, &password, &passwordLen, r = luks_init_keyslot_context(cd, NULL, verify_passphrase(0), false, &kc);
verify_passphrase(0), false, false, &kc);
if (r < 0) if (r < 0)
goto out; goto out;
crypt_safe_free(password);
password = NULL;
r = crypt_activate_by_keyslot_context(cd, activated_name, ARG_INT32(OPT_KEY_SLOT_ID), r = crypt_activate_by_keyslot_context(cd, activated_name, ARG_INT32(OPT_KEY_SLOT_ID),
kc, CRYPT_ANY_SLOT, kc, activate_flags); kc, CRYPT_ANY_SLOT, kc, activate_flags);
@@ -2221,8 +2224,7 @@ static int action_luksAddKey(void)
{ {
bool pin_provided = false; bool pin_provided = false;
int keyslot_old, keyslot_new, keysize = 0, r = -EINVAL; int keyslot_old, keyslot_new, keysize = 0, r = -EINVAL;
char *key, *vk_description, *password = NULL; char *key, *vk_description;
size_t password_size = 0;
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
struct crypt_keyslot_context *p_kc_new = NULL, *kc = NULL, *kc_new = NULL; struct crypt_keyslot_context *p_kc_new = NULL, *kc = NULL, *kc_new = NULL;
@@ -2321,11 +2323,9 @@ static int action_luksAddKey(void)
NULL, 0, NULL, &kc); NULL, 0, NULL, &kc);
} else { } else {
r = luks_init_keyslot_context(cd, _("Enter any existing passphrase: "), r = luks_init_keyslot_context(cd, _("Enter any existing passphrase: "),
&password, &password_size, verify_passphrase(0), false, &kc);
verify_passphrase(0), false, false, &kc);
if (r < 0) if (r < 0)
goto out; goto out;
crypt_safe_free(password);
/* Check password before asking for new one */ /* Check password before asking for new one */
r = crypt_activate_by_keyslot_context(cd, NULL, keyslot_old, kc, CRYPT_ANY_SLOT, NULL, 0); r = crypt_activate_by_keyslot_context(cd, NULL, keyslot_old, kc, CRYPT_ANY_SLOT, NULL, 0);
@@ -2551,8 +2551,7 @@ out:
static int luksDump_with_volume_key(struct crypt_device *cd) static int luksDump_with_volume_key(struct crypt_device *cd)
{ {
char *vk = NULL, *password = NULL; char *vk = NULL;
size_t passwordLen = 0;
struct crypt_keyslot_context *kc = NULL; struct crypt_keyslot_context *kc = NULL;
size_t vk_size; size_t vk_size;
int r; int r;
@@ -2569,11 +2568,9 @@ static int luksDump_with_volume_key(struct crypt_device *cd)
if (!vk) if (!vk)
return -ENOMEM; return -ENOMEM;
r = luks_init_keyslot_context(cd, NULL, &password, &passwordLen, r = luks_init_keyslot_context(cd, NULL, false, false, &kc);
false, false, false, &kc);
if (r < 0) if (r < 0)
goto out; goto out;
crypt_safe_free(password);
r = crypt_volume_key_get_by_keyslot_context(cd, CRYPT_ANY_SLOT, vk, &vk_size, kc); r = crypt_volume_key_get_by_keyslot_context(cd, CRYPT_ANY_SLOT, vk, &vk_size, kc);
tools_passphrase_msg(r); tools_passphrase_msg(r);
@@ -2726,8 +2723,7 @@ static int action_luksSuspend(void)
static int action_luksResume(void) static int action_luksResume(void)
{ {
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
char *password = NULL, *vk_description_activation = NULL; char *vk_description_activation = NULL;
size_t passwordLen;
int r, tries; int r, tries;
struct crypt_active_device cad; struct crypt_active_device cad;
const char *req_type = luksType(device_type); const char *req_type = luksType(device_type);
@@ -2798,12 +2794,9 @@ static int action_luksResume(void)
tries = set_tries_tty(true); tries = set_tries_tty(true);
do { do {
r = luks_init_keyslot_context(cd, NULL, &password, &passwordLen, r = luks_init_keyslot_context(cd, NULL, verify_passphrase(0), false, &kc);
verify_passphrase(0), false, false, &kc);
if (r < 0) if (r < 0)
goto out; goto out;
crypt_safe_free(password);
password = NULL;
r = crypt_resume_by_keyslot_context(cd, action_argv[0], ARG_INT32(OPT_KEY_SLOT_ID), kc); r = crypt_resume_by_keyslot_context(cd, action_argv[0], ARG_INT32(OPT_KEY_SLOT_ID), kc);
crypt_keyslot_context_free(kc); crypt_keyslot_context_free(kc);

View File

@@ -271,31 +271,32 @@ out:
return r; return r;
} }
/*
* FIXME: Refactor password and passwordLen params away after keyslot context support
* is added in --encrypt reencryption mode.
*/
int luks_init_keyslot_context(struct crypt_device *cd, int luks_init_keyslot_context(struct crypt_device *cd,
const char *msg, const char *msg,
char **password, size_t *passwordLen, bool verify, bool pwquality, bool verify, bool pwquality,
bool reencrypt, /* tmp hack to use old get_key */ struct crypt_keyslot_context **r_kc)
struct crypt_keyslot_context **kc)
{ {
char *password;
size_t passwordLen;
int r = -EINVAL; int r = -EINVAL;
assert(cd);
assert(r_kc);
if (ARG_SET(OPT_KEY_DESCRIPTION_ID)) if (ARG_SET(OPT_KEY_DESCRIPTION_ID))
r = crypt_keyslot_context_init_by_keyring(cd, ARG_STR(OPT_KEY_DESCRIPTION_ID), kc); r = crypt_keyslot_context_init_by_keyring(cd, ARG_STR(OPT_KEY_DESCRIPTION_ID), r_kc);
else if (ARG_SET(OPT_KEY_FILE_ID) && !tools_is_stdin(ARG_STR(OPT_KEY_FILE_ID)) && !reencrypt) else if (ARG_SET(OPT_KEY_FILE_ID) && !tools_is_stdin(ARG_STR(OPT_KEY_FILE_ID)))
r = crypt_keyslot_context_init_by_keyfile(cd, ARG_STR(OPT_KEY_FILE_ID), r = crypt_keyslot_context_init_by_keyfile(cd, ARG_STR(OPT_KEY_FILE_ID),
ARG_UINT32(OPT_KEYFILE_SIZE_ID), ARG_UINT32(OPT_KEYFILE_SIZE_ID),
ARG_UINT64(OPT_KEYFILE_OFFSET_ID), kc); ARG_UINT64(OPT_KEYFILE_OFFSET_ID), r_kc);
else if (password) { else {
r = tools_get_key(msg, password, passwordLen, ARG_UINT64(OPT_KEYFILE_OFFSET_ID), r = tools_get_key(msg, &password, &passwordLen, ARG_UINT64(OPT_KEYFILE_OFFSET_ID),
ARG_UINT32(OPT_KEYFILE_SIZE_ID), ARG_STR(OPT_KEY_FILE_ID), ARG_UINT32(OPT_KEYFILE_SIZE_ID), ARG_STR(OPT_KEY_FILE_ID),
ARG_UINT32(OPT_TIMEOUT_ID), verify, pwquality, cd); ARG_UINT32(OPT_TIMEOUT_ID), verify, pwquality, cd);
if (r < 0) if (r < 0)
return r; return r;
r = crypt_keyslot_context_init_by_passphrase(cd, *password, *passwordLen, kc); r = crypt_keyslot_context_init_by_passphrase(cd, password, passwordLen, r_kc);
crypt_safe_free(password);
} }
return r; return r;

View File

@@ -30,7 +30,7 @@ int set_tries_tty(bool keyring);
int get_adjusted_key_size(const char *cipher_mode, uint32_t keysize_bits, int get_adjusted_key_size(const char *cipher_mode, uint32_t keysize_bits,
uint32_t default_size_bits, int integrity_keysize); uint32_t default_size_bits, int integrity_keysize);
int luksFormat(struct crypt_device **r_cd, char **r_password, size_t *r_passwordLen); int luksFormat(struct crypt_device **r_cd, struct crypt_keyslot_context **r_kc);
int reencrypt(int action_argc, const char **action_argv); int reencrypt(int action_argc, const char **action_argv);
@@ -40,8 +40,7 @@ int reencrypt_luks1_in_progress(const char *device);
int luks_init_keyslot_context(struct crypt_device *cd, int luks_init_keyslot_context(struct crypt_device *cd,
const char *msg, const char *msg,
char **password, size_t *passwordLen, bool verify, bool verify, bool pwquality,
bool pwquality, bool reencrypt, /* tmp hack to use old get_key */ struct crypt_keyslot_context **r_kc);
struct crypt_keyslot_context **kc);
#endif /* UTILS_LUKS_H */ #endif /* UTILS_LUKS_H */

View File

@@ -493,8 +493,7 @@ static int encrypt_luks2_init(struct crypt_device **cd, const char *data_device,
{ {
int keyslot, r, fd; int keyslot, r, fd;
uuid_t uuid; uuid_t uuid;
size_t passwordLen; char *tmp, uuid_str[37], header_file[PATH_MAX] = { 0 };
char *tmp, uuid_str[37], header_file[PATH_MAX] = { 0 }, *password = NULL;
uint32_t activate_flags = 0; uint32_t activate_flags = 0;
const struct crypt_params_luks2 luks2_params = { const struct crypt_params_luks2 luks2_params = {
.sector_size = ARG_UINT32(OPT_SECTOR_SIZE_ID) ?: SECTOR_SIZE .sector_size = ARG_UINT32(OPT_SECTOR_SIZE_ID) ?: SECTOR_SIZE
@@ -509,6 +508,7 @@ static int encrypt_luks2_init(struct crypt_device **cd, const char *data_device,
.luks2 = &luks2_params, .luks2 = &luks2_params,
.flags = CRYPT_REENCRYPT_INITIALIZE_ONLY .flags = CRYPT_REENCRYPT_INITIALIZE_ONLY
}; };
struct crypt_keyslot_context *kc = NULL;
_set_reencryption_flags(&params.flags); _set_reencryption_flags(&params.flags);
@@ -603,7 +603,7 @@ static int encrypt_luks2_init(struct crypt_device **cd, const char *data_device,
} }
} }
r = luksFormat(cd, &password, &passwordLen); r = luksFormat(cd, &kc);
if (r < 0) if (r < 0)
goto out; goto out;
@@ -617,9 +617,11 @@ static int encrypt_luks2_init(struct crypt_device **cd, const char *data_device,
params.resilience = "datashift"; params.resilience = "datashift";
} }
keyslot = !ARG_SET(OPT_KEY_SLOT_ID) ? 0 : ARG_INT32(OPT_KEY_SLOT_ID); keyslot = !ARG_SET(OPT_KEY_SLOT_ID) ? 0 : ARG_INT32(OPT_KEY_SLOT_ID);
r = crypt_reencrypt_init_by_passphrase(*cd, NULL, password, passwordLen, r = crypt_reencrypt_init_by_keyslot_context(*cd, NULL, NULL, kc,
CRYPT_ANY_SLOT, keyslot, crypt_get_cipher(*cd), CRYPT_ANY_SLOT, keyslot,
crypt_get_cipher_mode(*cd), &params); crypt_get_cipher(*cd),
crypt_get_cipher_mode(*cd),
&params);
if (r < 0) { if (r < 0) {
crypt_keyslot_destroy(*cd, keyslot); crypt_keyslot_destroy(*cd, keyslot);
goto out; goto out;
@@ -643,7 +645,10 @@ static int encrypt_luks2_init(struct crypt_device **cd, const char *data_device,
/* activate device */ /* activate device */
if (device_name) { if (device_name) {
set_activation_flags(&activate_flags); set_activation_flags(&activate_flags);
r = crypt_activate_by_passphrase(*cd, device_name, ARG_INT32(OPT_KEY_SLOT_ID), password, passwordLen, activate_flags); r = crypt_activate_by_keyslot_context(*cd, device_name,
ARG_INT32(OPT_KEY_SLOT_ID), kc,
CRYPT_ANY_SLOT, NULL,
activate_flags);
if (r >= 0) if (r >= 0)
log_std(_("%s/%s is now active and ready for online encryption.\n"), crypt_get_dir(), device_name); log_std(_("%s/%s is now active and ready for online encryption.\n"), crypt_get_dir(), device_name);
} }
@@ -654,11 +659,12 @@ static int encrypt_luks2_init(struct crypt_device **cd, const char *data_device,
/* just load reencryption context to continue reencryption */ /* just load reencryption context to continue reencryption */
if (!ARG_SET(OPT_INIT_ONLY_ID)) { if (!ARG_SET(OPT_INIT_ONLY_ID)) {
params.flags &= ~CRYPT_REENCRYPT_INITIALIZE_ONLY; params.flags &= ~CRYPT_REENCRYPT_INITIALIZE_ONLY;
r = crypt_reencrypt_init_by_passphrase(*cd, device_name, password, passwordLen, r = crypt_reencrypt_init_by_keyslot_context(*cd, device_name, NULL, kc,
CRYPT_ANY_SLOT, keyslot, NULL, NULL, &params); CRYPT_ANY_SLOT, keyslot,
NULL, NULL, &params);
} }
out: out:
crypt_safe_free(password); crypt_keyslot_context_free(kc);
if (*header_file) if (*header_file)
unlink(header_file); unlink(header_file);
return r; return r;