github.com/varialus/godfly@v0.0.0-20130904042352-1934f9f095ab/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(version uint16) 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 aead func(key, fixedNonce []byte) cipher.AEAD 53 } 54 55 var cipherSuites = []*cipherSuite{ 56 // Ciphersuite order is chosen so that ECDHE comes before plain RSA 57 // and RC4 comes before AES (because of the Lucky13 attack). 58 {TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheRSAKA, true, nil, nil, aeadAESGCM}, 59 {TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheECDSAKA, true, nil, nil, aeadAESGCM}, 60 {TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, true, cipherRC4, macSHA1, nil}, 61 {TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheECDSAKA, true, cipherRC4, macSHA1, nil}, 62 {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, true, cipherAES, macSHA1, nil}, 63 {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheECDSAKA, true, cipherAES, macSHA1, nil}, 64 {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheRSAKA, true, cipherAES, macSHA1, nil}, 65 {TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheECDSAKA, true, cipherAES, macSHA1, nil}, 66 {TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, false, cipherRC4, macSHA1, nil}, 67 {TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, false, cipherAES, macSHA1, nil}, 68 {TLS_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, rsaKA, false, cipherAES, macSHA1, nil}, 69 {TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, true, cipher3DES, macSHA1, nil}, 70 {TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, false, cipher3DES, macSHA1, nil}, 71 } 72 73 func cipherRC4(key, iv []byte, isRead bool) interface{} { 74 cipher, _ := rc4.NewCipher(key) 75 return cipher 76 } 77 78 func cipher3DES(key, iv []byte, isRead bool) interface{} { 79 block, _ := des.NewTripleDESCipher(key) 80 if isRead { 81 return cipher.NewCBCDecrypter(block, iv) 82 } 83 return cipher.NewCBCEncrypter(block, iv) 84 } 85 86 func cipherAES(key, iv []byte, isRead bool) interface{} { 87 block, _ := aes.NewCipher(key) 88 if isRead { 89 return cipher.NewCBCDecrypter(block, iv) 90 } 91 return cipher.NewCBCEncrypter(block, iv) 92 } 93 94 // macSHA1 returns a macFunction for the given protocol version. 95 func macSHA1(version uint16, key []byte) macFunction { 96 if version == VersionSSL30 { 97 mac := ssl30MAC{ 98 h: sha1.New(), 99 key: make([]byte, len(key)), 100 } 101 copy(mac.key, key) 102 return mac 103 } 104 return tls10MAC{hmac.New(sha1.New, key)} 105 } 106 107 type macFunction interface { 108 Size() int 109 MAC(digestBuf, seq, header, data []byte) []byte 110 } 111 112 // fixedNonceAEAD wraps an AEAD and prefixes a fixed portion of the nonce to 113 // each call. 114 type fixedNonceAEAD struct { 115 // sealNonce and openNonce are buffers where the larger nonce will be 116 // constructed. Since a seal and open operation may be running 117 // concurrently, there is a separate buffer for each. 118 sealNonce, openNonce []byte 119 aead cipher.AEAD 120 } 121 122 func (f *fixedNonceAEAD) NonceSize() int { return 8 } 123 func (f *fixedNonceAEAD) Overhead() int { return f.aead.Overhead() } 124 125 func (f *fixedNonceAEAD) Seal(out, nonce, plaintext, additionalData []byte) []byte { 126 copy(f.sealNonce[len(f.sealNonce)-8:], nonce) 127 return f.aead.Seal(out, f.sealNonce, plaintext, additionalData) 128 } 129 130 func (f *fixedNonceAEAD) Open(out, nonce, plaintext, additionalData []byte) ([]byte, error) { 131 copy(f.openNonce[len(f.openNonce)-8:], nonce) 132 return f.aead.Open(out, f.openNonce, plaintext, additionalData) 133 } 134 135 func aeadAESGCM(key, fixedNonce []byte) cipher.AEAD { 136 aes, err := aes.NewCipher(key) 137 if err != nil { 138 panic(err) 139 } 140 aead, err := cipher.NewGCM(aes) 141 if err != nil { 142 panic(err) 143 } 144 145 nonce1, nonce2 := make([]byte, 12), make([]byte, 12) 146 copy(nonce1, fixedNonce) 147 copy(nonce2, fixedNonce) 148 149 return &fixedNonceAEAD{nonce1, nonce2, aead} 150 } 151 152 // ssl30MAC implements the SSLv3 MAC function, as defined in 153 // www.mozilla.org/projects/security/pki/nss/ssl/draft302.txt section 5.2.3.1 154 type ssl30MAC struct { 155 h hash.Hash 156 key []byte 157 } 158 159 func (s ssl30MAC) Size() int { 160 return s.h.Size() 161 } 162 163 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} 164 165 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} 166 167 func (s ssl30MAC) MAC(digestBuf, seq, header, data []byte) []byte { 168 padLength := 48 169 if s.h.Size() == 20 { 170 padLength = 40 171 } 172 173 s.h.Reset() 174 s.h.Write(s.key) 175 s.h.Write(ssl30Pad1[:padLength]) 176 s.h.Write(seq) 177 s.h.Write(header[:1]) 178 s.h.Write(header[3:5]) 179 s.h.Write(data) 180 digestBuf = s.h.Sum(digestBuf[:0]) 181 182 s.h.Reset() 183 s.h.Write(s.key) 184 s.h.Write(ssl30Pad2[:padLength]) 185 s.h.Write(digestBuf) 186 return s.h.Sum(digestBuf[:0]) 187 } 188 189 // tls10MAC implements the TLS 1.0 MAC function. RFC 2246, section 6.2.3. 190 type tls10MAC struct { 191 h hash.Hash 192 } 193 194 func (s tls10MAC) Size() int { 195 return s.h.Size() 196 } 197 198 func (s tls10MAC) MAC(digestBuf, seq, header, data []byte) []byte { 199 s.h.Reset() 200 s.h.Write(seq) 201 s.h.Write(header) 202 s.h.Write(data) 203 return s.h.Sum(digestBuf[:0]) 204 } 205 206 func rsaKA(version uint16) keyAgreement { 207 return rsaKeyAgreement{} 208 } 209 210 func ecdheECDSAKA(version uint16) keyAgreement { 211 return &ecdheKeyAgreement{ 212 sigType: signatureECDSA, 213 version: version, 214 } 215 } 216 217 func ecdheRSAKA(version uint16) keyAgreement { 218 return &ecdheKeyAgreement{ 219 sigType: signatureRSA, 220 version: version, 221 } 222 } 223 224 // mutualCipherSuite returns a cipherSuite given a list of supported 225 // ciphersuites and the id requested by the peer. 226 func mutualCipherSuite(have []uint16, want uint16) *cipherSuite { 227 for _, id := range have { 228 if id == want { 229 for _, suite := range cipherSuites { 230 if suite.id == want { 231 return suite 232 } 233 } 234 return nil 235 } 236 } 237 return nil 238 } 239 240 // A list of the possible cipher suite ids. Taken from 241 // http://www.iana.org/assignments/tls-parameters/tls-parameters.xml 242 const ( 243 TLS_RSA_WITH_RC4_128_SHA uint16 = 0x0005 244 TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000a 245 TLS_RSA_WITH_AES_128_CBC_SHA uint16 = 0x002f 246 TLS_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0035 247 TLS_ECDHE_ECDSA_WITH_RC4_128_SHA uint16 = 0xc007 248 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xc009 249 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xc00a 250 TLS_ECDHE_RSA_WITH_RC4_128_SHA uint16 = 0xc011 251 TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xc012 252 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0xc013 253 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0xc014 254 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02f 255 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02b 256 )