Skip to content

Commit 6a75451

Browse files
authored
Implement SupportsPBKDF2 (#207)
* implement SupportsPBKDF2 * add docs
1 parent d3e5c22 commit 6a75451

File tree

2 files changed

+41
-5
lines changed

2 files changed

+41
-5
lines changed

Diff for: pbkdf2.go

+30
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,38 @@ import "C"
77
import (
88
"errors"
99
"hash"
10+
"sync"
11+
"unsafe"
1012
)
1113

14+
// SupportsPBKDF2 reports whether the current OpenSSL version supports PBKDF2.
15+
func SupportsPBKDF2() bool {
16+
switch vMajor {
17+
case 1:
18+
return true
19+
case 3:
20+
_, err := fetchPBKDF2()
21+
return err == nil
22+
default:
23+
panic(errUnsupportedVersion())
24+
}
25+
}
26+
27+
// fetchPBKDF2 fetches the PBKDF2 algorithm.
28+
// It is safe to call this function concurrently.
29+
// The returned EVP_KDF_PTR shouldn't be freed.
30+
var fetchPBKDF2 = sync.OnceValues(func() (C.GO_EVP_KDF_PTR, error) {
31+
checkMajorVersion(3)
32+
33+
name := C.CString("PBKDF2")
34+
kdf := C.go_openssl_EVP_KDF_fetch(nil, name, nil)
35+
C.free(unsafe.Pointer(name))
36+
if kdf == nil {
37+
return nil, newOpenSSLError("EVP_KDF_fetch")
38+
}
39+
return kdf, nil
40+
})
41+
1242
func PBKDF2(password, salt []byte, iter, keyLen int, fh func() hash.Hash) ([]byte, error) {
1343
h, err := hashFuncHash(fh)
1444
if err != nil {

Diff for: pbkdf2_test.go

+11-5
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,9 @@ var sha256TestVectors = []testVector{
138138
}
139139

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

153-
func TestWithHMACSHA1(t *testing.T) {
156+
func TestPBKDF2WithHMACSHA1(t *testing.T) {
154157
testHash(t, openssl.NewSHA1, "SHA1", sha1TestVectors)
155158
}
156159

157-
func TestWithHMACSHA256(t *testing.T) {
160+
func TestPBKDF2WithHMACSHA256(t *testing.T) {
158161
testHash(t, openssl.NewSHA256, "SHA256", sha256TestVectors)
159162
}
160163

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

182-
func BenchmarkHMACSHA1(b *testing.B) {
188+
func BenchmarkPBKDF2HMACSHA1(b *testing.B) {
183189
benchmark(b, sha1.New)
184190
}
185191

186-
func BenchmarkHMACSHA256(b *testing.B) {
192+
func BenchmarkPBKDF2HMACSHA256(b *testing.B) {
187193
benchmark(b, sha256.New)
188194
}

0 commit comments

Comments
 (0)