]> Cypherpunks.ru repositories - gostls13.git/blobdiff - src/crypto/tls/cipher_suites.go
crypto/tls: remove RSA KEX ciphers from the default list
[gostls13.git] / src / crypto / tls / cipher_suites.go
index 76312984ab56afbc9c0ef0daf971c6beaeebbe56..eaeb7e04e6ccfdd118823151c375c9a50d00dd44 100644 (file)
@@ -4,20 +4,20 @@
 
 package tls
 
-import "crypto/internal/boring"
-
 import (
        "crypto"
        "crypto/aes"
        "crypto/cipher"
        "crypto/des"
        "crypto/hmac"
+       "crypto/internal/boring"
        "crypto/rc4"
        "crypto/sha1"
        "crypto/sha256"
        "fmt"
        "hash"
        "internal/cpu"
+       "internal/godebug"
        "runtime"
 
        "golang.org/x/crypto/chacha20poly1305"
@@ -46,7 +46,7 @@ var (
 
 // CipherSuites returns a list of cipher suites currently implemented by this
 // package, excluding those with security issues, which are returned by
-// InsecureCipherSuites.
+// [InsecureCipherSuites].
 //
 // The list is sorted by ID. Note that the default cipher suites selected by
 // this package might depend on logic that can't be captured by a static list,
@@ -79,7 +79,7 @@ func CipherSuites() []*CipherSuite {
 // this package and which have security issues.
 //
 // Most applications should not use the cipher suites in this list, and should
-// only use those returned by CipherSuites.
+// only use those returned by [CipherSuites].
 func InsecureCipherSuites() []*CipherSuite {
        // This list includes RC4, CBC_SHA256, and 3DES cipher suites. See
        // cipherSuitesPreferenceOrder for details.
@@ -219,57 +219,56 @@ var cipherSuitesTLS13 = []*cipherSuiteTLS13{ // TODO: replace with a map.
 //
 //   - Anything else comes before RC4
 //
-//       RC4 has practically exploitable biases. See https://www.rc4nomore.com.
+//     RC4 has practically exploitable biases. See https://www.rc4nomore.com.
 //
 //   - Anything else comes before CBC_SHA256
 //
-//       SHA-256 variants of the CBC ciphersuites don't implement any Lucky13
-//       countermeasures. See http://www.isg.rhul.ac.uk/tls/Lucky13.html and
-//       https://www.imperialviolet.org/2013/02/04/luckythirteen.html.
+//     SHA-256 variants of the CBC ciphersuites don't implement any Lucky13
+//     countermeasures. See http://www.isg.rhul.ac.uk/tls/Lucky13.html and
+//     https://www.imperialviolet.org/2013/02/04/luckythirteen.html.
 //
 //   - Anything else comes before 3DES
 //
-//       3DES has 64-bit blocks, which makes it fundamentally susceptible to
-//       birthday attacks. See https://sweet32.info.
+//     3DES has 64-bit blocks, which makes it fundamentally susceptible to
+//     birthday attacks. See https://sweet32.info.
 //
 //   - ECDHE comes before anything else
 //
-//       Once we got the broken stuff out of the way, the most important
-//       property a cipher suite can have is forward secrecy. We don't
-//       implement FFDHE, so that means ECDHE.
+//     Once we got the broken stuff out of the way, the most important
+//     property a cipher suite can have is forward secrecy. We don't
+//     implement FFDHE, so that means ECDHE.
 //
 //   - AEADs come before CBC ciphers
 //
-//       Even with Lucky13 countermeasures, MAC-then-Encrypt CBC cipher suites
-//       are fundamentally fragile, and suffered from an endless sequence of
-//       padding oracle attacks. See https://eprint.iacr.org/2015/1129,
-//       https://www.imperialviolet.org/2014/12/08/poodleagain.html, and
-//       https://blog.cloudflare.com/yet-another-padding-oracle-in-openssl-cbc-ciphersuites/.
+//     Even with Lucky13 countermeasures, MAC-then-Encrypt CBC cipher suites
+//     are fundamentally fragile, and suffered from an endless sequence of
+//     padding oracle attacks. See https://eprint.iacr.org/2015/1129,
+//     https://www.imperialviolet.org/2014/12/08/poodleagain.html, and
+//     https://blog.cloudflare.com/yet-another-padding-oracle-in-openssl-cbc-ciphersuites/.
 //
 //   - AES comes before ChaCha20
 //
-//       When AES hardware is available, AES-128-GCM and AES-256-GCM are faster
-//       than ChaCha20Poly1305.
+//     When AES hardware is available, AES-128-GCM and AES-256-GCM are faster
+//     than ChaCha20Poly1305.
 //
-//       When AES hardware is not available, AES-128-GCM is one or more of: much
-//       slower, way more complex, and less safe (because not constant time)
-//       than ChaCha20Poly1305.
+//     When AES hardware is not available, AES-128-GCM is one or more of: much
+//     slower, way more complex, and less safe (because not constant time)
+//     than ChaCha20Poly1305.
 //
-//       We use this list if we think both peers have AES hardware, and
-//       cipherSuitesPreferenceOrderNoAES otherwise.
+//     We use this list if we think both peers have AES hardware, and
+//     cipherSuitesPreferenceOrderNoAES otherwise.
 //
 //   - AES-128 comes before AES-256
 //
-//       The only potential advantages of AES-256 are better multi-target
-//       margins, and hypothetical post-quantum properties. Neither apply to
-//       TLS, and AES-256 is slower due to its four extra rounds (which don't
-//       contribute to the advantages above).
+//     The only potential advantages of AES-256 are better multi-target
+//     margins, and hypothetical post-quantum properties. Neither apply to
+//     TLS, and AES-256 is slower due to its four extra rounds (which don't
+//     contribute to the advantages above).
 //
 //   - ECDSA comes before RSA
 //
-//       The relative order of ECDSA and RSA cipher suites doesn't matter,
-//       as they depend on the certificate. Pick one to get a stable order.
-//
+//     The relative order of ECDSA and RSA cipher suites doesn't matter,
+//     as they depend on the certificate. Pick one to get a stable order.
 var cipherSuitesPreferenceOrder = []uint16{
        // AEADs w/ ECDHE
        TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
@@ -337,10 +336,35 @@ var disabledCipherSuites = []uint16{
 }
 
 var (
-       defaultCipherSuitesLen = len(cipherSuitesPreferenceOrder) - len(disabledCipherSuites)
-       defaultCipherSuites    = cipherSuitesPreferenceOrder[:defaultCipherSuitesLen]
+       defaultCipherSuitesLen int
+       defaultCipherSuites    []uint16
 )
 
+// rsaKexCiphers contains the ciphers which use RSA based key exchange,
+// which we disable by default.
+var rsaKexCiphers = map[uint16]bool{
+       TLS_RSA_WITH_RC4_128_SHA:        true,
+       TLS_RSA_WITH_3DES_EDE_CBC_SHA:   true,
+       TLS_RSA_WITH_AES_128_CBC_SHA:    true,
+       TLS_RSA_WITH_AES_256_CBC_SHA:    true,
+       TLS_RSA_WITH_AES_128_CBC_SHA256: true,
+       TLS_RSA_WITH_AES_128_GCM_SHA256: true,
+       TLS_RSA_WITH_AES_256_GCM_SHA384: true,
+}
+
+var rsaKEXgodebug = godebug.New("tlsrsakex")
+
+func init() {
+       rsaKexEnabled := rsaKEXgodebug.Value() == "1"
+       for _, c := range cipherSuitesPreferenceOrder[:len(cipherSuitesPreferenceOrder)-len(disabledCipherSuites)] {
+               if !rsaKexEnabled && rsaKexCiphers[c] {
+                       continue
+               }
+               defaultCipherSuites = append(defaultCipherSuites, c)
+       }
+       defaultCipherSuitesLen = len(defaultCipherSuites)
+}
+
 // defaultCipherSuitesTLS13 is also the preference order, since there are no
 // disabled by default TLS 1.3 cipher suites. The same AES vs ChaCha20 logic as
 // cipherSuitesPreferenceOrder applies.
@@ -379,14 +403,6 @@ var aesgcmCiphers = map[uint16]bool{
        TLS_AES_256_GCM_SHA384: true,
 }
 
-var nonAESGCMAEADCiphers = map[uint16]bool{
-       // TLS 1.2
-       TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305:   true,
-       TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305: true,
-       // TLS 1.3
-       TLS_CHACHA20_POLY1305_SHA256: true,
-}
-
 // aesgcmPreferred returns whether the first known cipher in the preference list
 // is an AES-GCM cipher, implying the peer has hardware support for it.
 func aesgcmPreferred(ciphers []uint16) bool {
@@ -475,7 +491,7 @@ func (f *prefixNonceAEAD) Open(out, nonce, ciphertext, additionalData []byte) ([
        return f.aead.Open(out, f.nonce[:], ciphertext, additionalData)
 }
 
-// xoredNonceAEAD wraps an AEAD by XORing in a fixed pattern to the nonce
+// xorNonceAEAD wraps an AEAD by XORing in a fixed pattern to the nonce
 // before each call.
 type xorNonceAEAD struct {
        nonceMask [aeadNonceLength]byte
@@ -518,12 +534,9 @@ func aeadAESGCM(key, noncePrefix []byte) aead {
        if err != nil {
                panic(err)
        }
-       type gcmtls interface {
-               NewGCMTLS() (cipher.AEAD, error)
-       }
        var aead cipher.AEAD
-       if aesTLS, ok := aes.(gcmtls); ok {
-               aead, err = aesTLS.NewGCMTLS()
+       if boring.Enabled {
+               aead, err = boring.NewGCMTLS(aes)
        } else {
                boring.Unreachable()
                aead, err = cipher.NewGCM(aes)