Skip to content

Commit 2b99290

Browse files
Bryan C. Millsbradfitz
authored andcommitted
sha3: align (*state).storage
Even on platforms that allow unaligned reads, the Go runtime assumes that a pointer to a given type has the alignment required by that type. Fixes golang/go#35173 Updates golang/go#34972 Updates golang/go#34964 Change-Id: I90361e096e59162e42ebde2914985af92f777ece Reviewed-on: https://go-review.googlesource.com/c/crypto/+/203837 Run-TryBot: Bryan C. Mills <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Filippo Valsorda <[email protected]>
1 parent 9f65086 commit 2b99290

File tree

3 files changed

+27
-12
lines changed

3 files changed

+27
-12
lines changed

sha3/sha3.go

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,9 @@ type state struct {
3838
// [1] http://csrc.nist.gov/publications/drafts/fips-202/fips_202_draft.pdf
3939
// "Draft FIPS 202: SHA-3 Standard: Permutation-Based Hash and
4040
// Extendable-Output Functions (May 2014)"
41-
dsbyte byte
42-
storage [maxRate]byte
41+
dsbyte byte
42+
43+
storage storageBuf
4344

4445
// Specific to SHA-3 and SHAKE.
4546
outputLen int // the default output size in bytes
@@ -60,15 +61,15 @@ func (d *state) Reset() {
6061
d.a[i] = 0
6162
}
6263
d.state = spongeAbsorbing
63-
d.buf = d.storage[:0]
64+
d.buf = d.storage.asBytes()[:0]
6465
}
6566

6667
func (d *state) clone() *state {
6768
ret := *d
6869
if ret.state == spongeAbsorbing {
69-
ret.buf = ret.storage[:len(ret.buf)]
70+
ret.buf = ret.storage.asBytes()[:len(ret.buf)]
7071
} else {
71-
ret.buf = ret.storage[d.rate-cap(d.buf) : d.rate]
72+
ret.buf = ret.storage.asBytes()[d.rate-cap(d.buf) : d.rate]
7273
}
7374

7475
return &ret
@@ -82,13 +83,13 @@ func (d *state) permute() {
8283
// If we're absorbing, we need to xor the input into the state
8384
// before applying the permutation.
8485
xorIn(d, d.buf)
85-
d.buf = d.storage[:0]
86+
d.buf = d.storage.asBytes()[:0]
8687
keccakF1600(&d.a)
8788
case spongeSqueezing:
8889
// If we're squeezing, we need to apply the permutatin before
8990
// copying more output.
9091
keccakF1600(&d.a)
91-
d.buf = d.storage[:d.rate]
92+
d.buf = d.storage.asBytes()[:d.rate]
9293
copyOut(d, d.buf)
9394
}
9495
}
@@ -97,15 +98,15 @@ func (d *state) permute() {
9798
// the multi-bitrate 10..1 padding rule, and permutes the state.
9899
func (d *state) padAndPermute(dsbyte byte) {
99100
if d.buf == nil {
100-
d.buf = d.storage[:0]
101+
d.buf = d.storage.asBytes()[:0]
101102
}
102103
// Pad with this instance's domain-separator bits. We know that there's
103104
// at least one byte of space in d.buf because, if it were full,
104105
// permute would have been called to empty it. dsbyte also contains the
105106
// first one bit for the padding. See the comment in the state struct.
106107
d.buf = append(d.buf, dsbyte)
107108
zerosStart := len(d.buf)
108-
d.buf = d.storage[:d.rate]
109+
d.buf = d.storage.asBytes()[:d.rate]
109110
for i := zerosStart; i < d.rate; i++ {
110111
d.buf[i] = 0
111112
}
@@ -116,7 +117,7 @@ func (d *state) padAndPermute(dsbyte byte) {
116117
// Apply the permutation
117118
d.permute()
118119
d.state = spongeSqueezing
119-
d.buf = d.storage[:d.rate]
120+
d.buf = d.storage.asBytes()[:d.rate]
120121
copyOut(d, d.buf)
121122
}
122123

@@ -127,7 +128,7 @@ func (d *state) Write(p []byte) (written int, err error) {
127128
panic("sha3: write to sponge after read")
128129
}
129130
if d.buf == nil {
130-
d.buf = d.storage[:0]
131+
d.buf = d.storage.asBytes()[:0]
131132
}
132133
written = len(p)
133134

sha3/xor.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@
66

77
package sha3
88

9+
// A storageBuf is an aligned array of maxRate bytes.
10+
type storageBuf [maxRate]byte
11+
12+
func (b *storageBuf) asBytes() *[maxRate]byte {
13+
return (*[maxRate]byte)(b)
14+
}
15+
916
var (
1017
xorIn = xorInGeneric
1118
copyOut = copyOutGeneric

sha3/xor_unaligned.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,16 @@ package sha3
99

1010
import "unsafe"
1111

12+
// A storageBuf is an aligned array of maxRate bytes.
13+
type storageBuf [maxRate / 8]uint64
14+
15+
func (b *storageBuf) asBytes() *[maxRate]byte {
16+
return (*[maxRate]byte)(unsafe.Pointer(b))
17+
}
18+
1219
func xorInUnaligned(d *state, buf []byte) {
13-
bw := (*[maxRate / 8]uint64)(unsafe.Pointer(&buf[0]))
1420
n := len(buf)
21+
bw := (*[maxRate / 8]uint64)(unsafe.Pointer(&buf[0]))[: n/8 : n/8]
1522
if n >= 72 {
1623
d.a[0] ^= bw[0]
1724
d.a[1] ^= bw[1]

0 commit comments

Comments
 (0)