Skip to content

Commit ea0b47a

Browse files
authored
rng: Fix subkeys not initialized (#230)
Ref: minio/warp#471
1 parent 54ff789 commit ea0b47a

2 files changed

Lines changed: 53 additions & 5 deletions

File tree

rng/reader.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,15 +79,14 @@ func (r *Reader) init() error {
7979
r.bufferSeeded = !r.o.fullReset
8080
}
8181
// Always reset subkeys.
82-
var tmp [32]byte
8382
_, err := io.ReadFull(r.o.rng, r.tmp[:])
8483
if err != nil {
8584
return err
8685
}
87-
r.subxor[0] = binary.LittleEndian.Uint64(tmp[:8])
88-
r.subxor[1] = binary.LittleEndian.Uint64(tmp[8:16])
89-
r.subxor[2] = binary.LittleEndian.Uint64(tmp[16:24])
90-
r.subxor[3] = binary.LittleEndian.Uint64(tmp[24:32])
86+
r.subxor[0] = binary.LittleEndian.Uint64(r.tmp[:8])
87+
r.subxor[1] = binary.LittleEndian.Uint64(r.tmp[8:16])
88+
r.subxor[2] = binary.LittleEndian.Uint64(r.tmp[16:24])
89+
r.subxor[3] = binary.LittleEndian.Uint64(r.tmp[24:32])
9190
r.offset = 0
9291
return nil
9392
}

rng/reader_test.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,55 @@ import (
2525
"testing"
2626
)
2727

28+
func TestSubkeysInitialized(t *testing.T) {
29+
src := rand.New(rand.NewSource(12345))
30+
r, err := NewReader(WithRNG(src))
31+
if err != nil {
32+
t.Fatal(err)
33+
}
34+
35+
allZero := true
36+
for _, v := range r.subxor {
37+
if v != 0 {
38+
allZero = false
39+
break
40+
}
41+
}
42+
if allZero {
43+
t.Fatal("subxor keys are all zero after initialization")
44+
}
45+
46+
// With fullReset=false (default), the buffer is reused across Reset.
47+
// If subkeys were always zero, output would be identical after reset.
48+
buf1 := make([]byte, 1024)
49+
io.ReadFull(r, buf1)
50+
51+
r.Reset()
52+
53+
buf2 := make([]byte, 1024)
54+
io.ReadFull(r, buf2)
55+
56+
if bytes.Equal(buf1, buf2) {
57+
t.Fatal("output identical after reset — subkeys not re-initialized")
58+
}
59+
}
60+
61+
func TestResetSizeProducesUniqueOutput(t *testing.T) {
62+
const size = 64 << 20 // 64 MiB
63+
r, _ := NewReader(WithSize(size))
64+
65+
out1 := make([]byte, size)
66+
io.ReadFull(r, out1)
67+
68+
r.ResetSize(size)
69+
out2 := make([]byte, size)
70+
io.ReadFull(r, out2)
71+
72+
if bytes.Equal(out1, out2) {
73+
t.Fatal("ResetSize produced identical output: subxor keys are not being randomized")
74+
}
75+
}
76+
2877
func BenchmarkReader(b *testing.B) {
2978
for _, size := range []int{1000, 1024, 16384, 1 << 20} {
3079
r, err := NewReader()

0 commit comments

Comments
 (0)