Move crypt_cipher to per-lib implementation.

For now, it calls kernel fallback only.
This commit is contained in:
Milan Broz
2019-02-24 19:30:27 +01:00
parent a859455aad
commit fc37d81144
7 changed files with 153 additions and 61 deletions

View File

@@ -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); uint32_t iterations, uint32_t memory, uint32_t parallel);
/* Block ciphers: fallback to kernel crypto API */ /* 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); 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 *in, char *out, size_t length,
const char *iv, size_t iv_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 *in, char *out, size_t length,
const char *iv, size_t iv_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 */ #endif /* _CRYPTO_BACKEND_INTERNAL_H */

View File

@@ -40,11 +40,6 @@
#define SOL_ALG 279 #define SOL_ALG 279
#endif #endif
struct crypt_cipher {
int tfmfd;
int opfd;
};
/* /*
* ciphers * ciphers
* *
@@ -52,44 +47,40 @@ struct crypt_cipher {
* ENOTSUP - AF_ALG family not available * ENOTSUP - AF_ALG family not available
* (but cannot check specifically for skcipher API) * (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, const void *key, size_t key_length,
struct sockaddr_alg *sa) struct sockaddr_alg *sa)
{ {
struct crypt_cipher *h; if (!ctx)
return -EINVAL;
h = malloc(sizeof(*h)); ctx->opfd = -1;
if (!h) ctx->tfmfd = socket(AF_ALG, SOCK_SEQPACKET, 0);
return -ENOMEM; if (ctx->tfmfd < 0) {
crypt_cipher_destroy_kernel(ctx);
h->opfd = -1;
h->tfmfd = socket(AF_ALG, SOCK_SEQPACKET, 0);
if (h->tfmfd < 0) {
crypt_cipher_destroy_kernel(h);
return -ENOTSUP; return -ENOTSUP;
} }
if (bind(h->tfmfd, (struct sockaddr *)sa, sizeof(*sa)) < 0) { if (bind(ctx->tfmfd, (struct sockaddr *)sa, sizeof(*sa)) < 0) {
crypt_cipher_destroy_kernel(h); crypt_cipher_destroy_kernel(ctx);
return -ENOENT; return -ENOENT;
} }
if (setsockopt(h->tfmfd, SOL_ALG, ALG_SET_KEY, key, key_length) < 0) { if (setsockopt(ctx->tfmfd, SOL_ALG, ALG_SET_KEY, key, key_length) < 0) {
crypt_cipher_destroy_kernel(h); crypt_cipher_destroy_kernel(ctx);
return -EINVAL; return -EINVAL;
} }
h->opfd = accept(h->tfmfd, NULL, 0); ctx->opfd = accept(ctx->tfmfd, NULL, 0);
if (h->opfd < 0) { if (ctx->opfd < 0) {
crypt_cipher_destroy_kernel(h); crypt_cipher_destroy_kernel(ctx);
return -EINVAL; return -EINVAL;
} }
*ctx = h;
return 0; 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) const char *mode, const void *key, size_t key_length)
{ {
struct sockaddr_alg sa = { 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 */ /* 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 *in, char *out, size_t length,
const char *iv, size_t iv_length, const char *iv, size_t iv_length,
uint32_t direction) uint32_t direction)
@@ -173,7 +164,7 @@ bad:
return r; 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 *in, char *out, size_t length,
const char *iv, size_t iv_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); 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 *in, char *out, size_t length,
const char *iv, size_t iv_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); 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) if (ctx->tfmfd >= 0)
close(ctx->tfmfd); close(ctx->tfmfd);
if (ctx->opfd >= 0) if (ctx->opfd >= 0)
close(ctx->opfd); 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, int crypt_cipher_check_kernel(const char *name, const char *mode,
const char *integrity, size_t key_length) 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; char mode_name[64], tmp_salg_name[180], *real_mode = NULL, *cipher_iv = NULL, *key;
const char *salg_type; const char *salg_type;
bool aead; bool aead;
@@ -252,32 +244,31 @@ int crypt_cipher_check_kernel(const char *name, const char *mode,
*key = 0xef; *key = 0xef;
r = _crypt_cipher_init(&c, key, key_length, &sa); r = _crypt_cipher_init(&c, key, key_length, &sa);
if (c) crypt_cipher_destroy_kernel(&c);
crypt_cipher_destroy_kernel(c);
free(key); free(key);
return r; return r;
} }
#else /* ENABLE_AF_ALG */ #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) const char *mode, const void *key, size_t key_length)
{ {
return -ENOTSUP; return -ENOTSUP;
} }
void crypt_cipher_destroy_kernel(struct crypt_cipher *ctx) void crypt_cipher_destroy_kernel(struct crypt_cipher_kernel *ctx)
{ {
return; 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 *in, char *out, size_t length,
const char *iv, size_t iv_length) const char *iv, size_t iv_length)
{ {
return -EINVAL; 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 *in, char *out, size_t length,
const char *iv, size_t iv_length) const char *iv, size_t iv_length)
{ {

View File

@@ -43,6 +43,10 @@ struct crypt_hmac {
int hash_len; int hash_len;
}; };
struct crypt_cipher {
struct crypt_cipher_kernel ck;
};
/* /*
* Test for wrong Whirlpool variant, * Test for wrong Whirlpool variant,
* Ref: http://lists.gnupg.org/pipermail/gcrypt-devel/2014-January/002889.html * 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, int crypt_cipher_init(struct crypt_cipher **ctx, const char *name,
const char *mode, const void *key, size_t key_length) 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) 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, int crypt_cipher_encrypt(struct crypt_cipher *ctx,
const char *in, char *out, size_t length, const char *in, char *out, size_t length,
const char *iv, size_t iv_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, int crypt_cipher_decrypt(struct crypt_cipher *ctx,
const char *in, char *out, size_t length, const char *in, char *out, size_t length,
const char *iv, size_t iv_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);
} }

View File

@@ -77,6 +77,10 @@ struct crypt_hmac {
int hash_len; 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, static int crypt_kernel_socket_init(struct sockaddr_alg *sa, int *tfmfd, int *opfd,
const void *key, size_t key_length) 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, int crypt_cipher_init(struct crypt_cipher **ctx, const char *name,
const char *mode, const void *key, size_t key_length) 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) 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, int crypt_cipher_encrypt(struct crypt_cipher *ctx,
const char *in, char *out, size_t length, const char *in, char *out, size_t length,
const char *iv, size_t iv_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, int crypt_cipher_decrypt(struct crypt_cipher *ctx,
const char *in, char *out, size_t length, const char *in, char *out, size_t length,
const char *iv, size_t iv_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);
} }

View File

@@ -192,6 +192,10 @@ struct crypt_hmac {
uint8_t *key; uint8_t *key;
}; };
struct crypt_cipher {
struct crypt_cipher_kernel ck;
};
uint32_t crypt_backend_flags(void) uint32_t crypt_backend_flags(void)
{ {
return 0; 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, int crypt_cipher_init(struct crypt_cipher **ctx, const char *name,
const char *mode, const void *key, size_t key_length) 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) 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, int crypt_cipher_encrypt(struct crypt_cipher *ctx,
const char *in, char *out, size_t length, const char *in, char *out, size_t length,
const char *iv, size_t iv_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, int crypt_cipher_decrypt(struct crypt_cipher *ctx,
const char *in, char *out, size_t length, const char *in, char *out, size_t length,
const char *iv, size_t iv_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);
} }

View File

@@ -59,6 +59,10 @@ struct crypt_hmac {
const struct hash_alg *hash; const struct hash_alg *hash;
}; };
struct crypt_cipher {
struct crypt_cipher_kernel ck;
};
static struct hash_alg *_get_alg(const char *name) static struct hash_alg *_get_alg(const char *name)
{ {
int i = 0; 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, int crypt_cipher_init(struct crypt_cipher **ctx, const char *name,
const char *mode, const void *key, size_t key_length) 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) 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, int crypt_cipher_encrypt(struct crypt_cipher *ctx,
const char *in, char *out, size_t length, const char *in, char *out, size_t length,
const char *iv, size_t iv_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, int crypt_cipher_decrypt(struct crypt_cipher *ctx,
const char *in, char *out, size_t length, const char *in, char *out, size_t length,
const char *iv, size_t iv_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);
} }

View File

@@ -49,6 +49,10 @@ struct crypt_hmac {
int hash_len; int hash_len;
}; };
struct crypt_cipher {
struct crypt_cipher_kernel ck;
};
/* /*
* Compatible wrappers for OpenSSL < 1.1.0 and LibreSSL < 2.7.0 * 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, int crypt_cipher_init(struct crypt_cipher **ctx, const char *name,
const char *mode, const void *key, size_t key_length) 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) 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, int crypt_cipher_encrypt(struct crypt_cipher *ctx,
const char *in, char *out, size_t length, const char *in, char *out, size_t length,
const char *iv, size_t iv_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, int crypt_cipher_decrypt(struct crypt_cipher *ctx,
const char *in, char *out, size_t length, const char *in, char *out, size_t length,
const char *iv, size_t iv_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);
} }