2021-03-09 22:24:35 +00:00
|
|
|
#include "async_key_exchange.hpp"
|
2019-04-21 16:44:27 +00:00
|
|
|
|
2021-03-09 22:24:35 +00:00
|
|
|
#include <llarp/crypto/crypto.hpp>
|
|
|
|
#include <llarp/crypto/types.hpp>
|
|
|
|
#include <llarp/util/meta/memfn.hpp>
|
2019-07-30 23:42:13 +00:00
|
|
|
#include <utility>
|
2019-04-21 16:44:27 +00:00
|
|
|
|
|
|
|
namespace llarp
|
|
|
|
{
|
|
|
|
namespace service
|
|
|
|
{
|
2019-07-30 23:42:13 +00:00
|
|
|
AsyncKeyExchange::AsyncKeyExchange(
|
2021-03-02 15:23:38 +00:00
|
|
|
EventLoop_ptr l,
|
2020-04-07 18:38:56 +00:00
|
|
|
ServiceInfo r,
|
|
|
|
const Identity& localident,
|
|
|
|
const PQPubKey& introsetPubKey,
|
|
|
|
const Introduction& remote,
|
|
|
|
IDataHandler* h,
|
|
|
|
const ConvoTag& t,
|
|
|
|
ProtocolType proto)
|
2021-03-02 07:02:59 +00:00
|
|
|
: loop(std::move(l))
|
2019-07-30 23:42:13 +00:00
|
|
|
, m_remote(std::move(r))
|
2019-04-21 16:44:27 +00:00
|
|
|
, m_LocalIdentity(localident)
|
|
|
|
, introPubKey(introsetPubKey)
|
|
|
|
, remoteIntro(remote)
|
|
|
|
, handler(h)
|
|
|
|
, tag(t)
|
|
|
|
{
|
2019-06-11 16:44:05 +00:00
|
|
|
msg.proto = proto;
|
2019-04-21 16:44:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2020-04-07 18:38:56 +00:00
|
|
|
AsyncKeyExchange::Result(
|
|
|
|
std::shared_ptr<AsyncKeyExchange> self, std::shared_ptr<ProtocolFrame> frame)
|
2019-04-21 16:44:27 +00:00
|
|
|
{
|
|
|
|
// put values
|
2019-08-02 09:27:27 +00:00
|
|
|
self->handler->PutSenderFor(self->msg.tag, self->m_remote, false);
|
2019-04-21 16:44:27 +00:00
|
|
|
self->handler->PutCachedSessionKeyFor(self->msg.tag, self->sharedKey);
|
|
|
|
self->handler->PutIntroFor(self->msg.tag, self->remoteIntro);
|
|
|
|
self->handler->PutReplyIntroFor(self->msg.tag, self->msg.introReply);
|
2019-11-27 15:59:36 +00:00
|
|
|
self->hook(frame);
|
2019-04-21 16:44:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2020-04-07 18:38:56 +00:00
|
|
|
AsyncKeyExchange::Encrypt(
|
|
|
|
std::shared_ptr<AsyncKeyExchange> self, std::shared_ptr<ProtocolFrame> frame)
|
2019-04-21 16:44:27 +00:00
|
|
|
{
|
|
|
|
// derive ntru session key component
|
|
|
|
SharedSecret K;
|
2019-05-28 19:45:08 +00:00
|
|
|
auto crypto = CryptoManager::instance();
|
2019-11-27 15:59:36 +00:00
|
|
|
crypto->pqe_encrypt(frame->C, K, self->introPubKey);
|
2019-04-21 16:44:27 +00:00
|
|
|
// randomize Nonce
|
2019-11-27 15:59:36 +00:00
|
|
|
frame->N.Randomize();
|
2019-04-21 16:44:27 +00:00
|
|
|
// compure post handshake session key
|
|
|
|
// PKE (A, B, N)
|
|
|
|
SharedSecret sharedSecret;
|
2019-06-02 21:19:10 +00:00
|
|
|
path_dh_func dh_client = util::memFn(&Crypto::dh_client, crypto);
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!self->m_LocalIdentity.KeyExchange(dh_client, sharedSecret, self->m_remote, frame->N))
|
2019-04-21 16:44:27 +00:00
|
|
|
{
|
|
|
|
LogError("failed to derive x25519 shared key component");
|
|
|
|
}
|
2020-04-07 18:38:56 +00:00
|
|
|
std::array<byte_t, 64> tmp = {{0}};
|
2019-04-21 16:44:27 +00:00
|
|
|
// K
|
|
|
|
std::copy(K.begin(), K.end(), tmp.begin());
|
|
|
|
// H (K + PKE(A, B, N))
|
|
|
|
std::copy(sharedSecret.begin(), sharedSecret.end(), tmp.begin() + 32);
|
2019-05-28 19:45:08 +00:00
|
|
|
crypto->shorthash(self->sharedKey, llarp_buffer_t(tmp));
|
2019-04-21 16:44:27 +00:00
|
|
|
// set tag
|
|
|
|
self->msg.tag = self->tag;
|
|
|
|
// set sender
|
|
|
|
self->msg.sender = self->m_LocalIdentity.pub;
|
|
|
|
// set version
|
|
|
|
self->msg.version = LLARP_PROTO_VERSION;
|
|
|
|
// encrypt and sign
|
2020-04-07 18:38:56 +00:00
|
|
|
if (frame->EncryptAndSign(self->msg, K, self->m_LocalIdentity))
|
2021-03-02 07:02:59 +00:00
|
|
|
self->loop->call([self, frame] { AsyncKeyExchange::Result(self, frame); });
|
2019-04-21 16:44:27 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
LogError("failed to encrypt and sign");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} // namespace service
|
|
|
|
} // namespace llarp
|