Merge pull request #190 from michael-loki/no_data

Remove implicit conversions between AlignedBuffers
pull/193/head
Jeff 6 years ago committed by GitHub
commit 85082daa6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -137,7 +137,7 @@ namespace llarp
/* encryption key */
if(!bencode_write_bytestring(buff, "e", 1))
return false;
if(!bencode_write_bytestring(buff, pubkey, PUBKEYSIZE))
if(!bencode_write_bytestring(buff, pubkey.data(), PUBKEYSIZE))
return false;
/** ip */
ipstr = inet_ntop(AF_INET6, (void *)&ip, ipbuff, sizeof(ipbuff));

@ -35,7 +35,7 @@ namespace llarp
Zero();
}
AlignedBuffer(const byte_t* data)
explicit AlignedBuffer(const byte_t* data)
{
new(&val) Data;
auto& b = as_array();
@ -45,10 +45,10 @@ namespace llarp
}
}
AlignedBuffer(const Data& buf)
explicit AlignedBuffer(const Data& buf)
{
new(&val) Data;
std::copy(buf.begin(), buf.end(), as_array().begin());
std::copy(buf.begin(), buf.end(), begin());
}
AlignedBuffer&
@ -74,8 +74,7 @@ namespace llarp
operator~() const
{
AlignedBuffer< sz > ret;
std::transform(as_array().begin(), as_array().end(),
ret.as_array().begin(), [](byte_t a) { return ~a; });
std::transform(begin(), end(), ret.begin(), [](byte_t a) { return ~a; });
return ret;
}
@ -120,8 +119,7 @@ namespace llarp
operator^(const AlignedBuffer& other) const
{
AlignedBuffer< sz > ret;
std::transform(as_array().begin(), as_array().end(),
other.as_array().begin(), ret.as_array().begin(),
std::transform(begin(), end(), other.begin(), ret.begin(),
std::bit_xor< byte_t >());
return ret;
}
@ -130,8 +128,6 @@ namespace llarp
operator^=(const AlignedBuffer& other)
{
// Mutate in place instead.
// Well defined for std::transform,
for(size_t i = 0; i < as_array().size(); ++i)
{
as_array()[i] ^= other.as_array()[i];
@ -139,6 +135,18 @@ namespace llarp
return *this;
}
byte_t& operator[](size_t idx)
{
assert(idx < SIZE);
return as_array()[idx];
}
const byte_t& operator[](size_t idx) const
{
assert(idx < SIZE);
return as_array()[idx];
}
static constexpr size_t
size()
{
@ -163,13 +171,24 @@ namespace llarp
return reinterpret_cast< const Data& >(val);
}
byte_t*
data()
{
return as_array().data();
}
const byte_t*
data() const
{
return as_array().data();
}
bool
IsZero() const
{
auto notZero = [](byte_t b) { return b != 0; };
return std::find_if(as_array().begin(), as_array().end(), notZero)
== as_array().end();
return std::find_if(begin(), end(), notZero) == end();
}
void
@ -181,45 +200,47 @@ namespace llarp
void
Randomize()
{
randombytes(as_array().data(), SIZE);
randombytes(data(), SIZE);
}
byte_t*
data()
typename Data::iterator
begin()
{
return as_array().data();
return as_array().begin();
}
const byte_t*
data() const
typename Data::iterator
end()
{
return as_array().data();
return as_array().end();
}
operator const byte_t*() const
typename Data::const_iterator
begin() const
{
return as_array().data();
}
operator byte_t*()
{
return as_array().data();
return as_array().cbegin();
}
operator const Data&() const
typename Data::const_iterator
end() const
{
return as_array();
return as_array().cend();
}
operator Data&()
llarp_buffer_t
as_buffer()
{
return as_array();
llarp_buffer_t buff;
buff.base = data();
buff.cur = buff.base;
buff.sz = size();
return buff;
}
bool
BEncode(llarp_buffer_t* buf) const
{
return bencode_write_bytestring(buf, as_array().data(), sz);
return bencode_write_bytestring(buf, data(), sz);
}
bool
@ -235,7 +256,7 @@ namespace llarp
llarp::LogError("bdecode buffer size missmatch ", strbuf.sz, "!=", sz);
return false;
}
memcpy(as_array().data(), strbuf.base, sz);
memcpy(data(), strbuf.base, sz);
return true;
}
@ -251,7 +272,7 @@ namespace llarp
size_t
operator()(const AlignedBuffer& buf) const
{
return std::accumulate(buf.as_array().begin(), buf.as_array().end(), 0,
return std::accumulate(buf.begin(), buf.end(), 0,
std::bit_xor< size_t >());
}
};

