{-# LINE 1 "src/Botan/Bindings/Cipher.hsc" #-}
{-|
Module      : Botan.Bindings.Cipher
Description : Symmetric cipher modes
Copyright   : (c) Leo D, 2023
License     : BSD-3-Clause
Maintainer  : leo@apotheca.io
Stability   : experimental
Portability : POSIX

A block cipher by itself, is only able to securely encrypt a single
data block. To be able to securely encrypt data of arbitrary length,
a mode of operation applies the block cipher’s single block operation
repeatedly to encrypt an entire message.
-}

{-# LANGUAGE CApiFFI #-}

module Botan.Bindings.Cipher where

import Botan.Bindings.Prelude



-- | Opaque Cipher struct
data {-# CTYPE "botan/ffi.h" "struct botan_cipher_struct" #-} BotanCipherStruct

-- | Botan Cipher object
newtype {-# CTYPE "botan/ffi.h" "botan_cipher_t" #-} BotanCipher
    = MkBotanCipher { BotanCipher -> Ptr BotanCipherStruct
runBotanCipher :: Ptr BotanCipherStruct }
        deriving newtype (BotanCipher -> BotanCipher -> Bool
(BotanCipher -> BotanCipher -> Bool)
-> (BotanCipher -> BotanCipher -> Bool) -> Eq BotanCipher
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: BotanCipher -> BotanCipher -> Bool
== :: BotanCipher -> BotanCipher -> Bool
$c/= :: BotanCipher -> BotanCipher -> Bool
/= :: BotanCipher -> BotanCipher -> Bool
Eq, Eq BotanCipher
Eq BotanCipher
-> (BotanCipher -> BotanCipher -> Ordering)
-> (BotanCipher -> BotanCipher -> Bool)
-> (BotanCipher -> BotanCipher -> Bool)
-> (BotanCipher -> BotanCipher -> Bool)
-> (BotanCipher -> BotanCipher -> Bool)
-> (BotanCipher -> BotanCipher -> BotanCipher)
-> (BotanCipher -> BotanCipher -> BotanCipher)
-> Ord BotanCipher
BotanCipher -> BotanCipher -> Bool
BotanCipher -> BotanCipher -> Ordering
BotanCipher -> BotanCipher -> BotanCipher
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: BotanCipher -> BotanCipher -> Ordering
compare :: BotanCipher -> BotanCipher -> Ordering
$c< :: BotanCipher -> BotanCipher -> Bool
< :: BotanCipher -> BotanCipher -> Bool
$c<= :: BotanCipher -> BotanCipher -> Bool
<= :: BotanCipher -> BotanCipher -> Bool
$c> :: BotanCipher -> BotanCipher -> Bool
> :: BotanCipher -> BotanCipher -> Bool
$c>= :: BotanCipher -> BotanCipher -> Bool
>= :: BotanCipher -> BotanCipher -> Bool
$cmax :: BotanCipher -> BotanCipher -> BotanCipher
max :: BotanCipher -> BotanCipher -> BotanCipher
$cmin :: BotanCipher -> BotanCipher -> BotanCipher
min :: BotanCipher -> BotanCipher -> BotanCipher
Ord, Ptr BotanCipher -> IO BotanCipher
Ptr BotanCipher -> Int -> IO BotanCipher
Ptr BotanCipher -> Int -> BotanCipher -> IO ()
Ptr BotanCipher -> BotanCipher -> IO ()
BotanCipher -> Int
(BotanCipher -> Int)
-> (BotanCipher -> Int)
-> (Ptr BotanCipher -> Int -> IO BotanCipher)
-> (Ptr BotanCipher -> Int -> BotanCipher -> IO ())
-> (forall b. Ptr b -> Int -> IO BotanCipher)
-> (forall b. Ptr b -> Int -> BotanCipher -> IO ())
-> (Ptr BotanCipher -> IO BotanCipher)
-> (Ptr BotanCipher -> BotanCipher -> IO ())
-> Storable BotanCipher
forall b. Ptr b -> Int -> IO BotanCipher
forall b. Ptr b -> Int -> BotanCipher -> IO ()
forall a.
(a -> Int)
-> (a -> Int)
-> (Ptr a -> Int -> IO a)
-> (Ptr a -> Int -> a -> IO ())
-> (forall b. Ptr b -> Int -> IO a)
-> (forall b. Ptr b -> Int -> a -> IO ())
-> (Ptr a -> IO a)
-> (Ptr a -> a -> IO ())
-> Storable a
$csizeOf :: BotanCipher -> Int
sizeOf :: BotanCipher -> Int
$calignment :: BotanCipher -> Int
alignment :: BotanCipher -> Int
$cpeekElemOff :: Ptr BotanCipher -> Int -> IO BotanCipher
peekElemOff :: Ptr BotanCipher -> Int -> IO BotanCipher
$cpokeElemOff :: Ptr BotanCipher -> Int -> BotanCipher -> IO ()
pokeElemOff :: Ptr BotanCipher -> Int -> BotanCipher -> IO ()
$cpeekByteOff :: forall b. Ptr b -> Int -> IO BotanCipher
peekByteOff :: forall b. Ptr b -> Int -> IO BotanCipher
$cpokeByteOff :: forall b. Ptr b -> Int -> BotanCipher -> IO ()
pokeByteOff :: forall b. Ptr b -> Int -> BotanCipher -> IO ()
$cpeek :: Ptr BotanCipher -> IO BotanCipher
peek :: Ptr BotanCipher -> IO BotanCipher
$cpoke :: Ptr BotanCipher -> BotanCipher -> IO ()
poke :: Ptr BotanCipher -> BotanCipher -> IO ()
Storable)

-- | Destroy the cipher object
foreign import capi safe "botan/ffi.h &botan_cipher_destroy"
    botan_cipher_destroy
        :: FinalizerPtr BotanCipherStruct

pattern BOTAN_CIPHER_MODE_CBC
    ,   BOTAN_CIPHER_MODE_CFB
    ,   BOTAN_CIPHER_MODE_XTS
    ::  (Eq a, IsString a) => a

pattern $mBOTAN_CIPHER_MODE_CBC :: forall {r} {a}.
(Eq a, IsString a) =>
a -> ((# #) -> r) -> ((# #) -> r) -> r
$bBOTAN_CIPHER_MODE_CBC :: forall a. (Eq a, IsString a) => a
BOTAN_CIPHER_MODE_CBC = "CBC"
pattern $mBOTAN_CIPHER_MODE_CFB :: forall {r} {a}.
(Eq a, IsString a) =>
a -> ((# #) -> r) -> ((# #) -> r) -> r
$bBOTAN_CIPHER_MODE_CFB :: forall a. (Eq a, IsString a) => a
BOTAN_CIPHER_MODE_CFB = "CFB"
pattern $mBOTAN_CIPHER_MODE_XTS :: forall {r} {a}.
(Eq a, IsString a) =>
a -> ((# #) -> r) -> ((# #) -> r) -> r
$bBOTAN_CIPHER_MODE_XTS :: forall a. (Eq a, IsString a) => a
BOTAN_CIPHER_MODE_XTS = "XTS"

pattern BOTAN_CBC_PADDING_PKCS7
    ,   BOTAN_CBC_PADDING_ONE_AND_ZEROS
    ,   BOTAN_CBC_PADDING_X9_23
    ,   BOTAN_CBC_PADDING_ESP
    ,   BOTAN_CBC_PADDING_CTS
    ,   BOTAN_CBC_PADDING_NO_PADDING
    ::  (Eq a, IsString a) => a

pattern $mBOTAN_CBC_PADDING_PKCS7 :: forall {r} {a}.
(Eq a, IsString a) =>
a -> ((# #) -> r) -> ((# #) -> r) -> r
$bBOTAN_CBC_PADDING_PKCS7 :: forall a. (Eq a, IsString a) => a
BOTAN_CBC_PADDING_PKCS7             = "PKCS7"
pattern $mBOTAN_CBC_PADDING_ONE_AND_ZEROS :: forall {r} {a}.
(Eq a, IsString a) =>
a -> ((# #) -> r) -> ((# #) -> r) -> r
$bBOTAN_CBC_PADDING_ONE_AND_ZEROS :: forall a. (Eq a, IsString a) => a
BOTAN_CBC_PADDING_ONE_AND_ZEROS    = "OneAndZeros"
pattern $mBOTAN_CBC_PADDING_X9_23 :: forall {r} {a}.
(Eq a, IsString a) =>
a -> ((# #) -> r) -> ((# #) -> r) -> r
$bBOTAN_CBC_PADDING_X9_23 :: forall a. (Eq a, IsString a) => a
BOTAN_CBC_PADDING_X9_23             = "X9.23"
pattern $mBOTAN_CBC_PADDING_ESP :: forall {r} {a}.
(Eq a, IsString a) =>
a -> ((# #) -> r) -> ((# #) -> r) -> r
$bBOTAN_CBC_PADDING_ESP :: forall a. (Eq a, IsString a) => a
BOTAN_CBC_PADDING_ESP               = "ESP"
pattern $mBOTAN_CBC_PADDING_CTS :: forall {r} {a}.
(Eq a, IsString a) =>
a -> ((# #) -> r) -> ((# #) -> r) -> r
$bBOTAN_CBC_PADDING_CTS :: forall a. (Eq a, IsString a) => a
BOTAN_CBC_PADDING_CTS               = "CTS"
pattern $mBOTAN_CBC_PADDING_NO_PADDING :: forall {r} {a}.
(Eq a, IsString a) =>
a -> ((# #) -> r) -> ((# #) -> r) -> r
$bBOTAN_CBC_PADDING_NO_PADDING :: forall a. (Eq a, IsString a) => a
BOTAN_CBC_PADDING_NO_PADDING        = "NoPadding"

pattern BOTAN_AEAD_CHACHA20POLY1305
    ::  (Eq a, IsString a) => a

pattern $mBOTAN_AEAD_CHACHA20POLY1305 :: forall {r} {a}.
(Eq a, IsString a) =>
a -> ((# #) -> r) -> ((# #) -> r) -> r
$bBOTAN_AEAD_CHACHA20POLY1305 :: forall a. (Eq a, IsString a) => a
BOTAN_AEAD_CHACHA20POLY1305 = "ChaCha20Poly1305"

pattern BOTAN_AEAD_MODE_GCM
    ,   BOTAN_AEAD_MODE_OCB
    ,   BOTAN_AEAD_MODE_EAX
    ,   BOTAN_AEAD_MODE_SIV
    ,   BOTAN_AEAD_MODE_CCM
    ::  (Eq a, IsString a) => a

pattern $mBOTAN_AEAD_MODE_GCM :: forall {r} {a}.
(Eq a, IsString a) =>
a -> ((# #) -> r) -> ((# #) -> r) -> r
$bBOTAN_AEAD_MODE_GCM :: forall a. (Eq a, IsString a) => a
BOTAN_AEAD_MODE_GCM         = "GCM"
pattern $mBOTAN_AEAD_MODE_OCB :: forall {r} {a}.
(Eq a, IsString a) =>
a -> ((# #) -> r) -> ((# #) -> r) -> r
$bBOTAN_AEAD_MODE_OCB :: forall a. (Eq a, IsString a) => a
BOTAN_AEAD_MODE_OCB         = "OCB"
pattern $mBOTAN_AEAD_MODE_EAX :: forall {r} {a}.
(Eq a, IsString a) =>
a -> ((# #) -> r) -> ((# #) -> r) -> r
$bBOTAN_AEAD_MODE_EAX :: forall a. (Eq a, IsString a) => a
BOTAN_AEAD_MODE_EAX         = "EAX"
pattern $mBOTAN_AEAD_MODE_SIV :: forall {r} {a}.
(Eq a, IsString a) =>
a -> ((# #) -> r) -> ((# #) -> r) -> r
$bBOTAN_AEAD_MODE_SIV :: forall a. (Eq a, IsString a) => a
BOTAN_AEAD_MODE_SIV         = "SIV"
pattern $mBOTAN_AEAD_MODE_CCM :: forall {r} {a}.
(Eq a, IsString a) =>
a -> ((# #) -> r) -> ((# #) -> r) -> r
$bBOTAN_AEAD_MODE_CCM :: forall a. (Eq a, IsString a) => a
BOTAN_AEAD_MODE_CCM         = "CCM"

pattern BOTAN_CIPHER_INIT_FLAG_MASK_DIRECTION
    ,   BOTAN_CIPHER_INIT_FLAG_ENCRYPT
    ,   BOTAN_CIPHER_INIT_FLAG_DECRYPT
    ::  (Eq a, Num a) => a
pattern $mBOTAN_CIPHER_INIT_FLAG_MASK_DIRECTION :: forall {r} {a}.
(Eq a, Num a) =>
a -> ((# #) -> r) -> ((# #) -> r) -> r
$bBOTAN_CIPHER_INIT_FLAG_MASK_DIRECTION :: forall a. (Eq a, Num a) => a
BOTAN_CIPHER_INIT_FLAG_MASK_DIRECTION = 1
{-# LINE 84 "src/Botan/Bindings/Cipher.hsc" #-}
pattern BOTAN_CIPHER_INIT_FLAG_ENCRYPT        = 0
{-# LINE 85 "src/Botan/Bindings/Cipher.hsc" #-}
pattern BOTAN_CIPHER_INIT_FLAG_DECRYPT        = 1
{-# LINE 86 "src/Botan/Bindings/Cipher.hsc" #-}

-- | Initialize a cipher object
foreign import capi safe "botan/ffi.h botan_cipher_init"
    botan_cipher_init
        :: Ptr BotanCipher  -- ^ __cipher__
        -> ConstPtr CChar   -- ^ __name__
        -> Word32           -- ^ __flags__
        -> IO CInt

-- | Return the name of the cipher object
foreign import capi safe "botan/ffi.h botan_cipher_name"
    botan_cipher_name
        :: BotanCipher  -- ^ __cipher__
        -> Ptr CChar    -- ^ __name__
        -> Ptr CSize    -- ^ __name_len__
        -> IO CInt

-- | Return the output length of this cipher, for a particular input length.
foreign import capi safe "botan/ffi.h botan_cipher_output_length"
    botan_cipher_output_length
        :: BotanCipher  -- ^ __cipher__
        -> CSize        -- ^ __in_len__
        -> Ptr CSize    -- ^ __out_len__
        -> IO CInt

-- | Return if the specified nonce length is valid for this cipher
--   (0 / SUCCESS if valid, 1 / INVALID_IDENTIFIER if not)
foreign import capi safe "botan/ffi.h botan_cipher_valid_nonce_length"
    botan_cipher_valid_nonce_length
        :: BotanCipher  -- ^ __cipher__
        -> CSize        -- ^ __nl__
        -> IO CInt

-- | Get the tag length of the cipher (0 for non-AEAD modes)
foreign import capi safe "botan/ffi.h botan_cipher_get_tag_length"
    botan_cipher_get_tag_length
        :: BotanCipher  -- ^ __cipher__
        -> Ptr CSize    -- ^ __tag_size__
        -> IO CInt

-- | Get the default nonce length of this cipher
foreign import capi safe "botan/ffi.h botan_cipher_get_default_nonce_length"
    botan_cipher_get_default_nonce_length
        :: BotanCipher  -- ^ __cipher__
        -> Ptr CSize    -- ^ __nl__
        -> IO CInt

-- | Return the update granularity of the cipher;
--   botan_cipher_update must be called with blocks of this size, except for the final.
foreign import capi safe "botan/ffi.h botan_cipher_get_update_granularity"
    botan_cipher_get_update_granularity
        :: BotanCipher  -- ^ __cipher__
        -> Ptr CSize    -- ^ __ug__
        -> IO CInt

{-
Return the ideal update granularity of the cipher.
This is some multiple of the update granularity,
reflecting possibilities for optimization.
-}
foreign import capi safe "botan/ffi.h botan_cipher_get_ideal_update_granularity"
    botan_cipher_get_ideal_update_granularity
        :: BotanCipher  -- ^ __cipher__
        -> Ptr CSize    -- ^ __ug__
        -> IO CInt

-- | Get information about the key lengths. Prefer botan_cipher_get_keyspec
foreign import capi safe "botan/ffi.h botan_cipher_query_keylen"
    botan_cipher_query_keylen
        :: BotanCipher  -- ^ __cipher__
        -> Ptr CSize    -- ^ __out_minimum_keylength__
        -> Ptr CSize    -- ^ __out_maximum_keylength__
        -> IO CInt

-- | Get information about the supported key lengths.
foreign import capi safe "botan/ffi.h botan_cipher_get_keyspec"
    botan_cipher_get_keyspec
        :: BotanCipher  -- ^ __cipher__
        -> Ptr CSize    -- ^ __min_keylen__
        -> Ptr CSize    -- ^ __max_keylen__
        -> Ptr CSize    -- ^ __mod_keylen__
        -> IO CInt

-- | Set the key for this cipher object
foreign import capi safe "botan/ffi.h botan_cipher_set_key"
    botan_cipher_set_key
        :: BotanCipher      -- ^ __cipher__
        -> ConstPtr Word8   -- ^ __key__
        -> CSize            -- ^ __key_len__
        -> IO CInt

{-
Reset the message specific state for this cipher.
Without resetting the keys, this resets the nonce, and any state
associated with any message bits that have been processed so far.

It is conceptually equivalent to calling botan_cipher_clear followed
by botan_cipher_set_key with the original key.
-}
foreign import capi safe "botan/ffi.h botan_cipher_reset"
    botan_cipher_reset
        :: BotanCipher -- ^ __cipher__
        -> IO CInt

-- | Set the associated data. Will fail if cipher is not an AEAD
foreign import capi safe "botan/ffi.h botan_cipher_set_associated_data"
    botan_cipher_set_associated_data
        :: BotanCipher      -- ^ __cipher__
        -> ConstPtr Word8   -- ^ __ad__
        -> CSize            -- ^ __ad_len__
        -> IO CInt

-- | Begin processing a new message using the provided nonce
foreign import capi safe "botan/ffi.h botan_cipher_start"
    botan_cipher_start
        :: BotanCipher      -- ^ __cipher__
        -> ConstPtr Word8   -- ^ __nonce__
        -> CSize            -- ^ __nonce_len__
        -> IO CInt

pattern BOTAN_CIPHER_UPDATE_FLAG_NONE
    ,   BOTAN_CIPHER_UPDATE_FLAG_FINAL
    ::  (Eq a, Num a) => a
pattern $mBOTAN_CIPHER_UPDATE_FLAG_NONE :: forall {r} {a}.
(Eq a, Num a) =>
a -> ((# #) -> r) -> ((# #) -> r) -> r
$bBOTAN_CIPHER_UPDATE_FLAG_NONE :: forall a. (Eq a, Num a) => a
BOTAN_CIPHER_UPDATE_FLAG_NONE   = 0
pattern $mBOTAN_CIPHER_UPDATE_FLAG_FINAL :: forall {r} {a}.
(Eq a, Num a) =>
a -> ((# #) -> r) -> ((# #) -> r) -> r
$bBOTAN_CIPHER_UPDATE_FLAG_FINAL :: forall a. (Eq a, Num a) => a
BOTAN_CIPHER_UPDATE_FLAG_FINAL  = 1
{-# LINE 211 "src/Botan/Bindings/Cipher.hsc" #-}

-- | Encrypt some data
foreign import capi safe "botan/ffi.h botan_cipher_update"
    botan_cipher_update
        :: BotanCipher      -- ^ __cipher__
        -> Word32           -- ^ __flags__
        -> Ptr Word8        -- ^ __output[]__
        -> CSize            -- ^ __output_size__
        -> Ptr CSize        -- ^ __output_written__
        -> ConstPtr Word8   -- ^ __input_bytes[]__
        -> CSize            -- ^ __input_size__
        -> Ptr CSize        -- ^ __input_consumed__
        -> IO CInt

-- | Reset the key, nonce, AD and all other state on this cipher object
foreign import capi safe "botan/ffi.h botan_cipher_clear"
    botan_cipher_clear
        :: BotanCipher -- ^ __hash__
        -> IO CInt