Salamander finalmask: Replace math/rand with crypto/rand in salt generation (#6228)

And https://github.com/XTLS/Xray-core/pull/6228#issuecomment-4612712100

Fixes https://github.com/XTLS/Xray-core/pull/6228#issuecomment-4599037015
This commit is contained in:
IconHHw
2026-06-09 03:55:06 +08:00
committed by GitHub
parent 2249f8b5c6
commit 83cf229909
4 changed files with 18 additions and 21 deletions
@@ -1,11 +1,11 @@
package salamander package salamander
import ( import (
"crypto/rand"
"fmt" "fmt"
"math/rand"
"sync" "sync"
"time"
"github.com/xtls/xray-core/common"
"golang.org/x/crypto/blake2b" "golang.org/x/crypto/blake2b"
) )
@@ -21,8 +21,7 @@ var ErrPSKTooShort = fmt.Errorf("PSK must be at least %d bytes", smPSKMinLen)
// the BLAKE2b-256 hash of a pre-shared key combined with a random salt. // the BLAKE2b-256 hash of a pre-shared key combined with a random salt.
// Packet format: [8-byte salt][payload] // Packet format: [8-byte salt][payload]
type SalamanderObfuscator struct { type SalamanderObfuscator struct {
PSK []byte PSK []byte
RandSrc *rand.Rand
lk sync.Mutex lk sync.Mutex
keyInput []byte keyInput []byte
@@ -37,7 +36,6 @@ func NewSalamanderObfuscator(psk []byte) (*SalamanderObfuscator, error) {
copy(keyInput, pskCopy) copy(keyInput, pskCopy)
return &SalamanderObfuscator{ return &SalamanderObfuscator{
PSK: pskCopy, PSK: pskCopy,
RandSrc: rand.New(rand.NewSource(time.Now().UnixNano())),
keyInput: keyInput, keyInput: keyInput,
}, nil }, nil
} }
@@ -47,8 +45,8 @@ func (o *SalamanderObfuscator) Obfuscate(in, out []byte) int {
if len(out) < outLen { if len(out) < outLen {
return 0 return 0
} }
common.Must2(rand.Read(out[:smSaltLen]))
o.lk.Lock() o.lk.Lock()
_, _ = o.RandSrc.Read(out[:smSaltLen])
key := o.keyLocked(out[:smSaltLen]) key := o.keyLocked(out[:smSaltLen])
o.lk.Unlock() o.lk.Unlock()
for i, c := range in { for i, c := range in {
+6 -6
View File
@@ -2,7 +2,7 @@ package sudoku
import ( import (
"fmt" "fmt"
"math/rand" "math/rand/v2"
) )
var perm4 = [24][4]byte{ var perm4 = [24][4]byte{
@@ -67,7 +67,7 @@ func pickPaddingChance(rng *rand.Rand, pMin, pMax int) int {
if pMax == pMin { if pMax == pMin {
return pMin return pMin
} }
return pMin + rng.Intn(pMax-pMin+1) return pMin + rng.IntN(pMax-pMin+1)
} }
func (c *codec) shouldPad() bool { func (c *codec) shouldPad() bool {
@@ -77,7 +77,7 @@ func (c *codec) shouldPad() bool {
if c.paddingChance >= 100 { if c.paddingChance >= 100 {
return true return true
} }
return c.rng.Intn(100) < c.paddingChance return c.rng.IntN(100) < c.paddingChance
} }
func (c *codec) currentTable() *table { func (c *codec) currentTable() *table {
@@ -89,7 +89,7 @@ func (c *codec) currentTable() *table {
func (c *codec) randomPadding(t *table) byte { func (c *codec) randomPadding(t *table) byte {
pool := t.layout.paddingPool pool := t.layout.paddingPool
return pool[c.rng.Intn(len(pool))] return pool[c.rng.IntN(len(pool))]
} }
func (c *codec) encode(in []byte) ([]byte, error) { func (c *codec) encode(in []byte) ([]byte, error) {
@@ -112,8 +112,8 @@ func (c *codec) encode(in []byte) ([]byte, error) {
return nil, fmt.Errorf("sudoku encode table missing for byte %d", b) return nil, fmt.Errorf("sudoku encode table missing for byte %d", b)
} }
hints := enc[c.rng.Intn(len(enc))] hints := enc[c.rng.IntN(len(enc))]
perm := perm4[c.rng.Intn(len(perm4))] perm := perm4[c.rng.IntN(len(perm4))]
for _, idx := range perm { for _, idx := range perm {
if c.shouldPad() { if c.shouldPad() {
out = append(out, c.randomPadding(t)) out = append(out, c.randomPadding(t))
@@ -72,7 +72,7 @@ func (e *packedEncoder) maybePad(out []byte, layout *byteLayout) []byte {
return append(out, layout.paddingPool[0]) return append(out, layout.paddingPool[0])
} }
for { for {
b := layout.paddingPool[e.codec.rng.Intn(len(layout.paddingPool))] b := layout.paddingPool[e.codec.rng.IntN(len(layout.paddingPool))]
if b != layout.padMarker { if b != layout.padMarker {
return append(out, b) return append(out, b)
} }
+7 -8
View File
@@ -7,10 +7,12 @@ import (
"fmt" "fmt"
"math/bits" "math/bits"
"math/rand" "math/rand"
rand_v2 "math/rand/v2"
"sort" "sort"
"strings" "strings"
"sync" "sync"
"time"
"github.com/xtls/xray-core/common"
) )
type table struct { type table struct {
@@ -570,11 +572,8 @@ func sort4(in [4]byte) [4]byte {
return in return in
} }
func newSeededRand() *rand.Rand { func newSeededRand() *rand_v2.Rand {
seed := time.Now().UnixNano() var seedBytes [32]byte
var seedBytes [8]byte common.Must2(crypto_rand.Read(seedBytes[:]))
if _, err := crypto_rand.Read(seedBytes[:]); err == nil { return rand_v2.New(rand_v2.NewChaCha8(seedBytes))
seed = int64(binary.BigEndian.Uint64(seedBytes[:]))
}
return rand.New(rand.NewSource(seed))
} }