// Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package sdf import ( "crypto/hmac" "hash" "xdx.jelly/xgcl/sm/sm3" ) // Split a premaster secret in two as specified in RFC 4346, Section 5. func splitPreMasterSecret(secret []byte) (s1, s2 []byte) { s1 = secret[0 : (len(secret)+1)/2] s2 = secret[len(secret)/2:] return } // pHash implements the P_hash function, as defined in RFC 4346, Section 5. func pHash(result, secret, seed []byte, hash func() hash.Hash) { h := hmac.New(hash, secret) h.Write(seed) a := h.Sum(nil) j := 0 for j < len(result) { h.Reset() h.Write(a) h.Write(seed) b := h.Sum(nil) copy(result[j:], b) j += len(b) h.Reset() h.Write(a) a = h.Sum(nil) } } func prfTLCP(result, secret, label, seed []byte) { labelAndSeed := make([]byte, len(label)+len(seed)) copy(labelAndSeed, label) copy(labelAndSeed[len(label):], seed) pHash(result, secret, labelAndSeed, sm3.New) } const ( masterSecretLength = 48 // Length of a master secret in TLS 1.1. finishedVerifyLength = 12 // Length of verify_data in a Finished message. ) var masterSecretLabel = []byte("master secret") var keyExpansionLabel = []byte("key expansion") // masterFromPreMasterSecret generates the master secret from the pre-master // secret. See RFC 5246, Section 8.1. func masterFromPreMasterSecretTLCP(preMasterSecret, clientRandom, serverRandom []byte) []byte { seed := make([]byte, 0, len(clientRandom)+len(serverRandom)) seed = append(seed, clientRandom...) seed = append(seed, serverRandom...) masterSecret := make([]byte, masterSecretLength) prfTLCP(masterSecret, preMasterSecret, masterSecretLabel, seed) return masterSecret } // keysFromMasterSecret generates the connection keys from the master // secret, given the lengths of the MAC key, cipher key and IV, as defined in // RFC 2246, Section 6.3. func keysFromMasterSecretTLCP(masterSecret, clientRandom, serverRandom []byte, macLen, keyLen, ivLen int) (clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV []byte) { seed := make([]byte, 0, len(serverRandom)+len(clientRandom)) seed = append(seed, serverRandom...) seed = append(seed, clientRandom...) n := 2*macLen + 2*keyLen + 2*ivLen keyMaterial := make([]byte, n) prfTLCP(keyMaterial, masterSecret, keyExpansionLabel, seed) clientMAC = keyMaterial[:macLen] keyMaterial = keyMaterial[macLen:] serverMAC = keyMaterial[:macLen] keyMaterial = keyMaterial[macLen:] clientKey = keyMaterial[:keyLen] keyMaterial = keyMaterial[keyLen:] serverKey = keyMaterial[:keyLen] keyMaterial = keyMaterial[keyLen:] clientIV = keyMaterial[:ivLen] keyMaterial = keyMaterial[ivLen:] serverIV = keyMaterial[:ivLen] return } func KeysFromPreMasterSecretTLCP(preMasterSecret, clientRandom, serverRandom []byte, macLen, keyLen, ivLen int) (clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV []byte) { masterSecret := masterFromPreMasterSecretTLCP(preMasterSecret, clientRandom, serverRandom) return keysFromMasterSecretTLCP(masterSecret, clientRandom, serverRandom, macLen, keyLen, ivLen) }