You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
lokinet/llarp/crypto_async.c

152 lines
5.2 KiB
C

7 years ago
#include <llarp/crypto_async.h>
#include <llarp/mem.h>
#include <string.h>
7 years ago
struct llarp_async_dh {
7 years ago
llarp_dh_func client;
llarp_dh_func server;
7 years ago
struct llarp_threadpool *tp;
struct llarp_ev_caller *caller;
7 years ago
llarp_seckey_t ourkey;
7 years ago
};
7 years ago
struct llarp_dh_internal {
7 years ago
llarp_pubkey_t theirkey;
7 years ago
uint8_t *ourkey;
7 years ago
llarp_tunnel_nounce_t nounce;
struct llarp_dh_result result;
7 years ago
llarp_dh_func func;
7 years ago
};
7 years ago
static void llarp_crypto_dh_work(void *user) {
struct llarp_dh_internal *impl = (struct llarp_dh_internal *)user;
7 years ago
impl->func(&impl->result.sharedkey, impl->theirkey, impl->nounce,
impl->ourkey);
7 years ago
}
7 years ago
static void llarp_crypto_dh_result(struct llarp_ev_async_call *call) {
struct llarp_dh_internal *impl = (struct llarp_dh_internal *)call->user;
7 years ago
impl->result.hook(&impl->result);
llarp_g_mem.free(impl);
}
7 years ago
static void llarp_async_dh_exec(struct llarp_async_dh *dh, llarp_dh_func func,
7 years ago
llarp_pubkey_t theirkey,
7 years ago
llarp_tunnel_nounce_t nounce,
llarp_dh_complete_hook result, void *user) {
struct llarp_dh_internal *impl =
7 years ago
llarp_g_mem.alloc(sizeof(struct llarp_dh_internal), 32);
7 years ago
struct llarp_thread_job job = {.caller = dh->caller,
.data = impl,
.user = impl,
.work = &llarp_crypto_dh_work};
7 years ago
memcpy(impl->theirkey, theirkey, sizeof(llarp_pubkey_t));
memcpy(impl->nounce, nounce, sizeof(llarp_tunnel_nounce_t));
7 years ago
impl->ourkey = dh->ourkey;
7 years ago
impl->result.user = user;
impl->result.hook = result;
impl->func = func;
llarp_threadpool_queue_job(dh->tp, job);
}
7 years ago
void llarp_async_client_dh(struct llarp_async_dh *dh, llarp_pubkey_t theirkey,
7 years ago
llarp_tunnel_nounce_t nounce,
llarp_dh_complete_hook result, void *user) {
7 years ago
llarp_async_dh_exec(dh, dh->client, theirkey, nounce, result, user);
7 years ago
}
7 years ago
void llarp_async_server_dh(struct llarp_async_dh *dh, llarp_pubkey_t theirkey,
7 years ago
llarp_tunnel_nounce_t nounce,
llarp_dh_complete_hook result, void *user) {
7 years ago
llarp_async_dh_exec(dh, dh->server, theirkey, nounce, result, user);
7 years ago
}
7 years ago
struct llarp_async_dh *llarp_async_dh_new(llarp_seckey_t ourkey,
struct llarp_crypto *crypto,
struct llarp_ev_loop *ev,
struct llarp_threadpool *tp) {
7 years ago
struct llarp_async_dh *dh =
llarp_g_mem.alloc(sizeof(struct llarp_async_dh), 16);
7 years ago
dh->client = crypto->dh_client;
dh->server = crypto->dh_server;
7 years ago
memcpy(dh->ourkey, ourkey, sizeof(llarp_seckey_t));
7 years ago
dh->tp = tp;
dh->caller = llarp_ev_prepare_async(ev, &llarp_crypto_dh_result);
return dh;
}
7 years ago
void llarp_async_dh_free(struct llarp_async_dh **dh) {
if (*dh) {
7 years ago
llarp_ev_caller_stop((*dh)->caller);
llarp_g_mem.free(*dh);
*dh = NULL;
}
}
7 years ago
7 years ago
struct llarp_async_cipher_internal {
uint8_t *key;
7 years ago
llarp_nounce_t nounce;
struct llarp_cipher_result result;
llarp_sym_cipher_func func;
};
7 years ago
struct llarp_async_cipher {
7 years ago
llarp_sharedkey_t key;
struct llarp_threadpool *tp;
struct llarp_ev_caller *caller;
llarp_sym_cipher_func func;
};
7 years ago
static void llarp_crypto_cipher_result(struct llarp_ev_async_call *job) {
struct llarp_async_cipher_internal *impl =
(struct llarp_async_cipher_internal *)job->user;
7 years ago
impl->result.hook(&impl->result);
llarp_g_mem.free(impl);
}
7 years ago
static void llarp_crypto_cipher_work(void *work) {
struct llarp_async_cipher_internal *impl =
(struct llarp_async_cipher_internal *)work;
7 years ago
impl->func(impl->result.buff, impl->key, impl->nounce);
}
7 years ago
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) {
struct llarp_async_cipher_internal *impl =
llarp_g_mem.alloc(sizeof(struct llarp_async_cipher_internal), 16);
7 years ago
impl->key = c->key;
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;
struct llarp_thread_job job = {.caller = c->caller,
.data = impl,
.user = impl,
.work = &llarp_crypto_cipher_work};
llarp_threadpool_queue_job(c->tp, job);
}
7 years ago
struct llarp_async_cipher *llarp_async_cipher_new(llarp_sharedkey_t key,
struct llarp_crypto *crypto,
struct llarp_ev_loop *ev,
struct llarp_threadpool *tp) {
struct llarp_async_cipher *cipher =
llarp_g_mem.alloc(sizeof(struct llarp_async_cipher), 16);
7 years ago
cipher->func = crypto->xchacha20;
cipher->tp = tp;
cipher->caller = llarp_ev_prepare_async(ev, &llarp_crypto_cipher_result);
memcpy(cipher->key, key, sizeof(llarp_sharedkey_t));
return cipher;
}
void llarp_async_cipher_free(struct llarp_async_cipher **c) {
if (*c) {
llarp_ev_caller_stop((*c)->caller);
llarp_g_mem.free(*c);
*c = NULL;
}
}