Commit aeea93fa authored by Milan Broz's avatar Milan Broz

Properly fail in luksFormat if cipher format is missing required IV.

For now, crypto API quietly used cipher witout IV if a cipher
algorithm wihtou IV specificaton was used (e.g. aes-xts).

This caused fail later during activation.

This patch allows only two specific backed use without specified IV
(ECB mode and NULL cipher).

Also check cipher string early during parsing of CLI options.
parent be417d66
...@@ -64,12 +64,15 @@ static int crypt_sector_iv_init(struct crypt_sector_iv *ctx, ...@@ -64,12 +64,15 @@ static int crypt_sector_iv_init(struct crypt_sector_iv *ctx,
if (ctx->iv_size < 8) if (ctx->iv_size < 8)
return -ENOENT; return -ENOENT;
if (!iv_name || if (!strcmp(cipher_name, "cipher_null") ||
!strcmp(cipher_name, "cipher_null") ||
!strcmp(mode_name, "ecb")) { !strcmp(mode_name, "ecb")) {
if (iv_name)
return -EINVAL;
ctx->type = IV_NONE; ctx->type = IV_NONE;
ctx->iv_size = 0; ctx->iv_size = 0;
return 0; return 0;
} else if (!iv_name) {
return -EINVAL;
} else if (!strcasecmp(iv_name, "null")) { } else if (!strcasecmp(iv_name, "null")) {
ctx->type = IV_NULL; ctx->type = IV_NULL;
} else if (!strcasecmp(iv_name, "plain64")) { } else if (!strcasecmp(iv_name, "plain64")) {
......
...@@ -179,7 +179,7 @@ static int luks2_keyslot_set_key(struct crypt_device *cd, ...@@ -179,7 +179,7 @@ static int luks2_keyslot_set_key(struct crypt_device *cd,
if (!json_object_object_get_ex(jobj_area, "encryption", &jobj2)) if (!json_object_object_get_ex(jobj_area, "encryption", &jobj2))
return -EINVAL; return -EINVAL;
r = crypt_parse_name_and_mode(json_object_get_string(jobj2), cipher, NULL, cipher_mode); r = crypt_parse_name_and_mode(json_object_get_string(jobj2), cipher, NULL, cipher_mode, 1);
if (r < 0) if (r < 0)
return r; return r;
...@@ -329,7 +329,7 @@ static int luks2_keyslot_get_key(struct crypt_device *cd, ...@@ -329,7 +329,7 @@ static int luks2_keyslot_get_key(struct crypt_device *cd,
if (!json_object_object_get_ex(jobj_area, "encryption", &jobj2)) if (!json_object_object_get_ex(jobj_area, "encryption", &jobj2))
return -EINVAL; return -EINVAL;
r = crypt_parse_name_and_mode(json_object_get_string(jobj2), cipher, NULL, cipher_mode); r = crypt_parse_name_and_mode(json_object_get_string(jobj2), cipher, NULL, cipher_mode, 1);
if (r < 0) if (r < 0)
return r; return r;
......
...@@ -717,7 +717,7 @@ int LUKS2_luks2_to_luks1(struct crypt_device *cd, struct luks2_hdr *hdr2, struct ...@@ -717,7 +717,7 @@ int LUKS2_luks2_to_luks1(struct crypt_device *cd, struct luks2_hdr *hdr2, struct
return -EINVAL; return -EINVAL;
if (!json_object_object_get_ex(jobj_area, "encryption", &jobj1)) if (!json_object_object_get_ex(jobj_area, "encryption", &jobj1))
return -EINVAL; return -EINVAL;
r = crypt_parse_name_and_mode(json_object_get_string(jobj1), cipher, NULL, cipher_mode); r = crypt_parse_name_and_mode(json_object_get_string(jobj1), cipher, NULL, cipher_mode, 1);
if (r < 0) if (r < 0)
return r; return r;
......
...@@ -660,7 +660,7 @@ static int _crypt_load_luks2(struct crypt_device *cd, int reload) ...@@ -660,7 +660,7 @@ static int _crypt_load_luks2(struct crypt_device *cd, int reload)
} }
r = crypt_parse_name_and_mode(LUKS2_get_cipher(&hdr2, CRYPT_DEFAULT_SEGMENT), r = crypt_parse_name_and_mode(LUKS2_get_cipher(&hdr2, CRYPT_DEFAULT_SEGMENT),
tmp_cipher, NULL, tmp_cipher_mode); tmp_cipher, NULL, tmp_cipher_mode, 0);
if (r < 0) { if (r < 0) {
log_dbg("Cannot parse cipher and mode from loaded device."); log_dbg("Cannot parse cipher and mode from loaded device.");
goto out; goto out;
...@@ -971,7 +971,7 @@ static int _init_by_name_crypt_none(struct crypt_device *cd) ...@@ -971,7 +971,7 @@ static int _init_by_name_crypt_none(struct crypt_device *cd)
if (r >= 0) if (r >= 0)
r = crypt_parse_name_and_mode(dmd.u.crypt.cipher, r = crypt_parse_name_and_mode(dmd.u.crypt.cipher,
cd->u.none.cipher, NULL, cd->u.none.cipher, NULL,
cd->u.none.cipher_mode); cd->u.none.cipher_mode, 0);
if (!r) if (!r)
cd->u.none.key_size = dmd.u.crypt.vk->keylength; cd->u.none.key_size = dmd.u.crypt.vk->keylength;
...@@ -1043,7 +1043,7 @@ static int _init_by_name_crypt(struct crypt_device *cd, const char *name) ...@@ -1043,7 +1043,7 @@ static int _init_by_name_crypt(struct crypt_device *cd, const char *name)
goto out; goto out;
r = crypt_parse_name_and_mode(dmd.u.crypt.cipher, cipher, r = crypt_parse_name_and_mode(dmd.u.crypt.cipher, cipher,
&key_nums, cipher_mode); &key_nums, cipher_mode, 0);
if (r < 0) { if (r < 0) {
log_dbg("Cannot parse cipher and mode from active device."); log_dbg("Cannot parse cipher and mode from active device.");
goto out; goto out;
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
#include "utils_crypt.h" #include "utils_crypt.h"
int crypt_parse_name_and_mode(const char *s, char *cipher, int *key_nums, int crypt_parse_name_and_mode(const char *s, char *cipher, int *key_nums,
char *cipher_mode) char *cipher_mode, int require_iv)
{ {
if (!s || !cipher || !cipher_mode) if (!s || !cipher || !cipher_mode)
return -EINVAL; return -EINVAL;
...@@ -37,7 +37,7 @@ int crypt_parse_name_and_mode(const char *s, char *cipher, int *key_nums, ...@@ -37,7 +37,7 @@ int crypt_parse_name_and_mode(const char *s, char *cipher, int *key_nums,
if (sscanf(s, "%" MAX_CIPHER_LEN_STR "[^-]-%" MAX_CIPHER_LEN_STR "s", if (sscanf(s, "%" MAX_CIPHER_LEN_STR "[^-]-%" MAX_CIPHER_LEN_STR "s",
cipher, cipher_mode) == 2) { cipher, cipher_mode) == 2) {
if (!strcmp(cipher_mode, "plain")) if (!strcmp(cipher_mode, "plain"))
strncpy(cipher_mode, "cbc-plain", 10); strcpy(cipher_mode, "cbc-plain");
if (key_nums) { if (key_nums) {
char *tmp = strchr(cipher, ':'); char *tmp = strchr(cipher, ':');
*key_nums = tmp ? atoi(++tmp) : 1; *key_nums = tmp ? atoi(++tmp) : 1;
...@@ -45,20 +45,27 @@ int crypt_parse_name_and_mode(const char *s, char *cipher, int *key_nums, ...@@ -45,20 +45,27 @@ int crypt_parse_name_and_mode(const char *s, char *cipher, int *key_nums,
return -EINVAL; return -EINVAL;
} }
/* Enforce IV */
if (require_iv) {
char *tmp = strchr(cipher_mode, '-');
if (!tmp || tmp[1] == '\0')
return -EINVAL;
}
return 0; return 0;
} }
/* Short version for "empty" cipher */ /* Short version for "empty" cipher */
if (!strcmp(s, "null")) { if (!strcmp(s, "null") || !strcmp(s, "cipher_null")) {
strncpy(cipher, "cipher_null", MAX_CIPHER_LEN); strcpy(cipher, "cipher_null");
strncpy(cipher_mode, "ecb", 9); strcpy(cipher_mode, "ecb");
if (key_nums) if (key_nums)
*key_nums = 0; *key_nums = 0;
return 0; return 0;
} }
if (sscanf(s, "%" MAX_CIPHER_LEN_STR "[^-]", cipher) == 1) { if (sscanf(s, "%" MAX_CIPHER_LEN_STR "[^-]", cipher) == 1) {
strncpy(cipher_mode, "cbc-plain", 10); strcpy(cipher_mode, "cbc-plain");
if (key_nums) if (key_nums)
*key_nums = 1; *key_nums = 1;
return 0; return 0;
......
...@@ -38,7 +38,7 @@ struct safe_allocation { ...@@ -38,7 +38,7 @@ struct safe_allocation {
}; };
int crypt_parse_name_and_mode(const char *s, char *cipher, int crypt_parse_name_and_mode(const char *s, char *cipher,
int *key_nums, char *cipher_mode); int *key_nums, char *cipher_mode, int require_iv);
int crypt_parse_hash_integrity_mode(const char *s, char *integrity); int crypt_parse_hash_integrity_mode(const char *s, char *integrity);
int crypt_parse_integrity_mode(const char *s, char *integrity, int crypt_parse_integrity_mode(const char *s, char *integrity,
int *integrity_key_size); int *integrity_key_size);
......
...@@ -175,9 +175,9 @@ static int action_open_plain(void) ...@@ -175,9 +175,9 @@ static int action_open_plain(void)
int r; int r;
r = crypt_parse_name_and_mode(opt_cipher ?: DEFAULT_CIPHER(PLAIN), r = crypt_parse_name_and_mode(opt_cipher ?: DEFAULT_CIPHER(PLAIN),
cipher, NULL, cipher_mode); cipher, NULL, cipher_mode, 1);
if (r < 0) { if (r < 0) {
log_err(_("No known cipher specification pattern detected.\n")); log_err(_("No known cipher specification pattern (cipher-mode-iv) detected.\n"));
goto out; goto out;
} }
...@@ -744,9 +744,9 @@ static int action_benchmark(void) ...@@ -744,9 +744,9 @@ static int action_benchmark(void)
opt_pbkdf = CRYPT_KDF_PBKDF2; opt_pbkdf = CRYPT_KDF_PBKDF2;
r = action_benchmark_kdf(opt_pbkdf, opt_hash, key_size); r = action_benchmark_kdf(opt_pbkdf, opt_hash, key_size);
} else if (opt_cipher) { } else if (opt_cipher) {
r = crypt_parse_name_and_mode(opt_cipher, cipher, NULL, cipher_mode); r = crypt_parse_name_and_mode(opt_cipher, cipher, NULL, cipher_mode, 0);
if (r < 0) { if (r < 0) {
log_err(_("No known cipher specification pattern detected.\n")); log_err(_("No known cipher specification pattern (cipher-mode-iv) detected.\n"));
return r; return r;
} }
if ((c = strchr(cipher_mode, '-'))) if ((c = strchr(cipher_mode, '-')))
...@@ -993,9 +993,9 @@ static int action_luksFormat(void) ...@@ -993,9 +993,9 @@ static int action_luksFormat(void)
goto out; goto out;
r = crypt_parse_name_and_mode(opt_cipher ?: DEFAULT_CIPHER(LUKS1), r = crypt_parse_name_and_mode(opt_cipher ?: DEFAULT_CIPHER(LUKS1),
cipher, NULL, cipher_mode); cipher, NULL, cipher_mode, 1);
if (r < 0) { if (r < 0) {
log_err(_("No known cipher specification pattern detected.\n")); log_err(_("No known cipher specification pattern (cipher-mode-iv) detected.\n"));
goto out; goto out;
} }
......
...@@ -579,9 +579,9 @@ static int backup_luks_headers(struct reenc_ctx *rc) ...@@ -579,9 +579,9 @@ static int backup_luks_headers(struct reenc_ctx *rc)
params2.sector_size = crypt_get_sector_size(cd); params2.sector_size = crypt_get_sector_size(cd);
if (opt_cipher) { if (opt_cipher) {
r = crypt_parse_name_and_mode(opt_cipher, cipher, NULL, cipher_mode); r = crypt_parse_name_and_mode(opt_cipher, cipher, NULL, cipher_mode, 1);
if (r < 0) { if (r < 0) {
log_err(_("No known cipher specification pattern detected.\n")); log_err(_("No known cipher specification pattern (cipher-mode-iv) detected.\n"));
goto out; goto out;
} }
} }
...@@ -647,9 +647,9 @@ static int backup_fake_header(struct reenc_ctx *rc) ...@@ -647,9 +647,9 @@ static int backup_fake_header(struct reenc_ctx *rc)
opt_key_size = DEFAULT_LUKS1_KEYBITS; opt_key_size = DEFAULT_LUKS1_KEYBITS;
if (opt_cipher) { if (opt_cipher) {
r = crypt_parse_name_and_mode(opt_cipher, cipher, NULL, cipher_mode); r = crypt_parse_name_and_mode(opt_cipher, cipher, NULL, cipher_mode, 1);
if (r < 0) { if (r < 0) {
log_err(_("No known cipher specification pattern detected.\n")); log_err(_("No known cipher specification pattern (cipher-mode-iv) detected.\n"));
goto out; goto out;
} }
} }
......
...@@ -137,7 +137,7 @@ dmcrypt aes-plain aes-cbc-plain ...@@ -137,7 +137,7 @@ dmcrypt aes-plain aes-cbc-plain
# empty cipher # empty cipher
PASSWORD="" PASSWORD=""
dmcrypt null cipher_null-ecb dmcrypt null cipher_null-ecb
dmcrypt cipher_null cipher_null-cbc-plain dmcrypt cipher_null cipher_null-ecb
dmcrypt cipher_null-ecb dmcrypt cipher_null-ecb
PASSWORD=$PASSWORD1 PASSWORD=$PASSWORD1
......
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