diff --git a/lib/crypto_backend/crypto_backend.h b/lib/crypto_backend/crypto_backend.h index f9e31403..d3e1960d 100644 --- a/lib/crypto_backend/crypto_backend.h +++ b/lib/crypto_backend/crypto_backend.h @@ -83,7 +83,7 @@ int crypt_pbkdf_perf(const char *kdf, const char *hash, /* CRC32 */ uint32_t crypt_crc32(uint32_t seed, const unsigned char *buf, size_t len); -/* ciphers */ +/* Block ciphers */ int crypt_cipher_ivsize(const char *name, const char *mode); int crypt_cipher_wrapped_key(const char *name, const char *mode); int crypt_cipher_init(struct crypt_cipher **ctx, const char *name, @@ -96,11 +96,11 @@ int crypt_cipher_decrypt(struct crypt_cipher *ctx, const char *in, char *out, size_t length, const char *iv, size_t iv_length); -/* Check availability of a cipher */ -int crypt_cipher_check(const char *name, const char *mode, - const char *integrity, size_t key_length); +/* Check availability of a cipher (in kernel only) */ +int crypt_cipher_check_kernel(const char *name, const char *mode, + const char *integrity, size_t key_length); -/* storage encryption wrappers */ +/* Storage encryption wrappers */ int crypt_storage_init(struct crypt_storage **ctx, uint64_t sector_start, const char *cipher, const char *cipher_mode, const void *key, size_t key_length); diff --git a/lib/crypto_backend/crypto_backend_internal.h b/lib/crypto_backend/crypto_backend_internal.h index 5da780c8..21d09f60 100644 --- a/lib/crypto_backend/crypto_backend_internal.h +++ b/lib/crypto_backend/crypto_backend_internal.h @@ -39,4 +39,15 @@ int argon2(const char *type, const char *password, size_t password_length, char *key, size_t key_length, uint32_t iterations, uint32_t memory, uint32_t parallel); +/* Block ciphers: fallback to kernel crypto API */ +int crypt_cipher_init_kernel(struct crypt_cipher **ctx, const char *name, + const char *mode, const void *key, size_t key_length); +int crypt_cipher_encrypt_kernel(struct crypt_cipher *ctx, + const char *in, char *out, size_t length, + const char *iv, size_t iv_length); +int crypt_cipher_decrypt_kernel(struct crypt_cipher *ctx, + const char *in, char *out, size_t length, + const char *iv, size_t iv_length); +void crypt_cipher_destroy_kernel(struct crypt_cipher *ctx); + #endif /* _CRYPTO_BACKEND_INTERNAL_H */ diff --git a/lib/crypto_backend/crypto_cipher_kernel.c b/lib/crypto_backend/crypto_cipher_kernel.c index 8c293991..8ee78f42 100644 --- a/lib/crypto_backend/crypto_cipher_kernel.c +++ b/lib/crypto_backend/crypto_cipher_kernel.c @@ -27,7 +27,7 @@ #include #include #include -#include "crypto_backend.h" +#include "crypto_backend_internal.h" #ifdef ENABLE_AF_ALG @@ -65,23 +65,23 @@ static int _crypt_cipher_init(struct crypt_cipher **ctx, h->opfd = -1; h->tfmfd = socket(AF_ALG, SOCK_SEQPACKET, 0); if (h->tfmfd < 0) { - crypt_cipher_destroy(h); + crypt_cipher_destroy_kernel(h); return -ENOTSUP; } if (bind(h->tfmfd, (struct sockaddr *)sa, sizeof(*sa)) < 0) { - crypt_cipher_destroy(h); + crypt_cipher_destroy_kernel(h); return -ENOENT; } if (setsockopt(h->tfmfd, SOL_ALG, ALG_SET_KEY, key, key_length) < 0) { - crypt_cipher_destroy(h); + crypt_cipher_destroy_kernel(h); return -EINVAL; } h->opfd = accept(h->tfmfd, NULL, 0); if (h->opfd < 0) { - crypt_cipher_destroy(h); + crypt_cipher_destroy_kernel(h); return -EINVAL; } @@ -89,8 +89,8 @@ static int _crypt_cipher_init(struct crypt_cipher **ctx, return 0; } -int crypt_cipher_init(struct crypt_cipher **ctx, const char *name, - const char *mode, const void *key, size_t key_length) +int crypt_cipher_init_kernel(struct crypt_cipher **ctx, const char *name, + const char *mode, const void *key, size_t key_length) { struct sockaddr_alg sa = { .salg_family = AF_ALG, @@ -106,10 +106,10 @@ int crypt_cipher_init(struct crypt_cipher **ctx, const char *name, } /* The in/out should be aligned to page boundary */ -static int crypt_cipher_crypt(struct crypt_cipher *ctx, - const char *in, char *out, size_t length, - const char *iv, size_t iv_length, - uint32_t direction) +static int _crypt_cipher_crypt(struct crypt_cipher *ctx, + const char *in, char *out, size_t length, + const char *iv, size_t iv_length, + uint32_t direction) { int r = 0; ssize_t len; @@ -173,23 +173,23 @@ bad: return r; } -int crypt_cipher_encrypt(struct crypt_cipher *ctx, - const char *in, char *out, size_t length, - const char *iv, size_t iv_length) +int crypt_cipher_encrypt_kernel(struct crypt_cipher *ctx, + const char *in, char *out, size_t length, + const char *iv, size_t iv_length) { - return crypt_cipher_crypt(ctx, in, out, length, - iv, iv_length, ALG_OP_ENCRYPT); + return _crypt_cipher_crypt(ctx, in, out, length, + iv, iv_length, ALG_OP_ENCRYPT); } -int crypt_cipher_decrypt(struct crypt_cipher *ctx, - const char *in, char *out, size_t length, - const char *iv, size_t iv_length) +int crypt_cipher_decrypt_kernel(struct crypt_cipher *ctx, + const char *in, char *out, size_t length, + const char *iv, size_t iv_length) { - return crypt_cipher_crypt(ctx, in, out, length, - iv, iv_length, ALG_OP_DECRYPT); + return _crypt_cipher_crypt(ctx, in, out, length, + iv, iv_length, ALG_OP_DECRYPT); } -void crypt_cipher_destroy(struct crypt_cipher *ctx) +void crypt_cipher_destroy_kernel(struct crypt_cipher *ctx) { if (ctx->tfmfd >= 0) close(ctx->tfmfd); @@ -199,8 +199,8 @@ void crypt_cipher_destroy(struct crypt_cipher *ctx) free(ctx); } -int crypt_cipher_check(const char *name, const char *mode, - const char *integrity, size_t key_length) +int crypt_cipher_check_kernel(const char *name, const char *mode, + const char *integrity, size_t key_length) { struct crypt_cipher *c = NULL; char mode_name[64], tmp_salg_name[180], *real_mode = NULL, *cipher_iv = NULL, *key; @@ -253,39 +253,40 @@ int crypt_cipher_check(const char *name, const char *mode, r = _crypt_cipher_init(&c, key, key_length, &sa); if (c) - crypt_cipher_destroy(c); + crypt_cipher_destroy_kernel(c); free(key); return r; } #else /* ENABLE_AF_ALG */ -int crypt_cipher_init(struct crypt_cipher **ctx, const char *name, - const char *mode, const void *buffer, size_t length) +int crypt_cipher_init_kernel(struct crypt_cipher **ctx, const char *name, + const char *mode, const void *key, size_t key_length) { return -ENOTSUP; } -void crypt_cipher_destroy(struct crypt_cipher *ctx) +void crypt_cipher_destroy_kernel(struct crypt_cipher *ctx) { return; } -int crypt_cipher_encrypt(struct crypt_cipher *ctx, - const char *in, char *out, size_t length, - const char *iv, size_t iv_length) +int crypt_cipher_encrypt_kernel(struct crypt_cipher *ctx, + const char *in, char *out, size_t length, + const char *iv, size_t iv_length) { return -EINVAL; } -int crypt_cipher_decrypt(struct crypt_cipher *ctx, - const char *in, char *out, size_t length, - const char *iv, size_t iv_length) +int crypt_cipher_decrypt_kernel(struct crypt_cipher *ctx, + const char *in, char *out, size_t length, + const char *iv, size_t iv_length) { return -EINVAL; } -int crypt_cipher_check(const char *name, const char *mode, - const char *integrity, size_t key_length) +int crypt_cipher_check_kernel(const char *name, const char *mode, + const char *integrity, size_t key_length) { + /* Cannot check, expect success. */ return 0; } #endif diff --git a/lib/crypto_backend/crypto_gcrypt.c b/lib/crypto_backend/crypto_gcrypt.c index 613807cd..c802af8e 100644 --- a/lib/crypto_backend/crypto_gcrypt.c +++ b/lib/crypto_backend/crypto_gcrypt.c @@ -366,3 +366,29 @@ int crypt_pbkdf(const char *kdf, const char *hash, key, key_length, iterations, memory, parallel); return -EINVAL; } + +/* Block ciphers */ +int crypt_cipher_init(struct crypt_cipher **ctx, const char *name, + const char *mode, const void *key, size_t key_length) +{ + return crypt_cipher_init_kernel(ctx, name, mode, key, key_length); +} + +void crypt_cipher_destroy(struct crypt_cipher *ctx) +{ + crypt_cipher_destroy_kernel(ctx); +} + +int crypt_cipher_encrypt(struct crypt_cipher *ctx, + const char *in, char *out, size_t length, + const char *iv, size_t iv_length) +{ + return crypt_cipher_encrypt_kernel(ctx, in, out, length, iv, iv_length); +} + +int crypt_cipher_decrypt(struct crypt_cipher *ctx, + const char *in, char *out, size_t length, + const char *iv, size_t iv_length) +{ + return crypt_cipher_decrypt_kernel(ctx, in, out, length, iv, iv_length); +} diff --git a/lib/crypto_backend/crypto_kernel.c b/lib/crypto_backend/crypto_kernel.c index e2f9280a..97106813 100644 --- a/lib/crypto_backend/crypto_kernel.c +++ b/lib/crypto_backend/crypto_kernel.c @@ -342,3 +342,29 @@ int crypt_pbkdf(const char *kdf, const char *hash, return -EINVAL; } + +/* Block ciphers */ +int crypt_cipher_init(struct crypt_cipher **ctx, const char *name, + const char *mode, const void *key, size_t key_length) +{ + return crypt_cipher_init_kernel(ctx, name, mode, key, key_length); +} + +void crypt_cipher_destroy(struct crypt_cipher *ctx) +{ + crypt_cipher_destroy_kernel(ctx); +} + +int crypt_cipher_encrypt(struct crypt_cipher *ctx, + const char *in, char *out, size_t length, + const char *iv, size_t iv_length) +{ + return crypt_cipher_encrypt_kernel(ctx, in, out, length, iv, iv_length); +} + +int crypt_cipher_decrypt(struct crypt_cipher *ctx, + const char *in, char *out, size_t length, + const char *iv, size_t iv_length) +{ + return crypt_cipher_decrypt_kernel(ctx, in, out, length, iv, iv_length); +} diff --git a/lib/crypto_backend/crypto_nettle.c b/lib/crypto_backend/crypto_nettle.c index 4599b56c..1cc12d64 100644 --- a/lib/crypto_backend/crypto_nettle.c +++ b/lib/crypto_backend/crypto_nettle.c @@ -383,3 +383,29 @@ int crypt_pbkdf(const char *kdf, const char *hash, return -EINVAL; } + +/* Block ciphers */ +int crypt_cipher_init(struct crypt_cipher **ctx, const char *name, + const char *mode, const void *key, size_t key_length) +{ + return crypt_cipher_init_kernel(ctx, name, mode, key, key_length); +} + +void crypt_cipher_destroy(struct crypt_cipher *ctx) +{ + crypt_cipher_destroy_kernel(ctx); +} + +int crypt_cipher_encrypt(struct crypt_cipher *ctx, + const char *in, char *out, size_t length, + const char *iv, size_t iv_length) +{ + return crypt_cipher_encrypt_kernel(ctx, in, out, length, iv, iv_length); +} + +int crypt_cipher_decrypt(struct crypt_cipher *ctx, + const char *in, char *out, size_t length, + const char *iv, size_t iv_length) +{ + return crypt_cipher_decrypt_kernel(ctx, in, out, length, iv, iv_length); +} diff --git a/lib/crypto_backend/crypto_nss.c b/lib/crypto_backend/crypto_nss.c index 1676e55a..769a6014 100644 --- a/lib/crypto_backend/crypto_nss.c +++ b/lib/crypto_backend/crypto_nss.c @@ -331,3 +331,29 @@ int crypt_pbkdf(const char *kdf, const char *hash, return -EINVAL; } + +/* Block ciphers */ +int crypt_cipher_init(struct crypt_cipher **ctx, const char *name, + const char *mode, const void *key, size_t key_length) +{ + return crypt_cipher_init_kernel(ctx, name, mode, key, key_length); +} + +void crypt_cipher_destroy(struct crypt_cipher *ctx) +{ + crypt_cipher_destroy_kernel(ctx); +} + +int crypt_cipher_encrypt(struct crypt_cipher *ctx, + const char *in, char *out, size_t length, + const char *iv, size_t iv_length) +{ + return crypt_cipher_encrypt_kernel(ctx, in, out, length, iv, iv_length); +} + +int crypt_cipher_decrypt(struct crypt_cipher *ctx, + const char *in, char *out, size_t length, + const char *iv, size_t iv_length) +{ + return crypt_cipher_decrypt_kernel(ctx, in, out, length, iv, iv_length); +} diff --git a/lib/crypto_backend/crypto_openssl.c b/lib/crypto_backend/crypto_openssl.c index 23fbcae3..d96d3bf9 100644 --- a/lib/crypto_backend/crypto_openssl.c +++ b/lib/crypto_backend/crypto_openssl.c @@ -335,3 +335,29 @@ int crypt_pbkdf(const char *kdf, const char *hash, return -EINVAL; } + +/* Block ciphers */ +int crypt_cipher_init(struct crypt_cipher **ctx, const char *name, + const char *mode, const void *key, size_t key_length) +{ + return crypt_cipher_init_kernel(ctx, name, mode, key, key_length); +} + +void crypt_cipher_destroy(struct crypt_cipher *ctx) +{ + crypt_cipher_destroy_kernel(ctx); +} + +int crypt_cipher_encrypt(struct crypt_cipher *ctx, + const char *in, char *out, size_t length, + const char *iv, size_t iv_length) +{ + return crypt_cipher_encrypt_kernel(ctx, in, out, length, iv, iv_length); +} + +int crypt_cipher_decrypt(struct crypt_cipher *ctx, + const char *in, char *out, size_t length, + const char *iv, size_t iv_length) +{ + return crypt_cipher_decrypt_kernel(ctx, in, out, length, iv, iv_length); +} diff --git a/lib/setup.c b/lib/setup.c index ec9d2669..1c5e9f24 100644 --- a/lib/setup.c +++ b/lib/setup.c @@ -1682,7 +1682,7 @@ static int _crypt_format_luks2(struct crypt_device *cd, /* FIXME: allow this later also for normal ciphers (check AF_ALG availability. */ if (integrity && !integrity_key_size) { - r = crypt_cipher_check(cipher, cipher_mode, integrity, volume_key_size); + r = crypt_cipher_check_kernel(cipher, cipher_mode, integrity, volume_key_size); if (r < 0) { log_err(cd, _("Cipher %s-%s (key size %zd bits) is not available."), cipher, cipher_mode, volume_key_size * 8);