lokinet/llarp/crypto_async.c

161 lines
5.2 KiB
C
Raw Normal View History

2018-01-31 19:59:26 +00:00
#include <llarp/crypto_async.h>
#include <llarp/mem.h>
#include <string.h>
2018-02-01 13:21:00 +00:00
struct llarp_async_dh {
2018-01-31 19:59:26 +00:00
llarp_dh_func client;
llarp_dh_func server;
2018-04-30 14:57:13 +00:00
struct llarp_threadpool *worker;
struct llarp_threadpool *result;
2018-02-01 22:04:58 +00:00
llarp_seckey_t ourkey;
2018-05-16 18:13:18 +00:00
struct llarp_alloc * mem;
2018-01-31 19:59:26 +00:00
};
2018-02-01 13:21:00 +00:00
struct llarp_dh_internal {
2018-01-31 19:59:26 +00:00
llarp_pubkey_t theirkey;
llarp_tunnel_nounce_t nounce;
struct llarp_dh_result result;
2018-02-01 22:04:58 +00:00
llarp_dh_func func;
2018-04-30 16:14:20 +00:00
struct llarp_async_dh *parent;
2018-01-31 19:59:26 +00:00
};
2018-04-30 14:57:13 +00:00
static void llarp_crypto_dh_result(void *call) {
struct llarp_dh_internal *impl = (struct llarp_dh_internal *)call;
2018-01-31 19:59:26 +00:00
impl->result.hook(&impl->result);
2018-05-16 18:13:18 +00:00
impl->parent->mem->free(impl->parent->mem, impl);
2018-01-31 19:59:26 +00:00
}
2018-04-30 14:57:13 +00:00
static void llarp_crypto_dh_work(void *user) {
struct llarp_dh_internal *impl = (struct llarp_dh_internal *)user;
impl->func(&impl->result.sharedkey, impl->theirkey, impl->nounce,
impl->parent->ourkey);
2018-04-30 16:14:20 +00:00
struct llarp_thread_job job = {.user = impl, .work = &llarp_crypto_dh_result};
2018-04-30 14:57:13 +00:00
llarp_threadpool_queue_job(impl->parent->result, job);
}
2018-02-01 13:21:00 +00:00
static void llarp_async_dh_exec(struct llarp_async_dh *dh, llarp_dh_func func,
2018-02-01 22:04:58 +00:00
llarp_pubkey_t theirkey,
2018-02-01 13:21:00 +00:00
llarp_tunnel_nounce_t nounce,
llarp_dh_complete_hook result, void *user) {
struct llarp_dh_internal *impl =
2018-05-16 18:13:18 +00:00
dh->mem->alloc(dh->mem, sizeof(struct llarp_dh_internal), 32);
2018-04-30 16:14:20 +00:00
struct llarp_thread_job job = {.user = impl, .work = &llarp_crypto_dh_work};
2018-01-31 19:59:26 +00:00
memcpy(impl->theirkey, theirkey, sizeof(llarp_pubkey_t));
memcpy(impl->nounce, nounce, sizeof(llarp_tunnel_nounce_t));
2018-04-30 14:57:13 +00:00
impl->parent = dh;
2018-01-31 19:59:26 +00:00
impl->result.user = user;
impl->result.hook = result;
impl->func = func;
2018-04-30 14:57:13 +00:00
llarp_threadpool_queue_job(dh->worker, job);
2018-01-31 19:59:26 +00:00
}
2018-02-01 22:34:04 +00:00
void llarp_async_client_dh(struct llarp_async_dh *dh, llarp_pubkey_t theirkey,
2018-02-01 13:21:00 +00:00
llarp_tunnel_nounce_t nounce,
llarp_dh_complete_hook result, void *user) {
2018-02-01 22:04:58 +00:00
llarp_async_dh_exec(dh, dh->client, theirkey, nounce, result, user);
2018-01-31 19:59:26 +00:00
}
2018-02-01 22:34:04 +00:00
void llarp_async_server_dh(struct llarp_async_dh *dh, llarp_pubkey_t theirkey,
2018-02-01 13:21:00 +00:00
llarp_tunnel_nounce_t nounce,
llarp_dh_complete_hook result, void *user) {
2018-02-01 22:04:58 +00:00
llarp_async_dh_exec(dh, dh->server, theirkey, nounce, result, user);
2018-01-31 19:59:26 +00:00
}
2018-05-16 18:13:18 +00:00
struct llarp_async_dh *llarp_async_dh_new(
struct llarp_alloc * mem,
llarp_seckey_t ourkey,
struct llarp_crypto *crypto,
struct llarp_threadpool *result,
struct llarp_threadpool *worker) {
2018-02-01 13:21:00 +00:00
struct llarp_async_dh *dh =
2018-05-16 18:13:18 +00:00
mem->alloc(mem, sizeof(struct llarp_async_dh), 16);
dh->mem = mem;
2018-01-31 19:59:26 +00:00
dh->client = crypto->dh_client;
dh->server = crypto->dh_server;
2018-02-01 22:04:58 +00:00
memcpy(dh->ourkey, ourkey, sizeof(llarp_seckey_t));
2018-04-30 14:57:13 +00:00
dh->result = result;
dh->worker = worker;
2018-01-31 19:59:26 +00:00
return dh;
}
2018-02-01 13:21:00 +00:00
void llarp_async_dh_free(struct llarp_async_dh **dh) {
if (*dh) {
2018-05-16 18:13:18 +00:00
struct llarp_alloc * mem = (*dh)->mem;
mem->free(mem, *dh);
2018-01-31 19:59:26 +00:00
*dh = NULL;
}
}
2018-02-01 22:04:58 +00:00
2018-02-01 22:34:04 +00:00
struct llarp_async_cipher_internal {
2018-02-01 22:04:58 +00:00
llarp_nounce_t nounce;
struct llarp_cipher_result result;
2018-04-30 16:14:20 +00:00
struct llarp_async_cipher *parent;
2018-02-01 22:04:58 +00:00
llarp_sym_cipher_func func;
};
2018-02-01 22:34:04 +00:00
struct llarp_async_cipher {
2018-02-01 22:04:58 +00:00
llarp_sharedkey_t key;
2018-04-30 14:57:13 +00:00
struct llarp_threadpool *worker;
struct llarp_threadpool *result;
2018-02-01 22:04:58 +00:00
llarp_sym_cipher_func func;
2018-05-16 18:13:18 +00:00
struct llarp_alloc * mem;
2018-02-01 22:04:58 +00:00
};
2018-04-30 14:57:13 +00:00
static void llarp_crypto_cipher_result(void *user) {
2018-02-01 22:34:04 +00:00
struct llarp_async_cipher_internal *impl =
2018-04-30 14:57:13 +00:00
(struct llarp_async_cipher_internal *)user;
2018-05-16 18:13:18 +00:00
struct llarp_alloc * mem = impl->parent->mem;
2018-02-01 22:04:58 +00:00
impl->result.hook(&impl->result);
2018-05-16 18:13:18 +00:00
mem->free(mem, impl);
2018-02-01 22:04:58 +00:00
}
2018-02-01 22:34:04 +00:00
static void llarp_crypto_cipher_work(void *work) {
struct llarp_async_cipher_internal *impl =
(struct llarp_async_cipher_internal *)work;
2018-04-30 14:57:13 +00:00
impl->func(impl->result.buff, impl->parent->key, impl->nounce);
2018-04-30 16:14:20 +00:00
struct llarp_thread_job job = {.user = impl,
.work = &llarp_crypto_cipher_result};
2018-04-30 14:57:13 +00:00
llarp_threadpool_queue_job(impl->parent->result, job);
2018-02-01 22:04:58 +00:00
}
2018-02-01 22:34:04 +00:00
void llarp_async_cipher_queue_op(struct llarp_async_cipher *c,
llarp_buffer_t *buff, llarp_nounce_t n,
llarp_cipher_complete_hook h, void *user) {
2018-05-16 18:13:18 +00:00
struct llarp_alloc * mem = c->mem;
2018-02-01 22:34:04 +00:00
struct llarp_async_cipher_internal *impl =
2018-05-16 18:13:18 +00:00
mem->alloc(mem, sizeof(struct llarp_async_cipher_internal), 16);
2018-04-30 14:57:13 +00:00
impl->parent = c;
2018-02-01 22:04:58 +00:00
memcpy(impl->nounce, n, sizeof(llarp_nounce_t));
impl->result.user = user;
impl->result.buff.base = buff->base;
impl->result.buff.sz = buff->sz;
impl->result.hook = h;
impl->func = c->func;
2018-04-30 14:57:13 +00:00
struct llarp_thread_job job = {.user = impl,
2018-02-01 22:04:58 +00:00
.work = &llarp_crypto_cipher_work};
2018-04-30 14:57:13 +00:00
llarp_threadpool_queue_job(c->worker, job);
2018-02-01 22:04:58 +00:00
}
2018-04-30 16:14:20 +00:00
struct llarp_async_cipher *llarp_async_cipher_new(
2018-05-16 18:13:18 +00:00
struct llarp_alloc * mem,
llarp_sharedkey_t key, struct llarp_crypto *crypto,
struct llarp_threadpool *result, struct llarp_threadpool *worker) {
2018-02-01 22:34:04 +00:00
struct llarp_async_cipher *cipher =
2018-05-16 18:13:18 +00:00
mem->alloc(mem, sizeof(struct llarp_async_cipher), 16);
cipher->mem = mem;
2018-02-01 22:04:58 +00:00
cipher->func = crypto->xchacha20;
2018-04-30 14:57:13 +00:00
cipher->result = result;
cipher->worker = worker;
2018-02-01 22:04:58 +00:00
memcpy(cipher->key, key, sizeof(llarp_sharedkey_t));
return cipher;
}
void llarp_async_cipher_free(struct llarp_async_cipher **c) {
if (*c) {
2018-05-16 18:13:18 +00:00
struct llarp_alloc * mem = (*c)->mem;
mem->free(mem, *c);
2018-02-01 22:04:58 +00:00
*c = NULL;
}
}