use "path:/usr/local/opt/libressl/lib" if osx and x86
use "path:/opt/homebrew/opt/libressl/lib" if osx and arm
use "lib:crypto"
use @PKCS5_PBKDF2_HMAC[I32](
pass: Pointer[U8] tag, passlen: I32,
salt: Pointer[U8] tag, saltlen: I32, iter: I32,
digest: Pointer[_EVPMD],
keylen: I32, out: Pointer[U8] tag) if "openssl_1.1.x" or "openssl_3.0.x" or "libressl"
primitive Pbkdf2Sha256
"""
Derive a key from a password using PBKDF2 with HMAC-SHA-256 as the PRF,
as defined in RFC 2898.
Returns a key of the requested length, or raises an error if the derivation
fails (e.g., zero iterations).
Supported on OpenSSL 1.1.x, OpenSSL 3.0.x, and LibreSSL.
```pony
let key = Pbkdf2Sha256("password", "salt", 4096, 32)?
```
"""
fun tag apply(password: ByteSeq, salt: ByteSeq, iterations: U32,
key_length: USize): Array[U8] val ?
=>
ifdef "openssl_1.1.x" or "openssl_3.0.x" or "libressl" then
recover
let arr = Array[U8].init(0, key_length)
let rc = @PKCS5_PBKDF2_HMAC(
password.cpointer(), password.size().i32(),
salt.cpointer(), salt.size().i32(),
iterations.i32(),
@EVP_sha256(),
key_length.i32(),
arr.cpointer())
if rc != 1 then error end
arr
end
else
compile_error "You must select an SSL version to use."
end