{-# LANGUAGE ForeignFunctionInterface         #-}
{-# LANGUAGE DataKinds                        #-}
{-# LANGUAGE MultiParamTypeClasses            #-}
{-# LANGUAGE FlexibleInstances                #-}

-- | Portable C implementation of AES ciphers.
module Raaz.Cipher.AES.CBC.Implementation.CPortable
       ( aes128cbcI, aes192cbcI, aes256cbcI
       ) where

import Control.Applicative
import Control.Monad.IO.Class   ( liftIO )
import Foreign.Ptr              ( Ptr    )
import Prelude

import Raaz.Core
import Raaz.Cipher.Internal
import Raaz.Cipher.AES.Internal

------------- Memory for 128-bit cbc --------------

-- | Memory for aes-128-cbc
data M128 = M128 { M128 -> MemoryCell EKEY128
m128ekey :: MemoryCell EKEY128
                 , M128 -> MemoryCell IV
m128iv   :: MemoryCell IV
                 }

instance Memory M128  where
  memoryAlloc :: Alloc M128
memoryAlloc     = MemoryCell EKEY128 -> MemoryCell IV -> M128
M128 (MemoryCell EKEY128 -> MemoryCell IV -> M128)
-> TwistRF AllocField (BYTES Int) (MemoryCell EKEY128)
-> TwistRF AllocField (BYTES Int) (MemoryCell IV -> M128)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TwistRF AllocField (BYTES Int) (MemoryCell EKEY128)
forall m. Memory m => Alloc m
memoryAlloc TwistRF AllocField (BYTES Int) (MemoryCell IV -> M128)
-> TwistRF AllocField (BYTES Int) (MemoryCell IV) -> Alloc M128
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> TwistRF AllocField (BYTES Int) (MemoryCell IV)
forall m. Memory m => Alloc m
memoryAlloc
  unsafeToPointer :: M128 -> Pointer
unsafeToPointer = MemoryCell EKEY128 -> Pointer
forall m. Memory m => m -> Pointer
unsafeToPointer (MemoryCell EKEY128 -> Pointer)
-> (M128 -> MemoryCell EKEY128) -> M128 -> Pointer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. M128 -> MemoryCell EKEY128
m128ekey

instance Initialisable M128 (KEY128, IV) where
  initialise :: (KEY128, IV) -> MT M128 ()
initialise (KEY128
k,IV
iv) = do
    (M128 -> MemoryCell EKEY128)
-> MT (MemoryCell EKEY128) () -> MT M128 ()
forall (mT :: * -> * -> *) mem submem a.
MemoryThread mT =>
(mem -> submem) -> mT submem a -> mT mem a
onSubMemory M128 -> MemoryCell EKEY128
m128ekey (MT (MemoryCell EKEY128) () -> MT M128 ())
-> MT (MemoryCell EKEY128) () -> MT M128 ()
forall a b. (a -> b) -> a -> b
$ do KEY128 -> MT (MemoryCell EKEY128) ()
forall m v. Initialisable m v => v -> MT m ()
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
$ Int -> Ptr EKEY128 -> IO ()
forall ekey. Int -> Ptr ekey -> IO ()
c_transpose Int
11
    (M128 -> MemoryCell IV) -> MT (MemoryCell IV) () -> MT M128 ()
forall (mT :: * -> * -> *) mem submem a.
MemoryThread mT =>
(mem -> submem) -> mT submem a -> mT mem a
onSubMemory M128 -> MemoryCell IV
m128iv   (MT (MemoryCell IV) () -> MT M128 ())
-> MT (MemoryCell IV) () -> MT M128 ()
forall a b. (a -> b) -> a -> b
$ do IV -> MT (MemoryCell IV) ()
forall m v. Initialisable m v => v -> MT m ()
initialise IV
iv
                              (Ptr IV -> IO ()) -> MT (MemoryCell IV) ()
forall (mT :: * -> * -> *) a b.
(MemoryThread mT, Storable a) =>
(Ptr a -> IO b) -> mT (MemoryCell a) b
withCellPointer ((Ptr IV -> IO ()) -> MT (MemoryCell IV) ())
-> (Ptr IV -> IO ()) -> MT (MemoryCell IV) ()
forall a b. (a -> b) -> a -> b
$ Int -> Ptr IV -> IO ()
forall ekey. Int -> Ptr ekey -> IO ()
c_transpose Int
1

------------- Memory for 192-bit cbc --------------

-- | Memory for aes-192-cbc
data M192 = M192 { M192 -> MemoryCell EKEY192
m192ekey :: MemoryCell EKEY192
                 , M192 -> MemoryCell IV
m192iv   :: MemoryCell IV
                 }

instance Memory M192  where
  memoryAlloc :: Alloc M192
memoryAlloc     = MemoryCell EKEY192 -> MemoryCell IV -> M192
M192 (MemoryCell EKEY192 -> MemoryCell IV -> M192)
-> TwistRF AllocField (BYTES Int) (MemoryCell EKEY192)
-> TwistRF AllocField (BYTES Int) (MemoryCell IV -> M192)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TwistRF AllocField (BYTES Int) (MemoryCell EKEY192)
forall m. Memory m => Alloc m
memoryAlloc TwistRF AllocField (BYTES Int) (MemoryCell IV -> M192)
-> TwistRF AllocField (BYTES Int) (MemoryCell IV) -> Alloc M192
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> TwistRF AllocField (BYTES Int) (MemoryCell IV)
forall m. Memory m => Alloc m
memoryAlloc
  unsafeToPointer :: M192 -> Pointer
unsafeToPointer = MemoryCell EKEY192 -> Pointer
forall m. Memory m => m -> Pointer
unsafeToPointer (MemoryCell EKEY192 -> Pointer)
-> (M192 -> MemoryCell EKEY192) -> M192 -> Pointer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. M192 -> MemoryCell EKEY192
m192ekey

instance Initialisable M192 (KEY192, IV) where
  initialise :: (KEY192, IV) -> MT M192 ()
initialise (KEY192
k,IV
iv) = do
    (M192 -> MemoryCell EKEY192)
-> MT (MemoryCell EKEY192) () -> MT M192 ()
forall (mT :: * -> * -> *) mem submem a.
MemoryThread mT =>
(mem -> submem) -> mT submem a -> mT mem a
onSubMemory M192 -> MemoryCell EKEY192
m192ekey (MT (MemoryCell EKEY192) () -> MT M192 ())
-> MT (MemoryCell EKEY192) () -> MT M192 ()
forall a b. (a -> b) -> a -> b
$ do KEY192 -> MT (MemoryCell EKEY192) ()
forall m v. Initialisable m v => v -> MT m ()
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
$ Int -> Ptr EKEY192 -> IO ()
forall ekey. Int -> Ptr ekey -> IO ()
c_transpose Int
13
    (M192 -> MemoryCell IV) -> MT (MemoryCell IV) () -> MT M192 ()
forall (mT :: * -> * -> *) mem submem a.
MemoryThread mT =>
(mem -> submem) -> mT submem a -> mT mem a
onSubMemory M192 -> MemoryCell IV
m192iv   (MT (MemoryCell IV) () -> MT M192 ())
-> MT (MemoryCell IV) () -> MT M192 ()
forall a b. (a -> b) -> a -> b
$ do IV -> MT (MemoryCell IV) ()
forall m v. Initialisable m v => v -> MT m ()
initialise IV
iv
                              (Ptr IV -> IO ()) -> MT (MemoryCell IV) ()
forall (mT :: * -> * -> *) a b.
(MemoryThread mT, Storable a) =>
(Ptr a -> IO b) -> mT (MemoryCell a) b
withCellPointer ((Ptr IV -> IO ()) -> MT (MemoryCell IV) ())
-> (Ptr IV -> IO ()) -> MT (MemoryCell IV) ()
forall a b. (a -> b) -> a -> b
$ Int -> Ptr IV -> IO ()
forall ekey. Int -> Ptr ekey -> IO ()
c_transpose Int
1


------------- Memory for 256-bit cbc --------------

-- | Memory for aes-256-cbc
data M256 = M256 { M256 -> MemoryCell EKEY256
m256ekey :: MemoryCell EKEY256
                 , M256 -> MemoryCell IV
m256iv   :: MemoryCell IV
                 }

instance Memory M256  where
  memoryAlloc :: Alloc M256
memoryAlloc     = MemoryCell EKEY256 -> MemoryCell IV -> M256
M256 (MemoryCell EKEY256 -> MemoryCell IV -> M256)
-> TwistRF AllocField (BYTES Int) (MemoryCell EKEY256)
-> TwistRF AllocField (BYTES Int) (MemoryCell IV -> M256)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TwistRF AllocField (BYTES Int) (MemoryCell EKEY256)
forall m. Memory m => Alloc m
memoryAlloc TwistRF AllocField (BYTES Int) (MemoryCell IV -> M256)
-> TwistRF AllocField (BYTES Int) (MemoryCell IV) -> Alloc M256
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> TwistRF AllocField (BYTES Int) (MemoryCell IV)
forall m. Memory m => Alloc m
memoryAlloc
  unsafeToPointer :: M256 -> Pointer
unsafeToPointer = MemoryCell EKEY256 -> Pointer
forall m. Memory m => m -> Pointer
unsafeToPointer (MemoryCell EKEY256 -> Pointer)
-> (M256 -> MemoryCell EKEY256) -> M256 -> Pointer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. M256 -> MemoryCell EKEY256
m256ekey

instance Initialisable M256 (KEY256, IV) where
  initialise :: (KEY256, IV) -> MT M256 ()
initialise (KEY256
k,IV
iv) = do
    (M256 -> MemoryCell EKEY256)
-> MT (MemoryCell EKEY256) () -> MT M256 ()
forall (mT :: * -> * -> *) mem submem a.
MemoryThread mT =>
(mem -> submem) -> mT submem a -> mT mem a
onSubMemory M256 -> MemoryCell EKEY256
m256ekey (MT (MemoryCell EKEY256) () -> MT M256 ())
-> MT (MemoryCell EKEY256) () -> MT M256 ()
forall a b. (a -> b) -> a -> b
$ do KEY256 -> MT (MemoryCell EKEY256) ()
forall m v. Initialisable m v => v -> MT m ()
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
$ Int -> Ptr EKEY256 -> IO ()
forall ekey. Int -> Ptr ekey -> IO ()
c_transpose Int
15
    (M256 -> MemoryCell IV) -> MT (MemoryCell IV) () -> MT M256 ()
forall (mT :: * -> * -> *) mem submem a.
MemoryThread mT =>
(mem -> submem) -> mT submem a -> mT mem a
onSubMemory M256 -> MemoryCell IV
m256iv   (MT (MemoryCell IV) () -> MT M256 ())
-> MT (MemoryCell IV) () -> MT M256 ()
forall a b. (a -> b) -> a -> b
$ do IV -> MT (MemoryCell IV) ()
forall m v. Initialisable m v => v -> MT m ()
initialise IV
iv
                              (Ptr IV -> IO ()) -> MT (MemoryCell IV) ()
forall (mT :: * -> * -> *) a b.
(MemoryThread mT, Storable a) =>
(Ptr a -> IO b) -> mT (MemoryCell a) b
withCellPointer ((Ptr IV -> IO ()) -> MT (MemoryCell IV) ())
-> (Ptr IV -> IO ()) -> MT (MemoryCell IV) ()
forall a b. (a -> b) -> a -> b
$ Int -> Ptr IV -> IO ()
forall ekey. Int -> Ptr ekey -> IO ()
c_transpose Int
1

------------------- 128-bit CBC Implementation ----------------

-- | Implementation of 128-bit AES in CBC mode using Portable C.
aes128cbcI :: Implementation (AES 128 'CBC)
aes128cbcI :: Implementation (AES 128 'CBC)
aes128cbcI = CipherI (AES 128 'CBC) M128 M128 -> SomeCipherI (AES 128 'CBC)
forall cipher encMem decMem.
CipherM cipher encMem decMem =>
CipherI cipher encMem decMem -> SomeCipherI cipher
SomeCipherI CipherI (AES 128 'CBC) M128 M128
cbc128CPortable

-- | 128-bit AES in CBC mode using Portable C.
cbc128CPortable :: CipherI (AES 128 'CBC) M128 M128
cbc128CPortable :: CipherI (AES 128 'CBC) M128 M128
cbc128CPortable =
  CipherI :: forall cipher encMem decMem.
String
-> String
-> (Pointer -> BLOCKS cipher -> MT encMem ())
-> (Pointer -> BLOCKS cipher -> MT decMem ())
-> Alignment
-> CipherI cipher encMem decMem
CipherI { cipherIName :: String
cipherIName = String
"aes128cbc-cportable"
          , cipherIDescription :: String
cipherIDescription =
            String
"128-bit AES in cbc mode implemented in Portable C"
          , encryptBlocks :: Pointer -> BLOCKS (AES 128 'CBC) -> MT M128 ()
encryptBlocks = Pointer -> BLOCKS (AES 128 'CBC) -> MT M128 ()
cbc128Encrypt
          , decryptBlocks :: Pointer -> BLOCKS (AES 128 'CBC) -> MT M128 ()
decryptBlocks = Pointer -> BLOCKS (AES 128 'CBC) -> MT M128 ()
cbc128Decrypt
          , cipherStartAlignment :: Alignment
cipherStartAlignment = Alignment
wordAlignment
          }

-- | The encryption action.
cbc128Encrypt :: Pointer -> BLOCKS (AES 128 'CBC) -> MT M128 ()
cbc128Encrypt :: Pointer -> BLOCKS (AES 128 'CBC) -> MT M128 ()
cbc128Encrypt Pointer
buf BLOCKS (AES 128 'CBC)
nBlocks =
  do Ptr EKEY128
eKeyPtr <- (M128 -> MemoryCell EKEY128)
-> MT (MemoryCell EKEY128) (Ptr EKEY128) -> MT M128 (Ptr EKEY128)
forall (mT :: * -> * -> *) mem submem a.
MemoryThread mT =>
(mem -> submem) -> mT submem a -> mT mem a
onSubMemory M128 -> MemoryCell EKEY128
m128ekey MT (MemoryCell EKEY128) (Ptr EKEY128)
forall (mT :: * -> * -> *) a.
(MemoryThread mT, Storable a) =>
mT (MemoryCell a) (Ptr a)
getCellPointer
     Ptr IV
ivPtr   <- (M128 -> MemoryCell IV)
-> MT (MemoryCell IV) (Ptr IV) -> MT M128 (Ptr IV)
forall (mT :: * -> * -> *) mem submem a.
MemoryThread mT =>
(mem -> submem) -> mT submem a -> mT mem a
onSubMemory M128 -> MemoryCell IV
m128iv   MT (MemoryCell IV) (Ptr IV)
forall (mT :: * -> * -> *) a.
(MemoryThread mT, Storable a) =>
mT (MemoryCell a) (Ptr a)
getCellPointer
     IO () -> MT M128 ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> MT M128 ()) -> IO () -> MT M128 ()
forall a b. (a -> b) -> a -> b
$ Pointer -> Int -> Int -> Ptr EKEY128 -> Ptr IV -> IO ()
forall ekey iv.
Pointer -> Int -> Int -> Ptr ekey -> Ptr iv -> IO ()
c_aes_cbc_e Pointer
buf (BLOCKS (AES 128 'CBC) -> Int
forall a. Enum a => a -> Int
fromEnum BLOCKS (AES 128 'CBC)
nBlocks) Int
10 Ptr EKEY128
eKeyPtr Ptr IV
ivPtr

-- | The decryption action.
cbc128Decrypt :: Pointer -> BLOCKS (AES 128 'CBC) -> MT M128 ()
cbc128Decrypt :: Pointer -> BLOCKS (AES 128 'CBC) -> MT M128 ()
cbc128Decrypt Pointer
buf BLOCKS (AES 128 'CBC)
nBlocks =
  do Ptr EKEY128
eKeyPtr <- (M128 -> MemoryCell EKEY128)
-> MT (MemoryCell EKEY128) (Ptr EKEY128) -> MT M128 (Ptr EKEY128)
forall (mT :: * -> * -> *) mem submem a.
MemoryThread mT =>
(mem -> submem) -> mT submem a -> mT mem a
onSubMemory M128 -> MemoryCell EKEY128
m128ekey MT (MemoryCell EKEY128) (Ptr EKEY128)
forall (mT :: * -> * -> *) a.
(MemoryThread mT, Storable a) =>
mT (MemoryCell a) (Ptr a)
getCellPointer
     Ptr IV
ivPtr   <- (M128 -> MemoryCell IV)
-> MT (MemoryCell IV) (Ptr IV) -> MT M128 (Ptr IV)
forall (mT :: * -> * -> *) mem submem a.
MemoryThread mT =>
(mem -> submem) -> mT submem a -> mT mem a
onSubMemory M128 -> MemoryCell IV
m128iv   MT (MemoryCell IV) (Ptr IV)
forall (mT :: * -> * -> *) a.
(MemoryThread mT, Storable a) =>
mT (MemoryCell a) (Ptr a)
getCellPointer
     IO () -> MT M128 ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> MT M128 ()) -> IO () -> MT M128 ()
forall a b. (a -> b) -> a -> b
$ Pointer -> Int -> Int -> Ptr EKEY128 -> Ptr IV -> IO ()
forall ekey iv.
Pointer -> Int -> Int -> Ptr ekey -> Ptr iv -> IO ()
c_aes_cbc_d Pointer
buf (BLOCKS (AES 128 'CBC) -> Int
forall a. Enum a => a -> Int
fromEnum BLOCKS (AES 128 'CBC)
nBlocks) Int
10 Ptr EKEY128
eKeyPtr Ptr IV
ivPtr



------------------- 192-bit CBC Implementation ----------------

-- | Implementation of 192-bit AES in CBC mode using Portable C.
aes192cbcI :: Implementation (AES 192 'CBC)
aes192cbcI :: Implementation (AES 192 'CBC)
aes192cbcI = CipherI (AES 192 'CBC) M192 M192 -> SomeCipherI (AES 192 'CBC)
forall cipher encMem decMem.
CipherM cipher encMem decMem =>
CipherI cipher encMem decMem -> SomeCipherI cipher
SomeCipherI CipherI (AES 192 'CBC) M192 M192
cbc192CPortable

-- | 192-bit AES in CBC mode using Portable C.
cbc192CPortable :: CipherI (AES 192 'CBC) M192 M192
cbc192CPortable :: CipherI (AES 192 'CBC) M192 M192
cbc192CPortable =
  CipherI :: forall cipher encMem decMem.
String
-> String
-> (Pointer -> BLOCKS cipher -> MT encMem ())
-> (Pointer -> BLOCKS cipher -> MT decMem ())
-> Alignment
-> CipherI cipher encMem decMem
CipherI { cipherIName :: String
cipherIName = String
"aes192cbc-cportable"
          , cipherIDescription :: String
cipherIDescription =
            String
"192-bit AES in cbc mode implemented in Portable C"
          , encryptBlocks :: Pointer -> BLOCKS (AES 192 'CBC) -> MT M192 ()
encryptBlocks = Pointer -> BLOCKS (AES 192 'CBC) -> MT M192 ()
cbc192Encrypt
          , decryptBlocks :: Pointer -> BLOCKS (AES 192 'CBC) -> MT M192 ()
decryptBlocks = Pointer -> BLOCKS (AES 192 'CBC) -> MT M192 ()
cbc192Decrypt
          , cipherStartAlignment :: Alignment
cipherStartAlignment = Alignment
wordAlignment
          }

-- | The encryption action.
cbc192Encrypt :: Pointer -> BLOCKS (AES 192 'CBC) -> MT M192 ()
cbc192Encrypt :: Pointer -> BLOCKS (AES 192 'CBC) -> MT M192 ()
cbc192Encrypt Pointer
buf BLOCKS (AES 192 'CBC)
nBlocks =
  do Ptr EKEY192
eKeyPtr <- (M192 -> MemoryCell EKEY192)
-> MT (MemoryCell EKEY192) (Ptr EKEY192) -> MT M192 (Ptr EKEY192)
forall (mT :: * -> * -> *) mem submem a.
MemoryThread mT =>
(mem -> submem) -> mT submem a -> mT mem a
onSubMemory M192 -> MemoryCell EKEY192
m192ekey MT (MemoryCell EKEY192) (Ptr EKEY192)
forall (mT :: * -> * -> *) a.
(MemoryThread mT, Storable a) =>
mT (MemoryCell a) (Ptr a)
getCellPointer
     Ptr IV
ivPtr   <- (M192 -> MemoryCell IV)
-> MT (MemoryCell IV) (Ptr IV) -> MT M192 (Ptr IV)
forall (mT :: * -> * -> *) mem submem a.
MemoryThread mT =>
(mem -> submem) -> mT submem a -> mT mem a
onSubMemory M192 -> MemoryCell IV
m192iv   MT (MemoryCell IV) (Ptr IV)
forall (mT :: * -> * -> *) a.
(MemoryThread mT, Storable a) =>
mT (MemoryCell a) (Ptr a)
getCellPointer
     IO () -> MT M192 ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> MT M192 ()) -> IO () -> MT M192 ()
forall a b. (a -> b) -> a -> b
$ Pointer -> Int -> Int -> Ptr EKEY192 -> Ptr IV -> IO ()
forall ekey iv.
Pointer -> Int -> Int -> Ptr ekey -> Ptr iv -> IO ()
c_aes_cbc_e Pointer
buf (BLOCKS (AES 192 'CBC) -> Int
forall a. Enum a => a -> Int
fromEnum BLOCKS (AES 192 'CBC)
nBlocks) Int
12 Ptr EKEY192
eKeyPtr Ptr IV
ivPtr

-- | The decryption action.
cbc192Decrypt :: Pointer -> BLOCKS (AES 192 'CBC) -> MT M192 ()
cbc192Decrypt :: Pointer -> BLOCKS (AES 192 'CBC) -> MT M192 ()
cbc192Decrypt Pointer
buf BLOCKS (AES 192 'CBC)
nBlocks =
  do Ptr EKEY192
eKeyPtr <- (M192 -> MemoryCell EKEY192)
-> MT (MemoryCell EKEY192) (Ptr EKEY192) -> MT M192 (Ptr EKEY192)
forall (mT :: * -> * -> *) mem submem a.
MemoryThread mT =>
(mem -> submem) -> mT submem a -> mT mem a
onSubMemory M192 -> MemoryCell EKEY192
m192ekey MT (MemoryCell EKEY192) (Ptr EKEY192)
forall (mT :: * -> * -> *) a.
(MemoryThread mT, Storable a) =>
mT (MemoryCell a) (Ptr a)
getCellPointer
     Ptr IV
ivPtr   <- (M192 -> MemoryCell IV)
-> MT (MemoryCell IV) (Ptr IV) -> MT M192 (Ptr IV)
forall (mT :: * -> * -> *) mem submem a.
MemoryThread mT =>
(mem -> submem) -> mT submem a -> mT mem a
onSubMemory M192 -> MemoryCell IV
m192iv   MT (MemoryCell IV) (Ptr IV)
forall (mT :: * -> * -> *) a.
(MemoryThread mT, Storable a) =>
mT (MemoryCell a) (Ptr a)
getCellPointer
     IO () -> MT M192 ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> MT M192 ()) -> IO () -> MT M192 ()
forall a b. (a -> b) -> a -> b
$ Pointer -> Int -> Int -> Ptr EKEY192 -> Ptr IV -> IO ()
forall ekey iv.
Pointer -> Int -> Int -> Ptr ekey -> Ptr iv -> IO ()
c_aes_cbc_d Pointer
buf (BLOCKS (AES 192 'CBC) -> Int
forall a. Enum a => a -> Int
fromEnum BLOCKS (AES 192 'CBC)
nBlocks) Int
12 Ptr EKEY192
eKeyPtr Ptr IV
ivPtr

------------------- 256-bit CBC Implementation ----------------

-- | Implementation of 256-bit AES in CBC mode using Portable C.
aes256cbcI :: Implementation (AES 256 'CBC)
aes256cbcI :: Implementation (AES 256 'CBC)
aes256cbcI = CipherI (AES 256 'CBC) M256 M256 -> SomeCipherI (AES 256 'CBC)
forall cipher encMem decMem.
CipherM cipher encMem decMem =>
CipherI cipher encMem decMem -> SomeCipherI cipher
SomeCipherI CipherI (AES 256 'CBC) M256 M256
cbc256CPortable

-- | 256-bit AES in CBC mode using Portable C.
cbc256CPortable :: CipherI (AES 256 'CBC) M256 M256
cbc256CPortable :: CipherI (AES 256 'CBC) M256 M256
cbc256CPortable =
  CipherI :: forall cipher encMem decMem.
String
-> String
-> (Pointer -> BLOCKS cipher -> MT encMem ())
-> (Pointer -> BLOCKS cipher -> MT decMem ())
-> Alignment
-> CipherI cipher encMem decMem
CipherI { cipherIName :: String
cipherIName = String
"aes256cbc-cportable"
          , cipherIDescription :: String
cipherIDescription =
            String
"256-bit AES in cbc mode implemented in Portable C"
          , encryptBlocks :: Pointer -> BLOCKS (AES 256 'CBC) -> MT M256 ()
encryptBlocks = Pointer -> BLOCKS (AES 256 'CBC) -> MT M256 ()
cbc256Encrypt
          , decryptBlocks :: Pointer -> BLOCKS (AES 256 'CBC) -> MT M256 ()
decryptBlocks = Pointer -> BLOCKS (AES 256 'CBC) -> MT M256 ()
cbc256Decrypt
          , cipherStartAlignment :: Alignment
cipherStartAlignment = Alignment
wordAlignment

          }

-- | The encryption action.
cbc256Encrypt :: Pointer -> BLOCKS (AES 256 'CBC) -> MT M256 ()
cbc256Encrypt :: Pointer -> BLOCKS (AES 256 'CBC) -> MT M256 ()
cbc256Encrypt Pointer
buf BLOCKS (AES 256 'CBC)
nBlocks =
  do Ptr EKEY256
eKeyPtr <- (M256 -> MemoryCell EKEY256)
-> MT (MemoryCell EKEY256) (Ptr EKEY256) -> MT M256 (Ptr EKEY256)
forall (mT :: * -> * -> *) mem submem a.
MemoryThread mT =>
(mem -> submem) -> mT submem a -> mT mem a
onSubMemory M256 -> MemoryCell EKEY256
m256ekey MT (MemoryCell EKEY256) (Ptr EKEY256)
forall (mT :: * -> * -> *) a.
(MemoryThread mT, Storable a) =>
mT (MemoryCell a) (Ptr a)
getCellPointer
     Ptr IV
ivPtr   <- (M256 -> MemoryCell IV)
-> MT (MemoryCell IV) (Ptr IV) -> MT M256 (Ptr IV)
forall (mT :: * -> * -> *) mem submem a.
MemoryThread mT =>
(mem -> submem) -> mT submem a -> mT mem a
onSubMemory M256 -> MemoryCell IV
m256iv   MT (MemoryCell IV) (Ptr IV)
forall (mT :: * -> * -> *) a.
(MemoryThread mT, Storable a) =>
mT (MemoryCell a) (Ptr a)
getCellPointer
     IO () -> MT M256 ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> MT M256 ()) -> IO () -> MT M256 ()
forall a b. (a -> b) -> a -> b
$ Pointer -> Int -> Int -> Ptr EKEY256 -> Ptr IV -> IO ()
forall ekey iv.
Pointer -> Int -> Int -> Ptr ekey -> Ptr iv -> IO ()
c_aes_cbc_e Pointer
buf (BLOCKS (AES 256 'CBC) -> Int
forall a. Enum a => a -> Int
fromEnum BLOCKS (AES 256 'CBC)
nBlocks) Int
14 Ptr EKEY256
eKeyPtr Ptr IV
ivPtr

-- | The decryption action.
cbc256Decrypt :: Pointer -> BLOCKS (AES 256 'CBC) -> MT M256 ()
cbc256Decrypt :: Pointer -> BLOCKS (AES 256 'CBC) -> MT M256 ()
cbc256Decrypt Pointer
buf BLOCKS (AES 256 'CBC)
nBlocks =
  do Ptr EKEY256
eKeyPtr <- (M256 -> MemoryCell EKEY256)
-> MT (MemoryCell EKEY256) (Ptr EKEY256) -> MT M256 (Ptr EKEY256)
forall (mT :: * -> * -> *) mem submem a.
MemoryThread mT =>
(mem -> submem) -> mT submem a -> mT mem a
onSubMemory M256 -> MemoryCell EKEY256
m256ekey MT (MemoryCell EKEY256) (Ptr EKEY256)
forall (mT :: * -> * -> *) a.
(MemoryThread mT, Storable a) =>
mT (MemoryCell a) (Ptr a)
getCellPointer
     Ptr IV
ivPtr   <- (M256 -> MemoryCell IV)
-> MT (MemoryCell IV) (Ptr IV) -> MT M256 (Ptr IV)
forall (mT :: * -> * -> *) mem submem a.
MemoryThread mT =>
(mem -> submem) -> mT submem a -> mT mem a
onSubMemory M256 -> MemoryCell IV
m256iv   MT (MemoryCell IV) (Ptr IV)
forall (mT :: * -> * -> *) a.
(MemoryThread mT, Storable a) =>
mT (MemoryCell a) (Ptr a)
getCellPointer
     IO () -> MT M256 ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> MT M256 ()) -> IO () -> MT M256 ()
forall a b. (a -> b) -> a -> b
$ Pointer -> Int -> Int -> Ptr EKEY256 -> Ptr IV -> IO ()
forall ekey iv.
Pointer -> Int -> Int -> Ptr ekey -> Ptr iv -> IO ()
c_aes_cbc_d Pointer
buf (BLOCKS (AES 256 'CBC) -> Int
forall a. Enum a => a -> Int
fromEnum BLOCKS (AES 256 'CBC)
nBlocks) Int
14 Ptr EKEY256
eKeyPtr Ptr IV
ivPtr

--------------------- Foreign functions ------------------------

-- | Transpose AES matrices.
foreign import ccall unsafe
  "raaz/cipher/aes/common.h raazAESTranspose"
  c_transpose :: Int -> Ptr ekey -> IO ()


-- | CBC encrypt.
foreign import ccall unsafe
  "raaz/cipher/aes/cportable.h raazAESCBCEncryptCPortable"
  c_aes_cbc_e :: Pointer  -- Input
              -> Int      -- number of blocks
              -> Int      -- rounds
              -> Ptr ekey -- extended key
              -> Ptr iv   -- iv
              -> IO ()
-- | CBC decrypt
foreign import ccall unsafe
  "raaz/cipher/aes/cportable.h raazAESCBCDecryptCPortable"
  c_aes_cbc_d :: Pointer  -- Input
              -> Int      -- number of blocks
              -> Int      -- rounds
              -> Ptr ekey -- extened key
              -> Ptr iv  -- iv
              -> IO ()