    -- |
    -- Module      : Crypto.Cipher.Types.Base
    -- License     : BSD-style
    -- Maintainer  : Vincent Hanquez <vincent@snarc.org>
    -- Stability   : Stable
    -- Portability : Excellent
    --
    -- symmetric cipher basic types
    --
    module Crypto.Cipher.Types.Base
        ( KeyError(..)
        , KeySizeSpecifier(..)
        , Key(..)
        , IV(..)
        , Cipher(..)
        , AuthTag(..)
        , AEADMode(..)
        , DataUnitOffset
        ) where

    import Data.Byteable
    import Data.SecureMem
    import Data.Word
    import Data.ByteString (ByteString)

    -- | Possible Error that can be reported when initializating a key
    data KeyError =
          KeyErrorTooSmall
        | KeyErrorTooBig
        | KeyErrorInvalid String
        deriving (Int -> KeyError -> ShowS
    [KeyError] -> ShowS
    KeyError -> String
    (Int -> KeyError -> ShowS)
    -> (KeyError -> String) -> ([KeyError] -> ShowS) -> Show KeyError
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> KeyError -> ShowS
    showsPrec :: Int -> KeyError -> ShowS
    $cshow :: KeyError -> String
    show :: KeyError -> String
    $cshowList :: [KeyError] -> ShowS
    showList :: [KeyError] -> ShowS
    Show,KeyError -> KeyError -> Bool
    (KeyError -> KeyError -> Bool)
    -> (KeyError -> KeyError -> Bool) -> Eq KeyError
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: KeyError -> KeyError -> Bool
    == :: KeyError -> KeyError -> Bool
    $c/= :: KeyError -> KeyError -> Bool
    /= :: KeyError -> KeyError -> Bool
    Eq)

    -- | Different specifier for key size in bytes
    data KeySizeSpecifier =
          KeySizeRange Int Int -- ^ in the range [min,max]
        | KeySizeEnum  [Int]   -- ^ one of the specified values
        | KeySizeFixed Int     -- ^ a specific size
        deriving (Int -> KeySizeSpecifier -> ShowS
    [KeySizeSpecifier] -> ShowS
    KeySizeSpecifier -> String
    (Int -> KeySizeSpecifier -> ShowS)
    -> (KeySizeSpecifier -> String)
    -> ([KeySizeSpecifier] -> ShowS)
    -> Show KeySizeSpecifier
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> KeySizeSpecifier -> ShowS
    showsPrec :: Int -> KeySizeSpecifier -> ShowS
    $cshow :: KeySizeSpecifier -> String
    show :: KeySizeSpecifier -> String
    $cshowList :: [KeySizeSpecifier] -> ShowS
    showList :: [KeySizeSpecifier] -> ShowS
    Show,KeySizeSpecifier -> KeySizeSpecifier -> Bool
    (KeySizeSpecifier -> KeySizeSpecifier -> Bool)
    -> (KeySizeSpecifier -> KeySizeSpecifier -> Bool)
    -> Eq KeySizeSpecifier
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: KeySizeSpecifier -> KeySizeSpecifier -> Bool
    == :: KeySizeSpecifier -> KeySizeSpecifier -> Bool
    $c/= :: KeySizeSpecifier -> KeySizeSpecifier -> Bool
    /= :: KeySizeSpecifier -> KeySizeSpecifier -> Bool
    Eq)

    -- | Offset inside an XTS data unit, measured in block size.
    type DataUnitOffset = Word32

    -- | a Key parametrized by the cipher
    newtype Key c = Key SecureMem deriving (Key c -> Key c -> Bool
    (Key c -> Key c -> Bool) -> (Key c -> Key c -> Bool) -> Eq (Key c)
    forall c. Key c -> Key c -> Bool
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: forall c. Key c -> Key c -> Bool
    == :: Key c -> Key c -> Bool
    $c/= :: forall c. Key c -> Key c -> Bool
    /= :: Key c -> Key c -> Bool
    Eq)

    instance ToSecureMem (Key c) where
        toSecureMem :: Key c -> SecureMem
    toSecureMem (Key SecureMem
    sm) = SecureMem
    sm
    instance Byteable (Key c) where
        toBytes :: Key c -> ByteString
    toBytes (Key SecureMem
    sm) = SecureMem -> ByteString
    forall a. Byteable a => a -> ByteString
    toBytes SecureMem
    sm

    -- | an IV parametrized by the cipher
    newtype IV c = IV ByteString deriving (IV c -> IV c -> Bool
    (IV c -> IV c -> Bool) -> (IV c -> IV c -> Bool) -> Eq (IV c)
    forall c. IV c -> IV c -> Bool
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: forall c. IV c -> IV c -> Bool
    == :: IV c -> IV c -> Bool
    $c/= :: forall c. IV c -> IV c -> Bool
    /= :: IV c -> IV c -> Bool
    Eq)

    instance Byteable (IV c) where
        toBytes :: IV c -> ByteString
    toBytes (IV ByteString
    sm) = ByteString
    sm

    -- | Authentification Tag for AE cipher mode
    newtype AuthTag = AuthTag ByteString
        deriving (Int -> AuthTag -> ShowS
    [AuthTag] -> ShowS
    AuthTag -> String
    (Int -> AuthTag -> ShowS)
    -> (AuthTag -> String) -> ([AuthTag] -> ShowS) -> Show AuthTag
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> AuthTag -> ShowS
    showsPrec :: Int -> AuthTag -> ShowS
    $cshow :: AuthTag -> String
    show :: AuthTag -> String
    $cshowList :: [AuthTag] -> ShowS
    showList :: [AuthTag] -> ShowS
    Show)

    instance Eq AuthTag where
        (AuthTag ByteString
    a) == :: AuthTag -> AuthTag -> Bool
    == (AuthTag ByteString
    b) = ByteString -> ByteString -> Bool
    forall a. Byteable a => a -> a -> Bool
    constEqBytes ByteString
    a ByteString
    b
    instance Byteable AuthTag where
        toBytes :: AuthTag -> ByteString
    toBytes (AuthTag ByteString
    bs) = ByteString
    bs

    -- | AEAD Mode
    data AEADMode =
          AEAD_OCB
        | AEAD_CCM
        | AEAD_EAX
        | AEAD_CWC
        | AEAD_GCM
        deriving (Int -> AEADMode -> ShowS
    [AEADMode] -> ShowS
    AEADMode -> String
    (Int -> AEADMode -> ShowS)
    -> (AEADMode -> String) -> ([AEADMode] -> ShowS) -> Show AEADMode
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> AEADMode -> ShowS
    showsPrec :: Int -> AEADMode -> ShowS
    $cshow :: AEADMode -> String
    show :: AEADMode -> String
    $cshowList :: [AEADMode] -> ShowS
    showList :: [AEADMode] -> ShowS
    Show,AEADMode -> AEADMode -> Bool
    (AEADMode -> AEADMode -> Bool)
    -> (AEADMode -> AEADMode -> Bool) -> Eq AEADMode
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: AEADMode -> AEADMode -> Bool
    == :: AEADMode -> AEADMode -> Bool
    $c/= :: AEADMode -> AEADMode -> Bool
    /= :: AEADMode -> AEADMode -> Bool
    Eq)

    -- | Symmetric cipher class.
    class Cipher cipher where
        -- | Initialize a cipher context from a key
        cipherInit    :: Key cipher -> cipher
        -- | Cipher name
        cipherName    :: cipher -> String
        -- | return the size of the key required for this cipher.
        -- Some cipher accept any size for key
        cipherKeySize :: cipher -> KeySizeSpecifier