1 // Copyright 2009 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.
16 // Split a premaster secret in two as specified in RFC 4346, section 5.
17 func splitPreMasterSecret(secret
[]byte) (s1
, s2
[]byte) {
18 s1
= secret
[0 : (len(secret
)+1)/2]
19 s2
= secret
[len(secret
)/2:]
23 // pHash implements the P_hash function, as defined in RFC 4346, section 5.
24 func pHash(result
, secret
, seed
[]byte, hash
func() hash
.Hash
) {
25 h
:= hmac
.New(hash
, secret
)
36 if j
+todo
> len(result
) {
37 todo
= len(result
) - j
39 copy(result
[j
:j
+todo
], b
)
48 // prf10 implements the TLS 1.0 pseudo-random function, as defined in RFC 2246, section 5.
49 func prf10(result
, secret
, label
, seed
[]byte) {
53 labelAndSeed
:= make([]byte, len(label
)+len(seed
))
54 copy(labelAndSeed
, label
)
55 copy(labelAndSeed
[len(label
):], seed
)
57 s1
, s2
:= splitPreMasterSecret(secret
)
58 pHash(result
, s1
, labelAndSeed
, hashMD5
)
59 result2
:= make([]byte, len(result
))
60 pHash(result2
, s2
, labelAndSeed
, hashSHA1
)
62 for i
, b
:= range result2
{
67 // prf12 implements the TLS 1.2 pseudo-random function, as defined in RFC 5246, section 5.
68 func prf12(result
, secret
, label
, seed
[]byte) {
69 labelAndSeed
:= make([]byte, len(label
)+len(seed
))
70 copy(labelAndSeed
, label
)
71 copy(labelAndSeed
[len(label
):], seed
)
73 pHash(result
, secret
, labelAndSeed
, sha256
.New
)
76 // prf30 implements the SSL 3.0 pseudo-random function, as defined in
77 // www.mozilla.org/projects/security/pki/nss/ssl/draft302.txt section 6.
78 func prf30(result
, secret
, label
, seed
[]byte) {
79 hashSHA1
:= sha1
.New()
84 // RFC5246 section 6.3 says that the largest PRF output needed is 128
85 // bytes. Since no more ciphersuites will be added to SSLv3, this will
86 // remain true. Each iteration gives us 16 bytes so 10 iterations will
89 for done
< len(result
) {
90 for j
:= 0; j
<= i
; j
++ {
95 hashSHA1
.Write(b
[:i
+1])
96 hashSHA1
.Write(secret
)
98 digest
:= hashSHA1
.Sum(nil)
101 hashMD5
.Write(secret
)
102 hashMD5
.Write(digest
)
104 done
+= copy(result
[done
:], hashMD5
.Sum(nil))
110 tlsRandomLength
= 32 // Length of a random nonce in TLS 1.1.
111 masterSecretLength
= 48 // Length of a master secret in TLS 1.1.
112 finishedVerifyLength
= 12 // Length of verify_data in a Finished message.
115 var masterSecretLabel
= []byte("master secret")
116 var keyExpansionLabel
= []byte("key expansion")
117 var clientFinishedLabel
= []byte("client finished")
118 var serverFinishedLabel
= []byte("server finished")
120 func prfForVersion(version
uint16) func(result
, secret
, label
, seed
[]byte) {
124 case VersionTLS10
, VersionTLS11
:
129 panic("unknown version")
133 // masterFromPreMasterSecret generates the master secret from the pre-master
134 // secret. See http://tools.ietf.org/html/rfc5246#section-8.1
135 func masterFromPreMasterSecret(version
uint16, preMasterSecret
, clientRandom
, serverRandom
[]byte) []byte {
136 var seed
[tlsRandomLength
* 2]byte
137 copy(seed
[0:len(clientRandom
)], clientRandom
)
138 copy(seed
[len(clientRandom
):], serverRandom
)
139 masterSecret
:= make([]byte, masterSecretLength
)
140 prfForVersion(version
)(masterSecret
, preMasterSecret
, masterSecretLabel
, seed
[0:])
144 // keysFromMasterSecret generates the connection keys from the master
145 // secret, given the lengths of the MAC key, cipher key and IV, as defined in
146 // RFC 2246, section 6.3.
147 func keysFromMasterSecret(version
uint16, masterSecret
, clientRandom
, serverRandom
[]byte, macLen
, keyLen
, ivLen
int) (clientMAC
, serverMAC
, clientKey
, serverKey
, clientIV
, serverIV
[]byte) {
148 var seed
[tlsRandomLength
* 2]byte
149 copy(seed
[0:len(clientRandom
)], serverRandom
)
150 copy(seed
[len(serverRandom
):], clientRandom
)
152 n
:= 2*macLen
+ 2*keyLen
+ 2*ivLen
153 keyMaterial
:= make([]byte, n
)
154 prfForVersion(version
)(keyMaterial
, masterSecret
, keyExpansionLabel
, seed
[0:])
155 clientMAC
= keyMaterial
[:macLen
]
156 keyMaterial
= keyMaterial
[macLen
:]
157 serverMAC
= keyMaterial
[:macLen
]
158 keyMaterial
= keyMaterial
[macLen
:]
159 clientKey
= keyMaterial
[:keyLen
]
160 keyMaterial
= keyMaterial
[keyLen
:]
161 serverKey
= keyMaterial
[:keyLen
]
162 keyMaterial
= keyMaterial
[keyLen
:]
163 clientIV
= keyMaterial
[:ivLen
]
164 keyMaterial
= keyMaterial
[ivLen
:]
165 serverIV
= keyMaterial
[:ivLen
]
169 func newFinishedHash(version
uint16) finishedHash
{
170 if version
>= VersionTLS12
{
171 return finishedHash
{sha256
.New(), sha256
.New(), nil, nil, version
}
173 return finishedHash
{sha1
.New(), sha1
.New(), md5
.New(), md5
.New(), version
}
176 // A finishedHash calculates the hash of a set of handshake messages suitable
177 // for including in a Finished message.
178 type finishedHash
struct {
182 // Prior to TLS 1.2, an additional MD5 hash is required.
189 func (h finishedHash
) Write(msg
[]byte) (n
int, err error
) {
193 if h
.version
< VersionTLS12
{
194 h
.clientMD5
.Write(msg
)
195 h
.serverMD5
.Write(msg
)
200 // finishedSum30 calculates the contents of the verify_data member of a SSLv3
201 // Finished message given the MD5 and SHA1 hashes of a set of handshake
203 func finishedSum30(md5
, sha1 hash
.Hash
, masterSecret
[]byte, magic
[4]byte) []byte {
205 md5
.Write(masterSecret
)
206 md5
.Write(ssl30Pad1
[:])
207 md5Digest
:= md5
.Sum(nil)
210 md5
.Write(masterSecret
)
211 md5
.Write(ssl30Pad2
[:])
213 md5Digest
= md5
.Sum(nil)
216 sha1
.Write(masterSecret
)
217 sha1
.Write(ssl30Pad1
[:40])
218 sha1Digest
:= sha1
.Sum(nil)
221 sha1
.Write(masterSecret
)
222 sha1
.Write(ssl30Pad2
[:40])
223 sha1
.Write(sha1Digest
)
224 sha1Digest
= sha1
.Sum(nil)
226 ret
:= make([]byte, len(md5Digest
)+len(sha1Digest
))
228 copy(ret
[len(md5Digest
):], sha1Digest
)
232 var ssl3ClientFinishedMagic
= [4]byte{0x43, 0x4c, 0x4e, 0x54}
233 var ssl3ServerFinishedMagic
= [4]byte{0x53, 0x52, 0x56, 0x52}
235 // clientSum returns the contents of the verify_data member of a client's
237 func (h finishedHash
) clientSum(masterSecret
[]byte) []byte {
238 if h
.version
== VersionSSL30
{
239 return finishedSum30(h
.clientMD5
, h
.client
, masterSecret
, ssl3ClientFinishedMagic
)
242 out
:= make([]byte, finishedVerifyLength
)
243 if h
.version
>= VersionTLS12
{
244 seed
:= h
.client
.Sum(nil)
245 prf12(out
, masterSecret
, clientFinishedLabel
, seed
)
247 seed
:= make([]byte, 0, md5
.Size
+sha1
.Size
)
248 seed
= h
.clientMD5
.Sum(seed
)
249 seed
= h
.client
.Sum(seed
)
250 prf10(out
, masterSecret
, clientFinishedLabel
, seed
)
255 // serverSum returns the contents of the verify_data member of a server's
257 func (h finishedHash
) serverSum(masterSecret
[]byte) []byte {
258 if h
.version
== VersionSSL30
{
259 return finishedSum30(h
.serverMD5
, h
.server
, masterSecret
, ssl3ServerFinishedMagic
)
262 out
:= make([]byte, finishedVerifyLength
)
263 if h
.version
>= VersionTLS12
{
264 seed
:= h
.server
.Sum(nil)
265 prf12(out
, masterSecret
, serverFinishedLabel
, seed
)
267 seed
:= make([]byte, 0, md5
.Size
+sha1
.Size
)
268 seed
= h
.serverMD5
.Sum(seed
)
269 seed
= h
.server
.Sum(seed
)
270 prf10(out
, masterSecret
, serverFinishedLabel
, seed
)
275 // hashForClientCertificate returns a digest, hash function, and TLS 1.2 hash
276 // id suitable for signing by a TLS client certificate.
277 func (h finishedHash
) hashForClientCertificate(sigType
uint8) ([]byte, crypto
.Hash
, uint8) {
278 if h
.version
>= VersionTLS12
{
279 digest
:= h
.server
.Sum(nil)
280 return digest
, crypto
.SHA256
, hashSHA256
282 if sigType
== signatureECDSA
{
283 digest
:= h
.server
.Sum(nil)
284 return digest
, crypto
.SHA1
, hashSHA1
287 digest
:= make([]byte, 0, 36)
288 digest
= h
.serverMD5
.Sum(digest
)
289 digest
= h
.server
.Sum(digest
)
290 return digest
, crypto
.MD5SHA1
, 0 /* not specified in TLS 1.2. */