Skip to content

Commit

Permalink
initial implementation of macOS crypto backend
Browse files Browse the repository at this point in the history
  • Loading branch information
gdams committed Dec 20, 2024
1 parent 6460860 commit 1004e62
Show file tree
Hide file tree
Showing 9 changed files with 3,811 additions and 76 deletions.
1 change: 1 addition & 0 deletions eng/pipeline/stages/go-builder-matrix-stages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ stages:
- { os: linux, arch: amd64, config: test, distro: ubuntu }
- { os: linux, arch: amd64, config: test, distro: mariner2 }
- { os: linux, arch: amd64, config: test, distro: azurelinux3 }
- { experiment: darwincrypto, os: darwin, arch: amd64, config: test }
- { experiment: opensslcrypto, os: linux, arch: amd64, config: test }
- { experiment: opensslcrypto, os: linux, arch: amd64, config: test, fips: true }
- { experiment: opensslcrypto, os: linux, arch: amd64, config: test, distro: ubuntu }
Expand Down
62 changes: 43 additions & 19 deletions patches/0001-Add-systemcrypto-GOEXPERIMENT.patch
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,18 @@ information about the behavior.
Includes new tests in "build_test.go" and "buildbackend_test.go" to help
maintain this feature. For more information, see the test files.
---
src/cmd/go/internal/modindex/build.go | 54 ++++++++++++++
src/cmd/go/internal/modindex/build_test.go | 73 +++++++++++++++++++
src/go/build/build.go | 54 ++++++++++++++
src/go/build/buildbackend_test.go | 66 +++++++++++++++++
src/cmd/go/internal/modindex/build.go | 57 +++++++++++++
src/cmd/go/internal/modindex/build_test.go | 73 ++++++++++++++++
src/go/build/build.go | 57 +++++++++++++
src/go/build/buildbackend_test.go | 84 +++++++++++++++++++
.../testdata/backendtags_openssl/main.go | 3 +
.../testdata/backendtags_openssl/openssl.go | 3 +
.../build/testdata/backendtags_system/main.go | 3 +
.../backendtags_system/systemcrypto.go | 3 +
.../goexperiment/exp_systemcrypto_off.go | 9 +++
.../goexperiment/exp_systemcrypto_on.go | 9 +++
.../goexperiment/exp_systemcrypto_off.go | 9 ++
.../goexperiment/exp_systemcrypto_on.go | 9 ++
src/internal/goexperiment/flags.go | 15 ++++
11 files changed, 292 insertions(+)
11 files changed, 316 insertions(+)
create mode 100644 src/cmd/go/internal/modindex/build_test.go
create mode 100644 src/go/build/buildbackend_test.go
create mode 100644 src/go/build/testdata/backendtags_openssl/main.go
Expand All @@ -33,16 +33,17 @@ maintain this feature. For more information, see the test files.
create mode 100644 src/internal/goexperiment/exp_systemcrypto_on.go

