Commit fc37d811 authored by Milan Broz's avatar Milan Broz

Move crypt_cipher to per-lib implementation.

For now, it calls kernel fallback only.
parent a859455a
......@@ -40,14 +40,20 @@ int argon2(const char *type, const char *password, size_t password_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,
struct crypt_cipher_kernel {
int tfmfd;
int opfd;
};
int crypt_cipher_init_kernel(struct crypt_cipher_kernel *ctx, const char *name,
const char *mode, const void *key, size_t key_length);
int crypt_cipher_encrypt_kernel(struct crypt_cipher *ctx,
int crypt_cipher_encrypt_kernel(struct crypt_cipher_kernel *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,
int crypt_cipher_decrypt_kernel(struct crypt_cipher_kernel *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);
void crypt_cipher_destroy_kernel(struct crypt_cipher_kernel *ctx);
#endif /* _CRYPTO_BACKEND_INTERNAL_H */
......@@ -40,11 +40,6 @@
#define SOL_ALG 279
#endif
struct crypt_cipher {
int tfmfd;
int opfd;
};
/*
* ciphers
*
......@@ -52,44 +47,40 @@ struct crypt_cipher {
* ENOTSUP - AF_ALG family not available
* (but cannot check specifically for skcipher API)
*/
static int _crypt_cipher_init(struct crypt_cipher **ctx,
static int _crypt_cipher_init(struct crypt_cipher_kernel *ctx,
const void *key, size_t key_length,
struct sockaddr_alg *sa)
{
struct crypt_cipher *h;
h = malloc(sizeof(*h));
if (!h)
return -ENOMEM;
if (!ctx)
return -EINVAL;
h->opfd = -1;
h->tfmfd = socket(AF_ALG, SOCK_SEQPACKET, 0);
if (h->tfmfd < 0) {
crypt_cipher_destroy_kernel(h);
ctx->opfd = -1;
ctx->tfmfd = socket(AF_ALG, SOCK_SEQPACKET, 0);
if (ctx->tfmfd < 0) {
crypt_cipher_destroy_kernel(ctx);
return -ENOTSUP;
}
if (bind(h->tfmfd, (struct sockaddr *)sa, sizeof(*sa)) < 0) {
crypt_cipher_destroy_kernel(h);
if (bind(ctx->tfmfd, (struct sockaddr *)sa, sizeof(*sa)) < 0) {
crypt_cipher_destroy_kernel(ctx);
return -ENOENT;
}
if (setsockopt(h->tfmfd, SOL_ALG, ALG_SET_KEY, key, key_length) < 0) {
crypt_cipher_destroy_kernel(h);
if (setsockopt(ctx->tfmfd, SOL_ALG, ALG_SET_KEY, key, key_length) < 0) {
crypt_cipher_destroy_kernel(ctx);
return -EINVAL;
}
h->opfd = accept(h->tfmfd, NULL, 0);
if (h->opfd < 0) {
crypt_cipher_destroy_kernel(h);
ctx->opfd = accept(ctx->tfmfd, NULL, 0);
if (ctx->opfd < 0) {
crypt_cipher_destroy_kernel(ctx);
return -EINVAL;
}
*ctx = h;
return 0;
}
int crypt_cipher_init_kernel(struct crypt_cipher **ctx, const char *name,
int crypt_cipher_init_kernel(struct crypt_cipher_kernel *ctx, const char *name,
const char *mode, const void *key, size_t key_length)
{
struct sockaddr_alg sa = {
......@@ -106,7 +97,7 @@ int crypt_cipher_init_kernel(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,
static int _crypt_cipher_crypt(struct crypt_cipher_kernel *ctx,
const char *in, char *out, size_t length,
const char *iv, size_t iv_length,
uint32_t direction)
......@@ -173,7 +164,7 @@ bad:
return r;
}
int crypt_cipher_encrypt_kernel(struct crypt_cipher *ctx,
int crypt_cipher_encrypt_kernel(struct crypt_cipher_kernel *ctx,
const char *in, char *out, size_t length,
const char *iv, size_t iv_length)
{
......@@ -181,7 +172,7 @@ int crypt_cipher_encrypt_kernel(struct crypt_cipher *ctx,
iv, iv_length, ALG_OP_ENCRYPT);
}
int crypt_cipher_decrypt_kernel(struct crypt_cipher *ctx,
int crypt_cipher_decrypt_kernel(struct crypt_cipher_kernel *ctx,
const char *in, char *out, size_t length,
const char *iv, size_t iv_length)
{
......@@ -189,20 +180,21 @@ int crypt_cipher_decrypt_kernel(struct crypt_cipher *ctx,
iv, iv_length, ALG_OP_DECRYPT);
}
void crypt_cipher_destroy_kernel(struct crypt_cipher *ctx)
void crypt_cipher_destroy_kernel(struct crypt_cipher_kernel *ctx)
{
if (ctx->tfmfd >= 0)
close(ctx->tfmfd);
if (ctx->opfd >= 0)
close(ctx->opfd);
memset(ctx, 0, sizeof(*ctx));
free(ctx);
ctx->tfmfd = -1;
ctx->opfd = -1;
}
int crypt_cipher_check_kernel(const char *name, const char *mode,
const char *integrity, size_t key_length)
{
struct crypt_cipher *c = NULL;
struct crypt_cipher_kernel c;
char mode_name[64], tmp_salg_name[180], *real_mode = NULL, *cipher_iv = NULL, *key;
const char *salg_type;
bool aead;
......@@ -252,32 +244,31 @@ int crypt_cipher_check_kernel(const char *name, const char *mode,
*key = 0xef;
r = _crypt_cipher_init(&c, key, key_length, &sa);
if (c)
crypt_cipher_destroy_kernel(c);
crypt_cipher_destroy_kernel(&c);
free(key);
return r;
}
#else /* ENABLE_AF_ALG */
int crypt_cipher_init_kernel(struct crypt_cipher **ctx, const char *name,
int crypt_cipher_init_kernel(struct crypt_cipher_kernel *ctx, const char *name,
const char *mode, const void *key, size_t key_length)
{
return -ENOTSUP;
}
void crypt_cipher_destroy_kernel(struct crypt_cipher *ctx)
void crypt_cipher_destroy_kernel(struct crypt_cipher_kernel *ctx)
{
return;
}
int crypt_cipher_encrypt_kernel(struct crypt_cipher *ctx,
int crypt_cipher_encrypt_kernel(struct crypt_cipher_kernel *ctx,
const char *in, char *out, size_t length,
const char *iv, size_t iv_length)
{
return -EINVAL;
}
int crypt_cipher_decrypt_kernel(struct crypt_cipher *ctx,
int crypt_cipher_decrypt_kernel(struct crypt_cipher_kernel *ctx,
const char *in, char *out, size_t length,
const char *iv, size_t iv_length)
{
......
......@@ -43,6 +43,10 @@ struct crypt_hmac {
int hash_len;
};
struct crypt_cipher {
struct crypt_cipher_kernel ck;
};
/*
* Test for wrong Whirlpool variant,
* Ref: http://lists.gnupg.org/pipermail/gcrypt-devel/2014-January/002889.html
......@@ -371,24 +375,39 @@ int crypt_pbkdf(const char *kdf, const char *hash,
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);
struct crypt_cipher *h;
int r;
h = malloc(sizeof(*h));
if (!h)
return -ENOMEM;
r = crypt_cipher_init_kernel(&h->ck, name, mode, key, key_length);
if (r < 0) {
free(h);
return r;
}
*ctx = h;
return 0;
}
void crypt_cipher_destroy(struct crypt_cipher *ctx)
{
crypt_cipher_destroy_kernel(ctx);
crypt_cipher_destroy_kernel(&ctx->ck);
free(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);
return crypt_cipher_encrypt_kernel(&ctx->ck, 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);
return crypt_cipher_decrypt_kernel(&ctx->ck, in, out, length, iv, iv_length);
}
......@@ -77,6 +77,10 @@ struct crypt_hmac {
int hash_len;
};
struct crypt_cipher {
struct crypt_cipher_kernel ck;
};
static int crypt_kernel_socket_init(struct sockaddr_alg *sa, int *tfmfd, int *opfd,
const void *key, size_t key_length)
{
......@@ -347,24 +351,39 @@ int crypt_pbkdf(const char *kdf, const char *hash,
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);
struct crypt_cipher *h;
int r;
h = malloc(sizeof(*h));
if (!h)
return -ENOMEM;
r = crypt_cipher_init_kernel(&h->ck, name, mode, key, key_length);
if (r < 0) {
free(h);
return r;
}
*ctx = h;
return 0;
}
void crypt_cipher_destroy(struct crypt_cipher *ctx)
{
crypt_cipher_destroy_kernel(ctx);
crypt_cipher_destroy_kernel(&ctx->ck);
free(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);
return crypt_cipher_encrypt_kernel(&ctx->ck, 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);
return crypt_cipher_decrypt_kernel(&ctx->ck, in, out, length, iv, iv_length);
}
......@@ -192,6 +192,10 @@ struct crypt_hmac {
uint8_t *key;
};
struct crypt_cipher {
struct crypt_cipher_kernel ck;
};
uint32_t crypt_backend_flags(void)
{
return 0;
......@@ -388,24 +392,39 @@ int crypt_pbkdf(const char *kdf, const char *hash,
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);
struct crypt_cipher *h;
int r;
h = malloc(sizeof(*h));
if (!h)
return -ENOMEM;
r = crypt_cipher_init_kernel(&h->ck, name, mode, key, key_length);
if (r < 0) {
free(h);
return r;
}
*ctx = h;
return 0;
}
void crypt_cipher_destroy(struct crypt_cipher *ctx)
{
crypt_cipher_destroy_kernel(ctx);
crypt_cipher_destroy_kernel(&ctx->ck);
free(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);
return crypt_cipher_encrypt_kernel(&ctx->ck, 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);
return crypt_cipher_decrypt_kernel(&ctx->ck, in, out, length, iv, iv_length);
}
......@@ -59,6 +59,10 @@ struct crypt_hmac {
const struct hash_alg *hash;
};
struct crypt_cipher {
struct crypt_cipher_kernel ck;
};
static struct hash_alg *_get_alg(const char *name)
{
int i = 0;
......@@ -336,24 +340,39 @@ int crypt_pbkdf(const char *kdf, const char *hash,
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);
struct crypt_cipher *h;
int r;
h = malloc(sizeof(*h));
if (!h)
return -ENOMEM;
r = crypt_cipher_init_kernel(&h->ck, name, mode, key, key_length);
if (r < 0) {
free(h);
return r;
}
*ctx = h;
return 0;
}
void crypt_cipher_destroy(struct crypt_cipher *ctx)
{
crypt_cipher_destroy_kernel(ctx);
crypt_cipher_destroy_kernel(&ctx->ck);
free(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);
return crypt_cipher_encrypt_kernel(&ctx->ck, 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);
return crypt_cipher_decrypt_kernel(&ctx->ck, in, out, length, iv, iv_length);
}
......@@ -49,6 +49,10 @@ struct crypt_hmac {
int hash_len;
};
struct crypt_cipher {
struct crypt_cipher_kernel ck;
};
/*
* Compatible wrappers for OpenSSL < 1.1.0 and LibreSSL < 2.7.0
*/
......@@ -340,24 +344,39 @@ int crypt_pbkdf(const char *kdf, const char *hash,
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);
struct crypt_cipher *h;
int r;
h = malloc(sizeof(*h));
if (!h)
return -ENOMEM;
r = crypt_cipher_init_kernel(&h->ck, name, mode, key, key_length);
if (r < 0) {
free(h);
return r;
}
*ctx = h;
return 0;
}
void crypt_cipher_destroy(struct crypt_cipher *ctx)
{
crypt_cipher_destroy_kernel(ctx);
crypt_cipher_destroy_kernel(&ctx->ck);
free(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);
return crypt_cipher_encrypt_kernel(&ctx->ck, 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);
return crypt_cipher_decrypt_kernel(&ctx->ck, in, out, length, iv, iv_length);
}
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