diff --git a/patches/0002-Add-crypto-backend-foundation.patch b/patches/0002-Add-crypto-backend-foundation.patch index 33b66759f1..607660e741 100644 --- a/patches/0002-Add-crypto-backend-foundation.patch +++ b/patches/0002-Add-crypto-backend-foundation.patch @@ -51,12 +51,11 @@ Subject: [PATCH] Add crypto backend foundation src/crypto/sha512/sha512_test.go | 20 +- src/crypto/tls/boring_test.go | 5 + src/crypto/tls/cipher_suites.go | 2 +- - src/crypto/tls/handshake_client.go | 25 ++- - src/crypto/tls/handshake_server.go | 25 ++- + src/crypto/tls/handshake_client.go | 10 +- + src/crypto/tls/handshake_server.go | 10 +- src/crypto/tls/handshake_server_tls13.go | 10 + - src/crypto/tls/key_schedule.go | 23 ++- - src/crypto/tls/prf.go | 77 ++++--- - src/crypto/tls/prf_test.go | 12 +- + src/crypto/tls/key_schedule.go | 23 +- + src/crypto/tls/prf.go | 36 ++++ src/crypto/x509/boring_test.go | 5 + src/go/build/deps_test.go | 4 + src/hash/boring_test.go | 9 + @@ -64,7 +63,7 @@ Subject: [PATCH] Add crypto backend foundation src/hash/notboring_test.go | 9 + src/net/smtp/smtp_test.go | 72 +++--- src/runtime/runtime_boring.go | 5 + - 60 files changed, 1148 insertions(+), 106 deletions(-) + 59 files changed, 1098 insertions(+), 73 deletions(-) create mode 100644 src/crypto/dsa/boring.go create mode 100644 src/crypto/dsa/notboring.go create mode 100644 src/crypto/ed25519/boring.go @@ -1846,129 +1845,47 @@ index 917a1eff42d34f..f6f57130b64f41 100644 "crypto/sha1" "crypto/sha256" diff --git a/src/crypto/tls/handshake_client.go b/src/crypto/tls/handshake_client.go -index 760e827f467f15..99b44d259e1e02 100644 +index 760e827f467f15..393c59ba8f1183 100644 --- a/src/crypto/tls/handshake_client.go +++ b/src/crypto/tls/handshake_client.go -@@ -770,12 +770,16 @@ func (hs *clientHandshakeState) doFullHandshake() error { - - if hs.serverHello.extendedMasterSecret { - c.extMasterSecret = true -- hs.masterSecret = extMasterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, -+ hs.masterSecret, err = extMasterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, - hs.finishedHash.Sum()) - } else { -- hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, -+ hs.masterSecret, err = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, - hs.hello.random, hs.serverHello.random) - } -+ if err != nil { -+ c.sendAlert(alertInternalError) -+ return err -+ } - if err := c.config.writeKeyLog(keyLogLabelTLS12, hs.hello.random, hs.masterSecret); err != nil { - c.sendAlert(alertInternalError) - return errors.New("tls: failed to write to key log: " + err.Error()) -@@ -836,8 +840,12 @@ func (hs *clientHandshakeState) doFullHandshake() error { - func (hs *clientHandshakeState) establishKeys() error { - c := hs.c +@@ -541,7 +541,15 @@ func (c *Conn) pickTLSVersion(serverHello *serverHelloMsg) error { -- clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV := -+ clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV, err := - keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen) -+ if err != nil { -+ c.sendAlert(alertInternalError) -+ return err -+ } - var clientCipher, serverCipher any - var clientHash, serverHash hash.Hash - if hs.suite.cipher != nil { -@@ -977,7 +985,11 @@ func (hs *clientHandshakeState) readFinished(out []byte) error { - return unexpectedMessageError(serverFinished, msg) - } - -- verify := hs.finishedHash.serverSum(hs.masterSecret) -+ verify, err := hs.finishedHash.serverSum(hs.masterSecret) -+ if err != nil { -+ c.sendAlert(alertHandshakeFailure) -+ return err -+ } - if len(verify) != len(serverFinished.verifyData) || - subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 { - c.sendAlert(alertHandshakeFailure) -@@ -1045,7 +1057,10 @@ func (hs *clientHandshakeState) sendFinished(out []byte) error { - } + // Does the handshake, either a full one or resumes old session. Requires hs.c, + // hs.hello, hs.serverHello, and, optionally, hs.session to be set. +-func (hs *clientHandshakeState) handshake() error { ++func (hs *clientHandshakeState) handshake() (err error) { ++ defer func() { ++ if err == nil { ++ err = recoverFromBoringPRFError() ++ if err != nil { ++ hs.c.sendAlert(alertInternalError) ++ } ++ } ++ }() + c := hs.c - finished := new(finishedMsg) -- finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret) -+ var err error -+ if finished.verifyData, err = hs.finishedHash.clientSum(hs.masterSecret); err != nil { -+ return err -+ } - if _, err := hs.c.writeHandshakeRecord(finished, &hs.finishedHash); err != nil { - return err - } + isResume, err := hs.processServerHello() diff --git a/src/crypto/tls/handshake_server.go b/src/crypto/tls/handshake_server.go -index bc4e51ba364cf1..8b4fc36e49fdf8 100644 +index bc4e51ba364cf1..0933837161573e 100644 --- a/src/crypto/tls/handshake_server.go +++ b/src/crypto/tls/handshake_server.go -@@ -686,12 +686,16 @@ func (hs *serverHandshakeState) doFullHandshake() error { - } - if hs.hello.extendedMasterSecret { - c.extMasterSecret = true -- hs.masterSecret = extMasterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, -+ hs.masterSecret, err = extMasterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, - hs.finishedHash.Sum()) - } else { -- hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, -+ hs.masterSecret, err = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, - hs.clientHello.random, hs.hello.random) - } -+ if err != nil { -+ c.sendAlert(alertInternalError) -+ return err -+ } - if err := c.config.writeKeyLog(keyLogLabelTLS12, hs.clientHello.random, hs.masterSecret); err != nil { - c.sendAlert(alertInternalError) - return err -@@ -755,8 +759,12 @@ func (hs *serverHandshakeState) doFullHandshake() error { - func (hs *serverHandshakeState) establishKeys() error { - c := hs.c - -- clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV := -+ clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV, err := - keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen) -+ if err != nil { -+ c.sendAlert(alertInternalError) -+ return err -+ } - - var clientCipher, serverCipher any - var clientHash, serverHash hash.Hash -@@ -797,7 +805,11 @@ func (hs *serverHandshakeState) readFinished(out []byte) error { - return unexpectedMessageError(clientFinished, msg) - } +@@ -62,7 +62,15 @@ func (c *Conn) serverHandshake(ctx context.Context) error { + return hs.handshake() + } -- verify := hs.finishedHash.clientSum(hs.masterSecret) -+ verify, err := hs.finishedHash.clientSum(hs.masterSecret) -+ if err != nil { -+ c.sendAlert(alertHandshakeFailure) -+ return err -+ } - if len(verify) != len(clientFinished.verifyData) || - subtle.ConstantTimeCompare(verify, clientFinished.verifyData) != 1 { - c.sendAlert(alertHandshakeFailure) -@@ -859,7 +871,10 @@ func (hs *serverHandshakeState) sendFinished(out []byte) error { - } +-func (hs *serverHandshakeState) handshake() error { ++func (hs *serverHandshakeState) handshake() (err error) { ++ defer func() { ++ if err == nil { ++ err = recoverFromBoringPRFError() ++ if err != nil { ++ hs.c.sendAlert(alertInternalError) ++ } ++ } ++ }() + c := hs.c - finished := new(finishedMsg) -- finished.verifyData = hs.finishedHash.serverSum(hs.masterSecret) -+ var err error -+ if finished.verifyData, err = hs.finishedHash.serverSum(hs.masterSecret); err != nil { -+ return err -+ } - if _, err := hs.c.writeHandshakeRecord(finished, &hs.finishedHash); err != nil { - return err - } + if err := hs.processClientHello(); err != nil { diff --git a/src/crypto/tls/handshake_server_tls13.go b/src/crypto/tls/handshake_server_tls13.go index b8cf4c3fa50b24..bc5d32a29c50c4 100644 --- a/src/crypto/tls/handshake_server_tls13.go @@ -2039,7 +1956,7 @@ index 1636baf79e7288..747c3c0883230c 100644 } diff --git a/src/crypto/tls/prf.go b/src/crypto/tls/prf.go -index a7fa3370e66c82..3470372b567eba 100644 +index a7fa3370e66c82..e63daa3ed9f894 100644 --- a/src/crypto/tls/prf.go +++ b/src/crypto/tls/prf.go @@ -7,6 +7,7 @@ package tls @@ -2050,204 +1967,57 @@ index a7fa3370e66c82..3470372b567eba 100644 "crypto/md5" "crypto/sha1" "crypto/sha256" -@@ -45,7 +46,13 @@ func pHash(result, secret, seed []byte, hash func() hash.Hash) { +@@ -44,8 +45,37 @@ func pHash(result, secret, seed []byte, hash func() hash.Hash) { + } } ++type boringPRFError struct { ++ err error ++} ++ ++func (e *boringPRFError) Error() string { ++ return e.err.Error() ++} ++ ++// recoverFromBoringPRFError recovers from a panic caused by the boring backend. ++// It returns the error if it was a boringPRFError, or panics if the panic was ++// caused by something else. ++func recoverFromBoringPRFError() error { ++ if p := recover(); p != nil { ++ if err, ok := p.(boringPRFError); ok { ++ // Could happen, for example, if the seed is too large. The Go implementation doesn't limit the seed size, ++ // as RFC 5705 doesn't specify a limit, but stock OpenSSL restrict it to 1024 and CNG to 256. ++ return err.err ++ } ++ panic(p) ++ } ++ return nil ++} ++ // prf10 implements the TLS 1.0 pseudo-random function, as defined in RFC 2246, Section 5. --func prf10(result, secret, label, seed []byte) { -+func prf10(result, secret, label, seed []byte) error { -+ if boring.Enabled && boring.SupportsTLS1PRF() && boring.SupportsHash(crypto.MD5SHA1) { + func prf10(result, secret, label, seed []byte) { ++ if boring.Enabled && boring.SupportsTLS1PRF() { + if err := boring.TLS1PRF(result, secret, label, seed, nil); err != nil { -+ return fmt.Errorf("crypto/tls: prf10: %v", err) ++ panic(boringPRFError{fmt.Errorf("crypto/tls: prf10: %v", err)}) + } -+ return nil ++ return + } hashSHA1 := sha1.New hashMD5 := md5.New -@@ -61,16 +68,24 @@ func prf10(result, secret, label, seed []byte) { - for i, b := range result2 { - result[i] ^= b - } -+ return nil - } - +@@ -66,6 +96,12 @@ func prf10(result, secret, label, seed []byte) { // prf12 implements the TLS 1.2 pseudo-random function, as defined in RFC 5246, Section 5. --func prf12(hashFunc func() hash.Hash) func(result, secret, label, seed []byte) { -- return func(result, secret, label, seed []byte) { -+func prf12(h crypto.Hash, hashFunc func() hash.Hash) func(result, secret, label, seed []byte) error { -+ return func(result, secret, label, seed []byte) error { -+ if boring.Enabled && boring.SupportsTLS1PRF() && boring.SupportsHash(h) { + func prf12(hashFunc func() hash.Hash) func(result, secret, label, seed []byte) { + return func(result, secret, label, seed []byte) { ++ if boring.Enabled && boring.SupportsTLS1PRF() { + if err := boring.TLS1PRF(result, secret, label, seed, hashFunc); err != nil { -+ return fmt.Errorf("crypto/tls: prf12: %v", err) ++ panic(boringPRFError{fmt.Errorf("crypto/tls: prf12: %v", err)}) + } -+ return nil ++ return + } labelAndSeed := make([]byte, len(label)+len(seed)) copy(labelAndSeed, label) copy(labelAndSeed[len(label):], seed) - - pHash(result, secret, labelAndSeed, hashFunc) -+ return nil - } - } - -@@ -85,56 +100,64 @@ var keyExpansionLabel = []byte("key expansion") - var clientFinishedLabel = []byte("client finished") - var serverFinishedLabel = []byte("server finished") - --func prfAndHashForVersion(version uint16, suite *cipherSuite) (func(result, secret, label, seed []byte), crypto.Hash) { -+func prfAndHashForVersion(version uint16, suite *cipherSuite) (func(result, secret, label, seed []byte) error, crypto.Hash) { - switch version { - case VersionTLS10, VersionTLS11: - return prf10, crypto.Hash(0) - case VersionTLS12: - if suite.flags&suiteSHA384 != 0 { -- return prf12(sha512.New384), crypto.SHA384 -+ h := crypto.SHA384 -+ return prf12(h, sha512.New384), h - } -- return prf12(sha256.New), crypto.SHA256 -+ h := crypto.SHA256 -+ return prf12(h, sha256.New), h - default: - panic("unknown version") - } - } - --func prfForVersion(version uint16, suite *cipherSuite) func(result, secret, label, seed []byte) { -+func prfForVersion(version uint16, suite *cipherSuite) func(result, secret, label, seed []byte) error { - prf, _ := prfAndHashForVersion(version, suite) - return prf - } - - // masterFromPreMasterSecret generates the master secret from the pre-master - // secret. See RFC 5246, Section 8.1. --func masterFromPreMasterSecret(version uint16, suite *cipherSuite, preMasterSecret, clientRandom, serverRandom []byte) []byte { -+func masterFromPreMasterSecret(version uint16, suite *cipherSuite, preMasterSecret, clientRandom, serverRandom []byte) ([]byte, error) { - seed := make([]byte, 0, len(clientRandom)+len(serverRandom)) - seed = append(seed, clientRandom...) - seed = append(seed, serverRandom...) - - masterSecret := make([]byte, masterSecretLength) -- prfForVersion(version, suite)(masterSecret, preMasterSecret, masterSecretLabel, seed) -- return masterSecret -+ if err := prfForVersion(version, suite)(masterSecret, preMasterSecret, masterSecretLabel, seed); err != nil { -+ return nil, err -+ } -+ return masterSecret, nil - } - - // extMasterFromPreMasterSecret generates the extended master secret from the - // pre-master secret. See RFC 7627. --func extMasterFromPreMasterSecret(version uint16, suite *cipherSuite, preMasterSecret, transcript []byte) []byte { -+func extMasterFromPreMasterSecret(version uint16, suite *cipherSuite, preMasterSecret, transcript []byte) ([]byte, error) { - masterSecret := make([]byte, masterSecretLength) -- prfForVersion(version, suite)(masterSecret, preMasterSecret, extendedMasterSecretLabel, transcript) -- return masterSecret -+ if err := prfForVersion(version, suite)(masterSecret, preMasterSecret, extendedMasterSecretLabel, transcript); err != nil { -+ return nil, err -+ } -+ return masterSecret, nil - } - - // keysFromMasterSecret generates the connection keys from the master - // secret, given the lengths of the MAC key, cipher key and IV, as defined in - // RFC 2246, Section 6.3. --func keysFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clientRandom, serverRandom []byte, macLen, keyLen, ivLen int) (clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV []byte) { -+func keysFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clientRandom, serverRandom []byte, macLen, keyLen, ivLen int) (clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV []byte, err error) { - seed := make([]byte, 0, len(serverRandom)+len(clientRandom)) - seed = append(seed, serverRandom...) - seed = append(seed, clientRandom...) - - n := 2*macLen + 2*keyLen + 2*ivLen - keyMaterial := make([]byte, n) -- prfForVersion(version, suite)(keyMaterial, masterSecret, keyExpansionLabel, seed) -+ if err = prfForVersion(version, suite)(keyMaterial, masterSecret, keyExpansionLabel, seed); err != nil { -+ return -+ } - clientMAC = keyMaterial[:macLen] - keyMaterial = keyMaterial[macLen:] - serverMAC = keyMaterial[:macLen] -@@ -177,7 +200,7 @@ type finishedHash struct { - buffer []byte - - version uint16 -- prf func(result, secret, label, seed []byte) -+ prf func(result, secret, label, seed []byte) error - } - - func (h *finishedHash) Write(msg []byte) (n int, err error) { -@@ -208,18 +231,22 @@ func (h finishedHash) Sum() []byte { - - // clientSum returns the contents of the verify_data member of a client's - // Finished message. --func (h finishedHash) clientSum(masterSecret []byte) []byte { -+func (h finishedHash) clientSum(masterSecret []byte) ([]byte, error) { - out := make([]byte, finishedVerifyLength) -- h.prf(out, masterSecret, clientFinishedLabel, h.Sum()) -- return out -+ if err := h.prf(out, masterSecret, clientFinishedLabel, h.Sum()); err != nil { -+ return nil, err -+ } -+ return out, nil - } - - // serverSum returns the contents of the verify_data member of a server's - // Finished message. --func (h finishedHash) serverSum(masterSecret []byte) []byte { -+func (h finishedHash) serverSum(masterSecret []byte) ([]byte, error) { - out := make([]byte, finishedVerifyLength) -- h.prf(out, masterSecret, serverFinishedLabel, h.Sum()) -- return out -+ if err := h.prf(out, masterSecret, serverFinishedLabel, h.Sum()); err != nil { -+ return nil, err -+ } -+ return out, nil - } - - // hashForClientCertificate returns the handshake messages so far, pre-hashed if -@@ -293,7 +320,11 @@ func ekmFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clien - } - - keyMaterial := make([]byte, length) -- prfForVersion(version, suite)(keyMaterial, masterSecret, []byte(label), seed) -+ if err := prfForVersion(version, suite)(keyMaterial, masterSecret, []byte(label), seed); err != nil { -+ // Could happen if the seed is too large. The Go implementation doesn't limit the seed size, -+ // as RFC 5705 doesn't specify a limit, but stock OpenSSL restrict it to 1024 and CNG to 256. -+ return nil, err -+ } - return keyMaterial, nil - } - } -diff --git a/src/crypto/tls/prf_test.go b/src/crypto/tls/prf_test.go -index 8233985a62bd22..f46d4636557714 100644 ---- a/src/crypto/tls/prf_test.go -+++ b/src/crypto/tls/prf_test.go -@@ -51,13 +51,21 @@ func TestKeysFromPreMasterSecret(t *testing.T) { - clientRandom, _ := hex.DecodeString(test.clientRandom) - serverRandom, _ := hex.DecodeString(test.serverRandom) - -- masterSecret := masterFromPreMasterSecret(test.version, test.suite, in, clientRandom, serverRandom) -+ masterSecret, err := masterFromPreMasterSecret(test.version, test.suite, in, clientRandom, serverRandom) -+ if err != nil { -+ t.Errorf("#%d: masterFromPreMasterSecret failed: %s", i, err) -+ continue -+ } - if s := hex.EncodeToString(masterSecret); s != test.masterSecret { - t.Errorf("#%d: bad master secret %s, want %s", i, s, test.masterSecret) - continue - } - -- clientMAC, serverMAC, clientKey, serverKey, _, _ := keysFromMasterSecret(test.version, test.suite, masterSecret, clientRandom, serverRandom, test.macLen, test.keyLen, 0) -+ clientMAC, serverMAC, clientKey, serverKey, _, _, err := keysFromMasterSecret(test.version, test.suite, masterSecret, clientRandom, serverRandom, test.macLen, test.keyLen, 0) -+ if err != nil { -+ t.Errorf("#%d: keysFromMasterSecret failed: %s", i, err) -+ continue -+ } - clientMACString := hex.EncodeToString(clientMAC) - serverMACString := hex.EncodeToString(serverMAC) - clientKeyString := hex.EncodeToString(clientKey) diff --git a/src/crypto/x509/boring_test.go b/src/crypto/x509/boring_test.go index 319ac61f49c994..1b2454dbaab264 100644 --- a/src/crypto/x509/boring_test.go