Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EVP API for crypto module #283

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 20 additions & 93 deletions crypto/aesni256.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,108 +29,35 @@

#include <openssl/opensslv.h>

#if OPENSSL_VERSION_NUMBER >= 0x10100000L
#include <openssl/modes.h>
void AES_ctr128_encrypt(
const unsigned char *in,
unsigned char *out,
size_t length,
const AES_KEY *key,
unsigned char ivec[AES_BLOCK_SIZE],
unsigned char ecount_buf[AES_BLOCK_SIZE],
unsigned int *num) {
CRYPTO_ctr128_encrypt(in, out, length, key, ivec, ecount_buf, num, (block128_f)AES_encrypt);
}
#endif

void tg_ssl_aes_ctr_crypt (tg_aes_ctx_t *ctx, const unsigned char *in, unsigned char *out, int size, unsigned char iv[16], unsigned long long offset) {
unsigned char iv_copy[16];
memcpy (iv_copy, iv, 16);
unsigned long long *p = (unsigned long long *) (iv_copy + 8);
(*p) += offset >> 4;
union {
unsigned char c[16];
unsigned long long d[2];
} u;
int i = offset & 15, l;
if (i) {
AES_encrypt (iv_copy, u.c, &ctx->u.key);
(*p)++;
l = i + size;
if (l > 16) {
l = 16;
}
size -= l - i;
do {
*out++ = (*in++) ^ u.c[i++];
} while (i < l);
}
const unsigned long long *I = (const unsigned long long *) in;
unsigned long long *O = (unsigned long long *) out;
int n = size >> 4;
while (--n >= 0) {
AES_encrypt (iv_copy, (unsigned char *) u.d, &ctx->u.key);
(*p)++;
*O++ = (*I++) ^ u.d[0];
*O++ = (*I++) ^ u.d[1];
}
l = size & 15;
if (l) {
AES_encrypt (iv_copy, u.c, &ctx->u.key);
in = (const unsigned char *) I;
out = (unsigned char *) O;
i = 0;
do {
*out++ = (*in++) ^ u.c[i++];
} while (i < l);
}
}


static void tg_ssl_aes_cbc_encrypt (tg_aes_ctx_t *ctx, const unsigned char *in, unsigned char *out, int size, unsigned char iv[16]) {
AES_cbc_encrypt (in, out, size, &ctx->u.key, iv, AES_ENCRYPT);
}

static void tg_ssl_aes_cbc_decrypt (tg_aes_ctx_t *ctx, const unsigned char *in, unsigned char *out, int size, unsigned char iv[16]) {
AES_cbc_encrypt (in, out, size, &ctx->u.key, iv, AES_DECRYPT);
}

static void tg_ssl_aes_ige_encrypt (tg_aes_ctx_t *ctx, const unsigned char *in, unsigned char *out, int size, unsigned char iv[32]) {
AES_ige_encrypt (in, out, size, &ctx->u.key, iv, AES_ENCRYPT);
}

