crypto/{blake2b,blake2s,argon2,chacha20poly1305}: replace CPU feature detection
This change removes package specific CPU-feature detection code and replaces it with x/sys/cpu. Fixes golang/go#24843 Change-Id: I150dd7b3aeb8eef428c91f9b1df741ceb8a87a24 Reviewed-on: https://go-review.googlesource.com/110355 Run-TryBot: Ilya Tocar <ilya.tocar@intel.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
committed by
Brad Fitzpatrick
parent
db7d12313a
commit
ae8bce0030
@@ -6,12 +6,11 @@
|
||||
|
||||
package argon2
|
||||
|
||||
func init() {
|
||||
useSSE4 = supportsSSE4()
|
||||
}
|
||||
import "golang.org/x/sys/cpu"
|
||||
|
||||
//go:noescape
|
||||
func supportsSSE4() bool
|
||||
func init() {
|
||||
useSSE4 = cpu.X86.HasSSE41
|
||||
}
|
||||
|
||||
//go:noescape
|
||||
func mixBlocksSSE2(out, a, b, c *block)
|
||||
|
||||
@@ -241,12 +241,3 @@ loop:
|
||||
SUBQ $2, BP
|
||||
JA loop
|
||||
RET
|
||||
|
||||
// func supportsSSE4() bool
|
||||
TEXT ·supportsSSE4(SB), 4, $0-1
|
||||
MOVL $1, AX
|
||||
CPUID
|
||||
SHRL $19, CX // Bit 19 indicates SSE4 support
|
||||
ANDL $1, CX // CX != 0 if support SSE4
|
||||
MOVB CX, ret+0(FP)
|
||||
RET
|
||||
|
||||
@@ -6,21 +6,14 @@
|
||||
|
||||
package blake2b
|
||||
|
||||
import "golang.org/x/sys/cpu"
|
||||
|
||||
func init() {
|
||||
useAVX2 = supportsAVX2()
|
||||
useAVX = supportsAVX()
|
||||
useSSE4 = supportsSSE4()
|
||||
useAVX2 = cpu.X86.HasAVX2
|
||||
useAVX = cpu.X86.HasAVX
|
||||
useSSE4 = cpu.X86.HasSSE41
|
||||
}
|
||||
|
||||
//go:noescape
|
||||
func supportsSSE4() bool
|
||||
|
||||
//go:noescape
|
||||
func supportsAVX() bool
|
||||
|
||||
//go:noescape
|
||||
func supportsAVX2() bool
|
||||
|
||||
//go:noescape
|
||||
func hashBlocksAVX2(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
|
||||
|
||||
@@ -31,13 +24,14 @@ func hashBlocksAVX(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
|
||||
func hashBlocksSSE4(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
|
||||
|
||||
func hashBlocks(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) {
|
||||
if useAVX2 {
|
||||
switch {
|
||||
case useAVX2:
|
||||
hashBlocksAVX2(h, c, flag, blocks)
|
||||
} else if useAVX {
|
||||
case useAVX:
|
||||
hashBlocksAVX(h, c, flag, blocks)
|
||||
} else if useSSE4 {
|
||||
case useSSE4:
|
||||
hashBlocksSSE4(h, c, flag, blocks)
|
||||
} else {
|
||||
default:
|
||||
hashBlocksGeneric(h, c, flag, blocks)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -748,15 +748,3 @@ noinc:
|
||||
|
||||
MOVQ BP, SP
|
||||
RET
|
||||
|
||||
// func supportsAVX2() bool
|
||||
TEXT ·supportsAVX2(SB), 4, $0-1
|
||||
MOVQ runtime·support_avx2(SB), AX
|
||||
MOVB AX, ret+0(FP)
|
||||
RET
|
||||
|
||||
// func supportsAVX() bool
|
||||
TEXT ·supportsAVX(SB), 4, $0-1
|
||||
MOVQ runtime·support_avx(SB), AX
|
||||
MOVB AX, ret+0(FP)
|
||||
RET
|
||||
|
||||
@@ -6,12 +6,11 @@
|
||||
|
||||
package blake2b
|
||||
|
||||
func init() {
|
||||
useSSE4 = supportsSSE4()
|
||||
}
|
||||
import "golang.org/x/sys/cpu"
|
||||
|
||||
//go:noescape
|
||||
func supportsSSE4() bool
|
||||
func init() {
|
||||
useSSE4 = cpu.X86.HasSSE41
|
||||
}
|
||||
|
||||
//go:noescape
|
||||
func hashBlocksSSE4(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
|
||||
|
||||
@@ -279,12 +279,3 @@ noinc:
|
||||
|
||||
MOVQ BP, SP
|
||||
RET
|
||||
|
||||
// func supportsSSE4() bool
|
||||
TEXT ·supportsSSE4(SB), 4, $0-1
|
||||
MOVL $1, AX
|
||||
CPUID
|
||||
SHRL $19, CX // Bit 19 indicates SSE4 support
|
||||
ANDL $1, CX // CX != 0 if support SSE4
|
||||
MOVB CX, ret+0(FP)
|
||||
RET
|
||||
|
||||
+8
-11
@@ -6,18 +6,14 @@
|
||||
|
||||
package blake2s
|
||||
|
||||
import "golang.org/x/sys/cpu"
|
||||
|
||||
var (
|
||||
useSSE4 = false
|
||||
useSSSE3 = supportSSSE3()
|
||||
useSSE2 = supportSSE2()
|
||||
useSSSE3 = cpu.X86.HasSSSE3
|
||||
useSSE2 = cpu.X86.HasSSE2
|
||||
)
|
||||
|
||||
//go:noescape
|
||||
func supportSSE2() bool
|
||||
|
||||
//go:noescape
|
||||
func supportSSSE3() bool
|
||||
|
||||
//go:noescape
|
||||
func hashBlocksSSE2(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
|
||||
|
||||
@@ -25,11 +21,12 @@ func hashBlocksSSE2(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
|
||||
func hashBlocksSSSE3(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
|
||||
|
||||
func hashBlocks(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte) {
|
||||
if useSSSE3 {
|
||||
switch {
|
||||
case useSSSE3:
|
||||
hashBlocksSSSE3(h, c, flag, blocks)
|
||||
} else if useSSE2 {
|
||||
case useSSE2:
|
||||
hashBlocksSSE2(h, c, flag, blocks)
|
||||
} else {
|
||||
default:
|
||||
hashBlocksGeneric(h, c, flag, blocks)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -433,28 +433,3 @@ loop:
|
||||
|
||||
MOVL BP, SP
|
||||
RET
|
||||
|
||||
// func supportSSSE3() bool
|
||||
TEXT ·supportSSSE3(SB), 4, $0-1
|
||||
MOVL $1, AX
|
||||
CPUID
|
||||
MOVL CX, BX
|
||||
ANDL $0x1, BX // supports SSE3
|
||||
JZ FALSE
|
||||
ANDL $0x200, CX // supports SSSE3
|
||||
JZ FALSE
|
||||
MOVB $1, ret+0(FP)
|
||||
RET
|
||||
|
||||
FALSE:
|
||||
MOVB $0, ret+0(FP)
|
||||
RET
|
||||
|
||||
// func supportSSE2() bool
|
||||
TEXT ·supportSSE2(SB), 4, $0-1
|
||||
MOVL $1, AX
|
||||
CPUID
|
||||
SHRL $26, DX
|
||||
ANDL $1, DX // DX != 0 if support SSE2
|
||||
MOVB DX, ret+0(FP)
|
||||
RET
|
||||
|
||||
+10
-13
@@ -6,18 +6,14 @@
|
||||
|
||||
package blake2s
|
||||
|
||||
import "golang.org/x/sys/cpu"
|
||||
|
||||
var (
|
||||
useSSE4 = supportSSE4()
|
||||
useSSSE3 = supportSSSE3()
|
||||
useSSE2 = true // Always available on amd64
|
||||
useSSE4 = cpu.X86.HasSSE41
|
||||
useSSSE3 = cpu.X86.HasSSSE3
|
||||
useSSE2 = cpu.X86.HasSSE2
|
||||
)
|
||||
|
||||
//go:noescape
|
||||
func supportSSSE3() bool
|
||||
|
||||
//go:noescape
|
||||
func supportSSE4() bool
|
||||
|
||||
//go:noescape
|
||||
func hashBlocksSSE2(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
|
||||
|
||||
@@ -28,13 +24,14 @@ func hashBlocksSSSE3(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
|
||||
func hashBlocksSSE4(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
|
||||
|
||||
func hashBlocks(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte) {
|
||||
if useSSE4 {
|
||||
switch {
|
||||
case useSSE4:
|
||||
hashBlocksSSE4(h, c, flag, blocks)
|
||||
} else if useSSSE3 {
|
||||
case useSSSE3:
|
||||
hashBlocksSSSE3(h, c, flag, blocks)
|
||||
} else if useSSE2 {
|
||||
case useSSE2:
|
||||
hashBlocksSSE2(h, c, flag, blocks)
|
||||
} else {
|
||||
default:
|
||||
hashBlocksGeneric(h, c, flag, blocks)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -436,28 +436,3 @@ TEXT ·hashBlocksSSSE3(SB), 0, $672-48 // frame = 656 + 16 byte alignment
|
||||
TEXT ·hashBlocksSSE4(SB), 0, $32-48 // frame = 16 + 16 byte alignment
|
||||
HASH_BLOCKS(h+0(FP), c+8(FP), flag+16(FP), blocks_base+24(FP), blocks_len+32(FP), BLAKE2s_SSE4)
|
||||
RET
|
||||
|
||||
// func supportSSE4() bool
|
||||
TEXT ·supportSSE4(SB), 4, $0-1
|
||||
MOVL $1, AX
|
||||
CPUID
|
||||
SHRL $19, CX // Bit 19 indicates SSE4.1.
|
||||
ANDL $1, CX
|
||||
MOVB CX, ret+0(FP)
|
||||
RET
|
||||
|
||||
// func supportSSSE3() bool
|
||||
TEXT ·supportSSSE3(SB), 4, $0-1
|
||||
MOVL $1, AX
|
||||
CPUID
|
||||
MOVL CX, BX
|
||||
ANDL $0x1, BX // Bit zero indicates SSE3 support.
|
||||
JZ FALSE
|
||||
ANDL $0x200, CX // Bit nine indicates SSSE3 support.
|
||||
JZ FALSE
|
||||
MOVB $1, ret+0(FP)
|
||||
RET
|
||||
|
||||
FALSE:
|
||||
MOVB $0, ret+0(FP)
|
||||
RET
|
||||
|
||||
@@ -6,7 +6,11 @@
|
||||
|
||||
package chacha20poly1305
|
||||
|
||||
import "encoding/binary"
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"golang.org/x/sys/cpu"
|
||||
)
|
||||
|
||||
//go:noescape
|
||||
func chacha20Poly1305Open(dst []byte, key []uint32, src, ad []byte) bool
|
||||
@@ -14,62 +18,11 @@ func chacha20Poly1305Open(dst []byte, key []uint32, src, ad []byte) bool
|
||||
//go:noescape
|
||||
func chacha20Poly1305Seal(dst []byte, key []uint32, src, ad []byte)
|
||||
|
||||
// cpuid is implemented in chacha20poly1305_amd64.s.
|
||||
func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32)
|
||||
|
||||
// xgetbv with ecx = 0 is implemented in chacha20poly1305_amd64.s.
|
||||
func xgetbv() (eax, edx uint32)
|
||||
|
||||
var (
|
||||
useASM bool
|
||||
useAVX2 bool
|
||||
useASM = cpu.X86.HasSSSE3
|
||||
useAVX2 = cpu.X86.HasAVX2
|
||||
)
|
||||
|
||||
func init() {
|
||||
detectCPUFeatures()
|
||||
}
|
||||
|
||||
// detectCPUFeatures is used to detect if cpu instructions
|
||||
// used by the functions implemented in assembler in
|
||||
// chacha20poly1305_amd64.s are supported.
|
||||
func detectCPUFeatures() {
|
||||
maxID, _, _, _ := cpuid(0, 0)
|
||||
if maxID < 1 {
|
||||
return
|
||||
}
|
||||
|
||||
_, _, ecx1, _ := cpuid(1, 0)
|
||||
|
||||
haveSSSE3 := isSet(9, ecx1)
|
||||
useASM = haveSSSE3
|
||||
|
||||
haveOSXSAVE := isSet(27, ecx1)
|
||||
|
||||
osSupportsAVX := false
|
||||
// For XGETBV, OSXSAVE bit is required and sufficient.
|
||||
if haveOSXSAVE {
|
||||
eax, _ := xgetbv()
|
||||
// Check if XMM and YMM registers have OS support.
|
||||
osSupportsAVX = isSet(1, eax) && isSet(2, eax)
|
||||
}
|
||||
haveAVX := isSet(28, ecx1) && osSupportsAVX
|
||||
|
||||
if maxID < 7 {
|
||||
return
|
||||
}
|
||||
|
||||
_, ebx7, _, _ := cpuid(7, 0)
|
||||
haveAVX2 := isSet(5, ebx7) && haveAVX
|
||||
haveBMI2 := isSet(8, ebx7)
|
||||
|
||||
useAVX2 = haveAVX2 && haveBMI2
|
||||
}
|
||||
|
||||
// isSet checks if bit at bitpos is set in value.
|
||||
func isSet(bitpos uint, value uint32) bool {
|
||||
return value&(1<<bitpos) != 0
|
||||
}
|
||||
|
||||
// setupState writes a ChaCha20 input matrix to state. See
|
||||
// https://tools.ietf.org/html/rfc7539#section-2.3.
|
||||
func setupState(state *[16]uint32, key *[8]uint32, nonce []byte) {
|
||||
|
||||
Reference in New Issue
Block a user