Skip to content

Commit f092c70

Browse files
committed
initial implementation of macOS crypto backend
1 parent 760f97d commit f092c70

10 files changed

+3794
-76
lines changed

eng/_util/buildutil/buildutil.go

+1
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ func AppendExperimentEnv(experiment string) {
9191
if strings.Contains(experiment, "opensslcrypto") ||
9292
strings.Contains(experiment, "cngcrypto") ||
9393
strings.Contains(experiment, "boringcrypto") ||
94+
strings.Contains(experiment, "darwincrypto") ||
9495
strings.Contains(experiment, "systemcrypto") {
9596

9697
experiment += ",allowcryptofallback"

eng/pipeline/stages/go-builder-matrix-stages.yml

+1
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ stages:
8686
- { os: linux, arch: amd64, config: test, distro: ubuntu }
8787
- { os: linux, arch: amd64, config: test, distro: mariner2 }
8888
- { os: linux, arch: amd64, config: test, distro: azurelinux3 }
89+
- { experiment: darwincrypto, os: darwin, arch: amd64, config: test }
8990
- { experiment: opensslcrypto, os: linux, arch: amd64, config: test }
9091
- { experiment: opensslcrypto, os: linux, arch: amd64, config: test, fips: true }
9192
- { experiment: opensslcrypto, os: linux, arch: amd64, config: test, distro: ubuntu }

patches/0001-Add-systemcrypto-GOEXPERIMENT.patch

+43-19
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,18 @@ information about the behavior.
1111
Includes new tests in "build_test.go" and "buildbackend_test.go" to help
1212
maintain this feature. For more information, see the test files.
1313
---
14-
src/cmd/go/internal/modindex/build.go | 54 ++++++++++++++
15-
src/cmd/go/internal/modindex/build_test.go | 73 +++++++++++++++++++
16-
src/go/build/build.go | 54 ++++++++++++++
17-
src/go/build/buildbackend_test.go | 66 +++++++++++++++++
14+
src/cmd/go/internal/modindex/build.go | 57 +++++++++++++
15+
src/cmd/go/internal/modindex/build_test.go | 73 ++++++++++++++++
16+
src/go/build/build.go | 57 +++++++++++++
17+
src/go/build/buildbackend_test.go | 84 +++++++++++++++++++
1818
.../testdata/backendtags_openssl/main.go | 3 +
1919
.../testdata/backendtags_openssl/openssl.go | 3 +
2020
.../build/testdata/backendtags_system/main.go | 3 +
2121
.../backendtags_system/systemcrypto.go | 3 +
22-
.../goexperiment/exp_systemcrypto_off.go | 9 +++
23-
.../goexperiment/exp_systemcrypto_on.go | 9 +++
22+
.../goexperiment/exp_systemcrypto_off.go | 9 ++
23+
.../goexperiment/exp_systemcrypto_on.go | 9 ++
2424
src/internal/goexperiment/flags.go | 15 ++++
25-
11 files changed, 292 insertions(+)
25+
11 files changed, 316 insertions(+)
2626
create mode 100644 src/cmd/go/internal/modindex/build_test.go
2727
create mode 100644 src/go/build/buildbackend_test.go
2828
create mode 100644 src/go/build/testdata/backendtags_openssl/main.go
@@ -33,16 +33,17 @@ maintain this feature. For more information, see the test files.
3333
create mode 100644 src/internal/goexperiment/exp_systemcrypto_on.go
3434

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

4343
+ const system = "goexperiment.systemcrypto"
4444
+ const openssl = "goexperiment.opensslcrypto"
4545
+ const cng = "goexperiment.cngcrypto"
46+
+ const darwin = "goexperiment.darwincrypto"
4647
+ const boring = "goexperiment.boringcrypto"
4748
+ // Implement the SystemCrypto GOEXPERIMENT logic. This is done here rather
4849
+ // than during GOEXPERIMENT parsing so "-tags goexperiment.systemcrypto"
@@ -63,11 +64,12 @@ index b57f2f6368f0fe..9ddde1ce9a2286 100644
6364
+ satisfiedByAnyBackend := name == system
6465
+ satisfiedBySystemCrypto :=
6566
+ (ctxt.GOOS == "linux" && name == openssl) ||
66-
+ (ctxt.GOOS == "windows" && name == cng)
67+
+ (ctxt.GOOS == "windows" && name == cng) ||
68+
+ (ctxt.GOOS == "darwin" && name == darwin)
6769
+ satisfiedBy := func(tag string) bool {
6870
+ if satisfiedByAnyBackend {
6971
+ switch tag {
70-
+ case openssl, cng, boring:
72+
+ case openssl, cng, darwin, boring:
7173
+ return true
7274
+ }
7375
+ }
@@ -81,6 +83,7 @@ index b57f2f6368f0fe..9ddde1ce9a2286 100644
8183
+ if satisfiedByAnyBackend {
8284
+ allTags[openssl] = true
8385
+ allTags[cng] = true
86+
+ allTags[darwin] = true
8487
+ allTags[boring] = true
8588
+ }
8689
+ if satisfiedBySystemCrypto {
@@ -184,16 +187,17 @@ index 00000000000000..1756c5d027fee0
184187
+ }
185188
+}
186189
diff --git a/src/go/build/build.go b/src/go/build/build.go
187-
index dd6cdc903a21a8..48adcfed5cf3cb 100644
190+
index 9ffffda08a99b1..78fd536fa6a6d1 100644
188191
--- a/src/go/build/build.go
189192
+++ b/src/go/build/build.go
190-
@@ -1947,13 +1947,67 @@ func (ctxt *Context) matchTag(name string, allTags map[string]bool) bool {
193+
@@ -1984,13 +1984,70 @@ func (ctxt *Context) matchTag(name string, allTags map[string]bool) bool {
191194
name = "goexperiment.boringcrypto" // boringcrypto is an old name for goexperiment.boringcrypto
192195
}
193196

194197
+ const system = "goexperiment.systemcrypto"
195198
+ const openssl = "goexperiment.opensslcrypto"
196199
+ const cng = "goexperiment.cngcrypto"
200+
+ const darwin = "goexperiment.darwincrypto"
197201
+ const boring = "goexperiment.boringcrypto"
198202
+ // Implement the SystemCrypto GOEXPERIMENT logic. This is done here rather
199203
+ // than during GOEXPERIMENT parsing so "-tags goexperiment.systemcrypto"
@@ -214,11 +218,12 @@ index dd6cdc903a21a8..48adcfed5cf3cb 100644
214218
+ satisfiedByAnyBackend := name == system
215219
+ satisfiedBySystemCrypto :=
216220
+ (ctxt.GOOS == "linux" && name == openssl) ||
217-
+ (ctxt.GOOS == "windows" && name == cng)
221+
+ (ctxt.GOOS == "windows" && name == cng) ||
222+
+ (ctxt.GOOS == "darwin" && name == darwin)
218223
+ satisfiedBy := func(tag string) bool {
219224
+ if satisfiedByAnyBackend {
220225
+ switch tag {
221-
+ case openssl, cng, boring:
226+
+ case openssl, cng, darwin, boring:
222227
+ return true
223228
+ }
224229
+ }
@@ -232,6 +237,7 @@ index dd6cdc903a21a8..48adcfed5cf3cb 100644
232237
+ if satisfiedByAnyBackend {
233238
+ allTags[openssl] = true
234239
+ allTags[cng] = true
240+
+ allTags[darwin] = true
235241
+ allTags[boring] = true
236242
+ }
237243
+ if satisfiedBySystemCrypto {
@@ -257,10 +263,10 @@ index dd6cdc903a21a8..48adcfed5cf3cb 100644
257263
}
258264
diff --git a/src/go/build/buildbackend_test.go b/src/go/build/buildbackend_test.go
259265
new file mode 100644
260-
index 00000000000000..a22abbb42e37c0
266+
index 00000000000000..096b9b4566667c
261267
--- /dev/null
262268
+++ b/src/go/build/buildbackend_test.go
263-
@@ -0,0 +1,66 @@
269+
@@ -0,0 +1,84 @@
264270
+// Copyright 2023 The Go Authors. All rights reserved.
265271
+// Use of this source code is governed by a BSD-style
266272
+// license that can be found in the LICENSE file.
@@ -326,6 +332,24 @@ index 00000000000000..a22abbb42e37c0
326332
+ if !reflect.DeepEqual(p.GoFiles, wantFiles) {
327333
+ t.Errorf("GoFiles = %v, want %v", p.GoFiles, wantFiles)
328334
+ }
335+
+
336+
+ ctxt.GOARCH = "amd64"
337+
+ ctxt.GOOS = "darwin"
338+
+ ctxt.BuildTags = []string{"goexperiment.darwincrypto"}
339+
+ p, err = ctxt.ImportDir("testdata/backendtags_openssl", 0)
340+
+ if err != nil {
341+
+ t.Fatal(err)
342+
+ }
343+
+ // Given the current GOOS (darwin), systemcrypto would not affect the
344+
+ // decision, so we don't want it to be included in AllTags.
345+
+ want = []string{"goexperiment.opensslcrypto"}
346+
+ if !reflect.DeepEqual(p.AllTags, want) {
347+
+ t.Errorf("AllTags = %v, want %v", p.AllTags, want)
348+
+ }
349+
+ wantFiles = []string{"main.go"}
350+
+ if !reflect.DeepEqual(p.GoFiles, wantFiles) {
351+
+ t.Errorf("GoFiles = %v, want %v", p.GoFiles, wantFiles)
352+
+ }
329353
+}
330354
diff --git a/src/go/build/testdata/backendtags_openssl/main.go b/src/go/build/testdata/backendtags_openssl/main.go
331355
new file mode 100644
@@ -394,14 +418,14 @@ index 00000000000000..9c5b0bbc7b99dc
394418
+const SystemCrypto = true
395419
+const SystemCryptoInt = 1
396420
diff --git a/src/internal/goexperiment/flags.go b/src/internal/goexperiment/flags.go
397-
index ae3cbaf89fa5dd..de79140b2d4780 100644
421+
index 31b3d0315b64f8..de1dfa6e567a71 100644
398422
--- a/src/internal/goexperiment/flags.go
399423
+++ b/src/internal/goexperiment/flags.go
400424
@@ -60,6 +60,21 @@ type Flags struct {
401425
StaticLockRanking bool
402426
BoringCrypto bool
403427

404-
+ // SystemCrypto enables the OpenSSL or CNG crypto experiment depending on
428+
+ // SystemCrypto enables the OpenSSL, CNG or Darwin crypto experiment depending on
405429
+ // which one is appropriate on the target GOOS.
406430
+ //
407431
+ // If SystemCrypto is enabled but no crypto experiment is appropriate on the

patches/0002-Add-crypto-backend-foundation.patch

+31-17
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,15 @@ Subject: [PATCH] Add crypto backend foundation
6969
src/crypto/tls/handshake_server_tls13.go | 24 +-
7070
src/crypto/tls/internal/fips140tls/fipstls.go | 3 +-
7171
src/crypto/tls/prf.go | 41 ++++
72+
src/go/build/buildbackend_test.go | 2 +-
7273
src/go/build/deps_test.go | 8 +-
7374
src/hash/boring_test.go | 9 +
7475
src/hash/example_test.go | 2 +
7576
src/hash/marshal_test.go | 5 +
7677
src/hash/notboring_test.go | 9 +
7778
src/net/smtp/smtp_test.go | 72 ++++--
7879
src/runtime/runtime_boring.go | 5 +
79-
72 files changed, 1181 insertions(+), 86 deletions(-)
80+
73 files changed, 1182 insertions(+), 87 deletions(-)
8081
create mode 100644 src/crypto/dsa/boring.go
8182
create mode 100644 src/crypto/dsa/notboring.go
8283
create mode 100644 src/crypto/ed25519/boring.go
@@ -619,11 +620,11 @@ index 00000000000000..3a7d7b76c8d8d7
619620
+}
620621
+
621622
+type boringPub struct {
622-
+ key *boring.PublicKeyEd25519
623+
+ key boring.PublicKeyEd25519
623624
+ orig [PublicKeySize]byte
624625
+}
625626
+
626-
+func boringPublicKey(pub PublicKey) (*boring.PublicKeyEd25519, error) {
627+
+func boringPublicKey(pub PublicKey) (boring.PublicKeyEd25519, error) {
627628
+ // Use the pointer to the underlying pub array as key.
628629
+ p := unsafe.SliceData(pub)
629630
+ b := pubCache.Get(p)
@@ -635,19 +636,19 @@ index 00000000000000..3a7d7b76c8d8d7
635636
+ copy(b.orig[:], pub)
636637
+ key, err := boring.NewPublicKeyEd25119(b.orig[:])
637638
+ if err != nil {
638-
+ return nil, err
639+
+ return key, err
639640
+ }
640641
+ b.key = key
641642
+ pubCache.Put(p, b)
642643
+ return key, nil
643644
+}
644645
+
645646
+type boringPriv struct {
646-
+ key *boring.PrivateKeyEd25519
647+
+ key boring.PrivateKeyEd25519
647648
+ orig [PrivateKeySize]byte
648649
+}
649650
+
650-
+func boringPrivateKey(priv PrivateKey) (*boring.PrivateKeyEd25519, error) {
651+
+func boringPrivateKey(priv PrivateKey) (boring.PrivateKeyEd25519, error) {
651652
+ // Use the pointer to the underlying priv array as key.
652653
+ p := unsafe.SliceData(priv)
653654
+ b := privCache.Get(p)
@@ -659,7 +660,7 @@ index 00000000000000..3a7d7b76c8d8d7
659660
+ copy(b.orig[:], priv)
660661
+ key, err := boring.NewPrivateKeyEd25119(b.orig[:])
661662
+ if err != nil {
662-
+ return nil, err
663+
+ return key, err
663664
+ }
664665
+ b.key = key
665666
+ privCache.Put(p, b)
@@ -807,10 +808,10 @@ index 00000000000000..b0cdd44d81c753
807808
+
808809
+import boring "crypto/internal/backend"
809810
+
810-
+func boringPublicKey(PublicKey) (*boring.PublicKeyEd25519, error) {
811+
+func boringPublicKey(PublicKey) (boring.PublicKeyEd25519, error) {
811812
+ panic("boringcrypto: not available")
812813
+}
813-
+func boringPrivateKey(PrivateKey) (*boring.PrivateKeyEd25519, error) {
814+
+func boringPrivateKey(PrivateKey) (boring.PrivateKeyEd25519, error) {
814815
+ panic("boringcrypto: not available")
815816
+}
816817
diff --git a/src/crypto/hkdf/hkdf.go b/src/crypto/hkdf/hkdf.go
@@ -1317,37 +1318,37 @@ index 00000000000000..71e0ec9dc25a02
13171318
+
13181319
+type PublicKeyEd25519 struct{}
13191320
+
1320-
+func (k *PublicKeyEd25519) Bytes() ([]byte, error) {
1321+
+func (k PublicKeyEd25519) Bytes() ([]byte, error) {
13211322
+ panic("cryptobackend: not available")
13221323
+}
13231324
+
13241325
+type PrivateKeyEd25519 struct{}
13251326
+
1326-
+func (k *PrivateKeyEd25519) Bytes() ([]byte, error) {
1327+
+func (k PrivateKeyEd25519) Bytes() ([]byte, error) {
13271328
+ panic("cryptobackend: not available")
13281329
+}
13291330
+
1330-
+func GenerateKeyEd25519() (*PrivateKeyEd25519, error) {
1331+
+func GenerateKeyEd25519() (PrivateKeyEd25519, error) {
13311332
+ panic("cryptobackend: not available")
13321333
+}
13331334
+
1334-
+func NewPrivateKeyEd25119(priv []byte) (*PrivateKeyEd25519, error) {
1335+
+func NewPrivateKeyEd25119(priv []byte) (PrivateKeyEd25519, error) {
13351336
+ panic("cryptobackend: not available")
13361337
+}
13371338
+
1338-
+func NewPublicKeyEd25119(pub []byte) (*PublicKeyEd25519, error) {
1339+
+func NewPublicKeyEd25119(pub []byte) (PublicKeyEd25519, error) {
13391340
+ panic("cryptobackend: not available")
13401341
+}
13411342
+
1342-
+func NewPrivateKeyEd25519FromSeed(seed []byte) (*PrivateKeyEd25519, error) {
1343+
+func NewPrivateKeyEd25519FromSeed(seed []byte) (PrivateKeyEd25519, error) {
13431344
+ panic("cryptobackend: not available")
13441345
+}
13451346
+
1346-
+func SignEd25519(priv *PrivateKeyEd25519, message []byte) ([]byte, error) {
1347+
+func SignEd25519(priv PrivateKeyEd25519, message []byte) ([]byte, error) {
13471348
+ panic("cryptobackend: not available")
13481349
+}
13491350
+
1350-
+func VerifyEd25519(pub *PublicKeyEd25519, message, sig []byte) error {
1351+
+func VerifyEd25519(pub PublicKeyEd25519, message, sig []byte) error {
13511352
+ panic("cryptobackend: not available")
13521353
+}
13531354
+
@@ -2317,6 +2318,19 @@ index e7369542a73270..ff52175e4ac636 100644
23172318
return tls12.PRF(hashFunc, secret, label, seed, keyLen)
23182319
}
23192320
}
2321+
diff --git a/src/go/build/buildbackend_test.go b/src/go/build/buildbackend_test.go
2322+
index 096b9b4566667c..aa3c5f1007ed79 100644
2323+
--- a/src/go/build/buildbackend_test.go
2324+
+++ b/src/go/build/buildbackend_test.go
2325+
@@ -55,7 +55,7 @@ func TestCryptoBackendAllTags(t *testing.T) {
2326+
if err != nil {
2327+
t.Fatal(err)
2328+
}
2329+
- want = []string{"goexperiment.boringcrypto", "goexperiment.cngcrypto", "goexperiment.opensslcrypto", "goexperiment.systemcrypto"}
2330+
+ want = []string{"goexperiment.boringcrypto", "goexperiment.cngcrypto", "goexperiment.darwincrypto", "goexperiment.opensslcrypto", "goexperiment.systemcrypto"}
2331+
if !reflect.DeepEqual(p.AllTags, want) {
2332+
t.Errorf("AllTags = %v, want %v", p.AllTags, want)
2333+
}
23202334
diff --git a/src/go/build/deps_test.go b/src/go/build/deps_test.go
23212335
index cc7f4df7f388ea..58082b3636f209 100644
23222336
--- a/src/go/build/deps_test.go

patches/0003-Add-BoringSSL-crypto-backend.patch

+8-8
Original file line numberDiff line numberDiff line change
@@ -235,37 +235,37 @@ index 00000000000000..b1bd6d5ba756d7
235235
+
236236
+type PublicKeyEd25519 struct{}
237237
+
238-
+func (k *PublicKeyEd25519) Bytes() ([]byte, error) {
238+
+func (k PublicKeyEd25519) Bytes() ([]byte, error) {
239239
+ panic("cryptobackend: not available")
240240
+}
241241
+
242242
+type PrivateKeyEd25519 struct{}
243243
+
244-
+func (k *PrivateKeyEd25519) Bytes() ([]byte, error) {
244+
+func (k PrivateKeyEd25519) Bytes() ([]byte, error) {
245245
+ panic("cryptobackend: not available")
246246
+}
247247
+
248-
+func GenerateKeyEd25519() (*PrivateKeyEd25519, error) {
248+
+func GenerateKeyEd25519() (PrivateKeyEd25519, error) {
249249
+ panic("cryptobackend: not available")
250250
+}
251251
+
252-
+func NewPrivateKeyEd25119(priv []byte) (*PrivateKeyEd25519, error) {
252+
+func NewPrivateKeyEd25119(priv []byte) (PrivateKeyEd25519, error) {
253253
+ panic("cryptobackend: not available")
254254
+}
255255
+
256-
+func NewPublicKeyEd25119(pub []byte) (*PublicKeyEd25519, error) {
256+
+func NewPublicKeyEd25119(pub []byte) (PublicKeyEd25519, error) {
257257
+ panic("cryptobackend: not available")
258258
+}
259259
+
260-
+func NewPrivateKeyEd25519FromSeed(seed []byte) (*PrivateKeyEd25519, error) {
260+
+func NewPrivateKeyEd25519FromSeed(seed []byte) (PrivateKeyEd25519, error) {
261261
+ panic("cryptobackend: not available")
262262
+}
263263
+
264-
+func SignEd25519(priv *PrivateKeyEd25519, message []byte) ([]byte, error) {
264+
+func SignEd25519(priv PrivateKeyEd25519, message []byte) ([]byte, error) {
265265
+ panic("cryptobackend: not available")
266266
+}
267267
+
268-
+func VerifyEd25519(pub *PublicKeyEd25519, message, sig []byte) error {
268+
+func VerifyEd25519(pub PublicKeyEd25519, message, sig []byte) error {
269269
+ panic("cryptobackend: not available")
270270
+}
271271
+

0 commit comments

Comments
 (0)