sha3: mark xorInUnaligned with go:nocheckptr
It is unclear whether unaligned reads should be allowed, or if they
are even actually a good idea here. However, while we figure that out,
we should un-break 'go test -race' for users of this package.
Updates golang/go#37644
Updates golang/go#37298
Updates golang/go#37715
Updates golang/go#34972
Updates golang/go#35128
Change-Id: I088f5703023e4f05ee274a6753e925973f12ac1b
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/222855
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
diff --git a/sha3/sha3_test.go b/sha3/sha3_test.go
index 005a242..83bd619 100644
--- a/sha3/sha3_test.go
+++ b/sha3/sha3_test.go
@@ -17,6 +17,7 @@
"encoding/json"
"fmt"
"hash"
+ "math/rand"
"os"
"strings"
"testing"
@@ -306,8 +307,14 @@
}
// sequentialBytes produces a buffer of size consecutive bytes 0x00, 0x01, ..., used for testing.
+//
+// The alignment of each slice is intentionally randomized to detect alignment
+// issues in the implementation. See https://golang.org/issue/37644.
+// Ideally, the compiler should fuzz the alignment itself.
+// (See https://golang.org/issue/35128.)
func sequentialBytes(size int) []byte {
- result := make([]byte, size)
+ alignmentOffset := rand.Intn(8)
+ result := make([]byte, size+alignmentOffset)[alignmentOffset:]
for i := range result {
result[i] = byte(i)
}
diff --git a/sha3/xor_unaligned.go b/sha3/xor_unaligned.go
index a3d0686..5ede2c6 100644
--- a/sha3/xor_unaligned.go
+++ b/sha3/xor_unaligned.go
@@ -16,6 +16,17 @@
return (*[maxRate]byte)(unsafe.Pointer(b))
}
+//go:nocheckptr
+//
+// xorInUnaligned intentionally reads the input buffer as an unaligned slice of
+// integers. The language spec is not clear on whether that is allowed.
+// See:
+// https://golang.org/issue/37644
+// https://golang.org/issue/37298
+// https://golang.org/issue/35381
+
+// xorInUnaligned uses unaligned reads and writes to update d.a to contain d.a
+// XOR buf.
func xorInUnaligned(d *state, buf []byte) {
n := len(buf)
bw := (*[maxRate / 8]uint64)(unsafe.Pointer(&buf[0]))[: n/8 : n/8]