aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cmd/compile/internal/gc/reflect.go27
-rw-r--r--src/cmd/go/go_boring_test.go20
-rw-r--r--src/cmd/go/go_test.go12
-rw-r--r--src/cmd/go/internal/load/pkg.go6
-rw-r--r--src/cmd/link/internal/ld/lib.go1
-rw-r--r--src/crypto/aes/cipher.go5
-rw-r--r--src/crypto/aes/cipher_asm.go4
-rw-r--r--src/crypto/ecdsa/boring.go100
-rw-r--r--src/crypto/ecdsa/ecdsa.go45
-rw-r--r--src/crypto/hmac/hmac.go9
-rw-r--r--src/crypto/hmac/hmac_test.go62
-rw-r--r--src/crypto/internal/boring/LICENSE200
-rw-r--r--src/crypto/internal/boring/aes.go391
-rw-r--r--src/crypto/internal/boring/boring.go83
-rw-r--r--src/crypto/internal/boring/boring_test.go34
-rw-r--r--src/crypto/internal/boring/build/README6
-rwxr-xr-xsrc/crypto/internal/boring/build/build.sh64
-rwxr-xr-xsrc/crypto/internal/boring/build/build_in_chroot.sh198
-rwxr-xr-xsrc/crypto/internal/boring/build/root_setup_in_chroot.sh13
-rw-r--r--src/crypto/internal/boring/build/sources.list10
-rw-r--r--src/crypto/internal/boring/doc.go14
-rw-r--r--src/crypto/internal/boring/ecdsa.go201
-rw-r--r--src/crypto/internal/boring/fipstls/dummy.s10
-rw-r--r--src/crypto/internal/boring/fipstls/tls.go49
-rw-r--r--src/crypto/internal/boring/goboringcrypto.h237
-rw-r--r--src/crypto/internal/boring/goboringcrypto_linux_amd64.sysobin0 -> 9713384 bytes
-rw-r--r--src/crypto/internal/boring/hmac.go156
-rw-r--r--src/crypto/internal/boring/notboring.go109
-rw-r--r--src/crypto/internal/boring/rand.go27
-rw-r--r--src/crypto/internal/boring/rsa.go350
-rw-r--r--src/crypto/internal/boring/sha.go480
-rw-r--r--src/crypto/internal/boring/sig/sig.go17
-rw-r--r--src/crypto/internal/boring/sig/sig_amd64.s54
-rw-r--r--src/crypto/internal/boring/sig/sig_other.s19
-rw-r--r--src/crypto/issue21104_test.go2
-rw-r--r--src/crypto/rand/rand_unix.go8
-rw-r--r--src/crypto/rsa/boring.go124
-rw-r--r--src/crypto/rsa/boring_test.go125
-rw-r--r--src/crypto/rsa/pkcs1v15.go86
-rw-r--r--src/crypto/rsa/pkcs1v15_test.go2
-rw-r--r--src/crypto/rsa/pss.go35
-rw-r--r--src/crypto/rsa/pss_test.go3
-rw-r--r--src/crypto/rsa/rsa.go68
-rw-r--r--src/crypto/rsa/rsa_test.go87
-rw-r--r--src/crypto/sha1/boring.go22
-rw-r--r--src/crypto/sha1/notboring.go17
-rw-r--r--src/crypto/sha1/sha1.go12
-rw-r--r--src/crypto/sha1/sha1_test.go8
-rw-r--r--src/crypto/sha256/sha256.go24
-rw-r--r--src/crypto/sha256/sha256_test.go5
-rw-r--r--src/crypto/sha512/sha512.go28
-rw-r--r--src/crypto/sha512/sha512_test.go5
-rw-r--r--src/crypto/tls/auth.go3
-rw-r--r--src/crypto/tls/auth_test.go2
-rw-r--r--src/crypto/tls/boring.go132
-rw-r--r--src/crypto/tls/boring_test.go630
-rw-r--r--src/crypto/tls/cipher_suites.go23
-rw-r--r--src/crypto/tls/common.go16
-rw-r--r--src/crypto/tls/fipsonly/fipsonly.go27
-rw-r--r--src/crypto/tls/fipsonly/fipsonly_test.go16
-rw-r--r--src/crypto/tls/handshake_client.go7
-rw-r--r--src/crypto/tls/handshake_client_tls13.go6
-rw-r--r--src/crypto/tls/handshake_messages_test.go8
-rw-r--r--src/crypto/tls/handshake_server.go4
-rw-r--r--src/crypto/tls/handshake_server_tls13.go8
-rw-r--r--src/crypto/x509/verify.go12
-rw-r--r--src/go/build/deps_test.go29
-rw-r--r--src/internal/boringtest/boring.go8
-rw-r--r--src/internal/boringtest/boring_test.go47
-rw-r--r--src/runtime/race/testdata/mop_test.go4
-rw-r--r--src/runtime/runtime_boring.go19
71 files changed, 4614 insertions, 61 deletions
diff --git a/src/cmd/compile/internal/gc/reflect.go b/src/cmd/compile/internal/gc/reflect.go
index 2670baf999..cc3e182c34 100644
--- a/src/cmd/compile/internal/gc/reflect.go
+++ b/src/cmd/compile/internal/gc/reflect.go
@@ -1343,6 +1343,33 @@ func dtypesym(t *types.Type) *obj.LSym {
// for security, only the exported fields.
case TSTRUCT:
fields := t.Fields().Slice()
+
+ // omitFieldForAwfulBoringCryptoKludge reports whether
+ // the field t should be omitted from the reflect data.
+ // In the crypto/... packages we omit an unexported field
+ // named "boring", to keep from breaking client code that
+ // expects rsa.PublicKey etc to have only public fields.
+ // As the name suggests, this is an awful kludge, but it is
+ // limited to the dev.boringcrypto branch and avoids
+ // much more invasive effects elsewhere.
+ omitFieldForAwfulBoringCryptoKludge := func(t *types.Field) bool {
+ if t.Sym == nil || t.Sym.Name != "boring" || t.Sym.Pkg == nil {
+ return false
+ }
+ path := t.Sym.Pkg.Path
+ if t.Sym.Pkg == localpkg {
+ path = myimportpath
+ }
+ return strings.HasPrefix(path, "crypto/")
+ }
+ newFields := fields[:0:0]
+ for _, t1 := range fields {
+ if !omitFieldForAwfulBoringCryptoKludge(t1) {
+ newFields = append(newFields, t1)
+ }
+ }
+ fields = newFields
+
for _, t1 := range fields {
dtypesym(t1.Type)
}
diff --git a/src/cmd/go/go_boring_test.go b/src/cmd/go/go_boring_test.go
new file mode 100644
index 0000000000..0000497f06
--- /dev/null
+++ b/src/cmd/go/go_boring_test.go
@@ -0,0 +1,20 @@
+// Copyright 2015 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 main_test
+
+import "testing"
+
+func TestBoringInternalLink(t *testing.T) {
+ tg := testgo(t)
+ defer tg.cleanup()
+ tg.parallel()
+ tg.tempFile("main.go", `package main
+ import "crypto/sha1"
+ func main() {
+ sha1.New()
+ }`)
+ tg.run("build", "-ldflags=-w -extld=false", tg.path("main.go"))
+ tg.run("build", "-ldflags=-extld=false", tg.path("main.go"))
+}
diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go
index 3f790cdeab..955deafcfb 100644
--- a/src/cmd/go/go_test.go
+++ b/src/cmd/go/go_test.go
@@ -1845,8 +1845,12 @@ func TestBinaryOnlyPackages(t *testing.T) {
tg.grepStdout("p2: false", "p2 listed as BinaryOnly")
}
-// Issue 16050.
-func TestAlwaysLinkSysoFiles(t *testing.T) {
+// Issue 16050 and 21884.
+func TestLinkSysoFiles(t *testing.T) {
+ if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" {
+ t.Skip("not linux/amd64")
+ }
+
tg := testgo(t)
defer tg.cleanup()
tg.parallel()
@@ -1865,6 +1869,10 @@ func TestAlwaysLinkSysoFiles(t *testing.T) {
tg.setenv("CGO_ENABLED", "0")
tg.run("list", "-f", "{{.SysoFiles}}", "syso")
tg.grepStdout("a.syso", "missing syso file with CGO_ENABLED=0")
+
+ tg.setenv("CGO_ENABLED", "1")
+ tg.run("list", "-msan", "-f", "{{.SysoFiles}}", "syso")
+ tg.grepStdoutNot("a.syso", "unexpected syso file with -msan")
}
// Issue 16120.
diff --git a/src/cmd/go/internal/load/pkg.go b/src/cmd/go/internal/load/pkg.go
index 2b5fbb1c5b..ddbb3b9be0 100644
--- a/src/cmd/go/internal/load/pkg.go
+++ b/src/cmd/go/internal/load/pkg.go
@@ -351,6 +351,12 @@ func (p *Package) copyBuild(pp *build.Package) {
p.SwigFiles = pp.SwigFiles
p.SwigCXXFiles = pp.SwigCXXFiles
p.SysoFiles = pp.SysoFiles
+ if cfg.BuildMSan {
+ // There's no way for .syso files to be built both with and without
+ // support for memory sanitizer. Assume they are built without,
+ // and drop them.
+ p.SysoFiles = nil
+ }
p.CgoCFLAGS = pp.CgoCFLAGS
p.CgoCPPFLAGS = pp.CgoCPPFLAGS
p.CgoCXXFLAGS = pp.CgoCXXFLAGS
diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go
index 5fb1776e8c..703986828b 100644
--- a/src/cmd/link/internal/ld/lib.go
+++ b/src/cmd/link/internal/ld/lib.go
@@ -1130,6 +1130,7 @@ var hostobj []Hostobj
// These packages can use internal linking mode.
// Others trigger external mode.
var internalpkg = []string{
+ "crypto/internal/boring",
"crypto/x509",
"net",
"os/user",
diff --git a/src/crypto/aes/cipher.go b/src/crypto/aes/cipher.go
index bb93fbb36e..29d01796eb 100644
--- a/src/crypto/aes/cipher.go
+++ b/src/crypto/aes/cipher.go
@@ -10,6 +10,8 @@ import (
"strconv"
)
+import "crypto/internal/boring"
+
// The AES block size in bytes.
const BlockSize = 16
@@ -37,6 +39,9 @@ func NewCipher(key []byte) (cipher.Block, error) {
case 16, 24, 32:
break
}
+ if boring.Enabled {
+ return boring.NewAESCipher(key)
+ }
return newCipher(key)
}
diff --git a/src/crypto/aes/cipher_asm.go b/src/crypto/aes/cipher_asm.go
index 646bdfa5c0..4936699481 100644
--- a/src/crypto/aes/cipher_asm.go
+++ b/src/crypto/aes/cipher_asm.go
@@ -12,6 +12,8 @@ import (
"internal/cpu"
)
+import "crypto/internal/boring"
+
// defined in asm_*.s
//go:noescape
@@ -56,6 +58,7 @@ func newCipher(key []byte) (cipher.Block, error) {
func (c *aesCipherAsm) BlockSize() int { return BlockSize }
func (c *aesCipherAsm) Encrypt(dst, src []byte) {
+ boring.Unreachable()
if len(src) < BlockSize {
panic("crypto/aes: input not full block")
}
@@ -69,6 +72,7 @@ func (c *aesCipherAsm) Encrypt(dst, src []byte) {
}
func (c *aesCipherAsm) Decrypt(dst, src []byte) {
+ boring.Unreachable()
if len(src) < BlockSize {
panic("crypto/aes: input not full block")
}
diff --git a/src/crypto/ecdsa/boring.go b/src/crypto/ecdsa/boring.go
new file mode 100644
index 0000000000..fa15ecb850
--- /dev/null
+++ b/src/crypto/ecdsa/boring.go
@@ -0,0 +1,100 @@
+// Copyright 2017 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 ecdsa
+
+import (
+ "crypto/internal/boring"
+ "math/big"
+ "sync/atomic"
+ "unsafe"
+)
+
+// Cached conversions from Go PublicKey/PrivateKey to BoringCrypto.
+//
+// A new 'boring atomic.Value' field in both PublicKey and PrivateKey
+// serves as a cache for the most recent conversion. The cache is an
+// atomic.Value because code might reasonably set up a key and then
+// (thinking it immutable) use it from multiple goroutines simultaneously.
+// The first operation initializes the cache; if there are multiple simultaneous
+// first operations, they will do redundant work but not step on each other.
+//
+// We could just assume that once used in a Sign or Verify operation,
+// a particular key is never again modified, but that has not been a
+// stated assumption before. Just in case there is any existing code that
+// does modify the key between operations, we save the original values
+// alongside the cached BoringCrypto key and check that the real key
+// still matches before using the cached key. The theory is that the real
+// operations are significantly more expensive than the comparison.
+
+type boringPub struct {
+ key *boring.PublicKeyECDSA
+ orig PublicKey
+}
+
+func boringPublicKey(pub *PublicKey) (*boring.PublicKeyECDSA, error) {
+ b := (*boringPub)(atomic.LoadPointer(&pub.boring))
+ if b != nil && publicKeyEqual(&b.orig, pub) {
+ return b.key, nil
+ }
+
+ b = new(boringPub)
+ b.orig = copyPublicKey(pub)
+ key, err := boring.NewPublicKeyECDSA(b.orig.Curve.Params().Name, b.orig.X, b.orig.Y)
+ if err != nil {
+ return nil, err
+ }
+ b.key = key
+ atomic.StorePointer(&pub.boring, unsafe.Pointer(b))
+ return key, nil
+}
+
+type boringPriv struct {
+ key *boring.PrivateKeyECDSA
+ orig PrivateKey
+}
+
+func boringPrivateKey(priv *PrivateKey) (*boring.PrivateKeyECDSA, error) {
+ b := (*boringPriv)(atomic.LoadPointer(&priv.boring))
+ if b != nil && privateKeyEqual(&b.orig, priv) {
+ return b.key, nil
+ }
+
+ b = new(boringPriv)
+ b.orig = copyPrivateKey(priv)
+ key, err := boring.NewPrivateKeyECDSA(b.orig.Curve.Params().Name, b.orig.X, b.orig.Y, b.orig.D)
+ if err != nil {
+ return nil, err
+ }
+ b.key = key
+ atomic.StorePointer(&priv.boring, unsafe.Pointer(b))
+ return key, nil
+}
+
+func publicKeyEqual(k1, k2 *PublicKey) bool {
+ return k1.X != nil &&
+ k1.Curve.Params() == k2.Curve.Params() &&
+ k1.X.Cmp(k2.X) == 0 &&
+ k1.Y.Cmp(k2.Y) == 0
+}
+
+func privateKeyEqual(k1, k2 *PrivateKey) bool {
+ return publicKeyEqual(&k1.PublicKey, &k2.PublicKey) &&
+ k1.D.Cmp(k2.D) == 0
+}
+
+func copyPublicKey(k *PublicKey) PublicKey {
+ return PublicKey{
+ Curve: k.Curve,
+ X: new(big.Int).Set(k.X),
+ Y: new(big.Int).Set(k.Y),
+ }
+}
+
+func copyPrivateKey(k *PrivateKey) PrivateKey {
+ return PrivateKey{
+ PublicKey: copyPublicKey(&k.PublicKey),
+ D: new(big.Int).Set(k.D),
+ }
+}
diff --git a/src/crypto/ecdsa/ecdsa.go b/src/crypto/ecdsa/ecdsa.go
index ccce873859..04738cdbd7 100644
--- a/src/crypto/ecdsa/ecdsa.go
+++ b/src/crypto/ecdsa/ecdsa.go
@@ -41,6 +41,11 @@ import (
"golang.org/x/crypto/cryptobyte/asn1"
)
+import (
+ "crypto/internal/boring"
+ "unsafe"
+)
+
// A invertible implements fast inverse mod Curve.Params().N
type invertible interface {
// Inverse returns the inverse of k in GF(P)
@@ -60,6 +65,8 @@ const (
type PublicKey struct {
elliptic.Curve
X, Y *big.Int
+
+ boring unsafe.Pointer
}
// Any methods implemented on PublicKey might need to also be implemented on
@@ -87,6 +94,8 @@ func (pub *PublicKey) Equal(x crypto.PublicKey) bool {
type PrivateKey struct {
PublicKey
D *big.Int
+
+ boring unsafe.Pointer
}
// Public returns the public key corresponding to priv.
@@ -113,6 +122,15 @@ func (priv *PrivateKey) Equal(x crypto.PrivateKey) bool {
// where the private part is kept in, for example, a hardware module. Common
// uses should use the Sign function in this package directly.
func (priv *PrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) {
+ if boring.Enabled && rand == boring.RandReader {
+ b, err := boringPrivateKey(priv)
+ if err != nil {
+ return nil, err
+ }
+ return boring.SignMarshalECDSA(b, digest)
+ }
+ boring.UnreachableExceptTests()
+
r, s, err := Sign(rand, priv, digest)
if err != nil {
return nil, err
@@ -147,6 +165,15 @@ func randFieldElement(c elliptic.Curve, rand io.Reader) (k *big.Int, err error)
// GenerateKey generates a public and private key pair.
func GenerateKey(c elliptic.Curve, rand io.Reader) (*PrivateKey, error) {
+ if boring.Enabled && rand == boring.RandReader {
+ x, y, d, err := boring.GenerateKeyECDSA(c.Params().Name)
+ if err != nil {
+ return nil, err
+ }
+ return &PrivateKey{PublicKey: PublicKey{Curve: c, X: x, Y: y}, D: d}, nil
+ }
+ boring.UnreachableExceptTests()
+
k, err := randFieldElement(c, rand)
if err != nil {
return nil, err
@@ -200,6 +227,15 @@ var errZeroParam = errors.New("zero parameter")
func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error) {
randutil.MaybeReadByte(rand)
+ if boring.Enabled && rand == boring.RandReader {
+ b, err := boringPrivateKey(priv)
+ if err != nil {
+ return nil, nil, err
+ }
+ return boring.SignECDSA(b, hash)
+ }
+ boring.UnreachableExceptTests()
+
// Get min(log2(q) / 2, 256) bits of entropy from rand.
entropylen := (priv.Curve.Params().BitSize + 7) / 16
if entropylen > 32 {
@@ -289,6 +325,15 @@ func SignASN1(rand io.Reader, priv *PrivateKey, hash []byte) ([]byte, error) {
// Verify verifies the signature in r, s of hash using the public key, pub. Its
// return value records whether the signature is valid.
func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool {
+ if boring.Enabled {
+ b, err := boringPublicKey(pub)
+ if err != nil {
+ return false
+ }
+ return boring.VerifyECDSA(b, hash, r, s)