1
0
зеркало из https://github.com/henrydcase/nobs.git synced 2024-11-26 00:51:22 +00:00

SHA-3: Fixes crash when cloning Shake state

Этот коммит содержится в:
Henry Case 2019-05-26 16:39:29 +01:00
родитель 9b3c0190b0
Коммит 15f6ee16b9
3 изменённых файлов: 35 добавлений и 10 удалений

Просмотреть файл

@ -65,15 +65,15 @@ func (d *state) Reset() {
d.buf = d.storage[:0]
}
func (d *state) clone() *state {
ret := *d
func (d *state) clone(ret *state) {
// shallow copy
*ret = *d
// deep copy for a buf
if ret.state == spongeAbsorbing {
ret.buf = ret.storage[:len(ret.buf)]
ret.buf = ret.storage[:len(d.buf)]
} else {
ret.buf = ret.storage[d.rate-cap(d.buf) : d.rate]
ret.buf = ret.storage[d.rate-len(d.buf) : d.rate]
}
return &ret
}
// permute applies the KeccakF-1600 permutation. It handles
@ -187,7 +187,8 @@ func (d *state) Read(out []byte) (n int, err error) {
func (d *state) Sum(in []byte) []byte {
// Make a copy of the original hash so that caller can keep writing
// and summing.
dup := d.clone()
var dup state
d.clone(&dup)
hash := make([]byte, dup.outputLen)
dup.Read(hash)
return append(in, hash...)

Просмотреть файл

@ -284,6 +284,28 @@ func TestClone(t *testing.T) {
}
}
// Checks wether reset works correctly after clone
func TestCloneAndReset(t *testing.T) {
// Shake 256, uses SHA-3 with rate = 136
d1 := NewShake256()
buf1 := make([]byte, 28, 28)
buf2 := make([]byte, 28, 28)
d1.Write([]byte{0xcc})
// Reading x bytes where x<168-136. This makes capability
// of the state buffer shorter.
d1.Read(buf1)
// This will crash if sha-3 code uses cap() instead
// of len() when calculating length of state buffer
d2 := d1.Clone()
d2.Reset()
d2.Write([]byte{0xcc})
d2.Read(buf2)
if !bytes.Equal(buf1, buf2) {
t.Error("Different value when reading after reset")
}
}
// BenchmarkPermutationFunction measures the speed of the permutation function
// with no input data.
func BenchmarkPermutationFunction(b *testing.B) {

Просмотреть файл

@ -86,9 +86,11 @@ func (c *CShake) Reset() {
// Clone returns copy of a cSHAKE context within its current state.
func (c *CShake) Clone() CShake {
b := make([]byte, len(c.initBlock))
copy(b, c.initBlock)
return CShake{state: *c.clone(), initBlock: b}
var ret CShake
c.clone(&ret.state)
ret.initBlock = make([]byte, len(c.initBlock))
copy(ret.initBlock, c.initBlock)
return ret
}
// NewShake128 creates a new SHAKE128 variable-output-length CShake.