Prad Nukala 47c3a53080
refactor/internal (#1216)
* refactor: update import paths in gateway handlers

* refactor: remove obsolete devtools Makefile and README

* build: optimize build process for improved efficiency

* refactor: remove obsolete pkl files related to Matrix and Sonr network configurations

* refactor: move embed code to x/dwn/types
2024-12-24 16:10:20 +00:00

56 lines
1.3 KiB
Go

package subtle
import (
"errors"
"fmt"
"io"
"golang.org/x/crypto/hkdf"
)
const (
// Minimum tag size in bytes. This provides minimum 80-bit security strength.
minTagSizeInBytes = uint32(10)
)
var errHKDFInvalidInput = errors.New("HKDF: invalid input")
// validateHKDFParams validates parameters of HKDF constructor.
func validateHKDFParams(hash string, _ uint32, tagSize uint32) error {
// validate tag size
digestSize, err := GetHashDigestSize(hash)
if err != nil {
return err
}
if tagSize > 255*digestSize {
return fmt.Errorf("tag size too big")
}
if tagSize < minTagSizeInBytes {
return fmt.Errorf("tag size too small")
}
return nil
}
// ComputeHKDF extracts a pseudorandom key.
func ComputeHKDF(hashAlg string, key []byte, salt []byte, info []byte, tagSize uint32) ([]byte, error) {
keySize := uint32(len(key))
if err := validateHKDFParams(hashAlg, keySize, tagSize); err != nil {
return nil, fmt.Errorf("hkdf: %s", err)
}
hashFunc := GetHashFunc(hashAlg)
if hashFunc == nil {
return nil, fmt.Errorf("hkdf: invalid hash algorithm")
}
if len(salt) == 0 {
salt = make([]byte, hashFunc().Size())
}
result := make([]byte, tagSize)
kdf := hkdf.New(hashFunc, key, salt, info)
n, err := io.ReadFull(kdf, result)
if n != len(result) || err != nil {
return nil, fmt.Errorf("compute of hkdf failed")
}
return result, nil
}