]> Cypherpunks.ru repositories - nncp.git/blob - doc/pkt.texi
MTH
[nncp.git] / doc / pkt.texi
1 @node Packet
2 @unnumbered Packet format
3
4 All packets are
5 @url{https://tools.ietf.org/html/rfc4506, XDR}-encoded structures.
6
7 @menu
8 * Plain packet: Plain.
9 * Encrypted packet: Encrypted.
10 @end menu
11
12 @node Plain
13 @section Plain packet
14
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
18 drive.
19
20 @verbatim
21             HEADER
22 +--------------------------------------+--...---+
23 | MAGIC | TYPE | NICE | PATHLEN | PATH | PAYLOAD|
24 +--------------------------------------+--...---+
25 @end verbatim
26
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
33     unsigned integer @tab
34     0 (file), 1 (freq), 2 (exec), 3 (transition), 4 (exec-fat)
35 @item Niceness @tab
36     unsigned integer @tab
37     1-255, preferred packet @ref{Niceness, niceness} level
38 @item Path length @tab
39     unsigned integer @tab
40     actual length of @emph{path} field's payload
41 @item Path @tab
42     255 byte, fixed length opaque data @tab
43     @itemize
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
48     @end itemize
49 @end multitable
50
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
55 practice.
56
57 Depending on the packet's type, payload could store:
58
59 @itemize
60 @item File contents
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
65 @end itemize
66
67 Also depending on packet's type, niceness level means:
68
69 @itemize
70 @item Preferable niceness level for files sent by freq
71 @item @env{NNCP_NICE} variable's value passed during @ref{CfgExec} invocation.
72 @end itemize
73
74 @node Encrypted
75 @section Encrypted packet
76
77 Encrypted packets are the only files found in spools, in exchangeable
78 storages and that are synchronized between TCP daemons.
79
80 Each encrypted packet has the following header:
81
82 @verbatim
83   +------------ HEADER --------------------+   +------------- ENCRYPTED -------------+
84  /                                          \ /                                       \
85 +--------------------------------------------+------+---------+----------...---+------+
86 | MAGIC | NICE | SENDER | RCPT | EPUB | SIGN | SIZE | BLOCK 0 | BLOCK 1  ...   | JUNK |
87 +-------------------------------------/------\------+---------+----------...---+------+
88                                      /        \
89                       +-------------------------------------+
90                       | MAGIC | NICE | SENDER | RCPT | EPUB |
91                       +-------------------------------------+
92 @end verbatim
93
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|}
99 @item Niceness @tab
100     unsigned integer @tab
101     1-255, packet @ref{Niceness, niceness} level
102 @item Sender @tab
103     32-byte, fixed length opaque data @tab
104     Sender node's id
105 @item Recipient @tab
106     32-byte, fixed length opaque data @tab
107     Recipient node's id
108 @item Exchange public key @tab
109     32-byte, fixed length opaque data @tab
110     Ephemeral curve25519 public key
111 @item Signature @tab
112     64-byte, fixed length opaque data @tab
113     ed25519 signature for that packet's header
114 @end multitable
115
116 Signature is calculated over all previous fields.
117
118 All following encryption is done in AEAD mode using
119 @url{https://cr.yp.to/chacha.html, ChaCha20}-@url{https://en.wikipedia.org/wiki/Poly1305, Poly1305}
120 algorithms. Data is divided on 128 KiB blocks. Each block is encrypted with
121 increasing nonce counter.
122
123 Authenticated and encrypted size come after the header:
124
125 @multitable @columnfractions 0.2 0.3 0.5
126 @headitem @tab XDR type @tab Value
127 @item Size @tab
128     unsigned hyper integer @tab
129     Payload size.
130 @end multitable
131
132 Then comes the actual payload.
133
134 Each node has static @strong{exchange} and @strong{signature} keypairs.
135 When node A want to send encrypted packet to node B, it:
136
137 @enumerate
138 @item generates ephemeral @url{http://cr.yp.to/ecdh.html, curve25519} keypair
139 @item prepares structure for signing
140 @item signs that structure using private
141     @url{http://ed25519.cr.yp.to/, ed25519} signature key
142 @item takes remote node's exchange public key and performs
143     Diffie-Hellman computation on this remote static public key and
144     private ephemeral one
145 @item derives 32-bytes AEAD encryption key with BLAKE3 derivation
146     function. Source key is the derived ephemeral key. Context is
147     @verb{|N N C P E 0x00 0x00 0x05|} magic number
148 @item encrypts size, appends its authenticated ciphertext to the header
149 @item encrypts each payload block, appending its authenticated ciphertext
150 @item possibly appends any kind of "junk" noise data to hide real
151     payload's size from the adversary (generated using BLAKE3 XOF, with
152     the key derived from the ephemeral one and context string of
153     @verb{|N N C P E 0x00 0x00 0x05 <SP> P A D|})
154 @end enumerate