mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-05 16:00:05 +01:00
Fix crypt_cipher_check_kernel to work with length-preserving modes too.
The check is currently used only with AEAD, but whould work also with common block ciphers and modes.
This commit is contained in:
committed by
Daniel Zaťovič
parent
5e04a82e53
commit
ce38d82025
@@ -200,8 +200,8 @@ int crypt_cipher_check_kernel(const char *name, const char *mode,
|
||||
const char *integrity, size_t key_length)
|
||||
{
|
||||
struct crypt_cipher_kernel c;
|
||||
char mode_name[64], tmp_salg_name[180], *real_mode = NULL, *cipher_iv = NULL, *key;
|
||||
const char *salg_type;
|
||||
char mode_name[64], tmp_salg_name[180], *cipher_iv = NULL, *key;
|
||||
const char *salg_type, *real_mode;
|
||||
bool aead;
|
||||
int r;
|
||||
struct sockaddr_alg sa = {
|
||||
@@ -209,6 +209,7 @@ int crypt_cipher_check_kernel(const char *name, const char *mode,
|
||||
};
|
||||
|
||||
aead = integrity && strcmp(integrity, "none");
|
||||
real_mode = NULL;
|
||||
|
||||
/* Remove IV if present */
|
||||
if (mode) {
|
||||
@@ -229,14 +230,22 @@ int crypt_cipher_check_kernel(const char *name, const char *mode,
|
||||
memset(tmp_salg_name, 0, sizeof(tmp_salg_name));
|
||||
|
||||
/* FIXME: this is duplicating a part of devmapper backend */
|
||||
if (aead && !strcmp(integrity, "poly1305"))
|
||||
r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "rfc7539(%s,%s)", name, integrity);
|
||||
else if (!real_mode)
|
||||
r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "%s", name);
|
||||
else if (aead && !strcmp(real_mode, "ccm"))
|
||||
r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "rfc4309(%s(%s))", real_mode, name);
|
||||
else
|
||||
r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "%s(%s)", real_mode, name);
|
||||
if (aead) {
|
||||
/* In AEAD, mode parameter can be just IV like "random" */
|
||||
if (!strcmp(integrity, "poly1305"))
|
||||
r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "rfc7539(%s,%s)", name, integrity);
|
||||
else if (!real_mode)
|
||||
r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "%s", name);
|
||||
else if (!strcmp(real_mode, "ccm"))
|
||||
r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "rfc4309(%s(%s))", real_mode, name);
|
||||
else
|
||||
r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "%s(%s)", real_mode, name);
|
||||
} else {
|
||||
if (!mode)
|
||||
r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "%s", name);
|
||||
else
|
||||
r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "%s(%s)", real_mode ?: mode_name, name);
|
||||
}
|
||||
|
||||
if (r < 0 || (size_t)r >= sizeof(tmp_salg_name))
|
||||
return -EINVAL;
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
#endif
|
||||
|
||||
static bool fips_active = false;
|
||||
|
||||
static void printhex(const char *s, const char *buf, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
@@ -1508,6 +1510,57 @@ static int memcmp_test(void)
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_AF_ALG
|
||||
struct capi_test_vector {
|
||||
const char *name;
|
||||
const char *mode;
|
||||
const char *integrity;
|
||||
size_t key_length;
|
||||
bool fips;
|
||||
};
|
||||
|
||||
static struct capi_test_vector capi_test_vectors[] = {
|
||||
{ "aes", "xts", NULL, 64, true },
|
||||
{ "aes", "xts-plain64", NULL, 32, true },
|
||||
{ "aes", "xts-plain64", NULL, 64, true },
|
||||
{ "aes", "xts-plain64", "none", 64, true },
|
||||
{ "aes", "gcm-random", "aead", 16, true },
|
||||
{ "aes", "gcm-random", "aead", 32, true },
|
||||
{ "aes", "ccm-random", "aead", 19, false },
|
||||
{ "aes", "ccm-random", "aead", 35, false },
|
||||
{ "chacha20", "random", "poly1305", 32, false },
|
||||
{ "aegis128", "random", "aead", 16, false },
|
||||
};
|
||||
#endif
|
||||
|
||||
static int kernel_capi_check_test(void)
|
||||
{
|
||||
#ifdef ENABLE_AF_ALG
|
||||
unsigned int i;
|
||||
int r;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(capi_test_vectors); i++) {
|
||||
printf("CAPI %s/%s/%s/%zu ", capi_test_vectors[i].name,
|
||||
capi_test_vectors[i].mode,
|
||||
capi_test_vectors[i].integrity ?: "NULL",
|
||||
capi_test_vectors[i].key_length);
|
||||
|
||||
r = crypt_cipher_check_kernel(capi_test_vectors[i].name,
|
||||
capi_test_vectors[i].mode,
|
||||
capi_test_vectors[i].integrity,
|
||||
capi_test_vectors[i].key_length);
|
||||
if (!r)
|
||||
printf("[OK]\n");
|
||||
else if (r == -ENOENT || r == -ENOTSUP ||
|
||||
(fips_active && !capi_test_vectors[i].fips))
|
||||
printf("[N/A]\n");
|
||||
else
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
#endif
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
static void __attribute__((noreturn)) exit_test(const char *msg, int r)
|
||||
{
|
||||
if (msg)
|
||||
@@ -1527,7 +1580,9 @@ int main(__attribute__ ((unused)) int argc, __attribute__ ((unused))char *argv[]
|
||||
}
|
||||
#endif
|
||||
|
||||
if (crypt_backend_init(fips_mode()))
|
||||
fips_active = fips_mode();
|
||||
|
||||
if (crypt_backend_init(fips_active))
|
||||
exit_test("Crypto backend init error.", EXIT_FAILURE);
|
||||
|
||||
printf("Test vectors using %s crypto backend.\n", crypt_backend_version());
|
||||
@@ -1556,6 +1611,9 @@ int main(__attribute__ ((unused)) int argc, __attribute__ ((unused))char *argv[]
|
||||
if (utf8_16_test())
|
||||
exit_test("UTF8/16 test failed.", EXIT_FAILURE);
|
||||
|
||||
if (kernel_capi_check_test())
|
||||
exit_test("Kernel CAPI test failed.", EXIT_FAILURE);
|
||||
|
||||
if (default_alg_test()) {
|
||||
if (fips_mode())
|
||||
printf("\nDefault compiled-in algorithms test ignored (FIPS mode on).\n");
|
||||
|
||||
Reference in New Issue
Block a user