]> Cypherpunks.ru repositories - nncp.git/blobdiff - doc/pkt.texi
MTH
[nncp.git] / doc / pkt.texi
index f82bd8bfd29d83162a486939c1b6ca97150d48a9..567d3f77226d7e2d192de79b3ea5fd14ddf8d744 100644 (file)
@@ -2,8 +2,7 @@
 @unnumbered Packet format
 
 All packets are
-@url{https://en.wikipedia.org/wiki/External_Data_Representation,
-XDR}-encoded structures.
+@url{https://tools.ietf.org/html/rfc4506, XDR}-encoded structures.
 
 @menu
 * Plain packet: Plain.
@@ -14,50 +13,62 @@ XDR}-encoded structures.
 @section Plain packet
 
 Plain packet contains either the whole file, or file request (freq), or
-transition packet or email message. It is called "plain", because it
+transition packet or exec message. It is called "plain", because it
 contains plaintext, but plain packets would never be stored on your hard
 drive.
 
 @verbatim
             HEADER
-+-------------------------------+--...---+
-| MAGIC | TYPE | PATHLEN | PATH | PAYLOAD|
-+-------------------------------+--...---+
++--------------------------------------+--...---+
+| MAGIC | TYPE | NICE | PATHLEN | PATH | PAYLOAD|
++--------------------------------------+--...---+
 @end verbatim
 
 @multitable @columnfractions 0.2 0.3 0.5
-@headitem  @tab XDR type @tab Value
+@headitem @tab XDR type @tab Value
 @item Magic number @tab
     8-byte, fixed length opaque data @tab
-    @code{NNCPP0x10x00x00}
+    @verb{|N N C P P 0x00 0x00 0x03|}
 @item Payload type @tab
     unsigned integer @tab
-    0 (file), 1 (freq), 2 (mail), 3 (transition)
+    0 (file), 1 (freq), 2 (exec), 3 (transition), 4 (exec-fat)
+@item Niceness @tab
+    unsigned integer @tab
+    1-255, preferred packet @ref{Niceness, niceness} level
 @item Path length @tab
     unsigned integer @tab
-    actual length of following field's payload
+    actual length of @emph{path} field's payload
 @item Path @tab
     255 byte, fixed length opaque data @tab
     @itemize
     @item UTF-8 encoded destination path for file transfer
     @item UTF-8 encoded source path for file request
-    @item UTF-8 encoded, space separated, email recipients list
-    @item Node id the transition packet must be relayed on
+    @item UTF-8 encoded, zero byte separated, exec's arguments
+    @item Node's id the transition packet must be relayed on
     @end itemize
 @end multitable
 
 Path has fixed size because of hiding its actual length -- it is
 valuable metadata. Payload is appended to the header -- it is not stored
-as XDR field, because most XDR libraries will store all that data in the
-memory.
+as XDR field, because XDR has no ability to pass more than 4 GiB of
+opaque data. Moreover most XDR libraries store fields in the memory in
+practice.
 
 Depending on the packet's type, payload could store:
 
 @itemize
 @item File contents
 @item Destination path for freq
