package tls
import (
"crypto"
"crypto/aes"
"crypto/cipher"
"crypto/des"
"crypto/hmac"
"crypto/internal/boring"
"crypto/rc4"
"crypto/sha1"
"crypto/sha256"
"fmt"
"hash"
"internal/cpu"
"runtime"
"golang.org/x/crypto/chacha20poly1305"
)
type CipherSuite struct {
ID uint16
Name string
SupportedVersions []uint16
Insecure bool
}
var (
supportedUpToTLS12 = []uint16 {VersionTLS10 , VersionTLS11 , VersionTLS12 }
supportedOnlyTLS12 = []uint16 {VersionTLS12 }
supportedOnlyTLS13 = []uint16 {VersionTLS13 }
)
func CipherSuites () []*CipherSuite {
return []*CipherSuite {
{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_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 },
}
}
func InsecureCipherSuites () []*CipherSuite {
return []*CipherSuite {
{TLS_RSA_WITH_RC4_128_SHA , "TLS_RSA_WITH_RC4_128_SHA" , supportedUpToTLS12 , true },
{TLS_RSA_WITH_3DES_EDE_CBC_SHA , "TLS_RSA_WITH_3DES_EDE_CBC_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_RSA_WITH_3DES_EDE_CBC_SHA , "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_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 },
}
}
func CipherSuiteName (id uint16 ) string {
for _ , c := range CipherSuites () {
if c .ID == id {
return c .Name
}
}
for _ , c := range InsecureCipherSuites () {
if c .ID == id {
return c .Name
}
}
return fmt .Sprintf ("0x%04X" , id )
}
const (
suiteECDHE = 1 << iota
suiteECSign
suiteTLS12
suiteSHA384
)
type cipherSuite struct {
id uint16
keyLen int
macLen int
ivLen int
ka func (version uint16 ) keyAgreement
flags int
cipher func (key, iv []byte , isRead bool ) any
mac func (key []byte ) hash .Hash
aead func (key, fixedNonce []byte ) aead
}
var cipherSuites = []*cipherSuite {
{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 , 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 , 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 , 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 },
{TLS_RSA_WITH_RC4_128_SHA , 16 , 20 , 0 , rsaKA , 0 , cipherRC4 , macSHA1 , nil },
{TLS_ECDHE_RSA_WITH_RC4_128_SHA , 16 , 20 , 0 , ecdheRSAKA , suiteECDHE , cipherRC4 , macSHA1 , nil },
{TLS_ECDHE_ECDSA_WITH_RC4_128_SHA , 16 , 20 , 0 , ecdheECDSAKA , suiteECDHE | suiteECSign , cipherRC4 , macSHA1 , nil },
}
func selectCipherSuite (ids , supportedIDs []uint16 , ok func (*cipherSuite ) bool ) *cipherSuite {
for _ , id := range ids {
candidate := cipherSuiteByID (id )
if candidate == nil || !ok (candidate ) {
continue
}
for _ , suppID := range supportedIDs {
if id == suppID {
return candidate
}
}
}
return nil
}
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 },
}
var cipherSuitesPreferenceOrder = []uint16 {
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 , TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 ,
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 , TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 ,
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 , TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 ,
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA , TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA ,
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA , TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA ,
TLS_RSA_WITH_AES_128_GCM_SHA256 ,
TLS_RSA_WITH_AES_256_GCM_SHA384 ,
TLS_RSA_WITH_AES_128_CBC_SHA ,
TLS_RSA_WITH_AES_256_CBC_SHA ,
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA ,
TLS_RSA_WITH_3DES_EDE_CBC_SHA ,
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 , TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 ,
TLS_RSA_WITH_AES_128_CBC_SHA256 ,
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA , TLS_ECDHE_RSA_WITH_RC4_128_SHA ,
TLS_RSA_WITH_RC4_128_SHA ,
}
var cipherSuitesPreferenceOrderNoAES = []uint16 {
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 , TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 ,
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 , TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 ,
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 , TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 ,
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA , TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA ,
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA , TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA ,
TLS_RSA_WITH_AES_128_GCM_SHA256 ,
TLS_RSA_WITH_AES_256_GCM_SHA384 ,
TLS_RSA_WITH_AES_128_CBC_SHA ,
TLS_RSA_WITH_AES_256_CBC_SHA ,
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA ,
TLS_RSA_WITH_3DES_EDE_CBC_SHA ,
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 , TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 ,
TLS_RSA_WITH_AES_128_CBC_SHA256 ,
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA , TLS_ECDHE_RSA_WITH_RC4_128_SHA ,
TLS_RSA_WITH_RC4_128_SHA ,
}
var disabledCipherSuites = []uint16 {
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 , TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 ,
TLS_RSA_WITH_AES_128_CBC_SHA256 ,
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA , TLS_ECDHE_RSA_WITH_RC4_128_SHA ,
TLS_RSA_WITH_RC4_128_SHA ,
}
var (
defaultCipherSuitesLen = len (cipherSuitesPreferenceOrder ) - len (disabledCipherSuites )
defaultCipherSuites = cipherSuitesPreferenceOrder [:defaultCipherSuitesLen ]
)
var defaultCipherSuitesTLS13 = []uint16 {
TLS_AES_128_GCM_SHA256 ,
TLS_AES_256_GCM_SHA384 ,
TLS_CHACHA20_POLY1305_SHA256 ,
}
var defaultCipherSuitesTLS13NoAES = []uint16 {
TLS_CHACHA20_POLY1305_SHA256 ,
TLS_AES_128_GCM_SHA256 ,
TLS_AES_256_GCM_SHA384 ,
}
var (
hasGCMAsmAMD64 = cpu .X86 .HasAES && cpu .X86 .HasPCLMULQDQ
hasGCMAsmARM64 = cpu .ARM64 .HasAES && cpu .ARM64 .HasPMULL
hasGCMAsmS390X = cpu .S390X .HasAES && cpu .S390X .HasAESCBC && cpu .S390X .HasAESCTR &&
(cpu .S390X .HasGHASH || cpu .S390X .HasAESGCM )
hasAESGCMHardwareSupport = runtime .GOARCH == "amd64" && hasGCMAsmAMD64 ||
runtime .GOARCH == "arm64" && hasGCMAsmARM64 ||
runtime .GOARCH == "s390x" && hasGCMAsmS390X
)
var aesgcmCiphers = map [uint16 ]bool {
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 : true ,
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 : true ,
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 : true ,
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 : true ,
TLS_AES_128_GCM_SHA256 : true ,
TLS_AES_256_GCM_SHA384 : true ,
}
func aesgcmPreferred (ciphers []uint16 ) bool {
for _ , cID := range ciphers {
if c := cipherSuiteByID (cID ); c != nil {
return aesgcmCiphers [cID ]
}
if c := cipherSuiteTLS13ByID (cID ); c != nil {
return aesgcmCiphers [cID ]
}
}
return false
}
func cipherRC4 (key , iv []byte , isRead bool ) any {
cipher , _ := rc4 .NewCipher (key )
return cipher
}
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 ) any {
block , _ := aes .NewCipher (key )
if isRead {
return cipher .NewCBCDecrypter (block , iv )
}
return cipher .NewCBCEncrypter (block , iv )
}
func macSHA1 (key []byte ) hash .Hash {
h := sha1 .New
if !boring .Enabled {
h = newConstantTimeHash (h )
}
return hmac .New (h , key )
}
func macSHA256 (key []byte ) hash .Hash {
return hmac .New (sha256 .New , key )
}
type aead interface {
cipher .AEAD
explicitNonceLen () int
}
const (
aeadNonceLength = 12
noncePrefixLength = 4
)
type prefixNonceAEAD struct {
nonce [aeadNonceLength ]byte
aead cipher .AEAD
}
func (f *prefixNonceAEAD ) NonceSize () int { return aeadNonceLength - noncePrefixLength }
func (f *prefixNonceAEAD ) Overhead () int { return f .aead .Overhead () }
func (f *prefixNonceAEAD ) explicitNonceLen () int { return f .NonceSize () }
func (f *prefixNonceAEAD ) Seal (out , nonce , plaintext , additionalData []byte ) []byte {
copy (f .nonce [4 :], nonce )
return f .aead .Seal (out , f .nonce [:], plaintext , additionalData )
}
func (f *prefixNonceAEAD ) Open (out , nonce , ciphertext , additionalData []byte ) ([]byte , error ) {
copy (f .nonce [4 :], nonce )
return f .aead .Open (out , f .nonce [:], ciphertext , additionalData )
}
type xorNonceAEAD struct {
nonceMask [aeadNonceLength ]byte
aead cipher .AEAD
}
func (f *xorNonceAEAD ) NonceSize () int { return 8 }
func (f *xorNonceAEAD ) Overhead () int { return f .aead .Overhead () }
func (f *xorNonceAEAD ) explicitNonceLen () int { return 0 }
func (f *xorNonceAEAD ) Seal (out , nonce , plaintext , additionalData []byte ) []byte {
for i , b := range nonce {
f .nonceMask [4 +i ] ^= b
}
result := f .aead .Seal (out , f .nonceMask [:], plaintext , additionalData )
for i , b := range nonce {
f .nonceMask [4 +i ] ^= b
}
return result
}
func (f *xorNonceAEAD ) Open (out , nonce , ciphertext , additionalData []byte ) ([]byte , error ) {
for i , b := range nonce {
f .nonceMask [4 +i ] ^= b
}
result , err := f .aead .Open (out , f .nonceMask [:], ciphertext , additionalData )
for i , b := range nonce {
f .nonceMask [4 +i ] ^= b
}
return result , err
}
func aeadAESGCM (key , noncePrefix []byte ) aead {
if len (noncePrefix ) != noncePrefixLength {
panic ("tls: internal error: wrong nonce length" )
}
aes , err := aes .NewCipher (key )
if err != nil {
panic (err )
}
var aead cipher .AEAD
if boring .Enabled {
aead , err = boring .NewGCMTLS (aes )
} else {
boring .Unreachable ()
aead , err = cipher .NewGCM (aes )
}
if err != nil {
panic (err )
}
ret := &prefixNonceAEAD {aead : aead }
copy (ret .nonce [:], noncePrefix )
return ret
}
func aeadAESGCMTLS13 (key , nonceMask []byte ) aead {
if len (nonceMask ) != aeadNonceLength {
panic ("tls: internal error: wrong nonce length" )
}
aes , err := aes .NewCipher (key )
if err != nil {
panic (err )
}
aead , err := cipher .NewGCM (aes )
if err != nil {
panic (err )
}
ret := &xorNonceAEAD {aead : aead }
copy (ret .nonceMask [:], nonceMask )
return ret
}
func aeadChaCha20Poly1305 (key , nonceMask []byte ) aead {
if len (nonceMask ) != aeadNonceLength {
panic ("tls: internal error: wrong nonce length" )
}
aead , err := chacha20poly1305 .New (key )
if err != nil {
panic (err )
}
ret := &xorNonceAEAD {aead : aead }
copy (ret .nonceMask [:], nonceMask )
return ret
}
type constantTimeHash interface {
hash .Hash
ConstantTimeSum (b []byte ) []byte
}
type cthWrapper struct {
h constantTimeHash
}
func (c *cthWrapper ) Size () int { return c .h .Size () }
func (c *cthWrapper ) BlockSize () int { return c .h .BlockSize () }
func (c *cthWrapper ) Reset () { c .h .Reset () }
func (c *cthWrapper ) Write (p []byte ) (int , error ) { return c .h .Write (p ) }
func (c *cthWrapper ) Sum (b []byte ) []byte { return c .h .ConstantTimeSum (b ) }
func newConstantTimeHash (h func () hash .Hash ) func () hash .Hash {
boring .Unreachable ()
return func () hash .Hash {
return &cthWrapper {h ().(constantTimeHash )}
}
}
func tls10MAC (h hash .Hash , out , seq , header , data , extra []byte ) []byte {
h .Reset ()
h .Write (seq )
h .Write (header )
h .Write (data )
res := h .Sum (out )
if extra != nil {
h .Write (extra )
}
return res
}
func rsaKA (version uint16 ) keyAgreement {
return rsaKeyAgreement {}
}
func ecdheECDSAKA (version uint16 ) keyAgreement {
return &ecdheKeyAgreement {
isRSA : false ,
version : version ,
}
}
func ecdheRSAKA (version uint16 ) keyAgreement {
return &ecdheKeyAgreement {
isRSA : true ,
version : version ,
}
}
func mutualCipherSuite (have []uint16 , want uint16 ) *cipherSuite {
for _ , id := range have {
if id == want {
return cipherSuiteByID (id )
}
}
return nil
}
func cipherSuiteByID (id uint16 ) *cipherSuite {
for _ , cipherSuite := range cipherSuites {
if cipherSuite .id == id {
return cipherSuite
}
}
return nil
}
func mutualCipherSuiteTLS13 (have []uint16 , want uint16 ) *cipherSuiteTLS13 {
for _ , id := range have {
if id == want {
return cipherSuiteTLS13ByID (id )
}
}
return nil
}
func cipherSuiteTLS13ByID (id uint16 ) *cipherSuiteTLS13 {
for _ , cipherSuite := range cipherSuitesTLS13 {
if cipherSuite .id == id {
return cipherSuite
}
}
return nil
}
const (
TLS_RSA_WITH_RC4_128_SHA uint16 = 0x0005
TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000a
TLS_RSA_WITH_AES_128_CBC_SHA uint16 = 0x002f
TLS_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0035
TLS_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x003c
TLS_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009c
TLS_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009d
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA uint16 = 0xc007
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xc009
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xc00a
TLS_ECDHE_RSA_WITH_RC4_128_SHA uint16 = 0xc011
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xc012
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0xc013
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0xc014
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 uint16 = 0xc023
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0xc027
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02f
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02b
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc030
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc02c
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xcca8
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xcca9
TLS_AES_128_GCM_SHA256 uint16 = 0x1301
TLS_AES_256_GCM_SHA384 uint16 = 0x1302
TLS_CHACHA20_POLY1305_SHA256 uint16 = 0x1303
TLS_FALLBACK_SCSV uint16 = 0x5600
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 = TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 = TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
)
The pages are generated with Golds v0.6.7 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds .