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"
// 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,
// 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.
ka func(version uint16) keyAgreement
// flags is a bitmask of the suite* values, above.
flags int
- cipher func(key, iv []byte, isRead bool) interface{}
+ cipher func(key, iv []byte, isRead bool) any
mac func(key []byte) hash.Hash
aead func(key, fixedNonce []byte) aead
}
//
// - 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,
}
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.
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 {
return false
}
-func cipherRC4(key, iv []byte, isRead bool) interface{} {
+func cipherRC4(key, iv []byte, isRead bool) any {
cipher, _ := rc4.NewCipher(key)
return cipher
}
-func cipher3DES(key, iv []byte, isRead bool) interface{} {
+func cipher3DES(key, iv []byte, isRead bool) any {
block, _ := des.NewTripleDESCipher(key)
if isRead {
return cipher.NewCBCDecrypter(block, iv)
return cipher.NewCBCEncrypter(block, iv)
}
-func cipherAES(key, iv []byte, isRead bool) interface{} {
+func cipherAES(key, iv []byte, isRead bool) any {
block, _ := aes.NewCipher(key)
if isRead {
return cipher.NewCBCDecrypter(block, iv)
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
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)