mirror of https://github.com/oxen-io/lokinet
encrypted frames
parent
ec53cab169
commit
9d749d20ae
@ -0,0 +1,30 @@
|
||||
#ifndef LLARP_ENCCRYPTED_HPP
|
||||
#define LLARP_ENCCRYPTED_HPP
|
||||
|
||||
#include <llarp/buffer.h>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
/// encrypted buffer base type
|
||||
struct Encrypted
|
||||
{
|
||||
Encrypted() = default;
|
||||
Encrypted(const byte_t* buf, size_t sz);
|
||||
Encrypted(size_t sz);
|
||||
~Encrypted();
|
||||
|
||||
llarp_buffer_t*
|
||||
Buffer()
|
||||
{
|
||||
return &m_Buffer;
|
||||
}
|
||||
|
||||
byte_t* data = nullptr;
|
||||
size_t size = 0;
|
||||
|
||||
private:
|
||||
llarp_buffer_t m_Buffer;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,14 @@
|
||||
#ifndef LLARP_ENCRYPTED_ACK_HPP
|
||||
#define LLARP_ENCRYPTED_ACK_HPP
|
||||
#include <llarp/encrypted.hpp>
|
||||
namespace llarp
|
||||
{
|
||||
struct EncryptedAck : public Encrypted
|
||||
{
|
||||
bool
|
||||
DecryptInPlace(const byte_t* symkey, const byte_t* nonce,
|
||||
llarp_crypto* crypto);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -1,31 +1,84 @@
|
||||
#include <llarp/encrypted_frame.hpp>
|
||||
#include "logger.hpp"
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
EncryptedFrame::EncryptedFrame() : m_Buf(nullptr), m_Sz(0)
|
||||
Encrypted::Encrypted(const byte_t* buf, size_t sz)
|
||||
{
|
||||
size = sz;
|
||||
data = new byte_t[sz];
|
||||
if(buf)
|
||||
memcpy(data, buf, sz);
|
||||
m_Buffer.base = data;
|
||||
m_Buffer.cur = data;
|
||||
m_Buffer.sz = size;
|
||||
}
|
||||
|
||||
EncryptedFrame::EncryptedFrame(const byte_t* buf, size_t sz)
|
||||
Encrypted::Encrypted(size_t sz) : Encrypted(nullptr, sz)
|
||||
{
|
||||
m_Sz = sz;
|
||||
m_Buf = new byte_t[m_Sz];
|
||||
memcpy(m_Buf, buf, sz);
|
||||
m_Buffer.base = m_Buf;
|
||||
m_Buffer.cur = m_Buf;
|
||||
m_Buffer.sz = sz;
|
||||
}
|
||||
|
||||
EncryptedFrame::~EncryptedFrame()
|
||||
Encrypted::~Encrypted()
|
||||
{
|
||||
if(m_Buf)
|
||||
delete[] m_Buf;
|
||||
if(data)
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
bool
|
||||
EncryptedFrame::DecryptInPlace(const byte_t* ourSecretKey,
|
||||
llarp_crypto* crypto)
|
||||
EncryptedFrame::DecryptInPlace(byte_t* ourSecretKey, llarp_crypto* crypto)
|
||||
{
|
||||
return false;
|
||||
if(size <= OverheadSize)
|
||||
{
|
||||
llarp::Warn("encrypted frame too small, ", size, " <= ", OverheadSize);
|
||||
return false;
|
||||
}
|
||||
// format of frame is
|
||||
// <32 bytes keyed hash of following data>
|
||||
// <32 bytes nonce>
|
||||
// <32 bytes pubkey>
|
||||
// <N bytes encrypted payload>
|
||||
//
|
||||
byte_t* hash = data;
|
||||
byte_t* nonce = hash + sizeof(llarp_pubkey_t);
|
||||
byte_t* otherPubkey = nonce + sizeof(llarp_tunnel_nonce_t);
|
||||
byte_t* body = otherPubkey + sizeof(llarp_shorthash_t);
|
||||
|
||||
// use dh_server becuase we are not the creator of this message
|
||||
auto DH = crypto->dh_server;
|
||||
auto Decrypt = crypto->xchacha20;
|
||||
auto Digest = crypto->hmac;
|
||||
|
||||
llarp_buffer_t buf;
|
||||
buf.base = body;
|
||||
buf.cur = buf.base;
|
||||
buf.sz = size - OverheadSize;
|
||||
|
||||
llarp_sharedkey_t shared;
|
||||
llarp_shorthash_t digest;
|
||||
|
||||
if(!DH(shared, otherPubkey, nonce, ourSecretKey))
|
||||
{
|
||||
llarp::Error("DH failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!Digest(digest, buf, shared))
|
||||
{
|
||||
llarp::Error("Digest failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(memcmp(digest, hash, sizeof(llarp_shorthash_t)))
|
||||
{
|
||||
llarp::Error("message authentication failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!Decrypt(buf, shared, nonce))
|
||||
{
|
||||
llarp::Error("decrypt failed");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue