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.
19 // Split a premaster secret in two as specified in RFC 4346, Section 5.
20 func splitPreMasterSecret(secret
[]byte) (s1
, s2
[]byte) {
21 s1
= secret
[0 : (len(secret
)+1)/2]
22 s2
= secret
[len(secret
)/2:]
26 // pHash implements the P_hash function, as defined in RFC 4346, Section 5.
27 func pHash(result
, secret
, seed
[]byte, hash
func() hash
.Hash
) {
28 h
:= hmac
.New(hash
, secret
)
47 // prf10 implements the TLS 1.0 pseudo-random function, as defined in RFC 2246, Section 5.
48 func prf10(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
{
66 // prf12 implements the TLS 1.2 pseudo-random function, as defined in RFC 5246, Section 5.
67 func prf12(hashFunc
func() hash
.Hash
) func(result
, secret
, label
, seed
[]byte) {
68 return func(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
, hashFunc
)
78 masterSecretLength
= 48 // Length of a master secret in TLS 1.1.
79 finishedVerifyLength
= 12 // Length of verify_data in a Finished message.
82 var masterSecretLabel
= []byte("master secret")
83 var keyExpansionLabel
= []byte("key expansion")
84 var clientFinishedLabel
= []byte("client finished")
85 var serverFinishedLabel
= []byte("server finished")
87 func prfAndHashForVersion(version
uint16, suite
*cipherSuite
) (func(result
, secret
, label
, seed
[]byte), crypto
.Hash
) {
89 case VersionTLS10
, VersionTLS11
:
90 return prf10
, crypto
.Hash(0)
92 if suite
.flags
&suiteSHA384
!= 0 {
93 return prf12(sha512
.New384
), crypto
.SHA384
95 return prf12(sha256
.New
), crypto
.SHA256
97 panic("unknown version")
101 func prfForVersion(version
uint16, suite
*cipherSuite
) func(result
, secret
, label
, seed
[]byte) {
102 prf
, _
:= prfAndHashForVersion(version
, suite
)
106 // masterFromPreMasterSecret generates the master secret from the pre-master
107 // secret. See RFC 5246, Section 8.1.
108 func masterFromPreMasterSecret(version
uint16, suite
*cipherSuite
, preMasterSecret
, clientRandom
, serverRandom
[]byte) []byte {
109 seed
:= make([]byte, 0, len(clientRandom
)+len(serverRandom
))
110 seed
= append(seed
, clientRandom
...)
111 seed
= append(seed
, serverRandom
...)
113 masterSecret
:= make([]byte, masterSecretLength
)
114 prfForVersion(version
, suite
)(masterSecret
, preMasterSecret
, masterSecretLabel
, seed
)
118 // keysFromMasterSecret generates the connection keys from the master
119 // secret, given the lengths of the MAC key, cipher key and IV, as defined in
120 // RFC 2246, Section 6.3.
121 func keysFromMasterSecret(version
uint16, suite
*cipherSuite
, masterSecret
, clientRandom
, serverRandom
[]byte, macLen
, keyLen
, ivLen
int) (clientMAC
, serverMAC
, clientKey
, serverKey
, clientIV
, serverIV
[]byte) {
122 seed
:= make([]byte, 0, len(serverRandom
)+len(clientRandom
))
123 seed
= append(seed
, serverRandom
...)
124 seed
= append(seed
, clientRandom
...)
126 n
:= 2*macLen
+ 2*keyLen
+ 2*ivLen
127 keyMaterial
:= make([]byte, n
)
128 prfForVersion(version
, suite
)(keyMaterial
, masterSecret
, keyExpansionLabel
, seed
)
129 clientMAC
= keyMaterial
[:macLen
]
130 keyMaterial
= keyMaterial
[macLen
:]
131 serverMAC
= keyMaterial
[:macLen
]
132 keyMaterial
= keyMaterial
[macLen
:]
133 clientKey
= keyMaterial
[:keyLen
]
134 keyMaterial
= keyMaterial
[keyLen
:]
135 serverKey
= keyMaterial
[:keyLen
]
136 keyMaterial
= keyMaterial
[keyLen
:]
137 clientIV
= keyMaterial
[:ivLen
]
138 keyMaterial
= keyMaterial
[ivLen
:]
139 serverIV
= keyMaterial
[:ivLen
]
143 func newFinishedHash(version
uint16, cipherSuite
*cipherSuite
) finishedHash
{
145 if version
>= VersionTLS12
{
149 prf
, hash
:= prfAndHashForVersion(version
, cipherSuite
)
151 return finishedHash
{hash
.New(), hash
.New(), nil, nil, buffer
, version
, prf
}
154 return finishedHash
{sha1
.New(), sha1
.New(), md5
.New(), md5
.New(), buffer
, version
, prf
}
157 // A finishedHash calculates the hash of a set of handshake messages suitable
158 // for including in a Finished message.
159 type finishedHash
struct {
163 // Prior to TLS 1.2, an additional MD5 hash is required.
167 // In TLS 1.2, a full buffer is sadly required.
171 prf
func(result
, secret
, label
, seed
[]byte)
174 func (h
*finishedHash
) Write(msg
[]byte) (n
int, err error
) {
178 if h
.version
< VersionTLS12
{
179 h
.clientMD5
.Write(msg
)
180 h
.serverMD5
.Write(msg
)
184 h
.buffer
= append(h
.buffer
, msg
...)
190 func (h finishedHash
) Sum() []byte {
191 if h
.version
>= VersionTLS12
{
192 return h
.client
.Sum(nil)
195 out
:= make([]byte, 0, md5
.Size
+sha1
.Size
)
196 out
= h
.clientMD5
.Sum(out
)
197 return h
.client
.Sum(out
)
200 // clientSum returns the contents of the verify_data member of a client's
202 func (h finishedHash
) clientSum(masterSecret
[]byte) []byte {
203 out
:= make([]byte, finishedVerifyLength
)
204 h
.prf(out
, masterSecret
, clientFinishedLabel
, h
.Sum())
208 // serverSum returns the contents of the verify_data member of a server's
210 func (h finishedHash
) serverSum(masterSecret
[]byte) []byte {
211 out
:= make([]byte, finishedVerifyLength
)
212 h
.prf(out
, masterSecret
, serverFinishedLabel
, h
.Sum())
216 // hashForClientCertificate returns the handshake messages so far, pre-hashed if
217 // necessary, suitable for signing by a TLS client certificate.
218 func (h finishedHash
) hashForClientCertificate(sigType
uint8, hashAlg crypto
.Hash
, masterSecret
[]byte) []byte {
219 if (h
.version
>= VersionTLS12 || sigType
== signatureEd25519
) && h
.buffer
== nil {
220 panic("tls: handshake hash for a client certificate requested after discarding the handshake buffer")
223 if sigType
== signatureEd25519
{
227 if h
.version
>= VersionTLS12
{
228 hash
:= hashAlg
.New()
233 if sigType
== signatureECDSA
{
234 return h
.server
.Sum(nil)
240 // discardHandshakeBuffer is called when there is no more need to
241 // buffer the entirety of the handshake messages.
242 func (h
*finishedHash
) discardHandshakeBuffer() {
246 // noExportedKeyingMaterial is used as a value of
247 // ConnectionState.ekm when renegotiation is enabled and thus
248 // we wish to fail all key-material export requests.
249 func noExportedKeyingMaterial(label
string, context
[]byte, length
int) ([]byte, error
) {
250 return nil, errors
.New("crypto/tls: ExportKeyingMaterial is unavailable when renegotiation is enabled")
253 // ekmFromMasterSecret generates exported keying material as defined in RFC 5705.
254 func ekmFromMasterSecret(version
uint16, suite
*cipherSuite
, masterSecret
, clientRandom
, serverRandom
[]byte) func(string, []byte, int) ([]byte, error
) {
255 return func(label
string, context
[]byte, length
int) ([]byte, error
) {
257 case "client finished", "server finished", "master secret", "key expansion":
258 // These values are reserved and may not be used.
259 return nil, fmt
.Errorf("crypto/tls: reserved ExportKeyingMaterial label: %s", label
)
262 seedLen
:= len(serverRandom
) + len(clientRandom
)
264 seedLen
+= 2 + len(context
)
266 seed
:= make([]byte, 0, seedLen
)
268 seed
= append(seed
, clientRandom
...)
269 seed
= append(seed
, serverRandom
...)
272 if len(context
) >= 1<<16 {
273 return nil, fmt
.Errorf("crypto/tls: ExportKeyingMaterial context too long")
275 seed
= append(seed
, byte(len(context
)>>8), byte(len(context
)))
276 seed
= append(seed
, context
...)
279 keyMaterial
:= make([]byte, length
)
280 prfForVersion(version
, suite
)(keyMaterial
, masterSecret
, []byte(label
), seed
)
281 return keyMaterial
, nil