Skip to content

Commit

Permalink
implement SupportsPBKDF2
Browse files Browse the repository at this point in the history
  • Loading branch information
qmuntal committed Oct 21, 2024
1 parent d3e5c22 commit 40f7816
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 5 deletions.
29 changes: 29 additions & 0 deletions pbkdf2.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,37 @@ import "C"
import (
"errors"
"hash"
"sync"
"unsafe"
)

func SupportsPBKDF2() bool {
switch vMajor {
case 1:
return true
case 3:
_, err := fetchPBKDF2()
return err == nil
default:
panic(errUnsupportedVersion())
}
}

// fetchPBKDF2 fetches the PBKDF2 algorithm.
// It is safe to call this function concurrently.
// The returned EVP_KDF_PTR shouldn't be freed.
var fetchPBKDF2 = sync.OnceValues(func() (C.GO_EVP_KDF_PTR, error) {
checkMajorVersion(3)

name := C.CString("PBKDF2")
kdf := C.go_openssl_EVP_KDF_fetch(nil, name, nil)
C.free(unsafe.Pointer(name))
if kdf == nil {
return nil, newOpenSSLError("EVP_KDF_fetch")
}
return kdf, nil
})

func PBKDF2(password, salt []byte, iter, keyLen int, fh func() hash.Hash) ([]byte, error) {
h, err := hashFuncHash(fh)
if err != nil {
Expand Down
16 changes: 11 additions & 5 deletions pbkdf2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,9 @@ var sha256TestVectors = []testVector{
}

func testHash(t *testing.T, h func() hash.Hash, hashName string, vectors []testVector) {
if !openssl.SupportsPBKDF2() {
t.Skip("PBKDF2 is not supported")
}
for i, v := range vectors {
o, err := openssl.PBKDF2([]byte(v.password), []byte(v.salt), v.iter, len(v.output), h)
if err != nil {
Expand All @@ -150,15 +153,18 @@ func testHash(t *testing.T, h func() hash.Hash, hashName string, vectors []testV
}
}

func TestWithHMACSHA1(t *testing.T) {
func TestPBKDF2WithHMACSHA1(t *testing.T) {
testHash(t, openssl.NewSHA1, "SHA1", sha1TestVectors)
}

func TestWithHMACSHA256(t *testing.T) {
func TestPBKDF2WithHMACSHA256(t *testing.T) {
testHash(t, openssl.NewSHA256, "SHA256", sha256TestVectors)
}

func TestWithUnsupportedHash(t *testing.T) {
func TestPBKDF2WithUnsupportedHash(t *testing.T) {
if !openssl.SupportsPBKDF2() {
t.Skip("PBKDF2 is not supported")
}
// Test that PBKDF2 returns an error for unsupported hashes instead of panicking.
_, err := openssl.PBKDF2([]byte{1, 2}, []byte{3, 4}, 0, 2, newStubHash)
if err == nil {
Expand All @@ -179,10 +185,10 @@ func benchmark(b *testing.B, h func() hash.Hash) {
sink += password[0]
}

func BenchmarkHMACSHA1(b *testing.B) {
func BenchmarkPBKDF2HMACSHA1(b *testing.B) {
benchmark(b, sha1.New)
}

func BenchmarkHMACSHA256(b *testing.B) {
func BenchmarkPBKDF2HMACSHA256(b *testing.B) {
benchmark(b, sha256.New)
}

0 comments on commit 40f7816

Please sign in to comment.