@ -35,7 +35,10 @@ namespace llarp
Buffer(T& t)
{
llarp_buffer_t buff;
buff.base = &t[0];
// use data over the first element to "enforce" the container used has
// contiguous memory. (Note this isn't required by the standard, but a
// reasonable test on most standard library implementations).
buff.base = t.data();
buff.cur = buff.base;
buff.sz = t.size();
return buff;

@ -7,7 +7,7 @@ namespace llarp
bool
PubKey::FromString(const std::string& str)
{
return HexDecode(str.c_str(), data(), size());
return HexDecode(str.c_str(), begin(), size());
}
std::string
@ -31,7 +31,8 @@ namespace llarp
if(sz == size())
{
// is raw buffer
f.read((char*)data(), 64);
std::copy(std::istream_iterator< byte_t >(f),
std::istream_iterator< byte_t >(), begin());
return true;
}
byte_t tmp[128];

@ -40,49 +40,135 @@ static constexpr uint32_t PATHIDSIZE = 16;
namespace llarp
{
using SharedSecret = AlignedBuffer< SHAREDKEYSIZE >;
using KeyExchangeNonce = AlignedBuffer< 32 >;
struct PubKey final : public AlignedBuffer< PUBKEYSIZE >
{
PubKey() : AlignedBuffer< SIZE >()
{
}
explicit PubKey(const byte_t *ptr) : AlignedBuffer< SIZE >(ptr)
{
}
explicit PubKey(const Data &data) : AlignedBuffer< SIZE >(data)
{
}
explicit PubKey(const AlignedBuffer< SIZE > &other)
: AlignedBuffer< SIZE >(other)
{
}
std::string
ToString() const;
bool
FromString(const std::string &str);
friend std::ostream &
operator<<(std::ostream &out, const PubKey &k)
{
return out << k.ToString();
}
operator RouterID() const
{
return RouterID(as_array());
}
PubKey &
operator=(const byte_t *ptr)
{
std::copy(ptr, ptr + SIZE, begin());
return *this;
}
};
struct SecretKey final : public AlignedBuffer< SECKEYSIZE >
{
friend std::ostream &
operator<<(std::ostream &out, const SecretKey &)
{
// make sure we never print out secret keys
return out << "[secretkey]";
}
PubKey
toPublic() const
{
return PubKey(data() + 32);
}
bool
LoadFromFile(const char *fname);
bool
SaveToFile(const char *fname) const;
SecretKey &
operator=(const byte_t *ptr)
{
std::copy(ptr, ptr + SIZE, begin());
return *this;
}
};
using ShortHash = AlignedBuffer< SHORTHASHSIZE >;
using Signature = AlignedBuffer< SIGSIZE >;
using TunnelNonce = AlignedBuffer< TUNNONCESIZE >;
using SymmNonce = AlignedBuffer< NONCESIZE >;
using SymmKey = AlignedBuffer< 32 >;
using PQCipherBlock = AlignedBuffer< PQ_CIPHERTEXTSIZE + 1 >;
using PQPubKey = AlignedBuffer< PQ_PUBKEYSIZE >;
using PQKeyPair = AlignedBuffer< PQ_KEYPAIRSIZE >;
/// label functors
/// PKE(result, publickey, secretkey, nonce)
using path_dh_func = std::function< bool(byte_t *, const byte_t *,
const byte_t *, const byte_t *) >;
using path_dh_func = std::function< bool(
SharedSecret &, const PubKey &, const SecretKey &, const TunnelNonce &) >;
/// TKE(result, publickey, secretkey, nonce)
using transport_dh_func = std::function< bool(
byte_t *, const byte_t *, const byte_t *, const byte_t *) >;
SharedSecret &, const PubKey &, const SecretKey &, const TunnelNonce &) >;
/// SD/SE(buffer, key, nonce)
using sym_cipher_func =
std::function< bool(llarp_buffer_t, const byte_t *, const byte_t *) >;
using sym_cipher_func = std::function< bool(
llarp_buffer_t, const SharedSecret &, const TunnelNonce &) >;
/// SD/SE(dst, src, key, nonce)
using sym_ciper_alt_func = std::function< bool(
llarp_buffer_t, llarp_buffer_t, const byte_t *, const byte_t *) >;
using sym_cipher_alt_func = std::function< bool(
llarp_buffer_t, llarp_buffer_t, const SharedSecret &, const byte_t *) >;
/// H(result, body)
using hash_func = std::function< bool(byte_t *, llarp_buffer_t) >;
/// SH(result, body)
using shorthash_func = std::function< bool(byte_t *, llarp_buffer_t) >;
using shorthash_func = std::function< bool(ShortHash &, llarp_buffer_t) >;
/// MDS(result, body, shared_secret)
using hmac_func =
std::function< bool(byte_t *, llarp_buffer_t, const byte_t *) >;
std::function< bool(byte_t *, llarp_buffer_t, const SharedSecret &) >;
/// S(sig, secretkey, body)
using sign_func =
std::function< bool(byte_t *, const byte_t *, llarp_buffer_t) >;
std::function< bool(Signature &, const SecretKey &, llarp_buffer_t) >;
/// V(pubkey, body, sig)
using verify_func =
std::function< bool(const byte_t *, llarp_buffer_t, const byte_t *) >;
std::function< bool(const PubKey &, llarp_buffer_t, const Signature &) >;
/// library crypto configuration
struct Crypto
{
/// xchacha symettric cipher
/// xchacha symmetric cipher
sym_cipher_func xchacha20;
/// xchacha symettric cipher (multibuffer)
sym_ciper_alt_func xchacha20_alt;
/// xchacha symmetric cipher (multibuffer)
sym_cipher_alt_func xchacha20_alt;
/// path dh creator's side
path_dh_func dh_client;
/// path dh relay side
@ -106,15 +192,17 @@ namespace llarp
/// randomizer memory
std::function< void(void *, size_t) > randbytes;
/// generate signing keypair
std::function< void(byte_t *) > identity_keygen;
std::function< void(SecretKey &) > identity_keygen;
/// generate encryption keypair
std::function< void(byte_t *) > encryption_keygen;
std::function< void(SecretKey &) > encryption_keygen;
/// generate post quantum encrytion key
std::function< void(byte_t *) > pqe_keygen;
std::function< void(PQKeyPair &) > pqe_keygen;
/// post quantum decrypt (buffer, sharedkey_dst, sec)
std::function< bool(const byte_t *, byte_t *, const byte_t *) > pqe_decrypt;
std::function< bool(const PQCipherBlock &, SharedSecret &, const byte_t *) >
pqe_decrypt;
/// post quantum encrypt (buffer, sharedkey_dst, pub)
std::function< bool(byte_t *, byte_t *, const byte_t *) > pqe_encrypt;
std::function< bool(PQCipherBlock &, SharedSecret &, const PQPubKey &) >
pqe_encrypt;
// Give a basic type tag for the constructor to pick libsodium
struct sodium
@ -129,79 +217,13 @@ namespace llarp
randint();
const byte_t *
seckey_topublic(const byte_t *secret);
seckey_topublic(const SecretKey &secret);
const byte_t *
pq_keypair_to_public(const byte_t *keypair);
pq_keypair_to_public(const PQKeyPair &keypair);
const byte_t *
pq_keypair_to_secret(const byte_t *keypair);
using SharedSecret = AlignedBuffer< SHAREDKEYSIZE >;
using KeyExchangeNonce = AlignedBuffer< 32 >;
struct PubKey final : public AlignedBuffer< PUBKEYSIZE >
{
PubKey() : AlignedBuffer< PUBKEYSIZE >(){};
PubKey(const byte_t *ptr) : AlignedBuffer< PUBKEYSIZE >(ptr){};
std::string
ToString() const;
bool
FromString(const std::string &str);
friend std::ostream &
operator<<(std::ostream &out, const PubKey &k)
{
return out << k.ToString();
}
operator RouterID() const
{
return RouterID(data());
}
PubKey &
operator=(const byte_t *ptr)
{
memcpy(data(), ptr, size());
return *this;
}
};
struct SecretKey final : public AlignedBuffer< SECKEYSIZE >
{
friend std::ostream &
operator<<(std::ostream &out, const SecretKey &)
{
// make sure we never print out secret keys
return out << "[secretkey]";
}
bool
LoadFromFile(const char *fname);
bool
SaveToFile(const char *fname) const;
SecretKey &
operator=(const byte_t *ptr)
{
memcpy(data(), ptr, size());
return *this;
}
};
using ShortHash = AlignedBuffer< SHORTHASHSIZE >;
using Signature = AlignedBuffer< SIGSIZE >;
using TunnelNonce = AlignedBuffer< TUNNONCESIZE >;
using SymmNonce = AlignedBuffer< NONCESIZE >;
using SymmKey = AlignedBuffer< 32 >;
using PQCipherBlock = AlignedBuffer< PQ_CIPHERTEXTSIZE + 1 >;
using PQPubKey = AlignedBuffer< PQ_PUBKEYSIZE >;
using PQKeyPair = AlignedBuffer< PQ_KEYPAIRSIZE >;
pq_keypair_to_secret(const PQKeyPair &keypair);
} // namespace llarp

@ -18,48 +18,51 @@ namespace llarp
namespace sodium
{
static bool
xchacha20(llarp_buffer_t buff, const byte_t *k, const byte_t *n)
xchacha20(llarp_buffer_t buff, const SharedSecret &k, const TunnelNonce &n)
{
return crypto_stream_xchacha20_xor(buff.base, buff.base, buff.sz, n, k)
return crypto_stream_xchacha20_xor(buff.base, buff.base, buff.sz,
n.data(), k.data())
== 0;
}
static bool
xchacha20_alt(llarp_buffer_t out, llarp_buffer_t in, const byte_t *k,
xchacha20_alt(llarp_buffer_t out, llarp_buffer_t in, const SharedSecret &k,
const byte_t *n)
{
if(in.sz > out.sz)
return false;
return crypto_stream_xchacha20_xor(out.base, in.base, in.sz, n, k) == 0;
return crypto_stream_xchacha20_xor(out.base, in.base, in.sz, n, k.data())
== 0;
}
static bool
dh(uint8_t *out, const uint8_t *client_pk, const uint8_t *server_pk,
const uint8_t *themPub, const uint8_t *usSec)
dh(llarp::SharedSecret &out, const PubKey &client_pk,
const PubKey &server_pk, const uint8_t *themPub, const SecretKey &usSec)
{
llarp::SharedSecret shared;
crypto_generichash_state h;
const size_t outsz = SHAREDKEYSIZE;
if(crypto_scalarmult_curve25519(shared, usSec, themPub))
if(crypto_scalarmult_curve25519(shared.data(), usSec.data(), themPub))
return false;
crypto_generichash_blake2b_init(&h, nullptr, 0U, outsz);
crypto_generichash_blake2b_update(&h, client_pk, 32);
crypto_generichash_blake2b_update(&h, server_pk, 32);
crypto_generichash_blake2b_update(&h, shared, 32);
crypto_generichash_blake2b_final(&h, out, outsz);
crypto_generichash_blake2b_update(&h, client_pk.data(), 32);
crypto_generichash_blake2b_update(&h, server_pk.data(), 32);
crypto_generichash_blake2b_update(&h, shared.data(), 32);
crypto_generichash_blake2b_final(&h, out.data(), outsz);
return true;
}
static bool
dh_client(uint8_t *shared, const uint8_t *pk, const uint8_t *sk,
const uint8_t *n)
dh_client(llarp::SharedSecret &shared, const PubKey &pk,
const SecretKey &sk, const TunnelNonce &n)
{
llarp::SharedSecret dh_result;
if(dh(dh_result, llarp::seckey_topublic(sk), pk, pk, sk))
if(dh(dh_result, sk.toPublic(), pk, pk.data(), sk))
{
return crypto_generichash_blake2b(shared, 32, n, 32, dh_result, 32)
return crypto_generichash_blake2b(shared.data(), 32, n.data(), 32,
dh_result.data(), 32)
!= -1;
}
llarp::LogWarn("crypto::dh_client - dh failed");
@ -67,13 +70,14 @@ namespace llarp
}
static bool
dh_server(uint8_t *shared, const uint8_t *pk, const uint8_t *sk,
const uint8_t *n)
dh_server(llarp::SharedSecret &shared, const PubKey &pk,
const SecretKey &sk, const TunnelNonce &n)
{
llarp::SharedSecret dh_result;
if(dh(dh_result, pk, llarp::seckey_topublic(sk), pk, sk))
if(dh(dh_result, pk, sk.toPublic(), pk.data(), sk))
{
return crypto_generichash_blake2b(shared, 32, n, 32, dh_result, 32)
return crypto_generichash_blake2b(shared.data(), 32, n.data(), 32,
dh_result.data(), 32)
!= -1;
}
llarp::LogWarn("crypto::dh_server - dh failed");
@ -89,32 +93,35 @@ namespace llarp
}
static bool
shorthash(uint8_t *result, llarp_buffer_t buff)
shorthash(ShortHash &result, llarp_buffer_t buff)
{
return crypto_generichash_blake2b(result, SHORTHASHSIZE, buff.base,
buff.sz, nullptr, 0)
return crypto_generichash_blake2b(result.data(), ShortHash::SIZE,
buff.base, buff.sz, nullptr, 0)
!= -1;
}
static bool
hmac(uint8_t *result, llarp_buffer_t buff, const uint8_t *secret)
hmac(byte_t *result, llarp_buffer_t buff, const SharedSecret &secret)
{
return crypto_generichash_blake2b(result, HMACSIZE, buff.base, buff.sz,
secret, HMACSECSIZE)
secret.data(), HMACSECSIZE)
!= -1;
}
static bool
sign(uint8_t *result, const uint8_t *secret, llarp_buffer_t buff)
sign(Signature &result, const SecretKey &secret, llarp_buffer_t buff)
{
return crypto_sign_detached(result, nullptr, buff.base, buff.sz, secret)
!= -1;
int rc = crypto_sign_detached(result.data(), nullptr, buff.base, buff.sz,
secret.data());
return rc != -1;
}
static bool
verify(const uint8_t *pub, llarp_buffer_t buff, const uint8_t *sig)
verify(const PubKey &pub, llarp_buffer_t buff, const Signature &sig)
{
return crypto_sign_verify_detached(sig, buff.base, buff.sz, pub) != -1;
int rc = crypto_sign_verify_detached(sig.data(), buff.base, buff.sz,
pub.data());
return rc != -1;
}
static void
@ -130,56 +137,62 @@ namespace llarp
}
static void
sigkeygen(uint8_t *keys)
sigkeygen(llarp::SecretKey &keys)
{
crypto_sign_keypair(keys + 32, keys);
byte_t *d = keys.data();
crypto_sign_keypair(d + 32, d);
}
static void
enckeygen(uint8_t *keys)
enckeygen(llarp::SecretKey &keys)
{
randombytes(keys, 32);
crypto_scalarmult_curve25519_base(keys + 32, keys);
auto d = keys.data();
randombytes(d, 32);
crypto_scalarmult_curve25519_base(d + 32, d);
}
} // namespace sodium
const byte_t *
seckey_topublic(const byte_t *sec)
seckey_topublic(const SecretKey &sec)
{
return sec + 32;
return sec.data() + 32;
}
namespace pq
{
bool
encrypt(byte_t *ciphertext, byte_t *sharedkey, const byte_t *pubkey)
encrypt(PQCipherBlock &ciphertext, SharedSecret &sharedkey,
const PQPubKey &pubkey)
{
return crypto_kem_enc(ciphertext, sharedkey, pubkey) != -1;
return crypto_kem_enc(ciphertext.data(), sharedkey.data(), pubkey.data())
!= -1;
}
bool
decrypt(const byte_t *ciphertext, byte_t *sharedkey,
decrypt(const PQCipherBlock &ciphertext, SharedSecret &sharedkey,
const byte_t *secretkey)
{
return crypto_kem_dec(sharedkey, ciphertext, secretkey) != -1;
return crypto_kem_dec(sharedkey.data(), ciphertext.data(), secretkey)
!= -1;
}
void
keygen(byte_t *keypair)
keygen(PQKeyPair &keypair)
{
crypto_kem_keypair(keypair + PQ_SECRETKEYSIZE, keypair);
auto d = keypair.data();
crypto_kem_keypair(d + PQ_SECRETKEYSIZE, d);
}
} // namespace pq
const byte_t *
pq_keypair_to_public(const byte_t *k)
pq_keypair_to_public(const PQKeyPair &k)
{
return k + PQ_SECRETKEYSIZE;
return k.data() + PQ_SECRETKEYSIZE;
}
const byte_t *
pq_keypair_to_secret(const byte_t *k)
pq_keypair_to_secret(const PQKeyPair &k)
{
return k;
return k.data();
}
Crypto::Crypto(Crypto::sodium tag)

@ -22,7 +22,7 @@ llarp_dht_context_free(struct llarp_dht_context *ctx)
void
__llarp_dht_remove_peer(struct llarp_dht_context *ctx, const byte_t *id)
{
ctx->impl.nodes->DelNode(id);
ctx->impl.nodes->DelNode(llarp::dht::Key_t(id));
}
void
@ -34,7 +34,7 @@ llarp_dht_allow_transit(llarp_dht_context *ctx)
void
llarp_dht_context_start(struct llarp_dht_context *ctx, const byte_t *key)
{
ctx->impl.Init(key, ctx->parent, 20000);
ctx->impl.Init(llarp::dht::Key_t(key), ctx->parent, 20000);
}
void

@ -57,7 +57,8 @@ namespace llarp
void
Start(const TXOwner &peer) override
{
parent->DHTSendTo(peer.node, new FindRouterMessage(peer.txid));
parent->DHTSendTo(peer.node.as_array(),
new FindRouterMessage(peer.txid));
}
bool
@ -92,8 +93,9 @@ namespace llarp
uint64_t txid = ++ids;
TXOwner peer(askpeer, txid);
TXOwner whoasked(OurKey(), txid);
pendingExploreLookups.NewTX(peer, whoasked, askpeer.data(),
new ExploreNetworkJob(askpeer.data(), this));
pendingExploreLookups.NewTX(
peer, whoasked, askpeer.as_array(),
new ExploreNetworkJob(askpeer.as_array(), this));
}
void
@ -211,8 +213,8 @@ namespace llarp
// is the next peer we ask closer to the target than us?
if((next ^ target) < (ourKey ^ target))
{
// yes it is closer, ask neighboor recursively
LookupRouterRecursive(target.data(), requester, txid, next);
// yes it is closer, ask neighbour recursively
LookupRouterRecursive(target.as_array(), requester, txid, next);
}
else
{
@ -240,7 +242,8 @@ namespace llarp
Context::GetIntroSetByServiceAddress(
const llarp::service::Address &addr) const
{
auto itr = services->nodes.find(addr.data());
auto key = addr.ToKey();
auto itr = services->nodes.find(key);
if(itr == services->nodes.end())
return nullptr;
return &itr->second.introset;
@ -282,7 +285,7 @@ namespace llarp
}
void
Context::DHTSendTo(const byte_t *peer, IMessage *msg, bool keepalive)
Context::DHTSendTo(const RouterID &peer, IMessage *msg, bool keepalive)
{
llarp::DHTImmeidateMessage m;
m.msgs.emplace_back(msg);
@ -343,14 +346,14 @@ namespace llarp
bool
GetNextPeer(Key_t &next, const std::set< Key_t > &exclude) override
{
Key_t k = target.data();
Key_t k = target.ToKey();
return parent->nodes->FindCloseExcluding(k, next, exclude);
}
void
Start(const TXOwner &peer) override
{
parent->DHTSendTo(peer.node,
parent->DHTSendTo(peer.node.as_array(),
new FindIntroMessage(peer.txid, target, R));
}
@ -371,7 +374,7 @@ namespace llarp
if(handleResult)
handleResult(valuesFound);
parent->DHTSendTo(whoasked.node,
parent->DHTSendTo(whoasked.node.as_array(),
new GotIntroMessage(valuesFound, whoasked.txid));
}
};
@ -392,8 +395,8 @@ namespace llarp
void
SendReply() override
{
auto path =
parent->router->paths.GetByUpstream(parent->OurKey(), localPath);
auto path = parent->router->paths.GetByUpstream(
parent->OurKey().as_array(), localPath);
if(!path)
{
llarp::LogWarn(
@ -460,7 +463,7 @@ namespace llarp
std::vector< Key_t > exclude;
for(const auto &router : dontTell)
exclude.push_back(router);
parent->DHTSendTo(peer.node,
parent->DHTSendTo(peer.node.as_array(),
new PublishIntroMessage(I, peer.txid, S, exclude));
}
@ -550,7 +553,7 @@ namespace llarp
void
Start(const TXOwner &peer) override
{
parent->DHTSendTo(peer.node,
parent->DHTSendTo(peer.node.as_array(),
new FindIntroMessage(target, peer.txid, R));
}
@ -587,7 +590,7 @@ namespace llarp
{
values.push_back(introset);
}
parent->DHTSendTo(whoasked.node,
parent->DHTSendTo(whoasked.node.as_array(),
new GotIntroMessage(values, whoasked.txid));
}
};
@ -619,8 +622,8 @@ namespace llarp
void
SendReply() override
{
auto path =
parent->router->paths.GetByUpstream(parent->OurKey(), localPath);
auto path = parent->router->paths.GetByUpstream(
parent->OurKey().as_array(), localPath);
if(!path)
{
llarp::LogWarn(
@ -657,7 +660,7 @@ namespace llarp
std::vector< std::unique_ptr< IMessage > > &reply)
{
std::vector< RouterID > closer;
Key_t t(target.data());
Key_t t(target.as_array());
std::set< Key_t > found;
if(!nodes)
return false;
@ -686,7 +689,7 @@ namespace llarp
return false;
}
for(const auto &f : found)
closer.emplace_back(f.data());
closer.emplace_back(f.as_array());
reply.emplace_back(new GotRouterMessage(txid, closer, false));
return true;
}
@ -728,7 +731,7 @@ namespace llarp
void
Start(const TXOwner &peer) override
{
parent->DHTSendTo(peer.node, new FindRouterMessage(peer.txid, target));
parent->DHTSendTo(peer.node.as_array(), new FindRouterMessage(peer.txid, target));
}
virtual void
@ -741,7 +744,7 @@ namespace llarp
else
{
parent->DHTSendTo(
whoasked.node,
whoasked.node.as_array(),
new GotRouterMessage({}, whoasked.txid, valuesFound, false));
}
}
@ -762,8 +765,8 @@ namespace llarp
void
SendReply() override
{
auto path =
parent->router->paths.GetByUpstream(parent->OurKey(), localPath);
auto path = parent->router->paths.GetByUpstream(
parent->OurKey().as_array(), localPath);
if(!path)
{
llarp::LogWarn(

@ -100,7 +100,7 @@ namespace llarp
if(next)
{
// explicit next peer provided
peer = next->data();
peer = *next;
}
else if(!GetNextPeer(peer, peersAsked))
{
@ -109,7 +109,7 @@ namespace llarp
return false;
}
const Key_t targetKey = target.data();
const Key_t targetKey{target};
if((prevPeer ^ targetKey) < (peer ^ targetKey))
{
// next peer is not closer
@ -118,7 +118,9 @@ namespace llarp
return false;
}
else
{
peersAsked.insert(peer);
}
DoNextRequest(peer);
return true;
}
@ -166,7 +168,7 @@ namespace llarp
LookupRouter(const RouterID& target, RouterLookupHandler result)
{
Key_t askpeer;
if(!nodes->FindClosest(target.data(), askpeer))
if(!nodes->FindClosest(Key_t(target), askpeer))
return false;
LookupRouterRecursive(target, OurKey(), 0, askpeer, result);
return true;
@ -203,7 +205,7 @@ namespace llarp
/// send a dht message to peer, if keepalive is true then keep the session
/// with that peer alive for 10 seconds
void
DHTSendTo(const byte_t* peer, IMessage* msg, bool keepalive = true);
DHTSendTo(const RouterID& peer, IMessage* msg, bool keepalive = true);
/// get routers closest to target excluding requester
bool
@ -260,7 +262,7 @@ namespace llarp
Bucket< ISNode >* services = nullptr;
bool allowTransit = false;
const byte_t*
const Key_t&
OurKey() const
{
return ourKey;

@ -18,7 +18,8 @@ namespace llarp
DHTImmeidateMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t *buf)
{
if(llarp_buffer_eq(key, "m"))
return llarp::dht::DecodeMesssageList(session->GetPubKey(), buf, msgs);
return llarp::dht::DecodeMesssageList(dht::Key_t(session->GetPubKey()),
buf, msgs);
if(llarp_buffer_eq(key, "v"))
{
if(!bencode_read_integer(buf, &version))

@ -117,7 +117,7 @@ namespace llarp
if(R == 0)
{
// we don't have it
Key_t target = S.data();
Key_t target = S.ToKey();
Key_t closer;
// find closer peer
if(!dht.nodes->FindClosest(target, closer))
@ -131,7 +131,7 @@ namespace llarp
else
{
Key_t us = dht.OurKey();
Key_t target = S.data();
Key_t target = S.ToKey();
// we are recursive
if(dht.nodes->FindCloseExcluding(target, peer, exclude))
{

@ -16,26 +16,25 @@ namespace llarp
auto &dht = ctx->impl;
/// lookup for us, send an immeidate reply
Key_t us = dht.OurKey();
Key_t k{K};
if(K == us)
{
auto path = dht.router->paths.GetByUpstream(K, pathID);
if(path)
{
replies.emplace_back(
new GotRouterMessage(K.data(), txid, {dht.router->rc()}, false));
new GotRouterMessage(k, txid, {dht.router->rc()}, false));
return true;
}
return false;
}
Key_t peer;
Key_t k = K.data();
// check if we know this in our nodedb first
RouterContact found;
if(dht.router->nodedb->Get(K, found))
{
replies.emplace_back(
new GotRouterMessage(K.data(), txid, {found}, false));
replies.emplace_back(new GotRouterMessage(k, txid, {found}, false));
return true;
}
// lookup if we don't have it in our nodedb
@ -124,7 +123,7 @@ namespace llarp
if(strbuf.sz != K.size())
return false;
memcpy(K.data(), strbuf.base, K.size());
std::copy(strbuf.base, strbuf.base + K.SIZE, K.begin());
return true;
}
if(llarp_buffer_eq(key, "T"))
@ -156,16 +155,16 @@ namespace llarp
return false;
}
RouterContact found;
Key_t k{K};
if(exploritory)
return dht.HandleExploritoryRouterLookup(From, txid, K, replies);
else if(dht.router->nodedb->Get(K, found))
{
replies.emplace_back(
new GotRouterMessage(K.data(), txid, {found}, false));
replies.emplace_back(new GotRouterMessage(k, txid, {found}, false));
return true;
}
else
dht.LookupRouterRelayed(From, txid, K.data(), !iterative, replies);
dht.LookupRouterRelayed(From, txid, k, !iterative, replies);
return true;
}
} // namespace dht

@ -99,7 +99,7 @@ namespace llarp
dht.pendingExploreLookups.NotFound(owner, K);
else
{
dht.pendingExploreLookups.Found(owner, From.data(), N);
dht.pendingExploreLookups.Found(owner, From.as_array(), N);
}
return true;
}

@ -9,18 +9,22 @@ namespace llarp
{
namespace dht
{
struct Key_t : public llarp::AlignedBuffer< 32 >
struct Key_t : public AlignedBuffer< 32 >
{
Key_t(const byte_t* buf) : llarp::AlignedBuffer< SIZE >(buf)
explicit Key_t(const byte_t* buf) : AlignedBuffer< SIZE >(buf)
{
}
Key_t(const std::array< byte_t, SIZE >& val)
: llarp::AlignedBuffer< SIZE >(val)
explicit Key_t(const Data& val) : AlignedBuffer< SIZE >(val)
{
}
Key_t() : llarp::AlignedBuffer< SIZE >()
explicit Key_t(const AlignedBuffer< SIZE >& val)
: AlignedBuffer< SIZE >(val)
{
}
Key_t() : AlignedBuffer< SIZE >()
{
}
@ -28,8 +32,7 @@ namespace llarp
operator^(const Key_t& other) const
{
Key_t dist;
std::transform(as_array().begin(), as_array().end(),
other.as_array().begin(), dist.as_array().begin(),
std::transform(begin(), end(), other.begin(), dist.begin(),
std::bit_xor< byte_t >());
return dist;
}

@ -20,10 +20,8 @@ namespace llarp
ID.Zero();
}
RCNode(const llarp::RouterContact& other)
RCNode(const llarp::RouterContact& other) : rc(other), ID(other.pubkey)
{
rc = other;
ID = other.pubkey.data();
}
bool
@ -47,7 +45,7 @@ namespace llarp
ISNode(const llarp::service::IntroSet& other)
{
introset = other;
introset.A.CalculateAddress(ID);
introset.A.CalculateAddress(ID.as_array());
}
bool

@ -65,7 +65,7 @@ namespace llarp
return true;
}
llarp::dht::Key_t addr;
if(!I.A.CalculateAddress(addr))
if(!I.A.CalculateAddress(addr.as_array()))
{
llarp::LogWarn(
"failed to calculate hidden service address for PubIntro message");

@ -41,12 +41,12 @@ decode_request_name(const std::string &name, llarp::AlignedBuffer< 32 > &addr,
auto pos = name.find(".snode");
if(pos != std::string::npos)
{
if(!llarp::HexDecode(name.substr(0, pos).c_str(), serviceAddr.data().data(),
if(!llarp::HexDecode(name.substr(0, pos).c_str(), serviceAddr.begin(),
serviceAddr.size()))
{
return false;
}
addr = snodeAddr.data();
addr = snodeAddr;
isSNode = true;
}
else
@ -55,7 +55,7 @@ decode_request_name(const std::string &name, llarp::AlignedBuffer< 32 > &addr,
{
return false;
}
addr = serviceAddr.data().data();
addr = serviceAddr;
isSNode = false;
}
return true;
@ -330,7 +330,7 @@ ReverseHandlerIter(struct llarp::service::Context::endpoint_iter *endpointCfg)
}
else
{
llarp::service::Address saddr = addr.data();
llarp::service::Address saddr(addr);
// llarp::LogInfo("Returning [", saddr.ToString(), "]");
writesend_dnss_revresponse(saddr.ToString(), context->request);
}
@ -448,7 +448,7 @@ llarp_dotlokilookup_handler(std::string name,
auto tun = routerHiddenServiceContext->getFirstTun();
if(isSNode)
{
if(tun->HasPathToSNode(addr.data()))
if(tun->HasPathToSNode(addr.as_array()))
{
llarp_dotlokilookup_checkQuery(qr, 0, 0);
response->dontSendResponse = true; // will send it shortly
@ -457,7 +457,7 @@ llarp_dotlokilookup_handler(std::string name,
}
else
{
if(tun->HasPathToService(addr.data()))
if(tun->HasPathToService(llarp::service::Address(addr)))
{
llarp_dotlokilookup_checkQuery(qr, 0, 0);
response->dontSendResponse = true; // will send it shortly

@ -14,16 +14,4 @@ namespace llarp
return input - 'a' + 10;
return 0;
}
bool
HexDecode(const char* src, uint8_t* target, size_t sz)
{
while(*src && src[1] && sz)
{
*(target++) = char2int(*src) * 16 + char2int(src[1]);
src += 2;
--sz;
}
return sz == 0;
}
} // namespace llarp

@ -133,8 +133,19 @@ namespace llarp
int
char2int(char input);
template < typename OutputIt >
bool
HexDecode(const char* src, uint8_t* target, size_t sz);
HexDecode(const char* src, OutputIt target, size_t sz)
{
while(*src && src[1] && sz)
{
*(target++) = char2int(*src) * 16 + char2int(src[1]);
src += 2;
--sz;
}
return sz == 0;
}
} // namespace llarp
#endif

@ -6,8 +6,8 @@
namespace llarp
{
bool
EncryptedFrame::EncryptInPlace(const byte_t* ourSecretKey,
const byte_t* otherPubkey,
EncryptedFrame::EncryptInPlace(const SecretKey& ourSecretKey,
const PubKey& otherPubkey,
llarp::Crypto* crypto)
{
// format of frame is
@ -16,10 +16,10 @@ namespace llarp
// <32 bytes pubkey>
// <N bytes encrypted payload>
//
byte_t* hash = data();
byte_t* nonce = hash + SHORTHASHSIZE;
byte_t* pubkey = nonce + TUNNONCESIZE;
byte_t* body = pubkey + PUBKEYSIZE;
byte_t* hash = data();
byte_t* noncePtr = hash + SHORTHASHSIZE;
byte_t* pubkey = noncePtr + TUNNONCESIZE;
byte_t* body = pubkey + PUBKEYSIZE;
SharedSecret shared;
@ -33,9 +33,10 @@ namespace llarp
buf.sz = size() - EncryptedFrameOverheadSize;
// set our pubkey
memcpy(pubkey, llarp::seckey_topublic(ourSecretKey), PUBKEYSIZE);
memcpy(pubkey, ourSecretKey.toPublic().data(), PUBKEYSIZE);
// randomize nonce
crypto->randbytes(nonce, TUNNONCESIZE);
crypto->randbytes(noncePtr, TUNNONCESIZE);
TunnelNonce nonce(noncePtr);
// derive shared key
if(!DH(shared, otherPubkey, ourSecretKey, nonce))
@ -52,20 +53,20 @@ namespace llarp
}
// generate message auth
buf.base = nonce;
buf.base = noncePtr;
buf.cur = buf.base;
buf.sz = size() - SHORTHASHSIZE;
if(!MDS(hash, buf, shared))
{
llarp::LogError("Failed to generate messgae auth");
llarp::LogError("Failed to generate message auth");
return false;
}
return true;
}
bool
EncryptedFrame::DecryptInPlace(const byte_t* ourSecretKey,
EncryptedFrame::DecryptInPlace(const SecretKey& ourSecretKey,
llarp::Crypto* crypto)
{
// format of frame is
@ -74,23 +75,18 @@ namespace llarp
// <32 bytes pubkey>
// <N bytes encrypted payload>
//
byte_t* hash = data();
byte_t* nonce = hash + SHORTHASHSIZE;
byte_t* otherPubkey = nonce + TUNNONCESIZE;
byte_t* body = otherPubkey + PUBKEYSIZE;
ShortHash hash(data());
byte_t* noncePtr = data() + SHORTHASHSIZE;
byte_t* body = data() + EncryptedFrameOverheadSize;
TunnelNonce nonce(noncePtr);
PubKey otherPubkey(noncePtr + TUNNONCESIZE);
// use dh_server becuase we are not the creator of this message
// use dh_server because we are not the creator of this message
auto DH = crypto->dh_server;
auto Decrypt = crypto->xchacha20;
auto MDS = crypto->hmac;
llarp_buffer_t buf;
buf.base = nonce;
buf.cur = buf.base;
buf.sz = size() - SHORTHASHSIZE;
SharedSecret shared;
ShortHash digest;
if(!DH(shared, otherPubkey, ourSecretKey, nonce))
{
@ -98,13 +94,19 @@ namespace llarp
return false;
}
if(!MDS(digest, buf, shared))
llarp_buffer_t buf;
buf.base = noncePtr;
buf.cur = buf.base;
buf.sz = size() - SHORTHASHSIZE;
ShortHash digest;
if(!MDS(digest.data(), buf, shared))
{
llarp::LogError("Digest failed");
return false;
}
if(memcmp(digest, hash, digest.size()))
if(!std::equal(digest.begin(), digest.end(), hash.begin()))
{
llarp::LogError("message authentication failed");
return false;

@ -38,14 +38,14 @@ namespace llarp
}
bool
DecryptInPlace(const byte_t* seckey, llarp::Crypto* crypto);
DecryptInPlace(const SecretKey& seckey, llarp::Crypto* crypto);
bool
EncryptInPlace(const byte_t* seckey, const byte_t* other,
EncryptInPlace(const SecretKey& seckey, const PubKey& other,
llarp::Crypto* crypto);
};
/// TOOD: can only handle 1 frame at a time
/// TODO: can only handle 1 frame at a time
template < typename User >
struct AsyncFrameEncrypter
{
@ -92,7 +92,7 @@ namespace llarp
}
};
/// TOOD: can only handle 1 frame at a time
/// TODO: can only handle 1 frame at a time
template < typename User >
struct AsyncFrameDecrypter
{
@ -114,7 +114,7 @@ namespace llarp
ctx->result(nullptr, ctx->context);
}
AsyncFrameDecrypter(llarp::Crypto* c, const byte_t* secretkey,
AsyncFrameDecrypter(llarp::Crypto* c, const SecretKey& secretkey,
DecryptHandler h)
: result(h), crypto(c), seckey(secretkey)
{
@ -123,7 +123,7 @@ namespace llarp
DecryptHandler result;
User* context;
llarp::Crypto* crypto;
const byte_t* seckey;
const SecretKey& seckey;
EncryptedFrame target;
void

@ -6,21 +6,6 @@ namespace llarp
{
namespace routing
{
ObtainExitMessage&
ObtainExitMessage::operator=(const ObtainExitMessage& other)
{
B = other.B;
E = other.E;
I = other.I;
T = other.T;
W = other.W;
X = other.X;
version = other.version;
S = other.S;
Z = other.Z;
return *this;
}
bool
ObtainExitMessage::Sign(llarp::Crypto* c, const llarp::SecretKey& sk)
{
@ -29,7 +14,9 @@ namespace llarp
I = llarp::seckey_topublic(sk);
Z.Zero();
if(!BEncode(&buf))
{
return false;
}
buf.sz = buf.cur - buf.base;
return c->sign(Z, sk, buf);
}
@ -43,7 +30,9 @@ namespace llarp
copy = *this;
copy.Z.Zero();
if(!copy.BEncode(&buf))
{
return false;
}
// rewind buffer
buf.sz = buf.cur - buf.base;
return c->verify(I, buf, Z);

@ -35,10 +35,12 @@ namespace llarp
// check 30 seconds into the future and see if we need more paths
const llarp_time_t future = now + (30 * 1000);
if(NumPathsExistingAt(future) < expect)
return llarp::randint() % 4 == 0; // 25% chance for build if we will run out soon
// if we don't have the expended number of paths right now try building some if the cooldown timer isn't hit
return llarp::randint() % 4
== 0; // 25% chance for build if we will run out soon
// if we don't have the expended number of paths right now try building
// some if the cooldown timer isn't hit
if(AvailablePaths(llarp::path::ePathRoleExit) < expect)
return !path::Builder::BuildCooldownHit(now);
return !path::Builder::BuildCooldownHit(now);
// maintain regular number of paths
return path::Builder::ShouldBuildMore(now);
}

@ -96,7 +96,8 @@ namespace llarp
if(r.FromString(msg.questions[0].qname))
{
huint32_t ip;
if(m_SNodeKeys.find(r.data()) == m_SNodeKeys.end())
PubKey pubKey(r);
if(m_SNodeKeys.find(pubKey) == m_SNodeKeys.end())
{
// we do not have it mapped
// map it
@ -106,7 +107,7 @@ namespace llarp
else
{
// we have it mapped already as a service node
auto itr = m_KeyToIP.find(r.data());
auto itr = m_KeyToIP.find(pubKey);
if(itr != m_KeyToIP.end())
{
ip = itr->second;
@ -194,7 +195,7 @@ namespace llarp
{
if(!itr->second->Flush())
{
llarp::LogWarn("failed to flushsnode traffic to ", itr->first,
llarp::LogWarn("failed to flush snode traffic to ", itr->first,
" via outbound session");
}
++itr;
@ -485,18 +486,19 @@ namespace llarp
huint32_t
ExitEndpoint::ObtainServiceNodeIP(const llarp::RouterID &other)
{
huint32_t ip = GetIPForIdent(other.data());
if(m_SNodeKeys.insert(other.data()).second)
PubKey pubKey(other);
huint32_t ip = GetIPForIdent(pubKey);
if(m_SNodeKeys.emplace(pubKey).second)
{
// this is a new service node make an outbound session to them
m_SNodeSessions.insert(
std::make_pair(other,
std::unique_ptr< llarp::exit::SNodeSession >(
new llarp::exit::SNodeSession(
other,
std::bind(&ExitEndpoint::QueueSNodePacket,
this, std::placeholders::_1, ip),
Router(), 2, 1, true))));
m_SNodeSessions.emplace(
other,
std::unique_ptr< llarp::exit::SNodeSession >(
new llarp::exit::SNodeSession(
other,
std::bind(&ExitEndpoint::QueueSNodePacket, this,
std::placeholders::_1, ip),
Router(), 2, 1, true)));
}
return ip;
}
@ -509,16 +511,15 @@ namespace llarp
if(wantInternet && !m_PermitExit)
return false;
huint32_t ip = GetIPForIdent(pk);
if(Router()->paths.TransitHopPreviousIsRouter(path, pk.data()))
if(Router()->paths.TransitHopPreviousIsRouter(path, pk.as_array()))
{
// we think this path belongs to a service node
// mark it as such so we don't make an outbound session to them
m_SNodeKeys.insert(pk.data());
m_SNodeKeys.emplace(pk.as_array());
}
m_ActiveExits.insert(
std::make_pair(pk,
std::make_unique< llarp::exit::Endpoint >(
pk, path, !wantInternet, ip, this)));
m_ActiveExits.emplace(pk,
std::make_unique< llarp::exit::Endpoint >(
pk, path, !wantInternet, ip, this));
m_Paths[path] = pk;
return HasLocalMappedAddrFor(pk);

@ -19,13 +19,13 @@ namespace llarp
}
huint32_t
ObtainIPForAddr(const byte_t *, bool) override
ObtainIPForAddr(const AlignedBuffer< 32 > &, bool) override
{
return {0};
}
bool
HasAddress(const byte_t *) const override
HasAddress(const AlignedBuffer< 32 > &) const override
{
return false;
}

@ -59,7 +59,7 @@ namespace llarp
{
llarp::RouterID exitRouter;
if(!(exitRouter.FromString(v)
|| HexDecode(v.c_str(), exitRouter, exitRouter.size())))
|| HexDecode(v.c_str(), exitRouter.begin(), exitRouter.size())))
{
llarp::LogError(Name(), " bad exit router key: ", v);
return false;
@ -226,9 +226,9 @@ namespace llarp
}
else if(addr.FromString(qname, ".loki"))
{
if(HasAddress(addr.data().data()))
if(HasAddress(addr))
{
huint32_t ip = ObtainIPForAddr(addr.data().data(), false);
huint32_t ip = ObtainIPForAddr(addr, false);
msg.AddINReply(ip);
}
else
@ -242,8 +242,8 @@ namespace llarp
else if(addr.FromString(qname, ".snode"))
{
// TODO: add hook to EnsurePathToSNode
EnsurePathToSNode(addr.data().data());
huint32_t ip = ObtainIPForAddr(addr.data().data(), true);
EnsurePathToSNode(addr.as_array());
huint32_t ip = ObtainIPForAddr(addr, true);
msg.AddINReply(ip);
}
else
@ -261,8 +261,8 @@ namespace llarp
reply(msg);
return true;
}
llarp::service::Address addr =
ObtainAddrForIP< llarp::service::Address >(ip, true);
llarp::service::Address addr(
ObtainAddrForIP< llarp::service::Address >(ip, true));
if(!addr.IsZero())
{
msg.AddAReply(addr.ToString(".snode"));
@ -325,7 +325,7 @@ namespace llarp
{
if(ctx)
{
huint32_t ip = ObtainIPForAddr(addr.data().data(), false);
huint32_t ip = ObtainIPForAddr(addr, false);
request.AddINReply(ip);
}
else
@ -343,14 +343,14 @@ namespace llarp
{
// XXX is calling inet_ntoa safe in this context? it's MP-unsafe
llarp::LogWarn(ip, " already mapped to ",
service::Address(itr->second).ToString());
service::Address(itr->second.as_array()).ToString());
return false;
}
llarp::LogInfo(Name() + " map ", addr.ToString(), " to ", ip);
m_IPToAddr[ip] = addr.data().data();
m_AddrToIP[addr.data().data()] = ip;
m_SNodes[addr.data().data()] = SNode;
m_IPToAddr[ip] = addr;
m_AddrToIP[addr] = ip;
m_SNodes[addr] = SNode;
MarkIPActiveForever(ip);
return true;
}
@ -495,12 +495,12 @@ namespace llarp
if(m_SNodes.at(itr->second))
{
sendFunc = std::bind(&TunEndpoint::SendToSNodeOrQueue, this,
itr->second.data(), std::placeholders::_1);
itr->second.as_array(), std::placeholders::_1);
}
else
{
sendFunc = std::bind(&TunEndpoint::SendToServiceOrQueue, this,
itr->second.data(), std::placeholders::_1,
itr->second.as_array(), std::placeholders::_1,
service::eProtocolTraffic);
}
// prepare packet for insertion into network
@ -555,11 +555,11 @@ namespace llarp
}
huint32_t
TunEndpoint::ObtainIPForAddr(const byte_t *a, bool snode)
TunEndpoint::ObtainIPForAddr(const AlignedBuffer< 32 > &addr, bool snode)
{
llarp_time_t now = Now();
huint32_t nextIP = {0};
AlignedBuffer< 32 > ident(a);
AlignedBuffer< 32 > ident(addr);
{
// previously allocated address
auto itr = m_AddrToIP.find(ident);

@ -111,18 +111,19 @@ namespace llarp
return addr;
}
// found
return itr->second.data();
return Addr{itr->second};
}
bool
HasAddress(const byte_t* addr) const override
HasAddress(const AlignedBuffer< 32 >& addr) const override
{
return m_AddrToIP.find(addr) != m_AddrToIP.end();
}
/// get ip address for key unconditionally
huint32_t
ObtainIPForAddr(const byte_t* addr, bool serviceNode) override;
ObtainIPForAddr(const AlignedBuffer< 32 >& addr,
bool serviceNode) override;
/// flush network traffic
void

@ -3,7 +3,7 @@
namespace llarp
{
ILinkLayer::ILinkLayer(const byte_t* routerEncSecret, GetRCFunc getrc,
ILinkLayer::ILinkLayer(const SecretKey& routerEncSecret, GetRCFunc getrc,
LinkMessageHandler handler, SignBufferFunc signbuf,
SessionEstablishedHandler establishedSession,
SessionRenegotiateHandler reneg,
@ -24,10 +24,10 @@ namespace llarp
}
bool
ILinkLayer::HasSessionTo(const byte_t* pk)
ILinkLayer::HasSessionTo(const RouterID& id)
{
Lock l(m_AuthedLinksMutex);
return m_AuthedLinks.find(pk) != m_AuthedLinks.end();
return m_AuthedLinks.find(id) != m_AuthedLinks.end();
}
void
@ -43,7 +43,7 @@ namespace llarp
}
bool
ILinkLayer::VisitSessionByPubkey(const byte_t* pk,
ILinkLayer::VisitSessionByPubkey(const RouterID& pk,
std::function< bool(ILinkSession*) > visit)
{
auto itr = m_AuthedLinks.find(pk);
@ -124,7 +124,7 @@ namespace llarp
}
void
ILinkLayer::MapAddr(const byte_t* pk, ILinkSession* s)
ILinkLayer::MapAddr(const RouterID& pk, ILinkSession* s)
{
static constexpr size_t MaxSessionsPerKey = 16;
Lock l_authed(m_AuthedLinksMutex);
@ -135,7 +135,7 @@ namespace llarp
if(itr->get() == s)
{
if(m_AuthedLinks.count(pk) < MaxSessionsPerKey)
m_AuthedLinks.insert(std::make_pair(pk, std::move(*itr)));
m_AuthedLinks.emplace(pk, std::move(*itr));
else
s->SendClose();
itr = m_Pending.erase(itr);
@ -168,7 +168,7 @@ namespace llarp
llarp::AddressInfo to;
if(!PickAddress(rc, to))
return false;
llarp::LogInfo("Try establish to ", RouterID(rc.pubkey.data()));
llarp::LogInfo("Try establish to ", RouterID(rc.pubkey.as_array()));
llarp::Addr addr(to);
auto s = NewOutboundSession(rc, to);
s->Start();
@ -210,7 +210,7 @@ namespace llarp
}
void
ILinkLayer::CloseSessionTo(const byte_t* remote)
ILinkLayer::CloseSessionTo(const RouterID& remote)
{
Lock l(m_AuthedLinksMutex);
RouterID r = remote;
@ -225,7 +225,7 @@ namespace llarp
}
void
ILinkLayer::KeepAliveSessionTo(const byte_t* remote)
ILinkLayer::KeepAliveSessionTo(const RouterID& remote)
{
Lock l(m_AuthedLinksMutex);
auto range = m_AuthedLinks.equal_range(remote);
@ -238,7 +238,7 @@ namespace llarp
}
bool
ILinkLayer::SendTo(const byte_t* remote, llarp_buffer_t buf)
ILinkLayer::SendTo(const RouterID& remote, llarp_buffer_t buf)
{
ILinkSession* s = nullptr;
{
@ -279,7 +279,7 @@ namespace llarp
return llarp::seckey_topublic(TransportSecretKey());
}
const byte_t*
const SecretKey&
ILinkLayer::TransportSecretKey() const
{
return m_SecretKey;

@ -42,7 +42,7 @@ namespace llarp
struct ILinkLayer
{
ILinkLayer(const byte_t* routerEncSecret, GetRCFunc getrc,
ILinkLayer(const SecretKey& routerEncSecret, GetRCFunc getrc,
LinkMessageHandler handler, SignBufferFunc signFunc,
SessionEstablishedHandler sessionEstablish,
SessionRenegotiateHandler renegotiate, TimeoutHandler timeout,
@ -57,7 +57,7 @@ namespace llarp
}
bool
HasSessionTo(const byte_t* pk);
HasSessionTo(const RouterID& pk);
bool
HasSessionVia(const Addr& addr);
@ -82,7 +82,7 @@ namespace llarp
llarp::LogWarn("no udp set");
return;
}
// maybe chekc from too?
// maybe check from too?
// no it's never null
static_cast< ILinkLayer* >(udp->user)->RecvFrom(*from, buf.base, buf.sz);
}
@ -116,19 +116,19 @@ namespace llarp
Name() const = 0;
void
CloseSessionTo(const byte_t* remote);
CloseSessionTo(const RouterID& remote);
void
KeepAliveSessionTo(const byte_t* remote);
KeepAliveSessionTo(const RouterID& remote);
bool
SendTo(const byte_t* remote, llarp_buffer_t buf);
SendTo(const RouterID& remote, llarp_buffer_t buf);
bool
GetOurAddressInfo(AddressInfo& addr) const;
bool
VisitSessionByPubkey(const byte_t* pk,
VisitSessionByPubkey(const RouterID& pk,
std::function< bool(ILinkSession*) > visit);
virtual uint16_t
@ -140,13 +140,13 @@ namespace llarp
const byte_t*
TransportPubKey() const;
const byte_t*
const SecretKey&
RouterEncryptionSecret() const
{
return m_RouterEncSecret;
}
const byte_t*
const SecretKey&
TransportSecretKey() const;
bool
@ -156,7 +156,7 @@ namespace llarp
GenEphemeralKeys();
void
MapAddr(const byte_t* pk, ILinkSession* s);
MapAddr(const RouterID& pk, ILinkSession* s);
virtual void Tick(llarp_time_t)
{
@ -187,7 +187,7 @@ namespace llarp
ScheduleTick(uint64_t interval);
uint32_t tick_id;
const byte_t* m_RouterEncSecret;
const SecretKey& m_RouterEncSecret;
protected:
using Lock = util::NullLock;

@ -42,7 +42,7 @@ namespace llarp
std::function< bool(llarp_time_t) > TimedOut;
/// get remote public identity key
std::function< const byte_t *(void) > GetPubKey;
std::function< const PubKey &(void) > GetPubKey;
/// get remote address
std::function< Addr(void) > GetRemoteEndpoint;

@ -126,12 +126,16 @@ namespace llarp
bool
Session::DoKeyExchange(transport_dh_func dh, SharedSecret& K,
const KeyExchangeNonce& n, const PubKey& other,
const byte_t* secret)
const SecretKey& secret)
{
ShortHash t_h;
AlignedBuffer< 64 > tmp;
memcpy(tmp.data(), K, K.size());
memcpy(tmp.data() + K.size(), n, n.size());
static constexpr size_t TMP_SIZE = 64;
static_assert(SharedSecret::SIZE + KeyExchangeNonce::SIZE == TMP_SIZE,
"Invalid sizes");
AlignedBuffer< TMP_SIZE > tmp;
std::copy(K.begin(), K.end(), tmp.begin());
std::copy(n.begin(), n.end(), tmp.begin() + K.size());
// t_h = HS(K + L.n)
if(!Crypto()->shorthash(t_h, ConstBuffer(tmp)))
{
@ -153,10 +157,10 @@ namespace llarp
Session::MutateKey(SharedSecret& K, const AlignedBuffer< 24 >& A)
{
AlignedBuffer< 56 > tmp;
auto buf = llarp::Buffer(tmp);
memcpy(buf.cur, K.data(), K.size());
auto buf = tmp.as_buffer();
std::copy(K.begin(), K.end(), buf.cur);
buf.cur += K.size();
memcpy(buf.cur, A, A.size());
std::copy(A.begin(), A.end(), buf.cur);
buf.cur = buf.base;
return Crypto()->shorthash(K, buf);
}
@ -183,7 +187,7 @@ namespace llarp
// yes it fills it
llarp::LogDebug("process leftovers, offset=", recvBufOffset,
" sz=", s, " left=", left);
memcpy(recvBuf.data() + recvBufOffset, buf, left);
std::copy(buf, buf + left, recvBuf.begin() + recvBufOffset);
s -= left;
recvBufOffset = 0;
buf += left;
@ -205,7 +209,7 @@ namespace llarp
{
// hold onto leftovers
llarp::LogDebug("leftovers sz=", s);
memcpy(recvBuf.data() + recvBufOffset, buf, s);
std::copy(buf, buf + s, recvBuf.begin() + recvBufOffset);
recvBufOffset += s;
}
return true;
@ -342,7 +346,8 @@ namespace llarp
return 0;
}
LinkLayer::LinkLayer(llarp::Crypto* crypto, const byte_t* routerEncSecret,
LinkLayer::LinkLayer(llarp::Crypto* crypto,
const SecretKey& routerEncSecret,
llarp::GetRCFunc getrc, llarp::LinkMessageHandler h,
llarp::SignBufferFunc sign,
llarp::SessionEstablishedHandler established,
@ -525,7 +530,7 @@ namespace llarp
}
std::unique_ptr< ILinkLayer >
NewServer(llarp::Crypto* crypto, const byte_t* routerEncSecret,
NewServer(llarp::Crypto* crypto, const SecretKey& routerEncSecret,
llarp::GetRCFunc getrc, llarp::LinkMessageHandler h,
llarp::SessionEstablishedHandler est,
llarp::SessionRenegotiateHandler reneg,
@ -612,9 +617,9 @@ namespace llarp
remoteTransportPubKey = addr.pubkey;
remoteRC = rc;
RouterID rid = remoteRC.pubkey;
Crypto()->shorthash(txKey, InitBuffer(rid.data(), PUBKEYSIZE));
rid = p->GetOurRC().pubkey.data();
Crypto()->shorthash(rxKey, llarp::InitBuffer(rid.data(), PUBKEYSIZE));
Crypto()->shorthash(txKey, rid.as_buffer());
rid = p->GetOurRC().pubkey;
Crypto()->shorthash(rxKey, rid.as_buffer());
sock = s;
assert(utp_set_userdata(sock, this) == this);
@ -628,7 +633,7 @@ namespace llarp
Session::Session(LinkLayer* p, utp_socket* s, const Addr& addr) : Session(p)
{
RouterID rid = p->GetOurRC().pubkey;
Crypto()->shorthash(rxKey, InitBuffer(rid.data(), PUBKEYSIZE));
Crypto()->shorthash(rxKey, rid.as_buffer());
remoteRC.Clear();
sock = s;
assert(s == sock);
@ -655,8 +660,7 @@ namespace llarp
if(!gotLIM)
{
remoteRC = msg->rc;
Crypto()->shorthash(
txKey, llarp::InitBuffer(remoteRC.pubkey.data(), PUBKEYSIZE));
Crypto()->shorthash(txKey, remoteRC.pubkey.as_buffer());
if(!DoKeyExchange(Crypto()->transport_dh_server, rxKey, msg->N,
remoteRC.enckey, parent->TransportSecretKey()))
@ -753,7 +757,8 @@ namespace llarp
}
EnterState(eSessionReady);
/// future LIM are used for session renegotiation
GotLIM = std::bind(&Session::GotSessionRenegotiate, this,std::placeholders::_1);
GotLIM = std::bind(&Session::GotSessionRenegotiate, this,
std::placeholders::_1);
return true;
}
@ -906,10 +911,10 @@ namespace llarp
vec.iov_base = buf.data();
vec.iov_len = FragmentBufferSize;
buf.Randomize();
byte_t* nonce = buf.data() + FragmentHashSize;
byte_t* body = nonce + FragmentNonceSize;
byte_t* base = body;
AlignedBuffer< 24 > A = base;
byte_t* noncePtr = buf.data() + FragmentHashSize;
byte_t* body = noncePtr + FragmentNonceSize;
byte_t* base = body;
AlignedBuffer< 24 > A(base);
// skip inner nonce
body += A.size();
// put msgid
@ -927,11 +932,13 @@ namespace llarp
auto payload =
InitBuffer(base, FragmentBufferSize - FragmentOverheadSize);
TunnelNonce nonce(noncePtr);
// encrypt
if(!Crypto()->xchacha20(payload, txKey, nonce))
return false;
payload.base = nonce;
payload.base = noncePtr;
payload.cur = payload.base;
payload.sz = FragmentBufferSize - FragmentHashSize;
// key'd hash
@ -947,7 +954,7 @@ namespace llarp
Alive();
if(st == eSessionReady)
{
parent->MapAddr(remoteRC.pubkey.data(), this);
parent->MapAddr(remoteRC.pubkey.as_array(), this);
parent->SessionEstablished(remoteRC);
}
}
@ -1018,7 +1025,7 @@ namespace llarp
auto in = InitBuffer(ptr + FragmentOverheadSize,
FragmentBufferSize - FragmentOverheadSize);
auto out = Buffer(rxFragBody);
llarp_buffer_t out = rxFragBody.as_buffer();
// decrypt
if(!Crypto()->xchacha20_alt(out, in, rxKey, ptr + FragmentHashSize))
@ -1027,7 +1034,7 @@ namespace llarp
return false;
}
// get inner nonce
AlignedBuffer< 24 > A = out.base;
AlignedBuffer< 24 > A(out.base);
// advance buffer
out.cur += A.size();
// read msgid
@ -1074,12 +1081,12 @@ namespace llarp
llarp::LogError("failed to mutate rx key");
return false;
}
if(remaining == 0)
{
// we done with this guy, prune next tick
itr->second.lastActive = 0;
llarp_buffer_t buf = itr->second.buffer;
llarp_buffer_t buf = itr->second.buffer;
// resize
buf.sz = buf.cur - buf.base;
// rewind

@ -55,7 +55,7 @@ namespace llarp
MessageBuffer _msg;
/// for accessing message buffer
llarp_buffer_t buffer = llarp::InitBuffer(_msg.data(), _msg.size());
llarp_buffer_t buffer = _msg.as_buffer();
bool
operator==(const InboundMessage& other) const
@ -208,7 +208,7 @@ namespace llarp
bool
DoKeyExchange(transport_dh_func dh, SharedSecret& K,
const KeyExchangeNonce& n, const PubKey& other,
const byte_t* secret);
const SecretKey& secret);
/// does K = HS(K + A)
bool
@ -283,7 +283,7 @@ namespace llarp
OnLog(utp_callback_arguments* arg);
/// construct
LinkLayer(llarp::Crypto* crypto, const byte_t* routerEncSecret,
LinkLayer(llarp::Crypto* crypto, const SecretKey& routerEncSecret,
llarp::GetRCFunc getrc, llarp::LinkMessageHandler h,
llarp::SignBufferFunc sign,
llarp::SessionEstablishedHandler established,

@ -20,7 +20,7 @@ namespace llarp
llarp_time_t X;
llarp::Signature Z;
ObtainExitMessage() : IMessage()
ObtainExitMessage() : IMessage(), E(0), T(0), X(0)
{
}
@ -28,11 +28,8 @@ namespace llarp
{
}
ObtainExitMessage&
operator=(const ObtainExitMessage& other);
void
Clear() override
Clear() override
{
B.clear();
W.clear();
@ -87,8 +84,10 @@ namespace llarp
bool
HandleMessage(IMessageHandler* h, llarp::Router* r) const override;
void
Clear() override {}
void
Clear() override
{
}
};
struct RejectExitMessage final : public IMessage
@ -108,7 +107,7 @@ namespace llarp
{
}
void
void
Clear() override
{
R.clear();
@ -148,8 +147,10 @@ namespace llarp
{
}
void
Clear() override {}
void
Clear() override
{
}
UpdateExitVerifyMessage&
operator=(const UpdateExitVerifyMessage& other);
@ -204,8 +205,10 @@ namespace llarp
bool
HandleMessage(IMessageHandler* h, llarp::Router* r) const override;
void
Clear() override {}
void
Clear() override
{
}
};
struct CloseExitMessage final : public IMessage
@ -240,9 +243,11 @@ namespace llarp
bool
Verify(llarp::Crypto* c, const llarp::PubKey& pk) const;
void
Clear() override {}
void
Clear() override
{
}
};
} // namespace routing

@ -15,7 +15,7 @@ static const char skiplist_subdirs[] = "0123456789abcdef";
static const std::string RC_FILE_EXT = ".signed";
bool
llarp_nodedb::Remove(const byte_t *pk)
llarp_nodedb::Remove(const llarp::RouterID &pk)
{
llarp::util::Lock lock(access);
auto itr = entries.find(pk);
@ -34,7 +34,7 @@ llarp_nodedb::Clear()
}
bool
llarp_nodedb::Get(const byte_t *pk, llarp::RouterContact &result)
llarp_nodedb::Get(const llarp::RouterID &pk, llarp::RouterContact &result)
{
llarp::util::Lock lock(access);
auto itr = entries.find(pk);
@ -45,7 +45,7 @@ llarp_nodedb::Get(const byte_t *pk, llarp::RouterContact &result)
}
bool
llarp_nodedb::Has(const byte_t *pk)
llarp_nodedb::Has(const llarp::RouterID &pk)
{
llarp::util::Lock lock(access);
return entries.find(pk) != entries.end();
@ -54,7 +54,7 @@ llarp_nodedb::Has(const byte_t *pk)
/// skiplist directory is hex encoded first nibble
/// skiplist filename is <base32encoded>.snode.signed
std::string
llarp_nodedb::getRCFilePath(const byte_t *pubkey) const
llarp_nodedb::getRCFilePath(const llarp::RouterID &pubkey) const
{
char ftmp[68] = {0};
const char *hexname =
@ -105,7 +105,7 @@ llarp_nodedb::Insert(const llarp::RouterContact &rc)
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
{
llarp::util::Lock lock(access);
entries.insert(std::make_pair(rc.pubkey.data(), rc));
entries.emplace(rc.pubkey.as_array(), rc);
}
if(!rc.BEncode(&buf))
return false;
@ -182,7 +182,7 @@ llarp_nodedb::loadfile(const fs::path &fpath)
}
{
llarp::util::Lock lock(access);
entries.insert(std::make_pair(rc.pubkey.data(), rc));
entries.emplace(rc.pubkey.as_array(), rc);
}
return true;
}

@ -47,19 +47,19 @@ struct llarp_nodedb
fs::path nodePath;
bool
Remove(const byte_t *pk);
Remove(const llarp::RouterID &pk);
void
Clear();
bool
Get(const byte_t *pk, llarp::RouterContact &result);
Get(const llarp::RouterID &pk, llarp::RouterContact &result);
bool
Has(const byte_t *pk);
Has(const llarp::RouterID &pk);
std::string
getRCFilePath(const byte_t *pubkey) const;
getRCFilePath(const llarp::RouterID &pubkey) const;
/// insert and write to disk
bool

@ -52,7 +52,7 @@ namespace llarp
return m_Router->logic;
}
byte_t*
llarp::SecretKey&
PathContext::EncryptionSecretKey()
{
return m_Router->encryption;
@ -61,14 +61,15 @@ namespace llarp
bool
PathContext::HopIsUs(const RouterID& k) const
{
return memcmp(k.data(), m_Router->pubkey(), PUBKEYSIZE) == 0;
return std::equal(m_Router->pubkey(), m_Router->pubkey() + PUBKEYSIZE,
k.begin());
}
bool
PathContext::ForwardLRCM(const RouterID& nextHop,
const std::array< EncryptedFrame, 8 >& frames)
{
llarp::LogDebug("fowarding LRCM to ", nextHop);
llarp::LogDebug("forwarding LRCM to ", nextHop);
LR_CommitMessage msg;
msg.frames = frames;
return m_Router->SendToOrQueue(nextHop, &msg);

@ -74,30 +74,27 @@ namespace llarp
|| upstream < other.upstream || downstream < other.downstream;
}
struct Hash
struct PathIDHash
{
std::size_t
operator()(TransitHopInfo const& a) const
operator()(const PathID_t& a) const
{
std::size_t idx0, idx1, idx2, idx3;
memcpy(&idx0, a.upstream, sizeof(std::size_t));
memcpy(&idx1, a.downstream, sizeof(std::size_t));
memcpy(&idx2, a.txID, sizeof(std::size_t));
memcpy(&idx3, a.rxID, sizeof(std::size_t));
return idx0 ^ idx1 ^ idx2;
return AlignedBuffer< PathID_t::SIZE >::Hash()(a);
}
};
};
struct PathIDHash
{
std::size_t
operator()(const PathID_t& a) const
struct Hash
{
std::size_t idx0;
memcpy(&idx0, a, sizeof(std::size_t));
return idx0;
}
std::size_t
operator()(TransitHopInfo const& a) const
{
std::size_t idx0 = RouterID::Hash()(a.upstream);
std::size_t idx1 = RouterID::Hash()(a.downstream);
std::size_t idx2 = PathIDHash()(a.txID);
std::size_t idx3 = PathIDHash()(a.rxID);
return idx0 ^ idx1 ^ idx2 ^ idx3;
}
};
};
struct IHopHandler
@ -660,7 +657,7 @@ namespace llarp
llarp::Router*
Router();
byte_t*
llarp::SecretKey&
EncryptionSecretKey();
const byte_t*

@ -56,18 +56,18 @@ namespace llarp
return;
}
// generate nonceXOR valueself->hop->pathKey
ctx->crypto->shorthash(hop.nonceXOR, llarp::Buffer(hop.shared));
ctx->crypto->shorthash(hop.nonceXOR, hop.shared.as_buffer());
++ctx->idx;
bool isFarthestHop = ctx->idx == ctx->path->hops.size();
if(isFarthestHop)
{
hop.upstream = hop.rc.pubkey.data();
hop.upstream = hop.rc.pubkey;
}
else
{
hop.upstream = ctx->path->hops[ctx->idx].rc.pubkey.data();
hop.upstream = ctx->path->hops[ctx->idx].rc.pubkey;
}
// build record
@ -90,7 +90,7 @@ namespace llarp
delete ctx;
return;
}
// use ephameral keypair for frame
// use ephemeral keypair for frame
SecretKey framekey;
ctx->crypto->encryption_keygen(framekey);
if(!frame.EncryptInPlace(framekey, hop.rc.enckey, ctx->crypto))
@ -210,7 +210,7 @@ namespace llarp
return keygens.load() > 0;
}
const byte_t*
const SecretKey&
Builder::GetTunnelEncryptionSecretKey() const
{
return enckey;
@ -219,8 +219,7 @@ namespace llarp
bool
Builder::BuildCooldownHit(llarp_time_t now) const
{
return now < lastBuild
|| now - lastBuild < buildIntervalLimit;
return now < lastBuild || now - lastBuild < buildIntervalLimit;
}
bool
@ -304,7 +303,8 @@ namespace llarp
{
// linear backoff
static constexpr llarp_time_t MaxBuildInterval = 10 * 1000;
buildIntervalLimit = std::max(1000 + buildIntervalLimit, MaxBuildInterval);
buildIntervalLimit =
std::max(1000 + buildIntervalLimit, MaxBuildInterval);
PathSet::HandlePathBuildTimeout(p);
}

@ -48,7 +48,7 @@ namespace llarp
ShouldBuildMore(llarp_time_t now) const override;
/// return true if we hit our soft limit for building paths too fast
bool
bool
BuildCooldownHit(llarp_time_t now) const;
virtual bool
@ -74,7 +74,7 @@ namespace llarp
void
ManualRebuild(size_t N, PathRole roles = ePathRoleAny);
virtual const byte_t*
virtual const SecretKey&
GetTunnelEncryptionSecretKey() const;
virtual void

@ -91,7 +91,7 @@ namespace llarp
Lock_t l(m_PathsMutex);
Path* path = nullptr;
AlignedBuffer< 32 > dist;
AlignedBuffer< 32 > to = id.data();
AlignedBuffer< 32 > to = id;
dist.Fill(0xff);
for(const auto& item : m_Paths)
{

@ -32,7 +32,7 @@ namespace llarp
if(now - timestamp > (uint64_t(extendedLifetime) * 1000))
return false;
byte_t digest[SHORTHASHSIZE];
ShortHash digest;
byte_t tmp[MaxSize];
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
// encode

@ -278,7 +278,7 @@ namespace llarp
}
// generate hash of hop key for nonce mutation
self->context->Crypto()->shorthash(self->hop->nonceXOR,
llarp::Buffer(self->hop->pathKey));
self->hop->pathKey.as_buffer());
if(self->record.work
&& self->record.work->IsValid(self->context->Crypto()->shorthash, now))
{

@ -47,7 +47,7 @@ struct TryConnectJob
void
Failed()
{
llarp::LogInfo("session to ", llarp::RouterID(rc.pubkey.data()), " closed");
llarp::LogInfo("session to ", llarp::RouterID(rc.pubkey), " closed");
link->CloseSessionTo(rc.pubkey);
}
@ -110,10 +110,10 @@ llarp_router_try_connect(llarp::Router *router,
return false;
}
auto link = router->outboundLink.get();
auto itr = router->pendingEstablishJobs.insert(std::make_pair(
remote.pubkey.data(),
std::make_unique< TryConnectJob >(remote, link, numretries, router)));
auto link = router->outboundLink.get();
auto itr = router->pendingEstablishJobs.emplace(
remote.pubkey,
std::make_unique< TryConnectJob >(remote, link, numretries, router));
TryConnectJob *job = itr.first->second.get();
// try establishing async
router->logic->queue_job({job, &on_try_connecting});
@ -122,7 +122,7 @@ llarp_router_try_connect(llarp::Router *router,
bool
llarp_findOrCreateIdentity(llarp::Crypto *crypto, const char *fpath,
byte_t *secretkey)
llarp::SecretKey &secretkey)
{
llarp::LogDebug("find or create ", fpath);
fs::path path(fpath);
@ -134,13 +134,15 @@ llarp_findOrCreateIdentity(llarp::Crypto *crypto, const char *fpath,
std::ofstream f(path.string(), std::ios::binary);
if(f.is_open())
{
f.write((char *)secretkey, SECKEYSIZE);
std::copy(secretkey.begin(), secretkey.end(),
std::ostream_iterator< byte_t >(f));
}
}
std::ifstream f(path.string(), std::ios::binary);
if(f.is_open())
{
f.read((char *)secretkey, SECKEYSIZE);
std::copy_n(std::istream_iterator< byte_t >(f), secretkey.size(),
secretkey.begin());
return true;
}
llarp::LogInfo("failed to get identity key");
@ -162,14 +164,16 @@ llarp_findOrCreateEncryption(llarp::Crypto *crypto, const char *fpath,
std::ofstream f(path.string(), std::ios::binary);
if(f.is_open())
{
f.write((char *)encryption.data(), SECKEYSIZE);
std::copy(encryption.begin(), encryption.end(),
std::ostream_iterator< byte_t >(f));
}
}
std::ifstream f(path.string(), std::ios::binary);
if(f.is_open())
{
f.read((char *)encryption.data(), SECKEYSIZE);
std::copy_n(std::istream_iterator< byte_t >(f), encryption.size(),
encryption.begin());
return true;
}
llarp::LogInfo("failed to get encryption key");
@ -260,13 +264,13 @@ namespace llarp
{
for(const auto &link : inboundLinks)
{
if(link->HasSessionTo(remote.data()))
if(link->HasSessionTo(remote))
{
SendTo(remote, msg, link.get());
return true;
}
}
if(outboundLink && outboundLink->HasSessionTo(remote.data()))
if(outboundLink && outboundLink->HasSessionTo(remote))
{
SendTo(remote, msg, outboundLink.get());
return true;
@ -504,7 +508,7 @@ namespace llarp
llarp::RouterContact rc = job->rc;
router->validRouters.insert(std::make_pair(pk.data(), rc));
router->validRouters.emplace(pk, rc);
// track valid router in dht
router->dht->impl.nodes->PutNode(rc);
@ -680,7 +684,7 @@ namespace llarp
// store it in nodedb async
nodedb->InsertAsync(newrc);
// update dht if required
if(dht->impl.nodes->HasNode(newrc.pubkey.data()))
if(dht->impl.nodes->HasNode(dht::Key_t{newrc.pubkey}))
{
dht->impl.nodes->PutNode(newrc);
}
@ -768,7 +772,7 @@ namespace llarp
for(const auto &rc : bootstrapRCList)
{
llarp_router_try_connect(this, rc, 4);
dht->impl.ExploreNetworkVia(rc.pubkey.data());
dht->impl.ExploreNetworkVia(dht::Key_t{rc.pubkey});
}
}
else
@ -841,7 +845,7 @@ namespace llarp
void
Router::SessionClosed(llarp::RouterID remote)
{
__llarp_dht_remove_peer(dht, remote);
__llarp_dht_remove_peer(dht, remote.data());
// remove from valid routers if it's a valid router
validRouters.erase(remote);
llarp::LogInfo("Session to ", remote, " fully closed");
@ -1440,7 +1444,7 @@ namespace llarp
llarp::PubKey pk;
if(pk.FromString(val))
{
if(self->strictConnectPubkeys.insert(pk.data()).second)
if(self->strictConnectPubkeys.emplace(pk).second)
llarp::LogInfo("added ", pk, " to strict connect list");
else
llarp::LogWarn("duplicate key for strict connect: ", pk);
@ -1517,11 +1521,11 @@ namespace llarp
auto &rc = self->bootstrapRCList.back();
if(rc.Read(val) && rc.Verify(&self->crypto, self->Now()))
{
llarp::LogInfo("Added bootstrap node ", RouterID(rc.pubkey.data()));
llarp::LogInfo("Added bootstrap node ", RouterID(rc.pubkey));
}
else if(self->Now() - rc.last_updated > RouterContact::Lifetime)
{
llarp::LogWarn("Bootstrap node ", RouterID(rc.pubkey.data()),
llarp::LogWarn("Bootstrap node ", RouterID(rc.pubkey),
" is too old and needs to be refreshed");
self->bootstrapRCList.pop_back();
}

@ -37,8 +37,8 @@ llarp_findOrCreateEncryption(llarp::Crypto *crypto, const char *fpath,
llarp::SecretKey &encryption);
bool
llarp_findOrCreateIdentity(struct llarp::Crypto *crypto, const char *path,
byte_t *secretkey);
llarp_findOrCreateIdentity(llarp::Crypto *crypto, const char *path,
llarp::SecretKey &secretkey);
struct TryConnectJob;
@ -357,11 +357,12 @@ namespace llarp
llarp::ILinkLayer *
GetLinkWithSessionByPubkey(const llarp::RouterID &remote);
/// parse a routing message in a buffer and handle it with a handler if successful parsing
/// return true on parse and handle success otherwise return false
/// parse a routing message in a buffer and handle it with a handler if
/// successful parsing return true on parse and handle success otherwise
/// return false
bool
ParseRoutingMessageBuffer(llarp_buffer_t buf, routing::IMessageHandler * h, PathID_t rxid);
ParseRoutingMessageBuffer(llarp_buffer_t buf, routing::IMessageHandler *h,
PathID_t rxid);
void
ConnectToRandomRouters(int N);

@ -25,7 +25,9 @@ namespace llarp
#endif
NetID::NetID() : AlignedBuffer< 8 >()
{
memcpy(data(), DefaultValue, strnlen((const char *)DefaultValue, size()));
size_t len =
strnlen(reinterpret_cast< const char * >(DefaultValue), size());
std::copy(DefaultValue, DefaultValue + len, begin());
}
bool
@ -37,8 +39,8 @@ namespace llarp
std::string
NetID::ToString() const
{
size_t l = strnlen((const char *)data(), size());
return std::string((const char *)data(), l);
auto term = std::find(begin(), end(), '\0');
return std::string(begin(), term);
}
bool
@ -50,15 +52,16 @@ namespace llarp
return false;
if(strbuf.sz > size())
return false;
memcpy(data(), strbuf.base, strbuf.sz);
std::copy(strbuf.base, strbuf.base + strbuf.sz, begin());
return true;
}
bool
NetID::BEncode(llarp_buffer_t *buf) const
{
size_t l = strnlen((const char *)data(), size());
return bencode_write_bytestring(buf, data(), l);
auto term = std::find(begin(), end(), '\0');
return bencode_write_bytestring(buf, begin(), std::distance(begin(), term));
}
bool
@ -158,7 +161,8 @@ namespace llarp
if(strbuf.sz > nickname.size())
return false;
nickname.Zero();
memcpy(nickname.data(), strbuf.base, strbuf.sz);
std::copy(strbuf.base, strbuf.base + strbuf.sz,
nickname.begin());
return true;
}
@ -196,7 +200,9 @@ namespace llarp
RouterContact::SetNick(const std::string &nick)
{
nickname.Zero();
memcpy(nickname, nick.c_str(), std::min(nick.size(), nickname.size()));
std::copy(nick.begin(),
nick.begin() + std::min(nick.size(), nickname.size()),
nickname.begin());
}
bool
@ -218,8 +224,8 @@ namespace llarp
std::string
RouterContact::Nick() const
{
const char *n = (const char *)nickname.data();
return std::string(n, strnlen(n, nickname.size()));
auto term = std::find(nickname.begin(), nickname.end(), '\0');
return std::string(nickname.begin(), term);
}
bool

@ -32,7 +32,7 @@ namespace llarp
RouterID&
operator=(const byte_t* ptr)
{
memcpy(data(), ptr, SIZE);
std::copy(ptr, ptr + SIZE, begin());
return *this;
}

@ -51,7 +51,7 @@ namespace llarp
DHTMessage::HandleMessage(IMessageHandler* h, llarp::Router* r) const
{
// set source as us
llarp::dht::Key_t us = r->pubkey();
llarp::dht::Key_t us{r->pubkey()};
for(const auto& msg : M)
{
msg->From = us;

@ -15,9 +15,9 @@ namespace llarp
struct IMessage : public llarp::IBEncodeMessage
{
llarp::PathID_t from;
uint64_t S = 0;
uint64_t S;
IMessage() : llarp::IBEncodeMessage()
IMessage() : llarp::IBEncodeMessage(), S(0)
{
}
@ -26,11 +26,10 @@ namespace llarp
virtual bool
HandleMessage(IMessageHandler* h, llarp::Router* r) const = 0;
virtual void
virtual void
Clear() = 0;
};
} // namespace routing
} // namespace llarp

@ -220,14 +220,15 @@ namespace llarp
}
bool
Identity::KeyExchange(path_dh_func dh, byte_t* result,
const ServiceInfo& other, const byte_t* N) const
Identity::KeyExchange(path_dh_func dh, SharedSecret& result,
const ServiceInfo& other,
const KeyExchangeNonce& N) const
{
return dh(result, other.EncryptionPublicKey(), enckey, N);
}
bool
Identity::Sign(llarp::Crypto* c, byte_t* sig, llarp_buffer_t buf) const
Identity::Sign(Crypto* c, Signature& sig, llarp_buffer_t buf) const
{
return c->sign(sig, signkey, buf);
}
@ -273,12 +274,12 @@ namespace llarp
if(!BDecode(&buf))
return false;
const byte_t* ptr = nullptr;
ServiceInfo::OptNonce van;
if(!vanity.IsZero())
ptr = vanity.data();
van = vanity;
// update pubkeys
pub.Update(llarp::seckey_topublic(enckey),
llarp::seckey_topublic(signkey), ptr);
llarp::seckey_topublic(signkey), van);
return true;
}

@ -40,8 +40,8 @@ namespace llarp
EnsureKeys(const std::string& fpath, llarp::Crypto* c);
bool
KeyExchange(llarp::path_dh_func dh, byte_t* sharedkey,
const ServiceInfo& other, const byte_t* N) const;
KeyExchange(llarp::path_dh_func dh, SharedSecret& sharedkey,
const ServiceInfo& other, const KeyExchangeNonce& N) const;
bool
DecodeKey(llarp_buffer_t key, llarp_buffer_t* buf) override;
@ -50,7 +50,7 @@ namespace llarp
SignIntroSet(IntroSet& i, llarp::Crypto* c, llarp_time_t now) const;
bool
Sign(llarp::Crypto*, byte_t* sig, llarp_buffer_t buf) const;
Sign(llarp::Crypto*, Signature& sig, llarp_buffer_t buf) const;
};
} // namespace service
} // namespace llarp

@ -5,6 +5,12 @@
#include <crypto.hpp>
#include <service/types.hpp>
#if __cplusplus >= 201703L
#include <optional>
#else
#include <tl/optional.hpp>
#endif
namespace llarp
{
namespace service
@ -18,6 +24,12 @@ namespace llarp
public:
VanityNonce vanity;
#if __cplusplus >= 201703L
using OptNonce = std::optional< VanityNonce >;
#else
using OptNonce = tl::optional< VanityNonce >;
#endif
ServiceInfo() = default;
ServiceInfo(ServiceInfo&& other)
@ -52,7 +64,7 @@ namespace llarp
return crypto->verify(signkey, payload, sig);
}
const byte_t*
const PubKey&
EncryptionPublicKey() const
{
return enckey;
@ -60,12 +72,14 @@ namespace llarp
bool
Update(const byte_t* enc, const byte_t* sign,
const byte_t* nonce = nullptr)
const OptNonce& nonce = OptNonce())
{
enckey = enc;
signkey = sign;
if(nonce)
vanity = nonce;
{
vanity = nonce.value();
}
return UpdateAddr();
}
@ -127,7 +141,7 @@ namespace llarp
BDecode(llarp_buffer_t* buf) override
{
if(IBEncodeMessage::BDecode(buf))
return CalculateAddress(m_CachedAddr.data());
return CalculateAddress(m_CachedAddr.as_array());
return false;
}

@ -14,88 +14,35 @@ namespace llarp
namespace service
{
/// Snapp/Snode Address
struct Address
struct Address : public AlignedBuffer< 32 >
{
static constexpr size_t SIZE = 32;
using Data = std::array< byte_t, SIZE >;
std::string
ToString(const char* tld = ".loki") const;
bool
FromString(const std::string& str, const char* tld = ".loki");
Address()
{
Zero();
}
Address(const byte_t* buf)
{
std::copy(buf, buf + SIZE, b.begin());
}
Address(const Address& other)
{
b = other.b;
}
byte_t& operator[](size_t idx)
{
return b[idx];
}
const byte_t& operator[](size_t idx) const
{
return b[idx];
}
bool
BEncode(llarp_buffer_t* buf) const
{
return bencode_write_bytestring(buf, b.data(), SIZE);
}
bool
BDecode(llarp_buffer_t* buf)
Address() : AlignedBuffer< SIZE >()
{
llarp_buffer_t strbuf;
if(!bencode_read_string(buf, &strbuf))
return false;
if(strbuf.sz != SIZE)
{
llarp::LogErrorTag("Address::BDecode",
"bdecode buffer size missmatch ", strbuf.sz,
"!=32");
return false;
}
std::copy(strbuf.base, strbuf.base + SIZE, b.begin());
return true;
}
static constexpr size_t
size()
explicit Address(const Data& buf) : AlignedBuffer< SIZE >(buf)
{
return SIZE;
}
bool
IsZero() const
Address(const Address& other) : AlignedBuffer< SIZE >(other.as_array())
{
return b == Data{};
}
void
Zero()
explicit Address(const AlignedBuffer< SIZE >& other)
: AlignedBuffer< SIZE >(other)
{
b.fill(0);
}
bool
operator<(const Address& other) const
{
return data() < other.data();
return as_array() < other.as_array();
}
friend std::ostream&
@ -107,40 +54,28 @@ namespace llarp
bool
operator==(const Address& other) const
{
return data() == other.data();
return as_array() == other.as_array();
}
bool
operator!=(const Address& other) const
{
return !(*this == other);
return as_array() != other.as_array();
}
Address&
operator=(const Address& other) = default;
const dht::Key_t
dht::Key_t
ToKey() const
{
return dht::Key_t(data());
return dht::Key_t(as_array());
}
const RouterID
RouterID
ToRouter() const
{
return RouterID(data().data());
}
const Data&
data() const
{
return b;
}
Data&
data()
{
return b;
return RouterID(as_array());
}
struct Hash
@ -148,13 +83,10 @@ namespace llarp
size_t
operator()(const Address& buf) const
{
return std::accumulate(buf.data().begin(), buf.data().end(), 0,
return std::accumulate(buf.begin(), buf.end(), 0,
std::bit_xor< size_t >());
}
};
private:
Data b;
};
} // namespace service

@ -141,7 +141,8 @@ namespace llarp
}
bool
Context::FindBestAddressFor(const byte_t *addr, bool isSNode, huint32_t &ip)
Context::FindBestAddressFor(const llarp::AlignedBuffer< 32 > &addr,
bool isSNode, huint32_t &ip)
{
auto itr = m_Endpoints.begin();
while(itr != m_Endpoints.end())

@ -33,7 +33,8 @@ namespace llarp
getFirstEndpoint();
bool
FindBestAddressFor(const byte_t *addr, bool isSNode, huint32_t &);
FindBestAddressFor(const llarp::AlignedBuffer< 32 > &addr, bool isSNode,
huint32_t &);
/// DRY refactor
llarp::handlers::TunEndpoint *

@ -462,12 +462,12 @@ namespace llarp
bool
Endpoint::GetCachedSessionKeyFor(const ConvoTag& tag,
const byte_t*& secret) const
SharedSecret& secret) const
{
auto itr = m_Sessions.find(tag);
if(itr == m_Sessions.end())
return false;
secret = itr->second.sharedKey.data();
secret = itr->second.sharedKey;
return true;
}
@ -563,7 +563,7 @@ namespace llarp
Endpoint::PublishIntroSet(llarp::Router* r)
{
// publish via near router
RouterID location = m_Identity.pub.Addr().data().data();
RouterID location = m_Identity.pub.Addr().as_array();
auto path = GetEstablishedPathClosestTo(location);
return path && PublishIntroSetVia(r, path);
}
@ -696,7 +696,7 @@ namespace llarp
Endpoint::PutNewOutboundContext(const llarp::service::IntroSet& introset)
{
Address addr;
introset.A.CalculateAddress(addr.data());
introset.A.CalculateAddress(addr.as_array());
if(m_RemoteSessions.count(addr) >= MAX_OUTBOUND_CONTEXT_COUNT)
{
@ -858,10 +858,9 @@ namespace llarp
if(msg->proto == eProtocolTraffic)
{
auto buf = llarp::Buffer(msg->payload);
return HandleWriteIPPacket(
buf,
std::bind(&Endpoint::ObtainIPForAddr, this,
msg->sender.Addr().data().data(), false));
return HandleWriteIPPacket(buf,
std::bind(&Endpoint::ObtainIPForAddr, this,
msg->sender.Addr(), false));
}
else if(msg->proto == eProtocolText)
{
@ -1139,7 +1138,7 @@ namespace llarp
}
bool
Endpoint::SendToSNodeOrQueue(const byte_t* addr, llarp_buffer_t buf)
Endpoint::SendToSNodeOrQueue(const RouterID& addr, llarp_buffer_t buf)
{
llarp::net::IPv4Packet pkt;
if(!pkt.Load(buf))
@ -1162,10 +1161,10 @@ namespace llarp
}
bool
Endpoint::SendToServiceOrQueue(const byte_t* addr, llarp_buffer_t data,
Endpoint::SendToServiceOrQueue(const RouterID& addr, llarp_buffer_t data,
ProtocolType t)
{
service::Address remote(addr);
service::Address remote(addr.as_array());
// inbound converstation
auto now = Now();
@ -1184,7 +1183,7 @@ namespace llarp
return false;
}
Introduction remoteIntro;
const byte_t* K = nullptr;
SharedSecret K;
for(const auto& tag : tags)
{
if(tag.IsZero())
@ -1470,17 +1469,22 @@ namespace llarp
// derive ntru session key component
SharedSecret K;
self->crypto->pqe_encrypt(self->frame.C, K, self->introPubKey);
// randomize Nounce
// randomize Nonce
self->frame.N.Randomize();
// compure post handshake session key
byte_t tmp[64];
// K
memcpy(tmp, K, 32);
// PKE (A, B, N)
if(!self->m_LocalIdentity.KeyExchange(self->crypto->dh_client, tmp + 32,
self->remote, self->frame.N))
SharedSecret sharedSecret;
if(!self->m_LocalIdentity.KeyExchange(self->crypto->dh_client,
sharedSecret, self->remote,
self->frame.N))
{
llarp::LogError("failed to derive x25519 shared key component");
}
std::array< byte_t, 64 > tmp;
// K
std::copy(K.begin(), K.end(), tmp.begin());
// H (K + PKE(A, B, N))
std::copy(sharedSecret.begin(), sharedSecret.end(), tmp.begin() + 32);
self->crypto->shorthash(self->sharedKey,
llarp::StackBuffer< decltype(tmp) >(tmp));
// set tag
@ -1561,7 +1565,7 @@ namespace llarp
llarp::LogError("Failed to send frame on path");
}
else
llarp::LogError("cannot send becuase we have no path to ",
llarp::LogError("cannot send because we have no path to ",
remoteIntro.router);
}
@ -1583,7 +1587,7 @@ namespace llarp
if(randomizePath)
path = m_Endpoint->PickRandomEstablishedPath();
else
path = m_Endpoint->GetEstablishedPathClosestTo(addr.data());
path = m_Endpoint->GetEstablishedPathClosestTo(addr.as_array());
if(path)
{
@ -1705,8 +1709,8 @@ namespace llarp
Endpoint::SendContext::EncryptAndSendTo(llarp_buffer_t payload,
ProtocolType t)
{
auto crypto = m_Endpoint->Router()->crypto;
const byte_t* shared = nullptr;
auto crypto = m_Endpoint->Router()->crypto;
SharedSecret shared;
routing::PathTransferMessage msg;
ProtocolFrame& f = msg.T;
f.N.Randomize();

@ -20,7 +20,7 @@ namespace llarp
{
namespace service
{
// foward declare
// forward declare
struct AsyncKeyExchange;
struct Endpoint : public path::Builder,
@ -104,10 +104,10 @@ namespace llarp
HasPathToService(const Address& remote) const;
virtual huint32_t
ObtainIPForAddr(const byte_t* addr, bool serviceNode) = 0;
ObtainIPForAddr(const AlignedBuffer< 32 >& addr, bool serviceNode) = 0;
virtual bool
HasAddress(const byte_t* addr) const = 0;
HasAddress(const AlignedBuffer< 32 >& addr) const = 0;
/// return true if we have a pending job to build to a hidden service but
/// it's not done yet
@ -154,11 +154,11 @@ namespace llarp
HandlePathBuilt(path::Path* path) override;
bool
SendToServiceOrQueue(const byte_t* addr, llarp_buffer_t payload,
SendToServiceOrQueue(const RouterID& addr, llarp_buffer_t payload,
ProtocolType t);
bool
SendToSNodeOrQueue(const byte_t* addr, llarp_buffer_t payload);
SendToSNodeOrQueue(const RouterID& addr, llarp_buffer_t payload);
void
FlushSNodeTraffic();
@ -177,7 +177,7 @@ namespace llarp
llarp_buffer_t
Buffer()
{
return llarp::InitBuffer(payload.data(), payload.size());
return llarp::Buffer(payload);
}
};
@ -351,7 +351,7 @@ namespace llarp
bool
GetCachedSessionKeyFor(const ConvoTag& remote,
const byte_t*& secret) const override;
SharedSecret& secret) const override;
void
PutCachedSessionKeyFor(const ConvoTag& remote,
const SharedSecret& secret) override;

@ -20,7 +20,7 @@ namespace llarp
virtual bool
GetCachedSessionKeyFor(const ConvoTag& remote,
const byte_t*& secret) const = 0;
SharedSecret& secret) const = 0;
virtual void
PutCachedSessionKeyFor(const ConvoTag& remote,
const SharedSecret& secret) = 0;

@ -50,7 +50,7 @@ namespace llarp
if(m_CachedAddr.IsZero())
{
Address addr;
CalculateAddress(addr.data());
CalculateAddress(addr.as_array());
return addr.ToString();
}
return m_CachedAddr.ToString();
@ -70,7 +70,7 @@ namespace llarp
bool
ServiceInfo::UpdateAddr()
{
return CalculateAddress(m_CachedAddr.data());
return CalculateAddress(m_CachedAddr.as_array());
}
} // namespace service

@ -154,7 +154,7 @@ namespace llarp
bool
ProtocolFrame::DecryptPayloadInto(llarp::Crypto* crypto,
const byte_t* sharedkey,
const SharedSecret& sharedkey,
ProtocolMessage& msg) const
{
Encrypted_t tmp = D;
@ -166,7 +166,7 @@ namespace llarp
bool
ProtocolFrame::EncryptAndSign(llarp::Crypto* crypto,
const ProtocolMessage& msg,
const byte_t* sessionKey,
const SharedSecret& sessionKey,
const Identity& localIdent)
{
byte_t tmp[MAX_PROTOCOL_MESSAGE_SIZE];
@ -266,11 +266,9 @@ namespace llarp
delete self;
return;
}
byte_t tmp[64];
// K
memcpy(tmp, K, 32);
// PKE (A, B, N)
if(!self->m_LocalIdentity.KeyExchange(crypto->dh_server, tmp + 32,
SharedSecret sharedSecret;
if(!self->m_LocalIdentity.KeyExchange(crypto->dh_server, sharedSecret,
self->msg->sender, self->frame.N))
{
llarp::LogError("x25519 key exchange failed");
@ -279,7 +277,11 @@ namespace llarp
delete self;
return;
}
std::array< byte_t, 64 > tmp;
// K
std::copy(K.begin(), K.end(), tmp.begin());
// S = HS( K + PKE( A, B, N))
std::copy(sharedSecret.begin(), sharedSecret.end(), tmp.begin() + 32);
crypto->shorthash(sharedKey, StackBuffer< decltype(tmp) >(tmp));
self->handler->PutIntroFor(self->msg->tag, self->msg->introReply);
@ -323,7 +325,7 @@ namespace llarp
llarp_threadpool_queue_job(worker, {dh, &AsyncFrameDecrypt::Work});
return true;
}
const byte_t* shared = nullptr;
SharedSecret shared;
if(!handler->GetCachedSessionKeyFor(T, shared))
{
llarp::LogError("No cached session for T=", T);

@ -99,7 +99,7 @@ namespace llarp
bool
EncryptAndSign(llarp::Crypto* c, const ProtocolMessage& msg,
const byte_t* sharedkey, const Identity& localIdent);
const SharedSecret& sharedkey, const Identity& localIdent);
bool
AsyncDecryptAndVerify(llarp::Logic* logic, llarp::Crypto* c,
@ -108,7 +108,7 @@ namespace llarp
IDataHandler* handler) const;
bool
DecryptPayloadInto(llarp::Crypto* c, const byte_t* sharedkey,
DecryptPayloadInto(llarp::Crypto* c, const SharedSecret& sharedkey,
ProtocolMessage& into) const;
bool

@ -7,7 +7,7 @@ namespace llarp
std::string
Tag::ToString() const
{
return std::string((const char *)data());
return std::string(begin(), end());
}
} // namespace service
} // namespace llarp

@ -16,11 +16,11 @@ namespace llarp
{
struct Tag : public llarp::AlignedBuffer< 16 >
{
Tag() : llarp::AlignedBuffer< 16 >()
Tag() : llarp::AlignedBuffer< SIZE >()
{
}
Tag(const byte_t* d) : llarp::AlignedBuffer< 16 >(d)
Tag(const byte_t* d) : llarp::AlignedBuffer< SIZE >(d)
{
}
@ -28,20 +28,22 @@ namespace llarp
{
// evidently, does nothing on LP64 systems (where size_t is *already*
// unsigned long but zero-extends this on LLP64 systems
memcpy(data(), str.c_str(), std::min(16UL, (unsigned long)str.size()));
std::copy(str.begin(), str.begin() + std::min(16UL, str.size()),
begin());
}
Tag&
operator=(const Tag& other)
{
memcpy(data(), other.data(), 16);
as_array() = other.as_array();
return *this;
}
Tag&
operator=(const std::string& str)
{
memcpy(data(), str.data(), std::min(16UL, (unsigned long)str.size()));
std::copy(str.begin(), str.begin() + std::min(16UL, str.size()),
begin());
return *this;
}

@ -53,7 +53,7 @@ TEST_F(FrameTest, TestFrameCrypto)
// rewind buffer
buf->cur = buf->base + llarp::EncryptedFrameOverheadSize;
// encrypt to alice
ASSERT_TRUE(f.EncryptInPlace(alice, llarp::seckey_topublic(bob), &crypto));
ASSERT_TRUE(f.EncryptInPlace(alice, bob.toPublic(), &crypto));
// decrypt from alice
ASSERT_TRUE(f.DecryptInPlace(bob, &crypto));

@ -5,11 +5,10 @@
struct HiddenServiceTest : public ::testing::Test
{
llarp::Crypto crypto;
llarp::Crypto crypto;
llarp::service::Identity ident;
HiddenServiceTest()
: crypto(llarp::Crypto::sodium{})
HiddenServiceTest() : crypto(llarp::Crypto::sodium{})
{
}
@ -31,7 +30,7 @@ struct HiddenServiceTest : public ::testing::Test
TEST_F(HiddenServiceTest, TestGenerateIntroSet)
{
llarp::service::Address addr;
ASSERT_TRUE(ident.pub.CalculateAddress(addr.data()));
ASSERT_TRUE(ident.pub.CalculateAddress(addr.as_array()));
llarp::service::IntroSet I;
auto now = llarp::time_now_ms();
I.T = now;

@ -7,11 +7,10 @@ using ObtainExitMessage = llarp::routing::ObtainExitMessage;
class ObtainExitTest : public ::testing::Test
{
public:
llarp::Crypto crypto;
llarp::Crypto crypto;
llarp::SecretKey alice;
ObtainExitTest()
: crypto(llarp::Crypto::sodium{})
ObtainExitTest() : crypto(llarp::Crypto::sodium{})
{
}
@ -32,9 +31,9 @@ TEST_F(ObtainExitTest, TestSignVerify)
msg.Z.Zero();
msg.S = llarp::randint();
msg.T = llarp::randint();
ASSERT_TRUE(msg.Sign(&crypto, alice));
ASSERT_TRUE(msg.Verify(&crypto));
ASSERT_TRUE(msg.I == llarp::PubKey(llarp::seckey_topublic(alice)));
ASSERT_FALSE(msg.version != LLARP_PROTO_VERSION);
ASSERT_FALSE(msg.Z.IsZero());
EXPECT_TRUE(msg.Sign(&crypto, alice));
EXPECT_TRUE(msg.Verify(&crypto));
EXPECT_TRUE(msg.I == llarp::PubKey(llarp::seckey_topublic(alice)));
EXPECT_FALSE(msg.version != LLARP_PROTO_VERSION);
EXPECT_FALSE(msg.Z.IsZero());
};

@ -6,11 +6,10 @@ namespace llarp
{
struct PQCryptoTest : public ::testing::Test
{
llarp::Crypto crypto;
llarp::Crypto crypto;
PQKeyPair keys;
PQCryptoTest()
: crypto(llarp::Crypto::sodium{})
PQCryptoTest() : crypto(llarp::Crypto::sodium{})
{
}
@ -34,7 +33,8 @@ namespace llarp
auto c = Crypto();
ASSERT_TRUE(keys.size() == PQ_KEYPAIRSIZE);
ASSERT_TRUE(c->pqe_encrypt(block, shared, pq_keypair_to_public(keys)));
ASSERT_TRUE(
c->pqe_encrypt(block, shared, PQPubKey(pq_keypair_to_public(keys))));
ASSERT_TRUE(c->pqe_decrypt(block, otherShared, pq_keypair_to_secret(keys)));
ASSERT_TRUE(otherShared == shared);
}

@ -230,7 +230,7 @@ TEST_F(UTPTest, TestAliceRenegWithBob)
[&](llarp::RouterContact rc) {
ASSERT_EQ(rc, Alice.GetRC());
llarp::LogInfo("bob established with alice");
Bob.link->VisitSessionByPubkey(Alice.GetRC().pubkey.data(),
Bob.link->VisitSessionByPubkey(Alice.GetRC().pubkey.as_array(),
sendDiscardMessage);
},
[&](llarp::RouterContact newrc, llarp::RouterContact oldrc) -> bool {
@ -318,7 +318,7 @@ TEST_F(UTPTest, TestAliceConnectToBob)
[&](llarp::RouterContact rc) {
ASSERT_EQ(rc, Alice.GetRC());
llarp::LogInfo("bob established with alice");
Bob.link->VisitSessionByPubkey(Alice.GetRC().pubkey.data(),
Bob.link->VisitSessionByPubkey(Alice.GetRC().pubkey.as_array(),
sendDiscardMessage);
},
[&](llarp::RouterContact, llarp::RouterContact) -> bool { return true; },

Loading…
Cancel
Save