we don't use crypto_async anymore

pull/19/head
Jeff Becker 6 years ago
parent 8e30af6619
commit 0b0278a312
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05

@ -322,7 +322,6 @@ set(LIB_SRC
llarp/buffer.cpp
llarp/config.cpp
llarp/context.cpp
llarp/crypto_async.cpp
llarp/crypto_libsodium.cpp
llarp/dht.cpp
llarp/dns.cpp

@ -1,229 +0,0 @@
#ifndef LLARP_CRYPTO_ASYNC_H_
#define LLARP_CRYPTO_ASYNC_H_
#include <llarp/crypto.h>
#include <llarp/ev.h>
#include <llarp/logic.h>
#include <llarp/threadpool.h>
#include <llarp/time.h>
/**
* crypto_async.h
*
* asynchronous crypto functions
*/
/// context for doing asynchronous cryptography for iwp
/// with a worker threadpool
/// defined in crypto_async.cpp
struct llarp_async_iwp;
/// allocator
/// use crypto as cryptograph implementation
/// use logic as the callback handler thread
/// use worker as threadpool that does the heavy lifting
struct llarp_async_iwp *
llarp_async_iwp_new(struct llarp_crypto *crypto, struct llarp_logic *logic,
struct llarp_threadpool *worker);
/// deallocator
void
llarp_async_iwp_free(struct llarp_async_iwp *iwp);
struct iwp_async_keygen;
/// define functor for keygen
typedef void (*iwp_keygen_hook)(struct iwp_async_keygen *);
/// key generation request
struct iwp_async_keygen
{
/// internal wire protocol async configuration
struct llarp_async_iwp *iwp;
/// a pointer to pass ourself to thread worker
void *user;
/// destination key buffer
uint8_t *keybuf;
/// result handler callback
iwp_keygen_hook hook;
};
/// generate an encryption keypair asynchronously
void
iwp_call_async_keygen(struct llarp_async_iwp *iwp,
struct iwp_async_keygen *keygen);
struct iwp_async_intro;
/// iwp_async_intro functor
typedef void (*iwp_intro_hook)(struct iwp_async_intro *);
/// iwp_async_intro request
struct iwp_async_intro
{
struct llarp_async_iwp *iwp;
void *user;
uint8_t *buf;
size_t sz;
/// nonce paramter
uint8_t nonce[32];
/// remote public key
uint8_t remote_pubkey[32];
/// local private key
uint8_t secretkey[64];
/// callback
iwp_intro_hook hook;
};
/// asynchronously generate an intro packet
void
iwp_call_async_gen_intro(struct llarp_async_iwp *iwp,
struct iwp_async_intro *intro);
/// asynchronously verify an intro packet
void
iwp_call_async_verify_intro(struct llarp_async_iwp *iwp,
struct iwp_async_intro *info);
struct iwp_async_introack;
/// introduction acknowledgement functor
typedef void (*iwp_introack_hook)(struct iwp_async_introack *);
/// introduction acknowledgement request
struct iwp_async_introack
{
struct llarp_async_iwp *iwp;
void *user;
uint8_t *buf;
size_t sz;
/// nonce paramter
uint8_t *nonce;
/// token paramter
uint8_t *token;
/// remote public key
uint8_t *remote_pubkey;
/// local private key
uint8_t *secretkey;
/// callback
iwp_introack_hook hook;
};
/// generate introduction acknowledgement packet asynchronously
void
iwp_call_async_gen_introack(struct llarp_async_iwp *iwp,
struct iwp_async_introack *introack);
/// verify introduction acknowledgement packet asynchronously
void
iwp_call_async_verify_introack(struct llarp_async_iwp *iwp,
struct iwp_async_introack *introack);
struct iwp_async_session_start;
/// start session functor
typedef void (*iwp_session_start_hook)(struct iwp_async_session_start *);
/// start session request
struct iwp_async_session_start
{
struct llarp_async_iwp *iwp;
void *user;
uint8_t *buf;
size_t sz;
/// nonce parameter
uint8_t *nonce;
/// token parameter
uint8_t *token;
/// memory to write session key to
uint8_t *sessionkey;
/// local secrkey key
uint8_t *secretkey;
/// remote public encryption key
uint8_t *remote_pubkey;
/// result callback handler
iwp_session_start_hook hook;
};
/// generate session start packet asynchronously
void
iwp_call_async_gen_session_start(struct llarp_async_iwp *iwp,
struct iwp_async_session_start *start);
/// verify session start packet asynchronously
void
iwp_call_async_verify_session_start(struct llarp_async_iwp *iwp,
struct iwp_async_session_start *start);
struct iwp_async_frame;
/// internal wire protocol frame request
typedef void (*iwp_async_frame_hook)(struct iwp_async_frame *);
struct iwp_async_frame
{
/// true if decryption succeded
bool success;
/// timestamp for CoDel
llarp_time_t created;
struct llarp_async_iwp *iwp;
/// a pointer to pass ourself
void *user;
/// current session key
byte_t *sessionkey;
/// size of the frame
size_t sz;
/// result handler
iwp_async_frame_hook hook;
/// memory holding the entire frame
byte_t buf[1500];
};
#ifdef __cplusplus
#include <memory>
struct FramePutTime
{
void
operator()(iwp_async_frame &frame) const
{
frame.created = llarp_time_now_ms();
}
};
struct FrameGetTime
{
llarp_time_t
operator()(const iwp_async_frame &frame) const
{
return frame.created;
}
};
struct FrameCompareTime
{
bool
operator()(const iwp_async_frame &left, const iwp_async_frame &right) const
{
return left.created < right.created;
}
};
#endif
/// synchronously decrypt a frame
bool
iwp_decrypt_frame(struct iwp_async_frame *frame);
/// synchronosuly encrypt a frame
bool
iwp_encrypt_frame(struct iwp_async_frame *frame);
/// decrypt iwp frame asynchronously
void
iwp_call_async_frame_decrypt(struct llarp_async_iwp *iwp,
struct iwp_async_frame *frame);
/// encrypt iwp frame asynchronously
void
iwp_call_async_frame_encrypt(struct llarp_async_iwp *iwp,
struct iwp_async_frame *frame);
#endif

@ -1,574 +0,0 @@
#include <llarp/crypto_async.h>
#include <llarp/mem.h>
#include <llarp/router_contact.hpp>
#include <string.h>
#include <llarp/crypto.hpp>
#include <llarp/router_id.hpp>
#include "buffer.hpp"
#include "logger.hpp"
#include "mem.hpp"
struct llarp_async_iwp
{
struct llarp_crypto *crypto;
struct llarp_logic *logic;
struct llarp_threadpool *worker;
};
namespace iwp
{
void
inform_intro(void *user)
{
iwp_async_intro *intro = static_cast< iwp_async_intro * >(user);
intro->hook(intro);
}
void
gen_intro(void *user)
{
iwp_async_intro *intro = static_cast< iwp_async_intro * >(user);
#ifdef neuroCryptoDebug
char ftmp[68] = {0};
const char *hexname = llarp::HexEncode< llarp::PubKey, decltype(ftmp) >(
intro->remote_pubkey, ftmp);
llarp::LogDebug("gen_intro remote_pubkey: ", hexname);
#endif
llarp::SharedSecret sharedkey;
llarp_crypto *crypto = intro->iwp->crypto;
// S = TKE(a.k, b.k, n)
crypto->transport_dh_client(sharedkey, intro->remote_pubkey,
intro->secretkey, intro->nonce);
#ifdef neuroCryptoDebug
char ftmpShared[68] = {0};
const char *hexShared =
llarp::HexEncode< llarp::SharedSecret, decltype(ftmpShared) >(
sharedkey, ftmpShared);
llarp::LogDebug("gen_intro sharedkey ", hexShared);
#endif
byte_t tmp[64];
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
llarp::SymmNonce n;
// copy nonce
memcpy(n, intro->nonce, 32); // was 24 bytes
/*
char ftmpN[68] = {0};
const char *hexN =
llarp::HexEncode< llarp::SymmNonce, decltype(ftmpN) >(n, ftmpN);
llarp::LogDebug("gen_intro nonce ", hexN);
*/
// e_k = HS(b.k + n)
llarp::ShortHash e_k;
memcpy(tmp, intro->remote_pubkey, 32);
memcpy(tmp + 32, intro->nonce, 32);
crypto->shorthash(e_k, buf);
#ifdef neuroCryptoDebug
char ftmpEk[68] = {0};
const char *hexEk =
llarp::HexEncode< llarp::ShortHash, decltype(ftmpEk) >(e_k, ftmpEk);
llarp::LogDebug("gen_intro e_k ", hexEk, " used ", strlen(hexEk));
#endif
// put nonce
memcpy(intro->buf + 32, intro->nonce, 32);
// e = SE(a.k, e_k, n[0:24])
memcpy(intro->buf + 64, llarp::seckey_topublic(intro->secretkey), 32);
#ifdef neuroCryptoDebug
char ftmpSk[68] = {0};
const char *hexSk = llarp::HexEncode< llarp::PubKey, decltype(ftmpSk) >(
intro->secretkey, ftmpSk);
llarp::LogDebug("gen_intro SK ", hexSk);
char ftmpSkPub[68] = {0};
const char *hexSkPub =
llarp::HexEncode< llarp::PubKey, decltype(ftmpSkPub) >(
llarp::seckey_topublic(intro->secretkey), ftmpSkPub);
llarp::LogDebug("gen_intro SK pub ", hexSkPub);
#endif
buf.base = intro->buf + 64;
buf.cur = buf.base;
buf.sz = 32;
crypto->xchacha20(buf, e_k, intro->nonce);
// h = MDS( n + e + w0, S)
buf.base = intro->buf + 32;
buf.cur = buf.base;
buf.sz = intro->sz - 32;
crypto->hmac(intro->buf, buf, sharedkey);
#ifdef neuroCryptoDebug
char ftmpHmac[68] = {0}; // probably could be 65
const char *hexHmac = llarp::HexEncode< llarp::PubKey, decltype(ftmpHmac) >(
intro->buf, ftmpHmac);
llarp::LogDebug("gen_intro Hmac ", hexHmac);
#endif
// inform result
// intro->hook(intro);
llarp_logic_queue_job(intro->iwp->logic, {intro, &inform_intro});
}
void
verify_intro(void *user)
{
iwp_async_intro *intro = static_cast< iwp_async_intro * >(user);
auto crypto = intro->iwp->crypto;
llarp::SharedSecret sharedkey;
llarp::ShortHash e_K;
llarp::SharedSecret h;
byte_t tmp[64];
const auto OurPK = llarp::seckey_topublic(intro->secretkey);
#ifdef neuroCryptoDebug
char ftmp[68] = {0};
const char *hexPk =
llarp::HexEncode< llarp::PubKey, decltype(ftmp) >(OurPK, ftmp);
llarp::LogDebug("intro OurPK ", hexPk);
#endif
// e_k = HS(b.k + n)
memcpy(tmp, OurPK, 32);
memcpy(tmp + 32, intro->nonce, 32);
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
crypto->shorthash(e_K, buf);
buf.base = intro->remote_pubkey;
buf.cur = buf.base;
buf.sz = 32;
// was using remote_pubkey directly (use buffer wrapper? directly?)
// memcpy(intro->remote_pubkey, intro->buf + 64, 32);
memcpy(buf.base, intro->buf + 64, 32);
crypto->xchacha20(buf, e_K, intro->nonce);
#ifdef neuroCryptoDebug
llarp::LogInfo("handshake from ", llarp::RouterID(intro->remote_pubkey));
char ftmp2[68] = {0};
const char *hexRemotePK = llarp::HexEncode< llarp::PubKey, decltype(ftmp) >(
intro->remote_pubkey, ftmp2);
llarp::LogDebug("intro remote_pubkey ", hexRemotePK);
#endif
// S = TKE(a.k, b.k, n)
crypto->transport_dh_server(sharedkey, intro->remote_pubkey,
intro->secretkey, intro->nonce);
#ifdef neuroCryptoDebug
char ftmpShared[68] = {0};
const char *hexShared =
llarp::HexEncode< llarp::PubKey, decltype(ftmpShared) >(sharedkey,
ftmpShared);
llarp::LogDebug("intro sharedkey ", hexShared);
#endif
// h = MDS( n + e + w2, S)
buf.base = intro->buf + 32;
buf.cur = buf.base;
buf.sz = intro->sz - 32;
crypto->hmac(h, buf, sharedkey);
if(memcmp(h, intro->buf, 32))
{
llarp::LogWarn("intro HMAC failure");
// hmac fail
delete[] intro->buf;
intro->buf = nullptr;
}
// inform result
llarp_logic_queue_job(intro->iwp->logic, {intro, &inform_intro});
}
void
inform_introack(void *user)
{
iwp_async_introack *introack = static_cast< iwp_async_introack * >(user);
introack->hook(introack);
}
void
verify_introack(void *user)
{
iwp_async_introack *introack = static_cast< iwp_async_introack * >(user);
auto crypto = introack->iwp->crypto;
auto logic = introack->iwp->logic;
llarp::ShortHash digest;
llarp::SharedSecret sharedkey;
auto hmac = introack->buf;
auto body = introack->buf + 32;
const auto pubkey = introack->remote_pubkey;
auto secretkey = introack->secretkey;
auto nonce = introack->buf + 32;
auto token = introack->buf + 64;
size_t bodysz = introack->sz - 32;
llarp_buffer_t buf;
buf.base = body;
buf.cur = body;
buf.sz = bodysz;
// S = TKE(a.k, b.k, n)
crypto->transport_dh_client(sharedkey, pubkey, secretkey, nonce);
// h = MDS(n + x + w1, S)
crypto->hmac(digest, buf, sharedkey);
if(!llarp_eq(digest, hmac, 32))
{
// fail to verify hmac
introack->buf = nullptr;
}
else
{
buf.base = token;
buf.sz = 32;
// token = SD(S, x, n[0:24])
crypto->xchacha20(buf, sharedkey, nonce);
// copy token
memcpy(introack->token, token, 32);
}
// introack->hook(introack);
llarp_logic_queue_job(logic, {introack, &inform_introack});
}
void
gen_introack(void *user)
{
iwp_async_introack *introack = static_cast< iwp_async_introack * >(user);
llarp::SharedSecret sharedkey;
auto crypto = introack->iwp->crypto;
const auto pubkey = introack->remote_pubkey;
auto secretkey = introack->secretkey;
auto nonce = introack->nonce;
// S = TKE(a.k, b.k, n)
crypto->transport_dh_server(sharedkey, pubkey, secretkey, nonce);
// x = SE(S, token, n[0:24])
llarp_buffer_t buf;
buf.base = introack->buf + 64;
buf.sz = 32;
buf.cur = buf.base;
memcpy(buf.base, introack->token, 32);
crypto->xchacha20(buf, sharedkey, nonce);
// h = MDS(n + x + w1, S)
buf.base = introack->buf + 32;
buf.sz = introack->sz - 32;
buf.cur = buf.base;
crypto->hmac(introack->buf, buf, sharedkey);
// introack->hook(introack);
llarp_logic_queue_job(introack->iwp->logic, {introack, &inform_introack});
}
void
inform_session_start(void *user)
{
iwp_async_session_start *session =
static_cast< iwp_async_session_start * >(user);
session->hook(session);
}
void
gen_session_start(void *user)
{
iwp_async_session_start *session =
static_cast< iwp_async_session_start * >(user);
auto crypto = session->iwp->crypto;
auto logic = session->iwp->logic;
auto dh = crypto->transport_dh_client;
auto shorthash = crypto->shorthash;
auto hmac = crypto->hmac;
auto encrypt = crypto->xchacha20;
// auto logic = session->iwp->logic;
auto a_sK = session->secretkey;
const auto b_K = session->remote_pubkey;
auto N = session->nonce;
auto token = session->token;
auto K = session->sessionkey;
llarp::SharedSecret e_K;
llarp::ShortHash T;
byte_t tmp[64];
llarp_buffer_t buf = llarp::StackBuffer< decltype(tmp) >(tmp);
// T = HS(token + n)
memcpy(tmp, token, 32);
memcpy(tmp + 32, N, 32);
shorthash(T, buf);
// e_K = TKE(a.k, b.k, n)
dh(e_K, b_K, a_sK, N);
// K = TKE(a.k, b.k, T)
dh(K, b_K, a_sK, T);
// x = SE(e_K, token, n[0:24])
buf.base = (session->buf + 64);
buf.sz = 32;
memcpy(buf.base, token, 32);
encrypt(buf, e_K, N);
// h = MDS(n + x + w2, e_K)
buf.base = (session->buf + 32);
buf.sz = session->sz - 32;
hmac(session->buf, buf, e_K);
// session->hook(session);
llarp_logic_queue_job(logic, {session, &inform_session_start});
}
void
verify_session_start(void *user)
{
iwp_async_session_start *session =
static_cast< iwp_async_session_start * >(user);
// possible repeat job
if(session->buf == nullptr)
return;
auto crypto = session->iwp->crypto;
auto logic = session->iwp->logic;
auto dh = crypto->transport_dh_server;
auto shorthash = crypto->shorthash;
auto hmac = crypto->hmac;
auto decrypt = crypto->xchacha20;
auto b_sK = session->secretkey;
auto a_K = session->remote_pubkey;
auto N = session->nonce;
auto token = session->token;
auto K = session->sessionkey;
llarp::SharedSecret e_K;
llarp::ShortHash T;
byte_t tmp[64];
llarp_buffer_t buf;
// e_K = TKE(a.k, b.k, N)
dh(e_K, a_K, b_sK, N);
// h = MDS( n + x + w2, e_K)
buf.base = session->buf + 32;
buf.cur = buf.base;
buf.sz = session->sz - 32;
hmac(tmp, buf, e_K);
if(memcmp(tmp, session->buf, 32) == 0)
{
// hmac good
buf.base = session->buf + 64;
buf.cur = buf.base;
buf.sz = 32;
// token = SD(e_K, x, n[0:24])
decrypt(buf, e_K, N);
// ensure it's the same token
if(memcmp(buf.base, token, 32) == 0)
{
// T = HS(token + n)
memcpy(tmp, token, 32);
memcpy(tmp + 32, N, 32);
buf.base = tmp;
buf.cur = buf.base;
buf.sz = sizeof(tmp);
shorthash(T, buf);
// K = TKE(a.k, b.k, T)
dh(K, a_K, b_sK, T);
}
else // token missmatch
{
session->buf = nullptr;
}
}
else // hmac fail
session->buf = nullptr;
// session->hook(session);
llarp_logic_queue_job(logic, {session, &inform_session_start});
}
void
inform_frame_done(void *user)
{
iwp_async_frame *frame = static_cast< iwp_async_frame * >(user);
frame->hook(frame);
delete frame;
}
void
hmac_then_decrypt(void *user)
{
iwp_async_frame *frame = static_cast< iwp_async_frame * >(user);
iwp_decrypt_frame(frame);
// inform result
llarp_logic_queue_job(frame->iwp->logic, {frame, &inform_frame_done});
}
void
encrypt_then_hmac(void *user)
{
iwp_async_frame *frame = static_cast< iwp_async_frame * >(user);
iwp_encrypt_frame(frame);
// call result RIGHT HERE
frame->hook(frame);
delete frame;
}
} // namespace iwp
bool
iwp_decrypt_frame(struct iwp_async_frame *frame)
{
auto crypto = frame->iwp->crypto;
byte_t *hmac = frame->buf;
byte_t *nonce = frame->buf + 32;
byte_t *body = frame->buf + 64;
llarp::ShortHash digest;
llarp_buffer_t buf;
buf.base = nonce;
buf.cur = buf.base;
buf.sz = frame->sz - 32;
// h = MDS(n + x, S)
crypto->hmac(digest, buf, frame->sessionkey);
// check hmac
frame->success = memcmp(digest, hmac, 32) == 0;
if(!frame->success)
{
// [", digest, "] vs [", hmac, "]
llarp::LogWarn("crypto_async::iwp_decrypt_frame failed to decrypt");
//} else {
// llarp::Debug("crypto_async::iwp_decrypt_frame decrypted");
}
// x = SE(S, p, n[0:24])
buf.base = body;
buf.cur = buf.base;
buf.sz = frame->sz - 64;
crypto->xchacha20(buf, frame->sessionkey, nonce);
return frame->success;
}
bool
iwp_encrypt_frame(struct iwp_async_frame *frame)
{
auto crypto = frame->iwp->crypto;
byte_t *hmac = frame->buf;
byte_t *nonce = frame->buf + 32;
byte_t *body = frame->buf + 64;
llarp_buffer_t buf;
buf.base = body;
buf.cur = buf.base;
buf.sz = frame->sz - 64;
// randomize N
crypto->randbytes(nonce, 32);
// x = SE(S, p, n[0:24])
crypto->xchacha20(buf, frame->sessionkey, nonce);
// h = MDS(n + x, S)
buf.base = nonce;
buf.cur = buf.base;
buf.sz = frame->sz - 32;
crypto->hmac(hmac, buf, frame->sessionkey);
return true;
}
void
iwp_call_async_gen_intro(struct llarp_async_iwp *iwp,
struct iwp_async_intro *intro)
{
intro->iwp = iwp;
llarp_threadpool_queue_job(iwp->worker, {intro, &iwp::gen_intro});
}
void
iwp_call_async_verify_introack(struct llarp_async_iwp *iwp,
struct iwp_async_introack *introack)
{
introack->iwp = iwp;
llarp_threadpool_queue_job(iwp->worker, {introack, &iwp::verify_introack});
}
void
iwp_call_async_gen_session_start(struct llarp_async_iwp *iwp,
struct iwp_async_session_start *session)
{
session->iwp = iwp;
llarp_threadpool_queue_job(iwp->worker, {session, &iwp::gen_session_start});
}
void
iwp_call_async_verify_intro(struct llarp_async_iwp *iwp,
struct iwp_async_intro *intro)
{
intro->iwp = iwp;
llarp_threadpool_queue_job(iwp->worker, {intro, &iwp::verify_intro});
}
void
iwp_call_async_gen_introack(struct llarp_async_iwp *iwp,
struct iwp_async_introack *introack)
{
introack->iwp = iwp;
llarp_threadpool_queue_job(iwp->worker, {introack, &iwp::gen_introack});
}
void
iwp_call_async_frame_decrypt(struct llarp_async_iwp *iwp,
struct iwp_async_frame *frame)
{
frame->iwp = iwp;
llarp_threadpool_queue_job(iwp->worker, {frame, &iwp::hmac_then_decrypt});
}
void
iwp_call_async_frame_encrypt(struct llarp_async_iwp *iwp,
struct iwp_async_frame *frame)
{
frame->iwp = iwp;
llarp_threadpool_queue_job(iwp->worker, {frame, &iwp::encrypt_then_hmac});
}
void
iwp_call_async_verify_session_start(struct llarp_async_iwp *iwp,
struct iwp_async_session_start *session)
{
session->iwp = iwp;
llarp_threadpool_queue_job(iwp->worker,
{session, &iwp::verify_session_start});
}
struct llarp_async_iwp *
llarp_async_iwp_new(struct llarp_crypto *crypto, struct llarp_logic *logic,
struct llarp_threadpool *worker)
{
llarp_async_iwp *iwp = new llarp_async_iwp;
if(iwp)
{
iwp->crypto = crypto;
iwp->logic = logic;
iwp->worker = worker;
}
return iwp;
}
void
llarp_async_iwp_free(struct llarp_async_iwp *iwp)
{
delete iwp;
}

@ -1,4 +1,4 @@
#include <llarp/crypto_async.h>
#include <llarp/logic.h>
#include <llarp/nodedb.hpp>
#include <llarp/router_contact.hpp>

Loading…
Cancel
Save