-- |
-- Module      : Crypto.Cipher.Types
-- License     : BSD-style
-- Maintainer  : Vincent Hanquez <vincent@snarc.org>
-- Stability   : Stable
-- Portability : Excellent
--
-- symmetric cipher basic types
--
{-# LANGUAGE DeriveDataTypeable #-}
module Crypto.Cipher.Types
    (
    -- * Cipher classes
      Cipher(..)
    , BlockCipher(..)
    , StreamCipher(..)
    , DataUnitOffset
    , KeySizeSpecifier(..)
    , KeyError(..)
    , AEAD(..)
    , AEADState(..)
    , AEADMode(..)
    , AEADModeImpl(..)
    , cfb8Encrypt
    , cfb8Decrypt
    -- * AEAD functions
    , module Crypto.Cipher.Types.AEAD
    -- * Key type and constructor
    , Key
    , makeKey
    -- * Initial Vector type and constructor
    , IV
    , makeIV
    , nullIV
    , ivAdd
    -- * Authentification Tag
    , AuthTag(..)
    ) where

import Data.SecureMem
import Data.Byteable
import Crypto.Cipher.Types.Base
import Crypto.Cipher.Types.Block
import Crypto.Cipher.Types.Stream
import Crypto.Cipher.Types.AEAD

-- | Create a Key for a specified cipher
makeKey :: (ToSecureMem b, Cipher c) => b -> Either KeyError (Key c)
makeKey :: forall b c.
(ToSecureMem b, Cipher c) =>
b -> Either KeyError (Key c)
makeKey b
b = c -> Either KeyError (Key c)
forall c. Cipher c => c -> Either KeyError (Key c)
toKey c
forall a. HasCallStack => a
undefined
  where sm :: SecureMem
sm    = b -> SecureMem
forall a. ToSecureMem a => a -> SecureMem
toSecureMem b
b
        smLen :: Int
smLen = SecureMem -> Int
forall a. Byteable a => a -> Int
byteableLength SecureMem
sm
        toKey :: Cipher c => c -> Either KeyError (Key c)
        toKey :: forall c. Cipher c => c -> Either KeyError (Key c)
toKey c
cipher = case c -> KeySizeSpecifier
forall cipher. Cipher cipher => cipher -> KeySizeSpecifier
cipherKeySize c
cipher of
            KeySizeRange Int
mi Int
ma | Int
smLen Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
mi -> KeyError -> Either KeyError (Key c)
forall a b. a -> Either a b
Left KeyError
KeyErrorTooSmall
                               | Int
smLen Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
ma -> KeyError -> Either KeyError (Key c)
forall a b. a -> Either a b
Left KeyError
KeyErrorTooBig
                               | Bool
otherwise  -> Key c -> Either KeyError (Key c)
forall a b. b -> Either a b
Right (Key c -> Either KeyError (Key c))
-> Key c -> Either KeyError (Key c)
forall a b. (a -> b) -> a -> b
$ SecureMem -> Key c
forall c. SecureMem -> Key c
Key SecureMem
sm
            KeySizeEnum [Int]
l | Int
smLen Int -> [Int] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Int]
l  -> Key c -> Either KeyError (Key c)
forall a b. b -> Either a b
Right (Key c -> Either KeyError (Key c))
-> Key c -> Either KeyError (Key c)
forall a b. (a -> b) -> a -> b
$ SecureMem -> Key c
forall c. SecureMem -> Key c
Key SecureMem
sm
                          | Bool
otherwise       -> KeyError -> Either KeyError (Key c)
forall a b. a -> Either a b
Left (KeyError -> Either KeyError (Key c))
-> KeyError -> Either KeyError (Key c)
forall a b. (a -> b) -> a -> b
$ String -> KeyError
KeyErrorInvalid (String
"valid size: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [Int] -> String
forall a. Show a => a -> String
show [Int]
l)
            KeySizeFixed Int
v | Int
smLen Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
v     -> Key c -> Either KeyError (Key c)
forall a b. b -> Either a b
Right (Key c -> Either KeyError (Key c))
-> Key c -> Either KeyError (Key c)
forall a b. (a -> b) -> a -> b
$ SecureMem -> Key c
forall c. SecureMem -> Key c
Key SecureMem
sm
                           | Bool
otherwise      -> KeyError -> Either KeyError (Key c)
forall a b. a -> Either a b
Left (KeyError -> Either KeyError (Key c))
-> KeyError -> Either KeyError (Key c)
forall a b. (a -> b) -> a -> b
$ String -> KeyError
KeyErrorInvalid (String
"valid size: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
v)