lokinet/llarp/encrypted_frame.hpp

141 lines
3.5 KiB
C++
Raw Normal View History

#ifndef LLARP_ENCRYPTED_FRAME_HPP
#define LLARP_ENCRYPTED_FRAME_HPP
#include <crypto.h>
#include <encrypted.hpp>
2018-12-20 16:49:05 +00:00
#include <buffer.hpp>
#include <mem.h>
#include <threadpool.h>
namespace llarp
{
2018-12-20 16:49:05 +00:00
static constexpr size_t EncryptedFrameOverheadSize =
PUBKEYSIZE + TUNNONCESIZE + SHORTHASHSIZE;
static constexpr size_t EncryptedFrameBodySize = 512;
static constexpr size_t EncryptedFrameSize =
EncryptedFrameOverheadSize + EncryptedFrameBodySize;
2018-06-21 12:55:02 +00:00
2018-12-20 16:49:05 +00:00
struct EncryptedFrame : public Encrypted< EncryptedFrameSize >
{
EncryptedFrame() : EncryptedFrame(EncryptedFrameBodySize)
2018-06-21 12:55:02 +00:00
{
}
2018-06-14 20:13:07 +00:00
EncryptedFrame(size_t sz)
2018-12-20 16:49:05 +00:00
: Encrypted< EncryptedFrameSize >(std::min(sz, EncryptedFrameBodySize)
+ EncryptedFrameOverheadSize)
2018-06-11 13:25:10 +00:00
{
2018-12-20 16:49:05 +00:00
UpdateBuffer();
2018-06-11 13:25:10 +00:00
}
2018-06-10 14:05:48 +00:00
2018-06-21 12:55:02 +00:00
EncryptedFrame&
operator=(const EncryptedFrame& other)
{
2018-12-20 16:49:05 +00:00
_sz = other._sz;
2018-10-19 11:34:27 +00:00
memcpy(data(), other.data(), size());
2018-12-20 16:49:05 +00:00
UpdateBuffer();
2018-06-21 12:55:02 +00:00
return *this;
}
2018-06-10 14:05:48 +00:00
bool
DecryptInPlace(const byte_t* seckey, llarp::Crypto* crypto);
2018-06-11 13:25:10 +00:00
bool
EncryptInPlace(const byte_t* seckey, const byte_t* other,
llarp::Crypto* crypto);
2018-06-11 13:25:10 +00:00
};
/// TOOD: can only handle 1 frame at a time
template < typename User >
struct AsyncFrameEncrypter
{
using EncryptHandler = std::function< void(EncryptedFrame*, User*) >;
2018-06-10 14:05:48 +00:00
2018-06-11 13:25:10 +00:00
static void
Encrypt(void* user)
2018-06-10 14:05:48 +00:00
{
2018-06-11 13:25:10 +00:00
AsyncFrameEncrypter< User >* ctx =
static_cast< AsyncFrameEncrypter< User >* >(user);
2018-12-20 16:49:05 +00:00
if(ctx->frame.EncryptInPlace(ctx->seckey, ctx->otherKey, ctx->crypto))
ctx->handler(&ctx->frame, ctx->user);
2018-06-11 13:25:10 +00:00
else
{
ctx->handler(nullptr, ctx->user);
}
2018-06-10 14:05:48 +00:00
}
llarp::Crypto* crypto;
2018-06-11 13:25:10 +00:00
byte_t* secretkey;
EncryptHandler handler;
2018-12-20 16:49:05 +00:00
EncryptedFrame frame;
2018-06-11 13:25:10 +00:00
User* user;
2018-06-11 13:44:49 +00:00
byte_t* otherKey;
2018-06-11 13:25:10 +00:00
AsyncFrameEncrypter(llarp::Crypto* c, byte_t* seckey, EncryptHandler h)
2018-06-11 13:25:10 +00:00
: crypto(c), secretkey(seckey), handler(h)
{
}
void
2018-06-11 13:44:49 +00:00
AsyncEncrypt(llarp_threadpool* worker, llarp_buffer_t buf, byte_t* other,
User* u)
2018-06-11 13:25:10 +00:00
{
2018-06-11 13:44:49 +00:00
// TODO: should we own otherKey?
otherKey = other;
2018-12-20 16:49:05 +00:00
if(buf.sz > EncryptedFrameBodySize)
return;
memcpy(frame.data() + PUBKEYSIZE + TUNNONCESIZE + SHORTHASHSIZE, buf.base,
buf.sz);
2018-06-11 13:25:10 +00:00
user = u;
llarp_threadpool_queue_job(worker, {this, &Encrypt});
}
2018-06-10 14:05:48 +00:00
};
2018-06-11 13:25:10 +00:00
/// TOOD: can only handle 1 frame at a time
2018-06-10 14:05:48 +00:00
template < typename User >
struct AsyncFrameDecrypter
{
using DecryptHandler = std::function< void(llarp_buffer_t*, User*) >;
2018-06-10 14:05:48 +00:00
static void
Decrypt(void* user)
{
AsyncFrameDecrypter< User >* ctx =
static_cast< AsyncFrameDecrypter< User >* >(user);
2018-12-20 16:49:05 +00:00
if(ctx->target.DecryptInPlace(ctx->seckey, ctx->crypto))
2018-06-21 12:55:02 +00:00
{
2018-12-20 16:49:05 +00:00
auto buf = ctx->target.Buffer();
buf->cur = buf->base + EncryptedFrameOverheadSize;
2018-06-21 12:55:02 +00:00
ctx->result(buf, ctx->context);
}
2018-06-10 14:05:48 +00:00
else
ctx->result(nullptr, ctx->context);
}
AsyncFrameDecrypter(llarp::Crypto* c, const byte_t* secretkey,
DecryptHandler h)
2018-06-10 14:05:48 +00:00
: result(h), crypto(c), seckey(secretkey)
{
}
DecryptHandler result;
User* context;
llarp::Crypto* crypto;
const byte_t* seckey;
2018-12-20 16:49:05 +00:00
EncryptedFrame target;
2018-06-20 12:34:48 +00:00
2018-06-10 14:05:48 +00:00
void
2018-12-20 16:49:05 +00:00
AsyncDecrypt(llarp_threadpool* worker, const EncryptedFrame& frame,
User* user)
2018-06-10 14:05:48 +00:00
{
target = frame;
context = user;
llarp_threadpool_queue_job(worker, {this, &Decrypt});
}
};
2018-06-14 20:13:07 +00:00
} // namespace llarp
#endif