Next: Handshake protocol, Up: Developer manual
ENCn(SERIAL) + ENC(KEY, ENCn(SERIAL), DATA) + AUTH(ENCn(SERIAL) + ENC(KEY, ENCn(SERIAL), DATA))
Each transport message is indistinguishable from pseudo random noise.
SERIAL
is message’s serial number. Odds are reserved for client(→server)
messages, evens for server(→client) messages.
ENCn
is XTEA block cipher algorithm used here as PRP (pseudo
random permutation) to randomize, obfuscate SERIAL
. Plaintext
SERIAL
state is kept in peers internal state, but encrypted
before transmission. XTEA is compact and fast enough. Salsa20 is PRF
function and requires much more code to create PRP from it. XTEA’s
encryption key is the first 128-bit of Salsa20’s output with established
common key and zero nonce (message nonces start from 1).
Encrypted SERIAL
is used as a nonce for DATA
encryption:
encryption key is different during each handshake, so (key, nonce) pair
is always used only once. ENC
is Salsa20 cipher, with established
session KEY
and encrypted SERIAL
used as a nonce.
AUTH
is Poly1305 authentication function. First 256 bits of
Salsa20 output are used as a one-time key for AUTH
. Next 256 bits
of Salsa20 are ignored. All remaining output is XORed with the data,
encrypting it.
To prevent replay attacks we remember latest SERIAL
from the
remote peer. If received message’s SERIAL
is not greater that the
saved one, then drop it. Optionally, because some UDP packets can be
reordered during transmission, we can allow some window for valid
serials with the -noncediff
option. -noncediff 10
with
current saved serial state equals to 78 allows messages with 68…78
serials. That time window can be used by attacker to replay packets, so
by default it equals to 1. However it can improve performance because of
rearranged UDP packets.
Next: Handshake protocol, Up: Developer manual