From c6b3fa25ff60cb43f80d34d6cf610a7b63fc3b90 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 14 Feb 2019 13:13:45 -0500 Subject: [PATCH] update proposed new wire protocol docs --- docs/wire-protocol.txt | 259 ++++++++++++++++++++++++++++------------- 1 file changed, 180 insertions(+), 79 deletions(-) diff --git a/docs/wire-protocol.txt b/docs/wire-protocol.txt index 6b3154e45..6070cad2e 100644 --- a/docs/wire-protocol.txt +++ b/docs/wire-protocol.txt @@ -11,96 +11,79 @@ datagram based network layer. outer message format: -{ - A: command, - B: <16 bytes flow id>, - C: , - X: -} +outer-header: -comamnds: +<1 byte command> +<1 byte reserved, R, set to '=' (0x3d)> +<32 bytes flow id, B> -A - get handshake cookie -obtain a handshake cookie +command 'O' - obtain flow id -B is randomized -X MUST contain the user agent string of the requester. +obtain a handshake cookie -the if the network id differs from the current network's id a reject message is -sent: + +<32 bytes random> +<8 bytes net id> + -{ - A: R, - B: msg.B, - X: "" -} +the if the network id differs from the current network's id a reject message +MUST be sent MUST be replied to with a message rejected or a give handshake cookie -C - give handshake cookie +command 'G' - give flow id -give a handshake cookie to a remote endpoint that asks for one + +<32 byte new flow-id, X> + -B is the B value from the get handshake cookie message -X is a 32 byte handshake cookie, calcuated via: - -r = RAND(32) -a = "" + " " + "" -X = HS(a + B + r) +give a flow id to a remote endpoint that asks for one -R - message rejected +B is the B value from the request flow id message +X is a 32 byte the flow id, calcuated via: -B is the flow id from the recipiant -X is a reply line +r = RAND(32) +a = "::ffff." + ":" + "" +X = HS(a + B + r + net id) -reject a message with flow id B +resulting message: -S - session negotiation + "G=<32 byte flowid><32 bytes new flowid>" -negotiate encrypted session +after recieving a give flow id message a session negotiation can happen -B is the flow id from the recipiant -C is the handshake cookie -X is encrypted session negotiation data +command 'R' - message rejected -D - encrypted data transmission + + -transmit encrypted data on session +reject a message on a flow id B is the flow id from the recipiant -X is authenticated and encrypted data - -BNF: - - ::= - - ::= - - ::= + - - ::= * | - - ::= "COOKIE" | "HANDSHAKE" - ::= +resulting message of reject with reason "no you" - ::= "lokinet" | "testnet" + "R=<32 byte flow-id>no you" - ::= " " +command 'S' - session negotiation - ::= "0" - - ::= "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" - - ::= | +negotiate encrypted session - ::= | * + +<24 bytes nounce, N> + + - ::= "." "." +B is the flow id from the recipiant generated by the give flow id message (from outer header) +N is a random nounce +X is encrypted session negotiation data +Z is a keyed hash - ::= +Z is generated via: +msg.Z = '0x00' * 32 +msg.Z = MDS(msg, tx_K) session negotiation: @@ -119,15 +102,9 @@ a.tx_K = k_b b.tx_K = k_a -inner message format: - -<32 bytes blake2s keyed hash of following data> -<24 bytes nounce> - - decryption is done via: -SD(remaining, rx_K, nounce) +SD(msg.X, rx_K, msg.N) encrypted payload is bencoded LIM (see proto_v0.txt) @@ -147,20 +124,144 @@ b.rx_K = k_b a.tx_K = k_b b.tx_K = k_a -afterwards data transmission may happen +afterwards data transmission may happen. +the intiator's remote address is permitted to change during data transmission. +remote address of the last successfully -data tranmission: +D - encrypted data transmission -message format: +transmit encrypted data on session -<10 byte header> - + +<24 bytes nonce, N> + + -header format: -<1 byte proto version> +B is the flow id from the recipiant (from outer header) +N is a random nounce +X is encrypted data +Z is keyed hash of entire message + +Z is generated via: + +msg.Z = '0x00' * 32 +msg.Z = MDS(msg, tx_K) + +data tranmission: + +inner message format of X (after decryption): + +header: + +<1 byte protocol version> <1 byte command> -<1 byte flags> -<1 byte fragno> -<2 bytes fraglen> -<4 bytes seqno> + + +command: 'K' (keep alive) + +tell other side to acknoledge they are alive + +
+<2 bytes resevered, set to 0> +<2 bytes attempt counter, set to 0 and incremented every retransmit, reset when we get a keepalive ack> +<2 bytes milliseconds ping timeout> +<8 bytes current session TX limit in bytes per second> +<8 bytes current session RX use in bytes per second> +<8 bytes milliseconds since epoch our current time> + + +command: 'L' (keep alive ack) + +acknolege keep alive message + +
+<6 bytes reserved, set to 0> +<8 bytes current session RX limit in bytes per second> +<8 bytes current session TX use in bytes per second> +<8 bytes milliseconds since epoch our current time> + + + +command: 'C' (congestion) + +tell other side to slow down + +
+<2 bytes reduce TX rate by this many 1024 bytes per second> +<4 bytes milliseconds slowdown lifetime> + + +command: 'D' (anti-congestion) + +tell other side to speed up + +
+<2 bytes increase TX rate by this many 1024 bytes per second> +<4 bytes milliseconds speedup lifetime> + + +command: 'T' (transmit) + +transit fragment + +
+<1 byte number of 16 byte blocks offset from beginning of message, O> +<1 byte number of 16 byte blocks size of fragment data, N> +<4 bytes sequence number> +<32 bytes expected digest of message, present if O is 0, otherwise omitted> +<16 * N bytes of data> + + +command: 'A' (ack) + +acknoledge fragments + +
+<1 byte number of acks following, N> +<8 * N bytes acks> + + +ack format: + +<4 byte message sequence number> +<1 byte reserved current set to 0> +<1 byte ack counter (number of acks sent for the corrisponding message)> +<1 byte bitmask fragments selective ack (msb is fragment 0, lsb is fragment 7)> +<1 byte bitmask fragments posative ack (msb is fragment 0, lsb is fragment 7)> + + +command: 'R' (rotate keys) + +inform remote that their RX key should be rotated + +given alice(A) sends this message to bob(B) the new keys are computed as such: + +n_K = TKE(K, B_e, K_seed, N) + +A.tx_K = n_K +B.rx_K = n_K + +<2 bytes milliseconds lifetime of old keys, retain them for this long and then discard> +<4 bytes reserved, set to 0> +<32 bytes key exchange nounce, N> +<32 bytes next public encryption key, K> + + +command: 'U' (upgrade) + +request protocol upgrade + +
+<1 byte protocol min version to upgrade to> +<1 byte protocol max version to upgrade to> + + +command: 'V' (version upgrade) + +sent in response to upgrade message + +
+<1 byte protocol version selected> +<1 byte protocol version highest we support> +