mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-19 14:50:09 +01:00
On reencryption transfer tokens to new LUKS2 header.
This commit is contained in:
committed by
Milan Broz
parent
8295bde95a
commit
e410ba9623
@@ -65,6 +65,7 @@ static uint64_t opt_device_size = 0;
|
|||||||
static const char **action_argv;
|
static const char **action_argv;
|
||||||
|
|
||||||
#define MAX_SLOT 32
|
#define MAX_SLOT 32
|
||||||
|
#define MAX_TOKEN 32
|
||||||
struct reenc_ctx {
|
struct reenc_ctx {
|
||||||
char *device;
|
char *device;
|
||||||
char *device_uuid;
|
char *device_uuid;
|
||||||
@@ -81,6 +82,7 @@ struct reenc_ctx {
|
|||||||
enum { REENCRYPT = 0, ENCRYPT = 1, DECRYPT = 2 } reencrypt_mode;
|
enum { REENCRYPT = 0, ENCRYPT = 1, DECRYPT = 2 } reencrypt_mode;
|
||||||
|
|
||||||
char header_file_org[PATH_MAX];
|
char header_file_org[PATH_MAX];
|
||||||
|
char header_file_tmp[PATH_MAX];
|
||||||
char header_file_new[PATH_MAX];
|
char header_file_new[PATH_MAX];
|
||||||
char log_file[PATH_MAX];
|
char log_file[PATH_MAX];
|
||||||
|
|
||||||
@@ -570,11 +572,78 @@ static int isLUKS2(const char *type)
|
|||||||
return (type && !strcmp(type, CRYPT_LUKS2));
|
return (type && !strcmp(type, CRYPT_LUKS2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int luks2_transfer_tokens(struct reenc_ctx *rc)
|
||||||
|
{
|
||||||
|
const char *json, *type;
|
||||||
|
crypt_token_info ti;
|
||||||
|
int i, r = -EINVAL;
|
||||||
|
struct crypt_device *cd_old = NULL, *cd_new = NULL;
|
||||||
|
|
||||||
|
if (crypt_init(&cd_old, rc->header_file_tmp) ||
|
||||||
|
crypt_load(cd_old, CRYPT_LUKS2, NULL))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (crypt_init(&cd_new, rc->header_file_new) ||
|
||||||
|
crypt_load(cd_new, CRYPT_LUKS2, NULL))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* we have to erase keyslots missing in new header so that we can
|
||||||
|
* transfer tokens from old header to new one
|
||||||
|
*/
|
||||||
|
for (i = 0; i < crypt_keyslot_max(CRYPT_LUKS2); i++)
|
||||||
|
if (!rc->p[i].password && crypt_keyslot_status(cd_old, i) == CRYPT_SLOT_ACTIVE) {
|
||||||
|
r = crypt_keyslot_destroy(cd_old, i);
|
||||||
|
if (r < 0)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_TOKEN; i++) {
|
||||||
|
ti = crypt_token_status(cd_old, i, &type);
|
||||||
|
switch (ti) {
|
||||||
|
case CRYPT_TOKEN_INVALID:
|
||||||
|
log_dbg("Internal error.");
|
||||||
|
r = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
case CRYPT_TOKEN_INACTIVE:
|
||||||
|
break;
|
||||||
|
case CRYPT_TOKEN_INTERNAL_UNKNOWN:
|
||||||
|
log_err(_("This version of cryptsetup-reencrypt can't handle new internal token type %s.\n"), type);
|
||||||
|
r = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
case CRYPT_TOKEN_INTERNAL:
|
||||||
|
/* fallthrough */
|
||||||
|
case CRYPT_TOKEN_EXTERNAL:
|
||||||
|
/* fallthrough */
|
||||||
|
case CRYPT_TOKEN_EXTERNAL_UNKNOWN:
|
||||||
|
if (crypt_token_json_get(cd_old, i, &json) != i) {
|
||||||
|
log_dbg("Failed to get %s token (%d).", type, i);
|
||||||
|
r = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (crypt_token_json_set(cd_new, i, json) != i) {
|
||||||
|
log_dbg("Failed to create %s token (%d).", type, i);
|
||||||
|
r = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
r = 0;
|
||||||
|
out:
|
||||||
|
crypt_free(cd_old);
|
||||||
|
crypt_free(cd_new);
|
||||||
|
unlink(rc->header_file_tmp);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
static int backup_luks_headers(struct reenc_ctx *rc)
|
static int backup_luks_headers(struct reenc_ctx *rc)
|
||||||
{
|
{
|
||||||
struct crypt_device *cd = NULL;
|
struct crypt_device *cd = NULL;
|
||||||
struct crypt_params_luks1 params = {0};
|
struct crypt_params_luks1 params = {0};
|
||||||
struct crypt_params_luks2 params2 = {0};
|
struct crypt_params_luks2 params2 = {0};
|
||||||
|
struct stat st;
|
||||||
char cipher [MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN];
|
char cipher [MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN];
|
||||||
char *old_key = NULL;
|
char *old_key = NULL;
|
||||||
size_t old_key_size;
|
size_t old_key_size;
|
||||||
@@ -588,6 +657,14 @@ static int backup_luks_headers(struct reenc_ctx *rc)
|
|||||||
|
|
||||||
if ((r = crypt_header_backup(cd, CRYPT_LUKS, rc->header_file_org)))
|
if ((r = crypt_header_backup(cd, CRYPT_LUKS, rc->header_file_org)))
|
||||||
goto out;
|
goto out;
|
||||||
|
if (isLUKS2(rc->type)) {
|
||||||
|
if ((r = crypt_header_backup(cd, CRYPT_LUKS2, rc->header_file_tmp)))
|
||||||
|
goto out;
|
||||||
|
if ((r = stat(rc->header_file_tmp, &st)))
|
||||||
|
goto out;
|
||||||
|
if ((r = chmod(rc->header_file_tmp, st.st_mode | S_IWUSR)))
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
log_verbose(_("%s header backup of device %s created.\n"), rc->device, isLUKS2(rc->type) ? "LUKS2" : "LUKS1");
|
log_verbose(_("%s header backup of device %s created.\n"), rc->device, isLUKS2(rc->type) ? "LUKS2" : "LUKS1");
|
||||||
|
|
||||||
/* For decrypt, new header will be fake one, so we are done here. */
|
/* For decrypt, new header will be fake one, so we are done here. */
|
||||||
@@ -635,6 +712,10 @@ static int backup_luks_headers(struct reenc_ctx *rc)
|
|||||||
opt_key_size ? opt_key_size / 8 : crypt_get_volume_key_size(cd),
|
opt_key_size ? opt_key_size / 8 : crypt_get_volume_key_size(cd),
|
||||||
rc->type,
|
rc->type,
|
||||||
isLUKS2(rc->type) ? (void*)¶ms2 : (void*)¶ms);
|
isLUKS2(rc->type) ? (void*)¶ms2 : (void*)¶ms);
|
||||||
|
|
||||||
|
if (!r && isLUKS2(rc->type))
|
||||||
|
r = luks2_transfer_tokens(rc);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
crypt_free(cd);
|
crypt_free(cd);
|
||||||
crypt_safe_free(old_key);
|
crypt_safe_free(old_key);
|
||||||
@@ -1239,6 +1320,9 @@ static int initialize_context(struct reenc_ctx *rc, const char *device)
|
|||||||
if (snprintf(rc->header_file_new, PATH_MAX,
|
if (snprintf(rc->header_file_new, PATH_MAX,
|
||||||
"LUKS-%s.new", rc->device_uuid) < 0)
|
"LUKS-%s.new", rc->device_uuid) < 0)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
if (snprintf(rc->header_file_tmp, PATH_MAX,
|
||||||
|
"LUKS-%s.tmp", rc->device_uuid) < 0)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
/* Paths to encrypted devices */
|
/* Paths to encrypted devices */
|
||||||
if (snprintf(rc->crypt_path_org, PATH_MAX,
|
if (snprintf(rc->crypt_path_org, PATH_MAX,
|
||||||
@@ -1293,6 +1377,7 @@ static void destroy_context(struct reenc_ctx *rc)
|
|||||||
unlink(rc->log_file);
|
unlink(rc->log_file);
|
||||||
unlink(rc->header_file_org);
|
unlink(rc->header_file_org);
|
||||||
unlink(rc->header_file_new);
|
unlink(rc->header_file_new);
|
||||||
|
unlink(rc->header_file_tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < MAX_SLOT; i++)
|
for (i = 0; i < MAX_SLOT; i++)
|
||||||
|
|||||||
Reference in New Issue
Block a user