-@item @url{http://zlib.net/, zlib} compressed email
+@item @url{https://facebook.github.io/zstd/, Zstandard} compressed exec body
 @item Whole encrypted packet we need to relay on
+@item Uncompressed exec body
+@end itemize
+
+Also depending on packet's type, niceness level means:
+
+@itemize
+@item Preferable niceness level for files sent by freq
+@item @env{NNCP_NICE} variable's value passed during @ref{CfgExec} invocation.
 @end itemize
 
 @node Encrypted
@@ -69,76 +80,75 @@ storages and that are synchronized between TCP daemons.
 Each encrypted packet has the following header:
 
 @verbatim
-                    HEADER
-+--------------------------------------------+-------...--------+
-| MAGIC | NICE | SENDER | EPUB | SIGN | SIZE | CIPHERTEXT | MAC |
-+------------------------------/------\------+-------...--------+
-                              /        \
-             +--------------------------------------------+
-             | MAGIC | NICE | RCPT | SENDER | EPUB | SIZE |
-             +--------------------------------------------+
+  +------------ HEADER --------------------+   +------------- ENCRYPTED -------------+
+ /                                          \ /                                       \
++--------------------------------------------+------+---------+----------...---+------+
+| MAGIC | NICE | SENDER | RCPT | EPUB | SIGN | SIZE | BLOCK 0 | BLOCK 1  ...   | JUNK |
++-------------------------------------/------\------+---------+----------...---+------+
+                                     /        \
+                      +-------------------------------------+
+                      | MAGIC | NICE | SENDER | RCPT | EPUB |
+                      +-------------------------------------+
 @end verbatim
 
 @multitable @columnfractions 0.2 0.3 0.5
-@headitem  @tab XDR type @tab Value
+@headitem @tab XDR type @tab Value
 @item Magic number @tab
     8-byte, fixed length opaque data @tab
-    @code{NNCPE0x10x00x00}
+    @verb{|N N C P E 0x00 0x00 0x05|}
 @item Niceness @tab
     unsigned integer @tab
     1-255, packet @ref{Niceness, niceness} level
 @item Sender @tab
     32-byte, fixed length opaque data @tab
     Sender node's id
+@item Recipient @tab
+    32-byte, fixed length opaque data @tab
+    Recipient node's id
 @item Exchange public key @tab
     32-byte, fixed length opaque data @tab
     Ephemeral curve25519 public key
 @item Signature @tab
     64-byte, fixed length opaque data @tab
     ed25519 signature for that packet's header
-@item Size @tab
-    unsigned hyper integer @tab
-    Encrypted payload size
 @end multitable
 
-Signature is calculated over the following structure:
+Signature is calculated over all previous fields.
 
-@itemize
-@item Magic number
-@item Niceness
-@item Recipient (32-byte recipient node's id)
-@item Sender
-@item Exchange public key
-@item Size
-@end itemize
+All following encryption is done in AEAD mode using
+@url{https://cr.yp.to/chacha.html, ChaCha20}-@url{https://en.wikipedia.org/wiki/Poly1305, Poly1305}
+algorithms. Data is divided on 128 KiB blocks. Each block is encrypted with
+increasing nonce counter.
+
+Authenticated and encrypted size come after the header:
+
+@multitable @columnfractions 0.2 0.3 0.5
+@headitem @tab XDR type @tab Value
+@item Size @tab
+    unsigned hyper integer @tab
+    Payload size.
+@end multitable
 
-Actual encrypted payload comes after that header. Payload is encrypted
-using @url{https://www.schneier.com/academic/twofish/, Twofish}
-algorithm with 256-bit key in
-@url{https://en.wikipedia.org/wiki/Counter_mode#Counter_.28CTR.29, CTR}
-mode of operation with zero initialization vector (because each
-encrypted packet has ephemeral exchange key). Ciphertext's length is
-equal to plaintext. @url{https://blake2.net/, BLAKE2b-256} MAC is
-appended to the ciphertext.
+Then comes the actual payload.
 
 Each node has static @strong{exchange} and @strong{signature} keypairs.
 When node A want to send encrypted packet to node B, it:
 
 @enumerate
 @item generates ephemeral @url{http://cr.yp.to/ecdh.html, curve25519} keypair
-@item prepares structure for signing (underlying payload size must be
-already known)
-@item signs that structure using private @url{http://ed25519.cr.yp.to/,
-ed25519} signature key
+@item prepares structure for signing
+@item signs that structure using private
+    @url{http://ed25519.cr.yp.to/, ed25519} signature key
 @item takes remote node's exchange public key and performs
-Diffie-Hellman computation on this remote static public key and private
-ephemeral one
-@item derived ephemeral key used as an input to
-@url{https://en.wikipedia.org/wiki/HKDF, HKDF}-BLAKE2b-256 key
-derivation function
-@item two 256-bit keys are derived from it for using with Twofish and
-BLAKE2b-MAC functions
-@item Twofish encryption is performed over the plaintext and
-BLAKE2b-MACing is performed over the ciphertext. Ciphertext and MAC tag
-go after header.
+    Diffie-Hellman computation on this remote static public key and
+    private ephemeral one
+@item derives 32-bytes AEAD encryption key with BLAKE3 derivation
+    function. Source key is the derived ephemeral key. Context is
+    @verb{|N N C P E 0x00 0x00 0x05|} magic number
+@item encrypts size, appends its authenticated ciphertext to the header
+@item encrypts each payload block, appending its authenticated ciphertext
+@item possibly appends any kind of "junk" noise data to hide real
+    payload's size from the adversary (generated using BLAKE3 XOF, with
+    the key derived from the ephemeral one and context string of
+    @verb{|N N C P E 0x00 0x00 0x05 <SP> P A D|})
 @end enumerate