mirror of https://github.com/oxen-io/lokinet
chahca nonce size is 24 bytes
Lots of code was using 32-byte nonces for xchacha20 symmetric encryption, but this just means 8 extra bytes per packet wasted as chacha is only using the first 24 bytes of that nonce anyway. Changing this resulted in a lot of dead/dying code breaking, so this commit also removes a lot of that (and comments a couple places with TODO instead) Also nounce -> nonce where it came up.pull/2216/head
parent
abb2f63ec6
commit
9e9c1ea732
@ -1,127 +0,0 @@
|
||||
#include "encrypted_frame.hpp"
|
||||
|
||||
#include "crypto.hpp"
|
||||
|
||||
#include <llarp/util/logging.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
bool
|
||||
EncryptedFrame::DoEncrypt(const SharedSecret& shared, bool noDH)
|
||||
{
|
||||
uint8_t* hash_ptr = data();
|
||||
uint8_t* nonce_ptr = hash_ptr + SHORTHASHSIZE;
|
||||
uint8_t* pubkey_ptr = nonce_ptr + TUNNONCESIZE;
|
||||
uint8_t* body_ptr = pubkey_ptr + PUBKEYSIZE;
|
||||
|
||||
if (noDH)
|
||||
{
|
||||
crypto::randbytes(nonce_ptr, TUNNONCESIZE);
|
||||
crypto::randbytes(pubkey_ptr, PUBKEYSIZE);
|
||||
}
|
||||
|
||||
TunnelNonce nonce(nonce_ptr);
|
||||
|
||||
// encrypt body
|
||||
if (!crypto::xchacha20(body_ptr, size() - EncryptedFrameOverheadSize, shared, nonce))
|
||||
{
|
||||
llarp::LogError("encrypt failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!crypto::hmac(hash_ptr, nonce_ptr, size() - SHORTHASHSIZE, shared))
|
||||
{
|
||||
llarp::LogError("Failed to generate message auth");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
EncryptedFrame::EncryptInPlace(const SecretKey& ourSecretKey, const PubKey& otherPubkey)
|
||||
{
|
||||
// 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* noncePtr = hash + SHORTHASHSIZE;
|
||||
byte_t* pubkey = noncePtr + TUNNONCESIZE;
|
||||
|
||||
SharedSecret shared;
|
||||
|
||||
// set our pubkey
|
||||
memcpy(pubkey, ourSecretKey.toPublic().data(), PUBKEYSIZE);
|
||||
// randomize nonce
|
||||
crypto::randbytes(noncePtr, TUNNONCESIZE);
|
||||
TunnelNonce nonce(noncePtr);
|
||||
|
||||
// derive shared key
|
||||
if (!crypto::dh_client(shared, otherPubkey, ourSecretKey, nonce))
|
||||
{
|
||||
llarp::LogError("DH failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return DoEncrypt(shared, false);
|
||||
}
|
||||
|
||||
bool
|
||||
EncryptedFrame::DoDecrypt(const SharedSecret& shared)
|
||||
{
|
||||
uint8_t* hash_ptr = data();
|
||||
uint8_t* nonce_ptr = hash_ptr + SHORTHASHSIZE;
|
||||
uint8_t* body_ptr = hash_ptr + EncryptedFrameOverheadSize;
|
||||
|
||||
TunnelNonce nonce(nonce_ptr);
|
||||
|
||||
ShortHash digest;
|
||||
if (!crypto::hmac(digest.data(), nonce_ptr, size() - SHORTHASHSIZE, shared))
|
||||
{
|
||||
llarp::LogError("Digest failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!std::equal(digest.begin(), digest.end(), hash_ptr))
|
||||
{
|
||||
llarp::LogError("message authentication failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!crypto::xchacha20(body_ptr, size() - EncryptedFrameOverheadSize, shared, nonce))
|
||||
{
|
||||
llarp::LogError("decrypt failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
EncryptedFrame::DecryptInPlace(const SecretKey& ourSecretKey)
|
||||
{
|
||||
// format of frame is
|
||||
// <32 bytes keyed hash of following data>
|
||||
// <32 bytes nonce>
|
||||
// <32 bytes pubkey>
|
||||
// <N bytes encrypted payload>
|
||||
//
|
||||
byte_t* noncePtr = data() + SHORTHASHSIZE;
|
||||
TunnelNonce nonce(noncePtr);
|
||||
PubKey otherPubkey(noncePtr + TUNNONCESIZE);
|
||||
|
||||
SharedSecret shared;
|
||||
|
||||
// use dh_server because we are not the creator of this message
|
||||
if (!crypto::dh_server(shared, otherPubkey, ourSecretKey, nonce))
|
||||
{
|
||||
llarp::LogError("DH failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return DoDecrypt(shared);
|
||||
}
|
||||
} // namespace llarp
|
@ -1,87 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "encrypted.hpp"
|
||||
#include "types.hpp"
|
||||
|
||||
#include <llarp/util/buffer.hpp>
|
||||
#include <llarp/util/mem.h>
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
static constexpr size_t EncryptedFrameOverheadSize = PUBKEYSIZE + TUNNONCESIZE + SHORTHASHSIZE;
|
||||
static constexpr size_t EncryptedFrameBodySize = 128 * 6;
|
||||
static constexpr size_t EncryptedFrameSize = EncryptedFrameOverheadSize + EncryptedFrameBodySize;
|
||||
|
||||
struct EncryptedFrame : public Encrypted<EncryptedFrameSize>
|
||||
{
|
||||
EncryptedFrame() : EncryptedFrame(EncryptedFrameBodySize)
|
||||
{}
|
||||
|
||||
EncryptedFrame(size_t sz)
|
||||
: Encrypted<EncryptedFrameSize>(
|
||||
std::min(sz, EncryptedFrameBodySize) + EncryptedFrameOverheadSize)
|
||||
{}
|
||||
|
||||
void
|
||||
Resize(size_t sz)
|
||||
{
|
||||
if (sz <= EncryptedFrameSize)
|
||||
{
|
||||
_sz = sz;
|
||||
UpdateBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
DoEncrypt(const SharedSecret& shared, bool noDH = false);
|
||||
|
||||
bool
|
||||
DecryptInPlace(const SecretKey& seckey);
|
||||
|
||||
bool
|
||||
DoDecrypt(const SharedSecret& shared);
|
||||
|
||||
bool
|
||||
EncryptInPlace(const SecretKey& seckey, const PubKey& other);
|
||||
};
|
||||
|
||||
template <typename User>
|
||||
struct AsyncFrameDecrypter
|
||||
{
|
||||
using User_ptr = std::shared_ptr<User>;
|
||||
using DecryptHandler = std::function<void(llarp_buffer_t*, User_ptr)>;
|
||||
|
||||
void
|
||||
Decrypt(User_ptr user)
|
||||
{
|
||||
if (target.DecryptInPlace(seckey))
|
||||
{
|
||||
auto buf = target.Buffer();
|
||||
buf->cur = buf->base + EncryptedFrameOverheadSize;
|
||||
result(buf, user);
|
||||
}
|
||||
else
|
||||
result(nullptr, user);
|
||||
}
|
||||
|
||||
AsyncFrameDecrypter(const SecretKey& secretkey, DecryptHandler h)
|
||||
: result(std::move(h)), seckey(secretkey)
|
||||
{}
|
||||
|
||||
DecryptHandler result;
|
||||
const SecretKey& seckey;
|
||||
EncryptedFrame target;
|
||||
|
||||
using WorkFunc_t = std::function<void(void)>;
|
||||
using WorkerFunction_t = std::function<void(WorkFunc_t)>;
|
||||
|
||||
void
|
||||
AsyncDecrypt(const EncryptedFrame& frame, User_ptr u, WorkerFunction_t worker)
|
||||
{
|
||||
target = frame;
|
||||
worker([this, u = std::move(u)]() mutable { Decrypt(std::move(u)); });
|
||||
}
|
||||
};
|
||||
} // namespace llarp
|
@ -1,123 +0,0 @@
|
||||
#include "relay.hpp"
|
||||
|
||||
#include <llarp/path/path_context.hpp>
|
||||
#include <llarp/router/router.hpp>
|
||||
#include <llarp/util/bencode.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
void
|
||||
RelayUpstreamMessage::clear()
|
||||
{
|
||||
pathid.Zero();
|
||||
enc.Clear();
|
||||
nonce.Zero();
|
||||
version = 0;
|
||||
}
|
||||
|
||||
std::string
|
||||
RelayUpstreamMessage::bt_encode() const
|
||||
{
|
||||
oxenc::bt_dict_producer btdp;
|
||||
|
||||
try
|
||||
{
|
||||
btdp.append("a", "u");
|
||||
btdp.append("p", pathid.ToView());
|
||||
btdp.append("v", llarp::constants::proto_version);
|
||||
btdp.append("x", std::string_view{reinterpret_cast<const char*>(enc.data()), enc.size()});
|
||||
btdp.append("y", std::string_view{reinterpret_cast<const char*>(nonce.data()), nonce.size()});
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
log::critical(link_cat, "Error: RelayUpstreamMessage failed to bt encode contents!");
|
||||
}
|
||||
|
||||
return std::move(btdp).str();
|
||||
}
|
||||
|
||||
bool
|
||||
RelayUpstreamMessage::decode_key(const llarp_buffer_t& key, llarp_buffer_t* buf)
|
||||
{
|
||||
bool read = false;
|
||||
if (!BEncodeMaybeReadDictEntry("p", pathid, read, key, buf))
|
||||
return false;
|
||||
if (!BEncodeMaybeVerifyVersion("v", version, llarp::constants::proto_version, read, key, buf))
|
||||
return false;
|
||||
if (!BEncodeMaybeReadDictEntry("x", enc, read, key, buf))
|
||||
return false;
|
||||
if (!BEncodeMaybeReadDictEntry("y", nonce, read, key, buf))
|
||||
return false;
|
||||
return read;
|
||||
}
|
||||
|
||||
bool
|
||||
RelayUpstreamMessage::handle_message(Router* r) const
|
||||
{
|
||||
path::HopHandler_ptr path = r->path_context().GetPath(pathid);
|
||||
path = path ? path : r->path_context().GetTransitHop(conn->remote_rc.router_id(), pathid);
|
||||
if (path)
|
||||
{
|
||||
return path->HandleUpstream(llarp_buffer_t(enc), nonce, r);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
RelayDownstreamMessage::clear()
|
||||
{
|
||||
pathid.Zero();
|
||||
enc.Clear();
|
||||
nonce.Zero();
|
||||
version = 0;
|
||||
}
|
||||
|
||||
std::string
|
||||
RelayDownstreamMessage::bt_encode() const
|
||||
{
|
||||
oxenc::bt_dict_producer btdp;
|
||||
|
||||
try
|
||||
{
|
||||
btdp.append("a", "d");
|
||||
btdp.append("p", pathid.ToView());
|
||||
btdp.append("v", llarp::constants::proto_version);
|
||||
btdp.append("x", std::string_view{reinterpret_cast<const char*>(enc.data()), enc.size()});
|
||||
btdp.append("y", std::string_view{reinterpret_cast<const char*>(nonce.data()), nonce.size()});
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
log::critical(link_cat, "Error: RelayDownstreamMessage failed to bt encode contents!");
|
||||
}
|
||||
|
||||
return std::move(btdp).str();
|
||||
}
|
||||
|
||||
bool
|
||||
RelayDownstreamMessage::decode_key(const llarp_buffer_t& key, llarp_buffer_t* buf)
|
||||
{
|
||||
bool read = false;
|
||||
if (!BEncodeMaybeReadDictEntry("p", pathid, read, key, buf))
|
||||
return false;
|
||||
if (!BEncodeMaybeVerifyVersion("v", version, llarp::constants::proto_version, read, key, buf))
|
||||
return false;
|
||||
if (!BEncodeMaybeReadDictEntry("x", enc, read, key, buf))
|
||||
return false;
|
||||
if (!BEncodeMaybeReadDictEntry("y", nonce, read, key, buf))
|
||||
return false;
|
||||
return read;
|
||||
}
|
||||
|
||||
bool
|
||||
RelayDownstreamMessage::handle_message(Router* r) const
|
||||
{
|
||||
path::HopHandler_ptr path = r->path_context().GetPath(pathid);
|
||||
path = path ? path : r->path_context().GetTransitHop(conn->remote_rc.router_id(), pathid);
|
||||
if (path)
|
||||
{
|
||||
return path->HandleDownstream(llarp_buffer_t(enc), nonce, r);
|
||||
}
|
||||
llarp::LogWarn("no path for downstream message id=", pathid);
|
||||
return false;
|
||||
}
|
||||
} // namespace llarp
|
@ -1,75 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "link_message.hpp"
|
||||
|
||||
#include <llarp/crypto/encrypted.hpp>
|
||||
#include <llarp/crypto/types.hpp>
|
||||
#include <llarp/path/path_types.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
/*
|
||||
Data messages to be sent via quic datagrams
|
||||
*/
|
||||
|
||||
struct RelayUpstreamMessage final : public AbstractLinkMessage
|
||||
{
|
||||
Encrypted<MAX_LINK_MSG_SIZE - 128> enc;
|
||||
TunnelNonce nonce;
|
||||
|
||||
bool
|
||||
decode_key(const llarp_buffer_t& key, llarp_buffer_t* buf) override;
|
||||
|
||||
std::string
|
||||
bt_encode() const override;
|
||||
|
||||
bool
|
||||
handle_message(Router* router) const override;
|
||||
|
||||
void
|
||||
clear() override;
|
||||
|
||||
const char*
|
||||
name() const override
|
||||
{
|
||||
return "RelayUpstream";
|
||||
}
|
||||
uint16_t
|
||||
priority() const override
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct RelayDownstreamMessage final : public AbstractLinkMessage
|
||||
{
|
||||
Encrypted<MAX_LINK_MSG_SIZE - 128> enc;
|
||||
TunnelNonce nonce;
|
||||
|
||||
bool
|
||||
decode_key(const llarp_buffer_t& key, llarp_buffer_t* buf) override;
|
||||
|
||||
std::string
|
||||
bt_encode() const override;
|
||||
|
||||
bool
|
||||
handle_message(Router* router) const override;
|
||||
|
||||
void
|
||||
clear() override;
|
||||
|
||||
const char*
|
||||
name() const override
|
||||
{
|
||||
return "RelayDownstream";
|
||||
}
|
||||
|
||||
uint16_t
|
||||
priority() const override
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
} // namespace llarp
|
Loading…
Reference in New Issue