From fa84373a81b75c96678b8a837ef7194963827065 Mon Sep 17 00:00:00 2001 From: "Brandon McGinty (chatgpt)" Date: Mon, 10 Aug 2026 04:06:12 -0400 Subject: [PATCH] Synchronize legacy UDP crypto setup --- gumble/gumble/crypt.go | 6 ++++++ gumble/gumble/crypt_test.go | 25 +++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/gumble/gumble/crypt.go b/gumble/gumble/crypt.go index 4907c34..5b1d4b6 100644 --- a/gumble/gumble/crypt.go +++ b/gumble/gumble/crypt.go @@ -233,6 +233,8 @@ type cryptState struct { } func (cs *cryptState) setup(key, iv []byte) error { + cs.mu.Lock() + defer cs.mu.Unlock() if len(key) != 16 { return errors.New("gumble: crypt key must be 16 bytes") } @@ -269,6 +271,8 @@ func (cs *cryptState) nonceForPacket(counter uint32) [12]byte { } func (cs *cryptState) encrypt(counter uint32, plaintext []byte) ([]byte, error) { + cs.mu.Lock() + defer cs.mu.Unlock() if !cs.initialized { return plaintext, nil } @@ -277,6 +281,8 @@ func (cs *cryptState) encrypt(counter uint32, plaintext []byte) ([]byte, error) } func (cs *cryptState) decrypt(counter uint32, ciphertext []byte) ([]byte, error) { + cs.mu.Lock() + defer cs.mu.Unlock() if !cs.initialized { return ciphertext, nil } diff --git a/gumble/gumble/crypt_test.go b/gumble/gumble/crypt_test.go index 1bd4314..2cf44ba 100644 --- a/gumble/gumble/crypt_test.go +++ b/gumble/gumble/crypt_test.go @@ -7,9 +7,34 @@ import ( "encoding/hex" "fmt" "strings" + "sync" "testing" ) +func TestCryptStateSetupAndEncryptAreConcurrentSafe(t *testing.T) { + key := make([]byte, 16) + iv := make([]byte, 16) + var cs cryptState + if err := cs.setup(key, iv); err != nil { + t.Fatal(err) + } + var wg sync.WaitGroup + for i := 0; i < 20; i++ { + wg.Add(1) + go func(counter uint32) { + defer wg.Done() + if counter%2 == 0 { + if err := cs.setup(key, iv); err != nil { + t.Error(err) + } + } else if _, err := cs.encrypt(counter, []byte("audio")); err != nil { + t.Error(err) + } + }(uint32(i)) + } + wg.Wait() +} + // TestOCBRoundTrip verifies encrypt-then-decrypt returns the original. func TestOCBRoundTrip(t *testing.T) { key := make([]byte, 16)