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