Commit 9e7f9f34 authored by Ondrej Kozina's avatar Ondrej Kozina Committed by Milan Broz

Parse compat values from LUKS2 default segment encryption.

We used to preset compat cipher and cipher_mode values during
crypt_format() or crypt_load(). Since we can change 'default segment'
dynamically during reencryption (encryption, decryption included) we
need to parse those values from default segment json encryption field
each time crypt_get_cipher() or crypt_get_cipher_mode() is called.
parent 493e8580
......@@ -63,8 +63,8 @@ struct crypt_device {
} luks1;
struct { /* used in CRYPT_LUKS2 */
struct luks2_hdr hdr;
char *cipher; /* only for compatibility, segment 0 */
char *cipher_mode; /* only for compatibility, segment 0 */
char cipher[MAX_CIPHER_LEN]; /* only for compatibility */
char cipher_mode[MAX_CIPHER_LEN]; /* only for compatibility */
} luks2;
struct { /* used in CRYPT_PLAIN */
struct crypt_params_plain hdr;
......@@ -649,8 +649,7 @@ struct crypt_pbkdf_type *crypt_get_pbkdf(struct crypt_device *cd)
static int _crypt_load_luks2(struct crypt_device *cd, int reload, int repair)
{
int r;
char tmp_cipher[MAX_CIPHER_LEN], tmp_cipher_mode[MAX_CIPHER_LEN],
*cipher = NULL, *cipher_mode = NULL, *type = NULL;
char *type = NULL;
struct luks2_hdr hdr2 = {};
log_dbg("%soading LUKS2 header (repair %sabled).", reload ? "Rel" : "L", repair ? "en" : "dis");
......@@ -664,43 +663,22 @@ static int _crypt_load_luks2(struct crypt_device *cd, int reload, int repair)
goto out;
}
r = crypt_parse_name_and_mode(LUKS2_get_cipher(&hdr2, CRYPT_DEFAULT_SEGMENT),
tmp_cipher, NULL, tmp_cipher_mode);
if (r < 0) {
log_dbg("Cannot parse cipher and mode from loaded device.");
goto out;
}
cipher = strdup(tmp_cipher);
cipher_mode = strdup(tmp_cipher_mode);
if (!cipher || !cipher_mode) {
r = -ENOMEM;
goto out;
}
if (verify_pbkdf_params(cd, &cd->pbkdf)) {
r = init_pbkdf_type(cd, NULL, CRYPT_LUKS2);
if (r)
goto out;
}
if (reload) {
if (reload)
LUKS2_hdr_free(&cd->u.luks2.hdr);
free(cd->u.luks2.cipher);
free(cd->u.luks2.cipher_mode);
} else
else
cd->type = type;
r = 0;
memcpy(&cd->u.luks2.hdr, &hdr2, sizeof(hdr2));
/* Save cipher and mode, compatibility only. */
cd->u.luks2.cipher = cipher;
cd->u.luks2.cipher_mode = cipher_mode;
out:
if (r) {
free(cipher);
free(cipher_mode);
free(type);
LUKS2_hdr_free(&hdr2);
}
......@@ -1019,8 +997,6 @@ static void crypt_free_type(struct crypt_device *cd)
free(cd->u.plain.cipher_mode);
} else if (isLUKS2(cd->type)) {
LUKS2_hdr_free(&cd->u.luks2.hdr);
free(cd->u.luks2.cipher);
free(cd->u.luks2.cipher_mode);
} else if (isLOOPAES(cd->type)) {
free(CONST_CAST(void*)cd->u.loopaes.hdr.hash);
free(cd->u.loopaes.cipher);
......@@ -1574,17 +1550,10 @@ static int _crypt_format_luks2(struct crypt_device *cd,
&required_alignment,
&alignment_offset, DEFAULT_DISK_ALIGNMENT);
/* Save cipher and mode, compatibility only. */
cd->u.luks2.cipher = strdup(cipher);
cd->u.luks2.cipher_mode = strdup(cipher_mode);
if (!cd->u.luks2.cipher || !cd->u.luks2.cipher_mode) {
r = -ENOMEM;
goto out;
}
/* FIXME: we have no way how to check AEAD ciphers,
* only length preserving mode or authenc() composed modes */
if ((!integrity || integrity_key_size) && !LUKS2_keyslot_cipher_incompatible(cd)) {
if ((!integrity || integrity_key_size) && !crypt_cipher_wrapped_key(cipher) &&
!INTEGRITY_tag_size(cd, NULL, cipher, cipher_mode)) {
r = LUKS_check_cipher(cd, volume_key_size - integrity_key_size,
cipher, cipher_mode);
if (r < 0)
......@@ -1659,13 +1628,8 @@ static int _crypt_format_luks2(struct crypt_device *cd,
}
out:
if (r) {
if (r)
LUKS2_hdr_free(&cd->u.luks2.hdr);
free(cd->u.luks2.cipher);
free(cd->u.luks2.cipher_mode);
cd->u.luks2.cipher = NULL;
cd->u.luks2.cipher_mode = NULL;
}
return r;
}
......@@ -3647,8 +3611,12 @@ const char *crypt_get_cipher(struct crypt_device *cd)
if (isLUKS1(cd->type))
return cd->u.luks1.hdr.cipherName;
if (isLUKS2(cd->type))
if (isLUKS2(cd->type)) {
if (crypt_parse_name_and_mode(LUKS2_get_cipher(&cd->u.luks2.hdr, CRYPT_DEFAULT_SEGMENT),
cd->u.luks2.cipher, NULL, cd->u.luks2.cipher_mode))
return NULL;
return cd->u.luks2.cipher;
}
if (isLOOPAES(cd->type))
return cd->u.loopaes.cipher;
......@@ -3673,8 +3641,12 @@ const char *crypt_get_cipher_mode(struct crypt_device *cd)
if (isLUKS1(cd->type))
return cd->u.luks1.hdr.cipherMode;
if (isLUKS2(cd->type))
if (isLUKS2(cd->type)) {
if (crypt_parse_name_and_mode(LUKS2_get_cipher(&cd->u.luks2.hdr, CRYPT_DEFAULT_SEGMENT),
cd->u.luks2.cipher, NULL, cd->u.luks2.cipher_mode))
return NULL;
return cd->u.luks2.cipher_mode;
}
if (isLOOPAES(cd->type))
return cd->u.loopaes.cipher_mode;
......
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