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 runner 6 7import ( 8 "crypto" 9 "crypto/hmac" 10 "crypto/md5" 11 "crypto/sha1" 12 "crypto/sha256" 13 "encoding" 14 "hash" 15 16 "golang.org/x/crypto/hkdf" 17) 18 19// copyHash returns a copy of |h|, which must be an instance of |hashType|. 20func copyHash(h hash.Hash, hash crypto.Hash) hash.Hash { 21 // While hash.Hash is not copyable, the documentation says all standard 22 // library hash.Hash implementations implement BinaryMarshaler and 23 // BinaryUnmarshaler interfaces. 24 m, ok := h.(encoding.BinaryMarshaler) 25 if !ok { 26 panic("hash did not implement encoding.BinaryMarshaler") 27 } 28 data, err := m.MarshalBinary() 29 if err != nil { 30 panic(err) 31 } 32 ret := hash.New() 33 u, ok := ret.(encoding.BinaryUnmarshaler) 34 if !ok { 35 panic("hash did not implement BinaryUnmarshaler") 36 } 37 if err := u.UnmarshalBinary(data); err != nil { 38 panic(err) 39 } 40 return ret 41} 42 43// Split a premaster secret in two as specified in RFC 4346, section 5. 44func splitPreMasterSecret(secret []byte) (s1, s2 []byte) { 45 s1 = secret[0 : (len(secret)+1)/2] 46 s2 = secret[len(secret)/2:] 47 return 48} 49 50// pHash implements the P_hash function, as defined in RFC 4346, section 5. 51func pHash(result, secret, seed []byte, hash func() hash.Hash) { 52 h := hmac.New(hash, secret) 53 h.Write(seed) 54 a := h.Sum(nil) 55 56 j := 0 57 for j < len(result) { 58 h.Reset() 59 h.Write(a) 60 h.Write(seed) 61 b := h.Sum(nil) 62 todo := len(b) 63 if j+todo > len(result) { 64 todo = len(result) - j 65 } 66 copy(result[j:j+todo], b) 67 j += todo 68 69 h.Reset() 70 h.Write(a) 71 a = h.Sum(nil) 72 } 73} 74 75// prf10 implements the TLS 1.0 pseudo-random function, as defined in RFC 2246, section 5. 76func prf10(result, secret, label, seed []byte) { 77 hashSHA1 := sha1.New 78 hashMD5 := md5.New 79 80 labelAndSeed := make([]byte, len(label)+len(seed)) 81 copy(labelAndSeed, label) 82 copy(labelAndSeed[len(label):], seed) 83 84 s1, s2 := splitPreMasterSecret(secret) 85 pHash(result, s1, labelAndSeed, hashMD5) 86 result2 := make([]byte, len(result)) 87 pHash(result2, s2, labelAndSeed, hashSHA1) 88 89 for i, b := range result2 { 90 result[i] ^= b 91 } 92} 93 94// prf12 implements the TLS 1.2 pseudo-random function, as defined in RFC 5246, section 5. 95func prf12(hashFunc func() hash.Hash) func(result, secret, label, seed []byte) { 96 return func(result, secret, label, seed []byte) { 97 labelAndSeed := make([]byte, len(label)+len(seed)) 98 copy(labelAndSeed, label) 99 copy(labelAndSeed[len(label):], seed) 100 101 pHash(result, secret, labelAndSeed, hashFunc) 102 } 103} 104 105const ( 106 tlsRandomLength = 32 // Length of a random nonce in TLS 1.1. 107 masterSecretLength = 48 // Length of a master secret in TLS 1.1. 108 finishedVerifyLength = 12 // Length of verify_data in a Finished message. 109) 110 111var masterSecretLabel = []byte("master secret") 112var extendedMasterSecretLabel = []byte("extended master secret") 113var keyExpansionLabel = []byte("key expansion") 114var clientFinishedLabel = []byte("client finished") 115var serverFinishedLabel = []byte("server finished") 116var finishedLabel = []byte("finished") 117var channelIDLabel = []byte("TLS Channel ID signature\x00") 118var channelIDResumeLabel = []byte("Resumption\x00") 119 120func prfForVersion(version uint16, suite *cipherSuite) func(result, secret, label, seed []byte) { 121 switch version { 122 case VersionTLS10, VersionTLS11: 123 return prf10 124 case VersionTLS12: 125 return prf12(suite.hash().New) 126 } 127 panic("unknown version") 128} 129 130// masterFromPreMasterSecret generates the master secret from the pre-master 131// secret. See http://tools.ietf.org/html/rfc5246#section-8.1 132func masterFromPreMasterSecret(version uint16, suite *cipherSuite, preMasterSecret, clientRandom, serverRandom []byte) []byte { 133 var seed [tlsRandomLength * 2]byte 134 copy(seed[0:len(clientRandom)], clientRandom) 135 copy(seed[len(clientRandom):], serverRandom) 136 masterSecret := make([]byte, masterSecretLength) 137 prfForVersion(version, suite)(masterSecret, preMasterSecret, masterSecretLabel, seed[0:]) 138 return masterSecret 139} 140 141// extendedMasterFromPreMasterSecret generates the master secret from the 142// pre-master secret when the Triple Handshake fix is in effect. See 143// https://tools.ietf.org/html/rfc7627 144func extendedMasterFromPreMasterSecret(version uint16, suite *cipherSuite, preMasterSecret []byte, h finishedHash) []byte { 145 masterSecret := make([]byte, masterSecretLength) 146 prfForVersion(version, suite)(masterSecret, preMasterSecret, extendedMasterSecretLabel, h.Sum()) 147 return masterSecret 148} 149 150// keysFromMasterSecret generates the connection keys from the master 151// secret, given the lengths of the MAC key, cipher key and IV, as defined in 152// RFC 2246, section 6.3. 153func keysFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clientRandom, serverRandom []byte, macLen, keyLen, ivLen int) (clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV []byte) { 154 var seed [tlsRandomLength * 2]byte 155 copy(seed[0:len(clientRandom)], serverRandom) 156 copy(seed[len(serverRandom):], clientRandom) 157 158 n := 2*macLen + 2*keyLen + 2*ivLen 159 keyMaterial := make([]byte, n) 160 prfForVersion(version, suite)(keyMaterial, masterSecret, keyExpansionLabel, seed[0:]) 161 clientMAC = keyMaterial[:macLen] 162 keyMaterial = keyMaterial[macLen:] 163 serverMAC = keyMaterial[:macLen] 164 keyMaterial = keyMaterial[macLen:] 165 clientKey = keyMaterial[:keyLen] 166 keyMaterial = keyMaterial[keyLen:] 167 serverKey = keyMaterial[:keyLen] 168 keyMaterial = keyMaterial[keyLen:] 169 clientIV = keyMaterial[:ivLen] 170 keyMaterial = keyMaterial[ivLen:] 171 serverIV = keyMaterial[:ivLen] 172 return 173} 174 175func newFinishedHash(wireVersion uint16, isDTLS bool, cipherSuite *cipherSuite) finishedHash { 176 version, ok := wireToVersion(wireVersion, isDTLS) 177 if !ok { 178 panic("unknown version") 179 } 180 181 var ret finishedHash 182 if version >= VersionTLS12 { 183 ret.hash = cipherSuite.hash().New() 184 185 if version == VersionTLS12 { 186 ret.prf = prf12(cipherSuite.hash().New) 187 } else { 188 ret.secret = make([]byte, ret.hash.Size()) 189 } 190 } else { 191 ret.hash = sha1.New() 192 ret.md5 = md5.New() 193 194 ret.prf = prf10 195 } 196 197 ret.suite = cipherSuite 198 ret.buffer = []byte{} 199 ret.version = version 200 ret.wireVersion = wireVersion 201 ret.isDTLS = isDTLS 202 return ret 203} 204 205// A finishedHash calculates the hash of a set of handshake messages suitable 206// for including in a Finished message. 207type finishedHash struct { 208 suite *cipherSuite 209 210 // hash maintains a running hash of handshake messages. In TLS 1.2 and up, 211 // the hash is determined from suite.hash(). In TLS 1.0 and 1.1, this is the 212 // SHA-1 half of the MD5/SHA-1 concatenation. 213 hash hash.Hash 214 215 // md5 is the MD5 half of the TLS 1.0 and 1.1 MD5/SHA1 concatenation. 216 md5 hash.Hash 217 218 // In TLS 1.2, a full buffer is required. 219 buffer []byte 220 221 version uint16 222 wireVersion uint16 223 isDTLS bool 224 prf func(result, secret, label, seed []byte) 225 226 // secret, in TLS 1.3, is the running input secret. 227 secret []byte 228} 229 230func (h *finishedHash) UpdateForHelloRetryRequest() { 231 data := newByteBuilder() 232 data.addU8(typeMessageHash) 233 data.addU24(h.hash.Size()) 234 data.addBytes(h.Sum()) 235 h.hash = h.suite.hash().New() 236 if h.buffer != nil { 237 h.buffer = []byte{} 238 } 239 h.Write(data.finish()) 240} 241 242func (h *finishedHash) Write(msg []byte) (n int, err error) { 243 h.hash.Write(msg) 244 245 if h.version < VersionTLS12 { 246 h.md5.Write(msg) 247 } 248 249 if h.buffer != nil { 250 h.buffer = append(h.buffer, msg...) 251 } 252 253 return len(msg), nil 254} 255 256// WriteHandshake appends |msg| to the hash, which must be a serialized 257// handshake message with a TLS header. In DTLS, the header is rewritten to a 258// DTLS header with |seqno| as the sequence number. 259func (h *finishedHash) WriteHandshake(msg []byte, seqno uint16) { 260 if h.isDTLS { 261 // This is somewhat hacky. DTLS hashes a slightly different format. 262 // First, the TLS header. 263 h.Write(msg[:4]) 264 // Then the sequence number and reassembled fragment offset (always 0). 265 h.Write([]byte{byte(seqno >> 8), byte(seqno), 0, 0, 0}) 266 // Then the reassembled fragment (always equal to the message length). 267 h.Write(msg[1:4]) 268 // And then the message body. 269 h.Write(msg[4:]) 270 } else { 271 h.Write(msg) 272 } 273} 274 275func (h finishedHash) Sum() []byte { 276 if h.version >= VersionTLS12 { 277 return h.hash.Sum(nil) 278 } 279 280 out := make([]byte, 0, md5.Size+sha1.Size) 281 out = h.md5.Sum(out) 282 return h.hash.Sum(out) 283} 284 285// clientSum returns the contents of the verify_data member of a client's 286// Finished message. 287func (h finishedHash) clientSum(baseKey []byte) []byte { 288 if h.version < VersionTLS13 { 289 out := make([]byte, finishedVerifyLength) 290 h.prf(out, baseKey, clientFinishedLabel, h.Sum()) 291 return out 292 } 293 294 clientFinishedKey := hkdfExpandLabel(h.suite.hash(), baseKey, finishedLabel, nil, h.hash.Size()) 295 finishedHMAC := hmac.New(h.suite.hash().New, clientFinishedKey) 296 finishedHMAC.Write(h.appendContextHashes(nil)) 297 return finishedHMAC.Sum(nil) 298} 299 300// serverSum returns the contents of the verify_data member of a server's 301// Finished message. 302func (h finishedHash) serverSum(baseKey []byte) []byte { 303 if h.version < VersionTLS13 { 304 out := make([]byte, finishedVerifyLength) 305 h.prf(out, baseKey, serverFinishedLabel, h.Sum()) 306 return out 307 } 308 309 serverFinishedKey := hkdfExpandLabel(h.suite.hash(), baseKey, finishedLabel, nil, h.hash.Size()) 310 finishedHMAC := hmac.New(h.suite.hash().New, serverFinishedKey) 311 finishedHMAC.Write(h.appendContextHashes(nil)) 312 return finishedHMAC.Sum(nil) 313} 314 315// hashForChannelID returns the hash to be signed for TLS Channel 316// ID. If a resumption, resumeHash has the previous handshake 317// hash. Otherwise, it is nil. 318func (h finishedHash) hashForChannelID(resumeHash []byte) []byte { 319 hash := sha256.New() 320 hash.Write(channelIDLabel) 321 if resumeHash != nil { 322 hash.Write(channelIDResumeLabel) 323 hash.Write(resumeHash) 324 } 325 hash.Write(h.Sum()) 326 return hash.Sum(nil) 327} 328 329// discardHandshakeBuffer is called when there is no more need to 330// buffer the entirety of the handshake messages. 331func (h *finishedHash) discardHandshakeBuffer() { 332 h.buffer = nil 333} 334 335// zeroSecretTLS13 returns the default all zeros secret for TLS 1.3, used when a 336// given secret is not available in the handshake. See RFC 8446, section 7.1. 337func (h *finishedHash) zeroSecret() []byte { 338 return make([]byte, h.hash.Size()) 339} 340 341// addEntropy incorporates ikm into the running TLS 1.3 secret with HKDF-Expand. 342func (h *finishedHash) addEntropy(ikm []byte) { 343 h.secret = hkdf.Extract(h.suite.hash().New, ikm, h.secret) 344} 345 346func (h *finishedHash) nextSecret() { 347 h.secret = hkdfExpandLabel(h.suite.hash(), h.secret, []byte("derived"), h.suite.hash().New().Sum(nil), h.hash.Size()) 348} 349 350// hkdfExpandLabel implements TLS 1.3's HKDF-Expand-Label function, as defined 351// in section 7.1 of RFC 8446. 352func hkdfExpandLabel(hash crypto.Hash, secret, label, hashValue []byte, length int) []byte { 353 if len(label) > 255 || len(hashValue) > 255 { 354 panic("hkdfExpandLabel: label or hashValue too long") 355 } 356 357 versionLabel := []byte("tls13 ") 358 hkdfLabel := make([]byte, 3+len(versionLabel)+len(label)+1+len(hashValue)) 359 x := hkdfLabel 360 x[0] = byte(length >> 8) 361 x[1] = byte(length) 362 x[2] = byte(len(versionLabel) + len(label)) 363 x = x[3:] 364 copy(x, versionLabel) 365 x = x[len(versionLabel):] 366 copy(x, label) 367 x = x[len(label):] 368 x[0] = byte(len(hashValue)) 369 copy(x[1:], hashValue) 370 ret := make([]byte, length) 371 if n, err := hkdf.Expand(hash.New, secret, hkdfLabel).Read(ret); err != nil || n != length { 372 panic("hkdfExpandLabel: hkdf.Expand unexpectedly failed") 373 } 374 return ret 375} 376 377// appendContextHashes returns the concatenation of the handshake hash and the 378// resumption context hash, as used in TLS 1.3. 379func (h *finishedHash) appendContextHashes(b []byte) []byte { 380 b = h.hash.Sum(b) 381 return b 382} 383 384var ( 385 externalPSKBinderLabel = []byte("ext binder") 386 resumptionPSKBinderLabel = []byte("res binder") 387 earlyTrafficLabel = []byte("c e traffic") 388 clientHandshakeTrafficLabel = []byte("c hs traffic") 389 serverHandshakeTrafficLabel = []byte("s hs traffic") 390 clientApplicationTrafficLabel = []byte("c ap traffic") 391 serverApplicationTrafficLabel = []byte("s ap traffic") 392 applicationTrafficLabel = []byte("traffic upd") 393 earlyExporterLabel = []byte("e exp master") 394 exporterLabel = []byte("exp master") 395 resumptionLabel = []byte("res master") 396 397 resumptionPSKLabel = []byte("resumption") 398 399 echAcceptConfirmationLabel = []byte("ech accept confirmation") 400 echAcceptConfirmationHRRLabel = []byte("hrr ech accept confirmation") 401) 402 403// deriveSecret implements TLS 1.3's Derive-Secret function, as defined in 404// section 7.1 of RFC8446. 405func (h *finishedHash) deriveSecret(label []byte) []byte { 406 return hkdfExpandLabel(h.suite.hash(), h.secret, label, h.appendContextHashes(nil), h.hash.Size()) 407} 408 409// echConfirmation computes the ECH accept confirmation signal, as defined in 410// sections 7.2 and 7.2.1 of draft-ietf-tls-esni-13. The transcript hash is 411// computed by concatenating |h| with |extraMessages|. 412func (h *finishedHash) echAcceptConfirmation(clientRandom, label, extraMessages []byte) []byte { 413 secret := hkdf.Extract(h.suite.hash().New, clientRandom, h.zeroSecret()) 414 hashCopy := copyHash(h.hash, h.suite.hash()) 415 hashCopy.Write(extraMessages) 416 return hkdfExpandLabel(h.suite.hash(), secret, label, hashCopy.Sum(nil), echAcceptConfirmationLength) 417} 418 419// The following are context strings for CertificateVerify in TLS 1.3. 420var ( 421 clientCertificateVerifyContextTLS13 = []byte("TLS 1.3, client CertificateVerify") 422 serverCertificateVerifyContextTLS13 = []byte("TLS 1.3, server CertificateVerify") 423 channelIDContextTLS13 = []byte("TLS 1.3, Channel ID") 424) 425 426// certificateVerifyMessage returns the input to be signed for CertificateVerify 427// in TLS 1.3. 428func (h *finishedHash) certificateVerifyInput(context []byte) []byte { 429 const paddingLen = 64 430 b := make([]byte, paddingLen, paddingLen+len(context)+1+2*h.hash.Size()) 431 for i := 0; i < paddingLen; i++ { 432 b[i] = 32 433 } 434 b = append(b, context...) 435 b = append(b, 0) 436 b = h.appendContextHashes(b) 437 return b 438} 439 440type trafficDirection int 441 442const ( 443 clientWrite trafficDirection = iota 444 serverWrite 445) 446 447var ( 448 keyTLS13 = []byte("key") 449 ivTLS13 = []byte("iv") 450) 451 452// deriveTrafficAEAD derives traffic keys and constructs an AEAD given a traffic 453// secret. 454func deriveTrafficAEAD(version uint16, suite *cipherSuite, secret []byte, side trafficDirection) interface{} { 455 key := hkdfExpandLabel(suite.hash(), secret, keyTLS13, nil, suite.keyLen) 456 iv := hkdfExpandLabel(suite.hash(), secret, ivTLS13, nil, suite.ivLen(version)) 457 458 return suite.aead(version, key, iv) 459} 460 461func updateTrafficSecret(hash crypto.Hash, version uint16, secret []byte) []byte { 462 return hkdfExpandLabel(hash, secret, applicationTrafficLabel, nil, hash.Size()) 463} 464 465func computePSKBinder(psk []byte, version uint16, label []byte, cipherSuite *cipherSuite, clientHello, helloRetryRequest, truncatedHello []byte) []byte { 466 finishedHash := newFinishedHash(version, false, cipherSuite) 467 finishedHash.addEntropy(psk) 468 binderKey := finishedHash.deriveSecret(label) 469 finishedHash.Write(clientHello) 470 if len(helloRetryRequest) != 0 { 471 finishedHash.UpdateForHelloRetryRequest() 472 } 473 finishedHash.Write(helloRetryRequest) 474 finishedHash.Write(truncatedHello) 475 return finishedHash.clientSum(binderKey) 476} 477 478func deriveSessionPSK(suite *cipherSuite, version uint16, masterSecret []byte, nonce []byte) []byte { 479 hash := suite.hash() 480 return hkdfExpandLabel(hash, masterSecret, resumptionPSKLabel, nonce, hash.Size()) 481} 482