github.com/Psiphon-Labs/tls-tris@v0.0.0-20230824155421-58bf6d336a9a/hkdf.go (about)

     1  // Copyright 2014 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  // Mostly derived from golang.org/x/crypto/hkdf, but with an exposed
     8  // Extract API.
     9  //
    10  // HKDF is a cryptographic key derivation function (KDF) with the goal of
    11  // expanding limited input keying material into one or more cryptographically
    12  // strong secret keys.
    13  //
    14  // RFC 5869: https://tools.ietf.org/html/rfc5869
    15  
    16  import (
    17  	"crypto"
    18  	"crypto/hmac"
    19  )
    20  
    21  func hkdfExpand(hash crypto.Hash, prk, info []byte, l int) []byte {
    22  	var (
    23  		expander = hmac.New(hash.New, prk)
    24  		res      = make([]byte, l)
    25  		counter  = byte(1)
    26  		prev     []byte
    27  	)
    28  
    29  	if l > 255*expander.Size() {
    30  		panic("hkdf: requested too much output")
    31  	}
    32  
    33  	p := res
    34  	for len(p) > 0 {
    35  		expander.Reset()
    36  		expander.Write(prev)
    37  		expander.Write(info)
    38  		expander.Write([]byte{counter})
    39  		prev = expander.Sum(prev[:0])
    40  		counter++
    41  		n := copy(p, prev)
    42  		p = p[n:]
    43  	}
    44  
    45  	return res
    46  }
    47  
    48  func hkdfExtract(hash crypto.Hash, secret, salt []byte) []byte {
    49  	if salt == nil {
    50  		salt = make([]byte, hash.Size())
    51  	}
    52  	if secret == nil {
    53  		secret = make([]byte, hash.Size())
    54  	}
    55  	extractor := hmac.New(hash.New, salt)
    56  	extractor.Write(secret)
    57  	return extractor.Sum(nil)
    58  }