]> Sergey Matveev's repositories - vors.git/commitdiff
Verify MACs on server side
authorSergey Matveev <stargrave@stargrave.org>
Wed, 10 Apr 2024 22:26:02 +0000 (01:26 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Wed, 10 Apr 2024 22:26:02 +0000 (01:26 +0300)
cmd/client/main.go
cmd/server/main.go
doc/index.texi
internal/var.go

index 87d77fcafa17ea0b33e53be978b3532e204277d4b854e442df06390d27598a5a..bad619faed3490fe9f5d1de277d770194152d61c263e260e6b8b93683a36ba39 100644 (file)
@@ -44,8 +44,6 @@ import (
        "gopkg.in/hraban/opus.v2"
 )
 
-const TagLen = 8
-
 type Stream struct {
        name  string
        ctr   uint32
@@ -314,15 +312,18 @@ func main() {
                                                ciph.XORKeyStream(macKey[:], macKey[:])
                                                ciph.SetCounter(1)
                                                mac = poly1305.New(&macKey)
-                                               if _, err = mac.Write(buf[4 : len(buf)-TagLen]); err != nil {
+                                               if _, err = mac.Write(buf[4 : len(buf)-vors.TagLen]); err != nil {
                                                        log.Fatal(err)
                                                }
                                                mac.Sum(tag[:0])
-                                               if subtle.ConstantTimeCompare(tag[:TagLen], buf[len(buf)-TagLen:]) != 1 {
+                                               if subtle.ConstantTimeCompare(
+                                                       tag[:vors.TagLen],
+                                                       buf[len(buf)-vors.TagLen:],
+                                               ) != 1 {
                                                        log.Println("decrypt:", stream.name, "tag differs")
                                                        continue
                                                }
-                                               pkt = buf[4 : len(buf)-TagLen]
+                                               pkt = buf[4 : len(buf)-vors.TagLen]
                                                ciph.XORKeyStream(pkt, pkt)
 
                                                ctr = binary.BigEndian.Uint32(nonce[len(nonce)-4:])
@@ -430,7 +431,7 @@ func main() {
                                log.Println("wrong addr:", from)
                                continue
                        }
-                       if n <= 1+4+poly1305.TagSize {
+                       if n <= 4+vors.TagLen {
                                log.Println("too small:", n)
                                continue
                        }
@@ -513,8 +514,8 @@ func main() {
                                log.Fatal(err)
                        }
                        mac.Sum(tag[:0])
-                       copy(buf[4+n:], tag[:TagLen])
-                       pkt = buf[:4+n+TagLen]
+                       copy(buf[4+n:], tag[:vors.TagLen])
+                       pkt = buf[:4+n+vors.TagLen]
 
                        OurStats.pkts++
                        OurStats.bytes += uint64(len(pkt))
index 52b34c351855b4263b959a5e7428eca2a8c4409ba43842bd23519f20b0503a95..76c479c0d0dec0f048b1ff90ab705adfab55dfac8c42734605e387ae880ba61f 100644 (file)
@@ -18,6 +18,7 @@ package main
 import (
        "bufio"
        "crypto/rand"
+       "crypto/subtle"
        "crypto/tls"
        "encoding/hex"
        "flag"
@@ -37,7 +38,9 @@ import (
        "github.com/jroimartin/gocui"
        vors "go.stargrave.org/vors/internal"
        "golang.org/x/crypto/blake2s"
+       "golang.org/x/crypto/chacha20"
        "golang.org/x/crypto/chacha20poly1305"
+       "golang.org/x/crypto/poly1305"
 )
 
 var (
@@ -312,6 +315,11 @@ func main() {
                var err error
                var sid byte
                var peer *Peer
+               var ciph *chacha20.Cipher
+               var macKey [32]byte
+               var mac *poly1305.MAC
+               tag := make([]byte, poly1305.TagSize)
+               nonce := make([]byte, 12)
                for {
                        n, from, err = lnUDP.ReadFromUDP(buf)
                        if err != nil {
@@ -335,6 +343,33 @@ func main() {
                        if n == 1 {
                                continue
                        }
+                       if n <= 4+vors.TagLen {
+                               slog.Info("too small:", "peer", peer.name, "len", n)
+                               continue
+                       }
+
+                       copy(nonce[len(nonce)-4:], buf)
+                       ciph, err = chacha20.NewUnauthenticatedCipher(peer.key, nonce)
+                       if err != nil {
+                               log.Fatal(err)
+                       }
+                       clear(macKey[:])
+                       ciph.XORKeyStream(macKey[:], macKey[:])
+                       ciph.SetCounter(1)
+                       mac = poly1305.New(&macKey)
+                       if _, err = mac.Write(buf[4 : n-vors.TagLen]); err != nil {
+                               log.Fatal(err)
+                       }
+                       mac.Sum(tag[:0])
+                       if subtle.ConstantTimeCompare(
+                               tag[:vors.TagLen],
+                               buf[n-vors.TagLen:n],
+                       ) != 1 {
+                               log.Println("decrypt:", peer.name, "tag differs")
+                               slog.Info("MAC failed:", "peer", peer.name, "len", n)
+                               continue
+                       }
+
                        peer.stats.last = time.Now()
                        for _, p := range Peers {
                                if p.sid == sid {
index f077115f12cf625925b2f3adcf9904ca8ad556f325762ce5f0b19399a011e0ac..8dfdb6dcad588d467e2e968aa97434d9b2c4b4d6ff18376b86a8b2f4b9d9b166 100644 (file)
@@ -53,9 +53,7 @@ appropriate and satisfiable as fast and secure encryption solution.
 
 @end itemize
 
-TODO: server should verify symmetric authentication tags on incoming
-traffic, before copying it to everyone. Look at latest Opus'es neural
-network abilities.
+TODO: Look at latest Opus'es neural network abilities.
 
 @include install.texi
 @include usage.texi
index df03cd5b36d3f225c14dc07451f8e8b006d1a4ea52a9cbd744de2ab5cbc0c96b..fbc5544345198995567663ce3ab766aa03c684a2cd1b4ea14398e36b72799c1b 100644 (file)
@@ -10,6 +10,7 @@ const (
 
        CN      = "vors"
        MaxLost = 32
+       TagLen  = 8
 
        CmdPing = "PING"
        CmdPong = "PONG"