Copyright 2010 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 tls

import (
	
	
	
	
	
	
	
	
	
	
	

	
)
CipherSuite is a TLS cipher suite. Note that most functions in this package accept and expose cipher suite IDs instead of this type.
Supported versions is the list of TLS protocol versions that can negotiate this cipher suite.
Insecure is true if the cipher suite has known security issues due to its primitives, design, or implementation.
CipherSuites returns a list of cipher suites currently implemented by this package, excluding those with security issues, which are returned by 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.
func () []*CipherSuite {
	return []*CipherSuite{
		{TLS_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA", supportedUpToTLS12, false},
		{TLS_RSA_WITH_AES_128_CBC_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA", supportedUpToTLS12, false},
		{TLS_RSA_WITH_AES_256_CBC_SHA, "TLS_RSA_WITH_AES_256_CBC_SHA", supportedUpToTLS12, false},
		{TLS_RSA_WITH_AES_128_GCM_SHA256, "TLS_RSA_WITH_AES_128_GCM_SHA256", supportedOnlyTLS12, false},
		{TLS_RSA_WITH_AES_256_GCM_SHA384, "TLS_RSA_WITH_AES_256_GCM_SHA384", supportedOnlyTLS12, false},

		{TLS_AES_128_GCM_SHA256, "TLS_AES_128_GCM_SHA256", supportedOnlyTLS13, false},
		{TLS_AES_256_GCM_SHA384, "TLS_AES_256_GCM_SHA384", supportedOnlyTLS13, false},
		{TLS_CHACHA20_POLY1305_SHA256, "TLS_CHACHA20_POLY1305_SHA256", supportedOnlyTLS13, false},

		{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", supportedUpToTLS12, false},
		{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", supportedUpToTLS12, false},
		{TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", supportedUpToTLS12, false},
		{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", supportedUpToTLS12, false},
		{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", supportedUpToTLS12, false},
		{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", supportedOnlyTLS12, false},
		{TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", supportedOnlyTLS12, false},
		{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", supportedOnlyTLS12, false},
		{TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", supportedOnlyTLS12, false},
		{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", supportedOnlyTLS12, false},
		{TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", supportedOnlyTLS12, false},
	}
}
InsecureCipherSuites returns a list of cipher suites currently implemented by 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.
RC4 suites are broken because RC4 is. CBC-SHA256 suites have no Lucky13 countermeasures.
	return []*CipherSuite{
		{TLS_RSA_WITH_RC4_128_SHA, "TLS_RSA_WITH_RC4_128_SHA", supportedUpToTLS12, true},
		{TLS_RSA_WITH_AES_128_CBC_SHA256, "TLS_RSA_WITH_AES_128_CBC_SHA256", supportedOnlyTLS12, true},
		{TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", supportedUpToTLS12, true},
		{TLS_ECDHE_RSA_WITH_RC4_128_SHA, "TLS_ECDHE_RSA_WITH_RC4_128_SHA", supportedUpToTLS12, true},
		{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", supportedOnlyTLS12, true},
		{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", supportedOnlyTLS12, true},
	}
}
CipherSuiteName returns the standard name for the passed cipher suite ID (e.g. "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"), or a fallback representation of the ID value if the cipher suite is not implemented by this package.
func ( uint16) string {
	for ,  := range CipherSuites() {
		if .ID ==  {
			return .Name
		}
	}
	for ,  := range InsecureCipherSuites() {
		if .ID ==  {
			return .Name
		}
	}
	return fmt.Sprintf("0x%04X", )
}
a keyAgreement implements the client and server side of a TLS key agreement protocol by generating and processing key exchange messages.
On the server side, the first two methods are called in order.
In the case that the key agreement protocol doesn't use a ServerKeyExchange message, generateServerKeyExchange can return nil, nil.
	generateServerKeyExchange(*Config, *Certificate, *clientHelloMsg, *serverHelloMsg) (*serverKeyExchangeMsg, error)
	processClientKeyExchange(*Config, *Certificate, *clientKeyExchangeMsg, uint16) ([]byte, error)
On the client side, the next two methods are called in order.
This method may not be called if the server doesn't send a ServerKeyExchange message.
suiteECDHE indicates that the cipher suite involves elliptic curve Diffie-Hellman. This means that it should only be selected when the client indicates that it supports ECC with a curve and point format that we're happy with.
suiteECSign indicates that the cipher suite involves an ECDSA or EdDSA signature and therefore may only be selected when the server's certificate is ECDSA or EdDSA. If this is not set then the cipher suite is RSA based.
suiteTLS12 indicates that the cipher suite should only be advertised and accepted when using TLS 1.2.
suiteSHA384 indicates that the cipher suite uses SHA384 as the handshake hash.
suiteDefaultOff indicates that this cipher suite is not included by default.
A cipherSuite is a specific combination of key agreement, cipher and MAC function.
type cipherSuite struct {
the lengths, in bytes, of the key material needed for each component.
flags is a bitmask of the suite* values, above.
	flags  int
	cipher func(key, iv []byte, isRead bool) interface{}
	mac    func(key []byte) hash.Hash
	aead   func(key, fixedNonce []byte) aead
}

Ciphersuite order is chosen so that ECDHE comes before plain RSA and AEADs are the top preference.
	{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 32, 0, 12, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadChaCha20Poly1305},
	{TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, 32, 0, 12, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12, nil, nil, aeadChaCha20Poly1305},
	{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadAESGCM},
	{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12, nil, nil, aeadAESGCM},
	{TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
	{TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
	{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteDefaultOff, cipherAES, macSHA256, nil},
	{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil},
	{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12 | suiteDefaultOff, cipherAES, macSHA256, nil},
	{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECSign, cipherAES, macSHA1, nil},
	{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil},
	{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECSign, cipherAES, macSHA1, nil},
	{TLS_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, rsaKA, suiteTLS12, nil, nil, aeadAESGCM},
	{TLS_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, rsaKA, suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
	{TLS_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, rsaKA, suiteTLS12 | suiteDefaultOff, cipherAES, macSHA256, nil},
	{TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil},
	{TLS_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil},
	{TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, suiteECDHE, cipher3DES, macSHA1, nil},
	{TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, 0, cipher3DES, macSHA1, nil},
selectCipherSuite returns the first cipher suite from ids which is also in supportedIDs and passes the ok filter.
func (,  []uint16,  func(*cipherSuite) bool) *cipherSuite {
	for ,  := range  {
		 := cipherSuiteByID()
		if  == nil || !() {
			continue
		}

		for ,  := range  {
			if  ==  {
				return 
			}
		}
	}
	return nil
}
A cipherSuiteTLS13 defines only the pair of the AEAD algorithm and hash algorithm to be used with HKDF. See RFC 8446, Appendix B.4.
type cipherSuiteTLS13 struct {
	id     uint16
	keyLen int
	aead   func(key, fixedNonce []byte) aead
	hash   crypto.Hash
}

var cipherSuitesTLS13 = []*cipherSuiteTLS13{
	{TLS_AES_128_GCM_SHA256, 16, aeadAESGCMTLS13, crypto.SHA256},
	{TLS_CHACHA20_POLY1305_SHA256, 32, aeadChaCha20Poly1305, crypto.SHA256},
	{TLS_AES_256_GCM_SHA384, 32, aeadAESGCMTLS13, crypto.SHA384},
}

func (,  []byte,  bool) interface{} {
	,  := rc4.NewCipher()
	return 
}

func (,  []byte,  bool) interface{} {
	,  := des.NewTripleDESCipher()
	if  {
		return cipher.NewCBCDecrypter(, )
	}
	return cipher.NewCBCEncrypter(, )
}

func (,  []byte,  bool) interface{} {
	,  := aes.NewCipher()
	if  {
		return cipher.NewCBCDecrypter(, )
	}
	return cipher.NewCBCEncrypter(, )
}
macSHA1 returns a SHA-1 based constant time MAC.
func ( []byte) hash.Hash {
	return hmac.New(newConstantTimeHash(sha1.New), )
}
macSHA256 returns a SHA-256 based MAC. This is only supported in TLS 1.2 and is currently only used in disabled-by-default cipher suites.
func ( []byte) hash.Hash {
	return hmac.New(sha256.New, )
}

type aead interface {
	cipher.AEAD
explicitNonceLen returns the number of bytes of explicit nonce included in each record. This is eight for older AEADs and zero for modern ones.
	explicitNonceLen() int
}

const (
	aeadNonceLength   = 12
	noncePrefixLength = 4
)
prefixNonceAEAD wraps an AEAD and prefixes a fixed portion of the nonce to each call.
nonce contains the fixed part of the nonce in the first four bytes.
	nonce [aeadNonceLength]byte
	aead  cipher.AEAD
}

func ( *prefixNonceAEAD) () int        { return aeadNonceLength - noncePrefixLength }
func ( *prefixNonceAEAD) () int         { return .aead.Overhead() }
func ( *prefixNonceAEAD) () int { return .NonceSize() }

func ( *prefixNonceAEAD) (, , ,  []byte) []byte {
	copy(.nonce[4:], )
	return .aead.Seal(, .nonce[:], , )
}

func ( *prefixNonceAEAD) (, , ,  []byte) ([]byte, error) {
	copy(.nonce[4:], )
	return .aead.Open(, .nonce[:], , )
}
xoredNonceAEAD wraps an AEAD by XORing in a fixed pattern to the nonce before each call.
type xorNonceAEAD struct {
	nonceMask [aeadNonceLength]byte
	aead      cipher.AEAD
}

func ( *xorNonceAEAD) () int        { return 8 } // 64-bit sequence number
func ( *xorNonceAEAD) () int         { return .aead.Overhead() }
func ( *xorNonceAEAD) () int { return 0 }

func ( *xorNonceAEAD) (, , ,  []byte) []byte {
	for ,  := range  {
		.nonceMask[4+] ^= 
	}
	 := .aead.Seal(, .nonceMask[:], , )
	for ,  := range  {
		.nonceMask[4+] ^= 
	}

	return 
}

func ( *xorNonceAEAD) (, , ,  []byte) ([]byte, error) {
	for ,  := range  {
		.nonceMask[4+] ^= 
	}
	,  := .aead.Open(, .nonceMask[:], , )
	for ,  := range  {
		.nonceMask[4+] ^= 
	}

	return , 
}

func (,  []byte) aead {
	if len() != noncePrefixLength {
		panic("tls: internal error: wrong nonce length")
	}
	,  := aes.NewCipher()
	if  != nil {
		panic()
	}
	,  := cipher.NewGCM()
	if  != nil {
		panic()
	}

	 := &prefixNonceAEAD{aead: }
	copy(.nonce[:], )
	return 
}

func (,  []byte) aead {
	if len() != aeadNonceLength {
		panic("tls: internal error: wrong nonce length")
	}
	,  := aes.NewCipher()
	if  != nil {
		panic()
	}
	,  := cipher.NewGCM()
	if  != nil {
		panic()
	}

	 := &xorNonceAEAD{aead: }
	copy(.nonceMask[:], )
	return 
}

func (,  []byte) aead {
	if len() != aeadNonceLength {
		panic("tls: internal error: wrong nonce length")
	}
	,  := chacha20poly1305.New()
	if  != nil {
		panic()
	}

	 := &xorNonceAEAD{aead: }
	copy(.nonceMask[:], )
	return 
}

type constantTimeHash interface {
	hash.Hash
	ConstantTimeSum(b []byte) []byte
}
cthWrapper wraps any hash.Hash that implements ConstantTimeSum, and replaces with that all calls to Sum. It's used to obtain a ConstantTimeSum-based HMAC.
type cthWrapper struct {
	h constantTimeHash
}

func ( *cthWrapper) () int                   { return .h.Size() }
func ( *cthWrapper) () int              { return .h.BlockSize() }
func ( *cthWrapper) ()                      { .h.Reset() }
func ( *cthWrapper) ( []byte) (int, error) { return .h.Write() }
func ( *cthWrapper) ( []byte) []byte         { return .h.ConstantTimeSum() }

func ( func() hash.Hash) func() hash.Hash {
	return func() hash.Hash {
		return &cthWrapper{().(constantTimeHash)}
	}
}
tls10MAC implements the TLS 1.0 MAC function. RFC 2246, Section 6.2.3.
func ( hash.Hash, , , , ,  []byte) []byte {
	.Reset()
	.Write()
	.Write()
	.Write()
	 := .Sum()
	if  != nil {
		.Write()
	}
	return 
}

func ( uint16) keyAgreement {
	return rsaKeyAgreement{}
}

func ( uint16) keyAgreement {
	return &ecdheKeyAgreement{
		isRSA:   false,
		version: ,
	}
}

func ( uint16) keyAgreement {
	return &ecdheKeyAgreement{
		isRSA:   true,
		version: ,
	}
}
mutualCipherSuite returns a cipherSuite given a list of supported ciphersuites and the id requested by the peer.
func ( []uint16,  uint16) *cipherSuite {
	for ,  := range  {
		if  ==  {
			return cipherSuiteByID()
		}
	}
	return nil
}

func ( uint16) *cipherSuite {
	for ,  := range cipherSuites {
		if .id ==  {
			return 
		}
	}
	return nil
}

func ( []uint16,  uint16) *cipherSuiteTLS13 {
	for ,  := range  {
		if  ==  {
			return cipherSuiteTLS13ByID()
		}
	}
	return nil
}

func ( uint16) *cipherSuiteTLS13 {
	for ,  := range cipherSuitesTLS13 {
		if .id ==  {
			return 
		}
	}
	return nil
}
A list of cipher suite IDs that are, or have been, implemented by this package. See https://www.iana.org/assignments/tls-parameters/tls-parameters.xml
TLS_FALLBACK_SCSV isn't a standard cipher suite but an indicator that the client is doing version fallback. See RFC 7507.
Legacy names for the corresponding cipher suites with the correct _SHA256 suffix, retained for backward compatibility.