botan-bindings-0.2.0.0: src/Botan/Bindings/PwdHash.hs
{-|
Module : Botan.Bindings.PwdHash
Description : Password hashing
Copyright : (c) 2023-2024, Apotheca Labs
(c) 2024-2025, Haskell Foundation
License : BSD-3-Clause
Maintainer : joris@well-typed.com, leo@apotheca.io
Stability : experimental
Portability : POSIX
This module is based on the [Password Based Key
Deriviation](https://botan.randombit.net/handbook/api_ref/pbkdf.html) section of
the C++ API reference.
-}
{-# LANGUAGE CApiFFI #-}
{-# LANGUAGE OverloadedStrings #-}
module Botan.Bindings.PwdHash (
botan_pwdhash
, botan_pwdhash_timed
-- * Available schemes
-- $available-schemes
, pattern BOTAN_PBKDF_PBKDF2
, pattern BOTAN_PBKDF_SCRYPT
, pattern BOTAN_PBKDF_ARGON2D
, pattern BOTAN_PBKDF_ARGON2I
, pattern BOTAN_PBKDF_ARGON2ID
, pattern BOTAN_PBKDF_BCRYPT_PBKDF
, pattern BOTAN_PBKDF_OPENPGP_S2K
) where
import Botan.Bindings.ConstPtr
import Data.String
import Data.Word
import Foreign.C.Types
import Foreign.Ptr
{-------------------------------------------------------------------------------
Password hashing
-------------------------------------------------------------------------------}
-- | Derive a cryptographic key from a passphrase using algorithm-specific parameters
--
-- NOTE: the interpretation of parameters @param1@, @param2@, and @param3@ are
-- different depending on the PBKDF algorithm that is picked. See the
-- documentation of the
-- [@from_params@](https://botan.randombit.net/handbook/api_ref/pbkdf.html#passwordhash)
-- C++ function for more information about the meaning of the parameters.
--
foreign import capi safe "botan/ffi.h botan_pwdhash"
botan_pwdhash
:: ConstPtr CChar -- ^ __algo__: PBKDF algorithm, e.g., "PBKDF2(SHA-256)" or "Scrypt"
-> CSize -- ^ __param1__: the first PBKDF algorithm parameter
-> CSize -- ^ __param2__: the second PBKDF algorithm parameter (may be zero if unneeded)
-> CSize -- ^ __param3__: the third PBKDF algorithm parameter (may be zero if unneeded)
-> Ptr Word8 -- ^ __out[]__: buffer to store the derived key, must be of out_len bytes
-> CSize -- ^ __out_len__: the desired length of the key to produce
-> ConstPtr CChar -- ^ __passphrase__: the password to derive the key from
-> CSize -- ^ __passphrase_len__: if > 0, specifies length of password. If len == 0, then
-- strlen will be called on passphrase to compute the length.
-> ConstPtr Word8 -- ^ __salt[]__: a randomly chosen salt
-> CSize -- ^ __salt_len__: length of salt in bytes
-> IO CInt -- ^ 0 on success, a negative value on failure
-- | Derive a cryptographic key from a passphrase using algorithm-specific
-- parameters that are tuned automatically for a desired running time of the
-- algorithm.
--
-- NOTE: for the @Argon2@ and @Scrypt@ PBKDF algorithms, 'botan_pwdhash_timed'
-- returns parameters in a different order than the order in which they should
-- be passed to 'botan_pwdhash'. This is a known issue with the Botan C++
-- library. See <https://github.com/randombit/botan/issues/2144> for more
-- information.
--
-- 'botan_pwdhash_timed' always returns parameters in this order:
--
-- > (iterations, parallelism, memoryParam)
--
-- 'botan_pwdhash' shoulds be given parameters in this order for the
-- @Argon2@ and @Scrypt@ algorithms:
--
-- > param1 = memoryParam
-- > param2 = iterations
-- > param3 = parallelism
--
foreign import capi safe "botan/ffi.h botan_pwdhash_timed"
botan_pwdhash_timed
:: ConstPtr CChar -- ^ __algo__: PBKDF algorithm, e.g., "Scrypt" or "PBKDF2(SHA-256)"
-> Word32 -- ^ __msec__: the desired runtime in milliseconds
-> Ptr CSize -- ^ __param1__: will be set to the first PBKDF algorithm parameter
-> Ptr CSize -- ^ __param2__: will be set to the second PBKDF algorithm parameter (may be zero if unneeded)
-> Ptr CSize -- ^ __param3__: will be set to the third PBKDF algorithm parameter (may be zero if unneeded)
-> Ptr Word8 -- ^ __out[]__: buffer to store the derived key, must be of out_len bytes
-> CSize -- ^ __out_len__: the desired length of the key to produce
-> ConstPtr CChar -- ^ __passphrase__: the password to derive the key from
-> CSize -- ^ __passphrase_len__: if > 0, specifies length of password. If len == 0, then
-- strlen will be called on passphrase to compute the length.
-> ConstPtr Word8 -- ^ __salt[]__: a randomly chosen salt
-> CSize -- ^ __salt_len__: length of salt in bytes
-> IO CInt -- ^ 0 on success, a negative value on failure
{-------------------------------------------------------------------------------
Available schemes
-------------------------------------------------------------------------------}
{- $available-schemes
A number of algorithms are available to be used as password derivation schemes.
An algorithm is selected by passing the /algorithm specification name/ of the
algorithm as a string to the password hashing functions. In some cases an
algorithm specification name is just the /algorithm name/, like @"Scrypt"@. In
other cases an algorithm specification name is a combination of an algorithm
name paired with some parameters, such as @"PKBDF2(SHA-256)"@ where @"PBKDF2"@
is the algorithm name followed by a single parameter. Pattern synonyms are
included for each available /algorithm name/. Where necessary, such as in the
@"PBKDF2"@ case, these algorithm names should be manually extended to full
algorithm specification names.
See the [Available
Schemes](https://botan.randombit.net/handbook/api_ref/pbkdf.html#available-schemes)
section of the C++ API reference for more information about available schemes.
-}
pattern BOTAN_PBKDF_PBKDF2
, BOTAN_PBKDF_SCRYPT
, BOTAN_PBKDF_ARGON2D
, BOTAN_PBKDF_ARGON2I
, BOTAN_PBKDF_ARGON2ID
, BOTAN_PBKDF_BCRYPT_PBKDF
, BOTAN_PBKDF_OPENPGP_S2K
:: (Eq a, IsString a) => a
-- |
-- >>> BOTAN_PBKDF_PBKDF2 @String
-- "PBKDF2"
pattern BOTAN_PBKDF_PBKDF2 = "PBKDF2"
-- |
-- >>> BOTAN_PBKDF_SCRYPT @String
-- "Scrypt"
pattern BOTAN_PBKDF_SCRYPT = "Scrypt"
-- |
-- >>> BOTAN_PBKDF_ARGON2D @String
-- "Argon2d"
pattern BOTAN_PBKDF_ARGON2D = "Argon2d"
-- |
-- >>> BOTAN_PBKDF_ARGON2I @String
-- "Argon2i"
pattern BOTAN_PBKDF_ARGON2I = "Argon2i"
-- |
-- >>> BOTAN_PBKDF_ARGON2ID @String
-- "Argon2id"
pattern BOTAN_PBKDF_ARGON2ID = "Argon2id"
-- |
-- >>> BOTAN_PBKDF_BCRYPT_PBKDF @String
-- "Bcrypt-PBKDF"
pattern BOTAN_PBKDF_BCRYPT_PBKDF = "Bcrypt-PBKDF"
-- |
-- >>> BOTAN_PBKDF_OPENPGP_S2K @String
-- "OpenPGP-S2K"
pattern BOTAN_PBKDF_OPENPGP_S2K = "OpenPGP-S2K"