doc/download.texi | 7 +++++++ doc/news.ru.texi | 14 ++++++++++++++ doc/news.texi | 13 +++++++++++++ doc/pkt/encrypted.texi | 144 +++++++++++++++++++++++++++++++++++++++++++---------- makedist.sh | 22 ++++++++++++++++------ src/cfg.go | 2 +- src/nncp.go | 2 +- src/tx.go | 12 ++++++++---- diff --git a/doc/download.texi b/doc/download.texi index cec442dfb654333d76a3b79f72c974912975779101fea878e2a53f6224ed595b..b442db8875d36ec7cb11c82312738d0e3427d88ad1625a8e89a2e6e872fcc7ee 100644 --- a/doc/download.texi +++ b/doc/download.texi @@ -30,6 +30,13 @@ @multitable {XXXXX} {XXXX-XX-XX} {XXXX KiB} {meta4 link sig} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} @headitem Version @tab Date @tab Size @tab Tarball @tab SHA256 checksum +@item @ref{Release 8_0_0, 8.0.0} @tab 2021-11-08 @tab 1203 KiB +@tab + @url{download/nncp-8.0.0.tar.xz.meta4, meta4} + @url{download/nncp-8.0.0.tar.xz, link} + @url{download/nncp-8.0.0.tar.xz.sig, sig} +@tab @code{376BE15D 956AE171 2D04B607 15D53B17 62CDFA72 86AA9957 2D8E4641 4DA987F0} + @item @ref{Release 7_7_0, 7.7.0} @tab 2021-09-11 @tab 1180 KiB @tab @url{download/nncp-7.7.0.tar.xz.meta4, meta4} diff --git a/doc/news.ru.texi b/doc/news.ru.texi index 9c152683a45791feec03804820c2856690c04341c58fa172393660323c7f4c37..4bc7ff97365822f774fcc435d4b3ca284b148d0c13264e63cfffa28333a76ee5 100644 --- a/doc/news.ru.texi +++ b/doc/news.ru.texi @@ -1,6 +1,20 @@ @node Новости @section Новости +@node Релиз 8.0.1 +@subsection Релиз 8.0.1 +@itemize + +@item +Исправлено некорректное вычисление @code{freq.chunked} значения, при +отсутствии которого всё равно форсированно включалась chunked передача. + +@item +Исправлено некорректное вычисление значения полного размера файла в +@file{.nncp.meta}. + +@end itemize + @node Релиз 8.0.0 @subsection Релиз 8.0.0 @itemize diff --git a/doc/news.texi b/doc/news.texi index c85092ef3284156ada1917873ce056f10d54a5dc972210553423145f74fc6ffd..c79e8b7ff9920f7e2b6d0a6584ea6a8caac3fc7a318346172237f41f2c72a4e7 100644 --- a/doc/news.texi +++ b/doc/news.texi @@ -3,6 +3,19 @@ @unnumbered News See also this page @ref{Новости, on russian}. +@node Release 8_0_1 +@section Release 8.0.1 +@itemize + +@item +Fixed incorrect @code{freq.chunked} value calculation. If it missed, +then anyway chunked transfer mode was forcefully turned on. + +@item +Fixed incorrect full file's size calculation in @file{.nncp.meta}. + +@end itemize + @node Release 8_0_0 @section Release 8.0.0 @itemize diff --git a/doc/pkt/encrypted.texi b/doc/pkt/encrypted.texi index ef7a7782bd267ac3a5ac766ad059cd44e0cb0e1df80ce9397c9267108501ba86..828f500ec55cfd88b933b398fe8fa4c6870ef8c2965b5208fc56ec2fe83661d7 100644 --- a/doc/pkt/encrypted.texi +++ b/doc/pkt/encrypted.texi @@ -7,11 +7,11 @@ Each encrypted packet has the following header: @verbatim - +------------ HEADER --------------------+ +------------- ENCRYPTED -------------+ - / \ / \ -+--------------------------------------------+------+---------+----------...---+------+ -| MAGIC | NICE | SENDER | RCPT | EPUB | SIGN | SIZE | BLOCK 0 | BLOCK 1 ... | JUNK | -+-------------------------------------/------\------+---------+----------...---+------+ + +------------ HEADER --------------------+ +------ ENCRYPTED -----+ + / \ / \ ++--------------------------------------------+---------+----------...---+-----...--+ +| MAGIC | NICE | SENDER | RCPT | EPUB | SIGN | BLOCK 0 | BLOCK 1 ... | OPAD | ++-------------------------------------/------\---------+----------...---+-----...--+ / \ +-------------------------------------+ | MAGIC | NICE | SENDER | RCPT | EPUB | @@ -22,7 +22,7 @@ @multitable @columnfractions 0.2 0.3 0.5 @headitem @tab XDR type @tab Value @item Magic number @tab 8-byte, fixed length opaque data @tab - @verb{|N N C P E 0x00 0x00 0x05|} + @verb{|N N C P E 0x00 0x00 0x06|} @item Niceness @tab unsigned integer @tab 1-255, packet @ref{Niceness, niceness} level @@ -40,17 +40,96 @@ 64-byte, fixed length opaque data @tab ed25519 signature for that packet's header over all previous fields. @end multitable -All following encryption is done in AEAD mode using +Each @code{BLOCK} is AEAD-encrypted 128 KiB data. Last block can have +smaller size. They are encrypted in AEAD mode using @url{https://cr.yp.to/chacha.html, ChaCha20}-@url{https://en.wikipedia.org/wiki/Poly1305, Poly1305} algorithms. Authenticated data is BLAKE3-256 hash of the unsigned -portion of the header (the same data used in the signature). Size is -XDR-encoded unsigned hyper integer, carrying the payload size, encrypted -as a single AEAD-block (with the tag) independently from the following -blocks. It is encoded with the zero nonce. +portion of the header (the same data used in the signature). Nonce is +block's sequence number (64-bit integer starting at 0). + +Concatenated plaintext of those blocks hold the following stream of data: -Payload with possible padding is divided on 128 KiB blocks blocks. They -are encrypted with the same authenticated data and increasing big-endian -64-bit nonce, starting at 1. +@verbatim ++-----------+--------+---------------------+--------+ +| PAYLOAD | SIZE | REST (OF PAYLOAD) | IPAD | ++-----------+--------+---------------------+--------+ + ^ + | + +-- always aligned to the beginning of block +@end verbatim + +Where @code{SIZE} is following XDR structure: + +@multitable @columnfractions 0.2 0.3 0.5 +@headitem @tab XDR type @tab Value +@item Payload @tab + unsigned hyper integer @tab + Full payload size. @code{len(PAYLOAD) + len(REST)} +@item Pad @tab + unsigned hyper integer @tab + Full padding size. @code{len(IPAD) + len(OPAD)} +@end multitable + +@code{SIZE} is always at the beginning of the block. So payload and rest +of it have variable length. Block containing @code{SIZE} is encrypted +with the different key (@code{key=size}), to distinguish it from the +"ordinary" ones (@code{key=full}). + +@code{IPAD} contains zeros and is shorter than single block. Padding is fully +optional and is used only to hide the payload full size. + +It is acceptable to have either @code{PAYLOAD} or @code{REST} of it of +zero length. For example: + +@verbatim ++------+-------------+ +| SIZE | PAYLOAD ... | ++------+-------------+ + \------ BLOCK -----/ + key=size + ++------+-------------+------+ +| SIZE | PAYLOAD ... | IPAD | ++------+-------------+------+ + \--------- BLOCK --------/ + key=size + ++--------------------------+ +------+-------------------+ +| PAYLOAD | .. | SIZE | IPAD ... | ++--------------------------+ +------+-------------------+ + \--------- BLOCK --------/ \--------- BLOCK --------/ + key=full key=size + ++--------------------------+ +------+-------------------+ +| PAYLOAD | .. | SIZE | PAYLOAD ... | ++--------------------------+ +------+-------------------+ + \--------- BLOCK --------/ \--------- BLOCK --------/ + key=full key=size + ++--------------------------+ +------+-------------+------+ +| PAYLOAD | .. | SIZE | PAYLOAD ... | IPAD | ++--------------------------+ +------+-------------+------+ + \--------- BLOCK --------/ \--------- BLOCK --------/ + key=full key=size + ++--------------------------+ +------+-------------------+ +--------------------------+ +| PAYLOAD | .. | SIZE | PAYLOAD ... | .. | PAYLOAD ... | ++--------------------------+ +------+-------------------+ +--------------------------+ + \--------- BLOCK --------/ \--------- BLOCK --------/ \--------- BLOCK --------/ + key=full key=size key=full + ++--------------------------+ +------+-------------------+ +-------------+-------------+ +| PAYLOAD | .. | SIZE | PAYLOAD ... | .. | PAYLOAD ... | IPAD ... | ++--------------------------+ +------+-------------------+ +-------------+------------+ + \--------- BLOCK --------/ \--------- BLOCK --------/ \--------- BLOCK --------/ + key=full key=size key=full +@end verbatim + +@code{OPAD} is appended if @code{IPAD} (inside the block) has not enough +length. @code{OPAD} is just an output of the XOF function. No encryption +and explicit authentication is applied to it. XOF is just faster and can +be computed deterministically on both ends -- you just have to +authenticate its length. Each node has static @strong{exchange} and @strong{signature} keypairs. When node A want to send encrypted packet to node B, it: @@ -63,17 +142,32 @@ @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 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 derives three keys using BLAKE3 derivation function from the + curve25519-derived ephemeral source key: + @itemize + @item @code{key=full} with the context of: + @verb{|N N C P E 0x00 0x00 0x06 F U L L|} + @item @code{key=size} with the context of: + @verb{|N N C P E 0x00 0x00 0x06 S I Z E|} + @item @code{key=pad} with the context of: + @verb{|N N C P E 0x00 0x00 0x06 P A D|} + @end itemize @item calculates authenticated data: it is BLAKE3-256 hash of the unsigned header (same used for signing) -@item encrypts size, appends its authenticated ciphertext to the header - (with authenticated data, nonce=0) -@item encrypts each payload block, appending its authenticated ciphertext - (with authenticated data, nonce starting at 1, increasing with each block) -@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 P A D|}) +@item reads the payload by 128 KiB chunks. If it is enough data to fill + the entire 128 KiB block, then encrypt the chunk with + @code{key=full} key +@item if there is not enough data, then payload is reaching the end. + @itemize + @item prepend @code{SIZE} structure to the finishing chunk of data. + All sizes at that time are known + @item produce block with @code{SIZE} even if there is no payload + data left + @item append remaining payload to the @code{SIZE}, if it is left + @item if there is padding, then fill current block to the end with + zeros (@code{IPAD}) + @item encrypt the block with @code{key=size} key + @end itemize +@item if there is more padding left (@code{OPAD}), then generate it with + BLAKE3 XOF function using the @code{key=pad} key @end enumerate diff --git a/makedist.sh b/makedist.sh index 3fa7c691272a73bb765a87afc4302fecd5d7232c24feeee4c901e7b72eea4562..820494c997edabd52aba6894c5267143d73be7985e4787550db86b135ff2fb76 100755 --- a/makedist.sh +++ b/makedist.sh @@ -17,14 +17,23 @@ rm -r \ github.com/flynn/noise/vector* \ github.com/gorhill/cronexpr/APLv2 \ github.com/hjson/hjson-go/build_release.sh \ - github.com/golang/snappy \ + github.com/klauspost/compress/gen.sh \ + github.com/klauspost/compress/gzhttp \ + github.com/klauspost/compress/internal \ + github.com/klauspost/compress/s2* \ + github.com/klauspost/compress/snappy \ github.com/klauspost/compress/zstd/snappy.go \ golang.org/x/sys/plan9 \ golang.org/x/sys/windows find github.com/klauspost/compress golang.org/x/sys -name "*_test.go" -delete +find . -type d -exec rmdir {} + || : cd ../.. rm -r ports -find . \( -name .gitignore -o -name .travis.yml \) -delete +find . \( \ + -name .gitignore -o \ + -name .travis.yml -o \ + -name .goreleaser.yml -o \ + -name .gitattributes \) -delete mkdir contrib cp ~/work/redo/minimal/do contrib/do @@ -40,7 +49,7 @@ perl -i -ne 'print unless /include pedro/' doc/index.texi doc/about.ru.texi perl -p -i -e 's/^(.verbatiminclude) .*$/$1 PUBKEY.asc/g' doc/integrity.texi mv doc/.well-known/openpgpkey/nncpgo.org/hu/i4cdqgcarfjdjnba6y4jnf498asg8c6p.asc PUBKEY.asc ln -s ../PUBKEY.asc doc -redo doc +redo doc/all ######################################################################## # Supplementary files autogeneration @@ -113,18 +122,19 @@ cd .. tar cvf nncp-"$release".tar --uid=0 --gid=0 --numeric-owner nncp-"$release" xz -9v nncp-"$release".tar -tarball=$cur/doc/download/nncp-"$release".tar.xz +tarball=nncp-"$release".tar.xz gpg --detach-sign --sign --local-user releases@nncpgo.org "$tarball" gpg --enarmor < "$tarball".sig | sed "/^Comment:/d ; s/ARMORED FILE/SIGNATURE/" > "$tarball".asc meta4-create -file "$tarball" -mtime "$tarball" -sig "$tarball".asc \ - hhttp://www.nncpgo.org/download/"$tarball" \ + http://www.nncpgo.org/download/"$tarball" \ https://nncp.mirrors.quux.org/download/"$tarball" > "$tarball".meta4 -mv -v $tmp/"$tarball" $tmp/"$tarball".sig $tmp/"$tarball".meta4 $cur/doc/download size=$(( $(stat -f %z $tarball) / 1024 )) hash=$(gpg --print-md SHA256 < $tarball) release_date=$(date "+%Y-%m-%d") + +mv -v $tmp/"$tarball" $tmp/"$tarball".sig $tmp/"$tarball".meta4 $cur/doc/download release_underscored=`echo $release | tr . _` cat <