prf.go 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
  2. // SPDX-License-Identifier: MIT
  3. // Package prf implements TLS 1.2 Pseudorandom functions
  4. package prf
  5. import ( //nolint:gci
  6. ellipticStdlib "crypto/elliptic"
  7. "crypto/hmac"
  8. "encoding/binary"
  9. "errors"
  10. "fmt"
  11. "hash"
  12. "math"
  13. "github.com/pion/dtls/v2/pkg/crypto/elliptic"
  14. "github.com/pion/dtls/v2/pkg/protocol"
  15. "golang.org/x/crypto/curve25519"
  16. )
  17. const (
  18. masterSecretLabel = "master secret"
  19. extendedMasterSecretLabel = "extended master secret"
  20. keyExpansionLabel = "key expansion"
  21. verifyDataClientLabel = "client finished"
  22. verifyDataServerLabel = "server finished"
  23. )
  24. // HashFunc allows callers to decide what hash is used in PRF
  25. type HashFunc func() hash.Hash
  26. // EncryptionKeys is all the state needed for a TLS CipherSuite
  27. type EncryptionKeys struct {
  28. MasterSecret []byte
  29. ClientMACKey []byte
  30. ServerMACKey []byte
  31. ClientWriteKey []byte
  32. ServerWriteKey []byte
  33. ClientWriteIV []byte
  34. ServerWriteIV []byte
  35. }
  36. var errInvalidNamedCurve = &protocol.FatalError{Err: errors.New("invalid named curve")} //nolint:goerr113
  37. func (e *EncryptionKeys) String() string {
  38. return fmt.Sprintf(`encryptionKeys:
  39. - masterSecret: %#v
  40. - clientMACKey: %#v
  41. - serverMACKey: %#v
  42. - clientWriteKey: %#v
  43. - serverWriteKey: %#v
  44. - clientWriteIV: %#v
  45. - serverWriteIV: %#v
  46. `,
  47. e.MasterSecret,
  48. e.ClientMACKey,
  49. e.ServerMACKey,
  50. e.ClientWriteKey,
  51. e.ServerWriteKey,
  52. e.ClientWriteIV,
  53. e.ServerWriteIV)
  54. }
  55. // PSKPreMasterSecret generates the PSK Premaster Secret
  56. // The premaster secret is formed as follows: if the PSK is N octets
  57. // long, concatenate a uint16 with the value N, N zero octets, a second
  58. // uint16 with the value N, and the PSK itself.
  59. //
  60. // https://tools.ietf.org/html/rfc4279#section-2
  61. func PSKPreMasterSecret(psk []byte) []byte {
  62. pskLen := uint16(len(psk))
  63. out := append(make([]byte, 2+pskLen+2), psk...)
  64. binary.BigEndian.PutUint16(out, pskLen)
  65. binary.BigEndian.PutUint16(out[2+pskLen:], pskLen)
  66. return out
  67. }
  68. // EcdhePSKPreMasterSecret implements TLS 1.2 Premaster Secret generation given a psk, a keypair and a curve
  69. //
  70. // https://datatracker.ietf.org/doc/html/rfc5489#section-2
  71. func EcdhePSKPreMasterSecret(psk, publicKey, privateKey []byte, curve elliptic.Curve) ([]byte, error) {
  72. preMasterSecret, err := PreMasterSecret(publicKey, privateKey, curve)
  73. if err != nil {
  74. return nil, err
  75. }
  76. out := make([]byte, 2+len(preMasterSecret)+2+len(psk))
  77. // write preMasterSecret length
  78. offset := 0
  79. binary.BigEndian.PutUint16(out[offset:], uint16(len(preMasterSecret)))
  80. offset += 2
  81. // write preMasterSecret
  82. copy(out[offset:], preMasterSecret)
  83. offset += len(preMasterSecret)
  84. // write psk length
  85. binary.BigEndian.PutUint16(out[offset:], uint16(len(psk)))
  86. offset += 2
  87. // write psk
  88. copy(out[offset:], psk)
  89. return out, nil
  90. }
  91. // PreMasterSecret implements TLS 1.2 Premaster Secret generation given a keypair and a curve
  92. func PreMasterSecret(publicKey, privateKey []byte, curve elliptic.Curve) ([]byte, error) {
  93. switch curve {
  94. case elliptic.X25519:
  95. return curve25519.X25519(privateKey, publicKey)
  96. case elliptic.P256:
  97. return ellipticCurvePreMasterSecret(publicKey, privateKey, ellipticStdlib.P256(), ellipticStdlib.P256())
  98. case elliptic.P384:
  99. return ellipticCurvePreMasterSecret(publicKey, privateKey, ellipticStdlib.P384(), ellipticStdlib.P384())
  100. default:
  101. return nil, errInvalidNamedCurve
  102. }
  103. }
  104. func ellipticCurvePreMasterSecret(publicKey, privateKey []byte, c1, c2 ellipticStdlib.Curve) ([]byte, error) {
  105. x, y := ellipticStdlib.Unmarshal(c1, publicKey)
  106. if x == nil || y == nil {
  107. return nil, errInvalidNamedCurve
  108. }
  109. result, _ := c2.ScalarMult(x, y, privateKey)
  110. preMasterSecret := make([]byte, (c2.Params().BitSize+7)>>3)
  111. resultBytes := result.Bytes()
  112. copy(preMasterSecret[len(preMasterSecret)-len(resultBytes):], resultBytes)
  113. return preMasterSecret, nil
  114. }
  115. // PHash is PRF is the SHA-256 hash function is used for all cipher suites
  116. // defined in this TLS 1.2 document and in TLS documents published prior to this
  117. // document when TLS 1.2 is negotiated. New cipher suites MUST explicitly
  118. // specify a PRF and, in general, SHOULD use the TLS PRF with SHA-256 or a
  119. // stronger standard hash function.
  120. //
  121. // P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
  122. // HMAC_hash(secret, A(2) + seed) +
  123. // HMAC_hash(secret, A(3) + seed) + ...
  124. //
  125. // A() is defined as:
  126. //
  127. // A(0) = seed
  128. // A(i) = HMAC_hash(secret, A(i-1))
  129. //
  130. // P_hash can be iterated as many times as necessary to produce the
  131. // required quantity of data. For example, if P_SHA256 is being used to
  132. // create 80 bytes of data, it will have to be iterated three times
  133. // (through A(3)), creating 96 bytes of output data; the last 16 bytes
  134. // of the final iteration will then be discarded, leaving 80 bytes of
  135. // output data.
  136. //
  137. // https://tools.ietf.org/html/rfc4346w
  138. func PHash(secret, seed []byte, requestedLength int, h HashFunc) ([]byte, error) {
  139. hmacSHA256 := func(key, data []byte) ([]byte, error) {
  140. mac := hmac.New(h, key)
  141. if _, err := mac.Write(data); err != nil {
  142. return nil, err
  143. }
  144. return mac.Sum(nil), nil
  145. }
  146. var err error
  147. lastRound := seed
  148. out := []byte{}
  149. iterations := int(math.Ceil(float64(requestedLength) / float64(h().Size())))
  150. for i := 0; i < iterations; i++ {
  151. lastRound, err = hmacSHA256(secret, lastRound)
  152. if err != nil {
  153. return nil, err
  154. }
  155. withSecret, err := hmacSHA256(secret, append(lastRound, seed...))
  156. if err != nil {
  157. return nil, err
  158. }
  159. out = append(out, withSecret...)
  160. }
  161. return out[:requestedLength], nil
  162. }
  163. // ExtendedMasterSecret generates a Extended MasterSecret as defined in
  164. // https://tools.ietf.org/html/rfc7627
  165. func ExtendedMasterSecret(preMasterSecret, sessionHash []byte, h HashFunc) ([]byte, error) {
  166. seed := append([]byte(extendedMasterSecretLabel), sessionHash...)
  167. return PHash(preMasterSecret, seed, 48, h)
  168. }
  169. // MasterSecret generates a TLS 1.2 MasterSecret
  170. func MasterSecret(preMasterSecret, clientRandom, serverRandom []byte, h HashFunc) ([]byte, error) {
  171. seed := append(append([]byte(masterSecretLabel), clientRandom...), serverRandom...)
  172. return PHash(preMasterSecret, seed, 48, h)
  173. }
  174. // GenerateEncryptionKeys is the final step TLS 1.2 PRF. Given all state generated so far generates
  175. // the final keys need for encryption
  176. func GenerateEncryptionKeys(masterSecret, clientRandom, serverRandom []byte, macLen, keyLen, ivLen int, h HashFunc) (*EncryptionKeys, error) {
  177. seed := append(append([]byte(keyExpansionLabel), serverRandom...), clientRandom...)
  178. keyMaterial, err := PHash(masterSecret, seed, (2*macLen)+(2*keyLen)+(2*ivLen), h)
  179. if err != nil {
  180. return nil, err
  181. }
  182. clientMACKey := keyMaterial[:macLen]
  183. keyMaterial = keyMaterial[macLen:]
  184. serverMACKey := keyMaterial[:macLen]
  185. keyMaterial = keyMaterial[macLen:]
  186. clientWriteKey := keyMaterial[:keyLen]
  187. keyMaterial = keyMaterial[keyLen:]
  188. serverWriteKey := keyMaterial[:keyLen]
  189. keyMaterial = keyMaterial[keyLen:]
  190. clientWriteIV := keyMaterial[:ivLen]
  191. keyMaterial = keyMaterial[ivLen:]
  192. serverWriteIV := keyMaterial[:ivLen]
  193. return &EncryptionKeys{
  194. MasterSecret: masterSecret,
  195. ClientMACKey: clientMACKey,
  196. ServerMACKey: serverMACKey,
  197. ClientWriteKey: clientWriteKey,
  198. ServerWriteKey: serverWriteKey,
  199. ClientWriteIV: clientWriteIV,
  200. ServerWriteIV: serverWriteIV,
  201. }, nil
  202. }
  203. func prfVerifyData(masterSecret, handshakeBodies []byte, label string, hashFunc HashFunc) ([]byte, error) {
  204. h := hashFunc()
  205. if _, err := h.Write(handshakeBodies); err != nil {
  206. return nil, err
  207. }
  208. seed := append([]byte(label), h.Sum(nil)...)
  209. return PHash(masterSecret, seed, 12, hashFunc)
  210. }
  211. // VerifyDataClient is caled on the Client Side to either verify or generate the VerifyData message
  212. func VerifyDataClient(masterSecret, handshakeBodies []byte, h HashFunc) ([]byte, error) {
  213. return prfVerifyData(masterSecret, handshakeBodies, verifyDataClientLabel, h)
  214. }
  215. // VerifyDataServer is caled on the Server Side to either verify or generate the VerifyData message
  216. func VerifyDataServer(masterSecret, handshakeBodies []byte, h HashFunc) ([]byte, error) {
  217. return prfVerifyData(masterSecret, handshakeBodies, verifyDataServerLabel, h)
  218. }