hkdf.go 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. package crypto
  2. import (
  3. "crypto"
  4. "crypto/hmac"
  5. "encoding/binary"
  6. )
  7. // copied from https://v2ray.com/core/external/github.com/cloudflare/tls-tris/blob/master/hkdf.go
  8. func hkdfExtract(hash crypto.Hash, secret, salt []byte) []byte {
  9. if salt == nil {
  10. salt = make([]byte, hash.Size())
  11. }
  12. if secret == nil {
  13. secret = make([]byte, hash.Size())
  14. }
  15. extractor := hmac.New(hash.New, salt)
  16. extractor.Write(secret)
  17. return extractor.Sum(nil)
  18. }
  19. // copied from https://v2ray.com/core/external/github.com/cloudflare/tls-tris/blob/master/hkdf.go
  20. func hkdfExpand(hash crypto.Hash, prk, info []byte, l int) []byte {
  21. var (
  22. expander = hmac.New(hash.New, prk)
  23. res = make([]byte, l)
  24. counter = byte(1)
  25. prev []byte
  26. )
  27. if l > 255*expander.Size() {
  28. panic("hkdf: requested too much output")
  29. }
  30. p := res
  31. for len(p) > 0 {
  32. expander.Reset()
  33. expander.Write(prev)
  34. expander.Write(info)
  35. expander.Write([]byte{counter})
  36. prev = expander.Sum(prev[:0])
  37. counter++
  38. n := copy(p, prev)
  39. p = p[n:]
  40. }
  41. return res
  42. }
  43. // hkdfExpandLabel HKDF expands a label
  44. func HkdfExpandLabel(hash crypto.Hash, secret []byte, label string, length int) []byte {
  45. const prefix = "quic "
  46. qlabel := make([]byte, 2 /* length */ +1 /* length of label */ +len(prefix)+len(label)+1 /* length of context (empty) */)
  47. binary.BigEndian.PutUint16(qlabel[0:2], uint16(length))
  48. qlabel[2] = uint8(len(prefix) + len(label))
  49. copy(qlabel[3:], []byte(prefix+label))
  50. return hkdfExpand(hash, secret, qlabel, length)
  51. }