.gitmodules | 3 --- VERSION | 2 +- doc/Makefile | 8 +++++++- doc/about.ru.texi | 2 +- doc/about.texi | 2 +- doc/client.texi | 4 ++-- doc/developer.texi | 12 ++++++------ doc/download.texi | 6 +++++- doc/encless.texi | 2 +- doc/example.texi | 4 ++-- doc/installation.texi | 1 - doc/integrity.texi | 3 ++- doc/mtu.texi | 2 +- doc/news.ru.texi | 10 ++++++++++ doc/news.texi | 9 +++++++++ doc/scripts.texi | 2 +- doc/server.texi | 6 +++--- doc/sources.texi | 1 - doc/style.css | 17 +++++------------ doc/timeout.texi | 2 +- doc/transport.texi | 10 +++++----- doc/user.texi | 2 +- src/chacha20 | 1 + src/cypherpunks.ru/govpn/aont/oaep.go | 32 +++++++++++++++++++------------- src/cypherpunks.ru/govpn/cmd/govpn-client/main.go | 6 +++--- src/cypherpunks.ru/govpn/cnw/cnw.go | 20 ++++++++++---------- src/cypherpunks.ru/govpn/encless.go | 8 ++++---- src/cypherpunks.ru/govpn/encless_test.go | 12 ++++++------ src/cypherpunks.ru/govpn/handshake.go | 63 ++++++++++++++++++++++++++--------------------------- src/cypherpunks.ru/govpn/identity.go | 8 ++++++-- src/cypherpunks.ru/govpn/peer.go | 39 ++++++++++++++++++++------------------- src/cypherpunks.ru/govpn/tap.go | 2 +- src/cypherpunks.ru/govpn/tap_linux.go | 7 ++++++- src/cypherpunks.ru/govpn/verifier.go | 13 +++++++++++-- utils/makedist.sh | 14 +++++++------- utils/newclient.sh | 2 +- diff --git a/.gitmodules b/.gitmodules index bb2b1f83ab61d548a662c6536318abd69342dea4..82df1f7e8a594fcda48fccdf6d3c937b356e89fb 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,9 +7,6 @@ url = https://github.com/agl/ed25519.git [submodule "src/golang.org/x/crypto"] path = src/golang.org/x/crypto url = https://go.googlesource.com/crypto -[submodule "src/github.com/dchest/blake2b"] - path = src/github.com/dchest/blake2b - url = https://github.com/dchest/blake2b.git [submodule "src/github.com/go-yaml/yaml"] path = src/github.com/go-yaml/yaml url = https://github.com/go-yaml/yaml.git diff --git a/VERSION b/VERSION index e0ea36feef6e828ce8587989537a827d0c3c98ed..4fedf1d20e15761409d6e4e3bf99c0beb499fdfe 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -6.0 +7.0 diff --git a/doc/Makefile b/doc/Makefile index 6e2b0db18d55075e9874298871bba0fc53b58fdc..239750c70179ed5464b0efd116b658443633ea06 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -8,11 +8,17 @@ govpn.info: *.texi handshake.utxt $(MAKEINFO) -o govpn.info index.texi +CSS != cat style.css + govpn.html: *.texi handshake.utxt rm -f govpn.html/*.html $(MAKEINFO) --html \ - --css-include=style.css \ + --set-customization-variable CSS_LINES='$(CSS)' \ --set-customization-variable SHOW_TITLE=0 \ + --set-customization-variable USE_ACCESSKEY=0 \ --set-customization-variable DATE_IN_HEADER=1 \ + --set-customization-variable TOP_NODE_UP_URL=index.html \ + --set-customization-variable CLOSE_QUOTE_SYMBOL=\" \ + --set-customization-variable OPEN_QUOTE_SYMBOL=\" \ -o govpn.html index.texi cp -r .well-known govpn.html/ diff --git a/doc/about.ru.texi b/doc/about.ru.texi index b91108345f9aa0d121b72be596e376b971694a39..0c45017ca7ed2b3d2422c36f4d2ebeb9bea5f6d8 100644 --- a/doc/about.ru.texi +++ b/doc/about.ru.texi @@ -70,7 +70,7 @@ конфигурацией. Клиенты имеют заранее установленный @ref{Identity, идентификатор}, невидимый третьим лицам (они анонимны для них). @item -Использует @url{https://ru.wikipedia.org/wiki/TUN/TAP, TAP} низлежащие +Использует @url{https://ru.wikipedia.org/wiki/TUN/TAP, TUN/TAP} низлежащие сетевые интерфейсы. @item diff --git a/doc/about.texi b/doc/about.texi index 59359c8947f7100bba7130dbfa0e34a2600d3dd3..7cda5af5d6db5f52bc8d6466b986c1888538a54b 100644 --- a/doc/about.texi +++ b/doc/about.texi @@ -66,7 +66,7 @@ options. Clients have pre-established @ref{Identity, identity} invisible for third-parties (they are anonymous). @item -Uses @url{https://en.wikipedia.org/wiki/TAP_(network_driver), TAP} +Uses @url{https://en.wikipedia.org/wiki/TAP_(network_driver), TUN/TAP} underlying network interfaces. @item diff --git a/doc/client.texi b/doc/client.texi index 58dc74bb2f3a8f3bd1e549769e0dfd7766a9e62d..42b8a65910f2a1e18ecef5f0d86f33d797c7a454 100644 --- a/doc/client.texi +++ b/doc/client.texi @@ -7,7 +7,7 @@ @table @option @item -mtu -Expected TAP interface @ref{MTU}. +Expected TUN/TAP interface @ref{MTU}. @item -proto @ref{Network, Network protocol} to use. Can be either @emph{udp} @@ -25,7 +25,7 @@ @item -remote Address (@code{host:port} format) of remote server we need to connect to. @item -iface -TAP interface name. +TUN/TAP interface name. @item -verifier Our client's @ref{Verifier}. diff --git a/doc/developer.texi b/doc/developer.texi index e147f7e280a82b5294db149d9e1a08cacc1b87ca..15e87800a314b44604730747b9a0610ab91c8f02 100644 --- a/doc/developer.texi +++ b/doc/developer.texi @@ -5,16 +5,16 @@ Pay attention how to get @ref{Sources, development source code}. @table @asis @item Data encryption - @url{http://cr.yp.to/snuffle.html, Salsa20}. + @url{https://cr.yp.to/chacha.html, ChaCha20}. @item Message authentication - @url{http://cr.yp.to/mac.html, Poly1305}. + @url{https://cr.yp.to/mac.html, Poly1305}. @item Nonce and identity obfuscation @url{https://blake2.net/, BLAKE2b-MAC}. @item Password authenticated key agreement - DH-A-EKE powered by @url{http://cr.yp.to/ecdh.html, Curve25519} - and @url{http://ed25519.cr.yp.to/, Ed25519}. + DH-A-EKE powered by @url{https://cr.yp.to/ecdh.html, Curve25519} + and @url{https://ed25519.cr.yp.to/, Ed25519}. @item DH elliptic-curve point encoding for public keys - @url{http://elligator.cr.yp.to/, Elligator}. + @url{https://elligator.cr.yp.to/, Elligator}. @item Verifier password hashing algorithm @url{https://crypto.stanford.edu/balloon/, Balloon hashing} based on BLAKE2b-256. @@ -25,7 +25,7 @@ over 128 bits of @url{http://theory.lcs.mit.edu/~cis/pubs/rivest/fusion.ps, All-Or-Nothing-Transformed} (based on @url{http://cseweb.ucsd.edu/~mihir/papers/oaep.html, OAEP} using - Salsa20 with BLAKE2b-256 based + ChaCha20 with BLAKE2b-256 based @url{http://crypto.stanford.edu/~dabo/abstracts/saep.html, SAEP+} checksums) data with 128-bits of feeded random. @item Packet overhead diff --git a/doc/download.texi b/doc/download.texi index 6fe34f224380701bdeba0454fd446f8b6152ffaf..31977c66c2bea397f712c3aabd18b5118f1ad55a 100644 --- a/doc/download.texi +++ b/doc/download.texi @@ -5,8 +5,12 @@ You can obtain releases source code prepared tarballs from the links below (or use @url{https://sourceforge.net/projects/govpn/files/, Sourceforge mirror}). Do not forget to check tarball @ref{Integrity, integrity}. -@multitable {XXXXX} {XXXX KiB} {link sign} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} +@multitable {XXXXX} {XXXX KiB} {link sign} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} @headitem Version @tab Size @tab Tarball @tab SHA256 checksum + +@item @ref{Release 6.0, 6.0} @tab 310 KiB +@tab @url{download/govpn-6.0.tar.xz, link} @url{download/govpn-6.0.tar.xz.sig, sign} +@tab @code{3ACAE3B9 884F3260 38FCA9CE 6A309DF6 71BE6386 1FB2058B C79AE7DC 2A1A1811} @item @ref{Release 5.10, 5.10} @tab 316 KiB @tab @url{download/govpn-5.10.tar.xz, link} @url{download/govpn-5.10.tar.xz.sig, sign} diff --git a/doc/encless.texi b/doc/encless.texi index 6d694b2a984217740f0dff2c321aaa088c28d4c3..9513d6ce67f5bd8b473b0a0cb44cabd478e3666f 100644 --- a/doc/encless.texi +++ b/doc/encless.texi @@ -8,7 +8,7 @@ some countries forbids usage of encryption (but again not the authentication). GoVPN provides special encryptionless mode of operation. In this mode it -replaces Salsa20 function used for confidentiality with rather +replaces ChaCha20 function used for confidentiality with rather well-known @url{http://people.csail.mit.edu/rivest/chaffing-980701.txt, Chaffing-and-Winnowing} (CnW) technology. This is rather traffic and resource hungry algorithm, so we use it after diff --git a/doc/example.texi b/doc/example.texi index 483177262533fdcca383f4dd0c6617b4720bb33a..688898a76bf350e646fac90b3ef7f702a5c40aa1 100644 --- a/doc/example.texi +++ b/doc/example.texi @@ -9,7 +9,7 @@ @item You have got @code{wlan0} NIC with 192.168.0/24 network on it. @item You want to create virtual encrypted and authenticated 172.16.0/24 network and use it as a default transport. @item Assume that outgoing GoVPN packets can be fragmented, so we do not -bother configuring MTU of TAP interfaces. For better performance just +bother configuring MTU of TUN/TAP interfaces. For better performance just lower it and check that no fragmentation of outgoing UDP packets occurs. @end itemize @@ -29,7 +29,7 @@ Place the following YAML configuration entry on the server's side: Alice: up: /path/to/up.sh - iface: or TAP interface name + iface: or TUN/TAP interface name verifier: $balloon$s=32768,t=16,p=2$bwR5VjeCYIQaa8SeaI3rqg$KCNIqfS4DGsBTtVytamAzcISgrlEWvNxan1UfBrFu10 @end verbatim diff --git a/doc/installation.texi b/doc/installation.texi index 01ac54b8e1cbc48aaf04a193ad7f7f08ac2c17dc..1443d7f95c8f752d3fd5e5d57a2b1694f9c956bb 100644 --- a/doc/installation.texi +++ b/doc/installation.texi @@ -26,7 +26,6 @@ @multitable @columnfractions .40 .20 .40 @headitem Library @tab Platform @tab Licence @item @code{github.com/agl/ed25519} @tab All @tab BSD 3-Clause @item @code{github.com/bigeagle/water} @tab GNU/Linux @tab BSD 3-Clause -@item @code{github.com/dchest/blake2b} @tab All @tab CC0 1.0 @item @code{github.com/go-yaml/yaml} @tab All @tab LGPLv3 and MIT @item @code{golang.org/x/crypto} @tab All @tab BSD 3-Clause @end multitable diff --git a/doc/integrity.texi b/doc/integrity.texi index ff692ff98d322f666c953629e18de09e2cc63b4e..b9bc1a1e60910a76ae8675f65e5176ca6e5635b5 100644 --- a/doc/integrity.texi +++ b/doc/integrity.texi @@ -23,9 +23,10 @@ public key fingerprint. @item @verbatim -% gpg --auto-key-locate pka --locate-keys releases at govpn dot info +% gpg --keyserver hkp://keys.gnupg.net/ --recv-keys 0xF2F59045FFE2F4A1 % gpg --auto-key-locate dane --locate-keys releases at govpn dot info % gpg --auto-key-locate wkd --locate-keys releases at govpn dot info +% gpg --auto-key-locate pka --locate-keys releases at govpn dot info @end verbatim @item diff --git a/doc/mtu.texi b/doc/mtu.texi index c11cef916020f2df315a579778fe128320f018a8..00aa7e7e94e14d68941021aa08b27a8e7a2b67d7 100644 --- a/doc/mtu.texi +++ b/doc/mtu.texi @@ -2,7 +2,7 @@ @node MTU @subsection Maximum Transmission Unit MTU option tells what maximum transmission unit is expected to get from -TAP interface. It is per-user configuration. Incoming packets of bigger +TUN/TAP interface. It is per-user configuration. Incoming packets of bigger sizes (including the padding byte) will be ignored. If either @ref{Noise, noise}, @ref{Encless, encryptionless mode} or @ref{CPR} are enabled, then all outgoing packets are filled up to that MTU value. diff --git a/doc/news.ru.texi b/doc/news.ru.texi index 47ba43bc1607d386173505a9fd3ccbbc483e5746..81c3139d90748b163fe4a5e731bf1df1202c0d56 100644 --- a/doc/news.ru.texi +++ b/doc/news.ru.texi @@ -1,6 +1,16 @@ @node Новости @section Новости +@node Релиз 7.0 +@subsection Релиз 7.0 +@itemize +@item (X)Salsa20 заменён на ChaCha20. Теоретически он должен быть +быстрее и более безопасным. Это несовместимое с предыдущими версиями +клиента изменение! +@item Возможность использовать TUN-интерфейсы под GNU/Linux. FreeBSD без +изменений уже поддерживала эту возможность. +@end itemize + @node Релиз 6.0 @subsection Релиз 6.0 @itemize diff --git a/doc/news.texi b/doc/news.texi index 631c5940ac541920570e9a02f9e807d232a872fe..5a6db8f5113d93524668df0fae901f1c9ff612d7 100644 --- a/doc/news.texi +++ b/doc/news.texi @@ -3,6 +3,15 @@ @unnumbered News See also this page @ref{Новости, on russian}. +@node Release 7.0 +@section Release 7.0 +@itemize +@item (X)Salsa20 is replaced with ChaCha20. Theoretically it should be +faster and more secure. Previous versions are not compatible with it! +@item Ability to use TUN-interfaces under GNU/Linux. FreeBSD has already +supported them without any modifications. +@end itemize + @node Release 6.0 @section Release 6.0 @itemize diff --git a/doc/scripts.texi b/doc/scripts.texi index 7b2e3c0f78b08c12b83efea73fdac384667c8ed7..69848a02a98f5ea4950c23cf16bcefa1371ad0f4 100644 --- a/doc/scripts.texi +++ b/doc/scripts.texi @@ -11,7 +11,7 @@ @item GOVPN_REMOTE Remote peer's address. In client mode it is server's address. @item GOVPN_IFACE -TAP interface name. In server mode this can be empty: that means that +TUN/TAP interface name. In server mode this can be empty: that means that script must output its name as the first line to stdout. @end table diff --git a/doc/server.texi b/doc/server.texi index 325d317cb4b435f88398e56d51382166919c008f..b3e9ac7d8118c551af7ba05ed4bb30452a8c6519 100644 --- a/doc/server.texi +++ b/doc/server.texi @@ -25,7 +25,7 @@ Configuration file is YAML file with following example structure: @verbatim stargrave: <-- Peer human readable name - iface: tap10 <-- OPTIONAL TAP interface name + iface: tap10 <-- OPTIONAL TUN/TAP interface name mtu: 1515 <-- OPTIONAL overriden MTU up: ./stargrave-up.sh <-- OPTIONAL up-script down: ./stargrave-down.sh <-- OPTIONAL down-script @@ -40,7 +40,7 @@ @end verbatim At least one of either @code{iface} or @code{up} must be specified. If you specify @code{iface}, then it will be forcefully used to determine -what TAP interface will be used. If it is not specified, then +what TUN/TAP interface will be used. If it is not specified, then up-@ref{Scripts, script} must output interface's name to stdout (first output line). @@ -69,7 +69,7 @@ Place the following YAML configuration entry on the server's side: Alice: up: /path/to/up.sh - iface: or TAP interface name + iface: or TUN/TAP interface name verifier: $balloon$s=32768,t=16,p=2$bwR5VjeCYIQaa8SeaI3rqg$KCNIqfS4DGsBTtVytamAzcISgrlEWvNxan1UfBrFu10 @end verbatim diff --git a/doc/sources.texi b/doc/sources.texi index 778a786a6600d67481b2eb5c123e4ab0c0e051e4..e7a13755b3fc8d9b44911ec4965e651fdbe66428 100644 --- a/doc/sources.texi +++ b/doc/sources.texi @@ -25,7 +25,6 @@ @headitem Software/library @tab Mirror @item @code{cypherpunks.ru/govpn} @tab @url{https://github.com/stargrave/govpn.git} @item @code{github.com/agl/ed25519} @tab @url{git://git.cypherpunks.ru/ed25519.git} @item @code{github.com/bigeagle/water} @tab @url{git://git.cypherpunks.ru/water.git} -@item @code{github.com/dchest/blake2b} @tab @url{git://git.cypherpunks.ru/blake2b.git} @item @code{github.com/go-yaml/yaml} @tab @url{git://git.cypherpunks.ru/yaml.git} @item @code{golang.org/x/crypto} @tab @url{git://git.cypherpunks.ru/crypto.git} @end multitable diff --git a/doc/style.css b/doc/style.css index 19806bed6822e719055ffc91189696efb09bdfe7..dc94af994247750d9bd208a37707c59ec75fda20 100644 --- a/doc/style.css +++ b/doc/style.css @@ -1,17 +1,10 @@ + diff --git a/doc/timeout.texi b/doc/timeout.texi index 89dd5b011579ae16c80dc05bf8d1f28eea33bcab..2cb52019d32608cf03ee33118b3987967d480188 100644 --- a/doc/timeout.texi +++ b/doc/timeout.texi @@ -8,7 +8,7 @@ dead. Timeout option should be synchronized both for server and client. If there were no packets at all during fourth part of timeout, then special heartbeat packet is sent. So VPN connection should be alive all -the time, even if there is no traffic in corresponding TAP interfaces. +the time, even if there is no traffic in corresponding TUN/TAP interfaces. @strong{Beware}: this consumes traffic. Stale peers and handshake states are cleaned up every timeout period. diff --git a/doc/transport.texi b/doc/transport.texi index 812322528f03019d4b882dab6e925ebdd386afa4..e5f5abba9eba15dec245489f2aa53c807d007b5f 100644 --- a/doc/transport.texi +++ b/doc/transport.texi @@ -2,7 +2,7 @@ @node Transport @section Transport protocol @verbatim - NONCE = 64bit(MAC(MAC_KEY, SERIAL)) + NONCE = 64bit(ZEROS) || 64bit(MAC(MAC_KEY, SERIAL)) PAYLOAD = DATA || PAD [|| ZEROS] CIPHERTEXT = ENCRYPT(KEY, NONCE, PAYLOAD) TAG = AUTH(AUTH_KEY, CIPHERTEXT || NONCE) @@ -13,16 +13,16 @@ @code{SERIAL} is message's serial number. Odds are reserved for client (to server) messages, evens for server (to client) messages. @code{MAC} is BLAKE2b-MAC used to obfuscate @code{SERIAL}. MAC's key -@code{MAC_KEY} is the first 256-bit of Salsa20's output with established +@code{MAC_KEY} is the first 256-bit of ChaCha20's output with established common key and zero nonce (message nonces start from 1). @verbatim MAC_KEY = 256bit(ENCRYPT(KEY, 0)) @end verbatim -@code{ENCRYPT} is Salsa20 stream cipher, with established session +@code{ENCRYPT} is ChaCha20 stream cipher, with established session @code{KEY} and obfuscated @code{SERIAL} used as a nonce. 512 bit of -Salsa20's output is ignored and only remaining is XORed with ther data, +ChaCha20's output is ignored and only remaining is XORed with ther data, encrypting it. @code{DATA} is padded using ISO/IEC 7816-4 format (@code{PAD} (0x80 @@ -30,7 +30,7 @@ byte) with optional @code{ZEROS} following), to fill up packet to conceal payload packet length. @code{AUTH} is Poly1305 authentication function. First 256 bits of -Salsa20's output are used as a one-time key for @code{AUTH}. +ChaCha20's output are used as a one-time key for @code{AUTH}. @verbatim AUTH_KEY = 256bit(ENCRYPT(KEY, NONCE)) diff --git a/doc/user.texi b/doc/user.texi index b27b35628d1281d8d0880cad898d28eecb699ef4..34a93c34c7caa8e981eefe63693ba0add283218d 100644 --- a/doc/user.texi +++ b/doc/user.texi @@ -5,7 +5,7 @@ Announcements about updates and new releases can be found in @ref{Contacts, contacts}. GoVPN is split into two pieces: @ref{Client} and @ref{Server}. Each of -them work on top of @ref{Network, UDP/TCP} and TAP virtual network +them work on top of @ref{Network, UDP/TCP} and TUN/TAP virtual network interfaces. GoVPN is just a tunnelling of Ethernet frames, nothing less, nothing more. All you IP-related network management is not touched by VPN at all. You can automate it using up and down shell scripts. diff --git a/src/chacha20 b/src/chacha20 new file mode 120000 index 0000000000000000000000000000000000000000..95f85aa47858705926bd6a73ccbf4f9d7bf5df74 --- /dev/null +++ b/src/chacha20 @@ -0,0 +1 @@ +golang.org/x/crypto/chacha20poly1305/internal/chacha20 \ No newline at end of file diff --git a/src/cypherpunks.ru/govpn/aont/oaep.go b/src/cypherpunks.ru/govpn/aont/oaep.go index 35d92fecf36c722404efae2c2f01f6485869565b..4b780ba427ed2e6f87e8d5724ed2488b4f8e8f17 100644 --- a/src/cypherpunks.ru/govpn/aont/oaep.go +++ b/src/cypherpunks.ru/govpn/aont/oaep.go @@ -30,7 +30,7 @@ // AONT takes 128-bit random r, data M to be encoded and produce the // package PKG: // // PKG = P1 || P2 -// P1 = Salsa20(key=r, nonce=0x00, 0x00) XOR (M || BLAKE2b(r || M)) +// P1 = ChaCha20(key=r, nonce=0x00, 0x00) XOR (M || BLAKE2b(r || M)) // P2 = BLAKE2b(P1) XOR r package aont @@ -38,8 +38,8 @@ import ( "crypto/subtle" "errors" - "github.com/dchest/blake2b" - "golang.org/x/crypto/salsa20" + "chacha20" + "golang.org/x/crypto/blake2b" ) const ( @@ -48,7 +48,7 @@ RSize = 16 ) var ( - dummyNonce []byte = make([]byte, 8) + dummyNonce *[16]byte = new([16]byte) ) // Encode the data, produce AONT package. Data size will be larger than @@ -56,13 +56,16 @@ // the original one for 48 bytes. func Encode(r *[RSize]byte, in []byte) ([]byte, error) { out := make([]byte, len(in)+HSize+RSize) copy(out, in) - h := blake2b.New256() + h, err := blake2b.New256(nil) + if err != nil { + return nil, err + } h.Write(r[:]) h.Write(in) copy(out[len(in):], h.Sum(nil)) - salsaKey := new([32]byte) - copy(salsaKey[:], r[:]) - salsa20.XORKeyStream(out, out, dummyNonce, salsaKey) + chachaKey := new([32]byte) + copy(chachaKey[:], r[:]) + chacha20.XORKeyStream(out, out, dummyNonce, chachaKey) h.Reset() h.Write(out[:len(in)+32]) for i, b := range h.Sum(nil)[:RSize] { @@ -77,16 +80,19 @@ func Decode(in []byte) ([]byte, error) { if len(in) < HSize+RSize { return nil, errors.New("Too small input buffer") } - h := blake2b.New256() + h, err := blake2b.New256(nil) + if err != nil { + return nil, err + } h.Write(in[:len(in)-RSize]) - salsaKey := new([32]byte) + chachaKey := new([32]byte) for i, b := range h.Sum(nil)[:RSize] { - salsaKey[i] = b ^ in[len(in)-RSize+i] + chachaKey[i] = b ^ in[len(in)-RSize+i] } h.Reset() - h.Write(salsaKey[:RSize]) + h.Write(chachaKey[:RSize]) out := make([]byte, len(in)-RSize) - salsa20.XORKeyStream(out, in[:len(in)-RSize], dummyNonce, salsaKey) + chacha20.XORKeyStream(out, in[:len(in)-RSize], dummyNonce, chachaKey) h.Write(out[:len(out)-HSize]) if subtle.ConstantTimeCompare(h.Sum(nil), out[len(out)-HSize:]) != 1 { return nil, errors.New("Invalid checksum") diff --git a/src/cypherpunks.ru/govpn/cmd/govpn-client/main.go b/src/cypherpunks.ru/govpn/cmd/govpn-client/main.go index c7b04a7635af89d2e2fdb8fa931543a996295764..36ff72a113e6ac0db3e809e90af6954fb57f9f6c 100644 --- a/src/cypherpunks.ru/govpn/cmd/govpn-client/main.go +++ b/src/cypherpunks.ru/govpn/cmd/govpn-client/main.go @@ -34,7 +34,7 @@ var ( remoteAddr = flag.String("remote", "", "Remote server address") proto = flag.String("proto", "udp", "Protocol to use: udp or tcp") - ifaceName = flag.String("iface", "tap0", "TAP network interface") + ifaceName = flag.String("iface", "tap0", "TUN/TAP network interface") verifierRaw = flag.String("verifier", "", "Verifier") keyPath = flag.String("key", "", "Path to passphrase file") upPath = flag.String("up", "", "Path to up-script") @@ -42,7 +42,7 @@ downPath = flag.String("down", "", "Path to down-script") stats = flag.String("stats", "", "Enable stats retrieving on host:port") proxyAddr = flag.String("proxy", "", "Use HTTP proxy on host:port") proxyAuth = flag.String("proxy-auth", "", "user:password Basic proxy auth") - mtu = flag.Int("mtu", govpn.MTUDefault, "MTU of TAP interface") + mtu = flag.Int("mtu", govpn.MTUDefault, "MTU of TUN/TAP interface") timeoutP = flag.Int("timeout", 60, "Timeout seconds") timeSync = flag.Int("timesync", 0, "Time synchronization requirement") noreconnect = flag.Bool("noreconnect", false, "Disable reconnection after timeout") @@ -127,7 +127,7 @@ log.Println(govpn.VersionGet()) tap, err = govpn.TAPListen(*ifaceName, *mtu) if err != nil { - log.Fatalln("Can not listen on TAP interface:", err) + log.Fatalln("Can not listen on TUN/TAP interface:", err) } if *stats != "" { diff --git a/src/cypherpunks.ru/govpn/cnw/cnw.go b/src/cypherpunks.ru/govpn/cnw/cnw.go index 931a0d11d62905ade2afad22227347254b0d54d2..c5d41a635afb3440558f19b3c351ccc1035a0229 100644 --- a/src/cypherpunks.ru/govpn/cnw/cnw.go +++ b/src/cypherpunks.ru/govpn/cnw/cnw.go @@ -34,11 +34,11 @@ // If bit value is 0, then first MAC is taken over "1" and the second // one is over "0". If bit value is 1, then first is taken over "0" and // second is over "1". // -// Poly1305 uses 256-bit one-time key. We generate it using XSalsa20 for +// Poly1305 uses 256-bit one-time key. We generate it using ChaCha20 for // for the whole byte at once (16 MACs). // -// MACKey1, MACKey2, ... = XSalsa20(authKey, nonce, 0x00...) -// nonce = prefix || 0x00... || big endian byte number +// MACKey1, MACKey2, ... = ChaCha20(authKey, nonce, 0x00...) +// nonce = prefix || big endian byte number package cnw import ( @@ -46,8 +46,8 @@ "crypto/subtle" "encoding/binary" "errors" + "chacha20" "golang.org/x/crypto/poly1305" - "golang.org/x/crypto/salsa20" ) const ( @@ -65,15 +65,15 @@ // larger: 256 bytes for each input byte. func Chaff(authKey *[32]byte, noncePrfx, in []byte) []byte { out := make([]byte, len(in)*EnlargeFactor) keys := make([]byte, 8*64) - nonce := make([]byte, 24) + nonce := new([16]byte) copy(nonce[:8], noncePrfx) var i int var v byte tag := new([16]byte) macKey := new([32]byte) for n, b := range in { - binary.BigEndian.PutUint64(nonce[16:], uint64(n)) - salsa20.XORKeyStream(keys, keys, nonce, authKey) + binary.BigEndian.PutUint64(nonce[8:], uint64(n)) + chacha20.XORKeyStream(keys, keys, nonce, authKey) for i = 0; i < 8; i++ { v = (b >> uint8(i)) & 1 copy(macKey[:], keys[64*i:64*i+32]) @@ -104,7 +104,7 @@ return nil, errors.New("Invalid data size") } out := make([]byte, len(in)/EnlargeFactor) keys := make([]byte, 8*64) - nonce := make([]byte, 24) + nonce := new([16]byte) copy(nonce[:8], noncePrfx) var i int var v byte @@ -116,8 +116,8 @@ var is00 bool var is11 bool var is10 bool for n := 0; n < len(out); n++ { - binary.BigEndian.PutUint64(nonce[16:], uint64(n)) - salsa20.XORKeyStream(keys, keys, nonce, authKey) + binary.BigEndian.PutUint64(nonce[8:], uint64(n)) + chacha20.XORKeyStream(keys, keys, nonce, authKey) v = 0 for i = 0; i < 8; i++ { copy(macKey[:], keys[64*i:64*i+32]) diff --git a/src/cypherpunks.ru/govpn/encless.go b/src/cypherpunks.ru/govpn/encless.go index f9d9bbfe075e587e6fd16fd9e023a62a5f343537..bd42f1d5729349e1a4c3bf6fe2bb813445ee6249 100644 --- a/src/cypherpunks.ru/govpn/encless.go +++ b/src/cypherpunks.ru/govpn/encless.go @@ -35,7 +35,7 @@ // It uses Chaffing-and-Winnowing technology (it is neither // encryption nor steganography) over All-Or-Nothing-Transformed data. // nonce is 64-bit nonce. Output data will be EnclessEnlargeSize larger. // It also consumes 64-bits of entropy. -func EnclessEncode(authKey *[32]byte, nonce, in []byte) ([]byte, error) { +func EnclessEncode(authKey *[32]byte, nonce *[16]byte, in []byte) ([]byte, error) { r := new([aont.RSize]byte) var err error if _, err = io.ReadFull(Rand, r[:]); err != nil { @@ -46,7 +46,7 @@ if err != nil { return nil, err } out := append( - cnw.Chaff(authKey, nonce, aonted[:aont.RSize]), + cnw.Chaff(authKey, nonce[8:], aonted[:aont.RSize]), aonted[aont.RSize:]..., ) SliceZero(aonted[:aont.RSize]) @@ -54,10 +54,10 @@ return out, nil } // Decode EnclessEncode-ed data. -func EnclessDecode(authKey *[32]byte, nonce, in []byte) ([]byte, error) { +func EnclessDecode(authKey *[32]byte, nonce *[16]byte, in []byte) ([]byte, error) { var err error winnowed, err := cnw.Winnow( - authKey, nonce, in[:aont.RSize*cnw.EnlargeFactor], + authKey, nonce[8:], in[:aont.RSize*cnw.EnlargeFactor], ) if err != nil { return nil, err diff --git a/src/cypherpunks.ru/govpn/encless_test.go b/src/cypherpunks.ru/govpn/encless_test.go index 1f9fece30e3207999ec3a01a6d779888299d15e6..fc00d2708d753735bb501e3886c1ee8d4df1cde5 100644 --- a/src/cypherpunks.ru/govpn/encless_test.go +++ b/src/cypherpunks.ru/govpn/encless_test.go @@ -35,9 +35,9 @@ io.ReadFull(Rand, testKey[:]) } func TestEnclessSymmetric(t *testing.T) { - nonce := make([]byte, 8) + nonce := new([16]byte) f := func(pktNum uint64, in []byte) bool { - binary.BigEndian.PutUint64(nonce, pktNum) + binary.BigEndian.PutUint64(nonce[8:], pktNum) encoded, err := EnclessEncode(testKey, nonce, in) if err != nil { return false @@ -54,9 +54,9 @@ } } func BenchmarkEnclessEncode(b *testing.B) { - nonce := make([]byte, 8) + nonce := new([16]byte) data := make([]byte, 128) - io.ReadFull(Rand, nonce) + io.ReadFull(Rand, nonce[8:]) io.ReadFull(Rand, data) b.ResetTimer() for i := 0; i < b.N; i++ { @@ -65,9 +65,9 @@ } } func BenchmarkEnclessDecode(b *testing.B) { - nonce := make([]byte, 8) + nonce := new([16]byte) data := make([]byte, 128) - io.ReadFull(Rand, nonce) + io.ReadFull(Rand, nonce[8:]) io.ReadFull(Rand, data) encoded, _ := EnclessEncode(testKey, nonce, data) b.ResetTimer() diff --git a/src/cypherpunks.ru/govpn/handshake.go b/src/cypherpunks.ru/govpn/handshake.go index 9c536b329371fe7a5a946229407285214dbd5e30..a3ef2b5cf536397c176678d38c8fcd4fff70d1d8 100644 --- a/src/cypherpunks.ru/govpn/handshake.go +++ b/src/cypherpunks.ru/govpn/handshake.go @@ -25,11 +25,11 @@ "io" "log" "time" + "chacha20" "github.com/agl/ed25519" "github.com/agl/ed25519/extra25519" - "github.com/dchest/blake2b" + "golang.org/x/crypto/blake2b" "golang.org/x/crypto/curve25519" - "golang.org/x/crypto/salsa20" ) const ( @@ -44,7 +44,7 @@ LastPing time.Time Conf *PeerConf dsaPubH *[ed25519.PublicKeySize]byte key *[32]byte - rNonce *[RSize]byte + rNonce *[16]byte dhPriv *[32]byte // own private DH key rServer *[RSize]byte // random string for authentication rClient *[RSize]byte @@ -88,10 +88,10 @@ SliceZero(h.sClient[:]) } } -func (h *Handshake) rNonceNext(count uint64) []byte { - nonce := make([]byte, RSize) - nonceCurrent, _ := binary.Uvarint(h.rNonce[:]) - binary.PutUvarint(nonce, nonceCurrent+count) +func (h *Handshake) rNonceNext(count uint64) *[16]byte { + nonce := new([16]byte) + nonceCurrent, _ := binary.Uvarint(h.rNonce[8:]) + binary.PutUvarint(nonce[8:], nonceCurrent+count) return nonce } @@ -136,7 +136,10 @@ func idTag(id *PeerId, timeSync int, data []byte) []byte { enc := make([]byte, 8) copy(enc, data) AddTimeSync(timeSync, enc) - mac := blake2b.NewMAC(8, id[:]) + mac, err := blake2b.New256(id[:]) + if err != nil { + panic(err) + } mac.Write(enc) mac.Sum(enc[:0]) return enc @@ -150,8 +153,8 @@ state := NewHandshake(addr, conn, conf) var dhPubRepr *[32]byte state.dhPriv, dhPubRepr = dhKeypairGen() - state.rNonce = new([RSize]byte) - if _, err := io.ReadFull(Rand, state.rNonce[:]); err != nil { + state.rNonce = new([16]byte) + if _, err := io.ReadFull(Rand, state.rNonce[8:]); err != nil { log.Fatalln("Error reading random for nonce:", err) } var enc []byte @@ -163,15 +166,15 @@ } copy(enc, dhPubRepr[:]) if conf.Encless { var err error - enc, err = EnclessEncode(state.dsaPubH, state.rNonce[:], enc) + enc, err = EnclessEncode(state.dsaPubH, state.rNonce, enc) if err != err { panic(err) } } else { - salsa20.XORKeyStream(enc, enc, state.rNonce[:], state.dsaPubH) + chacha20.XORKeyStream(enc, enc, state.rNonce, state.dsaPubH) } - data := append(state.rNonce[:], enc...) - data = append(data, idTag(state.Conf.Id, state.Conf.TimeSync, state.rNonce[:])...) + data := append(state.rNonce[8:], enc...) + data = append(data, idTag(state.Conf.Id, state.Conf.TimeSync, state.rNonce[8:])...) state.conn.Write(data) return state } @@ -185,15 +188,15 @@ func (h *Handshake) Server(data []byte) *Peer { // R + ENC(H(DSAPub), R, El(CDHPub)) + IDtag if h.rNonce == nil && ((!h.Conf.Encless && len(data) >= 48) || (h.Conf.Encless && len(data) == EnclessEnlargeSize+h.Conf.MTU)) { - h.rNonce = new([RSize]byte) - copy(h.rNonce[:], data[:RSize]) + h.rNonce = new([16]byte) + copy(h.rNonce[8:], data[:RSize]) // Decrypt remote public key cDHRepr := new([32]byte) if h.Conf.Encless { out, err := EnclessDecode( h.dsaPubH, - h.rNonce[:], + h.rNonce, data[RSize:len(data)-8], ) if err != nil { @@ -202,7 +205,7 @@ return nil } copy(cDHRepr[:], out) } else { - salsa20.XORKeyStream(cDHRepr[:], data[RSize:RSize+32], h.rNonce[:], h.dsaPubH) + chacha20.XORKeyStream(cDHRepr[:], data[RSize:RSize+32], h.rNonce, h.dsaPubH) } // Generate DH keypair @@ -225,7 +228,7 @@ panic(err) } } else { encPub = make([]byte, 32) - salsa20.XORKeyStream(encPub, dhPubRepr[:], h.rNonceNext(1), h.dsaPubH) + chacha20.XORKeyStream(encPub, dhPubRepr[:], h.rNonceNext(1), h.dsaPubH) } // Generate R* and encrypt them @@ -247,12 +250,12 @@ encRs = make([]byte, RSize+SSize) } copy(encRs, append(h.rServer[:], h.sServer[:]...)) if h.Conf.Encless { - encRs, err = EnclessEncode(h.key, h.rNonce[:], encRs) + encRs, err = EnclessEncode(h.key, h.rNonce, encRs) if err != nil { panic(err) } } else { - salsa20.XORKeyStream(encRs, encRs, h.rNonce[:], h.key) + chacha20.XORKeyStream(encRs, encRs, h.rNonce, h.key) } // Send that to client @@ -279,7 +282,7 @@ } dec = dec[:RSize+RSize+SSize+ed25519.SignatureSize] } else { dec = make([]byte, RSize+RSize+SSize+ed25519.SignatureSize) - salsa20.XORKeyStream( + chacha20.XORKeyStream( dec, data[:RSize+RSize+SSize+ed25519.SignatureSize], h.rNonceNext(1), @@ -311,7 +314,7 @@ if err != nil { panic(err) } } else { - salsa20.XORKeyStream(enc, enc, h.rNonceNext(2), h.key) + chacha20.XORKeyStream(enc, enc, h.rNonceNext(2), h.key) } h.conn.Write(append(enc, idTag(h.Conf.Id, h.Conf.TimeSync, enc)...)) @@ -356,7 +359,7 @@ return nil } copy(sDHRepr[:], tmp[:32]) } else { - salsa20.XORKeyStream(sDHRepr[:], data[:32], h.rNonceNext(1), h.dsaPubH) + chacha20.XORKeyStream(sDHRepr[:], data[:32], h.rNonceNext(1), h.dsaPubH) } // Compute shared key @@ -368,11 +371,7 @@ // Decrypt Rs h.rServer = new([RSize]byte) h.sServer = new([SSize]byte) if h.Conf.Encless { - tmp, err = EnclessDecode( - h.key, - h.rNonce[:], - data[len(data)/2:len(data)-8], - ) + tmp, err = EnclessDecode(h.key, h.rNonce, data[len(data)/2:len(data)-8]) if err != nil { log.Println("Unable to decode packet from", h.addr, err) return nil @@ -381,7 +380,7 @@ copy(h.rServer[:], tmp[:RSize]) copy(h.sServer[:], tmp[RSize:RSize+SSize]) } else { decRs := make([]byte, RSize+SSize) - salsa20.XORKeyStream(decRs, data[SSize:SSize+RSize+SSize], h.rNonce[:], h.key) + chacha20.XORKeyStream(decRs, data[SSize:SSize+RSize+SSize], h.rNonce, h.key) copy(h.rServer[:], decRs[:RSize]) copy(h.sServer[:], decRs[RSize:]) } @@ -413,7 +412,7 @@ if err != nil { panic(err) } } else { - salsa20.XORKeyStream(enc, enc, h.rNonceNext(1), h.key) + chacha20.XORKeyStream(enc, enc, h.rNonceNext(1), h.key) } // Send that to server @@ -435,7 +434,7 @@ } dec = dec[:RSize] } else { dec = make([]byte, RSize) - salsa20.XORKeyStream(dec, data[:RSize], h.rNonceNext(2), h.key) + chacha20.XORKeyStream(dec, data[:RSize], h.rNonceNext(2), h.key) } if subtle.ConstantTimeCompare(dec, h.rClient[:]) != 1 { log.Println("Invalid client's random number with", h.addr) diff --git a/src/cypherpunks.ru/govpn/identity.go b/src/cypherpunks.ru/govpn/identity.go index 4dc74eed0e330f4a3ec73570e0c9d73b2503baee..ece2dfcf0bb2131fd4c4a48c8467d39230728837 100644 --- a/src/cypherpunks.ru/govpn/identity.go +++ b/src/cypherpunks.ru/govpn/identity.go @@ -27,7 +27,7 @@ "log" "sync" "time" - "github.com/dchest/blake2b" + "golang.org/x/crypto/blake2b" ) const ( @@ -73,8 +73,12 @@ if _, exists := mc.cache[pid]; exists { mc.cache[pid].ts = pc.TimeSync } else { log.Println("Adding key", pid) + mac, err := blake2b.New256(pid[:]) + if err != nil { + panic(err) + } mc.cache[pid] = &MACAndTimeSync{ - mac: blake2b.NewMAC(8, pid[:]), + mac: mac, ts: pc.TimeSync, } } diff --git a/src/cypherpunks.ru/govpn/peer.go b/src/cypherpunks.ru/govpn/peer.go index 5a620a9c76692d23536aa87d0c6fabc770795fac..22c893c80fb51d3bb0bb1affbfa395e32a137257 100644 --- a/src/cypherpunks.ru/govpn/peer.go +++ b/src/cypherpunks.ru/govpn/peer.go @@ -28,16 +28,16 @@ "sync" "sync/atomic" "time" - "github.com/dchest/blake2b" + "chacha20" + "golang.org/x/crypto/blake2b" "golang.org/x/crypto/poly1305" - "golang.org/x/crypto/salsa20" ) const ( NonceSize = 8 NonceBucketSize = 256 TagSize = poly1305.TagSize - // S20BS is Salsa20's internal blocksize in bytes + // S20BS is ChaCha20's internal blocksize in bytes S20BS = 64 // Maximal amount of bytes transfered with single key (4 GiB) MaxBytesPerKey uint64 = 1 << 32 @@ -51,8 +51,11 @@ ) func newNonces(key *[32]byte, i uint64) chan *[NonceSize]byte { macKey := make([]byte, 32) - salsa20.XORKeyStream(macKey, make([]byte, 32), make([]byte, 8), key) - mac := blake2b.NewMAC(NonceSize, macKey) + chacha20.XORKeyStream(macKey, make([]byte, 32), new([16]byte), key) + mac, err := blake2b.New256(macKey) + if err != nil { + panic(err) + } nonces := make(chan *[NonceSize]byte, NonceBucketSize*3) go func() { for { @@ -105,6 +108,7 @@ BusyR sync.Mutex `json:"-"` bufR []byte tagR *[TagSize]byte keyAuthR *[SSize]byte + nonceR *[16]byte pktSizeR int // UDP-related @@ -123,6 +127,7 @@ BusyT sync.Mutex `json:"-"` bufT []byte tagT *[TagSize]byte keyAuthT *[SSize]byte + nonceT *[16]byte frameT []byte noncesT chan *[NonceSize]byte } @@ -198,7 +203,9 @@ bufT: make([]byte, bufSize), tagR: new([TagSize]byte), tagT: new([TagSize]byte), keyAuthR: new([SSize]byte), + nonceR: new([16]byte), keyAuthT: new([SSize]byte), + nonceT: new([16]byte), } if isClient { @@ -268,22 +275,19 @@ p.frameT = p.bufT[S20BS : S20BS+len(data)+1+NonceSize] } copy(p.frameT[len(p.frameT)-NonceSize:], (<-p.noncesT)[:]) var out []byte + copy(p.nonceT[8:], p.frameT[len(p.frameT)-NonceSize:]) if p.Encless { var err error - out, err = EnclessEncode( - p.key, - p.frameT[len(p.frameT)-NonceSize:], - p.frameT[:len(p.frameT)-NonceSize], - ) + out, err = EnclessEncode(p.key, p.nonceT, p.frameT[:len(p.frameT)-NonceSize]) if err != nil { panic(err) } out = append(out, p.frameT[len(p.frameT)-NonceSize:]...) } else { - salsa20.XORKeyStream( + chacha20.XORKeyStream( p.bufT[:S20BS+len(p.frameT)-NonceSize], p.bufT[:S20BS+len(p.frameT)-NonceSize], - p.frameT[len(p.frameT)-NonceSize:], + p.nonceT, p.key, ) copy(p.keyAuthT[:], p.bufT[:SSize]) @@ -305,13 +309,10 @@ return false } var out []byte p.BusyR.Lock() + copy(p.nonceR[8:], data[len(data)-NonceSize:]) if p.Encless { var err error - out, err = EnclessDecode( - p.key, - data[len(data)-NonceSize:], - data[:len(data)-NonceSize], - ) + out, err = EnclessDecode(p.key, p.nonceR, data[:len(data)-NonceSize]) if err != nil { p.FramesUnauth++ p.BusyR.Unlock() @@ -322,10 +323,10 @@ for i := 0; i < SSize; i++ { p.bufR[i] = 0 } copy(p.bufR[S20BS:], data[TagSize:]) - salsa20.XORKeyStream( + chacha20.XORKeyStream( p.bufR[:S20BS+len(data)-TagSize-NonceSize], p.bufR[:S20BS+len(data)-TagSize-NonceSize], - data[len(data)-NonceSize:], + p.nonceR, p.key, ) copy(p.keyAuthR[:], p.bufR[:SSize]) diff --git a/src/cypherpunks.ru/govpn/tap.go b/src/cypherpunks.ru/govpn/tap.go index 8a44575e5e4eddfd6235ca143d5af8ff9e318ef9..9010c55b6c3a89eb0b224298c74c4aa002c5aa0b 100644 --- a/src/cypherpunks.ru/govpn/tap.go +++ b/src/cypherpunks.ru/govpn/tap.go @@ -58,7 +58,7 @@ } bufZ = !bufZ n, err = tap.dev.Read(buf) if err != nil { - panic("Reading TAP:" + err.Error()) + panic("Reading TUN/TAP:" + err.Error()) } tap.Sink <- buf[:n] } diff --git a/src/cypherpunks.ru/govpn/tap_linux.go b/src/cypherpunks.ru/govpn/tap_linux.go index fb9df56437b80829340e007b7ec02421dd750148..8c5e883760a2bcafda219acc37a39c1a57b2eacd 100644 --- a/src/cypherpunks.ru/govpn/tap_linux.go +++ b/src/cypherpunks.ru/govpn/tap_linux.go @@ -9,10 +9,15 @@ package govpn import ( "io" + "strings" "github.com/bigeagle/water" ) func newTAPer(ifaceName string) (io.ReadWriter, error) { - return water.NewTAP(ifaceName) + if strings.HasPrefix(ifaceName, "tap") { + return water.NewTAP(ifaceName) + } else { + return water.NewTUN(ifaceName) + } } diff --git a/src/cypherpunks.ru/govpn/verifier.go b/src/cypherpunks.ru/govpn/verifier.go index b68063b94823361f25bc5734d50cd7aa43a6502b..832fafe2dacf4981ee3ffc39e20aa5cde77d3a68 100644 --- a/src/cypherpunks.ru/govpn/verifier.go +++ b/src/cypherpunks.ru/govpn/verifier.go @@ -23,6 +23,7 @@ "bytes" "encoding/base64" "errors" "fmt" + "hash" "io/ioutil" "log" "os" @@ -30,7 +31,7 @@ "strings" "cypherpunks.ru/balloon" "github.com/agl/ed25519" - "github.com/dchest/blake2b" + "golang.org/x/crypto/blake2b" "golang.org/x/crypto/ssh/terminal" ) @@ -54,10 +55,18 @@ func VerifierNew(s, t, p int, id *PeerId) *Verifier { return &Verifier{S: s, T: t, P: p, Id: id} } +func blake2bKeyless() hash.Hash { + h, err := blake2b.New256(nil) + if err != nil { + panic(err) + } + return h +} + // Apply the password: create Ed25519 keypair based on it, save public // key in verifier. func (v *Verifier) PasswordApply(password string) *[ed25519.PrivateKeySize]byte { - r := balloon.H(blake2b.New256, []byte(password), v.Id[:], v.S, v.T, v.P) + r := balloon.H(blake2bKeyless, []byte(password), v.Id[:], v.S, v.T, v.P) defer SliceZero(r) src := bytes.NewBuffer(r) pub, prv, err := ed25519.GenerateKey(src) diff --git a/utils/makedist.sh b/utils/makedist.sh index 96dfb60623f6cfc5cc407e2cb606103495c16889..f890c3a99c0f6e8240e9535b383d938792ffee3e 100755 --- a/utils/makedist.sh +++ b/utils/makedist.sh @@ -7,9 +7,9 @@ [ -n "$release" ] git clone . $tmp/govpn-$release repos=" + src/cypherpunks.ru/balloon src/github.com/agl/ed25519 src/github.com/bigeagle/water - src/github.com/dchest/blake2b src/github.com/go-yaml/yaml src/golang.org/x/crypto " @@ -26,11 +26,11 @@ golang.org/x/crypto/CONTRIBUTORS golang.org/x/crypto/LICENSE golang.org/x/crypto/PATENTS golang.org/x/crypto/README +golang.org/x/crypto/blake2b +golang.org/x/crypto/chacha20poly1305/internal/chacha20 golang.org/x/crypto/curve25519 golang.org/x/crypto/poly1305 -golang.org/x/crypto/salsa20 golang.org/x/crypto/ssh/terminal -golang.org/x/crypto/xtea EOF tar cfCI - src $tmp/includes | tar xfC - $tmp rm -fr src/golang.org @@ -87,13 +87,13 @@ heartbeating, rehandshaking, real-time statistics. Ability to work through UDP, TCP and HTTP proxies. IPv4/IPv6-compatibility. GNU/Linux and FreeBSD support. -----------------8<-----------------8<-----------------8<---------------- +------------------------ >8 ------------------------ The main improvements for that release are: $(git cat-file -p $release | sed -n '6,/^.*BEGIN/p' | sed '$d') -----------------8<-----------------8<-----------------8<---------------- +------------------------ >8 ------------------------ GoVPN's home page is: http://www.govpn.info/ also available as Tor hidden service: http://2wir2p7ibeu72jk3.onion/ @@ -133,13 +133,13 @@ функции сердцебиения (heartbeat), пересогласования ключей, статистика реального времени. Возможность работы поверх UDP, TCP и HTTP прокси. Совместимость с IPv4 и IPv6. Поддержка GNU/Linux и FreeBSD. -----------------8<-----------------8<-----------------8<---------------- +------------------------ >8 ------------------------ Основные усовершенствования в этом релизе: $(git cat-file -p $release | sed -n '6,/^.*BEGIN/p' | sed '$d') -----------------8<-----------------8<-----------------8<---------------- +------------------------ >8 ------------------------ Домашняя страница GoVPN: http://www.govpn.info/ также доступна как скрытый сервис Tor: http://2wir2p7ibeu72jk3.onion/ diff --git a/utils/newclient.sh b/utils/newclient.sh index aebc975b52e2f0f37c9810e925963733094e6781..98957ef6fb4bc6e604993c900caf707a10bb6fb4 100755 --- a/utils/newclient.sh +++ b/utils/newclient.sh @@ -26,6 +26,6 @@ Place the following YAML configuration entry on the server's side: $username: up: /path/to/up.sh - iface: or TAP interface name + iface: or TUN/TAP interface name verifier: $verifierS EOF