diff --git a/src/cmd/go/internal/modindex/build.go b/src/cmd/go/internal/modindex/build.go
index b57f2f6368f0fe..9ddde1ce9a2286 100644
index b4dacb0f523a8d..4315c288d10cb3 100644
--- a/src/cmd/go/internal/modindex/build.go
+++ b/src/cmd/go/internal/modindex/build.go
@@ -880,13 +880,67 @@ func (ctxt *Context) matchTag(name string, allTags map[string]bool) bool {
@@ -886,13 +886,70 @@ func (ctxt *Context) matchTag(name string, allTags map[string]bool) bool {
name = "goexperiment.boringcrypto" // boringcrypto is an old name for goexperiment.boringcrypto
}

+ const system = "goexperiment.systemcrypto"
+ const openssl = "goexperiment.opensslcrypto"
+ const cng = "goexperiment.cngcrypto"
+ const darwin = "goexperiment.darwincrypto"
+ const boring = "goexperiment.boringcrypto"
+ // Implement the SystemCrypto GOEXPERIMENT logic. This is done here rather
+ // than during GOEXPERIMENT parsing so "-tags goexperiment.systemcrypto"
Expand All @@ -63,11 +64,12 @@ index b57f2f6368f0fe..9ddde1ce9a2286 100644
+ satisfiedByAnyBackend := name == system
+ satisfiedBySystemCrypto :=
+ (ctxt.GOOS == "linux" && name == openssl) ||
+ (ctxt.GOOS == "windows" && name == cng)
+ (ctxt.GOOS == "windows" && name == cng) ||
+ (ctxt.GOOS == "darwin" && name == darwin)
+ satisfiedBy := func(tag string) bool {
+ if satisfiedByAnyBackend {
+ switch tag {
+ case openssl, cng, boring:
+ case openssl, cng, darwin, boring:
+ return true
+ }
+ }
Expand All @@ -81,6 +83,7 @@ index b57f2f6368f0fe..9ddde1ce9a2286 100644
+ if satisfiedByAnyBackend {
+ allTags[openssl] = true
+ allTags[cng] = true
+ allTags[darwin] = true
+ allTags[boring] = true
+ }
+ if satisfiedBySystemCrypto {
Expand Down Expand Up @@ -184,16 +187,17 @@ index 00000000000000..1756c5d027fee0
+ }
+}
diff --git a/src/go/build/build.go b/src/go/build/build.go
index dd6cdc903a21a8..48adcfed5cf3cb 100644
index 9ffffda08a99b1..78fd536fa6a6d1 100644
--- a/src/go/build/build.go
+++ b/src/go/build/build.go
@@ -1947,13 +1947,67 @@ func (ctxt *Context) matchTag(name string, allTags map[string]bool) bool {
@@ -1984,13 +1984,70 @@ func (ctxt *Context) matchTag(name string, allTags map[string]bool) bool {
name = "goexperiment.boringcrypto" // boringcrypto is an old name for goexperiment.boringcrypto
}

+ const system = "goexperiment.systemcrypto"
+ const openssl = "goexperiment.opensslcrypto"
+ const cng = "goexperiment.cngcrypto"
+ const darwin = "goexperiment.darwincrypto"
+ const boring = "goexperiment.boringcrypto"
+ // Implement the SystemCrypto GOEXPERIMENT logic. This is done here rather
+ // than during GOEXPERIMENT parsing so "-tags goexperiment.systemcrypto"
Expand All @@ -214,11 +218,12 @@ index dd6cdc903a21a8..48adcfed5cf3cb 100644
+ satisfiedByAnyBackend := name == system
+ satisfiedBySystemCrypto :=
+ (ctxt.GOOS == "linux" && name == openssl) ||
+ (ctxt.GOOS == "windows" && name == cng)
+ (ctxt.GOOS == "windows" && name == cng) ||
+ (ctxt.GOOS == "darwin" && name == darwin)
+ satisfiedBy := func(tag string) bool {
+ if satisfiedByAnyBackend {
+ switch tag {
+ case openssl, cng, boring:
+ case openssl, cng, darwin, boring:
+ return true
+ }
+ }
Expand All @@ -232,6 +237,7 @@ index dd6cdc903a21a8..48adcfed5cf3cb 100644
+ if satisfiedByAnyBackend {
+ allTags[openssl] = true
+ allTags[cng] = true
+ allTags[darwin] = true
+ allTags[boring] = true
+ }
+ if satisfiedBySystemCrypto {
Expand All @@ -257,10 +263,10 @@ index dd6cdc903a21a8..48adcfed5cf3cb 100644
}
diff --git a/src/go/build/buildbackend_test.go b/src/go/build/buildbackend_test.go
new file mode 100644
index 00000000000000..a22abbb42e37c0
index 00000000000000..096b9b4566667c
--- /dev/null
+++ b/src/go/build/buildbackend_test.go
@@ -0,0 +1,66 @@
@@ -0,0 +1,84 @@
+// Copyright 2023 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.
Expand Down Expand Up @@ -326,6 +332,24 @@ index 00000000000000..a22abbb42e37c0
+ if !reflect.DeepEqual(p.GoFiles, wantFiles) {
+ t.Errorf("GoFiles = %v, want %v", p.GoFiles, wantFiles)
+ }
+
+ ctxt.GOARCH = "amd64"
+ ctxt.GOOS = "darwin"
+ ctxt.BuildTags = []string{"goexperiment.darwincrypto"}
+ p, err = ctxt.ImportDir("testdata/backendtags_openssl", 0)
+ if err != nil {
+ t.Fatal(err)
+ }
+ // Given the current GOOS (darwin), systemcrypto would not affect the
+ // decision, so we don't want it to be included in AllTags.
+ want = []string{"goexperiment.opensslcrypto"}
+ if !reflect.DeepEqual(p.AllTags, want) {
+ t.Errorf("AllTags = %v, want %v", p.AllTags, want)
+ }
+ wantFiles = []string{"main.go"}
+ if !reflect.DeepEqual(p.GoFiles, wantFiles) {
+ t.Errorf("GoFiles = %v, want %v", p.GoFiles, wantFiles)
+ }
+}
diff --git a/src/go/build/testdata/backendtags_openssl/main.go b/src/go/build/testdata/backendtags_openssl/main.go
new file mode 100644
Expand Down Expand Up @@ -394,14 +418,14 @@ index 00000000000000..9c5b0bbc7b99dc
+const SystemCrypto = true
+const SystemCryptoInt = 1
diff --git a/src/internal/goexperiment/flags.go b/src/internal/goexperiment/flags.go
index ae3cbaf89fa5dd..de79140b2d4780 100644
index 31b3d0315b64f8..de1dfa6e567a71 100644
--- a/src/internal/goexperiment/flags.go
+++ b/src/internal/goexperiment/flags.go
@@ -60,6 +60,21 @@ type Flags struct {
StaticLockRanking bool
BoringCrypto bool

+ // SystemCrypto enables the OpenSSL or CNG crypto experiment depending on
+ // SystemCrypto enables the OpenSSL, CNG or Darwin crypto experiment depending on
+ // which one is appropriate on the target GOOS.
+ //
+ // If SystemCrypto is enabled but no crypto experiment is appropriate on the
Expand Down
48 changes: 31 additions & 17 deletions patches/0002-Add-crypto-backend-foundation.patch
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,15 @@ Subject: [PATCH] Add crypto backend foundation
src/crypto/tls/handshake_server_tls13.go | 10 +
src/crypto/tls/internal/fips140tls/fipstls.go | 3 +-
src/crypto/tls/prf.go | 41 ++++
src/go/build/buildbackend_test.go | 2 +-
src/go/build/deps_test.go | 8 +-
src/hash/boring_test.go | 9 +
src/hash/example_test.go | 2 +
src/hash/marshal_test.go | 5 +
src/hash/notboring_test.go | 9 +
src/net/smtp/smtp_test.go | 72 ++++--
src/runtime/runtime_boring.go | 5 +
71 files changed, 1159 insertions(+), 80 deletions(-)
72 files changed, 1160 insertions(+), 81 deletions(-)
create mode 100644 src/crypto/dsa/boring.go
create mode 100644 src/crypto/dsa/notboring.go
create mode 100644 src/crypto/ed25519/boring.go
Expand Down Expand Up @@ -618,11 +619,11 @@ index 00000000000000..3a7d7b76c8d8d7
+}
+
+type boringPub struct {
+ key *boring.PublicKeyEd25519
+ key boring.PublicKeyEd25519
+ orig [PublicKeySize]byte
+}
+
+func boringPublicKey(pub PublicKey) (*boring.PublicKeyEd25519, error) {
+func boringPublicKey(pub PublicKey) (boring.PublicKeyEd25519, error) {
+ // Use the pointer to the underlying pub array as key.
+ p := unsafe.SliceData(pub)
+ b := pubCache.Get(p)
Expand All @@ -634,19 +635,19 @@ index 00000000000000..3a7d7b76c8d8d7
+ copy(b.orig[:], pub)
+ key, err := boring.NewPublicKeyEd25119(b.orig[:])
+ if err != nil {
+ return nil, err
+ return key, err
+ }
+ b.key = key
+ pubCache.Put(p, b)
+ return key, nil
+}
+
+type boringPriv struct {
+ key *boring.PrivateKeyEd25519
+ key boring.PrivateKeyEd25519
+ orig [PrivateKeySize]byte
+}
+
+func boringPrivateKey(priv PrivateKey) (*boring.PrivateKeyEd25519, error) {
+func boringPrivateKey(priv PrivateKey) (boring.PrivateKeyEd25519, error) {
+ // Use the pointer to the underlying priv array as key.
+ p := unsafe.SliceData(priv)
+ b := privCache.Get(p)
Expand All @@ -658,7 +659,7 @@ index 00000000000000..3a7d7b76c8d8d7
+ copy(b.orig[:], priv)
+ key, err := boring.NewPrivateKeyEd25119(b.orig[:])
+ if err != nil {
+ return nil, err
+ return key, err
+ }
+ b.key = key
+ privCache.Put(p, b)
Expand Down Expand Up @@ -806,10 +807,10 @@ index 00000000000000..b0cdd44d81c753
+
+import boring "crypto/internal/backend"
+
+func boringPublicKey(PublicKey) (*boring.PublicKeyEd25519, error) {
+func boringPublicKey(PublicKey) (boring.PublicKeyEd25519, error) {
+ panic("boringcrypto: not available")
+}
+func boringPrivateKey(PrivateKey) (*boring.PrivateKeyEd25519, error) {
+func boringPrivateKey(PrivateKey) (boring.PrivateKeyEd25519, error) {
+ panic("boringcrypto: not available")
+}
diff --git a/src/crypto/hkdf/hkdf.go b/src/crypto/hkdf/hkdf.go
Expand Down Expand Up @@ -1316,37 +1317,37 @@ index 00000000000000..71e0ec9dc25a02
+
+type PublicKeyEd25519 struct{}
+
+func (k *PublicKeyEd25519) Bytes() ([]byte, error) {
+func (k PublicKeyEd25519) Bytes() ([]byte, error) {
+ panic("cryptobackend: not available")
+}
+
+type PrivateKeyEd25519 struct{}
+
+func (k *PrivateKeyEd25519) Bytes() ([]byte, error) {
+func (k PrivateKeyEd25519) Bytes() ([]byte, error) {
+ panic("cryptobackend: not available")
+}
+
+func GenerateKeyEd25519() (*PrivateKeyEd25519, error) {
+func GenerateKeyEd25519() (PrivateKeyEd25519, error) {
+ panic("cryptobackend: not available")
+}
+
+func NewPrivateKeyEd25119(priv []byte) (*PrivateKeyEd25519, error) {
+func NewPrivateKeyEd25119(priv []byte) (PrivateKeyEd25519, error) {
+ panic("cryptobackend: not available")
+}
+
+func NewPublicKeyEd25119(pub []byte) (*PublicKeyEd25519, error) {
+func NewPublicKeyEd25119(pub []byte) (PublicKeyEd25519, error) {
+ panic("cryptobackend: not available")
+}
+
+func NewPrivateKeyEd25519FromSeed(seed []byte) (*PrivateKeyEd25519, error) {
+func NewPrivateKeyEd25519FromSeed(seed []byte) (PrivateKeyEd25519, error) {
+ panic("cryptobackend: not available")
+}
+
+func SignEd25519(priv *PrivateKeyEd25519, message []byte) ([]byte, error) {
+func SignEd25519(priv PrivateKeyEd25519, message []byte) ([]byte, error) {
+ panic("cryptobackend: not available")
+}
+
+func VerifyEd25519(pub *PublicKeyEd25519, message, sig []byte) error {
+func VerifyEd25519(pub PublicKeyEd25519, message, sig []byte) error {
+ panic("cryptobackend: not available")
+}
+
Expand Down Expand Up @@ -2242,6 +2243,19 @@ index e7369542a73270..ff52175e4ac636 100644
return tls12.PRF(hashFunc, secret, label, seed, keyLen)
}
}
diff --git a/src/go/build/buildbackend_test.go b/src/go/build/buildbackend_test.go
index 096b9b4566667c..aa3c5f1007ed79 100644
--- a/src/go/build/buildbackend_test.go
+++ b/src/go/build/buildbackend_test.go
@@ -55,7 +55,7 @@ func TestCryptoBackendAllTags(t *testing.T) {
if err != nil {
t.Fatal(err)
}
- want = []string{"goexperiment.boringcrypto", "goexperiment.cngcrypto", "goexperiment.opensslcrypto", "goexperiment.systemcrypto"}
+ want = []string{"goexperiment.boringcrypto", "goexperiment.cngcrypto", "goexperiment.darwincrypto", "goexperiment.opensslcrypto", "goexperiment.systemcrypto"}
if !reflect.DeepEqual(p.AllTags, want) {
t.Errorf("AllTags = %v, want %v", p.AllTags, want)
}
diff --git a/src/go/build/deps_test.go b/src/go/build/deps_test.go
index cc7f4df7f388ea..58082b3636f209 100644
--- a/src/go/build/deps_test.go
Expand Down
16 changes: 8 additions & 8 deletions patches/0003-Add-BoringSSL-crypto-backend.patch
Original file line number Diff line number Diff line change
Expand Up @@ -235,37 +235,37 @@ index 00000000000000..b1bd6d5ba756d7
+
+type PublicKeyEd25519 struct{}
+
+func (k *PublicKeyEd25519) Bytes() ([]byte, error) {
+func (k PublicKeyEd25519) Bytes() ([]byte, error) {
+ panic("cryptobackend: not available")
+}
+
+type PrivateKeyEd25519 struct{}
+
+func (k *PrivateKeyEd25519) Bytes() ([]byte, error) {
+func (k PrivateKeyEd25519) Bytes() ([]byte, error) {
+ panic("cryptobackend: not available")
+}
+
+func GenerateKeyEd25519() (*PrivateKeyEd25519, error) {
+func GenerateKeyEd25519() (PrivateKeyEd25519, error) {
+ panic("cryptobackend: not available")
+}
+
+func NewPrivateKeyEd25119(priv []byte) (*PrivateKeyEd25519, error) {
+func NewPrivateKeyEd25119(priv []byte) (PrivateKeyEd25519, error) {
+ panic("cryptobackend: not available")
+}
+
+func NewPublicKeyEd25119(pub []byte) (*PublicKeyEd25519, error) {
+func NewPublicKeyEd25119(pub []byte) (PublicKeyEd25519, error) {
+ panic("cryptobackend: not available")
+}
+
+func NewPrivateKeyEd25519FromSeed(seed []byte) (*PrivateKeyEd25519, error) {
+func NewPrivateKeyEd25519FromSeed(seed []byte) (PrivateKeyEd25519, error) {
+ panic("cryptobackend: not available")
+}
+
+func SignEd25519(priv *PrivateKeyEd25519, message []byte) ([]byte, error) {
+func SignEd25519(priv PrivateKeyEd25519, message []byte) ([]byte, error) {
+ panic("cryptobackend: not available")
+}
+
+func VerifyEd25519(pub *PublicKeyEd25519, message, sig []byte) error {
+func VerifyEd25519(pub PublicKeyEd25519, message, sig []byte) error {
+ panic("cryptobackend: not available")
+}
+
Expand Down
Loading

0 comments on commit 1004e62

Please sign in to comment.