{-# LANGUAGE DataKinds                        #-}
{-# LANGUAGE KindSignatures                   #-}
{-# LANGUAGE GeneralizedNewtypeDeriving       #-}
{-# LANGUAGE ForeignFunctionInterface         #-}
{-# LANGUAGE FlexibleInstances                #-}
{-# LANGUAGE MultiParamTypeClasses            #-}
{-# LANGUAGE TypeFamilies                     #-}

-- | Internals of AES.
module Raaz.Cipher.AES.Internal
       (-- * AES cipher.
         AES(..)
       -- ** AES key types.
       , KEY128, KEY192, KEY256
       , EKEY128, EKEY192, EKEY256, IV
       , aes128cbc, aes192cbc, aes256cbc
       , aes128ctr
       ) where

import Data.String
import Data.Word

import Foreign.Ptr      ( castPtr, Ptr )
import Foreign.Storable (Storable, poke)
import GHC.TypeLits

import Raaz.Core
import Raaz.Random

import Raaz.Cipher.Internal

--------------- Basic types associated with AES -------------

-- | The type associated with AES ciphers. Raaz provides AES variants
-- with key lengths 128, 192 and 256. The key types for the above
-- ciphers in cbc mode are given by the types @(`KEY128`, IV)@,
-- @(`KEY192`, IV)@ @(`KEY256`, IV)@ respectively.
data AES (n :: Nat) (mode :: CipherMode) = AES

-- | The basic word used in AES.
type WORD    = BE Word32

-- | A tuple of AES words.
type TUPLE n = Tuple n WORD

-- | Key used for AES-128
newtype KEY128  = KEY128  (TUPLE 4)  deriving (Ptr b -> Int -> IO KEY128
Ptr b -> Int -> KEY128 -> IO ()
Ptr KEY128 -> IO KEY128
Ptr KEY128 -> Int -> IO KEY128
Ptr KEY128 -> Int -> KEY128 -> IO ()
Ptr KEY128 -> KEY128 -> IO ()
KEY128 -> Int
(KEY128 -> Int)
-> (KEY128 -> Int)
-> (Ptr KEY128 -> Int -> IO KEY128)
-> (Ptr KEY128 -> Int -> KEY128 -> IO ())
-> (forall b. Ptr b -> Int -> IO KEY128)
-> (forall b. Ptr b -> Int -> KEY128 -> IO ())
-> (Ptr KEY128 -> IO KEY128)
-> (Ptr KEY128 -> KEY128 -> IO ())
-> Storable KEY128
forall b. Ptr b -> Int -> IO KEY128
forall b. Ptr b -> Int -> KEY128 -> 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
poke :: Ptr KEY128 -> KEY128 -> IO ()
$cpoke :: Ptr KEY128 -> KEY128 -> IO ()
peek :: Ptr KEY128 -> IO KEY128
$cpeek :: Ptr KEY128 -> IO KEY128
pokeByteOff :: Ptr b -> Int -> KEY128 -> IO ()
$cpokeByteOff :: forall b. Ptr b -> Int -> KEY128 -> IO ()
peekByteOff :: Ptr b -> Int -> IO KEY128
$cpeekByteOff :: forall b. Ptr b -> Int -> IO KEY128
pokeElemOff :: Ptr KEY128 -> Int -> KEY128 -> IO ()
$cpokeElemOff :: Ptr KEY128 -> Int -> KEY128 -> IO ()
peekElemOff :: Ptr KEY128 -> Int -> IO KEY128
$cpeekElemOff :: Ptr KEY128 -> Int -> IO KEY128
alignment :: KEY128 -> Int
$calignment :: KEY128 -> Int
sizeOf :: KEY128 -> Int
$csizeOf :: KEY128 -> Int
Storable, Storable KEY128
Ptr KEY128 -> IO KEY128
Ptr KEY128 -> Int -> IO ()
Ptr KEY128 -> KEY128 -> IO ()
Storable KEY128
-> (Ptr KEY128 -> KEY128 -> IO ())
-> (Ptr KEY128 -> IO KEY128)
-> (Ptr KEY128 -> Int -> IO ())
-> EndianStore KEY128
forall w.
Storable w
-> (Ptr w -> w -> IO ())
-> (Ptr w -> IO w)
-> (Ptr w -> Int -> IO ())
-> EndianStore w
adjustEndian :: Ptr KEY128 -> Int -> IO ()
$cadjustEndian :: Ptr KEY128 -> Int -> IO ()
load :: Ptr KEY128 -> IO KEY128
$cload :: Ptr KEY128 -> IO KEY128
store :: Ptr KEY128 -> KEY128 -> IO ()
$cstore :: Ptr KEY128 -> KEY128 -> IO ()
$cp1EndianStore :: Storable KEY128
EndianStore)


-- | Key used for AES-128
newtype KEY192  = KEY192  (TUPLE 6)  deriving (Ptr b -> Int -> IO KEY192
Ptr b -> Int -> KEY192 -> IO ()
Ptr KEY192 -> IO KEY192
Ptr KEY192 -> Int -> IO KEY192
Ptr KEY192 -> Int -> KEY192 -> IO ()
Ptr KEY192 -> KEY192 -> IO ()
KEY192 -> Int
(KEY192 -> Int)
-> (KEY192 -> Int)
-> (Ptr KEY192 -> Int -> IO KEY192)
-> (Ptr KEY192 -> Int -> KEY192 -> IO ())
-> (forall b. Ptr b -> Int -> IO KEY192)
-> (forall b. Ptr b -> Int -> KEY192 -> IO ())
-> (Ptr KEY192 -> IO KEY192)
-> (Ptr KEY192 -> KEY192 -> IO ())
-> Storable KEY192
forall b. Ptr b -> Int -> IO KEY192
forall b. Ptr b -> Int -> KEY192 -> 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
poke :: Ptr KEY192 -> KEY192 -> IO ()
$cpoke :: Ptr KEY192 -> KEY192 -> IO ()
peek :: Ptr KEY192 -> IO KEY192
$cpeek :: Ptr KEY192 -> IO KEY192
pokeByteOff :: Ptr b -> Int -> KEY192 -> IO ()
$cpokeByteOff :: forall b. Ptr b -> Int -> KEY192 -> IO ()
peekByteOff :: Ptr b -> Int -> IO KEY192
$cpeekByteOff :: forall b. Ptr b -> Int -> IO KEY192
pokeElemOff :: Ptr KEY192 -> Int -> KEY192 -> IO ()
$cpokeElemOff :: Ptr KEY192 -> Int -> KEY192 -> IO ()
peekElemOff :: Ptr KEY192 -> Int -> IO KEY192
$cpeekElemOff :: Ptr KEY192 -> Int -> IO KEY192
alignment :: KEY192 -> Int
$calignment :: KEY192 -> Int
sizeOf :: KEY192 -> Int
$csizeOf :: KEY192 -> Int
Storable, Storable KEY192
Ptr KEY192 -> IO KEY192
Ptr KEY192 -> Int -> IO ()
Ptr KEY192 -> KEY192 -> IO ()
Storable KEY192
-> (Ptr KEY192 -> KEY192 -> IO ())
-> (Ptr KEY192 -> IO KEY192)
-> (Ptr KEY192 -> Int -> IO ())
-> EndianStore KEY192
forall w.
Storable w
-> (Ptr w -> w -> IO ())
-> (Ptr w -> IO w)
-> (Ptr w -> Int -> IO ())
-> EndianStore w
adjustEndian :: Ptr KEY192 -> Int -> IO ()
$cadjustEndian :: Ptr KEY192 -> Int -> IO ()
load :: Ptr KEY192 -> IO KEY192
$cload :: Ptr KEY192 -> IO KEY192
store :: Ptr KEY192 -> KEY192 -> IO ()
$cstore :: Ptr KEY192 -> KEY192 -> IO ()
$cp1EndianStore :: Storable KEY192
EndianStore)

-- | Key used for AES-128
newtype KEY256  = KEY256  (TUPLE 8)  deriving (Ptr b -> Int -> IO KEY256
Ptr b -> Int -> KEY256 -> IO ()
Ptr KEY256 -> IO KEY256
Ptr KEY256 -> Int -> IO KEY256
Ptr KEY256 -> Int -> KEY256 -> IO ()
Ptr KEY256 -> KEY256 -> IO ()
KEY256 -> Int
(KEY256 -> Int)
-> (KEY256 -> Int)
-> (Ptr KEY256 -> Int -> IO KEY256)
-> (Ptr KEY256 -> Int -> KEY256 -> IO ())
-> (forall b. Ptr b -> Int -> IO KEY256)
-> (forall b. Ptr b -> Int -> KEY256 -> IO ())
-> (Ptr KEY256 -> IO KEY256)
-> (Ptr KEY256 -> KEY256 -> IO ())
-> Storable KEY256
forall b. Ptr b -> Int -> IO KEY256
forall b. Ptr b -> Int -> KEY256 -> 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
poke :: Ptr KEY256 -> KEY256 -> IO ()
$cpoke :: Ptr KEY256 -> KEY256 -> IO ()
peek :: Ptr KEY256 -> IO KEY256
$cpeek :: Ptr KEY256 -> IO KEY256
pokeByteOff :: Ptr b -> Int -> KEY256 -> IO ()
$cpokeByteOff :: forall b. Ptr b -> Int -> KEY256 -> IO ()
peekByteOff :: Ptr b -> Int -> IO KEY256
$cpeekByteOff :: forall b. Ptr b -> Int -> IO KEY256
pokeElemOff :: Ptr KEY256 -> Int -> KEY256 -> IO ()
$cpokeElemOff :: Ptr KEY256 -> Int -> KEY256 -> IO ()
peekElemOff :: Ptr KEY256 -> Int -> IO KEY256
$cpeekElemOff :: Ptr KEY256 -> Int -> IO KEY256
alignment :: KEY256 -> Int
$calignment :: KEY256 -> Int
sizeOf :: KEY256 -> Int
$csizeOf :: KEY256 -> Int
Storable, Storable KEY256
Ptr KEY256 -> IO KEY256
Ptr KEY256 -> Int -> IO ()
Ptr KEY256 -> KEY256 -> IO ()
Storable KEY256
-> (Ptr KEY256 -> KEY256 -> IO ())
-> (Ptr KEY256 -> IO KEY256)
-> (Ptr KEY256 -> Int -> IO ())
-> EndianStore KEY256
forall w.
Storable w
-> (Ptr w -> w -> IO ())
-> (Ptr w -> IO w)
-> (Ptr w -> Int -> IO ())
-> EndianStore w
adjustEndian :: Ptr KEY256 -> Int -> IO ()
$cadjustEndian :: Ptr KEY256 -> Int -> IO ()
load :: Ptr KEY256 -> IO KEY256
$cload :: Ptr KEY256 -> IO KEY256
store :: Ptr KEY256 -> KEY256 -> IO ()
$cstore :: Ptr KEY256 -> KEY256 -> IO ()
$cp1EndianStore :: Storable KEY256
EndianStore)

instance Encodable KEY128
instance Encodable KEY192
instance Encodable KEY256

instance RandomStorable KEY128 where
  fillRandomElements :: Int -> Ptr KEY128 -> RT mem ()
fillRandomElements = Int -> Ptr KEY128 -> RT mem ()
forall mem a. (Memory mem, Storable a) => Int -> Ptr a -> RT mem ()
unsafeFillRandomElements


instance RandomStorable KEY192 where
  fillRandomElements :: Int -> Ptr KEY192 -> RT mem ()
fillRandomElements = Int -> Ptr KEY192 -> RT mem ()
forall mem a. (Memory mem, Storable a) => Int -> Ptr a -> RT mem ()
unsafeFillRandomElements

instance RandomStorable KEY256 where
  fillRandomElements :: Int -> Ptr KEY256 -> RT mem ()
fillRandomElements = Int -> Ptr KEY256 -> RT mem ()
forall mem a. (Memory mem, Storable a) => Int -> Ptr a -> RT mem ()
unsafeFillRandomElements

-- | Expects in base 16
instance IsString KEY128 where
  fromString :: String -> KEY128
fromString = String -> KEY128
forall a. Encodable a => String -> a
fromBase16

-- | Shows in base 16
instance Show KEY128 where
  show :: KEY128 -> String
show = KEY128 -> String
forall a. Encodable a => a -> String
showBase16

-- | Expects in  base 16
instance IsString KEY192 where
  fromString :: String -> KEY192
fromString = String -> KEY192
forall a. Encodable a => String -> a
fromBase16

-- | Shows in base 16
instance Show KEY192 where
  show :: KEY192 -> String
show = KEY192 -> String
forall a. Encodable a => a -> String
showBase16

-- | Expects in base 16
instance IsString KEY256 where
  fromString :: String -> KEY256
fromString = String -> KEY256
forall a. Encodable a => String -> a
fromBase16

-- | Shows in base 16
instance Show KEY256 where
  show :: KEY256 -> String
show = KEY256 -> String
forall a. Encodable a => a -> String
showBase16

--------------- AES CBC ---------------------------------

-- | The IV used by the CBC mode.
newtype IV  = IV (TUPLE 4) deriving (Ptr b -> Int -> IO IV
Ptr b -> Int -> IV -> IO ()
Ptr IV -> IO IV
Ptr IV -> Int -> IO IV
Ptr IV -> Int -> IV -> IO ()
Ptr IV -> IV -> IO ()
IV -> Int
(IV -> Int)
-> (IV -> Int)
-> (Ptr IV -> Int -> IO IV)
-> (Ptr IV -> Int -> IV -> IO ())
-> (forall b. Ptr b -> Int -> IO IV)
-> (forall b. Ptr b -> Int -> IV -> IO ())
-> (Ptr IV -> IO IV)
-> (Ptr IV -> IV -> IO ())
-> Storable IV
forall b. Ptr b -> Int -> IO IV
forall b. Ptr b -> Int -> IV -> 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
poke :: Ptr IV -> IV -> IO ()
$cpoke :: Ptr IV -> IV -> IO ()
peek :: Ptr IV -> IO IV
$cpeek :: Ptr IV -> IO IV
pokeByteOff :: Ptr b -> Int -> IV -> IO ()
$cpokeByteOff :: forall b. Ptr b -> Int -> IV -> IO ()
peekByteOff :: Ptr b -> Int -> IO IV
$cpeekByteOff :: forall b. Ptr b -> Int -> IO IV
pokeElemOff :: Ptr IV -> Int -> IV -> IO ()
$cpokeElemOff :: Ptr IV -> Int -> IV -> IO ()
peekElemOff :: Ptr IV -> Int -> IO IV
$cpeekElemOff :: Ptr IV -> Int -> IO IV
alignment :: IV -> Int
$calignment :: IV -> Int
sizeOf :: IV -> Int
$csizeOf :: IV -> Int
Storable, Storable IV
Ptr IV -> IO IV
Ptr IV -> Int -> IO ()
Ptr IV -> IV -> IO ()
Storable IV
-> (Ptr IV -> IV -> IO ())
-> (Ptr IV -> IO IV)
-> (Ptr IV -> Int -> IO ())
-> EndianStore IV
forall w.
Storable w
-> (Ptr w -> w -> IO ())
-> (Ptr w -> IO w)
-> (Ptr w -> Int -> IO ())
-> EndianStore w
adjustEndian :: Ptr IV -> Int -> IO ()
$cadjustEndian :: Ptr IV -> Int -> IO ()
load :: Ptr IV -> IO IV
$cload :: Ptr IV -> IO IV
store :: Ptr IV -> IV -> IO ()
$cstore :: Ptr IV -> IV -> IO ()
$cp1EndianStore :: Storable IV
EndianStore)

instance Encodable IV

instance RandomStorable IV where
  fillRandomElements :: Int -> Ptr IV -> RT mem ()
fillRandomElements = Int -> Ptr IV -> RT mem ()
forall mem a. (Memory mem, Storable a) => Int -> Ptr a -> RT mem ()
unsafeFillRandomElements

-- | Expects in base16.
instance IsString IV where
  fromString :: String -> IV
fromString = String -> IV
forall a. Encodable a => String -> a
fromBase16

-- | Shown as a its base16 encoding.
instance Show IV where
  show :: IV -> String
show = IV -> String
forall a. Encodable a => a -> String
showBase16

----------------- AES 128 CBC ------------------------------

-- | 128-bit aes cipher in `CBC` mode.
aes128cbc :: AES 128 'CBC
aes128cbc :: AES 128 'CBC
aes128cbc = AES 128 'CBC
forall (n :: Nat) (mode :: CipherMode). AES n mode
AES

-- | The 128-bit aes cipher in cbc mode.
instance Primitive (AES 128 'CBC) where
  blockSize :: AES 128 'CBC -> BYTES Int
blockSize AES 128 'CBC
_ = Int -> BYTES Int
forall a. a -> BYTES a
BYTES Int
16
  type Implementation (AES 128 'CBC) = SomeCipherI (AES 128 'CBC)

-- | Key is @(`KEY128`,`IV`)@ pair.
type instance Key (AES 128 'CBC) = (KEY128,IV)

instance Describable (AES 128 'CBC) where
  name :: AES 128 'CBC -> String
name AES 128 'CBC
_ = String
"aes-128-cbc"
  description :: AES 128 'CBC -> String
description AES 128 'CBC
_ = String
"The AES cipher in CBC mode with 128-bit key"

instance Cipher (AES 128 'CBC)

----------------- AES 192 CBC --------------------------------

-- | 128-bit aes cipher in `CBC` mode.
aes192cbc :: AES 192 'CBC
aes192cbc :: AES 192 'CBC
aes192cbc = AES 192 'CBC
forall (n :: Nat) (mode :: CipherMode). AES n mode
AES

-- | The 192-bit aes cipher in cbc mode.
instance Primitive (AES 192 'CBC) where
  blockSize :: AES 192 'CBC -> BYTES Int
blockSize AES 192 'CBC
_ = Int -> BYTES Int
forall a. a -> BYTES a
BYTES Int
16
  type Implementation (AES 192 'CBC) = SomeCipherI (AES 192 'CBC)

-- | Key is @(`KEY192`,`IV`)@ pair.
type instance Key (AES 192 'CBC) = (KEY192,IV)

instance Describable (AES 192 'CBC) where
  name :: AES 192 'CBC -> String
name AES 192 'CBC
_ = String
"aes-192-cbc"
  description :: AES 192 'CBC -> String
description AES 192 'CBC
_ = String
"The AES cipher in CBC mode with 192-bit key"

instance Cipher (AES 192 'CBC)

------------------- AES 256 CBC -----------------------------

-- | 128-bit aes cipher in `CBC` mode.
aes256cbc :: AES 256 'CBC
aes256cbc :: AES 256 'CBC
aes256cbc = AES 256 'CBC
forall (n :: Nat) (mode :: CipherMode). AES n mode
AES

-- | The 256-bit aes cipher in cbc mode.
instance Primitive (AES 256 'CBC) where
  blockSize :: AES 256 'CBC -> BYTES Int
blockSize AES 256 'CBC
_ = Int -> BYTES Int
forall a. a -> BYTES a
BYTES Int
16
  type Implementation (AES 256 'CBC) = SomeCipherI (AES 256 'CBC)

-- | Key is @(`KEY256`,`IV`)@ pair.
type instance Key (AES 256 'CBC) = (KEY256,IV)


instance Describable (AES 256 'CBC) where
  name :: AES 256 'CBC -> String
name AES 256 'CBC
_ = String
"aes-256-cbc"
  description :: AES 256 'CBC -> String
description AES 256 'CBC
_ = String
"The AES cipher in CBC mode with 256-bit key"

instance Cipher (AES 256 'CBC)


------------------- AES CTR mode ---------------------------

-- | Smart constructors for AES 128 ctr.
aes128ctr :: AES 128 'CTR
aes128ctr :: AES 128 'CTR
aes128ctr = AES 128 'CTR
forall (n :: Nat) (mode :: CipherMode). AES n mode
AES

--------------  Memory for storing extended keys ---------

-- | Extended key for aes128
newtype EKEY128 = EKEY128 (TUPLE 44) deriving (Ptr b -> Int -> IO EKEY128
Ptr b -> Int -> EKEY128 -> IO ()
Ptr EKEY128 -> IO EKEY128
Ptr EKEY128 -> Int -> IO EKEY128
Ptr EKEY128 -> Int -> EKEY128 -> IO ()
Ptr EKEY128 -> EKEY128 -> IO ()
EKEY128 -> Int
(EKEY128 -> Int)
-> (EKEY128 -> Int)
-> (Ptr EKEY128 -> Int -> IO EKEY128)
-> (Ptr EKEY128 -> Int -> EKEY128 -> IO ())
-> (forall b. Ptr b -> Int -> IO EKEY128)
-> (forall b. Ptr b -> Int -> EKEY128 -> IO ())
-> (Ptr EKEY128 -> IO EKEY128)
-> (Ptr EKEY128 -> EKEY128 -> IO ())
-> Storable EKEY128
forall b. Ptr b -> Int -> IO EKEY128
forall b. Ptr b -> Int -> EKEY128 -> 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
poke :: Ptr EKEY128 -> EKEY128 -> IO ()
$cpoke :: Ptr EKEY128 -> EKEY128 -> IO ()
peek :: Ptr EKEY128 -> IO EKEY128
$cpeek :: Ptr EKEY128 -> IO EKEY128
pokeByteOff :: Ptr b -> Int -> EKEY128 -> IO ()
$cpokeByteOff :: forall b. Ptr b -> Int -> EKEY128 -> IO ()
peekByteOff :: Ptr b -> Int -> IO EKEY128
$cpeekByteOff :: forall b. Ptr b -> Int -> IO EKEY128
pokeElemOff :: Ptr EKEY128 -> Int -> EKEY128 -> IO ()
$cpokeElemOff :: Ptr EKEY128 -> Int -> EKEY128 -> IO ()
peekElemOff :: Ptr EKEY128 -> Int -> IO EKEY128
$cpeekElemOff :: Ptr EKEY128 -> Int -> IO EKEY128
alignment :: EKEY128 -> Int
$calignment :: EKEY128 -> Int
sizeOf :: EKEY128 -> Int
$csizeOf :: EKEY128 -> Int
Storable, Storable EKEY128
Ptr EKEY128 -> IO EKEY128
Ptr EKEY128 -> Int -> IO ()
Ptr EKEY128 -> EKEY128 -> IO ()
Storable EKEY128
-> (Ptr EKEY128 -> EKEY128 -> IO ())
-> (Ptr EKEY128 -> IO EKEY128)
-> (Ptr EKEY128 -> Int -> IO ())
-> EndianStore EKEY128
forall w.
Storable w
-> (Ptr w -> w -> IO ())
-> (Ptr w -> IO w)
-> (Ptr w -> Int -> IO ())
-> EndianStore w
adjustEndian :: Ptr EKEY128 -> Int -> IO ()
$cadjustEndian :: Ptr EKEY128 -> Int -> IO ()
load :: Ptr EKEY128 -> IO EKEY128
$cload :: Ptr EKEY128 -> IO EKEY128
store :: Ptr EKEY128 -> EKEY128 -> IO ()
$cstore :: Ptr EKEY128 -> EKEY128 -> IO ()
$cp1EndianStore :: Storable EKEY128
EndianStore)
-- | Extended key for aes192
newtype EKEY192 = EKEY192 (TUPLE 52) deriving (Ptr b -> Int -> IO EKEY192
Ptr b -> Int -> EKEY192 -> IO ()
Ptr EKEY192 -> IO EKEY192
Ptr EKEY192 -> Int -> IO EKEY192
Ptr EKEY192 -> Int -> EKEY192 -> IO ()
Ptr EKEY192 -> EKEY192 -> IO ()
EKEY192 -> Int
(EKEY192 -> Int)
-> (EKEY192 -> Int)
-> (Ptr EKEY192 -> Int -> IO EKEY192)
-> (Ptr EKEY192 -> Int -> EKEY192 -> IO ())
-> (forall b. Ptr b -> Int -> IO EKEY192)
-> (forall b. Ptr b -> Int -> EKEY192 -> IO ())
-> (Ptr EKEY192 -> IO EKEY192)
-> (Ptr EKEY192 -> EKEY192 -> IO ())
-> Storable EKEY192
forall b. Ptr b -> Int -> IO EKEY192
forall b. Ptr b -> Int -> EKEY192 -> 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
poke :: Ptr EKEY192 -> EKEY192 -> IO ()
$cpoke :: Ptr EKEY192 -> EKEY192 -> IO ()
peek :: Ptr EKEY192 -> IO EKEY192
$cpeek :: Ptr EKEY192 -> IO EKEY192
pokeByteOff :: Ptr b -> Int -> EKEY192 -> IO ()
$cpokeByteOff :: forall b. Ptr b -> Int -> EKEY192 -> IO ()
peekByteOff :: Ptr b -> Int -> IO EKEY192
$cpeekByteOff :: forall b. Ptr b -> Int -> IO EKEY192
pokeElemOff :: Ptr EKEY192 -> Int -> EKEY192 -> IO ()
$cpokeElemOff :: Ptr EKEY192 -> Int -> EKEY192 -> IO ()
peekElemOff :: Ptr EKEY192 -> Int -> IO EKEY192
$cpeekElemOff :: Ptr EKEY192 -> Int -> IO EKEY192
alignment :: EKEY192 -> Int
$calignment :: EKEY192 -> Int
sizeOf :: EKEY192 -> Int
$csizeOf :: EKEY192 -> Int
Storable, Storable EKEY192
Ptr EKEY192 -> IO EKEY192
Ptr EKEY192 -> Int -> IO ()
Ptr EKEY192 -> EKEY192 -> IO ()
Storable EKEY192
-> (Ptr EKEY192 -> EKEY192 -> IO ())
-> (Ptr EKEY192 -> IO EKEY192)
-> (Ptr EKEY192 -> Int -> IO ())
-> EndianStore EKEY192
forall w.
Storable w
-> (Ptr w -> w -> IO ())
-> (Ptr w -> IO w)
-> (Ptr w -> Int -> IO ())
-> EndianStore w
adjustEndian :: Ptr EKEY192 -> Int -> IO ()
$cadjustEndian :: Ptr EKEY192 -> Int -> IO ()
load :: Ptr EKEY192 -> IO EKEY192
$cload :: Ptr EKEY192 -> IO EKEY192
store :: Ptr EKEY192 -> EKEY192 -> IO ()
$cstore :: Ptr EKEY192 -> EKEY192 -> IO ()
$cp1EndianStore :: Storable EKEY192
EndianStore)

-- | Extended key for aes256
newtype EKEY256 = EKEY256 (TUPLE 60) deriving (Ptr b -> Int -> IO EKEY256
Ptr b -> Int -> EKEY256 -> IO ()
Ptr EKEY256 -> IO EKEY256
Ptr EKEY256 -> Int -> IO EKEY256
Ptr EKEY256 -> Int -> EKEY256 -> IO ()
Ptr EKEY256 -> EKEY256 -> IO ()
EKEY256 -> Int
(EKEY256 -> Int)
-> (EKEY256 -> Int)
-> (Ptr EKEY256 -> Int -> IO EKEY256)
-> (Ptr EKEY256 -> Int -> EKEY256 -> IO ())
-> (forall b. Ptr b -> Int -> IO EKEY256)
-> (forall b. Ptr b -> Int -> EKEY256 -> IO ())
-> (Ptr EKEY256 -> IO EKEY256)
-> (Ptr EKEY256 -> EKEY256 -> IO ())
-> Storable EKEY256
forall b. Ptr b -> Int -> IO EKEY256
forall b. Ptr b -> Int -> EKEY256 -> 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
poke :: Ptr EKEY256 -> EKEY256 -> IO ()
$cpoke :: Ptr EKEY256 -> EKEY256 -> IO ()
peek :: Ptr EKEY256 -> IO EKEY256
$cpeek :: Ptr EKEY256 -> IO EKEY256
pokeByteOff :: Ptr b -> Int -> EKEY256 -> IO ()
$cpokeByteOff :: forall b. Ptr b -> Int -> EKEY256 -> IO ()
peekByteOff :: Ptr b -> Int -> IO EKEY256
$cpeekByteOff :: forall b. Ptr b -> Int -> IO EKEY256
pokeElemOff :: Ptr EKEY256 -> Int -> EKEY256 -> IO ()
$cpokeElemOff :: Ptr EKEY256 -> Int -> EKEY256 -> IO ()
peekElemOff :: Ptr EKEY256 -> Int -> IO EKEY256
$cpeekElemOff :: Ptr EKEY256 -> Int -> IO EKEY256
alignment :: EKEY256 -> Int
$calignment :: EKEY256 -> Int
sizeOf :: EKEY256 -> Int
$csizeOf :: EKEY256 -> Int
Storable, Storable EKEY256
Ptr EKEY256 -> IO EKEY256
Ptr EKEY256 -> Int -> IO ()
Ptr EKEY256 -> EKEY256 -> IO ()
Storable EKEY256
-> (Ptr EKEY256 -> EKEY256 -> IO ())
-> (Ptr EKEY256 -> IO EKEY256)
-> (Ptr EKEY256 -> Int -> IO ())
-> EndianStore EKEY256
forall w.
Storable w
-> (Ptr w -> w -> IO ())
-> (Ptr w -> IO w)
-> (Ptr w -> Int -> IO ())
-> EndianStore w
adjustEndian :: Ptr EKEY256 -> Int -> IO ()
$cadjustEndian :: Ptr EKEY256 -> Int -> IO ()
load :: Ptr EKEY256 -> IO EKEY256
$cload :: Ptr EKEY256 -> IO EKEY256
store :: Ptr EKEY256 -> EKEY256 -> IO ()
$cstore :: Ptr EKEY256 -> EKEY256 -> IO ()
$cp1EndianStore :: Storable EKEY256
EndianStore)

instance Initialisable (MemoryCell EKEY128) KEY128 where
  initialise :: KEY128 -> MT (MemoryCell EKEY128) ()
initialise KEY128
k = (Ptr EKEY128 -> IO ()) -> MT (MemoryCell EKEY128) ()
forall (mT :: * -> * -> *) a b.
(MemoryThread mT, Storable a) =>
(Ptr a -> IO b) -> mT (MemoryCell a) b
withCellPointer ((Ptr EKEY128 -> IO ()) -> MT (MemoryCell EKEY128) ())
-> (Ptr EKEY128 -> IO ()) -> MT (MemoryCell EKEY128) ()
forall a b. (a -> b) -> a -> b
$ KEY128 -> (Ptr EKEY128 -> IO ()) -> Ptr EKEY128 -> IO ()
forall k ekey.
Storable k =>
k -> (Ptr ekey -> IO ()) -> Ptr ekey -> IO ()
pokeAndExpand KEY128
k (Int -> Ptr EKEY128 -> IO ()
forall ekey. Int -> Ptr ekey -> IO ()
c_expand Int
4)

instance Initialisable (MemoryCell EKEY192) KEY192 where
  initialise :: KEY192 -> MT (MemoryCell EKEY192) ()
initialise KEY192
k = (Ptr EKEY192 -> IO ()) -> MT (MemoryCell EKEY192) ()
forall (mT :: * -> * -> *) a b.
(MemoryThread mT, Storable a) =>
(Ptr a -> IO b) -> mT (MemoryCell a) b
withCellPointer ((Ptr EKEY192 -> IO ()) -> MT (MemoryCell EKEY192) ())
-> (Ptr EKEY192 -> IO ()) -> MT (MemoryCell EKEY192) ()
forall a b. (a -> b) -> a -> b
$ KEY192 -> (Ptr EKEY192 -> IO ()) -> Ptr EKEY192 -> IO ()
forall k ekey.
Storable k =>
k -> (Ptr ekey -> IO ()) -> Ptr ekey -> IO ()
pokeAndExpand KEY192
k (Int -> Ptr EKEY192 -> IO ()
forall ekey. Int -> Ptr ekey -> IO ()
c_expand Int
6)

instance Initialisable (MemoryCell EKEY256) KEY256 where
  initialise :: KEY256 -> MT (MemoryCell EKEY256) ()
initialise KEY256
k = (Ptr EKEY256 -> IO ()) -> MT (MemoryCell EKEY256) ()
forall (mT :: * -> * -> *) a b.
(MemoryThread mT, Storable a) =>
(Ptr a -> IO b) -> mT (MemoryCell a) b
withCellPointer ((Ptr EKEY256 -> IO ()) -> MT (MemoryCell EKEY256) ())
-> (Ptr EKEY256 -> IO ()) -> MT (MemoryCell EKEY256) ()
forall a b. (a -> b) -> a -> b
$ KEY256 -> (Ptr EKEY256 -> IO ()) -> Ptr EKEY256 -> IO ()
forall k ekey.
Storable k =>
k -> (Ptr ekey -> IO ()) -> Ptr ekey -> IO ()
pokeAndExpand KEY256
k (Int -> Ptr EKEY256 -> IO ()
forall ekey. Int -> Ptr ekey -> IO ()
c_expand Int
8)

foreign import ccall unsafe
  "raaz/cipher/aes/common.h raazAESExpand"
  c_expand :: Int -> Ptr ekey -> IO ()

-- | Poke a key and expand it with the given routine.
pokeAndExpand :: Storable k
              => k                    -- ^ key to poke
              -> (Ptr ekey -> IO ())  -- ^ expansion algorithm
              -> Ptr ekey             -- ^ buffer pointer.
              -> IO ()
pokeAndExpand :: k -> (Ptr ekey -> IO ()) -> Ptr ekey -> IO ()
pokeAndExpand k
k Ptr ekey -> IO ()
expander Ptr ekey
ptr = Ptr k -> k -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke (Ptr ekey -> Ptr k
forall a b. Ptr a -> Ptr b
castPtr Ptr ekey
ptr) k
k IO () -> IO () -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Ptr ekey -> IO ()
expander Ptr ekey
ptr