2 @unnumbered Packet format
5 @url{https://tools.ietf.org/html/rfc4506, XDR}-encoded structures.
9 * Encrypted packet: Encrypted.
15 Plain packet contains either the whole file, or file request (freq), or
16 transition packet or exec message. It is called "plain", because it
17 contains plaintext, but plain packets would never be stored on your hard
22 +--------------------------------------+--...---+
23 | MAGIC | TYPE | NICE | PATHLEN | PATH | PAYLOAD|
24 +--------------------------------------+--...---+
27 @multitable @columnfractions 0.2 0.3 0.5
28 @headitem @tab XDR type @tab Value
29 @item Magic number @tab
30 8-byte, fixed length opaque data @tab
31 @verb{|N N C P P 0x00 0x00 0x03|}
32 @item Payload type @tab
34 0 (file), 1 (freq), 2 (exec), 3 (transition)
37 1-255, preferred packet @ref{Niceness, niceness} level
38 @item Path length @tab
40 actual length of @emph{path} field's payload
42 255 byte, fixed length opaque data @tab
44 @item UTF-8 encoded destination path for file transfer
45 @item UTF-8 encoded source path for file request
46 @item UTF-8 encoded, zero byte separated, exec's arguments
47 @item Node's id the transition packet must be relayed on
51 Path has fixed size because of hiding its actual length -- it is
52 valuable metadata. Payload is appended to the header -- it is not stored
53 as XDR field, because XDR has no ability to pass more than 4 GiB of
54 opaque data. Moreover most XDR libraries store fields in the memory in
57 Depending on the packet's type, payload could store:
61 @item Destination path for freq
62 @item @url{https://facebook.github.io/zstd/, Zstandard} compressed exec body
63 @item Whole encrypted packet we need to relay on
66 Also depending on packet's type, niceness level means:
69 @item Preferable niceness level for files sent by freq
70 @item @env{NNCP_NICE} variable's value passed during @ref{CfgExec} invocation.
74 @section Encrypted packet
76 Encrypted packets are the only files found in spools, in exchangeable
77 storages and that are synchronized between TCP daemons.
79 Each encrypted packet has the following header:
82 +------------ HEADER --------------------+ +------------- ENCRYPTED -------------+
84 +--------------------------------------------+------+---------+----------...---+------+
85 | MAGIC | NICE | SENDER | RCPT | EPUB | SIGN | SIZE | BLOCK 0 | BLOCK 1 ... | JUNK |
86 +-------------------------------------/------\------+---------+----------...---+------+
88 +-------------------------------------+
89 | MAGIC | NICE | SENDER | RCPT | EPUB |
90 +-------------------------------------+
93 @multitable @columnfractions 0.2 0.3 0.5
94 @headitem @tab XDR type @tab Value
95 @item Magic number @tab
96 8-byte, fixed length opaque data @tab
97 @verb{|N N C P E 0x00 0x00 0x04|}
100 1-255, packet @ref{Niceness, niceness} level
102 32-byte, fixed length opaque data @tab
105 32-byte, fixed length opaque data @tab
107 @item Exchange public key @tab
108 32-byte, fixed length opaque data @tab
109 Ephemeral curve25519 public key
111 64-byte, fixed length opaque data @tab
112 ed25519 signature for that packet's header
115 Signature is calculated over all previous fields.
117 All following encryption is done in AEAD mode using
118 @url{https://cr.yp.to/chacha.html, ChaCha20}-@url{https://en.wikipedia.org/wiki/Poly1305, Poly1305}
119 algorithms. Data is splitted on 128 KiB blocks. Each block is encrypted with
120 increasing nonce counter.
122 Authenticated and encrypted size come after the header:
124 @multitable @columnfractions 0.2 0.3 0.5
125 @headitem @tab XDR type @tab Value
127 unsigned hyper integer @tab
131 Then comes the actual payload.
133 Each node has static @strong{exchange} and @strong{signature} keypairs.
134 When node A want to send encrypted packet to node B, it:
137 @item generates ephemeral @url{http://cr.yp.to/ecdh.html, curve25519} keypair
138 @item prepares structure for signing
139 @item signs that structure using private
140 @url{http://ed25519.cr.yp.to/, ed25519} signature key
141 @item takes remote node's exchange public key and performs
142 Diffie-Hellman computation on this remote static public key and
143 private ephemeral one
144 @item derive the keys:
146 @item initialize @url{https://blake2.net/, BLAKE2Xb} XOF with
147 derived ephemeral key and 96-byte output length
148 @item feed @verb{|N N C P E 0x00 0x00 0x04|} magic number to XOF
149 @item read 32-bytes of "size" AEAD encryption key
150 @item read 32-bytes of payload AEAD encryption key
151 @item optionally read 32-bytes pad generation key
153 @item encrypts size, appends its authenticated ciphertext to the header
154 @item encrypts payload, appends its authenticated ciphertext
155 @item possibly appends any kind of "junk" noise data to hide real
156 payload's size from the adversary (generated using XOF with
157 unlimited output length)