github.com/hairyhenderson/gomplate/v4@v4.0.0-pre-2.0.20240520121557-362f058f0c93/crypto/pbkdf2.go (about)

     1  package crypto
     2  
     3  import (
     4  	"crypto"
     5  	"crypto/sha1" //nolint: gosec
     6  	"crypto/sha256"
     7  	"crypto/sha512"
     8  	"fmt"
     9  	"hash"
    10  	"sync"
    11  
    12  	"golang.org/x/crypto/pbkdf2"
    13  )
    14  
    15  var hashFuncs = sync.OnceValue[map[crypto.Hash]func() hash.Hash](func() map[crypto.Hash]func() hash.Hash {
    16  	h := make(map[crypto.Hash]func() hash.Hash)
    17  	h[crypto.SHA1] = sha1.New
    18  	h[crypto.SHA224] = sha256.New224
    19  	h[crypto.SHA256] = sha256.New
    20  	h[crypto.SHA384] = sha512.New384
    21  	h[crypto.SHA512] = sha512.New
    22  	h[crypto.SHA512_224] = sha512.New512_224
    23  	h[crypto.SHA512_256] = sha512.New512_256
    24  
    25  	return h
    26  })()
    27  
    28  // StrToHash - find a hash given a certain string
    29  func StrToHash(hash string) (crypto.Hash, error) {
    30  	switch hash {
    31  	case "SHA1", "SHA-1":
    32  		return crypto.SHA1, nil
    33  	case "SHA224", "SHA-224":
    34  		return crypto.SHA224, nil
    35  	case "SHA256", "SHA-256":
    36  		return crypto.SHA256, nil
    37  	case "SHA384", "SHA-384":
    38  		return crypto.SHA384, nil
    39  	case "SHA512", "SHA-512":
    40  		return crypto.SHA512, nil
    41  	case "SHA512_224", "SHA512/224", "SHA-512_224", "SHA-512/224":
    42  		return crypto.SHA512_224, nil
    43  	case "SHA512_256", "SHA512/256", "SHA-512_256", "SHA-512/256":
    44  		return crypto.SHA512_256, nil
    45  	}
    46  	return 0, fmt.Errorf("no such hash %s", hash)
    47  }
    48  
    49  // PBKDF2 - Run the Password-Based Key Derivation Function #2 as defined in
    50  // RFC 8018 (PKCS #5 v2.1)
    51  func PBKDF2(password, salt []byte, iter, keylen int, hashFunc crypto.Hash) ([]byte, error) {
    52  	h, ok := hashFuncs[hashFunc]
    53  	if !ok {
    54  		return nil, fmt.Errorf("hashFunc not supported: %v", hashFunc)
    55  	}
    56  	return pbkdf2.Key(password, salt, iter, keylen, h), nil
    57  }