vendor: golang.org/x/net@d8887717615a
This commit is contained in:
parent
4de0b33097
commit
5205d21f1e
4
go.mod
4
go.mod
|
@ -111,8 +111,8 @@ require (
|
||||||
go.uber.org/atomic v1.3.2 // indirect
|
go.uber.org/atomic v1.3.2 // indirect
|
||||||
go.uber.org/multierr v1.1.0 // indirect
|
go.uber.org/multierr v1.1.0 // indirect
|
||||||
go.uber.org/zap v1.9.1 // indirect
|
go.uber.org/zap v1.9.1 // indirect
|
||||||
golang.org/x/crypto v0.0.0-20190228050851-31a38585487a
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2
|
||||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a
|
||||||
golang.org/x/oauth2 v0.0.0-20190220154721-9b3c75971fc9
|
golang.org/x/oauth2 v0.0.0-20190220154721-9b3c75971fc9
|
||||||
google.golang.org/api v0.1.0
|
google.golang.org/api v0.1.0
|
||||||
google.golang.org/grpc v1.18.0
|
google.golang.org/grpc v1.18.0
|
||||||
|
|
6
go.sum
6
go.sum
|
@ -419,8 +419,8 @@ golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2 h1:NwxKRvbkH5MsNkvOtPZi3/
|
||||||
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20190222235706-ffb98f73852f h1:qWFY9ZxP3tfI37wYIs/MnIAqK0vlXp1xnYEa5HxFSSY=
|
golang.org/x/crypto v0.0.0-20190222235706-ffb98f73852f h1:qWFY9ZxP3tfI37wYIs/MnIAqK0vlXp1xnYEa5HxFSSY=
|
||||||
golang.org/x/crypto v0.0.0-20190222235706-ffb98f73852f/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20190222235706-ffb98f73852f/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20190228050851-31a38585487a h1:53VJPSIh1mc/PLK5AlXoj1HHfovtbS77YvYJ0AqjSgE=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
|
||||||
golang.org/x/crypto v0.0.0-20190228050851-31a38585487a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
|
@ -436,6 +436,8 @@ golang.org/x/net v0.0.0-20181129055619-fae4c4e3ad76/go.mod h1:mL1N/T3taQHkDXs73r
|
||||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd h1:HuTn7WObtcDo9uEEU7rEqL0jYthdXAmZ6PP+meazmaU=
|
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd h1:HuTn7WObtcDo9uEEU7rEqL0jYthdXAmZ6PP+meazmaU=
|
||||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
|
||||||
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890 h1:uESlIz09WIHT2I+pasSXcpLYqYK8wHcdCetU3VuMBJE=
|
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890 h1:uESlIz09WIHT2I+pasSXcpLYqYK8wHcdCetU3VuMBJE=
|
||||||
|
|
|
@ -6,15 +6,14 @@
|
||||||
|
|
||||||
package chacha20
|
package chacha20
|
||||||
|
|
||||||
var haveAsm = hasVectorFacility()
|
import (
|
||||||
|
"golang.org/x/sys/cpu"
|
||||||
|
)
|
||||||
|
|
||||||
|
var haveAsm = cpu.S390X.HasVX
|
||||||
|
|
||||||
const bufSize = 256
|
const bufSize = 256
|
||||||
|
|
||||||
// hasVectorFacility reports whether the machine supports the vector
|
|
||||||
// facility (vx).
|
|
||||||
// Implementation in asm_s390x.s.
|
|
||||||
func hasVectorFacility() bool
|
|
||||||
|
|
||||||
// xorKeyStreamVX is an assembly implementation of XORKeyStream. It must only
|
// xorKeyStreamVX is an assembly implementation of XORKeyStream. It must only
|
||||||
// be called when the vector facility is available.
|
// be called when the vector facility is available.
|
||||||
// Implementation in asm_s390x.s.
|
// Implementation in asm_s390x.s.
|
||||||
|
|
|
@ -258,26 +258,3 @@ tail:
|
||||||
MOVD R8, R3
|
MOVD R8, R3
|
||||||
MOVD $0, R4
|
MOVD $0, R4
|
||||||
JMP continue
|
JMP continue
|
||||||
|
|
||||||
// func hasVectorFacility() bool
|
|
||||||
TEXT ·hasVectorFacility(SB), NOSPLIT, $24-1
|
|
||||||
MOVD $x-24(SP), R1
|
|
||||||
XC $24, 0(R1), 0(R1) // clear the storage
|
|
||||||
MOVD $2, R0 // R0 is the number of double words stored -1
|
|
||||||
WORD $0xB2B01000 // STFLE 0(R1)
|
|
||||||
XOR R0, R0 // reset the value of R0
|
|
||||||
MOVBZ z-8(SP), R1
|
|
||||||
AND $0x40, R1
|
|
||||||
BEQ novector
|
|
||||||
|
|
||||||
vectorinstalled:
|
|
||||||
// check if the vector instruction has been enabled
|
|
||||||
VLEIB $0, $0xF, V16
|
|
||||||
VLGVB $0, V16, R1
|
|
||||||
CMPBNE R1, $0xF, novector
|
|
||||||
MOVB $1, ret+0(FP) // have vx
|
|
||||||
RET
|
|
||||||
|
|
||||||
novector:
|
|
||||||
MOVB $0, ret+0(FP) // no vx
|
|
||||||
RET
|
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !amd64 gccgo appengine
|
||||||
|
|
||||||
|
package poly1305
|
||||||
|
|
||||||
|
type mac struct{ macGeneric }
|
||||||
|
|
||||||
|
func newMAC(key *[32]byte) mac { return mac{newMACGeneric(key)} }
|
|
@ -2,21 +2,19 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
/*
|
// Package poly1305 implements Poly1305 one-time message authentication code as
|
||||||
Package poly1305 implements Poly1305 one-time message authentication code as
|
// specified in https://cr.yp.to/mac/poly1305-20050329.pdf.
|
||||||
specified in https://cr.yp.to/mac/poly1305-20050329.pdf.
|
//
|
||||||
|
// Poly1305 is a fast, one-time authentication function. It is infeasible for an
|
||||||
Poly1305 is a fast, one-time authentication function. It is infeasible for an
|
// attacker to generate an authenticator for a message without the key. However, a
|
||||||
attacker to generate an authenticator for a message without the key. However, a
|
// key must only be used for a single message. Authenticating two different
|
||||||
key must only be used for a single message. Authenticating two different
|
// messages with the same key allows an attacker to forge authenticators for other
|
||||||
messages with the same key allows an attacker to forge authenticators for other
|
// messages with the same key.
|
||||||
messages with the same key.
|
//
|
||||||
|
// Poly1305 was originally coupled with AES in order to make Poly1305-AES. AES was
|
||||||
Poly1305 was originally coupled with AES in order to make Poly1305-AES. AES was
|
// used with a fixed key in order to generate one-time keys from an nonce.
|
||||||
used with a fixed key in order to generate one-time keys from an nonce.
|
// However, in this package AES isn't used and the one-time key is specified
|
||||||
However, in this package AES isn't used and the one-time key is specified
|
// directly.
|
||||||
directly.
|
|
||||||
*/
|
|
||||||
package poly1305 // import "golang.org/x/crypto/poly1305"
|
package poly1305 // import "golang.org/x/crypto/poly1305"
|
||||||
|
|
||||||
import "crypto/subtle"
|
import "crypto/subtle"
|
||||||
|
@ -31,3 +29,55 @@ func Verify(mac *[16]byte, m []byte, key *[32]byte) bool {
|
||||||
Sum(&tmp, m, key)
|
Sum(&tmp, m, key)
|
||||||
return subtle.ConstantTimeCompare(tmp[:], mac[:]) == 1
|
return subtle.ConstantTimeCompare(tmp[:], mac[:]) == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// New returns a new MAC computing an authentication
|
||||||
|
// tag of all data written to it with the given key.
|
||||||
|
// This allows writing the message progressively instead
|
||||||
|
// of passing it as a single slice. Common users should use
|
||||||
|
// the Sum function instead.
|
||||||
|
//
|
||||||
|
// The key must be unique for each message, as authenticating
|
||||||
|
// two different messages with the same key allows an attacker
|
||||||
|
// to forge messages at will.
|
||||||
|
func New(key *[32]byte) *MAC {
|
||||||
|
return &MAC{
|
||||||
|
mac: newMAC(key),
|
||||||
|
finalized: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MAC is an io.Writer computing an authentication tag
|
||||||
|
// of the data written to it.
|
||||||
|
//
|
||||||
|
// MAC cannot be used like common hash.Hash implementations,
|
||||||
|
// because using a poly1305 key twice breaks its security.
|
||||||
|
// Therefore writing data to a running MAC after calling
|
||||||
|
// Sum causes it to panic.
|
||||||
|
type MAC struct {
|
||||||
|
mac // platform-dependent implementation
|
||||||
|
|
||||||
|
finalized bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// Size returns the number of bytes Sum will return.
|
||||||
|
func (h *MAC) Size() int { return TagSize }
|
||||||
|
|
||||||
|
// Write adds more data to the running message authentication code.
|
||||||
|
// It never returns an error.
|
||||||
|
//
|
||||||
|
// It must not be called after the first call of Sum.
|
||||||
|
func (h *MAC) Write(p []byte) (n int, err error) {
|
||||||
|
if h.finalized {
|
||||||
|
panic("poly1305: write to MAC after Sum")
|
||||||
|
}
|
||||||
|
return h.mac.Write(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sum computes the authenticator of all data written to the
|
||||||
|
// message authentication code.
|
||||||
|
func (h *MAC) Sum(b []byte) []byte {
|
||||||
|
var mac [TagSize]byte
|
||||||
|
h.mac.Sum(&mac)
|
||||||
|
h.finalized = true
|
||||||
|
return append(b, mac[:]...)
|
||||||
|
}
|
||||||
|
|
|
@ -6,17 +6,63 @@
|
||||||
|
|
||||||
package poly1305
|
package poly1305
|
||||||
|
|
||||||
// This function is implemented in sum_amd64.s
|
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func poly1305(out *[16]byte, m *byte, mlen uint64, key *[32]byte)
|
func initialize(state *[7]uint64, key *[32]byte)
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func update(state *[7]uint64, msg []byte)
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func finalize(tag *[TagSize]byte, state *[7]uint64)
|
||||||
|
|
||||||
// Sum generates an authenticator for m using a one-time key and puts the
|
// Sum generates an authenticator for m using a one-time key and puts the
|
||||||
// 16-byte result into out. Authenticating two different messages with the same
|
// 16-byte result into out. Authenticating two different messages with the same
|
||||||
// key allows an attacker to forge messages at will.
|
// key allows an attacker to forge messages at will.
|
||||||
func Sum(out *[16]byte, m []byte, key *[32]byte) {
|
func Sum(out *[16]byte, m []byte, key *[32]byte) {
|
||||||
var mPtr *byte
|
h := newMAC(key)
|
||||||
if len(m) > 0 {
|
h.Write(m)
|
||||||
mPtr = &m[0]
|
h.Sum(out)
|
||||||
}
|
}
|
||||||
poly1305(out, mPtr, uint64(len(m)), key)
|
|
||||||
|
func newMAC(key *[32]byte) (h mac) {
|
||||||
|
initialize(&h.state, key)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type mac struct {
|
||||||
|
state [7]uint64 // := uint64{ h0, h1, h2, r0, r1, pad0, pad1 }
|
||||||
|
|
||||||
|
buffer [TagSize]byte
|
||||||
|
offset int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *mac) Write(p []byte) (n int, err error) {
|
||||||
|
n = len(p)
|
||||||
|
if h.offset > 0 {
|
||||||
|
remaining := TagSize - h.offset
|
||||||
|
if n < remaining {
|
||||||
|
h.offset += copy(h.buffer[h.offset:], p)
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
copy(h.buffer[h.offset:], p[:remaining])
|
||||||
|
p = p[remaining:]
|
||||||
|
h.offset = 0
|
||||||
|
update(&h.state, h.buffer[:])
|
||||||
|
}
|
||||||
|
if nn := len(p) - (len(p) % TagSize); nn > 0 {
|
||||||
|
update(&h.state, p[:nn])
|
||||||
|
p = p[nn:]
|
||||||
|
}
|
||||||
|
if len(p) > 0 {
|
||||||
|
h.offset += copy(h.buffer[h.offset:], p)
|
||||||
|
}
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *mac) Sum(out *[16]byte) {
|
||||||
|
state := h.state
|
||||||
|
if h.offset > 0 {
|
||||||
|
update(&state, h.buffer[:h.offset])
|
||||||
|
}
|
||||||
|
finalize(out, &state)
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,20 +58,17 @@ DATA ·poly1305Mask<>+0x00(SB)/8, $0x0FFFFFFC0FFFFFFF
|
||||||
DATA ·poly1305Mask<>+0x08(SB)/8, $0x0FFFFFFC0FFFFFFC
|
DATA ·poly1305Mask<>+0x08(SB)/8, $0x0FFFFFFC0FFFFFFC
|
||||||
GLOBL ·poly1305Mask<>(SB), RODATA, $16
|
GLOBL ·poly1305Mask<>(SB), RODATA, $16
|
||||||
|
|
||||||
// func poly1305(out *[16]byte, m *byte, mlen uint64, key *[32]key)
|
// func update(state *[7]uint64, msg []byte)
|
||||||
TEXT ·poly1305(SB), $0-32
|
TEXT ·update(SB), $0-32
|
||||||
MOVQ out+0(FP), DI
|
MOVQ state+0(FP), DI
|
||||||
MOVQ m+8(FP), SI
|
MOVQ msg_base+8(FP), SI
|
||||||
MOVQ mlen+16(FP), R15
|
MOVQ msg_len+16(FP), R15
|
||||||
MOVQ key+24(FP), AX
|
|
||||||
|
|
||||||
MOVQ 0(AX), R11
|
MOVQ 0(DI), R8 // h0
|
||||||
MOVQ 8(AX), R12
|
MOVQ 8(DI), R9 // h1
|
||||||
ANDQ ·poly1305Mask<>(SB), R11 // r0
|
MOVQ 16(DI), R10 // h2
|
||||||
ANDQ ·poly1305Mask<>+8(SB), R12 // r1
|
MOVQ 24(DI), R11 // r0
|
||||||
XORQ R8, R8 // h0
|
MOVQ 32(DI), R12 // r1
|
||||||
XORQ R9, R9 // h1
|
|
||||||
XORQ R10, R10 // h2
|
|
||||||
|
|
||||||
CMPQ R15, $16
|
CMPQ R15, $16
|
||||||
JB bytes_between_0_and_15
|
JB bytes_between_0_and_15
|
||||||
|
@ -109,16 +106,42 @@ flush_buffer:
|
||||||
JMP multiply
|
JMP multiply
|
||||||
|
|
||||||
done:
|
done:
|
||||||
MOVQ R8, AX
|
MOVQ R8, 0(DI)
|
||||||
MOVQ R9, BX
|
MOVQ R9, 8(DI)
|
||||||
|
MOVQ R10, 16(DI)
|
||||||
|
RET
|
||||||
|
|
||||||
|
// func initialize(state *[7]uint64, key *[32]byte)
|
||||||
|
TEXT ·initialize(SB), $0-16
|
||||||
|
MOVQ state+0(FP), DI
|
||||||
|
MOVQ key+8(FP), SI
|
||||||
|
|
||||||
|
// state[0...7] is initialized with zero
|
||||||
|
MOVOU 0(SI), X0
|
||||||
|
MOVOU 16(SI), X1
|
||||||
|
MOVOU ·poly1305Mask<>(SB), X2
|
||||||
|
PAND X2, X0
|
||||||
|
MOVOU X0, 24(DI)
|
||||||
|
MOVOU X1, 40(DI)
|
||||||
|
RET
|
||||||
|
|
||||||
|
// func finalize(tag *[TagSize]byte, state *[7]uint64)
|
||||||
|
TEXT ·finalize(SB), $0-16
|
||||||
|
MOVQ tag+0(FP), DI
|
||||||
|
MOVQ state+8(FP), SI
|
||||||
|
|
||||||
|
MOVQ 0(SI), AX
|
||||||
|
MOVQ 8(SI), BX
|
||||||
|
MOVQ 16(SI), CX
|
||||||
|
MOVQ AX, R8
|
||||||
|
MOVQ BX, R9
|
||||||
SUBQ $0xFFFFFFFFFFFFFFFB, AX
|
SUBQ $0xFFFFFFFFFFFFFFFB, AX
|
||||||
SBBQ $0xFFFFFFFFFFFFFFFF, BX
|
SBBQ $0xFFFFFFFFFFFFFFFF, BX
|
||||||
SBBQ $3, R10
|
SBBQ $3, CX
|
||||||
CMOVQCS R8, AX
|
CMOVQCS R8, AX
|
||||||
CMOVQCS R9, BX
|
CMOVQCS R9, BX
|
||||||
MOVQ key+24(FP), R8
|
ADDQ 40(SI), AX
|
||||||
ADDQ 16(R8), AX
|
ADCQ 48(SI), BX
|
||||||
ADCQ 24(R8), BX
|
|
||||||
|
|
||||||
MOVQ AX, 0(DI)
|
MOVQ AX, 0(DI)
|
||||||
MOVQ BX, 8(DI)
|
MOVQ BX, 8(DI)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2012 The Go Authors. All rights reserved.
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -6,21 +6,79 @@ package poly1305
|
||||||
|
|
||||||
import "encoding/binary"
|
import "encoding/binary"
|
||||||
|
|
||||||
|
const (
|
||||||
|
msgBlock = uint32(1 << 24)
|
||||||
|
finalBlock = uint32(0)
|
||||||
|
)
|
||||||
|
|
||||||
// sumGeneric generates an authenticator for msg using a one-time key and
|
// sumGeneric generates an authenticator for msg using a one-time key and
|
||||||
// puts the 16-byte result into out. This is the generic implementation of
|
// puts the 16-byte result into out. This is the generic implementation of
|
||||||
// Sum and should be called if no assembly implementation is available.
|
// Sum and should be called if no assembly implementation is available.
|
||||||
func sumGeneric(out *[TagSize]byte, msg []byte, key *[32]byte) {
|
func sumGeneric(out *[TagSize]byte, msg []byte, key *[32]byte) {
|
||||||
var (
|
h := newMACGeneric(key)
|
||||||
h0, h1, h2, h3, h4 uint32 // the hash accumulators
|
h.Write(msg)
|
||||||
r0, r1, r2, r3, r4 uint64 // the r part of the key
|
h.Sum(out)
|
||||||
)
|
}
|
||||||
|
|
||||||
r0 = uint64(binary.LittleEndian.Uint32(key[0:]) & 0x3ffffff)
|
func newMACGeneric(key *[32]byte) (h macGeneric) {
|
||||||
r1 = uint64((binary.LittleEndian.Uint32(key[3:]) >> 2) & 0x3ffff03)
|
h.r[0] = binary.LittleEndian.Uint32(key[0:]) & 0x3ffffff
|
||||||
r2 = uint64((binary.LittleEndian.Uint32(key[6:]) >> 4) & 0x3ffc0ff)
|
h.r[1] = (binary.LittleEndian.Uint32(key[3:]) >> 2) & 0x3ffff03
|
||||||
r3 = uint64((binary.LittleEndian.Uint32(key[9:]) >> 6) & 0x3f03fff)
|
h.r[2] = (binary.LittleEndian.Uint32(key[6:]) >> 4) & 0x3ffc0ff
|
||||||
r4 = uint64((binary.LittleEndian.Uint32(key[12:]) >> 8) & 0x00fffff)
|
h.r[3] = (binary.LittleEndian.Uint32(key[9:]) >> 6) & 0x3f03fff
|
||||||
|
h.r[4] = (binary.LittleEndian.Uint32(key[12:]) >> 8) & 0x00fffff
|
||||||
|
|
||||||
|
h.s[0] = binary.LittleEndian.Uint32(key[16:])
|
||||||
|
h.s[1] = binary.LittleEndian.Uint32(key[20:])
|
||||||
|
h.s[2] = binary.LittleEndian.Uint32(key[24:])
|
||||||
|
h.s[3] = binary.LittleEndian.Uint32(key[28:])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type macGeneric struct {
|
||||||
|
h, r [5]uint32
|
||||||
|
s [4]uint32
|
||||||
|
|
||||||
|
buffer [TagSize]byte
|
||||||
|
offset int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *macGeneric) Write(p []byte) (n int, err error) {
|
||||||
|
n = len(p)
|
||||||
|
if h.offset > 0 {
|
||||||
|
remaining := TagSize - h.offset
|
||||||
|
if n < remaining {
|
||||||
|
h.offset += copy(h.buffer[h.offset:], p)
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
copy(h.buffer[h.offset:], p[:remaining])
|
||||||
|
p = p[remaining:]
|
||||||
|
h.offset = 0
|
||||||
|
updateGeneric(h.buffer[:], msgBlock, &(h.h), &(h.r))
|
||||||
|
}
|
||||||
|
if nn := len(p) - (len(p) % TagSize); nn > 0 {
|
||||||
|
updateGeneric(p, msgBlock, &(h.h), &(h.r))
|
||||||
|
p = p[nn:]
|
||||||
|
}
|
||||||
|
if len(p) > 0 {
|
||||||
|
h.offset += copy(h.buffer[h.offset:], p)
|
||||||
|
}
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *macGeneric) Sum(out *[16]byte) {
|
||||||
|
H, R := h.h, h.r
|
||||||
|
if h.offset > 0 {
|
||||||
|
var buffer [TagSize]byte
|
||||||
|
copy(buffer[:], h.buffer[:h.offset])
|
||||||
|
buffer[h.offset] = 1 // invariant: h.offset < TagSize
|
||||||
|
updateGeneric(buffer[:], finalBlock, &H, &R)
|
||||||
|
}
|
||||||
|
finalizeGeneric(out, &H, &(h.s))
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateGeneric(msg []byte, flag uint32, h, r *[5]uint32) {
|
||||||
|
h0, h1, h2, h3, h4 := h[0], h[1], h[2], h[3], h[4]
|
||||||
|
r0, r1, r2, r3, r4 := uint64(r[0]), uint64(r[1]), uint64(r[2]), uint64(r[3]), uint64(r[4])
|
||||||
R1, R2, R3, R4 := r1*5, r2*5, r3*5, r4*5
|
R1, R2, R3, R4 := r1*5, r2*5, r3*5, r4*5
|
||||||
|
|
||||||
for len(msg) >= TagSize {
|
for len(msg) >= TagSize {
|
||||||
|
@ -29,7 +87,7 @@ func sumGeneric(out *[TagSize]byte, msg []byte, key *[32]byte) {
|
||||||
h1 += (binary.LittleEndian.Uint32(msg[3:]) >> 2) & 0x3ffffff
|
h1 += (binary.LittleEndian.Uint32(msg[3:]) >> 2) & 0x3ffffff
|
||||||
h2 += (binary.LittleEndian.Uint32(msg[6:]) >> 4) & 0x3ffffff
|
h2 += (binary.LittleEndian.Uint32(msg[6:]) >> 4) & 0x3ffffff
|
||||||
h3 += (binary.LittleEndian.Uint32(msg[9:]) >> 6) & 0x3ffffff
|
h3 += (binary.LittleEndian.Uint32(msg[9:]) >> 6) & 0x3ffffff
|
||||||
h4 += (binary.LittleEndian.Uint32(msg[12:]) >> 8) | (1 << 24)
|
h4 += (binary.LittleEndian.Uint32(msg[12:]) >> 8) | flag
|
||||||
|
|
||||||
// h *= r
|
// h *= r
|
||||||
d0 := (uint64(h0) * r0) + (uint64(h1) * R4) + (uint64(h2) * R3) + (uint64(h3) * R2) + (uint64(h4) * R1)
|
d0 := (uint64(h0) * r0) + (uint64(h1) * R4) + (uint64(h2) * R3) + (uint64(h3) * R2) + (uint64(h4) * R1)
|
||||||
|
@ -52,36 +110,11 @@ func sumGeneric(out *[TagSize]byte, msg []byte, key *[32]byte) {
|
||||||
msg = msg[TagSize:]
|
msg = msg[TagSize:]
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(msg) > 0 {
|
h[0], h[1], h[2], h[3], h[4] = h0, h1, h2, h3, h4
|
||||||
var block [TagSize]byte
|
}
|
||||||
off := copy(block[:], msg)
|
|
||||||
block[off] = 0x01
|
|
||||||
|
|
||||||
// h += msg
|
func finalizeGeneric(out *[TagSize]byte, h *[5]uint32, s *[4]uint32) {
|
||||||
h0 += binary.LittleEndian.Uint32(block[0:]) & 0x3ffffff
|
h0, h1, h2, h3, h4 := h[0], h[1], h[2], h[3], h[4]
|
||||||
h1 += (binary.LittleEndian.Uint32(block[3:]) >> 2) & 0x3ffffff
|
|
||||||
h2 += (binary.LittleEndian.Uint32(block[6:]) >> 4) & 0x3ffffff
|
|
||||||
h3 += (binary.LittleEndian.Uint32(block[9:]) >> 6) & 0x3ffffff
|
|
||||||
h4 += (binary.LittleEndian.Uint32(block[12:]) >> 8)
|
|
||||||
|
|
||||||
// h *= r
|
|
||||||
d0 := (uint64(h0) * r0) + (uint64(h1) * R4) + (uint64(h2) * R3) + (uint64(h3) * R2) + (uint64(h4) * R1)
|
|
||||||
d1 := (d0 >> 26) + (uint64(h0) * r1) + (uint64(h1) * r0) + (uint64(h2) * R4) + (uint64(h3) * R3) + (uint64(h4) * R2)
|
|
||||||
d2 := (d1 >> 26) + (uint64(h0) * r2) + (uint64(h1) * r1) + (uint64(h2) * r0) + (uint64(h3) * R4) + (uint64(h4) * R3)
|
|
||||||
d3 := (d2 >> 26) + (uint64(h0) * r3) + (uint64(h1) * r2) + (uint64(h2) * r1) + (uint64(h3) * r0) + (uint64(h4) * R4)
|
|
||||||
d4 := (d3 >> 26) + (uint64(h0) * r4) + (uint64(h1) * r3) + (uint64(h2) * r2) + (uint64(h3) * r1) + (uint64(h4) * r0)
|
|
||||||
|
|
||||||
// h %= p
|
|
||||||
h0 = uint32(d0) & 0x3ffffff
|
|
||||||
h1 = uint32(d1) & 0x3ffffff
|
|
||||||
h2 = uint32(d2) & 0x3ffffff
|
|
||||||
h3 = uint32(d3) & 0x3ffffff
|
|
||||||
h4 = uint32(d4) & 0x3ffffff
|
|
||||||
|
|
||||||
h0 += uint32(d4>>26) * 5
|
|
||||||
h1 += h0 >> 26
|
|
||||||
h0 = h0 & 0x3ffffff
|
|
||||||
}
|
|
||||||
|
|
||||||
// h %= p reduction
|
// h %= p reduction
|
||||||
h2 += h1 >> 26
|
h2 += h1 >> 26
|
||||||
|
@ -123,13 +156,13 @@ func sumGeneric(out *[TagSize]byte, msg []byte, key *[32]byte) {
|
||||||
|
|
||||||
// s: the s part of the key
|
// s: the s part of the key
|
||||||
// tag = (h + s) % (2^128)
|
// tag = (h + s) % (2^128)
|
||||||
t := uint64(h0) + uint64(binary.LittleEndian.Uint32(key[16:]))
|
t := uint64(h0) + uint64(s[0])
|
||||||
h0 = uint32(t)
|
h0 = uint32(t)
|
||||||
t = uint64(h1) + uint64(binary.LittleEndian.Uint32(key[20:])) + (t >> 32)
|
t = uint64(h1) + uint64(s[1]) + (t >> 32)
|
||||||
h1 = uint32(t)
|
h1 = uint32(t)
|
||||||
t = uint64(h2) + uint64(binary.LittleEndian.Uint32(key[24:])) + (t >> 32)
|
t = uint64(h2) + uint64(s[2]) + (t >> 32)
|
||||||
h2 = uint32(t)
|
h2 = uint32(t)
|
||||||
t = uint64(h3) + uint64(binary.LittleEndian.Uint32(key[28:])) + (t >> 32)
|
t = uint64(h3) + uint64(s[3]) + (t >> 32)
|
||||||
h3 = uint32(t)
|
h3 = uint32(t)
|
||||||
|
|
||||||
binary.LittleEndian.PutUint32(out[0:], h0)
|
binary.LittleEndian.PutUint32(out[0:], h0)
|
|
@ -10,5 +10,7 @@ package poly1305
|
||||||
// 16-byte result into out. Authenticating two different messages with the same
|
// 16-byte result into out. Authenticating two different messages with the same
|
||||||
// key allows an attacker to forge messages at will.
|
// key allows an attacker to forge messages at will.
|
||||||
func Sum(out *[TagSize]byte, msg []byte, key *[32]byte) {
|
func Sum(out *[TagSize]byte, msg []byte, key *[32]byte) {
|
||||||
sumGeneric(out, msg, key)
|
h := newMAC(key)
|
||||||
|
h.Write(msg)
|
||||||
|
h.Sum(out)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,16 +6,9 @@
|
||||||
|
|
||||||
package poly1305
|
package poly1305
|
||||||
|
|
||||||
// hasVectorFacility reports whether the machine supports
|
import (
|
||||||
// the vector facility (vx).
|
"golang.org/x/sys/cpu"
|
||||||
func hasVectorFacility() bool
|
)
|
||||||
|
|
||||||
// hasVMSLFacility reports whether the machine supports
|
|
||||||
// Vector Multiply Sum Logical (VMSL).
|
|
||||||
func hasVMSLFacility() bool
|
|
||||||
|
|
||||||
var hasVX = hasVectorFacility()
|
|
||||||
var hasVMSL = hasVMSLFacility()
|
|
||||||
|
|
||||||
// poly1305vx is an assembly implementation of Poly1305 that uses vector
|
// poly1305vx is an assembly implementation of Poly1305 that uses vector
|
||||||
// instructions. It must only be called if the vector facility (vx) is
|
// instructions. It must only be called if the vector facility (vx) is
|
||||||
|
@ -33,12 +26,12 @@ func poly1305vmsl(out *[16]byte, m *byte, mlen uint64, key *[32]byte)
|
||||||
// 16-byte result into out. Authenticating two different messages with the same
|
// 16-byte result into out. Authenticating two different messages with the same
|
||||||
// key allows an attacker to forge messages at will.
|
// key allows an attacker to forge messages at will.
|
||||||
func Sum(out *[16]byte, m []byte, key *[32]byte) {
|
func Sum(out *[16]byte, m []byte, key *[32]byte) {
|
||||||
if hasVX {
|
if cpu.S390X.HasVX {
|
||||||
var mPtr *byte
|
var mPtr *byte
|
||||||
if len(m) > 0 {
|
if len(m) > 0 {
|
||||||
mPtr = &m[0]
|
mPtr = &m[0]
|
||||||
}
|
}
|
||||||
if hasVMSL && len(m) > 256 {
|
if cpu.S390X.HasVXE && len(m) > 256 {
|
||||||
poly1305vmsl(out, mPtr, uint64(len(m)), key)
|
poly1305vmsl(out, mPtr, uint64(len(m)), key)
|
||||||
} else {
|
} else {
|
||||||
poly1305vx(out, mPtr, uint64(len(m)), key)
|
poly1305vx(out, mPtr, uint64(len(m)), key)
|
||||||
|
|
|
@ -376,25 +376,3 @@ b1:
|
||||||
|
|
||||||
MOVD $0, R3
|
MOVD $0, R3
|
||||||
BR multiply
|
BR multiply
|
||||||
|
|
||||||
TEXT ·hasVectorFacility(SB), NOSPLIT, $24-1
|
|
||||||
MOVD $x-24(SP), R1
|
|
||||||
XC $24, 0(R1), 0(R1) // clear the storage
|
|
||||||
MOVD $2, R0 // R0 is the number of double words stored -1
|
|
||||||
WORD $0xB2B01000 // STFLE 0(R1)
|
|
||||||
XOR R0, R0 // reset the value of R0
|
|
||||||
MOVBZ z-8(SP), R1
|
|
||||||
AND $0x40, R1
|
|
||||||
BEQ novector
|
|
||||||
|
|
||||||
vectorinstalled:
|
|
||||||
// check if the vector instruction has been enabled
|
|
||||||
VLEIB $0, $0xF, V16
|
|
||||||
VLGVB $0, V16, R1
|
|
||||||
CMPBNE R1, $0xF, novector
|
|
||||||
MOVB $1, ret+0(FP) // have vx
|
|
||||||
RET
|
|
||||||
|
|
||||||
novector:
|
|
||||||
MOVB $0, ret+0(FP) // no vx
|
|
||||||
RET
|
|
||||||
|
|
|
@ -907,25 +907,3 @@ square:
|
||||||
MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M2, M3, M4, M5, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9)
|
MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M2, M3, M4, M5, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9)
|
||||||
REDUCE2(H0_0, H1_0, H2_0, M0, M1, M2, M3, M4, T_9, T_10, H0_1, M5)
|
REDUCE2(H0_0, H1_0, H2_0, M0, M1, M2, M3, M4, T_9, T_10, H0_1, M5)
|
||||||
BR next
|
BR next
|
||||||
|
|
||||||
TEXT ·hasVMSLFacility(SB), NOSPLIT, $24-1
|
|
||||||
MOVD $x-24(SP), R1
|
|
||||||
XC $24, 0(R1), 0(R1) // clear the storage
|
|
||||||
MOVD $2, R0 // R0 is the number of double words stored -1
|
|
||||||
WORD $0xB2B01000 // STFLE 0(R1)
|
|
||||||
XOR R0, R0 // reset the value of R0
|
|
||||||
MOVBZ z-8(SP), R1
|
|
||||||
AND $0x01, R1
|
|
||||||
BEQ novmsl
|
|
||||||
|
|
||||||
vectorinstalled:
|
|
||||||
// check if the vector instruction has been enabled
|
|
||||||
VLEIB $0, $0xF, V16
|
|
||||||
VLGVB $0, V16, R1
|
|
||||||
CMPBNE R1, $0xF, novmsl
|
|
||||||
MOVB $1, ret+0(FP) // have vx
|
|
||||||
RET
|
|
||||||
|
|
||||||
novmsl:
|
|
||||||
MOVB $0, ret+0(FP) // no vx
|
|
||||||
RET
|
|
||||||
|
|
|
@ -643,7 +643,7 @@ func (f *Framer) WriteData(streamID uint32, endStream bool, data []byte) error {
|
||||||
return f.WriteDataPadded(streamID, endStream, data, nil)
|
return f.WriteDataPadded(streamID, endStream, data, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteData writes a DATA frame with optional padding.
|
// WriteDataPadded writes a DATA frame with optional padding.
|
||||||
//
|
//
|
||||||
// If pad is nil, the padding bit is not sent.
|
// If pad is nil, the padding bit is not sent.
|
||||||
// The length of pad must not exceed 255 bytes.
|
// The length of pad must not exceed 255 bytes.
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
// hostByteOrder returns binary.LittleEndian on little-endian machines and
|
||||||
|
// binary.BigEndian on big-endian machines.
|
||||||
|
func hostByteOrder() binary.ByteOrder {
|
||||||
|
switch runtime.GOARCH {
|
||||||
|
case "386", "amd64", "amd64p32",
|
||||||
|
"arm", "arm64",
|
||||||
|
"mipsle", "mips64le", "mips64p32le",
|
||||||
|
"ppc64le",
|
||||||
|
"riscv", "riscv64":
|
||||||
|
return binary.LittleEndian
|
||||||
|
case "armbe", "arm64be",
|
||||||
|
"mips", "mips64", "mips64p32",
|
||||||
|
"ppc", "ppc64",
|
||||||
|
"s390", "s390x",
|
||||||
|
"sparc", "sparc64":
|
||||||
|
return binary.BigEndian
|
||||||
|
}
|
||||||
|
panic("unknown architecture")
|
||||||
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package cpu implements processor feature detection for
|
||||||
|
// various CPU architectures.
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
// CacheLinePad is used to pad structs to avoid false sharing.
|
||||||
|
type CacheLinePad struct{ _ [cacheLineSize]byte }
|
||||||
|
|
||||||
|
// X86 contains the supported CPU features of the
|
||||||
|
// current X86/AMD64 platform. If the current platform
|
||||||
|
// is not X86/AMD64 then all feature flags are false.
|
||||||
|
//
|
||||||
|
// X86 is padded to avoid false sharing. Further the HasAVX
|
||||||
|
// and HasAVX2 are only set if the OS supports XMM and YMM
|
||||||
|
// registers in addition to the CPUID feature bit being set.
|
||||||
|
var X86 struct {
|
||||||
|
_ CacheLinePad
|
||||||
|
HasAES bool // AES hardware implementation (AES NI)
|
||||||
|
HasADX bool // Multi-precision add-carry instruction extensions
|
||||||
|
HasAVX bool // Advanced vector extension
|
||||||
|
HasAVX2 bool // Advanced vector extension 2
|
||||||
|
HasBMI1 bool // Bit manipulation instruction set 1
|
||||||
|
HasBMI2 bool // Bit manipulation instruction set 2
|
||||||
|
HasERMS bool // Enhanced REP for MOVSB and STOSB
|
||||||
|
HasFMA bool // Fused-multiply-add instructions
|
||||||
|
HasOSXSAVE bool // OS supports XSAVE/XRESTOR for saving/restoring XMM registers.
|
||||||
|
HasPCLMULQDQ bool // PCLMULQDQ instruction - most often used for AES-GCM
|
||||||
|
HasPOPCNT bool // Hamming weight instruction POPCNT.
|
||||||
|
HasRDRAND bool // RDRAND instruction (on-chip random number generator)
|
||||||
|
HasRDSEED bool // RDSEED instruction (on-chip random number generator)
|
||||||
|
HasSSE2 bool // Streaming SIMD extension 2 (always available on amd64)
|
||||||
|
HasSSE3 bool // Streaming SIMD extension 3
|
||||||
|
HasSSSE3 bool // Supplemental streaming SIMD extension 3
|
||||||
|
HasSSE41 bool // Streaming SIMD extension 4 and 4.1
|
||||||
|
HasSSE42 bool // Streaming SIMD extension 4 and 4.2
|
||||||
|
_ CacheLinePad
|
||||||
|
}
|
||||||
|
|
||||||
|
// ARM64 contains the supported CPU features of the
|
||||||
|
// current ARMv8(aarch64) platform. If the current platform
|
||||||
|
// is not arm64 then all feature flags are false.
|
||||||
|
var ARM64 struct {
|
||||||
|
_ CacheLinePad
|
||||||
|
HasFP bool // Floating-point instruction set (always available)
|
||||||
|
HasASIMD bool // Advanced SIMD (always available)
|
||||||
|
HasEVTSTRM bool // Event stream support
|
||||||
|
HasAES bool // AES hardware implementation
|
||||||
|
HasPMULL bool // Polynomial multiplication instruction set
|
||||||
|
HasSHA1 bool // SHA1 hardware implementation
|
||||||
|
HasSHA2 bool // SHA2 hardware implementation
|
||||||
|
HasCRC32 bool // CRC32 hardware implementation
|
||||||
|
HasATOMICS bool // Atomic memory operation instruction set
|
||||||
|
HasFPHP bool // Half precision floating-point instruction set
|
||||||
|
HasASIMDHP bool // Advanced SIMD half precision instruction set
|
||||||
|
HasCPUID bool // CPUID identification scheme registers
|
||||||
|
HasASIMDRDM bool // Rounding double multiply add/subtract instruction set
|
||||||
|
HasJSCVT bool // Javascript conversion from floating-point to integer
|
||||||
|
HasFCMA bool // Floating-point multiplication and addition of complex numbers
|
||||||
|
HasLRCPC bool // Release Consistent processor consistent support
|
||||||
|
HasDCPOP bool // Persistent memory support
|
||||||
|
HasSHA3 bool // SHA3 hardware implementation
|
||||||
|
HasSM3 bool // SM3 hardware implementation
|
||||||
|
HasSM4 bool // SM4 hardware implementation
|
||||||
|
HasASIMDDP bool // Advanced SIMD double precision instruction set
|
||||||
|
HasSHA512 bool // SHA512 hardware implementation
|
||||||
|
HasSVE bool // Scalable Vector Extensions
|
||||||
|
HasASIMDFHM bool // Advanced SIMD multiplication FP16 to FP32
|
||||||
|
_ CacheLinePad
|
||||||
|
}
|
||||||
|
|
||||||
|
// PPC64 contains the supported CPU features of the current ppc64/ppc64le platforms.
|
||||||
|
// If the current platform is not ppc64/ppc64le then all feature flags are false.
|
||||||
|
//
|
||||||
|
// For ppc64/ppc64le, it is safe to check only for ISA level starting on ISA v3.00,
|
||||||
|
// since there are no optional categories. There are some exceptions that also
|
||||||
|
// require kernel support to work (DARN, SCV), so there are feature bits for
|
||||||
|
// those as well. The minimum processor requirement is POWER8 (ISA 2.07).
|
||||||
|
// The struct is padded to avoid false sharing.
|
||||||
|
var PPC64 struct {
|
||||||
|
_ CacheLinePad
|
||||||
|
HasDARN bool // Hardware random number generator (requires kernel enablement)
|
||||||
|
HasSCV bool // Syscall vectored (requires kernel enablement)
|
||||||
|
IsPOWER8 bool // ISA v2.07 (POWER8)
|
||||||
|
IsPOWER9 bool // ISA v3.00 (POWER9)
|
||||||
|
_ CacheLinePad
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
const cacheLineSize = 32
|
||||||
|
|
||||||
|
func doinit() {}
|
|
@ -0,0 +1,16 @@
|
||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build 386 amd64 amd64p32
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
// cpuid is implemented in cpu_x86.s for gc compiler
|
||||||
|
// and in cpu_gccgo.c for gccgo.
|
||||||
|
func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32)
|
||||||
|
|
||||||
|
// xgetbv with ecx = 0 is implemented in cpu_x86.s for gc compiler
|
||||||
|
// and in cpu_gccgo.c for gccgo.
|
||||||
|
func xgetbv() (eax, edx uint32)
|
|
@ -0,0 +1,43 @@
|
||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build 386 amd64 amd64p32
|
||||||
|
// +build gccgo
|
||||||
|
|
||||||
|
#include <cpuid.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// Need to wrap __get_cpuid_count because it's declared as static.
|
||||||
|
int
|
||||||
|
gccgoGetCpuidCount(uint32_t leaf, uint32_t subleaf,
|
||||||
|
uint32_t *eax, uint32_t *ebx,
|
||||||
|
uint32_t *ecx, uint32_t *edx)
|
||||||
|
{
|
||||||
|
return __get_cpuid_count(leaf, subleaf, eax, ebx, ecx, edx);
|
||||||
|
}
|
||||||
|
|
||||||
|
// xgetbv reads the contents of an XCR (Extended Control Register)
|
||||||
|
// specified in the ECX register into registers EDX:EAX.
|
||||||
|
// Currently, the only supported value for XCR is 0.
|
||||||
|
//
|
||||||
|
// TODO: Replace with a better alternative:
|
||||||
|
//
|
||||||
|
// #include <xsaveintrin.h>
|
||||||
|
//
|
||||||
|
// #pragma GCC target("xsave")
|
||||||
|
//
|
||||||
|
// void gccgoXgetbv(uint32_t *eax, uint32_t *edx) {
|
||||||
|
// unsigned long long x = _xgetbv(0);
|
||||||
|
// *eax = x & 0xffffffff;
|
||||||
|
// *edx = (x >> 32) & 0xffffffff;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Note that _xgetbv is defined starting with GCC 8.
|
||||||
|
void
|
||||||
|
gccgoXgetbv(uint32_t *eax, uint32_t *edx)
|
||||||
|
{
|
||||||
|
__asm(" xorl %%ecx, %%ecx\n"
|
||||||
|
" xgetbv"
|
||||||
|
: "=a"(*eax), "=d"(*edx));
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build 386 amd64 amd64p32
|
||||||
|
// +build gccgo
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
//extern gccgoGetCpuidCount
|
||||||
|
func gccgoGetCpuidCount(eaxArg, ecxArg uint32, eax, ebx, ecx, edx *uint32)
|
||||||
|
|
||||||
|
func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32) {
|
||||||
|
var a, b, c, d uint32
|
||||||
|
gccgoGetCpuidCount(eaxArg, ecxArg, &a, &b, &c, &d)
|
||||||
|
return a, b, c, d
|
||||||
|
}
|
||||||
|
|
||||||
|
//extern gccgoXgetbv
|
||||||
|
func gccgoXgetbv(eax, edx *uint32)
|
||||||
|
|
||||||
|
func xgetbv() (eax, edx uint32) {
|
||||||
|
var a, d uint32
|
||||||
|
gccgoXgetbv(&a, &d)
|
||||||
|
return a, d
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//+build !amd64,!amd64p32,!386
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
_AT_HWCAP = 16
|
||||||
|
_AT_HWCAP2 = 26
|
||||||
|
|
||||||
|
procAuxv = "/proc/self/auxv"
|
||||||
|
|
||||||
|
uintSize = int(32 << (^uint(0) >> 63))
|
||||||
|
)
|
||||||
|
|
||||||
|
// For those platforms don't have a 'cpuid' equivalent we use HWCAP/HWCAP2
|
||||||
|
// These are initialized in cpu_$GOARCH.go
|
||||||
|
// and should not be changed after they are initialized.
|
||||||
|
var hwCap uint
|
||||||
|
var hwCap2 uint
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
buf, err := ioutil.ReadFile(procAuxv)
|
||||||
|
if err != nil {
|
||||||
|
panic("read proc auxv failed: " + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
bo := hostByteOrder()
|
||||||
|
for len(buf) >= 2*(uintSize/8) {
|
||||||
|
var tag, val uint
|
||||||
|
switch uintSize {
|
||||||
|
case 32:
|
||||||
|
tag = uint(bo.Uint32(buf[0:]))
|
||||||
|
val = uint(bo.Uint32(buf[4:]))
|
||||||
|
buf = buf[8:]
|
||||||
|
case 64:
|
||||||
|
tag = uint(bo.Uint64(buf[0:]))
|
||||||
|
val = uint(bo.Uint64(buf[8:]))
|
||||||
|
buf = buf[16:]
|
||||||
|
}
|
||||||
|
switch tag {
|
||||||
|
case _AT_HWCAP:
|
||||||
|
hwCap = val
|
||||||
|
case _AT_HWCAP2:
|
||||||
|
hwCap2 = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
doinit()
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
const cacheLineSize = 64
|
||||||
|
|
||||||
|
// HWCAP/HWCAP2 bits. These are exposed by Linux.
|
||||||
|
const (
|
||||||
|
hwcap_FP = 1 << 0
|
||||||
|
hwcap_ASIMD = 1 << 1
|
||||||
|
hwcap_EVTSTRM = 1 << 2
|
||||||
|
hwcap_AES = 1 << 3
|
||||||
|
hwcap_PMULL = 1 << 4
|
||||||
|
hwcap_SHA1 = 1 << 5
|
||||||
|
hwcap_SHA2 = 1 << 6
|
||||||
|
hwcap_CRC32 = 1 << 7
|
||||||
|
hwcap_ATOMICS = 1 << 8
|
||||||
|
hwcap_FPHP = 1 << 9
|
||||||
|
hwcap_ASIMDHP = 1 << 10
|
||||||
|
hwcap_CPUID = 1 << 11
|
||||||
|
hwcap_ASIMDRDM = 1 << 12
|
||||||
|
hwcap_JSCVT = 1 << 13
|
||||||
|
hwcap_FCMA = 1 << 14
|
||||||
|
hwcap_LRCPC = 1 << 15
|
||||||
|
hwcap_DCPOP = 1 << 16
|
||||||
|
hwcap_SHA3 = 1 << 17
|
||||||
|
hwcap_SM3 = 1 << 18
|
||||||
|
hwcap_SM4 = 1 << 19
|
||||||
|
hwcap_ASIMDDP = 1 << 20
|
||||||
|
hwcap_SHA512 = 1 << 21
|
||||||
|
hwcap_SVE = 1 << 22
|
||||||
|
hwcap_ASIMDFHM = 1 << 23
|
||||||
|
)
|
||||||
|
|
||||||
|
func doinit() {
|
||||||
|
// HWCAP feature bits
|
||||||
|
ARM64.HasFP = isSet(hwCap, hwcap_FP)
|
||||||
|
ARM64.HasASIMD = isSet(hwCap, hwcap_ASIMD)
|
||||||
|
ARM64.HasEVTSTRM = isSet(hwCap, hwcap_EVTSTRM)
|
||||||
|
ARM64.HasAES = isSet(hwCap, hwcap_AES)
|
||||||
|
ARM64.HasPMULL = isSet(hwCap, hwcap_PMULL)
|
||||||
|
ARM64.HasSHA1 = isSet(hwCap, hwcap_SHA1)
|
||||||
|
ARM64.HasSHA2 = isSet(hwCap, hwcap_SHA2)
|
||||||
|
ARM64.HasCRC32 = isSet(hwCap, hwcap_CRC32)
|
||||||
|
ARM64.HasATOMICS = isSet(hwCap, hwcap_ATOMICS)
|
||||||
|
ARM64.HasFPHP = isSet(hwCap, hwcap_FPHP)
|
||||||
|
ARM64.HasASIMDHP = isSet(hwCap, hwcap_ASIMDHP)
|
||||||
|
ARM64.HasCPUID = isSet(hwCap, hwcap_CPUID)
|
||||||
|
ARM64.HasASIMDRDM = isSet(hwCap, hwcap_ASIMDRDM)
|
||||||
|
ARM64.HasJSCVT = isSet(hwCap, hwcap_JSCVT)
|
||||||
|
ARM64.HasFCMA = isSet(hwCap, hwcap_FCMA)
|
||||||
|
ARM64.HasLRCPC = isSet(hwCap, hwcap_LRCPC)
|
||||||
|
ARM64.HasDCPOP = isSet(hwCap, hwcap_DCPOP)
|
||||||
|
ARM64.HasSHA3 = isSet(hwCap, hwcap_SHA3)
|
||||||
|
ARM64.HasSM3 = isSet(hwCap, hwcap_SM3)
|
||||||
|
ARM64.HasSM4 = isSet(hwCap, hwcap_SM4)
|
||||||
|
ARM64.HasASIMDDP = isSet(hwCap, hwcap_ASIMDDP)
|
||||||
|
ARM64.HasSHA512 = isSet(hwCap, hwcap_SHA512)
|
||||||
|
ARM64.HasSVE = isSet(hwCap, hwcap_SVE)
|
||||||
|
ARM64.HasASIMDFHM = isSet(hwCap, hwcap_ASIMDFHM)
|
||||||
|
}
|
||||||
|
|
||||||
|
func isSet(hwc uint, value uint) bool {
|
||||||
|
return hwc&value != 0
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build linux
|
||||||
|
// +build ppc64 ppc64le
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
const cacheLineSize = 128
|
||||||
|
|
||||||
|
// HWCAP/HWCAP2 bits. These are exposed by the kernel.
|
||||||
|
const (
|
||||||
|
// ISA Level
|
||||||
|
_PPC_FEATURE2_ARCH_2_07 = 0x80000000
|
||||||
|
_PPC_FEATURE2_ARCH_3_00 = 0x00800000
|
||||||
|
|
||||||
|
// CPU features
|
||||||
|
_PPC_FEATURE2_DARN = 0x00200000
|
||||||
|
_PPC_FEATURE2_SCV = 0x00100000
|
||||||
|
)
|
||||||
|
|
||||||
|
func doinit() {
|
||||||
|
// HWCAP2 feature bits
|
||||||
|
PPC64.IsPOWER8 = isSet(hwCap2, _PPC_FEATURE2_ARCH_2_07)
|
||||||
|
PPC64.IsPOWER9 = isSet(hwCap2, _PPC_FEATURE2_ARCH_3_00)
|
||||||
|
PPC64.HasDARN = isSet(hwCap2, _PPC_FEATURE2_DARN)
|
||||||
|
PPC64.HasSCV = isSet(hwCap2, _PPC_FEATURE2_SCV)
|
||||||
|
}
|
||||||
|
|
||||||
|
func isSet(hwc uint, value uint) bool {
|
||||||
|
return hwc&value != 0
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build mips64 mips64le
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
const cacheLineSize = 32
|
||||||
|
|
||||||
|
func doinit() {}
|
|
@ -0,0 +1,11 @@
|
||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build mips mipsle
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
const cacheLineSize = 32
|
||||||
|
|
||||||
|
func doinit() {}
|
|
@ -0,0 +1,11 @@
|
||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !linux,arm64
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
const cacheLineSize = 64
|
||||||
|
|
||||||
|
func doinit() {}
|
|
@ -0,0 +1,12 @@
|
||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !linux
|
||||||
|
// +build ppc64 ppc64le
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
const cacheLineSize = 128
|
||||||
|
|
||||||
|
func doinit() {}
|
|
@ -0,0 +1,9 @@
|
||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
const cacheLineSize = 256
|
||||||
|
|
||||||
|
func doinit() {}
|
|
@ -0,0 +1,57 @@
|
||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build 386 amd64 amd64p32
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
const cacheLineSize = 64
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
maxID, _, _, _ := cpuid(0, 0)
|
||||||
|
|
||||||
|
if maxID < 1 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _, ecx1, edx1 := cpuid(1, 0)
|
||||||
|
X86.HasSSE2 = isSet(26, edx1)
|
||||||
|
|
||||||
|
X86.HasSSE3 = isSet(0, ecx1)
|
||||||
|
X86.HasPCLMULQDQ = isSet(1, ecx1)
|
||||||
|
X86.HasSSSE3 = isSet(9, ecx1)
|
||||||
|
X86.HasFMA = isSet(12, ecx1)
|
||||||
|
X86.HasSSE41 = isSet(19, ecx1)
|
||||||
|
X86.HasSSE42 = isSet(20, ecx1)
|
||||||
|
X86.HasPOPCNT = isSet(23, ecx1)
|
||||||
|
X86.HasAES = isSet(25, ecx1)
|
||||||
|
X86.HasOSXSAVE = isSet(27, ecx1)
|
||||||
|
X86.HasRDRAND = isSet(30, ecx1)
|
||||||
|
|
||||||
|
osSupportsAVX := false
|
||||||
|
// For XGETBV, OSXSAVE bit is required and sufficient.
|
||||||
|
if X86.HasOSXSAVE {
|
||||||
|
eax, _ := xgetbv()
|
||||||
|
// Check if XMM and YMM registers have OS support.
|
||||||
|
osSupportsAVX = isSet(1, eax) && isSet(2, eax)
|
||||||
|
}
|
||||||
|
|
||||||
|
X86.HasAVX = isSet(28, ecx1) && osSupportsAVX
|
||||||
|
|
||||||
|
if maxID < 7 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, ebx7, _, _ := cpuid(7, 0)
|
||||||
|
X86.HasBMI1 = isSet(3, ebx7)
|
||||||
|
X86.HasAVX2 = isSet(5, ebx7) && osSupportsAVX
|
||||||
|
X86.HasBMI2 = isSet(8, ebx7)
|
||||||
|
X86.HasERMS = isSet(9, ebx7)
|
||||||
|
X86.HasRDSEED = isSet(18, ebx7)
|
||||||
|
X86.HasADX = isSet(19, ebx7)
|
||||||
|
}
|
||||||
|
|
||||||
|
func isSet(bitpos uint, value uint32) bool {
|
||||||
|
return value&(1<<bitpos) != 0
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build 386 amd64 amd64p32
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
// func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32)
|
||||||
|
TEXT ·cpuid(SB), NOSPLIT, $0-24
|
||||||
|
MOVL eaxArg+0(FP), AX
|
||||||
|
MOVL ecxArg+4(FP), CX
|
||||||
|
CPUID
|
||||||
|
MOVL AX, eax+8(FP)
|
||||||
|
MOVL BX, ebx+12(FP)
|
||||||
|
MOVL CX, ecx+16(FP)
|
||||||
|
MOVL DX, edx+20(FP)
|
||||||
|
RET
|
||||||
|
|
||||||
|
// func xgetbv() (eax, edx uint32)
|
||||||
|
TEXT ·xgetbv(SB),NOSPLIT,$0-8
|
||||||
|
MOVL $0, CX
|
||||||
|
XGETBV
|
||||||
|
MOVL AX, eax+0(FP)
|
||||||
|
MOVL DX, edx+4(FP)
|
||||||
|
RET
|
|
@ -458,7 +458,7 @@ go.opencensus.io/trace/propagation
|
||||||
go.opencensus.io
|
go.opencensus.io
|
||||||
go.opencensus.io/stats/internal
|
go.opencensus.io/stats/internal
|
||||||
go.opencensus.io/internal/tagencoding
|
go.opencensus.io/internal/tagencoding
|
||||||
# golang.org/x/crypto v0.0.0-20190228050851-31a38585487a
|
# golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2
|
||||||
golang.org/x/crypto/ssh
|
golang.org/x/crypto/ssh
|
||||||
golang.org/x/crypto/ssh/agent
|
golang.org/x/crypto/ssh/agent
|
||||||
golang.org/x/crypto/ssh/knownhosts
|
golang.org/x/crypto/ssh/knownhosts
|
||||||
|
@ -480,7 +480,7 @@ golang.org/x/crypto/internal/subtle
|
||||||
golang.org/x/crypto/md4
|
golang.org/x/crypto/md4
|
||||||
golang.org/x/crypto/cast5
|
golang.org/x/crypto/cast5
|
||||||
golang.org/x/crypto/openpgp/elgamal
|
golang.org/x/crypto/openpgp/elgamal
|
||||||
# golang.org/x/net v0.0.0-20190213061140-3a22650c66bd
|
# golang.org/x/net v0.0.0-20190311183353-d8887717615a
|
||||||
golang.org/x/net/context
|
golang.org/x/net/context
|
||||||
golang.org/x/net/idna
|
golang.org/x/net/idna
|
||||||
golang.org/x/net/trace
|
golang.org/x/net/trace
|
||||||
|
@ -500,6 +500,7 @@ golang.org/x/oauth2/jws
|
||||||
golang.org/x/oauth2/google
|
golang.org/x/oauth2/google
|
||||||
# golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223
|
# golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223
|
||||||
golang.org/x/sys/unix
|
golang.org/x/sys/unix
|
||||||
|
golang.org/x/sys/cpu
|
||||||
# golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2
|
# golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2
|
||||||
golang.org/x/text/unicode/norm
|
golang.org/x/text/unicode/norm
|
||||||
golang.org/x/text/transform
|
golang.org/x/text/transform
|
||||||
|
|
Loading…
Reference in New Issue