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