aboutsummaryrefslogtreecommitdiff
path: root/src/crypto
diff options
context:
space:
mode:
authorJoe Tsai <joetsai@digital-static.net>2021-08-30 10:25:11 -0700
committerJoe Tsai <joetsai@digital-static.net>2021-09-23 16:54:46 +0000
commit5961134fa5530e8e07b5536b9577e4755ac1e04a (patch)
tree510d91943cdb456797ff9e034cca5bfbc6b7cdc4 /src/crypto
parent335e72bcb6a5f670e2b3c65170c4287ca7265934 (diff)
downloadgo-5961134fa5530e8e07b5536b9577e4755ac1e04a.tar.gz
go-5961134fa5530e8e07b5536b9577e4755ac1e04a.zip
crypto: avoid escaping Hash.Sum on generic architectures
For architectures without a specialized implementation (e.g. arm), the generic implementation allocates because it does: var block = blockGeneric which causes the compiler to give up trying to analyze block even though it is technically only ever one implementation. Instead of a variable, declare a function that wraps blockGeneric. We apply this fix to md5, sha1, and sha256, while sha512 already had the equivalent change. We add a test to all hashing packages to ensure no allocations. Credit goes to Cuong Manh Le for more specifically identifying the problem and Keith Randal for suggesting a concrete solution. Fixes #48055 Change-Id: I1a6a2e028038e051c83fd72b10a8bf4d210df57d Reviewed-on: https://go-review.googlesource.com/c/go/+/346209 Trust: Joe Tsai <joetsai@digital-static.net> Run-TryBot: Joe Tsai <joetsai@digital-static.net> Reviewed-by: Filippo Valsorda <filippo@golang.org> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Keith Randall <khr@golang.org> TryBot-Result: Go Bot <gobot@golang.org>
Diffstat (limited to 'src/crypto')
-rw-r--r--src/crypto/md5/md5_test.go14
-rw-r--r--src/crypto/md5/md5block_generic.go4
-rw-r--r--src/crypto/sha1/sha1_test.go14
-rw-r--r--src/crypto/sha1/sha1block_generic.go4
-rw-r--r--src/crypto/sha256/sha256_test.go14
-rw-r--r--src/crypto/sha256/sha256block_generic.go4
-rw-r--r--src/crypto/sha512/sha512_test.go14
7 files changed, 65 insertions, 3 deletions
diff --git a/src/crypto/md5/md5_test.go b/src/crypto/md5/md5_test.go
index acd456af21..851e7fb10d 100644
--- a/src/crypto/md5/md5_test.go
+++ b/src/crypto/md5/md5_test.go
@@ -211,6 +211,20 @@ func TestLargeHashes(t *testing.T) {
}
}
+func TestAllocations(t *testing.T) {
+ in := []byte("hello, world!")
+ out := make([]byte, 0, Size)
+ h := New()
+ n := int(testing.AllocsPerRun(10, func() {
+ h.Reset()
+ h.Write(in)
+ out = h.Sum(out[:0])
+ }))
+ if n > 0 {
+ t.Errorf("allocs = %d, want 0", n)
+ }
+}
+
var bench = New()
var buf = make([]byte, 1024*1024*8+1)
var sum = make([]byte, bench.Size())
diff --git a/src/crypto/md5/md5block_generic.go b/src/crypto/md5/md5block_generic.go
index ea4fbcd0b4..23ed75304f 100644
--- a/src/crypto/md5/md5block_generic.go
+++ b/src/crypto/md5/md5block_generic.go
@@ -9,4 +9,6 @@ package md5
const haveAsm = false
-var block = blockGeneric
+func block(dig *digest, p []byte) {
+ blockGeneric(dig, p)
+}
diff --git a/src/crypto/sha1/sha1_test.go b/src/crypto/sha1/sha1_test.go
index c3e6010af1..ab43c7792d 100644
--- a/src/crypto/sha1/sha1_test.go
+++ b/src/crypto/sha1/sha1_test.go
@@ -210,6 +210,20 @@ func TestLargeHashes(t *testing.T) {
}
}
+func TestAllocations(t *testing.T) {
+ in := []byte("hello, world!")
+ out := make([]byte, 0, Size)
+ h := New()
+ n := int(testing.AllocsPerRun(10, func() {
+ h.Reset()
+ h.Write(in)
+ out = h.Sum(out[:0])
+ }))
+ if n > 0 {
+ t.Errorf("allocs = %d, want 0", n)
+ }
+}
+
var bench = New()
var buf = make([]byte, 8192)
diff --git a/src/crypto/sha1/sha1block_generic.go b/src/crypto/sha1/sha1block_generic.go
index feaba5a23a..105aa31832 100644
--- a/src/crypto/sha1/sha1block_generic.go
+++ b/src/crypto/sha1/sha1block_generic.go
@@ -7,4 +7,6 @@
package sha1
-var block = blockGeneric
+func block(dig *digest, p []byte) {
+ blockGeneric(dig, p)
+}
diff --git a/src/crypto/sha256/sha256_test.go b/src/crypto/sha256/sha256_test.go
index a2794b015d..702aa0b371 100644
--- a/src/crypto/sha256/sha256_test.go
+++ b/src/crypto/sha256/sha256_test.go
@@ -289,6 +289,20 @@ func TestLargeHashes(t *testing.T) {
}
}
+func TestAllocations(t *testing.T) {
+ in := []byte("hello, world!")
+ out := make([]byte, 0, Size)
+ h := New()
+ n := int(testing.AllocsPerRun(10, func() {
+ h.Reset()
+ h.Write(in)
+ out = h.Sum(out[:0])
+ }))
+ if n > 0 {
+ t.Errorf("allocs = %d, want 0", n)
+ }
+}
+
var bench = New()
var buf = make([]byte, 8192)
diff --git a/src/crypto/sha256/sha256block_generic.go b/src/crypto/sha256/sha256block_generic.go
index 620c048b93..0f2bf8b231 100644
--- a/src/crypto/sha256/sha256block_generic.go
+++ b/src/crypto/sha256/sha256block_generic.go
@@ -7,4 +7,6 @@
package sha256
-var block = blockGeneric
+func block(dig *digest, p []byte) {
+ blockGeneric(dig, p)
+}
diff --git a/src/crypto/sha512/sha512_test.go b/src/crypto/sha512/sha512_test.go
index 0e1528fc69..aea772c7da 100644
--- a/src/crypto/sha512/sha512_test.go
+++ b/src/crypto/sha512/sha512_test.go
@@ -888,6 +888,20 @@ func TestLargeHashes(t *testing.T) {
}
}
+func TestAllocations(t *testing.T) {
+ in := []byte("hello, world!")
+ out := make([]byte, 0, Size)
+ h := New()
+ n := int(testing.AllocsPerRun(10, func() {
+ h.Reset()
+ h.Write(in)
+ out = h.Sum(out[:0])
+ }))
+ if n > 0 {
+ t.Errorf("allocs = %d, want 0", n)
+ }
+}
+
var bench = New()
var buf = make([]byte, 8192)