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), 4 (exec-fat)
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
64 @item Uncompressed exec body
67 Also depending on packet's type, niceness level means:
70 @item Preferable niceness level for files sent by freq
71 @item @env{NNCP_NICE} variable's value passed during @ref{CfgExec} invocation.
75 @section Encrypted packet
77 Encrypted packets are the only files found in spools, in exchangeable
78 storages and that are synchronized between TCP daemons.
80 Each encrypted packet has the following header:
83 +------------ HEADER --------------------+ +------------- ENCRYPTED -------------+
85 +--------------------------------------------+------+---------+----------...---+------+
86 | MAGIC | NICE | SENDER | RCPT | EPUB | SIGN | SIZE | BLOCK 0 | BLOCK 1 ... | JUNK |
87 +-------------------------------------/------\------+---------+----------...---+------+
89 +-------------------------------------+
90 | MAGIC | NICE | SENDER | RCPT | EPUB |
91 +-------------------------------------+
94 @multitable @columnfractions 0.2 0.3 0.5
95 @headitem @tab XDR type @tab Value
96 @item Magic number @tab
97 8-byte, fixed length opaque data @tab
98 @verb{|N N C P E 0x00 0x00 0x05|}
100 unsigned integer @tab
101 1-255, packet @ref{Niceness, niceness} level
103 32-byte, fixed length opaque data @tab
106 32-byte, fixed length opaque data @tab
108 @item Exchange public key @tab
109 32-byte, fixed length opaque data @tab
110 Ephemeral curve25519 public key
112 64-byte, fixed length opaque data @tab
113 ed25519 signature for that packet's header over all previous fields.
116 All following encryption is done in AEAD mode using
117 @url{https://cr.yp.to/chacha.html, ChaCha20}-@url{https://en.wikipedia.org/wiki/Poly1305, Poly1305}
118 algorithms. Authenticated data is BLAKE3-256 hash of the unsigned
119 portion of the header (the same data used in the signature). Size is
120 XDR-encoded unsigned hyper integer, carrying the payload size, encrypted
121 as a single AEAD-block (with the tag) independently from the following
122 blocks. It is encoded with the zero nonce.
124 Payload with possible padding is divided on 128 KiB blocks blocks. They
125 are encrypted with the same authenticated data and increasing big-endian
126 64-bit nonce, starting at 1.
128 Each node has static @strong{exchange} and @strong{signature} keypairs.
129 When node A want to send encrypted packet to node B, it:
132 @item generates ephemeral @url{http://cr.yp.to/ecdh.html, curve25519} keypair
133 @item prepares structure for signing
134 @item signs that structure using private
135 @url{http://ed25519.cr.yp.to/, ed25519} signature key
136 @item takes remote node's exchange public key and performs
137 Diffie-Hellman computation on this remote static public key and
138 private ephemeral one
139 @item derives 32-bytes AEAD encryption key with BLAKE3 derivation
140 function. Source key is the derived ephemeral key. Context is
141 @verb{|N N C P E 0x00 0x00 0x05|} magic number
142 @item calculates authenticated data: it is BLAKE3-256 hash of the
143 unsigned header (same used for signing)
144 @item encrypts size, appends its authenticated ciphertext to the header
145 (with authenticated data, nonce=0)
146 @item encrypts each payload block, appending its authenticated ciphertext
147 (with authenticated data, nonce starting at 1, increasing with each block)
148 @item possibly appends any kind of "junk" noise data to hide real
149 payload's size from the adversary (generated using BLAKE3 XOF, with
150 the key derived from the ephemeral one and context string of
151 @verb{|N N C P E 0x00 0x00 0x05 <SP> P A D|})