diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,55 @@
 # Changelog
 
+## 0.2.0.0 -- 2025-12-30
+
+* BREAKING: remove experimental FFI code related to `x509`. See PR
+  [#49](https://github.com/haskell-cryptography/botan/pull/49). This code might
+  be restored in some form in the future, but as of now it does not compile any
+  more, so it is removed. The modules that are removed are:
+  - `Botan.Bindings.X509.CA`
+  - `Botan.Bindings.X509.CRL`
+  - `Botan.Bindings.X509.CSR`
+  - `Botan.Bindings.X509.DN`
+  - `Botan.Bindings.X509.Extensions`
+  - `Botan.Bindings.X509.OCSP`
+  - `Botan.Bindings.X509.Options`
+  - `Botan.Bindings.X509.Path`
+  - `Botan.Bindings.X509.Store`
+* BREAKING: remove the `XFFI` cabal flag. See PR
+  [#49](https://github.com/haskell-cryptography/botan/pull/49). It has no effect
+  now that the experimental `x509` code is moved.
+* PATCH: enable `-Wall` in addition to a number of other GHC warnings. See PR
+  [#52](https://github.com/haskell-cryptography/botan/pull/52).
+* PATCH: use `GHC2021` as the default language. See PR
+  [#52](https://github.com/haskell-cryptography/botan/pull/52).
+* PATCH: update documentation in the `Botan.Bindings.Error` module. See PR
+  [#62](https://github.com/haskell-cryptography/botan/pull/62).
+* PATCH: update documentation in the `Botan.Bindings.Utility` module. See PR
+  [#62](https://github.com/haskell-cryptography/botan/pull/62).
+* PATCH: update documentation in the `Botan.Bindings.Version` module. See PR
+  [#62](https://github.com/haskell-cryptography/botan/pull/62).
+* PATCH: update documentation in the `Botan.Bindings.View` module. See PR
+  [#62](https://github.com/haskell-cryptography/botan/pull/62).
+* PATCH: update documentation in the `Botan.Bindings.PwdHash` module. See PR
+  [#63](https://github.com/haskell-cryptography/botan/pull/63).
+* PATCH: update documentation in the `Botan.Bindings.SRP6` module. See PR
+  [#65](https://github.com/haskell-cryptography/botan/pull/65).
+* PATCH: update documentation in the `Botan.Bindings.BlockCipher` module. See PR
+  [#74](https://github.com/haskell-cryptography/botan/pull/74).
+* BREAKING: in the `BlockCipher` module, remove `_128` from the identifiers of
+  pattern synonyms that start with `BOTAN_BLOCK_CIPHER_128`. See PR
+  [#74](https://github.com/haskell-cryptography/botan/pull/74).
+* NON-BREAKING: in the `BlockCipher` module, add new pattern synonyms
+  `BOTAN_BLOCK_CIPHER_LION` and `BOTAN_BLOCK_CIPHER_CASCADE` for the "Lion" and
+  "Cascade" ciphers respectively. See PR
+  [#74](https://github.com/haskell-cryptography/botan/pull/74).
+* PATCH: restrict the version of the C++ library to `<4`. See PR
+  [#103](https://github.com/haskell-cryptography/botan/pull/103).
+* BREAKING: enable `NoFieldSelectors`. See PR
+  [#106](https://github.com/haskell-cryptography/botan/pull/106). As a result,
+  this package no longer exports field selectors for datatypes defined in the
+  package.
+
 ## 0.1.0.0 -- 2025-09-17
 
 * PATCH: update the changelog to change the release date of version 0.0.1.0 from
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -2,6 +2,10 @@
 
 Raw bindings to the [Botan](https://botan.randombit.net/) cryptography library.
 
-> Botan's goal is to be the best option for cryptography in C++ by offering the tools necessary to implement a range of practical systems, such as TLS protocol, X.509 certificates, modern AEAD ciphers, PKCS#11 and TPM hardware support, password hashing, and post quantum crypto schemes.
+> Botan's goal is to be the best option for cryptography in C++ by offering the
+> tools necessary to implement a range of practical systems, such as TLS
+> protocol, X.509 certificates, modern AEAD ciphers, PKCS#11 and TPM hardware
+> support, password hashing, and post quantum crypto schemes.
 
-For more information, see the [README on Github](https://github.com/haskellfoundation/botan)
+For more information, see the [README on
+Github](https://github.com/haskell-cryptography/botan).
diff --git a/botan-bindings.cabal b/botan-bindings.cabal
--- a/botan-bindings.cabal
+++ b/botan-bindings.cabal
@@ -1,7 +1,7 @@
-cabal-version:   3.0
-name:            botan-bindings
-version:         0.1.0.0
-synopsis:        Raw Botan bindings
+cabal-version: 3.0
+name: botan-bindings
+version: 0.2.0.0
+synopsis: Raw Botan bindings
 description:
   Welcome to botan-bindings
 
@@ -12,76 +12,84 @@
   > X.509 certificates, modern AEAD ciphers, PKCS#11 and TPM hardware support,
   > password hashing, and post quantum crypto schemes.
 
-  For more information, see the [README on Github](https://github.com/haskellfoundation/botan)
+  For more information, see the [README on Github](https://github.com/haskell-cryptography/botan)
 
-author:          Leo D.
-maintainer:      joris@well-typed.com, leo@apotheca.io
-license:         BSD-3-Clause
-license-file:    LICENSE
+author: Leo D.
+maintainer: joris@well-typed.com, leo@apotheca.io
+license: BSD-3-Clause
+license-file: LICENSE
 copyright:
   Copyright (c) 2023-2024, Apotheca Labs
   Copyright (c) 2024-2025, Haskell Foundation
 
-build-type:      Simple
-category:        Cryptography
+build-type: Simple
+category: Cryptography
 extra-doc-files:
   CHANGELOG.md
   README.md
 
-tested-with:     GHC ==9.2 || ==9.4 || ==9.6 || ==9.8 || ==9.10 || ==9.12
+tested-with: ghc ==9.2 || ==9.4 || ==9.6 || ==9.8 || ==9.10 || ==9.12
 
 source-repository head
-  type:     git
-  location: https://github.com/haskellfoundation/botan
-  subdir:   botan-bindings
+  type: git
+  location: https://github.com/haskell-cryptography/botan
+  subdir: botan-bindings
 
 source-repository this
-  type:     git
-  location: https://github.com/haskellfoundation/botan
-  subdir:   botan-bindings
-  tag:      botan-bindings-0.1.0.0
+  type: git
+  location: https://github.com/haskell-cryptography/botan
+  subdir: botan-bindings
+  tag: botan-bindings-0.2.0.0
 
 flag pkg-config
-  default:     True
-  manual:      False
+  default: True
+  manual: False
   description: Use @pkg-config(1)@ to locate foreign @botan-3@ library.
 
-flag XFFI
-  description: Enable experimental / upstream ffi support
-  manual:      True
-  default:     False
+common warnings
+  ghc-options:
+    -Wall
+    -Wcompat
+    -Wincomplete-uni-patterns
+    -Wincomplete-record-updates
+    -Wpartial-fields
+    -Widentities
+    -Wredundant-constraints
+    -Wmissing-export-lists
+    -Wno-unticked-promoted-constructors
+    -Wunused-packages
+    -Wmissing-deriving-strategies
 
-library
-  hs-source-dirs:     src
-  default-language:   Haskell2010
+common language
+  default-language: GHC2021
   default-extensions:
-    DeriveDataTypeable
     DerivingStrategies
-    GeneralizedNewtypeDeriving
-    NoImplicitPrelude
-    OverloadedStrings
+    DuplicateRecordFields
+    NoFieldSelectors
+    OverloadedRecordDot
     PatternSynonyms
     RoleAnnotations
-    ScopedTypeVariables
-    StandaloneKindSignatures
 
+library
+  import: warnings, language
+  hs-source-dirs: src
   exposed-modules:
     Botan.Bindings.Bcrypt
     Botan.Bindings.BlockCipher
     Botan.Bindings.Cipher
+    Botan.Bindings.ConstPtr
     Botan.Bindings.Error
     Botan.Bindings.FPE
-    Botan.Bindings.Hash
     Botan.Bindings.HOTP
+    Botan.Bindings.Hash
     Botan.Bindings.KDF
     Botan.Bindings.KeyWrap
     Botan.Bindings.MAC
     Botan.Bindings.MPI
-    Botan.Bindings.Prelude
     Botan.Bindings.PubKey
-    Botan.Bindings.PubKey.Decrypt
     Botan.Bindings.PubKey.DH
     Botan.Bindings.PubKey.DSA
+    Botan.Bindings.PubKey.Decrypt
     Botan.Bindings.PubKey.ECDH
     Botan.Bindings.PubKey.ECDSA
     Botan.Bindings.PubKey.Ed25519
@@ -90,8 +98,8 @@
     Botan.Bindings.PubKey.KeyAgreement
     Botan.Bindings.PubKey.KeyEncapsulation
     Botan.Bindings.PubKey.RSA
-    Botan.Bindings.PubKey.Sign
     Botan.Bindings.PubKey.SM2
+    Botan.Bindings.PubKey.Sign
     Botan.Bindings.PubKey.Verify
     Botan.Bindings.PubKey.X25519
     Botan.Bindings.PwdHash
@@ -104,33 +112,11 @@
     Botan.Bindings.X509
     Botan.Bindings.ZFEC
 
-  other-modules:      Paths_botan_bindings
-  autogen-modules:    Paths_botan_bindings
-  build-depends:
-    , base        >=4.16 && <4.22
-    , bytestring  >=0.11 && <0.13
-
-  includes:           botan/ffi.h
+  build-depends: base >=4.16 && <4.22
+  includes: botan/ffi.h
 
   if flag(pkg-config)
     -- NB: pkg-config is available on windows as well when using msys2
-    pkgconfig-depends: botan-3 >=3.0.0
-
+    pkgconfig-depends: botan-3 >=3.0.0 && <4
   else
     extra-libraries: botan-3
-
-  ghc-options:        -Wall -Wno-name-shadowing
-
-  if flag(xffi)
-    -- Botan.Bindings.X509.OCSP
-    exposed-modules:
-      Botan.Bindings.X509.CA
-      Botan.Bindings.X509.CRL
-      Botan.Bindings.X509.CSR
-      Botan.Bindings.X509.DN
-      Botan.Bindings.X509.Extensions
-      Botan.Bindings.X509.Options
-      Botan.Bindings.X509.Path
-      Botan.Bindings.X509.Store
-
-    cpp-options:     -DXFFI
diff --git a/src/Botan/Bindings/Bcrypt.hs b/src/Botan/Bindings/Bcrypt.hs
--- a/src/Botan/Bindings/Bcrypt.hs
+++ b/src/Botan/Bindings/Bcrypt.hs
@@ -13,10 +13,19 @@
 
 {-# LANGUAGE CApiFFI #-}
 
-module Botan.Bindings.Bcrypt where
+module Botan.Bindings.Bcrypt (
+    pattern BOTAN_BCRYPT_WORK_FACTOR_FAST
+  , pattern BOTAN_BCRYPT_WORK_FACTOR_GOOD
+  , pattern BOTAN_BCRYPT_WORK_FACTOR_STRONG
+  , botan_bcrypt_generate
+  , botan_bcrypt_is_valid
+  ) where
 
-import Botan.Bindings.Prelude
-import Botan.Bindings.RNG
+import           Botan.Bindings.ConstPtr
+import           Botan.Bindings.RNG
+import           Data.Word
+import           Foreign.C.Types
+import           Foreign.Ptr
 
 -- TODO: Maybe move to Botan.Low.Bcrypt
 pattern BOTAN_BCRYPT_WORK_FACTOR_FAST
diff --git a/src/Botan/Bindings/BlockCipher.hs b/src/Botan/Bindings/BlockCipher.hs
--- a/src/Botan/Bindings/BlockCipher.hs
+++ b/src/Botan/Bindings/BlockCipher.hs
@@ -8,17 +8,68 @@
 Stability   : experimental
 Portability : POSIX
 
-This is a ‘raw’ interface to ECB mode block ciphers.
-Most applications want the higher level cipher API which provides authenticated encryption.
-This API exists as an escape hatch for applications which need to implement custom primitives using a PRP.
+This module is based on the [Block
+Ciphers](https://botan.randombit.net/handbook/api_ref/ffi.html#block-ciphers)
+section of the C Botan FFI documentation, and on the [Block
+Ciphers](https://botan.randombit.net/handbook/api_ref/block_cipher.html) section
+of the C++ API reference.
 -}
 
-{-# LANGUAGE CApiFFI #-}
+{-# LANGUAGE CApiFFI           #-}
+{-# LANGUAGE OverloadedStrings #-}
 
-module Botan.Bindings.BlockCipher where
+module Botan.Bindings.BlockCipher (
+    BotanBlockCipherStruct
+  , BotanBlockCipher (..)
+  , botan_block_cipher_destroy
+  , botan_block_cipher_init
+  , botan_block_cipher_clear
+  , botan_block_cipher_set_key
+  , botan_block_cipher_block_size
+  , botan_block_cipher_encrypt_blocks
+  , botan_block_cipher_decrypt_blocks
+  , botan_block_cipher_name
+  , botan_block_cipher_get_keyspec
+    -- * Available ciphers
+    -- $available-ciphers
+  , pattern BOTAN_BLOCK_CIPHER_AES_128
+  , pattern BOTAN_BLOCK_CIPHER_AES_192
+  , pattern BOTAN_BLOCK_CIPHER_AES_256
+  , pattern BOTAN_BLOCK_CIPHER_ARIA_128
+  , pattern BOTAN_BLOCK_CIPHER_ARIA_192
+  , pattern BOTAN_BLOCK_CIPHER_ARIA_256
+  , pattern BOTAN_BLOCK_CIPHER_BLOWFISH
+  , pattern BOTAN_BLOCK_CIPHER_CAMELLIA_128
+  , pattern BOTAN_BLOCK_CIPHER_CAMELLIA_192
+  , pattern BOTAN_BLOCK_CIPHER_CAMELLIA_256
+  , pattern BOTAN_BLOCK_CIPHER_CASCADE
+  , pattern BOTAN_BLOCK_CIPHER_CAST_128
+  , pattern BOTAN_BLOCK_CIPHER_DES
+  , pattern BOTAN_BLOCK_CIPHER_TRIPLEDES
+  , pattern BOTAN_BLOCK_CIPHER_GOST_28147_89
+  , pattern BOTAN_BLOCK_CIPHER_IDEA
+  , pattern BOTAN_BLOCK_CIPHER_LION
+  , pattern BOTAN_BLOCK_CIPHER_NOEKEON
+  , pattern BOTAN_BLOCK_CIPHER_SEED
+  , pattern BOTAN_BLOCK_CIPHER_SERPENT
+  , pattern BOTAN_BLOCK_CIPHER_SHACAL2
+  , pattern BOTAN_BLOCK_CIPHER_SM4
+  , pattern BOTAN_BLOCK_CIPHER_THREEFISH_512
+  , pattern BOTAN_BLOCK_CIPHER_TWOFISH
+  ) where
 
-import Botan.Bindings.Prelude
+import           Botan.Bindings.ConstPtr
+import           Data.String
+import           Data.Word
+import           Foreign.C.Types
+import           Foreign.ForeignPtr
+import           Foreign.Ptr
+import           Foreign.Storable
 
+{-------------------------------------------------------------------------------
+  Block ciphers
+-------------------------------------------------------------------------------}
+
 -- | Opaque BlockCipher struct
 data {-# CTYPE "botan/ffi.h" "struct botan_block_cipher_struct" #-} BotanBlockCipherStruct
 
@@ -28,118 +79,245 @@
         deriving newtype (Eq, Ord, Storable)
 
 -- | Destroy a block cipher object
+--
+-- NOTE: this a binding to the /address/ of the @botan_block_cipher_destroy@ C
+-- function.
 foreign import capi safe "botan/ffi.h &botan_block_cipher_destroy"
-    botan_block_cipher_destroy
-        :: FinalizerPtr BotanBlockCipherStruct
-
-pattern BOTAN_BLOCK_CIPHER_128_AES_128
-    ,   BOTAN_BLOCK_CIPHER_128_AES_192
-    ,   BOTAN_BLOCK_CIPHER_128_AES_256
-    ,   BOTAN_BLOCK_CIPHER_128_ARIA_128
-    ,   BOTAN_BLOCK_CIPHER_128_ARIA_192
-    ,   BOTAN_BLOCK_CIPHER_128_ARIA_256
-    ,   BOTAN_BLOCK_CIPHER_128_CAMELLIA_128
-    ,   BOTAN_BLOCK_CIPHER_128_CAMELLIA_192
-    ,   BOTAN_BLOCK_CIPHER_128_CAMELLIA_256
-    ,   BOTAN_BLOCK_CIPHER_128_NOEKEON
-    ,   BOTAN_BLOCK_CIPHER_128_SEED
-    ,   BOTAN_BLOCK_CIPHER_128_SM4
-    ,   BOTAN_BLOCK_CIPHER_128_SERPENT
-    ,   BOTAN_BLOCK_CIPHER_128_TWOFISH
-    :: (Eq a, IsString a) => a
-
-pattern BOTAN_BLOCK_CIPHER_128_AES_128      = "AES-128"
-pattern BOTAN_BLOCK_CIPHER_128_AES_192      = "AES-192"
-pattern BOTAN_BLOCK_CIPHER_128_AES_256      = "AES-256"
-pattern BOTAN_BLOCK_CIPHER_128_ARIA_128     = "ARIA-128"
-pattern BOTAN_BLOCK_CIPHER_128_ARIA_192     = "ARIA-192"
-pattern BOTAN_BLOCK_CIPHER_128_ARIA_256     = "ARIA-256"
-pattern BOTAN_BLOCK_CIPHER_128_CAMELLIA_128 = "Camellia-128"
-pattern BOTAN_BLOCK_CIPHER_128_CAMELLIA_192 = "Camellia-192"
-pattern BOTAN_BLOCK_CIPHER_128_CAMELLIA_256 = "Camellia-256"
-pattern BOTAN_BLOCK_CIPHER_128_NOEKEON      = "Noekeon"
-pattern BOTAN_BLOCK_CIPHER_128_SEED         = "SEED"
-pattern BOTAN_BLOCK_CIPHER_128_SM4          = "SM4"
-pattern BOTAN_BLOCK_CIPHER_128_SERPENT      = "Serpent"
-pattern BOTAN_BLOCK_CIPHER_128_TWOFISH      = "Twofish"
-
-pattern BOTAN_BLOCK_CIPHER_BLOWFISH
-    ,   BOTAN_BLOCK_CIPHER_CAST_128
-    ,   BOTAN_BLOCK_CIPHER_DES
-    ,   BOTAN_BLOCK_CIPHER_TRIPLEDES
-    ,   BOTAN_BLOCK_CIPHER_GOST_28147_89
-    ,   BOTAN_BLOCK_CIPHER_IDEA
-    ,   BOTAN_BLOCK_CIPHER_SHACAL2
-    ,   BOTAN_BLOCK_CIPHER_THREEFISH_512
-    :: (Eq a, IsString a) => a
-
-pattern BOTAN_BLOCK_CIPHER_BLOWFISH         = "Blowfish"
-pattern BOTAN_BLOCK_CIPHER_CAST_128         = "CAST-128"
-pattern BOTAN_BLOCK_CIPHER_DES              = "DES"
-pattern BOTAN_BLOCK_CIPHER_TRIPLEDES        = "TripleDES"
-pattern BOTAN_BLOCK_CIPHER_GOST_28147_89    = "GOST-28147-89"
-pattern BOTAN_BLOCK_CIPHER_IDEA             = "IDEA"
-pattern BOTAN_BLOCK_CIPHER_SHACAL2          = "SHACAL2"
-pattern BOTAN_BLOCK_CIPHER_THREEFISH_512    = "Threefish-512"
+  botan_block_cipher_destroy
+    :: FinalizerPtr BotanBlockCipherStruct
 
 -- | Initialize a block cipher object
 foreign import capi safe "botan/ffi.h botan_block_cipher_init"
-    botan_block_cipher_init
-        :: Ptr BotanBlockCipher -- ^ __bc__
-        -> ConstPtr CChar       -- ^ __cipher_name__
-        -> IO CInt
+  botan_block_cipher_init
+    :: Ptr BotanBlockCipher -- ^ __bc__
+    -> ConstPtr CChar       -- ^ __cipher_name__
+    -> IO CInt
 
 -- | Reinitializes the block cipher
 foreign import capi safe "botan/ffi.h botan_block_cipher_clear"
-    botan_block_cipher_clear
-        :: BotanBlockCipher -- ^ __bc__
-        -> IO CInt          -- ^ 0 on success, a negative value on failure
+  botan_block_cipher_clear
+    :: BotanBlockCipher -- ^ __bc__
+    -> IO CInt          -- ^ 0 on success, a negative value on failure
 
 -- | Set the key for a block cipher instance
 foreign import capi safe "botan/ffi.h botan_block_cipher_set_key"
-    botan_block_cipher_set_key
-        :: BotanBlockCipher -- ^ __bc__
-        -> ConstPtr Word8   -- ^ __key[]__
-        -> CSize            -- ^ __len__
-        -> IO CInt
+  botan_block_cipher_set_key
+    :: BotanBlockCipher -- ^ __bc__
+    -> ConstPtr Word8   -- ^ __key[]__
+    -> CSize            -- ^ __len__
+    -> IO CInt
 
 -- | Return the positive block size of this block cipher, or negative to indicate an error
 foreign import capi safe "botan/ffi.h botan_block_cipher_block_size"
-    botan_block_cipher_block_size
-        :: BotanBlockCipher -- ^ __bc__
-        -> IO CInt
+  botan_block_cipher_block_size
+    :: BotanBlockCipher -- ^ __bc__
+    -> IO CInt
 
 -- | Encrypt one or more blocks with the cipher
 foreign import capi safe "botan/ffi.h botan_block_cipher_encrypt_blocks"
-    botan_block_cipher_encrypt_blocks
-        :: BotanBlockCipher -- ^ __bc__
-        -> ConstPtr Word8   -- ^ __in[]__
-        -> Ptr Word8        -- ^ __out[]__
-        -> CSize            -- ^ __blocks__
-        -> IO CInt
+  botan_block_cipher_encrypt_blocks
+    :: BotanBlockCipher -- ^ __bc__
+    -> ConstPtr Word8   -- ^ __in[]__
+    -> Ptr Word8        -- ^ __out[]__
+    -> CSize            -- ^ __blocks__
+    -> IO CInt
 
 -- | Decrypt one or more blocks with the cipher
 foreign import capi safe "botan/ffi.h botan_block_cipher_decrypt_blocks"
-    botan_block_cipher_decrypt_blocks
-        :: BotanBlockCipher -- ^ __bc__
-        -> ConstPtr Word8   -- ^ __in[]__
-        -> Ptr Word8        -- ^ __out[]__
-        -> CSize            -- ^ __blocks__
-        -> IO CInt
+  botan_block_cipher_decrypt_blocks
+    :: BotanBlockCipher -- ^ __bc__
+    -> ConstPtr Word8   -- ^ __in[]__
+    -> Ptr Word8        -- ^ __out[]__
+    -> CSize            -- ^ __blocks__
+    -> IO CInt
 
 -- | Get the name of this block cipher
 foreign import capi safe "botan/ffi.h botan_block_cipher_name"
-    botan_block_cipher_name
-        :: BotanBlockCipher -- ^ __cipher__: the object to read
-        -> Ptr CChar        -- ^ __name__: output buffer
-        -> Ptr CSize        -- ^ __name_len__: on input, the length of buffer, on success the number of bytes written
-        -> IO CInt
+  botan_block_cipher_name
+    :: BotanBlockCipher -- ^ __cipher__: the object to read
+    -> Ptr CChar        -- ^ __name__: output buffer
+    -> Ptr CSize        -- ^ __name_len__: on input, the length of buffer, on success the number of bytes written
+    -> IO CInt
 
 -- | Get the key length limits of this block cipher
 foreign import capi safe "botan/ffi.h botan_block_cipher_get_keyspec"
-    botan_block_cipher_get_keyspec
-        :: BotanBlockCipher -- ^ __cipher__: the object to read
-        -> Ptr CSize        -- ^ __out_minimum_keylength__: if non-NULL, will be set to minimum keylength of cipher
-        -> Ptr CSize        -- ^ __out_maximum_keylength__: if non-NULL, will be set to maximum keylength of cipher
-        -> Ptr CSize        -- ^ __out_keylength_modulo__: if non-NULL will be set to byte multiple of valid keys
-        -> IO CInt
+  botan_block_cipher_get_keyspec
+    :: BotanBlockCipher -- ^ __cipher__: the object to read
+    -> Ptr CSize        -- ^ __out_minimum_keylength__: if non-NULL, will be set to minimum keylength of cipher
+    -> Ptr CSize        -- ^ __out_maximum_keylength__: if non-NULL, will be set to maximum keylength of cipher
+    -> Ptr CSize        -- ^ __out_keylength_modulo__: if non-NULL will be set to byte multiple of valid keys
+    -> IO CInt
+
+{-------------------------------------------------------------------------------
+  Available ciphers
+-------------------------------------------------------------------------------}
+
+{- $available-ciphers
+
+A number of algorithms are available to be used as block ciphers. An algorithm
+is selected by passing the /algorithm specification name/ of the algorithm as a
+string to the block cipher functions. In some cases an algorithm specification
+name is just the /algorithm name/, like @"AES-128"@. In other cases an algorithm
+specification name is a combination of an algorithm name paired with some
+parameters, such as @"Cascade(Serpent, AES-256)"@ where @"Cascade"@ is the
+algorithm name followed by a 2-tuple of parameters. Pattern synonyms are
+included for each available /algorithm name/. Where necessary, such as in the
+@"Cascade"@ case, these algorithm names should be manually extended to full
+algorithm specification names.
+
+WARNING: 64-bit block ciphers should be avoided.
+
+WARNING: the @Kuznyechik@ block ciphier is not included because its security is
+disputed.
+
+See the [Available
+Ciphers](https://botan.randombit.net/handbook/api_ref/block_cipher.html#available-ciphers)
+section of the C++ API reference for more information about available ciphers.
+-}
+
+pattern
+    BOTAN_BLOCK_CIPHER_AES_128
+  , BOTAN_BLOCK_CIPHER_AES_192
+  , BOTAN_BLOCK_CIPHER_AES_256
+  , BOTAN_BLOCK_CIPHER_ARIA_128
+  , BOTAN_BLOCK_CIPHER_ARIA_192
+  , BOTAN_BLOCK_CIPHER_ARIA_256
+  , BOTAN_BLOCK_CIPHER_BLOWFISH
+  , BOTAN_BLOCK_CIPHER_CAMELLIA_128
+  , BOTAN_BLOCK_CIPHER_CAMELLIA_192
+  , BOTAN_BLOCK_CIPHER_CAMELLIA_256
+  , BOTAN_BLOCK_CIPHER_CASCADE
+  , BOTAN_BLOCK_CIPHER_CAST_128
+  , BOTAN_BLOCK_CIPHER_DES
+  , BOTAN_BLOCK_CIPHER_TRIPLEDES
+  , BOTAN_BLOCK_CIPHER_GOST_28147_89
+  , BOTAN_BLOCK_CIPHER_IDEA
+  , BOTAN_BLOCK_CIPHER_LION
+  , BOTAN_BLOCK_CIPHER_NOEKEON
+  , BOTAN_BLOCK_CIPHER_SEED
+  , BOTAN_BLOCK_CIPHER_SERPENT
+  , BOTAN_BLOCK_CIPHER_SHACAL2
+  , BOTAN_BLOCK_CIPHER_SM4
+  , BOTAN_BLOCK_CIPHER_THREEFISH_512
+  , BOTAN_BLOCK_CIPHER_TWOFISH
+  :: (Eq a, IsString a) => a
+
+-- |
+-- >>> BOTAN_BLOCK_CIPHER_AES_128 @String
+-- "AES-128"
+pattern BOTAN_BLOCK_CIPHER_AES_128 = "AES-128"
+
+-- |
+-- >>> BOTAN_BLOCK_CIPHER_AES_192 @String
+-- "AES-192"
+pattern BOTAN_BLOCK_CIPHER_AES_192 = "AES-192"
+
+-- |
+-- >>> BOTAN_BLOCK_CIPHER_AES_256 @String
+-- "AES-256"
+pattern BOTAN_BLOCK_CIPHER_AES_256 = "AES-256"
+
+-- |
+-- >>> BOTAN_BLOCK_CIPHER_ARIA_128 @String
+-- "ARIA-128"
+pattern BOTAN_BLOCK_CIPHER_ARIA_128 = "ARIA-128"
+
+-- |
+-- >>> BOTAN_BLOCK_CIPHER_ARIA_192 @String
+-- "ARIA-192"
+pattern BOTAN_BLOCK_CIPHER_ARIA_192 = "ARIA-192"
+
+-- |
+-- >>> BOTAN_BLOCK_CIPHER_ARIA_256 @String
+-- "ARIA-256"
+pattern BOTAN_BLOCK_CIPHER_ARIA_256 = "ARIA-256"
+
+-- |
+-- >>> BOTAN_BLOCK_CIPHER_BLOWFISH @String
+-- "Blowfish"
+pattern BOTAN_BLOCK_CIPHER_BLOWFISH = "Blowfish"
+
+-- |
+-- >>> BOTAN_BLOCK_CIPHER_CAMELLIA_128 @String
+-- "Camellia-128"
+pattern BOTAN_BLOCK_CIPHER_CAMELLIA_128 = "Camellia-128"
+
+-- |
+-- >>> BOTAN_BLOCK_CIPHER_CAMELLIA_192 @String
+-- "Camellia-192"
+pattern BOTAN_BLOCK_CIPHER_CAMELLIA_192 = "Camellia-192"
+
+-- |
+-- >>> BOTAN_BLOCK_CIPHER_CAMELLIA_256 @String
+-- "Camellia-256"
+pattern BOTAN_BLOCK_CIPHER_CAMELLIA_256 = "Camellia-256"
+
+-- |
+-- >>> BOTAN_BLOCK_CIPHER_CASCADE @String
+-- "Cascade"
+pattern BOTAN_BLOCK_CIPHER_CASCADE = "Cascade"
+
+-- |
+-- >>> BOTAN_BLOCK_CIPHER_CAST_128 @String
+-- "CAST-128"
+pattern BOTAN_BLOCK_CIPHER_CAST_128 = "CAST-128"
+
+-- |
+-- >>> BOTAN_BLOCK_CIPHER_DES @String
+-- "DES"
+pattern BOTAN_BLOCK_CIPHER_DES = "DES"
+
+-- |
+-- >>> BOTAN_BLOCK_CIPHER_TRIPLEDES @String
+-- "TripleDES"
+pattern BOTAN_BLOCK_CIPHER_TRIPLEDES = "TripleDES"
+
+-- |
+-- >>> BOTAN_BLOCK_CIPHER_GOST_28147_89 @String
+-- "GOST-28147-89"
+pattern BOTAN_BLOCK_CIPHER_GOST_28147_89 = "GOST-28147-89"
+
+-- |
+-- >>> BOTAN_BLOCK_CIPHER_IDEA @String
+-- "IDEA"
+pattern BOTAN_BLOCK_CIPHER_IDEA = "IDEA"
+
+-- |
+-- >>> BOTAN_BLOCK_CIPHER_LION @String
+-- "Lion"
+pattern BOTAN_BLOCK_CIPHER_LION = "Lion"
+
+-- |
+-- >>> BOTAN_BLOCK_CIPHER_NOEKEON @String
+-- "Noekeon"
+pattern BOTAN_BLOCK_CIPHER_NOEKEON = "Noekeon"
+
+-- |
+-- >>> BOTAN_BLOCK_CIPHER_SEED @String
+-- "SEED"
+pattern BOTAN_BLOCK_CIPHER_SEED = "SEED"
+
+-- |
+-- >>> BOTAN_BLOCK_CIPHER_SERPENT @String
+-- "Serpent"
+pattern BOTAN_BLOCK_CIPHER_SERPENT = "Serpent"
+
+-- |
+-- >>> BOTAN_BLOCK_CIPHER_SHACAL2 @String
+-- "SHACAL2"
+pattern BOTAN_BLOCK_CIPHER_SHACAL2 = "SHACAL2"
+
+-- |
+-- >>> BOTAN_BLOCK_CIPHER_SM4 @String
+-- "SM4"
+pattern BOTAN_BLOCK_CIPHER_SM4 = "SM4"
+
+-- |
+-- >>> BOTAN_BLOCK_CIPHER_THREEFISH_512 @String
+-- "Threefish-512"
+pattern BOTAN_BLOCK_CIPHER_THREEFISH_512 = "Threefish-512"
+
+-- |
+-- >>> BOTAN_BLOCK_CIPHER_TWOFISH @String
+-- "Twofish"
+pattern BOTAN_BLOCK_CIPHER_TWOFISH = "Twofish"
diff --git a/src/Botan/Bindings/Cipher.hsc b/src/Botan/Bindings/Cipher.hsc
--- a/src/Botan/Bindings/Cipher.hsc
+++ b/src/Botan/Bindings/Cipher.hsc
@@ -15,10 +15,61 @@
 -}
 
 {-# LANGUAGE CApiFFI #-}
+{-# LANGUAGE OverloadedStrings #-}
 
-module Botan.Bindings.Cipher where
+module Botan.Bindings.Cipher (
+    BotanCipherStruct
+  , BotanCipher (..)
+  , botan_cipher_destroy
+  , pattern BOTAN_CIPHER_MODE_CBC
+  , pattern BOTAN_CIPHER_MODE_CFB
+  , pattern BOTAN_CIPHER_MODE_XTS
 
-import Botan.Bindings.Prelude
+  , pattern BOTAN_CBC_PADDING_PKCS7
+  , pattern BOTAN_CBC_PADDING_ONE_AND_ZEROS
+  , pattern BOTAN_CBC_PADDING_X9_23
+  , pattern BOTAN_CBC_PADDING_ESP
+  , pattern BOTAN_CBC_PADDING_CTS
+  , pattern BOTAN_CBC_PADDING_NO_PADDING
+
+  , pattern BOTAN_AEAD_CHACHA20POLY1305
+
+  , pattern BOTAN_AEAD_MODE_GCM
+  , pattern BOTAN_AEAD_MODE_OCB
+  , pattern BOTAN_AEAD_MODE_EAX
+  , pattern BOTAN_AEAD_MODE_SIV
+  , pattern BOTAN_AEAD_MODE_CCM
+
+  , pattern BOTAN_CIPHER_INIT_FLAG_MASK_DIRECTION
+  , pattern BOTAN_CIPHER_INIT_FLAG_ENCRYPT
+  , pattern BOTAN_CIPHER_INIT_FLAG_DECRYPT
+  , botan_cipher_init
+  , botan_cipher_name
+  , botan_cipher_output_length
+  , botan_cipher_valid_nonce_length
+  , botan_cipher_get_tag_length
+  , botan_cipher_get_default_nonce_length
+  , botan_cipher_get_update_granularity
+  , botan_cipher_get_ideal_update_granularity
+  , botan_cipher_query_keylen
+  , botan_cipher_get_keyspec
+  , botan_cipher_set_key
+  , botan_cipher_reset
+  , botan_cipher_set_associated_data
+  , botan_cipher_start
+  , pattern BOTAN_CIPHER_UPDATE_FLAG_NONE
+  , pattern BOTAN_CIPHER_UPDATE_FLAG_FINAL
+  , botan_cipher_update
+  , botan_cipher_clear
+  ) where
+
+import Botan.Bindings.ConstPtr
+import Data.String
+import Data.Word
+import Foreign.C.Types
+import Foreign.ForeignPtr
+import Foreign.Ptr
+import Foreign.Storable
 
 #include <botan/ffi.h>
 
diff --git a/src/Botan/Bindings/ConstPtr.hs b/src/Botan/Bindings/ConstPtr.hs
new file mode 100644
--- /dev/null
+++ b/src/Botan/Bindings/ConstPtr.hs
@@ -0,0 +1,37 @@
+{-# LANGUAGE CPP #-}
+
+module Botan.Bindings.ConstPtr (
+    ConstPtr(..)
+  ) where
+
+#if MIN_VERSION_base (4,18,0)
+import           Foreign.C.ConstPtr
+#else
+import           Data.Data
+import           Data.Kind
+import           Foreign.Ptr
+import           Foreign.Storable
+#endif
+
+#if !(MIN_VERSION_base (4,18,0))
+
+-- NOTE: Taken from Foreign.C.ConstPtr, more or less
+-- NOTE: Raises a warning on older base / compilers if the shim
+--       is a `newtype` instead of a `type`, because the special
+--       logic for const pointers didn't exist yet
+-- SEE: https://gitlab.haskell.org/ghc/ghc/-/issues/22043
+-- AFFECTS:
+--  botan_error_description
+--  botan_error_last_exception_message
+--  botan_x509_cert_validation_status
+--  botan_version_string
+type ConstPtr :: Type -> Type
+type role ConstPtr phantom
+newtype ConstPtr a = ConstPtr { unConstPtr :: Ptr a }
+    deriving stock (Data)
+    deriving newtype (Eq, Ord, Storable)
+
+instance Show (ConstPtr a) where
+    showsPrec d (ConstPtr p) = showParen (d > 10) $ showString "ConstPtr " . showsPrec 11 p
+
+#endif
diff --git a/src/Botan/Bindings/Error.hsc b/src/Botan/Bindings/Error.hsc
--- a/src/Botan/Bindings/Error.hsc
+++ b/src/Botan/Bindings/Error.hsc
@@ -8,17 +8,50 @@
 Stability   : experimental
 Portability : POSIX
 
+This module is based on the [Return
+codes](https://botan.randombit.net/handbook/api_ref/ffi.html#return-codes)
+section of the C Botan FFI documentation.
+
 Error values below -10000 are reserved for the application (these can be returned from view functions).
 -}
 
 {-# LANGUAGE CApiFFI #-}
 
-module Botan.Bindings.Error where
+module Botan.Bindings.Error (
+    pattern BOTAN_FFI_SUCCESS
+  , pattern BOTAN_FFI_INVALID_VERIFIER
+  , pattern BOTAN_FFI_ERROR_INVALID_INPUT
+  , pattern BOTAN_FFI_ERROR_BAD_MAC
+  , pattern BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE
+  , pattern BOTAN_FFI_ERROR_STRING_CONVERSION_ERROR
+  , pattern BOTAN_FFI_ERROR_EXCEPTION_THROWN
+  , pattern BOTAN_FFI_ERROR_OUT_OF_MEMORY
+  , pattern BOTAN_FFI_ERROR_SYSTEM_ERROR
+  , pattern BOTAN_FFI_ERROR_INTERNAL_ERROR
+  , pattern BOTAN_FFI_ERROR_BAD_FLAG
+  , pattern BOTAN_FFI_ERROR_NULL_POINTER
+  , pattern BOTAN_FFI_ERROR_BAD_PARAMETER
+  , pattern BOTAN_FFI_ERROR_KEY_NOT_SET
+  , pattern BOTAN_FFI_ERROR_INVALID_KEY_LENGTH
+  , pattern BOTAN_FFI_ERROR_INVALID_OBJECT_STATE
+  , pattern BOTAN_FFI_ERROR_NOT_IMPLEMENTED
+  , pattern BOTAN_FFI_ERROR_INVALID_OBJECT
+  , pattern BOTAN_FFI_ERROR_TLS_ERROR
+  , pattern BOTAN_FFI_ERROR_HTTP_ERROR
+  , pattern BOTAN_FFI_ERROR_ROUGHTIME_ERROR
+  , pattern BOTAN_FFI_ERROR_UNKNOWN_ERROR
+  , botan_error_description
+  , botan_error_last_exception_message
+  ) where
 
-import Botan.Bindings.Prelude
+import Botan.Bindings.ConstPtr
+import Foreign.C.Types
 
 #include <botan/ffi.h>
 
+-- TODO: consider making bindings in this module unsafe. See issue #61.
+
+-- TODO: make the representation of BOTAN_FFI_ERROR a CInt. See issue #59.
 pattern BOTAN_FFI_SUCCESS
     ,   BOTAN_FFI_INVALID_VERIFIER
     ,   BOTAN_FFI_ERROR_INVALID_INPUT
@@ -97,12 +130,19 @@
 -- | This is used if an object provided did not match the function. For example calling botan_hash_destroy on a botan_rng_t object will cause this error.
 pattern BOTAN_FFI_ERROR_INVALID_OBJECT = #const BOTAN_FFI_ERROR_INVALID_OBJECT
 
+-- | Note: this code is undocumented in @botan/ffi.h@.
 pattern BOTAN_FFI_ERROR_TLS_ERROR = #const BOTAN_FFI_ERROR_TLS_ERROR
+
+-- | Note: this code is undocumented in @botan/ffi.h@.
 pattern BOTAN_FFI_ERROR_HTTP_ERROR = #const BOTAN_FFI_ERROR_HTTP_ERROR
+
+-- | Note: this code is undocumented in @botan/ffi.h@.
 pattern BOTAN_FFI_ERROR_ROUGHTIME_ERROR = #const BOTAN_FFI_ERROR_ROUGHTIME_ERROR
 
 -- | Something bad happened, but we are not sure why or how.
 pattern BOTAN_FFI_ERROR_UNKNOWN_ERROR = #const BOTAN_FFI_ERROR_UNKNOWN_ERROR
+
+-- TODO: add a binding for BOTAN_FFI_TEMP_ERROR. See issue #44.
 
 foreign import capi safe "botan/ffi.h botan_error_description"
     botan_error_description
diff --git a/src/Botan/Bindings/FPE.hsc b/src/Botan/Bindings/FPE.hsc
--- a/src/Botan/Bindings/FPE.hsc
+++ b/src/Botan/Bindings/FPE.hsc
@@ -35,10 +35,24 @@
 
 {-# LANGUAGE CApiFFI #-}
 
-module Botan.Bindings.FPE where
+module Botan.Bindings.FPE (
+    BotanFPEStruct
+  , BotanFPE (..)
+  , botan_fpe_destroy
+  , pattern BOTAN_FPE_FLAG_NONE
+  , pattern BOTAN_FPE_FLAG_FE1_COMPAT_MODE
+  , botan_fpe_fe1_init
+  , botan_fpe_encrypt
+  , botan_fpe_decrypt
+  ) where
 
 import Botan.Bindings.MPI
-import Botan.Bindings.Prelude
+import Botan.Bindings.ConstPtr
+import Data.Word
+import Foreign.C.Types
+import Foreign.ForeignPtr
+import Foreign.Ptr
+import Foreign.Storable
 
 #include <botan/ffi.h>
 
diff --git a/src/Botan/Bindings/HOTP.hs b/src/Botan/Bindings/HOTP.hs
--- a/src/Botan/Bindings/HOTP.hs
+++ b/src/Botan/Bindings/HOTP.hs
@@ -38,8 +38,21 @@
 
 {-# LANGUAGE CApiFFI #-}
 
-module Botan.Bindings.HOTP where
-import Botan.Bindings.Prelude
+module Botan.Bindings.HOTP (
+    BotanHOTPStruct
+  , BotanHOTP (..)
+  , botan_hotp_destroy
+  , botan_hotp_init
+  , botan_hotp_generate
+  , botan_hotp_check
+  ) where
+
+import           Botan.Bindings.ConstPtr
+import           Data.Word
+import           Foreign.C.Types
+import           Foreign.ForeignPtr
+import           Foreign.Ptr
+import           Foreign.Storable
 
 -- | Opaque HOTP struct
 data {-# CTYPE "botan/ffi.h" "struct botan_hotp_struct" #-} BotanHOTPStruct
diff --git a/src/Botan/Bindings/Hash.hs b/src/Botan/Bindings/Hash.hs
--- a/src/Botan/Bindings/Hash.hs
+++ b/src/Botan/Bindings/Hash.hs
@@ -26,11 +26,58 @@
 hashFinal), the internal state is reset to begin hashing a new message.
 -}
 
-{-# LANGUAGE CApiFFI #-}
+{-# LANGUAGE CApiFFI           #-}
+{-# LANGUAGE OverloadedStrings #-}
 
-module Botan.Bindings.Hash where
+module Botan.Bindings.Hash (
+    BotanHashStruct
+  , BotanHash (..)
+  , botan_hash_destroy
+  , pattern BOTAN_HASH_BLAKE2B
+  , pattern BOTAN_HASH_KECCAK_1600
+  , pattern BOTAN_HASH_GOST_34_11
+  , pattern BOTAN_HASH_MD4
+  , pattern BOTAN_HASH_MD5
+  , pattern BOTAN_HASH_RIPEMD_160
+  , pattern BOTAN_HASH_SHA1
+  , pattern BOTAN_HASH_SHA_224
+  , pattern BOTAN_HASH_SHA_256
+  , pattern BOTAN_HASH_SHA_384
+  , pattern BOTAN_HASH_SHA_512
+  , pattern BOTAN_HASH_SHA_512_256
+  , pattern BOTAN_HASH_SHA_3
+  , pattern BOTAN_HASH_SHAKE_128
+  , pattern BOTAN_HASH_SHAKE_256
+  , pattern BOTAN_HASH_SM3
+  , pattern BOTAN_HASH_SKEIN_512
+  , pattern BOTAN_HASH_STREEBOG_256
+  , pattern BOTAN_HASH_STREEBOG_512
+  , pattern BOTAN_HASH_WHIRLPOOL
 
-import Botan.Bindings.Prelude
+  , pattern BOTAN_HASH_STRAT_PARALLEL
+  , pattern BOTAN_HASH_STRAT_COMB4P
+
+  , pattern BOTAN_CHECKSUM_ADLER32
+  , pattern BOTAN_CHECKSUM_CRC24
+  , pattern BOTAN_CHECKSUM_CRC32
+  , botan_hash_init
+  , botan_hash_name
+  , botan_hash_copy_state
+  , botan_hash_output_length
+  , botan_hash_block_size
+  , botan_hash_update
+  , botan_hash_final
+  , botan_hash_clear
+  , botan_pkcs_hash_id
+  ) where
+
+import           Botan.Bindings.ConstPtr
+import           Data.String
+import           Data.Word
+import           Foreign.C.Types
+import           Foreign.ForeignPtr
+import           Foreign.Ptr
+import           Foreign.Storable
 
 -- | Opaque Hash struct
 data {-# CTYPE "botan/ffi.h" "struct botan_hash_struct" #-} BotanHashStruct
diff --git a/src/Botan/Bindings/KDF.hs b/src/Botan/Bindings/KDF.hs
--- a/src/Botan/Bindings/KDF.hs
+++ b/src/Botan/Bindings/KDF.hs
@@ -27,11 +27,31 @@
 still use different keys in the two contexts.
 -}
 
-{-# LANGUAGE CApiFFI #-}
+{-# LANGUAGE CApiFFI           #-}
+{-# LANGUAGE OverloadedStrings #-}
 
-module Botan.Bindings.KDF where
+module Botan.Bindings.KDF (
+    pattern BOTAN_KDF_HKDF
+  , pattern BOTAN_KDF_HKDF_EXTRACT
+  , pattern BOTAN_KDF_HKDF_EXPAND
+  , pattern BOTAN_KDF_KDF2
+  , pattern BOTAN_KDF_KDF1_18033
+  , pattern BOTAN_KDF_KDF1
+  , pattern BOTAN_KDF_TLS_12_PRF
+  , pattern BOTAN_KDF_X9_42_PRF
+  , pattern BOTAN_KDF_SP800_108_COUNTER
+  , pattern BOTAN_KDF_SP800_108_FEEDBACK
+  , pattern BOTAN_KDF_SP800_108_PIPELINE
+  , pattern BOTAN_KDF_SP800_56A
+  , pattern BOTAN_KDF_SP800_56C
+  , botan_kdf
+  ) where
 
-import Botan.Bindings.Prelude
+import           Botan.Bindings.ConstPtr
+import           Data.String
+import           Data.Word
+import           Foreign.C.Types
+import           Foreign.Ptr
 
 pattern BOTAN_KDF_HKDF
     ,   BOTAN_KDF_HKDF_EXTRACT
diff --git a/src/Botan/Bindings/KeyWrap.hs b/src/Botan/Bindings/KeyWrap.hs
--- a/src/Botan/Bindings/KeyWrap.hs
+++ b/src/Botan/Bindings/KeyWrap.hs
@@ -24,9 +24,15 @@
 
 {-# LANGUAGE CApiFFI #-}
 
-module Botan.Bindings.KeyWrap where
+module Botan.Bindings.KeyWrap (
+    botan_nist_kw_enc
+  , botan_nist_kw_dec
+  ) where
 
-import Botan.Bindings.Prelude
+import           Botan.Bindings.ConstPtr
+import           Data.Word
+import           Foreign.C.Types
+import           Foreign.Ptr
 
 foreign import capi safe "botan/ffi.h botan_nist_kw_enc"
     botan_nist_kw_enc
diff --git a/src/Botan/Bindings/MAC.hs b/src/Botan/Bindings/MAC.hs
--- a/src/Botan/Bindings/MAC.hs
+++ b/src/Botan/Bindings/MAC.hs
@@ -35,11 +35,39 @@
 - Finalize the MAC computation.
 -}
 
-{-# LANGUAGE CApiFFI #-}
+{-# LANGUAGE CApiFFI           #-}
+{-# LANGUAGE OverloadedStrings #-}
 
-module Botan.Bindings.MAC where
+module Botan.Bindings.MAC (
+    BotanMACStruct
+  , BotanMAC (..)
+  , botan_mac_destroy
 
-import Botan.Bindings.Prelude
+  , pattern BOTAN_MAC_CMAC
+  , pattern BOTAN_MAC_GMAC
+  , pattern BOTAN_MAC_HMAC
+  , pattern BOTAN_MAC_Poly1305
+  , pattern BOTAN_MAC_SipHash
+  , pattern BOTAN_MAC_X9_19_MAC
+
+  , botan_mac_init
+  , botan_mac_output_length
+  , botan_mac_set_key
+  , botan_mac_set_nonce
+  , botan_mac_update
+  , botan_mac_final
+  , botan_mac_clear
+  , botan_mac_name
+  , botan_mac_get_keyspec
+  ) where
+
+import           Botan.Bindings.ConstPtr
+import           Data.String
+import           Data.Word
+import           Foreign.C.Types
+import           Foreign.ForeignPtr
+import           Foreign.Ptr
+import           Foreign.Storable
 
 -- | Opaque MAC struct
 data {-# CTYPE "botan/ffi.h" "struct botan_mac_struct" #-} BotanMACStruct
diff --git a/src/Botan/Bindings/MPI.hs b/src/Botan/Bindings/MPI.hs
--- a/src/Botan/Bindings/MPI.hs
+++ b/src/Botan/Bindings/MPI.hs
@@ -11,10 +11,57 @@
 
 {-# LANGUAGE CApiFFI #-}
 
-module Botan.Bindings.MPI where
+module Botan.Bindings.MPI (
+    BotanMPStruct
+  , BotanMP (..)
+  , botan_mp_destroy
+  , botan_mp_init
+  , botan_mp_to_hex
+  , botan_mp_to_str
+  , botan_mp_clear
+  , botan_mp_set_from_int
+  , botan_mp_set_from_mp
+  , botan_mp_set_from_str
+  , botan_mp_set_from_radix_str
+  , botan_mp_num_bits
+  , botan_mp_num_bytes
+  , botan_mp_to_bin
+  , botan_mp_from_bin
+  , botan_mp_to_uint32
+  , botan_mp_is_positive
+  , botan_mp_is_negative
+  , botan_mp_flip_sign
+  , botan_mp_is_zero
+  , botan_mp_add_u32
+  , botan_mp_sub_u32
+  , botan_mp_add
+  , botan_mp_sub
+  , botan_mp_mul
+  , botan_mp_div
+  , botan_mp_mod_mul
+  , botan_mp_equal
+  , botan_mp_cmp
+  , botan_mp_swap
+  , botan_mp_powmod
+  , botan_mp_lshift
+  , botan_mp_rshift
+  , botan_mp_mod_inverse
+  , botan_mp_rand_bits
+  , botan_mp_rand_range
+  , botan_mp_gcd
+  , botan_mp_is_prime
+  , botan_mp_get_bit
+  , botan_mp_set_bit
+  , botan_mp_clear_bit
+  ) where
 
-import Botan.Bindings.Prelude
-import Botan.Bindings.RNG
+import           Botan.Bindings.ConstPtr
+import           Botan.Bindings.RNG
+import           Data.Word
+import           Foreign.C.Types
+import           Foreign.ForeignPtr
+import           Foreign.Ptr
+import           Foreign.Storable
 
 -- | Opaque MP struct
 data {-# CTYPE "botan/ffi.h" "struct botan_mp_struct" #-} BotanMPStruct
diff --git a/src/Botan/Bindings/Prelude.hs b/src/Botan/Bindings/Prelude.hs
deleted file mode 100644
--- a/src/Botan/Bindings/Prelude.hs
+++ /dev/null
@@ -1,66 +0,0 @@
-{-# LANGUAGE CApiFFI
-           , CPP
-           #-}
-
-module Botan.Bindings.Prelude
-( module Prelude
--- , module Data.ByteString
-, module Data.String
-, module Data.Word
-, module System.IO
-, module Foreign.C.String
-, module Foreign.C.Types
-, module Foreign.ForeignPtr
-, module Foreign.Marshal.Alloc
-, module Foreign.Marshal.Array
-, module Foreign.Ptr
-, module Foreign.Storable
-, ConstPtr(..)
-) where
-
-import Prelude
-
--- import Data.ByteString (ByteString)
-import Data.String (IsString(..))
-import Data.Word
-
-import System.IO
-
-import Foreign.C.String
-import Foreign.C.Types
-import Foreign.ForeignPtr
-import Foreign.Marshal.Alloc
-import Foreign.Marshal.Array
-import Foreign.Ptr
-import Foreign.Storable
-
-
-#if MIN_VERSION_base (4,18,0)
-import Foreign.C.ConstPtr
-#else
-import Data.Data
-import Data.Kind
-#endif
-
-#if !(MIN_VERSION_base (4,18,0))
-
--- NOTE: Taken from Foreign.C.ConstPtr, more or less
--- NOTE: Raises a warning on older base / compilers if the shim
---       is a `newtype` instead of a `type`, because the special
---       logic for const pointers didn't exist yet
--- SEE: https://gitlab.haskell.org/ghc/ghc/-/issues/22043
--- AFFECTS:
---  botan_error_description
---  botan_error_last_exception_message
---  botan_x509_cert_validation_status
---  botan_version_string
-type ConstPtr :: Type -> Type
-type role ConstPtr phantom
-newtype ConstPtr a = ConstPtr { unConstPtr :: Ptr a }
-    deriving stock (Data)
-    deriving newtype (Eq, Ord, Storable)
-
-instance Show (ConstPtr a) where
-    showsPrec d (ConstPtr p) = showParen (d > 10) $ showString "ConstPtr " . showsPrec 11 p
-
-#endif
diff --git a/src/Botan/Bindings/PubKey.hsc b/src/Botan/Bindings/PubKey.hsc
--- a/src/Botan/Bindings/PubKey.hsc
+++ b/src/Botan/Bindings/PubKey.hsc
@@ -13,13 +13,144 @@
 -}
 
 {-# LANGUAGE CApiFFI #-}
+{-# LANGUAGE OverloadedStrings #-}
 
-module Botan.Bindings.PubKey where
+module Botan.Bindings.PubKey (
+    BotanPrivKeyStruct
+  , BotanPrivKey (..)
+  , botan_privkey_destroy
+  , pattern BOTAN_PK_RSA
+  , pattern BOTAN_PK_SM2
+  , pattern BOTAN_PK_ELGAMAL
+  , pattern BOTAN_PK_DSA
+  , pattern BOTAN_PK_ECDSA
+  , pattern BOTAN_PK_ECKCDSA
+  , pattern BOTAN_PK_ECGDSA
+  , pattern BOTAN_PK_GOST_34_10
+  , pattern BOTAN_PK_ED25519
+  , pattern BOTAN_PK_XMSS
+  , pattern BOTAN_PK_DH
+  , pattern BOTAN_PK_ECDH
+  , pattern BOTAN_PK_CURVE25519
+  , pattern BOTAN_PK_DILITHIUM
+  , pattern BOTAN_PK_KYBER
+  , pattern BOTAN_PK_MCELIECE
 
+  , pattern BOTAN_XMSS_SHA2_10_256
+  , pattern BOTAN_XMSS_SHA2_16_256
+  , pattern BOTAN_XMSS_SHA2_20_256
+  , pattern BOTAN_XMSS_SHA2_10_512
+  , pattern BOTAN_XMSS_SHA2_16_512
+  , pattern BOTAN_XMSS_SHA2_20_512
+  , pattern BOTAN_XMSS_SHAKE_10_256
+  , pattern BOTAN_XMSS_SHAKE_16_256
+  , pattern BOTAN_XMSS_SHAKE_20_256
+  , pattern BOTAN_XMSS_SHAKE_10_512
+  , pattern BOTAN_XMSS_SHAKE_16_512
+  , pattern BOTAN_XMSS_SHAKE_20_512
+
+  , pattern BOTAN_ECGROUP_SECP_160_K1
+  , pattern BOTAN_ECGROUP_SECP_160_R1
+  , pattern BOTAN_ECGROUP_SECP_160_R2
+  , pattern BOTAN_ECGROUP_SECP_192_K1
+  , pattern BOTAN_ECGROUP_SECP_192_R1
+  , pattern BOTAN_ECGROUP_SECP_224_K1
+  , pattern BOTAN_ECGROUP_SECP_224_R1
+  , pattern BOTAN_ECGROUP_SECP_256_K1
+  , pattern BOTAN_ECGROUP_SECP_256_R1
+  , pattern BOTAN_ECGROUP_SECP_384_R1
+  , pattern BOTAN_ECGROUP_SECP_521_R1
+  , pattern BOTAN_ECGROUP_BRAINPOOL_160_R1
+  , pattern BOTAN_ECGROUP_BRAINPOOL_192_R1
+  , pattern BOTAN_ECGROUP_BRAINPOOL_224_R1
+  , pattern BOTAN_ECGROUP_BRAINPOOL_256_R1
+  , pattern BOTAN_ECGROUP_BRAINPOOL_320_R1
+  , pattern BOTAN_ECGROUP_BRAINPOOL_384_R1
+  , pattern BOTAN_ECGROUP_BRAINPOOL_512_R1
+  , pattern BOTAN_ECGROUP_X962_P192_V2
+  , pattern BOTAN_ECGROUP_X962_P192_V3
+  , pattern BOTAN_ECGROUP_X962_P239_V1
+  , pattern BOTAN_ECGROUP_X962_P239_V2
+  , pattern BOTAN_ECGROUP_X962_P239_V3
+  , pattern BOTAN_ECGROUP_GOST_256A
+  , pattern BOTAN_ECGROUP_GOST_512A
+  , pattern BOTAN_ECGROUP_FRP_256_V1
+  , pattern BOTAN_ECGROUP_SM2_P256_V1
+
+  , pattern BOTAN_DLGROUP_FFDHE_IETF_2048
+  , pattern BOTAN_DLGROUP_FFDHE_IETF_3072
+  , pattern BOTAN_DLGROUP_FFDHE_IETF_4096
+  , pattern BOTAN_DLGROUP_FFDHE_IETF_6144
+  , pattern BOTAN_DLGROUP_FFDHE_IETF_8192
+  , pattern BOTAN_DLGROUP_MODP_IETF_1024
+  , pattern BOTAN_DLGROUP_MODP_IETF_1536
+  , pattern BOTAN_DLGROUP_MODP_IETF_2048
+  , pattern BOTAN_DLGROUP_MODP_IETF_3072
+  , pattern BOTAN_DLGROUP_MODP_IETF_4096
+  , pattern BOTAN_DLGROUP_MODP_IETF_6144
+  , pattern BOTAN_DLGROUP_MODP_IETF_8192
+  , pattern BOTAN_DLGROUP_MODP_SRP_1024
+  , pattern BOTAN_DLGROUP_MODP_SRP_1536
+  , pattern BOTAN_DLGROUP_MODP_SRP_2048
+  , pattern BOTAN_DLGROUP_MODP_SRP_3072
+  , pattern BOTAN_DLGROUP_MODP_SRP_4096
+  , pattern BOTAN_DLGROUP_MODP_SRP_6144
+  , pattern BOTAN_DLGROUP_MODP_SRP_8192
+  , pattern BOTAN_DLGROUP_DSA_JCE_1024
+  , pattern BOTAN_DLGROUP_DSA_BOTAN_2048
+  , pattern BOTAN_DLGROUP_DSA_BOTAN_3072
+
+  , pattern BOTAN_EME_RAW
+  , pattern BOTAN_EME_PKCS1_v1_5
+  , pattern BOTAN_EME_OAEP
+
+  , pattern BOTAN_MGF_MGF1
+  , botan_privkey_create
+  , pattern BOTAN_CHECK_KEY_NORMAL_TESTS
+  , pattern BOTAN_CHECK_KEY_EXPENSIVE_TESTS
+  , botan_privkey_check_key
+  , botan_privkey_load
+  , pattern BOTAN_PRIVKEY_EXPORT_FLAG_DER
+  , pattern BOTAN_PRIVKEY_EXPORT_FLAG_PEM
+  , botan_privkey_export
+  , botan_privkey_view_der
+  , botan_privkey_view_pem
+  , botan_privkey_algo_name
+  , botan_privkey_export_encrypted_pbkdf_msec
+  , botan_privkey_export_encrypted_pbkdf_iter
+  , botan_privkey_view_encrypted_der
+  , botan_privkey_view_encrypted_der_timed
+  , botan_privkey_view_encrypted_pem
+  , botan_privkey_view_encrypted_pem_timed
+  , botan_privkey_get_field
+  , BotanPubKeyStruct
+  , BotanPubKey (..)
+  , botan_pubkey_destroy
+  , botan_privkey_export_pubkey
+  , botan_pubkey_load
+  , pattern BOTAN_PUBKEY_EXPORT_FLAG_DER
+  , pattern BOTAN_PUBKEY_EXPORT_FLAG_PEM
+  , botan_pubkey_export
+  , botan_pubkey_view_der
+  , botan_pubkey_view_pem
+  , botan_pubkey_algo_name
+  , botan_pubkey_check_key
+  , botan_pubkey_estimated_strength
+  , botan_pubkey_fingerprint
+  , botan_pubkey_get_field
+  , botan_pubkey_view_ec_public_point
+  ) where
+
+import Botan.Bindings.ConstPtr
 import Botan.Bindings.MPI
-import Botan.Bindings.Prelude
 import Botan.Bindings.RNG
 import Botan.Bindings.View
+import Data.String
+import Data.Word
+import Foreign.C.Types
+import Foreign.ForeignPtr
+import Foreign.Ptr
+import Foreign.Storable
 
 #include <botan/ffi.h>
 
diff --git a/src/Botan/Bindings/PubKey/DH.hs b/src/Botan/Bindings/PubKey/DH.hs
--- a/src/Botan/Bindings/PubKey/DH.hs
+++ b/src/Botan/Bindings/PubKey/DH.hs
@@ -11,11 +11,15 @@
 
 {-# LANGUAGE CApiFFI #-}
 
-module Botan.Bindings.PubKey.DH where
+module Botan.Bindings.PubKey.DH (
+    botan_privkey_load_dh
+  , botan_pubkey_load_dh
+  ) where
 
-import Botan.Bindings.MPI
-import Botan.Bindings.Prelude
-import Botan.Bindings.PubKey
+import           Botan.Bindings.MPI
+import           Botan.Bindings.PubKey
+import           Foreign.C.Types
+import           Foreign.Ptr
 
 -- | Loads Diffie Hellman private key
 foreign import capi safe "botan/ffi.h botan_privkey_load_dh"
diff --git a/src/Botan/Bindings/PubKey/DSA.hs b/src/Botan/Bindings/PubKey/DSA.hs
--- a/src/Botan/Bindings/PubKey/DSA.hs
+++ b/src/Botan/Bindings/PubKey/DSA.hs
@@ -11,12 +11,17 @@
 
 {-# LANGUAGE CApiFFI #-}
 
-module Botan.Bindings.PubKey.DSA where
+module Botan.Bindings.PubKey.DSA (
+    botan_privkey_create_dsa
+  , botan_privkey_load_dsa
+  , botan_pubkey_load_dsa
+  ) where
 
-import Botan.Bindings.MPI
-import Botan.Bindings.Prelude
-import Botan.Bindings.PubKey
-import Botan.Bindings.RNG
+import           Botan.Bindings.MPI
+import           Botan.Bindings.PubKey
+import           Botan.Bindings.RNG
+import           Foreign.C.Types
+import           Foreign.Ptr
 
 {- |
 Generates DSA key pair. Gives to a caller control over key length
diff --git a/src/Botan/Bindings/PubKey/Decrypt.hsc b/src/Botan/Bindings/PubKey/Decrypt.hsc
--- a/src/Botan/Bindings/PubKey/Decrypt.hsc
+++ b/src/Botan/Bindings/PubKey/Decrypt.hsc
@@ -11,10 +11,23 @@
 
 {-# LANGUAGE CApiFFI #-}
 
-module Botan.Bindings.PubKey.Decrypt where
+module Botan.Bindings.PubKey.Decrypt (
+    BotanPKOpDecryptStruct
+  , BotanPKOpDecrypt (..)
+  , botan_pk_op_decrypt_destroy
+  , pattern BOTAN_PUBKEY_DECRYPT_FLAGS_NONE
+  , botan_pk_op_decrypt_create
+  , botan_pk_op_decrypt_output_length
+  , botan_pk_op_decrypt
+  ) where
 
-import Botan.Bindings.Prelude
+import Botan.Bindings.ConstPtr
 import Botan.Bindings.PubKey
+import Data.Word
+import Foreign.C.Types
+import Foreign.ForeignPtr
+import Foreign.Ptr
+import Foreign.Storable
 
 #include <botan/ffi.h>
 
diff --git a/src/Botan/Bindings/PubKey/ECDH.hs b/src/Botan/Bindings/PubKey/ECDH.hs
--- a/src/Botan/Bindings/PubKey/ECDH.hs
+++ b/src/Botan/Bindings/PubKey/ECDH.hs
@@ -11,11 +11,16 @@
 
 {-# LANGUAGE CApiFFI #-}
 
-module Botan.Bindings.PubKey.ECDH where
+module Botan.Bindings.PubKey.ECDH (
+    botan_pubkey_load_ecdh
+  , botan_privkey_load_ecdh
+  ) where
 
-import Botan.Bindings.MPI
-import Botan.Bindings.Prelude
-import Botan.Bindings.PubKey
+import           Botan.Bindings.ConstPtr
+import           Botan.Bindings.MPI
+import           Botan.Bindings.PubKey
+import           Foreign.C.Types
+import           Foreign.Ptr
 
 foreign import capi safe "botan/ffi.h botan_pubkey_load_ecdh"
     botan_pubkey_load_ecdh
diff --git a/src/Botan/Bindings/PubKey/ECDSA.hs b/src/Botan/Bindings/PubKey/ECDSA.hs
--- a/src/Botan/Bindings/PubKey/ECDSA.hs
+++ b/src/Botan/Bindings/PubKey/ECDSA.hs
@@ -11,11 +11,16 @@
 
 {-# LANGUAGE CApiFFI #-}
 
-module Botan.Bindings.PubKey.ECDSA where
+module Botan.Bindings.PubKey.ECDSA (
+    botan_privkey_load_ecdsa
+  , botan_pubkey_load_ecdsa
+  ) where
 
-import Botan.Bindings.MPI
-import Botan.Bindings.Prelude
-import Botan.Bindings.PubKey
+import           Botan.Bindings.ConstPtr
+import           Botan.Bindings.MPI
+import           Botan.Bindings.PubKey
+import           Foreign.C.Types
+import           Foreign.Ptr
 
 foreign import capi safe "botan/ffi.h botan_privkey_load_ecdsa"
     botan_privkey_load_ecdsa
diff --git a/src/Botan/Bindings/PubKey/Ed25519.hs b/src/Botan/Bindings/PubKey/Ed25519.hs
--- a/src/Botan/Bindings/PubKey/Ed25519.hs
+++ b/src/Botan/Bindings/PubKey/Ed25519.hs
@@ -11,10 +11,18 @@
 
 {-# LANGUAGE CApiFFI #-}
 
-module Botan.Bindings.PubKey.Ed25519 where
+module Botan.Bindings.PubKey.Ed25519 (
+    botan_privkey_load_ed25519
+  , botan_pubkey_load_ed25519
+  , botan_privkey_ed25519_get_privkey
+  , botan_pubkey_ed25519_get_pubkey
+  ) where
 
-import Botan.Bindings.Prelude
-import Botan.Bindings.PubKey
+import           Botan.Bindings.ConstPtr
+import           Botan.Bindings.PubKey
+import           Data.Word
+import           Foreign.C.Types
+import           Foreign.Ptr
 
 foreign import capi safe "botan/ffi.h botan_privkey_load_ed25519"
     botan_privkey_load_ed25519
diff --git a/src/Botan/Bindings/PubKey/ElGamal.hs b/src/Botan/Bindings/PubKey/ElGamal.hs
--- a/src/Botan/Bindings/PubKey/ElGamal.hs
+++ b/src/Botan/Bindings/PubKey/ElGamal.hs
@@ -11,12 +11,17 @@
 
 {-# LANGUAGE CApiFFI #-}
 
-module Botan.Bindings.PubKey.ElGamal where
+module Botan.Bindings.PubKey.ElGamal (
+    botan_privkey_create_elgamal
+  , botan_pubkey_load_elgamal
+  , botan_privkey_load_elgamal
+  ) where
 
-import Botan.Bindings.MPI
-import Botan.Bindings.Prelude
-import Botan.Bindings.PubKey
-import Botan.Bindings.RNG
+import           Botan.Bindings.MPI
+import           Botan.Bindings.PubKey
+import           Botan.Bindings.RNG
+import           Foreign.C.Types
+import           Foreign.Ptr
 
 {- |
 Generates ElGamal key pair. Caller has a control over key length
diff --git a/src/Botan/Bindings/PubKey/Encrypt.hsc b/src/Botan/Bindings/PubKey/Encrypt.hsc
--- a/src/Botan/Bindings/PubKey/Encrypt.hsc
+++ b/src/Botan/Bindings/PubKey/Encrypt.hsc
@@ -11,11 +11,24 @@
 
 {-# LANGUAGE CApiFFI #-}
 
-module Botan.Bindings.PubKey.Encrypt where
+module Botan.Bindings.PubKey.Encrypt (
+    BotanPKOpEncryptStruct
+  , BotanPKOpEncrypt (..)
+  , botan_pk_op_encrypt_destroy
+  , pattern BOTAN_PUBKEY_ENCRYPT_FLAGS_NONE
+  , botan_pk_op_encrypt_create
+  , botan_pk_op_encrypt_output_length
+  , botan_pk_op_encrypt
+  ) where
 
-import Botan.Bindings.Prelude
+import Botan.Bindings.ConstPtr
 import Botan.Bindings.PubKey
 import Botan.Bindings.RNG
+import Data.Word
+import Foreign.C.Types
+import Foreign.ForeignPtr
+import Foreign.Ptr
+import Foreign.Storable
 
 #include <botan/ffi.h>
 
diff --git a/src/Botan/Bindings/PubKey/KeyAgreement.hsc b/src/Botan/Bindings/PubKey/KeyAgreement.hsc
--- a/src/Botan/Bindings/PubKey/KeyAgreement.hsc
+++ b/src/Botan/Bindings/PubKey/KeyAgreement.hsc
@@ -11,11 +11,26 @@
 
 {-# LANGUAGE CApiFFI #-}
 
-module Botan.Bindings.PubKey.KeyAgreement where
+module Botan.Bindings.PubKey.KeyAgreement (
+    BotanPKOpKeyAgreementStruct
+  , BotanPKOpKeyAgreement (..)
+  , botan_pk_op_key_agreement_destroy
+  , pattern BOTAN_PUBKEY_KEY_AGREEMENT_FLAGS_NONE
+  , botan_pk_op_key_agreement_create
+  , botan_pk_op_key_agreement_export_public
+  , botan_pk_op_key_agreement_view_public
+  , botan_pk_op_key_agreement_size
+  , botan_pk_op_key_agreement
+  ) where
 
-import Botan.Bindings.Prelude
+import Botan.Bindings.ConstPtr
 import Botan.Bindings.PubKey
 import Botan.Bindings.View
+import Data.Word
+import Foreign.C.Types
+import Foreign.ForeignPtr
+import Foreign.Ptr
+import Foreign.Storable
 
 #include <botan/ffi.h>
 
diff --git a/src/Botan/Bindings/PubKey/KeyEncapsulation.hs b/src/Botan/Bindings/PubKey/KeyEncapsulation.hs
--- a/src/Botan/Bindings/PubKey/KeyEncapsulation.hs
+++ b/src/Botan/Bindings/PubKey/KeyEncapsulation.hs
@@ -11,11 +11,30 @@
 
 {-# LANGUAGE CApiFFI #-}
 
-module Botan.Bindings.PubKey.KeyEncapsulation where
+module Botan.Bindings.PubKey.KeyEncapsulation (
+    BotanPKOpKEMEncryptStruct
+  , BotanPKOpKEMEncrypt (..)
+  , botan_pk_op_kem_encrypt_destroy
+  , botan_pk_op_kem_encrypt_create
+  , botan_pk_op_kem_encrypt_shared_key_length
+  , botan_pk_op_kem_encrypt_encapsulated_key_length
+  , botan_pk_op_kem_encrypt_create_shared_key
+  , BotanPKOpKEMDecryptStruct
+  , BotanPKOpKEMDecrypt (..)
+  , botan_pk_op_kem_decrypt_destroy
+  , botan_pk_op_kem_decrypt_create
+  , botan_pk_op_kem_decrypt_shared_key_length
+  , botan_pk_op_kem_decrypt_shared_key
+  ) where
 
-import Botan.Bindings.Prelude
-import Botan.Bindings.PubKey
-import Botan.Bindings.RNG
+import           Botan.Bindings.ConstPtr
+import           Botan.Bindings.PubKey
+import           Botan.Bindings.RNG
+import           Data.Word
+import           Foreign.C.Types
+import           Foreign.ForeignPtr
+import           Foreign.Ptr
+import           Foreign.Storable
 
 -- | Opaque KEM encrypt struct
 data {-# CTYPE "botan/ffi.h" "struct botan_pk_op_kem_encrypt_struct" #-} BotanPKOpKEMEncryptStruct
diff --git a/src/Botan/Bindings/PubKey/RSA.hs b/src/Botan/Bindings/PubKey/RSA.hs
--- a/src/Botan/Bindings/PubKey/RSA.hs
+++ b/src/Botan/Bindings/PubKey/RSA.hs
@@ -11,11 +11,19 @@
 
 {-# LANGUAGE CApiFFI #-}
 
-module Botan.Bindings.PubKey.RSA where
+module Botan.Bindings.PubKey.RSA (
+    botan_privkey_load_rsa
+  , botan_privkey_load_rsa_pkcs1
+  , botan_privkey_rsa_get_privkey
+  , botan_pubkey_load_rsa
+  ) where
 
-import Botan.Bindings.MPI
-import Botan.Bindings.Prelude
-import Botan.Bindings.PubKey
+import           Botan.Bindings.ConstPtr
+import           Botan.Bindings.MPI
+import           Botan.Bindings.PubKey
+import           Data.Word
+import           Foreign.C.Types
+import           Foreign.Ptr
 
 foreign import capi safe "botan/ffi.h botan_privkey_load_rsa"
     botan_privkey_load_rsa
diff --git a/src/Botan/Bindings/PubKey/SM2.hs b/src/Botan/Bindings/PubKey/SM2.hs
--- a/src/Botan/Bindings/PubKey/SM2.hs
+++ b/src/Botan/Bindings/PubKey/SM2.hs
@@ -12,11 +12,18 @@
 
 {-# LANGUAGE CApiFFI #-}
 
-module Botan.Bindings.PubKey.SM2 where
+module Botan.Bindings.PubKey.SM2 (
+    botan_pubkey_load_sm2
+  , botan_privkey_load_sm2
+  , botan_pubkey_sm2_compute_za
+  ) where
 
-import Botan.Bindings.MPI
-import Botan.Bindings.Prelude
-import Botan.Bindings.PubKey
+import           Botan.Bindings.ConstPtr
+import           Botan.Bindings.MPI
+import           Botan.Bindings.PubKey
+import           Data.Word
+import           Foreign.C.Types
+import           Foreign.Ptr
 
 foreign import capi safe "botan/ffi.h botan_pubkey_load_sm2"
     botan_pubkey_load_sm2
diff --git a/src/Botan/Bindings/PubKey/Sign.hsc b/src/Botan/Bindings/PubKey/Sign.hsc
--- a/src/Botan/Bindings/PubKey/Sign.hsc
+++ b/src/Botan/Bindings/PubKey/Sign.hsc
@@ -11,11 +11,26 @@
 
 {-# LANGUAGE CApiFFI #-}
 
-module Botan.Bindings.PubKey.Sign where
+module Botan.Bindings.PubKey.Sign (
+    BotanPKOpSignStruct
+  , BotanPKOpSign (..)
+  , botan_pk_op_sign_destroy
+  , pattern BOTAN_PUBKEY_STD_FORMAT_SIGNATURE
+  , pattern BOTAN_PUBKEY_DER_FORMAT_SIGNATURE
+  , botan_pk_op_sign_create
+  , botan_pk_op_sign_output_length
+  , botan_pk_op_sign_update
+  , botan_pk_op_sign_finish
+  ) where
 
-import Botan.Bindings.Prelude
+import Botan.Bindings.ConstPtr
 import Botan.Bindings.PubKey
 import Botan.Bindings.RNG
+import Data.Word
+import Foreign.C.Types
+import Foreign.ForeignPtr
+import Foreign.Ptr
+import Foreign.Storable
 
 #include <botan/ffi.h>
 
diff --git a/src/Botan/Bindings/PubKey/Verify.hsc b/src/Botan/Bindings/PubKey/Verify.hsc
--- a/src/Botan/Bindings/PubKey/Verify.hsc
+++ b/src/Botan/Bindings/PubKey/Verify.hsc
@@ -11,20 +11,25 @@
 
 {-# LANGUAGE CApiFFI #-}
 
-module Botan.Bindings.PubKey.Verify
-( BotanPKOpVerifyStruct
-, BotanPKOpVerify(..)
-, botan_pk_op_verify_destroy
-, botan_pk_op_verify_create
-, botan_pk_op_verify_update
-, botan_pk_op_verify_finish
-, pattern BOTAN_PUBKEY_STD_FORMAT_SIGNATURE
-, pattern BOTAN_PUBKEY_DER_FORMAT_SIGNATURE
-) where
+module Botan.Bindings.PubKey.Verify (
+    BotanPKOpVerifyStruct
+  , BotanPKOpVerify (..)
+  , botan_pk_op_verify_destroy
+  , botan_pk_op_verify_create
+  , botan_pk_op_verify_update
+  , botan_pk_op_verify_finish
+  , pattern BOTAN_PUBKEY_STD_FORMAT_SIGNATURE
+  , pattern BOTAN_PUBKEY_DER_FORMAT_SIGNATURE
+  ) where
 
-import Botan.Bindings.Prelude
+import Botan.Bindings.ConstPtr
 import Botan.Bindings.PubKey
 import Botan.Bindings.PubKey.Sign
+import Data.Word
+import Foreign.C.Types
+import Foreign.ForeignPtr
+import Foreign.Ptr
+import Foreign.Storable
 
 -- | Opaque verify struct
 data {-# CTYPE "botan/ffi.h" "struct botan_pk_op_verify_struct" #-} BotanPKOpVerifyStruct
diff --git a/src/Botan/Bindings/PubKey/X25519.hs b/src/Botan/Bindings/PubKey/X25519.hs
--- a/src/Botan/Bindings/PubKey/X25519.hs
+++ b/src/Botan/Bindings/PubKey/X25519.hs
@@ -11,10 +11,18 @@
 
 {-# LANGUAGE CApiFFI #-}
 
-module Botan.Bindings.PubKey.X25519 where
+module Botan.Bindings.PubKey.X25519 (
+    botan_privkey_load_x25519
+  , botan_pubkey_load_x25519
+  , botan_privkey_x25519_get_privkey
+  , botan_pubkey_x25519_get_pubkey
+  ) where
 
-import Botan.Bindings.Prelude
-import Botan.Bindings.PubKey
+import           Botan.Bindings.ConstPtr
+import           Botan.Bindings.PubKey
+import           Data.Word
+import           Foreign.C.Types
+import           Foreign.Ptr
 
 foreign import capi safe "botan/ffi.h botan_privkey_load_x25519"
     botan_privkey_load_x25519
diff --git a/src/Botan/Bindings/PwdHash.hs b/src/Botan/Bindings/PwdHash.hs
--- a/src/Botan/Bindings/PwdHash.hs
+++ b/src/Botan/Bindings/PwdHash.hs
@@ -8,62 +8,160 @@
 Stability   : experimental
 Portability : POSIX
 
-Derive a key from a passphrase
+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 CApiFFI           #-}
+{-# LANGUAGE OverloadedStrings #-}
 
-module Botan.Bindings.PwdHash where
+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.Prelude
+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_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"
-pattern BOTAN_PBKDF_ARGON2ID = "Argon2id"
-pattern BOTAN_PBKDF_BCRYPT_PBKDF = "Bcrypt-PBKDF"
-pattern BOTAN_PBKDF_OPENPGP_S2K = "OpenPGP-S2K"
 
--- | Derive a key from a passphrase using algorithm-specific 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
+-- |
+-- >>> BOTAN_PBKDF_ARGON2ID @String
+-- "Argon2id"
+pattern BOTAN_PBKDF_ARGON2ID = "Argon2id"
 
+-- |
+-- >>> BOTAN_PBKDF_BCRYPT_PBKDF @String
+-- "Bcrypt-PBKDF"
+pattern BOTAN_PBKDF_BCRYPT_PBKDF = "Bcrypt-PBKDF"
 
--- | Derive a key from a passphrase using parameters generated over a specific duration
-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 password hash parameter
-        -> Ptr CSize       -- ^ __param2__: will be set to the second password hash parameter
-        -> Ptr CSize       -- ^ __param3__: will be set to the third password hash parameter
-        -> 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
+-- |
+-- >>> BOTAN_PBKDF_OPENPGP_S2K @String
+-- "OpenPGP-S2K"
+pattern BOTAN_PBKDF_OPENPGP_S2K = "OpenPGP-S2K"
diff --git a/src/Botan/Bindings/RNG.hs b/src/Botan/Bindings/RNG.hs
--- a/src/Botan/Bindings/RNG.hs
+++ b/src/Botan/Bindings/RNG.hs
@@ -9,10 +9,39 @@
 Portability : POSIX
 -}
 
-{-# LANGUAGE CApiFFI #-}
+{-# LANGUAGE CApiFFI           #-}
+{-# LANGUAGE OverloadedStrings #-}
 
-module Botan.Bindings.RNG where
-import Botan.Bindings.Prelude
+module Botan.Bindings.RNG (
+    BotanRNGStruct
+  , BotanRNG (..)
+  , botan_rng_destroy
+  , pattern BOTAN_RNG_TYPE_SYSTEM
+  , pattern BOTAN_RNG_TYPE_USER
+  , pattern BOTAN_RNG_TYPE_USER_THREADSAFE
+  , pattern BOTAN_RNG_TYPE_RDRAND
+  , botan_rng_init
+  , BotanRNGGetCallback
+  , mallocBotanRNGGetCallbackFunPtr
+  , BotanRNGAddEntropyCallback
+  , mallocBotanRNGAddEntropyCallbackFunPtr
+  , BotanRNGDestroyCallback
+  , mallocBotanRNGDestroyCallbackFunPtr
+  , botan_rng_init_custom
+  , botan_rng_get
+  , botan_system_rng_get
+  , botan_rng_reseed
+  , botan_rng_reseed_from_rng
+  , botan_rng_add_entropy
+  ) where
+
+import           Botan.Bindings.ConstPtr
+import           Data.String
+import           Data.Word
+import           Foreign.C.Types
+import           Foreign.ForeignPtr
+import           Foreign.Ptr
+import           Foreign.Storable
 
 -- | Opaque RNG struct
 data {-# CTYPE "botan/ffi.h" "struct botan_rng_struct" #-} BotanRNGStruct
diff --git a/src/Botan/Bindings/SRP6.hs b/src/Botan/Bindings/SRP6.hs
--- a/src/Botan/Bindings/SRP6.hs
+++ b/src/Botan/Bindings/SRP6.hs
@@ -8,111 +8,124 @@
 Stability   : experimental
 Portability : POSIX
 
-The library contains an implementation of the SRP6-a password
-authenticated key exchange protocol.
-
-A SRP client provides what is called a SRP verifier to the server.
-This verifier is based on a password, but the password cannot be
-easily derived from the verifier (however brute force attacks are
-possible). Later, the client and server can perform an SRP exchange,
-which results in a shared secret key. This key can be used for
-mutual authentication and/or encryption.
-
-SRP works in a discrete logarithm group. Special parameter sets for
-SRP6 are defined, denoted in the library as “modp/srp/<size>”, for
-example “modp/srp/2048”.
-
-Warning
-
-While knowledge of the verifier does not easily allow an attacker to
-get the raw password, they could still use the verifier to impersonate
-the server to the client, so verifiers should be protected as carefully
-as a plaintext password would be.
+This module is based on the [Secure Remote
+Password](https://botan.randombit.net/handbook/api_ref/srp.html) section of the
+C++ API reference.
 -}
 
 {-# LANGUAGE CApiFFI #-}
 
-module Botan.Bindings.SRP6 where
+module Botan.Bindings.SRP6 (
+    BotanSRP6ServerSessionStruct
+  , BotanSRP6ServerSession (..)
+  , botan_srp6_server_session_destroy
+  , botan_srp6_server_session_init
+  , botan_srp6_server_session_step1
+  , botan_srp6_server_session_step2
+  , botan_srp6_generate_verifier
+  , botan_srp6_client_agree
+  , botan_srp6_group_size
+  ) where
 
-import Botan.Bindings.Prelude
-import Botan.Bindings.RNG
+import           Botan.Bindings.ConstPtr
+import           Botan.Bindings.RNG
+import           Data.Word
+import           Foreign.C.Types
+import           Foreign.ForeignPtr
+import           Foreign.Ptr
+import           Foreign.Storable
 
 -- | Opaque SRP-6 server session struct
 data {-# CTYPE "botan/ffi.h" "struct botan_srp6_server_session_struct" #-} BotanSRP6ServerSessionStruct
 
--- | Botan SRP-6 server session object
+-- | SRP-6 server session object
 newtype {-# CTYPE "botan/ffi.h" "botan_srp6_server_session_t" #-} BotanSRP6ServerSession
-    = MkBotanSRP6ServerSession { runBotanSRP6ServerSession :: Ptr BotanSRP6ServerSessionStruct }
-        deriving newtype (Eq, Ord, Storable)
+  = MkBotanSRP6ServerSession { runBotanSRP6ServerSession :: Ptr BotanSRP6ServerSessionStruct }
+      deriving newtype (Eq, Ord, Storable)
 
 -- | Frees all resources of the SRP-6 server session object
+--
+-- NOTE: this a binding to the /address/ of the
+-- @botan_srp6_server_session_destroy@ C function.
 foreign import capi safe "botan/ffi.h &botan_srp6_server_session_destroy"
-    botan_srp6_server_session_destroy
-        :: FinalizerPtr BotanSRP6ServerSessionStruct
+  botan_srp6_server_session_destroy
+    :: FinalizerPtr BotanSRP6ServerSessionStruct
 
 -- | Initialize an SRP-6 server session object
 foreign import capi safe "botan/ffi.h botan_srp6_server_session_init"
-    botan_srp6_server_session_init
-        :: Ptr BotanSRP6ServerSession -- ^ __srp6__: SRP-6 server session object
-        -> IO CInt
+  botan_srp6_server_session_init
+    :: Ptr BotanSRP6ServerSession -- ^ __srp6__: SRP-6 server session object
+    -> IO CInt
 
--- | SRP-6 Server side step 1: Generate a server B-value
+-- | SRP-6 Server side step 1
+--
+-- NOTE: this function should be not be invoked twice on the same server
+-- session. Regardless of the result of the first invocation, the second
+-- invocation will result in an error. See
+-- https://github.com/randombit/botan/issues/5112 for more information. If a
+-- second invocation can not be prevented, try it on a newly initialised server
+-- session instead.
 foreign import capi safe "botan/ffi.h botan_srp6_server_session_step1"
-    botan_srp6_server_session_step1
-        :: BotanSRP6ServerSession   -- ^ __srp6__: SRP-6 server session object
-        -> ConstPtr Word8           -- ^ __verifier[]__: the verification value saved from client registration
-        -> CSize                    -- ^ __verifier_len__: SRP-6 verifier value length
-        -> ConstPtr CChar           -- ^ __group_id__: the SRP group id
-        -> ConstPtr CChar           -- ^ __hash_id__: the SRP hash in use
-        -> BotanRNG                 -- ^ __rng_obj__: a random number generator object
-        -> Ptr Word8                -- ^ __B_pub[]__: out buffer to store the SRP-6 B value
-        -> Ptr CSize                -- ^ __B_pub_len__: SRP-6 B value length
-        -> IO CInt                  -- ^ 0 on success, negative on failure
+  botan_srp6_server_session_step1
+    :: BotanSRP6ServerSession -- ^ __srp6__: SRP-6 server session object
+    -> ConstPtr Word8         -- ^ __verifier[]__: the verification value saved from client registration
+    -> CSize                  -- ^ __verifier_len__: SRP-6 verifier value length
+    -> ConstPtr CChar         -- ^ __group_id__: the SRP group id
+    -> ConstPtr CChar         -- ^ __hash_id__: the SRP hash in use
+    -> BotanRNG               -- ^ __rng_obj__: a random number generator object
+    -> Ptr Word8              -- ^ __B_pub[]__: out buffer to store the SRP-6 B value
+    -> Ptr CSize              -- ^ __B_pub_len__: SRP-6 B value length
+    -> IO CInt                -- ^ 0 on success, negative on failure
 
--- | SRP-6 Server side step 2:  Generate the server shared key
+-- | SRP-6 Server side step 2
 foreign import capi safe "botan/ffi.h botan_srp6_server_session_step2"
-    botan_srp6_server_session_step2
-        :: BotanSRP6ServerSession   -- ^ __srp6__: SRP-6 server session object
-        -> ConstPtr Word8           -- ^ __A[]__: the client's value
-        -> CSize                    -- ^ __A_len__: the client's value length
-        -> Ptr Word8                -- ^ __key[]__: out buffer to store the symmetric key value
-        -> Ptr CSize                -- ^ __key_len__: symmetric key length
-        -> IO CInt                  -- ^ 0 on success, negative on failure
+  botan_srp6_server_session_step2
+    :: BotanSRP6ServerSession -- ^ __srp6__: SRP-6 server session object
+    -> ConstPtr Word8         -- ^ __A[]__: the client's value
+    -> CSize                  -- ^ __A_len__: the client's value length
+    -> Ptr Word8              -- ^ __key[]__: out buffer to store the symmetric key value
+    -> Ptr CSize              -- ^ __key_len__: symmetric key length
+    -> IO CInt                -- ^ 0 on success, negative on failure
 
--- | SRP-6 Client side step 1:  Generate a new SRP-6 verifier
+-- | Generate a new SRP-6 verifier
 foreign import capi safe "botan/ffi.h botan_srp6_generate_verifier"
-    botan_srp6_generate_verifier
-        :: ConstPtr CChar -- ^ __identifier__: a username or other client identifier
-        -> ConstPtr CChar -- ^ __password__: the secret used to authenticate user
-        -> ConstPtr Word8 -- ^ __salt[]__: a randomly chosen value, at least 128 bits long
-        -> CSize          -- ^ __salt_len__: the length of salt
-        -> ConstPtr CChar -- ^ __group_id__: specifies the shared SRP group
-        -> ConstPtr CChar -- ^ __hash_id__: specifies a secure hash function
-        -> Ptr Word8      -- ^ __verifier[]__: out buffer to store the SRP-6 verifier value
-        -> Ptr CSize      -- ^ __verifier_len__: SRP-6 verifier value length
-        -> IO CInt        -- ^ 0 on success, negative on failure
+  botan_srp6_generate_verifier
+    :: ConstPtr CChar -- ^ __identifier__: a username or other client identifier
+    -> ConstPtr CChar -- ^ __password__: the secret used to authenticate user
+    -> ConstPtr Word8 -- ^ __salt[]__: a randomly chosen value, at least 128 bits long
+    -> CSize          -- ^ __salt_len__: the length of salt
+    -> ConstPtr CChar -- ^ __group_id__: specifies the shared SRP group
+    -> ConstPtr CChar -- ^ __hash_id__: specifies a secure hash function
+    -> Ptr Word8      -- ^ __verifier[]__: out buffer to store the SRP-6 verifier value
+    -> Ptr CSize      -- ^ __verifier_len__: SRP-6 verifier value length
+    -> IO CInt        -- ^ 0 on success, negative on failure
 
--- | SRP6a Client side step 2:  Generate a client A-value and the client shared key
+-- | SRP6a Client side
 foreign import capi safe "botan/ffi.h botan_srp6_client_agree"
-    botan_srp6_client_agree
-        :: ConstPtr CChar -- ^ __username__: the username we are attempting login for
-        -> ConstPtr CChar -- ^ __password__: the password we are attempting to use
-        -> ConstPtr CChar -- ^ __group_id__: specifies the shared SRP group
-        -> ConstPtr CChar -- ^ __hash_id__: specifies a secure hash function
-        -> ConstPtr Word8 -- ^ __salt[]__: is the salt value sent by the server
-        -> CSize          -- ^ __salt_len__: the length of salt
-        -> ConstPtr Word8 -- ^ __uint8_t__: B[] is the server's public value
-        -> CSize          -- ^ __B_len__: is the server's public value length
-        -> BotanRNG       -- ^ __rng_obj__: is a random number generator object
-        -> Ptr Word8      -- ^ __A[]__: out buffer to store the SRP-6 A value
-        -> Ptr CSize      -- ^ __A_len__: SRP-6 A verifier value length
-        -> Ptr Word8      -- ^ __K[]__: out buffer to store the symmetric value
-        -> Ptr CSize      -- ^ __K_len__: symmetric key length
-        -> IO CInt        -- ^ 0 on success, negative on failure
+  botan_srp6_client_agree
+    :: ConstPtr CChar -- ^ __username__: the username we are attempting login for
+    -> ConstPtr CChar -- ^ __password__: the password we are attempting to use
+    -> ConstPtr CChar -- ^ __group_id__: specifies the shared SRP group
+    -> ConstPtr CChar -- ^ __hash_id__: specifies a secure hash function
+    -> ConstPtr Word8 -- ^ __salt[]__: is the salt value sent by the server
+    -> CSize          -- ^ __salt_len__: the length of salt
+    -> ConstPtr Word8 -- ^ __B[]__: is the server's public value
+    -> CSize          -- ^ __B_len__: is the server's public value length
+    -> BotanRNG       -- ^ __rng_obj__: is a random number generator object
+    -> Ptr Word8      -- ^ __A[]__: out buffer to store the SRP-6 A value
+    -> Ptr CSize      -- ^ __A_len__: SRP-6 A verifier value length
+    -> Ptr Word8      -- ^ __K[]__: out buffer to store the symmetric value
+    -> Ptr CSize      -- ^ __K_len__: symmetric key length
+    -> IO CInt        -- ^ 0 on success, negative on failure
 
 -- | Return the size, in bytes, of the prime associated with group_id
+--
+-- This function can be used to determine the size of output buffers for
+-- generated keys in the SRP6 algorithm. Such buffers need to be allocated
+-- before calling SRP6 functions. An example of such a buffer is the
+-- @verifier[]@ buffer in the 'botan_srp6_generate_verifier' function.
 foreign import capi safe "botan/ffi.h botan_srp6_group_size"
-    botan_srp6_group_size
-        :: ConstPtr CChar -- ^ __group_id__
-        -> Ptr CSize      -- ^ __group_p_bytes__
-        -> IO CInt
+  botan_srp6_group_size
+    :: ConstPtr CChar -- ^ __group_id__
+    -> Ptr CSize      -- ^ __group_p_bytes__
+    -> IO CInt
diff --git a/src/Botan/Bindings/TOTP.hs b/src/Botan/Bindings/TOTP.hs
--- a/src/Botan/Bindings/TOTP.hs
+++ b/src/Botan/Bindings/TOTP.hs
@@ -41,9 +41,21 @@
 
 {-# LANGUAGE CApiFFI #-}
 
-module Botan.Bindings.TOTP where
+module Botan.Bindings.TOTP (
+    BotanTOTPStruct
+  , BotanTOTP (..)
+  , botan_totp_destroy
+  , botan_totp_init
+  , botan_totp_generate
+  , botan_totp_check
+  ) where
 
-import Botan.Bindings.Prelude
+import           Botan.Bindings.ConstPtr
+import           Data.Word
+import           Foreign.C.Types
+import           Foreign.ForeignPtr
+import           Foreign.Ptr
+import           Foreign.Storable
 
 -- NOTE: RFC 6238
 
diff --git a/src/Botan/Bindings/Utility.hsc b/src/Botan/Bindings/Utility.hsc
--- a/src/Botan/Bindings/Utility.hsc
+++ b/src/Botan/Bindings/Utility.hsc
@@ -7,15 +7,33 @@
 Maintainer  : joris@well-typed.com, leo@apotheca.io
 Stability   : experimental
 Portability : POSIX
+
+This module is based on the [Utility
+Functions](https://botan.randombit.net/handbook/api_ref/ffi.html#utility-functions)
+section of the C Botan FFI documentation.
 -}
 
 {-# LANGUAGE CApiFFI #-}
 
-module Botan.Bindings.Utility where
+module Botan.Bindings.Utility (
+    botan_constant_time_compare
+  , botan_scrub_mem
+  , pattern BOTAN_FFI_HEX_UPPER_CASE
+  , pattern BOTAN_FFI_HEX_LOWER_CASE
+  , botan_hex_encode
+  , botan_hex_decode
+  , botan_base64_encode
+  , botan_base64_decode
+  ) where
 
-import Botan.Bindings.Prelude
+import Botan.Bindings.ConstPtr
+import Data.Word
+import Foreign.C.Types
+import Foreign.Ptr
 
 #include <botan/ffi.h>
+
+-- TODO: consider making bindings in this module unsafe. See issue #48.
 
 -- | Returns 0 if x[0..len] == y[0..len], -1 otherwise.
 foreign import capi safe "botan/ffi.h botan_constant_time_compare"
diff --git a/src/Botan/Bindings/Version.hs b/src/Botan/Bindings/Version.hs
--- a/src/Botan/Bindings/Version.hs
+++ b/src/Botan/Bindings/Version.hs
@@ -7,13 +7,29 @@
 Maintainer  : joris@well-typed.com, leo@apotheca.io
 Stability   : experimental
 Portability : POSIX
+
+This module is based on the
+[Versioning](https://botan.randombit.net/handbook/api_ref/ffi.html#versioning)
+section of the C Botan FFI documentation.
 -}
 
 {-# LANGUAGE CApiFFI #-}
 
-module Botan.Bindings.Version where
+module Botan.Bindings.Version (
+    botan_ffi_api_version
+  , botan_ffi_supports_api
+  , botan_version_string
+  , botan_version_major
+  , botan_version_minor
+  , botan_version_patch
+  , botan_version_datestamp
+  ) where
 
-import Botan.Bindings.Prelude
+import           Botan.Bindings.ConstPtr
+import           Data.Word
+import           Foreign.C.Types
+
+-- TODO: consider making these bindings unsafe. See issue #47.
 
 foreign import capi safe "botan/ffi.h botan_ffi_api_version"
     botan_ffi_api_version :: IO Word32
diff --git a/src/Botan/Bindings/View.hs b/src/Botan/Bindings/View.hs
--- a/src/Botan/Bindings/View.hs
+++ b/src/Botan/Bindings/View.hs
@@ -7,20 +7,39 @@
 Maintainer  : joris@well-typed.com, leo@apotheca.io
 Stability   : experimental
 Portability : POSIX
+
+This module is based on the [View
+Functions](https://botan.randombit.net/handbook/api_ref/ffi.html#view-functions)
+section of the C Botan FFI documentation.
 -}
 
 {-# LANGUAGE CApiFFI #-}
 
-module Botan.Bindings.View where
+module Botan.Bindings.View (
+    BotanViewContext
+    -- * View binary
+  , BotanViewBinFn
+  , BotanViewBinCallback
+  , mallocBotanViewBinCallback
+  , freeBotanViewBinCallback
+    -- * View string
+  , BotanViewStrFn
+  , BotanViewStrCallback
+  , mallocBotanViewStrCallback
+  , freeBotanViewStrCallback
+  ) where
 
-import Botan.Bindings.Prelude
+import           Botan.Bindings.ConstPtr
+import           Data.Word
+import           Foreign.C.Types
+import           Foreign.Ptr
 
--- View context
 
--- NOTE: If the type variable proves problematic, we will revert back to Ptr Void
 type BotanViewContext a = Ptr a
 
--- View binary
+{-------------------------------------------------------------------------------
+  View binary
+-------------------------------------------------------------------------------}
 
 type BotanViewBinFn ctx
     =   BotanViewContext ctx    -- ^ __view_ctx__: some application context
@@ -30,7 +49,7 @@
 
 type BotanViewBinCallback ctx = FunPtr (BotanViewBinFn ctx)
 
--- NOTE: "Wrapper stubs can't be used with CApiFFI."
+-- NOTE: Wrapper stubs can't be used with CApiFFI.
 foreign import ccall "wrapper"
     mallocBotanViewBinCallback
         :: BotanViewBinFn ctx
@@ -39,7 +58,9 @@
 freeBotanViewBinCallback :: BotanViewBinCallback ctx -> IO ()
 freeBotanViewBinCallback = freeHaskellFunPtr
 
--- View string
+{-------------------------------------------------------------------------------
+  View string
+-------------------------------------------------------------------------------}
 
 type BotanViewStrFn ctx
     =   BotanViewContext ctx    -- ^ __view_ctx__: some application context
@@ -49,7 +70,7 @@
 
 type BotanViewStrCallback ctx = FunPtr (BotanViewStrFn ctx)
 
--- NOTE: "Wrapper stubs can't be used with CApiFFI."
+-- NOTE: Wrapper stubs can't be used with CApiFFI.
 foreign import ccall "wrapper"
     mallocBotanViewStrCallback
         :: BotanViewStrFn ctx
diff --git a/src/Botan/Bindings/X509.hsc b/src/Botan/Bindings/X509.hsc
--- a/src/Botan/Bindings/X509.hsc
+++ b/src/Botan/Bindings/X509.hsc
@@ -21,11 +21,59 @@
 
 {-# LANGUAGE CApiFFI #-}
 
-module Botan.Bindings.X509 where
+module Botan.Bindings.X509 (
+    BotanX509CertStruct
+  , BotanX509Cert (..)
+  , botan_x509_cert_destroy
+  , botan_x509_cert_load
+  , botan_x509_cert_load_file
+  , botan_x509_cert_dup
+  , botan_x509_cert_get_time_starts
+  , botan_x509_cert_get_time_expires
+  , botan_x509_cert_not_before
+  , botan_x509_cert_not_after
+  , botan_x509_cert_get_fingerprint
+  , botan_x509_cert_get_serial_number
+  , botan_x509_cert_get_authority_key_id
+  , botan_x509_cert_get_subject_key_id
+  , botan_x509_cert_get_public_key_bits
+  , botan_x509_cert_view_public_key_bits
+  , botan_x509_cert_get_public_key
+  , botan_x509_cert_get_issuer_dn
+  , botan_x509_cert_get_subject_dn
+  , botan_x509_cert_to_string
+  , botan_x509_cert_view_as_string
+  , pattern NO_CONSTRAINTS
+  , pattern DIGITAL_SIGNATURE
+  , pattern NON_REPUDIATION
+  , pattern KEY_ENCIPHERMENT
+  , pattern DATA_ENCIPHERMENT
+  , pattern KEY_AGREEMENT
+  , pattern KEY_CERT_SIGN
+  , pattern CRL_SIGN
+  , pattern ENCIPHER_ONLY
+  , pattern DECIPHER_ONLY
+  , botan_x509_cert_allowed_usage
+  , botan_x509_cert_hostname_match
+  , botan_x509_cert_verify
+  , botan_x509_cert_validation_status
+  , BotanX509CRLStruct
+  , BotanX509CRL (..)
+  , botan_x509_crl_destroy
+  , botan_x509_crl_load_file
+  , botan_x509_crl_load
+  , botan_x509_is_revoked
+  , botan_x509_cert_verify_with_crl
+  ) where
 
-import Botan.Bindings.Prelude
+import Botan.Bindings.ConstPtr
 import Botan.Bindings.PubKey
 import Botan.Bindings.View
+import Data.Word
+import Foreign.C.Types
+import Foreign.ForeignPtr
+import Foreign.Ptr
+import Foreign.Storable
 
 #include <botan/ffi.h>
 
diff --git a/src/Botan/Bindings/X509/CA.hs b/src/Botan/Bindings/X509/CA.hs
deleted file mode 100644
--- a/src/Botan/Bindings/X509/CA.hs
+++ /dev/null
@@ -1,89 +0,0 @@
-module Botan.Bindings.X509.CA where
-
-import Botan.Bindings.Error
-import Botan.Bindings.Prelude
-import Botan.Bindings.MPI
-import Botan.Bindings.PubKey
-import Botan.Bindings.PubKey.Sign
-import Botan.Bindings.RNG
-import Botan.Bindings.X509
-import Botan.Bindings.X509.CSR
-import Botan.Bindings.X509.Extensions
-import Botan.Bindings.X509.Options
-
--- Certificate Authority
-data X509CAStruct
-type X509CAPtr = Ptr X509CAStruct
-
-foreign import ccall unsafe botan_x509_ca_create
-    :: Ptr X509CAPtr
-    -> X509CertPtr
-    -> PrivKeyPtr
-    -> Ptr CChar
-    -> RNGPtr
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_ca_create_padding
-    :: Ptr X509CAPtr
-    -> X509CertPtr
-    -> PrivKeyPtr
-    -> Ptr CChar
-    -> Ptr CChar
-    -> RNGPtr
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe "&botan_x509_ca_destroy" botan_x509_ca_destroy :: FinalizerPtr X509CAStruct
-
-foreign import ccall unsafe botan_x509_ca_sign_request
-    :: Ptr X509CertPtr
-    -> X509CAPtr
-    -> X509CSRPtr
-    -> RNGPtr
-    -> Word64
-    -> Word64
-    -> IO BotanErrorCode
-
--- foreign import ccall unsafe botan_x509_ca_sign_request_serial
---     :: Ptr X509CertPtr
---     -> X509CAPtr
---     -> X509CSRPtr
---     -> RNGPtr
---     -> MPPtr
---     -> Word64
---     -> Word64
---     -> IO BotanErrorCode
-
--- foreign import ccall unsafe botan_x509_ca_make_cert
---     :: Ptr X509CertPtr
---     -> SignPtr
---     -> RNGPtr
---     -> MPPtr
---     -> Ptr CChar
---     -> PubKeyPtr
---     -> Word64
---     -> Word64
---     -> Ptr Word8 -> CSize
---     -> Ptr Word8 -> CSize
---     -> X509ExtensionsPtr
---     -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_ca_make_cert_serial
-    :: Ptr X509CertPtr
-    -> SignPtr
-    -> RNGPtr
-    -> MPPtr
-    -> Ptr CChar
-    -> PubKeyPtr
-    -> Word64
-    -> Word64
-    -> Ptr Word8 -> CSize
-    -> Ptr Word8 -> CSize
-    -> X509ExtensionsPtr
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_ca_choose_extensions
-    :: Ptr X509ExtensionsPtr
-    -> X509CSRPtr
-    -> X509CertPtr
-    -> Ptr CChar
-    -> IO BotanErrorCode
diff --git a/src/Botan/Bindings/X509/CRL.hs b/src/Botan/Bindings/X509/CRL.hs
deleted file mode 100644
--- a/src/Botan/Bindings/X509/CRL.hs
+++ /dev/null
@@ -1,142 +0,0 @@
-module Botan.Bindings.X509.CRL where
-
-import Botan.Bindings.Error
-import Botan.Bindings.Prelude
-import Botan.Bindings.X509
-import Botan.Bindings.X509.Extensions
-
-
---
--- Certificate Revocation List
---
--- TODO: Eventually move the read-only CRL functions into here
-
-{-
-data X509CRLStruct
-type X509CRLPtr = Ptr X509CRLStruct
-
-foreign import ccall unsafe botan_x509_crl_load :: Ptr X509CRLPtr -> Ptr Word8 -> CSize -> IO BotanErrorCode
-foreign import ccall unsafe botan_x509_crl_load_file :: Ptr X509CRLPtr -> Ptr CChar -> IO BotanErrorCode
-foreign import ccall unsafe "&botan_x509_crl_destroy" botan_x509_crl_destroy :: FinalizerPtr X509CRLStruct
--- NOTE: Need to rename botan_x509_is_revoked to botan_x509_crl_is_revoked first
-foreign import ccall unsafe botan_x509_crl_is_revoked :: X509CRLPtr -> X509CertPtr -> IO BotanErrorCode
--}
-
-foreign import ccall unsafe botan_x509_crl_get_revoked
-    :: Ptr X509CRLEntryPtr -> Ptr CSize
-    -> X509CRLPtr
-    -> IO BotanErrorCode
-
--- NOTE: If we were to follow the pattern set in `botan_x509_cert_get_issuer_dn`
---  then this would merely be an accessor for a single value using key + index)
--- NOTE: We're keeping our own return-value-first style still though so keep that
---  difference in mind
-foreign import ccall unsafe botan_x509_crl_get_issuer_dn
-    :: Ptr Word8 -> Ptr CSize
-    -> X509CRLPtr
-    -> Ptr CChar
-    -> CSize
-    -> IO BotanErrorCode
--- With actual DN objects, we could just return the object:
-{-
-foreign import ccall unsafe botan_x509_crl_issuer_dn
-    :: Ptr X509DNPtr
-    -> X509CRLPtr
-    -> IO BotanErrorCode
--}
--- Probably should create a new pattern using  botan_foo_get_dn_attribute(?)
---  (make consistent with DN object accessors) and botan_foo_get_dn_object
-
-foreign import ccall unsafe botan_x509_crl_extensions
-    :: Ptr X509ExtensionsPtr
-    -> X509CRLPtr
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_crl_authority_key_id
-    :: Ptr Word8 -> Ptr CSize
-    -> X509CRLPtr
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_crl_serial_number
-    :: Ptr Word32
-    -> X509CRLPtr
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_crl_this_update
-    :: Ptr Word64
-    -> X509CRLPtr
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_crl_next_update
-    :: Ptr Word64
-    -> X509CRLPtr
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_crl_issuing_distribution_point
-    :: Ptr Word8 -> Ptr CSize
-    -> X509CRLPtr
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_crl_create_der
-    :: Ptr X509CRLPtr
-    -> Ptr Word8 -> CSize
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_crl_create
-    :: Ptr X509CRLPtr
-    -> Ptr Word8 -> CSize           -- Encodeed Issuer DN, not DN object
-    -> Word64                       -- this update
-    -> Word64                       -- next update
-    -> Ptr X509CRLEntryPtr -> CSize -- Entries
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_crl_add_entry
-    :: X509CRLPtr
-    -> X509CRLEntryPtr
-    -> IO BotanErrorCode
-
--- NOTE: A convenience function
-foreign import ccall unsafe botan_x509_crl_revoke_cert
-    :: X509CRLPtr
-    -> X509CertPtr
-    -> Word32   -- Reason
-    -> IO BotanErrorCode
-
---
--- Certificate Revocation List Entry
---
-
-data X509CRLEntryStruct
-type X509CRLEntryPtr = Ptr X509CRLEntryStruct
--- TODO: These functions are only bound to declarations, and the functions are currently not implemented
--- Do not use them yet, it will just crash
-
-foreign import ccall unsafe "&botan_x509_crl_entry_destroy" botan_x509_crl_entry_destroy :: FinalizerPtr X509CRLEntryStruct
-
-foreign import ccall unsafe botan_x509_crl_entry_create
-    :: Ptr X509CRLEntryPtr
-    -> X509CertPtr
-    -> Word32   -- Reason
-    -> IO BotanErrorCode
-
--- TODO: CRL_Entry PEM / BER encode / decode (and for CRL too)
-
-foreign import ccall unsafe botan_x509_crl_entry_get_serial_number
-    :: Ptr Word8 -> Ptr CSize
-    -> X509CRLEntryPtr
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_crl_entry_get_expire_time
-    :: Ptr Word64
-    -> X509CRLEntryPtr
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_crl_entry_get_reason_code
-    :: Ptr Word32
-    -> X509CRLEntryPtr
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_crl_entry_get_extensions
-    :: Ptr X509ExtensionsPtr
-    -> X509CRLEntryPtr
-    -> IO BotanErrorCode
diff --git a/src/Botan/Bindings/X509/CSR.hs b/src/Botan/Bindings/X509/CSR.hs
deleted file mode 100644
--- a/src/Botan/Bindings/X509/CSR.hs
+++ /dev/null
@@ -1,45 +0,0 @@
-module Botan.Bindings.X509.CSR where
-
-import Botan.Bindings.Error
-import Botan.Bindings.Prelude
--- import Botan.Bindings.MPI
-import Botan.Bindings.PubKey
--- import Botan.Bindings.PubKey.Sign
-import Botan.Bindings.RNG
-import Botan.Bindings.X509
-import Botan.Bindings.X509.Extensions
-import Botan.Bindings.X509.Options
-
--- Certificate Signing Request, rename to that / CSR at higher levels
-data X509CSRStruct
-type X509CSRPtr = Ptr X509CSRStruct
-
-foreign import ccall unsafe "&botan_x509_csr_destroy" botan_x509_csr_destroy :: FinalizerPtr X509CSRStruct
-
-foreign import ccall unsafe botan_x509_create_cert_req
-    :: Ptr X509CSRPtr
-    -> X509CertOptionsPtr
-    -> PrivKeyPtr
-    -> Ptr CChar
-    -> RNGPtr
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_csr_create
-    :: Ptr X509CSRPtr
-    -> PrivKeyPtr
-    -> Ptr Word8 -> CSize
-    -> X509ExtensionsPtr
-    -> Ptr CChar
-    -> RNGPtr
-    -> Ptr CChar
-    -> Ptr CChar
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_create_self_signed_cert
-    :: Ptr X509CertPtr
-    -> X509CertOptionsPtr
-    -> PrivKeyPtr
-    -> Ptr CChar
-    -> RNGPtr
-    -> IO BotanErrorCode
-
diff --git a/src/Botan/Bindings/X509/DN.hs b/src/Botan/Bindings/X509/DN.hs
deleted file mode 100644
--- a/src/Botan/Bindings/X509/DN.hs
+++ /dev/null
@@ -1,56 +0,0 @@
-module Botan.Bindings.X509.DN where
-
-import Botan.Bindings.Error
-import Botan.Bindings.Prelude
-import Botan.Bindings.X509
-
-data X509DNStruct
-type X509DNPtr = Ptr X509DNStruct
-
-foreign import ccall unsafe "&botan_x509_dn_destroy" botan_x509_dn_destroy :: FinalizerPtr X509DNStruct
-
-
-foreign import ccall unsafe botan_x509_dn_create
-    :: Ptr X509DNPtr
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_dn_create_from_multimap
-    :: Ptr X509DNPtr
-    -> Ptr Word8 -> Ptr CSize
-    -> Ptr Word8 -> Ptr CSize
-    -> CSize
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_dn_to_string
-    :: Ptr Word8 -> Ptr CSize
-    -> X509DNPtr
-    -> IO BotanErrorCode
-
--- NOTE: Returns a bool success code
-foreign import ccall unsafe botan_x509_dn_has_field
-    :: X509DNPtr
-    -> Ptr Word8 -> CSize
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_dn_get_first_attribute
-    :: Ptr Word8 -> Ptr CSize
-    -> X509DNPtr
-    -> Ptr Word8 -> CSize
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_dn_get_attribute
-    :: Ptr (Ptr Word8) -> Ptr CSize -> Ptr CSize
-    -> X509DNPtr
-    -> Ptr Word8 -> CSize
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_dn_contents
-    :: Ptr (Ptr Word8) -> Ptr CSize -> Ptr (Ptr Word8) -> Ptr CSize -> Ptr CSize
-    -> X509DNPtr
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_dn_add_attribute
-    :: X509DNPtr
-    -> Ptr Word8 -> CSize
-    -> Ptr Word8 -> CSize
-    -> IO BotanErrorCode
diff --git a/src/Botan/Bindings/X509/Extensions.hs b/src/Botan/Bindings/X509/Extensions.hs
deleted file mode 100644
--- a/src/Botan/Bindings/X509/Extensions.hs
+++ /dev/null
@@ -1,19 +0,0 @@
-module Botan.Bindings.X509.Extensions where
-
-import Botan.Bindings.Error
-import Botan.Bindings.Prelude
-import Botan.Bindings.X509
-
-data X509ExtensionStruct
-type X509ExtensionPtr = Ptr X509ExtensionStruct
-
-foreign import ccall unsafe "&botan_x509_cert_ext_destroy" botan_x509_cert_ext_destroy :: FinalizerPtr X509ExtensionStruct
-
-data X509ExtensionsStruct
-type X509ExtensionsPtr = Ptr X509ExtensionsStruct
-
-foreign import ccall unsafe "&botan_x509_exts_destroy" botan_x509_exts_destroy :: FinalizerPtr X509ExtensionsStruct
-
-
--- TODO: See C FFI for discussion on pending implementation
-
diff --git a/src/Botan/Bindings/X509/Options.hs b/src/Botan/Bindings/X509/Options.hs
deleted file mode 100644
--- a/src/Botan/Bindings/X509/Options.hs
+++ /dev/null
@@ -1,152 +0,0 @@
-module Botan.Bindings.X509.Options where
-
-import Botan.Bindings.Error
-import Botan.Bindings.Prelude
-import Botan.Bindings.X509
-import Botan.Bindings.X509.Extensions
-
-data X509CertOptionsStruct
-type X509CertOptionsPtr = Ptr X509CertOptionsStruct
-
-foreign import ccall unsafe "&botan_x509_cert_options_destroy" botan_x509_cert_options_destroy :: FinalizerPtr X509CertOptionsStruct
-
-foreign import ccall unsafe botan_x509_cert_options_create
-    :: Ptr X509CertOptionsPtr
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_cert_options_create_common
-    :: Ptr X509CertOptionsPtr
-    -> Ptr CChar
-    -> Ptr CChar
-    -> Ptr CChar
-    -> Ptr CChar
-    -> Word32
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_cert_options_set_common_name
-    :: X509CertOptionsPtr
-    -> Ptr CChar
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_cert_options_set_country
-    :: X509CertOptionsPtr
-    -> Ptr CChar
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_cert_options_set_organization
-    :: X509CertOptionsPtr
-    -> Ptr CChar
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_cert_options_set_org_unit
-    :: X509CertOptionsPtr
-    -> Ptr CChar
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_cert_options_set_more_org_units
-    :: X509CertOptionsPtr
-    -> Ptr (Ptr CChar) -> CSize
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_cert_options_set_locality
-    :: X509CertOptionsPtr
-    -> Ptr CChar
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_cert_options_set_state
-    :: X509CertOptionsPtr
-    -> Ptr CChar
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_cert_options_set_serial_number
-    :: X509CertOptionsPtr
-    -> Ptr CChar
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_cert_options_set_email
-    :: X509CertOptionsPtr
-    -> Ptr CChar
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_cert_options_set_uri
-    :: X509CertOptionsPtr
-    -> Ptr CChar
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_cert_options_set_ip
-    :: X509CertOptionsPtr
-    -> Ptr CChar
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_cert_options_set_dns
-    :: X509CertOptionsPtr
-    -> Ptr CChar
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_cert_options_set_more_dns
-    :: X509CertOptionsPtr
-    -> Ptr (Ptr CChar) -> CSize
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_cert_options_set_xmpp
-    :: X509CertOptionsPtr
-    -> Ptr CChar
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_cert_options_set_challenge
-    :: X509CertOptionsPtr
-    -> Ptr CChar
-    -> IO BotanErrorCode
-
--- // Or _set_not_before
-foreign import ccall unsafe botan_x509_cert_options_set_start
-    :: X509CertOptionsPtr
-    -> Word64
-    -> IO BotanErrorCode
-
--- // Or _set_not_after
-foreign import ccall unsafe botan_x509_cert_options_set_end
-    :: X509CertOptionsPtr
-    -> Word64
-    -> IO BotanErrorCode
-
--- // TODO: Convenience functions for set_start_duration, set_expires
-
-foreign import ccall unsafe botan_x509_cert_options_set_is_ca
-    :: X509CertOptionsPtr
-    -> CBool
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_cert_options_set_path_limit
-    :: X509CertOptionsPtr
-    -> CSize
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_cert_options_set_padding_scheme
-    :: X509CertOptionsPtr
-    -> Ptr CChar
-    -> IO BotanErrorCode
-
--- // Or _set_key_usage
--- // NOTE: key constraints use unsigned int in ffi, definitely need to give it something proper
-foreign import ccall unsafe botan_x509_cert_options_set_key_constraints
-    :: X509CertOptionsPtr
-    -> CUInt
-    -> IO BotanErrorCode
-
--- // NOTE: Technically should take OIDs but no data type for that
--- // TODO: Create list / spreadsheet of FFI data type mappings
-foreign import ccall unsafe botan_x509_cert_options_set_ex_constraints
-    :: X509CertOptionsPtr
-    -> Ptr (Ptr CChar) -> CSize
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_cert_options_set_extensions
-    :: X509CertOptionsPtr
-    -> X509ExtensionsPtr
-    -> IO BotanErrorCode
-
--- TODO: botan_x509_cert_options getters
-
--- TODO: botan_x509_cert_options functions (above is just members)
--- There's only a few though so its easy
diff --git a/src/Botan/Bindings/X509/Path.hs b/src/Botan/Bindings/X509/Path.hs
deleted file mode 100644
--- a/src/Botan/Bindings/X509/Path.hs
+++ /dev/null
@@ -1,83 +0,0 @@
-module Botan.Bindings.X509.Path where
-
-import Botan.Bindings.Error
-import Botan.Bindings.Prelude
-import Botan.Bindings.X509
-import Botan.Bindings.X509.Store
-
-data X509PathRestrictionsStruct
-type X509PathRestrictionsPtr = Ptr X509PathRestrictionsStruct
-
-foreign import ccall unsafe "&botan_x509_path_restrictions_destroy" botan_x509_path_restrictions_destroy :: FinalizerPtr X509PathRestrictionsStruct
-
-foreign import ccall unsafe botan_x509_path_restrictions_create
-    :: Ptr X509PathRestrictionsPtr
-    -> CBool
-    -> CSize
-    -> CBool
-    -> Word64
-    -> X509CertStorePtr
-    -> IO BotanErrorCode
-
--- TODO: botan_x509_path_restrictions_create_trusted_hashes
-
-data X509PathValidationStruct
-type X509PathValidationPtr = Ptr X509PathValidationStruct
-
-foreign import ccall unsafe "&botan_x509_path_validation_destroy" botan_x509_path_validation_destroy :: FinalizerPtr X509PathValidationStruct
-
-foreign import ccall unsafe botan_x509_path_validate
-    :: Ptr X509PathValidationPtr
-    -> X509CertPtr
-    -> X509PathRestrictionsPtr
-    -> X509CertStorePtr
-    -> Ptr CChar
-    -> CUInt -- NOTE: Assumed to be Word32
-    -> Word64
-    -> Word64
-    -> Ptr () -- SEE NOTES ON OCSP RESPONSE - TYPE NOT YET IMPLEMENTED
-    -> IO BotanErrorCode
-
--- // NOTE: Returns a boolean success code
-foreign import ccall unsafe botan_x509_path_validation_successful_validation
-    :: X509PathValidationPtr
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_path_validation_result_string
-    :: Ptr CChar -> Ptr CSize
-    -> X509PathValidationPtr
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_path_validation_trust_root
-    :: Ptr X509CertPtr
-    -> X509PathValidationPtr
-    -> IO BotanErrorCode
-
--- // NOTE: Returns an array of results
--- // SEE: Discussion on arrays / ownership
--- NOTE: FFI function is actually x509_cert_t** but should be x509_cert_t* like here
-foreign import ccall unsafe botan_x509_path_validation_cert_path
-    :: Ptr X509CertPtr -> Ptr CSize
-    -> X509PathValidationPtr
-    -> IO BotanErrorCode
-
--- // NOTE: Botan FFI is using `int` for Certificate_Status_Code in existing code
-foreign import ccall unsafe botan_x509_path_validation_status_code
-    :: Ptr CInt
-    -> X509PathValidationPtr
-    -> IO BotanErrorCode
-
--- // NOTE: Returns an array of results
--- // SEE: Discussion on arrays / ownership
-foreign import ccall unsafe botan_x509_path_validation_all_status_codes
-    :: Ptr CInt -> Ptr CSize
-    -> X509PathValidationPtr
-    -> IO BotanErrorCode
-
--- // NOTE: Returns an array of results
--- // SEE: Discussion on arrays / ownership
--- // DOUBLE NOTE: It returns an array of cstrings
-foreign import ccall unsafe botan_x509_path_validation_trusted_hashes
-    :: Ptr (Ptr CChar) -> Ptr CSize -> Ptr CSize
-    -> X509PathValidationPtr
-    -> IO BotanErrorCode
diff --git a/src/Botan/Bindings/X509/Store.hs b/src/Botan/Bindings/X509/Store.hs
deleted file mode 100644
--- a/src/Botan/Bindings/X509/Store.hs
+++ /dev/null
@@ -1,188 +0,0 @@
-module Botan.Bindings.X509.Store where
-
-import Botan.Bindings.Error
-import Botan.Bindings.Prelude
-import Botan.Bindings.PubKey
-import Botan.Bindings.RNG
-import Botan.Bindings.X509
-
-data X509CertStoreStruct
-type X509CertStorePtr = Ptr X509CertStoreStruct
-
-foreign import ccall unsafe "&botan_x509_cert_store_destroy" botan_x509_cert_store_destroy :: FinalizerPtr X509CertStoreStruct
-
-foreign import ccall unsafe botan_x509_cert_store_find_cert
-    :: Ptr X509CertPtr
-    -> X509CertStorePtr
-    -> Ptr Word8 -> CSize
-    -> Ptr Word8 -> CSize
-    -> IO BotanErrorCode
-
--- // NOTE: Returns an array of results
--- // SEE: Discussion on arrays / ownership
--- NOTE: FFI function is actually x509_cert_t** but should be x509_cert_t* like here
-foreign import ccall unsafe botan_x509_cert_store_find_all_certs
-    :: Ptr X509CertPtr -> Ptr CSize
-    -> X509CertStorePtr
-    -> Ptr Word8 -> CSize
-    -> Ptr Word8 -> CSize
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_cert_store_find_cert_by_pubkey_sha1
-    :: Ptr X509CertPtr
-    -> X509CertStorePtr
-    -> Ptr Word8        -- NOTE: SHA1 hash length is static, so we can just drop the size_t
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_cert_store_find_cert_by_raw_subject_dn_sha256
-    :: Ptr X509CertPtr
-    -> X509CertStorePtr
-    -> Ptr Word8        -- NOTE: SHA1 hash length is static, so we can just drop the size_t
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_cert_store_find_crl_for
-    :: Ptr X509CRLPtr
-    -> X509CertStorePtr
-    -> X509CertPtr
-    -> IO BotanErrorCode
-
--- // NOTE: Returns cert_store.certificate_known ? 0 : -1;
-foreign import ccall unsafe botan_x509_cert_store_certificate_known
-    :: X509CertStorePtr
-    -> X509CertPtr
-    -> IO BotanErrorCode
-
-{-
-In-memory cert store
--}
-
-foreign import ccall unsafe botan_x509_cert_store_in_memory_load_dir
-    :: Ptr X509CertStorePtr
-    -> Ptr CChar
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_cert_store_in_memory_load_cert
-    :: Ptr X509CertStorePtr
-    -> X509CertPtr
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_cert_store_in_memory_create
-    :: Ptr X509CertStorePtr
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_cert_store_in_memory_add_certificate
-    :: X509CertStorePtr
-    -> X509CertPtr
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_cert_store_in_memory_add_crl
-    :: X509CertStorePtr
-    -> X509CRLPtr
-    -> IO BotanErrorCode
-
-{-
-Flatfile cert store
--}
-
-foreign import ccall unsafe botan_x509_cert_store_flatfile_create
-    :: Ptr X509CertStorePtr
-    -> Ptr CChar
-    -> CBool
-    -> IO BotanErrorCode
-
-{-
-SQL cert store
--}
-
--- NOTE: Returns boolean success code
-foreign import ccall unsafe botan_x509_cert_store_sql_insert_cert
-    :: X509CertStorePtr
-    -> X509CertPtr
-    -> IO BotanErrorCode
-
--- NOTE: Returns boolean success code
-foreign import ccall unsafe botan_x509_cert_store_sql_remove_cert
-    :: X509CertStorePtr
-    -> X509CertPtr
-    -> IO BotanErrorCode
-
--- NOTE: Returns nullPtr if not found
-foreign import ccall unsafe botan_x509_cert_store_sql_find_key
-    :: Ptr PrivKeyPtr
-    -> X509CertStorePtr
-    -> X509CertPtr
-    -> IO BotanErrorCode
-
--- NOTE: See notes about returning arrays of things, improper return pointer type
-foreign import ccall unsafe botan_x509_cert_store_sql_find_certs_for_key
-    :: Ptr X509CertPtr -> Ptr CSize
-    -> X509CertStorePtr
-    -> PrivKeyPtr
-    -> IO BotanErrorCode
-
--- NOTE: Returns boolean success code
-foreign import ccall unsafe botan_x509_cert_store_sql_insert_key
-    :: X509CertStorePtr
-    -> X509CertPtr
-    -> PrivKeyPtr
-    -> IO BotanErrorCode
-
--- NOTE: *DOES NOT* return boolean success code
-foreign import ccall unsafe botan_x509_cert_store_sql_remove_key
-    :: X509CertStorePtr
-    -> PrivKeyPtr
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_cert_store_sql_revoke_cert
-    :: X509CertStorePtr
-    -> X509CertPtr
-    -> Word32
-    -> Word64
-    -> IO BotanErrorCode
-
-foreign import ccall unsafe botan_x509_cert_store_sql_affirm_cert
-    :: X509CertStorePtr
-    -> X509CertPtr
-    -> IO BotanErrorCode
-
--- NOTE: See notes about returning arrays of things, improper return pointer type
-foreign import ccall unsafe botan_x509_cert_store_sql_generate_crls
-    :: Ptr X509CRLPtr -> Ptr CSize
-    -> X509CertStorePtr
-    -> IO BotanErrorCode
-
-{-
-SQLite3 cert store
--}
-
-foreign import ccall unsafe botan_x509_cert_store_sqlite3_create
-    :: Ptr X509CertStorePtr
-    -> Ptr CChar
-    -> Ptr CChar
-    -> RNGPtr
-    -> Ptr CChar
-    -> IO BotanErrorCode
-
-{-
-System cert store
--}
-
-foreign import ccall unsafe botan_x509_cert_store_system_create
-    :: Ptr X509CertStorePtr
-    -> IO BotanErrorCode
-
-{-
-MacOS cert store
--}
-
-foreign import ccall unsafe botan_x509_cert_store_macos_create
-    :: Ptr X509CertStorePtr
-    -> IO BotanErrorCode
-
-{-
-Windows cert store
--}
-
-foreign import ccall unsafe botan_x509_cert_store_windows_create
-    :: Ptr X509CertStorePtr
-    -> IO BotanErrorCode
diff --git a/src/Botan/Bindings/ZFEC.hs b/src/Botan/Bindings/ZFEC.hs
--- a/src/Botan/Bindings/ZFEC.hs
+++ b/src/Botan/Bindings/ZFEC.hs
@@ -37,9 +37,15 @@
 
 {-# LANGUAGE CApiFFI #-}
 
-module Botan.Bindings.ZFEC where
+module Botan.Bindings.ZFEC (
+    botan_zfec_encode
+  , botan_zfec_decode
+  ) where
 
-import Botan.Bindings.Prelude
+import           Botan.Bindings.ConstPtr
+import           Data.Word
+import           Foreign.C.Types
+import           Foreign.Ptr
 
 -- | Encode some bytes with certain ZFEC parameters.
 foreign import capi safe "botan/ffi.h botan_zfec_encode"
