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. 4 5package tls 6 7import ( 8 "crypto" 9 "crypto/hmac" 10 "crypto/md5" 11 "crypto/sha1" 12 "crypto/sha256" 13 "crypto/sha512" 14 "errors" 15 "fmt" 16 "hash" 17) 18 19// Split a premaster secret in two as specified in RFC 4346, Section 5. 20func splitPreMasterSecret(secret []byte) (s1, s2 []byte) { 21 s1 = secret[0 : (len(secret)+1)/2] 22 s2 = secret[len(secret)/2:] 23 return 24} 25 26// pHash implements the P_hash function, as defined in RFC 4346, Section 5. 27func pHash(result, secret, seed []byte, hash func() hash.Hash) { 28 h := hmac.New(hash, secret) 29 h.Write(seed) 30 a := h.Sum(nil) 31 32 j := 0 33 for j < len(result) { 34 h.Reset() 35 h.Write(a) 36 h.Write(seed) 37 b := h.Sum(nil) 38 copy(result[j:], b) 39 j += len(b) 40 41 h.Reset() 42 h.Write(a) 43 a = h.Sum(nil) 44 } 45} 46 47// prf10 implements the TLS 1.0 pseudo-random function, as defined in RFC 2246, Section 5. 48func prf10(result, secret, label, seed []byte) { 49 hashSHA1 := sha1.New 50 hashMD5 := md5.New 51 52 labelAndSeed := make([]byte, len(label)+len(seed)) 53 copy(labelAndSeed, label) 54 copy(labelAndSeed[len(label):], seed) 55 56 s1, s2 := splitPreMasterSecret(secret) 57 pHash(result, s1, labelAndSeed, hashMD5) 58 result2 := make([]byte, len(result)) 59 pHash(result2, s2, labelAndSeed, hashSHA1) 60 61 for i, b := range result2 { 62 result[i] ^= b 63 } 64} 65 66// prf12 implements the TLS 1.2 pseudo-random function, as defined in RFC 5246, Section 5. 67func 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) 72 73 pHash(result, secret, labelAndSeed, hashFunc) 74 } 75} 76 77const ( 78 masterSecretLength = 48 // Length of a master secret in TLS 1.1. 79 finishedVerifyLength = 12 // Length of verify_data in a Finished message. 80) 81 82var masterSecretLabel = []byte("master secret") 83var extendedMasterSecretLabel = []byte("extended master secret") 84var keyExpansionLabel = []byte("key expansion") 85var clientFinishedLabel = []byte("client finished") 86var serverFinishedLabel = []byte("server finished") 87 88func prfAndHashForVersion(version uint16, suite *cipherSuite) (func(result, secret, label, seed []byte), crypto.Hash) { 89 switch version { 90 case VersionTLS10, VersionTLS11: 91 return prf10, crypto.Hash(0) 92 case VersionTLS12: 93 if suite.flags&suiteSHA384 != 0 { 94 return prf12(sha512.New384), crypto.SHA384 95 } 96 return prf12(sha256.New), crypto.SHA256 97 default: 98 panic("unknown version") 99 } 100} 101 102func prfForVersion(version uint16, suite *cipherSuite) func(result, secret, label, seed []byte) { 103 prf, _ := prfAndHashForVersion(version, suite) 104 return prf 105} 106 107// masterFromPreMasterSecret generates the master secret from the pre-master 108// secret. See RFC 5246, Section 8.1. 109func masterFromPreMasterSecret(version uint16, suite *cipherSuite, preMasterSecret, clientRandom, serverRandom []byte) []byte { 110 seed := make([]byte, 0, len(clientRandom)+len(serverRandom)) 111 seed = append(seed, clientRandom...) 112 seed = append(seed, serverRandom...) 113 114 masterSecret := make([]byte, masterSecretLength) 115 prfForVersion(version, suite)(masterSecret, preMasterSecret, masterSecretLabel, seed) 116 return masterSecret 117} 118 119// extMasterFromPreMasterSecret generates the extended master secret from the 120// pre-master secret. See RFC 7627. 121func extMasterFromPreMasterSecret(version uint16, suite *cipherSuite, preMasterSecret, transcript []byte) []byte { 122 masterSecret := make([]byte, masterSecretLength) 123 prfForVersion(version, suite)(masterSecret, preMasterSecret, extendedMasterSecretLabel, transcript) 124 return masterSecret 125} 126 127// keysFromMasterSecret generates the connection keys from the master 128// secret, given the lengths of the MAC key, cipher key and IV, as defined in 129// RFC 2246, Section 6.3. 130func keysFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clientRandom, serverRandom []byte, macLen, keyLen, ivLen int) (clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV []byte) { 131 seed := make([]byte, 0, len(serverRandom)+len(clientRandom)) 132 seed = append(seed, serverRandom...) 133 seed = append(seed, clientRandom...) 134 135 n := 2*macLen + 2*keyLen + 2*ivLen 136 keyMaterial := make([]byte, n) 137 prfForVersion(version, suite)(keyMaterial, masterSecret, keyExpansionLabel, seed) 138 clientMAC = keyMaterial[:macLen] 139 keyMaterial = keyMaterial[macLen:] 140 serverMAC = keyMaterial[:macLen] 141 keyMaterial = keyMaterial[macLen:] 142 clientKey = keyMaterial[:keyLen] 143 keyMaterial = keyMaterial[keyLen:] 144 serverKey = keyMaterial[:keyLen] 145 keyMaterial = keyMaterial[keyLen:] 146 clientIV = keyMaterial[:ivLen] 147 keyMaterial = keyMaterial[ivLen:] 148 serverIV = keyMaterial[:ivLen] 149 return 150} 151 152func newFinishedHash(version uint16, cipherSuite *cipherSuite) finishedHash { 153 var buffer []byte 154 if version >= VersionTLS12 { 155 buffer = []byte{} 156 } 157 158 prf, hash := prfAndHashForVersion(version, cipherSuite) 159 if hash != 0 { 160 return finishedHash{hash.New(), hash.New(), nil, nil, buffer, version, prf} 161 } 162 163 return finishedHash{sha1.New(), sha1.New(), md5.New(), md5.New(), buffer, version, prf} 164} 165 166// A finishedHash calculates the hash of a set of handshake messages suitable 167// for including in a Finished message. 168type finishedHash struct { 169 client hash.Hash 170 server hash.Hash 171 172 // Prior to TLS 1.2, an additional MD5 hash is required. 173 clientMD5 hash.Hash 174 serverMD5 hash.Hash 175 176 // In TLS 1.2, a full buffer is sadly required. 177 buffer []byte 178 179 version uint16 180 prf func(result, secret, label, seed []byte) 181} 182 183func (h *finishedHash) Write(msg []byte) (n int, err error) { 184 h.client.Write(msg) 185 h.server.Write(msg) 186 187 if h.version < VersionTLS12 { 188 h.clientMD5.Write(msg) 189 h.serverMD5.Write(msg) 190 } 191 192 if h.buffer != nil { 193 h.buffer = append(h.buffer, msg...) 194 } 195 196 return len(msg), nil 197} 198 199func (h finishedHash) Sum() []byte { 200 if h.version >= VersionTLS12 { 201 return h.client.Sum(nil) 202 } 203 204 out := make([]byte, 0, md5.Size+sha1.Size) 205 out = h.clientMD5.Sum(out) 206 return h.client.Sum(out) 207} 208 209// clientSum returns the contents of the verify_data member of a client's 210// Finished message. 211func (h finishedHash) clientSum(masterSecret []byte) []byte { 212 out := make([]byte, finishedVerifyLength) 213 h.prf(out, masterSecret, clientFinishedLabel, h.Sum()) 214 return out 215} 216 217// serverSum returns the contents of the verify_data member of a server's 218// Finished message. 219func (h finishedHash) serverSum(masterSecret []byte) []byte { 220 out := make([]byte, finishedVerifyLength) 221 h.prf(out, masterSecret, serverFinishedLabel, h.Sum()) 222 return out 223} 224 225// hashForClientCertificate returns the handshake messages so far, pre-hashed if 226// necessary, suitable for signing by a TLS client certificate. 227func (h finishedHash) hashForClientCertificate(sigType uint8, hashAlg crypto.Hash) []byte { 228 if (h.version >= VersionTLS12 || sigType == signatureEd25519) && h.buffer == nil { 229 panic("tls: handshake hash for a client certificate requested after discarding the handshake buffer") 230 } 231 232 if sigType == signatureEd25519 { 233 return h.buffer 234 } 235 236 if h.version >= VersionTLS12 { 237 hash := hashAlg.New() 238 hash.Write(h.buffer) 239 return hash.Sum(nil) 240 } 241 242 if sigType == signatureECDSA { 243 return h.server.Sum(nil) 244 } 245 246 return h.Sum() 247} 248 249// discardHandshakeBuffer is called when there is no more need to 250// buffer the entirety of the handshake messages. 251func (h *finishedHash) discardHandshakeBuffer() { 252 h.buffer = nil 253} 254 255// noEKMBecauseRenegotiation is used as a value of 256// ConnectionState.ekm when renegotiation is enabled and thus 257// we wish to fail all key-material export requests. 258func noEKMBecauseRenegotiation(label string, context []byte, length int) ([]byte, error) { 259 return nil, errors.New("crypto/tls: ExportKeyingMaterial is unavailable when renegotiation is enabled") 260} 261 262// noEKMBecauseNoEMS is used as a value of ConnectionState.ekm when Extended 263// Master Secret is not negotiated and thus we wish to fail all key-material 264// export requests. 265func noEKMBecauseNoEMS(label string, context []byte, length int) ([]byte, error) { 266 return nil, errors.New("crypto/tls: ExportKeyingMaterial is unavailable when neither TLS 1.3 nor Extended Master Secret are negotiated; override with GODEBUG=tlsunsafeekm=1") 267} 268 269// ekmFromMasterSecret generates exported keying material as defined in RFC 5705. 270func ekmFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clientRandom, serverRandom []byte) func(string, []byte, int) ([]byte, error) { 271 return func(label string, context []byte, length int) ([]byte, error) { 272 switch label { 273 case "client finished", "server finished", "master secret", "key expansion": 274 // These values are reserved and may not be used. 275 return nil, fmt.Errorf("crypto/tls: reserved ExportKeyingMaterial label: %s", label) 276 } 277 278 seedLen := len(serverRandom) + len(clientRandom) 279 if context != nil { 280 seedLen += 2 + len(context) 281 } 282 seed := make([]byte, 0, seedLen) 283 284 seed = append(seed, clientRandom...) 285 seed = append(seed, serverRandom...) 286 287 if context != nil { 288 if len(context) >= 1<<16 { 289 return nil, fmt.Errorf("crypto/tls: ExportKeyingMaterial context too long") 290 } 291 seed = append(seed, byte(len(context)>>8), byte(len(context))) 292 seed = append(seed, context...) 293 } 294 295 keyMaterial := make([]byte, length) 296 prfForVersion(version, suite)(keyMaterial, masterSecret, []byte(label), seed) 297 return keyMaterial, nil 298 } 299} 300