static void tg_ssl_aes_ige_decrypt (tg_aes_ctx_t *ctx, const unsigned char *in, unsigned char *out, int size, unsigned char iv[32]) {
AES_ige_encrypt (in, out, size, &ctx->u.key, iv, AES_DECRYPT);
}
void tg_aes_encrypt_init (tg_aes_ctx_t *ctx, unsigned char *key, unsigned char iv[16], const EVP_CIPHER *cipher) {
ctx->evp_ctx = EVP_CIPHER_CTX_new();
assert(ctx->evp_ctx);

void tg_ssl_aes_ctr128_crypt (struct tg_aes_ctx *ctx, const unsigned char *in, unsigned char *out, int size, unsigned char iv[16], unsigned char ecount_buf[16], unsigned int *num) {
AES_ctr128_encrypt (in, out, size, &ctx->u.key, iv, ecount_buf, num);
assert(EVP_EncryptInit(ctx->evp_ctx, cipher, key, iv) == 1);
assert(EVP_CIPHER_CTX_set_padding(ctx->evp_ctx, 0) == 1);
}

static const struct tg_aes_methods ssl_aes_encrypt_methods = {
.cbc_crypt = tg_ssl_aes_cbc_encrypt,
.ige_crypt = tg_ssl_aes_ige_encrypt,
.ctr_crypt = tg_ssl_aes_ctr_crypt,
.ctr128_crypt = tg_ssl_aes_ctr128_crypt
};
void tg_aes_decrypt_init (tg_aes_ctx_t *ctx, unsigned char *key, unsigned char iv[16], const EVP_CIPHER *cipher) {
ctx->evp_ctx = EVP_CIPHER_CTX_new();
assert(ctx->evp_ctx);

void tg_aes_set_encrypt_key (tg_aes_ctx_t *ctx, unsigned char *key, int bits) {
AES_set_encrypt_key (key, bits, &ctx->u.key);
ctx->type = &ssl_aes_encrypt_methods;
assert(EVP_DecryptInit(ctx->evp_ctx, cipher, key, iv) == 1);
assert(EVP_CIPHER_CTX_set_padding(ctx->evp_ctx, 0) == 1);
}

static const struct tg_aes_methods ssl_aes_decrypt_methods = {
.cbc_crypt = tg_ssl_aes_cbc_decrypt,
.ige_crypt = tg_ssl_aes_ige_decrypt,
.ctr_crypt = NULL,
.ctr128_crypt = NULL
};
void tg_aes_crypt(tg_aes_ctx_t *ctx, const void *in, void *out, int size) {
int len;

void tg_aes_set_decrypt_key (tg_aes_ctx_t *ctx, unsigned char *key, int bits) {
AES_set_decrypt_key (key, bits, &ctx->u.key);
ctx->type = &ssl_aes_decrypt_methods;
if (EVP_CIPHER_CTX_encrypting(ctx->evp_ctx)) {
assert(EVP_EncryptUpdate(ctx->evp_ctx, out, &len, in, size) == 1);
assert(EVP_EncryptFinal_ex(ctx->evp_ctx, out + len, &len) == 1);
} else {
assert(EVP_DecryptUpdate(ctx->evp_ctx, out, &len, in, size) == 1);
assert(EVP_DecryptFinal_ex(ctx->evp_ctx, out + len, &len) == 1);
}
}

void tg_aes_ctx_cleanup (tg_aes_ctx_t *ctx) {
EVP_CIPHER_CTX_free(ctx->evp_ctx);
memset (ctx, 0, sizeof (tg_aes_ctx_t));
}
16 changes: 5 additions & 11 deletions crypto/aesni256.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,29 +24,23 @@
#pragma once

#include <openssl/aes.h>
#include <openssl/evp.h>

struct aesni256_ctx {
unsigned char a[256];
};

//TODO: move cbc_crypt, ige_crypt, ctr_crypt to the virtual method table
struct tg_aes_ctx;

struct tg_aes_methods {
void (*cbc_crypt) (struct tg_aes_ctx *ctx, const unsigned char *in, unsigned char *out, int size, unsigned char iv[16]);
void (*ige_crypt) (struct tg_aes_ctx *ctx, const unsigned char *in, unsigned char *out, int size, unsigned char iv[32]);
void (*ctr_crypt) (struct tg_aes_ctx *ctx, const unsigned char *in, unsigned char *out, int size, unsigned char iv[16], unsigned long long offset);
void (*ctr128_crypt) (struct tg_aes_ctx *ctx, const unsigned char *in, unsigned char *out, int size, unsigned char iv[16], unsigned char ecount_buf[16], unsigned int *num);
};

typedef struct tg_aes_ctx {
union {
AES_KEY key;
struct aesni256_ctx ctx;
} u;
const struct tg_aes_methods *type;
EVP_CIPHER_CTX *evp_ctx;
} tg_aes_ctx_t;

void tg_aes_set_encrypt_key (tg_aes_ctx_t *ctx, unsigned char *key, int bits);
void tg_aes_set_decrypt_key (tg_aes_ctx_t *ctx, unsigned char *key, int bits);
void tg_aes_encrypt_init (tg_aes_ctx_t *ctx, unsigned char *key, unsigned char iv[16], const EVP_CIPHER *cipher);
void tg_aes_decrypt_init (tg_aes_ctx_t *ctx, unsigned char *key, unsigned char iv[16], const EVP_CIPHER *cipher);
void tg_aes_crypt (tg_aes_ctx_t *ctx, const void *in, void *out, int size); //bidirectional
void tg_aes_ctx_cleanup (tg_aes_ctx_t *ctx);
21 changes: 12 additions & 9 deletions net/net-crypto-aes.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,10 @@ int aes_crypto_init (connection_job_t c, void *key_data, int key_data_len) {

MODULE_STAT->allocated_aes_crypto ++;

tg_aes_set_decrypt_key (&T->read_aeskey, D->read_key, 256);
tg_aes_decrypt_init (&T->read_aeskey, D->read_key, D->read_iv, EVP_aes_256_cbc());
memcpy (T->read_iv, D->read_iv, 16);
tg_aes_set_encrypt_key (&T->write_aeskey, D->write_key, 256);
tg_aes_encrypt_init (&T->write_aeskey, D->write_key, D->write_iv, EVP_aes_256_cbc());
memcpy (T->write_iv, D->write_iv, 16);
// T->read_pos = T->write_pos = 0;
T->read_num = T->write_num = 0;
CONN_INFO(c)->crypto = T;
return 0;
}
Expand All @@ -103,20 +101,25 @@ int aes_crypto_ctr128_init (connection_job_t c, void *key_data, int key_data_len
struct aes_key_data *D = key_data;
assert (T);

memset(&T->read_aeskey, 0, sizeof(T->read_aeskey));
memset(&T->write_aeskey, 0, sizeof(T->write_aeskey));

MODULE_STAT->allocated_aes_crypto ++;

tg_aes_set_encrypt_key (&T->read_aeskey, D->read_key, 256); // NB: *_encrypt_key here!
tg_aes_encrypt_init (&T->read_aeskey, D->read_key, D->read_iv, EVP_aes_256_ctr()); // NB: *_encrypt_init here!
memcpy (T->read_iv, D->read_iv, 16);
tg_aes_set_encrypt_key (&T->write_aeskey, D->write_key, 256);
tg_aes_encrypt_init (&T->write_aeskey, D->write_key, D->write_iv, EVP_aes_256_ctr());
memcpy (T->write_iv, D->write_iv, 16);
// T->read_pos = T->write_pos = 0;
T->read_num = T->write_num = 0;
CONN_INFO(c)->crypto = T;
return 0;
}

int aes_crypto_free (connection_job_t c) {
if (CONN_INFO(c)->crypto) {
struct aes_crypto *crypto = CONN_INFO(c)->crypto;
if (crypto) {
tg_aes_ctx_cleanup(&crypto->read_aeskey);
tg_aes_ctx_cleanup(&crypto->write_aeskey);

free (CONN_INFO(c)->crypto);
CONN_INFO(c)->crypto = 0;
MODULE_STAT->allocated_aes_crypto --;
Expand Down
3 changes: 0 additions & 3 deletions net/net-crypto-aes.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,8 @@ struct aes_key_data {
/* for c->crypto */
struct aes_crypto {
unsigned char read_iv[16], write_iv[16];
unsigned char read_ebuf[16], write_ebuf[16]; /* for AES-CTR modes */
tg_aes_ctx_t read_aeskey __attribute__ ((aligned (16)));
tg_aes_ctx_t write_aeskey __attribute__ ((aligned (16)));
unsigned int read_num, write_num; /* for AES-CTR modes */
// long long read_pos, write_pos; /* for AES-CTR modes */
};

extern int aes_initialized;
Expand Down
19 changes: 6 additions & 13 deletions net/net-msg.c
Original file line number Diff line number Diff line change
Expand Up @@ -1230,10 +1230,6 @@ struct rwm_encrypt_decrypt_tmp {
int block_size;
struct raw_message *raw;
struct tg_aes_ctx *ctx;
void (*crypt)(struct tg_aes_ctx *, const void *, void *, int, unsigned char *, void *, void *);
unsigned char *iv;
void *extra;
void *extra2;
char buf[16] __attribute__((aligned(16)));
};

Expand Down Expand Up @@ -1261,12 +1257,12 @@ int rwm_process_encrypt_decrypt (struct rwm_encrypt_decrypt_tmp *x, const void *
data += to_fill;
x->bp = 0;
if (x->buf_left >= bsize) {
x->crypt (x->ctx, x->buf, res->last->part->data + res->last_offset, bsize, x->iv, x->extra, x->extra2);
tg_aes_crypt (x->ctx, x->buf, res->last->part->data + res->last_offset, bsize);
res->last->data_end += bsize;
res->last_offset += bsize;
x->buf_left -= bsize;
} else {
x->crypt (x->ctx, x->buf, x->buf, bsize, x->iv, x->extra, x->extra2);
tg_aes_crypt (x->ctx, x->buf, x->buf, bsize);
memcpy (res->last->part->data + res->last_offset, x->buf, x->buf_left);
int t = x->buf_left;
res->last->data_end += t;
Expand Down Expand Up @@ -1316,15 +1312,15 @@ int rwm_process_encrypt_decrypt (struct rwm_encrypt_decrypt_tmp *x, const void *
assert (x->buf_left + res->last_offset <= res->last->part->chunk->buffer_size);
if (len <= x->buf_left) {
assert (!(len & (bsize - 1)));
x->crypt (x->ctx, data, (res->last->part->data + res->last_offset), len, x->iv, x->extra, x->extra2);
tg_aes_crypt (x->ctx, data, (res->last->part->data + res->last_offset), len);
res->last->data_end += len;
res->last_offset += len;
res->total_bytes += len;
x->buf_left -= len;
return 0;
} else {
int t = x->buf_left & -bsize;
x->crypt (x->ctx, data, res->last->part->data + res->last_offset, t, x->iv, x->extra, x->extra2);
tg_aes_crypt (x->ctx, data, res->last->part->data + res->last_offset, t);
res->last->data_end += t;
res->last_offset += t;
res->total_bytes += t;
Expand All @@ -1336,9 +1332,10 @@ int rwm_process_encrypt_decrypt (struct rwm_encrypt_decrypt_tmp *x, const void *
}


int rwm_encrypt_decrypt_to (struct raw_message *raw, struct raw_message *res, int bytes, struct tg_aes_ctx *ctx, void (*crypt)(struct tg_aes_ctx *ctx, const void *src, void *dst, int l, unsigned char *iv, void *extra, void *extra2), unsigned char *iv, int block_size, void *extra, void *extra2) {
int rwm_encrypt_decrypt_to (struct raw_message *raw, struct raw_message *res, int bytes, struct tg_aes_ctx *ctx, int block_size) {
assert (bytes >= 0);
assert (block_size && !(block_size & (block_size - 1)));

if (bytes > raw->total_bytes) {
bytes = raw->total_bytes;
}
Expand All @@ -1365,18 +1362,14 @@ int rwm_encrypt_decrypt_to (struct raw_message *raw, struct raw_message *res, in
}
struct rwm_encrypt_decrypt_tmp t;
t.bp = 0;
t.crypt = crypt;
if (res->last->part->refcnt == 1) {
t.buf_left = res->last->part->chunk->buffer_size - res->last_offset;
} else {
t.buf_left = 0;
}
t.raw = res;
t.ctx = ctx;
t.iv = iv;
t.left = bytes;
t.extra = extra;
t.extra2 = extra2;
t.block_size = block_size;
int r = rwm_process_and_advance (raw, bytes, (void *)rwm_process_encrypt_decrypt, &t);
if (locked) {
Expand Down
2 changes: 1 addition & 1 deletion net/net-msg.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ int rwm_process_and_advance (struct raw_message *raw, int bytes, int (*process_b
int rwm_sha1 (struct raw_message *raw, int bytes, unsigned char output[20]);
// int rwm_encrypt_decrypt (struct raw_message *raw, int bytes, tg_aes_ctx_t *ctx, unsigned char iv[32]);
// int rwm_encrypt_decrypt_cbc (struct raw_message *raw, int bytes, tg_aes_ctx_t *ctx, unsigned char iv[16]);
int rwm_encrypt_decrypt_to (struct raw_message *raw, struct raw_message *res, int bytes, tg_aes_ctx_t *ctx, void (*crypt)(tg_aes_ctx_t *ctx, const void *src, void *dst, int l, unsigned char *iv, void *extra, void *extra2), unsigned char *iv, int block_size, void *extra, void *extra2);
int rwm_encrypt_decrypt_to (struct raw_message *raw, struct raw_message *res, int bytes, tg_aes_ctx_t *ctx, int block_size);

void *rwm_get_block_ptr (struct raw_message *raw);
int rwm_get_block_ptr_bytes (struct raw_message *raw);
Expand Down
8 changes: 4 additions & 4 deletions net/net-tcp-connections.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ int cpu_tcp_aes_crypto_encrypt_output (connection_job_t C) /* {{{ */ {
int l = out->total_bytes;
l &= ~15;
if (l) {
assert (rwm_encrypt_decrypt_to (&c->out, &c->out_p, l, &T->write_aeskey, (void *)T->write_aeskey.type->cbc_crypt, T->write_iv, 16, 0, 0) == l);
assert (rwm_encrypt_decrypt_to (&c->out, &c->out_p, l, &T->write_aeskey, 16) == l);
}

return (-out->total_bytes) & 15;
Expand All @@ -218,7 +218,7 @@ int cpu_tcp_aes_crypto_decrypt_input (connection_job_t C) /* {{{ */ {
int l = in->total_bytes;
l &= ~15;
if (l) {
assert (rwm_encrypt_decrypt_to (&c->in_u, &c->in, l, &T->read_aeskey, (void *)T->read_aeskey.type->cbc_crypt, T->read_iv, 16, 0, 0) == l);
assert (rwm_encrypt_decrypt_to (&c->in_u, &c->in, l, &T->read_aeskey, 16) == l);
}

return (-in->total_bytes) & 15;
Expand All @@ -242,7 +242,7 @@ int cpu_tcp_aes_crypto_ctr128_encrypt_output (connection_job_t C) /* {{{ */ {

int l = out->total_bytes;
if (l) {
assert (rwm_encrypt_decrypt_to (&c->out, &c->out_p, l, &T->write_aeskey, (void *)T->write_aeskey.type->ctr128_crypt, T->write_iv, 1, T->write_ebuf, &T->write_num) == l);
assert (rwm_encrypt_decrypt_to (&c->out, &c->out_p, l, &T->write_aeskey, 1) == l);
}

return 0;
Expand All @@ -258,7 +258,7 @@ int cpu_tcp_aes_crypto_ctr128_decrypt_input (connection_job_t C) /* {{{ */ {

int l = in->total_bytes;
if (l) {
assert (rwm_encrypt_decrypt_to (&c->in_u, &c->in, l, &T->read_aeskey, (void *)T->read_aeskey.type->ctr128_crypt, T->read_iv, 1, T->read_ebuf, &T->read_num) == l);
assert (rwm_encrypt_decrypt_to (&c->in_u, &c->in, l, &T->read_aeskey, 1) == l);
}

return 0;
Expand Down
2 changes: 1 addition & 1 deletion net/net-tcp-rpc-ext-server.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ int tcp_rpcs_compact_parse_execute (connection_job_t C) {
assert (c->crypto);
struct aes_crypto *T = c->crypto;

T->read_aeskey.type->ctr128_crypt (&T->read_aeskey, random_header, random_header, 64, T->read_iv, T->read_ebuf, &T->read_num);
tg_aes_crypt(&T->read_aeskey, random_header, random_header, 64);
unsigned tag = *(unsigned *)(random_header + 56);

if (tag == 0xdddddddd || tag == 0xeeeeeeee || tag == 0xefefefef) {
Expand Down