mirror of
https://github.com/oxen-io/lokinet.git
synced 2024-11-15 12:13:24 +00:00
91 lines
2.5 KiB
Plaintext
91 lines
2.5 KiB
Plaintext
|
Wire Protocol (version ½)
|
||
|
|
||
|
|
||
|
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
|
||
|
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
|
||
|
document are to be interpreted as described in RFC 2119 [RFC2119].
|
||
|
|
||
|
LLARP supports by default an authenticated and framed transport over UTP [1]
|
||
|
|
||
|
Handshake:
|
||
|
|
||
|
Alice establishes a UTP "connection" with Bob.
|
||
|
|
||
|
Alice sends a LIM a_L encrpyted with the initial b_K key
|
||
|
|
||
|
if Bob accepts Alice's router, Bob replies with a LIM b_L encrpyted with the
|
||
|
b_K key.
|
||
|
|
||
|
next the session keys are generated via:
|
||
|
|
||
|
a_h = HS(a_K + a_L.n)
|
||
|
b_h = HS(b_K + b_L.n)
|
||
|
a_K = TKE(A.p, B_a.e, sk, a_h)
|
||
|
b_K = TKE(A.p, B_a.e, sk, b_h)
|
||
|
|
||
|
A.tx_K = b_K
|
||
|
A.rx_K = a_K
|
||
|
B.tx_K = a_K
|
||
|
B.rx_K = B_K
|
||
|
|
||
|
the initial value of a_K is HS(A.k) and b_K is HS(B.k)
|
||
|
|
||
|
1120 byte fragments are sent over UTP in an ordered fashion.
|
||
|
|
||
|
The each fragment F has the following structure:
|
||
|
|
||
|
[ 32 bytes blake2 keyed hash of the following 1088 bytes (h)]
|
||
|
[ 32 bytes random nonce (n)]
|
||
|
[ 1056 bytes encrypted payload (p)]
|
||
|
|
||
|
the recipiant verifies F.h == MDS(F.n + F.p, rx_K) and the UTP session
|
||
|
is reset if verification fails.
|
||
|
|
||
|
the decrypted payload P has the following structure:
|
||
|
|
||
|
[ 24 bytes random (A) ]
|
||
|
[ big endian unsigned 32 bit message id (I) ]
|
||
|
[ big endian unsigned 16 bit fragment length (N) ]
|
||
|
[ big endian unsigned 16 bit fragment remaining bytes (R) ]
|
||
|
[ N bytes of plaintext payload (X) ]
|
||
|
[ trailing bytes discarded ]
|
||
|
|
||
|
link layer messages fragmented and delievered in any order the sender chooses.
|
||
|
|
||
|
recipaint ensures a buffer for message number P.I exists, allocating one if it
|
||
|
does not exist.
|
||
|
|
||
|
recipiant appends P.X to the end of the buffer for message P.I
|
||
|
|
||
|
if P.R is zero then message number P.I is completed and processed as a link
|
||
|
layer messages. otherwise the recipiant expects P.R additional bytes.
|
||
|
P.R's value MUST decrease by P.N in the next fragment sent.
|
||
|
|
||
|
message size MUST NOT exceed 8192 bytes.
|
||
|
|
||
|
if a message is not received in 2 seconds it is discarded and any further
|
||
|
fragments for the message are also discarded.
|
||
|
|
||
|
P.I MUST have the initial value 0
|
||
|
P.I MUST be incremeneted by 1 for each new messsage transmitted
|
||
|
P.I MAY wrap around back to 0
|
||
|
|
||
|
|
||
|
after every fragment F the session key K is mutated via:
|
||
|
|
||
|
K = HS(K + P.A)
|
||
|
|
||
|
Periodically the connection initiator MUST renegotiate the session key by
|
||
|
sending a LIM after L.p milliseconds have elapsed.
|
||
|
|
||
|
If the local RC changes while a connection is established they MUST
|
||
|
renegotioate the session keys by sending a LIM to ensure the new RC is sent.
|
||
|
|
||
|
|
||
|
references:
|
||
|
|
||
|
[1] http://www.bittorrent.org/beps/bep_0029.html
|
||
|
|
||
|
|
||
|
|