Skip to content

Commit ef79040

Browse files
authored
Support backend ciphers in cipher.NewGCMWithRandomNonce (#1673)
* fix: implement aes aead * fix:correct return value * fix: implement extended aed * fix:patch the gcmwithrandomnonce * fix:wrap returned interface * fix:add missing returns * fix:use correct consts * use custom interface for checking if cipher returned from boring or not * Fix:openssl patches * add missing const * fix:update all backends * fix:remove extra token * fix:remove unneccesary code * revert changes in gcm * update:panic when none of the cases met for interface casting * fix: revert backend changes for minimal diff * fix:use newgcm * fix:use correct panic msg * fix:add extra check * fix:return customgcmwrapper by value * fix:address PR comments * readd checks in testgcmaead * fix:typo
1 parent 866021a commit ef79040

File tree

3 files changed

+306
-47
lines changed

3 files changed

+306
-47
lines changed

patches/0002-Vendor-crypto-backends.patch

Lines changed: 131 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Use a 'go' that was recently built by the current branch to ensure stable result
1818
.../github.com/golang-fips/openssl/v2/aes.go | 146 ++
1919
.../golang-fips/openssl/v2/bbig/big.go | 37 +
2020
.../github.com/golang-fips/openssl/v2/big.go | 11 +
21-
.../golang-fips/openssl/v2/cipher.go | 603 +++++
21+
.../golang-fips/openssl/v2/cipher.go | 654 ++++++
2222
.../golang-fips/openssl/v2/const.go | 93 +
2323
.../github.com/golang-fips/openssl/v2/des.go | 113 +
2424
.../github.com/golang-fips/openssl/v2/dsa.go | 309 +++
@@ -59,7 +59,7 @@ Use a 'go' that was recently built by the current branch to ensure stable result
5959
.../internal/cryptokit/hash.go | 255 +++
6060
.../internal/cryptokit/hkdf.go | 77 +
6161
.../internal/cryptokit/hmac.go | 144 ++
62-
.../microsoft/go-crypto-darwin/xcrypto/aes.go | 306 +++
62+
.../microsoft/go-crypto-darwin/xcrypto/aes.go | 336 +++
6363
.../microsoft/go-crypto-darwin/xcrypto/big.go | 16 +
6464
.../go-crypto-darwin/xcrypto/cgo_go124.go | 23 +
6565
.../go-crypto-darwin/xcrypto/cipher.go | 122 +
@@ -78,7 +78,7 @@ Use a 'go' that was recently built by the current branch to ensure stable result
7878
.../microsoft/go-crypto-darwin/xcrypto/rsa.go | 194 ++
7979
.../go-crypto-darwin/xcrypto/xcrypto.go | 49 +
8080
.../microsoft/go-crypto-winnative/LICENSE | 21 +
81-
.../microsoft/go-crypto-winnative/cng/aes.go | 393 ++++
81+
.../microsoft/go-crypto-winnative/cng/aes.go | 427 ++++
8282
.../go-crypto-winnative/cng/bbig/big.go | 31 +
8383
.../microsoft/go-crypto-winnative/cng/big.go | 30 +
8484
.../go-crypto-winnative/cng/cipher.go | 52 +
@@ -103,7 +103,7 @@ Use a 'go' that was recently built by the current branch to ensure stable result
103103
.../internal/subtle/aliasing.go | 32 +
104104
.../internal/sysdll/sys_windows.go | 55 +
105105
src/vendor/modules.txt | 17 +
106-
97 files changed, 17015 insertions(+), 7 deletions(-)
106+
97 files changed, 17130 insertions(+), 7 deletions(-)
107107
create mode 100644 src/crypto/internal/backend/deps_ignore.go
108108
create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/.gitignore
109109
create mode 100644 src/vendor/github.com/golang-fips/openssl/v2/.gitleaks.toml
@@ -226,7 +226,7 @@ index 00000000000000..ae4055d2d71303
226226
+// that are used by the backend package. This allows to track
227227
+// their versions in a single patch file.
228228
diff --git a/src/go.mod b/src/go.mod
229-
index 28e250668dd52c..0856b1d14f7d34 100644
229+
index 28e250668dd52c..e5aa4b223a54d4 100644
230230
--- a/src/go.mod
231231
+++ b/src/go.mod
232232
@@ -11,3 +11,9 @@ require (
@@ -240,7 +240,7 @@ index 28e250668dd52c..0856b1d14f7d34 100644
240240
+ github.com/microsoft/go-crypto-winnative v0.0.0-20250224213920-97653fcd3f40
241241
+)
242242
diff --git a/src/go.sum b/src/go.sum
243-
index ca2e7027fad3bd..00efdf0cb6041e 100644
243+
index ca2e7027fad3bd..f623f220d18598 100644
244244
--- a/src/go.sum
245245
+++ b/src/go.sum
246246
@@ -1,3 +1,9 @@
@@ -254,7 +254,7 @@ index ca2e7027fad3bd..00efdf0cb6041e 100644
254254
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
255255
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
256256
diff --git a/src/go/build/deps_test.go b/src/go/build/deps_test.go
257-
index 1eb683a5ae77b7..2adf8c897229cf 100644
257+
index b261af47e2167c..3ad0b0a3f2f465 100644
258258
--- a/src/go/build/deps_test.go
259259
+++ b/src/go/build/deps_test.go
260260
@@ -518,6 +518,24 @@ var depsRules = `
@@ -311,7 +311,7 @@ index 1eb683a5ae77b7..2adf8c897229cf 100644
311311
CRYPTO, FMT, math/big
312312
< crypto/internal/boring/bbig
313313
< crypto/rand
314-
@@ -858,7 +879,7 @@ var buildIgnore = []byte("\n//go:build ignore")
314+
@@ -861,7 +882,7 @@ var buildIgnore = []byte("\n//go:build ignore")
315315

316316
func findImports(pkg string) ([]string, error) {
317317
vpkg := pkg
@@ -320,7 +320,7 @@ index 1eb683a5ae77b7..2adf8c897229cf 100644
320320
vpkg = "vendor/" + pkg
321321
}
322322
dir := filepath.Join(Default.GOROOT, "src", vpkg)
323-
@@ -868,7 +889,7 @@ func findImports(pkg string) ([]string, error) {
323+
@@ -871,7 +892,7 @@ func findImports(pkg string) ([]string, error) {
324324
}
325325
var imports []string
326326
var haveImport = map[string]bool{}
@@ -679,10 +679,10 @@ index 00000000000000..6461f241f863fc
679679
+type BigInt []uint
680680
diff --git a/src/vendor/github.com/golang-fips/openssl/v2/cipher.go b/src/vendor/github.com/golang-fips/openssl/v2/cipher.go
681681
new file mode 100644
682-
index 00000000000000..2a3a91eb549a68
682+
index 00000000000000..c9b2a64e181d3e
683683
--- /dev/null
684684
+++ b/src/vendor/github.com/golang-fips/openssl/v2/cipher.go
685-
@@ -0,0 +1,603 @@
685+
@@ -0,0 +1,654 @@
686686
+//go:build !cmd_go_bootstrap
687687
+
688688
+package openssl
@@ -1010,6 +1010,7 @@ index 00000000000000..2a3a91eb549a68
10101010
+}
10111011
+
10121012
+const (
1013+
+ aesBlockSize = 16
10131014
+ gcmTagSize = 16
10141015
+ gcmStandardNonceSize = 12
10151016
+ // TLS 1.2 additional data is constructed as:
@@ -1165,6 +1166,56 @@ index 00000000000000..2a3a91eb549a68
11651166
+ return ret
11661167
+}
11671168
+
1169+
+func (g *cipherGCM) SealWithRandomNonce(out, nonce, plaintext, aad []byte) {
1170+
+ if uint64(len(plaintext)) > uint64((1<<32)-2)*aesBlockSize {
1171+
+ panic("crypto/cipher: message too large for GCM")
1172+
+ }
1173+
+ if len(nonce) != gcmStandardNonceSize {
1174+
+ panic("crypto/cipher: incorrect nonce length given to GCMWithRandomNonce")
1175+
+ }
1176+
+ if len(out) != len(plaintext)+gcmTagSize {
1177+
+ panic("crypto/cipher: incorrect output length given to GCMWithRandomNonce")
1178+
+ }
1179+
+ if inexactOverlap(out, plaintext) {
1180+
+ panic("crypto/cipher: invalid buffer overlap of output and input")
1181+
+ }
1182+
+ if anyOverlap(out, aad) {
1183+
+ panic("crypto/cipher: invalid buffer overlap of output and additional data")
1184+
+ }
1185+
+
1186+
+ if g.tls != cipherGCMTLSNone {
1187+
+ panic("cipher: encryption failed")
1188+
+ }
1189+
+
1190+
+ RandReader.Read(nonce)
1191+
+ ctx, err := newCipherCtx(g.c.kind, cipherModeGCM, cipherOpNone, g.c.key, nil)
1192+
+ if err != nil {
1193+
+ panic(err)
1194+
+ }
1195+
+ defer ossl.EVP_CIPHER_CTX_free(ctx)
1196+
+ if _, err := ossl.EVP_EncryptInit_ex(ctx, nil, nil, nil, base(nonce)); err != nil {
1197+
+ panic(err)
1198+
+ }
1199+
+ var outl, discard int32
1200+
+ if _, err := ossl.EVP_EncryptUpdate(ctx, nil, &discard, baseNeverEmpty(aad), int32(len(aad))); err != nil {
1201+
+ panic(err)
1202+
+ }
1203+
+ if _, err := ossl.EVP_EncryptUpdate(ctx, base(out), &outl, baseNeverEmpty(plaintext), int32(len(plaintext))); err != nil {
1204+
+ panic(err)
1205+
+ }
1206+
+ if len(plaintext) != int(outl) {
1207+
+ panic("cipher: incorrect length returned from GCM EncryptUpdate")
1208+
+ }
1209+
+ if _, err := ossl.EVP_EncryptFinal_ex(ctx, base(out[outl:]), &discard); err != nil {
1210+
+ panic(err)
1211+
+ }
1212+
+ if _, err := ossl.EVP_CIPHER_CTX_ctrl(ctx, ossl.EVP_CTRL_GCM_GET_TAG, 16, unsafe.Pointer(base(out[outl:]))); err != nil {
1213+
+ panic(err)
1214+
+ }
1215+
+ runtime.KeepAlive(g)
1216+
+ return
1217+
+}
1218+
+
11681219
+var errOpen = errors.New("cipher: message authentication failed")
11691220
+
11701221
+func (g *cipherGCM) Open(dst, nonce, ciphertext, aad []byte) (_ []byte, err error) {
@@ -12399,10 +12450,10 @@ index 00000000000000..c9f4d67de4c9f3
1239912450
+}
1240012451
diff --git a/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/aes.go b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/aes.go
1240112452
new file mode 100644
12402-
index 00000000000000..27a42bfc89ca06
12453+
index 00000000000000..c9611eef5e2697
1240312454
--- /dev/null
1240412455
+++ b/src/vendor/github.com/microsoft/go-crypto-darwin/xcrypto/aes.go
12405-
@@ -0,0 +1,306 @@
12456+
@@ -0,0 +1,336 @@
1240612457
+// Copyright (c) Microsoft Corporation.
1240712458
+// Licensed under the MIT License.
1240812459
+
@@ -12623,6 +12674,36 @@ index 00000000000000..27a42bfc89ca06
1262312674
+ return ret
1262412675
+}
1262512676
+
12677+
+func (g *aesGCM) SealWithRandomNonce(out, nonce, plaintext, additionalData []byte) {
12678+
+ if uint64(len(plaintext)) > uint64((1<<32)-2)*aesBlockSize {
12679+
+ panic("crypto/cipher: message too large for GCM")
12680+
+ }
12681+
+ if len(nonce) != gcmStandardNonceSize {
12682+
+ panic("crypto/cipher: incorrect nonce length given to GCMWithRandomNonce")
12683+
+ }
12684+
+ if len(out) != len(plaintext)+gcmTagSize {
12685+
+ panic("crypto/cipher: incorrect output length given to GCMWithRandomNonce")
12686+
+ }
12687+
+ if inexactOverlap(out, plaintext) {
12688+
+ panic("crypto/cipher: invalid buffer overlap of output and input")
12689+
+ }
12690+
+ if anyOverlap(out, additionalData) {
12691+
+ panic("crypto/cipher: invalid buffer overlap of output and additional data")
12692+
+ }
12693+
+
12694+
+ if g.tls != cipherGCMTLSNone {
12695+
+ panic("cipher: TLS 1.2 and 1.3 modes do not support random nonce")
12696+
+ }
12697+
+
12698+
+ tag := out[len(out)-gcmTagSize:]
12699+
+ // Generate a random nonce
12700+
+ RandReader.Read(nonce)
12701+
+ err := cryptokit.EncryptAESGCM(g.key, plaintext, nonce, additionalData, out[:len(out)-gcmTagSize], tag)
12702+
+ if err != 0 {
12703+
+ panic("cipher: encryption failed")
12704+
+ }
12705+
+}
12706+
+
1262612707
+var errOpen = errors.New("cipher: message authentication failed")
1262712708
+
1262812709
+func (g *aesGCM) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
@@ -14483,10 +14564,10 @@ index 00000000000000..9e841e7a26e4eb
1448314564
+ SOFTWARE
1448414565
diff --git a/src/vendor/github.com/microsoft/go-crypto-winnative/cng/aes.go b/src/vendor/github.com/microsoft/go-crypto-winnative/cng/aes.go
1448514566
new file mode 100644
14486-
index 00000000000000..097a0fc77f0adb
14567+
index 00000000000000..692a36ec7079cc
1448714568
--- /dev/null
1448814569
+++ b/src/vendor/github.com/microsoft/go-crypto-winnative/cng/aes.go
14489-
@@ -0,0 +1,393 @@
14570+
@@ -0,0 +1,427 @@
1449014571
+// Copyright (c) Microsoft Corporation.
1449114572
+// Licensed under the MIT License.
1449214573
+
@@ -14826,6 +14907,40 @@ index 00000000000000..097a0fc77f0adb
1482614907
+ return ret
1482714908
+}
1482814909
+
14910+
+func (g *aesGCM) SealWithRandomNonce(out, nonce, plaintext, additionalData []byte) {
14911+
+ if uint64(len(plaintext)) > uint64((1<<32)-2)*aesBlockSize {
14912+
+ panic("crypto/cipher: message too large for GCM")
14913+
+ }
14914+
+ if len(nonce) != gcmStandardNonceSize {
14915+
+ panic("crypto/cipher: incorrect nonce length given to GCMWithRandomNonce")
14916+
+ }
14917+
+ if len(out) != len(plaintext)+gcmTagSize {
14918+
+ panic("crypto/cipher: incorrect output length given to GCMWithRandomNonce")
14919+
+ }
14920+
+ if subtle.InexactOverlap(out, plaintext) {
14921+
+ panic("crypto/cipher: invalid buffer overlap of output and input")
14922+
+ }
14923+
+ if subtle.AnyOverlap(out, additionalData) {
14924+
+ panic("crypto/cipher: invalid buffer overlap of output and additional data")
14925+
+ }
14926+
+
14927+
+ if g.tls != cipherGCMTLSNone {
14928+
+ panic("cipher: TLS 1.2 and 1.3 modes do not support random nonce")
14929+
+ }
14930+
+
14931+
+ RandReader.Read(nonce)
14932+
+ info := bcrypt.NewAUTHENTICATED_CIPHER_MODE_INFO(nonce, additionalData, out[len(out)-gcmTagSize:])
14933+
+ var encSize uint32
14934+
+ err := bcrypt.Encrypt(g.kh, plaintext, unsafe.Pointer(info), nil, out, &encSize, 0)
14935+
+ if err != nil {
14936+
+ panic(err)
14937+
+ }
14938+
+ if int(encSize) != len(plaintext) {
14939+
+ panic("crypto/cipher: plaintext not fully encrypted")
14940+
+ }
14941+
+ runtime.KeepAlive(g)
14942+
+}
14943+
+
1482914944
+var errOpen = errors.New("cipher: message authentication failed")
1483014945
+
1483114946
+func (g *aesGCM) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
@@ -18837,7 +18952,7 @@ index 00000000000000..1722410e5af193
1883718952
+ return getSystemDirectory() + "\\" + dll
1883818953
+}
1883918954
diff --git a/src/vendor/modules.txt b/src/vendor/modules.txt
18840-
index 4c87639632f887..35848b6d6cd2dd 100644
18955+
index 4c87639632f887..271c698c1d681b 100644
1884118956
--- a/src/vendor/modules.txt
1884218957
+++ b/src/vendor/modules.txt
1884318958
@@ -1,3 +1,20 @@

patches/0003-Implement-crypto-internal-backend.patch

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2710,10 +2710,10 @@ index 00000000000000..5e4b436554d44d
27102710
+// from complaining about the missing body
27112711
+// (because the implementation might be here).
27122712
diff --git a/src/go/build/deps_test.go b/src/go/build/deps_test.go
2713-
index 0095243ce2b0b7..af62328edf5eca 100644
2713+
index 3ad0b0a3f2f465..2e4b1fd1b370cc 100644
27142714
--- a/src/go/build/deps_test.go
27152715
+++ b/src/go/build/deps_test.go
2716-
@@ -535,6 +535,11 @@ var depsRules = `
2716+
@@ -536,6 +536,11 @@ var depsRules = `
27172717
< github.com/microsoft/go-crypto-winnative/internal/bcrypt
27182718
< github.com/microsoft/go-crypto-winnative/cng;
27192719

@@ -2725,7 +2725,7 @@ index 0095243ce2b0b7..af62328edf5eca 100644
27252725
FIPS, internal/godebug < crypto/fips140;
27262726

27272727
crypto, hash !< FIPS;
2728-
@@ -545,16 +550,28 @@ var depsRules = `
2728+
@@ -546,16 +551,28 @@ var depsRules = `
27292729
NONE < crypto/internal/boring/sig, crypto/internal/boring/syso;
27302730
sync/atomic < crypto/internal/boring/bcache;
27312731

@@ -2756,7 +2756,7 @@ index 0095243ce2b0b7..af62328edf5eca 100644
27562756
< crypto/boring
27572757
< crypto/aes,
27582758
crypto/des,
2759-
@@ -578,8 +595,12 @@ var depsRules = `
2759+
@@ -579,8 +596,12 @@ var depsRules = `
27602760
math/big, github.com/microsoft/go-crypto-darwin/xcrypto < github.com/microsoft/go-crypto-darwin/bbig;
27612761
math/big, github.com/microsoft/go-crypto-winnative/cng < github.com/microsoft/go-crypto-winnative/cng/bbig;
27622762

@@ -2801,7 +2801,7 @@ index 00000000000000..8d0c3fde9ab5e8
28012801
+const AllowCryptoFallback = true
28022802
+const AllowCryptoFallbackInt = 1
28032803
diff --git a/src/internal/goexperiment/flags.go b/src/internal/goexperiment/flags.go
2804-
index c2a8b7f860d780..451a8924ae423d 100644
2804+
index 6b4289503d57ae..12fba96b868c9e 100644
28052805
--- a/src/internal/goexperiment/flags.go
28062806
+++ b/src/internal/goexperiment/flags.go
28072807
@@ -78,6 +78,14 @@ type Flags struct {

0 commit comments

Comments
 (0)