|
@@ -6,7 +6,11 @@
|
|
|
|
|
|
|
|
package chacha20poly1305
|
|
package chacha20poly1305
|
|
|
|
|
|
|
|
-import "encoding/binary"
|
|
|
|
|
|
|
+import (
|
|
|
|
|
+ "encoding/binary"
|
|
|
|
|
+
|
|
|
|
|
+ "golang.org/x/sys/cpu"
|
|
|
|
|
+)
|
|
|
|
|
|
|
|
//go:noescape
|
|
//go:noescape
|
|
|
func chacha20Poly1305Open(dst []byte, key []uint32, src, ad []byte) bool
|
|
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
|
|
//go:noescape
|
|
|
func chacha20Poly1305Seal(dst []byte, key []uint32, src, ad []byte)
|
|
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 (
|
|
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
|
|
// setupState writes a ChaCha20 input matrix to state. See
|
|
|
// https://tools.ietf.org/html/rfc7539#section-2.3.
|
|
// https://tools.ietf.org/html/rfc7539#section-2.3.
|
|
|
func setupState(state *[16]uint32, key *[8]uint32, nonce []byte) {
|
|
func setupState(state *[16]uint32, key *[8]uint32, nonce []byte) {
|