github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/pkg/crypto/tls/cipher_suites.go (about) 1 // Copyright 2010 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package tls 6 7 import ( 8 "crypto/aes" 9 "crypto/cipher" 10 "crypto/des" 11 "crypto/hmac" 12 "crypto/rc4" 13 "crypto/sha1" 14 "crypto/x509" 15 "hash" 16 ) 17 18 // a keyAgreement implements the client and server side of a TLS key agreement 19 // protocol by generating and processing key exchange messages. 20 type keyAgreement interface { 21 // On the server side, the first two methods are called in order. 22 23 // In the case that the key agreement protocol doesn't use a 24 // ServerKeyExchange message, generateServerKeyExchange can return nil, 25 // nil. 26 generateServerKeyExchange(*Config, *Certificate, *clientHelloMsg, *serverHelloMsg) (*serverKeyExchangeMsg, error) 27 processClientKeyExchange(*Config, *Certificate, *clientKeyExchangeMsg, uint16) ([]byte, error) 28 29 // On the client side, the next two methods are called in order. 30 31 // This method may not be called if the server doesn't send a 32 // ServerKeyExchange message. 33 processServerKeyExchange(*Config, *clientHelloMsg, *serverHelloMsg, *x509.Certificate, *serverKeyExchangeMsg) error 34 generateClientKeyExchange(*Config, *clientHelloMsg, *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) 35 } 36 37 // A cipherSuite is a specific combination of key agreement, cipher and MAC 38 // function. All cipher suites currently assume RSA key agreement. 39 type cipherSuite struct { 40 id uint16 41 // the lengths, in bytes, of the key material needed for each component. 42 keyLen int 43 macLen int 44 ivLen int 45 ka func() keyAgreement 46 // If elliptic is set, a server will only consider this ciphersuite if 47 // the ClientHello indicated that the client supports an elliptic curve 48 // and point format that we can handle. 49 elliptic bool 50 cipher func(key, iv []byte, isRead bool) interface{} 51 mac func(version uint16, macKey []byte) macFunction 52 } 53 54 var cipherSuites = []*cipherSuite{ 55 {TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, false, cipherRC4, macSHA1}, 56 {TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, false, cipher3DES, macSHA1}, 57 {TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, false, cipherAES, macSHA1}, 58 {TLS_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, rsaKA, false, cipherAES, macSHA1}, 59 {TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, true, cipherRC4, macSHA1}, 60 {TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, true, cipher3DES, macSHA1}, 61 {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, true, cipherAES, macSHA1}, 62 {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheRSAKA, true, cipherAES, macSHA1}, 63 } 64 65 func cipherRC4(key, iv []byte, isRead bool) interface{} { 66 cipher, _ := rc4.NewCipher(key) 67 return cipher 68 } 69 70 func cipher3DES(key, iv []byte, isRead bool) interface{} { 71 block, _ := des.NewTripleDESCipher(key) 72 if isRead { 73 return cipher.NewCBCDecrypter(block, iv) 74 } 75 return cipher.NewCBCEncrypter(block, iv) 76 } 77 78 func cipherAES(key, iv []byte, isRead bool) interface{} { 79 block, _ := aes.NewCipher(key) 80 if isRead { 81 return cipher.NewCBCDecrypter(block, iv) 82 } 83 return cipher.NewCBCEncrypter(block, iv) 84 } 85 86 // macSHA1 returns a macFunction for the given protocol version. 87 func macSHA1(version uint16, key []byte) macFunction { 88 if version == versionSSL30 { 89 mac := ssl30MAC{ 90 h: sha1.New(), 91 key: make([]byte, len(key)), 92 } 93 copy(mac.key, key) 94 return mac 95 } 96 return tls10MAC{hmac.New(sha1.New, key)} 97 } 98 99 type macFunction interface { 100 Size() int 101 MAC(digestBuf, seq, data []byte) []byte 102 } 103 104 // ssl30MAC implements the SSLv3 MAC function, as defined in 105 // www.mozilla.org/projects/security/pki/nss/ssl/draft302.txt section 5.2.3.1 106 type ssl30MAC struct { 107 h hash.Hash 108 key []byte 109 } 110 111 func (s ssl30MAC) Size() int { 112 return s.h.Size() 113 } 114 115 var ssl30Pad1 = [48]byte{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36} 116 117 var ssl30Pad2 = [48]byte{0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c} 118 119 func (s ssl30MAC) MAC(digestBuf, seq, record []byte) []byte { 120 padLength := 48 121 if s.h.Size() == 20 { 122 padLength = 40 123 } 124 125 s.h.Reset() 126 s.h.Write(s.key) 127 s.h.Write(ssl30Pad1[:padLength]) 128 s.h.Write(seq) 129 s.h.Write(record[:1]) 130 s.h.Write(record[3:5]) 131 s.h.Write(record[recordHeaderLen:]) 132 digestBuf = s.h.Sum(digestBuf[:0]) 133 134 s.h.Reset() 135 s.h.Write(s.key) 136 s.h.Write(ssl30Pad2[:padLength]) 137 s.h.Write(digestBuf) 138 return s.h.Sum(digestBuf[:0]) 139 } 140 141 // tls10MAC implements the TLS 1.0 MAC function. RFC 2246, section 6.2.3. 142 type tls10MAC struct { 143 h hash.Hash 144 } 145 146 func (s tls10MAC) Size() int { 147 return s.h.Size() 148 } 149 150 func (s tls10MAC) MAC(digestBuf, seq, record []byte) []byte { 151 s.h.Reset() 152 s.h.Write(seq) 153 s.h.Write(record) 154 return s.h.Sum(digestBuf[:0]) 155 } 156 157 func rsaKA() keyAgreement { 158 return rsaKeyAgreement{} 159 } 160 161 func ecdheRSAKA() keyAgreement { 162 return new(ecdheRSAKeyAgreement) 163 } 164 165 // mutualCipherSuite returns a cipherSuite given a list of supported 166 // ciphersuites and the id requested by the peer. 167 func mutualCipherSuite(have []uint16, want uint16) *cipherSuite { 168 for _, id := range have { 169 if id == want { 170 for _, suite := range cipherSuites { 171 if suite.id == want { 172 return suite 173 } 174 } 175 return nil 176 } 177 } 178 return nil 179 } 180 181 // A list of the possible cipher suite ids. Taken from 182 // http://www.iana.org/assignments/tls-parameters/tls-parameters.xml 183 const ( 184 TLS_RSA_WITH_RC4_128_SHA uint16 = 0x0005 185 TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000a 186 TLS_RSA_WITH_AES_128_CBC_SHA uint16 = 0x002f 187 TLS_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0035 188 TLS_ECDHE_RSA_WITH_RC4_128_SHA uint16 = 0xc011 189 TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xc012 190 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0xc013 191 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0xc014 192 )