packages feed

libsodium-bindings (empty) → 0.0.1.0

raw patch · 25 files changed

+4723/−0 lines, 25 filesdep +base

Dependencies added: base

Files

+ CHANGELOG.md view
@@ -0,0 +1,3 @@+# CHANGELOG++## [Unreleased]
+ LICENSE view
@@ -0,0 +1,11 @@+Copyright 2022 Hécate Moonlight and contributors++Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:++1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.++2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.++3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,4 @@+# libsodium-bindings [![CI](https://github.com/haskell-cryptography/libsodium-bindings/actions/workflows/libsodium-bindings.yml/badge.svg)](https://github.com/haskell-cryptography/libsodium-bindings/actions/workflows/libsodium-bindings.yml) [![made with Haskell](https://img.shields.io/badge/Made%20in-Haskell-%235e5086?logo=haskell&style=flat-square)](https://haskell.org)++`libsodium-bindings` exposes a set of FFI bindings from the `libsodium-1.0.18-stable` library.+It has no other dependency than `base`, and the documentation is strong enough to stand alone.
+ libsodium-bindings.cabal view
@@ -0,0 +1,89 @@+cabal-version:      3.0+name:               libsodium-bindings+version:            0.0.1.0+category:           Cryptography+synopsis:           FFI bindings to libsodium+description:+  This library embeds FFI bindings to the stable version of libsodium 1.0.18.+  The interface exposed by this library is kept close to the C library.++homepage:           https://github.com/haskell-cryptography/libsodium-bindings+bug-reports:+  https://github.com/haskell-cryptography/libsodium-bindings/issues++author:             Hécate Moonlight, Koz Ross+maintainer:         The Haskell Cryptography contributors+license:            BSD-3-Clause+build-type:         Simple+tested-with:+  GHC ==8.10.7 || ==9.0.2 || ==9.2.8 || ==9.4.7 || ==9.6.2++extra-source-files:+  LICENSE+  README.md++extra-doc-files:    CHANGELOG.md++flag use-pkg-config+  description: Use pkg-config to find Libsodium (macOS and linux only).+  default:     False+  manual:      True++flag homebrew-libsodium+  description: Use Homebrew version of Libsodium (macOS only).+  default:     False+  manual:      True++source-repository head+  type:     git+  location: https://github.com/haskell-cryptography/libsodium-bindings++common common+  build-depends:    base >=4.14 && <5+  ghc-options:+    -Wall -Wcompat -Widentities -Wincomplete-record-updates+    -Wincomplete-uni-patterns -Wpartial-fields -Wredundant-constraints+    -fhide-source-paths -Wno-unused-do-bind -haddock++  if (os(osx) && flag(homebrew-libsodium))+    include-dirs:   /opt/local/include+    extra-lib-dirs: /user/local/opt/libsodium/lib++  if flag(use-pkg-config)+    pkgconfig-depends: libsodium ==1.0.18++  else+    extra-libraries: sodium++  default-language: Haskell2010++common common-rts-options+  ghc-options: -rtsopts -threaded -with-rtsopts=-N++library+  import:          common+  hs-source-dirs:  src++  -- cabal-fmt: expand src/+  exposed-modules:+    LibSodium.Bindings+    LibSodium.Bindings.AEAD+    LibSodium.Bindings.Comparison+    LibSodium.Bindings.CryptoAuth+    LibSodium.Bindings.CryptoBox+    LibSodium.Bindings.CryptoSign+    LibSodium.Bindings.GenericHashing+    LibSodium.Bindings.KeyDerivation+    LibSodium.Bindings.KeyExchange+    LibSodium.Bindings.Main+    LibSodium.Bindings.PasswordHashing+    LibSodium.Bindings.Random+    LibSodium.Bindings.Scrypt+    LibSodium.Bindings.SealedBoxes+    LibSodium.Bindings.Secretbox+    LibSodium.Bindings.SecretStream+    LibSodium.Bindings.SecureMemory+    LibSodium.Bindings.SHA2+    LibSodium.Bindings.ShortHashing+    LibSodium.Bindings.Utils+    LibSodium.Bindings.XChaCha20
+ src/LibSodium/Bindings.hs view
@@ -0,0 +1,75 @@+-- |+--+-- Module: LibSodium.Bindings+-- Description: Index of the libsodium-bindings package+-- Copyright: (C) Hécate Moonlight 2023+-- License: BSD-3-Clause+-- Maintainer: The Haskell Cryptography Group+-- Stability: Stable+-- Portability: GHC only+--+-- You will find below a list of the cryptographic bindings exposed:+--+-- +--+-----------------------------+----------------------------------------------------------------------+---------------------------------------+---------------------------------------------------------++-- |  |           Purpose           | Description                                                          | Algorithms                            | Module                                                  |+-- +==+=============================+======================================================================+=======================================+=========================================================++-- |  | __Secret-key Cryptography__ |                                                                      |                                       |                                                         |+-- |  +-----------------------------+----------------------------------------------------------------------+---------------------------------------+---------------------------------------------------------++-- |  | Authenticated Encryption    | Encrypt a message and compute an authentication                      | Encryption: XSalsa20 stream cipher;   | [SecretBox]("LibSodium.Bindings.Secretbox")             |+-- |  |                             | tag to make sure the message hasn't been tampered with.              | Authentication: Poly1305 MAC          |                                                         |+-- |  +-----------------------------+----------------------------------------------------------------------+---------------------------------------+---------------------------------------------------------++-- |  | Encrypted Streams           | Encrypt a sequence of messages, or a single message split            | Initialisation: XChaCha20;            | [SecretStream]("LibSodium.Bindings.SecretStream")       |+-- |  |                             | into an arbitrary number of chunks, using a secret key.              | Encryption: ChaCha20Poly1305-IETF     |                                                         |+-- |  +-----------------------------+----------------------------------------------------------------------+---------------------------------------+---------------------------------------------------------++-- |  | Authentication              | Compute an authentication tag for a message and a secret key,        | Authentication: HMAC-SHA512-256       | [CryptoAuth]("LibSodium.Bindings.CryptoAuth")           |+-- |  |                             | and verify that a given tag is valid for a given message and a key.  |                                       |                                                         |+-- +--+-----------------------------+----------------------------------------------------------------------+---------------------------------------+---------------------------------------------------------++-- |  | __Public-key Cryptography__ |                                                                      |                                       |                                                         |+-- |  +-----------------------------+----------------------------------------------------------------------+---------------------------------------+---------------------------------------------------------++-- |  | Authenticated Encryption    | Encrypt a confidential message with the recipient's public key,      | Key exchange: X25519;                 | [CryptoBox]("LibSodium.Bindings.CryptoBox")             |+-- |  |                             | who can then decrypt it with their secret key.                       | Encryption: XSalsa20;                 |                                                         |+-- |  |                             |                                                                      | Authentication: Poly1305              |                                                         |+-- |  +-----------------------------+----------------------------------------------------------------------+---------------------------------------+---------------------------------------------------------++-- |  | Public-key Signatures       | Sign messages with a secret key, and distribute a public key,        | Single-part signature: Ed25519;       | [CryptoSign]("LibSodium.Bindings.CryptoSign")           |+-- |  |                             | which anybody can use to verify that the signature appended          | Multi-part signature: Ed25519ph       |                                                         |+-- |  |                             | to a message was issued by the creator of the public key.            |                                       |                                                         |+-- |  +-----------------------------+----------------------------------------------------------------------+---------------------------------------+---------------------------------------------------------++-- |  | Sealed Boxes                | Anonymously send messages to a recipient given their public key.     | Key Exchange: X25519;                 | [SealedBoxes]("LibSodium.Bindings.SealedBoxes")         |+-- |  |                             |                                                                      | Encryption: XSalsa20-Poly1305         |                                                         |+-- +--+-----------------------------+----------------------------------------------------------------------+---------------------------------------+---------------------------------------------------------++-- |  | __Hashing__                 |                                                                      |                                       |                                                         |+-- |  +-----------------------------+----------------------------------------------------------------------+---------------------------------------+---------------------------------------------------------++-- |  | Generic Hashing             | Computes a fixed-length fingerprint for an arbitrarily long message. | Hashing: BLAKE2b                      | [GenericHashing]("LibSodium.Bindings.GenericHashing")   |+-- |  |                             | Use this for file integrity checking and create unique identifiers   |                                       |                                                         |+-- |  |                             | to index arbitrarily long data.                                      |                                       |                                                         |+-- |  |                             | Do not use this API to hash passwords!                               |                                       |                                                         |+-- |  +-----------------------------+----------------------------------------------------------------------+---------------------------------------+---------------------------------------------------------++-- |  | Password Hashing            | Hash passwords with high control on the computation parameters.      | Hashing: Argon2id v1.3                | [PasswordHashing]("LibSodium.Bindings.PasswordHashing") |+-- |  +-----------------------------+----------------------------------------------------------------------+---------------------------------------+---------------------------------------------------------++-- |  | Short-input Hashing         | Produce short hashes for your data, suitable to build Hash tables,   | Hashing: SipHash-2-4                  | [ShortHashing]("LibSodium.Bindings.ShortHashing")       |+-- |  |                             | probabilistic data structures or perform integrity checking in       |                                       |                                                         |+-- |  |                             | interactive protocols.                                               |                                       |                                                         |+-- +--+-----------------------------+----------------------------------------------------------------------+---------------------------------------+---------------------------------------------------------++-- |  | __Cryptographic Keys__      |                                                                      |                                       |                                                         |+-- |  +-----------------------------+----------------------------------------------------------------------+---------------------------------------+---------------------------------------------------------++-- |  | Key Derivation              | Derive secret keys from a single high-entropy key.                   | Key derivation: BLAKE2B               | [KeyDerivation]("LibSodium.Bindings.KeyDerivation")     |+-- |  +-----------------------------+----------------------------------------------------------------------+---------------------------------------+---------------------------------------------------------++-- |  | Key Exchange                | Securely compute a set of shared keys using your                     | Key generation: BLAKE2B-512           | [KeyExchange]("LibSodium.Bindings.KeyExchange")         |+-- |  |                             | peer's public key and your own secret key.                           |                                       |                                                         |+-- +--+-----------------------------+----------------------------------------------------------------------+---------------------------------------+---------------------------------------------------------++-- |  | __Other constructs__        |                                                                      |                                       |                                                         |+-- +--+-----------------------------+----------------------------------------------------------------------+---------------------------------------+---------------------------------------------------------++-- |  | SHA-2                       | Provide compatibility with existing applications for                 | SHA-256 and SHA-512                   | [SHA2]("LibSodium.Bindings.SHA2")                       |+-- |  |                             | SHA-256 and SHA-512. You should prioritise GenericHashing            |                                       |                                                         |+-- |  |                             | and PasswordHashing for new developmentinstead.                      |                                       |                                                         |+-- +--+-----------------------------+----------------------------------------------------------------------+---------------------------------------+---------------------------------------------------------++-- |  | AEAD                        | Encrypt a message with a key and a nonce to keep it confidential,    | Encryption: XChaCha20 stream cipher;  | [AEAD]("LibSodium.Bindings.AEAD")                       |+-- |  |                             | compute an authentication tag, and store optional, non-confidential  | Authentication: Poly1305 MAC          |                                                         |+-- |  |                             | data.                                                                |                                       |                                                         |+-- +--+-----------------------------+----------------------------------------------------------------------+---------------------------------------+---------------------------------------------------------++-- |  | XChaCha20                   | Implementation of the XChaCha20 stream cipher                        | XChaCha20 stream cipher               | [XChaCha20]("LibSodium.Bindings.XChaCha20")             |+-- +--+-----------------------------+----------------------------------------------------------------------+---------------------------------------+---------------------------------------------------------++-- |  | Scrypt                      | Unless you have specific reasons to use scrypt, you                  | scrypt password hashing function      | [Scrypt]("LibSodium.Bindings.Scrypt")                   |+-- |  |                             | should instead consider the PasswordHashing module!                  |                                       |                                                         |+-- +--+-----------------------------+----------------------------------------------------------------------+---------------------------------------+---------------------------------------------------------++module LibSodium.Bindings where
+ src/LibSodium/Bindings/AEAD.hs view
@@ -0,0 +1,195 @@+{-# LANGUAGE CApiFFI #-}++-- |+--+-- Module: LibSodium.Bindings.AEAD+-- Description: Bindings to AEAD constructions with XChaCha20-Poly1305-IETF.+-- Copyright: (C) Hécate Moonlight 2023+-- License: BSD-3-Clause+-- Maintainer: The Haskell Cryptography Group+-- Stability: Stable+-- Portability: GHC only+module LibSodium.Bindings.AEAD+  ( -- * Introduction+    -- $introduction++    -- * Operations+    cryptoAEADXChaCha20Poly1305IETFEncrypt+  , cryptoAEADXChaCha20Poly1305IETFDecrypt+  , cryptoAEADXChaCha20Poly1305IETFEncryptDetached+  , cryptoAEADXChaCha20Poly1305IETFDecryptDetached++    -- * Constants+  , cryptoAEADXChaCha20Poly1305IETFKeyBytes+  , cryptoAEADXChaCha20Polt1305IETFPubBytes+  , cryptoAEADXChaCha20Poly1305IETFABytes+  )+where++import Foreign.C.Types (CInt (CInt), CSize (CSize), CUChar, CULLong (CULLong))+import Foreign.Ptr (Ptr)++-- $introduction+--+-- With @XChaCha20-Poly1305-IETF@, you can encrypt a message witha key and a nonce to keept it+-- confidential, as well as compute an authentication tag to make sure that the message+-- has not been tampered with.+--+-- A typical use case for additional data is to authenticate protocol-specific metadata+-- about the message, such as its length and encoding.+--+-- For a deeper dive into the limitations of the implementation, please refer to the manual:+-- https://doc.libsodium.org/secret-key_cryptography/aead#limitations++-- | This function encrypts a message, and then appends the authentication tag+-- to the encrypted message.+--+-- /See:/ [crypto_aead_xchacha20poly1305_ietf_encrypt()](https://doc.libsodium.org/secret-key_cryptography/aead/chacha20-poly1305/xchacha20-poly1305_construction#combined-mode)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_aead_xchacha20poly1305_ietf_encrypt"+  cryptoAEADXChaCha20Poly1305IETFEncrypt+    :: Ptr CUChar+    -- ^ Output buffer. Contains the encrypted message, authentication tag, and non-confidential additional data.+    -> Ptr CULLong+    -- ^ Size of computed output. Should be message length plus 'cryptoAEADXChaCha20Poly1305IETFABytes'.+    -- If set to 'Foreign.Ptr.nullPtr', then no bytes will be written to this buffer.+    -> Ptr CUChar+    -- ^ Message to be encrypted.+    -> CULLong+    -- ^ Message length.+    -> Ptr CUChar+    -- ^ Non-confidential additional data. Can be null with additional data length of 0 if+    -- no additional data is required.+    -> CULLong+    -- ^ Additional data length.+    -> Ptr CUChar+    -- ^ @nsec@, a parameter not used in this function. Should always be 'Foreign.Ptr.nullPtr'.+    -> Ptr CUChar+    -- ^ Public nonce of size 'cryptoAEADXChaCha20Polt1305IETFPubBytes'.+    -- Should never be reused with the same key. Nonces can be generated using 'LibSodium.Bindings.Random.randombytesBuf'.+    -> Ptr CUChar+    -- ^ Secret key of size 'cryptoAEADXChaCha20Poly1305IETFKeyBytes'.+    -> IO CInt+    -- ^ Returns -1 on failure, 0 on success.++-- | This function verifies that an encrypted ciphertext includes a valid tag.+--+-- /See:/ [crypto_aead_xchacha20poly1305_ietf_decrypt()](https://doc.libsodium.org/secret-key_cryptography/aead/chacha20-poly1305/xchacha20-poly1305_construction#combined-mode)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_aead_xchacha20poly1305_ietf_decrypt"+  cryptoAEADXChaCha20Poly1305IETFDecrypt+    :: Ptr CUChar+    -- ^ Output buffer. At most the cipher text length minus 'cryptoAEADXChaCha20Poly1305IETFABytes' will be put into this.+    -> Ptr CULLong+    -- ^ Size of computed output. Should be message length plus 'cryptoAEADXChaCha20Poly1305IETFABytes'.+    -- If set to 'Foreign.Ptr.nullPtr', then no bytes will be written to this buffer.+    -> Ptr CUChar+    -- ^ @nsec@, a parameter not used in this function. Should always be 'Foreign.Ptr.nullPtr'.+    -> Ptr CUChar+    -- ^ Ciphertext to decrypt.+    -> CULLong+    -- ^ Ciphertext length.+    -> Ptr CUChar+    -- ^ Non-confidential additional data. Can be null with additional data length of 0 if+    -- no additional data is required.+    -> CULLong+    -- ^ Additional data length.+    -> Ptr CUChar+    -- ^ Public nonce of size 'cryptoAEADXChaCha20Polt1305IETFPubBytes'.+    -- Should never be reused with the same key. Nonces can be generated using 'LibSodium.Bindings.Random.randombytesBuf'.+    -> Ptr CUChar+    -- ^ Secret key of size 'cryptoAEADXChaCha20Poly1305IETFKeyBytes'.+    -> IO CInt+    -- ^ Returns -1 on failure, 0 on success.++-- | This is the "detached" version of the encryption function.+-- The encrypted message and authentication tag are output to different buffers+-- instead of the tag being appended to the encrypted message.+--+-- /See:/ [crypto_aead_xchacha20poly1305_ietf_encrypt_detached()](https://doc.libsodium.org/secret-key_cryptography/aead/chacha20-poly1305/xchacha20-poly1305_construction#detached-mode)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_aead_xchacha20poly1305_ietf_encrypt_detached"+  cryptoAEADXChaCha20Poly1305IETFEncryptDetached+    :: Ptr CUChar+    -- ^ Output buffer. Contains the encrypted message with length equal to the message.+    -> Ptr CUChar+    -- ^ The authentication tag. Has length 'cryptoAEADXChaCha20Poly1305IETFABytes'.+    -> Ptr CULLong+    -- ^ Length of the authentication tag buffer.+    -> Ptr CUChar+    -- ^ Message to be encrypted.+    -> CULLong+    -- ^ Length of input message.+    -> Ptr CUChar+    -- ^ Additional, non-confidential data.+    -> CULLong+    -- ^ Length of the additional, non-confidential data.+    -> Ptr CUChar+    -- ^ Not used in this particular construction, should always be 'Foreign.Ptr.nullPtr'.+    -> Ptr CUChar+    -- ^ Public nonce of size 'cryptoAEADXChaCha20Polt1305IETFPubBytes'.+    -- Should never be reused with the same key. Nonces can be generated using 'LibSodium.Bindings.Random.randombytesBuf'.+    -> Ptr CUChar+    -- ^ Secret key of size 'cryptoAEADXChaCha20Poly1305IETFKeyBytes'.+    -> IO CInt+    -- ^ Returns -1 on failure, 0 on success.++-- | This is the "detached" version of the decryption function.+-- Verifies that the authentication tag is valid for the ciphertext, key, nonce,+-- and additional data.+--+-- /See:/ [crypto_aead_xchacha20poly1305_ietf_decrypt_detached()](https://doc.libsodium.org/secret-key_cryptography/aead/chacha20-poly1305/xchacha20-poly1305_construction#detached-mode)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_aead_xchacha20poly1305_ietf_decrypt_detached"+  cryptoAEADXChaCha20Poly1305IETFDecryptDetached+    :: Ptr CUChar+    -- ^ If the tag is valid, the ciphertext is decrypted and put into this buffer.+    -> Ptr CUChar+    -- ^ Not used in this particular construction, should always be 'Foreign.Ptr.nullPtr'.+    -> Ptr CUChar+    -- ^ Ciphertext to be decrypted.+    -> CULLong+    -- ^ Length of the ciphertext.+    -> Ptr CUChar+    -- ^ The authentication tag. Has length 'cryptoAEADXChaCha20Poly1305IETFABytes'.+    -> Ptr CUChar+    -- ^ Additional, non-confidential data.+    -> CULLong+    -- ^ Length of the additional, non-confidential data.+    -> Ptr CUChar+    -- ^ Public nonce of size 'cryptoAEADXChaCha20Polt1305IETFPubBytes'.+    -- Should never be reused with the same key. Nonces can be generated using 'LibSodium.Bindings.Random.randombytesBuf'.+    -> Ptr CUChar+    -- ^ Secret key of size 'cryptoAEADXChaCha20Poly1305IETFKeyBytes'.+    -> IO CInt+    -- ^ Returns 0 on success, -1 if tag is not valid.++-- == Constants.++-- | Recommended length of a key for this construction.+--+-- /See:/ [crypto_aead_xchacha20poly1305_ietf_KEYBYTES](https://doc.libsodium.org/secret-key_cryptography/aead/chacha20-poly1305/xchacha20-poly1305_construction#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_aead_xchacha20poly1305_ietf_KEYBYTES"+  cryptoAEADXChaCha20Poly1305IETFKeyBytes :: CSize++-- | Recommended length of a nonce for this construction.+--+-- /See:/ [crypto_aead_xchacha20poly1305_ietf_NPUBBYTES](https://doc.libsodium.org/secret-key_cryptography/aead/chacha20-poly1305/xchacha20-poly1305_construction#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_aead_xchacha20poly1305_ietf_NPUBBYTES"+  cryptoAEADXChaCha20Polt1305IETFPubBytes :: CSize++-- | Recommended length for the authentication tag.+--+-- /See:/ [crypto_aead_xchacha20poly1305_ietf_ABYTES](https://doc.libsodium.org/secret-key_cryptography/aead/chacha20-poly1305/xchacha20-poly1305_construction#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_aead_xchacha20poly1305_ietf_ABYTES"+  cryptoAEADXChaCha20Poly1305IETFABytes :: CSize
+ src/LibSodium/Bindings/Comparison.hs view
@@ -0,0 +1,53 @@+{-# LANGUAGE CApiFFI #-}+{-# LANGUAGE Trustworthy #-}++-- | Module: LibSodium.Bindings.Comparison+-- Description: Helper functions for constant-time comparison+-- Copyright: (C) Koz Ross 2022+-- License: BSD-3-Clause+-- Maintainer: koz.ross@retro-freedom.nz+-- Stability: Stable+-- Portability: GHC only+--+-- Secure comparison functions, designed to run in constant time for a given+-- input length.+module LibSodium.Bindings.Comparison+  ( sodiumMemcmp+  , sodiumIsZero+  )+where++import Foreign.C.Types (CInt (CInt), CSize (CSize), CUChar)+import Foreign.Ptr (Ptr)++-- | Compares the given amount of bytes at the given locations for equality.+-- Constant-time for any given length.+--+-- /See:/ [sodium_memcmp()](https://doc.libsodium.org/helpers#constant-time-test-for-equality)+--+-- @since 0.0.1.0+foreign import capi "sodium.h sodium_memcmp"+  sodiumMemcmp+    :: Ptr CUChar+    -- ^ First location with data to compare+    -> Ptr CUChar+    -- ^ Second location with data to compare+    -> CSize+    -- ^ How many bytes to compare+    -> CInt+    -- ^ 0 if all bytes match, -1 otherwise++-- | Checks if the given number of bytes at the given location are all equal to+-- zero. Constant-time for any given length.+--+-- /See:/ [sodium_is_zero()](https://doc.libsodium.org/helpers#testing-for-all-zeros)+--+-- @since 0.0.1.0+foreign import capi "sodium.h sodium_is_zero"+  sodiumIsZero+    :: Ptr CUChar+    -- ^ Location with data to check+    -> CSize+    -- ^ How many bytes to check+    -> CInt+    -- ^ 1 if all the bytes were zeroes, 0 otherwise
+ src/LibSodium/Bindings/CryptoAuth.hs view
@@ -0,0 +1,122 @@+{-# LANGUAGE CApiFFI #-}+{-# LANGUAGE ScopedTypeVariables #-}++-- |+-- Module: LibSodium.Bindings.CryptoAuth+-- Description: Direct bindings to the secret key authentication primitives backed by HMAC-SHA512-256+-- Copyright: (C) Hécate Moonlight+-- License: BSD-3-Clause+-- Maintainer: The Haskell Cryptography Group+-- Stability: Stable+-- Portability: GHC only+module LibSodium.Bindings.CryptoAuth+  ( -- * Introduction+    -- $introduction++    -- * Usage+    -- $usage++    -- * Functions+    cryptoAuth+  , cryptoAuthVerify+  , cryptoAuthKeygen++    -- * Constants+  , cryptoAuthKeyBytes+  , cryptoAuthBytes+  ) where++import Foreign+import Foreign.C++-- $introduction+-- Compute an authentication tag for a message and a secret key,+-- and verify that a given tag is valid for a given message and a key.+--+-- The function computing the tag is deterministic: the same (message, key)+-- tuple will always produce the same output.+-- However, even if the message is public, knowing the key is required in order to be+-- able to compute a valid tag.+-- Therefore, the key __should remain confidential__. The tag, however, can be public.+--+-- The operations of this module are backed by the HMAC-SHA512-256 algorithm.++-- $usage+--+-- A typical use case is:+--+-- * @A@ prepares a message, adds an authentication tag, sends it to @B@+-- * @A@ doesn't store the message+-- * Later on, @B@ sends the message and the authentication tag to @A@+-- * @A@ uses the authentication tag to verify that it created this message.+--+-- This operation does not encrypt the message.+-- It only computes and verifies an authentication tag.++-- | Compute a tag for the provided message and key.+--+-- /See:/ [crypto_auth()](https://doc.libsodium.org/secret-key_cryptography/secret-key_authentication#usage)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_auth"+  cryptoAuth+    :: Ptr CUChar+    -- ^ Buffer that will hold the computed authenticated tag, of size 'cryptoAuthBytes'+    -> Ptr CUChar+    -- ^ Buffer that holds the input message+    -> CULLong+    -- ^ Length of the message+    -> Ptr CUChar+    -- ^ Buffer that holds the secret key of size 'cryptoAuthKeyBytes'+    -> IO CInt++-- | Verify that the tag is valid for the provided message and secret key.+--+-- /See:/ [crypto_auth_verify()](https://doc.libsodium.org/secret-key_cryptography/secret-key_authentication#usage)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_auth_verify"+  cryptoAuthVerify+    :: Ptr CUChar+    -- ^ Buffer that holds the tag+    -> Ptr CUChar+    -- ^ Buffer that holds the message+    -> CULLong+    -- ^ Length of the message+    -> Ptr CUChar+    -- ^ Buffer that holds the secret key of size 'cryptoAuthKeyBytes'+    -> IO CInt+    -- ^ Returns -1 if the verification fails, and 0 if it passes.++-- | Create a random secret key of size 'cryptoAuthKeyBytes'+--+-- It is equivalent to calling 'LibSodium.Bindings.Random.randombytesBuf' but+-- improves code clarity and can prevent misuse by ensuring that the provided+-- key length is always be correct.+--+-- /See:/ [crypto_auth_keygen()](https://doc.libsodium.org/secret-key_cryptography/secret-key_authentication#usage)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_auth_keygen"+  cryptoAuthKeygen+    :: Ptr CUChar+    -- ^ Buffer that holds the secret key of size 'cryptoAuthKeyBytes'+    -> IO ()++-- === Constants ===++-- | Size of the secret key+--+-- /See:/ [crypto_auth_KEYBYTES](https://doc.libsodium.org/secret-key_cryptography/secret-key_authentication#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_auth_KEYBYTES"+  cryptoAuthKeyBytes :: CSize++-- | Size of the tag+--+-- /See:/ [crypto_auth_BYTES](https://doc.libsodium.org/secret-key_cryptography/secret-key_authentication#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_auth_BYTES"+  cryptoAuthBytes :: CSize
+ src/LibSodium/Bindings/CryptoBox.hs view
@@ -0,0 +1,373 @@+{-# LANGUAGE CApiFFI #-}++-- |+-- Module: LibSodium.Bindings.CryptoBox+-- Description: Direct bindings to the public key authentication primitives backed by X25519 (key exchange), XSalsa20 (encryption) and Poly1305 (authentication)+-- Copyright: (C) Hécate Moonlight+-- License: BSD-3-Clause+-- Maintainer: The Haskell Cryptography Group+-- Stability: Stable+-- Portability: GHC only+module LibSodium.Bindings.CryptoBox+  ( -- ** Introduction+    -- $introduction++    -- ** Usage+    -- $usage++    -- ** Functions++    -- *** Key Pair Generation+    cryptoBoxKeyPair+  , cryptoBoxSeedKeyPair++    -- *** Combined Mode+  , cryptoBoxEasy+  , cryptoBoxOpenEasy++    -- *** Detached Mode+  , cryptoBoxDetached+  , cryptoBoxOpenDetached++    -- *** Precalculation Interface+  , cryptoBoxBeforeNM+  , cryptoBoxEasyAfterNM+  , cryptoBoxOpenEasyAfterNM+  , cryptoBoxDetachedAfterNM+  , cryptoBoxOpenDetachedAfterNM++    -- ** Constants+  , cryptoBoxPublicKeyBytes+  , cryptoBoxSecretKeyBytes+  , cryptoBoxSeedBytes+  , cryptoBoxMACBytes+  , cryptoBoxNonceBytes+  , cryptoBoxBeforeNMBytes+  ) where++import Foreign (Ptr)+import Foreign.C (CInt (CInt), CSize (CSize), CUChar, CULLong (CULLong))++-- $introduction+-- Using public-key authenticated encryption, Alice can encrypt a confidential message specifically for Bob, using Bob's public key.+--+-- Based on Bob's public key, Alice can compute a shared secret key. Using Alice's public key and his secret key, Bob can compute the same shared secret key.+-- That shared secret key can be used to verify that the encrypted message was not tampered with before decryption.+--+-- To send messages to Bob, Alice only needs Bob's public key. Bob should never share his secret key, even with Alice.+--+-- For verification and decryption, Bob only needs Alice's public key, the nonce, and the ciphertext. Alice should never share her secret key either, even with Bob.+--+-- Bob can reply to Alice using the same system without needing to generate a distinct key pair.+--+-- The nonce doesn't have to be confidential, but it should be used with just one invocation of 'cryptoBoxEasy' for a particular pair of public and secret keys.+--+-- One easy way to generate a nonce is to use 'LibSodium.Bindings.Random.randombytesBuf'. Considering the size of the nonce, the risk of a random collision is negligible.+--+-- For some applications, if you wish to use nonces to detect missing messages or to ignore replayed messages, it is also acceptable to use a simple+-- incrementing counter as a nonce.+-- However, you must ensure that the same value is never reused. Be careful as you may have multiple threads or even hosts generating messages using the same key pairs.+-- A better alternative is to use the 'LibSodium.Bindings.SecretStream' API.+--+-- As stated above, senders can decrypt their own messages and compute a valid authentication tag for any messages encrypted with a given shared secret key.+-- This is generally not an issue for online protocols. If this is not acceptable, then check out the Sealed Boxes and Key Exchange sections of the documentation.++-- $usage+-- There are three families of APIs exposed:+--+-- 1. Combined Mode: It is the most commonly used entry point to this module.+-- 2. Detached Mode: If you need to store the authentication tag and encrypted message at different locations+-- 3. Precalculation Interface: Applications that send several messages to the same recipient or receive several messages from the same sender can improve performance by calculating the shared key only once and reusing it in subsequent operations.++-- === Key Pair Generation ===++-- | Generate a random secret key and the corresponding public key.+--+-- /See:/ [crypto_box_keypair()](https://doc.libsodium.org/public-key_cryptography/authenticated_encryption#key-pair-generation)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_box_keypair"+  cryptoBoxKeyPair+    :: Ptr CUChar+    -- ^ Buffer that will hold the public key, of size 'cryptoBoxPublicKeyBytes'+    -> Ptr CUChar+    -- ^ Buffer that will hold the secret key, of size 'cryptoBoxSecretKeyBytes'+    -> IO CInt+    -- ^ The function returns 0 on success and -1 if something fails.++-- | Generate a random secret key and the corresponding public key in a deterministic manner+-- from a single key that acts as a seed.+--+-- /See:/ [crypto_box_seed_keypair()](https://doc.libsodium.org/public-key_cryptography/authenticated_encryption#key-pair-generation)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_box_seed_keypair"+  cryptoBoxSeedKeyPair+    :: Ptr CUChar+    -- ^ Buffer that will hold the public key, of size 'cryptoBoxPublicKeyBytes'+    -> Ptr CUChar+    -- ^ Buffer that will hold the secret key, of size 'cryptoBoxSecretKeyBytes'+    -> Ptr CUChar+    -- ^ Buffer that holds the seed, of size 'cryptoBoxSeedBytes'+    -> IO CInt+    -- ^ The function returns 0 on success and -1 if something fails.++-- === Combined Mode ===++-- | Encrypt a message using the public key of the recipient, the secret key of the sender and a cryptographic nonce.+--+-- The pointers to the buffers containing the message to encrypt and the+-- combination of authentication tag and encrypted message can overlap, making in-place+-- encryption possible. However do not forget that 'cryptoBoxMACBytes' extra bytes are required to prepend the tag.+--+-- /See:/ [crypto_box_easy()](https://doc.libsodium.org/public-key_cryptography/authenticated_encryption#combined-mode)+--+-- @since 0.0.1.0+foreign import capi "crypto_box_easy"+  cryptoBoxEasy+    :: Ptr CUChar+    -- ^ Buffer that will hold the encrypted message, of size 'cryptoBoxMACBytes' + @messageLength@.+    -> Ptr CUChar+    -- ^ Buffer that holds the message to be encrypted+    -> CULLong+    -- ^ Length of the message in bytes (@messageLength@)+    -> Ptr CUChar+    -- ^ Nonce, that should be of size 'cryptoBoxNonceBytes'+    -> Ptr CUChar+    -- ^ Buffer that holds the public key, of size 'cryptoBoxPublicKeyBytes'+    -> Ptr CUChar+    -- ^ Buffer that holds the secret key, of size 'cryptoBoxSecretKeyBytes'+    -> IO CInt+    -- ^ The function returns 0 on success and -1 if something fails.++-- | Verify and decrypt a cyphertext produced by 'cryptoBoxEasy'.+-- The first argument is a pointer to a combination of authentication tag and message+-- as produced by 'cryptoBoxEasy'.+--+-- The pointers to the buffers containing the plaintext message and the+-- combination of authentication tag and encrypted message can overlap, making in-place+-- decryption possible.+--+-- /See:/ [crypto_box_open_easy()](https://doc.libsodium.org/public-key_cryptography/authenticated_encryption#combined-mode)+--+-- @since 0.0.1.0+foreign import capi "crypto_box_open_easy"+  cryptoBoxOpenEasy+    :: Ptr CUChar+    -- ^ Buffer that will hold the decrypted message+    -> Ptr CUChar+    -- ^ Buffer that holds the authentication tag and encrypted message combination produced by 'cryptoBoxEasy'.+    -> CULLong+    -- ^ Length of the authentication tag and encrypted message combination, which is 'cryptoBoxMACBytes' + length of the message+    -> Ptr CUChar+    -- ^ Nonce, that should be at least of size 'cryptoBoxNonceBytes'. It must match the nonce used by 'cryptoBoxEasy'.+    -> Ptr CUChar+    -- ^ Buffer that holds the recipient's public key, of size 'cryptoBoxPublicKeyBytes'+    -> Ptr CUChar+    -- ^ Buffer that holds the sender's secret key, of size 'cryptoBoxSecretKeyBytes'+    -> IO CInt+    -- ^ The function returns -1 if the verification fails and 0 on success++-- | Encrypt a message in the same way as 'cryptoBoxEasy' with the+-- the authentication tag and the encrypted message held in separate buffers.+--+-- /See:/ [crypto_box_detached()](https://doc.libsodium.org/public-key_cryptography/authenticated_encryption#detached-mode)+--+-- @since 0.0.1.0+foreign import capi "crypto_box_detached"+  cryptoBoxDetached+    :: Ptr CUChar+    -- ^ Buffer that will hold the encrypted message.+    -> Ptr CUChar+    -- ^ Buffer that will hold the authentication tag, of size 'cryptoBoxMACBytes'+    -> Ptr CUChar+    -- ^ Buffer that holds the message to be encrypted.+    -> CULLong+    -- ^ Length of the message to be encrypted.+    -> Ptr CUChar+    -- ^ Nonce, that should be of size 'cryptoBoxNonceBytes'.+    -- It must match the nonce used by 'cryptoBoxEasy'.+    -> Ptr CUChar+    -- ^ Buffer that holds the public key, of size 'cryptoBoxPublicKeyBytes'+    -> Ptr CUChar+    -- ^ Buffer that holds the secret key, of size 'cryptoBoxSecretKeyBytes'+    -> IO CInt+    -- ^ The function returns -1 if the verification fails and 0 on success++-- | Decrypt a message in the same way as 'cryptoBoxEasy' with the+-- the authentication tag and the encrypted message held in separate buffers.+--+-- /See:/ [crypto_box_open_detached()](https://doc.libsodium.org/public-key_cryptography/authenticated_encryption#detached-mode)+--+-- @since 0.0.1.0+foreign import capi "crypto_box_open_detached"+  cryptoBoxOpenDetached+    :: Ptr CUChar+    -- ^ Buffer that will hold the plaintext message+    -> Ptr CUChar+    -- ^ Buffer that holds the encrypted message+    -> Ptr CUChar+    -- ^ Buffer that will hold the authentication tag, of size 'cryptoBoxMACBytes'+    -> CULLong+    -- ^ Length of the plaintext message+    -> Ptr CUChar+    -- ^ Nonce, that should be at least of size 'cryptoBoxNonceBytes'.+    -> Ptr CUChar+    -- ^ Buffer that holds the public key, of size 'cryptoBoxPublicKeyBytes'+    -> Ptr CUChar+    -- ^ Buffer that holds the secret key, of size 'cryptoBoxSecretKeyBytes'+    -> IO CInt+    -- ^ The function returns -1 if the verification fails and 0 on success++-- | Compute a shared secret key of size 'cryptoBoxBeforeNMBytes'+-- given a public key and a secret key.+--+-- /See:/ [crypto_box_beforenm()](https://doc.libsodium.org/public-key_cryptography/authenticated_encryption#precalculation-interface)+--+-- @since 0.0.1.0+foreign import capi "crypto_box_beforenm"+  cryptoBoxBeforeNM+    :: Ptr CUChar+    -- ^ Buffer that will hold the newly-generated shared secret key, of size 'cryptoBoxBeforeNMBytes'+    -> Ptr CUChar+    -- ^ Buffer that holds the public key, of size 'cryptoBoxPublicKeyBytes'+    -> Ptr CUChar+    -- ^ Buffer that holds the secret key, of size 'cryptoBoxSecretKeyBytes'+    -> IO CInt+    -- ^ The function returns 0 on success and -1 if something fails.++-- | Encrypt a message using the public key of the recipient, a cryptographic nonce and a shared secret key.+--+-- /See:/ [crypto_box_easy_afternm()](https://doc.libsodium.org/public-key_cryptography/authenticated_encryption#precalculation-interface)+--+-- @since 0.0.1.0+foreign import capi "crypto_box_easy_afternm"+  cryptoBoxEasyAfterNM+    :: Ptr CUChar+    -- ^ Buffer that will holds the encrypted message.+    -> Ptr CUChar+    -- ^ Buffer that holds the plaintext message.+    -> CULLong+    -- ^ Length of the plaintext message+    -> Ptr CUChar+    -- ^ Nonce, that should of size 'cryptoBoxNonceBytes'.+    -> Ptr CUChar+    -- ^ Precalculated shared secret key (created by 'cryptoBoxBeforeNM').+    -> IO CInt+    -- ^ The function returns -1 if the verification fails and 0 on success++-- | Decrypt a message using the public key of the recipient, a cryptographic nonce and a shared secret key.+--+-- /See:/ [crypto_box_open_easy_afternm()](https://doc.libsodium.org/public-key_cryptography/authenticated_encryption#precalculation-interface)+--+-- @since 0.0.1.0+foreign import capi "crypto_box_open_easy_afternm"+  cryptoBoxOpenEasyAfterNM+    :: Ptr CUChar+    -- ^ Buffer that will hold the decrypted plaintext message.+    -> Ptr CUChar+    -- ^ Buffer that holds the encrypted message.+    -> CULLong+    -- ^ Length of the plaintext message+    -> Ptr CUChar+    -- ^ Nonce, that should be at least of size 'cryptoBoxNonceBytes'.+    -> Ptr CUChar+    -- ^ Precalculated shared secret key (created by 'cryptoBoxBeforeNM').+    -> IO CInt+    -- ^ The function returns -1 if the verification fails and 0 on success++-- | Encrypt a message in the same way as 'cryptoBoxDetached' with the+-- the authentication tag and the encrypted message held in separate buffers, with the difference+-- that a precalculated, shared secret key is used instead of a public/secret key pair.+--+-- /See:/ [crypto_box_detached_afternm()](https://doc.libsodium.org/public-key_cryptography/authenticated_encryption#precalculation-interface)+--+-- @since 0.0.1.0+foreign import capi "crypto_box_detached_afternm"+  cryptoBoxDetachedAfterNM+    :: Ptr CUChar+    -- ^ Buffer that will hold the encrypted message.+    -> Ptr CUChar+    -- ^ Buffer that will hold the authentication tag, of size 'cryptoBoxMACBytes'+    -> Ptr CUChar+    -- ^ Buffer that holds the plaintext message.+    -> CULLong+    -- ^ Length of the plaintext message+    -> Ptr CUChar+    -- ^ Nonce, that should be at least of size 'cryptoBoxNonceBytes'.+    -> Ptr CUChar+    -- ^ Precalculated shared secret key (created by 'cryptoBoxBeforeNM').+    -> IO CInt+    -- ^ The function returns -1 if the verification fails and 0 on success++-- | Decrypt a message using the public key of the recipient, a cryptographic nonce and a shared secret key.+--+-- /See:/ [crypto_box_open_detached_afternm()](https://doc.libsodium.org/public-key_cryptography/authenticated_encryption#precalculation-interface)+--+-- @since 0.0.1.0+foreign import capi "crypto_box_open_detached_afternm"+  cryptoBoxOpenDetachedAfterNM+    :: Ptr CUChar+    -- ^ Buffer that will hold the decrypted plaintext message.+    -> Ptr CUChar+    -- ^ Buffer that holds the encrypted message.+    -> Ptr CUChar+    -- ^ Buffer that holds the authentication tag, of size 'cryptoBoxMACBytes'+    -> CULLong+    -- ^ Length of the plaintext message+    -> Ptr CUChar+    -- ^ Nonce, that should be at least of size 'cryptoBoxNonceBytes'.+    -> Ptr CUChar+    -- ^ Precalculated shared secret key (created by 'cryptoBoxBeforeNM').+    -> IO CInt+    -- ^ The function returns -1 if the verification fails and 0 on success++-- === Constants++-- |+--+-- /See:/ [crypto_box_PUBLICKEYBYTES](https://doc.libsodium.org/public-key_cryptography/authenticated_encryption#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_box_PUBLICKEYBYTES"+  cryptoBoxPublicKeyBytes :: CSize++-- |+--+-- /See:/ [crypto_box_SECRETKEYBYTES](https://doc.libsodium.org/public-key_cryptography/authenticated_encryption#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_box_SECRETKEYBYTES"+  cryptoBoxSecretKeyBytes :: CSize++-- |+--+-- /See:/ [crypto_box_SEEDBYTES](https://doc.libsodium.org/public-key_cryptography/authenticated_encryption#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_box_SEEDBYTES"+  cryptoBoxSeedBytes :: CSize++-- |+--+-- /See:/ [crypto_box_MACBYTES](https://doc.libsodium.org/public-key_cryptography/authenticated_encryption#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_box_MACBYTES"+  cryptoBoxMACBytes :: CSize++-- |+--+-- /See:/ [crypto_box_NONCEBYTES](https://doc.libsodium.org/public-key_cryptography/authenticated_encryption#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_box_NONCEBYTES"+  cryptoBoxNonceBytes :: CSize++-- |+--+-- /See:/ [crypto_box_BEFORENMBYTES](https://doc.libsodium.org/public-key_cryptography/authenticated_encryption#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_box_BEFORENMBYTES"+  cryptoBoxBeforeNMBytes :: CSize
+ src/LibSodium/Bindings/CryptoSign.hs view
@@ -0,0 +1,397 @@+{-# LANGUAGE CApiFFI #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE Trustworthy #-}++-- |+-- Module: LibSodium.Bindings.Signing+-- Description: Direct bindings to the public-key signing algorithm ed25519 implemented in Libsodium+-- Copyright: (C) Hécate Moonlight 2022+-- License: BSD-3-Clause+-- Maintainer: The Haskell Cryptography Group+-- Stability: Stable+-- Portability: GHC only+module LibSodium.Bindings.CryptoSign+  ( -- * Introduction+    -- $introduction++    -- * Key pair generation+    cryptoSignKeyPair+  , cryptoSignSeedKeyPair++    -- * Combined mode+  , cryptoSign+  , cryptoSignOpen++    -- * Detached Mode+    -- $detachedMode+  , cryptoSignDetached+  , cryptoSignVerifyDetached++    -- * Multi-part messages+    -- $mpm+  , CryptoSignState+  , withSignState+  , cryptoSignInit+  , cryptoSignUpdate+  , cryptoSignFinalCreate+  , cryptoSignFinalVerify+  , cryptoSignED25519SkToSeed+  , cryptoSignED25519SkToPk++    -- * Constants+  , cryptoSignStateBytes+  , cryptoSignPublicKeyBytes+  , cryptoSignSecretKeyBytes+  , cryptoSignBytes+  , cryptoSignSeedBytes+  )+where++import Foreign (Ptr, allocaBytes)+import Foreign.C (CInt (..), CSize (..), CUChar (..), CULLong (..))++-- $introduction+--+-- When signing with public-key cryptography, a signer generates a key pair consisting of:+--+--   * A secret key, which you can use to append a signature to any number of messages.+--   * A public key, which anybody can use to verify that the signature appended to a+--     message was issued by the creator of the public key.+--+-- Verifiers need to already know and ultimately trust a public key before messages signed using+-- it can be verified.+--+-- Warning: this is different from authenticated encryption. Appending a signature does not change+-- the representation of the message itself.++-------------------------+-- Key pair generation --+-------------------------++-- | Randomly generate a secret key and a corresponding public key.+--+-- /See:/ [crypto_sign_keypair()](https://doc.libsodium.org/public-key_cryptography/public-key_signatures#key-pair-generation)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_sign_keypair"+  cryptoSignKeyPair+    :: Ptr CUChar+    -- ^ A pointer to the buffer holding the public key. It has a length of 'cryptoSignPublicKeyBytes' bytes.+    -> Ptr CUChar+    -- ^ A pointer to the buffer holding the secret key. It has a length of 'cryptoSignSecretKeyBytes' bytes.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++-- | Derive a keypair (secret key and public key) from a seed.+-- It is deterministic.+--+-- /See:/ [crypto_sign_seed_keypair()](https://doc.libsodium.org/public-key_cryptography/public-key_signatures#key-pair-generation)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_sign_seed_keypair"+  cryptoSignSeedKeyPair+    :: Ptr CUChar+    -- ^ A pointer to the buffer holding the public key. It has a length of 'cryptoSignPublicKeyBytes'.+    -> Ptr CUChar+    -- ^ A pointer to the buffer holding the secret key. It has a length of 'cryptoSignSecretKeyBytes'.+    -> Ptr CUChar+    -- ^ A pointer to the seed. It has a length of 'cryptoSignSeedBytes'.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++-------------------+-- Combined Mode --+-------------------++-- | Prepend a signature to a message, using the secret key.+--+-- The signed message, which includes the signature plus an unaltered copy of the message, is put+-- into the signed message buffer, and is of length 'cryptoSignBytes' + @length of the message@ bytes.+--+-- If the pointer to the length of the signed message is not a 'Foreign.nullPtr',+-- then the actual length of the signed message is stored in it.+--+-- /See:/ [crypto_sign()](https://doc.libsodium.org/public-key_cryptography/public-key_signatures#combined-mode)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_sign"+  cryptoSign+    :: Ptr CUChar+    -- ^ Pointer to the signed message.+    -> Ptr CULLong+    -- ^ Pointer to the length of the signed message.+    -> Ptr CUChar+    -- ^ Pointer to the message to sign.+    -> CULLong+    -- ^ Length of the message.+    -> Ptr CUChar+    -- ^ Pointer to the secret key.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++-- | Check that the signed message has a valid signature for the public key.+--+-- On success, it puts the message, without the signature into the first buffer.+-- The length of the message will be stored in the , if the pointer is not a 'Foreign.nullPtr'.+--+-- /See:/ [crypto_sign_open()](https://doc.libsodium.org/public-key_cryptography/public-key_signatures#key-pair-generation)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_sign_open"+  cryptoSignOpen+    :: Ptr CUChar+    -- ^ Pointer to the buffer holding the message without the signature.+    -> Ptr CULLong+    -- ^ Pointer to the buffer holding the length of the message, if it+    -- is not a 'Foreign.nullPtr'.+    -> Ptr CUChar+    -- ^ Pointer to the signed message.+    -> CULLong+    -- ^ Length of the signed message.+    -> Ptr CUChar+    -- ^ Pointer to the public key.+    -> IO CInt+    -- ^ On success, the function returns 0+    -- If the signature isn't valid, then the function returns -1.++-------------------+-- Detached Mode --+-------------------++-- $detachedMode+--+-- In detached mode, the signature is stored without attaching a copy of the original message to it.++-- | Sign the message using the secret key and put the signature into a buffer, which can be up to+-- 'cryptoSignBytes' bytes long.+-- The actual length of the signature is put into a buffer if its pointer is not 'Foreign.nullPtr'.+-- It is safe to ignore the length of the signature and always consider a signature as 'cryptoSignBytes' bytes long;+-- shorter signatures will be transparently padded with zeros if necessary.+--+-- /See:/ [crypto_sign_detached()](https://doc.libsodium.org/public-key_cryptography/public-key_signatures#detached-mode)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_sign_detached"+  cryptoSignDetached+    :: Ptr CUChar+    -- ^ Pointer to the signature.+    -> Ptr CULLong+    -- ^ Pointer to the length of the signature.+    -> Ptr CUChar+    -- ^ Pointer to the message to sign.+    -> CULLong+    -- ^ Length of the message.+    -> Ptr CUChar+    -- ^ Pointer to the secret key.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++-- | Verify that the signature is valid for the message, using the+-- signer's public key.+--+-- /See:/ [crypto_sign_verify_detached()](https://doc.libsodium.org/public-key_cryptography/public-key_signatures#detached-mode)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_sign_verify_detached"+  cryptoSignVerifyDetached+    :: Ptr CUChar+    -- ^ Pointer to the signature+    -> Ptr CUChar+    -- ^ Pointer to the message+    -> CULLong+    -- ^ Length of the message+    -> Ptr CUChar+    -- ^ Pointer to the signer's public key+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++-------------------------+-- Multi-part messages --+-------------------------++-- $mpm+-- If the message you're trying to sign doesn't fit in memory, then it can be provided as a sequence+-- of arbitrarily-sized chunks.+-- This uses the @Ed25519ph@ signature system, which pre-hashes the message. In other words,+-- what gets signed is not the message itself but its image through a hash function. If the message+-- can fit in memory and be supplied as a single chunk, then the single-part API should be+-- preferred.+--+-- == Note+--+-- @Ed25519ph(m)@ is intentionally not equivalent to @Ed25519(SHA512(m))@. If, for+-- some reason, you need to pre-hash the message yourself, then use the multi-part+-- 'LibSodium.Bindings.GenericHashing' module and sign the 512-bit output.++-- | Opaque tag representing the hash state struct @crypto_sign_state@ used by the C API.+--+-- It is of size 'cryptoSignStateBytes'.+--+-- To use a 'CryptoSignState', use 'withSignState'.+--+-- @since 0.0.1.0+data CryptoSignState++-- | Perform an operation with a 'CryptoSignState' of size 'cryptoSignStateBytes' allocated+-- and deallocated automatically.+--+-- ⚠️ The return value of 'withSignState' __MUST NOT__ leak the 'CryptoSignState'.+--+-- Please refer to the documentation of 'Foreign.allocaBytes' for more operational details.+--+-- @since 0.0.1.0+withSignState :: (Ptr CryptoSignState -> IO a) -> IO a+withSignState action = do+  let size :: Int = fromIntegral cryptoSignStateBytes+  allocaBytes size action++-- | Initialise the 'CryptoSignState' state.+--+-- It must be called before the first 'cryptoSignUpdate' call.+--+-- /See:/ [crypto_sign_init()](https://doc.libsodium.org/public-key_cryptography/public-key_signatures#multi-part-messages)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_sign_init"+  cryptoSignInit+    :: Ptr CryptoSignState+    -- ^ A pointer to the cryptographic state. Cannot be 'Foreign.nullPtr'.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++-- | Add a new chunk to the message that will eventually be signed.+--+-- After all parts have been supplied, 'cryptoSignFinalCreate' or 'cryptoSignFinalVerify'+-- can be used.+--+-- /See:/ [crypto_sign_update()](https://doc.libsodium.org/public-key_cryptography/public-key_signatures#multi-part-messages)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_sign_update"+  cryptoSignUpdate+    :: Ptr CryptoSignState+    -- ^ A pointer to an initialized cryptographic state. Cannot be 'Foreign.nullPtr'.+    -> Ptr CUChar+    -- ^ Pointer to the new chunk to sign.+    -> CULLong+    -- ^ Length of the new chunk.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++-- | Compute a signature for the previously supplied message+-- using the secret key, and put it into the signature buffer.+--+-- If the pointer to the length of the signature is not a 'Foreign.nullPtr',+-- then the length of the signature is stored at this address.+-- It is safe to ignore the length of the signature and always consider+-- a signature as 'cryptoSignBytes' bytes long;+-- shorter signatures will be transparently padded with zeros if necessary.+--+-- /See:/ [crypto_sign_final_create()](https://doc.libsodium.org/public-key_cryptography/public-key_signatures#multi-part-messages)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_sign_final_create"+  cryptoSignFinalCreate+    :: Ptr CryptoSignState+    -- ^ A pointer to an initialized cryptographic state. Cannot be 'Foreign.nullPtr'.+    -> Ptr CUChar+    -- ^ Pointer to the signature. Cannot be 'Foreign.nullPtr'.+    -> Ptr CULLong+    -- ^ A pointer to the length of the signature. Can be 'Foreign.nullPtr'.+    -> Ptr CUChar+    -- ^ Pointer to the secret key. Cannot be 'Foreign.nullPtr'.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++-- | Verify that the signature is valid using the public key+-- for the message whose content has been previously supplied using 'cryptoSignUpdate'.+--+-- /See:/ [crypto_sign_final_verify()](https://doc.libsodium.org/public-key_cryptography/public-key_signatures#multi-part-messages)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_sign_final_verify"+  cryptoSignFinalVerify+    :: Ptr CryptoSignState+    -- ^ A pointer to an initialized cryptographic state. Cannot be 'Foreign.nullPtr'.+    -> Ptr CUChar+    -- ^ Pointer to the signature.+    -> Ptr CUChar+    -- ^ Pointer to the public key.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++-- | This function extracts the seed from the+-- secret key secret key and copies it into the buffer holding the seed.+-- The size of the seed will be equal to 'cryptoSignSeedBytes'.+--+-- /See:/ [crypto_sign_ed25519_sk_to_seed()](https://doc.libsodium.org/public-key_cryptography/public-key_signatures#extracting-the-seed-and-the-public-key-from-the-secret-key)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_sign_ed25519_sk_to_seed"+  cryptoSignED25519SkToSeed+    :: Ptr CUChar+    -- ^ Pointer to the seed.+    -> Ptr CUChar+    -- ^ Pointer to the secret key.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++-- | This function extracts the public key from the secret key secret key+-- and copies it into public key.+-- The size of public key will be equal to 'cryptoSignPublicKeyBytes'.+--+-- /See:/ [crypto_sign_ed25519_sk_to_pk()](https://doc.libsodium.org/public-key_cryptography/public-key_signatures#extracting-the-seed-and-the-public-key-from-the-secret-key)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_sign_ed25519_sk_to_pk"+  cryptoSignED25519SkToPk+    :: Ptr CUChar+    -- ^ Pointer to the public key.+    -> Ptr CUChar+    -- ^ Pointer to the secret key.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++---------------+-- Constants --+---------------++-- | The amount of memory needed to store a 'CryptoSignState'.+--+-- /See:/ [crypto_sign_statebytes](https://doc.libsodium.org/public-key_cryptography/public-key_signatures#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_sign_statebytes"+  cryptoSignStateBytes :: CSize++-- |+--+-- /See:/ [crypto_sign_PUBLICKEYBYTES](https://doc.libsodium.org/public-key_cryptography/public-key_signatures#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_sign_PUBLICKEYBYTES"+  cryptoSignPublicKeyBytes :: CSize++-- |+--+-- /See:/ [crypto_sign_SECRETKEYBYTES](https://doc.libsodium.org/public-key_cryptography/public-key_signatures#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_sign_SECRETKEYBYTES"+  cryptoSignSecretKeyBytes :: CSize++-- |+--+-- /See:/ [crypto_sign_BYTES](https://doc.libsodium.org/public-key_cryptography/public-key_signatures#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_sign_BYTES"+  cryptoSignBytes :: CSize++-- |+--+-- /See:/ [crypto_sign_SEEDBYTES](https://doc.libsodium.org/public-key_cryptography/public-key_signatures#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_sign_SEEDBYTES"+  cryptoSignSeedBytes :: CSize
+ src/LibSodium/Bindings/GenericHashing.hs view
@@ -0,0 +1,247 @@+{-# LANGUAGE CApiFFI #-}+{-# LANGUAGE Trustworthy #-}++-- |+--+-- Module: LibSodium.Bindings.GenericHashing+-- Description: Direct bindings to the Blake2 hashing primitives of Libsodium.+-- Copyright: (C) Hécate Moonlight 2022+-- License: BSD-3-Clause+-- Maintainer: The Haskell Cryptography Group+-- Stability: Stable+-- Portability: GHC only+module LibSodium.Bindings.GenericHashing+  ( -- * Introduction+    -- $introduction++    -- * Operations+    CryptoGenericHashState+  , cryptoGenericHash+  , cryptoGenericHashKeyGen+  , withGenericHashState+  , withGenericHashStateOfSize+  , cryptoGenericHashInit+  , cryptoGenericHashUpdate+  , cryptoGenericHashFinal++    -- * Constants+  , cryptoGenericHashBytes+  , cryptoGenericHashBytesMin+  , cryptoGenericHashBytesMax+  , cryptoGenericHashKeyBytes+  , cryptoGenericHashKeyBytesMin+  , cryptoGenericHashKeyBytesMax+  , cryptoGenericHashStateBytes+  )+where++import Foreign (Ptr, allocaBytes)+import Foreign.C (CInt (CInt), CSize (CSize), CUChar, CULLong (CULLong))++-- $introduction+-- This API computes a fixed-length fingerprint for an arbitrarily long message.+-- It is backed by the [BLAKE2b](https://blake2.net) algorithm.+--+-- Sample use cases:+--+--   * File integrity checking+--   * Creating unique identifiers to index arbitrarily long data+--+-- ⚠️ Do not use this API module to hash passwords!+--+-- Whenever there is a @'Ptr' 'CryptoGenericHashState'@, it must point to enough memory+-- to hold the hash state.+-- This is at least 'cryptoGenericHashBytesMin', at most+-- 'cryptoGenericHashBytesMax', and should typically be 'cryptoGenericHashBytes'.+-- It is the caller's responsibility to ensure that this holds.++-- | Opaque tag representing the hash state struct @crypto_generichash_state@ used by the C API.+--+-- To use a 'CryptoGenericHashState', use 'withGenericHashState'.+--+-- @since 0.0.1.0+data CryptoGenericHashState++-- | This function allocates a 'CryptoGenericHashState' of size 'cryptoGenericHashBytes'.+-- If you want more control over the size of the hash state, use 'withGenericHashStateOfSize'.+--+-- ⚠️ Do not leak the 'CryptoGenericHashState' outside of the lambda,+-- otherwise you will point at deallocated memory!+--+-- @since 0.0.1.0+withGenericHashState :: (Ptr CryptoGenericHashState -> IO a) -> IO a+withGenericHashState action = withGenericHashStateOfSize cryptoGenericHashBytes action++-- | This function allocates a 'CryptoGenericHashState' of the desired size.+--+-- Use the following constants as parameter to this function:+--+--   * 'cryptoGenericHashBytesMin' (16U)+--   * 'cryptoGenericHashBytes' (32U)+--   * 'cryptoGenericHashBytesMax' (64U)+--+-- @since 0.0.1.0+withGenericHashStateOfSize :: CSize -> (Ptr CryptoGenericHashState -> IO a) -> IO a+withGenericHashStateOfSize size action = allocaBytes (fromIntegral size) action++-- | Put a fingerprint of the message (the @in@ parameter) of length @inlen@ into+-- the @out@ buffer.+-- The minimum recommended output size (@outlen@) is 'cryptoGenericHashBytes'.+-- However, for specific use cases, the size can be any value between 'cryptoGenericHashBytesMin' (included)+-- and 'cryptoGenericHashBytesMax' (included).+--+-- The @key@ parameter can be 'Foreign.nullPtr' and keylen can be 0. In this case, a message will always have the same fingerprint+-- But a key can also be specified. A message will always have the same fingerprint for a given key, but different+-- keys used to hash the same message are very likely to produce distinct fingerprints.+-- In particular, the key can be used to make sure that different applications generate different fingerprints even+-- if they process the same data.+--+-- The recommended key size is 'cryptoGenericHashKeyBytes' bytes.+--+-- However, the key size can be any value between 0 (included) and 'cryptoGenericHashKeyBytesMax' (included).+-- If the key is meant to be secret, the recommended minimum length is 'cryptoGenericHashKeyBytesMin'.+--+-- /See:/ [crypto_generichash()](https://doc.libsodium.org/hashing/generic_hashing#usage)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_generichash"+  cryptoGenericHash+    :: Ptr CUChar+    -- ^ @out@ parameter.+    -> CSize+    -- ^ @outlen@ parameter.+    -> Ptr CUChar+    -- ^ @in@ parameter.+    -> CULLong+    -- ^ @inlen@ parameter.+    -> Ptr CUChar+    -- ^ @key@ parameter.+    -> CSize+    -- ^ @keylen@ parameter.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++-- | Initialise a hash state with a key of a specified length, and+-- produce an output with the specified length in bytes.+--+-- The @'Ptr' 'CUChar'@ argument must point to enough memory to hold a key,+-- which must also be initialised.+-- This is at least 'cryptoGenericHashKeyBytesMin', at most+-- 'cryptoGenericHashKeyBytesMax', and should typically be 'cryptoGenericHashKeyBytes'.+-- It is the caller's responsibility to ensure that these hold.+--+-- /See:/ [crypto_generichash_init()](https://doc.libsodium.org/hashing/generic_hashing#usage)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_generichash_init"+  cryptoGenericHashInit+    :: Ptr CryptoGenericHashState+    -- ^ Pointer to the hash state+    -> Ptr CUChar+    -- ^ Pointer to a key+    -> CSize+    -- ^ Length of the key+    -> CSize+    -- ^ Length of the result+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++-- | If you process a message in chunks, you can sequentially process each chunk by calling 'cryptoGenericHashUpdate'+-- by providing a pointer to the previously initialised state, a pointer to the input chunk,+-- and the length of the chunk in bytes.+--+-- /See:/ [crypto_generichash_update()](https://doc.libsodium.org/hashing/generic_hashing#usage)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_generichash_update"+  cryptoGenericHashUpdate+    :: Ptr CryptoGenericHashState+    -- ^ Pointer to the hash state+    -> Ptr CUChar+    -- ^ Pointer to a chunk to be processed+    -> CULLong+    -- ^ Length of the chunk in bytes+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++-- | After processing everything you need with 'cryptoGenericHashUpdate', you can finalise the operation+-- with 'cryptoGenericHashFinal'.+--+-- /See:/ [crypto_generichash_final()](https://doc.libsodium.org/hashing/generic_hashing#usage)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_generichash_final"+  cryptoGenericHashFinal+    :: Ptr CryptoGenericHashState+    -- ^ The hash state used throughout the previous hashing operations.+    -> Ptr CUChar+    -- ^ The pointer to the resulting fingerprint.+    -> CSize+    -- ^ Size of the hash.+    -> IO CInt+    -- ^ Returns 0 on success, -1 if called twice.++-- | This function creates a key of the recommended length 'cryptoGenericHashKeyBytes'.+--+-- /See:/ [crypto_generichash_keygen()](https://doc.libsodium.org/hashing/generic_hashing#usage)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_generichash_keygen"+  cryptoGenericHashKeyGen+    :: Ptr CUChar+    -- ^ A pointer to the key+    -> IO ()++-- | Size of the generated hash.+--+-- /See:/ [crypto_generichash_BYTES](https://doc.libsodium.org/hashing/generic_hashing#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_generichash_BYTES"+  cryptoGenericHashBytes :: CSize++-- | Minimum size of a generated hash+--+-- /See:/ [crypto_generichash_BYTES_MIN](https://doc.libsodium.org/hashing/generic_hashing#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_generichash_BYTES_MIN"+  cryptoGenericHashBytesMin :: CSize++-- | Maximum size of a generated hash+--+-- /See:/ [crypto_generichash_BYTES_MAX](https://doc.libsodium.org/hashing/generic_hashing#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_generichash_BYTES_MAX"+  cryptoGenericHashBytesMax :: CSize++-- | Size of a generated key+--+-- /See:/ [crypto_generichash_KEYBYTES](https://doc.libsodium.org/hashing/generic_hashing#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_generichash_KEYBYTES"+  cryptoGenericHashKeyBytes :: CSize++-- | Minimum size of a generated key+--+-- /See:/ [crypto_generichash_KEYBYTES_MIN](https://doc.libsodium.org/hashing/generic_hashing#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_generichash_KEYBYTES_MIN"+  cryptoGenericHashKeyBytesMin :: CSize++-- | Maximum size of a generated key+--+-- /See:/ [crypto_generichash_KEYBYTES_MAX](https://doc.libsodium.org/hashing/generic_hashing#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_generichash_KEYBYTES_MAX"+  cryptoGenericHashKeyBytesMax :: CSize++-- | Size of a 'CryptoGenericHashState'+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_generichash_blake2b_statebytes"+  cryptoGenericHashStateBytes :: CSize
+ src/LibSodium/Bindings/KeyDerivation.hs view
@@ -0,0 +1,101 @@+{-# LANGUAGE CApiFFI #-}++-- |+-- Module: LibSodium.Bindings.KeyDerivation+-- Description: Direct bindings to the key exchange functions implemented in Libsodium. The algorithm used is blake2b.+-- Copyright: (C) Hécate Moonlight 2022+-- License: BSD-3-Clause+-- Maintainer: The Haskell Cryptography Group+-- Stability: Stable+-- Portability: GHC only+module LibSodium.Bindings.KeyDerivation+  ( -- * Introduction+    -- $introduction++    -- ** Key Generation+    cryptoKDFKeygen+  , cryptoKDFDeriveFromKey++    -- ** Constants+  , cryptoKDFBytesMin+  , cryptoKDFBytesMax+  , cryptoKDFKeyBytes+  , cryptoKDFContextBytes+  )+where++import Foreign (Ptr, Word64, Word8)+import Foreign.C (CChar, CInt (CInt), CSize (CSize), CUChar)++-- $introduction+--+-- From a single, high-entropy key, you can derive multiple secret sub-keys.+--+-- This API can derive up to 2⁶⁴ keys from a single key and context, and these+-- sub-keys can have an arbitrary length between 128 (16 bytes) and 512 bits (64 bytes).++-- | Generate a high-entropy key from which the sub-keys will be derived.+--+-- /See:/ [crypto_kdf_keygen()](https://doc.libsodium.org/key_derivation)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_kdf_keygen"+  cryptoKDFKeygen+    :: Ptr Word8+    -- ^ Pointer that will hold the master key of length 'cryptoKDFKeyBytes'+    -> IO ()++-- | Derive a sub-key from a high-entropy secre key with a unique identifier.+-- The identifier can be any value up to 2⁶⁴-1+--+-- /See:/ [crypto_kdf_derive_from_key()](https://doc.libsodium.org/key_derivation)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_kdf_derive_from_key"+  cryptoKDFDeriveFromKey+    :: Ptr CUChar+    -- ^ Pointer that will hold the sub-key.+    -> CSize+    -- ^ Length of the sub-key.+    -> Word64+    -- ^ Identifier of the sub-key. Must not be reused for another sub-key.+    -> Ptr CChar+    -- ^ Pointer to the context, of size 'cryptoKDFContextBytes'.+    -> Ptr CUChar+    -- ^ Pointer to the master key, which will be of length 'cryptoKDFKeyBytes'.+    -> IO CInt+    -- ^ Returns 0 on success and -1 on error.++-- == Constants++-- | Minimum length of a sub-key.+--+-- /See:/ [crypto_kdf_BYTES_MIN](https://doc.libsodium.org/key_derivation)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_kdf_BYTES_MIN"+  cryptoKDFBytesMin :: CSize++-- | Maximum length of a sub-key.+--+-- /See:/ [crypto_kdf_BYTES_MAX](https://doc.libsodium.org/key_derivation)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_kdf_BYTES_MAX"+  cryptoKDFBytesMax :: CSize++-- | Length of a Context.+--+-- /See:/ [crypto_kdf_CONTEXTBYTES](https://doc.libsodium.org/key_derivation)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_kdf_CONTEXTBYTES"+  cryptoKDFContextBytes :: CSize++-- | Length of the master key.+--+-- /See:/ [crypto_kdf_KEYBYTES](https://doc.libsodium.org/key_derivation)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_kdf_KEYBYTES"+  cryptoKDFKeyBytes :: CSize
+ src/LibSodium/Bindings/KeyExchange.hs view
@@ -0,0 +1,184 @@+{-# LANGUAGE CApiFFI #-}+{-# LANGUAGE ScopedTypeVariables #-}++-- |+-- Module: LibSodium.Bindings.KeyExchange+-- Description: Direct bindings to the key exchange functions implemented in Libsodium+-- Copyright: (C) Hécate Moonlight 2022+-- License: BSD-3-Clause+-- Maintainer: The Haskell Cryptography Group+-- Stability: Stable+-- Portability: GHC only+module LibSodium.Bindings.KeyExchange+  ( -- * Introduction+    -- $introduction++    -- * Key Exchange++    -- ** Key generation+    cryptoKXKeyPair+  , cryptoKXSeedKeypair++    -- ** Client+  , cryptoKXClientSessionKeys++    -- ** Server+  , cryptoKXServerSessionKeys++    -- ** Constants+  , cryptoKXPublicKeyBytes+  , cryptoKXSecretKeyBytes+  , cryptoKXSeedBytes+  , cryptoKXSessionKeyBytes+  , cryptoKXPrimitive+  )+where++import Foreign (Ptr)+import Foreign.C (CChar, CInt (CInt), CSize (CSize), CUChar)++-- $introduction+--+-- The key exchange API allows two parties to securely compute a set of shared keys using their peer's public key, and+-- their own secret key.++-- | Create a new key pair.+--+-- This function takes pointers to two empty buffers that will hold (respectively) the public and secret keys.+--+-- /See:/ [crypto_kx_keypair()](https://doc.libsodium.org/key_exchange#usage)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_kx_keypair"+  cryptoKXKeyPair+    :: Ptr CUChar+    -- ^ The buffer that will hold the public key, of size 'cryptoKXPublicKeyBytes'.+    -> Ptr CUChar+    -- ^ The buffer that will hold the secret key, of size 'cryptoKXSecretKeyBytes'.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++-- | Create a new key pair from a seed.+--+-- This function takes pointers to two empty buffers that will hold (respectively) the public and secret keys,+-- as well as the seed from which these keys will be derived.+--+-- /See:/ [crypto_kx_seed_keypair()](https://doc.libsodium.org/key_exchange#usage)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_kx_seed_keypair"+  cryptoKXSeedKeypair+    :: Ptr CUChar+    -- ^ The buffer that will hold the public key, of size 'cryptoKXPublicKeyBytes'.+    -> Ptr CUChar+    -- ^ The buffer that will hold the secret key, of size 'cryptoKXSecretKeyBytes'.+    -> Ptr CUChar+    -- ^ The pointer to the seed from which the keys are derived. It is of size 'cryptoKXSeedBytes' bytes.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++-- | Compute a pair of shared session keys (secret and public).+--+-- These session keys are computed using:+--+-- * The client's public key+-- * The client's secret key+-- * The server's public key+--+-- The shared secret key should be used by the client to receive data from the server, whereas the shared+-- public key should be used for data flowing to the server.+--+-- If only one session key is required, either the pointer to the shared secret key or the pointer+-- to the shared public key can be set to 'Foreign.nullPtr'.+--+-- /See:/ [crypto_kx_client_session_keys()](https://doc.libsodium.org/key_exchange#usage)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_kx_client_session_keys"+  cryptoKXClientSessionKeys+    :: Ptr CUChar+    -- ^ A pointer to the buffer that will hold the shared secret key, of size 'cryptoKXSessionKeyBytes' bytes.+    -> Ptr CUChar+    -- ^ A pointer to the buffer that will hold the shared public key, of size 'cryptoKXSessionKeyBytes' bytes.+    -> Ptr CUChar+    -- ^ A pointer to the client's public key, of size 'cryptoKXPublicKeyBytes' bytes.+    -> Ptr CUChar+    -- ^ A pointer to the client's secret key, of size 'cryptoKXSecretKeyBytes' bytes.+    -> Ptr CUChar+    -- ^ A pointer to the server's public key, of size 'cryptoKXPublicKeyBytes' bytes.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error, such as when the server's public key is not acceptable.++--++-- | Compute a pair of shared session keys (secret and public).+--+-- These session keys are computed using:+--+-- * The server's public key+-- * The server's secret key+-- * The client's public key+--+-- The shared secret key should be used by the server to receive data from the client, whereas the shared+-- public key should be used for data flowing to the client.+--+-- If only one session key is required, either the pointer to the shared secret key or the pointer+-- to the shared public key can be set to 'Foreign.nullPtr'.+--+-- /See:/ [crypto_kx_server_session_keys()](https://doc.libsodium.org/key_exchange#usage)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_kx_server_session_keys"+  cryptoKXServerSessionKeys+    :: Ptr CUChar+    -- ^ A pointer to the buffer that will hold the shared secret key, of size 'cryptoKXSessionKeyBytes' bytes.+    -> Ptr CUChar+    -- ^ A pointer to the buffer that will hold the shared public key, of size 'cryptoKXSessionKeyBytes' bytes.+    -> Ptr CUChar+    -- ^ A pointer to the server's public key, of size 'cryptoKXPublicKeyBytes' bytes.+    -> Ptr CUChar+    -- ^ A pointer to the server's secret key, of size 'cryptoKXSecretKeyBytes' bytes.+    -> Ptr CUChar+    -- ^ A pointer to the client's public key, of size 'cryptoKXPublicKeyBytes' bytes.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error, such as when the server's public key is not acceptable.++-- | Size of the public key in bytes.+--+-- /See:/ [crypto_kx_PUBLICKEYBYTES](https://doc.libsodium.org/key_exchange#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_kx_PUBLICKEYBYTES"+  cryptoKXPublicKeyBytes :: CSize++-- | Size of the secret key in bytes.+--+-- /See:/ [crypto_kx_SECRETKEYBYTES](https://doc.libsodium.org/key_exchange#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_kx_SECRETKEYBYTES"+  cryptoKXSecretKeyBytes :: CSize++-- | Size of the seed in bytes.+--+-- /See:/ [crypto_kx_SEEDBYTES](https://doc.libsodium.org/key_exchange#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_kx_SEEDBYTES"+  cryptoKXSeedBytes :: CSize++-- | Size of the session key in bytes.+--+-- /See:/ [crypto_kx_SESSIONKEYBYTES](https://doc.libsodium.org/key_exchange#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_kx_SESSIONKEYBYTES"+  cryptoKXSessionKeyBytes :: CSize++-- | Primitive used by this module+--+-- /See:/ [crypto_kx_PRIMITIVE](https://doc.libsodium.org/key_exchange#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_kx_PRIMITIVE"+  cryptoKXPrimitive :: Ptr CChar
+ src/LibSodium/Bindings/Main.hs view
@@ -0,0 +1,84 @@+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE CApiFFI #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE ScopedTypeVariables #-}++-- | Module: LibSodium.Bindings.Main+-- Description: Wrappers for initialisation+-- Copyright: (C) Koz Ross 2022+-- License: BSD-3-Clause+-- Maintainer: koz.ross@retro-freedom.nz+-- Stability: Stable+-- Portability: GHC only+--+-- @libsodium@ requires initialisation before use. We provide a binding to the+-- initialisation function, as well as some high-level wrappers for applications+-- to use without needing to call an FFI wrapper.+--+-- = Note+--+-- If you are using @cryptography-libsodium@ as a dependency for a library, you+-- are probably not interested in this; it's designed for application authors who+-- need capabilities provided by @cryptography-libsodium@.+module LibSodium.Bindings.Main+  ( -- * High-level wrappers+    secureMain+  , secureMainWithError++    -- * Low-level binding+  , sodiumInit+  )+where++import Data.Kind (Type)+import Foreign.C.Types (CInt (CInt))+import System.Exit (die)++-- | Initialise all security-related functionality, then perform the given+-- action. Abort with an error message if security-related functionality cannot+-- be initialised. This will also indicate failure to the shell, as with 'die'.+--+-- = Use+--+-- > main :: IO ()+-- > main = secureMain doTheThingIActuallyWant+--+-- @since 0.0.1.0+secureMain+  :: forall (a :: Type)+   . IO a+  -- ^ Action that will perform cryptographic operations+  -> IO a+secureMain = secureMainWithError (die "libsodium-bindings: Could not initialise secure functionality, aborting.")++-- | Similar to 'secureMain', but allows responding to a failure of+-- initialisation.+--+-- = Use+--+-- > main :: IO ()+-- > main = secureMainWith reportErrorWithLogging doTheThingIActuallyWant+--+-- @since 0.0.1.0+secureMainWithError+  :: forall (a :: Type)+   . IO a+  -- ^ Code to execute if there is an initialisation failure.+  -> IO a+  -- ^ Action that will perform cryptographic operations after libsodium is initialised.+  -> IO a+secureMainWithError badPath goodPath = do+  !res <- sodiumInit+  if res == (-1) then badPath else goodPath++-- | Initialise @libsodium@ for future use. This only needs to be called once,+-- before any use of any other functionality, but multiple calls to this+-- function are not harmful (just redundant).+--+-- /See:/ [sodium_init()](https://doc.libsodium.org/usage)+--+-- @since 0.0.1.0+foreign import capi "sodium.h sodium_init"+  sodiumInit+    :: IO CInt+    -- ^ 0 if successful, -1 on failure, 1 on repeat calls
+ src/LibSodium/Bindings/PasswordHashing.hs view
@@ -0,0 +1,331 @@+{-# LANGUAGE CApiFFI #-}+{-# LANGUAGE Trustworthy #-}++-- |+--+-- Module: LibSodium.Bindings.PasswordHashing+-- Description: Direct bindings to the password hashing primitives of Libsodium.+-- Copyright: (C) Hécate Moonlight 2022+-- License: BSD-3-Clause+-- Maintainer: The Haskell Cryptography Group+-- Stability: Stable+-- Portability: GHC only+module LibSodium.Bindings.PasswordHashing+  ( -- * Introduction+    -- $introduction++    -- * Operations+    cryptoPWHash+  , cryptoPWHashStr+  , cryptoPWHashStrVerify+  , cryptoPWHashStrNeedsRehash++    -- * Constants+  , cryptoPWHashAlgDefault+  , cryptoPWHashAlgArgon2I13+  , cryptoPWHashAlgArgon2ID13+  , cryptoPWHashSaltBytes+  , cryptoPWHashPasswdMin+  , cryptoPWHashPasswdMax+  , cryptoPWHashOpsLimitInteractive+  , cryptoPWHashOpsLimitSensitive+  , cryptoPWHashOpsLimitModerate+  , cryptoPWHashOpsLimitMin+  , cryptoPWHashOpsLimitMax+  , cryptoPWHashMemLimitModerate+  , cryptoPWHashMemLimitInteractive+  , cryptoPWHashMemLimitSensitive+  , cryptoPWHashMemLimitMin+  , cryptoPWHashMemLimitMax+  , cryptoPWHashBytesMax+  , cryptoPWHashBytesMin+  , cryptoPWHashStrBytes+  , cryptoPWHashStrPrefix+  )+where++import Foreign (Ptr)+import Foreign.C (CChar, CInt (CInt), CLLong (CLLong), CSize (CSize), CUChar, CULLong (CULLong))++-- $introduction+-- This modules provides an API that can be used both for key derivation using a low-entropy input and password storage.+--+-- === Guidelines for choosing the parameters+-- Start by determining how much memory the function can use.+-- What will be the highest number of threads/processes evaluating the function simultaneously+-- (ideally, no more than 1 per CPU core)? How much physical memory is guaranteed to be available?+--+-- Set @memlimit@ to the amount of memory you want to reserve for password hashing.+--+-- Then set @opslimit@ to 3 and measure the time it takes to hash a password.+--+-- If this is way too long for your application, reduce @memlimit@, but keep @opslimit@ set to 3.+--+-- If the function is so fast that you can afford it to be more computationally intensive without+-- any usability issues, then increase @opslimit@.+--+-- For online use (e.g. logging in on a website), a 1 second computation is likely to be the+-- acceptable maximum.+--+-- For interactive use (e.g. a desktop application), a 5 second pause after having entered a+-- password is acceptable if the password doesn't need to be entered more than once per session.+--+-- For non-interactive and infrequent use (e.g. restoring an encrypted backup),+-- an even slower computation can be an option.+--+-- However, the best defense against brute-force password cracking is to use strong passwords.+-- Libraries such as [passwdqc](http://www.openwall.com/passwdqc/) can help enforce this.++-- | This functions derives a key from a password. The computed key is then stored in the @out@ parameter.+--+-- /See:/ [crypto_pwhash()](https://doc.libsodium.org/password_hashing/default_phf)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_pwhash"+  cryptoPWHash+    :: Ptr CUChar+    -- ^ @out@ parameter. It represents the address of a dedicated storage area of @outlen@ bytes.+    -> CLLong+    -- ^ @outlen@ parameter. It is the length of the key derived from the @passwd@ parameter.+    -- This should be a least 'cryptoPWHashBytesMin' and at most 'cryptoPWHashBytesMax'.+    -> Ptr CChar+    -- ^ @passwd@ parameter. It is a pointer to the password that is to be derived.+    -> CULLong+    -- ^ @passwdlen@ parameter. It is the size of the password.+    -> Ptr CUChar+    -- ^ @salt@ parameter. It is of a fixed length established by 'cryptoPWHashSaltBytes'. It should be unpredictable.+    -- 'LibSodium.Bindings.Random.randombytesBuf' is the best way to fill the 'cryptoPWHashSaltBytes' of the+    -- salt.+    -> CULLong+    -- ^ @opslimit@ parameter. It represents the maximum amount of computations to perform. Raising this number will make the function require more CPU cycles+    -- to compute a key. This number must be between 'cryptoPWHashOpsLimitMin' and 'cryptoPWHashOpsLimitMax'.+    -> CSize+    -- ^ @memlimit@ parameter. It is the maximum amount of RAM in bytes that the function will use.+    -- This number must be between 'cryptoPWHashMemLimitMin' 'cryptoPWHashMemLimitMax'+    -> CInt+    -- ^ @alg@ parameter. It is an identifier for the algorithm to use and should be set to one of the following values:+    --     'cryptoPWHashAlgDefault', 'cryptoPWHashAlgArgon2I13' or 'cryptoPWHashAlgArgon2ID13'.+    -> IO CInt+    -- ^ The return code is 0 on success and -1 if the computation didn't complete,+    -- usually because the operating system refused to allocate the amount of requested memory.++-- | This function is used for password storage, like an SQL database.+-- It stores an ASCII-encoded string into its @out@ parameter,+-- which includes:+--+--   * The result of a memory-hard, CPU-intensive hash function applied to the password passwd of length passwdlen;+--   * The automatically generated salt used for the previous computation;+--   * The other parameters required to verify the password, including the algorithm identifier, its version, opslimit, and memlimit.+--+-- The @out@ parameter must be a dedicated storage area that's large enough to hold 'cryptoPWHashStrBytes' bytes,+-- but the actual output string may be shorter.+--+-- /See:/ [crypto_pwhash_str()](https://doc.libsodium.org/password_hashing/default_phf)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_pwhash_str"+  cryptoPWHashStr+    :: Ptr CChar+    -- ^ @out@ parameter. It must be of size 'cryptoPWHashStrBytes'.+    -> Ptr CChar+    -- ^ @passwd@ parameter. Points to a password to be stored.+    -> CULLong+    -- ^ @passwdlen@ parameter. Length of the password.+    -> CULLong+    -- ^ @opslimit@ parameter. It represents the maximum amount of computations to perform.+    -> CSize+    -- ^ @memlimit@ parameter. It is the maximum amount of RAM in bytes that the function will use.+    -> IO CInt+    -- ^ The function returns 0 on success and -1 if it didn't complete successfully.++-- | This function verifies that the @str@ parameter is a valid password verification string+-- (as generated by 'cryptoPWHashStr'), for a @passwd@ whose length is @passwdlen@.+--+-- /See:/ [crypto_pwhash_str_verify()](https://doc.libsodium.org/password_hashing/default_phf)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_pwhash_str_verify"+  cryptoPWHashStrVerify+    :: Ptr CChar+    -- ^ @str@ parameter. It must be zero-terminated.+    -> Ptr CChar+    -- ^ @passwd@ parameter.+    -> CULLong+    -- ^ @passwdlen@ parameter.+    -> IO CInt+    -- ^ It returns 0 if the verification succeeds and -1 on error.++-- | This functions checks if a password verification string @str@ matches the parameters @opslimit@, @memlimit@, and the current default algorithm.+--+-- /See:/ [crypto_pwhash_str_needs_rehash()](https://doc.libsodium.org/password_hashing/default_phf)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_pwhash_str_needs_rehash"+  cryptoPWHashStrNeedsRehash+    :: Ptr CChar+    -- ^ @str@ parameter.+    -> CULLong+    -- ^ @opslimit@ parameter.+    -> CSize+    -- ^ @memlimit@ parameter.+    -> IO CInt+    -- ^ The function returns 0 if the parameters already match the given ones, and returns 1 on error. In particular, It will return 1 if the string appears to be correct but doesn't match the given parameters. In that situation, applications may want to compute a new hash using the current parameters the next time the user logs in.++-- | Numeric indicator for the default algorithm, Argon2id v1.3.+--+-- /See:/ [crypto_pwhash_ALG_DEFAULT](https://doc.libsodium.org/password_hashing/default_phf#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_pwhash_ALG_DEFAULT"+  cryptoPWHashAlgDefault :: CInt++-- | Numeric indicator for the Argon2i v1.3 algorithm.+--+-- /See:/ [crypto_pwhash_ALG_ARGON2I13](https://doc.libsodium.org/password_hashing/default_phf#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_pwhash_ALG_ARGON2I13"+  cryptoPWHashAlgArgon2I13 :: CInt++-- | Numeric indicator for the Argon2id v1.3 algorithm.+--+-- /See:/ [crypto_pwhash_ALG_ARGON2ID13](https://doc.libsodium.org/password_hashing/default_phf#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_pwhash_ALG_ARGON2ID13"+  cryptoPWHashAlgArgon2ID13 :: CInt++-- | Size of the salt parameter, in bytes.+--+-- /See:/ [crypto_pwhash_SALTBYTES](https://doc.libsodium.org/password_hashing/default_phf#constants)+--+--  @since 0.0.1.0+foreign import capi "sodium.h value crypto_pwhash_SALTBYTES"+  cryptoPWHashSaltBytes :: CSize++-- | Minimum size of a password, in bytes.+--+-- /See:/ [crypto_pwhash_PASSWD_MIN](https://doc.libsodium.org/password_hashing/default_phf#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_pwhash_PASSWD_MIN"+  cryptoPWHashPasswdMin :: CSize++-- | Maximum size of a password, in bytes.+--+-- /See:/ [crypto_pwhash_PASSWD_MAX](https://doc.libsodium.org/password_hashing/default_phf#constants)+--+--  @since 0.0.1.0+foreign import capi "sodium.h value crypto_pwhash_PASSWD_MAX"+  cryptoPWHashPasswdMax :: CSize++-- | Upper limit of operations in an interactive setting.+--+-- /See:/ [crypto_pwhash_OPSLIMIT_INTERACTIVE](https://doc.libsodium.org/password_hashing/default_phf#constants)+--+--  @since 0.0.1.0+foreign import capi "sodium.h value crypto_pwhash_OPSLIMIT_INTERACTIVE"+  cryptoPWHashOpsLimitInteractive :: CULLong++-- | Cryptographic perations done in a sensitive setting.+--+-- /See:/ [crypto_pwhash_OPSLIMIT_SENSITIVE](https://doc.libsodium.org/password_hashing/default_phf#constants)+--+--  @since 0.0.1.0+foreign import capi "sodium.h value crypto_pwhash_OPSLIMIT_SENSITIVE"+  cryptoPWHashOpsLimitSensitive :: CULLong++-- | Cryptographic operations in a moderately sensitive setting.+--+-- /See:/ [crypto_pwhash_OPSLIMIT_MODERATE](https://doc.libsodium.org/password_hashing/default_phf#constants)+--+--  @since 0.0.1.0+foreign import capi "sodium.h value crypto_pwhash_OPSLIMIT_MODERATE"+  cryptoPWHashOpsLimitModerate :: CULLong++-- | Lower limit of cryptographic operations.+--+-- /See:/ [crypto_pwhash_OPSLIMIT_MIN](https://doc.libsodium.org/password_hashing/default_phf#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_pwhash_OPSLIMIT_MIN"+  cryptoPWHashOpsLimitMin :: CULLong++-- | Upper limit of cryptographic operations.+--+-- /See:/ [crypto_pwhash_OPSLIMIT_MAX](https://doc.libsodium.org/password_hashing/default_phf#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_pwhash_OPSLIMIT_MAX"+  cryptoPWHashOpsLimitMax :: CULLong++-- | Memory used in a moderately sensitive setting, in bytes.+--+-- /See:/ [crypto_pwhash_MEMLIMIT_MODERATE](https://doc.libsodium.org/password_hashing/default_phf#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_pwhash_MEMLIMIT_MODERATE"+  cryptoPWHashMemLimitModerate :: CSize++-- | Memory used in an interactive setting, in bytes.+--+-- /See:/ [crypto_pwhash_MEMLIMIT_INTERACTIVE](https://doc.libsodium.org/password_hashing/default_phf#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_pwhash_MEMLIMIT_INTERACTIVE"+  cryptoPWHashMemLimitInteractive :: CSize++-- | Memory used in a sensitive setting, in bytes.+--+-- /See:/ [crypto_pwhash_MEMLIMIT_INTERACTIVE](https://doc.libsodium.org/password_hashing/default_phf#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_pwhash_MEMLIMIT_SENSITIVE"+  cryptoPWHashMemLimitSensitive :: CSize++-- | Minimum amount of memory that the caller can use, in bytes.+--+-- /See:/ [crypto_pwhash_MEMLIMIT_MIN](https://doc.libsodium.org/password_hashing/default_phf#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_pwhash_MEMLIMIT_MIN"+  cryptoPWHashMemLimitMin :: CSize++-- | Maximum amount of memory that the caller can use, in bytes.+--+-- /See:/ [crypto_pwhash_MEMLIMIT_MAX](https://doc.libsodium.org/password_hashing/default_phf#constants)+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_pwhash_MEMLIMIT_MAX"+  cryptoPWHashMemLimitMax :: CSize++-- | Maximum size of the hash, in bytes.+--+-- /See:/ [crypto_pwhash_BYTES_MAX](https://doc.libsodium.org/password_hashing/default_phf#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_pwhash_BYTES_MAX"+  cryptoPWHashBytesMax :: CULLong++-- | Minimum size of the hash, in bytes.+--+-- /See:/ [crypto_pwhash_BYTES_MIN](https://doc.libsodium.org/password_hashing/default_phf#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_pwhash_BYTES_MIN"+  cryptoPWHashBytesMin :: CULLong++-- | Expected size of a hash's textual representation, as generated by 'cryptoPWHashStr'.+--+-- /See:/ [crypto_pwhash_BYTES_MIN](https://doc.libsodium.org/password_hashing/default_phf#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_pwhash_STRBYTES"+  cryptoPWHashStrBytes :: CSize++-- | Prefix used in the hash's textual representation, as generated by 'cryptoPWHashStr': @"$argon2id$"@+--+-- /See:/ [crypto_pwhash_STRPREFIX](https://doc.libsodium.org/password_hashing/default_phf#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_pwhash_STRPREFIX"+  cryptoPWHashStrPrefix :: Ptr CChar
+ src/LibSodium/Bindings/Random.hs view
@@ -0,0 +1,61 @@+{-# LANGUAGE CApiFFI #-}++-- | Module: LibSodium.Bindings.Random+-- Description: Secure random number generation+-- Copyright: (C) Koz Ross 2022+-- License: BSD-3-Clause+-- Maintainer: koz.ross@retro-freedom.nz+-- Stability: Stable+-- Portability: GHC only+--+-- A collection of functions for securely generating unpredictable data. This+-- uses the best option on each platform, as follows:+--+-- * On Windows, @RtlGenRandom@.+-- * On FreeBSD and Linux, @getrandom@ syscall.+-- * On other UNIX platforms, @\/dev\/urandom@.+module LibSodium.Bindings.Random+  ( randombytesRandom+  , randombytesUniform+  , randombytesBuf+  )+where++import Data.Word (Word32, Word8)+import Foreign.C.Types (CSize (CSize))+import Foreign.Ptr (Ptr)++-- | Produces an unpredictable four-byte value.+--+-- /See:/ [randombytes_random()](https://doc.libsodium.org/generating_random_data#usage)+--+-- @since 0.0.1.0+foreign import capi "sodium.h randombytes_random"+  randombytesRandom :: IO Word32++-- | Produces an unpredictable four-byte value not larger than the argument. This+-- function guarantees a uniform distribution on results, even if the upper+-- limit is not a power of 2.+--+-- /See:/ [randombytes_uniform()](https://doc.libsodium.org/generating_random_data#usage)+--+-- @since 0.0.1.0+foreign import capi "sodium.h randombytes_uniform"+  randombytesUniform+    :: Word32+    -- ^ upper limit (exclusive)+    -> IO Word32++-- | Fills a buffer of the given size with unpredictable bytes.+--+-- /See:/ [randombytes_buf()](https://doc.libsodium.org/generating_random_data#usage)+--+-- @since 0.0.1.0+foreign import capi "sodium.h randombytes_buf"+  randombytesBuf+    :: Ptr Word8+    -- ^ Out-parameter to fill+    -> CSize+    -- ^ How many bytes to generate+    -> IO ()+    -- ^ No meaningful return value
+ src/LibSodium/Bindings/SHA2.hs view
@@ -0,0 +1,800 @@+{-# LANGUAGE CApiFFI #-}+{-# LANGUAGE ScopedTypeVariables #-}++-- |+--+-- Module: LibSodium.Bindings.SHA2+-- Description: Direct bindings to the SHA-256 and SHA-512 hashing functions, and their HMAC variants+-- Copyright: (C) Hécate Moonlight 2022+-- License: BSD-3-Clause+-- Maintainer: The Haskell Cryptography Group+-- Stability: Stable+-- Portability: GHC only+module LibSodium.Bindings.SHA2+  ( -- * Introduction+    -- $introduction++    -- * SHA-256++    -- ** Single-part message+    cryptoHashSHA256++    -- ** Multi-part messages+  , CryptoHashSHA256State+  , withCryptoHashSHA256State+  , cryptoHashSHA256Init+  , cryptoHashSHA256Update+  , cryptoHashSHA256Final++    -- ** Constants+  , cryptoHashSHA256Bytes+  , cryptoHashSHA256StateBytes++    -- * HMAC-SHA-256++    -- ** Single-part message+  , cryptoAuthHMACSHA256+  , cryptoAuthHMACSHA256Verify+  , cryptoAuthHMACSHA256Keygen++    -- ** Multi-part messages+  , CryptoAuthHMACSHA256State+  , withCryptoAuthHMACSHA256State+  , cryptoAuthHMACSHA256Init+  , cryptoAuthHMACSHA256Update+  , cryptoAuthHMACSHA256Final++    -- ** Constants+  , cryptoAuthHMACSHA256StateBytes+  , cryptoAuthHMACSHA256Bytes+  , cryptoAuthHMACSHA256KeyBytes++    -- * SHA-512++    -- ** Single-part message+  , cryptoHashSHA512++    -- ** Multi-part messages+  , CryptoHashSHA512State+  , withCryptoHashSHA512State+  , cryptoHashSHA512Init+  , cryptoHashSHA512Update+  , cryptoHashSHA512Final++    -- ** Constants+  , cryptoHashSHA512Bytes+  , cryptoHashSHA512StateBytes++    -- * HMAC-SHA-512++    -- ** Single-part message+  , CryptoAuthHMACSHA512State+  , withCryptoAuthHMACSHA512State+  , cryptoAuthHMACSHA512+  , cryptoAuthHMACSHA512Verify+  , cryptoAuthHMACSHA512Keygen++    -- ** Multi-part messages+  , cryptoAuthHMACSHA512Init+  , cryptoAuthHMACSHA512Update+  , cryptoAuthHMACSHA512Final++    -- ** Constants+  , cryptoAuthHMACSHA512StateBytes+  , cryptoAuthHMACSHA512Bytes+  , cryptoAuthHMACSHA512KeyBytes++    -- * HMAC-SHA-512-256+    -- $hmacsha512256++    -- ** Single-part message+  , CryptoAuthHMACSHA512256State+  , withCryptoAuthHMACSHA512256State+  , cryptoAuthHMACSHA512256+  , cryptoAuthHMACSHA512256Verify+  , cryptoAuthHMACSHA512256Keygen++    -- ** Multi-part messages+  , cryptoAuthHMACSHA512256Init+  , cryptoAuthHMACSHA512256Update+  , cryptoAuthHMACSHA512256Final++    -- ** Constants+  , cryptoAuthHMACSHA512256StateBytes+  , cryptoAuthHMACSHA512256Bytes+  , cryptoAuthHMACSHA512256KeyBytes+  )+where++import Foreign (Ptr, allocaBytes)+import Foreign.C (CInt (CInt), CSize (CSize), CUChar, CULLong (CULLong))++-- $introduction+--+-- The SHA-256 and SHA-512 functions are provided for interoperability with other applications. If you are+-- looking for a generic hash function and not specifically SHA-2, using+-- 'LibSodium.Bindings.GenericHashing' (BLAKE2b) might be a better choice.+-- These functions are also not suitable for hashing passwords or deriving keys from passwords.+-- Use 'LibSodium.Bindings.PasswordHashing' instead.+--+-- Only use these functions for interoperability with 3rd party services.+--+-- These functions are not keyed and are thus deterministic. In addition, the untruncated versions+-- are vulnerable to length extension attacks. A message can be hashed in a single pass, but a+-- streaming API is also available to process a message as a sequence of multiple chunks.++-------------+-- SHA-256 --+-------------++-- | Hash the content of the second buffer and put the result in the first buffer.+--+-- /See:/ [crypto_hash_sha256()](https://doc.libsodium.org/advanced/sha-2_hash_function#sha-256)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_hash_sha256"+  cryptoHashSHA256+    :: Ptr CUChar+    -- ^ A pointer to the hash of your data.+    -> Ptr CUChar+    -- ^ A pointer to the data you want to hash.+    -> CULLong+    -- ^ The length of the data you want to hash.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++-- | This is the opaque state held and used by the SHA-256 functions.+--+-- Its size is 'cryptoHashSHA256StateBytes'.+--+-- /See:/ [crypto_hash_sha256_state](https://doc.libsodium.org/advanced/sha-2_hash_function#data-types)+--+-- @since 0.0.1.0+data CryptoHashSHA256State++-- | Perform an operation with a 'CryptoHashSHA256State' of size 'cryptoHashSHA256StateBytes'+-- allocated and deallocated automatically.+--+-- ⚠️ The return value of 'withCryptoHashSHA256State' __MUST NOT__ leak the 'CryptoHashSHA256State'.+--+-- Please refer to the documentation of 'Foreign.allocaBytes' for more operational details.+--+-- @since 0.0.1.0+withCryptoHashSHA256State :: (Ptr CryptoHashSHA256State -> IO a) -> IO a+withCryptoHashSHA256State action = do+  let size :: Int = fromIntegral cryptoHashSHA256StateBytes+  allocaBytes size action++-- | This function initializes the 'CryptoHashSHA256State' state.+--+-- Call this function on a 'Ptr' 'CryptoHashSHA256State' before using it+-- as an argument in any other function in this module.+--+-- /See:/ [crypto_hash_sha256_init()](https://doc.libsodium.org/advanced/sha-2_hash_function#sha-256)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_hash_sha256_init"+  cryptoHashSHA256Init+    :: Ptr CryptoHashSHA256State+    -- ^ A pointer to an uninitialised hash state. Cannot be 'Foreign.nullPtr'.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++-- | Add a new chunk to the message that will eventually be hashed.+--+-- After all parts have been supplied, 'cryptoHashSHA256Final' can be used to finalise the operation+-- and get the final hash.+--+-- /See:/ [crypto_hash_sha256_update()](https://doc.libsodium.org/advanced/sha-2_hash_function#sha-256)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_hash_sha256_update"+  cryptoHashSHA256Update+    :: Ptr CryptoHashSHA256State+    -- ^ A pointer to an initialised hash state. Cannot be 'Foreign.nullPtr'.+    -> Ptr CUChar+    -- ^ A pointer to the new message chunk to process.+    -> CULLong+    -- ^ The length in bytes of the chunk.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++-- | Finalise the hashing of a message. The final hash is padded with extra zeros if necessary,+-- then put in a buffer.+--+-- After this operation, the buffer containing the 'CryptoHashSHA256State' is emptied and+-- cannot be relied upon.+--+-- /See:/ [crypto_hash_sha256_final()](https://doc.libsodium.org/advanced/sha-2_hash_function#sha-256)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_hash_sha256_final"+  cryptoHashSHA256Final+    :: Ptr CryptoHashSHA256State+    -- ^ A pointer to an initialised hash state. Cannot be 'Foreign.nullPtr'.+    -> Ptr CUChar+    -- ^ The buffer in which the final hash is stored.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++-------------------+--  HMAC-SHA-256 --+-------------------++-- | Authenticate a message given its size and a secret key, and produce an authenticator to be+-- validated with 'cryptoAuthHMACSHA256Verify'.+--+-- /See:/ [crypto_auth_hmacsha256()](https://doc.libsodium.org/advanced/hmac-sha2#hmac-sha-256).+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_auth_hmacsha256"+  cryptoAuthHMACSHA256+    :: Ptr CUChar+    -- ^ A pointer to the buffer holding the authenticator.+    -> Ptr CUChar+    -- ^ A pointer to the message to be authenticated.+    -> CULLong+    -- ^ The length of the message to be authenticated.+    -> Ptr CUChar+    -- ^ A pointer to the secret key used for authentication, of length 'cryptoAuthHMACSHA256Bytes'.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++-- | Verify that an authenticator provided by 'cryptoAuthHMACSHA256' is correct.+--+-- /See:/ [crypto_auth_hmacsha256_verify()](https://doc.libsodium.org/advanced/hmac-sha2#hmac-sha-256)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_auth_hmacsha256_verify"+  cryptoAuthHMACSHA256Verify+    :: Ptr CUChar+    -- ^ A pointer to buffer holding the authenticator.+    -> Ptr CUChar+    -- ^ A pointer to the message that is being authenticated.+    -> CULLong+    -- ^ The length of the message that is being authenticated.+    -> Ptr CUChar+    -- ^ A pointer to the secret key, of size 'cryptoAuthHMACSHA256KeyBytes'.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on failure.++-- | Create a random key of the correct length.+--+-- /See:/ [crypto_auth_hmacsha256_keygen()](https://doc.libsodium.org/advanced/hmac-sha2#hmac-sha-256)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_auth_hmacsha256_keygen"+  cryptoAuthHMACSHA256Keygen+    :: Ptr CUChar+    -- ^ A pointer to the buffer that will hold the secret key, of size 'cryptoAuthHMACSHA256KeyBytes'.+    -> IO ()+    -- ^ Nothing is returned++-- | This is the opaque state held and used by the HMAC-SHA-256 functions.+--+-- Its size is 'cryptoAuthHMACSHA256StateBytes' bytes.+--+-- Please refer to the documentation of 'Foreign.allocaBytes' for more operational details.+--+-- /See:/ [crypto_auth_hmacsha256_state](https://doc.libsodium.org/advanced/hmac-sha2#data-types)+--+-- @since 0.0.1.0+data CryptoAuthHMACSHA256State++-- | Perform an operation with a 'CryptoAuthHMACSHA256State' of size 'cryptoAuthHMACSHA256StateBytes'+-- allocated and deallocated automatically.+--+-- ⚠️ The return value of 'withCryptoAuthHMACSHA256State' __MUST NOT__ leak the 'CryptoAuthHMACSHA256State'.+--+-- Please refer to the documentation of 'Foreign.allocaBytes' for more operational details.+--+-- @since 0.0.1.0+withCryptoAuthHMACSHA256State :: (Ptr CryptoAuthHMACSHA256State -> IO a) -> IO a+withCryptoAuthHMACSHA256State action = do+  let size :: Int = fromIntegral cryptoAuthHMACSHA256StateBytes+  allocaBytes size action++-- | This function initializes the 'CryptoAuthHMACSHA256State' state.+--+-- Call this function on a 'Ptr' 'CryptoAuthHMACSHA256State' before using it+-- as an argument in any other function in this module.+--+-- /See:/ [crypto_auth_hmacsha256_init()](https://doc.libsodium.org/advanced/hmac-sha2#hmac-sha-256)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_auth_hmacsha256_init"+  cryptoAuthHMACSHA256Init+    :: Ptr CryptoAuthHMACSHA256State+    -- ^ A pointer to an uninitialised hash state. Cannot be 'Foreign.nullPtr'.+    -> Ptr CUChar+    -- ^ A pointer to the secret key.+    -> CSize+    -- ^ The size of the key.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++-- | Add a new chunk to the message that will eventually be hashed.+--+-- After all parts have been supplied, 'cryptoAuthHMACSHA256Final' can be used to finalise the operation+-- and get the final hash.+--+-- /See:/ [crypto_auth_hmacsha256_update()](https://doc.libsodium.org/advanced/hmac-sha2#hmac-sha-256)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_auth_hmacsha256_update"+  cryptoAuthHMACSHA256Update+    :: Ptr CryptoAuthHMACSHA256State+    -- ^ A pointer to an initialised hash state. Cannot be 'Foreign.nullPtr'.+    -> Ptr CUChar+    -- ^ A pointer to the message to authenticate.+    -> CULLong+    -- ^ The size of the message to authenticate.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++-- | Finalise the hashing of a message. The final hash is padded with extra zeros if necessary,+-- then put in a buffer.+--+-- After this operation, the buffer containing the 'CryptoAuthHMACSHA256State' is emptied and+-- cannot be relied upon.+--+-- /See:/ [crypto_auth_hmacsha256_final()](https://doc.libsodium.org/advanced/hmac-sha2#hmac-sha-256)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_auth_hmacsha256_final"+  cryptoAuthHMACSHA256Final+    :: Ptr CryptoAuthHMACSHA256State+    -- ^ A pointer to an initialised hash state. Cannot be 'Foreign.nullPtr'.+    -> Ptr CUChar+    -- ^ A pointer to the buffer that will hold the authenticator.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++-------------+-- SHA-512 --+-------------++-- | Hash the content of the second buffer and put the result in the first buffer.+--+-- /See:/ [crypto_hash_sha512()](https://doc.libsodium.org/advanced/sha-2_hash_function#sha-512)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_hash_sha512"+  cryptoHashSHA512+    :: Ptr CUChar+    -- ^ A pointer to the hash of your data.+    -> Ptr CUChar+    -- ^ A pointer to the data you want to hash.+    -> CULLong+    -- ^ The length of the data you want to hash.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++-- | This is the opaque state held and used by the SHA-512 functions.+--+-- Its size is 'cryptoHashSHA512StateBytes'.+--+-- /See:/ [crypto_hash_sha512_state](https://doc.libsodium.org/advanced/sha-2_hash_function#data-types)+--+-- @since 0.0.1.0+data CryptoHashSHA512State++-- | Perform an operation with a 'CryptoHashSHA512State of size 'cryptoHashSHA512StateBytes'+-- allocated and deallocated automatically.+--+-- ⚠️ The return value of 'withCryptoHashSHA512State' __MUST NOT__ leak the 'CryptoHashSHA512State'.+--+-- Please refer to the documentation of 'Foreign.allocaBytes' for more operational details.+--+-- @since 0.0.1.0+withCryptoHashSHA512State :: (Ptr CryptoHashSHA512State -> IO a) -> IO a+withCryptoHashSHA512State action = do+  let size :: Int = fromIntegral cryptoHashSHA512StateBytes+  allocaBytes size action++-- | This function initializes the 'CryptoHashSHA512State' state.+--+-- Call this function on a 'Ptr CryptoHashSHA512State' before using it+-- as an argument in any other function in this module.+--+-- /See:/ [crypto_hash_sha512_init()](https://doc.libsodium.org/advanced/sha-2_hash_function#sha-512)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_hash_sha512_init"+  cryptoHashSHA512Init+    :: Ptr CryptoHashSHA512State+    -- ^ A pointer to an initialised hash state. Cannot be 'Foreign.nullPtr'.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++-- | Add a new chunk to the message that will eventually be hashed.+--+-- After all parts have been supplied, 'cryptoHashSHA512Final' can be used to finalise the operation+-- and get the final hash.+--+-- /See:/ [crypto_hash_sha512_update()](https://doc.libsodium.org/advanced/sha-2_hash_function#sha-512)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_hash_sha512_update"+  cryptoHashSHA512Update+    :: Ptr CryptoHashSHA512State+    -- ^ A pointer to an initialised hash state. Cannot be 'Foreign.nullPtr'.+    -> Ptr CUChar+    -- ^ A pointer to the new message chunk to process.+    -> CULLong+    -- ^ The length in bytes of the chunk.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++-- | Finalise the hashing of a message. The final hash is padded with extra zeros if necessary,+-- then put in a buffer.+--+-- After this operation, the buffer containing the 'CryptoHashSHA512State' is emptied and+-- cannot be relied upon.+--+-- /See:/ [crypto_hash_sha512_final()](https://doc.libsodium.org/advanced/sha-2_hash_function#sha-512)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_hash_sha512_final"+  cryptoHashSHA512Final+    :: Ptr CryptoHashSHA512State+    -- ^ A pointer to an initialised hash state. Cannot be 'Foreign.nullPtr'.+    -> Ptr CUChar+    -- ^ The buffer in which the final hash is stored.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++-------------------+--  HMAC-SHA-512 --+-------------------++-- | Authenticate a message given its size and a secret key, and produce an authenticator to be+-- validated with 'cryptoAuthHMACSHA512Verify'.+--+-- /See:/ [crypto_auth_hmacsha512()](https://doc.libsodium.org/advanced/hmac-sha2#hmac-sha-512).+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_auth_hmacsha512"+  cryptoAuthHMACSHA512+    :: Ptr CUChar+    -- ^ A pointer to the buffer holding the authenticator.+    -> Ptr CUChar+    -- ^ A pointer to the message to be authenticated.+    -> CULLong+    -- ^ The length of the message to be authenticated.+    -> Ptr CUChar+    -- ^ A pointer to the secret key used for authentication, of length 'cryptoAuthHMACSHA512Bytes'.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++-- | Verify that an authenticator provided by 'cryptoAuthHMACSHA512' is correct.+--+-- /See:/ [crypto_auth_hmacsha512_verify()](https://doc.libsodium.org/advanced/hmac-sha2#hmac-sha-512)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_auth_hmacsha512_verify"+  cryptoAuthHMACSHA512Verify+    :: Ptr CUChar+    -- ^ A pointer to buffer holding the authenticator.+    -> Ptr CUChar+    -- ^ A pointer to the message that is being authenticated.+    -> CULLong+    -- ^ The length of the message that is being authenticated.+    -> Ptr CUChar+    -- ^ A pointer to the secret key, of size 'cryptoAuthHMACSHA512KeyBytes'.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on failure.++-- | Create a random key of the correct length.+--+-- /See:/ [crypto_auth_hmacsha512_keygen()](https://doc.libsodium.org/advanced/hmac-sha2#hmac-sha-512)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_auth_hmacsha512_keygen"+  cryptoAuthHMACSHA512Keygen+    :: Ptr CUChar+    -- ^ A pointer to the buffer that will hold the secret key, of size 'cryptoAuthHMACSHA512KeyBytes'.+    -> IO ()+    -- ^ Nothing is returned++-- | This is the opaque state held and used by the HMAC-SHA-512 functions.+--+-- Its size is 'cryptoAuthHMACSHA512StateBytes' bytes.+--+-- Please refer to the documentation of 'Foreign.allocaBytes' for more operational details.+--+-- /See:/ [crypto_auth_hmacsha512_state](https://doc.libsodium.org/advanced/hmac-sha2#data-types)+--+-- @since 0.0.1.0+data CryptoAuthHMACSHA512State++-- | Perform an operation with a 'CryptoAuthHMACSHA512State' of size 'cryptoAuthHMACSHA512StateBytes'+-- allocated and deallocated automatically.+--+-- ⚠️ The return value of 'withCryptoAuthHMACSHA512State' __MUST NOT__ leak the 'CryptoAuthHMACSHA512State'.+--+-- Please refer to the documentation of 'Foreign.allocaBytes' for more operational details.+--+-- @since 0.0.1.0+withCryptoAuthHMACSHA512State :: (Ptr CryptoAuthHMACSHA512State -> IO a) -> IO a+withCryptoAuthHMACSHA512State action = do+  let size :: Int = fromIntegral cryptoAuthHMACSHA512StateBytes+  allocaBytes size action++-- | This function initializes the 'CryptoAuthHMACSHA512State' state.+--+-- Call this function on a 'Ptr CryptoAuthHMACSHA512State' before using it+-- as an argument in any other function in this module.+--+-- /See:/ [crypto_auth_hmacsha512_init()](https://doc.libsodium.org/advanced/hmac-sha2#hmac-sha-512)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_auth_hmacsha512_init"+  cryptoAuthHMACSHA512Init+    :: Ptr CryptoAuthHMACSHA512State+    -- ^ A pointer to an uninitialised hash state. Cannot be 'Foreign.nullPtr'.+    -> Ptr CUChar+    -- ^ A pointer to the secret key.+    -> CSize+    -- ^ The size of the key.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++-- | Add a new chunk to the message that will eventually be hashed.+--+-- After all parts have been supplied, 'cryptoAuthHMACSHA512Final' can be used+-- to finalise the operation and get the final hash.+--+-- /See:/ [crypto_auth_hmacsha512_update()](https://doc.libsodium.org/advanced/hmac-sha2#hmac-sha-512)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_auth_hmacsha512_update"+  cryptoAuthHMACSHA512Update+    :: Ptr CryptoAuthHMACSHA512State+    -- ^ A pointer to an initialised hash state. Cannot be 'Foreign.nullPtr'.+    -> Ptr CUChar+    -- ^ A pointer to the message to authenticate.+    -> CULLong+    -- ^ The size of the message to authenticate.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++-- | Finalise the hashing of a message. The final hash is padded with extra zeros if necessary,+-- then put in a buffer.+--+-- After this operation, the buffer containing the 'CryptoAuthHMACSHA512State' is emptied and+-- cannot be relied upon.+--+-- /See:/ [crypto_auth_hmacsha512_final()](https://doc.libsodium.org/advanced/hmac-sha2#hmac-sha-512)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_auth_hmacsha512_final"+  cryptoAuthHMACSHA512Final+    :: Ptr CryptoAuthHMACSHA512State+    -- ^ A pointer to an initialised hash state. Cannot be 'Foreign.nullPtr'.+    -> Ptr CUChar+    -- ^ A pointer to the buffer that will hold the authenticator.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++-----------------------+--  HMAC-SHA-512-256 --+-----------------------++-- $hmacsha512256+-- HMAC-SHA-512-256 is implemented as HMAC-SHA-512 with the output truncated to 256 bits.+-- This is slightly faster than HMAC-SHA-256.+-- Note that this construction is not the same as HMAC-SHA-512\/256, which is HMAC using the SHA-512\/256 function.++-- | Authenticate a message given its size and a secret key, and produce an authenticator to be+-- validated with 'cryptoAuthHMACSHA512256Verify'.+--+-- /See:/ [crypto_auth_hmacsha512256()](https://doc.libsodium.org/advanced/hmac-sha2#hmac-sha-512256-256).+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_auth_hmacsha512256"+  cryptoAuthHMACSHA512256+    :: Ptr CUChar+    -- ^ A pointer to the buffer holding the authenticator.+    -> Ptr CUChar+    -- ^ A pointer to the message to be authenticated.+    -> CULLong+    -- ^ The length of the message to be authenticated.+    -> Ptr CUChar+    -- ^ A pointer to the secret key used for authentication, of length 'cryptoAuthHMACSHA512256Bytes'.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++-- | Verify that an authenticator provided by 'cryptoAuthHMACSHA512256' is correct.+--+-- /See:/ [crypto_auth_hmacsha512256_verify()](https://doc.libsodium.org/advanced/hmac-sha2#hmac-sha-512256-256)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_auth_hmacsha512256_verify"+  cryptoAuthHMACSHA512256Verify+    :: Ptr CUChar+    -- ^ A pointer to buffer holding the authenticator.+    -> Ptr CUChar+    -- ^ A pointer to the message that is being authenticated.+    -> CULLong+    -- ^ The length of the message that is being authenticated.+    -> Ptr CUChar+    -- ^ A pointer to the secret key, of size 'cryptoAuthHMACSHA512256KeyBytes'.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on failure.++-- | Create a random key of the correct length.+--+-- /See:/ [crypto_auth_hmacsha512256_keygen()](https://doc.libsodium.org/advanced/hmac-sha2#hmac-sha-512256-256)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_auth_hmacsha512256_keygen"+  cryptoAuthHMACSHA512256Keygen+    :: Ptr CUChar+    -- ^ A pointer to the buffer that will hold the secret key,+    -- of size 'cryptoAuthHMACSHA512256KeyBytes'.+    -> IO ()+    -- ^ Nothing is returned++-- | This is the opaque state held and used by the HMAC-SHA-512256 functions.+--+-- Its size is 'cryptoAuthHMACSHA512256StateBytes' bytes.+--+-- Please refer to the documentation of 'Foreign.allocaBytes' for more operational details.+--+-- /See:/ [crypto_auth_hmacsha512256_state](https://doc.libsodium.org/advanced/hmac-sha2#data-types)+--+-- @since 0.0.1.0+data CryptoAuthHMACSHA512256State++-- | Perform an operation with a 'CryptoAuthHMACSHA512256State'+-- of size 'cryptoAuthHMACSHA512256StateBytes' allocated and deallocated automatically.+--+-- ⚠️ The return value of 'withCryptoAuthHMACSHA512256State' __MUST NOT__ leak+-- the 'CryptoAuthHMACSHA512256State'.+--+-- Please refer to the documentation of 'Foreign.allocaBytes' for more operational details.+--+-- @since 0.0.1.0+withCryptoAuthHMACSHA512256State :: (Ptr CryptoAuthHMACSHA512256State -> IO a) -> IO a+withCryptoAuthHMACSHA512256State action = do+  let size :: Int = fromIntegral cryptoAuthHMACSHA512256StateBytes+  allocaBytes size action++-- | This function initializes the 'CryptoAuthHMACSHA512256State' state.+--+-- Call this function on a 'Ptr' 'CryptoAuthHMACSHA512256State' before using it+-- as an argument in any other function in this module.+--+-- /See:/ [crypto_auth_hmacsha512256_init()](https://doc.libsodium.org/advanced/hmac-sha2#hmac-sha-512256-256)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_auth_hmacsha512256_init"+  cryptoAuthHMACSHA512256Init+    :: Ptr CryptoAuthHMACSHA512256State+    -- ^ A pointer to an uninitialised hash state. Cannot be 'Foreign.nullPtr'.+    -> Ptr CUChar+    -- ^ A pointer to the secret key.+    -> CSize+    -- ^ The size of the key.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++-- | Add a new chunk to the message that will eventually be hashed.+--+-- After all parts have been supplied, 'cryptoAuthHMACSHA512256Final' can be+-- used to finalise the operation and get the final hash.+--+-- /See:/ [crypto_auth_hmacsha512256_update()](https://doc.libsodium.org/advanced/hmac-sha2#hmac-sha-512256-256)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_auth_hmacsha512256_update"+  cryptoAuthHMACSHA512256Update+    :: Ptr CryptoAuthHMACSHA512256State+    -- ^ A pointer to an initialised hash state. Cannot be 'Foreign.nullPtr'.+    -> Ptr CUChar+    -- ^ A pointer to the message to authenticate.+    -> CULLong+    -- ^ The size of the message to authenticate.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++-- | Finalise the hashing of a message. The final hash is padded with extra zeros if necessary,+-- then put in a buffer.+--+-- After this operation, the buffer containing the 'CryptoAuthHMACSHA512256State' is emptied and+-- cannot be relied upon.+--+-- /See:/ [crypto_auth_hmacsha512256_final()](https://doc.libsodium.org/advanced/hmac-sha2#hmac-sha-512256-256)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_auth_hmacsha512256_final"+  cryptoAuthHMACSHA512256Final+    :: Ptr CryptoAuthHMACSHA512256State+    -- ^ A pointer to an initialised hash state. Cannot be 'Foreign.nullPtr'.+    -> Ptr CUChar+    -- ^ A pointer to the buffer that will hold the authenticator.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++---------------+-- Constants --+---------------++-- | The size of a SHA256-hashed message.+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_hash_sha256_BYTES"+  cryptoHashSHA256Bytes :: CSize++-- | The size of a 'CryptoHashSHA256State'.+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_hash_sha256_statebytes"+  cryptoHashSHA256StateBytes :: CSize++-- | The size of a SHA512-hash message.+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_hash_sha512_BYTES"+  cryptoHashSHA512Bytes :: CSize++-- | The size of a 'CryptoHashSHA512State'.+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_hash_sha512_statebytes"+  cryptoHashSHA512StateBytes :: CSize++-- | The size of a 'CryptoAuthHMACSHA256State'.+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_auth_hmacsha256_statebytes"+  cryptoAuthHMACSHA256StateBytes :: CSize++-- | The size of a HMAC-SHA-256 hash+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_auth_hmacsha256_BYTES"+  cryptoAuthHMACSHA256Bytes :: CSize++-- | The size of a HMAC-SHA-256 key+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_auth_hmacsha256_KEYBYTES"+  cryptoAuthHMACSHA256KeyBytes :: CSize++-- | The size of a HMAC-SHA-512 hash+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_auth_hmacsha512_BYTES"+  cryptoAuthHMACSHA512Bytes :: CSize++-- | The size of a HMAC-SHA-512 key+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_auth_hmacsha512_KEYBYTES"+  cryptoAuthHMACSHA512KeyBytes :: CSize++-- | The size of a 'CryptoAuthHMACSHA512State'.+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_auth_hmacsha512_statebytes"+  cryptoAuthHMACSHA512StateBytes :: CSize++-- | The size of a HMAC-SHA-512256 hash+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_auth_hmacsha512256_BYTES"+  cryptoAuthHMACSHA512256Bytes :: CSize++-- | The size of a HMAC-SHA-512256 key+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_auth_hmacsha512256_KEYBYTES"+  cryptoAuthHMACSHA512256KeyBytes :: CSize++-- | The size of a 'CryptoAuthHMACSHA512256State'.+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_auth_hmacsha512256_statebytes"+  cryptoAuthHMACSHA512256StateBytes :: CSize
+ src/LibSodium/Bindings/Scrypt.hs view
@@ -0,0 +1,292 @@+{-# LANGUAGE CApiFFI #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE Trustworthy #-}+{-# OPTIONS_GHC -Wno-unused-imports #-}++-- |+--+-- Module: LibSodium.Bindings.Scrypt+-- Description: Direct bindings to the scrypt password hashing function.+-- Copyright: (C) Hécate Moonlight 2022+-- License: BSD-3-Clause+-- Maintainer: The Haskell Cryptography Group+-- Stability: Stable+-- Portability: GHC only+module LibSodium.Bindings.Scrypt+  ( -- * Introduction+    -- $introduction++    -- * Key Derivation+    cryptoPWHashScryptSalsa2018SHA256++    -- * Password storage+  , cryptoPWHashScryptSalsa2018SHA256Str+  , cryptoPWHashScryptSalsa2018SHA256StrVerify++    -- * Constants+  , cryptoPWHashScryptSalsa2018SHA256BytesMin+  , cryptoPWHashScryptSalsa2018SHA256BytesMax+  , cryptoPWHashScryptSalsa2018SHA256PasswdMin+  , cryptoPWHashScryptSalsa2018SHA256PasswdMax+  , cryptoPWHashScryptSalsa2018SHA256SaltBytes+  , cryptoPWHashScryptSalsa2018SHA256StrBytes+  , cryptoPWHashScryptSalsa2018SHA256StrPrefix+  , cryptoPWHashScryptSalsa2018SHA256OpsLimitMin+  , cryptoPWHashScryptSalsa2018SHA256OpsLimitMax+  , cryptoPWHashScryptSalsa2018SHA256MemLimitMin+  , cryptoPWHashScryptSalsa2018SHA256MemLimitMax+  , cryptoPWHashScryptSalsa2018SHA256OpsLimitInteractive+  , cryptoPWHashScryptSalsa2018SHA256MemLimitInteractive+  , cryptoPWHashScryptSalsa2018SHA256OpsLimitSensitive+  , cryptoPWHashScryptSalsa2018SHA256MemLimitSensitive+  )+where++import Foreign (Ptr)+import Foreign.C (CChar (CChar), CInt (CInt), CSize (CSize), CUChar, CULLong (CULLong))++-- $introduction+-- This is an implementation of the scrypt password hashing function.+-- However, unless you have specific reasons to use scrypt, you __should__ instead consider the default function Argon2.+--+-- == Glossary+--+-- * /opslimit/: The maximum amount of computations to perform. Raising this number will make the function require more CPU cycles to compute a key.+-- * /memlimit/: The maximum amount of RAM in bytes that the function will use.+--+-- == Guidelines for choosing scrypt parameters+--+-- Start by determining how much memory the scrypt function can use.+--+-- * What will be the highest number of threads/processes evaluating the function+-- simultaneously (ideally, no more than 1 per CPU core)?+--+-- * How much physical memory is guaranteed to be available?+-- The /memlimit/ parameter should be a power of 2.+--+-- Do not use anything less than 16 MiB, even for interactive use.+-- A reasonable starting point for /opslimit/ is @memlimit / 32@.+-- Measure how long the scrypt function needs to hash a password.+-- If this is way too long for your application, reduce /memlimit/ and adjust /opslimit/ using the above formula.+-- If the function is so fast that you can afford it to be more computationally intensive without any usability issues, increase /opslimit/. For online use (e.g.+-- logging in on a website), a 1 second computation is likely to be the acceptable maximum. For interactive use (e.g. a desktop application), a 5 second+-- pause after having entered a password is acceptable if the password doesn't need to be entered more than once per session. For non-interactive and+-- infrequent use (e.g. restoring an encrypted backup), an even slower computation can be an option. However, the best defense against brute-force password+-- cracking is to use strong passwords. Libraries such as [passwdqc](https://www.openwall.com/passwdqc/) can help enforce this.+--+-- == Notes+--+-- Do not use constants to verify a password or produce a deterministic output.+-- Save the parameters alongside the hash instead.+-- By doing so, passwords can be rehashed using different parameters if required later on.+--+-- By design, a password whose length is 65 bytes or more is reduced to SHA-256(password).+-- This can have security implications if the password is present in another password database+-- using raw, unsalted SHA-256 or when upgrading passwords previously hashed with unsalted SHA-256 to scrypt.+--+-- It is highly recommended to use 'LibSodium.Bindings.SecureMemory.lock'+-- to lock memory regions storing plaintext passwords and to call+-- 'LibSodium.Bindings.SecureMemory.unlock' right after+-- 'cryptoPWHashScryptSalsa2018SHA256Str' and 'cryptoPWHashScryptSalsa2018SHA256StrVerify'+-- return.++-- | Derive a key from a password.+--+-- For interactive, online operations, 'cryptoPWHashScryptSalsa2018SHA256OpsLimitInteractive'+-- and 'cryptoPWHashScryptSalsa2018SHA256MemLimitInteractive' provide a safe baseline to be used.+-- However, using higher values may improve security.+--+-- For highly sensitive data, 'cryptoPWHashScryptSalsa2018SHA256OpsLimitSensitive' and+-- 'cryptoPWHashScryptSalsa2018SHA256MemLimitSensitive' can be used as an alternative.+-- However, with these parameters, deriving a key takes about+-- 2 seconds on a 2.8 GHz Core i7 CPU and requires up to 1 GiB of dedicated RAM.+--+-- The salt should be unpredictable. 'LibSodium.Bindings.Random.randombytesBuf'+-- is the easiest way to fill the 'cryptoPWHashScryptSalsa2018SHA256SaltBytes' bytes+-- of the salt.+--+-- Keep in mind that to produce the same key from the same password, the same salt,+-- opslimit, and memlimit values must be used. Therefore, these parameters must be stored for each user.+--+-- /See:/ [crypto_pwhash_scryptsalsa208sha256()](https://doc.libsodium.org/advanced/scrypt#key-derivation)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_pwhash_scryptsalsa208sha256"+  cryptoPWHashScryptSalsa2018SHA256+    :: Ptr CUChar+    -- ^ A pointer to the computed key.+    -> CULLong+    -- ^ The length of the computed key.+    -- Should be  between 'cryptoPWHashScryptSalsa2018SHA256BytesMin'+    -- and 'cryptoPWHashScryptSalsa2018SHA256BytesMax' (~127 GB).+    -> Ptr CChar+    -- ^ A pointer to the password from which the key is derived+    -> CULLong+    -- ^ The length of the password.+    -- Should be between 'cryptoPWHashScryptSalsa2018SHA256PasswdMin'+    -- and 'cryptoPWHashScryptSalsa2018SHA256PasswdMax'.+    -> Ptr CUChar+    -- ^ The salt, of length 'cryptoPWHashScryptSalsa2018SHA256SaltBytes'.+    -> CULLong+    -- ^ /opslimit:/ The maximum amount of computations to perform.+    -- Must be between 'cryptoPWHashScryptSalsa2018SHA256OpsLimitMin'+    -- and 'cryptoPWHashScryptSalsa2018SHA256OpsLimitMax'.+    -> CSize+    -- ^ /memlimit:/ The maximum amount of RAM in bytes that the function will use.+    -- It is highly recommended to allow the function to use at least 16 MiB.+    -- This number must be between 'cryptoPWHashScryptSalsa2018SHA256MemLimitMin'+    -- and 'cryptoPWHashScryptSalsa2018SHA256MemLimitMax'.+    -> IO CInt+    -- ^ Returns 0 on success, -1 if the computation didn't complete,+    -- usually because the operating system refused to allocate the amount of+    -- requested memory.++----------------------+-- Password Storage --+----------------------++-- | Generate an ASCII C-String string which includes:+--+-- * The result of a memory-hard, CPU-intensive hash function applied to the password;+-- * The automatically generated salt used for the previous computation;+-- * The other parameters required to verify the password: opslimit and memlimit.+--+-- /See:/ [crypto_pwhash_scryptsalsa208sha256_str()](https://doc.libsodium.org/advanced/scrypt#password-storage)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_pwhash_scryptsalsa208sha256_str"+  cryptoPWHashScryptSalsa2018SHA256Str+    :: Ptr CChar+    -- ^ A pointer to the buffer receiving the string.+    -> Ptr CChar+    -- ^ The password+    -> CULLong+    -- ^ Password length+    -> CULLong+    -- ^ /opslimit:/ The maximum amount of computations to perform.+    -- The 'cryptoPWHashScryptSalsa2018SHA256OpsLimitInteractive' constant+    -- is a safe baseline value to use.+    -> CSize+    -- ^ /memlimit:/ The maximum amount of RAM in bytes that the function will use.+    -- The 'cryptoPWHashScryptSalsa2018SHA256MemLimitInteractive' constant+    -- is a safe baseline value to use.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++-- | Verify that the password verification string is valid for the associated password.+--+-- /See:/ [crypto_pwhash_scryptsalsa208sha256_str_verify()](https://doc.libsodium.org/advanced/scrypt#password-storage)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_pwhash_scryptsalsa208sha256_str_verify"+  cryptoPWHashScryptSalsa2018SHA256StrVerify+    :: Ptr CChar+    -- ^ The password verification C-string, of size 'cryptoPWHashScryptSalsa2018SHA256StrBytes' bytes.+    -> Ptr CChar+    -- ^ The password.+    -> CULLong+    -- ^ The password length.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on password verification failure.++---------------+-- Constants --+---------------++-- | Minimum size of the computed key.+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_pwhash_scryptsalsa208sha256_BYTES_MIN"+  cryptoPWHashScryptSalsa2018SHA256BytesMin :: CSize++-- | Maximum size of the computed key (~127GB).+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_pwhash_scryptsalsa208sha256_BYTES_MAX"+  cryptoPWHashScryptSalsa2018SHA256BytesMax :: CSize++-- | Minimum size of the password.+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_pwhash_scryptsalsa208sha256_PASSWD_MIN"+  cryptoPWHashScryptSalsa2018SHA256PasswdMin :: CSize++-- | Maximum size of the password.+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_pwhash_scryptsalsa208sha256_PASSWD_MAX"+  cryptoPWHashScryptSalsa2018SHA256PasswdMax :: CSize++-- | Length of the salt used by 'cryptoPWHashScryptSalsa2018SHA256'.+-- The easiest way to get a salt is to use 'LibSodium.Bindings.Random.randombytesBuf'.+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_pwhash_scryptsalsa208sha256_SALTBYTES"+  cryptoPWHashScryptSalsa2018SHA256SaltBytes :: CSize++-- | Length of the buffer receiving the string when using+-- 'cryptoPWHashScryptSalsa2018SHA256Str'.+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_pwhash_scryptsalsa208sha256_STRBYTES"+  cryptoPWHashScryptSalsa2018SHA256StrBytes :: CSize++-- | The string prefix that is prepended to the computed keys.+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_pwhash_scryptsalsa208sha256_STRPREFIX"+  cryptoPWHashScryptSalsa2018SHA256StrPrefix :: Ptr CChar++-- | The minimum amount of operations during the computation process+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MIN"+  cryptoPWHashScryptSalsa2018SHA256OpsLimitMin :: CSize++-- | The maximum amount of operations during the computation process+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MAX"+  cryptoPWHashScryptSalsa2018SHA256OpsLimitMax :: CSize++-- | The minimum amount of memory during the computation process+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MIN"+  cryptoPWHashScryptSalsa2018SHA256MemLimitMin :: CSize++-- | The maximum amount of memory during the computation process+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MAX"+  cryptoPWHashScryptSalsa2018SHA256MemLimitMax :: CSize++-- | The amount of operations most suitable for an interactive usage.+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE"+  cryptoPWHashScryptSalsa2018SHA256OpsLimitInteractive :: CSize++-- | The amount of memory most suitable for an interactive usage.+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE"+  cryptoPWHashScryptSalsa2018SHA256MemLimitInteractive :: CSize++-- | The amount of operations most suitable for for highly sensitive data.+--+-- ⚠️  using the sensitive parameters can take up to 2 seconds on a 2.8GHz Core i7 CPU+-- and require up to 1GiB of dedicated RAM.+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE"+  cryptoPWHashScryptSalsa2018SHA256OpsLimitSensitive :: CSize++-- | The amount of memory most suitable for for highly sensitive data.+--+-- ⚠️  using the sensitive parameters can take up to 2 seconds on a 2.8GHz Core i7 CPU+-- and require up to 1GiB of dedicated RAM.+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE"+  cryptoPWHashScryptSalsa2018SHA256MemLimitSensitive :: CSize
+ src/LibSodium/Bindings/SealedBoxes.hs view
@@ -0,0 +1,98 @@+{-# LANGUAGE CApiFFI #-}++-- |+-- Module: LibSodium.Bindings.SealedBoxes+-- Description: Direct bindings to the sealed boxes API of Libsodium+-- License: BSD-3-Clause+-- Maintainer: The Haskell Cryptography Group+-- Stability: Stable+-- Portability: GHC only+module LibSodium.Bindings.SealedBoxes+  ( -- * Introduction+    -- $introduction++    -- * Functions+    cryptoBoxSeal+  , cryptoBoxSealOpen+  , cryptoBoxKeyPair+  , cryptoBoxSeedKeyPair++    -- * Constants+  , cryptoBoxSealbytes+  ) where++import Foreign (Ptr)+import Foreign.C (CInt (CInt), CSize (CSize), CUChar, CULLong (CULLong))+import LibSodium.Bindings.CryptoBox (cryptoBoxKeyPair, cryptoBoxSeedKeyPair)++-- $introduction+-- Sealed boxes are designed to anonymously send messages to a recipient+-- given their public key.+--+-- Only the recipient can decrypt these messages using their secret key.+-- While the recipient can verify the integrity of the message, they cannot+-- verify the identity of the sender.+--+-- A message is encrypted using an ephemeral key pair, with the secret key being+-- erased right after the encryption process.+--+-- Without knowing the secret key used for a given message, the sender cannot decrypt+-- the message later. Furthermore, without additional data, a message cannot be+-- correlated with the identity of its sender.++-- | @cryptoBoxSeal@ creates a new key pair for each message and attaches the public+--   key to the ciphertext. The secret key is overwritten and is not accessible+--   after this function returns.+--+-- /See:/ [crypto_box_seal()](https://doc.libsodium.org/public-key_cryptography/sealed_boxes#usage)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_box_seal"+  cryptoBoxSeal+    :: Ptr CUChar+    -- ^ Buffer that will hold the encrypted message of size+    --   (size of original message + 'cryptoBoxSealbytes') bytes+    -> Ptr CUChar+    -- ^ Buffer that holds the plaintext message+    -> CULLong+    -- ^ Length of the plaintext message+    -> Ptr CUChar+    -- ^ Buffer that holds public key of size+    --  'LibSodium.Bindings.CryptoBox.cryptoBoxPublicKeyBytes' bytes.+    -> IO CInt+    -- ^ Returns 0 on success and -1 on error.++-- | 'cryptoBoxSealOpen' doesn't require passing the public key of+--   the sender as the ciphertext already includes this information.+--+--   Key pairs are compatible with operations from 'LibSodium.Bindings.CryptoBox'+--   module and can be created using 'LibSodium.Bindings.CryptoBox.cryptoBoxKeyPair'+--   or 'LibSodium.Bindings.CryptoBox.cryptoBoxSeedKeyPair'.+--+-- /See:/ [crypto_box_seal_open()](https://doc.libsodium.org/public-key_cryptography/sealed_boxes#usage)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_box_seal_open"+  cryptoBoxSealOpen+    :: Ptr CUChar+    -- ^ Buffer that will hold the plaintext message of size+    --   (size of original message - 'cryptoBoxSealbytes') bytes+    -> Ptr CUChar+    -- ^ Buffer that holds the encrypted message.+    -> CULLong+    -- ^ Length of the encrypted message+    -> Ptr CUChar+    -- ^ Buffer that holds public key of size+    --  'LibSodium.Bindings.CryptoBox.cryptoBoxPublicKeyBytes' bytes.+    -> Ptr CUChar+    -- ^ Buffer that holds secret key of size+    --  'LibSodium.Bindings.CryptoBox.cryptoBoxSecretKeyBytes' bytes.+    -> IO CInt+    -- ^ Returns 0 on success and -1 on error.++-- | Size diff in bytes between encrypted and plaintext messages, i.e.+--   @cryptoBoxSealbytes = length encryptedMsg - length plaintextMsg@+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_box_SEALBYTES"+  cryptoBoxSealbytes :: CSize
+ src/LibSodium/Bindings/SecretStream.hs view
@@ -0,0 +1,312 @@+{-# LANGUAGE CApiFFI #-}+{-# LANGUAGE ScopedTypeVariables #-}++-- |+-- Module: LibSodium.Bindings.SecretStream+-- Description: Direct bindings to the stream and file encryption primitives of libsodium+-- Copyright: (C) Hécate Moonlight 2022+-- License: BSD-3-Clause+-- Maintainer: The Haskell Cryptography Group+-- Stability: Stable+-- Portability: GHC only+module LibSodium.Bindings.SecretStream+  ( -- * Introduction+    -- $introduction++    -- * Usage+    -- $usage+    CryptoSecretStreamXChaCha20Poly1305State+  , withCryptoSecretStreamXChaCha20Poly1305State++    -- * Encryption+  , cryptoSecretStreamXChaCha20Poly1305KeyGen+  , cryptoSecretStreamXChaCha20Poly1305InitPush+  , cryptoSecretStreamXChaCha20Poly1305Push++    -- * Decryption+  , cryptoSecretStreamXChaCha20Poly1305InitPull+  , cryptoSecretStreamXChaCha20Poly1305Pull++    -- * Rekeying+  , cryptoSecretStreamXChaCha20Poly1305Rekey++    -- * Constants++    -- ** Key, Header and State size constants+  , cryptoSecretStreamXChaCha20Poly1305KeyBytes+  , cryptoSecretStreamXChaCha20Poly1305HeaderBytes+  , cryptoSecretStreamXChaCha20Poly1305StateBytes+  , cryptoSecretStreamXChaCha20Poly1305ABytes+  , cryptoSecretStreamXChaCha20Poly1305MessageBytesMax++    -- ** Tag constants+  , cryptoSecretStreamXChaCha20Poly1305TagMessage+  , cryptoSecretStreamXChaCha20Poly1305TagPush+  , cryptoSecretStreamXChaCha20Poly1305TagRekey+  , cryptoSecretStreamXChaCha20Poly1305TagFinal+  ) where++import Foreign (Ptr)+import Foreign.C (CInt (CInt), CSize (CSize), CUChar (CUChar), CULLong (CULLong))+import Foreign.Marshal (allocaBytes)++-- $introduction+-- This high-level API encrypts a sequence of messages, or a single message split into an arbitrary number of chunks, using a secret key, with the following properties:+--+-- * Messages cannot be truncated, removed, reordered, duplicated or modified without this being detected by the decryption functions.+-- * The same sequence encrypted twice will produce different ciphertexts.+-- * An authentication tag is added to each encrypted message: stream corruption will be detected early, without having to read the stream until the end.+-- * Each message can include additional data (ex: timestamp, protocol version) in the computation of the authentication tag.+-- * Messages can have different sizes.+-- * There are no practical limits to the total length of the stream, or to the total number of individual messages.+-- * Ratcheting: at any point in the stream, it is possible to "forget" the secret key used to encrypt the previous messages, and switch to a new key.++-- $usage+-- An encrypted stream starts with a short header, whose size is 'cryptoSecretStreamXChaCha20Poly1305HeaderBytes' bytes.+-- That header must be sent/stored before the sequence of encrypted messages, as it is required to decrypt the stream.+-- The header content doesn't have to be secret and decryption with a different header would fail.+--+-- A tag is attached to each message. That tag can be any of:+--+-- * 0, or 'cryptoSecretStreamXChaCha20Poly1305TagMessage': the most common tag, that doesn't add any information about the nature of the message.+--+-- * 'cryptoSecretStreamXChaCha20Poly1305TagFinal': indicates that the message marks the end of the stream, and erases the secret key used to encrypt the previous sequence.+--+-- * 'cryptoSecretStreamXChaCha20Poly1305TagPush': indicates that the message marks the end of a set of messages, but not the end of the stream.+--   For example, a huge JSON string sent as multiple chunks can use this tag to indicate to the application that the string is complete and that it+--   can be decoded. But the stream itself is not closed, and more data may follow.+--+-- * 'cryptoSecretStreamXChaCha20Poly1305TagRekey': "forget" the secret key used to encrypt this message and the previous ones, and derive a new secret key.+--+-- A typical encrypted stream simply attaches 0 as a tag to all messages, except the last one which is tagged as 'cryptoSecretStreamXChaCha20Poly1305TagFinal'.+--+-- Note that tags are encrypted; encrypted streams do not reveal any information about sequence boundaries+-- ('cryptoSecretStreamXChaCha20Poly1305TagPush' and 'cryptoSecretStreamXChaCha20Poly1305TagRekey' tags).+--+-- For each message, additional data can be included in the computation of the authentication tag.+-- With this API, additional data is rarely required, and most applications can just use 'Foreign.Ptr.nullPtr' and a length of 0 instead.++-- | Opaque tag representing the hash state struct @crypto_secretstream_xchacha20poly1305_state@ used by the C API.+--+-- To use a 'CryptoSecretStreamXChaCha20Poly1305State', use 'withCryptoSecretStreamXChaCha20Poly1305State'.+--+-- @since 0.0.1.0+data CryptoSecretStreamXChaCha20Poly1305State++-- | Allocate an opaque 'CryptoSecretStreamXChaCha20Poly1305State' of size 'cryptoSecretStreamXChaCha20Poly1305StateBytes'.+--+-- ⚠️ Do not leak the 'CryptoSecretStreamXChaCha20Poly1305State' outside of the lambda,+-- otherwise you will point at deallocated memory!+--+-- @since 0.0.1.0+withCryptoSecretStreamXChaCha20Poly1305State :: (Ptr CryptoSecretStreamXChaCha20Poly1305State -> IO a) -> IO a+withCryptoSecretStreamXChaCha20Poly1305State action = allocaBytes (fromIntegral cryptoSecretStreamXChaCha20Poly1305StateBytes) action++-- === Encryption ===++-- | Create a random secret key to encrypt a stream, and store it into the parameter+--+-- Note that using this function is not required to obtain a suitable key:+-- the secretstream API can use any secret key whose size is+-- 'cryptoSecretStreamXChaCha20Poly1305KeyBytes' bytes.+--+-- /See:/ [crypto_secretstream_xchacha20poly1305_keygen()](https://doc.libsodium.org/secret-key_cryptography/secretstream#encryption)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_secretstream_xchacha20poly1305_keygen"+  cryptoSecretStreamXChaCha20Poly1305KeyGen+    :: Ptr CUChar+    -- ^ Pointer in which the secret key will be stored+    -> IO ()++-- | Initialise the cryptographic state using the secret key, then stores the stream header into the header buffer+--+-- /See:/ [crypto_secretstream_xchacha20poly1305_init_push()](https://doc.libsodium.org/secret-key_cryptography/secretstream#encryption)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_secretstream_xchacha20poly1305_init_push"+  cryptoSecretStreamXChaCha20Poly1305InitPush+    :: Ptr CryptoSecretStreamXChaCha20Poly1305State+    -- ^ Cryptographic state+    -> Ptr CUChar+    -- ^ Header buffer, must be of size 'cryptoSecretStreamXChaCha20Poly1305HeaderBytes'.+    -> Ptr CUChar+    -- ^ Buffer holding the secret key. Must be of size 'cryptoSecretStreamXChaCha20Poly1305KeyBytes'.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++-- | Encrypt a message using a cryptographic state and a tag.+--+-- Additional data can be optionally provided.+-- The maximum length of an individual message is 'cryptoSecretStreamXChaCha20Poly1305MessageBytesMax' bytes (~ 256 GB).+--+-- /See:/ [crypto_secretstream_xchacha20poly1305_push()](https://doc.libsodium.org/secret-key_cryptography/secretstream#encryption)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_secretstream_xchacha20poly1305_push"+  cryptoSecretStreamXChaCha20Poly1305Push+    :: Ptr CryptoSecretStreamXChaCha20Poly1305State+    -- ^ Cryptographic state+    -> Ptr CUChar+    -- ^ Buffer that receives the cipher text.+    -> Ptr CULLong+    -- ^ If this pointer is not 'Foreign.Ptr.nullPtr', it will store the length of the cipher text.+    -- It is guaranteed to be always @(messageLength + 'cryptoSecretStreamXChaCha20Poly1305ABytes' )@.+    -> Ptr CUChar+    -- ^ Pointer to the message to encrypt+    -> CULLong+    -- ^ Length of the message (@messageLength@).+    -> Ptr CUChar+    -- ^ Additional, optional data that can be included in the computation. Can be 'Foreign.Ptr.nullPtr' if you have nothing to add.+    -> CULLong+    -- ^ Length of the additional, optional data. Can be 0 if you have nothing to add.+    -> CUChar+    -- ^ Tag for the cipher text.+    -> IO CInt+    -- ^ Returns 0 on success, -1 on error.++-- === Decryption ===++-- | Initialise the cryptographic state using the secret key and a header.+-- The secret key will not be required any more for subsequent operations+--+-- @since 0.0.1.0+--+-- /See:/ [crypto_secretstream_xchacha20poly1305_init_pull()](https://doc.libsodium.org/secret-key_cryptography/secretstream#decryption)+foreign import capi "sodium.h crypto_secretstream_xchacha20poly1305_init_pull"+  cryptoSecretStreamXChaCha20Poly1305InitPull+    :: Ptr CryptoSecretStreamXChaCha20Poly1305State+    -- ^ Cryptographic state+    -> Ptr CUChar+    -- ^ Header buffer, must be of size 'cryptoSecretStreamXChaCha20Poly1305HeaderBytes'.+    -> Ptr CUChar+    -- ^ Buffer holding the secret key. Must be of size 'cryptoSecretStreamXChaCha20Poly1305KeyBytes'.+    -> IO CInt+    -- ^ Returns 0 on success, -1 if the header is invalid.++-- | Decrypt a message chunk.+--+-- Applications will typically call this function in a loop, until a message with the+-- 'cryptoSecretStreamXChaCha20Poly1305TagFinal' tag is found.+--+-- /See:/ [crypto_secretstream_xchacha20poly1305_pull()](https://doc.libsodium.org/secret-key_cryptography/secretstream#decryption)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_secretstream_xchacha20poly1305_pull"+  cryptoSecretStreamXChaCha20Poly1305Pull+    :: Ptr CryptoSecretStreamXChaCha20Poly1305State+    -- ^ Cryptographic state.+    -> Ptr CUChar+    -- ^ Buffer that will hold the decrypted message.+    -> Ptr CULLong+    -- ^ If this pointer is not 'Foreign.Ptr.nullPtr', it will store the length of the message.+    -- It is guaranteed to be always @(cipherTextLength - 'cryptoSecretStreamXChaCha20Poly1305ABytes' )@.+    -> Ptr CUChar+    -- ^ If this pointer is not 'Foreign.Ptr.nullPtr', the tag attached to the message is stored in that buffer.+    -> Ptr CUChar+    -- ^ Cipher text to be decrypted.+    -> CULLong+    -- ^ Length in bytes of the cipher text.+    -> Ptr CUChar+    -- ^ Additional, optional data that was bundled with the cipher text will be put there. Can be 'Foreign.Ptr.nullPtr' if you know that nothing was added.+    -> CULLong+    -- ^ Length of the additional, optional data. Can be 0 if you have nothing to add.+    -> IO CInt+    -- ^ Return 0 on success, -1 if the ciphertext appears to be invalid.++-- === Rekeying ===++-- | Rekeying happens automatically and transparently, before the internal counter of the underlying cipher wraps. Therefore, streams can be arbitrary large.+--+-- Optionally, applications for which forward secrecy is critical can attach the 'cryptoSecretStreamXChaCha20Poly1305TagRekey'+-- tag to a message in order to trigger an explicit rekeying.+--+-- The decryption API will automatically update the secret key if this tag is found attached to a message.+-- Explicit rekeying can also be performed without adding a tag, by calling this function.+--+-- This updates the state, but doesn't add any information about the secret key change to the stream.+-- If this function is used to create an encrypted stream, the decryption process must call+-- that function at the exact same stream location.+--+-- /See:/ [crypto_secretstream_xchacha20poly1305_rekey()](https://doc.libsodium.org/secret-key_cryptography/secretstream#rekeying)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_secretstream_xchacha20poly1305_rekey"+  cryptoSecretStreamXChaCha20Poly1305Rekey+    :: Ptr CryptoSecretStreamXChaCha20Poly1305State+    -- ^ Cryptographic state.+    -> IO ()++-- === Constants ===++-- | Size of the secret key+--+-- /See:/ [crypto_secretstream_xchacha20poly1305_KEYBYTES](https://doc.libsodium.org/secret-key_cryptography/secretstream#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_secretstream_xchacha20poly1305_KEYBYTES"+  cryptoSecretStreamXChaCha20Poly1305KeyBytes :: CSize++-- | Size of the encryption header+--+-- /See:/ [crypto_secretstream_xchacha20poly1305_HEADERBYTES](https://doc.libsodium.org/secret-key_cryptography/secretstream#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_secretstream_xchacha20poly1305_HEADERBYTES"+  cryptoSecretStreamXChaCha20Poly1305HeaderBytes :: CSize++-- | Size of an opaque 'CryptoSecretStreamXChaCha20Poly1305State'+--+-- /See:/ [crypto_secretstream_xchacha20poly1305_statebytes](https://doc.libsodium.org/secret-key_cryptography/secretstream#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_secretstream_xchacha20poly1305_statebytes"+  cryptoSecretStreamXChaCha20Poly1305StateBytes :: CSize++-- | Size of an authentication tag in bytes+--+-- /See:/ [crypto_secretstream_xchacha20poly1305_ABYTES](https://doc.libsodium.org/secret-key_cryptography/secretstream#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_secretstream_xchacha20poly1305_ABYTES"+  cryptoSecretStreamXChaCha20Poly1305ABytes :: CSize++-- | Maximum length of an invidual message in bytes (~ 256 GB)+--+-- /See:/ [crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX](https://doc.libsodium.org/secret-key_cryptography/secretstream#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX"+  cryptoSecretStreamXChaCha20Poly1305MessageBytesMax :: CSize++-- | Most common tag, add no information about the nature of the message+--+-- /See:/ [crypto_secretstream_xchacha20poly1305_TAG_MESSAGE](https://doc.libsodium.org/secret-key_cryptography/secretstream#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_secretstream_xchacha20poly1305_TAG_MESSAGE"+  cryptoSecretStreamXChaCha20Poly1305TagMessage :: CSize++-- | Indicates that the message marks the end of a set of messages, but not the end of the stream+--+-- /See:/ [crypto_secretstream_xchacha20poly1305_TAG_PUSH](https://doc.libsodium.org/secret-key_cryptography/secretstream#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_secretstream_xchacha20poly1305_TAG_PUSH"+  cryptoSecretStreamXChaCha20Poly1305TagPush :: CSize++-- | "forget" the secret key used to encrypt this message and the previous ones, and derive a new secret key.+--+-- /See:/ [crypto_secretstream_xchacha20poly1305_TAG_REKEY](https://doc.libsodium.org/secret-key_cryptography/secretstream#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_secretstream_xchacha20poly1305_TAG_REKEY"+  cryptoSecretStreamXChaCha20Poly1305TagRekey :: CSize++-- | Marks the end of the stream, and erases the secret key used to encrypt the previous sequence.+--+-- /See:/ [crypto_secretstream_xchacha20poly1305_TAG_FINAL](https://doc.libsodium.org/secret-key_cryptography/secretstream#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_secretstream_xchacha20poly1305_TAG_FINAL"+  cryptoSecretStreamXChaCha20Poly1305TagFinal :: CSize
+ src/LibSodium/Bindings/Secretbox.hs view
@@ -0,0 +1,202 @@+{-# LANGUAGE CApiFFI #-}+{-# LANGUAGE Trustworthy #-}++-- |+-- Module: LibSodium.Bindings.Secretbox+-- Description: Direct bindings to the secretbox API of Libsodium+-- License: BSD-3-Clause+-- Maintainer: The Haskell Cryptography Group+-- Stability: Stable+-- Portability: GHC only+module LibSodium.Bindings.Secretbox+  ( -- * Introduction+    -- $introduction++    -- * Secretbox++    -- ** Keygen+    cryptoSecretboxKeygen++    -- ** Easy+  , cryptoSecretboxEasy+  , cryptoSecretboxOpenEasy++    -- ** Detached+  , cryptoSecretboxDetached+  , cryptoSecretboxOpenDetached++    -- ** Constants+  , cryptoSecretboxKeyBytes+  , cryptoSecretboxNonceBytes+  , cryptoSecretboxMACBytes+  , cryptoSecretboxPrimitive+  , cryptoSecretboxMessageBytesMax+  )+where++import Foreign (Ptr)+import Foreign.C (CChar, CInt (CInt), CSize (CSize), CUChar, CULLong (CULLong))++-- $introduction+-- This API allows encrypting a message using a secret key and a nonce.+-- The ciphertext is accompanied by an authentication tag.+--+--+-- It comes in two flavours:+--+--   [easy] Both the ciphertext and authentication tag are stored in the same buffer.+--   [detached] The ciphertext and authentication tag may be stored in separate buffers.+--+--+-- The same key is used for both encryption and decryption, so it must be kept secret.+-- A key can be generated using the 'cryptoSecretboxKeygen' primitive.+--+--+-- Each message must use a unique nonce, which may be generated with the 'LibSodium.Bindings.Random.randombytesBuf' primitive.+-- The nonce does not need to be kept secret but should never be reused with the same secret key.+--+-- For more information see the upstream docs: <https://doc.libsodium.org/secret-key_cryptography/secretbox>++-- | Generate a key that can be used by the primitives of the secretbox API.+--+-- /See:/ [crypto_secretbox_keygen()](https://doc.libsodium.org/secret-key_cryptography/secretbox#detached-mode)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_secretbox_keygen"+  cryptoSecretboxKeygen+    :: Ptr CUChar+    -- ^ key buffer of length 'cryptoSecretboxKeyBytes'+    -> IO ()++-- | Encrypt a message using a secret key and nonce.+--+-- The message and ciphertext buffers may overlap enabling in-place encryption, but note that the+-- ciphertext will be 'cryptoSecretboxMACBytes' bytes longer than the message.+--+-- /See:/ [crytpo_secretbox_easy()](https://doc.libsodium.org/secret-key_cryptography/secretbox#combined-mode)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_secretbox_easy"+  cryptoSecretboxEasy+    :: Ptr CUChar+    -- ^ A pointer to the buffer that will hold the ciphertext.+    -- The length of the ciphertext is the length of the message in bytes plus 'cryptoSecretboxMACBytes' bytes.+    -> Ptr CUChar+    -- ^ A pointer to the buffer holding the message to be encrypted.+    -> CULLong+    -- ^ The length of the message in bytes.+    -> Ptr CUChar+    -- ^ A pointer to the nonce of size 'cryptoSecretboxNonceBytes' bytes.+    -> Ptr CUChar+    -- ^ A pointer to the secret key of size 'cryptoSecretboxKeyBytes' bytes.+    -> IO CInt+    -- ^ Returns 0 on success and -1 on error.++-- | Verify and decrypt ciphertext using a secret key and nonce.+--+-- The message and ciphertext buffers may overlap enabling in-place decryption, but note that the+-- message will be 'cryptoSecretboxMACBytes' bytes shorter than the ciphertext.+--+-- /See:/ [crypto_secretbox_open_easy()](https://doc.libsodium.org/secret-key_cryptography/secretbox#combined-mode)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_secretbox_open_easy"+  cryptoSecretboxOpenEasy+    :: Ptr CUChar+    -- ^ A pointer to the buffer that will hold the decrypted message.+    -- The length of the message is the length of the ciphertext in bytes minus 'cryptoSecretboxMACBytes' bytes.+    -> Ptr CUChar+    -- ^ A pointer to the buffer holding the ciphertext to be verified and decrypted.+    -> CULLong+    -- ^ The length of the ciphertext in bytes.+    -> Ptr CUChar+    -- ^ A pointer to the nonce of size 'cryptoSecretboxNonceBytes' bytes.+    -> Ptr CUChar+    -- ^ A pointer to the secret key of size 'cryptoSecretboxKeyBytes' bytes.+    -> IO CInt+    -- ^ Returns 0 on success and -1 on error.++-- | Encrypt a message using a secret key and nonce.+--+-- /See:/ [crypto_secretbox_detached()](https://doc.libsodium.org/secret-key_cryptography/secretbox#detached-mode)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_secretbox_detached"+  cryptoSecretboxDetached+    :: Ptr CUChar+    -- ^ A pointer to the buffer that will hold the ciphertext. This will have the same length as the message.+    -> Ptr CUChar+    -- ^ A pointer to the buffer that will hold the authentication tag.+    -- This will be of length 'cryptoSecretboxMACBytes' bytes.+    -> Ptr CUChar+    -- ^ A pointer to the buffer holding the message to be encrypted.+    -> CULLong+    -- ^ The length of the message in bytes.+    -> Ptr CUChar+    -- ^ A pointer to the nonce of size 'cryptoSecretboxNonceBytes' bytes.+    -> Ptr CUChar+    -- ^ A pointer to the secret key of size 'cryptoSecretboxKeyBytes' bytes.+    -> IO CInt+    -- ^ Returns 0 on success and -1 on error.++-- | Verify and decrypt ciphertext using a secret key and nonce+--+-- /See:/ [crypto_secretbox_open_detached()](https://doc.libsodium.org/secret-key_cryptography/secretbox#detached-mode)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_secretbox_open_detached"+  cryptoSecretboxOpenDetached+    :: Ptr CUChar+    -- ^ A pointer to the buffer that will hold the decrypted message. This will have the same length as the ciphertext.+    -> Ptr CUChar+    -- ^ A pointer to the buffer holding the ciphertext to be decrypted.+    -> Ptr CUChar+    -- ^ A pointer to the buffer holding the authentication tag to be verified.+    -> CULLong+    -- ^ The length of the ciphertext in bytes.+    -> Ptr CUChar+    -- ^ A pointer to the nonce of size 'cryptoSecretboxNonceBytes' bytes.+    -> Ptr CUChar+    -- ^ A pointer to the secret key of size 'cryptoSecretboxKeyBytes' bytes.+    -> IO CInt+    -- ^ Returns 0 on success and -1 on error.++-- | The length of a secretbox key in bytes.+--+-- /See:/ [crypto_secretbox_KEYBYTES](https://doc.libsodium.org/secret-key_cryptography/secretbox#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_secretbox_KEYBYTES"+  cryptoSecretboxKeyBytes :: CSize++-- | The length of a secretbox nonce in bytes.+--+-- /See:/ [crypto_secretbox_NONCEBYTES](https://doc.libsodium.org/secret-key_cryptography/secretbox#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_secretbox_NONCEBYTES"+  cryptoSecretboxNonceBytes :: CSize++-- | The length of a secretbox authentication tag in bytes.+--+-- /See:/ [crypto_secretbox_MACBYTES](https://doc.libsodium.org/secret-key_cryptography/secretbox#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_secretbox_MACBYTES"+  cryptoSecretboxMACBytes :: CSize++-- | The underlying cryptographic algorithm used to implement the secretbox API.+--+-- /See:/ [crypto_secretbox_PRIMITIVE](https://doc.libsodium.org/secret-key_cryptography/secretbox#algorithm-details)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_secretbox_PRIMITIVE"+  cryptoSecretboxPrimitive :: Ptr CChar++-- | Maximum length of a message in bytes that can be encrypted using the secretbox API.+--+-- /See:/ [crypto_secretbox_MESSAGEBYTES_MAX](https://doc.libsodium.org/secret-key_cryptography/secretbox#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_secretbox_MESSAGEBYTES_MAX"+  cryptoSecretboxMessageBytesMax :: CSize
+ src/LibSodium/Bindings/SecureMemory.hs view
@@ -0,0 +1,216 @@+{-# LANGUAGE CApiFFI #-}+{-# LANGUAGE ScopedTypeVariables #-}++-- |+--+-- Module: LibSodium.Bindings.SecureMemory+-- Description: Direct bindings to the libsodium secure memory functions+-- Copyright: (C) Hécate Moonlight 2022+-- License: BSD-3-Clause+-- Maintainer: The Haskell Cryptography Group+-- Portability: GHC only+module LibSodium.Bindings.SecureMemory+  ( -- ** Introduction+    -- $introduction++    -- ** Zeroing memory+    sodiumMemZero++    -- ** Locking memory+  , sodiumMlock+  , sodiumMunlock++    -- ** Allocating memory+  , sodiumMalloc+  , sodiumAllocArray+  , sodiumFree+  , finalizerSodiumFree+  )+where++import Data.Word (Word8)+import Foreign (FinalizerPtr, Ptr)+import Foreign.C.Types (CInt (CInt), CSize (CSize))++-- $introduction+-- This module provides bindings to the secure memory functions provided by Libsodium.+-- It is intended to be qualified on import:+--+-- > import qualified LibSodium.Bindings.SecureMemory as SecureMemory+--+-- It is recommended to disable swap partitions on machines processing sensitive+-- data or, as a second choice, use encrypted swap partitions.+--+-- For similar reasons, on Unix systems, one should also disable core dumps when+-- running crypto code outside a development environment.+-- This can be achieved using a shell built-in such as @ulimit@ or programmatically+-- using [@setResourceLimit@](https://hackage.haskell.org/package/unix/docs/System-Posix-Resource.html#v:setResourceLimit):+--+-- >>> setResourceLimit ResourceCoreFileSize (ResourceLimits 0 0)+--+-- On operating systems where this feature is implemented, kernel crash dumps+-- should also be disabled.+--+-- The 'sodiumMlock' function wraps @mlock(2)@ and+-- [@VirtualLock()@](https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtuallock).+--+-- Note: Many systems place limits on the amount of memory that may be locked+-- by a process. Care should be taken to raise those limits (e.g. Unix ulimits)+-- where necessary.++-- | Overwrite the memory region starting at the pointer+-- address with zeros.+--+-- @memset()@ and hand-written code can be silently stripped out by+-- an optimizing compiler or the linker.+--+-- This function tries to effectively zero the amount of bytes starting+-- at the provided pointer, even if optimizations are being applied to the code.+--+-- /See:/ [sodium_memzero()](https://doc.libsodium.org/memory_management)+--+-- @since 0.0.1.0+foreign import capi "sodium.h sodium_memzero"+  sodiumMemZero+    :: Ptr Word8+    -- ^ Start pointer+    -> CSize+    -- ^ Length in bytes of the area to zero+    -> IO ()++-- | Lock a memory region starting at the pointer+-- address. This can help avoid swapping sensitive+-- data to disk.+--+-- /See:/ [sodium_mlock()](https://doc.libsodium.org/memory_management)+--+-- @since 0.0.1.0+foreign import capi "sodium.h sodium_mlock"+  sodiumMlock+    :: Ptr Word8+    -- ^ Start pointer+    -> CSize+    -- ^ Size of the memory region to lock+    -> IO CInt+    -- ^ Returns 0 on success, -1 if any system limit is reached.++-- | Unlock the memory region by overwriting it with zeros and and flagging the+-- pages as swappable again. Calling 'sodiumMemZero' prior to 'sodiumMunlock' is thus not required.+--+-- On systems where it is supported, 'sodiumMlock' also wraps @madvise(2)@ and advises the kernel not to include the locked memory in core dumps. The 'sodiumMunlock'+-- function also undoes this additional protection.+--+-- /See:/ [sodium_munlock()](https://doc.libsodium.org/memory_management)+--+-- @since 0.0.1.0+foreign import capi "sodium.h sodium_munlock"+  sodiumMunlock+    :: Ptr Word8+    -- ^ Start pointer+    -> CSize+    -- ^ Size of the memory region to unlock+    -> IO CInt++-- | This function takes an amount (called @size@) and returns a pointer from which+-- exactly @size@ contiguous bytes of memory can be accessed. The pointer may be+-- 'Foreign.Ptr.nullPtr' and there may be an error when allocating memory,+-- through @errno@. Upon failure, @errno@ will be set to 'Foreign.C.Error.eNOMEM'+--+-- It is recommended that the caller use "Foreign.C.Error" to handle potential failure.+--+-- Moreover, 'LibSodium.Bindings.Main.sodiumInit' must be called before using this+-- function.+--+-- === Explanation+-- The allocated region is placed at the end of a page boundary,+-- immediately followed by a guard page (or an emulation,+-- if unsupported by the platform). As a result, accessing memory past the end of the+-- region will immediately terminate the application.+--+-- A canary is also placed right before the returned pointer. Modifications of this+-- canary are detected when trying to free the allocated region with 'sodiumFree'+-- and cause the application to immediately terminate.+--+-- If supported by the platform, an additional guard page is placed before this canary+-- to make it less likely for sensitive data to be accessible when reading past the end+-- of an unrelated region.+-- The allocated region is filled with 0xdb bytes to help catch bugs due to+-- uninitialized data.+--+-- In addition, @mlock(2)@ is called on the region to help avoid it being swapped to disk.+-- Note however that @mlock(2)@ may not be supported, may fail or may be a no-op,+-- in which case 'sodiumMalloc' will return the memory regardless, but it will not be+-- locked. If you specifically need to rely on memory locking, consider calling+-- 'sodiumMlock' and checking its return value.+--+-- On operating systems supporting @MAP_NOCORE@ or @MADV_DONTDUMP@, memory allocated this+-- way will also not be part of core dumps.+-- The returned address will not be aligned if the allocation size is not a multiple+-- of the required alignment.+-- For this reason, 'sodiumMalloc' should not be used with packed or variable-length+-- structures unless the size given to 'sodiumMalloc' is rounded up to ensure proper+-- alignment.+--+-- All the structures used by libsodium can safely be allocated using+-- 'sodiumMalloc'.+--+-- Allocating 0 bytes is a valid operation. It returns a pointer that can be+-- successfully passed to 'sodiumFree'.+--+-- ⚠️  This is not a general-purpose allocation function, and requires 3 or 4 extra+-- pages of virtual memory. Since it is very expensive, do not use it to allocate+-- every-day memory.+--+-- /See:/ [sodium_malloc()](https://doc.libsodium.org/memory_management)+--+-- @since 0.0.1.0+foreign import capi "sodium.h sodium_malloc"+  sodiumMalloc+    :: forall a+     . CSize+    -- ^ Amount of memory to allocate+    -> IO (Ptr a)++-- | This function takes an amount of objects and the size of each object, and+-- returns a pointer from which this amount of objects that are of the specified+-- size each can be accessed.+--+-- It provides the same guarantees as 'sodiumMalloc' but also protects against+-- arithmetic overflows when @count * size@ exceeds @SIZE_MAX@.+--+-- /See:/ [sodium_allocarray()](https://doc.libsodium.org/memory_management)+--+-- @since 0.0.1.0+foreign import capi "sodium.h sodium_allocarray"+  sodiumAllocArray+    :: forall a+     . CSize+    -- ^ Amount of objects+    -> CSize+    -- ^ Size of each objects+    -> IO (Ptr a)++-- | Unlock and deallocate memory allocated using 'sodiumMalloc' or 'sodiumAllocArray'.+--+-- The memory region is filled with zeros before the deallocation.+--+-- /See:/ [sodium_free()](https://doc.libsodium.org/memory_management)+--+-- @since 0.0.1.0+foreign import capi "sodium.h sodium_free"+  sodiumFree+    :: forall a+     . Ptr a+    -> IO ()++-- | Function pointer to use as 'Foreign.ForeignPtr' finalizer for sodium-allocated memory.+--+-- The memory region is filled with zeros before the deallocation.+--+-- /See:/ [sodium_free()](https://doc.libsodium.org/memory_management)+--+-- @since 0.0.1.0+foreign import capi "sodium.h &sodium_free"+  finalizerSodiumFree+    :: forall a+     . FinalizerPtr a
+ src/LibSodium/Bindings/ShortHashing.hs view
@@ -0,0 +1,137 @@+{-# LANGUAGE CApiFFI #-}++-- |+-- Module: LibSodium.Bindings.ShortHashing+-- Description: Short but unpredictable hashes based on SipHash-2-4.+-- Copyright: (C) Hécate Moonlight+-- License: BSD-3-Clause+-- Maintainer: The Haskell Cryptography Group+-- Stability: Stable+-- Portability: GHC only+--+-- The short-input hashing functions have a variety of use-cases, such as:+--+-- * Hash Tables+-- * Probabilistic data structures, such as Bloom filters+-- * Integrity checking in interactive protocols+--+-- Note however that the output of 'cryptoShortHash' is only 64 bit. Therefore, it should not be considered resistant to collisions.+--+-- The 'cryptoShortHashX24' function has a 128-bit output which is more resistant to collisions.+module LibSodium.Bindings.ShortHashing+  ( -- ** Functions+    cryptoShortHashKeyGen+  , cryptoShortHash+  , cryptoShortHashX24KeyGen+  , cryptoShortHashX24++    -- ** Constants+  , cryptoShortHashKeyBytes+  , cryptoShortHashBytes+  , cryptoShortHashSipHashX24KeyBytes+  , cryptoShortHashSipHashX24Bytes+  ) where++import Data.Word (Word8)+import Foreign.C (CInt (CInt), CSize (CSize), CUChar, CULLong (CULLong))+import Foreign.Ptr (Ptr, castPtr)+import LibSodium.Bindings.Random (randombytesBuf)++-- | Create a secret key of size 'cryptoShortHashKeyBytes'.+--+--  It is implemented by libsodium with 'randombytesBuf'+--+--  /See:/ [crypto_shorthash_keygen()](https://github.com/jedisct1/libsodium/blob/1.0.18/src/libsodium/crypto_shorthash/crypto_shorthash.c#L30-L34)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_shorthash_keygen"+  cryptoShortHashKeyGen+    :: Ptr CUChar+    -- ^ Buffer that will hold the secret key.+    -> IO ()++-- | Hash an input message with a secret key.+-- The secret key is of size 'cryptoShortHashKeyBytes'+-- and can be generated with 'cryptoShortHashKeyGen'.+--+-- /See:/ [crypto_shorthash()](https://doc.libsodium.org/hashing/short-input_hashing#usage)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_shorthash"+  cryptoShortHash+    :: Ptr CUChar+    -- ^ Buffer that will hold the fingerprint, of size 'cryptoShortHashBytes'.+    -> Ptr CUChar+    -- ^ Buffer that holds the input message.+    -> CULLong+    -- ^ Length of the input message.+    -> Ptr CUChar+    -- ^ Buffer that holds the secret key, of size 'cryptoShortHashKeyBytes'.+    -> IO CInt+    -- ^ The function returns -1 if the hashing fails and 0 on success.++-- | Create a secret key of size 'cryptoShortHashSipHashX24KeyBytes'.+--+-- It is implemented with 'randombytesBuf'+--+-- @since 0.0.1.0+cryptoShortHashX24KeyGen+  :: Ptr CUChar+  -- ^ Buffer that will hold the secret key.+  -> IO ()+cryptoShortHashX24KeyGen ptr =+  randombytesBuf (castPtr ptr :: Ptr Word8) cryptoShortHashSipHashX24KeyBytes++-- | Hash an input message with a secret key to a 128-bit fingerprint.+--+-- The secret key can be generated with 'cryptoShortHashX24KeyGen'.+--+-- /See:/ [crypto_shorthash_siphashx24()](https://github.com/jedisct1/libsodium/blob/1.0.18/src/libsodium/crypto_shorthash/siphash24/ref/shorthash_siphashx24_ref.c#L6)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_shorthash_siphashx24"+  cryptoShortHashX24+    :: Ptr CUChar+    -- ^ Buffer that will hold the fingerprint, of size 'cryptoShortHashSipHashX24Bytes'.+    -> Ptr CUChar+    -- ^ Buffer that holds the input message.+    -> CULLong+    -- ^ Length of the input message.+    -> Ptr CUChar+    -- ^ Buffer that holds the secret key, of size 'cryptoShortHashSipHashX24KeyBytes'.+    -> IO CInt+    -- ^ The function returns -1 if the hashing fails and 0 on success.++-- === Constants++-- | Size of the key generated by 'cryptoShortHashKeyGen'.+--+-- /See:/ [crypto_shorthash_KEYBYTES](https://doc.libsodium.org/hashing/short-input_hashing#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_shorthash_KEYBYTES"+  cryptoShortHashKeyBytes :: CSize++-- | Size of the fingerprint computed by 'cryptoShortHash'.+--+-- /See:/ [crypto_shorthash_BYTES](https://doc.libsodium.org/hashing/short-input_hashing#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_shorthash_BYTES"+  cryptoShortHashBytes :: CSize++-- | Size of the key generated by 'cryptoShortHashKeyGen'.+--+-- /See:/ [crypto_shorthash_siphashx24_BYTES](https://github.com/jedisct1/libsodium/blob/1.0.18/src/libsodium/include/sodium/crypto_shorthash_siphash24.h#LL32C9-L32C42)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_shorthash_siphashx24_KEYBYTES"+  cryptoShortHashSipHashX24KeyBytes :: CSize++-- | Size of the fingerprint computed by 'cryptoShortHashX24'.+--+-- /See:/ [crypto_shorthash_siphashx24_KEYBYTES](https://github.com/jedisct1/libsodium/blob/1.0.18/src/libsodium/include/sodium/crypto_shorthash_siphash24.h#L36)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_shorthash_siphashx24_BYTES"+  cryptoShortHashSipHashX24Bytes :: CSize
+ src/LibSodium/Bindings/Utils.hs view
@@ -0,0 +1,183 @@+{-# LANGUAGE CApiFFI #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE Trustworthy #-}+{-# OPTIONS_GHC -Wno-unused-imports #-}++-- |+-- Module: LibSodium.Bindings.Utils+-- Description: Helpers exposed by the libsodium C library+-- Copyright: (C) Seth Livy 2022+-- License: BSD-3-Clause+-- Maintainer: The Haskell Cryptography Group+-- Stability: Stable+-- Portability: GHC only+--+-- These are bindings to some of libsodium's [utils.h](https://github.com/jedisct1/libsodium/blob/master/src/libsodium/include/sodium/utils.h).+-- Included are Hex and Base64 encoding/decoding functions along with a constant-time @memcmp@ for handling secret data.+module LibSodium.Bindings.Utils+  ( -- * Low-level binding+    sodiumMemcmp+  , sodiumBin2Hex+  --  , sodiumHex2Bin+  , sodiumBin2Base64+  --  , sodiumBase642Bin++    -- * Constants+  , sodiumBase64VariantOriginal+  , sodiumBase64VariantOriginalNoPadding+  , sodiumBase64VariantURLSafe+  , sodiumBase64VariantURLSafeNoPadding+  )+where++import Foreign (Ptr)+import Foreign.C (CChar (..), CInt (..), CSize (..), CUChar (..))+import Foreign.C.String++-- | Constant-time comparison function.+--+-- This function is not a lexicographic comparator and should be never+-- used for this purpose. It should only be used when comparing two pieces+-- of secret data, such as keys or authentication tags.+--+-- @since 0.0.1.0+foreign import capi "sodium.h sodium_memcmp"+  sodiumMemcmp+    :: Ptr CUChar+    -- ^ First pointer to some secret data.+    -> Ptr CUChar+    -- ^ Second pointer to some secret data.+    -- Must be the same length as the first pointer.+    -> CSize+    -- ^ The length of bytes that pointed to by both previous arguments.+    -> IO CInt+    -- ^ 0 if successful, -1 on failure.++-- | Encode bytes to a hexidecimal string. Constant-time.+--+-- @since 0.0.1.0+foreign import capi "sodium.h sodium_bin2hex"+  sodiumBin2Hex+    :: CString+    -- ^ @hex@, The output buffer.+    -> CSize+    -- ^ @hex_len@, The maximum number of bytes this function is allowed to write+    -- to the output buffer. Must be at least @bin_len * 2 + 1@ bytes long.+    -> Ptr CUChar+    -- ^ @bin@, The input buffer.+    -> CSize+    -- ^ @bin_len@, The length of the input buffer.+    -> IO CString+    -- ^ The return string, terminated with a null byte.++{-++Due to a deficiency in Haskell's C FFI regarding nested pointers,+this function and its Base64 counterpart have been commented out.++The C shim that GHC generates ignores the @const@ qualifier in the+type for @hex_end@, leading to multiple type errors.++There is a pull request in GHC to fix this that is to ship with GHC 9.6.+https://gitlab.haskell.org/ghc/ghc/-/commit/4f70a8a0b5db49ff249271faefec14bf1421f365++-}++{-+-- | Decode a hexadecimal string to bytes. Constant-time.+foreign import capi "sodium.h sodium_hex2bin"+  sodiumHex2Bin+    :: Ptr CUChar+    -- ^ @bin@, The output buffer.+    -> CSize+    -- ^ @bin_maxlen@, The maximum length of the output buffer.+    -> CString+    -- ^ @hex@, The input string.+    -> CSize+    -- ^ @hex_len@, The length of the input.+    -> CString+    -- ^ @ignore@, a string of characters for the parser to skip.+    -- For example, the string ": " allows colons and spaces in the input.+    -- These characters will ignored and will not be present in the output.+    -> Ptr CSize+    -- ^ @bin_len@, The length of the output buffer.+    -> Ptr CString+    -- ^ @hex_end@, A pointer to the end of the input string.+    -- If this isn't null, then it will be set to the first byte after the last+    -- valid parsed character.+    -> IO CInt+    -- ^ 0 if successful, -1 on failure. Common failures are if the string+    -- couldn't be fully parsed or if the parsed string is longer than the+    -- maximum amount of bytes allocated to store it.+-}++-- | Encode bytes to a Base64 string. Constant-time.+foreign import capi "sodium.h sodium_bin2base64"+  sodiumBin2Base64+    :: CString+    -- ^ @b64@, The output buffer.+    -> CSize+    -- ^ @b64_maxlen@, The maximum length of the output buffer.+    -- Choosing a correct size is not straightforward and depends on+    -- the variant. The @sodium_base64_ENCODED_LEN(BIN_LEN, VARIANT)@+    -- macro computes the minimum amount of bytes needed to encode BIN_LEN+    -- bytes with a chosen VARIANT.+    -> Ptr CUChar+    -- ^ @bin@, The input buffer.+    -> CSize+    -- ^ @bin_len@, The length of the input buffer.+    -> CInt+    -- ^ @variant@, Which Base64 variant to use. None of the variants provide+    -- any encryption.+    -> IO CString+    -- ^ The returned Base64 string, terminated with a null byte.++{-+foreign import capi "sodium.h sodium_base642bin"+  sodiumBase642Bin+    :: Ptr CUChar+    -- ^ @bin@, The output buffer.+    -> CSize+    -- ^ @bin_maxlen@, The maximum length of the output buffer.+    -> CString+    -- ^ @b64@, The input string.+    -> CSize+    -- ^ @b64_len@, The length of the input.+    -> CString+    -- ^ @ignore@, a string of characters for the parser to skip.+    -- For example, the string ": " allows colons and spaces in the input.+    -- These characters will ignored and will not be present in the output.+    -> Ptr CSize+    -- ^ @bin_len@, The length of the output buffer.+    -- This will always be at most @b64_len / 4 * 3@ bytes long.+    -> Ptr CString+    -- ^ @b64_end@, A pointer to the end of the input string.+    -- If this isn't null, then it will be set to the first byte after the last+    -- valid parsed character.+    -> CInt+    -- ^ @variant@, Which Base64 variant to use. None of the variants provide+    -- any encryption.+    -> IO CInt+    -- ^ 0 if successful, -1 on failure. Common failures are if the string+    -- couldn't be fully parsed or if the parsed string is longer than the+    -- maximum amount of bytes allocated to store it.+-}++-- | The original variant of Base64 with padding. This ensures that the+-- length of the encoded data will always be a multiple of four bytes.+foreign import capi "sodium.h value sodium_base64_VARIANT_ORIGINAL"+  sodiumBase64VariantOriginal :: CInt++-- | The original variant of Base64. No variant offers any security advantages+-- over the other.+foreign import capi "sodium.h value sodium_base64_VARIANT_ORIGINAL_NO_PADDING"+  sodiumBase64VariantOriginalNoPadding :: CInt++-- | The URL-safe variant of Base64 with padding.+foreign import capi "sodium.h value sodium_base64_VARIANT_URLSAFE"+  sodiumBase64VariantURLSafe :: CInt++-- | The URL-safe variant of Base64. This is the same as the original variant,+-- except '+' and '/' are replaced with '-' and '_'.+foreign import capi "sodium.h value sodium_base64_VARIANT_URLSAFE_NO_PADDING"+  sodiumBase64VariantURLSafeNoPadding :: CInt
+ src/LibSodium/Bindings/XChaCha20.hs view
@@ -0,0 +1,153 @@+{-# LANGUAGE CApiFFI #-}+{-# LANGUAGE Trustworthy #-}++-- |+-- Module: LibSodium.Bindings.XChaCha20+-- Description: Direct bindings to XChaCha20 primitives+-- Copyright: (C) Koz Ross 2022+-- License: BSD-3-Clause+-- Maintainer: koz.ross@retro-freedom.nz+-- Stability: Stable+-- Portability: GHC only+--+-- Direct bindings to XChaCha20 primitives.+module LibSodium.Bindings.XChaCha20+  ( -- * Functions+    cryptoStreamXChaCha20+  , cryptoStreamXChaCha20Xor+  , cryptoStreamXChaCha20XorIC+  , cryptoStreamXChaCha20Keygen++    -- * Constants+  , cryptoStreamXChaCha20KeyBytes+  , cryptoStreamXChaCha20NonceBytes+  )+where++import Data.Word (Word64)+import Foreign.C.Types+  ( CInt (CInt)+  , CSize (CSize)+  , CUChar+  , CULLong (CULLong)+  )+import Foreign.Ptr (Ptr)++-- | Generate and store a given number of pseudorandom bytes, using a nonce+-- and a secret key. The amount of data read from the nonce location and secret+-- key location will be 'cryptoStreamXChaCha20NonceBytes' and+-- 'cryptoStreamXChaCha20KeyBytes' respectively.+--+-- This function theoretically returns 0 on success, and -1 on failure. However,+-- [this cannot ever+-- fail](https://github.com/jedisct1/libsodium/discussions/1148#discussioncomment-1979161),+-- although its documentation does not explain this.+--+-- /See:/ [crypto_stream_xchacha20()](https://doc.libsodium.org/advanced/stream_ciphers/xchacha20#usage)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_stream_xchacha20"+  cryptoStreamXChaCha20+    :: Ptr CUChar+    -- ^ Out-parameter where pseudorandom bytes will be stored+    -> CULLong+    -- ^ How many bytes to write+    -> Ptr CUChar+    -- ^ Nonce location (see documentation, won't be modified)+    -> Ptr CUChar+    -- ^ Secret key location (see documentation, won't be modified)+    -> IO CInt+    -- ^ Always 0 (see documentation)++-- | Encrypt a message of the given length, using a nonce and a secret key. The+-- amount of data read from the nonce location and secret key location will be+-- 'cryptoStreamXChaCha20NonceBytes' and 'cryptoStreamXChaCha20KeyBytes'+-- respectively.+--+-- The resulting ciphertext does /not/ include an authentication tag. It will be+-- combined with the output of the stream cipher using the XOR operation.+--+-- This function theoretically returns 0 on success, and -1 on failure. However,+-- [this cannot ever+-- fail](https://github.com/jedisct1/libsodium/discussions/1148#discussioncomment-1979161),+-- although its documentation does not explain this.+--+-- = Important note+--+-- The message location and ciphertext location can be the same: this will+-- produce in-place encryption. However, if they are /not/ the same, they must+-- be non-overlapping.+--+-- /See:/ [crypto_stream_xchacha20_xor()](https://doc.libsodium.org/advanced/stream_ciphers/xchacha20#usage)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_stream_xchacha20_xor"+  cryptoStreamXChaCha20Xor+    :: Ptr CUChar+    -- ^ Out-parameter where the ciphertext will be stored+    -> Ptr CUChar+    -- ^ Message location (won't be modified)+    -> CULLong+    -- ^ Message length+    -> Ptr CUChar+    -- ^ Nonce location (see documentation, won't be modified)+    -> Ptr CUChar+    -- ^ Secret key location (see documentation, won't be modified)+    -> IO CInt+    -- ^ Always 0 (see documentation)++-- | As 'cryptoStreamXChaCha20Xor', but allows setting the initial value of the+-- block counter to a non-zero value. This permits direct access to any block+-- without having to compute previous ones.+--+-- See the documentation of 'cryptoStreamXChaCha20Xor' for caveats on the use of+-- this function.+--+-- /See:/ [crypto_stream_xchacha20_xor_ic()](https://doc.libsodium.org/advanced/stream_ciphers/xchacha20#usage)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_stream_xchacha20_xor_ic"+  cryptoStreamXChaCha20XorIC+    :: Ptr CUChar+    -- ^ Out-parameter where the ciphertext will be stored+    -> Ptr CUChar+    -- ^ Message location (won't be modified)+    -> CULLong+    -- ^ Message length+    -> Ptr CUChar+    -- ^ Nonce location (see documentation, won't be modified)+    -> Word64+    -- ^ Value of block counter (see documentation)+    -> Ptr CUChar+    -- ^ Secret key location (see documentation, won't be modified)+    -> IO CInt+    -- ^ Always 0 (see documentation)++-- | Generate a random XChaCha20 secret key. This will always write+-- 'cryptoStreamXChaCha20KeyBytes' to the out-parameter.+--+-- /See:/ [crypto_stream_xchacha20_keygen()](https://doc.libsodium.org/advanced/stream_ciphers/xchacha20#usage)+--+-- @since 0.0.1.0+foreign import capi "sodium.h crypto_stream_xchacha20_keygen"+  cryptoStreamXChaCha20Keygen+    :: Ptr CUChar+    -- ^ Out-parameter where the key will be stored+    -> IO ()+    -- ^ Doesn't return anything meaningful++-- | The number of bytes in an XChaCha20 secret key.+--+-- /See:/ [crypto_stream_xchacha20_KEYBYTES](https://doc.libsodium.org/advanced/stream_ciphers/xchacha20#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_stream_xchacha20_KEYBYTES"+  cryptoStreamXChaCha20KeyBytes :: CSize++-- | The number of bytes in an XChaCha20 nonce.+--+-- /See:/ [crypto_stream_xchacha20_NONCEBYTES](https://doc.libsodium.org/advanced/stream_ciphers/xchacha20#constants)+--+-- @since 0.0.1.0+foreign import capi "sodium.h value crypto_stream_xchacha20_NONCEBYTES"+  cryptoStreamXChaCha20NonceBytes :: CSize