From f7b00557c8c46a1ea4b035cae84f52028c2c0564 Mon Sep 17 00:00:00 2001 From: "Bryan C. Mills" Date: Wed, 11 Mar 2020 09:15:05 -0400 Subject: [PATCH] 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 TryBot-Result: Gobot Gobot Reviewed-by: Matthew Dempsky --- sha3/sha3_test.go | 9 ++++++++- sha3/xor_unaligned.go | 11 +++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/sha3/sha3_test.go b/sha3/sha3_test.go index 005a24247b..83bd6195d6 100644 --- a/sha3/sha3_test.go +++ b/sha3/sha3_test.go @@ -17,6 +17,7 @@ import ( "encoding/json" "fmt" "hash" + "math/rand" "os" "strings" "testing" @@ -306,8 +307,14 @@ func TestSqueezing(t *testing.T) { } // 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 a3d068634c..5ede2c61b4 100644 --- a/sha3/xor_unaligned.go +++ b/sha3/xor_unaligned.go @@ -16,6 +16,17 @@ func (b *storageBuf) asBytes() *[maxRate]byte { 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]