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.
15 // Split a premaster secret in two as specified in RFC 4346, section 5.
16 func splitPreMasterSecret(secret
[]byte) (s1
, s2
[]byte) {
17 s1
= secret
[0 : (len(secret
)+1)/2]
18 s2
= secret
[len(secret
)/2:]
22 // pHash implements the P_hash function, as defined in RFC 4346, section 5.
23 func pHash(result
, secret
, seed
[]byte, hash
func() hash
.Hash
) {
24 h
:= hmac
.New(hash
, secret
)
35 if j
+todo
> len(result
) {
36 todo
= len(result
) - j
38 copy(result
[j
:j
+todo
], b
)
47 // pRF11 implements the TLS 1.1 pseudo-random function, as defined in RFC 4346, section 5.
48 func pRF11(result
, secret
, label
, seed
[]byte) {
52 labelAndSeed
:= make([]byte, len(label
)+len(seed
))
53 copy(labelAndSeed
, label
)
54 copy(labelAndSeed
[len(label
):], seed
)
56 s1
, s2
:= splitPreMasterSecret(secret
)
57 pHash(result
, s1
, labelAndSeed
, hashMD5
)
58 result2
:= make([]byte, len(result
))
59 pHash(result2
, s2
, labelAndSeed
, hashSHA1
)
61 for i
, b
:= range result2
{
67 tlsRandomLength
= 32 // Length of a random nonce in TLS 1.1.
68 masterSecretLength
= 48 // Length of a master secret in TLS 1.1.
69 finishedVerifyLength
= 12 // Length of verify_data in a Finished message.
72 var masterSecretLabel
= []byte("master secret")
73 var keyExpansionLabel
= []byte("key expansion")
74 var clientFinishedLabel
= []byte("client finished")
75 var serverFinishedLabel
= []byte("server finished")
77 // keysFromPreMasterSecret generates the connection keys from the pre master
78 // secret, given the lengths of the MAC and cipher keys, as defined in RFC
80 func keysFromPreMasterSecret11(preMasterSecret
, clientRandom
, serverRandom
[]byte, macLen
, keyLen
int) (masterSecret
, clientMAC
, serverMAC
, clientKey
, serverKey
[]byte) {
81 var seed
[tlsRandomLength
* 2]byte
82 copy(seed
[0:len(clientRandom
)], clientRandom
)
83 copy(seed
[len(clientRandom
):], serverRandom
)
84 masterSecret
= make([]byte, masterSecretLength
)
85 pRF11(masterSecret
, preMasterSecret
, masterSecretLabel
, seed
[0:])
87 copy(seed
[0:len(clientRandom
)], serverRandom
)
88 copy(seed
[len(serverRandom
):], clientRandom
)
90 n
:= 2*macLen
+ 2*keyLen
91 keyMaterial
:= make([]byte, n
)
92 pRF11(keyMaterial
, masterSecret
, keyExpansionLabel
, seed
[0:])
93 clientMAC
= keyMaterial
[0:macLen
]
94 serverMAC
= keyMaterial
[macLen
: macLen
*2]
95 clientKey
= keyMaterial
[macLen
*2 : macLen
*2+keyLen
]
96 serverKey
= keyMaterial
[macLen
*2+keyLen
:]
100 // A finishedHash calculates the hash of a set of handshake messages suitable
101 // for including in a Finished message.
102 type finishedHash
struct {
109 func newFinishedHash() finishedHash
{
110 return finishedHash
{md5
.New(), sha1
.New(), md5
.New(), sha1
.New()}
113 func (h finishedHash
) Write(msg
[]byte) (n
int, err os
.Error
) {
114 h
.clientMD5
.Write(msg
)
115 h
.clientSHA1
.Write(msg
)
116 h
.serverMD5
.Write(msg
)
117 h
.serverSHA1
.Write(msg
)
121 // finishedSum calculates the contents of the verify_data member of a Finished
122 // message given the MD5 and SHA1 hashes of a set of handshake messages.
123 func finishedSum(md5
, sha1
, label
, masterSecret
[]byte) []byte {
124 seed
:= make([]byte, len(md5
)+len(sha1
))
126 copy(seed
[len(md5
):], sha1
)
127 out
:= make([]byte, finishedVerifyLength
)
128 pRF11(out
, masterSecret
, label
, seed
)
132 // clientSum returns the contents of the verify_data member of a client's
134 func (h finishedHash
) clientSum(masterSecret
[]byte) []byte {
135 md5
:= h
.clientMD5
.Sum()
136 sha1
:= h
.clientSHA1
.Sum()
137 return finishedSum(md5
, sha1
, clientFinishedLabel
, masterSecret
)
140 // serverSum returns the contents of the verify_data member of a server's
142 func (h finishedHash
) serverSum(masterSecret
[]byte) []byte {
143 md5
:= h
.serverMD5
.Sum()
144 sha1
:= h
.serverSHA1
.Sum()
145 return finishedSum(md5
, sha1
, serverFinishedLabel
, masterSecret
)