From 38d21cc16419056979d17564ff19a47b998c72cd Mon Sep 17 00:00:00 2001 From: Davis Goodin Date: Wed, 26 Jan 2022 17:58:33 -0600 Subject: [PATCH 01/47] Fork 1.17 from main branch Update submodule to 1.17 commit. --- go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go b/go index 2c58bb2e428..9de1ac6ac2c 160000 --- a/go +++ b/go @@ -1 +1 @@ -Subproject commit 2c58bb2e428c1f587dc30817bc211570f6fd4793 +Subproject commit 9de1ac6ac2cad3871760d0aa288f5ca713afd0a6 From 50ba7c0c6d9ce08e0c71bce6ed85cf86bb96f14f Mon Sep 17 00:00:00 2001 From: Jon Fortescue Date: Wed, 20 Oct 2021 16:24:57 -0700 Subject: [PATCH 02/47] Switch to 1ES servicing pools on microsoft/release-branch.go1.17 (#238) --- eng/pipeline/jobs/sign-job.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/pipeline/jobs/sign-job.yml b/eng/pipeline/jobs/sign-job.yml index 3ed566cbbae..d00df0d1bea 100644 --- a/eng/pipeline/jobs/sign-job.yml +++ b/eng/pipeline/jobs/sign-job.yml @@ -18,7 +18,7 @@ jobs: - ${{ builder.id }} pool: # This is a utility job that doesn't use Go: use a pool that supports signing. - name: NetCore1ESPool-Internal + name: NetCore1ESPool-Svc-Internal demands: ImageOverride -equals build.windows.10.amd64.vs2019 variables: - name: TeamName From a0895e34f0e9752dd23fae90c48af5197d168483 Mon Sep 17 00:00:00 2001 From: Davis Goodin Date: Mon, 6 Dec 2021 17:01:49 -0600 Subject: [PATCH 03/47] [microsoft/release-branch.go1.17] Add "make" retry capability, with 5 in Windows CI (#299) * Add "make" retry capability, with 5 in Windows CI * Report error if GO_MAKE_MAX_RETRY_ATTEMPTS is not an int --- eng/_core/cmd/build/build.go | 41 +++++++++++++++++++++++++++++++++-- eng/pipeline/jobs/run-job.yml | 5 +++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/eng/_core/cmd/build/build.go b/eng/_core/cmd/build/build.go index de088efc796..76153e8c1b5 100644 --- a/eng/_core/cmd/build/build.go +++ b/eng/_core/cmd/build/build.go @@ -11,6 +11,7 @@ import ( "os/exec" "path/filepath" "runtime" + "strconv" "github.com/microsoft/go/_core/archive" "github.com/microsoft/go/_core/patch" @@ -126,12 +127,35 @@ func build(o *options) error { } } - buildCommandLine := append(shellPrefix, "make"+scriptExtension) + // Set GOBUILDEXIT so 'make.bat' exits with exit code upon failure. The ordinary behavior of + // 'make.bat' is to always end with 0 exit code even if an error occurred, so 'all.bat' can + // handle the error. See https://github.com/golang/go/issues/7806. + if err := os.Setenv("GOBUILDEXIT", "1"); err != nil { + return err + } - if err := runCommandLine(buildCommandLine...); err != nil { + maxAttempts, err := getMaxMakeRetryAttempts() + if err != nil { return err } + buildCommandLine := append(shellPrefix, "make"+scriptExtension) + + for i := 0; i < maxAttempts; i++ { + if maxAttempts > 1 { + fmt.Printf("---- Running 'make' attempt %v of %v...\n", i+1, maxAttempts) + } + err := runCommandLine(buildCommandLine...) + if err != nil { + if i+1 < maxAttempts { + fmt.Printf("---- Build command failed with error: %v\n", err) + continue + } + return err + } + break + } + if os.Getenv("CGO_ENABLED") != "0" { fmt.Println("---- Building race runtime...") err := runCommandLine( @@ -216,3 +240,16 @@ func runCmd(cmd *exec.Cmd) error { fmt.Printf("---- Running command: %v\n", cmd.Args) return cmd.Run() } + +func getMaxMakeRetryAttempts() (int, error) { + const retryEnvVarName = "GO_MAKE_MAX_RETRY_ATTEMPTS" + a := os.Getenv(retryEnvVarName) + if a == "" { + return 1, nil + } + i, err := strconv.Atoi(a) + if err != nil { + return 0, fmt.Errorf("env var '%v' is not an int: %w", retryEnvVarName, err) + } + return i, nil +} diff --git a/eng/pipeline/jobs/run-job.yml b/eng/pipeline/jobs/run-job.yml index a5e5336f34a..89797a2b8c5 100644 --- a/eng/pipeline/jobs/run-job.yml +++ b/eng/pipeline/jobs/run-job.yml @@ -36,6 +36,11 @@ jobs: - ${{ if eq(parameters.builder.os, 'windows') }}: - template: ../steps/checkout-windows-task.yml + - pwsh: | + Write-Host "Increasing max build retries to mitigate 'Access denied' flakiness during EXE copying on Windows." + Write-Host "##vso[task.setvariable variable=GO_MAKE_MAX_RETRY_ATTEMPTS]5" + displayName: Increase 'make' retry attempts + # Initialize stage 0 toolset ahead of time so we can track timing data separately from the # build operations. When we call this script again later, it won't download Go again. From 156625327e0a89b2d58332f75fad4d27a628e6db Mon Sep 17 00:00:00 2001 From: Davis Goodin Date: Wed, 26 Jan 2022 18:31:06 -0600 Subject: [PATCH 04/47] Update submodule to dev.boringcrypto.go1.17; patch Add OpenSSL with two patches: one to vendor the OpenSSL crypto module, another to integrate it with the crypto libraries in Go. --- go | 2 +- ...d-JSON-output-support-for-some-tests.patch | 8 +- ...dd-vendored-go-crypto-openssl-module.patch | 3099 +++++++++++++++++ ...0003-Integrate-OpenSSL-crypto-module.patch | 702 ++++ 4 files changed, 3806 insertions(+), 5 deletions(-) create mode 100644 patches/0002-Add-vendored-go-crypto-openssl-module.patch create mode 100644 patches/0003-Integrate-OpenSSL-crypto-module.patch diff --git a/go b/go index 9de1ac6ac2c..cfad1ff84c4 160000 --- a/go +++ b/go @@ -1 +1 @@ -Subproject commit 9de1ac6ac2cad3871760d0aa288f5ca713afd0a6 +Subproject commit cfad1ff84c45f99f6ceee17f76e2cbaf2ff8598b diff --git a/patches/0001-cmd-dist-add-JSON-output-support-for-some-tests.patch b/patches/0001-cmd-dist-add-JSON-output-support-for-some-tests.patch index a9bcff182ae..d2fb5d83ff4 100644 --- a/patches/0001-cmd-dist-add-JSON-output-support-for-some-tests.patch +++ b/patches/0001-cmd-dist-add-JSON-output-support-for-some-tests.patch @@ -1,4 +1,4 @@ -From be418f20052ddea746451bafe21fdbf2bb1c915d Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Davis Goodin Date: Tue, 4 Jan 2022 11:23:27 -0600 Subject: [PATCH] cmd/dist: add JSON output support for some tests @@ -17,7 +17,7 @@ in JSON format, and the ordinary logs are still important. 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/cmd/dist/test.go b/src/cmd/dist/test.go -index 50a2e5936c..0436c63063 100644 +index f40fa926df..f76ecbe28c 100644 --- a/src/cmd/dist/test.go +++ b/src/cmd/dist/test.go @@ -29,6 +29,7 @@ func cmdtest() { @@ -36,7 +36,7 @@ index 50a2e5936c..0436c63063 100644 rebuild bool failed bool keepGoing bool -@@ -294,9 +296,13 @@ func short() string { +@@ -286,9 +288,13 @@ func short() string { // Callers should use goTest and then pass flags overriding these // defaults as later arguments in the command line. func (t *tester) goTest() []string { @@ -51,7 +51,7 @@ index 50a2e5936c..0436c63063 100644 } func (t *tester) tags() string { -@@ -379,6 +385,9 @@ func (t *tester) registerStdTest(pkg string, useG3 bool) { +@@ -371,6 +377,9 @@ func (t *tester) registerStdTest(pkg string, useG3 bool) { t.timeout(timeoutSec), "-gcflags=all=" + gcflags, } diff --git a/patches/0002-Add-vendored-go-crypto-openssl-module.patch b/patches/0002-Add-vendored-go-crypto-openssl-module.patch new file mode 100644 index 00000000000..16dbb77f8a9 --- /dev/null +++ b/patches/0002-Add-vendored-go-crypto-openssl-module.patch @@ -0,0 +1,3099 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: microsoft-golang-bot +Date: Thu, 27 Jan 2022 11:44:32 -0600 +Subject: [PATCH] Add vendored go-crypto-openssl module + +--- + src/go.mod | 1 + + src/go.sum | 2 + + .../microsoft/go-crypto-openssl/LICENSE | 21 + + .../go-crypto-openssl/openssl/aes.go | 487 ++++++++++++++++++ + .../go-crypto-openssl/openssl/apibridge_1_1.c | 291 +++++++++++ + .../go-crypto-openssl/openssl/apibridge_1_1.h | 28 + + .../go-crypto-openssl/openssl/ecdsa.go | 199 +++++++ + .../go-crypto-openssl/openssl/goopenssl.c | 199 +++++++ + .../go-crypto-openssl/openssl/goopenssl.h | 240 +++++++++ + .../go-crypto-openssl/openssl/hmac.go | 162 ++++++ + .../openssl/internal/subtle/aliasing.go | 32 ++ + .../go-crypto-openssl/openssl/openssl.go | 107 ++++ + .../go-crypto-openssl/openssl/openssl_funcs.h | 215 ++++++++ + .../openssl/openssl_lock_setup.c | 53 ++ + .../go-crypto-openssl/openssl/rand.go | 24 + + .../go-crypto-openssl/openssl/rsa.go | 397 ++++++++++++++ + .../go-crypto-openssl/openssl/sha.go | 477 +++++++++++++++++ + src/vendor/modules.txt | 4 + + 18 files changed, 2939 insertions(+) + create mode 100644 src/vendor/github.com/microsoft/go-crypto-openssl/LICENSE + create mode 100644 src/vendor/github.com/microsoft/go-crypto-openssl/openssl/aes.go + create mode 100644 src/vendor/github.com/microsoft/go-crypto-openssl/openssl/apibridge_1_1.c + create mode 100644 src/vendor/github.com/microsoft/go-crypto-openssl/openssl/apibridge_1_1.h + create mode 100644 src/vendor/github.com/microsoft/go-crypto-openssl/openssl/ecdsa.go + create mode 100644 src/vendor/github.com/microsoft/go-crypto-openssl/openssl/goopenssl.c + create mode 100644 src/vendor/github.com/microsoft/go-crypto-openssl/openssl/goopenssl.h + create mode 100644 src/vendor/github.com/microsoft/go-crypto-openssl/openssl/hmac.go + create mode 100644 src/vendor/github.com/microsoft/go-crypto-openssl/openssl/internal/subtle/aliasing.go + create mode 100644 src/vendor/github.com/microsoft/go-crypto-openssl/openssl/openssl.go + create mode 100644 src/vendor/github.com/microsoft/go-crypto-openssl/openssl/openssl_funcs.h + create mode 100644 src/vendor/github.com/microsoft/go-crypto-openssl/openssl/openssl_lock_setup.c + create mode 100644 src/vendor/github.com/microsoft/go-crypto-openssl/openssl/rand.go + create mode 100644 src/vendor/github.com/microsoft/go-crypto-openssl/openssl/rsa.go + create mode 100644 src/vendor/github.com/microsoft/go-crypto-openssl/openssl/sha.go + +diff --git a/src/go.mod b/src/go.mod +index af435fa335..b251be6e34 100644 +--- a/src/go.mod ++++ b/src/go.mod +@@ -3,6 +3,7 @@ module std + go 1.17 + + require ( ++ github.com/microsoft/go-crypto-openssl v0.0.0-20220124101237-183c44c3cf71 + golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e + golang.org/x/net v0.0.0-20220106012031-21a9c9cfe9c3 + ) +diff --git a/src/go.sum b/src/go.sum +index 3e3fa7989f..8ab0218786 100644 +--- a/src/go.sum ++++ b/src/go.sum +@@ -1,3 +1,5 @@ ++github.com/microsoft/go-crypto-openssl v0.0.0-20220124101237-183c44c3cf71 h1:NO1CTk7yHEtgUjfV7eqU4+sRe8OHRqZAznWe8WpVj7I= ++github.com/microsoft/go-crypto-openssl v0.0.0-20220124101237-183c44c3cf71/go.mod h1:rC+rtBU3m60UCQifBmpWII0VETfu78w6YGZQvVc0rd4= + golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e h1:1SzTfNOXwIS2oWiMF+6qu0OUDKb0dauo6MoDUQyu+yU= + golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= + golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +diff --git a/src/vendor/github.com/microsoft/go-crypto-openssl/LICENSE b/src/vendor/github.com/microsoft/go-crypto-openssl/LICENSE +new file mode 100644 +index 0000000000..9e841e7a26 +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-openssl/LICENSE +@@ -0,0 +1,21 @@ ++ MIT License ++ ++ Copyright (c) Microsoft Corporation. ++ ++ Permission is hereby granted, free of charge, to any person obtaining a copy ++ of this software and associated documentation files (the "Software"), to deal ++ in the Software without restriction, including without limitation the rights ++ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++ copies of the Software, and to permit persons to whom the Software is ++ furnished to do so, subject to the following conditions: ++ ++ The above copyright notice and this permission notice shall be included in all ++ copies or substantial portions of the Software. ++ ++ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ SOFTWARE +diff --git a/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/aes.go b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/aes.go +new file mode 100644 +index 0000000000..7b743f67fb +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/aes.go +@@ -0,0 +1,487 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++//go:build linux && !android ++// +build linux,!android ++ ++package openssl ++ ++// #include "goopenssl.h" ++import "C" ++import ( ++ "crypto/cipher" ++ "errors" ++ "runtime" ++ "strconv" ++ "unsafe" ++ ++ "github.com/microsoft/go-crypto-openssl/openssl/internal/subtle" ++) ++ ++type aesKeySizeError int ++ ++func (k aesKeySizeError) Error() string { ++ return "crypto/aes: invalid key size " + strconv.Itoa(int(k)) ++} ++ ++const aesBlockSize = 16 ++ ++type aesCipher struct { ++ key []byte ++ enc_ctx *C.EVP_CIPHER_CTX ++ dec_ctx *C.EVP_CIPHER_CTX ++ cipher *C.EVP_CIPHER ++} ++ ++type extraModes interface { ++ // Copied out of crypto/aes/modes.go. ++ NewCBCEncrypter(iv []byte) cipher.BlockMode ++ NewCBCDecrypter(iv []byte) cipher.BlockMode ++ NewCTR(iv []byte) cipher.Stream ++ NewGCM(nonceSize, tagSize int) (cipher.AEAD, error) ++ ++ // Invented for BoringCrypto. ++ NewGCMTLS() (cipher.AEAD, error) ++} ++ ++var _ extraModes = (*aesCipher)(nil) ++ ++func NewAESCipher(key []byte) (cipher.Block, error) { ++ c := &aesCipher{key: make([]byte, len(key))} ++ copy(c.key, key) ++ ++ switch len(c.key) * 8 { ++ case 128: ++ c.cipher = C._goboringcrypto_EVP_aes_128_ecb() ++ case 192: ++ c.cipher = C._goboringcrypto_EVP_aes_192_ecb() ++ case 256: ++ c.cipher = C._goboringcrypto_EVP_aes_256_ecb() ++ default: ++ return nil, errors.New("crypto/cipher: Invalid key size") ++ } ++ ++ runtime.SetFinalizer(c, (*aesCipher).finalize) ++ ++ return c, nil ++} ++ ++func (c *aesCipher) finalize() { ++ if c.enc_ctx != nil { ++ C._goboringcrypto_EVP_CIPHER_CTX_free(c.enc_ctx) ++ } ++ if c.dec_ctx != nil { ++ C._goboringcrypto_EVP_CIPHER_CTX_free(c.dec_ctx) ++ } ++} ++ ++func (c *aesCipher) BlockSize() int { return aesBlockSize } ++ ++func (c *aesCipher) Encrypt(dst, src []byte) { ++ if subtle.InexactOverlap(dst, src) { ++ panic("crypto/cipher: invalid buffer overlap") ++ } ++ if len(src) < aesBlockSize { ++ panic("crypto/aes: input not full block") ++ } ++ if len(dst) < aesBlockSize { ++ panic("crypto/aes: output not full block") ++ } ++ ++ if c.enc_ctx == nil { ++ var err error ++ c.enc_ctx, err = newCipherCtx(c.cipher, C.GO_AES_ENCRYPT, c.key, nil) ++ if err != nil { ++ panic(err) ++ } ++ } ++ ++ outlen := C.int(0) ++ C._goboringcrypto_EVP_CipherUpdate(c.enc_ctx, (*C.uchar)(unsafe.Pointer(&dst[0])), &outlen, (*C.uchar)(unsafe.Pointer(&src[0])), C.int(aesBlockSize)) ++ runtime.KeepAlive(c) ++} ++ ++func (c *aesCipher) Decrypt(dst, src []byte) { ++ if subtle.InexactOverlap(dst, src) { ++ panic("crypto/cipher: invalid buffer overlap") ++ } ++ if len(src) < aesBlockSize { ++ panic("crypto/aes: input not full block") ++ } ++ if len(dst) < aesBlockSize { ++ panic("crypto/aes: output not full block") ++ } ++ if c.dec_ctx == nil { ++ var err error ++ c.dec_ctx, err = newCipherCtx(c.cipher, C.GO_AES_DECRYPT, c.key, nil) ++ if err != nil { ++ panic(err) ++ } ++ } ++ ++ outlen := C.int(0) ++ C._goboringcrypto_EVP_CipherUpdate(c.dec_ctx, (*C.uchar)(unsafe.Pointer(&dst[0])), &outlen, (*C.uchar)(unsafe.Pointer(&src[0])), C.int(aesBlockSize)) ++ runtime.KeepAlive(c) ++} ++ ++type aesCBC struct { ++ ctx *C.EVP_CIPHER_CTX ++} ++ ++func (x *aesCBC) BlockSize() int { return aesBlockSize } ++ ++func (x *aesCBC) CryptBlocks(dst, src []byte) { ++ if subtle.InexactOverlap(dst, src) { ++ panic("crypto/cipher: invalid buffer overlap") ++ } ++ if len(src)%aesBlockSize != 0 { ++ panic("crypto/cipher: input not full blocks") ++ } ++ if len(dst) < len(src) { ++ panic("crypto/cipher: output smaller than input") ++ } ++ if len(src) > 0 { ++ outlen := C.int(0) ++ if C._goboringcrypto_EVP_CipherUpdate( ++ x.ctx, ++ base(dst), &outlen, ++ base(src), C.int(len(src)), ++ ) != C.int(1) { ++ panic("crypto/cipher: CipherUpdate failed") ++ } ++ runtime.KeepAlive(x) ++ } ++} ++ ++func (x *aesCBC) SetIV(iv []byte) { ++ if len(iv) != aesBlockSize { ++ panic("cipher: incorrect length IV") ++ } ++ if C.int(1) != C._goboringcrypto_EVP_CipherInit_ex(x.ctx, nil, nil, nil, (*C.uchar)(unsafe.Pointer(&iv[0])), -1) { ++ panic("cipher: unable to initialize EVP cipher ctx") ++ } ++} ++ ++func (c *aesCipher) NewCBCEncrypter(iv []byte) cipher.BlockMode { ++ x := new(aesCBC) ++ ++ var cipher *C.EVP_CIPHER ++ switch len(c.key) * 8 { ++ case 128: ++ cipher = C._goboringcrypto_EVP_aes_128_cbc() ++ case 192: ++ cipher = C._goboringcrypto_EVP_aes_192_cbc() ++ case 256: ++ cipher = C._goboringcrypto_EVP_aes_256_cbc() ++ default: ++ panic("crypto/boring: unsupported key length") ++ } ++ var err error ++ x.ctx, err = newCipherCtx(cipher, C.GO_AES_ENCRYPT, c.key, iv) ++ if err != nil { ++ panic(err) ++ } ++ ++ runtime.SetFinalizer(x, (*aesCBC).finalize) ++ ++ return x ++} ++ ++func (c *aesCBC) finalize() { ++ C._goboringcrypto_EVP_CIPHER_CTX_free(c.ctx) ++} ++ ++func (c *aesCipher) NewCBCDecrypter(iv []byte) cipher.BlockMode { ++ x := new(aesCBC) ++ ++ var cipher *C.EVP_CIPHER ++ switch len(c.key) * 8 { ++ case 128: ++ cipher = C._goboringcrypto_EVP_aes_128_cbc() ++ case 192: ++ cipher = C._goboringcrypto_EVP_aes_192_cbc() ++ case 256: ++ cipher = C._goboringcrypto_EVP_aes_256_cbc() ++ default: ++ panic("crypto/boring: unsupported key length") ++ } ++ ++ var err error ++ x.ctx, err = newCipherCtx(cipher, C.GO_AES_DECRYPT, c.key, iv) ++ if err != nil { ++ panic(err) ++ } ++ if C.int(1) != C._goboringcrypto_EVP_CIPHER_CTX_set_padding(x.ctx, 0) { ++ panic("cipher: unable to set padding") ++ } ++ ++ runtime.SetFinalizer(x, (*aesCBC).finalize) ++ return x ++} ++ ++type aesCTR struct { ++ ctx *C.EVP_CIPHER_CTX ++} ++ ++func (x *aesCTR) XORKeyStream(dst, src []byte) { ++ if subtle.InexactOverlap(dst, src) { ++ panic("crypto/cipher: invalid buffer overlap") ++ } ++ if len(dst) < len(src) { ++ panic("crypto/cipher: output smaller than input") ++ } ++ if len(src) == 0 { ++ return ++ } ++ C._goboringcrypto_EVP_AES_ctr128_enc( ++ x.ctx, ++ (*C.uint8_t)(unsafe.Pointer(&src[0])), ++ (*C.uint8_t)(unsafe.Pointer(&dst[0])), ++ C.size_t(len(src))) ++ runtime.KeepAlive(x) ++} ++ ++func (c *aesCipher) NewCTR(iv []byte) cipher.Stream { ++ x := new(aesCTR) ++ ++ var cipher *C.EVP_CIPHER ++ switch len(c.key) * 8 { ++ case 128: ++ cipher = C._goboringcrypto_EVP_aes_128_ctr() ++ case 192: ++ cipher = C._goboringcrypto_EVP_aes_192_ctr() ++ case 256: ++ cipher = C._goboringcrypto_EVP_aes_256_ctr() ++ default: ++ panic("crypto/boring: unsupported key length") ++ } ++ var err error ++ x.ctx, err = newCipherCtx(cipher, C.GO_AES_ENCRYPT, c.key, iv) ++ if err != nil { ++ panic(err) ++ } ++ ++ runtime.SetFinalizer(x, (*aesCTR).finalize) ++ ++ return x ++} ++ ++func (c *aesCTR) finalize() { ++ C._goboringcrypto_EVP_CIPHER_CTX_free(c.ctx) ++} ++ ++type aesGCM struct { ++ key []byte ++ tls bool ++ cipher *C.EVP_CIPHER ++} ++ ++const ( ++ gcmBlockSize = 16 ++ gcmTagSize = 16 ++ gcmStandardNonceSize = 12 ++) ++ ++type aesNonceSizeError int ++ ++func (n aesNonceSizeError) Error() string { ++ return "crypto/aes: invalid GCM nonce size " + strconv.Itoa(int(n)) ++} ++ ++type noGCM struct { ++ cipher.Block ++} ++ ++func (c *aesCipher) NewGCM(nonceSize, tagSize int) (cipher.AEAD, error) { ++ if nonceSize != gcmStandardNonceSize && tagSize != gcmTagSize { ++ return nil, errors.New("crypto/aes: GCM tag and nonce sizes can't be non-standard at the same time") ++ } ++ // Fall back to standard library for GCM with non-standard nonce or tag size. ++ if nonceSize != gcmStandardNonceSize { ++ return cipher.NewGCMWithNonceSize(&noGCM{c}, nonceSize) ++ } ++ if tagSize != gcmTagSize { ++ return cipher.NewGCMWithTagSize(&noGCM{c}, tagSize) ++ } ++ return c.newGCM(false) ++} ++ ++func (c *aesCipher) NewGCMTLS() (cipher.AEAD, error) { ++ return c.newGCM(true) ++} ++ ++func (c *aesCipher) newGCM(tls bool) (cipher.AEAD, error) { ++ g := &aesGCM{key: c.key, tls: tls} ++ switch len(c.key) * 8 { ++ case 128: ++ g.cipher = C._goboringcrypto_EVP_aes_128_gcm() ++ case 192: ++ g.cipher = C._goboringcrypto_EVP_aes_192_gcm() ++ case 256: ++ g.cipher = C._goboringcrypto_EVP_aes_256_gcm() ++ default: ++ panic("crypto/boring: unsupported key length") ++ } ++ ++ return g, nil ++} ++ ++func (g *aesGCM) NonceSize() int { ++ return gcmStandardNonceSize ++} ++ ++func (g *aesGCM) Overhead() int { ++ return gcmTagSize ++} ++ ++// base returns the address of the underlying array in b, ++// being careful not to panic when b has zero length. ++func base(b []byte) *C.uint8_t { ++ if len(b) == 0 { ++ return nil ++ } ++ return (*C.uint8_t)(unsafe.Pointer(&b[0])) ++} ++ ++func (g *aesGCM) Seal(dst, nonce, plaintext, additionalData []byte) []byte { ++ if len(nonce) != gcmStandardNonceSize { ++ panic("cipher: incorrect nonce length given to GCM") ++ } ++ if uint64(len(plaintext)) > ((1<<32)-2)*aesBlockSize || len(plaintext)+gcmTagSize < len(plaintext) { ++ panic("cipher: message too large for GCM") ++ } ++ if len(dst)+len(plaintext)+gcmTagSize < len(dst) { ++ panic("cipher: message too large for buffer") ++ } ++ ++ // Make room in dst to append plaintext+overhead. ++ ret, out := sliceForAppend(dst, len(plaintext)+gcmTagSize) ++ ++ // Check delayed until now to make sure len(dst) is accurate. ++ if subtle.InexactOverlap(out, plaintext) { ++ panic("cipher: invalid buffer overlap") ++ } ++ ++ ctx, err := newCipherCtx(g.cipher, C.GO_AES_ENCRYPT, g.key, nonce) ++ if err != nil { ++ panic(err) ++ } ++ defer C._goboringcrypto_EVP_CIPHER_CTX_free(ctx) ++ ++ var encLen C.int ++ // Encrypt additional data. ++ if C._goboringcrypto_EVP_EncryptUpdate(ctx, nil, &encLen, base(additionalData), C.int(len(additionalData))) != C.int(1) { ++ panic(fail("EVP_CIPHER_CTX_seal")) ++ } ++ ++ // Encrypt plain text. ++ if C._goboringcrypto_EVP_EncryptUpdate(ctx, base(out), &encLen, base(plaintext), C.int(len(plaintext))) != C.int(1) { ++ panic(fail("EVP_CIPHER_CTX_seal")) ++ } ++ ++ // Finalise encryption. ++ var encFinalLen C.int ++ if C._goboringcrypto_EVP_EncryptFinal_ex(ctx, base(out[encLen:]), &encFinalLen) != C.int(1) { ++ panic(fail("EVP_CIPHER_CTX_seal")) ++ } ++ encLen += encFinalLen ++ ++ if C._goboringcrypto_EVP_CIPHER_CTX_ctrl(ctx, C.EVP_CTRL_GCM_GET_TAG, C.int(16), unsafe.Pointer(&out[encLen])) != C.int(1) { ++ panic(fail("EVP_CIPHER_CTX_seal")) ++ } ++ encLen += 16 ++ ++ if int(encLen) != len(plaintext)+gcmTagSize { ++ panic("internal confusion about GCM tag size") ++ } ++ return ret ++} ++ ++var errOpen = errors.New("cipher: message authentication failed") ++ ++func (g *aesGCM) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) { ++ if len(nonce) != gcmStandardNonceSize { ++ panic("cipher: incorrect nonce length given to GCM") ++ } ++ if len(ciphertext) < gcmTagSize { ++ return nil, errOpen ++ } ++ if uint64(len(ciphertext)) > ((1<<32)-2)*aesBlockSize+gcmTagSize { ++ return nil, errOpen ++ } ++ ++ tag := ciphertext[len(ciphertext)-gcmTagSize:] ++ ciphertext = ciphertext[:len(ciphertext)-gcmTagSize] ++ ++ // Make room in dst to append ciphertext without tag. ++ ret, out := sliceForAppend(dst, len(ciphertext)) ++ ++ // Check delayed until now to make sure len(dst) is accurate. ++ if subtle.InexactOverlap(out, ciphertext) { ++ panic("cipher: invalid buffer overlap") ++ } ++ ++ ctx, err := newCipherCtx(g.cipher, C.GO_AES_DECRYPT, g.key, nonce) ++ if err != nil { ++ panic(err) ++ } ++ defer C._goboringcrypto_EVP_CIPHER_CTX_free(ctx) ++ ++ clearAndFail := func(err error) ([]byte, error) { ++ for i := range out { ++ out[i] = 0 ++ } ++ return nil, err ++ } ++ ++ // Provide any AAD data. ++ var tmplen C.int ++ if C._goboringcrypto_EVP_DecryptUpdate(ctx, nil, &tmplen, base(additionalData), C.int(len(additionalData))) != C.int(1) { ++ return clearAndFail(errOpen) ++ } ++ ++ // Provide the message to be decrypted, and obtain the plaintext output. ++ var decLen C.int ++ if C._goboringcrypto_EVP_DecryptUpdate(ctx, base(out), &decLen, base(ciphertext), C.int(len(ciphertext))) != C.int(1) { ++ return clearAndFail(errOpen) ++ } ++ ++ // Set expected tag value. Works in OpenSSL 1.0.1d and later. ++ if C._goboringcrypto_EVP_CIPHER_CTX_ctrl(ctx, C.EVP_CTRL_GCM_SET_TAG, 16, unsafe.Pointer(&tag[0])) != C.int(1) { ++ return clearAndFail(errOpen) ++ } ++ ++ // Finalise the decryption. ++ var tagLen C.int ++ if C._goboringcrypto_EVP_DecryptFinal_ex(ctx, base(out[int(decLen):]), &tagLen) != C.int(1) { ++ return clearAndFail(errOpen) ++ } ++ ++ if int(decLen+tagLen) != len(ciphertext) { ++ panic("internal confusion about GCM tag size") ++ } ++ return ret, nil ++} ++ ++// sliceForAppend is a mirror of crypto/cipher.sliceForAppend. ++func sliceForAppend(in []byte, n int) (head, tail []byte) { ++ if total := len(in) + n; cap(in) >= total { ++ head = in[:total] ++ } else { ++ head = make([]byte, total) ++ copy(head, in) ++ } ++ tail = head[len(in):] ++ return ++} ++ ++func newCipherCtx(cipher *C.EVP_CIPHER, mode C.int, key, iv []byte) (*C.EVP_CIPHER_CTX, error) { ++ ctx := C._goboringcrypto_EVP_CIPHER_CTX_new() ++ if ctx == nil { ++ return nil, fail("unable to create EVP cipher ctx") ++ } ++ if C.int(1) != C._goboringcrypto_EVP_CipherInit_ex(ctx, cipher, nil, base(key), base(iv), mode) { ++ return nil, fail("unable to initialize EVP cipher ctx") ++ } ++ return ctx, nil ++} +diff --git a/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/apibridge_1_1.c b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/apibridge_1_1.c +new file mode 100644 +index 0000000000..1aa521bf29 +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/apibridge_1_1.c +@@ -0,0 +1,291 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++//go:build linux && !android ++// +build linux,!android ++ ++#include "goopenssl.h" ++#include "apibridge_1_1.h" ++ ++// Minimally define the structs from 1.0.x which went opaque in 1.1.0 for the ++// portable build building against the 1.1.x headers ++#if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_1_1_0_RTM ++// The crypto_ex_data_st struct is smaller in 1.1, which changes the packing of ++// dsa_st ++struct crypto_ex_data_10_st ++{ ++ STACK_OF(void) * sk; ++ int dummy; ++}; ++ ++struct hmac_ctx_st ++{ ++ const EVP_MD *md; ++ const void* _ignored0; ++ const void* _ignored1; ++ const void* _ignored2; ++ unsigned int _ignored3; ++ unsigned char _ignored4[128]; ++}; ++struct rsa_st ++{ ++ int _ignored0; ++ long _ignored1; ++ const void* _ignored2; ++ const void* _ignored3; ++ BIGNUM* n; ++ BIGNUM* e; ++ BIGNUM* d; ++ BIGNUM* p; ++ BIGNUM* q; ++ BIGNUM* dmp1; ++ BIGNUM* dmq1; ++ BIGNUM* iqmp; ++ struct crypto_ex_data_10_st _ignored4; ++ int _ignored5; ++ int _ignored6; ++}; ++struct evp_md_ctx_st { ++ const void *_ignored0; ++ void *_ignored1; ++ unsigned long _ignored2; ++ void *md_data; ++ void *_ignored3; ++ int (*_ignored4) (void *ctx, const void *data, size_t count); ++}; ++struct evp_md_st { ++ int type; ++ int pkey_type; ++ int md_size; ++ unsigned long flags; ++ int (*init) (EVP_MD_CTX *ctx); ++ int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count); ++ int (*final) (EVP_MD_CTX *ctx, unsigned char *md); ++ int (*copy) (EVP_MD_CTX *to, const EVP_MD_CTX *from); ++ int (*cleanup) (EVP_MD_CTX *ctx); ++ /* FIXME: prototype these some day */ ++ int (*sign) (int type, const unsigned char *m, unsigned int m_length, ++ unsigned char *sigret, unsigned int *siglen, void *key); ++ int (*verify) (int type, const unsigned char *m, unsigned int m_length, ++ const unsigned char *sigbuf, unsigned int siglen, ++ void *key); ++ int required_pkey_type[5]; /* EVP_PKEY_xxx */ ++ int block_size; ++ int ctx_size; /* how big does the ctx->md_data need to be */ ++ /* control function */ ++ int (*md_ctrl) (EVP_MD_CTX *ctx, int cmd, int p1, void *p2); ++}; ++#define EVP_PKEY_NULL_method NULL,NULL,{0,0,0,0} ++#endif ++ ++void ++local_HMAC_CTX_free(HMAC_CTX* ctx) ++{ ++ if (ctx != NULL) ++ { ++ _goboringcrypto_internal_HMAC_CTX_cleanup(ctx); ++ free(ctx); ++ } ++} ++ ++void* ++local_EVP_MD_CTX_md_data(EVP_MD_CTX *ctx) ++{ ++ return ctx->md_data; ++} ++ ++const EVP_MD* ++local_HMAC_CTX_get_md(const HMAC_CTX* ctx) ++{ ++ return ctx->md; ++} ++ ++HMAC_CTX* ++local_HMAC_CTX_new() ++{ ++ HMAC_CTX* ctx = malloc(sizeof(HMAC_CTX)); ++ if (ctx) ++ { ++ _goboringcrypto_internal_HMAC_CTX_init(ctx); ++ } ++ ++ return ctx; ++} ++ ++void ++local_HMAC_CTX_reset(HMAC_CTX* ctx) { ++ _goboringcrypto_internal_HMAC_CTX_cleanup(ctx); ++ _goboringcrypto_internal_HMAC_CTX_init(ctx); ++} ++ ++struct md5_sha1_ctx { ++ MD5_CTX md5; ++ SHA_CTX sha1; ++}; ++ ++static int ++md5_sha1_init(EVP_MD_CTX *ctx) ++{ ++ struct md5_sha1_ctx *mctx = _goboringcrypto_internal_EVP_MD_CTX_md_data(ctx); ++ if (!_goboringcrypto_internal_MD5_Init(&mctx->md5)) ++ return 0; ++ return _goboringcrypto_SHA1_Init(&mctx->sha1); ++} ++ ++static int md5_sha1_update(EVP_MD_CTX *ctx, const void *data, size_t count) ++{ ++ struct md5_sha1_ctx *mctx = _goboringcrypto_internal_EVP_MD_CTX_md_data(ctx); ++ if (!_goboringcrypto_internal_MD5_Update(&mctx->md5, data, count)) ++ return 0; ++ return _goboringcrypto_SHA1_Update(&mctx->sha1, data, count); ++} ++ ++static int md5_sha1_final(EVP_MD_CTX *ctx, unsigned char *md) ++{ ++ struct md5_sha1_ctx *mctx = _goboringcrypto_internal_EVP_MD_CTX_md_data(ctx); ++ if (!_goboringcrypto_internal_MD5_Final(md, &mctx->md5)) ++ return 0; ++ return _goboringcrypto_SHA1_Final(md + MD5_DIGEST_LENGTH, &mctx->sha1); ++} ++ ++// Change: Removed: ++// static int ctrl(EVP_MD_CTX *ctx, int cmd, int mslen, void *ms) ++ ++static const EVP_MD md5_sha1_md = { ++ NID_md5_sha1, ++ NID_md5_sha1, ++ MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, ++ 0, ++ md5_sha1_init, ++ md5_sha1_update, ++ md5_sha1_final, ++ NULL, ++ NULL, ++ EVP_PKEY_NULL_method, // Change: inserted ++ MD5_CBLOCK, ++ sizeof(EVP_MD *) + sizeof(struct md5_sha1_ctx), ++ NULL, // Change: was ctrl ++}; ++ ++const EVP_MD* local_EVP_md5_sha1(void) ++{ ++ return &md5_sha1_md; ++} ++ ++int ++local_RSA_set0_crt_params(RSA * r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) ++{ ++ if ((r->dmp1 == NULL && dmp1 == NULL) ++ || (r->dmq1 == NULL && dmq1 == NULL) ++ || (r->iqmp == NULL && iqmp == NULL)) ++ return 0; ++ ++ if (dmp1 != NULL) ++ { ++ _goboringcrypto_internal_BN_clear_free(r->dmp1); ++ r->dmp1 = dmp1; ++ } ++ if (dmq1 != NULL) ++ { ++ _goboringcrypto_internal_BN_clear_free(r->dmq1); ++ r->dmq1 = dmq1; ++ } ++ if (iqmp != NULL) ++ { ++ _goboringcrypto_internal_BN_clear_free(r->iqmp); ++ r->iqmp = iqmp; ++ } ++ ++ return 1; ++} ++ ++void ++local_RSA_get0_crt_params(const RSA *r, const BIGNUM **dmp1, const BIGNUM **dmq1, const BIGNUM **iqmp) ++{ ++ if (dmp1 != NULL) ++ *dmp1 = r->dmp1; ++ if (dmq1 != NULL) ++ *dmq1 = r->dmq1; ++ if (iqmp != NULL) ++ *iqmp = r->iqmp; ++} ++ ++int ++local_RSA_set0_key(RSA * r, BIGNUM *n, BIGNUM *e, BIGNUM *d) ++{ ++ /* If the fields n and e in r are NULL, the corresponding input ++ * parameters MUST be non-NULL for n and e. d may be ++ * left NULL (in case only the public key is used). ++ */ ++ if ((r->n == NULL && n == NULL) ++ || (r->e == NULL && e == NULL)) ++ return 0; ++ ++ if (n != NULL) ++ { ++ _goboringcrypto_BN_free(r->n); ++ r->n = n; ++ } ++ if (e != NULL) ++ { ++ _goboringcrypto_BN_free(r->e); ++ r->e = e; ++ } ++ if (d != NULL) ++ { ++ _goboringcrypto_internal_BN_clear_free(r->d); ++ r->d = d; ++ } ++ ++ return 1; ++} ++ ++int ++local_RSA_set0_factors(RSA * r, BIGNUM *p, BIGNUM *q) ++{ ++ /* If the fields p and q in r are NULL, the corresponding input ++ * parameters MUST be non-NULL. ++ */ ++ if ((r->p == NULL && p == NULL) ++ || (r->q == NULL && q == NULL)) ++ return 0; ++ ++ if (p != NULL) ++ { ++ _goboringcrypto_internal_BN_clear_free(r->p); ++ r->p = p; ++ } ++ if (q != NULL) ++ { ++ _goboringcrypto_internal_BN_clear_free(r->q); ++ r->q = q; ++ } ++ ++ return 1; ++} ++ ++void ++local_RSA_get0_factors(const RSA *rsa, const BIGNUM **p, const BIGNUM **q) ++{ ++ if (p) ++ *p = rsa->p; ++ if (q) ++ *q = rsa->q; ++} ++ ++void ++local_RSA_get0_key(const RSA *rsa, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) ++{ ++ if (n) ++ *n = rsa->n; ++ if (e) ++ *e = rsa->e; ++ if (d) ++ *d = rsa->d; ++} ++ ++int ++local_RSA_pkey_ctx_ctrl(EVP_PKEY_CTX* ctx, int optype, int cmd, int p1, void* p2) ++{ ++ return _goboringcrypto_internal_EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, optype, cmd, p1, p2); ++} +\ No newline at end of file +diff --git a/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/apibridge_1_1.h b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/apibridge_1_1.h +new file mode 100644 +index 0000000000..3b50f12598 +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/apibridge_1_1.h +@@ -0,0 +1,28 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++//go:build linux && !android ++// +build linux,!android ++ ++// Functions based on OpenSSL 1.1 API, used when building against/running with OpenSSL 1.0.x ++ ++void local_HMAC_CTX_free(HMAC_CTX * ctx); ++void* local_EVP_MD_CTX_md_data(EVP_MD_CTX *ctx); ++const EVP_MD* local_HMAC_CTX_get_md(const HMAC_CTX* ctx); ++HMAC_CTX* local_HMAC_CTX_new(); ++void local_HMAC_CTX_reset(HMAC_CTX *ctx); ++const EVP_MD* local_EVP_md5_sha1(void); ++int local_RSA_set0_crt_params(RSA * r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp); ++void local_RSA_get0_crt_params(const RSA *r, const BIGNUM **dmp1, const BIGNUM **dmq1, const BIGNUM **iqmp); ++int local_RSA_set0_key(RSA * r, BIGNUM *n, BIGNUM *e, BIGNUM *d); ++int local_RSA_set0_factors(RSA * r, BIGNUM *p, BIGNUM *q); ++void local_RSA_get0_factors(const RSA *rsa, const BIGNUM **p, const BIGNUM **q); ++void local_RSA_get0_key(const RSA *rsa, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d); ++int local_RSA_pkey_ctx_ctrl(EVP_PKEY_CTX* ctx, int optype, int cmd, int p1, void* p2); ++ ++#if OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_1_1_0_RTM ++#define OPENSSL_INIT_LOAD_CRYPTO_STRINGS 0x00000002L ++#define OPENSSL_INIT_ADD_ALL_CIPHERS 0x00000004L ++#define OPENSSL_INIT_ADD_ALL_DIGESTS 0x00000008L ++#define OPENSSL_INIT_LOAD_CONFIG 0x00000040L ++#endif +\ No newline at end of file +diff --git a/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/ecdsa.go b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/ecdsa.go +new file mode 100644 +index 0000000000..b13e7c9c5a +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/ecdsa.go +@@ -0,0 +1,199 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++//go:build linux && !android ++// +build linux,!android ++ ++package openssl ++ ++// #include "goopenssl.h" ++import "C" ++import ( ++ "encoding/asn1" ++ "errors" ++ "math/big" ++ "runtime" ++ "unsafe" ++) ++ ++type ecdsaSignature struct { ++ R, S *big.Int ++} ++ ++type PrivateKeyECDSA struct { ++ key *C.GO_EC_KEY ++} ++ ++func (k *PrivateKeyECDSA) finalize() { ++ C._goboringcrypto_EC_KEY_free(k.key) ++} ++ ++type PublicKeyECDSA struct { ++ key *C.GO_EC_KEY ++} ++ ++func (k *PublicKeyECDSA) finalize() { ++ C._goboringcrypto_EC_KEY_free(k.key) ++} ++ ++var errUnknownCurve = errors.New("boringcrypto: unknown elliptic curve") ++var errUnsupportedCurve = errors.New("boringcrypto: unsupported elliptic curve") ++ ++func curveNID(curve string) (C.int, error) { ++ switch curve { ++ case "P-224": ++ return C.GO_NID_secp224r1, nil ++ case "P-256": ++ return C.GO_NID_X9_62_prime256v1, nil ++ case "P-384": ++ return C.GO_NID_secp384r1, nil ++ case "P-521": ++ return C.GO_NID_secp521r1, nil ++ } ++ return 0, errUnknownCurve ++} ++ ++func NewPublicKeyECDSA(curve string, X, Y *big.Int) (*PublicKeyECDSA, error) { ++ key, err := newECKey(curve, X, Y) ++ if err != nil { ++ return nil, err ++ } ++ k := &PublicKeyECDSA{key} ++ // Note: Because of the finalizer, any time k.key is passed to cgo, ++ // that call must be followed by a call to runtime.KeepAlive(k), ++ // to make sure k is not collected (and finalized) before the cgo ++ // call returns. ++ runtime.SetFinalizer(k, (*PublicKeyECDSA).finalize) ++ return k, nil ++} ++ ++func newECKey(curve string, X, Y *big.Int) (*C.GO_EC_KEY, error) { ++ nid, err := curveNID(curve) ++ if err != nil { ++ return nil, err ++ } ++ key := C._goboringcrypto_EC_KEY_new_by_curve_name(nid) ++ if key == nil { ++ return nil, newOpenSSLError("EC_KEY_new_by_curve_name failed") ++ } ++ group := C._goboringcrypto_EC_KEY_get0_group(key) ++ pt := C._goboringcrypto_EC_POINT_new(group) ++ if pt == nil { ++ C._goboringcrypto_EC_KEY_free(key) ++ return nil, newOpenSSLError("EC_POINT_new failed") ++ } ++ bx := bigToBN(X) ++ by := bigToBN(Y) ++ ok := bx != nil && by != nil && C._goboringcrypto_EC_POINT_set_affine_coordinates_GFp(group, pt, bx, by, nil) != 0 && ++ C._goboringcrypto_EC_KEY_set_public_key(key, pt) != 0 ++ if bx != nil { ++ C._goboringcrypto_BN_free(bx) ++ } ++ if by != nil { ++ C._goboringcrypto_BN_free(by) ++ } ++ C._goboringcrypto_EC_POINT_free(pt) ++ if !ok { ++ C._goboringcrypto_EC_KEY_free(key) ++ return nil, newOpenSSLError("EC_POINT_free failed") ++ } ++ return key, nil ++} ++ ++func NewPrivateKeyECDSA(curve string, X, Y *big.Int, D *big.Int) (*PrivateKeyECDSA, error) { ++ key, err := newECKey(curve, X, Y) ++ if err != nil { ++ return nil, err ++ } ++ bd := bigToBN(D) ++ ok := bd != nil && C._goboringcrypto_EC_KEY_set_private_key(key, bd) != 0 ++ if bd != nil { ++ C._goboringcrypto_BN_free(bd) ++ } ++ if !ok { ++ C._goboringcrypto_EC_KEY_free(key) ++ return nil, newOpenSSLError("EC_KEY_set_private_key failed") ++ } ++ k := &PrivateKeyECDSA{key} ++ // Note: Because of the finalizer, any time k.key is passed to cgo, ++ // that call must be followed by a call to runtime.KeepAlive(k), ++ // to make sure k is not collected (and finalized) before the cgo ++ // call returns. ++ runtime.SetFinalizer(k, (*PrivateKeyECDSA).finalize) ++ return k, nil ++} ++ ++func SignECDSA(priv *PrivateKeyECDSA, hash []byte) (r, s *big.Int, err error) { ++ // We could use ECDSA_do_sign instead but would need to convert ++ // the resulting BIGNUMs to *big.Int form. If we're going to do a ++ // conversion, converting the ASN.1 form is more convenient and ++ // likely not much more expensive. ++ sig, err := SignMarshalECDSA(priv, hash) ++ if err != nil { ++ return nil, nil, err ++ } ++ var esig ecdsaSignature ++ if _, err := asn1.Unmarshal(sig, &esig); err != nil { ++ return nil, nil, err ++ } ++ return esig.R, esig.S, nil ++} ++ ++func SignMarshalECDSA(priv *PrivateKeyECDSA, hash []byte) ([]byte, error) { ++ size := C._goboringcrypto_ECDSA_size(priv.key) ++ sig := make([]byte, size) ++ var sigLen C.uint ++ if C._goboringcrypto_ECDSA_sign(0, base(hash), C.size_t(len(hash)), (*C.uint8_t)(unsafe.Pointer(&sig[0])), &sigLen, priv.key) == 0 { ++ return nil, newOpenSSLError("ECDSA_sign failed") ++ } ++ runtime.KeepAlive(priv) ++ return sig[:sigLen], nil ++} ++ ++func VerifyECDSA(pub *PublicKeyECDSA, hash []byte, r, s *big.Int) bool { ++ // We could use ECDSA_do_verify instead but would need to convert ++ // r and s to BIGNUM form. If we're going to do a conversion, marshaling ++ // to ASN.1 is more convenient and likely not much more expensive. ++ sig, err := asn1.Marshal(ecdsaSignature{r, s}) ++ if err != nil { ++ return false ++ } ++ ok := C._goboringcrypto_ECDSA_verify(0, base(hash), C.size_t(len(hash)), (*C.uint8_t)(unsafe.Pointer(&sig[0])), C.uint(len(sig)), pub.key) > 0 ++ runtime.KeepAlive(pub) ++ return ok ++} ++ ++func GenerateKeyECDSA(curve string) (X, Y, D *big.Int, err error) { ++ nid, err := curveNID(curve) ++ if err != nil { ++ return nil, nil, nil, err ++ } ++ key := C._goboringcrypto_EC_KEY_new_by_curve_name(nid) ++ if key == nil { ++ return nil, nil, nil, newOpenSSLError("EC_KEY_new_by_curve_name failed") ++ } ++ defer C._goboringcrypto_EC_KEY_free(key) ++ if C._goboringcrypto_EC_KEY_generate_key(key) == 0 { ++ return nil, nil, nil, newOpenSSLError("EC_KEY_generate_key failed") ++ } ++ group := C._goboringcrypto_EC_KEY_get0_group(key) ++ pt := C._goboringcrypto_EC_KEY_get0_public_key(key) ++ bd := C._goboringcrypto_EC_KEY_get0_private_key(key) ++ if pt == nil || bd == nil { ++ return nil, nil, nil, newOpenSSLError("EC_KEY_get0_private_key failed") ++ } ++ bx := C._goboringcrypto_BN_new() ++ if bx == nil { ++ return nil, nil, nil, newOpenSSLError("BN_new failed") ++ } ++ defer C._goboringcrypto_BN_free(bx) ++ by := C._goboringcrypto_BN_new() ++ if by == nil { ++ return nil, nil, nil, newOpenSSLError("BN_new failed") ++ } ++ defer C._goboringcrypto_BN_free(by) ++ if C._goboringcrypto_EC_POINT_get_affine_coordinates_GFp(group, pt, bx, by, nil) == 0 { ++ return nil, nil, nil, newOpenSSLError("EC_POINT_get_affine_coordinates_GFp failed") ++ } ++ return bnToBig(bx), bnToBig(by), bnToBig(bd), nil ++} +diff --git a/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/goopenssl.c b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/goopenssl.c +new file mode 100644 +index 0000000000..1abd17c202 +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/goopenssl.c +@@ -0,0 +1,199 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++//go:build linux && !android ++// +build linux,!android ++ ++#include "goopenssl.h" ++ ++#include ++#include ++ ++// Approach taken from .Net System.Security.Cryptography.Native ++// https://github.com/dotnet/runtime/blob/f64246ce08fb7a58221b2b7c8e68f69c02522b0d/src/libraries/Native/Unix/System.Security.Cryptography.Native/opensslshim.c ++ ++#define DEFINEFUNC(ret, func, args, argscall) ret (*_g_##func)args; ++#define DEFINEFUNCINTERNAL(ret, func, args, argscall) ret (*_g_internal_##func)args; ++#define DEFINEFUNC_LEGACY(ret, func, args, argscall) DEFINEFUNCINTERNAL(ret, func, args, argscall) ++#define DEFINEFUNC_110(ret, func, args, argscall) DEFINEFUNCINTERNAL(ret, func, args, argscall) ++#define DEFINEFUNC_RENAMED(ret, func, oldfunc, args, argscall) DEFINEFUNCINTERNAL(ret, func, args, argscall) ++#define DEFINEFUNC_FALLBACK(ret, func, args, argscall) DEFINEFUNCINTERNAL(ret, func, args, argscall) ++ ++FOR_ALL_OPENSSL_FUNCTIONS ++ ++#undef DEFINEFUNC ++#undef DEFINEFUNCINTERNAL ++#undef DEFINEFUNC_LEGACY ++#undef DEFINEFUNC_110 ++#undef DEFINEFUNC_RENAMED ++#undef DEFINEFUNC_FALLBACK ++ ++static void* handle = NULL; ++ ++// Load all the functions stored in FOR_ALL_OPENSSL_FUNCTIONS ++// and assign them to their corresponding function pointer ++// defined in goopenssl.h. ++static void ++_goboringcrypto_load_openssl_functions(const void* v1_0_sentinel) ++{ ++ // This function could be called concurrently from different Goroutines unless correctly locked. ++ // If that happen there could be a race in DEFINEFUNC_RENAMED where the global function pointer is NULL, ++ // then properly loaded, then goes back to NULL right before being used (then loaded again). ++ // To avoid this situation only assign the function pointer when the function has been successfully ++ // loaded in tmp_ptr. ++ void* tmp_ptr; ++ ++#define DEFINEFUNC(ret, func, args, argscall) \ ++ _g_##func = dlsym(handle, #func); \ ++ if (_g_##func == NULL) { fprintf(stderr, "Cannot get required symbol " #func " from libcrypto\n"); abort(); } ++#define DEFINEFUNCINTERNAL(ret, func, args, argscall) \ ++ _g_internal_##func = dlsym(handle, #func); \ ++ if (_g_internal_##func == NULL) { fprintf(stderr, "Cannot get required symbol " #func " from libcrypto\n"); abort(); } ++#define DEFINEFUNC_LEGACY(ret, func, args, argscall) \ ++ if (v1_0_sentinel != NULL) \ ++ { \ ++ DEFINEFUNCINTERNAL(ret, func, args, argscall) \ ++ } ++#define DEFINEFUNC_110(ret, func, args, argscall) \ ++ if (v1_0_sentinel == NULL) \ ++ { \ ++ DEFINEFUNCINTERNAL(ret, func, args, argscall) \ ++ } ++#define DEFINEFUNC_RENAMED(ret, func, oldfunc, args, argscall) \ ++ tmp_ptr = dlsym(handle, #func); \ ++ if (tmp_ptr == NULL) \ ++ { \ ++ tmp_ptr = dlsym(handle, #oldfunc); \ ++ if (tmp_ptr == NULL) \ ++ { \ ++ fprintf(stderr, "Cannot get required symbol " #func " nor " #oldfunc " from libcrypto\n"); \ ++ abort(); \ ++ } \ ++ } \ ++ _g_internal_##func = tmp_ptr; ++#define DEFINEFUNC_FALLBACK(ret, func, args, argscall) \ ++ tmp_ptr = dlsym(handle, #func); \ ++ if (tmp_ptr == NULL) { tmp_ptr = (void*)local_##func; } \ ++ _g_internal_##func = tmp_ptr; ++ ++FOR_ALL_OPENSSL_FUNCTIONS ++ ++#undef DEFINEFUNC ++#undef DEFINEFUNCINTERNAL ++#undef DEFINEFUNC_LEGACY ++#undef DEFINEFUNC_110 ++#undef DEFINEFUNC_RENAMED ++#undef DEFINEFUNC_FALLBACK ++} ++ ++#define SONAME_BASE "libcrypto.so." ++#define MAKELIB(v) SONAME_BASE v ++ ++static void ++_goboringcrypto_DLOPEN(const char* libraryName) ++{ ++ handle = dlopen(libraryName, RTLD_LAZY | RTLD_GLOBAL); ++} ++ ++void* ++_goboringcrypto_internal_DLOPEN_OPENSSL(void) ++{ ++ if (handle) ++ { ++ return handle; ++ } ++ ++ // If there is an override of the version specified using the GO_OPENSSL_VERSION_OVERRIDE ++ // env variable, try to load that first. ++ // The format of the value in the env variable is expected to be the version numbers, ++ // like 1.0.0, 1.0.2 etc. ++ char* versionOverride = getenv("GO_OPENSSL_VERSION_OVERRIDE"); ++ if ((versionOverride != NULL) && strnlen(versionOverride, MaxVersionStringLength + 1) <= MaxVersionStringLength) ++ { ++ char soName[sizeof(SONAME_BASE) + MaxVersionStringLength] = SONAME_BASE; ++ strcat(soName, versionOverride); ++ _goboringcrypto_DLOPEN(soName); ++ } ++ ++ if (handle == NULL) ++ { ++ _goboringcrypto_DLOPEN(MAKELIB("3")); ++ } ++ ++ if (handle == NULL) ++ { ++ _goboringcrypto_DLOPEN(MAKELIB("1.1")); ++ } ++ ++ // FreeBSD uses a different suffix numbering convention. ++ // Current supported FreeBSD releases should use the order .11 -> .111 ++ if (handle == NULL) ++ { ++ _goboringcrypto_DLOPEN(MAKELIB("11")); ++ } ++ ++ if (handle == NULL) ++ { ++ _goboringcrypto_DLOPEN(MAKELIB("111")); ++ } ++ ++ if (handle == NULL) ++ { ++ // Debian 9 has dropped support for SSLv3 and so they have bumped their soname. Let's try it ++ // before trying the version 1.0.0 to make it less probable that some of our other dependencies ++ // end up loading conflicting version of libcrypto. ++ _goboringcrypto_DLOPEN(MAKELIB("1.0.2")); ++ } ++ ++ if (handle == NULL) ++ { ++ // Now try the default versioned so naming as described in the OpenSSL doc ++ _goboringcrypto_DLOPEN(MAKELIB("1.0.0")); ++ } ++ ++ if (handle == NULL) ++ { ++ // Fedora derived distros use different naming for the version 1.0.0 ++ _goboringcrypto_DLOPEN(MAKELIB("10")); ++ } ++ ++ return handle; ++} ++ ++int _goboringcrypto_internal_OPENSSL_thread_setup(void); ++ ++int ++_goboringcrypto_internal_OPENSSL_setup(void) ++{ ++ // A function defined in libcrypto.so.1.0.x that is not defined in libcrypto.so.1.1.0 ++ const void* v1_0_sentinel = dlsym(handle, "EVP_MD_CTX_cleanup"); ++ _goboringcrypto_load_openssl_functions(v1_0_sentinel); ++ // OPENSSL_init initialize FIPS callbacks and rand generator. ++ // no-op from OpenSSL 1.1.1 onwards. ++ _goboringcrypto_internal_OPENSSL_init(); ++ ++ if (v1_0_sentinel != NULL) ++ { ++ if (_goboringcrypto_internal_OPENSSL_thread_setup() != 1) ++ { ++ return 0; ++ } ++ // Load all algorithms and the openssl configuration file. ++ _goboringcrypto_internal_OPENSSL_add_all_algorithms_conf(); ++ ++ // Ensure that the error message table is loaded. ++ _goboringcrypto_internal_ERR_load_crypto_strings(); ++ return 1; ++ } ++ else ++ { ++ // In OpenSSL 1.0 we call OPENSSL_add_all_algorithms_conf() and ERR_load_crypto_strings(), ++ // so do the same for 1.1 ++ return _goboringcrypto_internal_OPENSSL_init_crypto( ++ OPENSSL_INIT_ADD_ALL_CIPHERS | ++ OPENSSL_INIT_ADD_ALL_DIGESTS | ++ OPENSSL_INIT_LOAD_CONFIG | ++ OPENSSL_INIT_LOAD_CRYPTO_STRINGS, ++ NULL); ++ } ++} +diff --git a/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/goopenssl.h b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/goopenssl.h +new file mode 100644 +index 0000000000..0b0acb1bcf +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/goopenssl.h +@@ -0,0 +1,240 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++// This header file describes the OpenSSL ABI as built for use in Go. ++ ++#include // size_t ++#include // uint8_t, getenv ++#include // strnlen ++ ++#include "openssl_funcs.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++void* _goboringcrypto_internal_DLOPEN_OPENSSL(void); ++int _goboringcrypto_internal_OPENSSL_setup(void); ++ ++static inline void* ++_goboringcrypto_DLOPEN_OPENSSL(void) ++{ ++ return _goboringcrypto_internal_DLOPEN_OPENSSL(); ++} ++ ++static inline int ++_goboringcrypto_OPENSSL_setup(void) ++{ ++ return _goboringcrypto_internal_OPENSSL_setup(); ++} ++ ++// x.x.x, considering the max number of decimal digits for each component ++#define MaxVersionStringLength 32 ++#define OPENSSL_VERSION_3_0_RTM 0x30000000L ++#define OPENSSL_VERSION_1_1_1_RTM 0x10101000L ++#define OPENSSL_VERSION_1_1_0_RTM 0x10100000L ++#define OPENSSL_VERSION_1_0_2_RTM 0x10002000L ++ ++#include "apibridge_1_1.h" ++ ++enum ++{ ++ GO_NID_secp224r1 = NID_secp224r1, ++ GO_NID_X9_62_prime256v1 = NID_X9_62_prime256v1, ++ GO_NID_secp384r1 = NID_secp384r1, ++ GO_NID_secp521r1 = NID_secp521r1, ++ GO_AES_ENCRYPT = 1, ++ GO_AES_DECRYPT = 0, ++ GO_RSA_PKCS1_PADDING = 1, ++ GO_RSA_NO_PADDING = 3, ++ GO_RSA_PKCS1_OAEP_PADDING = 4, ++ GO_RSA_PKCS1_PSS_PADDING = 6, ++}; ++ ++typedef SHA_CTX GO_SHA_CTX; ++typedef SHA256_CTX GO_SHA256_CTX; ++typedef SHA512_CTX GO_SHA512_CTX; ++typedef EVP_MD GO_EVP_MD; ++typedef HMAC_CTX GO_HMAC_CTX; ++typedef BN_CTX GO_BN_CTX; ++typedef BIGNUM GO_BIGNUM; ++typedef EC_GROUP GO_EC_GROUP; ++typedef EC_POINT GO_EC_POINT; ++typedef EC_KEY GO_EC_KEY; ++typedef ECDSA_SIG GO_ECDSA_SIG; ++typedef RSA GO_RSA; ++typedef BN_GENCB GO_BN_GENCB; ++typedef EVP_PKEY GO_EVP_PKEY; ++typedef EVP_PKEY_CTX GO_EVP_PKEY_CTX; ++ ++// Define pointers to all the used OpenSSL functions. ++// Calling C function pointers from Go is currently not supported. ++// It is possible to circumvent this by using a C function wrapper. ++// https://pkg.go.dev/cmd/cgo ++#define DEFINEFUNC(ret, func, args, argscall) \ ++ extern ret (*_g_##func)args; \ ++ static inline ret _goboringcrypto_##func args \ ++ { \ ++ return _g_##func argscall; \ ++ } ++#define DEFINEFUNCINTERNAL(ret, func, args, argscall) \ ++ extern ret (*_g_internal_##func)args; \ ++ static inline ret _goboringcrypto_internal_##func args \ ++ { \ ++ return _g_internal_##func argscall; \ ++ } ++#define DEFINEFUNC_LEGACY(ret, func, args, argscall) \ ++ DEFINEFUNCINTERNAL(ret, func, args, argscall) ++#define DEFINEFUNC_110(ret, func, args, argscall) \ ++ DEFINEFUNCINTERNAL(ret, func, args, argscall) ++#define DEFINEFUNC_RENAMED(ret, func, oldfunc, args, argscall) \ ++ DEFINEFUNCINTERNAL(ret, func, args, argscall) ++#define DEFINEFUNC_FALLBACK(ret, func, args, argscall) \ ++ DEFINEFUNCINTERNAL(ret, func, args, argscall) ++ ++FOR_ALL_OPENSSL_FUNCTIONS ++ ++#undef DEFINEFUNC ++#undef DEFINEFUNCINTERNAL ++#undef DEFINEFUNC_LEGACY ++#undef DEFINEFUNC_110 ++#undef DEFINEFUNC_RENAMED ++#undef DEFINEFUNC_FALLBACK ++ ++static inline void ++_goboringcrypto_EVP_AES_ctr128_enc(EVP_CIPHER_CTX *ctx, const uint8_t *in, uint8_t *out, size_t in_len) ++{ ++ int len; ++ _goboringcrypto_EVP_EncryptUpdate(ctx, out, &len, in, in_len); ++} ++ ++static inline int ++_goboringcrypto_HMAC_CTX_copy_ex(GO_HMAC_CTX *dest, const GO_HMAC_CTX *src) ++{ ++ return _goboringcrypto_HMAC_CTX_copy(dest, (GO_HMAC_CTX *) src); ++} ++ ++static inline int ++_goboringcrypto_EVP_MD_type(const GO_EVP_MD *md) ++{ ++ return _goboringcrypto_internal_EVP_MD_get_type(md); ++} ++ ++static inline const GO_EVP_MD* ++_goboringcrypto_EVP_md5_sha1(void) ++{ ++ return _goboringcrypto_internal_EVP_md5_sha1(); ++} ++ ++static inline void ++_goboringcrypto_HMAC_CTX_free(HMAC_CTX *ctx) ++{ ++ _goboringcrypto_internal_HMAC_CTX_free(ctx); ++} ++ ++static inline size_t ++_goboringcrypto_HMAC_size(const GO_HMAC_CTX* arg0) ++{ ++ const EVP_MD* md = _goboringcrypto_internal_HMAC_CTX_get_md(arg0); ++ return _goboringcrypto_internal_EVP_MD_get_size(md); ++} ++ ++static inline GO_HMAC_CTX* ++_goboringcrypto_HMAC_CTX_new(void) ++{ ++ return _goboringcrypto_internal_HMAC_CTX_new(); ++} ++ ++static inline void ++_goboringcrypto_HMAC_CTX_reset(GO_HMAC_CTX* ctx) ++{ ++ _goboringcrypto_internal_HMAC_CTX_reset(ctx); ++} ++ ++static inline unsigned int ++_goboringcrypto_BN_num_bytes(const GO_BIGNUM* a) ++{ ++ return ((_goboringcrypto_internal_BN_num_bits(a)+7)/8); ++} ++ ++static inline int ++_goboringcrypto_RSA_set0_factors(GO_RSA * r, GO_BIGNUM *p, GO_BIGNUM *q) ++{ ++ return _goboringcrypto_internal_RSA_set0_factors(r, p, q); ++} ++ ++static inline int ++_goboringcrypto_RSA_set0_crt_params(GO_RSA * r, GO_BIGNUM *dmp1, GO_BIGNUM *dmq1, GO_BIGNUM *iqmp) ++{ ++ return _goboringcrypto_internal_RSA_set0_crt_params(r, dmp1, dmq1, iqmp); ++} ++ ++static inline void ++_goboringcrypto_RSA_get0_crt_params(const GO_RSA *r, const GO_BIGNUM **dmp1, const GO_BIGNUM **dmq1, const GO_BIGNUM **iqmp) ++{ ++ _goboringcrypto_internal_RSA_get0_crt_params(r, dmp1, dmq1, iqmp); ++} ++ ++static inline int ++_goboringcrypto_RSA_set0_key(GO_RSA * r, GO_BIGNUM *n, GO_BIGNUM *e, GO_BIGNUM *d) ++{ ++ return _goboringcrypto_internal_RSA_set0_key(r, n, e, d); ++} ++ ++static inline void ++_goboringcrypto_RSA_get0_factors(const GO_RSA *rsa, const GO_BIGNUM **p, const GO_BIGNUM **q) ++{ ++ _goboringcrypto_internal_RSA_get0_factors(rsa, p, q); ++} ++ ++static inline void ++_goboringcrypto_RSA_get0_key(const GO_RSA *rsa, const GO_BIGNUM **n, const GO_BIGNUM **e, const GO_BIGNUM **d) ++{ ++ _goboringcrypto_internal_RSA_get0_key(rsa, n, e, d); ++} ++ ++static inline int ++_goboringcrypto_EVP_PKEY_CTX_set_rsa_padding(GO_EVP_PKEY_CTX* ctx, int pad) ++{ ++ return _goboringcrypto_internal_RSA_pkey_ctx_ctrl(ctx, -1, EVP_PKEY_CTRL_RSA_PADDING, pad, NULL); ++} ++ ++static inline int ++_goboringcrypto_EVP_PKEY_CTX_set0_rsa_oaep_label(GO_EVP_PKEY_CTX *ctx, uint8_t *l, int llen) ++{ ++ return _goboringcrypto_internal_EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, EVP_PKEY_CTRL_RSA_OAEP_LABEL, llen, (void *)l); ++} ++ ++static inline int ++_goboringcrypto_EVP_PKEY_CTX_set_rsa_oaep_md(GO_EVP_PKEY_CTX *ctx, const GO_EVP_MD *md) ++{ ++ return _goboringcrypto_internal_EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, EVP_PKEY_CTRL_RSA_OAEP_MD, 0, (void *)md); ++} ++ ++static inline int ++_goboringcrypto_EVP_PKEY_CTX_set_rsa_pss_saltlen(GO_EVP_PKEY_CTX * arg0, int arg1) ++{ ++ return _goboringcrypto_internal_EVP_PKEY_CTX_ctrl(arg0, EVP_PKEY_RSA, ++ (EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), ++ EVP_PKEY_CTRL_RSA_PSS_SALTLEN, ++ arg1, NULL); ++} ++ ++static inline int ++_goboringcrypto_EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) ++{ ++ return _goboringcrypto_internal_EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, EVP_PKEY_CTRL_MD, 0, (void *)md); ++} +diff --git a/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/hmac.go b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/hmac.go +new file mode 100644 +index 0000000000..0582201ac9 +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/hmac.go +@@ -0,0 +1,162 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++//go:build linux && !android ++// +build linux,!android ++ ++package openssl ++ ++// #include "goopenssl.h" ++import "C" ++import ( ++ "crypto" ++ "hash" ++ "runtime" ++ "unsafe" ++) ++ ++// hashToMD converts a hash.Hash implementation from this package ++// to a BoringCrypto *C.GO_EVP_MD. ++func hashToMD(h hash.Hash) *C.GO_EVP_MD { ++ switch h.(type) { ++ case *sha1Hash: ++ return C._goboringcrypto_EVP_sha1() ++ case *sha224Hash: ++ return C._goboringcrypto_EVP_sha224() ++ case *sha256Hash: ++ return C._goboringcrypto_EVP_sha256() ++ case *sha384Hash: ++ return C._goboringcrypto_EVP_sha384() ++ case *sha512Hash: ++ return C._goboringcrypto_EVP_sha512() ++ } ++ return nil ++} ++ ++// cryptoHashToMD converts a crypto.Hash ++// to a BoringCrypto *C.GO_EVP_MD. ++func cryptoHashToMD(ch crypto.Hash) *C.GO_EVP_MD { ++ switch ch { ++ case crypto.MD5: ++ return C._goboringcrypto_EVP_md5() ++ case crypto.MD5SHA1: ++ return C._goboringcrypto_EVP_md5_sha1() ++ case crypto.SHA1: ++ return C._goboringcrypto_EVP_sha1() ++ case crypto.SHA224: ++ return C._goboringcrypto_EVP_sha224() ++ case crypto.SHA256: ++ return C._goboringcrypto_EVP_sha256() ++ case crypto.SHA384: ++ return C._goboringcrypto_EVP_sha384() ++ case crypto.SHA512: ++ return C._goboringcrypto_EVP_sha512() ++ } ++ return nil ++} ++ ++// NewHMAC returns a new HMAC using BoringCrypto. ++// The function h must return a hash implemented by ++// BoringCrypto (for example, h could be boring.NewSHA256). ++// If h is not recognized, NewHMAC returns nil. ++func NewHMAC(h func() hash.Hash, key []byte) hash.Hash { ++ ch := h() ++ md := hashToMD(ch) ++ if md == nil { ++ return nil ++ } ++ ++ var hkey []byte ++ if key != nil && len(key) > 0 { ++ // Note: Could hash down long keys here using EVP_Digest. ++ hkey = make([]byte, len(key)) ++ copy(hkey, key) ++ } else { ++ // This is supported in BoringSSL/Standard lib and as such ++ // we must support it here. When using HMAC with a null key ++ // HMAC_Init will try and reuse the key from the ctx. This is ++ // not the bahavior previously implemented, so as a workaround ++ // we pass an "empty" key. ++ hkey = make([]byte, C.EVP_MAX_MD_SIZE) ++ } ++ hmac := &boringHMAC{ ++ md: md, ++ size: ch.Size(), ++ blockSize: ch.BlockSize(), ++ key: hkey, ++ ctx: C._goboringcrypto_HMAC_CTX_new(), ++ } ++ hmac.Reset() ++ return hmac ++} ++ ++type boringHMAC struct { ++ md *C.GO_EVP_MD ++ ctx *C.GO_HMAC_CTX ++ ctx2 *C.GO_HMAC_CTX ++ size int ++ blockSize int ++ key []byte ++ sum []byte ++ needCleanup bool ++} ++ ++func (h *boringHMAC) Reset() { ++ if !h.needCleanup { ++ h.needCleanup = true ++ // Note: Because of the finalizer, any time h.ctx is passed to cgo, ++ // that call must be followed by a call to runtime.KeepAlive(h), ++ // to make sure h is not collected (and finalized) before the cgo ++ // call returns. ++ runtime.SetFinalizer(h, (*boringHMAC).finalize) ++ } ++ C._goboringcrypto_HMAC_CTX_reset(h.ctx) ++ ++ if C._goboringcrypto_HMAC_Init_ex(h.ctx, unsafe.Pointer(base(h.key)), C.int(len(h.key)), h.md, nil) == 0 { ++ panic("boringcrypto: HMAC_Init failed") ++ } ++ if int(C._goboringcrypto_HMAC_size(h.ctx)) != h.size { ++ println("boringcrypto: HMAC size:", C._goboringcrypto_HMAC_size(h.ctx), "!=", h.size) ++ panic("boringcrypto: HMAC size mismatch") ++ } ++ runtime.KeepAlive(h) // Next line will keep h alive too; just making doubly sure. ++ h.sum = nil ++} ++ ++func (h *boringHMAC) finalize() { ++ C._goboringcrypto_HMAC_CTX_free(h.ctx) ++} ++ ++func (h *boringHMAC) Write(p []byte) (int, error) { ++ if len(p) > 0 { ++ C._goboringcrypto_HMAC_Update(h.ctx, (*C.uint8_t)(unsafe.Pointer(&p[0])), C.size_t(len(p))) ++ } ++ runtime.KeepAlive(h) ++ return len(p), nil ++} ++ ++func (h *boringHMAC) Size() int { ++ return h.size ++} ++ ++func (h *boringHMAC) BlockSize() int { ++ return h.blockSize ++} ++ ++func (h *boringHMAC) Sum(in []byte) []byte { ++ if h.sum == nil { ++ size := h.Size() ++ h.sum = make([]byte, size) ++ } ++ // Make copy of context because Go hash.Hash mandates ++ // that Sum has no effect on the underlying stream. ++ // In particular it is OK to Sum, then Write more, then Sum again, ++ // and the second Sum acts as if the first didn't happen. ++ h.ctx2 = C._goboringcrypto_HMAC_CTX_new() ++ if C._goboringcrypto_HMAC_CTX_copy_ex(h.ctx2, h.ctx) == 0 { ++ panic("boringcrypto: HMAC_CTX_copy_ex failed") ++ } ++ C._goboringcrypto_HMAC_Final(h.ctx2, (*C.uint8_t)(unsafe.Pointer(&h.sum[0])), nil) ++ C._goboringcrypto_HMAC_CTX_free(h.ctx2) ++ return append(in, h.sum...) ++} +diff --git a/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/internal/subtle/aliasing.go b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/internal/subtle/aliasing.go +new file mode 100644 +index 0000000000..db09e4aae6 +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/internal/subtle/aliasing.go +@@ -0,0 +1,32 @@ ++// 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 subtle implements functions that are often useful in cryptographic ++// code but require careful thought to use correctly. ++// ++// This is a mirror of golang.org/x/crypto/internal/subtle. ++package subtle ++ ++import "unsafe" ++ ++// AnyOverlap reports whether x and y share memory at any (not necessarily ++// corresponding) index. The memory beyond the slice length is ignored. ++func AnyOverlap(x, y []byte) bool { ++ return len(x) > 0 && len(y) > 0 && ++ uintptr(unsafe.Pointer(&x[0])) <= uintptr(unsafe.Pointer(&y[len(y)-1])) && ++ uintptr(unsafe.Pointer(&y[0])) <= uintptr(unsafe.Pointer(&x[len(x)-1])) ++} ++ ++// InexactOverlap reports whether x and y share memory at any non-corresponding ++// index. The memory beyond the slice length is ignored. Note that x and y can ++// have different lengths and still not have any inexact overlap. ++// ++// InexactOverlap can be used to implement the requirements of the crypto/cipher ++// AEAD, Block, BlockMode and Stream interfaces. ++func InexactOverlap(x, y []byte) bool { ++ if len(x) == 0 || len(y) == 0 || &x[0] == &y[0] { ++ return false ++ } ++ return AnyOverlap(x, y) ++} +diff --git a/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/openssl.go b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/openssl.go +new file mode 100644 +index 0000000000..fe13f92531 +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/openssl.go +@@ -0,0 +1,107 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++//go:build linux && !android ++// +build linux,!android ++ ++// Package openssl provides access to OpenSSLCrypto implementation functions. ++// Check the constant Enabled to find out whether OpenSSLCrypto is available. ++// If OpenSSLCrypto is not available, the functions in this package all panic. ++package openssl ++ ++// #include "goopenssl.h" ++// #cgo LDFLAGS: -ldl ++import "C" ++import ( ++ "errors" ++ "math/big" ++ "runtime" ++ "strings" ++) ++ ++// Init loads and initializes OpenSSL. ++// It must be called before any other OpenSSL call. ++func Init() error { ++ runtime.LockOSThread() ++ defer runtime.UnlockOSThread() ++ ++ if C._goboringcrypto_DLOPEN_OPENSSL() == C.NULL { ++ return errors.New("boringcrypto: OpenSSL dlopen failed") ++ } ++ ++ if C._goboringcrypto_OPENSSL_setup() != 1 { ++ return errors.New("boringcrypto: OpenSSL setup failed") ++ } ++ return nil ++} ++ ++// FIPS returns true if OpenSSL is running in FIPS mode, else returns false. ++func FIPS() bool { ++ return C._goboringcrypto_FIPS_mode() == 1 ++} ++ ++// SetFIPS enables or disables FIPS mode. ++func SetFIPS(enabled bool) error { ++ var mode C.int ++ if enabled { ++ mode = C.int(1) ++ } else { ++ mode = C.int(0) ++ } ++ if C._goboringcrypto_FIPS_mode_set(mode) != 1 { ++ return newOpenSSLError("boringcrypto: set FIPS mode") ++ } ++ return nil ++} ++ ++func newOpenSSLError(msg string) error { ++ var b strings.Builder ++ var e C.ulong ++ ++ b.WriteString(msg) ++ b.WriteString("\nopenssl error(s):\n") ++ ++ for { ++ e = C._goboringcrypto_ERR_get_error() ++ if e == 0 { ++ break ++ } ++ var buf [256]byte ++ C._goboringcrypto_ERR_error_string_n(e, base(buf[:]), 256) ++ b.Write(buf[:]) ++ b.WriteByte('\n') ++ } ++ return errors.New(b.String()) ++} ++ ++type fail string ++ ++func (e fail) Error() string { return "boringcrypto: " + string(e) + " failed" } ++ ++func bigToBN(x *big.Int) *C.GO_BIGNUM { ++ raw := x.Bytes() ++ return C._goboringcrypto_BN_bin2bn(base(raw), C.size_t(len(raw)), nil) ++} ++ ++func bnToBig(bn *C.GO_BIGNUM) *big.Int { ++ raw := make([]byte, C._goboringcrypto_BN_num_bytes(bn)) ++ n := C._goboringcrypto_BN_bn2bin(bn, base(raw)) ++ return new(big.Int).SetBytes(raw[:n]) ++} ++ ++func bigToBn(bnp **C.GO_BIGNUM, b *big.Int) bool { ++ if *bnp != nil { ++ C._goboringcrypto_BN_free(*bnp) ++ *bnp = nil ++ } ++ if b == nil { ++ return true ++ } ++ raw := b.Bytes() ++ bn := C._goboringcrypto_BN_bin2bn(base(raw), C.size_t(len(raw)), nil) ++ if bn == nil { ++ return false ++ } ++ *bnp = bn ++ return true ++} +diff --git a/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/openssl_funcs.h b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/openssl_funcs.h +new file mode 100644 +index 0000000000..bec47b8783 +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/openssl_funcs.h +@@ -0,0 +1,215 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++#include // size_t ++#include // uint8_t ++ ++// List of all functions from the libcrypto that are used in the crypto/internal/boring. ++// Forgetting to add a function here results in build failure with message reporting the function ++// that needs to be added. ++// ++// The purpose of FOR_ALL_OPENSSL_FUNCTIONS is to define all libcrypto functions ++// without depending on the openssl headers so it is easier to use this package ++// with an openssl version different that the one used at build time. ++// ++// The following macros may not be defined at this point, ++// they are not resolved here but just accumulated in FOR_ALL_OPENSSL_FUNCTIONS. ++// ++// DEFINEFUNC defines and loads openssl functions that can be directly called from Go as their signatures match ++// the boringssl and do not require special logic. ++// The process will be aborted if the function can't be loaded. ++// ++// DEFINEFUNCINTERNAL defines and loads openssl functions that will be wrapped due to signature incompatibility or ++// because it does not exist in all supported openssl versions. ++// The process will be aborted if the function can't be loaded. ++// ++// DEFINEFUNC_LEGACY acts like DEFINEFUNCINTERNAL but only aborts the process if the function can't be loaded ++// when using 1.0.x. This indicates the function is required when using 1.0.x, but is unused when using later versions. ++// It also might not exist in later versions. ++// ++// DEFINEFUNC_110 acts like DEFINEFUNCINTERNAL but only aborts the process if function can't be loaded ++// when using 1.1.0 or higher. ++// ++// DEFINEFUNC_RENAMED acts like DEFINEFUNCINTERNAL but if the function can't be loaded it will try with another ++// function name, as in some version jumps openssl has renamed functions without changing the signature. ++// The process will be aborted if neither function can be loaded. ++// ++#define FOR_ALL_OPENSSL_FUNCTIONS \ ++DEFINEFUNC(unsigned long, ERR_get_error, (void), ()) \ ++DEFINEFUNC(void, ERR_error_string_n, (unsigned long e, unsigned char *buf, size_t len), (e, buf, len)) \ ++DEFINEFUNCINTERNAL(int, RAND_poll, (void), ()) \ ++DEFINEFUNCINTERNAL(void, OPENSSL_init, (void), ()) \ ++DEFINEFUNC_LEGACY(void, ERR_load_crypto_strings, (void), ()) \ ++DEFINEFUNC_LEGACY(int, CRYPTO_num_locks, (void), ()) \ ++DEFINEFUNC_LEGACY(void, CRYPTO_set_id_callback, (unsigned long (*id_function)(void)), (id_function)) \ ++DEFINEFUNC_LEGACY(void, CRYPTO_set_locking_callback, \ ++ (void (*locking_function)(int mode, int n, const char *file, int line)), \ ++ (locking_function)) \ ++DEFINEFUNC_LEGACY(void, OPENSSL_add_all_algorithms_conf, (void), ()) \ ++DEFINEFUNC_110(int, OPENSSL_init_crypto, (uint64_t ops, const void *settings), (ops, settings)) \ ++DEFINEFUNC(int, FIPS_mode, (void), ()) \ ++DEFINEFUNC(int, FIPS_mode_set, (int r), (r)) \ ++DEFINEFUNC(int, RAND_bytes, (uint8_t * arg0, size_t arg1), (arg0, arg1)) \ ++DEFINEFUNC(int, SHA1_Init, (GO_SHA_CTX * arg0), (arg0)) \ ++DEFINEFUNC(int, SHA1_Update, (GO_SHA_CTX * arg0, const void *arg1, size_t arg2), (arg0, arg1, arg2)) \ ++DEFINEFUNC(int, SHA1_Final, (uint8_t * arg0, GO_SHA_CTX *arg1), (arg0, arg1)) \ ++DEFINEFUNC(int, SHA224_Init, (GO_SHA256_CTX * arg0), (arg0)) \ ++DEFINEFUNC(int, SHA224_Update, (GO_SHA256_CTX * arg0, const void *arg1, size_t arg2), (arg0, arg1, arg2)) \ ++DEFINEFUNC(int, SHA224_Final, (uint8_t * arg0, GO_SHA256_CTX *arg1), (arg0, arg1)) \ ++DEFINEFUNC(int, SHA256_Init, (GO_SHA256_CTX * arg0), (arg0)) \ ++DEFINEFUNC(int, SHA256_Update, (GO_SHA256_CTX * arg0, const void *arg1, size_t arg2), (arg0, arg1, arg2)) \ ++DEFINEFUNC(int, SHA256_Final, (uint8_t * arg0, GO_SHA256_CTX *arg1), (arg0, arg1)) \ ++DEFINEFUNC(int, SHA384_Init, (GO_SHA512_CTX * arg0), (arg0)) \ ++DEFINEFUNC(int, SHA384_Update, (GO_SHA512_CTX * arg0, const void *arg1, size_t arg2), (arg0, arg1, arg2)) \ ++DEFINEFUNC(int, SHA384_Final, (uint8_t * arg0, GO_SHA512_CTX *arg1), (arg0, arg1)) \ ++DEFINEFUNC(int, SHA512_Init, (GO_SHA512_CTX * arg0), (arg0)) \ ++DEFINEFUNC(int, SHA512_Update, (GO_SHA512_CTX * arg0, const void *arg1, size_t arg2), (arg0, arg1, arg2)) \ ++DEFINEFUNC(int, SHA512_Final, (uint8_t * arg0, GO_SHA512_CTX *arg1), (arg0, arg1)) \ ++DEFINEFUNC(const GO_EVP_MD *, EVP_md5, (void), ()) \ ++DEFINEFUNC(const GO_EVP_MD *, EVP_sha1, (void), ()) \ ++DEFINEFUNC(const GO_EVP_MD *, EVP_sha224, (void), ()) \ ++DEFINEFUNC(const GO_EVP_MD *, EVP_sha256, (void), ()) \ ++DEFINEFUNC(const GO_EVP_MD *, EVP_sha384, (void), ()) \ ++DEFINEFUNC(const GO_EVP_MD *, EVP_sha512, (void), ()) \ ++DEFINEFUNC_RENAMED(int, EVP_MD_get_type, EVP_MD_type, (const GO_EVP_MD *arg0), (arg0)) \ ++DEFINEFUNC_RENAMED(size_t, EVP_MD_get_size, EVP_MD_size, (const GO_EVP_MD *arg0), (arg0)) \ ++DEFINEFUNC_FALLBACK(const GO_EVP_MD*, EVP_md5_sha1, (void), ()) \ ++DEFINEFUNC_FALLBACK(void*, EVP_MD_CTX_md_data, (EVP_MD_CTX *ctx), (ctx)) \ ++DEFINEFUNCINTERNAL(int, MD5_Init, (MD5_CTX *c), (c)) \ ++DEFINEFUNCINTERNAL(int, MD5_Update, (MD5_CTX *c, const void *data, size_t len), (c, data, len)) \ ++DEFINEFUNCINTERNAL(int, MD5_Final, (unsigned char *md, MD5_CTX *c), (md, c)) \ ++DEFINEFUNC_LEGACY(void, HMAC_CTX_init, (GO_HMAC_CTX * arg0), (arg0)) \ ++DEFINEFUNC_LEGACY(void, HMAC_CTX_cleanup, (GO_HMAC_CTX * arg0), (arg0)) \ ++DEFINEFUNC(int, HMAC_Init_ex, \ ++ (GO_HMAC_CTX * arg0, const void *arg1, int arg2, const GO_EVP_MD *arg3, ENGINE *arg4), \ ++ (arg0, arg1, arg2, arg3, arg4)) \ ++DEFINEFUNC(int, HMAC_Update, (GO_HMAC_CTX * arg0, const uint8_t *arg1, size_t arg2), (arg0, arg1, arg2)) \ ++DEFINEFUNC(int, HMAC_Final, (GO_HMAC_CTX * arg0, uint8_t *arg1, unsigned int *arg2), (arg0, arg1, arg2)) \ ++DEFINEFUNC(size_t, HMAC_CTX_copy, (GO_HMAC_CTX *dest, GO_HMAC_CTX *src), (dest, src)) \ ++DEFINEFUNC_FALLBACK(void, HMAC_CTX_free, (GO_HMAC_CTX * arg0), (arg0)) \ ++DEFINEFUNC_FALLBACK(const EVP_MD*, HMAC_CTX_get_md, (const GO_HMAC_CTX* ctx), (ctx)) \ ++DEFINEFUNC_FALLBACK(GO_HMAC_CTX*, HMAC_CTX_new, (void), ()) \ ++DEFINEFUNC_FALLBACK(void, HMAC_CTX_reset, (GO_HMAC_CTX * arg0), (arg0)) \ ++DEFINEFUNC(EVP_CIPHER_CTX *, EVP_CIPHER_CTX_new, (void), ()) \ ++DEFINEFUNC(int, EVP_CIPHER_CTX_set_padding, (EVP_CIPHER_CTX *x, int padding), (x, padding)) \ ++DEFINEFUNC(int, EVP_CipherInit_ex, \ ++ (EVP_CIPHER_CTX * ctx, const EVP_CIPHER *type, ENGINE *impl, const unsigned char *key, const unsigned char *iv, int enc), \ ++ (ctx, type, impl, key, iv, enc)) \ ++DEFINEFUNC(int, EVP_CipherUpdate, \ ++ (EVP_CIPHER_CTX * ctx, unsigned char *out, int *outl, const unsigned char *in, int inl), \ ++ (ctx, out, outl, in, inl)) \ ++DEFINEFUNC(GO_BIGNUM *, BN_new, (void), ()) \ ++DEFINEFUNC(void, BN_free, (GO_BIGNUM * arg0), (arg0)) \ ++DEFINEFUNCINTERNAL(void, BN_clear_free, (GO_BIGNUM * arg0), (arg0)) \ ++DEFINEFUNC(int, BN_set_word, (GO_BIGNUM *a, BN_ULONG w), (a, w)) \ ++DEFINEFUNCINTERNAL(unsigned int, BN_num_bits, (const GO_BIGNUM *arg0), (arg0)) \ ++DEFINEFUNC(GO_BIGNUM *, BN_bin2bn, (const uint8_t *arg0, size_t arg1, GO_BIGNUM *arg2), (arg0, arg1, arg2)) \ ++DEFINEFUNC(size_t, BN_bn2bin, (const GO_BIGNUM *arg0, uint8_t *arg1), (arg0, arg1)) \ ++DEFINEFUNC(void, EC_GROUP_free, (GO_EC_GROUP * arg0), (arg0)) \ ++DEFINEFUNC(GO_EC_POINT *, EC_POINT_new, (const GO_EC_GROUP *arg0), (arg0)) \ ++DEFINEFUNC(void, EC_POINT_free, (GO_EC_POINT * arg0), (arg0)) \ ++DEFINEFUNC(int, EC_POINT_get_affine_coordinates_GFp, \ ++ (const GO_EC_GROUP *arg0, const GO_EC_POINT *arg1, GO_BIGNUM *arg2, GO_BIGNUM *arg3, GO_BN_CTX *arg4), \ ++ (arg0, arg1, arg2, arg3, arg4)) \ ++DEFINEFUNC(int, EC_POINT_set_affine_coordinates_GFp, \ ++ (const GO_EC_GROUP *arg0, GO_EC_POINT *arg1, const GO_BIGNUM *arg2, const GO_BIGNUM *arg3, GO_BN_CTX *arg4), \ ++ (arg0, arg1, arg2, arg3, arg4)) \ ++DEFINEFUNC(GO_EC_KEY *, EC_KEY_new_by_curve_name, (int arg0), (arg0)) \ ++DEFINEFUNC(void, EC_KEY_free, (GO_EC_KEY * arg0), (arg0)) \ ++DEFINEFUNC(const GO_EC_GROUP *, EC_KEY_get0_group, (const GO_EC_KEY *arg0), (arg0)) \ ++DEFINEFUNC(int, EC_KEY_generate_key, (GO_EC_KEY * arg0), (arg0)) \ ++DEFINEFUNC(int, EC_KEY_set_private_key, (GO_EC_KEY * arg0, const GO_BIGNUM *arg1), (arg0, arg1)) \ ++DEFINEFUNC(int, EC_KEY_set_public_key, (GO_EC_KEY * arg0, const GO_EC_POINT *arg1), (arg0, arg1)) \ ++DEFINEFUNC(const GO_BIGNUM *, EC_KEY_get0_private_key, (const GO_EC_KEY *arg0), (arg0)) \ ++DEFINEFUNC(const GO_EC_POINT *, EC_KEY_get0_public_key, (const GO_EC_KEY *arg0), (arg0)) \ ++DEFINEFUNC(int, ECDSA_do_verify, (const uint8_t *arg0, size_t arg1, const GO_ECDSA_SIG *arg2, const GO_EC_KEY *arg3), (arg0, arg1, arg2, arg3)) \ ++DEFINEFUNC(size_t, ECDSA_size, (const GO_EC_KEY *arg0), (arg0)) \ ++DEFINEFUNC(int, ECDSA_sign, \ ++ (int type, const unsigned char *dgst, size_t dgstlen, unsigned char *sig, unsigned int *siglen, EC_KEY *eckey), \ ++ (type, dgst, dgstlen, sig, siglen, eckey)) \ ++DEFINEFUNC(int, ECDSA_verify, \ ++ (int type, const unsigned char *dgst, size_t dgstlen, const unsigned char *sig, unsigned int siglen, EC_KEY *eckey), \ ++ (type, dgst, dgstlen, sig, siglen, eckey)) \ ++DEFINEFUNC(GO_RSA *, RSA_new, (void), ()) \ ++DEFINEFUNC(void, RSA_free, (GO_RSA * arg0), (arg0)) \ ++DEFINEFUNC(int, RSA_sign, \ ++ (int arg0, const uint8_t *arg1, unsigned int arg2, uint8_t *arg3, unsigned int *arg4, GO_RSA *arg5), \ ++ (arg0, arg1, arg2, arg3, arg4, arg5)) \ ++DEFINEFUNC(int, RSA_verify, \ ++ (int arg0, const uint8_t *arg1, unsigned int arg2, const uint8_t *arg3, unsigned int arg4, GO_RSA *arg5), \ ++ (arg0, arg1, arg2, arg3, arg4, arg5)) \ ++DEFINEFUNC(int, RSA_private_encrypt, \ ++ (int flen, uint8_t *from, uint8_t *to, GO_RSA *rsa, int padding), \ ++ (flen, from, to, rsa, padding)) \ ++DEFINEFUNC(int, RSA_public_decrypt, \ ++ (int flen, uint8_t *from, uint8_t *to, GO_RSA *rsa, int padding), \ ++ (flen, from, to, rsa, padding)) \ ++DEFINEFUNC(int, RSA_generate_key_ex, \ ++ (GO_RSA * arg0, int arg1, GO_BIGNUM *arg2, GO_BN_GENCB *arg3), \ ++ (arg0, arg1, arg2, arg3)) \ ++DEFINEFUNC_FALLBACK(int, RSA_set0_factors, (GO_RSA * rsa, GO_BIGNUM *p, GO_BIGNUM *q), (rsa, p, q)) \ ++DEFINEFUNC_FALLBACK(int, RSA_set0_crt_params, \ ++ (GO_RSA * rsa, GO_BIGNUM *dmp1, GO_BIGNUM *dmp2, GO_BIGNUM *iqmp), \ ++ (rsa, dmp1, dmp2, iqmp)) \ ++DEFINEFUNC_FALLBACK(void, RSA_get0_crt_params, \ ++ (const GO_RSA *r, const GO_BIGNUM **dmp1, const GO_BIGNUM **dmq1, const GO_BIGNUM **iqmp), \ ++ (r, dmp1, dmq1, iqmp)) \ ++DEFINEFUNC_FALLBACK(int, RSA_set0_key, (GO_RSA * r, GO_BIGNUM *n, GO_BIGNUM *e, GO_BIGNUM *d), (r, n, e, d)) \ ++DEFINEFUNC_FALLBACK(void, RSA_get0_factors, (const GO_RSA *rsa, const GO_BIGNUM **p, const GO_BIGNUM **q), (rsa, p, q)) \ ++DEFINEFUNC_FALLBACK(void, RSA_get0_key, \ ++ (const GO_RSA *rsa, const GO_BIGNUM **n, const GO_BIGNUM **e, const GO_BIGNUM **d), \ ++ (rsa, n, e, d)) \ ++DEFINEFUNC(unsigned int, RSA_size, (const GO_RSA *arg0), (arg0)) \ ++DEFINEFUNC(int, EVP_EncryptInit_ex, \ ++ (EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, ENGINE *impl, const unsigned char *key, const unsigned char *iv), \ ++ (ctx, type, impl, key, iv)) \ ++DEFINEFUNC(int, EVP_EncryptUpdate, \ ++ (EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl), \ ++ (ctx, out, outl, in, inl)) \ ++DEFINEFUNC(int, EVP_EncryptFinal_ex, \ ++ (EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl), \ ++ (ctx, out, outl)) \ ++DEFINEFUNC(int, EVP_DecryptUpdate, \ ++ (EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl), (ctx, out, outl, in, inl)) \ ++DEFINEFUNC(int, EVP_DecryptFinal_ex, (EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl), (ctx, outm, outl)) \ ++DEFINEFUNC(const EVP_CIPHER*, EVP_aes_128_gcm, (void), ()) \ ++DEFINEFUNC(const EVP_CIPHER*, EVP_aes_128_cbc, (void), ()) \ ++DEFINEFUNC(const EVP_CIPHER*, EVP_aes_128_ctr, (void), ()) \ ++DEFINEFUNC(const EVP_CIPHER*, EVP_aes_128_ecb, (void), ()) \ ++DEFINEFUNC(const EVP_CIPHER*, EVP_aes_192_gcm, (void), ()) \ ++DEFINEFUNC(const EVP_CIPHER*, EVP_aes_192_cbc, (void), ()) \ ++DEFINEFUNC(const EVP_CIPHER*, EVP_aes_192_ctr, (void), ()) \ ++DEFINEFUNC(const EVP_CIPHER*, EVP_aes_192_ecb, (void), ()) \ ++DEFINEFUNC(const EVP_CIPHER*, EVP_aes_256_cbc, (void), ()) \ ++DEFINEFUNC(const EVP_CIPHER*, EVP_aes_256_ctr, (void), ()) \ ++DEFINEFUNC(const EVP_CIPHER*, EVP_aes_256_ecb, (void), ()) \ ++DEFINEFUNC(const EVP_CIPHER*, EVP_aes_256_gcm, (void), ()) \ ++DEFINEFUNC(void, EVP_CIPHER_CTX_free, (EVP_CIPHER_CTX* arg0), (arg0)) \ ++DEFINEFUNC(int, EVP_CIPHER_CTX_ctrl, (EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr), (ctx, type, arg, ptr)) \ ++DEFINEFUNC(GO_EVP_PKEY *, EVP_PKEY_new, (void), ()) \ ++DEFINEFUNC(void, EVP_PKEY_free, (GO_EVP_PKEY * arg0), (arg0)) \ ++DEFINEFUNC(int, EVP_PKEY_set1_RSA, (GO_EVP_PKEY * arg0, GO_RSA *arg1), (arg0, arg1)) \ ++DEFINEFUNC(int, EVP_PKEY_verify, \ ++ (GO_EVP_PKEY_CTX *ctx, const uint8_t *sig, unsigned int siglen, const uint8_t *tbs, unsigned int tbslen), \ ++ (ctx, sig, siglen, tbs, tbslen)) \ ++DEFINEFUNC(GO_EVP_PKEY_CTX *, EVP_PKEY_CTX_new, (GO_EVP_PKEY * arg0, ENGINE *arg1), (arg0, arg1)) \ ++DEFINEFUNC(void, EVP_PKEY_CTX_free, (GO_EVP_PKEY_CTX * arg0), (arg0)) \ ++DEFINEFUNCINTERNAL(int, EVP_PKEY_CTX_ctrl, \ ++ (GO_EVP_PKEY_CTX * ctx, int keytype, int optype, int cmd, int p1, void *p2), \ ++ (ctx, keytype, optype, cmd, p1, p2)) \ ++DEFINEFUNC_FALLBACK(int, RSA_pkey_ctx_ctrl, \ ++ (GO_EVP_PKEY_CTX *ctx, int optype, int cmd, int p1, void *p2), \ ++ (ctx, optype, cmd, p1, p2)) \ ++DEFINEFUNC(int, EVP_PKEY_decrypt, \ ++ (GO_EVP_PKEY_CTX * arg0, uint8_t *arg1, unsigned int *arg2, const uint8_t *arg3, unsigned int arg4), \ ++ (arg0, arg1, arg2, arg3, arg4)) \ ++DEFINEFUNC(int, EVP_PKEY_encrypt, \ ++ (GO_EVP_PKEY_CTX * arg0, uint8_t *arg1, unsigned int *arg2, const uint8_t *arg3, unsigned int arg4), \ ++ (arg0, arg1, arg2, arg3, arg4)) \ ++DEFINEFUNC(int, EVP_PKEY_decrypt_init, (GO_EVP_PKEY_CTX * arg0), (arg0)) \ ++DEFINEFUNC(int, EVP_PKEY_encrypt_init, (GO_EVP_PKEY_CTX * arg0), (arg0)) \ ++DEFINEFUNC(int, EVP_PKEY_sign_init, (GO_EVP_PKEY_CTX * arg0), (arg0)) \ ++DEFINEFUNC(int, EVP_PKEY_verify_init, (GO_EVP_PKEY_CTX * arg0), (arg0)) \ ++DEFINEFUNC(int, EVP_PKEY_sign, \ ++ (GO_EVP_PKEY_CTX * arg0, uint8_t *arg1, unsigned int *arg2, const uint8_t *arg3, unsigned int arg4), \ ++ (arg0, arg1, arg2, arg3, arg4)) +diff --git a/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/openssl_lock_setup.c b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/openssl_lock_setup.c +new file mode 100644 +index 0000000000..26ea3c3b99 +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/openssl_lock_setup.c +@@ -0,0 +1,53 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++//go:build linux && !android ++// +build linux,!android ++ ++#include "goopenssl.h" ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define _GNU_SOURCE ++#include ++ ++#define MUTEX_TYPE pthread_mutex_t ++#define MUTEX_SETUP(x) pthread_mutex_init(&(x), NULL) ++#define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x)) ++#define MUTEX_LOCK(x) pthread_mutex_lock(&(x)) ++#define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x)) ++#define THREAD_ID pthread_self() ++ ++/* This array will store all of the mutexes available to OpenSSL. */ ++static MUTEX_TYPE *mutex_buf = NULL; ++ ++static void locking_function(int mode, int n, const char *file, int line) ++{ ++ if(mode & CRYPTO_LOCK) ++ MUTEX_LOCK(mutex_buf[n]); ++ else ++ MUTEX_UNLOCK(mutex_buf[n]); ++} ++ ++static unsigned long id_function(void) ++{ ++ return ((unsigned long)syscall(__NR_gettid)); ++} ++ ++int _goboringcrypto_internal_OPENSSL_thread_setup(void) ++{ ++ int i; ++ ++ mutex_buf = malloc(_goboringcrypto_internal_CRYPTO_num_locks() * sizeof(MUTEX_TYPE)); ++ if(!mutex_buf) ++ return 0; ++ for(i = 0; i < _goboringcrypto_internal_CRYPTO_num_locks(); i++) ++ MUTEX_SETUP(mutex_buf[i]); ++ _goboringcrypto_internal_CRYPTO_set_id_callback(id_function); ++ _goboringcrypto_internal_CRYPTO_set_locking_callback(locking_function); ++ return 1; ++} +diff --git a/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/rand.go b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/rand.go +new file mode 100644 +index 0000000000..05d39f1d48 +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/rand.go +@@ -0,0 +1,24 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++//go:build linux && !android ++// +build linux,!android ++ ++package openssl ++ ++// #include "goopenssl.h" ++import "C" ++import "unsafe" ++ ++type randReader int ++ ++func (randReader) Read(b []byte) (int, error) { ++ // Note: RAND_bytes should never fail; the return value exists only for historical reasons. ++ // We check it even so. ++ if len(b) > 0 && C._goboringcrypto_RAND_bytes((*C.uint8_t)(unsafe.Pointer(&b[0])), C.size_t(len(b))) == 0 { ++ return 0, fail("RAND_bytes") ++ } ++ return len(b), nil ++} ++ ++const RandReader = randReader(0) +diff --git a/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/rsa.go b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/rsa.go +new file mode 100644 +index 0000000000..071cda557d +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/rsa.go +@@ -0,0 +1,397 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++//go:build linux && !android ++// +build linux,!android ++ ++package openssl ++ ++// #include "goopenssl.h" ++import "C" ++import ( ++ "crypto" ++ "crypto/subtle" ++ "errors" ++ "hash" ++ "math/big" ++ "runtime" ++ "strconv" ++ "unsafe" ++) ++ ++func GenerateKeyRSA(bits int) (N, E, D, P, Q, Dp, Dq, Qinv *big.Int, err error) { ++ bad := func(e error) (N, E, D, P, Q, Dp, Dq, Qinv *big.Int, err error) { ++ return nil, nil, nil, nil, nil, nil, nil, nil, e ++ } ++ ++ key := C._goboringcrypto_RSA_new() ++ if key == nil { ++ return bad(newOpenSSLError("RSA_new failed")) ++ } ++ defer C._goboringcrypto_RSA_free(key) ++ ++ bn := C._goboringcrypto_BN_new() ++ if bn == nil { ++ return bad(newOpenSSLError("BN_new failed")) ++ } ++ defer C._goboringcrypto_BN_free(bn) ++ ++ if C._goboringcrypto_BN_set_word(bn, C.RSA_F4) != C.int(1) { ++ return bad(newOpenSSLError("BN_set_word failed")) ++ } ++ if C._goboringcrypto_RSA_generate_key_ex(key, C.int(bits), bn, nil) != C.int(1) { ++ return bad(newOpenSSLError("RSA_generate_key_ex failed")) ++ } ++ ++ var n, e, d, p, q, dp, dq, qinv *C.GO_BIGNUM ++ C._goboringcrypto_RSA_get0_key(key, &n, &e, &d) ++ C._goboringcrypto_RSA_get0_factors(key, &p, &q) ++ C._goboringcrypto_RSA_get0_crt_params(key, &dp, &dq, &qinv) ++ return bnToBig(n), bnToBig(e), bnToBig(d), bnToBig(p), bnToBig(q), bnToBig(dp), bnToBig(dq), bnToBig(qinv), nil ++} ++ ++type PublicKeyRSA struct { ++ // _key MUST NOT be accessed directly. Instead, use the withKey method. ++ _key *C.GO_RSA ++} ++ ++func NewPublicKeyRSA(N, E *big.Int) (*PublicKeyRSA, error) { ++ key := C._goboringcrypto_RSA_new() ++ if key == nil { ++ return nil, newOpenSSLError("RSA_new failed") ++ } ++ var n, e *C.GO_BIGNUM ++ n = bigToBN(N) ++ e = bigToBN(E) ++ C._goboringcrypto_RSA_set0_key(key, n, e, nil) ++ k := &PublicKeyRSA{_key: key} ++ runtime.SetFinalizer(k, (*PublicKeyRSA).finalize) ++ return k, nil ++} ++ ++func (k *PublicKeyRSA) finalize() { ++ C._goboringcrypto_RSA_free(k._key) ++} ++ ++func (k *PublicKeyRSA) withKey(f func(*C.GO_RSA) C.int) C.int { ++ // Because of the finalizer, any time _key is passed to cgo, that call must ++ // be followed by a call to runtime.KeepAlive, to make sure k is not ++ // collected (and finalized) before the cgo call returns. ++ defer runtime.KeepAlive(k) ++ return f(k._key) ++} ++ ++type PrivateKeyRSA struct { ++ // _key MUST NOT be accessed directly. Instead, use the withKey method. ++ _key *C.GO_RSA ++} ++ ++func NewPrivateKeyRSA(N, E, D, P, Q, Dp, Dq, Qinv *big.Int) (*PrivateKeyRSA, error) { ++ key := C._goboringcrypto_RSA_new() ++ if key == nil { ++ return nil, newOpenSSLError("RSA_new failed") ++ } ++ var n, e, d, p, q, dp, dq, qinv *C.GO_BIGNUM ++ n = bigToBN(N) ++ e = bigToBN(E) ++ d = bigToBN(D) ++ C._goboringcrypto_RSA_set0_key(key, n, e, d) ++ if P != nil && Q != nil { ++ p = bigToBN(P) ++ q = bigToBN(Q) ++ C._goboringcrypto_RSA_set0_factors(key, p, q) ++ } ++ if Dp != nil && Dq != nil && Qinv != nil { ++ dp = bigToBN(Dp) ++ dq = bigToBN(Dq) ++ qinv = bigToBN(Qinv) ++ C._goboringcrypto_RSA_set0_crt_params(key, dp, dq, qinv) ++ } ++ k := &PrivateKeyRSA{_key: key} ++ runtime.SetFinalizer(k, (*PrivateKeyRSA).finalize) ++ return k, nil ++} ++ ++func (k *PrivateKeyRSA) finalize() { ++ C._goboringcrypto_RSA_free(k._key) ++} ++ ++func (k *PrivateKeyRSA) withKey(f func(*C.GO_RSA) C.int) C.int { ++ // Because of the finalizer, any time _key is passed to cgo, that call must ++ // be followed by a call to runtime.KeepAlive, to make sure k is not ++ // collected (and finalized) before the cgo call returns. ++ defer runtime.KeepAlive(k) ++ return f(k._key) ++} ++ ++func setupRSA(withKey func(func(*C.GO_RSA) C.int) C.int, ++ padding C.int, h hash.Hash, label []byte, saltLen int, ch crypto.Hash, ++ init func(*C.GO_EVP_PKEY_CTX) C.int) (pkey *C.GO_EVP_PKEY, ctx *C.GO_EVP_PKEY_CTX, err error) { ++ defer func() { ++ if err != nil { ++ if pkey != nil { ++ C._goboringcrypto_EVP_PKEY_free(pkey) ++ pkey = nil ++ } ++ if ctx != nil { ++ C._goboringcrypto_EVP_PKEY_CTX_free(ctx) ++ ctx = nil ++ } ++ } ++ }() ++ ++ pkey = C._goboringcrypto_EVP_PKEY_new() ++ if pkey == nil { ++ return nil, nil, newOpenSSLError("EVP_PKEY_new failed") ++ } ++ if withKey(func(key *C.GO_RSA) C.int { ++ return C._goboringcrypto_EVP_PKEY_set1_RSA(pkey, key) ++ }) == 0 { ++ return nil, nil, fail("EVP_PKEY_set1_RSA") ++ } ++ ctx = C._goboringcrypto_EVP_PKEY_CTX_new(pkey, nil) ++ if ctx == nil { ++ return nil, nil, newOpenSSLError("EVP_PKEY_CTX_new failed") ++ } ++ if init(ctx) == 0 { ++ return nil, nil, newOpenSSLError("EVP_PKEY_operation_init failed") ++ } ++ if C._goboringcrypto_EVP_PKEY_CTX_set_rsa_padding(ctx, padding) == 0 { ++ return nil, nil, newOpenSSLError("EVP_PKEY_CTX_set_rsa_padding failed") ++ } ++ if padding == C.GO_RSA_PKCS1_OAEP_PADDING { ++ md := hashToMD(h) ++ if md == nil { ++ return nil, nil, errors.New("crypto/rsa: unsupported hash function") ++ } ++ if C._goboringcrypto_EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md) == 0 { ++ return nil, nil, newOpenSSLError("EVP_PKEY_set_rsa_oaep_md failed") ++ } ++ // ctx takes ownership of label, so malloc a copy for BoringCrypto to free. ++ clabel := (*C.uint8_t)(C.malloc(C.size_t(len(label)))) ++ if clabel == nil { ++ return nil, nil, fail("OPENSSL_malloc") ++ } ++ copy((*[1 << 30]byte)(unsafe.Pointer(clabel))[:len(label)], label) ++ if C._goboringcrypto_EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, clabel, C.int(len(label))) == 0 { ++ return nil, nil, newOpenSSLError("EVP_PKEY_CTX_set0_rsa_oaep_label failed") ++ } ++ } ++ if padding == C.GO_RSA_PKCS1_PSS_PADDING { ++ if saltLen != 0 { ++ if C._goboringcrypto_EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, C.int(saltLen)) == 0 { ++ return nil, nil, newOpenSSLError("EVP_PKEY_set_rsa_pss_saltlen failed") ++ } ++ } ++ md := cryptoHashToMD(ch) ++ if md == nil { ++ return nil, nil, errors.New("crypto/rsa: unsupported hash function") ++ } ++ if C._goboringcrypto_EVP_PKEY_CTX_set_signature_md(ctx, md) == 0 { ++ return nil, nil, newOpenSSLError("EVP_PKEY_CTX_set_signature_md failed") ++ } ++ } ++ ++ return pkey, ctx, nil ++} ++ ++func cryptRSA(withKey func(func(*C.GO_RSA) C.int) C.int, ++ padding C.int, h hash.Hash, label []byte, saltLen int, ch crypto.Hash, ++ init func(*C.GO_EVP_PKEY_CTX) C.int, ++ crypt func(*C.GO_EVP_PKEY_CTX, *C.uint8_t, *C.uint, *C.uint8_t, C.uint) C.int, ++ out, in []byte) ([]byte, error) { ++ ++ pkey, ctx, err := setupRSA(withKey, padding, h, label, saltLen, ch, init) ++ if err != nil { ++ return nil, err ++ } ++ defer C._goboringcrypto_EVP_PKEY_free(pkey) ++ defer C._goboringcrypto_EVP_PKEY_CTX_free(ctx) ++ ++ var outLen C.uint ++ if out == nil { ++ if crypt(ctx, nil, &outLen, base(in), C.uint(len(in))) == 0 { ++ return nil, newOpenSSLError("EVP_PKEY_decrypt/encrypt failed") ++ } ++ out = make([]byte, outLen) ++ } else { ++ outLen = C.uint(len(out)) ++ } ++ if crypt(ctx, base(out), &outLen, base(in), C.uint(len(in))) <= 0 { ++ return nil, newOpenSSLError("EVP_PKEY_decrypt/encrypt failed") ++ } ++ return out[:outLen], nil ++} ++ ++func DecryptRSAOAEP(h hash.Hash, priv *PrivateKeyRSA, ciphertext, label []byte) ([]byte, error) { ++ return cryptRSA(priv.withKey, C.GO_RSA_PKCS1_OAEP_PADDING, h, label, 0, 0, decryptInit, decrypt, nil, ciphertext) ++} ++ ++func EncryptRSAOAEP(h hash.Hash, pub *PublicKeyRSA, msg, label []byte) ([]byte, error) { ++ return cryptRSA(pub.withKey, C.GO_RSA_PKCS1_OAEP_PADDING, h, label, 0, 0, encryptInit, encrypt, nil, msg) ++} ++ ++func DecryptRSAPKCS1(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) { ++ return cryptRSA(priv.withKey, C.GO_RSA_PKCS1_PADDING, nil, nil, 0, 0, decryptInit, decrypt, nil, ciphertext) ++} ++ ++func EncryptRSAPKCS1(pub *PublicKeyRSA, msg []byte) ([]byte, error) { ++ return cryptRSA(pub.withKey, C.GO_RSA_PKCS1_PADDING, nil, nil, 0, 0, encryptInit, encrypt, nil, msg) ++} ++ ++func DecryptRSANoPadding(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) { ++ ret, err := cryptRSA(priv.withKey, C.GO_RSA_NO_PADDING, nil, nil, 0, 0, decryptInit, decrypt, nil, ciphertext) ++ if err != nil { ++ return nil, err ++ } ++ // We could return here, but the Go standard library test expects DecryptRSANoPadding to verify the result ++ // in order to defend against errors in the CRT computation. ++ // ++ // The following code tries to replicate the verification implemented in the upstream function decryptAndCheck, found at ++ // https://github.com/golang/go/blob/9de1ac6ac2cad3871760d0aa288f5ca713afd0a6/src/crypto/rsa/rsa.go#L569-L582. ++ var n, e, d *C.GO_BIGNUM ++ priv.withKey(func(key *C.GO_RSA) C.int { ++ C._goboringcrypto_RSA_get0_key(key, &n, &e, &d) ++ return 1 ++ }) ++ pub, err := NewPublicKeyRSA(bnToBig(n), bnToBig(e)) ++ if err != nil { ++ return nil, err ++ } ++ enc, err := EncryptRSANoPadding(pub, ret) ++ if err != nil { ++ return nil, err ++ } ++ // Upstream does not do a constant time comparison because it works with math/big instead of byte slices, ++ // and math/big does not support constant-time arithmetic yet. See #20654 for more info. ++ if subtle.ConstantTimeCompare(ciphertext, enc) != 1 { ++ return nil, errors.New("rsa: internal error") ++ } ++ return ret, nil ++} ++ ++func EncryptRSANoPadding(pub *PublicKeyRSA, msg []byte) ([]byte, error) { ++ return cryptRSA(pub.withKey, C.GO_RSA_NO_PADDING, nil, nil, 0, 0, encryptInit, encrypt, nil, msg) ++} ++ ++// These dumb wrappers work around the fact that cgo functions cannot be used as values directly. ++ ++func decryptInit(ctx *C.GO_EVP_PKEY_CTX) C.int { ++ return C._goboringcrypto_EVP_PKEY_decrypt_init(ctx) ++} ++ ++func decrypt(ctx *C.GO_EVP_PKEY_CTX, out *C.uint8_t, outLen *C.uint, in *C.uint8_t, inLen C.uint) C.int { ++ return C._goboringcrypto_EVP_PKEY_decrypt(ctx, out, outLen, in, inLen) ++} ++ ++func encryptInit(ctx *C.GO_EVP_PKEY_CTX) C.int { ++ return C._goboringcrypto_EVP_PKEY_encrypt_init(ctx) ++} ++ ++func encrypt(ctx *C.GO_EVP_PKEY_CTX, out *C.uint8_t, outLen *C.uint, in *C.uint8_t, inLen C.uint) C.int { ++ return C._goboringcrypto_EVP_PKEY_encrypt(ctx, out, outLen, in, inLen) ++} ++ ++func signtInit(ctx *C.GO_EVP_PKEY_CTX) C.int { ++ return C._goboringcrypto_EVP_PKEY_sign_init(ctx) ++} ++ ++func sign(ctx *C.GO_EVP_PKEY_CTX, out *C.uint8_t, outLen *C.uint, in *C.uint8_t, inLen C.uint) C.int { ++ return C._goboringcrypto_EVP_PKEY_sign(ctx, out, outLen, in, inLen) ++} ++ ++func verifyInit(ctx *C.GO_EVP_PKEY_CTX) C.int { ++ return C._goboringcrypto_EVP_PKEY_verify_init(ctx) ++} ++ ++func verify(ctx *C.GO_EVP_PKEY_CTX, out *C.uint8_t, outLen *C.uint, in *C.uint8_t, inLen C.uint) C.int { ++ return C._goboringcrypto_EVP_PKEY_verify(ctx, out, *outLen, in, inLen) ++} ++ ++func SignRSAPSS(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte, saltLen int) ([]byte, error) { ++ if saltLen == 0 { ++ saltLen = -1 // RSA_PSS_SALTLEN_DIGEST ++ } ++ return cryptRSA(priv.withKey, C.RSA_PKCS1_PSS_PADDING, nil, nil, saltLen, h, signtInit, sign, nil, hashed) ++} ++ ++func VerifyRSAPSS(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte, saltLen int) error { ++ if saltLen == 0 { ++ saltLen = -2 // RSA_PSS_SALTLEN_AUTO ++ } ++ _, err := cryptRSA(pub.withKey, C.RSA_PKCS1_PSS_PADDING, nil, nil, saltLen, h, verifyInit, verify, sig, hashed) ++ return err ++} ++ ++func SignRSAPKCS1v15(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte) ([]byte, error) { ++ if h == 0 { ++ // No hashing. ++ var out []byte ++ var outLen C.int ++ if priv.withKey(func(key *C.GO_RSA) C.int { ++ out = make([]byte, C._goboringcrypto_RSA_size(key)) ++ outLen = C._goboringcrypto_RSA_private_encrypt(C.int(len(hashed)), base(hashed), ++ base(out), key, C.GO_RSA_PKCS1_PADDING) ++ return outLen ++ }) <= 0 { ++ return nil, newOpenSSLError("RSA_private_encrypt") ++ } ++ return out[:outLen], nil ++ } ++ ++ md := cryptoHashToMD(h) ++ if md == nil { ++ return nil, errors.New("crypto/rsa: unsupported hash function: " + strconv.Itoa(int(h))) ++ } ++ ++ nid := C._goboringcrypto_EVP_MD_type(md) ++ var out []byte ++ var outLen C.uint ++ if priv.withKey(func(key *C.GO_RSA) C.int { ++ out = make([]byte, C._goboringcrypto_RSA_size(key)) ++ return C._goboringcrypto_RSA_sign(nid, base(hashed), C.uint(len(hashed)), ++ base(out), &outLen, key) ++ }) == 0 { ++ return nil, newOpenSSLError("RSA_sign") ++ } ++ return out[:outLen], nil ++} ++ ++func VerifyRSAPKCS1v15(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte) error { ++ if pub.withKey(func(key *C.GO_RSA) C.int { ++ size := int(C._goboringcrypto_RSA_size(key)) ++ if len(sig) < size { ++ return 0 ++ } ++ return 1 ++ }) == 0 { ++ return errors.New("crypto/rsa: verification error") ++ } ++ if h == 0 { ++ var out []byte ++ var outLen C.int ++ if pub.withKey(func(key *C.GO_RSA) C.int { ++ out = make([]byte, C._goboringcrypto_RSA_size(key)) ++ outLen = C._goboringcrypto_RSA_public_decrypt(C.int(len(sig)), base(sig), base(out), key, C.GO_RSA_PKCS1_PADDING) ++ return outLen ++ }) <= 0 { ++ return newOpenSSLError("RSA_verify") ++ } ++ if subtle.ConstantTimeCompare(hashed, out[:outLen]) != 1 { ++ return fail("RSA_verify") ++ } ++ return nil ++ } ++ md := cryptoHashToMD(h) ++ if md == nil { ++ return errors.New("crypto/rsa: unsupported hash function") ++ } ++ nid := C._goboringcrypto_EVP_MD_type(md) ++ if pub.withKey(func(key *C.GO_RSA) C.int { ++ return C._goboringcrypto_RSA_verify(nid, base(hashed), C.uint(len(hashed)), ++ base(sig), C.uint(len(sig)), key) ++ }) == 0 { ++ return newOpenSSLError("RSA_verify failed") ++ } ++ return nil ++} +diff --git a/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/sha.go b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/sha.go +new file mode 100644 +index 0000000000..9681dc3a7e +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/sha.go +@@ -0,0 +1,477 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++//go:build linux && !android ++// +build linux,!android ++ ++package openssl ++ ++// #include "goopenssl.h" ++import "C" ++import ( ++ "errors" ++ "hash" ++ "unsafe" ++) ++ ++// NewSHA1 returns a new SHA1 hash. ++func NewSHA1() hash.Hash { ++ h := new(sha1Hash) ++ h.Reset() ++ return h ++} ++ ++type sha1Hash struct { ++ ctx C.GO_SHA_CTX ++ out [20]byte ++} ++ ++type sha1Ctx struct { ++ h [5]uint32 ++ nl, nh uint32 ++ x [64]byte ++ nx uint32 ++} ++ ++func (h *sha1Hash) Reset() { C._goboringcrypto_SHA1_Init(&h.ctx) } ++func (h *sha1Hash) Size() int { return 20 } ++func (h *sha1Hash) BlockSize() int { return 64 } ++func (h *sha1Hash) Sum(in []byte) []byte { return append(in, h.sum()...) } ++ ++func (h *sha1Hash) Write(p []byte) (int, error) { ++ if len(p) > 0 && C._goboringcrypto_SHA1_Update(&h.ctx, unsafe.Pointer(&p[0]), C.size_t(len(p))) == 0 { ++ panic("boringcrypto: SHA1_Update failed") ++ } ++ return len(p), nil ++} ++ ++func (h0 *sha1Hash) sum() []byte { ++ h := *h0 // make copy so future Write+Sum is valid ++ if C._goboringcrypto_SHA1_Final((*C.uint8_t)(unsafe.Pointer(&h.out[0])), &h.ctx) == 0 { ++ panic("boringcrypto: SHA1_Final failed") ++ } ++ return h.out[:] ++} ++ ++const ( ++ sha1Magic = "sha\x01" ++ sha1MarshaledSize = len(sha1Magic) + 5*4 + 64 + 8 ++) ++ ++func (h *sha1Hash) MarshalBinary() ([]byte, error) { ++ d := (*sha1Ctx)(unsafe.Pointer(&h.ctx)) ++ b := make([]byte, 0, sha1MarshaledSize) ++ b = append(b, sha1Magic...) ++ b = appendUint32(b, d.h[0]) ++ b = appendUint32(b, d.h[1]) ++ b = appendUint32(b, d.h[2]) ++ b = appendUint32(b, d.h[3]) ++ b = appendUint32(b, d.h[4]) ++ b = append(b, d.x[:d.nx]...) ++ b = b[:len(b)+len(d.x)-int(d.nx)] // already zero ++ b = appendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29) ++ return b, nil ++} ++ ++func (h *sha1Hash) UnmarshalBinary(b []byte) error { ++ if len(b) < len(sha1Magic) || string(b[:len(sha1Magic)]) != sha1Magic { ++ return errors.New("crypto/sha1: invalid hash state identifier") ++ } ++ if len(b) != sha1MarshaledSize { ++ return errors.New("crypto/sha1: invalid hash state size") ++ } ++ d := (*sha1Ctx)(unsafe.Pointer(&h.ctx)) ++ b = b[len(sha1Magic):] ++ b, d.h[0] = consumeUint32(b) ++ b, d.h[1] = consumeUint32(b) ++ b, d.h[2] = consumeUint32(b) ++ b, d.h[3] = consumeUint32(b) ++ b, d.h[4] = consumeUint32(b) ++ b = b[copy(d.x[:], b):] ++ b, n := consumeUint64(b) ++ d.nl = uint32(n << 3) ++ d.nh = uint32(n >> 29) ++ d.nx = uint32(n) % 64 ++ return nil ++} ++ ++// NewSHA224 returns a new SHA224 hash. ++func NewSHA224() hash.Hash { ++ h := new(sha224Hash) ++ h.Reset() ++ return h ++} ++ ++type sha224Hash struct { ++ ctx C.GO_SHA256_CTX ++ out [224 / 8]byte ++} ++ ++func (h *sha224Hash) Reset() { C._goboringcrypto_SHA224_Init(&h.ctx) } ++func (h *sha224Hash) Size() int { return 224 / 8 } ++func (h *sha224Hash) BlockSize() int { return 64 } ++func (h *sha224Hash) Sum(in []byte) []byte { return append(in, h.sum()...) } ++ ++func (h *sha224Hash) Write(p []byte) (int, error) { ++ if len(p) > 0 && C._goboringcrypto_SHA224_Update(&h.ctx, unsafe.Pointer(&p[0]), C.size_t(len(p))) == 0 { ++ panic("boringcrypto: SHA224_Update failed") ++ } ++ return len(p), nil ++} ++ ++func (h0 *sha224Hash) sum() []byte { ++ h := *h0 // make copy so future Write+Sum is valid ++ if C._goboringcrypto_SHA224_Final((*C.uint8_t)(unsafe.Pointer(&h.out[0])), &h.ctx) == 0 { ++ panic("boringcrypto: SHA224_Final failed") ++ } ++ return h.out[:] ++} ++ ++// NewSHA256 returns a new SHA256 hash. ++func NewSHA256() hash.Hash { ++ h := new(sha256Hash) ++ h.Reset() ++ return h ++} ++ ++type sha256Hash struct { ++ ctx C.GO_SHA256_CTX ++ out [256 / 8]byte ++} ++ ++func (h *sha256Hash) Reset() { C._goboringcrypto_SHA256_Init(&h.ctx) } ++func (h *sha256Hash) Size() int { return 256 / 8 } ++func (h *sha256Hash) BlockSize() int { return 64 } ++func (h *sha256Hash) Sum(in []byte) []byte { return append(in, h.sum()...) } ++ ++func (h *sha256Hash) Write(p []byte) (int, error) { ++ if len(p) > 0 && C._goboringcrypto_SHA256_Update(&h.ctx, unsafe.Pointer(&p[0]), C.size_t(len(p))) == 0 { ++ panic("boringcrypto: SHA256_Update failed") ++ } ++ return len(p), nil ++} ++ ++func (h0 *sha256Hash) sum() []byte { ++ h := *h0 // make copy so future Write+Sum is valid ++ if C._goboringcrypto_SHA256_Final((*C.uint8_t)(unsafe.Pointer(&h.out[0])), &h.ctx) == 0 { ++ panic("boringcrypto: SHA256_Final failed") ++ } ++ return h.out[:] ++} ++ ++const ( ++ magic224 = "sha\x02" ++ magic256 = "sha\x03" ++ marshaledSize256 = len(magic256) + 8*4 + 64 + 8 ++) ++ ++type sha256Ctx struct { ++ h [8]uint32 ++ nl, nh uint32 ++ x [64]byte ++ nx uint32 ++} ++ ++func (h *sha224Hash) MarshalBinary() ([]byte, error) { ++ d := (*sha256Ctx)(unsafe.Pointer(&h.ctx)) ++ b := make([]byte, 0, marshaledSize256) ++ b = append(b, magic224...) ++ b = appendUint32(b, d.h[0]) ++ b = appendUint32(b, d.h[1]) ++ b = appendUint32(b, d.h[2]) ++ b = appendUint32(b, d.h[3]) ++ b = appendUint32(b, d.h[4]) ++ b = appendUint32(b, d.h[5]) ++ b = appendUint32(b, d.h[6]) ++ b = appendUint32(b, d.h[7]) ++ b = append(b, d.x[:d.nx]...) ++ b = b[:len(b)+len(d.x)-int(d.nx)] // already zero ++ b = appendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29) ++ return b, nil ++} ++ ++func (h *sha256Hash) MarshalBinary() ([]byte, error) { ++ d := (*sha256Ctx)(unsafe.Pointer(&h.ctx)) ++ b := make([]byte, 0, marshaledSize256) ++ b = append(b, magic256...) ++ b = appendUint32(b, d.h[0]) ++ b = appendUint32(b, d.h[1]) ++ b = appendUint32(b, d.h[2]) ++ b = appendUint32(b, d.h[3]) ++ b = appendUint32(b, d.h[4]) ++ b = appendUint32(b, d.h[5]) ++ b = appendUint32(b, d.h[6]) ++ b = appendUint32(b, d.h[7]) ++ b = append(b, d.x[:d.nx]...) ++ b = b[:len(b)+len(d.x)-int(d.nx)] // already zero ++ b = appendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29) ++ return b, nil ++} ++ ++func (h *sha224Hash) UnmarshalBinary(b []byte) error { ++ if len(b) < len(magic224) || string(b[:len(magic224)]) != magic224 { ++ return errors.New("crypto/sha256: invalid hash state identifier") ++ } ++ if len(b) != marshaledSize256 { ++ return errors.New("crypto/sha256: invalid hash state size") ++ } ++ d := (*sha256Ctx)(unsafe.Pointer(&h.ctx)) ++ b = b[len(magic224):] ++ b, d.h[0] = consumeUint32(b) ++ b, d.h[1] = consumeUint32(b) ++ b, d.h[2] = consumeUint32(b) ++ b, d.h[3] = consumeUint32(b) ++ b, d.h[4] = consumeUint32(b) ++ b, d.h[5] = consumeUint32(b) ++ b, d.h[6] = consumeUint32(b) ++ b, d.h[7] = consumeUint32(b) ++ b = b[copy(d.x[:], b):] ++ b, n := consumeUint64(b) ++ d.nl = uint32(n << 3) ++ d.nh = uint32(n >> 29) ++ d.nx = uint32(n) % 64 ++ return nil ++} ++ ++func (h *sha256Hash) UnmarshalBinary(b []byte) error { ++ if len(b) < len(magic256) || string(b[:len(magic256)]) != magic256 { ++ return errors.New("crypto/sha256: invalid hash state identifier") ++ } ++ if len(b) != marshaledSize256 { ++ return errors.New("crypto/sha256: invalid hash state size") ++ } ++ d := (*sha256Ctx)(unsafe.Pointer(&h.ctx)) ++ b = b[len(magic256):] ++ b, d.h[0] = consumeUint32(b) ++ b, d.h[1] = consumeUint32(b) ++ b, d.h[2] = consumeUint32(b) ++ b, d.h[3] = consumeUint32(b) ++ b, d.h[4] = consumeUint32(b) ++ b, d.h[5] = consumeUint32(b) ++ b, d.h[6] = consumeUint32(b) ++ b, d.h[7] = consumeUint32(b) ++ b = b[copy(d.x[:], b):] ++ b, n := consumeUint64(b) ++ d.nl = uint32(n << 3) ++ d.nh = uint32(n >> 29) ++ d.nx = uint32(n) % 64 ++ return nil ++} ++ ++// NewSHA384 returns a new SHA384 hash. ++func NewSHA384() hash.Hash { ++ h := new(sha384Hash) ++ h.Reset() ++ return h ++} ++ ++type sha384Hash struct { ++ ctx C.GO_SHA512_CTX ++ out [384 / 8]byte ++} ++ ++func (h *sha384Hash) Reset() { C._goboringcrypto_SHA384_Init(&h.ctx) } ++func (h *sha384Hash) Size() int { return 384 / 8 } ++func (h *sha384Hash) BlockSize() int { return 128 } ++func (h *sha384Hash) Sum(in []byte) []byte { return append(in, h.sum()...) } ++ ++func (h *sha384Hash) Write(p []byte) (int, error) { ++ if len(p) > 0 && C._goboringcrypto_SHA384_Update(&h.ctx, unsafe.Pointer(&p[0]), C.size_t(len(p))) == 0 { ++ panic("boringcrypto: SHA384_Update failed") ++ } ++ return len(p), nil ++} ++ ++func (h0 *sha384Hash) sum() []byte { ++ h := *h0 // make copy so future Write+Sum is valid ++ if C._goboringcrypto_SHA384_Final((*C.uint8_t)(unsafe.Pointer(&h.out[0])), &h.ctx) == 0 { ++ panic("boringcrypto: SHA384_Final failed") ++ } ++ return h.out[:] ++} ++ ++// NewSHA512 returns a new SHA512 hash. ++func NewSHA512() hash.Hash { ++ h := new(sha512Hash) ++ h.Reset() ++ return h ++} ++ ++type sha512Hash struct { ++ ctx C.GO_SHA512_CTX ++ out [512 / 8]byte ++} ++ ++func (h *sha512Hash) Reset() { C._goboringcrypto_SHA512_Init(&h.ctx) } ++func (h *sha512Hash) Size() int { return 512 / 8 } ++func (h *sha512Hash) BlockSize() int { return 128 } ++func (h *sha512Hash) Sum(in []byte) []byte { return append(in, h.sum()...) } ++ ++func (h *sha512Hash) Write(p []byte) (int, error) { ++ if len(p) > 0 && C._goboringcrypto_SHA512_Update(&h.ctx, unsafe.Pointer(&p[0]), C.size_t(len(p))) == 0 { ++ panic("boringcrypto: SHA512_Update failed") ++ } ++ return len(p), nil ++} ++ ++func (h0 *sha512Hash) sum() []byte { ++ h := *h0 // make copy so future Write+Sum is valid ++ if C._goboringcrypto_SHA512_Final((*C.uint8_t)(unsafe.Pointer(&h.out[0])), &h.ctx) == 0 { ++ panic("boringcrypto: SHA512_Final failed") ++ } ++ return h.out[:] ++} ++ ++type sha512Ctx struct { ++ h [8]uint64 ++ nl, nh uint64 ++ x [128]byte ++ nx uint32 ++} ++ ++const ( ++ magic384 = "sha\x04" ++ magic512_224 = "sha\x05" ++ magic512_256 = "sha\x06" ++ magic512 = "sha\x07" ++ marshaledSize512 = len(magic512) + 8*8 + 128 + 8 ++) ++ ++var zero [128]byte ++ ++func (h *sha384Hash) MarshalBinary() ([]byte, error) { ++ d := (*sha512Ctx)(unsafe.Pointer(&h.ctx)) ++ b := make([]byte, 0, marshaledSize512) ++ b = append(b, magic384...) ++ b = appendUint64(b, d.h[0]) ++ b = appendUint64(b, d.h[1]) ++ b = appendUint64(b, d.h[2]) ++ b = appendUint64(b, d.h[3]) ++ b = appendUint64(b, d.h[4]) ++ b = appendUint64(b, d.h[5]) ++ b = appendUint64(b, d.h[6]) ++ b = appendUint64(b, d.h[7]) ++ b = append(b, d.x[:d.nx]...) ++ b = b[:len(b)+len(d.x)-int(d.nx)] // already zero ++ b = appendUint64(b, d.nl>>3|d.nh<<61) ++ return b, nil ++} ++ ++func (h *sha512Hash) MarshalBinary() ([]byte, error) { ++ d := (*sha512Ctx)(unsafe.Pointer(&h.ctx)) ++ b := make([]byte, 0, marshaledSize512) ++ b = append(b, magic512...) ++ b = appendUint64(b, d.h[0]) ++ b = appendUint64(b, d.h[1]) ++ b = appendUint64(b, d.h[2]) ++ b = appendUint64(b, d.h[3]) ++ b = appendUint64(b, d.h[4]) ++ b = appendUint64(b, d.h[5]) ++ b = appendUint64(b, d.h[6]) ++ b = appendUint64(b, d.h[7]) ++ b = append(b, d.x[:d.nx]...) ++ b = b[:len(b)+len(d.x)-int(d.nx)] // already zero ++ b = appendUint64(b, d.nl>>3|d.nh<<61) ++ return b, nil ++} ++ ++func (h *sha384Hash) UnmarshalBinary(b []byte) error { ++ if len(b) < len(magic512) { ++ return errors.New("crypto/sha512: invalid hash state identifier") ++ } ++ if string(b[:len(magic384)]) != magic384 { ++ return errors.New("crypto/sha512: invalid hash state identifier") ++ } ++ if len(b) != marshaledSize512 { ++ return errors.New("crypto/sha512: invalid hash state size") ++ } ++ d := (*sha512Ctx)(unsafe.Pointer(&h.ctx)) ++ b = b[len(magic512):] ++ b, d.h[0] = consumeUint64(b) ++ b, d.h[1] = consumeUint64(b) ++ b, d.h[2] = consumeUint64(b) ++ b, d.h[3] = consumeUint64(b) ++ b, d.h[4] = consumeUint64(b) ++ b, d.h[5] = consumeUint64(b) ++ b, d.h[6] = consumeUint64(b) ++ b, d.h[7] = consumeUint64(b) ++ b = b[copy(d.x[:], b):] ++ b, n := consumeUint64(b) ++ d.nl = n << 3 ++ d.nh = n >> 61 ++ d.nx = uint32(n) % 128 ++ return nil ++} ++ ++func (h *sha512Hash) UnmarshalBinary(b []byte) error { ++ if len(b) < len(magic512) { ++ return errors.New("crypto/sha512: invalid hash state identifier") ++ } ++ if string(b[:len(magic512)]) != magic512 { ++ return errors.New("crypto/sha512: invalid hash state identifier") ++ } ++ if len(b) != marshaledSize512 { ++ return errors.New("crypto/sha512: invalid hash state size") ++ } ++ d := (*sha512Ctx)(unsafe.Pointer(&h.ctx)) ++ b = b[len(magic512):] ++ b, d.h[0] = consumeUint64(b) ++ b, d.h[1] = consumeUint64(b) ++ b, d.h[2] = consumeUint64(b) ++ b, d.h[3] = consumeUint64(b) ++ b, d.h[4] = consumeUint64(b) ++ b, d.h[5] = consumeUint64(b) ++ b, d.h[6] = consumeUint64(b) ++ b, d.h[7] = consumeUint64(b) ++ b = b[copy(d.x[:], b):] ++ b, n := consumeUint64(b) ++ d.nl = n << 3 ++ d.nh = n >> 61 ++ d.nx = uint32(n) % 128 ++ return nil ++} ++ ++func appendUint64(b []byte, x uint64) []byte { ++ var a [8]byte ++ putUint64(a[:], x) ++ return append(b, a[:]...) ++} ++ ++func appendUint32(b []byte, x uint32) []byte { ++ var a [4]byte ++ putUint32(a[:], x) ++ return append(b, a[:]...) ++} ++ ++func consumeUint64(b []byte) ([]byte, uint64) { ++ _ = b[7] ++ x := uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 | ++ uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56 ++ return b[8:], x ++} ++ ++func consumeUint32(b []byte) ([]byte, uint32) { ++ _ = b[3] ++ x := uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24 ++ return b[4:], x ++} ++ ++func putUint64(x []byte, s uint64) { ++ _ = x[7] ++ x[0] = byte(s >> 56) ++ x[1] = byte(s >> 48) ++ x[2] = byte(s >> 40) ++ x[3] = byte(s >> 32) ++ x[4] = byte(s >> 24) ++ x[5] = byte(s >> 16) ++ x[6] = byte(s >> 8) ++ x[7] = byte(s) ++} ++ ++func putUint32(x []byte, s uint32) { ++ _ = x[3] ++ x[0] = byte(s >> 24) ++ x[1] = byte(s >> 16) ++ x[2] = byte(s >> 8) ++ x[3] = byte(s) ++} +diff --git a/src/vendor/modules.txt b/src/vendor/modules.txt +index a1b16d7b84..a733603e8b 100644 +--- a/src/vendor/modules.txt ++++ b/src/vendor/modules.txt +@@ -1,3 +1,7 @@ ++# github.com/microsoft/go-crypto-openssl v0.0.0-20220124101237-183c44c3cf71 ++## explicit; go 1.16 ++github.com/microsoft/go-crypto-openssl/openssl ++github.com/microsoft/go-crypto-openssl/openssl/internal/subtle + # golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e + ## explicit; go 1.17 + golang.org/x/crypto/chacha20 diff --git a/patches/0003-Integrate-OpenSSL-crypto-module.patch b/patches/0003-Integrate-OpenSSL-crypto-module.patch new file mode 100644 index 00000000000..d551a3f4752 --- /dev/null +++ b/patches/0003-Integrate-OpenSSL-crypto-module.patch @@ -0,0 +1,702 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: microsoft-golang-bot +Date: Thu, 27 Jan 2022 11:45:14 -0600 +Subject: [PATCH] Integrate OpenSSL crypto module + +--- + src/cmd/link/internal/ld/lib.go | 2 +- + src/crypto/aes/cipher.go | 2 +- + src/crypto/aes/cipher_asm.go | 2 +- + src/crypto/boring/boring.go | 2 +- + src/crypto/boring/boring_test.go | 1 + + src/crypto/ecdsa/boring.go | 2 +- + src/crypto/ecdsa/ecdsa.go | 2 +- + src/crypto/hmac/hmac.go | 2 +- + src/crypto/hmac/hmac_test.go | 2 +- + src/crypto/internal/backend/backend_test.go | 30 ++++ + src/crypto/internal/backend/dummy.s | 10 ++ + src/crypto/internal/backend/nobackend.go | 112 ++++++++++++++ + src/crypto/internal/backend/openssl_linux.go | 145 +++++++++++++++++++ + src/crypto/rand/rand_unix.go | 2 +- + src/crypto/rsa/boring.go | 2 +- + src/crypto/rsa/pkcs1v15.go | 2 +- + src/crypto/rsa/pss.go | 2 +- + src/crypto/rsa/rsa.go | 2 +- + src/crypto/rsa/rsa_test.go | 2 +- + src/crypto/sha1/boring.go | 4 +- + src/crypto/sha1/sha1_test.go | 2 +- + src/crypto/sha256/sha256.go | 2 +- + src/crypto/sha256/sha256_test.go | 2 +- + src/crypto/sha512/sha512.go | 2 +- + src/crypto/sha512/sha512_test.go | 2 +- + src/crypto/tls/cipher_suites.go | 2 +- + src/go/build/deps_test.go | 13 +- + src/runtime/runtime_boring.go | 5 + + 28 files changed, 335 insertions(+), 25 deletions(-) + create mode 100644 src/crypto/internal/backend/backend_test.go + create mode 100644 src/crypto/internal/backend/dummy.s + create mode 100644 src/crypto/internal/backend/nobackend.go + create mode 100644 src/crypto/internal/backend/openssl_linux.go + +diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go +index d7e408669e..09c5dd152c 100644 +--- a/src/cmd/link/internal/ld/lib.go ++++ b/src/cmd/link/internal/ld/lib.go +@@ -1013,7 +1013,7 @@ var hostobj []Hostobj + // These packages can use internal linking mode. + // Others trigger external mode. + var internalpkg = []string{ +- "crypto/internal/boring", ++ "vendor/github.com/microsoft/go-crypto-openssl/openssl", + "crypto/x509", + "net", + "os/user", +diff --git a/src/crypto/aes/cipher.go b/src/crypto/aes/cipher.go +index 29d01796eb..f3680ad6b4 100644 +--- a/src/crypto/aes/cipher.go ++++ b/src/crypto/aes/cipher.go +@@ -10,7 +10,7 @@ import ( + "strconv" + ) + +-import "crypto/internal/boring" ++import boring "crypto/internal/backend" + + // The AES block size in bytes. + const BlockSize = 16 +diff --git a/src/crypto/aes/cipher_asm.go b/src/crypto/aes/cipher_asm.go +index 846f56ab56..e8666b40b6 100644 +--- a/src/crypto/aes/cipher_asm.go ++++ b/src/crypto/aes/cipher_asm.go +@@ -13,7 +13,7 @@ import ( + "internal/cpu" + ) + +-import "crypto/internal/boring" ++import boring "crypto/internal/backend" + + // defined in asm_*.s + +diff --git a/src/crypto/boring/boring.go b/src/crypto/boring/boring.go +index 19e2a0876f..2829231f4a 100644 +--- a/src/crypto/boring/boring.go ++++ b/src/crypto/boring/boring.go +@@ -11,7 +11,7 @@ + // is satisfied, so that applications can tag files that use this package. + package boring + +-import "crypto/internal/boring" ++import boring "crypto/internal/backend" + + // Enabled reports whether BoringCrypto handles supported crypto operations. + func Enabled() bool { +diff --git a/src/crypto/boring/boring_test.go b/src/crypto/boring/boring_test.go +index ace50de0c2..83ef05d872 100644 +--- a/src/crypto/boring/boring_test.go ++++ b/src/crypto/boring/boring_test.go +@@ -11,6 +11,7 @@ import ( + ) + + func TestEnabled(t *testing.T) { ++ t.Skip("upstream assumes boring is enabled at build time, we don't") + supportedPlatform := runtime.GOOS == "linux" && runtime.GOARCH == "amd64" + if supportedPlatform && !boring.Enabled() { + t.Error("Enabled returned false on a supported platform") +diff --git a/src/crypto/ecdsa/boring.go b/src/crypto/ecdsa/boring.go +index fa15ecb850..92c42e28d5 100644 +--- a/src/crypto/ecdsa/boring.go ++++ b/src/crypto/ecdsa/boring.go +@@ -5,7 +5,7 @@ + package ecdsa + + import ( +- "crypto/internal/boring" ++ boring "crypto/internal/backend" + "math/big" + "sync/atomic" + "unsafe" +diff --git a/src/crypto/ecdsa/ecdsa.go b/src/crypto/ecdsa/ecdsa.go +index 1a7635ec2b..6d27b818dd 100644 +--- a/src/crypto/ecdsa/ecdsa.go ++++ b/src/crypto/ecdsa/ecdsa.go +@@ -42,7 +42,7 @@ import ( + ) + + import ( +- "crypto/internal/boring" ++ boring "crypto/internal/backend" + "unsafe" + ) + +diff --git a/src/crypto/hmac/hmac.go b/src/crypto/hmac/hmac.go +index 34805765d5..79fd58d0da 100644 +--- a/src/crypto/hmac/hmac.go ++++ b/src/crypto/hmac/hmac.go +@@ -26,7 +26,7 @@ import ( + "hash" + ) + +-import "crypto/internal/boring" ++import boring "crypto/internal/backend" + + // FIPS 198-1: + // https://csrc.nist.gov/publications/fips/fips198-1/FIPS-198-1_final.pdf +diff --git a/src/crypto/hmac/hmac_test.go b/src/crypto/hmac/hmac_test.go +index 55415abf02..904925377b 100644 +--- a/src/crypto/hmac/hmac_test.go ++++ b/src/crypto/hmac/hmac_test.go +@@ -6,7 +6,7 @@ package hmac + + import ( + "bytes" +- "crypto/internal/boring" ++ boring "crypto/internal/backend" + "crypto/md5" + "crypto/sha1" + "crypto/sha256" +diff --git a/src/crypto/internal/backend/backend_test.go b/src/crypto/internal/backend/backend_test.go +new file mode 100644 +index 0000000000..c2c06d3bff +--- /dev/null ++++ b/src/crypto/internal/backend/backend_test.go +@@ -0,0 +1,30 @@ ++// 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 backend ++ ++import ( ++ "testing" ++) ++ ++// Test that Unreachable panics. ++func TestUnreachable(t *testing.T) { ++ defer func() { ++ if Enabled { ++ if err := recover(); err == nil { ++ t.Fatal("expected Unreachable to panic") ++ } ++ } else { ++ if err := recover(); err != nil { ++ t.Fatalf("expected Unreachable to be a no-op") ++ } ++ } ++ }() ++ Unreachable() ++} ++ ++// Test that UnreachableExceptTests does not panic (this is a test). ++func TestUnreachableExceptTests(t *testing.T) { ++ UnreachableExceptTests() ++} +diff --git a/src/crypto/internal/backend/dummy.s b/src/crypto/internal/backend/dummy.s +new file mode 100644 +index 0000000000..157adeeeb3 +--- /dev/null ++++ b/src/crypto/internal/backend/dummy.s +@@ -0,0 +1,10 @@ ++// 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. ++ ++// runtime_arg0 is declared in openssl_linux.go without a body. ++// It's provided by package runtime, ++// but the go command doesn't know that. ++// Having this assembly file keeps the go command ++// from complaining about the missing body ++// (because the implementation might be here). +diff --git a/src/crypto/internal/backend/nobackend.go b/src/crypto/internal/backend/nobackend.go +new file mode 100644 +index 0000000000..4de8d404f8 +--- /dev/null ++++ b/src/crypto/internal/backend/nobackend.go +@@ -0,0 +1,112 @@ ++// 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. ++ ++//go:build !linux || !cgo || android || cmd_go_bootstrap || msan || gocrypt ++// +build !linux !cgo android cmd_go_bootstrap msan gocrypt ++ ++package backend ++ ++import ( ++ "crypto" ++ "crypto/cipher" ++ "crypto/internal/boring/sig" ++ "hash" ++ "math/big" ++) ++ ++const Enabled = false ++ ++// Unreachable marks code that should be unreachable ++// when OpenSSLCrypto is in use. It is a no-op without OpenSSLCrypto. ++func Unreachable() { ++ // Code that's unreachable when using OpenSSLCrypto ++ // is exactly the code we want to detect for reporting ++ // standard Go crypto. ++ sig.StandardCrypto() ++} ++ ++// UnreachableExceptTests marks code that should be unreachable ++// when OpenSSLCrypto is in use. It is a no-op without OpenSSLCrypto. ++func UnreachableExceptTests() {} ++ ++type randReader int ++ ++func (randReader) Read(b []byte) (int, error) { panic("opensslcrypto: not available") } ++ ++const RandReader = randReader(0) ++ ++func NewSHA1() hash.Hash { panic("opensslcrypto: not available") } ++func NewSHA224() hash.Hash { panic("opensslcrypto: not available") } ++func NewSHA256() hash.Hash { panic("opensslcrypto: not available") } ++func NewSHA384() hash.Hash { panic("opensslcrypto: not available") } ++func NewSHA512() hash.Hash { panic("opensslcrypto: not available") } ++ ++func NewHMAC(h func() hash.Hash, key []byte) hash.Hash { panic("opensslcrypto: not available") } ++ ++func NewAESCipher(key []byte) (cipher.Block, error) { panic("opensslcrypto: not available") } ++ ++type PublicKeyECDSA struct{ _ int } ++type PrivateKeyECDSA struct{ _ int } ++ ++func GenerateKeyECDSA(curve string) (X, Y, D *big.Int, err error) { ++ panic("opensslcrypto: not available") ++} ++func NewPrivateKeyECDSA(curve string, X, Y, D *big.Int) (*PrivateKeyECDSA, error) { ++ panic("opensslcrypto: not available") ++} ++func NewPublicKeyECDSA(curve string, X, Y *big.Int) (*PublicKeyECDSA, error) { ++ panic("opensslcrypto: not available") ++} ++func SignECDSA(priv *PrivateKeyECDSA, hash []byte) (r, s *big.Int, err error) { ++ panic("opensslcrypto: not available") ++} ++func SignMarshalECDSA(priv *PrivateKeyECDSA, hash []byte) ([]byte, error) { ++ panic("opensslcrypto: not available") ++} ++func VerifyECDSA(pub *PublicKeyECDSA, hash []byte, r, s *big.Int) bool { ++ panic("opensslcrypto: not available") ++} ++ ++type PublicKeyRSA struct{ _ int } ++type PrivateKeyRSA struct{ _ int } ++ ++func DecryptRSAOAEP(h hash.Hash, priv *PrivateKeyRSA, ciphertext, label []byte) ([]byte, error) { ++ panic("opensslcrypto: not available") ++} ++func DecryptRSAPKCS1(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) { ++ panic("opensslcrypto: not available") ++} ++func DecryptRSANoPadding(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) { ++ panic("opensslcrypto: not available") ++} ++func EncryptRSAOAEP(h hash.Hash, pub *PublicKeyRSA, msg, label []byte) ([]byte, error) { ++ panic("opensslcrypto: not available") ++} ++func EncryptRSAPKCS1(pub *PublicKeyRSA, msg []byte) ([]byte, error) { ++ panic("opensslcrypto: not available") ++} ++func EncryptRSANoPadding(pub *PublicKeyRSA, msg []byte) ([]byte, error) { ++ panic("opensslcrypto: not available") ++} ++func GenerateKeyRSA(bits int) (N, E, D, P, Q, Dp, Dq, Qinv *big.Int, err error) { ++ panic("opensslcrypto: not available") ++} ++func NewPrivateKeyRSA(N, E, D, P, Q, Dp, Dq, Qinv *big.Int) (*PrivateKeyRSA, error) { ++ panic("opensslcrypto: not available") ++} ++func NewPublicKeyRSA(N, E *big.Int) (*PublicKeyRSA, error) { ++ panic("opensslcrypto: not available") ++} ++func SignRSAPKCS1v15(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte) ([]byte, error) { ++ panic("opensslcrypto: not available") ++} ++func SignRSAPSS(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte, saltLen int) ([]byte, error) { ++ panic("opensslcrypto: not available") ++} ++func VerifyRSAPKCS1v15(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte) error { ++ panic("opensslcrypto: not available") ++} ++func VerifyRSAPSS(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte, saltLen int) error { ++ panic("opensslcrypto: not available") ++} +diff --git a/src/crypto/internal/backend/openssl_linux.go b/src/crypto/internal/backend/openssl_linux.go +new file mode 100644 +index 0000000000..c1656d6576 +--- /dev/null ++++ b/src/crypto/internal/backend/openssl_linux.go +@@ -0,0 +1,145 @@ ++// 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. ++ ++//go:build linux && !android && !gocrypt && !cmd_go_bootstrap && !msan ++// +build linux,!android,!gocrypt,!cmd_go_bootstrap,!msan ++ ++// Package openssl provides access to OpenSSLCrypto implementation functions. ++// Check the variable Enabled to find out whether OpenSSLCrypto is available. ++// If OpenSSLCrypto is not available, the functions in this package all panic. ++package backend ++ ++import ( ++ "crypto/internal/boring/sig" ++ "syscall" ++ ++ "github.com/microsoft/go-crypto-openssl/openssl" ++) ++ ++// Enabled controls whether FIPS crypto is enabled. ++var Enabled = false ++ ++func init() { ++ if !needFIPS() { ++ return ++ } ++ err := openssl.Init() ++ if err != nil { ++ panic(err) ++ } ++ ++ if !openssl.FIPS() { ++ if err = openssl.SetFIPS(true); err != nil { ++ panic(err) ++ } ++ } ++ ++ Enabled = true ++ sig.BoringCrypto() ++} ++ ++func needFIPS() bool { ++ if envFips, ok := syscall.Getenv("GOFIPS"); ok { ++ return envFips != "0" ++ } ++ // TODO: Remove GOLANG_FIPS once our CI uses GOFIPS. ++ if envFips, ok := syscall.Getenv("GOLANG_FIPS"); ok { ++ return envFips != "0" ++ } ++ var fd int ++ for { ++ var err error ++ fd, err = syscall.Open("/proc/sys/crypto/fips_enabled", syscall.O_RDONLY, 0) ++ if err == nil { ++ break ++ } ++ switch err { ++ case syscall.EINTR: ++ continue ++ case syscall.ENOENT: ++ return false ++ default: ++ // If there is an error reading we could either panic or assume FIPS is not enabled. ++ // Panicking would be too disruptive for apps that don't require FIPS. ++ // If an app wants to be 100% sure that is running in FIPS mode ++ // it should use boring.Enabled() or GOFIPS=1. ++ return false ++ } ++ } ++ defer syscall.Close(fd) ++ var tmp [1]byte ++ n, err := syscall.Read(fd, tmp[:]) ++ if n != 1 || err != nil { ++ // We return false instead of panicing for the same reason as before. ++ return false ++ } ++ // fips_enabled can be either '0' or '1'. ++ return tmp[0] == '1' ++} ++ ++// Unreachable marks code that should be unreachable ++// when OpenSSLCrypto is in use. It panics only when ++// the system is in FIPS mode. ++func Unreachable() { ++ if Enabled { ++ panic("opensslcrypto: invalid code execution") ++ } ++} ++ ++// Provided by runtime.crypto_backend_runtime_arg0 to avoid os import. ++func runtime_arg0() string ++ ++func hasSuffix(s, t string) bool { ++ return len(s) > len(t) && s[len(s)-len(t):] == t ++} ++ ++// UnreachableExceptTests marks code that should be unreachable ++// when OpenSSLCrypto is in use. It panics. ++func UnreachableExceptTests() { ++ name := runtime_arg0() ++ // If OpenSSLCrypto ran on Windows we'd need to allow _test.exe and .test.exe as well. ++ if Enabled && !hasSuffix(name, "_test") && !hasSuffix(name, ".test") { ++ println("opensslcrypto: unexpected code execution in", name) ++ panic("opensslcrypto: invalid code execution") ++ } ++} ++ ++const RandReader = openssl.RandReader ++ ++var NewSHA1 = openssl.NewSHA1 ++var NewSHA224 = openssl.NewSHA224 ++var NewSHA256 = openssl.NewSHA256 ++var NewSHA384 = openssl.NewSHA384 ++var NewSHA512 = openssl.NewSHA512 ++ ++var NewHMAC = openssl.NewHMAC ++ ++var NewAESCipher = openssl.NewAESCipher ++ ++type PublicKeyECDSA = openssl.PublicKeyECDSA ++type PrivateKeyECDSA = openssl.PrivateKeyECDSA ++ ++var GenerateKeyECDSA = openssl.GenerateKeyECDSA ++var NewPrivateKeyECDSA = openssl.NewPrivateKeyECDSA ++var NewPublicKeyECDSA = openssl.NewPublicKeyECDSA ++var SignECDSA = openssl.SignECDSA ++var SignMarshalECDSA = openssl.SignMarshalECDSA ++var VerifyECDSA = openssl.VerifyECDSA ++ ++type PublicKeyRSA = openssl.PublicKeyRSA ++type PrivateKeyRSA = openssl.PrivateKeyRSA ++ ++var DecryptRSAOAEP = openssl.DecryptRSAOAEP ++var DecryptRSAPKCS1 = openssl.DecryptRSAPKCS1 ++var DecryptRSANoPadding = openssl.DecryptRSANoPadding ++var EncryptRSAOAEP = openssl.EncryptRSAOAEP ++var EncryptRSAPKCS1 = openssl.EncryptRSAPKCS1 ++var EncryptRSANoPadding = openssl.EncryptRSANoPadding ++var GenerateKeyRSA = openssl.GenerateKeyRSA ++var NewPrivateKeyRSA = openssl.NewPrivateKeyRSA ++var NewPublicKeyRSA = openssl.NewPublicKeyRSA ++var SignRSAPKCS1v15 = openssl.SignRSAPKCS1v15 ++var SignRSAPSS = openssl.SignRSAPSS ++var VerifyRSAPKCS1v15 = openssl.VerifyRSAPKCS1v15 ++var VerifyRSAPSS = openssl.VerifyRSAPSS +diff --git a/src/crypto/rand/rand_unix.go b/src/crypto/rand/rand_unix.go +index 34f4481a9b..486d71e7a3 100644 +--- a/src/crypto/rand/rand_unix.go ++++ b/src/crypto/rand/rand_unix.go +@@ -23,7 +23,7 @@ import ( + "time" + ) + +-import "crypto/internal/boring" ++import boring "crypto/internal/backend" + + const urandomDevice = "/dev/urandom" + +diff --git a/src/crypto/rsa/boring.go b/src/crypto/rsa/boring.go +index 0f362a2f16..856bc26aea 100644 +--- a/src/crypto/rsa/boring.go ++++ b/src/crypto/rsa/boring.go +@@ -5,7 +5,7 @@ + package rsa + + import ( +- "crypto/internal/boring" ++ boring "crypto/internal/backend" + "math/big" + "sync/atomic" + "unsafe" +diff --git a/src/crypto/rsa/pkcs1v15.go b/src/crypto/rsa/pkcs1v15.go +index 213ddb4add..5a44b4a71c 100644 +--- a/src/crypto/rsa/pkcs1v15.go ++++ b/src/crypto/rsa/pkcs1v15.go +@@ -14,7 +14,7 @@ import ( + "crypto/internal/randutil" + ) + +-import "crypto/internal/boring" ++import boring "crypto/internal/backend" + + // This file implements encryption and decryption using PKCS #1 v1.5 padding. + +diff --git a/src/crypto/rsa/pss.go b/src/crypto/rsa/pss.go +index 16ebc0e6a7..54afa8992e 100644 +--- a/src/crypto/rsa/pss.go ++++ b/src/crypto/rsa/pss.go +@@ -15,7 +15,7 @@ import ( + "math/big" + ) + +-import "crypto/internal/boring" ++import boring "crypto/internal/backend" + + // Per RFC 8017, Section 9.1 + // +diff --git a/src/crypto/rsa/rsa.go b/src/crypto/rsa/rsa.go +index eef967f826..550e66fdd9 100644 +--- a/src/crypto/rsa/rsa.go ++++ b/src/crypto/rsa/rsa.go +@@ -36,7 +36,7 @@ import ( + ) + + import ( +- "crypto/internal/boring" ++ boring "crypto/internal/backend" + "unsafe" + ) + +diff --git a/src/crypto/rsa/rsa_test.go b/src/crypto/rsa/rsa_test.go +index 766d9a954f..f2602b94ab 100644 +--- a/src/crypto/rsa/rsa_test.go ++++ b/src/crypto/rsa/rsa_test.go +@@ -15,7 +15,7 @@ import ( + "testing" + ) + +-import "crypto/internal/boring" ++import boring "crypto/internal/backend" + + func TestKeyGeneration(t *testing.T) { + for _, size := range []int{128, 1024, 2048, 3072} { +diff --git a/src/crypto/sha1/boring.go b/src/crypto/sha1/boring.go +index 44c26092ee..ed00d7cd8f 100644 +--- a/src/crypto/sha1/boring.go ++++ b/src/crypto/sha1/boring.go +@@ -11,11 +11,11 @@ + package sha1 + + import ( +- "crypto/internal/boring" ++ boring "crypto/internal/backend" + "hash" + ) + +-const boringEnabled = boring.Enabled ++var boringEnabled = boring.Enabled + + func boringNewSHA1() hash.Hash { return boring.NewSHA1() } + +diff --git a/src/crypto/sha1/sha1_test.go b/src/crypto/sha1/sha1_test.go +index e369c3b7f4..af10f68853 100644 +--- a/src/crypto/sha1/sha1_test.go ++++ b/src/crypto/sha1/sha1_test.go +@@ -16,7 +16,7 @@ import ( + "testing" + ) + +-import "crypto/internal/boring" ++import boring "crypto/internal/backend" + + type sha1Test struct { + out string +diff --git a/src/crypto/sha256/sha256.go b/src/crypto/sha256/sha256.go +index 8b54a427d7..c6aa7a3788 100644 +--- a/src/crypto/sha256/sha256.go ++++ b/src/crypto/sha256/sha256.go +@@ -13,7 +13,7 @@ import ( + "hash" + ) + +-import "crypto/internal/boring" ++import boring "crypto/internal/backend" + + func init() { + crypto.RegisterHash(crypto.SHA224, New224) +diff --git a/src/crypto/sha256/sha256_test.go b/src/crypto/sha256/sha256_test.go +index 91a4edde04..71eacf53a7 100644 +--- a/src/crypto/sha256/sha256_test.go ++++ b/src/crypto/sha256/sha256_test.go +@@ -16,7 +16,7 @@ import ( + "testing" + ) + +-import "crypto/internal/boring" ++import boring "crypto/internal/backend" + + type sha256Test struct { + out string +diff --git a/src/crypto/sha512/sha512.go b/src/crypto/sha512/sha512.go +index 1a2cef317c..b6b390a1b8 100644 +--- a/src/crypto/sha512/sha512.go ++++ b/src/crypto/sha512/sha512.go +@@ -17,7 +17,7 @@ import ( + "hash" + ) + +-import "crypto/internal/boring" ++import boring "crypto/internal/backend" + + func init() { + crypto.RegisterHash(crypto.SHA384, New384) +diff --git a/src/crypto/sha512/sha512_test.go b/src/crypto/sha512/sha512_test.go +index 966cd51d15..44e3769b0b 100644 +--- a/src/crypto/sha512/sha512_test.go ++++ b/src/crypto/sha512/sha512_test.go +@@ -17,7 +17,7 @@ import ( + "testing" + ) + +-import "crypto/internal/boring" ++import boring "crypto/internal/backend" + + type sha512Test struct { + out string +diff --git a/src/crypto/tls/cipher_suites.go b/src/crypto/tls/cipher_suites.go +index e07d742bd3..3f72b1e5a0 100644 +--- a/src/crypto/tls/cipher_suites.go ++++ b/src/crypto/tls/cipher_suites.go +@@ -4,7 +4,7 @@ + + package tls + +-import "crypto/internal/boring" ++import boring "crypto/internal/backend" + + import ( + "crypto" +diff --git a/src/go/build/deps_test.go b/src/go/build/deps_test.go +index c399946435..ed5b74ee7b 100644 +--- a/src/go/build/deps_test.go ++++ b/src/go/build/deps_test.go +@@ -400,7 +400,14 @@ var depsRules = ` + < crypto/ed25519/internal/edwards25519 + < crypto/cipher + < encoding/asn1 +- < crypto/internal/boring ++ < CRYPTO; ++ ++ CRYPTO < crypto/internal/boring; ++ ++ CRYPTO ++ < github.com/microsoft/go-crypto-openssl/openssl/internal/subtle ++ < github.com/microsoft/go-crypto-openssl/openssl ++ < crypto/internal/backend + < crypto/aes, crypto/des, crypto/hmac, crypto/md5, crypto/rc4, + crypto/sha1, crypto/sha256, crypto/sha512 + < crypto/rand +@@ -430,7 +437,7 @@ var depsRules = ` + crypto/internal/boring/sig, crypto/internal/boring/fipstls + < crypto/tls/fipsonly; + +- crypto/internal/boring ++ crypto/internal/backend + < crypto/boring; + + # crypto-aware packages +@@ -623,7 +630,7 @@ var buildIgnore = []byte("\n// +build ignore") + + func findImports(pkg string) ([]string, error) { + vpkg := pkg +- if strings.HasPrefix(pkg, "golang.org") { ++ if strings.HasPrefix(pkg, "golang.org") || strings.HasPrefix(pkg, "github.com") { + vpkg = "vendor/" + pkg + } + dir := filepath.Join(Default.GOROOT, "src", vpkg) +diff --git a/src/runtime/runtime_boring.go b/src/runtime/runtime_boring.go +index 5a98b20253..9042f2c279 100644 +--- a/src/runtime/runtime_boring.go ++++ b/src/runtime/runtime_boring.go +@@ -17,3 +17,8 @@ func boring_runtime_arg0() string { + + //go:linkname fipstls_runtime_arg0 crypto/internal/boring/fipstls.runtime_arg0 + func fipstls_runtime_arg0() string { return boring_runtime_arg0() } ++ ++//go:linkname crypto_backend_runtime_arg0 crypto/internal/backend.runtime_arg0 ++func crypto_backend_runtime_arg0() string { ++ return boring_runtime_arg0() ++} From 1ab9abcc7d0c3c00235fa750281b034bb7ad0fff Mon Sep 17 00:00:00 2001 From: Davis Goodin Date: Thu, 27 Jan 2022 17:34:31 -0600 Subject: [PATCH 05/47] Fork 1.16 from 1.17 branch --- go | 2 +- ...dist-add-JSON-output-support-for-some-tests.patch | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/go b/go index 9de1ac6ac2c..378766af9ed 160000 --- a/go +++ b/go @@ -1 +1 @@ -Subproject commit 9de1ac6ac2cad3871760d0aa288f5ca713afd0a6 +Subproject commit 378766af9ed0f2e28d67c2b50e73db7573656669 diff --git a/patches/0001-cmd-dist-add-JSON-output-support-for-some-tests.patch b/patches/0001-cmd-dist-add-JSON-output-support-for-some-tests.patch index a9bcff182ae..342a4443613 100644 --- a/patches/0001-cmd-dist-add-JSON-output-support-for-some-tests.patch +++ b/patches/0001-cmd-dist-add-JSON-output-support-for-some-tests.patch @@ -1,4 +1,4 @@ -From be418f20052ddea746451bafe21fdbf2bb1c915d Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Davis Goodin Date: Tue, 4 Jan 2022 11:23:27 -0600 Subject: [PATCH] cmd/dist: add JSON output support for some tests @@ -17,7 +17,7 @@ in JSON format, and the ordinary logs are still important. 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/cmd/dist/test.go b/src/cmd/dist/test.go -index 50a2e5936c..0436c63063 100644 +index 4f081c9f88..c4f1157751 100644 --- a/src/cmd/dist/test.go +++ b/src/cmd/dist/test.go @@ -29,6 +29,7 @@ func cmdtest() { @@ -28,7 +28,7 @@ index 50a2e5936c..0436c63063 100644 flag.BoolVar(&t.rebuild, "rebuild", false, "rebuild everything first") flag.BoolVar(&noRebuild, "no-rebuild", false, "overrides -rebuild (historical dreg)") flag.BoolVar(&t.keepGoing, "k", false, "keep going even when error occurred") -@@ -50,6 +51,7 @@ func cmdtest() { +@@ -49,6 +50,7 @@ func cmdtest() { type tester struct { race bool listMode bool @@ -36,7 +36,7 @@ index 50a2e5936c..0436c63063 100644 rebuild bool failed bool keepGoing bool -@@ -294,9 +296,13 @@ func short() string { +@@ -270,9 +272,13 @@ func short() string { // Callers should use goTest and then pass flags overriding these // defaults as later arguments in the command line. func (t *tester) goTest() []string { @@ -51,9 +51,9 @@ index 50a2e5936c..0436c63063 100644 } func (t *tester) tags() string { -@@ -379,6 +385,9 @@ func (t *tester) registerStdTest(pkg string, useG3 bool) { +@@ -345,6 +351,9 @@ func (t *tester) registerStdTest(pkg string) { t.timeout(timeoutSec), - "-gcflags=all=" + gcflags, + "-gcflags=all=" + gogcflags, } + if t.jsonMode { + args = append(args, "-json") From 5ef23a6a7f5e624a4ffd72c86154a251b31ef170 Mon Sep 17 00:00:00 2001 From: microsoft-golang-bot Date: Fri, 28 Jan 2022 16:06:58 +0000 Subject: [PATCH 06/47] Update submodule to latest release-branch.go1.17 (539d430e): [release-branch.go1.17] math/big: pr[...] --- go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go b/go index 9de1ac6ac2c..539d430efb5 160000 --- a/go +++ b/go @@ -1 +1 @@ -Subproject commit 9de1ac6ac2cad3871760d0aa288f5ca713afd0a6 +Subproject commit 539d430efb5043cc6a2d4d4fcd2866b11717039a From b06f38c8e411d17ac8f3387c58f11ae20444b5d4 Mon Sep 17 00:00:00 2001 From: qmuntal Date: Fri, 28 Jan 2022 17:58:39 -0600 Subject: [PATCH 07/47] Add FIPS OpenSSL documentation --- eng/doc/fips/README.md | 89 +++++ eng/doc/fips/UserGuide.md | 687 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 776 insertions(+) create mode 100644 eng/doc/fips/README.md create mode 100644 eng/doc/fips/UserGuide.md diff --git a/eng/doc/fips/README.md b/eng/doc/fips/README.md new file mode 100644 index 00000000000..c0014398d47 --- /dev/null +++ b/eng/doc/fips/README.md @@ -0,0 +1,89 @@ +# Crypto FIPS 140-2 support + +## Background + +FIPS 140-2 is a U.S. government computer security standard used to approve cryptographic modules. FIPS compliance may come up when working with U.S. government and other regulated industries. + +### Go FIPS compliance + +The Go `crypto` package is not FIPS certified, and the Go team has stated that it won't be, e.g. in [golang/go/issues/21734](https://github.com/golang/go/issues/21734#issuecomment-326980213) Adam Langley says: + +> The status of FIPS 140 for Go itself remains "no plans, basically zero chance". + +On the other hand, Google maintains a branch that uses cgo and BoringSSL to implement various crypto primitives: https://github.com/golang/go/blob/dev.boringcrypto/README.boringcrypto.md. As BoringSSL is FIPS 140-2 certified, an application using that branch is more likely to be FIPS 140-2 compliant, yet Google does not provide any liability about the suitability of this code in relation to the FIPS 140-2 standard. + +In addition to that, the dev.boringcrypto branch also provides a mechanism to restrict all TLS configuration to FIPS-approved settings. The effect is triggered by importing the package anywhere in a program, as in: + +```go + import _ "crypto/tls/fipsonly" +``` + +## Microsoft Go fork FIPS compliance + +Microsoft's Go Linux runtime has been modified to implement several crypto primitives using cgo and OpenSSL. Similar to BoringSSL, certain OpenSSL versions are also FIPS 140-2 certified. + +It is important to note that an application built with Microsoft's Go toolchain and running in FIPS compatible mode is not FIPS compliant _per-se_. It is on the application development team to use FIPS-compliant crypto primitives and workflows. The crypto runtime will fall back to Go standard library crypto in case it cannot provide a FIPS-compliant implementation, e.g. when hashing a message using `crypto/md5` hashes or when using an AES-GCM cipher with a non-standard nonce size. + +## Usage + +FIPS compatibility mode, and therefore the OpenSSL crypto backend, can be enabled using any of these options: + +- Explicitly setting the environment variable `GOFIPS=1`. +- Implicitly enabling it by booting the Linux Kernel in FIPS mode. + - Linux FIPS mode sets the content of `/proc/sys/crypto/fips_enabled` to `1`. The Go runtime reads this file. + - To opt out, set `GOFIPS=0`. + +Whichever is the approach used, the program initialization will panic if FIPS mode is requested but the Go runtime can't find a suitable OpenSSL shared library or OPENSSL FIPS mode can't be enabled. + +The whole OpenSSL functionality can be disabled by building your program with `-tags gocrypto`. + +## Features + +### No code changes required + +Applications requiring FIPS-compliance don't require any code change to activate FIPS compatibility mode. The Go runtime will favor OpenSSL crypto primitives over Go standard library when the application is FIPS-enabled. + +### Multiple OpenSSL versions allowed + +OpenSSL does not maintain ABI compatibility between different releases, even if only the patch version is increased. The Go crypto package has support for multiple OpenSSL versions, yet each version has a different amount of automated validation: + +- OpenSSL 1.1.1: the Microsoft CI builds official releases and runs automated tests with this version. +- OpenSSL 1.0.1: the Microsoft CI builds official releases, but doesn't run tests, so it may not produce working applications. +- OpenSSL 1.1.0 and 3.0: the Microsoft CI does not build nor test these versions, so they may or may not work. + +Versions not listed above are not supported at all. + +### Dynamic OpenSSL linking + +Go automatically loads the OpenSSL shared library `libcrypto` using [dlopen](https://man7.org/linux/man-pages/man3/dlopen.3.html) when initializing a FIPS-enabled program. Therefore, dlopen's shared library search conventions also apply here. + +The `libcrypto` shared library file name varies among different platforms, so a best-effort is done to find and load the right file: + +- The base name is always `libcrypto.so.` +- Well-known version strings are appended to the base name, until the file is found, in the following order: `3` -> `1.1` -> `11` -> `111` -> `1.0.2` -> `1.0.0`. + +This algorithm can be overridden by setting the environment variable `GO_OPENSSL_VERSION_OVERRIDE` to the desired version string. For example, `GO_OPENSSL_VERSION_OVERRIDE="1.1.1k-fips"` makes the runtime look for the shared library `libcrypto.so.1.1.1k-fips` before running the checks for well-known versions. + +### Portable OpenSSL + +The OpenSSL bindings are implemented in such a way that the OpenSSL version used when building a program does not have to match with the OpenSSL version used when running it. It is even possible to build a program using plain Go crypto (i.e. setting `GOFIPS=0`) and then running that same program in FIPS mode. + +This feature does not require any additional configuration, but it only works with OpenSSL versions known and supported by the Go toolchain. + +### TLS with FIPS-approved settings + +The Go TLS stack will automatically use OpenSSL crypto primitives when running in FIPS mode. Yet, the FIPS 140-2 standard places additional restrictions on TLS communications, mainly on which cyphers and signers are allowed. + +A program can import the `crypto/tls/fipsonly` package to configure the Go TLS stack so it is compliant with these restrictions. The configuration is done by an `init()` function. Note that this can reduce compatibility with old devices that do not support modern cryptography techniques such as TLS 1.2. + +## Acknowledgements + +The work done to support FIPS compatibility mode leverages code and ideas from other open-source projects: + +- All crypto stubs are a mirror of Google's [dev.boringcrypto branch](https://github.com/golang/go/tree/dev.boringcrypto) and the release branch ports of that branch. +- The mapping between BoringSSL and OpenSSL APIs is taken from Fedora's [Go fork](https://pagure.io/go). +- Portable OpenSSL implementation ported from Microsoft's [.NET runtime](https://github.com/dotnet/runtime) cryptography module. + +## Disclaimer + +A program running in FIPS mode can claim it is using a FIPS-certified cryptographic module, but it can't claim the program as a whole is FIPS certified without passing the certification process, nor claim it is FIPS compliant without ensuring all crypto APIs and workflows are implemented in a FIPS-compliant manner. diff --git a/eng/doc/fips/UserGuide.md b/eng/doc/fips/UserGuide.md new file mode 100644 index 00000000000..156fee008e8 --- /dev/null +++ b/eng/doc/fips/UserGuide.md @@ -0,0 +1,687 @@ +# FIPS 140-2 User Guide + +This document is a user guide for the Microsoft Go crypto package running on FIPS 140-2 compatibility mode (hereafter referred to as FIPS) when in use with the OpenSSL cryptographic library. It is intended as a technical reference for developers using, and system administrators installing, the Go toolset and the OpenSSL FIPS software, and for use in risk assessment reviews by security auditors. This is not a replacement for the Go crypto documentation, rather it is a collection of notes and more detailed explanations in the context of FIPS compatibility. + +The Go crypto documentation is available online at https://pkg.go.dev/crypto. + +- [FIPS 140-2 User Guide](#fips-140-2-user-guide) + - [Using Go crypto APIs](#using-go-crypto-apis) + - [crypto/aes](#cryptoaes) + - [func NewCipher](#func-newcipher) + - [crypto/cipher](#cryptocipher) + - [func NewGCM](#func-newgcm) + - [func NewGCMWithNonceSize](#func-newgcmwithnoncesize) + - [func NewGCMWithTagSize](#func-newgcmwithtagsize) + - [func NewCBCDecrypter](#func-newcbcdecrypter) + - [func NewCBCEncrypter](#func-newcbcencrypter) + - [func NewCFBDecrypter](#func-newcfbdecrypter) + - [func NewCFBEncrypter](#func-newcfbencrypter) + - [func NewCTR](#func-newctr) + - [func NewOFB](#func-newofb) + - [func StreamReader.Read](#func-streamreaderread) + - [func StreamWriter.Write](#func-streamwriterwrite) + - [func StreamWriter.Close](#func-streamwriterclose) + - [crypto/des](#cryptodes) + - [crypto/dsa](#cryptodsa) + - [crypto/dsa](#cryptodsa-1) + - [crypto/ecdsa](#cryptoecdsa) + - [func Sign](#func-sign) + - [func SignASN1](#func-signasn1) + - [func Verify](#func-verify) + - [func VerifyASN1](#func-verifyasn1) + - [func GenerateKey](#func-generatekey) + - [func PrivateKey.Sign](#func-privatekeysign) + - [crypto/ed25519](#cryptoed25519) + - [crypto/elliptic](#cryptoelliptic) + - [crypto/hmac](#cryptohmac) + - [func Equal](#func-equal) + - [func New](#func-new) + - [crypto/md5](#cryptomd5) + - [crypto/rand](#cryptorand) + - [var Reader](#var-reader) + - [func Int](#func-int) + - [func Prime](#func-prime) + - [func Read](#func-read) + - [crypto/rc4](#cryptorc4) + - [crypto/sha1](#cryptosha1) + - [func New](#func-new-1) + - [func Sum](#func-sum) + - [crypto/sha256](#cryptosha256) + - [func New](#func-new-2) + - [func New224](#func-new224) + - [func Sum224](#func-sum224) + - [func Sum256](#func-sum256) + - [crypto/sha512](#cryptosha512) + - [func New](#func-new-3) + - [func New384](#func-new384) + - [func New512_224](#func-new512_224) + - [func New512_256](#func-new512_256) + - [func Sum384](#func-sum384) + - [func Sum512](#func-sum512) + - [func Sum512_224](#func-sum512_224) + - [func Sum512_256](#func-sum512_256) + - [crypto/subtle](#cryptosubtle) + - [crypto/tls](#cryptotls) + +## Using Go crypto APIs + +This section describes how to use Go crypto APIs in a FIPS compliant manner. + +### [crypto/aes](https://pkg.go.dev/crypto/aes) + +Package aes implements AES encryption (formerly Rijndael), as defined in U.S. Federal Information Processing Standards Publication 197. + +#### func [NewCipher](https://pkg.go.dev/crypto/aes#NewCipher) + +```go +func aes.NewCipher(key []byte) (cipher cipher.Block, err error) +``` + +NewCipher creates and returns a new [cipher.Block](https://pkg.go.dev/crypto/cipher#Block). + +**Parameters** + +`key` is an AES key of length 16, 24, or 32 bytes. + +**Return values** + +`cipher` implements the cipher.Block interface using an OpenSSL cipher function that depends on the `key` length: + +- If `len(key) == 16` then the cipher used is [EVP_aes_128_ecb](https://www.openssl.org/docs/man3.0/man3/EVP_aes_128_ecb.html). +- If `len(key) == 24` then the cipher used is [EVP_aes_192_ecb](https://www.openssl.org/docs/man3.0/man3/EVP_aes_192_ecb.html). +- If `len(key) == 32` then the cipher used is [EVP_aes_256_ecb](https://www.openssl.org/docs/man3.0/man3/EVP_aes_256_ecb.html). + +The cipher.Block methods are implemented as follows: + +- `BlockSize() int` always returns `16`. +- `Encrypt(dst, src []byte)` encrypts `src` into `dst` using [EVP_EncryptUpdate]. +- `Decrypt(dst, src []byte` decrypts `src` into `dst` using [EVP_DecryptUpdate]. + +### [crypto/cipher](https://pkg.go.dev/crypto/cipher) + +Package cipher implements standard block cipher modes that can be wrapped around low-level block cipher implementations. + +#### func [NewGCM](https://pkg.go.dev/crypto/cipher#NewGCM) + +```go +func cipher.NewGCM(cipher cipher.Block) (aead cipher.AEAD, err error) +``` + +NewGCM returns the given 128-bit, block cipher wrapped in Galois Counter Mode with the standard nonce length. + +**Parameters** + +`cipher` must be an object created by [aes.NewCipher](https://pkg.go.dev/crypto/aes#NewCipher) in order to be FIPS compliant. + +**Return values** + +If `cipher` is FIPS compliant then `aead` implements the cipher.AEAD interface as follows: + +- `NonceSize() int` always returns `12`. +- `Overhead() int` always returns `16`. +- The cipher used in `Seal` and `Open` depends on the key length used in `aes.NewCipher(key []byte)`: + - If `len(key) == 16` then the cipher used is [EVP_aes_128_gcm](https://www.openssl.org/docs/man3.0/man3/EVP_aes_128_gcm.html). + - If `len(key) == 24` then the cipher used is [EVP_aes_192_gcm](https://www.openssl.org/docs/man3.0/man3/EVP_aes_192_gcm.html). + - If `len(key) == 32` then the cipher used is [EVP_aes_256_gcm](https://www.openssl.org/docs/man3.0/man3/EVP_aes_256_gcm.html). +- `Seal(dst, nonce, plaintext, additionalData []byte) []byte` encrypts plaintext and uses additionalData to authenticate. It uses [EVP_EncryptUpdate] for the encryption and [EVP_EncryptFinal_ex](https://www.openssl.org/docs/man3.0/man3/EVP_EncryptFinal_ex.html) for authenticating. +- `Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error)` decrypts plaintext and uses additionalData to authenticate. It uses [EVP_DecryptUpdate] for the decryption and [EVP_DecryptFinal_ex](https://www.openssl.org/docs/man3.0/man3/EVP_DecryptFinal_ex.html) for authenticating. + +If `cipher` is not FIPS compliant then `aead` is implemented by the standard Go library. + +#### func [NewGCMWithNonceSize](https://pkg.go.dev/crypto/cipher#NewGCMWithNonceSize) + +```go +func cipher.NewGCMWithNonceSize(cipher cipher.Block, size int) (aead cipher.AEAD, error) +``` + +NewGCMWithNonceSize returns the given 128-bit, block cipher wrapped in Galois Counter Mode, which accepts nonces of the given length. + +**Parameters** + +`cipher` must be an object created by aes.NewCipher and `size = 12` in order to be FIPS compliant, else the function will fall back to standard Go crypto. + +**Return values** + +`aead` can have different implementations depending on the supplied parameters: + +- If the parameters are FIPS compliant then `aead` behaves exactly as if it was created with cipher.NewGCM. +- If `cipher` is an object created by aes.NewCipher and `size != 12` then `aead` is implemented by the standard Go library and OpenSSL is only used for encryption and decryption. +- Else `aead` is completely implemented by the standard Go library. + +#### func [NewGCMWithTagSize](https://pkg.go.dev/crypto/cipher#NewGCMWithTagSize) + +```go +func cipher.NewGCMWithTagSize(cipher cipher.Block, tagSize int) (aead cipher.AEAD, error) +``` + +NewGCMWithTagSize returns the given 128-bit, block cipher wrapped in Galois Counter Mode, which generates tags with the given length. + +**Parameters** + +`cipher` must be an object created by aes.NewCipher and `tagSize = 16` in order to be FIPS compliant, else the function will fall back to standard Go crypto. + +**Return values** + +`aead` can have different implementations depending on the supplied parameters: + +- If the parameters are FIPS compliant then `aead` behaves exactly as if it was created with cipher.NewGCM. +- If `cipher` is an object created by aes.NewCipher and `tagSize != 16` then `aead` is implemented by the standard Go library using OpenSSL for encryption and decryption. +- Else `aead` is completely implemented by the standard Go library. + +#### func [NewCBCDecrypter](https://pkg.go.dev/crypto/cipher#NewCBCDecrypter) + +```go +func cipher.NewCBCDecrypter(block Block, iv []byte) (cbc cipher.BlockMode) +``` + +NewCBCDecrypter returns a BlockMode which decrypts in cipher block chaining mode, using the given Block. + +**Parameters** + +`block` must be an object created by [aes.NewCipher](https://pkg.go.dev/crypto/aes#NewCipher) in order to be FIPS compliant. + +**Return values** + +If `block` is FIPS compliant then `cbc` implements the cipher.BlockMode using an OpenSSL cipher that depends on the `block` key length: + +- If `len(key) == 16` then the cipher used is [EVP_aes_128_cbc](https://www.openssl.org/docs/man3.0/man3/EVP_aes_128_cbc.html). +- If `len(key) == 24` then the cipher used is [EVP_aes_192_cbc](https://www.openssl.org/docs/man3.0/man3/EVP_aes_192_cbc.html). +- If `len(key) == 32` then the cipher used is [EVP_aes_256_cbc](https://www.openssl.org/docs/man3.0/man3/EVP_aes_256_cbc.html). + +In all cases the cipher will have the padding disabled using [EVP_CIPHER_CTX_set_padding](https://www.openssl.org/docs/man3.0/man3/EVP_CIPHER_CTX_set_padding.html). + +The cipher.BlockMode methods are implemented as follows: + +- `BlockSize() int` always returns `16`. +- `CryptBlocks(dst, src []byte)` decrypts `src` into `dst` using [EVP_DecryptUpdate]. + +If `block` is not FIPS compliant then `cbc` is implemented by the standard Go library. + +#### func [NewCBCEncrypter](https://pkg.go.dev/crypto/cipher#NewCBCEncrypter) + +```go +func cipher.NewCBCEncrypter(block Block, iv []byte) (cbc cipher.BlockMode) +``` + +NewCBCEncrypter returns a BlockMode which encrypts in cipher block chaining mode, using the given Block. + +**Parameters** + +`block` must be an object created by [aes.NewCipher](https://pkg.go.dev/crypto/aes#NewCipher) in order to be FIPS compliant. + +**Return values** + +If `block` is FIPS compliant then `cbc` implements the cipher.BlockMode using an OpenSSL cipher that depends on the `block` key length: + +- If `len(key) == 16` then the cipher used is [EVP_aes_128_cbc](https://www.openssl.org/docs/man3.0/man3/EVP_aes_128_cbc.html). +- If `len(key) == 24` then the cipher used is [EVP_aes_192_cbc](https://www.openssl.org/docs/man3.0/man3/EVP_aes_192_cbc.html). +- If `len(key) == 32` then the cipher used is [EVP_aes_256_cbc](https://www.openssl.org/docs/man3.0/man3/EVP_aes_256_cbc.html). + +The cipher.BlockMode methods are implemented as follows: + +- `BlockSize() int` always returns `16`. +- `CryptBlocks(dst, src []byte)` encrypts `src` into `dst` using [EVP_EncryptUpdate]. + +If `block` is not FIPS compliant then `cbc` is implemented by the standard Go library. + +#### func [NewCFBDecrypter](https://pkg.go.dev/crypto/cipher#NewCFBDecrypter) + +cipher.NewCFBDecrypter is not FIPS compliant. + +#### func [NewCFBEncrypter](https://pkg.go.dev/crypto/cipher#NewCFBEncrypter) + +cipher.NewCFBEncrypter is not FIPS compliant. + +#### func [NewCTR](https://pkg.go.dev/crypto/cipher#NewCTR) + +```go +func cipher.NewCTR(block Block, iv []byte) (ctr cipher.BlockMode) +``` + +NewCTR returns a Stream which encrypts/decrypts using the given Block in counter mode. + +**Parameters** + +`block` must be an object created by [aes.NewCipher](https://pkg.go.dev/crypto/aes#NewCipher) in order to be FIPS compliant. + +**Return values** + +If `block` is FIPS compliant then `ctr` implements the cipher.Stream using an OpenSSL cipher that depends on the `block` key length: + +- If `len(key) == 16` then the cipher used is [EVP_aes_128_ctr](https://www.openssl.org/docs/man3.0/man3/EVP_aes_128_ctr.html). +- If `len(key) == 24` then the cipher used is [EVP_aes_192_ctr](https://www.openssl.org/docs/man3.0/man3/EVP_aes_192_ctr.html). +- If `len(key) == 32` then the cipher used is [EVP_aes_256_ctr](https://www.openssl.org/docs/man3.0/man3/EVP_aes_256_ctr.html). + + +The cipher.Stream methods are implemented as follows: +- `XORKeyStream(dst, src []byte)` XORs each byte in the given slice using [EVP_EncryptUpdate]. + +If `block` is not FIPS compliant then `ctr` is implemented by the standard Go library. + +#### func [NewOFB](https://pkg.go.dev/crypto/cipher#NewOFB) + +cipher.NewOFB is not FIPS compliant. + +#### func [StreamReader.Read](https://pkg.go.dev/crypto/cipher#StreamReader.Read) + +```go +func (r cipher.StreamReader) Read(dst []byte) (n int, err error) +``` + +Can be used in a FIPS compliant manner if `r.S` is an object created using cipher.NewCTR with FIPS compliant parameters. + +#### func [StreamWriter.Write](https://pkg.go.dev/crypto/cipher#StreamWriter.Write) + +```go +func (w cipher.StreamWriter) Write(src []byte) (n int, err error) +``` + +Can be used in a FIPS 140-2 compliant manner if `w.S` is an object created using cipher.NewCTR with FIPS compliant parameters. + +#### func [StreamWriter.Close](https://pkg.go.dev/crypto/cipher#StreamWriter.Close) + +```go +func (w cipher.StreamWriter) Close() error +``` + +Can be used in a FIPS 140-2 compliant manner if `w.S` is an object created using cipher.NewCTR with FIPS compliant parameters. + +### [crypto/des](https://pkg.go.dev/crypto/des) + +Not FIPS compliant. + +### [crypto/dsa](https://pkg.go.dev/crypto/dsa) + +Not FIPS compliant. + +### [crypto/dsa](https://pkg.go.dev/crypto/dsa) + +Not FIPS compliant. + +### [crypto/ecdsa](https://pkg.go.dev/crypto/ecdsa) + +Package ecdsa implements the Elliptic Curve Digital Signature Algorithm, as defined in FIPS 186-3. + +#### func [Sign](https://pkg.go.dev/crypto/ecdsa#Sign) + +```go +func ecdsa.Sign(rand io.Reader, priv *ecdsa.PrivateKey, hash []byte) (r, s *big.Int, err error) +``` + +Sign signs a hash using the private key. + +**Parameters** + +`rand` must be boring.RandReader, else Sign will panic. `crypto/rand.Reader` normally meets this invariant, as it is assigned to boring.RandReader in the crypto/rand init function. + +`hash` must be the result of hashing a message using a FIPS compliant hashing algorithm. If this invariant is not met, Sign won't be FIPS compliant but still will sign the message. + +**Return values** + +`r` and `s` are generated using [ECDSA_sign](https://www.openssl.org/docs/man3.0/man3/ECDSA_sign.html). + +#### func [SignASN1](https://pkg.go.dev/crypto/ecdsa#SignASN1) + +```go +func ecdsa.SignASN1(rand io.Reader, priv *ecdsa.PrivateKey, hash []byte) (sig []byte, err error) +``` + +SignASN1 signs a hash using the private key. It behaves as ecdsa.Sign but returns an ASN.1 encoded signature instead. + +#### func [Verify](https://pkg.go.dev/crypto/ecdsa#Verify) + +```go +func ecdsa.Verify(pub *ecdsa.PublicKey, hash []byte, r, s *big.Int) bool +``` + +Verify verifies the signature in r, s of hash using the public key. + +**Parameters** + +There are no specific parameters requirements in order to be FIPS compliant. + +**Return values** + +Returns `true` if the signature is valid using [ECDSA_verify](https://www.openssl.org/docs/man3.0/man3/ECDSA_verify.html). + +#### func [VerifyASN1](https://pkg.go.dev/crypto/ecdsa#VerifyASN1) + +```go +func ecdsa.VerifyASN1(pub *ecdsa.PublicKey, hash, sig []byte) bool +``` + +VerifyASN1 verifies the ASN.1 encoded signature, sig, of hash using the public key. It behaves as ecdsa.Verify but accepts an ASN.1 encoded signature instead. + +#### func [GenerateKey](https://pkg.go.dev/crypto/ecdsa#GenerateKey) + +```go +func ecdsa.GenerateKey(c elliptic.Curve, rand io.Reader) (priv *ecdsa.PrivateKey, err error) +``` + +GenerateKey generates a public and private key pair. + +**Parameters** + +`rand` must be boring.RandReader, else Sign will panic. `crypto/rand.Reader` normally meet this invariant as it is assigned to boring.RandReader in the crypto/rand init function. + +**Return values** + +The `priv` curve algorithm depends on the value of `c`: + +- If `c.Params().Name == "P-224"` then curve is `NID_secp224r1`. +- If `c.Params().Name == "P-256"` then curve is `NID_X9_62_prime256v1`. +- If `c.Params().Name == "P-384"` then curve is `NID_secp384r1`. +- If `c.Params().Name == "P-521"` then curve is `NID_secp521r1`. + +Other `c` values will result in an error. + +#### func [PrivateKey.Sign](https://pkg.go.dev/crypto/ecdsa#PrivateKey.Sign) + +```go +func (priv *ecdsa.PrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) +``` + +Sign signs `digest` with `priv`. + +**Parameters** + +`rand` must be boring.RandReader, else Sign will panic. `crypto/rand.Reader` normally meet this invariant as it is assigned to boring.RandReader in the crypto/rand init function. + +`digest` must be the result of hashing a message using a FIPS compliant hashing algorithm. If this invariant is not met, Sign won't be FIPS compliant but still will sign the message. + +**Return values** + +Signed messaged using [ECDSA_sign](https://www.openssl.org/docs/man3.0/man3/ECDSA_sign.html). + +### [crypto/ed25519](https://pkg.go.dev/crypto/ed25519) + +Not FIPS compliant. + +### [crypto/elliptic](https://pkg.go.dev/crypto/elliptic) + +Not FIPS compliant. + +### [crypto/hmac](https://pkg.go.dev/crypto/hmac) + +Package hmac implements the Keyed-Hash Message Authentication Code (HMAC) as defined in U.S. Federal Information Processing Standards Publication 198. + +#### func [Equal](https://pkg.go.dev/crypto/hmac#Equal) + +```go +func hmac.Equal(mac1, mac2 []byte) bool +``` + +Equal compares two MACs for equality without leaking timing information. + +This function does not implement any cryptographic algorithm, therefore out of FIPS scope. + +#### func [New](https://pkg.go.dev/crypto/hmac#New) + +```go +func hmac.New(h func() hash.Hash, key []byte) hash.Hash +``` + +New returns a new HMAC hash using the given hash.Hash type and key. + +**Parameters** + +`h` must be one of the following functions in order to be FIPS compliant: sha1.New, sha256.New, or sha512.New. + +**Return values** + +The hash.Hash methods are implemented as follows: + +- `Write(p []byte) (int, error)` using [HMAC_Update](https://www.openssl.org/docs/manmaster/man3/HMAC_Update.html). +- `Sum(in []byte) []byte` using [HMAC_Final](https://www.openssl.org/docs/manmaster/man3/HMAC_Final.html). +- `Reset()` using [HMAC_Init_ex](https://www.openssl.org/docs/manmaster/man3/HMAC_Init_ex.html). + +### [crypto/md5](https://pkg.go.dev/crypto/md5) + +Not FIPS compliant. + +### [crypto/rand](https://pkg.go.dev/crypto/rand) + +Package rand implements a cryptographically secure random number generator. + +#### var [Reader](https://pkg.go.dev/crypto/rand#pkg-variables) + +```go +var Reader io.Reader +``` + +Reader is a global, shared instance of a cryptographically secure random number generator. +It is assigned to boring.RandReader in the crypto/rand init function, which implements `io.Reader` by using the OpenSSL function [RAND_bytes](https://www.openssl.org/docs/man3.0/man3/RAND_bytes.html). + + +#### func [Int](https://pkg.go.dev/crypto/rand#Int) + +```go +func rand.Int(rand io.Reader, max *big.Int) (n *big.Int, err error) +``` + +Int returns a uniform random value in [0, max). It panics if max <= 0. + +**Parameters** + +`rand` must be boring.RandReader in order to be FIPS compliant. `crypto/rand.Reader` normally meet this invariant as it is assigned to boring.RandReader in the crypto/rand init function. + +#### func [Prime](https://pkg.go.dev/crypto/rand#Prime) + +```go +func Prime(rand io.Reader, bits int) (p *big.Int, err error) +``` + +func Prime(rand io.Reader, bits int) (p *big.Int, err error) + +**Parameters** + +`rand` must be boring.RandReader in order to be FIPS compliant. `crypto/rand.Reader` normally meet this invariant as it is assigned to boring.RandReader in the crypto/rand init function. + +#### func [Read](https://pkg.go.dev/crypto/rand#Read) + +```go +func Read(b []byte) (n int, err error) +``` + +Read is a helper function that calls rand.Reader.Read using io.ReadFull. It is FIPS compliant as long as `rand.Reader == boring.RandReader`. + +### [crypto/rc4](https://pkg.go.dev/crypto/rc4) + +Not FIPS compliant. + +### [crypto/sha1](https://pkg.go.dev/crypto/sha1) + +Package sha1 implements the SHA-1 hash algorithm as defined in RFC 3174. + +SHA-1 is an approved FIPS 140-2 hash algorithm although it is cryptographically broken and should not be used for secure applications. + +#### func [New](https://pkg.go.dev/crypto/sha1#New) + +```go +func sha1.New() hash.Hash +``` + +New returns a new hash.Hash computing the SHA1 checksum. + +**Return values** + +The hash.Hash methods are implemented as follows: + +- `Write(p []byte) (int, error)` using [SHA1_Update](https://www.openssl.org/docs/manmaster/man3/SHA1_Update.html). +- `Sum(in []byte) []byte` using [SHA1_Final](https://www.openssl.org/docs/manmaster/man3/SHA1_Final.html). +- `Reset()` using [SHA1_Init](https://www.openssl.org/docs/manmaster/man3/SHA1_Init.html). + +#### func [Sum](https://pkg.go.dev/crypto/sha1#Sum) + +```go +func sha1.Sum(data []byte) [20]byte +``` + +Sum returns the SHA-1 checksum of the data. +It internally uses sha1.New() to compute the checksum. + +### [crypto/sha256](https://pkg.go.dev/crypto/sha256) + +Package sha256 implements the SHA224 and SHA256 hash algorithms as defined in FIPS 180-4. + +#### func [New](https://pkg.go.dev/crypto/sha256#New) + +```go +func sha256.New() hash.Hash +``` + +New returns a new hash.Hash computing the SHA256 checksum. + +**Return values** + +The hash.Hash methods are implemented as follows: + +- `Write(p []byte) (int, error)` using [SHA256_Update](https://www.openssl.org/docs/manmaster/man3/SHA256_Update.html). +- `Sum(in []byte) []byte` using [SHA256_Final](https://www.openssl.org/docs/manmaster/man3/SHA256_Final.html). +- `Reset()` using [SHA256_Init](https://www.openssl.org/docs/manmaster/man3/SHA256_Init.html). + + +#### func [New224](https://pkg.go.dev/crypto/sha256#New224) + +```go +func sha256.New224() hash.Hash +``` + +New224 returns a new hash.Hash computing the SHA224 checksum. + +**Return values** + +The hash.Hash methods are implemented as follows: + +- `Write(p []byte) (int, error)` using [SHA224_Update](https://www.openssl.org/docs/manmaster/man3/SHA224_Update.html). +- `Sum(in []byte) []byte` using [SHA224_Final](https://www.openssl.org/docs/manmaster/man3/SHA224_Final.html). +- `Reset()` using [SHA224_Init](https://www.openssl.org/docs/manmaster/man3/SHA224_Init.html). + +#### func [Sum224](https://pkg.go.dev/crypto/sha256#Sum224) + +```go +func sha256.Sum224(data []byte) [24]byte +``` + +Sum224 returns the SHA224 checksum of the data. +It internally uses sha224.New() to compute the checksum. + +#### func [Sum256](https://pkg.go.dev/crypto/sha256#Sum256) + +```go +func sha256.Sum256(data []byte) [32]byte +``` + +Sum256 returns the SHA256 checksum of the data. +It internally uses sha256.New() to compute the checksum. + +### [crypto/sha512](https://pkg.go.dev/crypto/sha512) + +Package sha512 implements the SHA-384, SHA-512, SHA-512/224, and SHA-512/256 hash algorithms as defined in FIPS 180-4. + +#### func [New](https://pkg.go.dev/crypto/sha512#New) + +```go +func sha512.New() hash.Hash +``` + +New returns a new hash.Hash computing the SHA-512 checksum. + +**Return values** + +The hash.Hash methods are implemented as follows: + +- `Write(p []byte) (int, error)` using [SHA512_Update](https://www.openssl.org/docs/manmaster/man3/SHA512_Update.html). +- `Sum(in []byte) []byte` using [SHA512_Final](https://www.openssl.org/docs/manmaster/man3/SHA512_Final.html). +- `Reset()` using [SHA512_Init](https://www.openssl.org/docs/manmaster/man3/SHA512_Init.html). + +#### func [New384](https://pkg.go.dev/crypto/sha512#New384) + +```go +func sha512.New384() hash.Hash +``` + +New384 returns a new hash.Hash computing the SHA-384 checksum. + +**Return values** + +The hash.Hash methods are implemented as follows: + +- `Write(p []byte) (int, error)` using [SHA384_Update](https://www.openssl.org/docs/manmaster/man3/SHA384_Update.html). +- `Sum(in []byte) []byte` using [SHA384_Final](https://www.openssl.org/docs/manmaster/man3/SHA384_Final.html). +- `Reset()` using [SHA384_Init](https://www.openssl.org/docs/manmaster/man3/SHA384_Init.html). + +#### func [New512_224](https://pkg.go.dev/crypto/sha512#New512_224) + +sha512.New512_224 is not FIPS compliant. + +#### func [New512_256](https://pkg.go.dev/crypto/sha512#New512_256) + +sha512.New512_256 is not FIPS compliant. + +#### func [Sum384](https://pkg.go.dev/crypto/sha512#Sum384) + +```go +func sha512.Sum384(data []byte) [48]byte +``` + +Sum384 returns the SHA384 checksum of the data. +It internally uses sha512.New384() to compute the checksum. + +#### func [Sum512](https://pkg.go.dev/crypto/sha512#Sum512) + +```go +func sha512.Sum512(data []byte) [64]byte +``` + +Sum512 returns the SHA512 checksum of the data. +It internally uses sha512.New() to compute the checksum. + +#### func [Sum512_224](https://pkg.go.dev/crypto/sha512#Sum512_224) + +sha512.Sum512_224 is not FIPS compliant. + +#### func [Sum512_256](https://pkg.go.dev/crypto/sha512#Sum512_256) + +sha512.Sum512_256 is not FIPS compliant. + +### [crypto/subtle](https://pkg.go.dev/crypto/subtle) + +Does not contain crypto primitives, out of FIPS scope. + +### [crypto/tls](https://pkg.go.dev/crypto/tls) + +Package tls partially implements TLS 1.2, as specified in RFC 5246, and TLS 1.3, as specified in RFC 8446. + +Package tls will automatically use FIPS compliant primitives implemented in other crypto packages, but it will accept non-FIPS ciphers and signature algorithms unless `crypto/tls/fipsonly` is imported. + +When using TLS in FIPS-only mode the TLS handshake has the following restrictions: + +- TLS versions: `tls.VersionTLS12` +- ECDSA elliptic curves: + - `tls.CurveP256` + - `tls.CurveP384` + - `tls.CurveP521` +- Cipher suites: + - `tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256` + - `tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384` + - `tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256` + - `tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384` + - `tls.TLS_RSA_WITH_AES_128_GCM_SHA256` + - `tls.TLS_RSA_WITH_AES_256_GCM_SHA384` +- x509 certificate public key: + - `rsa.PublicKey` with a bit length of 2048 or 3072. Bit length of 4096 is still not supported, see [this issue](https://github.com/golang/go/issues/41147) for more info. + - `ecdsa.PublicKey` with a supported elliptic curve. +- Signature algorithms: + - `tls.PSSWithSHA256` + - `tls.PSSWithSHA384` + - `tls.PSSWithSHA512` + - `tls.PKCS1WithSHA256` + - `tls.ECDSAWithP256AndSHA256` + - `tls.PKCS1WithSHA384` + - `tls.ECDSAWithP384AndSHA384` + - `tls.PKCS1WithSHA512` + - `tls.ECDSAWithP521AndSHA512` + +[EVP_EncryptUpdate]: https://www.openssl.org/docs/manmaster/man3/EVP_EncryptUpdate.html +[EVP_DecryptUpdate]: https://www.openssl.org/docs/manmaster/man3/EVP_DecryptUpdate.html \ No newline at end of file From cdf357409f65428e63cacacaf54436f3708a9025 Mon Sep 17 00:00:00 2001 From: Davis Goodin Date: Mon, 31 Jan 2022 12:39:36 -0600 Subject: [PATCH 08/47] Find submodule VERSION file for build asset json (#391) Cherry-pick 1878cac907cf565ca190500e3b78f1493e2b771e --- eng/pipeline/jobs/run-job.yml | 21 +---------------- eng/pipeline/rolling-internal-pipeline.yml | 3 ++- eng/pipeline/steps/init-submodule-task.yml | 26 ++++++++++++++++++++++ 3 files changed, 29 insertions(+), 21 deletions(-) create mode 100644 eng/pipeline/steps/init-submodule-task.yml diff --git a/eng/pipeline/jobs/run-job.yml b/eng/pipeline/jobs/run-job.yml index 89797a2b8c5..f1ed89cdeac 100644 --- a/eng/pipeline/jobs/run-job.yml +++ b/eng/pipeline/jobs/run-job.yml @@ -49,26 +49,7 @@ jobs: Get-Stage0GoRoot displayName: Init stage 0 Go toolset - - pwsh: | - function fetch_submodule() { - eng/run.ps1 submodule-refresh -shallow @args - } - - if ("$env:FETCH_BEARER_TOKEN") { - fetch_submodule ` - -origin 'https://dnceng@dev.azure.com/dnceng/internal/_git/microsoft-go-mirror' ` - -fetch-bearer-token $env:FETCH_BEARER_TOKEN - } else { - fetch_submodule - } - # If non-public, use access token to fetch from repo. If public, don't use the access token, - # because anonymous auth is fine. - ${{ if ne(variables['System.TeamProject'], 'public') }}: - env: - FETCH_BEARER_TOKEN: $(System.AccessToken) - displayName: Set up submodule from internal mirror - ${{ if eq(variables['System.TeamProject'], 'public') }}: - displayName: Set up submodule + - template: ../steps/init-submodule-task.yml # Use build script directly for "buildandpack". If we used run-builder, we would need to # download its external module dependencies. diff --git a/eng/pipeline/rolling-internal-pipeline.yml b/eng/pipeline/rolling-internal-pipeline.yml index f459b740ecf..eded261f086 100644 --- a/eng/pipeline/rolling-internal-pipeline.yml +++ b/eng/pipeline/rolling-internal-pipeline.yml @@ -37,6 +37,7 @@ stages: steps: - template: steps/checkout-unix-task.yml - template: steps/init-pwsh-task.yml + - template: steps/init-submodule-task.yml - pwsh: | function TrimStart($s, $prefix) { @@ -68,7 +69,7 @@ stages: - pwsh: | eng/run.ps1 createbuildassetjson ` -artifacts-dir '$(Pipeline.Workspace)/Binaries Signed/' ` - -source-dir '$(Build.SourcesDirectory)' ` + -source-dir '$(Build.SourcesDirectory)/go' ` -destination-url '$(blobDestinationUrl)' ` -branch '$(PublishBranchAlias)' ` -o '$(Pipeline.Workspace)/Binaries Signed/assets.json' diff --git a/eng/pipeline/steps/init-submodule-task.yml b/eng/pipeline/steps/init-submodule-task.yml new file mode 100644 index 00000000000..dc6f2dd3a90 --- /dev/null +++ b/eng/pipeline/steps/init-submodule-task.yml @@ -0,0 +1,26 @@ +# Copyright (c) Microsoft Corporation. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + +# Shallow checkout sources on Windows +steps: + - pwsh: | + function fetch_submodule() { + eng/run.ps1 submodule-refresh -shallow @args + } + + if ("$env:FETCH_BEARER_TOKEN") { + fetch_submodule ` + -origin 'https://dnceng@dev.azure.com/dnceng/internal/_git/microsoft-go-mirror' ` + -fetch-bearer-token $env:FETCH_BEARER_TOKEN + } else { + fetch_submodule + } + # If non-public, use access token to fetch from repo. If public, don't use the access token, + # because anonymous auth is fine. + ${{ if ne(variables['System.TeamProject'], 'public') }}: + env: + FETCH_BEARER_TOKEN: $(System.AccessToken) + displayName: Set up submodule from internal mirror + ${{ if eq(variables['System.TeamProject'], 'public') }}: + displayName: Set up submodule From 04d934328ec587d6fa01647c09be1c2a2b0d3a58 Mon Sep 17 00:00:00 2001 From: microsoft-golang-bot Date: Fri, 4 Feb 2022 16:04:59 +0000 Subject: [PATCH 09/47] Update submodule to latest release-branch.go1.17 (1b867ce3): [release-branch.go1.17] debug/pe,deb[...] --- go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go b/go index 539d430efb5..1b867ce3efa 160000 --- a/go +++ b/go @@ -1 +1 @@ -Subproject commit 539d430efb5043cc6a2d4d4fcd2866b11717039a +Subproject commit 1b867ce3efa427d8b4bb07f51b0f8a262f3a1227 From 7f876da4c4f722bc1cf07f41d6c39714c58bd86f Mon Sep 17 00:00:00 2001 From: microsoft-golang-bot Date: Wed, 9 Feb 2022 16:02:25 +0000 Subject: [PATCH 10/47] Update submodule to latest release-branch.go1.17 (1952c65f): [release-branch.go1.17] runtime: set[...] --- go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go b/go index 1b867ce3efa..1952c65f9af 160000 --- a/go +++ b/go @@ -1 +1 @@ -Subproject commit 1b867ce3efa427d8b4bb07f51b0f8a262f3a1227 +Subproject commit 1952c65f9af1820d1528a1b38fed26dceddd92a0 From d52c9c650b801391590d5ec38294b2a7c1bac22b Mon Sep 17 00:00:00 2001 From: Davis Goodin Date: Wed, 9 Feb 2022 12:52:41 -0600 Subject: [PATCH 11/47] Create source archive during CI (#408) (#413) * Create source archive during CI * Update go-infra for createbuildassetjson src archive support (cherry picked from commit 3365189f8bf8e9c620132886f8f39283567ec5c4) --- eng/_core/archive/archive.go | 65 ++++++++++++++++--- eng/_core/cmd/pack-source/pack-source.go | 46 +++++++++++++ .../submodule-refresh/submodule-refresh.go | 5 ++ eng/_util/go.mod | 2 +- eng/_util/go.sum | 4 +- eng/pipeline/jobs/builders-to-jobs.yml | 3 + eng/pipeline/jobs/go-builder-matrix-jobs.yml | 2 + eng/pipeline/jobs/run-job.yml | 18 ++++- eng/pipeline/rolling-internal-pipeline.yml | 1 + eng/pipeline/steps/init-submodule-task.yml | 2 +- 10 files changed, 133 insertions(+), 15 deletions(-) create mode 100644 eng/_core/cmd/pack-source/pack-source.go diff --git a/eng/_core/archive/archive.go b/eng/_core/archive/archive.go index 9ac017d77ba..213c874e5ed 100644 --- a/eng/_core/archive/archive.go +++ b/eng/_core/archive/archive.go @@ -16,12 +16,49 @@ import ( "io" "io/fs" "os" + "os/exec" "path/filepath" "runtime" "strings" "time" ) +// CreateFromSource runs a Git command to generate an archive file from the Go source code at +// "source". If output is "", the archive is produced in the build directory inside the +// "eng/artifacts/bin" directory. A checksum file is also produced. +func CreateFromSource(source string, output string) error { + fmt.Printf("---- Creating Go source archive (tarball) from '%v'...\n", source) + + if output == "" { + output = filepath.Join(getBinDir(source), fmt.Sprintf("go.%v.src.tar.gz", getBuildID())) + } + + // Ensure the target directory exists. + archiveDir := filepath.Dir(output) + if err := os.MkdirAll(archiveDir, os.ModeDir|os.ModePerm); err != nil { + return err + } + + // Use "^{tree}" to avoid Git including a global extended pax header. The commit it would list + // is a temporary commit, and would only be confusing. See https://git-scm.com/docs/git-archive. + cmd := exec.Command("git", "archive", "-o", output, "--prefix=go/", "HEAD^{tree}") + cmd.Dir = source + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + fmt.Printf("---- Running command: %v\n", cmd.Args) + if err := cmd.Run(); err != nil { + return err + } + + fmt.Printf("---- Creating checksum file...\n") + if err := writeSHA256ChecksumFile(output); err != nil { + return err + } + + fmt.Printf("---- Pack complete.\n") + return nil +} + // CreateFromBuild walks the Go build directory at "source" and produces an archive with the path // "output". If output is "", CreateFromBuild produces a file in the build directory inside the // "eng/artifacts/bin" directory. The output directory is created if it doesn't exist. This function @@ -34,21 +71,14 @@ func CreateFromBuild(source string, output string) error { fmt.Printf("---- Creating Go archive (zip/tarball) from '%v'...\n", source) if output == "" { - // If BUILD_BUILDNUMBER is defined (e.g. a CI build), use it. For local builds, use "dev". - archiveVersion := os.Getenv("BUILD_BUILDNUMBER") - if archiveVersion == "" { - archiveVersion = "dev" - } - + archiveVersion := getBuildID() archiveExtension := ".tar.gz" if runtime.GOOS == "windows" { archiveExtension = ".zip" } archiveName := fmt.Sprintf("go.%v.%v-%v%v", archiveVersion, runtime.GOOS, runtime.GOARCH, archiveExtension) - binDir := filepath.Join(source, "..", "eng", "artifacts", "bin") - - output = filepath.Join(binDir, archiveName) + output = filepath.Join(getBinDir(source), archiveName) } // Ensure the target directory exists. @@ -186,12 +216,27 @@ func CreateFromBuild(source string, output string) error { } fmt.Printf("---- Creating checksum file...\n") - writeSHA256ChecksumFile(output) + if err := writeSHA256ChecksumFile(output); err != nil { + return err + } fmt.Printf("---- Pack complete.\n") return nil } +// getBuildID returns BUILD_BUILDNUMBER if defined (e.g. a CI build). Otherwise, "dev". +func getBuildID() string { + archiveVersion := os.Getenv("BUILD_BUILDNUMBER") + if archiveVersion == "" { + return "dev" + } + return archiveVersion +} + +func getBinDir(source string) string { + return filepath.Join(source, "..", "eng", "artifacts", "bin") +} + // getArchivePathRuntime takes a path like "go1.7.linux-amd64.tar.gz" and extension like ".tar.gz", // and returns the os (linux) and arch (amd64). The "path" extension may have multiple '.' // characters in it, so "ext" must be passed in explicitly or else the match would be ambiguous. diff --git a/eng/_core/cmd/pack-source/pack-source.go b/eng/_core/cmd/pack-source/pack-source.go new file mode 100644 index 00000000000..62e7f294113 --- /dev/null +++ b/eng/_core/cmd/pack-source/pack-source.go @@ -0,0 +1,46 @@ +// Copyright (c) Microsoft Corporation. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "flag" + "fmt" + "os" + "path/filepath" + + "github.com/microsoft/go/_core/archive" +) + +const description = ` +This command creates a source archive of the Go submodule at HEAD. +` + +func main() { + output := flag.String("o", "", "The path of the archive file to create, including extension. Default: a tar.gz file including build number in 'eng/artifacts/bin'.") + help := flag.Bool("h", false, "Print this help message.") + + flag.Usage = func() { + fmt.Fprintf(flag.CommandLine.Output(), "Usage:\n") + flag.PrintDefaults() + fmt.Fprintf(flag.CommandLine.Output(), "%s\n", description) + } + + flag.Parse() + if *help { + flag.Usage() + return + } + + repoRootDir, err := os.Getwd() + if err != nil { + panic(err) + } + + goRootDir := filepath.Join(repoRootDir, "go") + + if err := archive.CreateFromSource(goRootDir, *output); err != nil { + panic(err) + } +} diff --git a/eng/_core/cmd/submodule-refresh/submodule-refresh.go b/eng/_core/cmd/submodule-refresh/submodule-refresh.go index ca582702585..9566fb11511 100644 --- a/eng/_core/cmd/submodule-refresh/submodule-refresh.go +++ b/eng/_core/cmd/submodule-refresh/submodule-refresh.go @@ -19,6 +19,7 @@ applies patches to the stage by default, or optionally as commits. ` var commits = flag.Bool("commits", false, "Apply the patches as commits.") +var skipPatch = flag.Bool("skip-patch", false, "Skip applying patches.") var origin = flag.String("origin", "", "Use this origin instead of the default defined in '.gitmodules' to fetch the repository.") var shallow = flag.Bool("shallow", false, "Clone the submodule with depth 1.") var fetchBearerToken = flag.String("fetch-bearer-token", "", "Use this bearer token to fetch the submodule repository.") @@ -57,6 +58,10 @@ func refresh(rootDir string) error { return err } + if *skipPatch { + return nil + } + mode := patch.ApplyModeIndex if *commits { mode = patch.ApplyModeCommits diff --git a/eng/_util/go.mod b/eng/_util/go.mod index e821571fcfb..dbb261edf7c 100644 --- a/eng/_util/go.mod +++ b/eng/_util/go.mod @@ -7,6 +7,6 @@ module github.com/microsoft/go/_util go 1.16 require ( - github.com/microsoft/go-infra v0.0.0-20211206195537-520f2621bcf4 + github.com/microsoft/go-infra v0.0.0-20220208232830-51df6c5b8843 gotest.tools/gotestsum v1.6.5-0.20210515201937-ecb7c6956f6d ) diff --git a/eng/_util/go.sum b/eng/_util/go.sum index 1b46c2b6f8b..06f8bd92ba4 100644 --- a/eng/_util/go.sum +++ b/eng/_util/go.sum @@ -15,8 +15,8 @@ github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/microsoft/go-infra v0.0.0-20211206195537-520f2621bcf4 h1:goYnnCGbN9HBwd0CtdiokVAlq5rTQkqq66K43kvGnhc= -github.com/microsoft/go-infra v0.0.0-20211206195537-520f2621bcf4/go.mod h1:3IVGTm7qFJldQHximiWLg2kYfmugjZMGNHnvUo5Mo5M= +github.com/microsoft/go-infra v0.0.0-20220208232830-51df6c5b8843 h1:IAk1GrsBP2l3sdWnaARrLALS9m6fVkGNgefpWRS0x2c= +github.com/microsoft/go-infra v0.0.0-20220208232830-51df6c5b8843/go.mod h1:3IVGTm7qFJldQHximiWLg2kYfmugjZMGNHnvUo5Mo5M= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= diff --git a/eng/pipeline/jobs/builders-to-jobs.yml b/eng/pipeline/jobs/builders-to-jobs.yml index fb28e1517a0..05d7a751e9a 100644 --- a/eng/pipeline/jobs/builders-to-jobs.yml +++ b/eng/pipeline/jobs/builders-to-jobs.yml @@ -10,12 +10,15 @@ parameters: # If true, include a signing job that depends on all 'buildandpack' builder jobs finishing. This # lets us start the lengthy tasks of signing and testing in parallel. sign: false + # If true, generate source archive tarballs, and sign them if signing is enabled. + createSourceArchive: false jobs: - ${{ each builder in parameters.builders }}: - template: run-job.yml parameters: builder: ${{ builder }} + createSourceArchive: ${{ parameters.createSourceArchive }} - ${{ if eq(parameters.sign, true) }}: - template: sign-job.yml diff --git a/eng/pipeline/jobs/go-builder-matrix-jobs.yml b/eng/pipeline/jobs/go-builder-matrix-jobs.yml index 375d5e49f87..588287276bf 100644 --- a/eng/pipeline/jobs/go-builder-matrix-jobs.yml +++ b/eng/pipeline/jobs/go-builder-matrix-jobs.yml @@ -9,6 +9,7 @@ parameters: innerloop: false outerloop: false sign: false + createSourceArchive: false jobs: - template: shorthand-builders-to-builders.yml @@ -16,6 +17,7 @@ jobs: jobsTemplate: builders-to-jobs.yml jobsParameters: sign: ${{ parameters.sign }} + createSourceArchive: ${{ parameters.createSourceArchive }} shorthandBuilders: - ${{ if eq(parameters.innerloop, true) }}: - { os: linux, arch: amd64, config: buildandpack } diff --git a/eng/pipeline/jobs/run-job.yml b/eng/pipeline/jobs/run-job.yml index f1ed89cdeac..cd6546aaabb 100644 --- a/eng/pipeline/jobs/run-job.yml +++ b/eng/pipeline/jobs/run-job.yml @@ -7,6 +7,7 @@ parameters: # { id, os, arch, config, distro? } builder: {} + createSourceArchive: false jobs: - job: ${{ parameters.builder.id }} @@ -41,7 +42,6 @@ jobs: Write-Host "##vso[task.setvariable variable=GO_MAKE_MAX_RETRY_ATTEMPTS]5" displayName: Increase 'make' retry attempts - # Initialize stage 0 toolset ahead of time so we can track timing data separately from the # build operations. When we call this script again later, it won't download Go again. - pwsh: | @@ -51,6 +51,22 @@ jobs: - template: ../steps/init-submodule-task.yml + # Create the source archive on one job only. The os choice is arbitrary. + - ${{ if and(eq(parameters.createSourceArchive, true), eq(parameters.builder.config, 'buildandpack'), eq(parameters.builder.os, 'linux')) }}: + - pwsh: | + git config --global user.name "microsoft-golang-bot" + git config --global user.email "microsoft-golang-bot@users.noreply.github.com" + + # Turn the patches into commits, so HEAD includes the changes. + eng/run.ps1 submodule-refresh -commits + eng/run.ps1 pack-source + displayName: Archive submodule source + + - pwsh: | + # Apply the patches as staged changes, so the HEAD commit is the same as upstream. + eng/run.ps1 submodule-refresh + displayName: Apply patches + # Use build script directly for "buildandpack". If we used run-builder, we would need to # download its external module dependencies. - ${{ if eq(parameters.builder.config, 'buildandpack' ) }}: diff --git a/eng/pipeline/rolling-internal-pipeline.yml b/eng/pipeline/rolling-internal-pipeline.yml index eded261f086..1ec8425471e 100644 --- a/eng/pipeline/rolling-internal-pipeline.yml +++ b/eng/pipeline/rolling-internal-pipeline.yml @@ -20,6 +20,7 @@ stages: parameters: innerloop: true sign: true + createSourceArchive: true - stage: Publish dependsOn: Build diff --git a/eng/pipeline/steps/init-submodule-task.yml b/eng/pipeline/steps/init-submodule-task.yml index dc6f2dd3a90..8e370d3b8ab 100644 --- a/eng/pipeline/steps/init-submodule-task.yml +++ b/eng/pipeline/steps/init-submodule-task.yml @@ -6,7 +6,7 @@ steps: - pwsh: | function fetch_submodule() { - eng/run.ps1 submodule-refresh -shallow @args + eng/run.ps1 submodule-refresh -shallow -skip-patch @args } if ("$env:FETCH_BEARER_TOKEN") { From 4a14e6247a300f88761fac535abc3fe0a6562bc4 Mon Sep 17 00:00:00 2001 From: Davis Goodin Date: Wed, 9 Feb 2022 12:59:21 -0600 Subject: [PATCH 12/47] Fix up patch with 3-way resolution --- ...d-dist-add-JSON-output-support-for-some-tests.patch | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/patches/0001-cmd-dist-add-JSON-output-support-for-some-tests.patch b/patches/0001-cmd-dist-add-JSON-output-support-for-some-tests.patch index 342a4443613..d2fb5d83ff4 100644 --- a/patches/0001-cmd-dist-add-JSON-output-support-for-some-tests.patch +++ b/patches/0001-cmd-dist-add-JSON-output-support-for-some-tests.patch @@ -17,7 +17,7 @@ in JSON format, and the ordinary logs are still important. 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/cmd/dist/test.go b/src/cmd/dist/test.go -index 4f081c9f88..c4f1157751 100644 +index f40fa926df..f76ecbe28c 100644 --- a/src/cmd/dist/test.go +++ b/src/cmd/dist/test.go @@ -29,6 +29,7 @@ func cmdtest() { @@ -28,7 +28,7 @@ index 4f081c9f88..c4f1157751 100644 flag.BoolVar(&t.rebuild, "rebuild", false, "rebuild everything first") flag.BoolVar(&noRebuild, "no-rebuild", false, "overrides -rebuild (historical dreg)") flag.BoolVar(&t.keepGoing, "k", false, "keep going even when error occurred") -@@ -49,6 +50,7 @@ func cmdtest() { +@@ -50,6 +51,7 @@ func cmdtest() { type tester struct { race bool listMode bool @@ -36,7 +36,7 @@ index 4f081c9f88..c4f1157751 100644 rebuild bool failed bool keepGoing bool -@@ -270,9 +272,13 @@ func short() string { +@@ -286,9 +288,13 @@ func short() string { // Callers should use goTest and then pass flags overriding these // defaults as later arguments in the command line. func (t *tester) goTest() []string { @@ -51,9 +51,9 @@ index 4f081c9f88..c4f1157751 100644 } func (t *tester) tags() string { -@@ -345,6 +351,9 @@ func (t *tester) registerStdTest(pkg string) { +@@ -371,6 +377,9 @@ func (t *tester) registerStdTest(pkg string, useG3 bool) { t.timeout(timeoutSec), - "-gcflags=all=" + gogcflags, + "-gcflags=all=" + gcflags, } + if t.jsonMode { + args = append(args, "-json") From 13c3cef38136e7270173153458e2a7cd6927a5f3 Mon Sep 17 00:00:00 2001 From: microsoft-golang-bot Date: Wed, 9 Feb 2022 23:55:45 +0000 Subject: [PATCH 13/47] Update submodule to latest release-branch.go1.16 (0a6cf870): [release-branch.go1.16] go1.16.14 --- go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go b/go index 378766af9ed..0a6cf8706fd 160000 --- a/go +++ b/go @@ -1 +1 @@ -Subproject commit 378766af9ed0f2e28d67c2b50e73db7573656669 +Subproject commit 0a6cf8706fdd0fe1bd26e4d1ecbcd41650bf5e6c From d240ef989e4b2ad52f48769419b610e69bc2f043 Mon Sep 17 00:00:00 2001 From: Davis Goodin Date: Thu, 10 Feb 2022 02:19:47 -0600 Subject: [PATCH 14/47] Update submodule to latest tag, go1.17.7 (#422) --- go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go b/go index 1952c65f9af..6a70ee2873b 160000 --- a/go +++ b/go @@ -1 +1 @@ -Subproject commit 1952c65f9af1820d1528a1b38fed26dceddd92a0 +Subproject commit 6a70ee2873b2367e2a0d6e7d7e167c072b99daf0 From e3688330c074e3d58475f232c2076d0d63b96042 Mon Sep 17 00:00:00 2001 From: microsoft-golang-bot Date: Fri, 11 Feb 2022 16:02:00 +0000 Subject: [PATCH 15/47] Update submodule to latest release-branch.go1.17 (cd6e0d7c): [release-branch.go1.17] crypto/x509:[...] --- go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go b/go index 6a70ee2873b..cd6e0d7cad1 160000 --- a/go +++ b/go @@ -1 +1 @@ -Subproject commit 6a70ee2873b2367e2a0d6e7d7e167c072b99daf0 +Subproject commit cd6e0d7cad147b686f9f8066b651b0079e6f51c6 From 20c73633354ee5a2664b07dc233e34290de96a9a Mon Sep 17 00:00:00 2001 From: microsoft-golang-bot Date: Fri, 11 Feb 2022 16:02:00 +0000 Subject: [PATCH 16/47] Update submodule to latest dev.boringcrypto.go1.17 (172559d2): [dev.boringcrypto.go1.17] all: merge[...] --- go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go b/go index cfad1ff84c4..172559d22b5 160000 --- a/go +++ b/go @@ -1 +1 @@ -Subproject commit cfad1ff84c45f99f6ceee17f76e2cbaf2ff8598b +Subproject commit 172559d22b5d9fe2dfbe9d4bf16ca0cb8f76c541 From 6a38a087f00e80e0f5876337c5160467704233ee Mon Sep 17 00:00:00 2001 From: Davis Goodin Date: Tue, 15 Feb 2022 14:34:31 -0600 Subject: [PATCH 17/47] Update go-infra: detect VERSION or go/VERSION (#429) (#433) (cherry picked from commit 25f8233222a1566e2c4e2864fc0b81b5aff9da61) --- eng/_util/go.mod | 2 +- eng/_util/go.sum | 4 ++-- eng/pipeline/rolling-internal-pipeline.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/eng/_util/go.mod b/eng/_util/go.mod index dbb261edf7c..dc95b46f4ab 100644 --- a/eng/_util/go.mod +++ b/eng/_util/go.mod @@ -7,6 +7,6 @@ module github.com/microsoft/go/_util go 1.16 require ( - github.com/microsoft/go-infra v0.0.0-20220208232830-51df6c5b8843 + github.com/microsoft/go-infra v0.0.0-20220209233812-d528ea99adb8 gotest.tools/gotestsum v1.6.5-0.20210515201937-ecb7c6956f6d ) diff --git a/eng/_util/go.sum b/eng/_util/go.sum index 06f8bd92ba4..fa5aa4d8ca1 100644 --- a/eng/_util/go.sum +++ b/eng/_util/go.sum @@ -15,8 +15,8 @@ github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/microsoft/go-infra v0.0.0-20220208232830-51df6c5b8843 h1:IAk1GrsBP2l3sdWnaARrLALS9m6fVkGNgefpWRS0x2c= -github.com/microsoft/go-infra v0.0.0-20220208232830-51df6c5b8843/go.mod h1:3IVGTm7qFJldQHximiWLg2kYfmugjZMGNHnvUo5Mo5M= +github.com/microsoft/go-infra v0.0.0-20220209233812-d528ea99adb8 h1:2aNRJlGG6hOhHsQV3/5+udsetpNT24/5eeJBMWOmjDY= +github.com/microsoft/go-infra v0.0.0-20220209233812-d528ea99adb8/go.mod h1:3IVGTm7qFJldQHximiWLg2kYfmugjZMGNHnvUo5Mo5M= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= diff --git a/eng/pipeline/rolling-internal-pipeline.yml b/eng/pipeline/rolling-internal-pipeline.yml index 1ec8425471e..028cdba95c8 100644 --- a/eng/pipeline/rolling-internal-pipeline.yml +++ b/eng/pipeline/rolling-internal-pipeline.yml @@ -70,7 +70,7 @@ stages: - pwsh: | eng/run.ps1 createbuildassetjson ` -artifacts-dir '$(Pipeline.Workspace)/Binaries Signed/' ` - -source-dir '$(Build.SourcesDirectory)/go' ` + -source-dir '$(Build.SourcesDirectory)' ` -destination-url '$(blobDestinationUrl)' ` -branch '$(PublishBranchAlias)' ` -o '$(Pipeline.Workspace)/Binaries Signed/assets.json' From 001ce31383faea69ce7f3ebab5c4c8dda62d5eff Mon Sep 17 00:00:00 2001 From: Davis Goodin Date: Tue, 15 Feb 2022 17:39:08 -0600 Subject: [PATCH 18/47] Add VERSION file: 1.17.7 --- VERSION | 1 + 1 file changed, 1 insertion(+) create mode 100644 VERSION diff --git a/VERSION b/VERSION new file mode 100644 index 00000000000..d458efbf6b3 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +go1.17.7 \ No newline at end of file From e27e25143ae8cdd43ea2add1b2ded7d941f42e5f Mon Sep 17 00:00:00 2001 From: microsoft-golang-bot Date: Wed, 16 Feb 2022 16:01:48 +0000 Subject: [PATCH 19/47] Update submodule to latest dev.boringcrypto.go1.17 (6666adc1): [dev.boringcrypto.go1.17] misc/borin[...] --- go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go b/go index 172559d22b5..6666adc18c2 160000 --- a/go +++ b/go @@ -1 +1 @@ -Subproject commit 172559d22b5d9fe2dfbe9d4bf16ca0cb8f76c541 +Subproject commit 6666adc18c24667f4b431b8f3492bb7aa96ef71e From 96ce61a11e81ca0258f295da123d459c9965d8f2 Mon Sep 17 00:00:00 2001 From: microsoft-golang-bot Date: Fri, 18 Feb 2022 16:01:40 +0000 Subject: [PATCH 20/47] Update submodule to latest release-branch.go1.17 (7d8fa657): [release-branch.go1.17] cmd/compile:[...] --- go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go b/go index cd6e0d7cad1..7d8fa657893 160000 --- a/go +++ b/go @@ -1 +1 @@ -Subproject commit cd6e0d7cad147b686f9f8066b651b0079e6f51c6 +Subproject commit 7d8fa657893f93dd04071bb164166d12fbdeb8a5 From 690c325855b6ca4dec6206eda5a6b891e5098c99 Mon Sep 17 00:00:00 2001 From: microsoft-golang-bot Date: Thu, 3 Mar 2022 21:09:16 +0000 Subject: [PATCH 21/47] Update submodule to latest release-branch.go1.17 (7dd10d4c): [release-branch.go1.17] go1.17.8 --- go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go b/go index 7d8fa657893..7dd10d4ce20 160000 --- a/go +++ b/go @@ -1 +1 @@ -Subproject commit 7d8fa657893f93dd04071bb164166d12fbdeb8a5 +Subproject commit 7dd10d4ce20e64d96a10cb67794851a58d96a2aa From c4f89b7448fe386f9f7e2bbfdabff139c226b44c Mon Sep 17 00:00:00 2001 From: Davis Goodin Date: Mon, 7 Mar 2022 10:49:14 -0600 Subject: [PATCH 22/47] Add pointer in FIPS docs to new location (#457) --- eng/doc/fips/README.md | 90 +---- eng/doc/fips/UserGuide.md | 688 +------------------------------------- 2 files changed, 2 insertions(+), 776 deletions(-) diff --git a/eng/doc/fips/README.md b/eng/doc/fips/README.md index c0014398d47..f56549db194 100644 --- a/eng/doc/fips/README.md +++ b/eng/doc/fips/README.md @@ -1,89 +1 @@ -# Crypto FIPS 140-2 support - -## Background - -FIPS 140-2 is a U.S. government computer security standard used to approve cryptographic modules. FIPS compliance may come up when working with U.S. government and other regulated industries. - -### Go FIPS compliance - -The Go `crypto` package is not FIPS certified, and the Go team has stated that it won't be, e.g. in [golang/go/issues/21734](https://github.com/golang/go/issues/21734#issuecomment-326980213) Adam Langley says: - -> The status of FIPS 140 for Go itself remains "no plans, basically zero chance". - -On the other hand, Google maintains a branch that uses cgo and BoringSSL to implement various crypto primitives: https://github.com/golang/go/blob/dev.boringcrypto/README.boringcrypto.md. As BoringSSL is FIPS 140-2 certified, an application using that branch is more likely to be FIPS 140-2 compliant, yet Google does not provide any liability about the suitability of this code in relation to the FIPS 140-2 standard. - -In addition to that, the dev.boringcrypto branch also provides a mechanism to restrict all TLS configuration to FIPS-approved settings. The effect is triggered by importing the package anywhere in a program, as in: - -```go - import _ "crypto/tls/fipsonly" -``` - -## Microsoft Go fork FIPS compliance - -Microsoft's Go Linux runtime has been modified to implement several crypto primitives using cgo and OpenSSL. Similar to BoringSSL, certain OpenSSL versions are also FIPS 140-2 certified. - -It is important to note that an application built with Microsoft's Go toolchain and running in FIPS compatible mode is not FIPS compliant _per-se_. It is on the application development team to use FIPS-compliant crypto primitives and workflows. The crypto runtime will fall back to Go standard library crypto in case it cannot provide a FIPS-compliant implementation, e.g. when hashing a message using `crypto/md5` hashes or when using an AES-GCM cipher with a non-standard nonce size. - -## Usage - -FIPS compatibility mode, and therefore the OpenSSL crypto backend, can be enabled using any of these options: - -- Explicitly setting the environment variable `GOFIPS=1`. -- Implicitly enabling it by booting the Linux Kernel in FIPS mode. - - Linux FIPS mode sets the content of `/proc/sys/crypto/fips_enabled` to `1`. The Go runtime reads this file. - - To opt out, set `GOFIPS=0`. - -Whichever is the approach used, the program initialization will panic if FIPS mode is requested but the Go runtime can't find a suitable OpenSSL shared library or OPENSSL FIPS mode can't be enabled. - -The whole OpenSSL functionality can be disabled by building your program with `-tags gocrypto`. - -## Features - -### No code changes required - -Applications requiring FIPS-compliance don't require any code change to activate FIPS compatibility mode. The Go runtime will favor OpenSSL crypto primitives over Go standard library when the application is FIPS-enabled. - -### Multiple OpenSSL versions allowed - -OpenSSL does not maintain ABI compatibility between different releases, even if only the patch version is increased. The Go crypto package has support for multiple OpenSSL versions, yet each version has a different amount of automated validation: - -- OpenSSL 1.1.1: the Microsoft CI builds official releases and runs automated tests with this version. -- OpenSSL 1.0.1: the Microsoft CI builds official releases, but doesn't run tests, so it may not produce working applications. -- OpenSSL 1.1.0 and 3.0: the Microsoft CI does not build nor test these versions, so they may or may not work. - -Versions not listed above are not supported at all. - -### Dynamic OpenSSL linking - -Go automatically loads the OpenSSL shared library `libcrypto` using [dlopen](https://man7.org/linux/man-pages/man3/dlopen.3.html) when initializing a FIPS-enabled program. Therefore, dlopen's shared library search conventions also apply here. - -The `libcrypto` shared library file name varies among different platforms, so a best-effort is done to find and load the right file: - -- The base name is always `libcrypto.so.` -- Well-known version strings are appended to the base name, until the file is found, in the following order: `3` -> `1.1` -> `11` -> `111` -> `1.0.2` -> `1.0.0`. - -This algorithm can be overridden by setting the environment variable `GO_OPENSSL_VERSION_OVERRIDE` to the desired version string. For example, `GO_OPENSSL_VERSION_OVERRIDE="1.1.1k-fips"` makes the runtime look for the shared library `libcrypto.so.1.1.1k-fips` before running the checks for well-known versions. - -### Portable OpenSSL - -The OpenSSL bindings are implemented in such a way that the OpenSSL version used when building a program does not have to match with the OpenSSL version used when running it. It is even possible to build a program using plain Go crypto (i.e. setting `GOFIPS=0`) and then running that same program in FIPS mode. - -This feature does not require any additional configuration, but it only works with OpenSSL versions known and supported by the Go toolchain. - -### TLS with FIPS-approved settings - -The Go TLS stack will automatically use OpenSSL crypto primitives when running in FIPS mode. Yet, the FIPS 140-2 standard places additional restrictions on TLS communications, mainly on which cyphers and signers are allowed. - -A program can import the `crypto/tls/fipsonly` package to configure the Go TLS stack so it is compliant with these restrictions. The configuration is done by an `init()` function. Note that this can reduce compatibility with old devices that do not support modern cryptography techniques such as TLS 1.2. - -## Acknowledgements - -The work done to support FIPS compatibility mode leverages code and ideas from other open-source projects: - -- All crypto stubs are a mirror of Google's [dev.boringcrypto branch](https://github.com/golang/go/tree/dev.boringcrypto) and the release branch ports of that branch. -- The mapping between BoringSSL and OpenSSL APIs is taken from Fedora's [Go fork](https://pagure.io/go). -- Portable OpenSSL implementation ported from Microsoft's [.NET runtime](https://github.com/dotnet/runtime) cryptography module. - -## Disclaimer - -A program running in FIPS mode can claim it is using a FIPS-certified cryptographic module, but it can't claim the program as a whole is FIPS certified without passing the certification process, nor claim it is FIPS compliant without ensuring all crypto APIs and workflows are implemented in a FIPS-compliant manner. +This document has moved! It is now maintained in the main branch: https://github.com/microsoft/go/tree/microsoft/main/eng/doc/fips diff --git a/eng/doc/fips/UserGuide.md b/eng/doc/fips/UserGuide.md index 156fee008e8..f56549db194 100644 --- a/eng/doc/fips/UserGuide.md +++ b/eng/doc/fips/UserGuide.md @@ -1,687 +1 @@ -# FIPS 140-2 User Guide - -This document is a user guide for the Microsoft Go crypto package running on FIPS 140-2 compatibility mode (hereafter referred to as FIPS) when in use with the OpenSSL cryptographic library. It is intended as a technical reference for developers using, and system administrators installing, the Go toolset and the OpenSSL FIPS software, and for use in risk assessment reviews by security auditors. This is not a replacement for the Go crypto documentation, rather it is a collection of notes and more detailed explanations in the context of FIPS compatibility. - -The Go crypto documentation is available online at https://pkg.go.dev/crypto. - -- [FIPS 140-2 User Guide](#fips-140-2-user-guide) - - [Using Go crypto APIs](#using-go-crypto-apis) - - [crypto/aes](#cryptoaes) - - [func NewCipher](#func-newcipher) - - [crypto/cipher](#cryptocipher) - - [func NewGCM](#func-newgcm) - - [func NewGCMWithNonceSize](#func-newgcmwithnoncesize) - - [func NewGCMWithTagSize](#func-newgcmwithtagsize) - - [func NewCBCDecrypter](#func-newcbcdecrypter) - - [func NewCBCEncrypter](#func-newcbcencrypter) - - [func NewCFBDecrypter](#func-newcfbdecrypter) - - [func NewCFBEncrypter](#func-newcfbencrypter) - - [func NewCTR](#func-newctr) - - [func NewOFB](#func-newofb) - - [func StreamReader.Read](#func-streamreaderread) - - [func StreamWriter.Write](#func-streamwriterwrite) - - [func StreamWriter.Close](#func-streamwriterclose) - - [crypto/des](#cryptodes) - - [crypto/dsa](#cryptodsa) - - [crypto/dsa](#cryptodsa-1) - - [crypto/ecdsa](#cryptoecdsa) - - [func Sign](#func-sign) - - [func SignASN1](#func-signasn1) - - [func Verify](#func-verify) - - [func VerifyASN1](#func-verifyasn1) - - [func GenerateKey](#func-generatekey) - - [func PrivateKey.Sign](#func-privatekeysign) - - [crypto/ed25519](#cryptoed25519) - - [crypto/elliptic](#cryptoelliptic) - - [crypto/hmac](#cryptohmac) - - [func Equal](#func-equal) - - [func New](#func-new) - - [crypto/md5](#cryptomd5) - - [crypto/rand](#cryptorand) - - [var Reader](#var-reader) - - [func Int](#func-int) - - [func Prime](#func-prime) - - [func Read](#func-read) - - [crypto/rc4](#cryptorc4) - - [crypto/sha1](#cryptosha1) - - [func New](#func-new-1) - - [func Sum](#func-sum) - - [crypto/sha256](#cryptosha256) - - [func New](#func-new-2) - - [func New224](#func-new224) - - [func Sum224](#func-sum224) - - [func Sum256](#func-sum256) - - [crypto/sha512](#cryptosha512) - - [func New](#func-new-3) - - [func New384](#func-new384) - - [func New512_224](#func-new512_224) - - [func New512_256](#func-new512_256) - - [func Sum384](#func-sum384) - - [func Sum512](#func-sum512) - - [func Sum512_224](#func-sum512_224) - - [func Sum512_256](#func-sum512_256) - - [crypto/subtle](#cryptosubtle) - - [crypto/tls](#cryptotls) - -## Using Go crypto APIs - -This section describes how to use Go crypto APIs in a FIPS compliant manner. - -### [crypto/aes](https://pkg.go.dev/crypto/aes) - -Package aes implements AES encryption (formerly Rijndael), as defined in U.S. Federal Information Processing Standards Publication 197. - -#### func [NewCipher](https://pkg.go.dev/crypto/aes#NewCipher) - -```go -func aes.NewCipher(key []byte) (cipher cipher.Block, err error) -``` - -NewCipher creates and returns a new [cipher.Block](https://pkg.go.dev/crypto/cipher#Block). - -**Parameters** - -`key` is an AES key of length 16, 24, or 32 bytes. - -**Return values** - -`cipher` implements the cipher.Block interface using an OpenSSL cipher function that depends on the `key` length: - -- If `len(key) == 16` then the cipher used is [EVP_aes_128_ecb](https://www.openssl.org/docs/man3.0/man3/EVP_aes_128_ecb.html). -- If `len(key) == 24` then the cipher used is [EVP_aes_192_ecb](https://www.openssl.org/docs/man3.0/man3/EVP_aes_192_ecb.html). -- If `len(key) == 32` then the cipher used is [EVP_aes_256_ecb](https://www.openssl.org/docs/man3.0/man3/EVP_aes_256_ecb.html). - -The cipher.Block methods are implemented as follows: - -- `BlockSize() int` always returns `16`. -- `Encrypt(dst, src []byte)` encrypts `src` into `dst` using [EVP_EncryptUpdate]. -- `Decrypt(dst, src []byte` decrypts `src` into `dst` using [EVP_DecryptUpdate]. - -### [crypto/cipher](https://pkg.go.dev/crypto/cipher) - -Package cipher implements standard block cipher modes that can be wrapped around low-level block cipher implementations. - -#### func [NewGCM](https://pkg.go.dev/crypto/cipher#NewGCM) - -```go -func cipher.NewGCM(cipher cipher.Block) (aead cipher.AEAD, err error) -``` - -NewGCM returns the given 128-bit, block cipher wrapped in Galois Counter Mode with the standard nonce length. - -**Parameters** - -`cipher` must be an object created by [aes.NewCipher](https://pkg.go.dev/crypto/aes#NewCipher) in order to be FIPS compliant. - -**Return values** - -If `cipher` is FIPS compliant then `aead` implements the cipher.AEAD interface as follows: - -- `NonceSize() int` always returns `12`. -- `Overhead() int` always returns `16`. -- The cipher used in `Seal` and `Open` depends on the key length used in `aes.NewCipher(key []byte)`: - - If `len(key) == 16` then the cipher used is [EVP_aes_128_gcm](https://www.openssl.org/docs/man3.0/man3/EVP_aes_128_gcm.html). - - If `len(key) == 24` then the cipher used is [EVP_aes_192_gcm](https://www.openssl.org/docs/man3.0/man3/EVP_aes_192_gcm.html). - - If `len(key) == 32` then the cipher used is [EVP_aes_256_gcm](https://www.openssl.org/docs/man3.0/man3/EVP_aes_256_gcm.html). -- `Seal(dst, nonce, plaintext, additionalData []byte) []byte` encrypts plaintext and uses additionalData to authenticate. It uses [EVP_EncryptUpdate] for the encryption and [EVP_EncryptFinal_ex](https://www.openssl.org/docs/man3.0/man3/EVP_EncryptFinal_ex.html) for authenticating. -- `Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error)` decrypts plaintext and uses additionalData to authenticate. It uses [EVP_DecryptUpdate] for the decryption and [EVP_DecryptFinal_ex](https://www.openssl.org/docs/man3.0/man3/EVP_DecryptFinal_ex.html) for authenticating. - -If `cipher` is not FIPS compliant then `aead` is implemented by the standard Go library. - -#### func [NewGCMWithNonceSize](https://pkg.go.dev/crypto/cipher#NewGCMWithNonceSize) - -```go -func cipher.NewGCMWithNonceSize(cipher cipher.Block, size int) (aead cipher.AEAD, error) -``` - -NewGCMWithNonceSize returns the given 128-bit, block cipher wrapped in Galois Counter Mode, which accepts nonces of the given length. - -**Parameters** - -`cipher` must be an object created by aes.NewCipher and `size = 12` in order to be FIPS compliant, else the function will fall back to standard Go crypto. - -**Return values** - -`aead` can have different implementations depending on the supplied parameters: - -- If the parameters are FIPS compliant then `aead` behaves exactly as if it was created with cipher.NewGCM. -- If `cipher` is an object created by aes.NewCipher and `size != 12` then `aead` is implemented by the standard Go library and OpenSSL is only used for encryption and decryption. -- Else `aead` is completely implemented by the standard Go library. - -#### func [NewGCMWithTagSize](https://pkg.go.dev/crypto/cipher#NewGCMWithTagSize) - -```go -func cipher.NewGCMWithTagSize(cipher cipher.Block, tagSize int) (aead cipher.AEAD, error) -``` - -NewGCMWithTagSize returns the given 128-bit, block cipher wrapped in Galois Counter Mode, which generates tags with the given length. - -**Parameters** - -`cipher` must be an object created by aes.NewCipher and `tagSize = 16` in order to be FIPS compliant, else the function will fall back to standard Go crypto. - -**Return values** - -`aead` can have different implementations depending on the supplied parameters: - -- If the parameters are FIPS compliant then `aead` behaves exactly as if it was created with cipher.NewGCM. -- If `cipher` is an object created by aes.NewCipher and `tagSize != 16` then `aead` is implemented by the standard Go library using OpenSSL for encryption and decryption. -- Else `aead` is completely implemented by the standard Go library. - -#### func [NewCBCDecrypter](https://pkg.go.dev/crypto/cipher#NewCBCDecrypter) - -```go -func cipher.NewCBCDecrypter(block Block, iv []byte) (cbc cipher.BlockMode) -``` - -NewCBCDecrypter returns a BlockMode which decrypts in cipher block chaining mode, using the given Block. - -**Parameters** - -`block` must be an object created by [aes.NewCipher](https://pkg.go.dev/crypto/aes#NewCipher) in order to be FIPS compliant. - -**Return values** - -If `block` is FIPS compliant then `cbc` implements the cipher.BlockMode using an OpenSSL cipher that depends on the `block` key length: - -- If `len(key) == 16` then the cipher used is [EVP_aes_128_cbc](https://www.openssl.org/docs/man3.0/man3/EVP_aes_128_cbc.html). -- If `len(key) == 24` then the cipher used is [EVP_aes_192_cbc](https://www.openssl.org/docs/man3.0/man3/EVP_aes_192_cbc.html). -- If `len(key) == 32` then the cipher used is [EVP_aes_256_cbc](https://www.openssl.org/docs/man3.0/man3/EVP_aes_256_cbc.html). - -In all cases the cipher will have the padding disabled using [EVP_CIPHER_CTX_set_padding](https://www.openssl.org/docs/man3.0/man3/EVP_CIPHER_CTX_set_padding.html). - -The cipher.BlockMode methods are implemented as follows: - -- `BlockSize() int` always returns `16`. -- `CryptBlocks(dst, src []byte)` decrypts `src` into `dst` using [EVP_DecryptUpdate]. - -If `block` is not FIPS compliant then `cbc` is implemented by the standard Go library. - -#### func [NewCBCEncrypter](https://pkg.go.dev/crypto/cipher#NewCBCEncrypter) - -```go -func cipher.NewCBCEncrypter(block Block, iv []byte) (cbc cipher.BlockMode) -``` - -NewCBCEncrypter returns a BlockMode which encrypts in cipher block chaining mode, using the given Block. - -**Parameters** - -`block` must be an object created by [aes.NewCipher](https://pkg.go.dev/crypto/aes#NewCipher) in order to be FIPS compliant. - -**Return values** - -If `block` is FIPS compliant then `cbc` implements the cipher.BlockMode using an OpenSSL cipher that depends on the `block` key length: - -- If `len(key) == 16` then the cipher used is [EVP_aes_128_cbc](https://www.openssl.org/docs/man3.0/man3/EVP_aes_128_cbc.html). -- If `len(key) == 24` then the cipher used is [EVP_aes_192_cbc](https://www.openssl.org/docs/man3.0/man3/EVP_aes_192_cbc.html). -- If `len(key) == 32` then the cipher used is [EVP_aes_256_cbc](https://www.openssl.org/docs/man3.0/man3/EVP_aes_256_cbc.html). - -The cipher.BlockMode methods are implemented as follows: - -- `BlockSize() int` always returns `16`. -- `CryptBlocks(dst, src []byte)` encrypts `src` into `dst` using [EVP_EncryptUpdate]. - -If `block` is not FIPS compliant then `cbc` is implemented by the standard Go library. - -#### func [NewCFBDecrypter](https://pkg.go.dev/crypto/cipher#NewCFBDecrypter) - -cipher.NewCFBDecrypter is not FIPS compliant. - -#### func [NewCFBEncrypter](https://pkg.go.dev/crypto/cipher#NewCFBEncrypter) - -cipher.NewCFBEncrypter is not FIPS compliant. - -#### func [NewCTR](https://pkg.go.dev/crypto/cipher#NewCTR) - -```go -func cipher.NewCTR(block Block, iv []byte) (ctr cipher.BlockMode) -``` - -NewCTR returns a Stream which encrypts/decrypts using the given Block in counter mode. - -**Parameters** - -`block` must be an object created by [aes.NewCipher](https://pkg.go.dev/crypto/aes#NewCipher) in order to be FIPS compliant. - -**Return values** - -If `block` is FIPS compliant then `ctr` implements the cipher.Stream using an OpenSSL cipher that depends on the `block` key length: - -- If `len(key) == 16` then the cipher used is [EVP_aes_128_ctr](https://www.openssl.org/docs/man3.0/man3/EVP_aes_128_ctr.html). -- If `len(key) == 24` then the cipher used is [EVP_aes_192_ctr](https://www.openssl.org/docs/man3.0/man3/EVP_aes_192_ctr.html). -- If `len(key) == 32` then the cipher used is [EVP_aes_256_ctr](https://www.openssl.org/docs/man3.0/man3/EVP_aes_256_ctr.html). - - -The cipher.Stream methods are implemented as follows: -- `XORKeyStream(dst, src []byte)` XORs each byte in the given slice using [EVP_EncryptUpdate]. - -If `block` is not FIPS compliant then `ctr` is implemented by the standard Go library. - -#### func [NewOFB](https://pkg.go.dev/crypto/cipher#NewOFB) - -cipher.NewOFB is not FIPS compliant. - -#### func [StreamReader.Read](https://pkg.go.dev/crypto/cipher#StreamReader.Read) - -```go -func (r cipher.StreamReader) Read(dst []byte) (n int, err error) -``` - -Can be used in a FIPS compliant manner if `r.S` is an object created using cipher.NewCTR with FIPS compliant parameters. - -#### func [StreamWriter.Write](https://pkg.go.dev/crypto/cipher#StreamWriter.Write) - -```go -func (w cipher.StreamWriter) Write(src []byte) (n int, err error) -``` - -Can be used in a FIPS 140-2 compliant manner if `w.S` is an object created using cipher.NewCTR with FIPS compliant parameters. - -#### func [StreamWriter.Close](https://pkg.go.dev/crypto/cipher#StreamWriter.Close) - -```go -func (w cipher.StreamWriter) Close() error -``` - -Can be used in a FIPS 140-2 compliant manner if `w.S` is an object created using cipher.NewCTR with FIPS compliant parameters. - -### [crypto/des](https://pkg.go.dev/crypto/des) - -Not FIPS compliant. - -### [crypto/dsa](https://pkg.go.dev/crypto/dsa) - -Not FIPS compliant. - -### [crypto/dsa](https://pkg.go.dev/crypto/dsa) - -Not FIPS compliant. - -### [crypto/ecdsa](https://pkg.go.dev/crypto/ecdsa) - -Package ecdsa implements the Elliptic Curve Digital Signature Algorithm, as defined in FIPS 186-3. - -#### func [Sign](https://pkg.go.dev/crypto/ecdsa#Sign) - -```go -func ecdsa.Sign(rand io.Reader, priv *ecdsa.PrivateKey, hash []byte) (r, s *big.Int, err error) -``` - -Sign signs a hash using the private key. - -**Parameters** - -`rand` must be boring.RandReader, else Sign will panic. `crypto/rand.Reader` normally meets this invariant, as it is assigned to boring.RandReader in the crypto/rand init function. - -`hash` must be the result of hashing a message using a FIPS compliant hashing algorithm. If this invariant is not met, Sign won't be FIPS compliant but still will sign the message. - -**Return values** - -`r` and `s` are generated using [ECDSA_sign](https://www.openssl.org/docs/man3.0/man3/ECDSA_sign.html). - -#### func [SignASN1](https://pkg.go.dev/crypto/ecdsa#SignASN1) - -```go -func ecdsa.SignASN1(rand io.Reader, priv *ecdsa.PrivateKey, hash []byte) (sig []byte, err error) -``` - -SignASN1 signs a hash using the private key. It behaves as ecdsa.Sign but returns an ASN.1 encoded signature instead. - -#### func [Verify](https://pkg.go.dev/crypto/ecdsa#Verify) - -```go -func ecdsa.Verify(pub *ecdsa.PublicKey, hash []byte, r, s *big.Int) bool -``` - -Verify verifies the signature in r, s of hash using the public key. - -**Parameters** - -There are no specific parameters requirements in order to be FIPS compliant. - -**Return values** - -Returns `true` if the signature is valid using [ECDSA_verify](https://www.openssl.org/docs/man3.0/man3/ECDSA_verify.html). - -#### func [VerifyASN1](https://pkg.go.dev/crypto/ecdsa#VerifyASN1) - -```go -func ecdsa.VerifyASN1(pub *ecdsa.PublicKey, hash, sig []byte) bool -``` - -VerifyASN1 verifies the ASN.1 encoded signature, sig, of hash using the public key. It behaves as ecdsa.Verify but accepts an ASN.1 encoded signature instead. - -#### func [GenerateKey](https://pkg.go.dev/crypto/ecdsa#GenerateKey) - -```go -func ecdsa.GenerateKey(c elliptic.Curve, rand io.Reader) (priv *ecdsa.PrivateKey, err error) -``` - -GenerateKey generates a public and private key pair. - -**Parameters** - -`rand` must be boring.RandReader, else Sign will panic. `crypto/rand.Reader` normally meet this invariant as it is assigned to boring.RandReader in the crypto/rand init function. - -**Return values** - -The `priv` curve algorithm depends on the value of `c`: - -- If `c.Params().Name == "P-224"` then curve is `NID_secp224r1`. -- If `c.Params().Name == "P-256"` then curve is `NID_X9_62_prime256v1`. -- If `c.Params().Name == "P-384"` then curve is `NID_secp384r1`. -- If `c.Params().Name == "P-521"` then curve is `NID_secp521r1`. - -Other `c` values will result in an error. - -#### func [PrivateKey.Sign](https://pkg.go.dev/crypto/ecdsa#PrivateKey.Sign) - -```go -func (priv *ecdsa.PrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) -``` - -Sign signs `digest` with `priv`. - -**Parameters** - -`rand` must be boring.RandReader, else Sign will panic. `crypto/rand.Reader` normally meet this invariant as it is assigned to boring.RandReader in the crypto/rand init function. - -`digest` must be the result of hashing a message using a FIPS compliant hashing algorithm. If this invariant is not met, Sign won't be FIPS compliant but still will sign the message. - -**Return values** - -Signed messaged using [ECDSA_sign](https://www.openssl.org/docs/man3.0/man3/ECDSA_sign.html). - -### [crypto/ed25519](https://pkg.go.dev/crypto/ed25519) - -Not FIPS compliant. - -### [crypto/elliptic](https://pkg.go.dev/crypto/elliptic) - -Not FIPS compliant. - -### [crypto/hmac](https://pkg.go.dev/crypto/hmac) - -Package hmac implements the Keyed-Hash Message Authentication Code (HMAC) as defined in U.S. Federal Information Processing Standards Publication 198. - -#### func [Equal](https://pkg.go.dev/crypto/hmac#Equal) - -```go -func hmac.Equal(mac1, mac2 []byte) bool -``` - -Equal compares two MACs for equality without leaking timing information. - -This function does not implement any cryptographic algorithm, therefore out of FIPS scope. - -#### func [New](https://pkg.go.dev/crypto/hmac#New) - -```go -func hmac.New(h func() hash.Hash, key []byte) hash.Hash -``` - -New returns a new HMAC hash using the given hash.Hash type and key. - -**Parameters** - -`h` must be one of the following functions in order to be FIPS compliant: sha1.New, sha256.New, or sha512.New. - -**Return values** - -The hash.Hash methods are implemented as follows: - -- `Write(p []byte) (int, error)` using [HMAC_Update](https://www.openssl.org/docs/manmaster/man3/HMAC_Update.html). -- `Sum(in []byte) []byte` using [HMAC_Final](https://www.openssl.org/docs/manmaster/man3/HMAC_Final.html). -- `Reset()` using [HMAC_Init_ex](https://www.openssl.org/docs/manmaster/man3/HMAC_Init_ex.html). - -### [crypto/md5](https://pkg.go.dev/crypto/md5) - -Not FIPS compliant. - -### [crypto/rand](https://pkg.go.dev/crypto/rand) - -Package rand implements a cryptographically secure random number generator. - -#### var [Reader](https://pkg.go.dev/crypto/rand#pkg-variables) - -```go -var Reader io.Reader -``` - -Reader is a global, shared instance of a cryptographically secure random number generator. -It is assigned to boring.RandReader in the crypto/rand init function, which implements `io.Reader` by using the OpenSSL function [RAND_bytes](https://www.openssl.org/docs/man3.0/man3/RAND_bytes.html). - - -#### func [Int](https://pkg.go.dev/crypto/rand#Int) - -```go -func rand.Int(rand io.Reader, max *big.Int) (n *big.Int, err error) -``` - -Int returns a uniform random value in [0, max). It panics if max <= 0. - -**Parameters** - -`rand` must be boring.RandReader in order to be FIPS compliant. `crypto/rand.Reader` normally meet this invariant as it is assigned to boring.RandReader in the crypto/rand init function. - -#### func [Prime](https://pkg.go.dev/crypto/rand#Prime) - -```go -func Prime(rand io.Reader, bits int) (p *big.Int, err error) -``` - -func Prime(rand io.Reader, bits int) (p *big.Int, err error) - -**Parameters** - -`rand` must be boring.RandReader in order to be FIPS compliant. `crypto/rand.Reader` normally meet this invariant as it is assigned to boring.RandReader in the crypto/rand init function. - -#### func [Read](https://pkg.go.dev/crypto/rand#Read) - -```go -func Read(b []byte) (n int, err error) -``` - -Read is a helper function that calls rand.Reader.Read using io.ReadFull. It is FIPS compliant as long as `rand.Reader == boring.RandReader`. - -### [crypto/rc4](https://pkg.go.dev/crypto/rc4) - -Not FIPS compliant. - -### [crypto/sha1](https://pkg.go.dev/crypto/sha1) - -Package sha1 implements the SHA-1 hash algorithm as defined in RFC 3174. - -SHA-1 is an approved FIPS 140-2 hash algorithm although it is cryptographically broken and should not be used for secure applications. - -#### func [New](https://pkg.go.dev/crypto/sha1#New) - -```go -func sha1.New() hash.Hash -``` - -New returns a new hash.Hash computing the SHA1 checksum. - -**Return values** - -The hash.Hash methods are implemented as follows: - -- `Write(p []byte) (int, error)` using [SHA1_Update](https://www.openssl.org/docs/manmaster/man3/SHA1_Update.html). -- `Sum(in []byte) []byte` using [SHA1_Final](https://www.openssl.org/docs/manmaster/man3/SHA1_Final.html). -- `Reset()` using [SHA1_Init](https://www.openssl.org/docs/manmaster/man3/SHA1_Init.html). - -#### func [Sum](https://pkg.go.dev/crypto/sha1#Sum) - -```go -func sha1.Sum(data []byte) [20]byte -``` - -Sum returns the SHA-1 checksum of the data. -It internally uses sha1.New() to compute the checksum. - -### [crypto/sha256](https://pkg.go.dev/crypto/sha256) - -Package sha256 implements the SHA224 and SHA256 hash algorithms as defined in FIPS 180-4. - -#### func [New](https://pkg.go.dev/crypto/sha256#New) - -```go -func sha256.New() hash.Hash -``` - -New returns a new hash.Hash computing the SHA256 checksum. - -**Return values** - -The hash.Hash methods are implemented as follows: - -- `Write(p []byte) (int, error)` using [SHA256_Update](https://www.openssl.org/docs/manmaster/man3/SHA256_Update.html). -- `Sum(in []byte) []byte` using [SHA256_Final](https://www.openssl.org/docs/manmaster/man3/SHA256_Final.html). -- `Reset()` using [SHA256_Init](https://www.openssl.org/docs/manmaster/man3/SHA256_Init.html). - - -#### func [New224](https://pkg.go.dev/crypto/sha256#New224) - -```go -func sha256.New224() hash.Hash -``` - -New224 returns a new hash.Hash computing the SHA224 checksum. - -**Return values** - -The hash.Hash methods are implemented as follows: - -- `Write(p []byte) (int, error)` using [SHA224_Update](https://www.openssl.org/docs/manmaster/man3/SHA224_Update.html). -- `Sum(in []byte) []byte` using [SHA224_Final](https://www.openssl.org/docs/manmaster/man3/SHA224_Final.html). -- `Reset()` using [SHA224_Init](https://www.openssl.org/docs/manmaster/man3/SHA224_Init.html). - -#### func [Sum224](https://pkg.go.dev/crypto/sha256#Sum224) - -```go -func sha256.Sum224(data []byte) [24]byte -``` - -Sum224 returns the SHA224 checksum of the data. -It internally uses sha224.New() to compute the checksum. - -#### func [Sum256](https://pkg.go.dev/crypto/sha256#Sum256) - -```go -func sha256.Sum256(data []byte) [32]byte -``` - -Sum256 returns the SHA256 checksum of the data. -It internally uses sha256.New() to compute the checksum. - -### [crypto/sha512](https://pkg.go.dev/crypto/sha512) - -Package sha512 implements the SHA-384, SHA-512, SHA-512/224, and SHA-512/256 hash algorithms as defined in FIPS 180-4. - -#### func [New](https://pkg.go.dev/crypto/sha512#New) - -```go -func sha512.New() hash.Hash -``` - -New returns a new hash.Hash computing the SHA-512 checksum. - -**Return values** - -The hash.Hash methods are implemented as follows: - -- `Write(p []byte) (int, error)` using [SHA512_Update](https://www.openssl.org/docs/manmaster/man3/SHA512_Update.html). -- `Sum(in []byte) []byte` using [SHA512_Final](https://www.openssl.org/docs/manmaster/man3/SHA512_Final.html). -- `Reset()` using [SHA512_Init](https://www.openssl.org/docs/manmaster/man3/SHA512_Init.html). - -#### func [New384](https://pkg.go.dev/crypto/sha512#New384) - -```go -func sha512.New384() hash.Hash -``` - -New384 returns a new hash.Hash computing the SHA-384 checksum. - -**Return values** - -The hash.Hash methods are implemented as follows: - -- `Write(p []byte) (int, error)` using [SHA384_Update](https://www.openssl.org/docs/manmaster/man3/SHA384_Update.html). -- `Sum(in []byte) []byte` using [SHA384_Final](https://www.openssl.org/docs/manmaster/man3/SHA384_Final.html). -- `Reset()` using [SHA384_Init](https://www.openssl.org/docs/manmaster/man3/SHA384_Init.html). - -#### func [New512_224](https://pkg.go.dev/crypto/sha512#New512_224) - -sha512.New512_224 is not FIPS compliant. - -#### func [New512_256](https://pkg.go.dev/crypto/sha512#New512_256) - -sha512.New512_256 is not FIPS compliant. - -#### func [Sum384](https://pkg.go.dev/crypto/sha512#Sum384) - -```go -func sha512.Sum384(data []byte) [48]byte -``` - -Sum384 returns the SHA384 checksum of the data. -It internally uses sha512.New384() to compute the checksum. - -#### func [Sum512](https://pkg.go.dev/crypto/sha512#Sum512) - -```go -func sha512.Sum512(data []byte) [64]byte -``` - -Sum512 returns the SHA512 checksum of the data. -It internally uses sha512.New() to compute the checksum. - -#### func [Sum512_224](https://pkg.go.dev/crypto/sha512#Sum512_224) - -sha512.Sum512_224 is not FIPS compliant. - -#### func [Sum512_256](https://pkg.go.dev/crypto/sha512#Sum512_256) - -sha512.Sum512_256 is not FIPS compliant. - -### [crypto/subtle](https://pkg.go.dev/crypto/subtle) - -Does not contain crypto primitives, out of FIPS scope. - -### [crypto/tls](https://pkg.go.dev/crypto/tls) - -Package tls partially implements TLS 1.2, as specified in RFC 5246, and TLS 1.3, as specified in RFC 8446. - -Package tls will automatically use FIPS compliant primitives implemented in other crypto packages, but it will accept non-FIPS ciphers and signature algorithms unless `crypto/tls/fipsonly` is imported. - -When using TLS in FIPS-only mode the TLS handshake has the following restrictions: - -- TLS versions: `tls.VersionTLS12` -- ECDSA elliptic curves: - - `tls.CurveP256` - - `tls.CurveP384` - - `tls.CurveP521` -- Cipher suites: - - `tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256` - - `tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384` - - `tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256` - - `tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384` - - `tls.TLS_RSA_WITH_AES_128_GCM_SHA256` - - `tls.TLS_RSA_WITH_AES_256_GCM_SHA384` -- x509 certificate public key: - - `rsa.PublicKey` with a bit length of 2048 or 3072. Bit length of 4096 is still not supported, see [this issue](https://github.com/golang/go/issues/41147) for more info. - - `ecdsa.PublicKey` with a supported elliptic curve. -- Signature algorithms: - - `tls.PSSWithSHA256` - - `tls.PSSWithSHA384` - - `tls.PSSWithSHA512` - - `tls.PKCS1WithSHA256` - - `tls.ECDSAWithP256AndSHA256` - - `tls.PKCS1WithSHA384` - - `tls.ECDSAWithP384AndSHA384` - - `tls.PKCS1WithSHA512` - - `tls.ECDSAWithP521AndSHA512` - -[EVP_EncryptUpdate]: https://www.openssl.org/docs/manmaster/man3/EVP_EncryptUpdate.html -[EVP_DecryptUpdate]: https://www.openssl.org/docs/manmaster/man3/EVP_DecryptUpdate.html \ No newline at end of file +This document has moved! It is now maintained in the main branch: https://github.com/microsoft/go/tree/microsoft/main/eng/doc/fips From 9645f3c6a08cbd2c0431814fa587263927c98117 Mon Sep 17 00:00:00 2001 From: microsoft-golang-bot Date: Mon, 7 Mar 2022 19:29:12 +0000 Subject: [PATCH 23/47] Update submodule to latest dev.boringcrypto.go1.17 (4ea866a9): [dev.boringcrypto.go1.17] all: merge[...] --- go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go b/go index 6666adc18c2..4ea866a9969 160000 --- a/go +++ b/go @@ -1 +1 @@ -Subproject commit 6666adc18c24667f4b431b8f3492bb7aa96ef71e +Subproject commit 4ea866a9969f4ff2ffd975116a17bbe01ce00469 From 396389c45220bdeea6d912e27d59b517165e8e78 Mon Sep 17 00:00:00 2001 From: microsoft-golang-bot Date: Tue, 15 Mar 2022 20:08:52 +0000 Subject: [PATCH 24/47] Update submodule to latest release-branch.go1.17 (88be85f1): [release-branch.go1.17] runtime: cou[...] --- go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go b/go index 7dd10d4ce20..88be85f18bf 160000 --- a/go +++ b/go @@ -1 +1 @@ -Subproject commit 7dd10d4ce20e64d96a10cb67794851a58d96a2aa +Subproject commit 88be85f18bf0244a2470fdf6719e1b5ca5a5e50a From 4b02077465449078a8a1b655cd04beb286c9e55e Mon Sep 17 00:00:00 2001 From: Davis Goodin Date: Fri, 25 Mar 2022 12:09:31 -0500 Subject: [PATCH 25/47] [microsoft/release-branch.go1.17] Add linux-arm64 builders (#495) * Add arm64 internal builds and build script support (#474) (cherry picked from commit 52f84ccf8692b8bc141a79a4e8e19668c67e9428) * Recreate all dirs, not only "s", for component governance (#490) (cherry picked from commit f353ee35d96022c4a0bef1baa8dd324126715355) --- eng/init-pwsh.sh | 27 ++++++++-- eng/pipeline/jobs/go-builder-matrix-jobs.yml | 4 ++ eng/pipeline/jobs/run-job.yml | 51 +++++++++++++++---- eng/pipeline/steps/init-pwsh-task.yml | 2 + eng/utilities.ps1 | 29 +++++++++-- ...d-JSON-output-support-for-some-tests.patch | 2 +- ...t-Skip-TestDialCancel-on-linux-arm64.patch | 25 +++++++++ 7 files changed, 120 insertions(+), 20 deletions(-) create mode 100644 patches/0002-net-Skip-TestDialCancel-on-linux-arm64.patch diff --git a/eng/init-pwsh.sh b/eng/init-pwsh.sh index f13b4c39c1f..82123bce5fe 100755 --- a/eng/init-pwsh.sh +++ b/eng/init-pwsh.sh @@ -9,9 +9,29 @@ set -euo pipefail -pwsh_version='7.1.3' -pwsh_sha256='9f853fb8f7c7719005bd1054fa13ca4d925c519b893f439dd2574e84503e6a85' -pwsh_url="https://github.com/PowerShell/PowerShell/releases/download/v$pwsh_version/powershell-$pwsh_version-linux-x64.tar.gz" +# Default values for x64. +pwsh_version='7.2.1' +pwsh_sha256='337d9864799ad09b46d261071b9f835f69f078814409bc2681f4cc2857b6bda5' +pwsh_arch='x64' + +# 'uname' approach adapted from .NET install script: https://github.com/dotnet/install-scripts/blob/df8f863720a462448ad244f03ffeb619f0631bad/src/dotnet-install.sh#L295-L315 +if command -v uname > /dev/null; then + CPUName=$(uname -m) + case $CPUName in + armv*l) + echo "armv*l was detected, but it is not supported by the microsoft/go build infrastructure." + exit 1 + ;; + aarch64|arm64) + pwsh_sha256='f0d6c9c36d69e1466e5a9412085ef52cafd10b73f862d29479b806279a2975f4' + pwsh_arch='arm64' + ;; + esac +else + echo "uname command not detected. Assuming $pwsh_arch." +fi + +pwsh_url="https://github.com/PowerShell/PowerShell/releases/download/v$pwsh_version/powershell-$pwsh_version-linux-$pwsh_arch.tar.gz" # pwsh must be installed outside of the Go repo. If it's in the repo, longtest "TestAllDependencies" # fails. It tries to traverse the pwsh directory and can't handle the "no such file or directory" @@ -22,6 +42,7 @@ download_complete_indicator="$pwsh_dir/.downloaded" if [ ! -f "$download_complete_indicator" ]; then echo "Downloading PowerShell $pwsh_version and extracting to '$pwsh_dir' ..." + echo "URL: $pwsh_url" # Clear existing dir in case it's in a broken state. rm -rf "$pwsh_dir" diff --git a/eng/pipeline/jobs/go-builder-matrix-jobs.yml b/eng/pipeline/jobs/go-builder-matrix-jobs.yml index 588287276bf..e7e600aa48f 100644 --- a/eng/pipeline/jobs/go-builder-matrix-jobs.yml +++ b/eng/pipeline/jobs/go-builder-matrix-jobs.yml @@ -27,6 +27,10 @@ jobs: - { os: windows, arch: amd64, config: buildandpack } - { os: windows, arch: amd64, config: devscript } - { os: windows, arch: amd64, config: test } + # Only build arm64 if we're running a signed (internal, rolling) build. Avoid contention + # with other projects' builds that use the same limited-capacity pool of arm64 agents. + - ${{ if eq(parameters.sign, true) }}: + - { os: linux, arch: arm64, config: buildandpack } - ${{ if eq(parameters.outerloop, true) }}: # Upstream builders. - { os: linux, arch: amd64, config: clang } diff --git a/eng/pipeline/jobs/run-job.yml b/eng/pipeline/jobs/run-job.yml index cd6546aaabb..6953c339c62 100644 --- a/eng/pipeline/jobs/run-job.yml +++ b/eng/pipeline/jobs/run-job.yml @@ -19,19 +19,36 @@ jobs: vmImage: windows-2019 ${{ if eq(parameters.builder.os, 'linux') }}: - pool: - # The VM image of the Docker host. This doesn't need to match the container image, but it may - # give slightly better coverage by matching the kernel version. - vmImage: ubuntu-18.04 - # The image used for the container this job runs in. The tests run in this container, so it - # should match what we support as closely as possible. - ${{ if not(parameters.builder.distro) }}: - container: golangpublicimages.azurecr.io/go-infra-images/prereqs:cbl-mariner-1.0.20211027-20211201-0cccc22 - ${{ if eq(parameters.builder.distro, 'ubuntu') }}: - container: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-20211022152710-047508b + ${{ if eq(parameters.builder.arch, 'amd64') }}: + pool: + # The VM image of the Docker host. This doesn't need to match the container image, but it may + # give slightly better coverage by matching the kernel version. + vmImage: ubuntu-18.04 + # The image used for the container this job runs in. The tests run in this container, so it + # should match what we support as closely as possible. + ${{ if not(parameters.builder.distro) }}: + container: golangpublicimages.azurecr.io/go-infra-images/prereqs:cbl-mariner-1.0.20211027-20211201-0cccc22 + ${{ if eq(parameters.builder.distro, 'ubuntu') }}: + container: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-20211022152710-047508b + ${{ if eq(parameters.builder.arch, 'arm64') }}: + pool: + name: Docker-Linux-Arm-Internal + ${{ if not(parameters.builder.distro) }}: + container: golangpublicimages.azurecr.io/go-infra-images/prereqs:cbl-mariner-arm64-1.0-20220314-a003148 steps: - ${{ if eq(parameters.builder.os, 'linux') }}: + # AzDO builds don't seem to set user ID in the running container, so files from a previous + # build might be owned by root and unable to be cleaned up by AzDO's cleanup step. Clean up + # the build dirs ourselves in another Docker container to avoid failures. + - script: | + set -x + echo 'Cleaning old build dirs with sudo in case of root ownership.' + sudo rm -v -rf a b s + mkdir a b s + workingDirectory: $(Agent.BuildDirectory) + displayName: Cleanup + - template: ../steps/checkout-unix-task.yml - template: ../steps/init-pwsh-task.yml @@ -52,7 +69,7 @@ jobs: - template: ../steps/init-submodule-task.yml # Create the source archive on one job only. The os choice is arbitrary. - - ${{ if and(eq(parameters.createSourceArchive, true), eq(parameters.builder.config, 'buildandpack'), eq(parameters.builder.os, 'linux')) }}: + - ${{ if and(eq(parameters.createSourceArchive, true), eq(parameters.builder.config, 'buildandpack'), eq(parameters.builder.os, 'linux'), eq(parameters.builder.arch, 'amd64')) }}: - pwsh: | git config --global user.name "microsoft-golang-bot" git config --global user.email "microsoft-golang-bot@users.noreply.github.com" @@ -106,3 +123,15 @@ jobs: buildPlatform: ${{ parameters.builder.arch }} buildConfiguration: ${{ parameters.builder.config }} publishRunAttachments: true + + - ${{ if eq(parameters.builder.os, 'linux') }}: + # Files may be owned by root because builds don't set user ID. If this build is running on a + # persistent machine, later builds may fail to clean up this build's directory as as + # result--even if it also uses a build container. This step prevents that kind of failure by + # using chown to make sure the machine's agent user can access/delete the files. + - script: | + sudo chown -R $(id -u):$(id -g) * + workingDirectory: $(Agent.BuildDirectory) + displayName: Update file ownership from root to build agent account + continueOnError: true + condition: succeededOrFailed() diff --git a/eng/pipeline/steps/init-pwsh-task.yml b/eng/pipeline/steps/init-pwsh-task.yml index f8621029dc3..e3a903aa8ba 100644 --- a/eng/pipeline/steps/init-pwsh-task.yml +++ b/eng/pipeline/steps/init-pwsh-task.yml @@ -12,4 +12,6 @@ steps: . eng/init-pwsh.sh echo "##vso[task.prependpath]$pwsh_dir" + # Enable invariant mode to make .NET/PowerShell work without libicu installed. + echo "##vso[task.setvariable variable=DOTNET_SYSTEM_GLOBALIZATION_INVARIANT]1" displayName: Init PowerShell diff --git a/eng/utilities.ps1 b/eng/utilities.ps1 index 70b21be4add..868b6d6b913 100644 --- a/eng/utilities.ps1 +++ b/eng/utilities.ps1 @@ -24,14 +24,33 @@ function Get-Stage0GoRoot() { # pre-installed. This CI script installs a consistent, official version of Go to a directory in # $HOME to handle this. This also makes it easier to locally repro issues in CI that involve a # specific version of Go. The downloaded copy of Go is called the "stage 0" version. - $stage0_go_version = '1.16.5' + $stage0_go_version = '1.17.8' + $proc_arch = ([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture).ToString().ToLowerInvariant() if ($IsWindows) { - $stage0_go_sha256 = '0a3fa279ae5b91bc8c88017198c8f1ba5d9925eb6e5d7571316e567c73add39d' - $stage0_go_suffix = 'windows-amd64.zip' + switch ($proc_arch) { + 'x64' { + $stage0_go_sha256 = '85ccf2608dca6ea9a46b6538c9e75e7cf2aebdf502379843b248e26b8bb110be' + $stage0_go_suffix = 'windows-amd64.zip' + } + 'arm64' { + $stage0_go_sha256 = '4a0d960f5c0cbff1edaf54f333cf857a2779f6ae4c8e759b7872b44fde5ae43f' + $stage0_go_suffix = 'windows-arm64.zip' + } + Default { throw "Unable to match Windows '$proc_arch' to an architecture supported by the Microsoft scripts to build Go." } + } } elseif ($IsLinux) { - $stage0_go_sha256 = 'b12c23023b68de22f74c0524f10b753e7b08b1504cb7e417eccebdd3fae49061' - $stage0_go_suffix = 'linux-amd64.tar.gz' + switch ($proc_arch) { + 'x64' { + $stage0_go_sha256 = '980e65a863377e69fd9b67df9d8395fd8e93858e7a24c9f55803421e453f4f99' + $stage0_go_suffix = 'linux-amd64.tar.gz' + } + 'arm64' { + $stage0_go_sha256 = '57a9171682e297df1a5bd287be056ed0280195ad079af90af16dcad4f64710cb' + $stage0_go_suffix = 'linux-arm64.tar.gz' + } + Default { throw "Unable to match Linux '$proc_arch' to an architecture supported by the Microsoft scripts to build Go." } + } } else { throw "Current OS/Platform is not supported by the Microsoft scripts to build Go." } diff --git a/patches/0001-cmd-dist-add-JSON-output-support-for-some-tests.patch b/patches/0001-cmd-dist-add-JSON-output-support-for-some-tests.patch index d2fb5d83ff4..f947b43a036 100644 --- a/patches/0001-cmd-dist-add-JSON-output-support-for-some-tests.patch +++ b/patches/0001-cmd-dist-add-JSON-output-support-for-some-tests.patch @@ -1,5 +1,5 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Davis Goodin +From: microsoft-golang-bot Date: Tue, 4 Jan 2022 11:23:27 -0600 Subject: [PATCH] cmd/dist: add JSON output support for some tests diff --git a/patches/0002-net-Skip-TestDialCancel-on-linux-arm64.patch b/patches/0002-net-Skip-TestDialCancel-on-linux-arm64.patch new file mode 100644 index 00000000000..a2692bd508c --- /dev/null +++ b/patches/0002-net-Skip-TestDialCancel-on-linux-arm64.patch @@ -0,0 +1,25 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: microsoft-golang-bot +Date: Thu, 24 Feb 2022 17:57:24 -0600 +Subject: [PATCH] net: Skip TestDialCancel on linux-arm64 + +The test is flaky on our linux-arm64 builder and gets "network is unreachable". See https://github.com/golang/go/issues/37330 +--- + src/net/dial_test.go | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/net/dial_test.go b/src/net/dial_test.go +index b9aead0371..f4f383a365 100644 +--- a/src/net/dial_test.go ++++ b/src/net/dial_test.go +@@ -758,6 +758,10 @@ func TestDialerKeepAlive(t *testing.T) { + func TestDialCancel(t *testing.T) { + mustHaveExternalNetwork(t) + ++ if strings.HasPrefix(testenv.Builder(), "linux-arm64") { ++ t.Skip("skipping on linux-arm64-*; incompatible network config? issue 37330") ++ } ++ + blackholeIPPort := JoinHostPort(slowDst4, "1234") + if !supportsIPv4() { + blackholeIPPort = JoinHostPort(slowDst6, "1234") From 8c1418a054faea9d83e66b1cd72eba76f5374f60 Mon Sep 17 00:00:00 2001 From: Quim Muntal Date: Tue, 29 Mar 2022 18:27:40 +0200 Subject: [PATCH 26/47] gate openssl backend behind cgo build constraint (#503) --- patches/0003-Integrate-OpenSSL-crypto-module.patch | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/patches/0003-Integrate-OpenSSL-crypto-module.patch b/patches/0003-Integrate-OpenSSL-crypto-module.patch index d551a3f4752..6a2b79a6fbe 100644 --- a/patches/0003-Integrate-OpenSSL-crypto-module.patch +++ b/patches/0003-Integrate-OpenSSL-crypto-module.patch @@ -326,7 +326,7 @@ index 0000000000..4de8d404f8 +} diff --git a/src/crypto/internal/backend/openssl_linux.go b/src/crypto/internal/backend/openssl_linux.go new file mode 100644 -index 0000000000..c1656d6576 +index 0000000000..9fa156894a --- /dev/null +++ b/src/crypto/internal/backend/openssl_linux.go @@ -0,0 +1,145 @@ @@ -334,8 +334,8 @@ index 0000000000..c1656d6576 +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + -+//go:build linux && !android && !gocrypt && !cmd_go_bootstrap && !msan -+// +build linux,!android,!gocrypt,!cmd_go_bootstrap,!msan ++//go:build linux && cgo && !android && !gocrypt && !cmd_go_bootstrap && !msan ++// +build linux,cgo,!android,!gocrypt,!cmd_go_bootstrap,!msan + +// Package openssl provides access to OpenSSLCrypto implementation functions. +// Check the variable Enabled to find out whether OpenSSLCrypto is available. From 0018dc9de747397711d4997fb166ce52fdd9ad7e Mon Sep 17 00:00:00 2001 From: Davis Goodin Date: Tue, 29 Mar 2022 13:58:15 -0500 Subject: [PATCH 27/47] Fix version; increment Microsoft revision (#507) --- MICROSOFT_REVISION | 1 + VERSION | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 MICROSOFT_REVISION diff --git a/MICROSOFT_REVISION b/MICROSOFT_REVISION new file mode 100644 index 00000000000..d8263ee9860 --- /dev/null +++ b/MICROSOFT_REVISION @@ -0,0 +1 @@ +2 \ No newline at end of file diff --git a/VERSION b/VERSION index d458efbf6b3..cea581fa747 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -go1.17.7 \ No newline at end of file +go1.17.8 \ No newline at end of file From dfb9361802fbb1d462887c1a30d45d36be12594c Mon Sep 17 00:00:00 2001 From: microsoft-golang-bot Date: Wed, 30 Mar 2022 16:02:22 +0000 Subject: [PATCH 28/47] Update submodule to latest release-branch.go1.17 (4e69fddc): [release-branch.go1.17] runtime: fix net poll races --- go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go b/go index 88be85f18bf..4e69fddc640 160000 --- a/go +++ b/go @@ -1 +1 @@ -Subproject commit 88be85f18bf0244a2470fdf6719e1b5ca5a5e50a +Subproject commit 4e69fddc640c727865490706633833870408e6ff From 924c64bf3df00aa1a2b436e2a23110968170fe36 Mon Sep 17 00:00:00 2001 From: Davis Goodin Date: Thu, 31 Mar 2022 14:11:00 -0500 Subject: [PATCH 29/47] Rearrange FIPS patches, start at 0100 (#514) --- ...h => 0100-Add-OpenSSL-crypto-module.patch} | 394 ++---------------- patches/0101-Integrate-OpenSSL-module.patch | 321 ++++++++++++++ ... 0102-Vendor-OpenSSL-crypto-library.patch} | 31 +- ...-Go-tests-to-work-with-crypto-module.patch | 60 +++ 4 files changed, 412 insertions(+), 394 deletions(-) rename patches/{0003-Integrate-OpenSSL-crypto-module.patch => 0100-Add-OpenSSL-crypto-module.patch} (50%) create mode 100644 patches/0101-Integrate-OpenSSL-module.patch rename patches/{0002-Add-vendored-go-crypto-openssl-module.patch => 0102-Vendor-OpenSSL-crypto-library.patch} (98%) create mode 100644 patches/0103-Adjust-Go-tests-to-work-with-crypto-module.patch diff --git a/patches/0003-Integrate-OpenSSL-crypto-module.patch b/patches/0100-Add-OpenSSL-crypto-module.patch similarity index 50% rename from patches/0003-Integrate-OpenSSL-crypto-module.patch rename to patches/0100-Add-OpenSSL-crypto-module.patch index 6a2b79a6fbe..98649c184a2 100644 --- a/patches/0003-Integrate-OpenSSL-crypto-module.patch +++ b/patches/0100-Add-OpenSSL-crypto-module.patch @@ -1,159 +1,22 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: microsoft-golang-bot -Date: Thu, 27 Jan 2022 11:45:14 -0600 -Subject: [PATCH] Integrate OpenSSL crypto module +Date: Wed, 30 Mar 2022 18:54:05 -0500 +Subject: [PATCH] Add OpenSSL crypto module +github.com/microsoft/go-infra/cmd/git-go-patch command: patch number 0100 --- - src/cmd/link/internal/ld/lib.go | 2 +- - src/crypto/aes/cipher.go | 2 +- - src/crypto/aes/cipher_asm.go | 2 +- - src/crypto/boring/boring.go | 2 +- - src/crypto/boring/boring_test.go | 1 + - src/crypto/ecdsa/boring.go | 2 +- - src/crypto/ecdsa/ecdsa.go | 2 +- - src/crypto/hmac/hmac.go | 2 +- - src/crypto/hmac/hmac_test.go | 2 +- src/crypto/internal/backend/backend_test.go | 30 ++++ src/crypto/internal/backend/dummy.s | 10 ++ src/crypto/internal/backend/nobackend.go | 112 ++++++++++++++ src/crypto/internal/backend/openssl_linux.go | 145 +++++++++++++++++++ - src/crypto/rand/rand_unix.go | 2 +- - src/crypto/rsa/boring.go | 2 +- - src/crypto/rsa/pkcs1v15.go | 2 +- - src/crypto/rsa/pss.go | 2 +- - src/crypto/rsa/rsa.go | 2 +- - src/crypto/rsa/rsa_test.go | 2 +- - src/crypto/sha1/boring.go | 4 +- - src/crypto/sha1/sha1_test.go | 2 +- - src/crypto/sha256/sha256.go | 2 +- - src/crypto/sha256/sha256_test.go | 2 +- - src/crypto/sha512/sha512.go | 2 +- - src/crypto/sha512/sha512_test.go | 2 +- - src/crypto/tls/cipher_suites.go | 2 +- - src/go/build/deps_test.go | 13 +- - src/runtime/runtime_boring.go | 5 + - 28 files changed, 335 insertions(+), 25 deletions(-) + src/go.mod | 1 + + src/go.sum | 2 + + 6 files changed, 300 insertions(+) create mode 100644 src/crypto/internal/backend/backend_test.go create mode 100644 src/crypto/internal/backend/dummy.s create mode 100644 src/crypto/internal/backend/nobackend.go create mode 100644 src/crypto/internal/backend/openssl_linux.go -diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go -index d7e408669e..09c5dd152c 100644 ---- a/src/cmd/link/internal/ld/lib.go -+++ b/src/cmd/link/internal/ld/lib.go -@@ -1013,7 +1013,7 @@ var hostobj []Hostobj - // These packages can use internal linking mode. - // Others trigger external mode. - var internalpkg = []string{ -- "crypto/internal/boring", -+ "vendor/github.com/microsoft/go-crypto-openssl/openssl", - "crypto/x509", - "net", - "os/user", -diff --git a/src/crypto/aes/cipher.go b/src/crypto/aes/cipher.go -index 29d01796eb..f3680ad6b4 100644 ---- a/src/crypto/aes/cipher.go -+++ b/src/crypto/aes/cipher.go -@@ -10,7 +10,7 @@ import ( - "strconv" - ) - --import "crypto/internal/boring" -+import boring "crypto/internal/backend" - - // The AES block size in bytes. - const BlockSize = 16 -diff --git a/src/crypto/aes/cipher_asm.go b/src/crypto/aes/cipher_asm.go -index 846f56ab56..e8666b40b6 100644 ---- a/src/crypto/aes/cipher_asm.go -+++ b/src/crypto/aes/cipher_asm.go -@@ -13,7 +13,7 @@ import ( - "internal/cpu" - ) - --import "crypto/internal/boring" -+import boring "crypto/internal/backend" - - // defined in asm_*.s - -diff --git a/src/crypto/boring/boring.go b/src/crypto/boring/boring.go -index 19e2a0876f..2829231f4a 100644 ---- a/src/crypto/boring/boring.go -+++ b/src/crypto/boring/boring.go -@@ -11,7 +11,7 @@ - // is satisfied, so that applications can tag files that use this package. - package boring - --import "crypto/internal/boring" -+import boring "crypto/internal/backend" - - // Enabled reports whether BoringCrypto handles supported crypto operations. - func Enabled() bool { -diff --git a/src/crypto/boring/boring_test.go b/src/crypto/boring/boring_test.go -index ace50de0c2..83ef05d872 100644 ---- a/src/crypto/boring/boring_test.go -+++ b/src/crypto/boring/boring_test.go -@@ -11,6 +11,7 @@ import ( - ) - - func TestEnabled(t *testing.T) { -+ t.Skip("upstream assumes boring is enabled at build time, we don't") - supportedPlatform := runtime.GOOS == "linux" && runtime.GOARCH == "amd64" - if supportedPlatform && !boring.Enabled() { - t.Error("Enabled returned false on a supported platform") -diff --git a/src/crypto/ecdsa/boring.go b/src/crypto/ecdsa/boring.go -index fa15ecb850..92c42e28d5 100644 ---- a/src/crypto/ecdsa/boring.go -+++ b/src/crypto/ecdsa/boring.go -@@ -5,7 +5,7 @@ - package ecdsa - - import ( -- "crypto/internal/boring" -+ boring "crypto/internal/backend" - "math/big" - "sync/atomic" - "unsafe" -diff --git a/src/crypto/ecdsa/ecdsa.go b/src/crypto/ecdsa/ecdsa.go -index 1a7635ec2b..6d27b818dd 100644 ---- a/src/crypto/ecdsa/ecdsa.go -+++ b/src/crypto/ecdsa/ecdsa.go -@@ -42,7 +42,7 @@ import ( - ) - - import ( -- "crypto/internal/boring" -+ boring "crypto/internal/backend" - "unsafe" - ) - -diff --git a/src/crypto/hmac/hmac.go b/src/crypto/hmac/hmac.go -index 34805765d5..79fd58d0da 100644 ---- a/src/crypto/hmac/hmac.go -+++ b/src/crypto/hmac/hmac.go -@@ -26,7 +26,7 @@ import ( - "hash" - ) - --import "crypto/internal/boring" -+import boring "crypto/internal/backend" - - // FIPS 198-1: - // https://csrc.nist.gov/publications/fips/fips198-1/FIPS-198-1_final.pdf -diff --git a/src/crypto/hmac/hmac_test.go b/src/crypto/hmac/hmac_test.go -index 55415abf02..904925377b 100644 ---- a/src/crypto/hmac/hmac_test.go -+++ b/src/crypto/hmac/hmac_test.go -@@ -6,7 +6,7 @@ package hmac - - import ( - "bytes" -- "crypto/internal/boring" -+ boring "crypto/internal/backend" - "crypto/md5" - "crypto/sha1" - "crypto/sha256" diff --git a/src/crypto/internal/backend/backend_test.go b/src/crypto/internal/backend/backend_test.go new file mode 100644 index 0000000000..c2c06d3bff @@ -475,228 +338,25 @@ index 0000000000..9fa156894a +var SignRSAPSS = openssl.SignRSAPSS +var VerifyRSAPKCS1v15 = openssl.VerifyRSAPKCS1v15 +var VerifyRSAPSS = openssl.VerifyRSAPSS -diff --git a/src/crypto/rand/rand_unix.go b/src/crypto/rand/rand_unix.go -index 34f4481a9b..486d71e7a3 100644 ---- a/src/crypto/rand/rand_unix.go -+++ b/src/crypto/rand/rand_unix.go -@@ -23,7 +23,7 @@ import ( - "time" - ) - --import "crypto/internal/boring" -+import boring "crypto/internal/backend" - - const urandomDevice = "/dev/urandom" - -diff --git a/src/crypto/rsa/boring.go b/src/crypto/rsa/boring.go -index 0f362a2f16..856bc26aea 100644 ---- a/src/crypto/rsa/boring.go -+++ b/src/crypto/rsa/boring.go -@@ -5,7 +5,7 @@ - package rsa - - import ( -- "crypto/internal/boring" -+ boring "crypto/internal/backend" - "math/big" - "sync/atomic" - "unsafe" -diff --git a/src/crypto/rsa/pkcs1v15.go b/src/crypto/rsa/pkcs1v15.go -index 213ddb4add..5a44b4a71c 100644 ---- a/src/crypto/rsa/pkcs1v15.go -+++ b/src/crypto/rsa/pkcs1v15.go -@@ -14,7 +14,7 @@ import ( - "crypto/internal/randutil" - ) - --import "crypto/internal/boring" -+import boring "crypto/internal/backend" - - // This file implements encryption and decryption using PKCS #1 v1.5 padding. - -diff --git a/src/crypto/rsa/pss.go b/src/crypto/rsa/pss.go -index 16ebc0e6a7..54afa8992e 100644 ---- a/src/crypto/rsa/pss.go -+++ b/src/crypto/rsa/pss.go -@@ -15,7 +15,7 @@ import ( - "math/big" - ) - --import "crypto/internal/boring" -+import boring "crypto/internal/backend" - - // Per RFC 8017, Section 9.1 - // -diff --git a/src/crypto/rsa/rsa.go b/src/crypto/rsa/rsa.go -index eef967f826..550e66fdd9 100644 ---- a/src/crypto/rsa/rsa.go -+++ b/src/crypto/rsa/rsa.go -@@ -36,7 +36,7 @@ import ( - ) - - import ( -- "crypto/internal/boring" -+ boring "crypto/internal/backend" - "unsafe" +diff --git a/src/go.mod b/src/go.mod +index af435fa335..b251be6e34 100644 +--- a/src/go.mod ++++ b/src/go.mod +@@ -3,6 +3,7 @@ module std + go 1.17 + + require ( ++ github.com/microsoft/go-crypto-openssl v0.0.0-20220124101237-183c44c3cf71 + golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e + golang.org/x/net v0.0.0-20220106012031-21a9c9cfe9c3 ) - -diff --git a/src/crypto/rsa/rsa_test.go b/src/crypto/rsa/rsa_test.go -index 766d9a954f..f2602b94ab 100644 ---- a/src/crypto/rsa/rsa_test.go -+++ b/src/crypto/rsa/rsa_test.go -@@ -15,7 +15,7 @@ import ( - "testing" - ) - --import "crypto/internal/boring" -+import boring "crypto/internal/backend" - - func TestKeyGeneration(t *testing.T) { - for _, size := range []int{128, 1024, 2048, 3072} { -diff --git a/src/crypto/sha1/boring.go b/src/crypto/sha1/boring.go -index 44c26092ee..ed00d7cd8f 100644 ---- a/src/crypto/sha1/boring.go -+++ b/src/crypto/sha1/boring.go -@@ -11,11 +11,11 @@ - package sha1 - - import ( -- "crypto/internal/boring" -+ boring "crypto/internal/backend" - "hash" - ) - --const boringEnabled = boring.Enabled -+var boringEnabled = boring.Enabled - - func boringNewSHA1() hash.Hash { return boring.NewSHA1() } - -diff --git a/src/crypto/sha1/sha1_test.go b/src/crypto/sha1/sha1_test.go -index e369c3b7f4..af10f68853 100644 ---- a/src/crypto/sha1/sha1_test.go -+++ b/src/crypto/sha1/sha1_test.go -@@ -16,7 +16,7 @@ import ( - "testing" - ) - --import "crypto/internal/boring" -+import boring "crypto/internal/backend" - - type sha1Test struct { - out string -diff --git a/src/crypto/sha256/sha256.go b/src/crypto/sha256/sha256.go -index 8b54a427d7..c6aa7a3788 100644 ---- a/src/crypto/sha256/sha256.go -+++ b/src/crypto/sha256/sha256.go -@@ -13,7 +13,7 @@ import ( - "hash" - ) - --import "crypto/internal/boring" -+import boring "crypto/internal/backend" - - func init() { - crypto.RegisterHash(crypto.SHA224, New224) -diff --git a/src/crypto/sha256/sha256_test.go b/src/crypto/sha256/sha256_test.go -index 91a4edde04..71eacf53a7 100644 ---- a/src/crypto/sha256/sha256_test.go -+++ b/src/crypto/sha256/sha256_test.go -@@ -16,7 +16,7 @@ import ( - "testing" - ) - --import "crypto/internal/boring" -+import boring "crypto/internal/backend" - - type sha256Test struct { - out string -diff --git a/src/crypto/sha512/sha512.go b/src/crypto/sha512/sha512.go -index 1a2cef317c..b6b390a1b8 100644 ---- a/src/crypto/sha512/sha512.go -+++ b/src/crypto/sha512/sha512.go -@@ -17,7 +17,7 @@ import ( - "hash" - ) - --import "crypto/internal/boring" -+import boring "crypto/internal/backend" - - func init() { - crypto.RegisterHash(crypto.SHA384, New384) -diff --git a/src/crypto/sha512/sha512_test.go b/src/crypto/sha512/sha512_test.go -index 966cd51d15..44e3769b0b 100644 ---- a/src/crypto/sha512/sha512_test.go -+++ b/src/crypto/sha512/sha512_test.go -@@ -17,7 +17,7 @@ import ( - "testing" - ) - --import "crypto/internal/boring" -+import boring "crypto/internal/backend" - - type sha512Test struct { - out string -diff --git a/src/crypto/tls/cipher_suites.go b/src/crypto/tls/cipher_suites.go -index e07d742bd3..3f72b1e5a0 100644 ---- a/src/crypto/tls/cipher_suites.go -+++ b/src/crypto/tls/cipher_suites.go -@@ -4,7 +4,7 @@ - - package tls - --import "crypto/internal/boring" -+import boring "crypto/internal/backend" - - import ( - "crypto" -diff --git a/src/go/build/deps_test.go b/src/go/build/deps_test.go -index c399946435..ed5b74ee7b 100644 ---- a/src/go/build/deps_test.go -+++ b/src/go/build/deps_test.go -@@ -400,7 +400,14 @@ var depsRules = ` - < crypto/ed25519/internal/edwards25519 - < crypto/cipher - < encoding/asn1 -- < crypto/internal/boring -+ < CRYPTO; -+ -+ CRYPTO < crypto/internal/boring; -+ -+ CRYPTO -+ < github.com/microsoft/go-crypto-openssl/openssl/internal/subtle -+ < github.com/microsoft/go-crypto-openssl/openssl -+ < crypto/internal/backend - < crypto/aes, crypto/des, crypto/hmac, crypto/md5, crypto/rc4, - crypto/sha1, crypto/sha256, crypto/sha512 - < crypto/rand -@@ -430,7 +437,7 @@ var depsRules = ` - crypto/internal/boring/sig, crypto/internal/boring/fipstls - < crypto/tls/fipsonly; - -- crypto/internal/boring -+ crypto/internal/backend - < crypto/boring; - - # crypto-aware packages -@@ -623,7 +630,7 @@ var buildIgnore = []byte("\n// +build ignore") - - func findImports(pkg string) ([]string, error) { - vpkg := pkg -- if strings.HasPrefix(pkg, "golang.org") { -+ if strings.HasPrefix(pkg, "golang.org") || strings.HasPrefix(pkg, "github.com") { - vpkg = "vendor/" + pkg - } - dir := filepath.Join(Default.GOROOT, "src", vpkg) -diff --git a/src/runtime/runtime_boring.go b/src/runtime/runtime_boring.go -index 5a98b20253..9042f2c279 100644 ---- a/src/runtime/runtime_boring.go -+++ b/src/runtime/runtime_boring.go -@@ -17,3 +17,8 @@ func boring_runtime_arg0() string { - - //go:linkname fipstls_runtime_arg0 crypto/internal/boring/fipstls.runtime_arg0 - func fipstls_runtime_arg0() string { return boring_runtime_arg0() } -+ -+//go:linkname crypto_backend_runtime_arg0 crypto/internal/backend.runtime_arg0 -+func crypto_backend_runtime_arg0() string { -+ return boring_runtime_arg0() -+} +diff --git a/src/go.sum b/src/go.sum +index 3e3fa7989f..8ab0218786 100644 +--- a/src/go.sum ++++ b/src/go.sum +@@ -1,3 +1,5 @@ ++github.com/microsoft/go-crypto-openssl v0.0.0-20220124101237-183c44c3cf71 h1:NO1CTk7yHEtgUjfV7eqU4+sRe8OHRqZAznWe8WpVj7I= ++github.com/microsoft/go-crypto-openssl v0.0.0-20220124101237-183c44c3cf71/go.mod h1:rC+rtBU3m60UCQifBmpWII0VETfu78w6YGZQvVc0rd4= + golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e h1:1SzTfNOXwIS2oWiMF+6qu0OUDKb0dauo6MoDUQyu+yU= + golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= + golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= diff --git a/patches/0101-Integrate-OpenSSL-module.patch b/patches/0101-Integrate-OpenSSL-module.patch new file mode 100644 index 00000000000..40c690dd0fe --- /dev/null +++ b/patches/0101-Integrate-OpenSSL-module.patch @@ -0,0 +1,321 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: microsoft-golang-bot +Date: Wed, 30 Mar 2022 18:55:16 -0500 +Subject: [PATCH] Integrate OpenSSL module + +--- + src/cmd/link/internal/ld/lib.go | 2 +- + src/crypto/aes/cipher.go | 2 +- + src/crypto/aes/cipher_asm.go | 2 +- + src/crypto/boring/boring.go | 2 +- + src/crypto/ecdsa/boring.go | 2 +- + src/crypto/ecdsa/ecdsa.go | 2 +- + src/crypto/hmac/hmac.go | 2 +- + src/crypto/hmac/hmac_test.go | 2 +- + src/crypto/rand/rand_unix.go | 2 +- + src/crypto/rsa/boring.go | 2 +- + src/crypto/rsa/pkcs1v15.go | 2 +- + src/crypto/rsa/pss.go | 2 +- + src/crypto/rsa/rsa.go | 2 +- + src/crypto/rsa/rsa_test.go | 2 +- + src/crypto/sha1/boring.go | 4 ++-- + src/crypto/sha1/sha1_test.go | 2 +- + src/crypto/sha256/sha256.go | 2 +- + src/crypto/sha256/sha256_test.go | 2 +- + src/crypto/sha512/sha512.go | 2 +- + src/crypto/sha512/sha512_test.go | 2 +- + src/crypto/tls/cipher_suites.go | 2 +- + src/runtime/runtime_boring.go | 5 +++++ + 22 files changed, 27 insertions(+), 22 deletions(-) + +diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go +index 0c277f5424..5e83150181 100644 +--- a/src/cmd/link/internal/ld/lib.go ++++ b/src/cmd/link/internal/ld/lib.go +@@ -1013,7 +1013,7 @@ var hostobj []Hostobj + // These packages can use internal linking mode. + // Others trigger external mode. + var internalpkg = []string{ +- "crypto/internal/boring", ++ "vendor/github.com/microsoft/go-crypto-openssl/openssl", + "crypto/x509", + "net", + "os/user", +diff --git a/src/crypto/aes/cipher.go b/src/crypto/aes/cipher.go +index 29d01796eb..f3680ad6b4 100644 +--- a/src/crypto/aes/cipher.go ++++ b/src/crypto/aes/cipher.go +@@ -10,7 +10,7 @@ import ( + "strconv" + ) + +-import "crypto/internal/boring" ++import boring "crypto/internal/backend" + + // The AES block size in bytes. + const BlockSize = 16 +diff --git a/src/crypto/aes/cipher_asm.go b/src/crypto/aes/cipher_asm.go +index 846f56ab56..e8666b40b6 100644 +--- a/src/crypto/aes/cipher_asm.go ++++ b/src/crypto/aes/cipher_asm.go +@@ -13,7 +13,7 @@ import ( + "internal/cpu" + ) + +-import "crypto/internal/boring" ++import boring "crypto/internal/backend" + + // defined in asm_*.s + +diff --git a/src/crypto/boring/boring.go b/src/crypto/boring/boring.go +index 19e2a0876f..2829231f4a 100644 +--- a/src/crypto/boring/boring.go ++++ b/src/crypto/boring/boring.go +@@ -11,7 +11,7 @@ + // is satisfied, so that applications can tag files that use this package. + package boring + +-import "crypto/internal/boring" ++import boring "crypto/internal/backend" + + // Enabled reports whether BoringCrypto handles supported crypto operations. + func Enabled() bool { +diff --git a/src/crypto/ecdsa/boring.go b/src/crypto/ecdsa/boring.go +index fa15ecb850..92c42e28d5 100644 +--- a/src/crypto/ecdsa/boring.go ++++ b/src/crypto/ecdsa/boring.go +@@ -5,7 +5,7 @@ + package ecdsa + + import ( +- "crypto/internal/boring" ++ boring "crypto/internal/backend" + "math/big" + "sync/atomic" + "unsafe" +diff --git a/src/crypto/ecdsa/ecdsa.go b/src/crypto/ecdsa/ecdsa.go +index 1a7635ec2b..6d27b818dd 100644 +--- a/src/crypto/ecdsa/ecdsa.go ++++ b/src/crypto/ecdsa/ecdsa.go +@@ -42,7 +42,7 @@ import ( + ) + + import ( +- "crypto/internal/boring" ++ boring "crypto/internal/backend" + "unsafe" + ) + +diff --git a/src/crypto/hmac/hmac.go b/src/crypto/hmac/hmac.go +index 34805765d5..79fd58d0da 100644 +--- a/src/crypto/hmac/hmac.go ++++ b/src/crypto/hmac/hmac.go +@@ -26,7 +26,7 @@ import ( + "hash" + ) + +-import "crypto/internal/boring" ++import boring "crypto/internal/backend" + + // FIPS 198-1: + // https://csrc.nist.gov/publications/fips/fips198-1/FIPS-198-1_final.pdf +diff --git a/src/crypto/hmac/hmac_test.go b/src/crypto/hmac/hmac_test.go +index 55415abf02..904925377b 100644 +--- a/src/crypto/hmac/hmac_test.go ++++ b/src/crypto/hmac/hmac_test.go +@@ -6,7 +6,7 @@ package hmac + + import ( + "bytes" +- "crypto/internal/boring" ++ boring "crypto/internal/backend" + "crypto/md5" + "crypto/sha1" + "crypto/sha256" +diff --git a/src/crypto/rand/rand_unix.go b/src/crypto/rand/rand_unix.go +index 34f4481a9b..486d71e7a3 100644 +--- a/src/crypto/rand/rand_unix.go ++++ b/src/crypto/rand/rand_unix.go +@@ -23,7 +23,7 @@ import ( + "time" + ) + +-import "crypto/internal/boring" ++import boring "crypto/internal/backend" + + const urandomDevice = "/dev/urandom" + +diff --git a/src/crypto/rsa/boring.go b/src/crypto/rsa/boring.go +index 0f362a2f16..856bc26aea 100644 +--- a/src/crypto/rsa/boring.go ++++ b/src/crypto/rsa/boring.go +@@ -5,7 +5,7 @@ + package rsa + + import ( +- "crypto/internal/boring" ++ boring "crypto/internal/backend" + "math/big" + "sync/atomic" + "unsafe" +diff --git a/src/crypto/rsa/pkcs1v15.go b/src/crypto/rsa/pkcs1v15.go +index 213ddb4add..5a44b4a71c 100644 +--- a/src/crypto/rsa/pkcs1v15.go ++++ b/src/crypto/rsa/pkcs1v15.go +@@ -14,7 +14,7 @@ import ( + "crypto/internal/randutil" + ) + +-import "crypto/internal/boring" ++import boring "crypto/internal/backend" + + // This file implements encryption and decryption using PKCS #1 v1.5 padding. + +diff --git a/src/crypto/rsa/pss.go b/src/crypto/rsa/pss.go +index 16ebc0e6a7..54afa8992e 100644 +--- a/src/crypto/rsa/pss.go ++++ b/src/crypto/rsa/pss.go +@@ -15,7 +15,7 @@ import ( + "math/big" + ) + +-import "crypto/internal/boring" ++import boring "crypto/internal/backend" + + // Per RFC 8017, Section 9.1 + // +diff --git a/src/crypto/rsa/rsa.go b/src/crypto/rsa/rsa.go +index eef967f826..550e66fdd9 100644 +--- a/src/crypto/rsa/rsa.go ++++ b/src/crypto/rsa/rsa.go +@@ -36,7 +36,7 @@ import ( + ) + + import ( +- "crypto/internal/boring" ++ boring "crypto/internal/backend" + "unsafe" + ) + +diff --git a/src/crypto/rsa/rsa_test.go b/src/crypto/rsa/rsa_test.go +index 766d9a954f..f2602b94ab 100644 +--- a/src/crypto/rsa/rsa_test.go ++++ b/src/crypto/rsa/rsa_test.go +@@ -15,7 +15,7 @@ import ( + "testing" + ) + +-import "crypto/internal/boring" ++import boring "crypto/internal/backend" + + func TestKeyGeneration(t *testing.T) { + for _, size := range []int{128, 1024, 2048, 3072} { +diff --git a/src/crypto/sha1/boring.go b/src/crypto/sha1/boring.go +index 44c26092ee..ed00d7cd8f 100644 +--- a/src/crypto/sha1/boring.go ++++ b/src/crypto/sha1/boring.go +@@ -11,11 +11,11 @@ + package sha1 + + import ( +- "crypto/internal/boring" ++ boring "crypto/internal/backend" + "hash" + ) + +-const boringEnabled = boring.Enabled ++var boringEnabled = boring.Enabled + + func boringNewSHA1() hash.Hash { return boring.NewSHA1() } + +diff --git a/src/crypto/sha1/sha1_test.go b/src/crypto/sha1/sha1_test.go +index e369c3b7f4..af10f68853 100644 +--- a/src/crypto/sha1/sha1_test.go ++++ b/src/crypto/sha1/sha1_test.go +@@ -16,7 +16,7 @@ import ( + "testing" + ) + +-import "crypto/internal/boring" ++import boring "crypto/internal/backend" + + type sha1Test struct { + out string +diff --git a/src/crypto/sha256/sha256.go b/src/crypto/sha256/sha256.go +index 8b54a427d7..c6aa7a3788 100644 +--- a/src/crypto/sha256/sha256.go ++++ b/src/crypto/sha256/sha256.go +@@ -13,7 +13,7 @@ import ( + "hash" + ) + +-import "crypto/internal/boring" ++import boring "crypto/internal/backend" + + func init() { + crypto.RegisterHash(crypto.SHA224, New224) +diff --git a/src/crypto/sha256/sha256_test.go b/src/crypto/sha256/sha256_test.go +index 91a4edde04..71eacf53a7 100644 +--- a/src/crypto/sha256/sha256_test.go ++++ b/src/crypto/sha256/sha256_test.go +@@ -16,7 +16,7 @@ import ( + "testing" + ) + +-import "crypto/internal/boring" ++import boring "crypto/internal/backend" + + type sha256Test struct { + out string +diff --git a/src/crypto/sha512/sha512.go b/src/crypto/sha512/sha512.go +index 1a2cef317c..b6b390a1b8 100644 +--- a/src/crypto/sha512/sha512.go ++++ b/src/crypto/sha512/sha512.go +@@ -17,7 +17,7 @@ import ( + "hash" + ) + +-import "crypto/internal/boring" ++import boring "crypto/internal/backend" + + func init() { + crypto.RegisterHash(crypto.SHA384, New384) +diff --git a/src/crypto/sha512/sha512_test.go b/src/crypto/sha512/sha512_test.go +index 966cd51d15..44e3769b0b 100644 +--- a/src/crypto/sha512/sha512_test.go ++++ b/src/crypto/sha512/sha512_test.go +@@ -17,7 +17,7 @@ import ( + "testing" + ) + +-import "crypto/internal/boring" ++import boring "crypto/internal/backend" + + type sha512Test struct { + out string +diff --git a/src/crypto/tls/cipher_suites.go b/src/crypto/tls/cipher_suites.go +index e07d742bd3..3f72b1e5a0 100644 +--- a/src/crypto/tls/cipher_suites.go ++++ b/src/crypto/tls/cipher_suites.go +@@ -4,7 +4,7 @@ + + package tls + +-import "crypto/internal/boring" ++import boring "crypto/internal/backend" + + import ( + "crypto" +diff --git a/src/runtime/runtime_boring.go b/src/runtime/runtime_boring.go +index 5a98b20253..9042f2c279 100644 +--- a/src/runtime/runtime_boring.go ++++ b/src/runtime/runtime_boring.go +@@ -17,3 +17,8 @@ func boring_runtime_arg0() string { + + //go:linkname fipstls_runtime_arg0 crypto/internal/boring/fipstls.runtime_arg0 + func fipstls_runtime_arg0() string { return boring_runtime_arg0() } ++ ++//go:linkname crypto_backend_runtime_arg0 crypto/internal/backend.runtime_arg0 ++func crypto_backend_runtime_arg0() string { ++ return boring_runtime_arg0() ++} diff --git a/patches/0002-Add-vendored-go-crypto-openssl-module.patch b/patches/0102-Vendor-OpenSSL-crypto-library.patch similarity index 98% rename from patches/0002-Add-vendored-go-crypto-openssl-module.patch rename to patches/0102-Vendor-OpenSSL-crypto-library.patch index 16dbb77f8a9..080662cfe23 100644 --- a/patches/0002-Add-vendored-go-crypto-openssl-module.patch +++ b/patches/0102-Vendor-OpenSSL-crypto-library.patch @@ -1,11 +1,10 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: microsoft-golang-bot -Date: Thu, 27 Jan 2022 11:44:32 -0600 -Subject: [PATCH] Add vendored go-crypto-openssl module +Date: Wed, 30 Mar 2022 18:56:01 -0500 +Subject: [PATCH] Vendor OpenSSL crypto library +To reproduce, run 'go mod vendor' in 'go/src'. --- - src/go.mod | 1 + - src/go.sum | 2 + .../microsoft/go-crypto-openssl/LICENSE | 21 + .../go-crypto-openssl/openssl/aes.go | 487 ++++++++++++++++++ .../go-crypto-openssl/openssl/apibridge_1_1.c | 291 +++++++++++ @@ -22,7 +21,7 @@ Subject: [PATCH] Add vendored go-crypto-openssl module .../go-crypto-openssl/openssl/rsa.go | 397 ++++++++++++++ .../go-crypto-openssl/openssl/sha.go | 477 +++++++++++++++++ src/vendor/modules.txt | 4 + - 18 files changed, 2939 insertions(+) + 16 files changed, 2936 insertions(+) create mode 100644 src/vendor/github.com/microsoft/go-crypto-openssl/LICENSE create mode 100644 src/vendor/github.com/microsoft/go-crypto-openssl/openssl/aes.go create mode 100644 src/vendor/github.com/microsoft/go-crypto-openssl/openssl/apibridge_1_1.c @@ -39,28 +38,6 @@ Subject: [PATCH] Add vendored go-crypto-openssl module create mode 100644 src/vendor/github.com/microsoft/go-crypto-openssl/openssl/rsa.go create mode 100644 src/vendor/github.com/microsoft/go-crypto-openssl/openssl/sha.go -diff --git a/src/go.mod b/src/go.mod -index af435fa335..b251be6e34 100644 ---- a/src/go.mod -+++ b/src/go.mod -@@ -3,6 +3,7 @@ module std - go 1.17 - - require ( -+ github.com/microsoft/go-crypto-openssl v0.0.0-20220124101237-183c44c3cf71 - golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e - golang.org/x/net v0.0.0-20220106012031-21a9c9cfe9c3 - ) -diff --git a/src/go.sum b/src/go.sum -index 3e3fa7989f..8ab0218786 100644 ---- a/src/go.sum -+++ b/src/go.sum -@@ -1,3 +1,5 @@ -+github.com/microsoft/go-crypto-openssl v0.0.0-20220124101237-183c44c3cf71 h1:NO1CTk7yHEtgUjfV7eqU4+sRe8OHRqZAznWe8WpVj7I= -+github.com/microsoft/go-crypto-openssl v0.0.0-20220124101237-183c44c3cf71/go.mod h1:rC+rtBU3m60UCQifBmpWII0VETfu78w6YGZQvVc0rd4= - golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e h1:1SzTfNOXwIS2oWiMF+6qu0OUDKb0dauo6MoDUQyu+yU= - golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= - golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= diff --git a/src/vendor/github.com/microsoft/go-crypto-openssl/LICENSE b/src/vendor/github.com/microsoft/go-crypto-openssl/LICENSE new file mode 100644 index 0000000000..9e841e7a26 diff --git a/patches/0103-Adjust-Go-tests-to-work-with-crypto-module.patch b/patches/0103-Adjust-Go-tests-to-work-with-crypto-module.patch new file mode 100644 index 00000000000..98838f51281 --- /dev/null +++ b/patches/0103-Adjust-Go-tests-to-work-with-crypto-module.patch @@ -0,0 +1,60 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: microsoft-golang-bot +Date: Wed, 30 Mar 2022 18:56:30 -0500 +Subject: [PATCH] Adjust Go tests to work with crypto module + +--- + src/crypto/boring/boring_test.go | 1 + + src/go/build/deps_test.go | 13 ++++++++++--- + 2 files changed, 11 insertions(+), 3 deletions(-) + +diff --git a/src/crypto/boring/boring_test.go b/src/crypto/boring/boring_test.go +index ace50de0c2..83ef05d872 100644 +--- a/src/crypto/boring/boring_test.go ++++ b/src/crypto/boring/boring_test.go +@@ -11,6 +11,7 @@ import ( + ) + + func TestEnabled(t *testing.T) { ++ t.Skip("upstream assumes boring is enabled at build time, we don't") + supportedPlatform := runtime.GOOS == "linux" && runtime.GOARCH == "amd64" + if supportedPlatform && !boring.Enabled() { + t.Error("Enabled returned false on a supported platform") +diff --git a/src/go/build/deps_test.go b/src/go/build/deps_test.go +index c399946435..ed5b74ee7b 100644 +--- a/src/go/build/deps_test.go ++++ b/src/go/build/deps_test.go +@@ -400,7 +400,14 @@ var depsRules = ` + < crypto/ed25519/internal/edwards25519 + < crypto/cipher + < encoding/asn1 +- < crypto/internal/boring ++ < CRYPTO; ++ ++ CRYPTO < crypto/internal/boring; ++ ++ CRYPTO ++ < github.com/microsoft/go-crypto-openssl/openssl/internal/subtle ++ < github.com/microsoft/go-crypto-openssl/openssl ++ < crypto/internal/backend + < crypto/aes, crypto/des, crypto/hmac, crypto/md5, crypto/rc4, + crypto/sha1, crypto/sha256, crypto/sha512 + < crypto/rand +@@ -430,7 +437,7 @@ var depsRules = ` + crypto/internal/boring/sig, crypto/internal/boring/fipstls + < crypto/tls/fipsonly; + +- crypto/internal/boring ++ crypto/internal/backend + < crypto/boring; + + # crypto-aware packages +@@ -623,7 +630,7 @@ var buildIgnore = []byte("\n// +build ignore") + + func findImports(pkg string) ([]string, error) { + vpkg := pkg +- if strings.HasPrefix(pkg, "golang.org") { ++ if strings.HasPrefix(pkg, "golang.org") || strings.HasPrefix(pkg, "github.com") { + vpkg = "vendor/" + pkg + } + dir := filepath.Join(Default.GOROOT, "src", vpkg) From f971b146028afc85aa69018cf2e9b17b7bb844a6 Mon Sep 17 00:00:00 2001 From: Quim Muntal Date: Fri, 1 Apr 2022 09:58:42 +0200 Subject: [PATCH 30/47] Use FIPS-enabled Mariner image when running CI tests --- eng/pipeline/jobs/run-job.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/pipeline/jobs/run-job.yml b/eng/pipeline/jobs/run-job.yml index cd6546aaabb..ae0962abba2 100644 --- a/eng/pipeline/jobs/run-job.yml +++ b/eng/pipeline/jobs/run-job.yml @@ -26,7 +26,7 @@ jobs: # The image used for the container this job runs in. The tests run in this container, so it # should match what we support as closely as possible. ${{ if not(parameters.builder.distro) }}: - container: golangpublicimages.azurecr.io/go-infra-images/prereqs:cbl-mariner-1.0.20211027-20211201-0cccc22 + container: golangpublicimages.azurecr.io/go-infra-images/prereqs:cbl-mariner-1.0.20211027-fips-20211206-e78b6d3 ${{ if eq(parameters.builder.distro, 'ubuntu') }}: container: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-20211022152710-047508b From e258137481b7bad84838bb4f75755695a80d8eeb Mon Sep 17 00:00:00 2001 From: Quim Muntal Date: Mon, 4 Apr 2022 12:07:12 +0200 Subject: [PATCH 31/47] Update run-job.yml --- eng/pipeline/jobs/run-job.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/pipeline/jobs/run-job.yml b/eng/pipeline/jobs/run-job.yml index 282d6ace624..190cb37fc9c 100644 --- a/eng/pipeline/jobs/run-job.yml +++ b/eng/pipeline/jobs/run-job.yml @@ -27,7 +27,7 @@ jobs: # The image used for the container this job runs in. The tests run in this container, so it # should match what we support as closely as possible. ${{ if not(parameters.builder.distro) }}: - container: golangpublicimages.azurecr.io/go-infra-images/prereqs:cbl-mariner-1.0.20211027-fips-20211206-e78b6d3 + container: golangpublicimages.azurecr.io/go-infra-images/prereqs:cbl-mariner-1.0.20211027-fips-20211206-e78b6d3 ${{ if eq(parameters.builder.distro, 'ubuntu') }}: container: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-20211022152710-047508b ${{ if eq(parameters.builder.arch, 'arm64') }}: From d2b3c0aa3b3622017fa08ac2914770a2309ab95c Mon Sep 17 00:00:00 2001 From: microsoft-golang-bot Date: Tue, 12 Apr 2022 17:01:32 +0000 Subject: [PATCH 32/47] Update submodule to latest release-branch.go1.17 (346b18ee): [release-branch.go1.17] go1.17.9 --- go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go b/go index 4e69fddc640..346b18ee9d1 160000 --- a/go +++ b/go @@ -1 +1 @@ -Subproject commit 4e69fddc640c727865490706633833870408e6ff +Subproject commit 346b18ee9d15410ab08dd583787c64dbed0666d2 From 2eb964a48b4b04dea5933d0a2aa50b2c03c2ec04 Mon Sep 17 00:00:00 2001 From: microsoft-golang-bot Date: Thu, 14 Apr 2022 17:43:17 +0000 Subject: [PATCH 33/47] Update submodule to latest dev.boringcrypto.go1.17 (ed86dfc4): [dev.boringcrypto.go1.17] all: merge go1.17.9 into dev.boringcrypto.go1.17 --- go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go b/go index 4ea866a9969..ed86dfc4e44 160000 --- a/go +++ b/go @@ -1 +1 @@ -Subproject commit 4ea866a9969f4ff2ffd975116a17bbe01ce00469 +Subproject commit ed86dfc4e441ee7597586dd858fb87c987f1f3c8 From 111b83030c795379107ef243ce7c29480cdc1bd6 Mon Sep 17 00:00:00 2001 From: Davis Goodin Date: Thu, 14 Apr 2022 15:43:23 -0500 Subject: [PATCH 34/47] Update version to 1.17.9-1 (#529) --- MICROSOFT_REVISION | 2 +- VERSION | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/MICROSOFT_REVISION b/MICROSOFT_REVISION index d8263ee9860..56a6051ca2b 100644 --- a/MICROSOFT_REVISION +++ b/MICROSOFT_REVISION @@ -1 +1 @@ -2 \ No newline at end of file +1 \ No newline at end of file diff --git a/VERSION b/VERSION index cea581fa747..699d953a7f8 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -go1.17.8 \ No newline at end of file +go1.17.9 \ No newline at end of file From a3dfe9176f38ca8992bd476bbe934c13e1cb1a60 Mon Sep 17 00:00:00 2001 From: Davis Goodin Date: Thu, 7 Apr 2022 12:52:56 -0500 Subject: [PATCH 35/47] Add test retries on Windows CI (#475) * Add test retries on Windows CI * Delete unnecessary funcs, reject empty string, check earlier * Fix test run: don't reuse cmd, remove redundant runCmd Also replace '%v' with %q when possible. (cherry picked from commit 20d99861d2aec41075ee0df30cc7591bfa602243) --- eng/_core/cmd/build/build.go | 117 ++++++++++++++++++++++------------ eng/pipeline/jobs/run-job.yml | 2 + 2 files changed, 77 insertions(+), 42 deletions(-) diff --git a/eng/_core/cmd/build/build.go b/eng/_core/cmd/build/build.go index 76153e8c1b5..0d7b7366e0b 100644 --- a/eng/_core/cmd/build/build.go +++ b/eng/_core/cmd/build/build.go @@ -7,6 +7,7 @@ package main import ( "flag" "fmt" + "log" "os" "os/exec" "path/filepath" @@ -48,6 +49,9 @@ func main() { "Refresh Go submodule: clean untracked files, reset tracked files, and apply patches before building.\n"+ "For more refresh options, use the top level 'submodule-refresh' command instead of 'build'.") + o.MaxMakeAttempts = getMaxAttemptsOrExit("GO_MAKE_MAX_RETRY_ATTEMPTS", 1) + o.MaxTestAttempts = getMaxAttemptsOrExit("GO_TEST_MAX_RETRY_ATTEMPTS", 1) + flag.Usage = func() { fmt.Fprintf(flag.CommandLine.Output(), "Usage:\n") flag.PrintDefaults() @@ -75,6 +79,9 @@ type options struct { JSON bool Pack bool Refresh bool + + MaxMakeAttempts int + MaxTestAttempts int } func build(o *options) error { @@ -134,26 +141,12 @@ func build(o *options) error { return err } - maxAttempts, err := getMaxMakeRetryAttempts() - if err != nil { - return err - } - buildCommandLine := append(shellPrefix, "make"+scriptExtension) - for i := 0; i < maxAttempts; i++ { - if maxAttempts > 1 { - fmt.Printf("---- Running 'make' attempt %v of %v...\n", i+1, maxAttempts) - } - err := runCommandLine(buildCommandLine...) - if err != nil { - if i+1 < maxAttempts { - fmt.Printf("---- Build command failed with error: %v\n", err) - continue - } - return err - } - break + if err := retry(o.MaxMakeAttempts, func() error { + return runCommandLine(buildCommandLine...) + }); err != nil { + return err } if os.Getenv("CGO_ENABLED") != "0" { @@ -194,26 +187,30 @@ func build(o *options) error { testCommandLine = append(testCommandLine, "-json") } - testCmd := exec.Command(testCommandLine[0], testCommandLine[1:]...) - testCmd.Stdout = os.Stdout - // Redirect stderr to stdout. We expect some lines of stderr to always show up during the - // test run, but "build"'s caller might not understand that. - // - // For example, if we're running in CI, gotestsum may be capturing our output to report in a - // JUnit file. If gotestsum detects output in stderr, it prints it in an error message. This - // error message stands out, and could mislead someone trying to diagnose a failed test run. - // Redirecting all stderr output avoids this scenario. (See /eng/_core/README.md for more - // info on why we may be wrapped by gotestsum.) - // - // An example of benign stderr output is when the tests check for machine capabilities. A - // Cgo static linking test emits "/usr/bin/ld: cannot find -lc" when it checks the - // capabilities of "ld" on the current system. - // - // The stderr output isn't used to determine whether the tests succeeded or not. (The - // redirect doesn't cause an issue where tests succeed that should have failed.) - testCmd.Stderr = os.Stdout + test := func() error { + testCmd := exec.Command(testCommandLine[0], testCommandLine[1:]...) + testCmd.Stdout = os.Stdout + // Redirect stderr to stdout. We expect some lines of stderr to always show up during the + // test run, but "build"'s caller might not understand that. + // + // For example, if we're running in CI, gotestsum may be capturing our output to report in a + // JUnit file. If gotestsum detects output in stderr, it prints it in an error message. This + // error message stands out, and could mislead someone trying to diagnose a failed test run. + // Redirecting all stderr output avoids this scenario. (See /eng/_core/README.md for more + // info on why we may be wrapped by gotestsum.) + // + // An example of benign stderr output is when the tests check for machine capabilities. A + // Cgo static linking test emits "/usr/bin/ld: cannot find -lc" when it checks the + // capabilities of "ld" on the current system. + // + // The stderr output isn't used to determine whether the tests succeeded or not. (The + // redirect doesn't cause an issue where tests succeed that should have failed.) + testCmd.Stderr = os.Stdout + + return runCmd(testCmd) + } - if err := runCmd(testCmd); err != nil { + if err := retry(o.MaxTestAttempts, test); err != nil { return err } } @@ -241,15 +238,51 @@ func runCmd(cmd *exec.Cmd) error { return cmd.Run() } -func getMaxMakeRetryAttempts() (int, error) { - const retryEnvVarName = "GO_MAKE_MAX_RETRY_ATTEMPTS" - a := os.Getenv(retryEnvVarName) +func retry(attempts int, f func() error) error { + var i = 0 + for ; i < attempts; i++ { + if attempts > 1 { + fmt.Printf("---- Running attempt %v of %v...\n", i+1, attempts) + } + err := f() + if err != nil { + if i+1 < attempts { + fmt.Printf("---- Attempt failed with error: %v\n", err) + continue + } + fmt.Printf("---- Final attempt failed.\n") + return err + } + break + } + fmt.Printf("---- Successful on attempt %v of %v.\n", i+1, attempts) + return nil +} + +func getMaxAttemptsOrExit(varName string, defaultValue int) int { + attempts, err := getEnvIntOrDefault(varName, defaultValue) + if err != nil { + log.Fatal(err) + } + if attempts <= 0 { + log.Fatalf("Expected positive integer for environment variable %q, but found: %v\n", varName, attempts) + } + return attempts +} + +func getEnvIntOrDefault(varName string, defaultValue int) (int, error) { + a, ok := os.LookupEnv(varName) + if !ok { + return defaultValue, nil + } if a == "" { - return 1, nil + return 0, fmt.Errorf( + "env var %q is set to empty string, which is not an int. To use the default value %v, unset the env var", + varName, defaultValue) } i, err := strconv.Atoi(a) if err != nil { - return 0, fmt.Errorf("env var '%v' is not an int: %w", retryEnvVarName, err) + return 0, fmt.Errorf("env var %q is not an int: %w", varName, err) } return i, nil } diff --git a/eng/pipeline/jobs/run-job.yml b/eng/pipeline/jobs/run-job.yml index 6953c339c62..4fa209632ce 100644 --- a/eng/pipeline/jobs/run-job.yml +++ b/eng/pipeline/jobs/run-job.yml @@ -57,6 +57,8 @@ jobs: - pwsh: | Write-Host "Increasing max build retries to mitigate 'Access denied' flakiness during EXE copying on Windows." Write-Host "##vso[task.setvariable variable=GO_MAKE_MAX_RETRY_ATTEMPTS]5" + Write-Host "Increasing max test retries to mitigate access denied issues as well as general test flakiness on Windows." + Write-Host "##vso[task.setvariable variable=GO_TEST_MAX_RETRY_ATTEMPTS]5" displayName: Increase 'make' retry attempts # Initialize stage 0 toolset ahead of time so we can track timing data separately from the From 3b1a95729d64a5aab4e74255d29b2697948550ec Mon Sep 17 00:00:00 2001 From: Davis Goodin Date: Wed, 20 Apr 2022 11:53:33 -0500 Subject: [PATCH 36/47] Add arm/v6 cross-compiled build (#523) * Add arm/v6 cross-compiled build Update bootstrap Go to 1.18 for strings.Cut. Add missing err checks in pack code. * Use 'finally' in Invoke-CrossGoBlock * Explain getEnvOrDefault error case in doc comment * Update go-infra for build asset JSON arm/v6 fix (cherry picked from commit 41afc845ac89f84647607eaf8fd4f7d58ec2d0b9) --- eng/_core/archive/archive.go | 129 +++++++++++++++--- eng/_core/archive/writer.go | 40 ++++-- eng/_core/cmd/build/build.go | 53 +++++-- eng/_core/cmd/pack/pack.go | 5 + eng/_util/go.mod | 2 +- eng/_util/go.sum | 6 +- eng/pipeline/jobs/builders-to-jobs.yml | 2 +- eng/pipeline/jobs/go-builder-matrix-jobs.yml | 1 + eng/pipeline/jobs/run-job.yml | 13 +- .../jobs/shorthand-builders-to-builders.yml | 7 +- eng/run.ps1 | 16 ++- eng/utilities.ps1 | 24 +++- 12 files changed, 241 insertions(+), 57 deletions(-) diff --git a/eng/_core/archive/archive.go b/eng/_core/archive/archive.go index 213c874e5ed..e514db511a2 100644 --- a/eng/_core/archive/archive.go +++ b/eng/_core/archive/archive.go @@ -67,18 +67,14 @@ func CreateFromSource(source string, output string) error { // The inclusion of some files depends on the OS/ARCH. If output is specified, its filename must // follow the pattern "*{GOOS}-{GOARCH}{extension}" so OS and ARCH can be detected. If output is not // specified, the current Go runtime's OS and ARCH are used. -func CreateFromBuild(source string, output string) error { +// +// If runtime.GOOS and runtime.GOARCH don't match the OS/ARCH of the output file name, the build +// directory is treated as a cross-compiled build of Go. +func CreateFromBuild(source, output string) error { fmt.Printf("---- Creating Go archive (zip/tarball) from '%v'...\n", source) if output == "" { - archiveVersion := getBuildID() - archiveExtension := ".tar.gz" - if runtime.GOOS == "windows" { - archiveExtension = ".zip" - } - - archiveName := fmt.Sprintf("go.%v.%v-%v%v", archiveVersion, runtime.GOOS, runtime.GOARCH, archiveExtension) - output = filepath.Join(getBinDir(source), archiveName) + output = DefaultBuildOutputPath(source, "", "") } // Ensure the target directory exists. @@ -111,6 +107,22 @@ func CreateFromBuild(source string, output string) error { filepath.Join("pkg", "tool", os+"_"+arch, "api.exe"), } + hostOS := runtime.GOOS + hostArch := runtime.GOARCH + if hostOS != os || hostArch != arch { + fmt.Printf("Handling cross-compile: %v-%v host to %v-%v target\n", hostOS, hostArch, os, arch) + skipPaths = append(skipPaths, []string{ + // Don't include binaries that were built for the host toolchain. + filepath.Join("pkg", hostOS+"_"+hostArch), + filepath.Join("pkg", "tool", hostOS+"_"+hostArch), + // Don't include the host binaries: the target binaries are in a subdir. + filepath.Join("bin", "go"), + filepath.Join("bin", "go.exe"), + filepath.Join("bin", "gofmt"), + filepath.Join("bin", "gofmt.exe"), + }...) + } + // Figure out what the race detection syso (precompiled binary) is named for the current // os/arch. We want to exclude all race syso files other than this one. targetRuntimeRaceSyso := fmt.Sprintf("race_%v_%v.syso", os, arch) @@ -119,7 +131,13 @@ func CreateFromBuild(source string, output string) error { // data the script has processed to avoid appearing unresponsive. lastProgressUpdate := time.Now() - filepath.WalkDir(source, func(path string, info fs.DirEntry, err error) error { + // Keep track of target paths added to the archive (key) and the source path that it comes from + // (value). This map ensures no target files are double-added. + addedPaths := make(map[string]string) + // Keep track of dir entries that have been added. + addedDirs := make(map[string]struct{}) + + err := filepath.WalkDir(source, func(path string, info fs.DirEntry, err error) error { if err != nil { fmt.Printf("Failure accessing a path %q: %v\n", path, err) return err @@ -127,9 +145,12 @@ func CreateFromBuild(source string, output string) error { relPath, err := filepath.Rel(source, path) if err != nil { - panic(err) + return err } + // targetPath is where relPath should be placed in the output archive, if it belongs inside. + targetPath := relPath + // Walk every dir/file in the root of the repository. if relPath == "." { // Ignore the rest of the logic in this func by returning nil early. @@ -168,6 +189,11 @@ func CreateFromBuild(source string, output string) error { } } + // Include "bin/{OS}_{ARCH}/go" as "bin/go" if this is a cross-compilation build. + if filepath.Dir(relPath) == filepath.Join("bin", os+"_"+arch) { + targetPath = filepath.Join("bin", filepath.Base(relPath)) + } + // Skip race detection syso file if it doesn't match the target runtime. // // Ignore error: the only possible error is one that says the pattern is invalid (see @@ -181,16 +207,52 @@ func CreateFromBuild(source string, output string) error { if info.IsDir() { // We want to continue the recursive search in this directory for more files, but we - // don't need to add it to the archive. Return nil to continue. + // don't necessarily want to add this dir to the archive. Return nil to continue. return nil } - // At this point, we know "path" is a file that should be included. Add it. - archiver.AddFile( - path, - // Store everything in a root "go" directory to match upstream Go archives. - filepath.Join("go", relPath), - ) + if relPath != targetPath { + fmt.Printf("Archiving %#q as %#q\n", relPath, targetPath) + } + + if otherSource, ok := addedPaths[targetPath]; ok { + return fmt.Errorf( + "adding archive file %#q from %#q, but target already added from %#q", + targetPath, relPath, otherSource) + } + addedPaths[targetPath] = relPath + + // At this point, we know "path" is a file that should be included. Add it. Store everything + // in a root "go" directory to match upstream Go archives. + goTargetPath := filepath.Join("go", targetPath) + if err := archiver.AddFile(path, goTargetPath); err != nil { + return err + } + + // Add all dirs that are ancestors of this target file. Even though explicitly added dirs + // aren't necessary to create a valid archive file, upstream does this, so we do too. This + // reduces the diff, e.g. when comparing results with tools like "tar -tf". + dir := goTargetPath + for { + dir = filepath.Dir(dir) + if dir == "." { + break + } + if dir == "/" { + return fmt.Errorf("unexpected rooted target path: %#q", goTargetPath) + } + + if _, ok := addedDirs[dir]; ok { + break + } + // Use root repository dir as a stand-in for any filesystem information. This is simpler + // than reproducing the actual dir's path based on the target path, especially + // considering the target path may not match up with a directory that actually exists. + if err := archiver.AddFile(source, dir); err != nil { + return err + } + addedDirs[dir] = struct{}{} + } // If it's been long enough, log an update on our progress. now := time.Now() @@ -204,6 +266,9 @@ func CreateFromBuild(source string, output string) error { return nil }) + if err != nil { + return err + } fmt.Printf( "Complete! %v (%v kB uncompressed data archived)\n", @@ -224,6 +289,31 @@ func CreateFromBuild(source string, output string) error { return nil } +// DefaultBuildOutputPath returns the default path to place the output archive given a built Go +// directory. Optionally takes os and arch, or detects their values from the environment and runtime +// if empty string. +func DefaultBuildOutputPath(source, os, arch string) string { + if os == "" { + os = runtime.GOOS + } + if arch == "" { + arch = runtime.GOARCH + } + // Add "v6l" suffix to "arm" arch. More robust handling would be necessary if there were + // multiple "arm" builds with GOARM=6 and GOARM=7, but there are not, and "arm64" obsoletes it. + if arch == "arm" { + arch += "v6l" + } + + ext := ".tar.gz" + if runtime.GOOS == "windows" { + ext = ".zip" + } + + archiveName := fmt.Sprintf("go.%v.%v-%v%v", getBuildID(), os, arch, ext) + return filepath.Join(getBinDir(source), archiveName) +} + // getBuildID returns BUILD_BUILDNUMBER if defined (e.g. a CI build). Otherwise, "dev". func getBuildID() string { archiveVersion := os.Getenv("BUILD_BUILDNUMBER") @@ -244,7 +334,8 @@ func getArchivePathRuntime(path string, ext string) (os string, arch string) { pathNoExt := path[0 : len(path)-len(ext)] firstRuntimeIndex := strings.LastIndex(pathNoExt, ".") + 1 osArch := strings.Split(pathNoExt[firstRuntimeIndex:], "-") - return osArch[0], osArch[1] + // "v6l" is added to the end of the "arm" arch filename, but is not part of the arch. Remove it. + return osArch[0], strings.TrimSuffix(osArch[1], "v6l") } // writeSHA256ChecksumFile reads the content of the file at the given path into a SHA256 hasher, and diff --git a/eng/_core/archive/writer.go b/eng/_core/archive/writer.go index fd2c55d5be1..3596ebdd0ce 100644 --- a/eng/_core/archive/writer.go +++ b/eng/_core/archive/writer.go @@ -88,14 +88,20 @@ func (a *tarGzArchiver) AddFile(filePath string, archivePath string) error { // tar.FileInfoHeader only takes base name, so set full path here. See FileInfoHeader doc. header.Name = archivePath + if stat.IsDir() { + header.Name += "/" + } if err := a.tarWriter.WriteHeader(header); err != nil { return err } - n, err := io.Copy(a.tarWriter, fileReader) - a.processedBytes += n - return err + if !stat.IsDir() { + n, err := io.Copy(a.tarWriter, fileReader) + a.processedBytes += n + return err + } + return nil } func (a *tarGzArchiver) Close() error { @@ -129,20 +135,36 @@ func newZipArchiver(path string) *zipArchiver { } func (a *zipArchiver) AddFile(filePath string, archivePath string) error { - archiveFileWriter, err := a.writer.Create(archivePath) + fileReader, err := os.Open(filePath) if err != nil { return err } + defer fileReader.Close() - fileReader, err := os.Open(filePath) + stat, err := fileReader.Stat() if err != nil { return err } - defer fileReader.Close() - n, err := io.Copy(archiveFileWriter, fileReader) - a.processedBytes += n - return err + // Upstream Go uses "/" for archive dir separators, even on Windows. + archivePath = filepath.ToSlash(archivePath) + + // Give dirs a trailing forward slash to indicate to the zip writer that it's a dir. + if stat.IsDir() { + archivePath += "/" + } + + archiveFileWriter, err := a.writer.Create(archivePath) + if err != nil { + return err + } + + if !stat.IsDir() { + n, err := io.Copy(archiveFileWriter, fileReader) + a.processedBytes += n + return err + } + return nil } func (a *zipArchiver) Close() error { diff --git a/eng/_core/cmd/build/build.go b/eng/_core/cmd/build/build.go index 0d7b7366e0b..d9b4701c71f 100644 --- a/eng/_core/cmd/build/build.go +++ b/eng/_core/cmd/build/build.go @@ -112,6 +112,19 @@ func build(o *options) error { } } + // Get the target platform information. If the environment variable is different from the + // runtime value, this means we're doing a cross-compiled build. These values are used for + // capability checks and to make sure that if Pack is enabled, the output archive is formatted + // correctly and uses the right filename. + targetOS, err := getEnvOrDefault("GOOS", runtime.GOOS) + if err != nil { + return err + } + targetArch, err := getEnvOrDefault("GOARCH", runtime.GOARCH) + if err != nil { + return err + } + // The upstream build scripts in {repo-root}/src require your working directory to be src, or // they instantly fail. Change the current process dir so that we can run them. if err := os.Chdir("go/src"); err != nil { @@ -149,7 +162,10 @@ func build(o *options) error { return err } - if os.Getenv("CGO_ENABLED") != "0" { + // The race runtime requires cgo. + // It isn't supported on arm. + // It's supported on arm64, but the official linux-arm64 distribution doesn't include it. + if os.Getenv("CGO_ENABLED") != "0" && targetArch != "arm" && targetArch != "arm64" { fmt.Println("---- Building race runtime...") err := runCommandLine( filepath.Join("..", "bin", "go"+executableExtension), @@ -217,7 +233,8 @@ func build(o *options) error { if o.Pack { goRootDir := filepath.Join(rootDir, "go") - if err := archive.CreateFromBuild(goRootDir, ""); err != nil { + output := archive.DefaultBuildOutputPath(goRootDir, targetOS, targetArch) + if err := archive.CreateFromBuild(goRootDir, output); err != nil { return err } } @@ -271,14 +288,9 @@ func getMaxAttemptsOrExit(varName string, defaultValue int) int { } func getEnvIntOrDefault(varName string, defaultValue int) (int, error) { - a, ok := os.LookupEnv(varName) - if !ok { - return defaultValue, nil - } - if a == "" { - return 0, fmt.Errorf( - "env var %q is set to empty string, which is not an int. To use the default value %v, unset the env var", - varName, defaultValue) + a, err := getEnvOrDefault(varName, strconv.Itoa(defaultValue)) + if err != nil { + return 0, err } i, err := strconv.Atoi(a) if err != nil { @@ -286,3 +298,24 @@ func getEnvIntOrDefault(varName string, defaultValue int) (int, error) { } return i, nil } + +// getEnvOrDefault find an environment variable with name varName and returns its value. If the env +// var is not set, returns defaultValue. +// +// If the env var is found and its value is empty string, returns an error. This can't happen on +// Windows because setting an env var to empty string deletes it. However, on Linux, it is possible. +// It's likely a mistake, so we let the user know what happened with an error. For example, the env +// var might be empty string because it was set by "example=$(someCommand)" and someCommand +// encountered an error and didn't send any output to stdout. +func getEnvOrDefault(varName, defaultValue string) (string, error) { + v, ok := os.LookupEnv(varName) + if !ok { + return defaultValue, nil + } + if v == "" { + return "", fmt.Errorf( + "env var %q is empty, not a valid string. To use the default string %v, unset the env var", + varName, defaultValue) + } + return v, nil +} diff --git a/eng/_core/cmd/pack/pack.go b/eng/_core/cmd/pack/pack.go index 0fc9cdbb103..ed106033aa3 100644 --- a/eng/_core/cmd/pack/pack.go +++ b/eng/_core/cmd/pack/pack.go @@ -16,6 +16,11 @@ import ( const description = ` This command packs a built Go directory into an archive file and produces a checksum file for the archive. It filters out the files that aren't necessary. + +Pack does not support packing cross-compiled Go directories. Use the "-pack" +argument with the build command for this, instead. The Pack command is intended +to repackage an extracted Go archive that was already in the correct format. +To re-run pack quickly on a cross-compiled build, use "build -skipbuild -pack". ` func main() { diff --git a/eng/_util/go.mod b/eng/_util/go.mod index dc95b46f4ab..8786d747cd2 100644 --- a/eng/_util/go.mod +++ b/eng/_util/go.mod @@ -7,6 +7,6 @@ module github.com/microsoft/go/_util go 1.16 require ( - github.com/microsoft/go-infra v0.0.0-20220209233812-d528ea99adb8 + github.com/microsoft/go-infra v0.0.0-20220419195018-e437e0d7a6f9 gotest.tools/gotestsum v1.6.5-0.20210515201937-ecb7c6956f6d ) diff --git a/eng/_util/go.sum b/eng/_util/go.sum index fa5aa4d8ca1..4963f26cc4f 100644 --- a/eng/_util/go.sum +++ b/eng/_util/go.sum @@ -4,6 +4,8 @@ github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg= github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= +github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -15,8 +17,8 @@ github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/microsoft/go-infra v0.0.0-20220209233812-d528ea99adb8 h1:2aNRJlGG6hOhHsQV3/5+udsetpNT24/5eeJBMWOmjDY= -github.com/microsoft/go-infra v0.0.0-20220209233812-d528ea99adb8/go.mod h1:3IVGTm7qFJldQHximiWLg2kYfmugjZMGNHnvUo5Mo5M= +github.com/microsoft/go-infra v0.0.0-20220419195018-e437e0d7a6f9 h1:TztudEX3sCZvuB9ZrKclZtxNRRE87GF5v7/U7DsLOVo= +github.com/microsoft/go-infra v0.0.0-20220419195018-e437e0d7a6f9/go.mod h1:eGPzRx36eMvtr8J3LLHYyP720NNE6kWLn78BcK/APOs= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= diff --git a/eng/pipeline/jobs/builders-to-jobs.yml b/eng/pipeline/jobs/builders-to-jobs.yml index 05d7a751e9a..fe2eef7a07f 100644 --- a/eng/pipeline/jobs/builders-to-jobs.yml +++ b/eng/pipeline/jobs/builders-to-jobs.yml @@ -5,7 +5,7 @@ # This template expands a list of builders into a list of jobs. parameters: - # [] of { id, os, arch, config, distro? } + # [] of { id, os, arch, hostarch, config, distro? } builders: [] # If true, include a signing job that depends on all 'buildandpack' builder jobs finishing. This # lets us start the lengthy tasks of signing and testing in parallel. diff --git a/eng/pipeline/jobs/go-builder-matrix-jobs.yml b/eng/pipeline/jobs/go-builder-matrix-jobs.yml index e7e600aa48f..c8414a75e1b 100644 --- a/eng/pipeline/jobs/go-builder-matrix-jobs.yml +++ b/eng/pipeline/jobs/go-builder-matrix-jobs.yml @@ -27,6 +27,7 @@ jobs: - { os: windows, arch: amd64, config: buildandpack } - { os: windows, arch: amd64, config: devscript } - { os: windows, arch: amd64, config: test } + - { os: linux, arch: arm, hostArch: amd64, config: buildandpack } # Only build arm64 if we're running a signed (internal, rolling) build. Avoid contention # with other projects' builds that use the same limited-capacity pool of arm64 agents. - ${{ if eq(parameters.sign, true) }}: diff --git a/eng/pipeline/jobs/run-job.yml b/eng/pipeline/jobs/run-job.yml index 4fa209632ce..a082ecede6e 100644 --- a/eng/pipeline/jobs/run-job.yml +++ b/eng/pipeline/jobs/run-job.yml @@ -5,7 +5,7 @@ # This job runs a builder for any OS. parameters: - # { id, os, arch, config, distro? } + # { id, os, arch, hostArch, config, distro? } builder: {} createSourceArchive: false @@ -19,7 +19,7 @@ jobs: vmImage: windows-2019 ${{ if eq(parameters.builder.os, 'linux') }}: - ${{ if eq(parameters.builder.arch, 'amd64') }}: + ${{ if eq(parameters.builder.hostArch, 'amd64') }}: pool: # The VM image of the Docker host. This doesn't need to match the container image, but it may # give slightly better coverage by matching the kernel version. @@ -30,7 +30,7 @@ jobs: container: golangpublicimages.azurecr.io/go-infra-images/prereqs:cbl-mariner-1.0.20211027-20211201-0cccc22 ${{ if eq(parameters.builder.distro, 'ubuntu') }}: container: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-20211022152710-047508b - ${{ if eq(parameters.builder.arch, 'arm64') }}: + ${{ if eq(parameters.builder.hostArch, 'arm64') }}: pool: name: Docker-Linux-Arm-Internal ${{ if not(parameters.builder.distro) }}: @@ -86,6 +86,13 @@ jobs: eng/run.ps1 submodule-refresh displayName: Apply patches + - ${{ if ne(parameters.builder.hostArch, parameters.builder.arch) }}: + - pwsh: Write-Host "##vso[task.setvariable variable=GOARCH]${{ parameters.builder.arch }}" + displayName: Set GOARCH for cross-compile + - ${{ if eq(parameters.builder.arch, 'arm') }}: + - pwsh: Write-Host "##vso[task.setvariable variable=GOARM]6" + displayName: Set GOARM for cross-compile + # Use build script directly for "buildandpack". If we used run-builder, we would need to # download its external module dependencies. - ${{ if eq(parameters.builder.config, 'buildandpack' ) }}: diff --git a/eng/pipeline/jobs/shorthand-builders-to-builders.yml b/eng/pipeline/jobs/shorthand-builders-to-builders.yml index c1f7fe7baf6..02879766776 100644 --- a/eng/pipeline/jobs/shorthand-builders-to-builders.yml +++ b/eng/pipeline/jobs/shorthand-builders-to-builders.yml @@ -11,11 +11,12 @@ # to be used by template expressions, as of writing. parameters: - # [] of { os, arch, config, distro? } + # [] of { os, arch, hostArch, config, distro? } + # If hostArch is not defined, defaults to the arch value. shorthandBuilders: [] # The inner jobs template to pass the filed-out builders into. # - # It should accept parameter "builders", [] of { id, os, arch, config, distro? } + # It should accept parameter "builders", [] of { id, os, arch, hostArch, config, distro? } jobsTemplate: "" jobsParameters: {} @@ -30,5 +31,7 @@ jobs: id: ${{ builder.os }}_${{ builder.distro }}_${{ builder.arch }}_${{ builder.config }} ${{ if not(builder.distro) }}: id: ${{ builder.os }}_${{ builder.arch }}_${{ builder.config }} + ${{ if not(builder.hostArch) }}: + hostArch: ${{ builder.arch }} diff --git a/eng/run.ps1 b/eng/run.ps1 index 237ab6cc176..a12878de720 100644 --- a/eng/run.ps1 +++ b/eng/run.ps1 @@ -99,12 +99,18 @@ try { # Use a module-local path so Go resolves imports correctly. $module_local_script_path = Join-Path "." "cmd" "$tool" - Write-Host "In '$tool_module', building '$module_local_script_path' -> $tool_output" - & (Join-Path $stage0_goroot "bin" "go") build -o $tool_output $module_local_script_path - if ($LASTEXITCODE) { - Write-Host "Failed to build tool." - exit 1 + # The caller may have passed in GOOS/GOARCH to cross-compile Go. We can't use those values here: + # we need to be able to run the tool on the host, so we must always target the host OS/ARCH. Clear + # out the GOOS/GOARCH values (empty string) to detect host OS/ARCH automatically for the tools. + Invoke-CrossGoBlock "" "" { + Write-Host "In '$tool_module', building '$module_local_script_path' -> $tool_output" + & (Join-Path $stage0_goroot "bin" "go") build -o $tool_output $module_local_script_path + if ($LASTEXITCODE) { + Write-Host "Failed to build tool." + exit 1 + } } + Write-Host "Building done." } finally { Pop-Location diff --git a/eng/utilities.ps1 b/eng/utilities.ps1 index 868b6d6b913..baff8efde17 100644 --- a/eng/utilities.ps1 +++ b/eng/utilities.ps1 @@ -24,17 +24,17 @@ function Get-Stage0GoRoot() { # pre-installed. This CI script installs a consistent, official version of Go to a directory in # $HOME to handle this. This also makes it easier to locally repro issues in CI that involve a # specific version of Go. The downloaded copy of Go is called the "stage 0" version. - $stage0_go_version = '1.17.8' + $stage0_go_version = '1.18' $proc_arch = ([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture).ToString().ToLowerInvariant() if ($IsWindows) { switch ($proc_arch) { 'x64' { - $stage0_go_sha256 = '85ccf2608dca6ea9a46b6538c9e75e7cf2aebdf502379843b248e26b8bb110be' + $stage0_go_sha256 = '65c5c0c709a7ca1b357091b10b795b439d8b50e579d3893edab4c7e9b384f435' $stage0_go_suffix = 'windows-amd64.zip' } 'arm64' { - $stage0_go_sha256 = '4a0d960f5c0cbff1edaf54f333cf857a2779f6ae4c8e759b7872b44fde5ae43f' + $stage0_go_sha256 = '1c454eb60c64d481965a165c623ff1ed6cf32d68c6b31f36069c8768d908f093' $stage0_go_suffix = 'windows-arm64.zip' } Default { throw "Unable to match Windows '$proc_arch' to an architecture supported by the Microsoft scripts to build Go." } @@ -42,11 +42,11 @@ function Get-Stage0GoRoot() { } elseif ($IsLinux) { switch ($proc_arch) { 'x64' { - $stage0_go_sha256 = '980e65a863377e69fd9b67df9d8395fd8e93858e7a24c9f55803421e453f4f99' + $stage0_go_sha256 = 'e85278e98f57cdb150fe8409e6e5df5343ecb13cebf03a5d5ff12bd55a80264f' $stage0_go_suffix = 'linux-amd64.tar.gz' } 'arm64' { - $stage0_go_sha256 = '57a9171682e297df1a5bd287be056ed0280195ad079af90af16dcad4f64710cb' + $stage0_go_sha256 = '7ac7b396a691e588c5fb57687759e6c4db84a2a3bbebb0765f4b38e5b1c5b00e' $stage0_go_suffix = 'linux-arm64.tar.gz' } Default { throw "Unable to match Linux '$proc_arch' to an architecture supported by the Microsoft scripts to build Go." } @@ -126,6 +126,20 @@ function Invoke-WithRetry([ScriptBlock]$ScriptBlock, [int]$MaxAttempts = 3, [int } } +function Invoke-CrossGoBlock([string] $GOOS, [string] $GOARCH, [ScriptBlock] $block) { + $oldGOOS = $env:GOOS + $oldGOARCH = $env:GOARCH + + try { + $env:GOOS = $GOOS + $env:GOARCH = $GOARCH + & $block + } finally { + $env:GOOS = $oldGOOS + $env:GOARCH = $oldGOARCH + } +} + # Utility method to unzip a file to a specific path. function Extract-Zip([string] $file, [string] $destination) { Add-Type -AssemblyName System.IO.Compression.FileSystem From 8db55fd48a6b69ff31c00bf6034f1b0a0b64979c Mon Sep 17 00:00:00 2001 From: microsoft-golang-bot Date: Fri, 6 May 2022 16:02:08 +0000 Subject: [PATCH 37/47] Update submodule to latest release-branch.go1.17 (2150be1a): [release-branch.go1.17] syscall: relax output check in TestGroupCleanupUserNamespace --- go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go b/go index 346b18ee9d1..2150be1a9be 160000 --- a/go +++ b/go @@ -1 +1 @@ -Subproject commit 346b18ee9d15410ab08dd583787c64dbed0666d2 +Subproject commit 2150be1a9be0a333dbdb9759d8dd98905d987828 From 67f2af941d7a42db2ed4e07548b1859ff60e079e Mon Sep 17 00:00:00 2001 From: microsoft-golang-bot Date: Mon, 9 May 2022 16:02:07 +0000 Subject: [PATCH 38/47] Update submodule to latest release-branch.go1.17 (78992411): [release-branch.go1.17] runtime: don't block preemption signal in new M's or ensureSigM --- go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go b/go index 2150be1a9be..78992411ded 160000 --- a/go +++ b/go @@ -1 +1 @@ -Subproject commit 2150be1a9be0a333dbdb9759d8dd98905d987828 +Subproject commit 78992411ded8288ed32790ece2b998f0a6c7d997 From 989e3edbe014b251454e6174da39af88e153c211 Mon Sep 17 00:00:00 2001 From: microsoft-golang-bot Date: Tue, 10 May 2022 20:43:30 +0000 Subject: [PATCH 39/47] Update submodule to latest release-branch.go1.17 (085c61ae): [release-branch.go1.17] go1.17.10 --- go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go b/go index 78992411ded..085c61ae517 160000 --- a/go +++ b/go @@ -1 +1 @@ -Subproject commit 78992411ded8288ed32790ece2b998f0a6c7d997 +Subproject commit 085c61ae517110168841be0afeb8f883d66fe95a From 69ec4929ee55f688fe72e92259249a80823af9f1 Mon Sep 17 00:00:00 2001 From: Davis Goodin Date: Tue, 10 May 2022 16:14:00 -0500 Subject: [PATCH 40/47] Resolve patch conflicts: neighboring line changes --- .../0002-net-Skip-TestDialCancel-on-linux-arm64.patch | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/patches/0002-net-Skip-TestDialCancel-on-linux-arm64.patch b/patches/0002-net-Skip-TestDialCancel-on-linux-arm64.patch index a2692bd508c..8096d0b6c92 100644 --- a/patches/0002-net-Skip-TestDialCancel-on-linux-arm64.patch +++ b/patches/0002-net-Skip-TestDialCancel-on-linux-arm64.patch @@ -9,10 +9,10 @@ The test is flaky on our linux-arm64 builder and gets "network is unreachable". 1 file changed, 4 insertions(+) diff --git a/src/net/dial_test.go b/src/net/dial_test.go -index b9aead0371..f4f383a365 100644 +index 8f6dd714db..fd1d111788 100644 --- a/src/net/dial_test.go +++ b/src/net/dial_test.go -@@ -758,6 +758,10 @@ func TestDialerKeepAlive(t *testing.T) { +@@ -751,6 +751,10 @@ func TestDialerKeepAlive(t *testing.T) { func TestDialCancel(t *testing.T) { mustHaveExternalNetwork(t) @@ -20,6 +20,6 @@ index b9aead0371..f4f383a365 100644 + t.Skip("skipping on linux-arm64-*; incompatible network config? issue 37330") + } + - blackholeIPPort := JoinHostPort(slowDst4, "1234") - if !supportsIPv4() { - blackholeIPPort = JoinHostPort(slowDst6, "1234") + if strings.HasPrefix(testenv.Builder(), "darwin-arm64") { + // The darwin-arm64 machines run in an environment that's not + // compatible with this test. From 82bc6f9fb22c91787b359d8f1f53268cbbdfcf65 Mon Sep 17 00:00:00 2001 From: microsoft-golang-bot Date: Tue, 10 May 2022 22:11:49 +0000 Subject: [PATCH 41/47] Update submodule to latest dev.boringcrypto.go1.17 (6b07de79): [dev.boringcrypto.go1.17] all: merge go1.17.10 into dev.boringcrypto.go1.17 --- go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go b/go index ed86dfc4e44..6b07de790c0 160000 --- a/go +++ b/go @@ -1 +1 @@ -Subproject commit ed86dfc4e441ee7597586dd858fb87c987f1f3c8 +Subproject commit 6b07de790c08967d0dbe3a36ec86f3d13e1cfcbd From be67047c08eb8dad28506d00f94ec90c1c192253 Mon Sep 17 00:00:00 2001 From: Davis Goodin Date: Tue, 10 May 2022 17:27:06 -0500 Subject: [PATCH 42/47] Update VERSION to 1.17.10 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 699d953a7f8..d1ab52a8a26 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -go1.17.9 \ No newline at end of file +go1.17.10 \ No newline at end of file From a2cff57d8696016ac7855d796f0ff6a5cb984125 Mon Sep 17 00:00:00 2001 From: qmuntal Date: Thu, 12 May 2022 10:56:18 +0200 Subject: [PATCH 43/47] upgrade go-crypto-openssl --- patches/0100-Add-OpenSSL-crypto-module.patch | 10 +- .../0102-Vendor-OpenSSL-crypto-library.patch | 3248 ++++++++--------- 2 files changed, 1586 insertions(+), 1672 deletions(-) diff --git a/patches/0100-Add-OpenSSL-crypto-module.patch b/patches/0100-Add-OpenSSL-crypto-module.patch index 98649c184a2..9485a180fd3 100644 --- a/patches/0100-Add-OpenSSL-crypto-module.patch +++ b/patches/0100-Add-OpenSSL-crypto-module.patch @@ -339,24 +339,24 @@ index 0000000000..9fa156894a +var VerifyRSAPKCS1v15 = openssl.VerifyRSAPKCS1v15 +var VerifyRSAPSS = openssl.VerifyRSAPSS diff --git a/src/go.mod b/src/go.mod -index af435fa335..b251be6e34 100644 +index af435fa3351..93cf5b8f74e 100644 --- a/src/go.mod +++ b/src/go.mod @@ -3,6 +3,7 @@ module std go 1.17 require ( -+ github.com/microsoft/go-crypto-openssl v0.0.0-20220124101237-183c44c3cf71 ++ github.com/microsoft/go-crypto-openssl v0.0.0-20220420170843-a127057fb794 golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e golang.org/x/net v0.0.0-20220106012031-21a9c9cfe9c3 ) diff --git a/src/go.sum b/src/go.sum -index 3e3fa7989f..8ab0218786 100644 +index 3e3fa7989fa..3f5fa23dbb9 100644 --- a/src/go.sum +++ b/src/go.sum @@ -1,3 +1,5 @@ -+github.com/microsoft/go-crypto-openssl v0.0.0-20220124101237-183c44c3cf71 h1:NO1CTk7yHEtgUjfV7eqU4+sRe8OHRqZAznWe8WpVj7I= -+github.com/microsoft/go-crypto-openssl v0.0.0-20220124101237-183c44c3cf71/go.mod h1:rC+rtBU3m60UCQifBmpWII0VETfu78w6YGZQvVc0rd4= ++github.com/microsoft/go-crypto-openssl v0.0.0-20220420170843-a127057fb794 h1:wKgYWu1182SANsEy946ijVOck8VGbSMXuvg5YtDJdM8= ++github.com/microsoft/go-crypto-openssl v0.0.0-20220420170843-a127057fb794/go.mod h1:rC+rtBU3m60UCQifBmpWII0VETfu78w6YGZQvVc0rd4= golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e h1:1SzTfNOXwIS2oWiMF+6qu0OUDKb0dauo6MoDUQyu+yU= golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= diff --git a/patches/0102-Vendor-OpenSSL-crypto-library.patch b/patches/0102-Vendor-OpenSSL-crypto-library.patch index 080662cfe23..16b6b40073b 100644 --- a/patches/0102-Vendor-OpenSSL-crypto-library.patch +++ b/patches/0102-Vendor-OpenSSL-crypto-library.patch @@ -6,27 +6,25 @@ Subject: [PATCH] Vendor OpenSSL crypto library To reproduce, run 'go mod vendor' in 'go/src'. --- .../microsoft/go-crypto-openssl/LICENSE | 21 + - .../go-crypto-openssl/openssl/aes.go | 487 ++++++++++++++++++ - .../go-crypto-openssl/openssl/apibridge_1_1.c | 291 +++++++++++ - .../go-crypto-openssl/openssl/apibridge_1_1.h | 28 + - .../go-crypto-openssl/openssl/ecdsa.go | 199 +++++++ - .../go-crypto-openssl/openssl/goopenssl.c | 199 +++++++ - .../go-crypto-openssl/openssl/goopenssl.h | 240 +++++++++ - .../go-crypto-openssl/openssl/hmac.go | 162 ++++++ + .../go-crypto-openssl/openssl/aes.go | 466 +++++++++++++++ + .../go-crypto-openssl/openssl/ecdsa.go | 214 +++++++ + .../go-crypto-openssl/openssl/evpkey.go | 279 +++++++++ + .../go-crypto-openssl/openssl/goopenssl.c | 153 +++++ + .../go-crypto-openssl/openssl/goopenssl.h | 127 +++++ + .../go-crypto-openssl/openssl/hmac.go | 147 +++++ .../openssl/internal/subtle/aliasing.go | 32 ++ - .../go-crypto-openssl/openssl/openssl.go | 107 ++++ - .../go-crypto-openssl/openssl/openssl_funcs.h | 215 ++++++++ + .../go-crypto-openssl/openssl/openssl.go | 260 +++++++++ + .../go-crypto-openssl/openssl/openssl_funcs.h | 242 ++++++++ .../openssl/openssl_lock_setup.c | 53 ++ .../go-crypto-openssl/openssl/rand.go | 24 + - .../go-crypto-openssl/openssl/rsa.go | 397 ++++++++++++++ - .../go-crypto-openssl/openssl/sha.go | 477 +++++++++++++++++ + .../go-crypto-openssl/openssl/rsa.go | 303 ++++++++++ + .../go-crypto-openssl/openssl/sha.go | 534 ++++++++++++++++++ src/vendor/modules.txt | 4 + - 16 files changed, 2936 insertions(+) + 15 files changed, 2859 insertions(+) create mode 100644 src/vendor/github.com/microsoft/go-crypto-openssl/LICENSE create mode 100644 src/vendor/github.com/microsoft/go-crypto-openssl/openssl/aes.go - create mode 100644 src/vendor/github.com/microsoft/go-crypto-openssl/openssl/apibridge_1_1.c - create mode 100644 src/vendor/github.com/microsoft/go-crypto-openssl/openssl/apibridge_1_1.h create mode 100644 src/vendor/github.com/microsoft/go-crypto-openssl/openssl/ecdsa.go + create mode 100644 src/vendor/github.com/microsoft/go-crypto-openssl/openssl/evpkey.go create mode 100644 src/vendor/github.com/microsoft/go-crypto-openssl/openssl/goopenssl.c create mode 100644 src/vendor/github.com/microsoft/go-crypto-openssl/openssl/goopenssl.h create mode 100644 src/vendor/github.com/microsoft/go-crypto-openssl/openssl/hmac.go @@ -40,7 +38,7 @@ To reproduce, run 'go mod vendor' in 'go/src'. diff --git a/src/vendor/github.com/microsoft/go-crypto-openssl/LICENSE b/src/vendor/github.com/microsoft/go-crypto-openssl/LICENSE new file mode 100644 -index 0000000000..9e841e7a26 +index 00000000000..9e841e7a26e --- /dev/null +++ b/src/vendor/github.com/microsoft/go-crypto-openssl/LICENSE @@ -0,0 +1,21 @@ @@ -67,10 +65,10 @@ index 0000000000..9e841e7a26 + SOFTWARE diff --git a/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/aes.go b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/aes.go new file mode 100644 -index 0000000000..7b743f67fb +index 00000000000..3177c0d37c8 --- /dev/null +++ b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/aes.go -@@ -0,0 +1,487 @@ +@@ -0,0 +1,466 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + @@ -101,9 +99,9 @@ index 0000000000..7b743f67fb + +type aesCipher struct { + key []byte -+ enc_ctx *C.EVP_CIPHER_CTX -+ dec_ctx *C.EVP_CIPHER_CTX -+ cipher *C.EVP_CIPHER ++ enc_ctx C.GO_EVP_CIPHER_CTX_PTR ++ dec_ctx C.GO_EVP_CIPHER_CTX_PTR ++ cipher C.GO_EVP_CIPHER_PTR +} + +type extraModes interface { @@ -125,11 +123,11 @@ index 0000000000..7b743f67fb + + switch len(c.key) * 8 { + case 128: -+ c.cipher = C._goboringcrypto_EVP_aes_128_ecb() ++ c.cipher = C.go_openssl_EVP_aes_128_ecb() + case 192: -+ c.cipher = C._goboringcrypto_EVP_aes_192_ecb() ++ c.cipher = C.go_openssl_EVP_aes_192_ecb() + case 256: -+ c.cipher = C._goboringcrypto_EVP_aes_256_ecb() ++ c.cipher = C.go_openssl_EVP_aes_256_ecb() + default: + return nil, errors.New("crypto/cipher: Invalid key size") + } @@ -141,10 +139,10 @@ index 0000000000..7b743f67fb + +func (c *aesCipher) finalize() { + if c.enc_ctx != nil { -+ C._goboringcrypto_EVP_CIPHER_CTX_free(c.enc_ctx) ++ C.go_openssl_EVP_CIPHER_CTX_free(c.enc_ctx) + } + if c.dec_ctx != nil { -+ C._goboringcrypto_EVP_CIPHER_CTX_free(c.dec_ctx) ++ C.go_openssl_EVP_CIPHER_CTX_free(c.dec_ctx) + } +} + @@ -169,8 +167,7 @@ index 0000000000..7b743f67fb + } + } + -+ outlen := C.int(0) -+ C._goboringcrypto_EVP_CipherUpdate(c.enc_ctx, (*C.uchar)(unsafe.Pointer(&dst[0])), &outlen, (*C.uchar)(unsafe.Pointer(&src[0])), C.int(aesBlockSize)) ++ C.go_openssl_EVP_EncryptUpdate_wrapper(c.enc_ctx, base(dst), base(src), aesBlockSize) + runtime.KeepAlive(c) +} + @@ -192,13 +189,12 @@ index 0000000000..7b743f67fb + } + } + -+ outlen := C.int(0) -+ C._goboringcrypto_EVP_CipherUpdate(c.dec_ctx, (*C.uchar)(unsafe.Pointer(&dst[0])), &outlen, (*C.uchar)(unsafe.Pointer(&src[0])), C.int(aesBlockSize)) ++ C.go_openssl_EVP_DecryptUpdate_wrapper(c.dec_ctx, base(dst), base(src), aesBlockSize) + runtime.KeepAlive(c) +} + +type aesCBC struct { -+ ctx *C.EVP_CIPHER_CTX ++ ctx C.GO_EVP_CIPHER_CTX_PTR +} + +func (x *aesCBC) BlockSize() int { return aesBlockSize } @@ -214,12 +210,7 @@ index 0000000000..7b743f67fb + panic("crypto/cipher: output smaller than input") + } + if len(src) > 0 { -+ outlen := C.int(0) -+ if C._goboringcrypto_EVP_CipherUpdate( -+ x.ctx, -+ base(dst), &outlen, -+ base(src), C.int(len(src)), -+ ) != C.int(1) { ++ if C.go_openssl_EVP_CipherUpdate_wrapper(x.ctx, base(dst), base(src), C.int(len(src))) != 1 { + panic("crypto/cipher: CipherUpdate failed") + } + runtime.KeepAlive(x) @@ -230,7 +221,7 @@ index 0000000000..7b743f67fb + if len(iv) != aesBlockSize { + panic("cipher: incorrect length IV") + } -+ if C.int(1) != C._goboringcrypto_EVP_CipherInit_ex(x.ctx, nil, nil, nil, (*C.uchar)(unsafe.Pointer(&iv[0])), -1) { ++ if C.go_openssl_EVP_CipherInit_ex(x.ctx, nil, nil, nil, base(iv), -1) != 1 { + panic("cipher: unable to initialize EVP cipher ctx") + } +} @@ -238,16 +229,16 @@ index 0000000000..7b743f67fb +func (c *aesCipher) NewCBCEncrypter(iv []byte) cipher.BlockMode { + x := new(aesCBC) + -+ var cipher *C.EVP_CIPHER ++ var cipher C.GO_EVP_CIPHER_PTR + switch len(c.key) * 8 { + case 128: -+ cipher = C._goboringcrypto_EVP_aes_128_cbc() ++ cipher = C.go_openssl_EVP_aes_128_cbc() + case 192: -+ cipher = C._goboringcrypto_EVP_aes_192_cbc() ++ cipher = C.go_openssl_EVP_aes_192_cbc() + case 256: -+ cipher = C._goboringcrypto_EVP_aes_256_cbc() ++ cipher = C.go_openssl_EVP_aes_256_cbc() + default: -+ panic("crypto/boring: unsupported key length") ++ panic("openssl: unsupported key length") + } + var err error + x.ctx, err = newCipherCtx(cipher, C.GO_AES_ENCRYPT, c.key, iv) @@ -261,22 +252,22 @@ index 0000000000..7b743f67fb +} + +func (c *aesCBC) finalize() { -+ C._goboringcrypto_EVP_CIPHER_CTX_free(c.ctx) ++ C.go_openssl_EVP_CIPHER_CTX_free(c.ctx) +} + +func (c *aesCipher) NewCBCDecrypter(iv []byte) cipher.BlockMode { + x := new(aesCBC) + -+ var cipher *C.EVP_CIPHER ++ var cipher C.GO_EVP_CIPHER_PTR + switch len(c.key) * 8 { + case 128: -+ cipher = C._goboringcrypto_EVP_aes_128_cbc() ++ cipher = C.go_openssl_EVP_aes_128_cbc() + case 192: -+ cipher = C._goboringcrypto_EVP_aes_192_cbc() ++ cipher = C.go_openssl_EVP_aes_192_cbc() + case 256: -+ cipher = C._goboringcrypto_EVP_aes_256_cbc() ++ cipher = C.go_openssl_EVP_aes_256_cbc() + default: -+ panic("crypto/boring: unsupported key length") ++ panic("openssl: unsupported key length") + } + + var err error @@ -284,7 +275,7 @@ index 0000000000..7b743f67fb + if err != nil { + panic(err) + } -+ if C.int(1) != C._goboringcrypto_EVP_CIPHER_CTX_set_padding(x.ctx, 0) { ++ if C.go_openssl_EVP_CIPHER_CTX_set_padding(x.ctx, 0) != 1 { + panic("cipher: unable to set padding") + } + @@ -293,7 +284,7 @@ index 0000000000..7b743f67fb +} + +type aesCTR struct { -+ ctx *C.EVP_CIPHER_CTX ++ ctx C.GO_EVP_CIPHER_CTX_PTR +} + +func (x *aesCTR) XORKeyStream(dst, src []byte) { @@ -306,27 +297,23 @@ index 0000000000..7b743f67fb + if len(src) == 0 { + return + } -+ C._goboringcrypto_EVP_AES_ctr128_enc( -+ x.ctx, -+ (*C.uint8_t)(unsafe.Pointer(&src[0])), -+ (*C.uint8_t)(unsafe.Pointer(&dst[0])), -+ C.size_t(len(src))) ++ C.go_openssl_EVP_EncryptUpdate_wrapper(x.ctx, base(dst), base(src), C.int(len(src))) + runtime.KeepAlive(x) +} + +func (c *aesCipher) NewCTR(iv []byte) cipher.Stream { + x := new(aesCTR) + -+ var cipher *C.EVP_CIPHER ++ var cipher C.GO_EVP_CIPHER_PTR + switch len(c.key) * 8 { + case 128: -+ cipher = C._goboringcrypto_EVP_aes_128_ctr() ++ cipher = C.go_openssl_EVP_aes_128_ctr() + case 192: -+ cipher = C._goboringcrypto_EVP_aes_192_ctr() ++ cipher = C.go_openssl_EVP_aes_192_ctr() + case 256: -+ cipher = C._goboringcrypto_EVP_aes_256_ctr() ++ cipher = C.go_openssl_EVP_aes_256_ctr() + default: -+ panic("crypto/boring: unsupported key length") ++ panic("openssl: unsupported key length") + } + var err error + x.ctx, err = newCipherCtx(cipher, C.GO_AES_ENCRYPT, c.key, iv) @@ -340,19 +327,20 @@ index 0000000000..7b743f67fb +} + +func (c *aesCTR) finalize() { -+ C._goboringcrypto_EVP_CIPHER_CTX_free(c.ctx) ++ C.go_openssl_EVP_CIPHER_CTX_free(c.ctx) +} + +type aesGCM struct { -+ key []byte -+ tls bool -+ cipher *C.EVP_CIPHER ++ ctx C.GO_EVP_CIPHER_CTX_PTR ++ tls bool ++ minNextNonce uint64 +} + +const ( -+ gcmBlockSize = 16 + gcmTagSize = 16 + gcmStandardNonceSize = 12 ++ gcmTlsAddSize = 13 ++ gcmTlsFixedNonceSize = 4 +) + +type aesNonceSizeError int @@ -384,21 +372,30 @@ index 0000000000..7b743f67fb +} + +func (c *aesCipher) newGCM(tls bool) (cipher.AEAD, error) { -+ g := &aesGCM{key: c.key, tls: tls} ++ var cipher C.GO_EVP_CIPHER_PTR + switch len(c.key) * 8 { + case 128: -+ g.cipher = C._goboringcrypto_EVP_aes_128_gcm() ++ cipher = C.go_openssl_EVP_aes_128_gcm() + case 192: -+ g.cipher = C._goboringcrypto_EVP_aes_192_gcm() ++ cipher = C.go_openssl_EVP_aes_192_gcm() + case 256: -+ g.cipher = C._goboringcrypto_EVP_aes_256_gcm() ++ cipher = C.go_openssl_EVP_aes_256_gcm() + default: -+ panic("crypto/boring: unsupported key length") ++ panic("openssl: unsupported key length") + } -+ ++ ctx, err := newCipherCtx(cipher, -1, c.key, nil) ++ if err != nil { ++ return nil, err ++ } ++ g := &aesGCM{ctx: ctx, tls: tls} ++ runtime.SetFinalizer(g, (*aesGCM).finalize) + return g, nil +} + ++func (g *aesGCM) finalize() { ++ C.go_openssl_EVP_CIPHER_CTX_free(g.ctx) ++} ++ +func (g *aesGCM) NonceSize() int { + return gcmStandardNonceSize +} @@ -409,11 +406,11 @@ index 0000000000..7b743f67fb + +// base returns the address of the underlying array in b, +// being careful not to panic when b has zero length. -+func base(b []byte) *C.uint8_t { ++func base(b []byte) *C.uchar { + if len(b) == 0 { + return nil + } -+ return (*C.uint8_t)(unsafe.Pointer(&b[0])) ++ return (*C.uchar)(unsafe.Pointer(&b[0])) +} + +func (g *aesGCM) Seal(dst, nonce, plaintext, additionalData []byte) []byte { @@ -426,6 +423,25 @@ index 0000000000..7b743f67fb + if len(dst)+len(plaintext)+gcmTagSize < len(dst) { + panic("cipher: message too large for buffer") + } ++ if g.tls { ++ if len(additionalData) != gcmTlsAddSize { ++ panic("cipher: incorrect additional data length given to GCM TLS") ++ } ++ // BoringCrypto enforces strictly monotonically increasing explicit nonces ++ // and to fail after 2^64 - 1 keys as per FIPS 140-2 IG A.5, ++ // but OpenSSL does not perform this check, so it is implemented here. ++ const maxUint64 = 1<<64 - 1 ++ counter := bigUint64(nonce[gcmTlsFixedNonceSize:]) ++ if counter == maxUint64 { ++ panic("cipher: nonce counter must be less than 2^64 - 1") ++ } ++ if counter < g.minNextNonce { ++ panic("cipher: nonce counter must be strictly monotonically increasing") ++ } ++ defer func() { ++ g.minNextNonce = counter + 1 ++ }() ++ } + + // Make room in dst to append plaintext+overhead. + ret, out := sliceForAppend(dst, len(plaintext)+gcmTagSize) @@ -435,38 +451,20 @@ index 0000000000..7b743f67fb + panic("cipher: invalid buffer overlap") + } + -+ ctx, err := newCipherCtx(g.cipher, C.GO_AES_ENCRYPT, g.key, nonce) -+ if err != nil { -+ panic(err) -+ } -+ defer C._goboringcrypto_EVP_CIPHER_CTX_free(ctx) -+ -+ var encLen C.int + // Encrypt additional data. -+ if C._goboringcrypto_EVP_EncryptUpdate(ctx, nil, &encLen, base(additionalData), C.int(len(additionalData))) != C.int(1) { -+ panic(fail("EVP_CIPHER_CTX_seal")) -+ } -+ -+ // Encrypt plain text. -+ if C._goboringcrypto_EVP_EncryptUpdate(ctx, base(out), &encLen, base(plaintext), C.int(len(plaintext))) != C.int(1) { -+ panic(fail("EVP_CIPHER_CTX_seal")) -+ } -+ -+ // Finalise encryption. -+ var encFinalLen C.int -+ if C._goboringcrypto_EVP_EncryptFinal_ex(ctx, base(out[encLen:]), &encFinalLen) != C.int(1) { -+ panic(fail("EVP_CIPHER_CTX_seal")) -+ } -+ encLen += encFinalLen ++ // When sealing a TLS payload, OpenSSL app sets the additional data using ++ // 'EVP_CIPHER_CTX_ctrl(g.ctx, C.EVP_CTRL_AEAD_TLS1_AAD, C.EVP_AEAD_TLS1_AAD_LEN, base(additionalData))'. ++ // This makes the explicit nonce component to monotonically increase on every Seal operation without ++ // relying in the explicit nonce being securely set externally, ++ // and it also gives some interesting speed gains. ++ // Unfortunately we can't use it because Go expects AEAD.Seal to honor the provided nonce. ++ if C.go_openssl_EVP_CIPHER_CTX_seal_wrapper(g.ctx, base(out), base(nonce), ++ base(plaintext), C.int(len(plaintext)), ++ base(additionalData), C.int(len(additionalData))) != 1 { + -+ if C._goboringcrypto_EVP_CIPHER_CTX_ctrl(ctx, C.EVP_CTRL_GCM_GET_TAG, C.int(16), unsafe.Pointer(&out[encLen])) != C.int(1) { + panic(fail("EVP_CIPHER_CTX_seal")) + } -+ encLen += 16 -+ -+ if int(encLen) != len(plaintext)+gcmTagSize { -+ panic("internal confusion about GCM tag size") -+ } ++ runtime.KeepAlive(g) + return ret +} + @@ -482,6 +480,7 @@ index 0000000000..7b743f67fb + if uint64(len(ciphertext)) > ((1<<32)-2)*aesBlockSize+gcmTagSize { + return nil, errOpen + } ++ // BoringCrypto does not do any TLS check when decrypting, neither do we. + + tag := ciphertext[len(ciphertext)-gcmTagSize:] + ciphertext = ciphertext[:len(ciphertext)-gcmTagSize] @@ -494,45 +493,16 @@ index 0000000000..7b743f67fb + panic("cipher: invalid buffer overlap") + } + -+ ctx, err := newCipherCtx(g.cipher, C.GO_AES_DECRYPT, g.key, nonce) -+ if err != nil { -+ panic(err) -+ } -+ defer C._goboringcrypto_EVP_CIPHER_CTX_free(ctx) ++ if C.go_openssl_EVP_CIPHER_CTX_open_wrapper(g.ctx, base(out), base(nonce), ++ base(ciphertext), C.int(len(ciphertext)), ++ base(additionalData), C.int(len(additionalData)), base(tag)) != 1 { + -+ clearAndFail := func(err error) ([]byte, error) { + for i := range out { + out[i] = 0 + } -+ return nil, err -+ } -+ -+ // Provide any AAD data. -+ var tmplen C.int -+ if C._goboringcrypto_EVP_DecryptUpdate(ctx, nil, &tmplen, base(additionalData), C.int(len(additionalData))) != C.int(1) { -+ return clearAndFail(errOpen) -+ } -+ -+ // Provide the message to be decrypted, and obtain the plaintext output. -+ var decLen C.int -+ if C._goboringcrypto_EVP_DecryptUpdate(ctx, base(out), &decLen, base(ciphertext), C.int(len(ciphertext))) != C.int(1) { -+ return clearAndFail(errOpen) -+ } -+ -+ // Set expected tag value. Works in OpenSSL 1.0.1d and later. -+ if C._goboringcrypto_EVP_CIPHER_CTX_ctrl(ctx, C.EVP_CTRL_GCM_SET_TAG, 16, unsafe.Pointer(&tag[0])) != C.int(1) { -+ return clearAndFail(errOpen) -+ } -+ -+ // Finalise the decryption. -+ var tagLen C.int -+ if C._goboringcrypto_EVP_DecryptFinal_ex(ctx, base(out[int(decLen):]), &tagLen) != C.int(1) { -+ return clearAndFail(errOpen) -+ } -+ -+ if int(decLen+tagLen) != len(ciphertext) { -+ panic("internal confusion about GCM tag size") ++ return nil, errOpen + } ++ runtime.KeepAlive(g) + return ret, nil +} + @@ -548,355 +518,29 @@ index 0000000000..7b743f67fb + return +} + -+func newCipherCtx(cipher *C.EVP_CIPHER, mode C.int, key, iv []byte) (*C.EVP_CIPHER_CTX, error) { -+ ctx := C._goboringcrypto_EVP_CIPHER_CTX_new() ++func newCipherCtx(cipher C.GO_EVP_CIPHER_PTR, mode C.int, key, iv []byte) (C.GO_EVP_CIPHER_CTX_PTR, error) { ++ ctx := C.go_openssl_EVP_CIPHER_CTX_new() + if ctx == nil { + return nil, fail("unable to create EVP cipher ctx") + } -+ if C.int(1) != C._goboringcrypto_EVP_CipherInit_ex(ctx, cipher, nil, base(key), base(iv), mode) { ++ if C.go_openssl_EVP_CipherInit_ex(ctx, cipher, nil, base(key), base(iv), mode) != 1 { ++ C.go_openssl_EVP_CIPHER_CTX_free(ctx) + return nil, fail("unable to initialize EVP cipher ctx") + } + return ctx, nil +} -diff --git a/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/apibridge_1_1.c b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/apibridge_1_1.c -new file mode 100644 -index 0000000000..1aa521bf29 ---- /dev/null -+++ b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/apibridge_1_1.c -@@ -0,0 +1,291 @@ -+// Copyright (c) Microsoft Corporation. -+// Licensed under the MIT License. -+ -+//go:build linux && !android -+// +build linux,!android -+ -+#include "goopenssl.h" -+#include "apibridge_1_1.h" -+ -+// Minimally define the structs from 1.0.x which went opaque in 1.1.0 for the -+// portable build building against the 1.1.x headers -+#if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_1_1_0_RTM -+// The crypto_ex_data_st struct is smaller in 1.1, which changes the packing of -+// dsa_st -+struct crypto_ex_data_10_st -+{ -+ STACK_OF(void) * sk; -+ int dummy; -+}; -+ -+struct hmac_ctx_st -+{ -+ const EVP_MD *md; -+ const void* _ignored0; -+ const void* _ignored1; -+ const void* _ignored2; -+ unsigned int _ignored3; -+ unsigned char _ignored4[128]; -+}; -+struct rsa_st -+{ -+ int _ignored0; -+ long _ignored1; -+ const void* _ignored2; -+ const void* _ignored3; -+ BIGNUM* n; -+ BIGNUM* e; -+ BIGNUM* d; -+ BIGNUM* p; -+ BIGNUM* q; -+ BIGNUM* dmp1; -+ BIGNUM* dmq1; -+ BIGNUM* iqmp; -+ struct crypto_ex_data_10_st _ignored4; -+ int _ignored5; -+ int _ignored6; -+}; -+struct evp_md_ctx_st { -+ const void *_ignored0; -+ void *_ignored1; -+ unsigned long _ignored2; -+ void *md_data; -+ void *_ignored3; -+ int (*_ignored4) (void *ctx, const void *data, size_t count); -+}; -+struct evp_md_st { -+ int type; -+ int pkey_type; -+ int md_size; -+ unsigned long flags; -+ int (*init) (EVP_MD_CTX *ctx); -+ int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count); -+ int (*final) (EVP_MD_CTX *ctx, unsigned char *md); -+ int (*copy) (EVP_MD_CTX *to, const EVP_MD_CTX *from); -+ int (*cleanup) (EVP_MD_CTX *ctx); -+ /* FIXME: prototype these some day */ -+ int (*sign) (int type, const unsigned char *m, unsigned int m_length, -+ unsigned char *sigret, unsigned int *siglen, void *key); -+ int (*verify) (int type, const unsigned char *m, unsigned int m_length, -+ const unsigned char *sigbuf, unsigned int siglen, -+ void *key); -+ int required_pkey_type[5]; /* EVP_PKEY_xxx */ -+ int block_size; -+ int ctx_size; /* how big does the ctx->md_data need to be */ -+ /* control function */ -+ int (*md_ctrl) (EVP_MD_CTX *ctx, int cmd, int p1, void *p2); -+}; -+#define EVP_PKEY_NULL_method NULL,NULL,{0,0,0,0} -+#endif -+ -+void -+local_HMAC_CTX_free(HMAC_CTX* ctx) -+{ -+ if (ctx != NULL) -+ { -+ _goboringcrypto_internal_HMAC_CTX_cleanup(ctx); -+ free(ctx); -+ } -+} -+ -+void* -+local_EVP_MD_CTX_md_data(EVP_MD_CTX *ctx) -+{ -+ return ctx->md_data; -+} -+ -+const EVP_MD* -+local_HMAC_CTX_get_md(const HMAC_CTX* ctx) -+{ -+ return ctx->md; -+} -+ -+HMAC_CTX* -+local_HMAC_CTX_new() -+{ -+ HMAC_CTX* ctx = malloc(sizeof(HMAC_CTX)); -+ if (ctx) -+ { -+ _goboringcrypto_internal_HMAC_CTX_init(ctx); -+ } -+ -+ return ctx; -+} -+ -+void -+local_HMAC_CTX_reset(HMAC_CTX* ctx) { -+ _goboringcrypto_internal_HMAC_CTX_cleanup(ctx); -+ _goboringcrypto_internal_HMAC_CTX_init(ctx); -+} -+ -+struct md5_sha1_ctx { -+ MD5_CTX md5; -+ SHA_CTX sha1; -+}; -+ -+static int -+md5_sha1_init(EVP_MD_CTX *ctx) -+{ -+ struct md5_sha1_ctx *mctx = _goboringcrypto_internal_EVP_MD_CTX_md_data(ctx); -+ if (!_goboringcrypto_internal_MD5_Init(&mctx->md5)) -+ return 0; -+ return _goboringcrypto_SHA1_Init(&mctx->sha1); -+} + -+static int md5_sha1_update(EVP_MD_CTX *ctx, const void *data, size_t count) -+{ -+ struct md5_sha1_ctx *mctx = _goboringcrypto_internal_EVP_MD_CTX_md_data(ctx); -+ if (!_goboringcrypto_internal_MD5_Update(&mctx->md5, data, count)) -+ return 0; -+ return _goboringcrypto_SHA1_Update(&mctx->sha1, data, count); -+} -+ -+static int md5_sha1_final(EVP_MD_CTX *ctx, unsigned char *md) -+{ -+ struct md5_sha1_ctx *mctx = _goboringcrypto_internal_EVP_MD_CTX_md_data(ctx); -+ if (!_goboringcrypto_internal_MD5_Final(md, &mctx->md5)) -+ return 0; -+ return _goboringcrypto_SHA1_Final(md + MD5_DIGEST_LENGTH, &mctx->sha1); -+} -+ -+// Change: Removed: -+// static int ctrl(EVP_MD_CTX *ctx, int cmd, int mslen, void *ms) -+ -+static const EVP_MD md5_sha1_md = { -+ NID_md5_sha1, -+ NID_md5_sha1, -+ MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, -+ 0, -+ md5_sha1_init, -+ md5_sha1_update, -+ md5_sha1_final, -+ NULL, -+ NULL, -+ EVP_PKEY_NULL_method, // Change: inserted -+ MD5_CBLOCK, -+ sizeof(EVP_MD *) + sizeof(struct md5_sha1_ctx), -+ NULL, // Change: was ctrl -+}; -+ -+const EVP_MD* local_EVP_md5_sha1(void) -+{ -+ return &md5_sha1_md; -+} -+ -+int -+local_RSA_set0_crt_params(RSA * r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) -+{ -+ if ((r->dmp1 == NULL && dmp1 == NULL) -+ || (r->dmq1 == NULL && dmq1 == NULL) -+ || (r->iqmp == NULL && iqmp == NULL)) -+ return 0; -+ -+ if (dmp1 != NULL) -+ { -+ _goboringcrypto_internal_BN_clear_free(r->dmp1); -+ r->dmp1 = dmp1; -+ } -+ if (dmq1 != NULL) -+ { -+ _goboringcrypto_internal_BN_clear_free(r->dmq1); -+ r->dmq1 = dmq1; -+ } -+ if (iqmp != NULL) -+ { -+ _goboringcrypto_internal_BN_clear_free(r->iqmp); -+ r->iqmp = iqmp; -+ } -+ -+ return 1; -+} -+ -+void -+local_RSA_get0_crt_params(const RSA *r, const BIGNUM **dmp1, const BIGNUM **dmq1, const BIGNUM **iqmp) -+{ -+ if (dmp1 != NULL) -+ *dmp1 = r->dmp1; -+ if (dmq1 != NULL) -+ *dmq1 = r->dmq1; -+ if (iqmp != NULL) -+ *iqmp = r->iqmp; -+} -+ -+int -+local_RSA_set0_key(RSA * r, BIGNUM *n, BIGNUM *e, BIGNUM *d) -+{ -+ /* If the fields n and e in r are NULL, the corresponding input -+ * parameters MUST be non-NULL for n and e. d may be -+ * left NULL (in case only the public key is used). -+ */ -+ if ((r->n == NULL && n == NULL) -+ || (r->e == NULL && e == NULL)) -+ return 0; -+ -+ if (n != NULL) -+ { -+ _goboringcrypto_BN_free(r->n); -+ r->n = n; -+ } -+ if (e != NULL) -+ { -+ _goboringcrypto_BN_free(r->e); -+ r->e = e; -+ } -+ if (d != NULL) -+ { -+ _goboringcrypto_internal_BN_clear_free(r->d); -+ r->d = d; -+ } -+ -+ return 1; -+} -+ -+int -+local_RSA_set0_factors(RSA * r, BIGNUM *p, BIGNUM *q) -+{ -+ /* If the fields p and q in r are NULL, the corresponding input -+ * parameters MUST be non-NULL. -+ */ -+ if ((r->p == NULL && p == NULL) -+ || (r->q == NULL && q == NULL)) -+ return 0; -+ -+ if (p != NULL) -+ { -+ _goboringcrypto_internal_BN_clear_free(r->p); -+ r->p = p; -+ } -+ if (q != NULL) -+ { -+ _goboringcrypto_internal_BN_clear_free(r->q); -+ r->q = q; -+ } -+ -+ return 1; -+} -+ -+void -+local_RSA_get0_factors(const RSA *rsa, const BIGNUM **p, const BIGNUM **q) -+{ -+ if (p) -+ *p = rsa->p; -+ if (q) -+ *q = rsa->q; -+} -+ -+void -+local_RSA_get0_key(const RSA *rsa, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) -+{ -+ if (n) -+ *n = rsa->n; -+ if (e) -+ *e = rsa->e; -+ if (d) -+ *d = rsa->d; -+} -+ -+int -+local_RSA_pkey_ctx_ctrl(EVP_PKEY_CTX* ctx, int optype, int cmd, int p1, void* p2) -+{ -+ return _goboringcrypto_internal_EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, optype, cmd, p1, p2); ++func bigUint64(b []byte) uint64 { ++ _ = b[7] // bounds check hint to compiler; see go.dev/issue/14808 ++ return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 | ++ uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56 +} -\ No newline at end of file -diff --git a/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/apibridge_1_1.h b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/apibridge_1_1.h -new file mode 100644 -index 0000000000..3b50f12598 ---- /dev/null -+++ b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/apibridge_1_1.h -@@ -0,0 +1,28 @@ -+// Copyright (c) Microsoft Corporation. -+// Licensed under the MIT License. -+ -+//go:build linux && !android -+// +build linux,!android -+ -+// Functions based on OpenSSL 1.1 API, used when building against/running with OpenSSL 1.0.x -+ -+void local_HMAC_CTX_free(HMAC_CTX * ctx); -+void* local_EVP_MD_CTX_md_data(EVP_MD_CTX *ctx); -+const EVP_MD* local_HMAC_CTX_get_md(const HMAC_CTX* ctx); -+HMAC_CTX* local_HMAC_CTX_new(); -+void local_HMAC_CTX_reset(HMAC_CTX *ctx); -+const EVP_MD* local_EVP_md5_sha1(void); -+int local_RSA_set0_crt_params(RSA * r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp); -+void local_RSA_get0_crt_params(const RSA *r, const BIGNUM **dmp1, const BIGNUM **dmq1, const BIGNUM **iqmp); -+int local_RSA_set0_key(RSA * r, BIGNUM *n, BIGNUM *e, BIGNUM *d); -+int local_RSA_set0_factors(RSA * r, BIGNUM *p, BIGNUM *q); -+void local_RSA_get0_factors(const RSA *rsa, const BIGNUM **p, const BIGNUM **q); -+void local_RSA_get0_key(const RSA *rsa, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d); -+int local_RSA_pkey_ctx_ctrl(EVP_PKEY_CTX* ctx, int optype, int cmd, int p1, void* p2); -+ -+#if OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_1_1_0_RTM -+#define OPENSSL_INIT_LOAD_CRYPTO_STRINGS 0x00000002L -+#define OPENSSL_INIT_ADD_ALL_CIPHERS 0x00000004L -+#define OPENSSL_INIT_ADD_ALL_DIGESTS 0x00000008L -+#define OPENSSL_INIT_LOAD_CONFIG 0x00000040L -+#endif -\ No newline at end of file diff --git a/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/ecdsa.go b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/ecdsa.go new file mode 100644 -index 0000000000..b13e7c9c5a +index 00000000000..84f82e903ce --- /dev/null +++ b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/ecdsa.go -@@ -0,0 +1,199 @@ +@@ -0,0 +1,214 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + @@ -920,23 +564,35 @@ index 0000000000..b13e7c9c5a +} + +type PrivateKeyECDSA struct { -+ key *C.GO_EC_KEY ++ // _pkey MUST NOT be accessed directly. Instead, use the withKey method. ++ _pkey C.GO_EVP_PKEY_PTR +} + +func (k *PrivateKeyECDSA) finalize() { -+ C._goboringcrypto_EC_KEY_free(k.key) ++ C.go_openssl_EVP_PKEY_free(k._pkey) ++} ++ ++func (k *PrivateKeyECDSA) withKey(f func(C.GO_EVP_PKEY_PTR) C.int) C.int { ++ defer runtime.KeepAlive(k) ++ return f(k._pkey) +} + +type PublicKeyECDSA struct { -+ key *C.GO_EC_KEY ++ // _pkey MUST NOT be accessed directly. Instead, use the withKey method. ++ _pkey C.GO_EVP_PKEY_PTR +} + +func (k *PublicKeyECDSA) finalize() { -+ C._goboringcrypto_EC_KEY_free(k.key) ++ C.go_openssl_EVP_PKEY_free(k._pkey) ++} ++ ++func (k *PublicKeyECDSA) withKey(f func(C.GO_EVP_PKEY_PTR) C.int) C.int { ++ defer runtime.KeepAlive(k) ++ return f(k._pkey) +} + -+var errUnknownCurve = errors.New("boringcrypto: unknown elliptic curve") -+var errUnsupportedCurve = errors.New("boringcrypto: unsupported elliptic curve") ++var errUnknownCurve = errors.New("openssl: unknown elliptic curve") ++var errUnsupportedCurve = errors.New("openssl: unsupported elliptic curve") + +func curveNID(curve string) (C.int, error) { + switch curve { @@ -953,11 +609,11 @@ index 0000000000..b13e7c9c5a +} + +func NewPublicKeyECDSA(curve string, X, Y *big.Int) (*PublicKeyECDSA, error) { -+ key, err := newECKey(curve, X, Y) ++ pkey, err := newECKey(curve, X, Y, nil) + if err != nil { + return nil, err + } -+ k := &PublicKeyECDSA{key} ++ k := &PublicKeyECDSA{_pkey: pkey} + // Note: Because of the finalizer, any time k.key is passed to cgo, + // that call must be followed by a call to runtime.KeepAlive(k), + // to make sure k is not collected (and finalized) before the cgo @@ -966,54 +622,68 @@ index 0000000000..b13e7c9c5a + return k, nil +} + -+func newECKey(curve string, X, Y *big.Int) (*C.GO_EC_KEY, error) { -+ nid, err := curveNID(curve) -+ if err != nil { ++func newECKey(curve string, X, Y, D *big.Int) (pkey C.GO_EVP_PKEY_PTR, err error) { ++ var nid C.int ++ if nid, err = curveNID(curve); err != nil { + return nil, err + } -+ key := C._goboringcrypto_EC_KEY_new_by_curve_name(nid) -+ if key == nil { ++ var bx, by C.GO_BIGNUM_PTR ++ var key C.GO_EC_KEY_PTR ++ defer func() { ++ if bx != nil { ++ C.go_openssl_BN_free(bx) ++ } ++ if by != nil { ++ C.go_openssl_BN_free(by) ++ } ++ if err != nil { ++ if key != nil { ++ C.go_openssl_EC_KEY_free(key) ++ } ++ if pkey != nil { ++ C.go_openssl_EVP_PKEY_free(pkey) ++ // pkey is a named return, so in case of error ++ // it have to be cleared before returing. ++ pkey = nil ++ } ++ } ++ }() ++ bx = bigToBN(X) ++ by = bigToBN(Y) ++ if bx == nil || by == nil { ++ return nil, newOpenSSLError("BN_bin2bn failed") ++ } ++ if key = C.go_openssl_EC_KEY_new_by_curve_name(nid); key == nil { + return nil, newOpenSSLError("EC_KEY_new_by_curve_name failed") + } -+ group := C._goboringcrypto_EC_KEY_get0_group(key) -+ pt := C._goboringcrypto_EC_POINT_new(group) -+ if pt == nil { -+ C._goboringcrypto_EC_KEY_free(key) -+ return nil, newOpenSSLError("EC_POINT_new failed") ++ if C.go_openssl_EC_KEY_set_public_key_affine_coordinates(key, bx, by) != 1 { ++ return nil, newOpenSSLError("EC_KEY_set_public_key_affine_coordinates failed") + } -+ bx := bigToBN(X) -+ by := bigToBN(Y) -+ ok := bx != nil && by != nil && C._goboringcrypto_EC_POINT_set_affine_coordinates_GFp(group, pt, bx, by, nil) != 0 && -+ C._goboringcrypto_EC_KEY_set_public_key(key, pt) != 0 -+ if bx != nil { -+ C._goboringcrypto_BN_free(bx) ++ if D != nil { ++ bd := bigToBN(D) ++ if bd == nil { ++ return nil, newOpenSSLError("BN_bin2bn failed") ++ } ++ defer C.go_openssl_BN_free(bd) ++ if C.go_openssl_EC_KEY_set_private_key(key, bd) != 1 { ++ return nil, newOpenSSLError("EC_KEY_set_private_key failed") ++ } + } -+ if by != nil { -+ C._goboringcrypto_BN_free(by) ++ if pkey = C.go_openssl_EVP_PKEY_new(); pkey == nil { ++ return nil, newOpenSSLError("EVP_PKEY_new failed") + } -+ C._goboringcrypto_EC_POINT_free(pt) -+ if !ok { -+ C._goboringcrypto_EC_KEY_free(key) -+ return nil, newOpenSSLError("EC_POINT_free failed") ++ if C.go_openssl_EVP_PKEY_assign(pkey, C.GO_EVP_PKEY_EC, (unsafe.Pointer)(key)) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_assign failed") + } -+ return key, nil ++ return pkey, nil +} + +func NewPrivateKeyECDSA(curve string, X, Y *big.Int, D *big.Int) (*PrivateKeyECDSA, error) { -+ key, err := newECKey(curve, X, Y) ++ pkey, err := newECKey(curve, X, Y, D) + if err != nil { + return nil, err + } -+ bd := bigToBN(D) -+ ok := bd != nil && C._goboringcrypto_EC_KEY_set_private_key(key, bd) != 0 -+ if bd != nil { -+ C._goboringcrypto_BN_free(bd) -+ } -+ if !ok { -+ C._goboringcrypto_EC_KEY_free(key) -+ return nil, newOpenSSLError("EC_KEY_set_private_key failed") -+ } -+ k := &PrivateKeyECDSA{key} ++ k := &PrivateKeyECDSA{_pkey: pkey} + // Note: Because of the finalizer, any time k.key is passed to cgo, + // that call must be followed by a call to runtime.KeepAlive(k), + // to make sure k is not collected (and finalized) before the cgo @@ -1039,14 +709,7 @@ index 0000000000..b13e7c9c5a +} + +func SignMarshalECDSA(priv *PrivateKeyECDSA, hash []byte) ([]byte, error) { -+ size := C._goboringcrypto_ECDSA_size(priv.key) -+ sig := make([]byte, size) -+ var sigLen C.uint -+ if C._goboringcrypto_ECDSA_sign(0, base(hash), C.size_t(len(hash)), (*C.uint8_t)(unsafe.Pointer(&sig[0])), &sigLen, priv.key) == 0 { -+ return nil, newOpenSSLError("ECDSA_sign failed") -+ } -+ runtime.KeepAlive(priv) -+ return sig[:sigLen], nil ++ return evpSign(priv.withKey, 0, 0, 0, hash) +} + +func VerifyECDSA(pub *PublicKeyECDSA, hash []byte, r, s *big.Int) bool { @@ -1057,51 +720,332 @@ index 0000000000..b13e7c9c5a + if err != nil { + return false + } -+ ok := C._goboringcrypto_ECDSA_verify(0, base(hash), C.size_t(len(hash)), (*C.uint8_t)(unsafe.Pointer(&sig[0])), C.uint(len(sig)), pub.key) > 0 -+ runtime.KeepAlive(pub) -+ return ok ++ return evpVerify(pub.withKey, 0, 0, 0, sig, hash) == nil +} + +func GenerateKeyECDSA(curve string) (X, Y, D *big.Int, err error) { -+ nid, err := curveNID(curve) ++ pkey, err := generateEVPPKey(C.GO_EVP_PKEY_EC, 0, curve) + if err != nil { + return nil, nil, nil, err + } -+ key := C._goboringcrypto_EC_KEY_new_by_curve_name(nid) ++ defer C.go_openssl_EVP_PKEY_free(pkey) ++ key := C.go_openssl_EVP_PKEY_get1_EC_KEY(pkey) + if key == nil { -+ return nil, nil, nil, newOpenSSLError("EC_KEY_new_by_curve_name failed") -+ } -+ defer C._goboringcrypto_EC_KEY_free(key) -+ if C._goboringcrypto_EC_KEY_generate_key(key) == 0 { -+ return nil, nil, nil, newOpenSSLError("EC_KEY_generate_key failed") ++ return nil, nil, nil, newOpenSSLError("EVP_PKEY_get1_EC_KEY failed") + } -+ group := C._goboringcrypto_EC_KEY_get0_group(key) -+ pt := C._goboringcrypto_EC_KEY_get0_public_key(key) -+ bd := C._goboringcrypto_EC_KEY_get0_private_key(key) ++ defer C.go_openssl_EC_KEY_free(key) ++ group := C.go_openssl_EC_KEY_get0_group(key) ++ pt := C.go_openssl_EC_KEY_get0_public_key(key) ++ bd := C.go_openssl_EC_KEY_get0_private_key(key) + if pt == nil || bd == nil { + return nil, nil, nil, newOpenSSLError("EC_KEY_get0_private_key failed") + } -+ bx := C._goboringcrypto_BN_new() ++ bx := C.go_openssl_BN_new() + if bx == nil { + return nil, nil, nil, newOpenSSLError("BN_new failed") + } -+ defer C._goboringcrypto_BN_free(bx) -+ by := C._goboringcrypto_BN_new() ++ defer C.go_openssl_BN_free(bx) ++ by := C.go_openssl_BN_new() + if by == nil { + return nil, nil, nil, newOpenSSLError("BN_new failed") + } -+ defer C._goboringcrypto_BN_free(by) -+ if C._goboringcrypto_EC_POINT_get_affine_coordinates_GFp(group, pt, bx, by, nil) == 0 { ++ defer C.go_openssl_BN_free(by) ++ if C.go_openssl_EC_POINT_get_affine_coordinates_GFp(group, pt, bx, by, nil) == 0 { + return nil, nil, nil, newOpenSSLError("EC_POINT_get_affine_coordinates_GFp failed") + } + return bnToBig(bx), bnToBig(by), bnToBig(bd), nil +} +diff --git a/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/evpkey.go b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/evpkey.go +new file mode 100644 +index 00000000000..03a652aef13 +--- /dev/null ++++ b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/evpkey.go +@@ -0,0 +1,279 @@ ++// Copyright (c) Microsoft Corporation. ++// Licensed under the MIT License. ++ ++//go:build linux && !android ++// +build linux,!android ++ ++package openssl ++ ++// #include "goopenssl.h" ++import "C" ++import ( ++ "crypto" ++ "errors" ++ "hash" ++ "unsafe" ++) ++ ++// hashToMD converts a hash.Hash implementation from this package to a GO_EVP_MD_PTR. ++func hashToMD(h hash.Hash) C.GO_EVP_MD_PTR { ++ switch h.(type) { ++ case *sha1Hash: ++ return C.go_openssl_EVP_sha1() ++ case *sha224Hash: ++ return C.go_openssl_EVP_sha224() ++ case *sha256Hash: ++ return C.go_openssl_EVP_sha256() ++ case *sha384Hash: ++ return C.go_openssl_EVP_sha384() ++ case *sha512Hash: ++ return C.go_openssl_EVP_sha512() ++ } ++ return nil ++} ++ ++// cryptoHashToMD converts a crypto.Hash to a GO_EVP_MD_PTR. ++func cryptoHashToMD(ch crypto.Hash) C.GO_EVP_MD_PTR { ++ switch ch { ++ case crypto.MD5: ++ return C.go_openssl_EVP_md5() ++ case crypto.MD5SHA1: ++ if vMajor == 1 && vMinor == 0 { ++ // MD5SHA1 is not implemented in OpenSSL 1.0.2. ++ // It is implemented in higher versions but without FIPS support. ++ // It is considered a deprecated digest, not approved by FIPS 140-2 ++ // and only used in pre-TLS 1.2, so we would rather not support it ++ // if using 1.0.2 than than implement something that is not properly validated. ++ return nil ++ } ++ return C.go_openssl_EVP_md5_sha1() ++ case crypto.SHA1: ++ return C.go_openssl_EVP_sha1() ++ case crypto.SHA224: ++ return C.go_openssl_EVP_sha224() ++ case crypto.SHA256: ++ return C.go_openssl_EVP_sha256() ++ case crypto.SHA384: ++ return C.go_openssl_EVP_sha384() ++ case crypto.SHA512: ++ return C.go_openssl_EVP_sha512() ++ } ++ return nil ++} ++ ++func generateEVPPKey(id C.int, bits int, curve string) (C.GO_EVP_PKEY_PTR, error) { ++ if (bits == 0 && curve == "") || (bits != 0 && curve != "") { ++ return nil, fail("incorrect generateEVPPKey parameters") ++ } ++ ctx := C.go_openssl_EVP_PKEY_CTX_new_id(id, nil) ++ if ctx == nil { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_new_id failed") ++ } ++ defer C.go_openssl_EVP_PKEY_CTX_free(ctx) ++ if C.go_openssl_EVP_PKEY_keygen_init(ctx) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_keygen_init failed") ++ } ++ if bits != 0 { ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, id, -1, C.GO_EVP_PKEY_CTRL_RSA_KEYGEN_BITS, C.int(bits), nil) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_ctrl failed") ++ } ++ } ++ if curve != "" { ++ nid, err := curveNID(curve) ++ if err != nil { ++ return nil, err ++ } ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, id, -1, C.GO_EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, nid, nil) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_ctrl failed") ++ } ++ } ++ var pkey C.GO_EVP_PKEY_PTR ++ if C.go_openssl_EVP_PKEY_keygen(ctx, &pkey) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_keygen failed") ++ } ++ return pkey, nil ++} ++ ++type withKeyFunc func(func(C.GO_EVP_PKEY_PTR) C.int) C.int ++type initFunc func(C.GO_EVP_PKEY_CTX_PTR) C.int ++type cryptFunc func(C.GO_EVP_PKEY_CTX_PTR, *C.uchar, *C.size_t, *C.uchar, C.size_t) C.int ++type verifyFunc func(C.GO_EVP_PKEY_CTX_PTR, *C.uchar, C.size_t, *C.uchar, C.size_t) C.int ++ ++func setupEVP(withKey withKeyFunc, padding C.int, ++ h hash.Hash, label []byte, saltLen int, ch crypto.Hash, ++ init initFunc) (ctx C.GO_EVP_PKEY_CTX_PTR, err error) { ++ defer func() { ++ if err != nil { ++ if ctx != nil { ++ C.go_openssl_EVP_PKEY_CTX_free(ctx) ++ ctx = nil ++ } ++ } ++ }() ++ ++ withKey(func(pkey C.GO_EVP_PKEY_PTR) C.int { ++ ctx = C.go_openssl_EVP_PKEY_CTX_new(pkey, nil) ++ return 1 ++ }) ++ if ctx == nil { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_new failed") ++ } ++ if init(ctx) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_operation_init failed") ++ } ++ if padding == 0 { ++ return ctx, nil ++ } ++ // Each padding type has its own requirements in terms of when to apply the padding, ++ // so it can't be just set at this point. ++ setPadding := func() error { ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, C.GO_EVP_PKEY_RSA, -1, C.GO_EVP_PKEY_CTRL_RSA_PADDING, padding, nil) != 1 { ++ return newOpenSSLError("EVP_PKEY_CTX_ctrl failed") ++ } ++ return nil ++ } ++ switch padding { ++ case C.GO_RSA_PKCS1_OAEP_PADDING: ++ md := hashToMD(h) ++ if md == nil { ++ return nil, errors.New("crypto/rsa: unsupported hash function") ++ } ++ // setPadding must happen before setting EVP_PKEY_CTRL_RSA_OAEP_MD. ++ if err := setPadding(); err != nil { ++ return nil, err ++ } ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, C.GO_EVP_PKEY_RSA, -1, C.GO_EVP_PKEY_CTRL_RSA_OAEP_MD, 0, unsafe.Pointer(md)) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_ctrl failed") ++ } ++ // ctx takes ownership of label, so malloc a copy for OpenSSL to free. ++ // OpenSSL 1.1.1 and higher does not take ownership of the label if the length is zero, ++ // so better avoid the allocation. ++ var clabel *C.uchar ++ if len(label) > 0 { ++ // Go guarantees C.malloc never returns nil. ++ clabel = (*C.uchar)(C.malloc(C.size_t(len(label)))) ++ copy((*[1 << 30]byte)(unsafe.Pointer(clabel))[:len(label)], label) ++ } ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, C.GO_EVP_PKEY_RSA, -1, C.GO_EVP_PKEY_CTRL_RSA_OAEP_LABEL, C.int(len(label)), unsafe.Pointer(clabel)) != 1 { ++ if clabel != nil { ++ C.free(unsafe.Pointer(clabel)) ++ } ++ return nil, newOpenSSLError("EVP_PKEY_CTX_ctrl failed") ++ } ++ case C.GO_RSA_PKCS1_PSS_PADDING: ++ md := cryptoHashToMD(ch) ++ if md == nil { ++ return nil, errors.New("crypto/rsa: unsupported hash function") ++ } ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, C.GO_EVP_PKEY_RSA, -1, C.GO_EVP_PKEY_CTRL_MD, 0, unsafe.Pointer(md)) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_ctrl failed") ++ } ++ // setPadding must happen after setting EVP_PKEY_CTRL_MD. ++ if err := setPadding(); err != nil { ++ return nil, err ++ } ++ if saltLen != 0 { ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, C.GO_EVP_PKEY_RSA, -1, C.GO_EVP_PKEY_CTRL_RSA_PSS_SALTLEN, C.int(saltLen), nil) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_ctrl failed") ++ } ++ } ++ ++ case C.GO_RSA_PKCS1_PADDING: ++ if ch != 0 { ++ // We support unhashed messages. ++ md := cryptoHashToMD(ch) ++ if md == nil { ++ return nil, errors.New("crypto/rsa: unsupported hash function") ++ } ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, -1, -1, C.GO_EVP_PKEY_CTRL_MD, 0, unsafe.Pointer(md)) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_ctrl failed") ++ } ++ if err := setPadding(); err != nil { ++ return nil, err ++ } ++ } ++ default: ++ if err := setPadding(); err != nil { ++ return nil, err ++ } ++ } ++ return ctx, nil ++} ++ ++func cryptEVP(withKey withKeyFunc, padding C.int, ++ h hash.Hash, label []byte, saltLen int, ch crypto.Hash, ++ init initFunc, crypt cryptFunc, in []byte) ([]byte, error) { ++ ++ ctx, err := setupEVP(withKey, padding, h, label, saltLen, ch, init) ++ if err != nil { ++ return nil, err ++ } ++ defer C.go_openssl_EVP_PKEY_CTX_free(ctx) ++ pkeySize := withKey(func(pkey C.GO_EVP_PKEY_PTR) C.int { ++ return C.go_openssl_EVP_PKEY_get_size(pkey) ++ }) ++ outLen := C.size_t(pkeySize) ++ out := make([]byte, pkeySize) ++ if crypt(ctx, base(out), &outLen, base(in), C.size_t(len(in))) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_decrypt/encrypt failed") ++ } ++ // The size returned by EVP_PKEY_get_size() is only preliminary and not exact, ++ // so the final contents of the out buffer may be smaller. ++ return out[:outLen], nil ++} ++ ++func verifyEVP(withKey withKeyFunc, padding C.int, ++ h hash.Hash, label []byte, saltLen int, ch crypto.Hash, ++ init initFunc, verify verifyFunc, ++ sig, in []byte) error { ++ ++ ctx, err := setupEVP(withKey, padding, h, label, saltLen, ch, init) ++ if err != nil { ++ return err ++ } ++ defer C.go_openssl_EVP_PKEY_CTX_free(ctx) ++ if verify(ctx, base(sig), C.size_t(len(sig)), base(in), C.size_t(len(in))) != 1 { ++ return newOpenSSLError("EVP_PKEY_decrypt/encrypt failed") ++ } ++ return nil ++} ++ ++func evpEncrypt(withKey withKeyFunc, padding C.int, h hash.Hash, label, msg []byte) ([]byte, error) { ++ encryptInit := func(ctx C.GO_EVP_PKEY_CTX_PTR) C.int { ++ return C.go_openssl_EVP_PKEY_encrypt_init(ctx) ++ } ++ encrypt := func(ctx C.GO_EVP_PKEY_CTX_PTR, out *C.uchar, outLen *C.size_t, in *C.uchar, inLen C.size_t) C.int { ++ return C.go_openssl_EVP_PKEY_encrypt(ctx, out, outLen, in, inLen) ++ } ++ return cryptEVP(withKey, padding, h, label, 0, 0, encryptInit, encrypt, msg) ++} ++ ++func evpDecrypt(withKey withKeyFunc, padding C.int, h hash.Hash, label, msg []byte) ([]byte, error) { ++ decryptInit := func(ctx C.GO_EVP_PKEY_CTX_PTR) C.int { ++ return C.go_openssl_EVP_PKEY_decrypt_init(ctx) ++ } ++ decrypt := func(ctx C.GO_EVP_PKEY_CTX_PTR, out *C.uchar, outLen *C.size_t, in *C.uchar, inLen C.size_t) C.int { ++ return C.go_openssl_EVP_PKEY_decrypt(ctx, out, outLen, in, inLen) ++ } ++ return cryptEVP(withKey, padding, h, label, 0, 0, decryptInit, decrypt, msg) ++} ++ ++func evpSign(withKey withKeyFunc, padding C.int, saltLen int, h crypto.Hash, hashed []byte) ([]byte, error) { ++ signtInit := func(ctx C.GO_EVP_PKEY_CTX_PTR) C.int { ++ return C.go_openssl_EVP_PKEY_sign_init(ctx) ++ } ++ sign := func(ctx C.GO_EVP_PKEY_CTX_PTR, out *C.uchar, outLen *C.size_t, in *C.uchar, inLen C.size_t) C.int { ++ return C.go_openssl_EVP_PKEY_sign(ctx, out, outLen, in, inLen) ++ } ++ return cryptEVP(withKey, padding, nil, nil, saltLen, h, signtInit, sign, hashed) ++} ++ ++func evpVerify(withKey withKeyFunc, padding C.int, saltLen int, h crypto.Hash, sig, hashed []byte) error { ++ verifyInit := func(ctx C.GO_EVP_PKEY_CTX_PTR) C.int { ++ return C.go_openssl_EVP_PKEY_verify_init(ctx) ++ } ++ verify := func(ctx C.GO_EVP_PKEY_CTX_PTR, out *C.uchar, outLen C.size_t, in *C.uchar, inLen C.size_t) C.int { ++ return C.go_openssl_EVP_PKEY_verify(ctx, out, outLen, in, inLen) ++ } ++ return verifyEVP(withKey, padding, nil, nil, saltLen, h, verifyInit, verify, sig, hashed) ++} diff --git a/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/goopenssl.c b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/goopenssl.c new file mode 100644 -index 0000000000..1abd17c202 +index 00000000000..7bbf7418512 --- /dev/null +++ b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/goopenssl.c -@@ -0,0 +1,199 @@ +@@ -0,0 +1,153 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + @@ -1110,284 +1054,170 @@ index 0000000000..1abd17c202 + +#include "goopenssl.h" + -+#include -+#include ++#include ++#include ++ ++static unsigned long ++version_num(void* handle) ++{ ++ unsigned long (*fn)(void); ++ // OPENSSL_version_num is defined in OpenSSL 1.1.0 and 1.1.1. ++ fn = (unsigned long (*)(void))dlsym(handle, "OpenSSL_version_num"); ++ if (fn != NULL) ++ return fn(); ++ ++ // SSLeay is defined in OpenSSL 1.0.2. ++ fn = (unsigned long (*)(void))dlsym(handle, "SSLeay"); ++ if (fn != NULL) ++ return fn(); ++ ++ return 0; ++} ++ ++int ++go_openssl_version_major(void* handle) ++{ ++ unsigned int (*fn)(void); ++ // OPENSSL_version_major is supported since OpenSSL 3. ++ fn = (unsigned int (*)(void))dlsym(handle, "OPENSSL_version_major"); ++ if (fn != NULL) ++ return (int)fn(); ++ ++ // If OPENSSL_version_major is not defined, try with OpenSSL 1 functions. ++ unsigned long num = version_num(handle); ++ if (num < 0x10000000L || num >= 0x20000000L) ++ return -1; ++ ++ return 1; ++} ++ ++int ++go_openssl_version_minor(void* handle) ++{ ++ unsigned int (*fn)(void); ++ // OPENSSL_version_major is supported since OpenSSL 3. ++ fn = (unsigned int (*)(void))dlsym(handle, "OPENSSL_version_minor"); ++ if (fn != NULL) ++ return (int)fn(); ++ ++ // If OPENSSL_version_major is not defined, try with OpenSSL 1 functions. ++ unsigned long num = version_num(handle); ++ // OpenSSL version number follows this schema: ++ // MNNFFPPS: major minor fix patch status. ++ if (num < 0x10000000L || num >= 0x10200000L) ++ { ++ // We only support minor version 0 and 1, ++ // so there is no need to implement an algorithm ++ // that decodes the version number into individual components. ++ return -1; ++ } ++ ++ if (num >= 0x10100000L) ++ return 1; ++ ++ return 0; ++} + +// Approach taken from .Net System.Security.Cryptography.Native +// https://github.com/dotnet/runtime/blob/f64246ce08fb7a58221b2b7c8e68f69c02522b0d/src/libraries/Native/Unix/System.Security.Cryptography.Native/opensslshim.c + -+#define DEFINEFUNC(ret, func, args, argscall) ret (*_g_##func)args; -+#define DEFINEFUNCINTERNAL(ret, func, args, argscall) ret (*_g_internal_##func)args; -+#define DEFINEFUNC_LEGACY(ret, func, args, argscall) DEFINEFUNCINTERNAL(ret, func, args, argscall) -+#define DEFINEFUNC_110(ret, func, args, argscall) DEFINEFUNCINTERNAL(ret, func, args, argscall) -+#define DEFINEFUNC_RENAMED(ret, func, oldfunc, args, argscall) DEFINEFUNCINTERNAL(ret, func, args, argscall) -+#define DEFINEFUNC_FALLBACK(ret, func, args, argscall) DEFINEFUNCINTERNAL(ret, func, args, argscall) ++#define DEFINEFUNC(ret, func, args, argscall) ret (*_g_##func)args; ++#define DEFINEFUNC_LEGACY_1_0(ret, func, args, argscall) DEFINEFUNC(ret, func, args, argscall) ++#define DEFINEFUNC_LEGACY_1(ret, func, args, argscall) DEFINEFUNC(ret, func, args, argscall) ++#define DEFINEFUNC_1_1(ret, func, args, argscall) DEFINEFUNC(ret, func, args, argscall) ++#define DEFINEFUNC_3_0(ret, func, args, argscall) DEFINEFUNC(ret, func, args, argscall) ++#define DEFINEFUNC_RENAMED_1_1(ret, func, oldfunc, args, argscall) DEFINEFUNC(ret, func, args, argscall) ++#define DEFINEFUNC_RENAMED_3_0(ret, func, oldfunc, args, argscall) DEFINEFUNC(ret, func, args, argscall) + +FOR_ALL_OPENSSL_FUNCTIONS + +#undef DEFINEFUNC -+#undef DEFINEFUNCINTERNAL -+#undef DEFINEFUNC_LEGACY -+#undef DEFINEFUNC_110 -+#undef DEFINEFUNC_RENAMED -+#undef DEFINEFUNC_FALLBACK -+ -+static void* handle = NULL; ++#undef DEFINEFUNC_LEGACY_1_0 ++#undef DEFINEFUNC_LEGACY_1 ++#undef DEFINEFUNC_1_1 ++#undef DEFINEFUNC_3_0 ++#undef DEFINEFUNC_RENAMED_1_1 ++#undef DEFINEFUNC_RENAMED_3_0 + +// Load all the functions stored in FOR_ALL_OPENSSL_FUNCTIONS +// and assign them to their corresponding function pointer +// defined in goopenssl.h. -+static void -+_goboringcrypto_load_openssl_functions(const void* v1_0_sentinel) ++void ++go_openssl_load_functions(void* handle, int major, int minor) +{ -+ // This function could be called concurrently from different Goroutines unless correctly locked. -+ // If that happen there could be a race in DEFINEFUNC_RENAMED where the global function pointer is NULL, -+ // then properly loaded, then goes back to NULL right before being used (then loaded again). -+ // To avoid this situation only assign the function pointer when the function has been successfully -+ // loaded in tmp_ptr. -+ void* tmp_ptr; -+ ++#define DEFINEFUNC_INTERNAL(name, func) \ ++ _g_##name = dlsym(handle, func); \ ++ if (_g_##name == NULL) { fprintf(stderr, "Cannot get required symbol " #func " from libcrypto version %d.%d\n", major, minor); abort(); } +#define DEFINEFUNC(ret, func, args, argscall) \ -+ _g_##func = dlsym(handle, #func); \ -+ if (_g_##func == NULL) { fprintf(stderr, "Cannot get required symbol " #func " from libcrypto\n"); abort(); } -+#define DEFINEFUNCINTERNAL(ret, func, args, argscall) \ -+ _g_internal_##func = dlsym(handle, #func); \ -+ if (_g_internal_##func == NULL) { fprintf(stderr, "Cannot get required symbol " #func " from libcrypto\n"); abort(); } -+#define DEFINEFUNC_LEGACY(ret, func, args, argscall) \ -+ if (v1_0_sentinel != NULL) \ -+ { \ -+ DEFINEFUNCINTERNAL(ret, func, args, argscall) \ -+ } -+#define DEFINEFUNC_110(ret, func, args, argscall) \ -+ if (v1_0_sentinel == NULL) \ -+ { \ -+ DEFINEFUNCINTERNAL(ret, func, args, argscall) \ -+ } -+#define DEFINEFUNC_RENAMED(ret, func, oldfunc, args, argscall) \ -+ tmp_ptr = dlsym(handle, #func); \ -+ if (tmp_ptr == NULL) \ -+ { \ -+ tmp_ptr = dlsym(handle, #oldfunc); \ -+ if (tmp_ptr == NULL) \ -+ { \ -+ fprintf(stderr, "Cannot get required symbol " #func " nor " #oldfunc " from libcrypto\n"); \ -+ abort(); \ -+ } \ -+ } \ -+ _g_internal_##func = tmp_ptr; -+#define DEFINEFUNC_FALLBACK(ret, func, args, argscall) \ -+ tmp_ptr = dlsym(handle, #func); \ -+ if (tmp_ptr == NULL) { tmp_ptr = (void*)local_##func; } \ -+ _g_internal_##func = tmp_ptr; -+ -+FOR_ALL_OPENSSL_FUNCTIONS -+ -+#undef DEFINEFUNC -+#undef DEFINEFUNCINTERNAL -+#undef DEFINEFUNC_LEGACY -+#undef DEFINEFUNC_110 -+#undef DEFINEFUNC_RENAMED -+#undef DEFINEFUNC_FALLBACK -+} -+ -+#define SONAME_BASE "libcrypto.so." -+#define MAKELIB(v) SONAME_BASE v -+ -+static void -+_goboringcrypto_DLOPEN(const char* libraryName) -+{ -+ handle = dlopen(libraryName, RTLD_LAZY | RTLD_GLOBAL); -+} -+ -+void* -+_goboringcrypto_internal_DLOPEN_OPENSSL(void) -+{ -+ if (handle) -+ { -+ return handle; -+ } -+ -+ // If there is an override of the version specified using the GO_OPENSSL_VERSION_OVERRIDE -+ // env variable, try to load that first. -+ // The format of the value in the env variable is expected to be the version numbers, -+ // like 1.0.0, 1.0.2 etc. -+ char* versionOverride = getenv("GO_OPENSSL_VERSION_OVERRIDE"); -+ if ((versionOverride != NULL) && strnlen(versionOverride, MaxVersionStringLength + 1) <= MaxVersionStringLength) -+ { -+ char soName[sizeof(SONAME_BASE) + MaxVersionStringLength] = SONAME_BASE; -+ strcat(soName, versionOverride); -+ _goboringcrypto_DLOPEN(soName); -+ } -+ -+ if (handle == NULL) -+ { -+ _goboringcrypto_DLOPEN(MAKELIB("3")); -+ } -+ -+ if (handle == NULL) -+ { -+ _goboringcrypto_DLOPEN(MAKELIB("1.1")); ++ DEFINEFUNC_INTERNAL(func, #func) ++#define DEFINEFUNC_LEGACY_1_0(ret, func, args, argscall) \ ++ if (major == 1 && minor == 0) \ ++ { \ ++ DEFINEFUNC_INTERNAL(func, #func) \ + } -+ -+ // FreeBSD uses a different suffix numbering convention. -+ // Current supported FreeBSD releases should use the order .11 -> .111 -+ if (handle == NULL) -+ { -+ _goboringcrypto_DLOPEN(MAKELIB("11")); ++#define DEFINEFUNC_LEGACY_1(ret, func, args, argscall) \ ++ if (major == 1) \ ++ { \ ++ DEFINEFUNC_INTERNAL(func, #func) \ + } -+ -+ if (handle == NULL) -+ { -+ _goboringcrypto_DLOPEN(MAKELIB("111")); ++#define DEFINEFUNC_1_1(ret, func, args, argscall) \ ++ if (major == 3 || (major == 1 && minor == 1)) \ ++ { \ ++ DEFINEFUNC_INTERNAL(func, #func) \ + } -+ -+ if (handle == NULL) -+ { -+ // Debian 9 has dropped support for SSLv3 and so they have bumped their soname. Let's try it -+ // before trying the version 1.0.0 to make it less probable that some of our other dependencies -+ // end up loading conflicting version of libcrypto. -+ _goboringcrypto_DLOPEN(MAKELIB("1.0.2")); ++#define DEFINEFUNC_3_0(ret, func, args, argscall) \ ++ if (major == 3) \ ++ { \ ++ DEFINEFUNC_INTERNAL(func, #func) \ + } -+ -+ if (handle == NULL) -+ { -+ // Now try the default versioned so naming as described in the OpenSSL doc -+ _goboringcrypto_DLOPEN(MAKELIB("1.0.0")); ++#define DEFINEFUNC_RENAMED_1_1(ret, func, oldfunc, args, argscall) \ ++ if (major == 1 && minor == 0) \ ++ { \ ++ DEFINEFUNC_INTERNAL(func, #oldfunc) \ ++ } \ ++ else \ ++ { \ ++ DEFINEFUNC_INTERNAL(func, #func) \ + } -+ -+ if (handle == NULL) -+ { -+ // Fedora derived distros use different naming for the version 1.0.0 -+ _goboringcrypto_DLOPEN(MAKELIB("10")); ++#define DEFINEFUNC_RENAMED_3_0(ret, func, oldfunc, args, argscall) \ ++ if (major == 1) \ ++ { \ ++ DEFINEFUNC_INTERNAL(func, #oldfunc) \ ++ } \ ++ else \ ++ { \ ++ DEFINEFUNC_INTERNAL(func, #func) \ + } + -+ return handle; -+} -+ -+int _goboringcrypto_internal_OPENSSL_thread_setup(void); ++FOR_ALL_OPENSSL_FUNCTIONS + -+int -+_goboringcrypto_internal_OPENSSL_setup(void) -+{ -+ // A function defined in libcrypto.so.1.0.x that is not defined in libcrypto.so.1.1.0 -+ const void* v1_0_sentinel = dlsym(handle, "EVP_MD_CTX_cleanup"); -+ _goboringcrypto_load_openssl_functions(v1_0_sentinel); -+ // OPENSSL_init initialize FIPS callbacks and rand generator. -+ // no-op from OpenSSL 1.1.1 onwards. -+ _goboringcrypto_internal_OPENSSL_init(); -+ -+ if (v1_0_sentinel != NULL) -+ { -+ if (_goboringcrypto_internal_OPENSSL_thread_setup() != 1) -+ { -+ return 0; -+ } -+ // Load all algorithms and the openssl configuration file. -+ _goboringcrypto_internal_OPENSSL_add_all_algorithms_conf(); -+ -+ // Ensure that the error message table is loaded. -+ _goboringcrypto_internal_ERR_load_crypto_strings(); -+ return 1; -+ } -+ else -+ { -+ // In OpenSSL 1.0 we call OPENSSL_add_all_algorithms_conf() and ERR_load_crypto_strings(), -+ // so do the same for 1.1 -+ return _goboringcrypto_internal_OPENSSL_init_crypto( -+ OPENSSL_INIT_ADD_ALL_CIPHERS | -+ OPENSSL_INIT_ADD_ALL_DIGESTS | -+ OPENSSL_INIT_LOAD_CONFIG | -+ OPENSSL_INIT_LOAD_CRYPTO_STRINGS, -+ NULL); -+ } ++#undef DEFINEFUNC ++#undef DEFINEFUNC_LEGACY_1_0 ++#undef DEFINEFUNC_LEGACY_1 ++#undef DEFINEFUNC_1_1 ++#undef DEFINEFUNC_3_0 ++#undef DEFINEFUNC_RENAMED_1_1 ++#undef DEFINEFUNC_RENAMED_3_0 +} diff --git a/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/goopenssl.h b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/goopenssl.h new file mode 100644 -index 0000000000..0b0acb1bcf +index 00000000000..745637d63cf --- /dev/null +++ b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/goopenssl.h -@@ -0,0 +1,240 @@ +@@ -0,0 +1,127 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +// This header file describes the OpenSSL ABI as built for use in Go. + +#include // size_t -+#include // uint8_t, getenv -+#include // strnlen + +#include "openssl_funcs.h" + -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+void* _goboringcrypto_internal_DLOPEN_OPENSSL(void); -+int _goboringcrypto_internal_OPENSSL_setup(void); -+ -+static inline void* -+_goboringcrypto_DLOPEN_OPENSSL(void) -+{ -+ return _goboringcrypto_internal_DLOPEN_OPENSSL(); -+} -+ -+static inline int -+_goboringcrypto_OPENSSL_setup(void) -+{ -+ return _goboringcrypto_internal_OPENSSL_setup(); -+} -+ -+// x.x.x, considering the max number of decimal digits for each component -+#define MaxVersionStringLength 32 -+#define OPENSSL_VERSION_3_0_RTM 0x30000000L -+#define OPENSSL_VERSION_1_1_1_RTM 0x10101000L -+#define OPENSSL_VERSION_1_1_0_RTM 0x10100000L -+#define OPENSSL_VERSION_1_0_2_RTM 0x10002000L -+ -+#include "apibridge_1_1.h" -+ -+enum -+{ -+ GO_NID_secp224r1 = NID_secp224r1, -+ GO_NID_X9_62_prime256v1 = NID_X9_62_prime256v1, -+ GO_NID_secp384r1 = NID_secp384r1, -+ GO_NID_secp521r1 = NID_secp521r1, -+ GO_AES_ENCRYPT = 1, -+ GO_AES_DECRYPT = 0, -+ GO_RSA_PKCS1_PADDING = 1, -+ GO_RSA_NO_PADDING = 3, -+ GO_RSA_PKCS1_OAEP_PADDING = 4, -+ GO_RSA_PKCS1_PSS_PADDING = 6, -+}; -+ -+typedef SHA_CTX GO_SHA_CTX; -+typedef SHA256_CTX GO_SHA256_CTX; -+typedef SHA512_CTX GO_SHA512_CTX; -+typedef EVP_MD GO_EVP_MD; -+typedef HMAC_CTX GO_HMAC_CTX; -+typedef BN_CTX GO_BN_CTX; -+typedef BIGNUM GO_BIGNUM; -+typedef EC_GROUP GO_EC_GROUP; -+typedef EC_POINT GO_EC_POINT; -+typedef EC_KEY GO_EC_KEY; -+typedef ECDSA_SIG GO_ECDSA_SIG; -+typedef RSA GO_RSA; -+typedef BN_GENCB GO_BN_GENCB; -+typedef EVP_PKEY GO_EVP_PKEY; -+typedef EVP_PKEY_CTX GO_EVP_PKEY_CTX; ++int go_openssl_version_major(void* handle); ++int go_openssl_version_minor(void* handle); ++int go_openssl_thread_setup(void); ++void go_openssl_load_functions(void* handle, int major, int minor); + +// Define pointers to all the used OpenSSL functions. +// Calling C function pointers from Go is currently not supported. @@ -1395,164 +1225,120 @@ index 0000000000..0b0acb1bcf +// https://pkg.go.dev/cmd/cgo +#define DEFINEFUNC(ret, func, args, argscall) \ + extern ret (*_g_##func)args; \ -+ static inline ret _goboringcrypto_##func args \ ++ static inline ret go_openssl_##func args \ + { \ -+ return _g_##func argscall; \ ++ return _g_##func argscall; \ + } -+#define DEFINEFUNCINTERNAL(ret, func, args, argscall) \ -+ extern ret (*_g_internal_##func)args; \ -+ static inline ret _goboringcrypto_internal_##func args \ -+ { \ -+ return _g_internal_##func argscall; \ -+ } -+#define DEFINEFUNC_LEGACY(ret, func, args, argscall) \ -+ DEFINEFUNCINTERNAL(ret, func, args, argscall) -+#define DEFINEFUNC_110(ret, func, args, argscall) \ -+ DEFINEFUNCINTERNAL(ret, func, args, argscall) -+#define DEFINEFUNC_RENAMED(ret, func, oldfunc, args, argscall) \ -+ DEFINEFUNCINTERNAL(ret, func, args, argscall) -+#define DEFINEFUNC_FALLBACK(ret, func, args, argscall) \ -+ DEFINEFUNCINTERNAL(ret, func, args, argscall) ++#define DEFINEFUNC_LEGACY_1_0(ret, func, args, argscall) \ ++ DEFINEFUNC(ret, func, args, argscall) ++#define DEFINEFUNC_LEGACY_1(ret, func, args, argscall) \ ++ DEFINEFUNC(ret, func, args, argscall) ++#define DEFINEFUNC_1_1(ret, func, args, argscall) \ ++ DEFINEFUNC(ret, func, args, argscall) ++#define DEFINEFUNC_3_0(ret, func, args, argscall) \ ++ DEFINEFUNC(ret, func, args, argscall) ++#define DEFINEFUNC_RENAMED_1_1(ret, func, oldfunc, args, argscall) \ ++ DEFINEFUNC(ret, func, args, argscall) ++#define DEFINEFUNC_RENAMED_3_0(ret, func, oldfunc, args, argscall) \ ++ DEFINEFUNC(ret, func, args, argscall) + +FOR_ALL_OPENSSL_FUNCTIONS + +#undef DEFINEFUNC -+#undef DEFINEFUNCINTERNAL -+#undef DEFINEFUNC_LEGACY -+#undef DEFINEFUNC_110 -+#undef DEFINEFUNC_RENAMED -+#undef DEFINEFUNC_FALLBACK -+ -+static inline void -+_goboringcrypto_EVP_AES_ctr128_enc(EVP_CIPHER_CTX *ctx, const uint8_t *in, uint8_t *out, size_t in_len) -+{ -+ int len; -+ _goboringcrypto_EVP_EncryptUpdate(ctx, out, &len, in, in_len); -+} -+ ++#undef DEFINEFUNC_LEGACY_1_0 ++#undef DEFINEFUNC_LEGACY_1 ++#undef DEFINEFUNC_1_1 ++#undef DEFINEFUNC_3_0 ++#undef DEFINEFUNC_RENAMED_1_1 ++#undef DEFINEFUNC_RENAMED_3_0 ++ ++// These wrappers allocate out_len on the C stack to avoid having to pass a pointer from Go, which would escape to the heap. ++// Use them only in situations where the output length can be safely discarded. +static inline int -+_goboringcrypto_HMAC_CTX_copy_ex(GO_HMAC_CTX *dest, const GO_HMAC_CTX *src) ++go_openssl_EVP_EncryptUpdate_wrapper(GO_EVP_CIPHER_CTX_PTR ctx, unsigned char *out, const unsigned char *in, int in_len) +{ -+ return _goboringcrypto_HMAC_CTX_copy(dest, (GO_HMAC_CTX *) src); ++ int len; ++ return go_openssl_EVP_EncryptUpdate(ctx, out, &len, in, in_len); +} + +static inline int -+_goboringcrypto_EVP_MD_type(const GO_EVP_MD *md) -+{ -+ return _goboringcrypto_internal_EVP_MD_get_type(md); -+} -+ -+static inline const GO_EVP_MD* -+_goboringcrypto_EVP_md5_sha1(void) -+{ -+ return _goboringcrypto_internal_EVP_md5_sha1(); -+} -+ -+static inline void -+_goboringcrypto_HMAC_CTX_free(HMAC_CTX *ctx) -+{ -+ _goboringcrypto_internal_HMAC_CTX_free(ctx); -+} -+ -+static inline size_t -+_goboringcrypto_HMAC_size(const GO_HMAC_CTX* arg0) -+{ -+ const EVP_MD* md = _goboringcrypto_internal_HMAC_CTX_get_md(arg0); -+ return _goboringcrypto_internal_EVP_MD_get_size(md); -+} -+ -+static inline GO_HMAC_CTX* -+_goboringcrypto_HMAC_CTX_new(void) ++go_openssl_EVP_DecryptUpdate_wrapper(GO_EVP_CIPHER_CTX_PTR ctx, unsigned char *out, const unsigned char *in, int in_len) +{ -+ return _goboringcrypto_internal_HMAC_CTX_new(); -+} -+ -+static inline void -+_goboringcrypto_HMAC_CTX_reset(GO_HMAC_CTX* ctx) -+{ -+ _goboringcrypto_internal_HMAC_CTX_reset(ctx); -+} -+ -+static inline unsigned int -+_goboringcrypto_BN_num_bytes(const GO_BIGNUM* a) -+{ -+ return ((_goboringcrypto_internal_BN_num_bits(a)+7)/8); ++ int len; ++ return go_openssl_EVP_DecryptUpdate(ctx, out, &len, in, in_len); +} + +static inline int -+_goboringcrypto_RSA_set0_factors(GO_RSA * r, GO_BIGNUM *p, GO_BIGNUM *q) ++go_openssl_EVP_CipherUpdate_wrapper(GO_EVP_CIPHER_CTX_PTR ctx, unsigned char *out, const unsigned char *in, int in_len) +{ -+ return _goboringcrypto_internal_RSA_set0_factors(r, p, q); ++ int len; ++ return go_openssl_EVP_CipherUpdate(ctx, out, &len, in, in_len); +} + -+static inline int -+_goboringcrypto_RSA_set0_crt_params(GO_RSA * r, GO_BIGNUM *dmp1, GO_BIGNUM *dmq1, GO_BIGNUM *iqmp) -+{ -+ return _goboringcrypto_internal_RSA_set0_crt_params(r, dmp1, dmq1, iqmp); -+} + -+static inline void -+_goboringcrypto_RSA_get0_crt_params(const GO_RSA *r, const GO_BIGNUM **dmp1, const GO_BIGNUM **dmq1, const GO_BIGNUM **iqmp) -+{ -+ _goboringcrypto_internal_RSA_get0_crt_params(r, dmp1, dmq1, iqmp); -+} ++// These wrappers allocate out_len on the C stack, and check that it matches the expected ++// value, to avoid having to pass a pointer from Go, which would escape to the heap. + +static inline int -+_goboringcrypto_RSA_set0_key(GO_RSA * r, GO_BIGNUM *n, GO_BIGNUM *e, GO_BIGNUM *d) ++go_openssl_EVP_CIPHER_CTX_seal_wrapper(const GO_EVP_CIPHER_CTX_PTR ctx, ++ unsigned char *out, ++ const unsigned char *nonce, ++ const unsigned char *in, int in_len, ++ const unsigned char *add, int add_len) +{ -+ return _goboringcrypto_internal_RSA_set0_key(r, n, e, d); -+} ++ if (go_openssl_EVP_CipherInit_ex(ctx, NULL, NULL, NULL, nonce, GO_AES_ENCRYPT) != 1) ++ return 0; + -+static inline void -+_goboringcrypto_RSA_get0_factors(const GO_RSA *rsa, const GO_BIGNUM **p, const GO_BIGNUM **q) -+{ -+ _goboringcrypto_internal_RSA_get0_factors(rsa, p, q); -+} ++ int discard_len, out_len; ++ if (go_openssl_EVP_EncryptUpdate(ctx, NULL, &discard_len, add, add_len) != 1 ++ || go_openssl_EVP_EncryptUpdate(ctx, out, &out_len, in, in_len) != 1 ++ || go_openssl_EVP_EncryptFinal_ex(ctx, out + out_len, &discard_len) != 1) ++ { ++ return 0; ++ } + -+static inline void -+_goboringcrypto_RSA_get0_key(const GO_RSA *rsa, const GO_BIGNUM **n, const GO_BIGNUM **e, const GO_BIGNUM **d) -+{ -+ _goboringcrypto_internal_RSA_get0_key(rsa, n, e, d); -+} ++ if (in_len != out_len) ++ return 0; + -+static inline int -+_goboringcrypto_EVP_PKEY_CTX_set_rsa_padding(GO_EVP_PKEY_CTX* ctx, int pad) -+{ -+ return _goboringcrypto_internal_RSA_pkey_ctx_ctrl(ctx, -1, EVP_PKEY_CTRL_RSA_PADDING, pad, NULL); -+} ++ return go_openssl_EVP_CIPHER_CTX_ctrl(ctx, GO_EVP_CTRL_GCM_GET_TAG, 16, out + out_len); ++}; + +static inline int -+_goboringcrypto_EVP_PKEY_CTX_set0_rsa_oaep_label(GO_EVP_PKEY_CTX *ctx, uint8_t *l, int llen) ++go_openssl_EVP_CIPHER_CTX_open_wrapper(const GO_EVP_CIPHER_CTX_PTR ctx, ++ unsigned char *out, ++ const unsigned char *nonce, ++ const unsigned char *in, int in_len, ++ const unsigned char *add, int add_len, ++ const unsigned char *tag) +{ -+ return _goboringcrypto_internal_EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, EVP_PKEY_CTRL_RSA_OAEP_LABEL, llen, (void *)l); -+} ++ if (go_openssl_EVP_CipherInit_ex(ctx, NULL, NULL, NULL, nonce, GO_AES_DECRYPT) != 1) ++ return 0; + -+static inline int -+_goboringcrypto_EVP_PKEY_CTX_set_rsa_oaep_md(GO_EVP_PKEY_CTX *ctx, const GO_EVP_MD *md) -+{ -+ return _goboringcrypto_internal_EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, EVP_PKEY_CTRL_RSA_OAEP_MD, 0, (void *)md); -+} ++ int discard_len, out_len; ++ if (go_openssl_EVP_DecryptUpdate(ctx, NULL, &discard_len, add, add_len) != 1 ++ || go_openssl_EVP_DecryptUpdate(ctx, out, &out_len, in, in_len) != 1) ++ { ++ return 0; ++ } + -+static inline int -+_goboringcrypto_EVP_PKEY_CTX_set_rsa_pss_saltlen(GO_EVP_PKEY_CTX * arg0, int arg1) -+{ -+ return _goboringcrypto_internal_EVP_PKEY_CTX_ctrl(arg0, EVP_PKEY_RSA, -+ (EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), -+ EVP_PKEY_CTRL_RSA_PSS_SALTLEN, -+ arg1, NULL); -+} ++ if (go_openssl_EVP_CIPHER_CTX_ctrl(ctx, GO_EVP_CTRL_GCM_SET_TAG, 16, (unsigned char *)(tag)) != 1) ++ return 0; + -+static inline int -+_goboringcrypto_EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) -+{ -+ return _goboringcrypto_internal_EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, EVP_PKEY_CTRL_MD, 0, (void *)md); -+} ++ if (go_openssl_EVP_DecryptFinal_ex(ctx, out + out_len, &discard_len) != 1) ++ return 0; ++ ++ if (out_len != in_len) ++ return 0; ++ ++ return 1; ++}; +\ No newline at end of file diff --git a/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/hmac.go b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/hmac.go new file mode 100644 -index 0000000000..0582201ac9 +index 00000000000..204c94cd94f --- /dev/null +++ b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/hmac.go -@@ -0,0 +1,162 @@ +@@ -0,0 +1,147 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + @@ -1564,55 +1350,14 @@ index 0000000000..0582201ac9 +// #include "goopenssl.h" +import "C" +import ( -+ "crypto" + "hash" + "runtime" + "unsafe" +) + -+// hashToMD converts a hash.Hash implementation from this package -+// to a BoringCrypto *C.GO_EVP_MD. -+func hashToMD(h hash.Hash) *C.GO_EVP_MD { -+ switch h.(type) { -+ case *sha1Hash: -+ return C._goboringcrypto_EVP_sha1() -+ case *sha224Hash: -+ return C._goboringcrypto_EVP_sha224() -+ case *sha256Hash: -+ return C._goboringcrypto_EVP_sha256() -+ case *sha384Hash: -+ return C._goboringcrypto_EVP_sha384() -+ case *sha512Hash: -+ return C._goboringcrypto_EVP_sha512() -+ } -+ return nil -+} -+ -+// cryptoHashToMD converts a crypto.Hash -+// to a BoringCrypto *C.GO_EVP_MD. -+func cryptoHashToMD(ch crypto.Hash) *C.GO_EVP_MD { -+ switch ch { -+ case crypto.MD5: -+ return C._goboringcrypto_EVP_md5() -+ case crypto.MD5SHA1: -+ return C._goboringcrypto_EVP_md5_sha1() -+ case crypto.SHA1: -+ return C._goboringcrypto_EVP_sha1() -+ case crypto.SHA224: -+ return C._goboringcrypto_EVP_sha224() -+ case crypto.SHA256: -+ return C._goboringcrypto_EVP_sha256() -+ case crypto.SHA384: -+ return C._goboringcrypto_EVP_sha384() -+ case crypto.SHA512: -+ return C._goboringcrypto_EVP_sha512() -+ } -+ return nil -+} -+ -+// NewHMAC returns a new HMAC using BoringCrypto. ++// NewHMAC returns a new HMAC using OpenSSL. +// The function h must return a hash implemented by -+// BoringCrypto (for example, h could be boring.NewSHA256). ++// OpenSSL (for example, h could be openssl.NewSHA256). +// If h is not recognized, NewHMAC returns nil. +func NewHMAC(h func() hash.Hash, key []byte) hash.Hash { + ch := h() @@ -1622,83 +1367,73 @@ index 0000000000..0582201ac9 + } + + var hkey []byte -+ if key != nil && len(key) > 0 { ++ if len(key) > 0 { + // Note: Could hash down long keys here using EVP_Digest. + hkey = make([]byte, len(key)) + copy(hkey, key) + } else { -+ // This is supported in BoringSSL/Standard lib and as such ++ // This is supported in OpenSSL/Standard lib and as such + // we must support it here. When using HMAC with a null key + // HMAC_Init will try and reuse the key from the ctx. This is + // not the bahavior previously implemented, so as a workaround + // we pass an "empty" key. -+ hkey = make([]byte, C.EVP_MAX_MD_SIZE) ++ hkey = make([]byte, C.GO_EVP_MAX_MD_SIZE) + } -+ hmac := &boringHMAC{ ++ hmac := &opensslHMAC{ + md: md, + size: ch.Size(), + blockSize: ch.BlockSize(), + key: hkey, -+ ctx: C._goboringcrypto_HMAC_CTX_new(), ++ ctx: hmacCtxNew(), + } + hmac.Reset() + return hmac +} + -+type boringHMAC struct { -+ md *C.GO_EVP_MD -+ ctx *C.GO_HMAC_CTX -+ ctx2 *C.GO_HMAC_CTX -+ size int -+ blockSize int -+ key []byte -+ sum []byte -+ needCleanup bool ++type opensslHMAC struct { ++ md C.GO_EVP_MD_PTR ++ ctx C.GO_HMAC_CTX_PTR ++ size int ++ blockSize int ++ key []byte ++ sum []byte +} + -+func (h *boringHMAC) Reset() { -+ if !h.needCleanup { -+ h.needCleanup = true -+ // Note: Because of the finalizer, any time h.ctx is passed to cgo, -+ // that call must be followed by a call to runtime.KeepAlive(h), -+ // to make sure h is not collected (and finalized) before the cgo -+ // call returns. -+ runtime.SetFinalizer(h, (*boringHMAC).finalize) -+ } -+ C._goboringcrypto_HMAC_CTX_reset(h.ctx) ++func (h *opensslHMAC) Reset() { ++ hmacCtxReset(h.ctx) + -+ if C._goboringcrypto_HMAC_Init_ex(h.ctx, unsafe.Pointer(base(h.key)), C.int(len(h.key)), h.md, nil) == 0 { -+ panic("boringcrypto: HMAC_Init failed") ++ if C.go_openssl_HMAC_Init_ex(h.ctx, unsafe.Pointer(&h.key[0]), C.int(len(h.key)), h.md, nil) == 0 { ++ panic("openssl: HMAC_Init failed") + } -+ if int(C._goboringcrypto_HMAC_size(h.ctx)) != h.size { -+ println("boringcrypto: HMAC size:", C._goboringcrypto_HMAC_size(h.ctx), "!=", h.size) -+ panic("boringcrypto: HMAC size mismatch") ++ if size := C.go_openssl_EVP_MD_get_size(h.md); size != C.int(h.size) { ++ println("openssl: HMAC size:", size, "!=", h.size) ++ panic("openssl: HMAC size mismatch") + } + runtime.KeepAlive(h) // Next line will keep h alive too; just making doubly sure. + h.sum = nil +} + -+func (h *boringHMAC) finalize() { -+ C._goboringcrypto_HMAC_CTX_free(h.ctx) ++func (h *opensslHMAC) finalize() { ++ hmacCtxFree(h.ctx) +} + -+func (h *boringHMAC) Write(p []byte) (int, error) { ++func (h *opensslHMAC) Write(p []byte) (int, error) { + if len(p) > 0 { -+ C._goboringcrypto_HMAC_Update(h.ctx, (*C.uint8_t)(unsafe.Pointer(&p[0])), C.size_t(len(p))) ++ C.go_openssl_HMAC_Update(h.ctx, base(p), C.size_t(len(p))) + } + runtime.KeepAlive(h) + return len(p), nil +} + -+func (h *boringHMAC) Size() int { ++func (h *opensslHMAC) Size() int { + return h.size +} + -+func (h *boringHMAC) BlockSize() int { ++func (h *opensslHMAC) BlockSize() int { + return h.blockSize +} + -+func (h *boringHMAC) Sum(in []byte) []byte { ++func (h *opensslHMAC) Sum(in []byte) []byte { + if h.sum == nil { + size := h.Size() + h.sum = make([]byte, size) @@ -1707,17 +1442,53 @@ index 0000000000..0582201ac9 + // that Sum has no effect on the underlying stream. + // In particular it is OK to Sum, then Write more, then Sum again, + // and the second Sum acts as if the first didn't happen. -+ h.ctx2 = C._goboringcrypto_HMAC_CTX_new() -+ if C._goboringcrypto_HMAC_CTX_copy_ex(h.ctx2, h.ctx) == 0 { -+ panic("boringcrypto: HMAC_CTX_copy_ex failed") ++ ctx2 := hmacCtxNew() ++ defer hmacCtxFree(ctx2) ++ if C.go_openssl_HMAC_CTX_copy(ctx2, h.ctx) == 0 { ++ panic("openssl: HMAC_CTX_copy failed") + } -+ C._goboringcrypto_HMAC_Final(h.ctx2, (*C.uint8_t)(unsafe.Pointer(&h.sum[0])), nil) -+ C._goboringcrypto_HMAC_CTX_free(h.ctx2) ++ C.go_openssl_HMAC_Final(ctx2, base(h.sum), nil) + return append(in, h.sum...) +} ++ ++func hmacCtxNew() C.GO_HMAC_CTX_PTR { ++ if vMajor == 1 && vMinor == 0 { ++ // 0x120 is the sizeof value when building against OpenSSL 1.0.2 on Ubuntu 16.04. ++ ctx := (C.GO_HMAC_CTX_PTR)(C.malloc(0x120)) ++ if ctx != nil { ++ C.go_openssl_HMAC_CTX_init(ctx) ++ } ++ return ctx ++ } ++ return C.go_openssl_HMAC_CTX_new() ++} ++ ++func hmacCtxReset(ctx C.GO_HMAC_CTX_PTR) { ++ if ctx == nil { ++ return ++ } ++ if vMajor == 1 && vMinor == 0 { ++ C.go_openssl_HMAC_CTX_cleanup(ctx) ++ C.go_openssl_HMAC_CTX_init(ctx) ++ return ++ } ++ C.go_openssl_HMAC_CTX_reset(ctx) ++} ++ ++func hmacCtxFree(ctx C.GO_HMAC_CTX_PTR) { ++ if ctx == nil { ++ return ++ } ++ if vMajor == 1 && vMinor == 0 { ++ C.go_openssl_HMAC_CTX_cleanup(ctx) ++ C.free(unsafe.Pointer(ctx)) ++ return ++ } ++ C.go_openssl_HMAC_CTX_free(ctx) ++} diff --git a/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/internal/subtle/aliasing.go b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/internal/subtle/aliasing.go new file mode 100644 -index 0000000000..db09e4aae6 +index 00000000000..db09e4aae64 --- /dev/null +++ b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/internal/subtle/aliasing.go @@ -0,0 +1,32 @@ @@ -1755,64 +1526,228 @@ index 0000000000..db09e4aae6 +} diff --git a/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/openssl.go b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/openssl.go new file mode 100644 -index 0000000000..fe13f92531 +index 00000000000..2c354e1df0f --- /dev/null +++ b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/openssl.go -@@ -0,0 +1,107 @@ +@@ -0,0 +1,260 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +//go:build linux && !android +// +build linux,!android + -+// Package openssl provides access to OpenSSLCrypto implementation functions. -+// Check the constant Enabled to find out whether OpenSSLCrypto is available. -+// If OpenSSLCrypto is not available, the functions in this package all panic. ++// Package openssl provides access to OpenSSL cryptographic functions. +package openssl + +// #include "goopenssl.h" ++// #include +// #cgo LDFLAGS: -ldl +import "C" +import ( + "errors" + "math/big" -+ "runtime" ++ "strconv" + "strings" ++ "sync" ++ "syscall" ++ "unsafe" ++) ++ ++var ( ++ providerNameFips = C.CString("fips") ++ providerNameDefault = C.CString("default") ++ propFipsYes = C.CString("fips=yes") ++ propFipsNo = C.CString("fips=no") ++ algProve = C.CString("SHA2-256") ++) ++ ++var ( ++ initOnce sync.Once ++ // errInit is set when first calling Init(). ++ errInit error ++ // vMajor and vMinor hold the major/minor OpenSSL version. ++ // It is only populated if Init has been called. ++ vMajor, vMinor int +) + ++// knownVersions is a list of supported and well-known libcrypto.so suffixes in decreasing version order. ++// ++// FreeBSD library version numbering does not directly align to the version of OpenSSL. ++// Its preferred search order is 11 -> 111. ++// ++// Some distributions use 1.0.0 and others (such as Debian) 1.0.2 to refer to the same OpenSSL 1.0.2 version. ++// ++// Fedora derived distros use different naming for the version 1.0.x. ++var knownVersions = [...]string{"3", "1.1", "11", "111", "1.0.2", "1.0.0", "10"} ++ ++func errUnsuportedVersion() error { ++ return errors.New("openssl: OpenSSL version: " + strconv.Itoa(vMajor) + "." + strconv.Itoa(vMinor)) ++} ++ +// Init loads and initializes OpenSSL. +// It must be called before any other OpenSSL call. ++// ++// Only the first call to Init is effective, ++// subsequent calls will return the same error result as the one from the first call. ++// ++// If GO_OPENSSL_VERSION_OVERRIDE environment variable is not empty, its value will be appended to the OpenSSL shared library name ++// as a version suffix when calling dlopen. For example, "GO_OPENSSL_VERSION_OVERRIDE=1.1.1k-fips" ++// makes Init look for the shared library libcrypto.so.1.1.1k-fips. ++// If GO_OPENSSL_VERSION_OVERRIDE environment variable is empty, Init will try to load the OpenSSL shared library ++// using a list if supported and well-known version suffixes, going from higher to lower versions. +func Init() error { -+ runtime.LockOSThread() -+ defer runtime.UnlockOSThread() ++ initOnce.Do(func() { ++ version, _ := syscall.Getenv("GO_OPENSSL_VERSION_OVERRIDE") ++ handle, err := loadLibrary(version) ++ if err != nil { ++ errInit = err ++ return ++ } ++ ++ vMajor = int(C.go_openssl_version_major(handle)) ++ vMinor = int(C.go_openssl_version_minor(handle)) ++ if vMajor == -1 || vMinor == -1 { ++ errInit = errors.New("openssl: can't retrieve OpenSSL version") ++ return ++ } ++ var supported bool ++ if vMajor == 1 { ++ supported = vMinor == 0 || vMinor == 1 ++ } else if vMajor == 3 { ++ // OpenSSL team guarantees API and ABI compatibility within the same major version since OpenSSL 3. ++ supported = true ++ } ++ if !supported { ++ errInit = errUnsuportedVersion() ++ return ++ } ++ ++ C.go_openssl_load_functions(handle, C.int(vMajor), C.int(vMinor)) ++ C.go_openssl_OPENSSL_init() ++ if vMajor == 1 && vMinor == 0 { ++ if C.go_openssl_thread_setup() != 1 { ++ errInit = newOpenSSLError("openssl: thread setup") ++ return ++ } ++ C.go_openssl_OPENSSL_add_all_algorithms_conf() ++ C.go_openssl_ERR_load_crypto_strings() ++ } else { ++ flags := C.uint64_t(C.GO_OPENSSL_INIT_ADD_ALL_CIPHERS | C.GO_OPENSSL_INIT_ADD_ALL_DIGESTS | C.GO_OPENSSL_INIT_LOAD_CONFIG | C.GO_OPENSSL_INIT_LOAD_CRYPTO_STRINGS) ++ if C.go_openssl_OPENSSL_init_crypto(flags, nil) != 1 { ++ errInit = newOpenSSLError("openssl: init crypto") ++ return ++ } ++ } ++ }) ++ return errInit ++} + -+ if C._goboringcrypto_DLOPEN_OPENSSL() == C.NULL { -+ return errors.New("boringcrypto: OpenSSL dlopen failed") ++func dlopen(version string) unsafe.Pointer { ++ cv := C.CString("libcrypto.so." + version) ++ defer C.free(unsafe.Pointer(cv)) ++ return C.dlopen(cv, C.RTLD_LAZY|C.RTLD_LOCAL) ++} ++ ++func loadLibrary(version string) (unsafe.Pointer, error) { ++ if version != "" { ++ // If version is specified try to load it or error out. ++ handle := dlopen(version) ++ if handle == nil { ++ errstr := C.GoString(C.dlerror()) ++ return nil, errors.New("openssl: can't load libcrypto.so." + version + ": " + errstr) ++ } ++ return handle, nil ++ } ++ for _, v := range knownVersions { ++ handle := dlopen(v) ++ if handle != nil { ++ return handle, nil ++ } + } ++ return nil, errors.New("openssl: can't load libcrypto.so using any known version suffix") ++} + -+ if C._goboringcrypto_OPENSSL_setup() != 1 { -+ return errors.New("boringcrypto: OpenSSL setup failed") ++// providerAvailable looks through provider's digests ++// checking if there is any that matches the props query. ++func providerAvailable(props *C.char) bool { ++ C.go_openssl_ERR_set_mark() ++ md := C.go_openssl_EVP_MD_fetch(nil, algProve, props) ++ C.go_openssl_ERR_pop_to_mark() ++ if md == nil { ++ return false + } -+ return nil ++ C.go_openssl_EVP_MD_free(md) ++ return true +} + +// FIPS returns true if OpenSSL is running in FIPS mode, else returns false. +func FIPS() bool { -+ return C._goboringcrypto_FIPS_mode() == 1 ++ switch vMajor { ++ case 1: ++ return C.go_openssl_FIPS_mode() == 1 ++ case 3: ++ if C.go_openssl_EVP_default_properties_is_fips_enabled(nil) == 0 { ++ return false ++ } ++ // EVP_default_properties_is_fips_enabled can return true even if the FIPS provider isn't loaded, ++ // it is only based on the default properties. ++ return providerAvailable(propFipsYes) ++ default: ++ panic(errUnsuportedVersion()) ++ } +} + +// SetFIPS enables or disables FIPS mode. ++// ++// It implements the following provider fallback logic for OpenSSL 3: ++// - The "fips" provider is loaded if enabled=true and no loaded provider matches "fips=yes". ++// - The "default" provider is loaded if enabled=false and no loaded provider matches "fips=no". ++// This logic allows advanced users to define their own providers that match "fips=yes" and "fips=no" using the OpenSSL config file. +func SetFIPS(enabled bool) error { -+ var mode C.int -+ if enabled { -+ mode = C.int(1) -+ } else { -+ mode = C.int(0) -+ } -+ if C._goboringcrypto_FIPS_mode_set(mode) != 1 { -+ return newOpenSSLError("boringcrypto: set FIPS mode") ++ switch vMajor { ++ case 1: ++ var mode C.int ++ if enabled { ++ mode = C.int(1) ++ } else { ++ mode = C.int(0) ++ } ++ if C.go_openssl_FIPS_mode_set(mode) != 1 { ++ return newOpenSSLError("openssl: FIPS_mode_set") ++ } ++ return nil ++ case 3: ++ var props, provName *C.char ++ if enabled { ++ props = propFipsYes ++ provName = providerNameFips ++ } else { ++ props = propFipsNo ++ provName = providerNameDefault ++ } ++ // Check if there is any provider that matches props. ++ if !providerAvailable(props) { ++ // If not, fallback to provName provider. ++ if C.go_openssl_OSSL_PROVIDER_load(nil, provName) == nil { ++ return newOpenSSLError("openssl: OSSL_PROVIDER_try_load") ++ } ++ // Make sure we now have a provider available. ++ if !providerAvailable(props) { ++ return fail("SetFIPS(" + strconv.FormatBool(enabled) + ") not supported") ++ } ++ } ++ if C.go_openssl_EVP_set_default_properties(nil, props) != 1 { ++ return newOpenSSLError("openssl: EVP_set_default_properties") ++ } ++ return nil ++ default: ++ panic(errUnsuportedVersion()) + } -+ return nil ++} ++ ++// VersionText returns the version text of the OpenSSL currently loaded. ++func VersionText() string { ++ return C.GoString(C.go_openssl_OpenSSL_version(0)) +} + +func newOpenSSLError(msg string) error { @@ -1823,12 +1758,12 @@ index 0000000000..fe13f92531 + b.WriteString("\nopenssl error(s):\n") + + for { -+ e = C._goboringcrypto_ERR_get_error() ++ e = C.go_openssl_ERR_get_error() + if e == 0 { + break + } + var buf [256]byte -+ C._goboringcrypto_ERR_error_string_n(e, base(buf[:]), 256) ++ C.go_openssl_ERR_error_string_n(e, (*C.char)(unsafe.Pointer(&buf[0])), 256) + b.Write(buf[:]) + b.WriteByte('\n') + } @@ -1837,48 +1772,113 @@ index 0000000000..fe13f92531 + +type fail string + -+func (e fail) Error() string { return "boringcrypto: " + string(e) + " failed" } ++func (e fail) Error() string { return "openssl: " + string(e) + " failed" } + -+func bigToBN(x *big.Int) *C.GO_BIGNUM { ++func bigToBN(x *big.Int) C.GO_BIGNUM_PTR { ++ if x == nil { ++ return nil ++ } + raw := x.Bytes() -+ return C._goboringcrypto_BN_bin2bn(base(raw), C.size_t(len(raw)), nil) -+} -+ -+func bnToBig(bn *C.GO_BIGNUM) *big.Int { -+ raw := make([]byte, C._goboringcrypto_BN_num_bytes(bn)) -+ n := C._goboringcrypto_BN_bn2bin(bn, base(raw)) -+ return new(big.Int).SetBytes(raw[:n]) ++ return C.go_openssl_BN_bin2bn(base(raw), C.int(len(raw)), nil) +} + -+func bigToBn(bnp **C.GO_BIGNUM, b *big.Int) bool { -+ if *bnp != nil { -+ C._goboringcrypto_BN_free(*bnp) -+ *bnp = nil -+ } -+ if b == nil { -+ return true -+ } -+ raw := b.Bytes() -+ bn := C._goboringcrypto_BN_bin2bn(base(raw), C.size_t(len(raw)), nil) ++func bnToBig(bn C.GO_BIGNUM_PTR) *big.Int { + if bn == nil { -+ return false ++ return nil + } -+ *bnp = bn -+ return true ++ raw := make([]byte, (C.go_openssl_BN_num_bits(bn)+7)/8) ++ n := C.go_openssl_BN_bn2bin(bn, base(raw)) ++ return new(big.Int).SetBytes(raw[:n]) +} diff --git a/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/openssl_funcs.h b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/openssl_funcs.h new file mode 100644 -index 0000000000..bec47b8783 +index 00000000000..95024cf8ecb --- /dev/null +++ b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/openssl_funcs.h -@@ -0,0 +1,215 @@ +@@ -0,0 +1,242 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + ++// To make this header standalone (so that building Go does not require ++// having a full set of OpenSSL headers), the struct details are not here. ++// Instead, while testing the openssl module, we generate and compile a C program ++// that checks that the function signatures match the OpenSSL equivalents. ++// The generation of the checking program depends on the declaration ++// forms used below, which includes commented directives (#include, #if and #endif) ++// and comments starting with `check:`. ++ +#include // size_t -+#include // uint8_t ++#include // uint64_t ++ ++// #include ++enum { ++ GO_OPENSSL_INIT_LOAD_CRYPTO_STRINGS = 0x00000002L, ++ GO_OPENSSL_INIT_ADD_ALL_CIPHERS = 0x00000004L, ++ GO_OPENSSL_INIT_ADD_ALL_DIGESTS = 0x00000008L, ++ GO_OPENSSL_INIT_LOAD_CONFIG = 0x00000040L ++}; ++ ++// #include ++enum { ++ GO_AES_ENCRYPT = 1, ++ GO_AES_DECRYPT = 0 ++}; ++ ++// #include ++enum { ++ GO_EVP_CTRL_GCM_GET_TAG = 0x10, ++ GO_EVP_CTRL_GCM_SET_TAG = 0x11, ++ GO_EVP_PKEY_CTRL_MD = 1, ++ GO_EVP_PKEY_RSA = 6, ++ GO_EVP_PKEY_EC = 408, ++ GO_EVP_MAX_MD_SIZE = 64 ++}; ++ ++// #include ++enum { ++ GO_EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID = 0x1001 ++}; ++ ++// #include ++enum { ++ GO_NID_X9_62_prime256v1 = 415, ++ GO_NID_secp224r1 = 713, ++ GO_NID_secp384r1 = 715, ++ GO_NID_secp521r1 = 716 ++}; ++ ++// #include ++enum { ++ GO_RSA_PKCS1_PADDING = 1, ++ GO_RSA_NO_PADDING = 3, ++ GO_RSA_PKCS1_OAEP_PADDING = 4, ++ GO_RSA_PKCS1_PSS_PADDING = 6, ++ GO_EVP_PKEY_CTRL_RSA_PADDING = 0x1001, ++ GO_EVP_PKEY_CTRL_RSA_PSS_SALTLEN = 0x1002, ++ GO_EVP_PKEY_CTRL_RSA_KEYGEN_BITS = 0x1003, ++ GO_EVP_PKEY_CTRL_RSA_OAEP_MD = 0x1009, ++ GO_EVP_PKEY_CTRL_RSA_OAEP_LABEL = 0x100A ++}; + -+// List of all functions from the libcrypto that are used in the crypto/internal/boring. ++typedef void* GO_EVP_CIPHER_PTR; ++typedef void* GO_EVP_CIPHER_CTX_PTR; ++typedef void* GO_EVP_PKEY_PTR; ++typedef void* GO_EVP_PKEY_CTX_PTR; ++typedef void* GO_EVP_MD_PTR; ++typedef void* GO_EVP_MD_CTX_PTR; ++typedef void* GO_HMAC_CTX_PTR; ++typedef void* GO_OPENSSL_INIT_SETTINGS_PTR; ++typedef void* GO_OSSL_LIB_CTX_PTR; ++typedef void* GO_OSSL_PROVIDER_PTR; ++typedef void* GO_ENGINE_PTR; ++typedef void* GO_BIGNUM_PTR; ++typedef void* GO_BN_CTX_PTR; ++typedef void* GO_EC_KEY_PTR; ++typedef void* GO_EC_POINT_PTR; ++typedef void* GO_EC_GROUP_PTR; ++typedef void* GO_RSA_PTR; ++ ++// List of all functions from the libcrypto that are used in this package. +// Forgetting to add a function here results in build failure with message reporting the function +// that needs to be added. +// @@ -1890,206 +1890,157 @@ index 0000000000..bec47b8783 +// they are not resolved here but just accumulated in FOR_ALL_OPENSSL_FUNCTIONS. +// +// DEFINEFUNC defines and loads openssl functions that can be directly called from Go as their signatures match -+// the boringssl and do not require special logic. -+// The process will be aborted if the function can't be loaded. -+// -+// DEFINEFUNCINTERNAL defines and loads openssl functions that will be wrapped due to signature incompatibility or -+// because it does not exist in all supported openssl versions. ++// the OpenSSL API and do not require special logic. +// The process will be aborted if the function can't be loaded. +// -+// DEFINEFUNC_LEGACY acts like DEFINEFUNCINTERNAL but only aborts the process if the function can't be loaded ++// DEFINEFUNC_LEGACY_1_0 acts like DEFINEFUNC but only aborts the process if the function can't be loaded +// when using 1.0.x. This indicates the function is required when using 1.0.x, but is unused when using later versions. +// It also might not exist in later versions. +// -+// DEFINEFUNC_110 acts like DEFINEFUNCINTERNAL but only aborts the process if function can't be loaded ++// DEFINEFUNC_LEGACY_1 acts like DEFINEFUNC but only aborts the process if the function can't be loaded ++// when using 1.x. This indicates the function is required when using 1.x, but is unused when using later versions. ++// It also might not exist in later versions. ++// ++// DEFINEFUNC_1_1 acts like DEFINEFUNC but only aborts the process if function can't be loaded +// when using 1.1.0 or higher. +// -+// DEFINEFUNC_RENAMED acts like DEFINEFUNCINTERNAL but if the function can't be loaded it will try with another -+// function name, as in some version jumps openssl has renamed functions without changing the signature. -+// The process will be aborted if neither function can be loaded. ++// DEFINEFUNC_3_0 acts like DEFINEFUNC but only aborts the process if function can't be loaded ++// when using 3.0.0 or higher. ++// ++// DEFINEFUNC_RENAMED_1_1 acts like DEFINEFUNC but tries to load the function using the new name when using >= 1.1.x ++// and the old name when using 1.0.2. In both cases the function will have the new name. +// ++// DEFINEFUNC_RENAMED_3_0 acts like DEFINEFUNC but tries to load the function using the new name when using >= 3.x ++// and the old name when using 1.x. In both cases the function will have the new name. ++// ++// #include ++// #include ++// #include ++// #include ++// #include ++// #include ++// #include ++// #if OPENSSL_VERSION_NUMBER >= 0x30000000L ++// #include ++// #endif +#define FOR_ALL_OPENSSL_FUNCTIONS \ ++DEFINEFUNC(int, ERR_set_mark, (void), ()) \ ++DEFINEFUNC(int, ERR_pop_to_mark, (void), ()) \ +DEFINEFUNC(unsigned long, ERR_get_error, (void), ()) \ -+DEFINEFUNC(void, ERR_error_string_n, (unsigned long e, unsigned char *buf, size_t len), (e, buf, len)) \ -+DEFINEFUNCINTERNAL(int, RAND_poll, (void), ()) \ -+DEFINEFUNCINTERNAL(void, OPENSSL_init, (void), ()) \ -+DEFINEFUNC_LEGACY(void, ERR_load_crypto_strings, (void), ()) \ -+DEFINEFUNC_LEGACY(int, CRYPTO_num_locks, (void), ()) \ -+DEFINEFUNC_LEGACY(void, CRYPTO_set_id_callback, (unsigned long (*id_function)(void)), (id_function)) \ -+DEFINEFUNC_LEGACY(void, CRYPTO_set_locking_callback, \ -+ (void (*locking_function)(int mode, int n, const char *file, int line)), \ -+ (locking_function)) \ -+DEFINEFUNC_LEGACY(void, OPENSSL_add_all_algorithms_conf, (void), ()) \ -+DEFINEFUNC_110(int, OPENSSL_init_crypto, (uint64_t ops, const void *settings), (ops, settings)) \ -+DEFINEFUNC(int, FIPS_mode, (void), ()) \ -+DEFINEFUNC(int, FIPS_mode_set, (int r), (r)) \ -+DEFINEFUNC(int, RAND_bytes, (uint8_t * arg0, size_t arg1), (arg0, arg1)) \ -+DEFINEFUNC(int, SHA1_Init, (GO_SHA_CTX * arg0), (arg0)) \ -+DEFINEFUNC(int, SHA1_Update, (GO_SHA_CTX * arg0, const void *arg1, size_t arg2), (arg0, arg1, arg2)) \ -+DEFINEFUNC(int, SHA1_Final, (uint8_t * arg0, GO_SHA_CTX *arg1), (arg0, arg1)) \ -+DEFINEFUNC(int, SHA224_Init, (GO_SHA256_CTX * arg0), (arg0)) \ -+DEFINEFUNC(int, SHA224_Update, (GO_SHA256_CTX * arg0, const void *arg1, size_t arg2), (arg0, arg1, arg2)) \ -+DEFINEFUNC(int, SHA224_Final, (uint8_t * arg0, GO_SHA256_CTX *arg1), (arg0, arg1)) \ -+DEFINEFUNC(int, SHA256_Init, (GO_SHA256_CTX * arg0), (arg0)) \ -+DEFINEFUNC(int, SHA256_Update, (GO_SHA256_CTX * arg0, const void *arg1, size_t arg2), (arg0, arg1, arg2)) \ -+DEFINEFUNC(int, SHA256_Final, (uint8_t * arg0, GO_SHA256_CTX *arg1), (arg0, arg1)) \ -+DEFINEFUNC(int, SHA384_Init, (GO_SHA512_CTX * arg0), (arg0)) \ -+DEFINEFUNC(int, SHA384_Update, (GO_SHA512_CTX * arg0, const void *arg1, size_t arg2), (arg0, arg1, arg2)) \ -+DEFINEFUNC(int, SHA384_Final, (uint8_t * arg0, GO_SHA512_CTX *arg1), (arg0, arg1)) \ -+DEFINEFUNC(int, SHA512_Init, (GO_SHA512_CTX * arg0), (arg0)) \ -+DEFINEFUNC(int, SHA512_Update, (GO_SHA512_CTX * arg0, const void *arg1, size_t arg2), (arg0, arg1, arg2)) \ -+DEFINEFUNC(int, SHA512_Final, (uint8_t * arg0, GO_SHA512_CTX *arg1), (arg0, arg1)) \ -+DEFINEFUNC(const GO_EVP_MD *, EVP_md5, (void), ()) \ -+DEFINEFUNC(const GO_EVP_MD *, EVP_sha1, (void), ()) \ -+DEFINEFUNC(const GO_EVP_MD *, EVP_sha224, (void), ()) \ -+DEFINEFUNC(const GO_EVP_MD *, EVP_sha256, (void), ()) \ -+DEFINEFUNC(const GO_EVP_MD *, EVP_sha384, (void), ()) \ -+DEFINEFUNC(const GO_EVP_MD *, EVP_sha512, (void), ()) \ -+DEFINEFUNC_RENAMED(int, EVP_MD_get_type, EVP_MD_type, (const GO_EVP_MD *arg0), (arg0)) \ -+DEFINEFUNC_RENAMED(size_t, EVP_MD_get_size, EVP_MD_size, (const GO_EVP_MD *arg0), (arg0)) \ -+DEFINEFUNC_FALLBACK(const GO_EVP_MD*, EVP_md5_sha1, (void), ()) \ -+DEFINEFUNC_FALLBACK(void*, EVP_MD_CTX_md_data, (EVP_MD_CTX *ctx), (ctx)) \ -+DEFINEFUNCINTERNAL(int, MD5_Init, (MD5_CTX *c), (c)) \ -+DEFINEFUNCINTERNAL(int, MD5_Update, (MD5_CTX *c, const void *data, size_t len), (c, data, len)) \ -+DEFINEFUNCINTERNAL(int, MD5_Final, (unsigned char *md, MD5_CTX *c), (md, c)) \ -+DEFINEFUNC_LEGACY(void, HMAC_CTX_init, (GO_HMAC_CTX * arg0), (arg0)) \ -+DEFINEFUNC_LEGACY(void, HMAC_CTX_cleanup, (GO_HMAC_CTX * arg0), (arg0)) \ -+DEFINEFUNC(int, HMAC_Init_ex, \ -+ (GO_HMAC_CTX * arg0, const void *arg1, int arg2, const GO_EVP_MD *arg3, ENGINE *arg4), \ -+ (arg0, arg1, arg2, arg3, arg4)) \ -+DEFINEFUNC(int, HMAC_Update, (GO_HMAC_CTX * arg0, const uint8_t *arg1, size_t arg2), (arg0, arg1, arg2)) \ -+DEFINEFUNC(int, HMAC_Final, (GO_HMAC_CTX * arg0, uint8_t *arg1, unsigned int *arg2), (arg0, arg1, arg2)) \ -+DEFINEFUNC(size_t, HMAC_CTX_copy, (GO_HMAC_CTX *dest, GO_HMAC_CTX *src), (dest, src)) \ -+DEFINEFUNC_FALLBACK(void, HMAC_CTX_free, (GO_HMAC_CTX * arg0), (arg0)) \ -+DEFINEFUNC_FALLBACK(const EVP_MD*, HMAC_CTX_get_md, (const GO_HMAC_CTX* ctx), (ctx)) \ -+DEFINEFUNC_FALLBACK(GO_HMAC_CTX*, HMAC_CTX_new, (void), ()) \ -+DEFINEFUNC_FALLBACK(void, HMAC_CTX_reset, (GO_HMAC_CTX * arg0), (arg0)) \ -+DEFINEFUNC(EVP_CIPHER_CTX *, EVP_CIPHER_CTX_new, (void), ()) \ -+DEFINEFUNC(int, EVP_CIPHER_CTX_set_padding, (EVP_CIPHER_CTX *x, int padding), (x, padding)) \ -+DEFINEFUNC(int, EVP_CipherInit_ex, \ -+ (EVP_CIPHER_CTX * ctx, const EVP_CIPHER *type, ENGINE *impl, const unsigned char *key, const unsigned char *iv, int enc), \ -+ (ctx, type, impl, key, iv, enc)) \ -+DEFINEFUNC(int, EVP_CipherUpdate, \ -+ (EVP_CIPHER_CTX * ctx, unsigned char *out, int *outl, const unsigned char *in, int inl), \ -+ (ctx, out, outl, in, inl)) \ -+DEFINEFUNC(GO_BIGNUM *, BN_new, (void), ()) \ -+DEFINEFUNC(void, BN_free, (GO_BIGNUM * arg0), (arg0)) \ -+DEFINEFUNCINTERNAL(void, BN_clear_free, (GO_BIGNUM * arg0), (arg0)) \ -+DEFINEFUNC(int, BN_set_word, (GO_BIGNUM *a, BN_ULONG w), (a, w)) \ -+DEFINEFUNCINTERNAL(unsigned int, BN_num_bits, (const GO_BIGNUM *arg0), (arg0)) \ -+DEFINEFUNC(GO_BIGNUM *, BN_bin2bn, (const uint8_t *arg0, size_t arg1, GO_BIGNUM *arg2), (arg0, arg1, arg2)) \ -+DEFINEFUNC(size_t, BN_bn2bin, (const GO_BIGNUM *arg0, uint8_t *arg1), (arg0, arg1)) \ -+DEFINEFUNC(void, EC_GROUP_free, (GO_EC_GROUP * arg0), (arg0)) \ -+DEFINEFUNC(GO_EC_POINT *, EC_POINT_new, (const GO_EC_GROUP *arg0), (arg0)) \ -+DEFINEFUNC(void, EC_POINT_free, (GO_EC_POINT * arg0), (arg0)) \ -+DEFINEFUNC(int, EC_POINT_get_affine_coordinates_GFp, \ -+ (const GO_EC_GROUP *arg0, const GO_EC_POINT *arg1, GO_BIGNUM *arg2, GO_BIGNUM *arg3, GO_BN_CTX *arg4), \ -+ (arg0, arg1, arg2, arg3, arg4)) \ -+DEFINEFUNC(int, EC_POINT_set_affine_coordinates_GFp, \ -+ (const GO_EC_GROUP *arg0, GO_EC_POINT *arg1, const GO_BIGNUM *arg2, const GO_BIGNUM *arg3, GO_BN_CTX *arg4), \ -+ (arg0, arg1, arg2, arg3, arg4)) \ -+DEFINEFUNC(GO_EC_KEY *, EC_KEY_new_by_curve_name, (int arg0), (arg0)) \ -+DEFINEFUNC(void, EC_KEY_free, (GO_EC_KEY * arg0), (arg0)) \ -+DEFINEFUNC(const GO_EC_GROUP *, EC_KEY_get0_group, (const GO_EC_KEY *arg0), (arg0)) \ -+DEFINEFUNC(int, EC_KEY_generate_key, (GO_EC_KEY * arg0), (arg0)) \ -+DEFINEFUNC(int, EC_KEY_set_private_key, (GO_EC_KEY * arg0, const GO_BIGNUM *arg1), (arg0, arg1)) \ -+DEFINEFUNC(int, EC_KEY_set_public_key, (GO_EC_KEY * arg0, const GO_EC_POINT *arg1), (arg0, arg1)) \ -+DEFINEFUNC(const GO_BIGNUM *, EC_KEY_get0_private_key, (const GO_EC_KEY *arg0), (arg0)) \ -+DEFINEFUNC(const GO_EC_POINT *, EC_KEY_get0_public_key, (const GO_EC_KEY *arg0), (arg0)) \ -+DEFINEFUNC(int, ECDSA_do_verify, (const uint8_t *arg0, size_t arg1, const GO_ECDSA_SIG *arg2, const GO_EC_KEY *arg3), (arg0, arg1, arg2, arg3)) \ -+DEFINEFUNC(size_t, ECDSA_size, (const GO_EC_KEY *arg0), (arg0)) \ -+DEFINEFUNC(int, ECDSA_sign, \ -+ (int type, const unsigned char *dgst, size_t dgstlen, unsigned char *sig, unsigned int *siglen, EC_KEY *eckey), \ -+ (type, dgst, dgstlen, sig, siglen, eckey)) \ -+DEFINEFUNC(int, ECDSA_verify, \ -+ (int type, const unsigned char *dgst, size_t dgstlen, const unsigned char *sig, unsigned int siglen, EC_KEY *eckey), \ -+ (type, dgst, dgstlen, sig, siglen, eckey)) \ -+DEFINEFUNC(GO_RSA *, RSA_new, (void), ()) \ -+DEFINEFUNC(void, RSA_free, (GO_RSA * arg0), (arg0)) \ -+DEFINEFUNC(int, RSA_sign, \ -+ (int arg0, const uint8_t *arg1, unsigned int arg2, uint8_t *arg3, unsigned int *arg4, GO_RSA *arg5), \ -+ (arg0, arg1, arg2, arg3, arg4, arg5)) \ -+DEFINEFUNC(int, RSA_verify, \ -+ (int arg0, const uint8_t *arg1, unsigned int arg2, const uint8_t *arg3, unsigned int arg4, GO_RSA *arg5), \ -+ (arg0, arg1, arg2, arg3, arg4, arg5)) \ -+DEFINEFUNC(int, RSA_private_encrypt, \ -+ (int flen, uint8_t *from, uint8_t *to, GO_RSA *rsa, int padding), \ -+ (flen, from, to, rsa, padding)) \ -+DEFINEFUNC(int, RSA_public_decrypt, \ -+ (int flen, uint8_t *from, uint8_t *to, GO_RSA *rsa, int padding), \ -+ (flen, from, to, rsa, padding)) \ -+DEFINEFUNC(int, RSA_generate_key_ex, \ -+ (GO_RSA * arg0, int arg1, GO_BIGNUM *arg2, GO_BN_GENCB *arg3), \ -+ (arg0, arg1, arg2, arg3)) \ -+DEFINEFUNC_FALLBACK(int, RSA_set0_factors, (GO_RSA * rsa, GO_BIGNUM *p, GO_BIGNUM *q), (rsa, p, q)) \ -+DEFINEFUNC_FALLBACK(int, RSA_set0_crt_params, \ -+ (GO_RSA * rsa, GO_BIGNUM *dmp1, GO_BIGNUM *dmp2, GO_BIGNUM *iqmp), \ -+ (rsa, dmp1, dmp2, iqmp)) \ -+DEFINEFUNC_FALLBACK(void, RSA_get0_crt_params, \ -+ (const GO_RSA *r, const GO_BIGNUM **dmp1, const GO_BIGNUM **dmq1, const GO_BIGNUM **iqmp), \ -+ (r, dmp1, dmq1, iqmp)) \ -+DEFINEFUNC_FALLBACK(int, RSA_set0_key, (GO_RSA * r, GO_BIGNUM *n, GO_BIGNUM *e, GO_BIGNUM *d), (r, n, e, d)) \ -+DEFINEFUNC_FALLBACK(void, RSA_get0_factors, (const GO_RSA *rsa, const GO_BIGNUM **p, const GO_BIGNUM **q), (rsa, p, q)) \ -+DEFINEFUNC_FALLBACK(void, RSA_get0_key, \ -+ (const GO_RSA *rsa, const GO_BIGNUM **n, const GO_BIGNUM **e, const GO_BIGNUM **d), \ -+ (rsa, n, e, d)) \ -+DEFINEFUNC(unsigned int, RSA_size, (const GO_RSA *arg0), (arg0)) \ -+DEFINEFUNC(int, EVP_EncryptInit_ex, \ -+ (EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, ENGINE *impl, const unsigned char *key, const unsigned char *iv), \ -+ (ctx, type, impl, key, iv)) \ -+DEFINEFUNC(int, EVP_EncryptUpdate, \ -+ (EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl), \ -+ (ctx, out, outl, in, inl)) \ -+DEFINEFUNC(int, EVP_EncryptFinal_ex, \ -+ (EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl), \ -+ (ctx, out, outl)) \ -+DEFINEFUNC(int, EVP_DecryptUpdate, \ -+ (EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl), (ctx, out, outl, in, inl)) \ -+DEFINEFUNC(int, EVP_DecryptFinal_ex, (EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl), (ctx, outm, outl)) \ -+DEFINEFUNC(const EVP_CIPHER*, EVP_aes_128_gcm, (void), ()) \ -+DEFINEFUNC(const EVP_CIPHER*, EVP_aes_128_cbc, (void), ()) \ -+DEFINEFUNC(const EVP_CIPHER*, EVP_aes_128_ctr, (void), ()) \ -+DEFINEFUNC(const EVP_CIPHER*, EVP_aes_128_ecb, (void), ()) \ -+DEFINEFUNC(const EVP_CIPHER*, EVP_aes_192_gcm, (void), ()) \ -+DEFINEFUNC(const EVP_CIPHER*, EVP_aes_192_cbc, (void), ()) \ -+DEFINEFUNC(const EVP_CIPHER*, EVP_aes_192_ctr, (void), ()) \ -+DEFINEFUNC(const EVP_CIPHER*, EVP_aes_192_ecb, (void), ()) \ -+DEFINEFUNC(const EVP_CIPHER*, EVP_aes_256_cbc, (void), ()) \ -+DEFINEFUNC(const EVP_CIPHER*, EVP_aes_256_ctr, (void), ()) \ -+DEFINEFUNC(const EVP_CIPHER*, EVP_aes_256_ecb, (void), ()) \ -+DEFINEFUNC(const EVP_CIPHER*, EVP_aes_256_gcm, (void), ()) \ -+DEFINEFUNC(void, EVP_CIPHER_CTX_free, (EVP_CIPHER_CTX* arg0), (arg0)) \ -+DEFINEFUNC(int, EVP_CIPHER_CTX_ctrl, (EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr), (ctx, type, arg, ptr)) \ -+DEFINEFUNC(GO_EVP_PKEY *, EVP_PKEY_new, (void), ()) \ -+DEFINEFUNC(void, EVP_PKEY_free, (GO_EVP_PKEY * arg0), (arg0)) \ -+DEFINEFUNC(int, EVP_PKEY_set1_RSA, (GO_EVP_PKEY * arg0, GO_RSA *arg1), (arg0, arg1)) \ -+DEFINEFUNC(int, EVP_PKEY_verify, \ -+ (GO_EVP_PKEY_CTX *ctx, const uint8_t *sig, unsigned int siglen, const uint8_t *tbs, unsigned int tbslen), \ -+ (ctx, sig, siglen, tbs, tbslen)) \ -+DEFINEFUNC(GO_EVP_PKEY_CTX *, EVP_PKEY_CTX_new, (GO_EVP_PKEY * arg0, ENGINE *arg1), (arg0, arg1)) \ -+DEFINEFUNC(void, EVP_PKEY_CTX_free, (GO_EVP_PKEY_CTX * arg0), (arg0)) \ -+DEFINEFUNCINTERNAL(int, EVP_PKEY_CTX_ctrl, \ -+ (GO_EVP_PKEY_CTX * ctx, int keytype, int optype, int cmd, int p1, void *p2), \ -+ (ctx, keytype, optype, cmd, p1, p2)) \ -+DEFINEFUNC_FALLBACK(int, RSA_pkey_ctx_ctrl, \ -+ (GO_EVP_PKEY_CTX *ctx, int optype, int cmd, int p1, void *p2), \ -+ (ctx, optype, cmd, p1, p2)) \ -+DEFINEFUNC(int, EVP_PKEY_decrypt, \ -+ (GO_EVP_PKEY_CTX * arg0, uint8_t *arg1, unsigned int *arg2, const uint8_t *arg3, unsigned int arg4), \ -+ (arg0, arg1, arg2, arg3, arg4)) \ -+DEFINEFUNC(int, EVP_PKEY_encrypt, \ -+ (GO_EVP_PKEY_CTX * arg0, uint8_t *arg1, unsigned int *arg2, const uint8_t *arg3, unsigned int arg4), \ -+ (arg0, arg1, arg2, arg3, arg4)) \ -+DEFINEFUNC(int, EVP_PKEY_decrypt_init, (GO_EVP_PKEY_CTX * arg0), (arg0)) \ -+DEFINEFUNC(int, EVP_PKEY_encrypt_init, (GO_EVP_PKEY_CTX * arg0), (arg0)) \ -+DEFINEFUNC(int, EVP_PKEY_sign_init, (GO_EVP_PKEY_CTX * arg0), (arg0)) \ -+DEFINEFUNC(int, EVP_PKEY_verify_init, (GO_EVP_PKEY_CTX * arg0), (arg0)) \ -+DEFINEFUNC(int, EVP_PKEY_sign, \ -+ (GO_EVP_PKEY_CTX * arg0, uint8_t *arg1, unsigned int *arg2, const uint8_t *arg3, unsigned int arg4), \ -+ (arg0, arg1, arg2, arg3, arg4)) ++DEFINEFUNC(void, ERR_error_string_n, (unsigned long e, char *buf, size_t len), (e, buf, len)) \ ++DEFINEFUNC_RENAMED_1_1(const char *, OpenSSL_version, SSLeay_version, (int type), (type)) \ ++DEFINEFUNC(void, OPENSSL_init, (void), ()) \ ++DEFINEFUNC_LEGACY_1_0(void, ERR_load_crypto_strings, (void), ()) \ ++DEFINEFUNC_LEGACY_1_0(int, CRYPTO_num_locks, (void), ()) \ ++DEFINEFUNC_LEGACY_1_0(void, CRYPTO_set_id_callback, (unsigned long (*id_function)(void)), (id_function)) \ ++DEFINEFUNC_LEGACY_1_0(void, CRYPTO_set_locking_callback, (void (*locking_function)(int mode, int n, const char *file, int line)), (locking_function)) \ ++DEFINEFUNC_LEGACY_1_0(void, OPENSSL_add_all_algorithms_conf, (void), ()) \ ++DEFINEFUNC_1_1(int, OPENSSL_init_crypto, (uint64_t ops, const GO_OPENSSL_INIT_SETTINGS_PTR settings), (ops, settings)) \ ++DEFINEFUNC_LEGACY_1(int, FIPS_mode, (void), ()) \ ++DEFINEFUNC_LEGACY_1(int, FIPS_mode_set, (int r), (r)) \ ++DEFINEFUNC_3_0(int, EVP_default_properties_is_fips_enabled, (GO_OSSL_LIB_CTX_PTR libctx), (libctx)) \ ++DEFINEFUNC_3_0(int, EVP_set_default_properties, (GO_OSSL_LIB_CTX_PTR libctx, const char *propq), (libctx, propq)) \ ++DEFINEFUNC_3_0(GO_OSSL_PROVIDER_PTR, OSSL_PROVIDER_load, (GO_OSSL_LIB_CTX_PTR libctx, const char *name), (libctx, name)) \ ++DEFINEFUNC(int, RAND_bytes, (unsigned char* arg0, int arg1), (arg0, arg1)) \ ++DEFINEFUNC(int, EVP_DigestInit_ex, (GO_EVP_MD_CTX_PTR ctx, const GO_EVP_MD_PTR type, GO_ENGINE_PTR impl), (ctx, type, impl)) \ ++DEFINEFUNC(int, EVP_DigestUpdate, (GO_EVP_MD_CTX_PTR ctx, const void *d, size_t cnt), (ctx, d, cnt)) \ ++DEFINEFUNC(int, EVP_DigestFinal_ex, (GO_EVP_MD_CTX_PTR ctx, unsigned char *md, unsigned int *s), (ctx, md, s)) \ ++DEFINEFUNC_RENAMED_1_1(GO_EVP_MD_CTX_PTR, EVP_MD_CTX_new, EVP_MD_CTX_create, (), ()) \ ++DEFINEFUNC_RENAMED_1_1(void, EVP_MD_CTX_free, EVP_MD_CTX_destroy, (GO_EVP_MD_CTX_PTR ctx), (ctx)) \ ++DEFINEFUNC(int, EVP_MD_CTX_copy_ex, (GO_EVP_MD_CTX_PTR out, const GO_EVP_MD_CTX_PTR in), (out, in)) \ ++DEFINEFUNC_RENAMED_1_1(int, EVP_MD_CTX_reset, EVP_MD_CTX_cleanup, (GO_EVP_MD_CTX_PTR ctx), (ctx)) \ ++DEFINEFUNC(const GO_EVP_MD_PTR, EVP_md5, (void), ()) \ ++DEFINEFUNC(const GO_EVP_MD_PTR, EVP_sha1, (void), ()) \ ++DEFINEFUNC(const GO_EVP_MD_PTR, EVP_sha224, (void), ()) \ ++DEFINEFUNC(const GO_EVP_MD_PTR, EVP_sha256, (void), ()) \ ++DEFINEFUNC(const GO_EVP_MD_PTR, EVP_sha384, (void), ()) \ ++DEFINEFUNC(const GO_EVP_MD_PTR, EVP_sha512, (void), ()) \ ++DEFINEFUNC_1_1(const GO_EVP_MD_PTR, EVP_md5_sha1, (void), ()) \ ++DEFINEFUNC_3_0(GO_EVP_MD_PTR, EVP_MD_fetch, (GO_OSSL_LIB_CTX_PTR ctx, const char *algorithm, const char *properties), (ctx, algorithm, properties)) \ ++DEFINEFUNC_3_0(void, EVP_MD_free, (GO_EVP_MD_PTR md), (md)) \ ++DEFINEFUNC_RENAMED_3_0(int, EVP_MD_get_size, EVP_MD_size, (const GO_EVP_MD_PTR arg0), (arg0)) \ ++DEFINEFUNC_LEGACY_1_0(void, HMAC_CTX_init, (GO_HMAC_CTX_PTR arg0), (arg0)) \ ++DEFINEFUNC_LEGACY_1_0(void, HMAC_CTX_cleanup, (GO_HMAC_CTX_PTR arg0), (arg0)) \ ++DEFINEFUNC(int, HMAC_Init_ex, (GO_HMAC_CTX_PTR arg0, const void *arg1, int arg2, const GO_EVP_MD_PTR arg3, GO_ENGINE_PTR arg4), (arg0, arg1, arg2, arg3, arg4)) \ ++DEFINEFUNC(int, HMAC_Update, (GO_HMAC_CTX_PTR arg0, const unsigned char *arg1, size_t arg2), (arg0, arg1, arg2)) \ ++DEFINEFUNC(int, HMAC_Final, (GO_HMAC_CTX_PTR arg0, unsigned char *arg1, unsigned int *arg2), (arg0, arg1, arg2)) \ ++DEFINEFUNC(int, HMAC_CTX_copy, (GO_HMAC_CTX_PTR dest, GO_HMAC_CTX_PTR src), (dest, src)) \ ++DEFINEFUNC_1_1(void, HMAC_CTX_free, (GO_HMAC_CTX_PTR arg0), (arg0)) \ ++DEFINEFUNC_1_1(GO_HMAC_CTX_PTR, HMAC_CTX_new, (void), ()) \ ++DEFINEFUNC_1_1(int, HMAC_CTX_reset, (GO_HMAC_CTX_PTR arg0), (arg0)) \ ++DEFINEFUNC(GO_EVP_CIPHER_CTX_PTR, EVP_CIPHER_CTX_new, (void), ()) \ ++DEFINEFUNC(int, EVP_CIPHER_CTX_set_padding, (GO_EVP_CIPHER_CTX_PTR x, int padding), (x, padding)) \ ++DEFINEFUNC(int, EVP_CipherInit_ex, (GO_EVP_CIPHER_CTX_PTR ctx, const GO_EVP_CIPHER_PTR type, GO_ENGINE_PTR impl, const unsigned char *key, const unsigned char *iv, int enc), (ctx, type, impl, key, iv, enc)) \ ++DEFINEFUNC(int, EVP_CipherUpdate, (GO_EVP_CIPHER_CTX_PTR ctx, unsigned char *out, int *outl, const unsigned char *in, int inl), (ctx, out, outl, in, inl)) \ ++DEFINEFUNC(GO_BIGNUM_PTR, BN_new, (void), ()) \ ++DEFINEFUNC(void, BN_free, (GO_BIGNUM_PTR arg0), (arg0)) \ ++DEFINEFUNC(void, BN_clear_free, (GO_BIGNUM_PTR arg0), (arg0)) \ ++DEFINEFUNC(int, BN_num_bits, (const GO_BIGNUM_PTR arg0), (arg0)) \ ++DEFINEFUNC(GO_BIGNUM_PTR, BN_bin2bn, (const unsigned char *arg0, int arg1, GO_BIGNUM_PTR arg2), (arg0, arg1, arg2)) \ ++DEFINEFUNC(int, BN_bn2bin, (const GO_BIGNUM_PTR arg0, unsigned char *arg1), (arg0, arg1)) \ ++DEFINEFUNC(void, EC_GROUP_free, (GO_EC_GROUP_PTR arg0), (arg0)) \ ++DEFINEFUNC(GO_EC_POINT_PTR, EC_POINT_new, (const GO_EC_GROUP_PTR arg0), (arg0)) \ ++DEFINEFUNC(void, EC_POINT_free, (GO_EC_POINT_PTR arg0), (arg0)) \ ++DEFINEFUNC(int, EC_POINT_get_affine_coordinates_GFp, (const GO_EC_GROUP_PTR arg0, const GO_EC_POINT_PTR arg1, GO_BIGNUM_PTR arg2, GO_BIGNUM_PTR arg3, GO_BN_CTX_PTR arg4), (arg0, arg1, arg2, arg3, arg4)) \ ++DEFINEFUNC(GO_EC_KEY_PTR, EC_KEY_new_by_curve_name, (int arg0), (arg0)) \ ++DEFINEFUNC(int, EC_KEY_set_public_key_affine_coordinates, (GO_EC_KEY_PTR key, GO_BIGNUM_PTR x, GO_BIGNUM_PTR y), (key, x, y)) \ ++DEFINEFUNC(void, EC_KEY_free, (GO_EC_KEY_PTR arg0), (arg0)) \ ++DEFINEFUNC(const GO_EC_GROUP_PTR, EC_KEY_get0_group, (const GO_EC_KEY_PTR arg0), (arg0)) \ ++DEFINEFUNC(int, EC_KEY_set_private_key, (GO_EC_KEY_PTR arg0, const GO_BIGNUM_PTR arg1), (arg0, arg1)) \ ++DEFINEFUNC(const GO_BIGNUM_PTR, EC_KEY_get0_private_key, (const GO_EC_KEY_PTR arg0), (arg0)) \ ++DEFINEFUNC(const GO_EC_POINT_PTR, EC_KEY_get0_public_key, (const GO_EC_KEY_PTR arg0), (arg0)) \ ++DEFINEFUNC(GO_RSA_PTR, RSA_new, (void), ()) \ ++DEFINEFUNC(void, RSA_free, (GO_RSA_PTR arg0), (arg0)) \ ++DEFINEFUNC_1_1(int, RSA_set0_factors, (GO_RSA_PTR rsa, GO_BIGNUM_PTR p, GO_BIGNUM_PTR q), (rsa, p, q)) \ ++DEFINEFUNC_1_1(int, RSA_set0_crt_params, (GO_RSA_PTR rsa, GO_BIGNUM_PTR dmp1, GO_BIGNUM_PTR dmp2,GO_BIGNUM_PTR iqmp), (rsa, dmp1, dmp2, iqmp)) \ ++DEFINEFUNC_1_1(void, RSA_get0_crt_params, (const GO_RSA_PTR r, const GO_BIGNUM_PTR *dmp1, const GO_BIGNUM_PTR *dmq1, const GO_BIGNUM_PTR *iqmp), (r, dmp1, dmq1, iqmp)) \ ++DEFINEFUNC_1_1(int, RSA_set0_key, (GO_RSA_PTR r, GO_BIGNUM_PTR n, GO_BIGNUM_PTR e, GO_BIGNUM_PTR d), (r, n, e, d)) \ ++DEFINEFUNC_1_1(void, RSA_get0_factors, (const GO_RSA_PTR rsa, const GO_BIGNUM_PTR *p, const GO_BIGNUM_PTR *q), (rsa, p, q)) \ ++DEFINEFUNC_1_1(void, RSA_get0_key, (const GO_RSA_PTR rsa, const GO_BIGNUM_PTR *n, const GO_BIGNUM_PTR *e, const GO_BIGNUM_PTR *d), (rsa, n, e, d)) \ ++DEFINEFUNC(int, EVP_EncryptInit_ex, (GO_EVP_CIPHER_CTX_PTR ctx, const GO_EVP_CIPHER_PTR type, GO_ENGINE_PTR impl, const unsigned char *key, const unsigned char *iv), (ctx, type, impl, key, iv)) \ ++DEFINEFUNC(int, EVP_EncryptUpdate, (GO_EVP_CIPHER_CTX_PTR ctx, unsigned char *out, int *outl, const unsigned char *in, int inl), (ctx, out, outl, in, inl)) \ ++DEFINEFUNC(int, EVP_EncryptFinal_ex, (GO_EVP_CIPHER_CTX_PTR ctx, unsigned char *out, int *outl), (ctx, out, outl)) \ ++DEFINEFUNC(int, EVP_DecryptUpdate, (GO_EVP_CIPHER_CTX_PTR ctx, unsigned char *out, int *outl, const unsigned char *in, int inl), (ctx, out, outl, in, inl)) \ ++DEFINEFUNC(int, EVP_DecryptFinal_ex, (GO_EVP_CIPHER_CTX_PTR ctx, unsigned char *outm, int *outl), (ctx, outm, outl)) \ ++DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_128_gcm, (void), ()) \ ++DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_128_cbc, (void), ()) \ ++DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_128_ctr, (void), ()) \ ++DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_128_ecb, (void), ()) \ ++DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_192_gcm, (void), ()) \ ++DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_192_cbc, (void), ()) \ ++DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_192_ctr, (void), ()) \ ++DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_192_ecb, (void), ()) \ ++DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_256_cbc, (void), ()) \ ++DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_256_ctr, (void), ()) \ ++DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_256_ecb, (void), ()) \ ++DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_256_gcm, (void), ()) \ ++DEFINEFUNC(void, EVP_CIPHER_CTX_free, (GO_EVP_CIPHER_CTX_PTR arg0), (arg0)) \ ++DEFINEFUNC(int, EVP_CIPHER_CTX_ctrl, (GO_EVP_CIPHER_CTX_PTR ctx, int type, int arg, void *ptr), (ctx, type, arg, ptr)) \ ++DEFINEFUNC(GO_EVP_PKEY_PTR, EVP_PKEY_new, (void), ()) \ ++/* EVP_PKEY_size pkey parameter is const since OpenSSL 1.1.1. */ \ ++/* Exclude it from headercheck tool when using previous OpenSSL versions. */ \ ++/*check:from=1.1.1*/ DEFINEFUNC_RENAMED_3_0(int, EVP_PKEY_get_size, EVP_PKEY_size, (const GO_EVP_PKEY_PTR pkey), (pkey)) \ ++DEFINEFUNC(void, EVP_PKEY_free, (GO_EVP_PKEY_PTR arg0), (arg0)) \ ++DEFINEFUNC(GO_EC_KEY_PTR, EVP_PKEY_get1_EC_KEY, (GO_EVP_PKEY_PTR pkey), (pkey)) \ ++DEFINEFUNC(GO_RSA_PTR, EVP_PKEY_get1_RSA, (GO_EVP_PKEY_PTR pkey), (pkey)) \ ++DEFINEFUNC(int, EVP_PKEY_assign, (GO_EVP_PKEY_PTR pkey, int type, void *key), (pkey, type, key)) \ ++DEFINEFUNC(int, EVP_PKEY_verify, (GO_EVP_PKEY_CTX_PTR ctx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, size_t tbslen), (ctx, sig, siglen, tbs, tbslen)) \ ++DEFINEFUNC(GO_EVP_PKEY_CTX_PTR, EVP_PKEY_CTX_new, (GO_EVP_PKEY_PTR arg0, GO_ENGINE_PTR arg1), (arg0, arg1)) \ ++DEFINEFUNC(GO_EVP_PKEY_CTX_PTR, EVP_PKEY_CTX_new_id, (int id, GO_ENGINE_PTR e), (id, e)) \ ++DEFINEFUNC(int, EVP_PKEY_keygen_init, (GO_EVP_PKEY_CTX_PTR ctx), (ctx)) \ ++DEFINEFUNC(int, EVP_PKEY_keygen, (GO_EVP_PKEY_CTX_PTR ctx, GO_EVP_PKEY_PTR *ppkey), (ctx, ppkey)) \ ++DEFINEFUNC(void, EVP_PKEY_CTX_free, (GO_EVP_PKEY_CTX_PTR arg0), (arg0)) \ ++DEFINEFUNC(int, EVP_PKEY_CTX_ctrl, (GO_EVP_PKEY_CTX_PTR ctx, int keytype, int optype, int cmd, int p1, void *p2), (ctx, keytype, optype, cmd, p1, p2)) \ ++DEFINEFUNC(int, EVP_PKEY_decrypt, (GO_EVP_PKEY_CTX_PTR arg0, unsigned char *arg1, size_t *arg2, const unsigned char *arg3, size_t arg4), (arg0, arg1, arg2, arg3, arg4)) \ ++DEFINEFUNC(int, EVP_PKEY_encrypt, (GO_EVP_PKEY_CTX_PTR arg0, unsigned char *arg1, size_t *arg2, const unsigned char *arg3, size_t arg4), (arg0, arg1, arg2, arg3, arg4)) \ ++DEFINEFUNC(int, EVP_PKEY_decrypt_init, (GO_EVP_PKEY_CTX_PTR arg0), (arg0)) \ ++DEFINEFUNC(int, EVP_PKEY_encrypt_init, (GO_EVP_PKEY_CTX_PTR arg0), (arg0)) \ ++DEFINEFUNC(int, EVP_PKEY_sign_init, (GO_EVP_PKEY_CTX_PTR arg0), (arg0)) \ ++DEFINEFUNC(int, EVP_PKEY_verify_init, (GO_EVP_PKEY_CTX_PTR arg0), (arg0)) \ ++DEFINEFUNC(int, EVP_PKEY_sign, (GO_EVP_PKEY_CTX_PTR arg0, unsigned char *arg1, size_t *arg2, const unsigned char *arg3, size_t arg4), (arg0, arg1, arg2, arg3, arg4)) diff --git a/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/openssl_lock_setup.c b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/openssl_lock_setup.c new file mode 100644 -index 0000000000..26ea3c3b99 +index 00000000000..5cd7275f407 --- /dev/null +++ b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/openssl_lock_setup.c @@ -0,0 +1,53 @@ @@ -2103,7 +2054,6 @@ index 0000000000..26ea3c3b99 + +#include +#include -+#include +#include +#include + @@ -2116,7 +2066,8 @@ index 0000000000..26ea3c3b99 +#define MUTEX_LOCK(x) pthread_mutex_lock(&(x)) +#define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x)) +#define THREAD_ID pthread_self() -+ ++#define CRYPTO_LOCK 0x01 ++ +/* This array will store all of the mutexes available to OpenSSL. */ +static MUTEX_TYPE *mutex_buf = NULL; + @@ -2133,22 +2084,22 @@ index 0000000000..26ea3c3b99 + return ((unsigned long)syscall(__NR_gettid)); +} + -+int _goboringcrypto_internal_OPENSSL_thread_setup(void) ++int go_openssl_thread_setup(void) +{ + int i; + -+ mutex_buf = malloc(_goboringcrypto_internal_CRYPTO_num_locks() * sizeof(MUTEX_TYPE)); ++ mutex_buf = malloc(go_openssl_CRYPTO_num_locks() * sizeof(MUTEX_TYPE)); + if(!mutex_buf) + return 0; -+ for(i = 0; i < _goboringcrypto_internal_CRYPTO_num_locks(); i++) ++ for(i = 0; i < go_openssl_CRYPTO_num_locks(); i++) + MUTEX_SETUP(mutex_buf[i]); -+ _goboringcrypto_internal_CRYPTO_set_id_callback(id_function); -+ _goboringcrypto_internal_CRYPTO_set_locking_callback(locking_function); ++ go_openssl_CRYPTO_set_id_callback(id_function); ++ go_openssl_CRYPTO_set_locking_callback(locking_function); + return 1; +} diff --git a/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/rand.go b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/rand.go new file mode 100644 -index 0000000000..05d39f1d48 +index 00000000000..17f64a52ae5 --- /dev/null +++ b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/rand.go @@ -0,0 +1,24 @@ @@ -2169,7 +2120,7 @@ index 0000000000..05d39f1d48 +func (randReader) Read(b []byte) (int, error) { + // Note: RAND_bytes should never fail; the return value exists only for historical reasons. + // We check it even so. -+ if len(b) > 0 && C._goboringcrypto_RAND_bytes((*C.uint8_t)(unsafe.Pointer(&b[0])), C.size_t(len(b))) == 0 { ++ if len(b) > 0 && C.go_openssl_RAND_bytes((*C.uchar)(unsafe.Pointer(&b[0])), C.int(len(b))) == 0 { + return 0, fail("RAND_bytes") + } + return len(b), nil @@ -2178,10 +2129,10 @@ index 0000000000..05d39f1d48 +const RandReader = randReader(0) diff --git a/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/rsa.go b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/rsa.go new file mode 100644 -index 0000000000..071cda557d +index 00000000000..05ff62cd739 --- /dev/null +++ b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/rsa.go -@@ -0,0 +1,397 @@ +@@ -0,0 +1,303 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + @@ -2199,7 +2150,6 @@ index 0000000000..071cda557d + "hash" + "math/big" + "runtime" -+ "strconv" + "unsafe" +) + @@ -2207,224 +2157,129 @@ index 0000000000..071cda557d + bad := func(e error) (N, E, D, P, Q, Dp, Dq, Qinv *big.Int, err error) { + return nil, nil, nil, nil, nil, nil, nil, nil, e + } -+ -+ key := C._goboringcrypto_RSA_new() -+ if key == nil { -+ return bad(newOpenSSLError("RSA_new failed")) -+ } -+ defer C._goboringcrypto_RSA_free(key) -+ -+ bn := C._goboringcrypto_BN_new() -+ if bn == nil { -+ return bad(newOpenSSLError("BN_new failed")) -+ } -+ defer C._goboringcrypto_BN_free(bn) -+ -+ if C._goboringcrypto_BN_set_word(bn, C.RSA_F4) != C.int(1) { -+ return bad(newOpenSSLError("BN_set_word failed")) ++ pkey, err := generateEVPPKey(C.GO_EVP_PKEY_RSA, bits, "") ++ if err != nil { ++ return bad(err) + } -+ if C._goboringcrypto_RSA_generate_key_ex(key, C.int(bits), bn, nil) != C.int(1) { -+ return bad(newOpenSSLError("RSA_generate_key_ex failed")) ++ defer C.go_openssl_EVP_PKEY_free(pkey) ++ key := C.go_openssl_EVP_PKEY_get1_RSA(pkey) ++ if key == nil { ++ return bad(newOpenSSLError("EVP_PKEY_get1_RSA failed")) + } -+ -+ var n, e, d, p, q, dp, dq, qinv *C.GO_BIGNUM -+ C._goboringcrypto_RSA_get0_key(key, &n, &e, &d) -+ C._goboringcrypto_RSA_get0_factors(key, &p, &q) -+ C._goboringcrypto_RSA_get0_crt_params(key, &dp, &dq, &qinv) -+ return bnToBig(n), bnToBig(e), bnToBig(d), bnToBig(p), bnToBig(q), bnToBig(dp), bnToBig(dq), bnToBig(qinv), nil ++ N, E, D = rsaGetKey(key) ++ P, Q = rsaGetFactors(key) ++ Dp, Dq, Qinv = rsaGetCRTParams(key) ++ return +} + +type PublicKeyRSA struct { -+ // _key MUST NOT be accessed directly. Instead, use the withKey method. -+ _key *C.GO_RSA ++ // _pkey MUST NOT be accessed directly. Instead, use the withKey method. ++ _pkey C.GO_EVP_PKEY_PTR +} + +func NewPublicKeyRSA(N, E *big.Int) (*PublicKeyRSA, error) { -+ key := C._goboringcrypto_RSA_new() ++ key := C.go_openssl_RSA_new() + if key == nil { + return nil, newOpenSSLError("RSA_new failed") + } -+ var n, e *C.GO_BIGNUM -+ n = bigToBN(N) -+ e = bigToBN(E) -+ C._goboringcrypto_RSA_set0_key(key, n, e, nil) -+ k := &PublicKeyRSA{_key: key} ++ if !rsaSetKey(key, N, E, nil) { ++ return nil, fail("RSA_set0_key") ++ } ++ pkey := C.go_openssl_EVP_PKEY_new() ++ if pkey == nil { ++ C.go_openssl_RSA_free(key) ++ return nil, newOpenSSLError("EVP_PKEY_new failed") ++ } ++ if C.go_openssl_EVP_PKEY_assign(pkey, C.GO_EVP_PKEY_RSA, (unsafe.Pointer)(key)) != 1 { ++ C.go_openssl_RSA_free(key) ++ C.go_openssl_EVP_PKEY_free(pkey) ++ return nil, newOpenSSLError("EVP_PKEY_assign failed") ++ } ++ k := &PublicKeyRSA{_pkey: pkey} + runtime.SetFinalizer(k, (*PublicKeyRSA).finalize) + return k, nil +} + +func (k *PublicKeyRSA) finalize() { -+ C._goboringcrypto_RSA_free(k._key) ++ C.go_openssl_EVP_PKEY_free(k._pkey) +} + -+func (k *PublicKeyRSA) withKey(f func(*C.GO_RSA) C.int) C.int { -+ // Because of the finalizer, any time _key is passed to cgo, that call must ++func (k *PublicKeyRSA) withKey(f func(C.GO_EVP_PKEY_PTR) C.int) C.int { ++ // Because of the finalizer, any time _pkey is passed to cgo, that call must + // be followed by a call to runtime.KeepAlive, to make sure k is not + // collected (and finalized) before the cgo call returns. + defer runtime.KeepAlive(k) -+ return f(k._key) ++ return f(k._pkey) +} + +type PrivateKeyRSA struct { -+ // _key MUST NOT be accessed directly. Instead, use the withKey method. -+ _key *C.GO_RSA ++ // _pkey MUST NOT be accessed directly. Instead, use the withKey method. ++ _pkey C.GO_EVP_PKEY_PTR +} + +func NewPrivateKeyRSA(N, E, D, P, Q, Dp, Dq, Qinv *big.Int) (*PrivateKeyRSA, error) { -+ key := C._goboringcrypto_RSA_new() ++ key := C.go_openssl_RSA_new() + if key == nil { + return nil, newOpenSSLError("RSA_new failed") + } -+ var n, e, d, p, q, dp, dq, qinv *C.GO_BIGNUM -+ n = bigToBN(N) -+ e = bigToBN(E) -+ d = bigToBN(D) -+ C._goboringcrypto_RSA_set0_key(key, n, e, d) ++ if !rsaSetKey(key, N, E, D) { ++ return nil, fail("RSA_set0_key") ++ } + if P != nil && Q != nil { -+ p = bigToBN(P) -+ q = bigToBN(Q) -+ C._goboringcrypto_RSA_set0_factors(key, p, q) ++ if !rsaSetFactors(key, P, Q) { ++ return nil, fail("RSA_set0_factors") ++ } + } + if Dp != nil && Dq != nil && Qinv != nil { -+ dp = bigToBN(Dp) -+ dq = bigToBN(Dq) -+ qinv = bigToBN(Qinv) -+ C._goboringcrypto_RSA_set0_crt_params(key, dp, dq, qinv) ++ if !rsaSetCRTParams(key, Dp, Dq, Qinv) { ++ return nil, fail("RSA_set0_crt_params") ++ } + } -+ k := &PrivateKeyRSA{_key: key} ++ pkey := C.go_openssl_EVP_PKEY_new() ++ if pkey == nil { ++ C.go_openssl_RSA_free(key) ++ return nil, newOpenSSLError("EVP_PKEY_new failed") ++ } ++ if C.go_openssl_EVP_PKEY_assign(pkey, C.GO_EVP_PKEY_RSA, (unsafe.Pointer)(key)) != 1 { ++ C.go_openssl_RSA_free(key) ++ C.go_openssl_EVP_PKEY_free(pkey) ++ return nil, newOpenSSLError("EVP_PKEY_assign failed") ++ } ++ k := &PrivateKeyRSA{_pkey: pkey} + runtime.SetFinalizer(k, (*PrivateKeyRSA).finalize) + return k, nil +} + +func (k *PrivateKeyRSA) finalize() { -+ C._goboringcrypto_RSA_free(k._key) ++ C.go_openssl_EVP_PKEY_free(k._pkey) +} + -+func (k *PrivateKeyRSA) withKey(f func(*C.GO_RSA) C.int) C.int { -+ // Because of the finalizer, any time _key is passed to cgo, that call must ++func (k *PrivateKeyRSA) withKey(f func(C.GO_EVP_PKEY_PTR) C.int) C.int { ++ // Because of the finalizer, any time _pkey is passed to cgo, that call must + // be followed by a call to runtime.KeepAlive, to make sure k is not + // collected (and finalized) before the cgo call returns. + defer runtime.KeepAlive(k) -+ return f(k._key) -+} -+ -+func setupRSA(withKey func(func(*C.GO_RSA) C.int) C.int, -+ padding C.int, h hash.Hash, label []byte, saltLen int, ch crypto.Hash, -+ init func(*C.GO_EVP_PKEY_CTX) C.int) (pkey *C.GO_EVP_PKEY, ctx *C.GO_EVP_PKEY_CTX, err error) { -+ defer func() { -+ if err != nil { -+ if pkey != nil { -+ C._goboringcrypto_EVP_PKEY_free(pkey) -+ pkey = nil -+ } -+ if ctx != nil { -+ C._goboringcrypto_EVP_PKEY_CTX_free(ctx) -+ ctx = nil -+ } -+ } -+ }() -+ -+ pkey = C._goboringcrypto_EVP_PKEY_new() -+ if pkey == nil { -+ return nil, nil, newOpenSSLError("EVP_PKEY_new failed") -+ } -+ if withKey(func(key *C.GO_RSA) C.int { -+ return C._goboringcrypto_EVP_PKEY_set1_RSA(pkey, key) -+ }) == 0 { -+ return nil, nil, fail("EVP_PKEY_set1_RSA") -+ } -+ ctx = C._goboringcrypto_EVP_PKEY_CTX_new(pkey, nil) -+ if ctx == nil { -+ return nil, nil, newOpenSSLError("EVP_PKEY_CTX_new failed") -+ } -+ if init(ctx) == 0 { -+ return nil, nil, newOpenSSLError("EVP_PKEY_operation_init failed") -+ } -+ if C._goboringcrypto_EVP_PKEY_CTX_set_rsa_padding(ctx, padding) == 0 { -+ return nil, nil, newOpenSSLError("EVP_PKEY_CTX_set_rsa_padding failed") -+ } -+ if padding == C.GO_RSA_PKCS1_OAEP_PADDING { -+ md := hashToMD(h) -+ if md == nil { -+ return nil, nil, errors.New("crypto/rsa: unsupported hash function") -+ } -+ if C._goboringcrypto_EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md) == 0 { -+ return nil, nil, newOpenSSLError("EVP_PKEY_set_rsa_oaep_md failed") -+ } -+ // ctx takes ownership of label, so malloc a copy for BoringCrypto to free. -+ clabel := (*C.uint8_t)(C.malloc(C.size_t(len(label)))) -+ if clabel == nil { -+ return nil, nil, fail("OPENSSL_malloc") -+ } -+ copy((*[1 << 30]byte)(unsafe.Pointer(clabel))[:len(label)], label) -+ if C._goboringcrypto_EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, clabel, C.int(len(label))) == 0 { -+ return nil, nil, newOpenSSLError("EVP_PKEY_CTX_set0_rsa_oaep_label failed") -+ } -+ } -+ if padding == C.GO_RSA_PKCS1_PSS_PADDING { -+ if saltLen != 0 { -+ if C._goboringcrypto_EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, C.int(saltLen)) == 0 { -+ return nil, nil, newOpenSSLError("EVP_PKEY_set_rsa_pss_saltlen failed") -+ } -+ } -+ md := cryptoHashToMD(ch) -+ if md == nil { -+ return nil, nil, errors.New("crypto/rsa: unsupported hash function") -+ } -+ if C._goboringcrypto_EVP_PKEY_CTX_set_signature_md(ctx, md) == 0 { -+ return nil, nil, newOpenSSLError("EVP_PKEY_CTX_set_signature_md failed") -+ } -+ } -+ -+ return pkey, ctx, nil -+} -+ -+func cryptRSA(withKey func(func(*C.GO_RSA) C.int) C.int, -+ padding C.int, h hash.Hash, label []byte, saltLen int, ch crypto.Hash, -+ init func(*C.GO_EVP_PKEY_CTX) C.int, -+ crypt func(*C.GO_EVP_PKEY_CTX, *C.uint8_t, *C.uint, *C.uint8_t, C.uint) C.int, -+ out, in []byte) ([]byte, error) { -+ -+ pkey, ctx, err := setupRSA(withKey, padding, h, label, saltLen, ch, init) -+ if err != nil { -+ return nil, err -+ } -+ defer C._goboringcrypto_EVP_PKEY_free(pkey) -+ defer C._goboringcrypto_EVP_PKEY_CTX_free(ctx) -+ -+ var outLen C.uint -+ if out == nil { -+ if crypt(ctx, nil, &outLen, base(in), C.uint(len(in))) == 0 { -+ return nil, newOpenSSLError("EVP_PKEY_decrypt/encrypt failed") -+ } -+ out = make([]byte, outLen) -+ } else { -+ outLen = C.uint(len(out)) -+ } -+ if crypt(ctx, base(out), &outLen, base(in), C.uint(len(in))) <= 0 { -+ return nil, newOpenSSLError("EVP_PKEY_decrypt/encrypt failed") -+ } -+ return out[:outLen], nil ++ return f(k._pkey) +} + +func DecryptRSAOAEP(h hash.Hash, priv *PrivateKeyRSA, ciphertext, label []byte) ([]byte, error) { -+ return cryptRSA(priv.withKey, C.GO_RSA_PKCS1_OAEP_PADDING, h, label, 0, 0, decryptInit, decrypt, nil, ciphertext) ++ return evpDecrypt(priv.withKey, C.GO_RSA_PKCS1_OAEP_PADDING, h, label, ciphertext) +} + +func EncryptRSAOAEP(h hash.Hash, pub *PublicKeyRSA, msg, label []byte) ([]byte, error) { -+ return cryptRSA(pub.withKey, C.GO_RSA_PKCS1_OAEP_PADDING, h, label, 0, 0, encryptInit, encrypt, nil, msg) ++ return evpEncrypt(pub.withKey, C.GO_RSA_PKCS1_OAEP_PADDING, h, label, msg) +} + +func DecryptRSAPKCS1(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) { -+ return cryptRSA(priv.withKey, C.GO_RSA_PKCS1_PADDING, nil, nil, 0, 0, decryptInit, decrypt, nil, ciphertext) ++ return evpDecrypt(priv.withKey, C.GO_RSA_PKCS1_PADDING, nil, nil, ciphertext) +} + +func EncryptRSAPKCS1(pub *PublicKeyRSA, msg []byte) ([]byte, error) { -+ return cryptRSA(pub.withKey, C.GO_RSA_PKCS1_PADDING, nil, nil, 0, 0, encryptInit, encrypt, nil, msg) ++ return evpEncrypt(pub.withKey, C.GO_RSA_PKCS1_PADDING, nil, nil, msg) +} + +func DecryptRSANoPadding(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) { -+ ret, err := cryptRSA(priv.withKey, C.GO_RSA_NO_PADDING, nil, nil, 0, 0, decryptInit, decrypt, nil, ciphertext) ++ ret, err := evpDecrypt(priv.withKey, C.GO_RSA_NO_PADDING, nil, nil, ciphertext) + if err != nil { + return nil, err + } @@ -2433,15 +2288,8 @@ index 0000000000..071cda557d + // + // The following code tries to replicate the verification implemented in the upstream function decryptAndCheck, found at + // https://github.com/golang/go/blob/9de1ac6ac2cad3871760d0aa288f5ca713afd0a6/src/crypto/rsa/rsa.go#L569-L582. -+ var n, e, d *C.GO_BIGNUM -+ priv.withKey(func(key *C.GO_RSA) C.int { -+ C._goboringcrypto_RSA_get0_key(key, &n, &e, &d) -+ return 1 -+ }) -+ pub, err := NewPublicKeyRSA(bnToBig(n), bnToBig(e)) -+ if err != nil { -+ return nil, err -+ } ++ pub := &PublicKeyRSA{_pkey: priv._pkey} ++ // A private EVP_PKEY can be used as a public key as it contains the public information. + enc, err := EncryptRSANoPadding(pub, ret) + if err != nil { + return nil, err @@ -2455,136 +2303,145 @@ index 0000000000..071cda557d +} + +func EncryptRSANoPadding(pub *PublicKeyRSA, msg []byte) ([]byte, error) { -+ return cryptRSA(pub.withKey, C.GO_RSA_NO_PADDING, nil, nil, 0, 0, encryptInit, encrypt, nil, msg) -+} -+ -+// These dumb wrappers work around the fact that cgo functions cannot be used as values directly. -+ -+func decryptInit(ctx *C.GO_EVP_PKEY_CTX) C.int { -+ return C._goboringcrypto_EVP_PKEY_decrypt_init(ctx) -+} -+ -+func decrypt(ctx *C.GO_EVP_PKEY_CTX, out *C.uint8_t, outLen *C.uint, in *C.uint8_t, inLen C.uint) C.int { -+ return C._goboringcrypto_EVP_PKEY_decrypt(ctx, out, outLen, in, inLen) -+} -+ -+func encryptInit(ctx *C.GO_EVP_PKEY_CTX) C.int { -+ return C._goboringcrypto_EVP_PKEY_encrypt_init(ctx) -+} -+ -+func encrypt(ctx *C.GO_EVP_PKEY_CTX, out *C.uint8_t, outLen *C.uint, in *C.uint8_t, inLen C.uint) C.int { -+ return C._goboringcrypto_EVP_PKEY_encrypt(ctx, out, outLen, in, inLen) -+} -+ -+func signtInit(ctx *C.GO_EVP_PKEY_CTX) C.int { -+ return C._goboringcrypto_EVP_PKEY_sign_init(ctx) -+} -+ -+func sign(ctx *C.GO_EVP_PKEY_CTX, out *C.uint8_t, outLen *C.uint, in *C.uint8_t, inLen C.uint) C.int { -+ return C._goboringcrypto_EVP_PKEY_sign(ctx, out, outLen, in, inLen) -+} -+ -+func verifyInit(ctx *C.GO_EVP_PKEY_CTX) C.int { -+ return C._goboringcrypto_EVP_PKEY_verify_init(ctx) -+} -+ -+func verify(ctx *C.GO_EVP_PKEY_CTX, out *C.uint8_t, outLen *C.uint, in *C.uint8_t, inLen C.uint) C.int { -+ return C._goboringcrypto_EVP_PKEY_verify(ctx, out, *outLen, in, inLen) ++ return evpEncrypt(pub.withKey, C.GO_RSA_NO_PADDING, nil, nil, msg) +} + +func SignRSAPSS(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte, saltLen int) ([]byte, error) { + if saltLen == 0 { + saltLen = -1 // RSA_PSS_SALTLEN_DIGEST + } -+ return cryptRSA(priv.withKey, C.RSA_PKCS1_PSS_PADDING, nil, nil, saltLen, h, signtInit, sign, nil, hashed) ++ return evpSign(priv.withKey, C.GO_RSA_PKCS1_PSS_PADDING, saltLen, h, hashed) +} + +func VerifyRSAPSS(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte, saltLen int) error { + if saltLen == 0 { + saltLen = -2 // RSA_PSS_SALTLEN_AUTO + } -+ _, err := cryptRSA(pub.withKey, C.RSA_PKCS1_PSS_PADDING, nil, nil, saltLen, h, verifyInit, verify, sig, hashed) -+ return err ++ return evpVerify(pub.withKey, C.GO_RSA_PKCS1_PSS_PADDING, saltLen, h, sig, hashed) +} + +func SignRSAPKCS1v15(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte) ([]byte, error) { -+ if h == 0 { -+ // No hashing. -+ var out []byte -+ var outLen C.int -+ if priv.withKey(func(key *C.GO_RSA) C.int { -+ out = make([]byte, C._goboringcrypto_RSA_size(key)) -+ outLen = C._goboringcrypto_RSA_private_encrypt(C.int(len(hashed)), base(hashed), -+ base(out), key, C.GO_RSA_PKCS1_PADDING) -+ return outLen -+ }) <= 0 { -+ return nil, newOpenSSLError("RSA_private_encrypt") -+ } -+ return out[:outLen], nil -+ } -+ -+ md := cryptoHashToMD(h) -+ if md == nil { -+ return nil, errors.New("crypto/rsa: unsupported hash function: " + strconv.Itoa(int(h))) -+ } -+ -+ nid := C._goboringcrypto_EVP_MD_type(md) -+ var out []byte -+ var outLen C.uint -+ if priv.withKey(func(key *C.GO_RSA) C.int { -+ out = make([]byte, C._goboringcrypto_RSA_size(key)) -+ return C._goboringcrypto_RSA_sign(nid, base(hashed), C.uint(len(hashed)), -+ base(out), &outLen, key) -+ }) == 0 { -+ return nil, newOpenSSLError("RSA_sign") -+ } -+ return out[:outLen], nil ++ return evpSign(priv.withKey, C.GO_RSA_PKCS1_PADDING, 0, h, hashed) +} + +func VerifyRSAPKCS1v15(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte) error { -+ if pub.withKey(func(key *C.GO_RSA) C.int { -+ size := int(C._goboringcrypto_RSA_size(key)) -+ if len(sig) < size { ++ if pub.withKey(func(pkey C.GO_EVP_PKEY_PTR) C.int { ++ size := C.go_openssl_EVP_PKEY_get_size(pkey) ++ if len(sig) < int(size) { + return 0 + } + return 1 + }) == 0 { + return errors.New("crypto/rsa: verification error") + } -+ if h == 0 { -+ var out []byte -+ var outLen C.int -+ if pub.withKey(func(key *C.GO_RSA) C.int { -+ out = make([]byte, C._goboringcrypto_RSA_size(key)) -+ outLen = C._goboringcrypto_RSA_public_decrypt(C.int(len(sig)), base(sig), base(out), key, C.GO_RSA_PKCS1_PADDING) -+ return outLen -+ }) <= 0 { -+ return newOpenSSLError("RSA_verify") ++ return evpVerify(pub.withKey, C.GO_RSA_PKCS1_PADDING, 0, h, sig, hashed) ++} ++ ++// rsa_st_1_0_2 is rsa_st memory layout in OpenSSL 1.0.2. ++type rsa_st_1_0_2 struct { ++ _ C.int ++ _ C.long ++ _ [2]unsafe.Pointer ++ n, e, d C.GO_BIGNUM_PTR ++ p, q C.GO_BIGNUM_PTR ++ dmp1, dmq1, iqmp C.GO_BIGNUM_PTR ++ // It contains more fields, but we are not interesed on them. ++} ++ ++func bnSet(b1 *C.GO_BIGNUM_PTR, b2 *big.Int) { ++ if b2 == nil { ++ return ++ } ++ if *b1 != nil { ++ C.go_openssl_BN_clear_free(*b1) ++ } ++ *b1 = bigToBN(b2) ++} ++ ++func rsaSetKey(key C.GO_RSA_PTR, n, e, d *big.Int) bool { ++ if vMajor == 1 && vMinor == 0 { ++ r := (*rsa_st_1_0_2)(unsafe.Pointer(key)) ++ //r.d and d will be nil for public keys. ++ if (r.n == nil && n == nil) || ++ (r.e == nil && e == nil) { ++ return false + } -+ if subtle.ConstantTimeCompare(hashed, out[:outLen]) != 1 { -+ return fail("RSA_verify") ++ bnSet(&r.n, n) ++ bnSet(&r.e, e) ++ bnSet(&r.d, d) ++ return true ++ } ++ return C.go_openssl_RSA_set0_key(key, bigToBN(n), bigToBN(e), bigToBN(d)) == 1 ++} ++ ++func rsaSetFactors(key C.GO_RSA_PTR, p, q *big.Int) bool { ++ if vMajor == 1 && vMinor == 0 { ++ r := (*rsa_st_1_0_2)(unsafe.Pointer(key)) ++ if (r.p == nil && p == nil) || ++ (r.q == nil && q == nil) { ++ return false + } -+ return nil ++ bnSet(&r.p, p) ++ bnSet(&r.q, q) ++ return true + } -+ md := cryptoHashToMD(h) -+ if md == nil { -+ return errors.New("crypto/rsa: unsupported hash function") ++ return C.go_openssl_RSA_set0_factors(key, bigToBN(p), bigToBN(q)) == 1 ++} ++ ++func rsaSetCRTParams(key C.GO_RSA_PTR, dmp1, dmq1, iqmp *big.Int) bool { ++ if vMajor == 1 && vMinor == 0 { ++ r := (*rsa_st_1_0_2)(unsafe.Pointer(key)) ++ if (r.dmp1 == nil && dmp1 == nil) || ++ (r.dmq1 == nil && dmq1 == nil) || ++ (r.iqmp == nil && iqmp == nil) { ++ return false ++ } ++ bnSet(&r.dmp1, dmp1) ++ bnSet(&r.dmq1, dmq1) ++ bnSet(&r.iqmp, iqmp) ++ return true + } -+ nid := C._goboringcrypto_EVP_MD_type(md) -+ if pub.withKey(func(key *C.GO_RSA) C.int { -+ return C._goboringcrypto_RSA_verify(nid, base(hashed), C.uint(len(hashed)), -+ base(sig), C.uint(len(sig)), key) -+ }) == 0 { -+ return newOpenSSLError("RSA_verify failed") ++ return C.go_openssl_RSA_set0_crt_params(key, bigToBN(dmp1), bigToBN(dmq1), bigToBN(iqmp)) == 1 ++} ++ ++func rsaGetKey(key C.GO_RSA_PTR) (*big.Int, *big.Int, *big.Int) { ++ var n, e, d C.GO_BIGNUM_PTR ++ if vMajor == 1 && vMinor == 0 { ++ r := (*rsa_st_1_0_2)(unsafe.Pointer(key)) ++ n, e, d = r.n, r.e, r.d ++ } else { ++ C.go_openssl_RSA_get0_key(key, &n, &e, &d) + } -+ return nil ++ return bnToBig(n), bnToBig(e), bnToBig(d) ++} ++ ++func rsaGetFactors(key C.GO_RSA_PTR) (*big.Int, *big.Int) { ++ var p, q C.GO_BIGNUM_PTR ++ if vMajor == 1 && vMinor == 0 { ++ r := (*rsa_st_1_0_2)(unsafe.Pointer(key)) ++ p, q = r.p, r.q ++ } else { ++ C.go_openssl_RSA_get0_factors(key, &p, &q) ++ } ++ return bnToBig(p), bnToBig(q) ++} ++ ++func rsaGetCRTParams(key C.GO_RSA_PTR) (*big.Int, *big.Int, *big.Int) { ++ var dmp1, dmq1, iqmp C.GO_BIGNUM_PTR ++ if vMajor == 1 && vMinor == 0 { ++ r := (*rsa_st_1_0_2)(unsafe.Pointer(key)) ++ dmp1, dmq1, iqmp = r.dmp1, r.dmq1, r.iqmp ++ } else { ++ C.go_openssl_RSA_get0_crt_params(key, &dmp1, &dmq1, &iqmp) ++ } ++ return bnToBig(dmp1), bnToBig(dmq1), bnToBig(iqmp) +} diff --git a/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/sha.go b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/sha.go new file mode 100644 -index 0000000000..9681dc3a7e +index 00000000000..c5b0189efc8 --- /dev/null +++ b/src/vendor/github.com/microsoft/go-crypto-openssl/openssl/sha.go -@@ -0,0 +1,477 @@ +@@ -0,0 +1,534 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + @@ -2596,48 +2453,144 @@ index 0000000000..9681dc3a7e +// #include "goopenssl.h" +import "C" +import ( ++ "crypto" + "errors" + "hash" ++ "runtime" ++ "strconv" + "unsafe" +) + -+// NewSHA1 returns a new SHA1 hash. -+func NewSHA1() hash.Hash { -+ h := new(sha1Hash) ++type evpHash struct { ++ md C.GO_EVP_MD_PTR ++ ctx C.GO_EVP_MD_CTX_PTR ++ // ctx2 is used in evpHash.sum to avoid changing ++ // the state of ctx. Having it here allows reusing the ++ // same allocated object multiple times. ++ ctx2 C.GO_EVP_MD_CTX_PTR ++ size int ++ blockSize int ++} ++ ++func newEvpHash(ch crypto.Hash, size, blockSize int) *evpHash { ++ md := cryptoHashToMD(ch) ++ if md == nil { ++ panic("openssl: unsupported hash function: " + strconv.Itoa(int(ch))) ++ } ++ ctx := C.go_openssl_EVP_MD_CTX_new() ++ ctx2 := C.go_openssl_EVP_MD_CTX_new() ++ h := &evpHash{ ++ md: md, ++ ctx: ctx, ++ ctx2: ctx2, ++ size: size, ++ blockSize: blockSize, ++ } ++ runtime.SetFinalizer(h, (*evpHash).finalize) + h.Reset() + return h +} + -+type sha1Hash struct { -+ ctx C.GO_SHA_CTX -+ out [20]byte ++func (h *evpHash) finalize() { ++ C.go_openssl_EVP_MD_CTX_free(h.ctx) ++ C.go_openssl_EVP_MD_CTX_free(h.ctx2) +} + -+type sha1Ctx struct { -+ h [5]uint32 -+ nl, nh uint32 -+ x [64]byte -+ nx uint32 -+} ++func (h *evpHash) Reset() { ++ // There is no need to reset h.ctx2 because it is always reset after ++ // use in evpHash.sum. ++ C.go_openssl_EVP_MD_CTX_reset(h.ctx) + -+func (h *sha1Hash) Reset() { C._goboringcrypto_SHA1_Init(&h.ctx) } -+func (h *sha1Hash) Size() int { return 20 } -+func (h *sha1Hash) BlockSize() int { return 64 } -+func (h *sha1Hash) Sum(in []byte) []byte { return append(in, h.sum()...) } ++ if C.go_openssl_EVP_DigestInit_ex(h.ctx, h.md, nil) != 1 { ++ panic("openssl: EVP_DigestInit_ex failed") ++ } ++ runtime.KeepAlive(h) ++} + -+func (h *sha1Hash) Write(p []byte) (int, error) { -+ if len(p) > 0 && C._goboringcrypto_SHA1_Update(&h.ctx, unsafe.Pointer(&p[0]), C.size_t(len(p))) == 0 { -+ panic("boringcrypto: SHA1_Update failed") ++func (h *evpHash) Write(p []byte) (int, error) { ++ if len(p) > 0 && C.go_openssl_EVP_DigestUpdate(h.ctx, unsafe.Pointer(&p[0]), C.size_t(len(p))) != 1 { ++ panic("openssl: EVP_DigestUpdate failed") + } ++ runtime.KeepAlive(h) + return len(p), nil +} + -+func (h0 *sha1Hash) sum() []byte { -+ h := *h0 // make copy so future Write+Sum is valid -+ if C._goboringcrypto_SHA1_Final((*C.uint8_t)(unsafe.Pointer(&h.out[0])), &h.ctx) == 0 { -+ panic("boringcrypto: SHA1_Final failed") ++func (h *evpHash) Size() int { ++ return h.size ++} ++ ++func (h *evpHash) BlockSize() int { ++ return h.blockSize ++} ++ ++func (h *evpHash) sum(out []byte) { ++ // Make copy of context because Go hash.Hash mandates ++ // that Sum has no effect on the underlying stream. ++ // In particular it is OK to Sum, then Write more, then Sum again, ++ // and the second Sum acts as if the first didn't happen. ++ C.go_openssl_EVP_DigestInit_ex(h.ctx2, h.md, nil) ++ if C.go_openssl_EVP_MD_CTX_copy_ex(h.ctx2, h.ctx) != 1 { ++ panic("openssl: EVP_MD_CTX_copy_ex failed") ++ } ++ if C.go_openssl_EVP_DigestFinal_ex(h.ctx2, base(out), nil) != 1 { ++ panic("openssl: EVP_DigestFinal_ex failed") ++ } ++ C.go_openssl_EVP_MD_CTX_reset(h.ctx2) ++ runtime.KeepAlive(h) ++} ++ ++// shaState returns a pointer to the internal sha structure. ++// ++// The EVP_MD_CTX memory layout has changed in OpenSSL 3 ++// and the property holding the internal structure is no longer md_data but algctx. ++func (h *evpHash) shaState() unsafe.Pointer { ++ switch vMajor { ++ case 1: ++ // https://github.com/openssl/openssl/blob/0418e993c717a6863f206feaa40673a261de7395/crypto/evp/evp_local.h#L12. ++ type mdCtx struct { ++ _ [2]unsafe.Pointer ++ _ C.ulong ++ md_data unsafe.Pointer ++ } ++ return (*mdCtx)(unsafe.Pointer(h.ctx)).md_data ++ case 3: ++ // https://github.com/openssl/openssl/blob/5675a5aaf6a2e489022bcfc18330dae9263e598e/crypto/evp/evp_local.h#L16. ++ type mdCtx struct { ++ _ [3]unsafe.Pointer ++ _ C.ulong ++ _ [3]unsafe.Pointer ++ algctx unsafe.Pointer ++ } ++ return (*mdCtx)(unsafe.Pointer(h.ctx)).algctx ++ default: ++ panic(errUnsuportedVersion()) ++ } ++} ++ ++// NewSHA1 returns a new SHA1 hash. ++func NewSHA1() hash.Hash { ++ return &sha1Hash{ ++ evpHash: newEvpHash(crypto.SHA1, 20, 64), + } -+ return h.out[:] ++} ++ ++type sha1Hash struct { ++ *evpHash ++ out [20]byte ++} ++ ++func (h *sha1Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) ++} ++ ++// sha1State layout is taken from ++// https://github.com/openssl/openssl/blob/0418e993c717a6863f206feaa40673a261de7395/include/openssl/sha.h#L34. ++type sha1State struct { ++ h [5]uint32 ++ nl, nh uint32 ++ x [64]byte ++ nx uint32 +} + +const ( @@ -2646,7 +2599,10 @@ index 0000000000..9681dc3a7e +) + +func (h *sha1Hash) MarshalBinary() ([]byte, error) { -+ d := (*sha1Ctx)(unsafe.Pointer(&h.ctx)) ++ d := (*sha1State)(h.shaState()) ++ if d == nil { ++ return nil, errors.New("crypto/sha1: can't retrieve hash state") ++ } + b := make([]byte, 0, sha1MarshaledSize) + b = append(b, sha1Magic...) + b = appendUint32(b, d.h[0]) @@ -2667,7 +2623,10 @@ index 0000000000..9681dc3a7e + if len(b) != sha1MarshaledSize { + return errors.New("crypto/sha1: invalid hash state size") + } -+ d := (*sha1Ctx)(unsafe.Pointer(&h.ctx)) ++ d := (*sha1State)(h.shaState()) ++ if d == nil { ++ return errors.New("crypto/sha1: can't retrieve hash state") ++ } + b = b[len(sha1Magic):] + b, d.h[0] = consumeUint32(b) + b, d.h[1] = consumeUint32(b) @@ -2675,7 +2634,7 @@ index 0000000000..9681dc3a7e + b, d.h[3] = consumeUint32(b) + b, d.h[4] = consumeUint32(b) + b = b[copy(d.x[:], b):] -+ b, n := consumeUint64(b) ++ _, n := consumeUint64(b) + d.nl = uint32(n << 3) + d.nh = uint32(n >> 29) + d.nx = uint32(n) % 64 @@ -2684,66 +2643,36 @@ index 0000000000..9681dc3a7e + +// NewSHA224 returns a new SHA224 hash. +func NewSHA224() hash.Hash { -+ h := new(sha224Hash) -+ h.Reset() -+ return h ++ return &sha224Hash{ ++ evpHash: newEvpHash(crypto.SHA224, 224/8, 64), ++ } +} + +type sha224Hash struct { -+ ctx C.GO_SHA256_CTX ++ *evpHash + out [224 / 8]byte +} + -+func (h *sha224Hash) Reset() { C._goboringcrypto_SHA224_Init(&h.ctx) } -+func (h *sha224Hash) Size() int { return 224 / 8 } -+func (h *sha224Hash) BlockSize() int { return 64 } -+func (h *sha224Hash) Sum(in []byte) []byte { return append(in, h.sum()...) } -+ -+func (h *sha224Hash) Write(p []byte) (int, error) { -+ if len(p) > 0 && C._goboringcrypto_SHA224_Update(&h.ctx, unsafe.Pointer(&p[0]), C.size_t(len(p))) == 0 { -+ panic("boringcrypto: SHA224_Update failed") -+ } -+ return len(p), nil -+} -+ -+func (h0 *sha224Hash) sum() []byte { -+ h := *h0 // make copy so future Write+Sum is valid -+ if C._goboringcrypto_SHA224_Final((*C.uint8_t)(unsafe.Pointer(&h.out[0])), &h.ctx) == 0 { -+ panic("boringcrypto: SHA224_Final failed") -+ } -+ return h.out[:] ++func (h *sha224Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) +} + +// NewSHA256 returns a new SHA256 hash. +func NewSHA256() hash.Hash { -+ h := new(sha256Hash) -+ h.Reset() -+ return h ++ return &sha256Hash{ ++ evpHash: newEvpHash(crypto.SHA256, 256/8, 64), ++ } +} + +type sha256Hash struct { -+ ctx C.GO_SHA256_CTX ++ *evpHash + out [256 / 8]byte +} + -+func (h *sha256Hash) Reset() { C._goboringcrypto_SHA256_Init(&h.ctx) } -+func (h *sha256Hash) Size() int { return 256 / 8 } -+func (h *sha256Hash) BlockSize() int { return 64 } -+func (h *sha256Hash) Sum(in []byte) []byte { return append(in, h.sum()...) } -+ -+func (h *sha256Hash) Write(p []byte) (int, error) { -+ if len(p) > 0 && C._goboringcrypto_SHA256_Update(&h.ctx, unsafe.Pointer(&p[0]), C.size_t(len(p))) == 0 { -+ panic("boringcrypto: SHA256_Update failed") -+ } -+ return len(p), nil -+} -+ -+func (h0 *sha256Hash) sum() []byte { -+ h := *h0 // make copy so future Write+Sum is valid -+ if C._goboringcrypto_SHA256_Final((*C.uint8_t)(unsafe.Pointer(&h.out[0])), &h.ctx) == 0 { -+ panic("boringcrypto: SHA256_Final failed") -+ } -+ return h.out[:] ++func (h *sha256Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) +} + +const ( @@ -2752,7 +2681,9 @@ index 0000000000..9681dc3a7e + marshaledSize256 = len(magic256) + 8*4 + 64 + 8 +) + -+type sha256Ctx struct { ++// sha256State layout is taken from ++// https://github.com/openssl/openssl/blob/0418e993c717a6863f206feaa40673a261de7395/include/openssl/sha.h#L51. ++type sha256State struct { + h [8]uint32 + nl, nh uint32 + x [64]byte @@ -2760,7 +2691,10 @@ index 0000000000..9681dc3a7e +} + +func (h *sha224Hash) MarshalBinary() ([]byte, error) { -+ d := (*sha256Ctx)(unsafe.Pointer(&h.ctx)) ++ d := (*sha256State)(h.shaState()) ++ if d == nil { ++ return nil, errors.New("crypto/sha256: can't retrieve hash state") ++ } + b := make([]byte, 0, marshaledSize256) + b = append(b, magic224...) + b = appendUint32(b, d.h[0]) @@ -2778,7 +2712,10 @@ index 0000000000..9681dc3a7e +} + +func (h *sha256Hash) MarshalBinary() ([]byte, error) { -+ d := (*sha256Ctx)(unsafe.Pointer(&h.ctx)) ++ d := (*sha256State)(h.shaState()) ++ if d == nil { ++ return nil, errors.New("crypto/sha256: can't retrieve hash state") ++ } + b := make([]byte, 0, marshaledSize256) + b = append(b, magic256...) + b = appendUint32(b, d.h[0]) @@ -2802,7 +2739,10 @@ index 0000000000..9681dc3a7e + if len(b) != marshaledSize256 { + return errors.New("crypto/sha256: invalid hash state size") + } -+ d := (*sha256Ctx)(unsafe.Pointer(&h.ctx)) ++ d := (*sha256State)(h.shaState()) ++ if d == nil { ++ return errors.New("crypto/sha256: can't retrieve hash state") ++ } + b = b[len(magic224):] + b, d.h[0] = consumeUint32(b) + b, d.h[1] = consumeUint32(b) @@ -2813,7 +2753,7 @@ index 0000000000..9681dc3a7e + b, d.h[6] = consumeUint32(b) + b, d.h[7] = consumeUint32(b) + b = b[copy(d.x[:], b):] -+ b, n := consumeUint64(b) ++ _, n := consumeUint64(b) + d.nl = uint32(n << 3) + d.nh = uint32(n >> 29) + d.nx = uint32(n) % 64 @@ -2827,7 +2767,10 @@ index 0000000000..9681dc3a7e + if len(b) != marshaledSize256 { + return errors.New("crypto/sha256: invalid hash state size") + } -+ d := (*sha256Ctx)(unsafe.Pointer(&h.ctx)) ++ d := (*sha256State)(h.shaState()) ++ if d == nil { ++ return errors.New("crypto/sha256: can't retrieve hash state") ++ } + b = b[len(magic256):] + b, d.h[0] = consumeUint32(b) + b, d.h[1] = consumeUint32(b) @@ -2838,7 +2781,7 @@ index 0000000000..9681dc3a7e + b, d.h[6] = consumeUint32(b) + b, d.h[7] = consumeUint32(b) + b = b[copy(d.x[:], b):] -+ b, n := consumeUint64(b) ++ _, n := consumeUint64(b) + d.nl = uint32(n << 3) + d.nh = uint32(n >> 29) + d.nx = uint32(n) % 64 @@ -2847,69 +2790,41 @@ index 0000000000..9681dc3a7e + +// NewSHA384 returns a new SHA384 hash. +func NewSHA384() hash.Hash { -+ h := new(sha384Hash) -+ h.Reset() -+ return h ++ return &sha384Hash{ ++ evpHash: newEvpHash(crypto.SHA384, 384/8, 128), ++ } +} + +type sha384Hash struct { -+ ctx C.GO_SHA512_CTX ++ *evpHash + out [384 / 8]byte +} + -+func (h *sha384Hash) Reset() { C._goboringcrypto_SHA384_Init(&h.ctx) } -+func (h *sha384Hash) Size() int { return 384 / 8 } -+func (h *sha384Hash) BlockSize() int { return 128 } -+func (h *sha384Hash) Sum(in []byte) []byte { return append(in, h.sum()...) } -+ -+func (h *sha384Hash) Write(p []byte) (int, error) { -+ if len(p) > 0 && C._goboringcrypto_SHA384_Update(&h.ctx, unsafe.Pointer(&p[0]), C.size_t(len(p))) == 0 { -+ panic("boringcrypto: SHA384_Update failed") -+ } -+ return len(p), nil -+} -+ -+func (h0 *sha384Hash) sum() []byte { -+ h := *h0 // make copy so future Write+Sum is valid -+ if C._goboringcrypto_SHA384_Final((*C.uint8_t)(unsafe.Pointer(&h.out[0])), &h.ctx) == 0 { -+ panic("boringcrypto: SHA384_Final failed") -+ } -+ return h.out[:] ++func (h *sha384Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) +} + +// NewSHA512 returns a new SHA512 hash. +func NewSHA512() hash.Hash { -+ h := new(sha512Hash) -+ h.Reset() -+ return h ++ return &sha512Hash{ ++ evpHash: newEvpHash(crypto.SHA512, 512/8, 128), ++ } +} + +type sha512Hash struct { -+ ctx C.GO_SHA512_CTX ++ *evpHash + out [512 / 8]byte +} + -+func (h *sha512Hash) Reset() { C._goboringcrypto_SHA512_Init(&h.ctx) } -+func (h *sha512Hash) Size() int { return 512 / 8 } -+func (h *sha512Hash) BlockSize() int { return 128 } -+func (h *sha512Hash) Sum(in []byte) []byte { return append(in, h.sum()...) } -+ -+func (h *sha512Hash) Write(p []byte) (int, error) { -+ if len(p) > 0 && C._goboringcrypto_SHA512_Update(&h.ctx, unsafe.Pointer(&p[0]), C.size_t(len(p))) == 0 { -+ panic("boringcrypto: SHA512_Update failed") -+ } -+ return len(p), nil -+} -+ -+func (h0 *sha512Hash) sum() []byte { -+ h := *h0 // make copy so future Write+Sum is valid -+ if C._goboringcrypto_SHA512_Final((*C.uint8_t)(unsafe.Pointer(&h.out[0])), &h.ctx) == 0 { -+ panic("boringcrypto: SHA512_Final failed") -+ } -+ return h.out[:] ++func (h *sha512Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) +} + -+type sha512Ctx struct { ++// sha256State layout is taken from ++// https://github.com/openssl/openssl/blob/0418e993c717a6863f206feaa40673a261de7395/include/openssl/sha.h#L95. ++type sha512State struct { + h [8]uint64 + nl, nh uint64 + x [128]byte @@ -2924,10 +2839,11 @@ index 0000000000..9681dc3a7e + marshaledSize512 = len(magic512) + 8*8 + 128 + 8 +) + -+var zero [128]byte -+ +func (h *sha384Hash) MarshalBinary() ([]byte, error) { -+ d := (*sha512Ctx)(unsafe.Pointer(&h.ctx)) ++ d := (*sha512State)(h.shaState()) ++ if d == nil { ++ return nil, errors.New("crypto/sha512: can't retrieve hash state") ++ } + b := make([]byte, 0, marshaledSize512) + b = append(b, magic384...) + b = appendUint64(b, d.h[0]) @@ -2945,7 +2861,10 @@ index 0000000000..9681dc3a7e +} + +func (h *sha512Hash) MarshalBinary() ([]byte, error) { -+ d := (*sha512Ctx)(unsafe.Pointer(&h.ctx)) ++ d := (*sha512State)(h.shaState()) ++ if d == nil { ++ return nil, errors.New("crypto/sha512: can't retrieve hash state") ++ } + b := make([]byte, 0, marshaledSize512) + b = append(b, magic512...) + b = appendUint64(b, d.h[0]) @@ -2972,7 +2891,10 @@ index 0000000000..9681dc3a7e + if len(b) != marshaledSize512 { + return errors.New("crypto/sha512: invalid hash state size") + } -+ d := (*sha512Ctx)(unsafe.Pointer(&h.ctx)) ++ d := (*sha512State)(h.shaState()) ++ if d == nil { ++ return errors.New("crypto/sha512: can't retrieve hash state") ++ } + b = b[len(magic512):] + b, d.h[0] = consumeUint64(b) + b, d.h[1] = consumeUint64(b) @@ -2983,7 +2905,7 @@ index 0000000000..9681dc3a7e + b, d.h[6] = consumeUint64(b) + b, d.h[7] = consumeUint64(b) + b = b[copy(d.x[:], b):] -+ b, n := consumeUint64(b) ++ _, n := consumeUint64(b) + d.nl = n << 3 + d.nh = n >> 61 + d.nx = uint32(n) % 128 @@ -3000,7 +2922,10 @@ index 0000000000..9681dc3a7e + if len(b) != marshaledSize512 { + return errors.New("crypto/sha512: invalid hash state size") + } -+ d := (*sha512Ctx)(unsafe.Pointer(&h.ctx)) ++ d := (*sha512State)(h.shaState()) ++ if d == nil { ++ return errors.New("crypto/sha512: can't retrieve hash state") ++ } + b = b[len(magic512):] + b, d.h[0] = consumeUint64(b) + b, d.h[1] = consumeUint64(b) @@ -3011,25 +2936,33 @@ index 0000000000..9681dc3a7e + b, d.h[6] = consumeUint64(b) + b, d.h[7] = consumeUint64(b) + b = b[copy(d.x[:], b):] -+ b, n := consumeUint64(b) ++ _, n := consumeUint64(b) + d.nl = n << 3 + d.nh = n >> 61 + d.nx = uint32(n) % 128 + return nil +} + ++// appendUint64 appends x into b as a big endian byte sequence. +func appendUint64(b []byte, x uint64) []byte { -+ var a [8]byte -+ putUint64(a[:], x) -+ return append(b, a[:]...) -+} -+ ++ return append(b, ++ byte(x>>56), ++ byte(x>>48), ++ byte(x>>40), ++ byte(x>>32), ++ byte(x>>24), ++ byte(x>>16), ++ byte(x>>8), ++ byte(x), ++ ) ++} ++ ++// appendUint32 appends x into b as a big endian byte sequence. +func appendUint32(b []byte, x uint32) []byte { -+ var a [4]byte -+ putUint32(a[:], x) -+ return append(b, a[:]...) ++ return append(b, byte(x>>24), byte(x>>16), byte(x>>8), byte(x)) +} + ++// consumeUint64 reads a big endian uint64 number from b. +func consumeUint64(b []byte) ([]byte, uint64) { + _ = b[7] + x := uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 | @@ -3037,37 +2970,18 @@ index 0000000000..9681dc3a7e + return b[8:], x +} + ++// consumeUint32 reads a big endian uint32 number from b. +func consumeUint32(b []byte) ([]byte, uint32) { + _ = b[3] + x := uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24 + return b[4:], x +} -+ -+func putUint64(x []byte, s uint64) { -+ _ = x[7] -+ x[0] = byte(s >> 56) -+ x[1] = byte(s >> 48) -+ x[2] = byte(s >> 40) -+ x[3] = byte(s >> 32) -+ x[4] = byte(s >> 24) -+ x[5] = byte(s >> 16) -+ x[6] = byte(s >> 8) -+ x[7] = byte(s) -+} -+ -+func putUint32(x []byte, s uint32) { -+ _ = x[3] -+ x[0] = byte(s >> 24) -+ x[1] = byte(s >> 16) -+ x[2] = byte(s >> 8) -+ x[3] = byte(s) -+} diff --git a/src/vendor/modules.txt b/src/vendor/modules.txt -index a1b16d7b84..a733603e8b 100644 +index a1b16d7b84f..846e1c54ee8 100644 --- a/src/vendor/modules.txt +++ b/src/vendor/modules.txt @@ -1,3 +1,7 @@ -+# github.com/microsoft/go-crypto-openssl v0.0.0-20220124101237-183c44c3cf71 ++# github.com/microsoft/go-crypto-openssl v0.0.0-20220420170843-a127057fb794 +## explicit; go 1.16 +github.com/microsoft/go-crypto-openssl/openssl +github.com/microsoft/go-crypto-openssl/openssl/internal/subtle From bcaa2ae21f2d21d902ae1c56fb1d6342295784ea Mon Sep 17 00:00:00 2001 From: microsoft-golang-bot Date: Thu, 2 Jun 2022 17:52:13 +0000 Subject: [PATCH 44/47] Update submodule to latest dev.boringcrypto.go1.17 (4658e6e3): [dev.boringcrypto.go1.17] all: merge go1.17.11 into dev.boringcrypto.go1.17 --- MICROSOFT_REVISION | 1 - VERSION | 2 +- go | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) delete mode 100644 MICROSOFT_REVISION diff --git a/MICROSOFT_REVISION b/MICROSOFT_REVISION deleted file mode 100644 index 56a6051ca2b..00000000000 --- a/MICROSOFT_REVISION +++ /dev/null @@ -1 +0,0 @@ -1 \ No newline at end of file diff --git a/VERSION b/VERSION index d1ab52a8a26..3e9980643ef 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -go1.17.10 \ No newline at end of file +go1.17.11 \ No newline at end of file diff --git a/go b/go index 6b07de790c0..4658e6e324a 160000 --- a/go +++ b/go @@ -1 +1 @@ -Subproject commit 6b07de790c08967d0dbe3a36ec86f3d13e1cfcbd +Subproject commit 4658e6e324a85b0076f66acdab77799ffa9ac7bb From e8d3dace147f7ee98a599a4d2fcdbe78dd03e8e8 Mon Sep 17 00:00:00 2001 From: microsoft-golang-bot Date: Wed, 13 Jul 2022 16:02:52 +0000 Subject: [PATCH 45/47] Update submodule to latest dev.boringcrypto.go1.17 (7d5078e3): [dev.boringcrypto.go1.17] all: merge go1.17.12 into dev.boringcrypto.go1.17 --- go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go b/go index 4658e6e324a..7d5078e3bf2 160000 --- a/go +++ b/go @@ -1 +1 @@ -Subproject commit 4658e6e324a85b0076f66acdab77799ffa9ac7bb +Subproject commit 7d5078e3bf2d865526e8ec2d211f61b2fac2936f From a57a91cddf54455271e5fa0d7d15c8f0240f01cb Mon Sep 17 00:00:00 2001 From: microsoft-golang-bot Date: Wed, 13 Jul 2022 17:58:05 +0000 Subject: [PATCH 46/47] Update submodule to latest dev.boringcrypto.go1.17 (7d5078e3): [dev.boringcrypto.go1.17] all: merge go1.17.12 into dev.boringcrypto.go1.17 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 3e9980643ef..760e3832356 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -go1.17.11 \ No newline at end of file +go1.17.12 \ No newline at end of file From c0efbba6bd23c4c5c38ba757fe18a17c3b207153 Mon Sep 17 00:00:00 2001 From: microsoft-golang-bot Date: Mon, 1 Aug 2022 17:41:37 +0000 Subject: [PATCH 47/47] Update submodule to latest dev.boringcrypto.go1.17 (349da2d4): [dev.boringcrypto.go1.17] all: merge go1.17.13 into dev.boringcrypto.go1.17 --- VERSION | 2 +- go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index 760e3832356..1db9985a169 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -go1.17.12 \ No newline at end of file +go1.17.13 \ No newline at end of file diff --git a/go b/go index 7d5078e3bf2..349da2d42d3 160000 --- a/go +++ b/go @@ -1 +1 @@ -Subproject commit 7d5078e3bf2d865526e8ec2d211f61b2fac2936f +Subproject commit 349da2d42d3193af7f54170ae842166e4571134a