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
import (
"crypto/rand"
"fmt"
"math/rand"
"sync"
"time"
"github.com/xtls/xray-core/common"
"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.
// Packet format: [8-byte salt][payload]
type SalamanderObfuscator struct {
PSK []byte
RandSrc *rand.Rand
PSK []byte
lk sync.Mutex
keyInput []byte
@@ -37,7 +36,6 @@ func NewSalamanderObfuscator(psk []byte) (*SalamanderObfuscator, error) {
copy(keyInput, pskCopy)
return &SalamanderObfuscator{
PSK: pskCopy,
RandSrc: rand.New(rand.NewSource(time.Now().UnixNano())),
keyInput: keyInput,
}, nil
}
@@ -47,8 +45,8 @@ func (o *SalamanderObfuscator) Obfuscate(in, out []byte) int {
if len(out) < outLen {
return 0
}
common.Must2(rand.Read(out[:smSaltLen]))
o.lk.Lock()
_, _ = o.RandSrc.Read(out[:smSaltLen])
key := o.keyLocked(out[:smSaltLen])
o.lk.Unlock()
for i, c := range in {
+6 -6
View File
@@ -2,7 +2,7 @@ package sudoku
import (
"fmt"
"math/rand"
"math/rand/v2"
)
var perm4 = [24][4]byte{
@@ -67,7 +67,7 @@ func pickPaddingChance(rng *rand.Rand, pMin, pMax int) int {
if pMax == pMin {
return pMin
}
return pMin + rng.Intn(pMax-pMin+1)
return pMin + rng.IntN(pMax-pMin+1)
}
func (c *codec) shouldPad() bool {
@@ -77,7 +77,7 @@ func (c *codec) shouldPad() bool {
if c.paddingChance >= 100 {
return true
}
return c.rng.Intn(100) < c.paddingChance
return c.rng.IntN(100) < c.paddingChance
}
func (c *codec) currentTable() *table {
@@ -89,7 +89,7 @@ func (c *codec) currentTable() *table {
func (c *codec) randomPadding(t *table) byte {
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) {
@@ -112,8 +112,8 @@ func (c *codec) encode(in []byte) ([]byte, error) {
return nil, fmt.Errorf("sudoku encode table missing for byte %d", b)
}
hints := enc[c.rng.Intn(len(enc))]
perm := perm4[c.rng.Intn(len(perm4))]
hints := enc[c.rng.IntN(len(enc))]
perm := perm4[c.rng.IntN(len(perm4))]
for _, idx := range perm {
if c.shouldPad() {
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])
}
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 {
return append(out, b)
}
+7 -8
View File
@@ -7,10 +7,12 @@ import (
"fmt"
"math/bits"
"math/rand"
rand_v2 "math/rand/v2"
"sort"
"strings"
"sync"
"time"
"github.com/xtls/xray-core/common"
)
type table struct {
@@ -570,11 +572,8 @@ func sort4(in [4]byte) [4]byte {
return in
}
func newSeededRand() *rand.Rand {
seed := time.Now().UnixNano()
var seedBytes [8]byte
if _, err := crypto_rand.Read(seedBytes[:]); err == nil {
seed = int64(binary.BigEndian.Uint64(seedBytes[:]))
}
return rand.New(rand.NewSource(seed))
func newSeededRand() *rand_v2.Rand {
var seedBytes [32]byte
common.Must2(crypto_rand.Read(seedBytes[:]))
return rand_v2.New(rand_v2.NewChaCha8(seedBytes))
}