github.com/JimmyHuang454/JLS-go@v0.0.0-20230831150107-90d536585ba0/tls/prf.go (about) 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 5 package tls 6 7 import ( 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. 20 func 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. 27 func 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. 48 func 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. 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) 72 73 pHash(result, secret, labelAndSeed, hashFunc) 74 } 75 } 76 77 const ( 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 82 var masterSecretLabel = []byte("master secret") 83 var extendedMasterSecretLabel = []byte("extended master secret") 84 var keyExpansionLabel = []byte("key expansion") 85 var clientFinishedLabel = []byte("client finished") 86 var serverFinishedLabel = []byte("server finished") 87 88 func 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 102 func 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. 109 func 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. 121 func 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. 130 func 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 152 func 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. 168 type 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 183 func (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 199 func (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. 211 func (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. 219 func (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. 227 func (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. 251 func (h *finishedHash) discardHandshakeBuffer() { 252 h.buffer = nil 253 } 254 255 // noExportedKeyingMaterial 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. 258 func noExportedKeyingMaterial(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 // ekmFromMasterSecret generates exported keying material as defined in RFC 5705. 263 func ekmFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clientRandom, serverRandom []byte) func(string, []byte, int) ([]byte, error) { 264 return func(label string, context []byte, length int) ([]byte, error) { 265 switch label { 266 case "client finished", "server finished", "master secret", "key expansion": 267 // These values are reserved and may not be used. 268 return nil, fmt.Errorf("crypto/tls: reserved ExportKeyingMaterial label: %s", label) 269 } 270 271 seedLen := len(serverRandom) + len(clientRandom) 272 if context != nil { 273 seedLen += 2 + len(context) 274 } 275 seed := make([]byte, 0, seedLen) 276 277 seed = append(seed, clientRandom...) 278 seed = append(seed, serverRandom...) 279 280 if context != nil { 281 if len(context) >= 1<<16 { 282 return nil, fmt.Errorf("crypto/tls: ExportKeyingMaterial context too long") 283 } 284 seed = append(seed, byte(len(context)>>8), byte(len(context))) 285 seed = append(seed, context...) 286 } 287 288 keyMaterial := make([]byte, length) 289 prfForVersion(version, suite)(keyMaterial, masterSecret, []byte(label), seed) 290 return keyMaterial, nil 291 } 292 }