Source file src/pkg/crypto/tls/cipher_suites.go
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_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, true, cipherRC4, macSHA1},
59 {TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, true, cipher3DES, macSHA1},
60 {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, true, cipherAES, macSHA1},
61 }
62
63 func cipherRC4(key, iv []byte, isRead bool) interface{} {
64 cipher, _ := rc4.NewCipher(key)
65 return cipher
66 }
67
68 func cipher3DES(key, iv []byte, isRead bool) interface{} {
69 block, _ := des.NewTripleDESCipher(key)
70 if isRead {
71 return cipher.NewCBCDecrypter(block, iv)
72 }
73 return cipher.NewCBCEncrypter(block, iv)
74 }
75
76 func cipherAES(key, iv []byte, isRead bool) interface{} {
77 block, _ := aes.NewCipher(key)
78 if isRead {
79 return cipher.NewCBCDecrypter(block, iv)
80 }
81 return cipher.NewCBCEncrypter(block, iv)
82 }
83
84 // macSHA1 returns a macFunction for the given protocol version.
85 func macSHA1(version uint16, key []byte) macFunction {
86 if version == versionSSL30 {
87 mac := ssl30MAC{
88 h: sha1.New(),
89 key: make([]byte, len(key)),
90 }
91 copy(mac.key, key)
92 return mac
93 }
94 return tls10MAC{hmac.New(sha1.New, key)}
95 }
96
97 type macFunction interface {
98 Size() int
99 MAC(digestBuf, seq, data []byte) []byte
100 }
101
102 // ssl30MAC implements the SSLv3 MAC function, as defined in
103 // www.mozilla.org/projects/security/pki/nss/ssl/draft302.txt section 5.2.3.1
104 type ssl30MAC struct {
105 h hash.Hash
106 key []byte
107 }
108
109 func (s ssl30MAC) Size() int {
110 return s.h.Size()
111 }
112
113 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}
114
115 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}
116
117 func (s ssl30MAC) MAC(digestBuf, seq, record []byte) []byte {
118 padLength := 48
119 if s.h.Size() == 20 {
120 padLength = 40
121 }
122
123 s.h.Reset()
124 s.h.Write(s.key)
125 s.h.Write(ssl30Pad1[:padLength])
126 s.h.Write(seq)
127 s.h.Write(record[:1])
128 s.h.Write(record[3:5])
129 s.h.Write(record[recordHeaderLen:])
130 digestBuf = s.h.Sum(digestBuf[:0])
131
132 s.h.Reset()
133 s.h.Write(s.key)
134 s.h.Write(ssl30Pad2[:padLength])
135 s.h.Write(digestBuf)
136 return s.h.Sum(digestBuf[:0])
137 }
138
139 // tls10MAC implements the TLS 1.0 MAC function. RFC 2246, section 6.2.3.
140 type tls10MAC struct {
141 h hash.Hash
142 }
143
144 func (s tls10MAC) Size() int {
145 return s.h.Size()
146 }
147
148 func (s tls10MAC) MAC(digestBuf, seq, record []byte) []byte {
149 s.h.Reset()
150 s.h.Write(seq)
151 s.h.Write(record)
152 return s.h.Sum(digestBuf[:0])
153 }
154
155 func rsaKA() keyAgreement {
156 return rsaKeyAgreement{}
157 }
158
159 func ecdheRSAKA() keyAgreement {
160 return new(ecdheRSAKeyAgreement)
161 }
162
163 // mutualCipherSuite returns a cipherSuite given a list of supported
164 // ciphersuites and the id requested by the peer.
165 func mutualCipherSuite(have []uint16, want uint16) *cipherSuite {
166 for _, id := range have {
167 if id == want {
168 for _, suite := range cipherSuites {
169 if suite.id == want {
170 return suite
171 }
172 }
173 return nil
174 }
175 }
176 return nil
177 }
178
179 // A list of the possible cipher suite ids. Taken from
180 // http://www.iana.org/assignments/tls-parameters/tls-parameters.xml
181 const (
182 TLS_RSA_WITH_RC4_128_SHA uint16 = 0x0005
183 TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000a
184 TLS_RSA_WITH_AES_128_CBC_SHA uint16 = 0x002f
185 TLS_ECDHE_RSA_WITH_RC4_128_SHA uint16 = 0xc011
186 TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xc012
187 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0xc013
188 )