{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Crypto.Cipher.AES.Primitive
(
AES
, AESGCM
, AESOCB
, initAES
, genCTR
, genCounter
, encryptECB
, encryptCBC
, encryptCTR
, encryptXTS
, decryptECB
, decryptCBC
, decryptCTR
, decryptXTS
, combineC32
, gcmMode
, gcmInit
, ocbMode
, ocbInit
, ccmMode
, ccmInit
) where
import Data.Word
import Foreign.Ptr
import Foreign.C.Types
import Foreign.C.String
import Crypto.Error
import Crypto.Cipher.Types
import Crypto.Cipher.Types.Block (IV(..))
import Crypto.Internal.Compat
import Crypto.Internal.Imports
import Crypto.Internal.ByteArray (ByteArray, ByteArrayAccess, ScrubbedBytes, withByteArray)
import qualified Crypto.Internal.ByteArray as B
instance Cipher AES where
cipherName :: AES -> String
cipherName AES
_ = String
"AES"
cipherKeySize :: AES -> KeySizeSpecifier
cipherKeySize AES
_ = [Int] -> KeySizeSpecifier
KeySizeEnum [Int
16,Int
24,Int
32]
cipherInit :: forall key. ByteArray key => key -> CryptoFailable AES
cipherInit key
k = forall key. ByteArrayAccess key => key -> CryptoFailable AES
initAES key
k
instance BlockCipher AES where
blockSize :: AES -> Int
blockSize AES
_ = Int
16
ecbEncrypt :: forall ba. ByteArray ba => AES -> ba -> ba
ecbEncrypt = forall ba. ByteArray ba => AES -> ba -> ba
encryptECB
ecbDecrypt :: forall ba. ByteArray ba => AES -> ba -> ba
ecbDecrypt = forall ba. ByteArray ba => AES -> ba -> ba
decryptECB
cbcEncrypt :: forall ba. ByteArray ba => AES -> IV AES -> ba -> ba
cbcEncrypt = forall ba. ByteArray ba => AES -> IV AES -> ba -> ba
encryptCBC
cbcDecrypt :: forall ba. ByteArray ba => AES -> IV AES -> ba -> ba
cbcDecrypt = forall ba. ByteArray ba => AES -> IV AES -> ba -> ba
decryptCBC
ctrCombine :: forall ba. ByteArray ba => AES -> IV AES -> ba -> ba
ctrCombine = forall ba. ByteArray ba => AES -> IV AES -> ba -> ba
encryptCTR
aeadInit :: forall iv.
ByteArrayAccess iv =>
AEADMode -> AES -> iv -> CryptoFailable (AEAD AES)
aeadInit AEADMode
AEAD_GCM AES
aes iv
iv = forall a. a -> CryptoFailable a
CryptoPassed forall a b. (a -> b) -> a -> b
$ forall cipher st. AEADModeImpl st -> st -> AEAD cipher
AEAD (AES -> AEADModeImpl AESGCM
gcmMode AES
aes) (forall iv. ByteArrayAccess iv => AES -> iv -> AESGCM
gcmInit AES
aes iv
iv)
aeadInit AEADMode
AEAD_OCB AES
aes iv
iv = forall a. a -> CryptoFailable a
CryptoPassed forall a b. (a -> b) -> a -> b
$ forall cipher st. AEADModeImpl st -> st -> AEAD cipher
AEAD (AES -> AEADModeImpl AESOCB
ocbMode AES
aes) (forall iv. ByteArrayAccess iv => AES -> iv -> AESOCB
ocbInit AES
aes iv
iv)
aeadInit (AEAD_CCM Int
n CCM_M
m CCM_L
l) AES
aes iv
iv = forall cipher st. AEADModeImpl st -> st -> AEAD cipher
AEAD (AES -> AEADModeImpl AESCCM
ccmMode AES
aes) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall iv.
ByteArrayAccess iv =>
AES -> iv -> Int -> CCM_M -> CCM_L -> CryptoFailable AESCCM
ccmInit AES
aes iv
iv Int
n CCM_M
m CCM_L
l
aeadInit AEADMode
_ AES
_ iv
_ = forall a. CryptoError -> CryptoFailable a
CryptoFailed CryptoError
CryptoError_AEADModeNotSupported
instance BlockCipher128 AES where
xtsEncrypt :: forall ba.
ByteArray ba =>
(AES, AES) -> IV AES -> DataUnitOffset -> ba -> ba
xtsEncrypt = forall ba.
ByteArray ba =>
(AES, AES) -> IV AES -> DataUnitOffset -> ba -> ba
encryptXTS
xtsDecrypt :: forall ba.
ByteArray ba =>
(AES, AES) -> IV AES -> DataUnitOffset -> ba -> ba
xtsDecrypt = forall ba.
ByteArray ba =>
(AES, AES) -> IV AES -> DataUnitOffset -> ba -> ba
decryptXTS
gcmMode :: AES -> AEADModeImpl AESGCM
gcmMode :: AES -> AEADModeImpl AESGCM
gcmMode AES
aes = AEADModeImpl
{ aeadImplAppendHeader :: forall ba. ByteArrayAccess ba => AESGCM -> ba -> AESGCM
aeadImplAppendHeader = forall ba. ByteArrayAccess ba => AESGCM -> ba -> AESGCM
gcmAppendAAD
, aeadImplEncrypt :: forall ba. ByteArray ba => AESGCM -> ba -> (ba, AESGCM)
aeadImplEncrypt = forall ba. ByteArray ba => AES -> AESGCM -> ba -> (ba, AESGCM)
gcmAppendEncrypt AES
aes
, aeadImplDecrypt :: forall ba. ByteArray ba => AESGCM -> ba -> (ba, AESGCM)
aeadImplDecrypt = forall ba. ByteArray ba => AES -> AESGCM -> ba -> (ba, AESGCM)
gcmAppendDecrypt AES
aes
, aeadImplFinalize :: AESGCM -> Int -> AuthTag
aeadImplFinalize = AES -> AESGCM -> Int -> AuthTag
gcmFinish AES
aes
}
ocbMode :: AES -> AEADModeImpl AESOCB
ocbMode :: AES -> AEADModeImpl AESOCB
ocbMode AES
aes = AEADModeImpl
{ aeadImplAppendHeader :: forall ba. ByteArrayAccess ba => AESOCB -> ba -> AESOCB
aeadImplAppendHeader = forall aad. ByteArrayAccess aad => AES -> AESOCB -> aad -> AESOCB
ocbAppendAAD AES
aes
, aeadImplEncrypt :: forall ba. ByteArray ba => AESOCB -> ba -> (ba, AESOCB)
aeadImplEncrypt = forall ba. ByteArray ba => AES -> AESOCB -> ba -> (ba, AESOCB)
ocbAppendEncrypt AES
aes
, aeadImplDecrypt :: forall ba. ByteArray ba => AESOCB -> ba -> (ba, AESOCB)
aeadImplDecrypt = forall ba. ByteArray ba => AES -> AESOCB -> ba -> (ba, AESOCB)
ocbAppendDecrypt AES
aes
, aeadImplFinalize :: AESOCB -> Int -> AuthTag
aeadImplFinalize = AES -> AESOCB -> Int -> AuthTag
ocbFinish AES
aes
}
ccmMode :: AES -> AEADModeImpl AESCCM
ccmMode :: AES -> AEADModeImpl AESCCM
ccmMode AES
aes = AEADModeImpl
{ aeadImplAppendHeader :: forall ba. ByteArrayAccess ba => AESCCM -> ba -> AESCCM
aeadImplAppendHeader = forall aad. ByteArrayAccess aad => AES -> AESCCM -> aad -> AESCCM
ccmAppendAAD AES
aes
, aeadImplEncrypt :: forall ba. ByteArray ba => AESCCM -> ba -> (ba, AESCCM)
aeadImplEncrypt = forall ba. ByteArray ba => AES -> AESCCM -> ba -> (ba, AESCCM)
ccmEncrypt AES
aes
, aeadImplDecrypt :: forall ba. ByteArray ba => AESCCM -> ba -> (ba, AESCCM)
aeadImplDecrypt = forall ba. ByteArray ba => AES -> AESCCM -> ba -> (ba, AESCCM)
ccmDecrypt AES
aes
, aeadImplFinalize :: AESCCM -> Int -> AuthTag
aeadImplFinalize = AES -> AESCCM -> Int -> AuthTag
ccmFinish AES
aes
}
newtype AES = AES ScrubbedBytes
deriving (AES -> ()
forall a. (a -> ()) -> NFData a
rnf :: AES -> ()
$crnf :: AES -> ()
NFData)
newtype AESGCM = AESGCM ScrubbedBytes
deriving (AESGCM -> ()
forall a. (a -> ()) -> NFData a
rnf :: AESGCM -> ()
$crnf :: AESGCM -> ()
NFData)
newtype AESOCB = AESOCB ScrubbedBytes
deriving (AESOCB -> ()
forall a. (a -> ()) -> NFData a
rnf :: AESOCB -> ()
$crnf :: AESOCB -> ()
NFData)
newtype AESCCM = AESCCM ScrubbedBytes
deriving (AESCCM -> ()
forall a. (a -> ()) -> NFData a
rnf :: AESCCM -> ()
$crnf :: AESCCM -> ()
NFData)
sizeGCM :: Int
sizeGCM :: Int
sizeGCM = Int
320
sizeOCB :: Int
sizeOCB :: Int
sizeOCB = Int
160
sizeCCM :: Int
sizeCCM :: Int
sizeCCM = Int
80
keyToPtr :: AES -> (Ptr AES -> IO a) -> IO a
keyToPtr :: forall a. AES -> (Ptr AES -> IO a) -> IO a
keyToPtr (AES ScrubbedBytes
b) Ptr AES -> IO a
f = forall ba p a. ByteArrayAccess ba => ba -> (Ptr p -> IO a) -> IO a
withByteArray ScrubbedBytes
b (Ptr AES -> IO a
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. Ptr a -> Ptr b
castPtr)
ivToPtr :: ByteArrayAccess iv => iv -> (Ptr Word8 -> IO a) -> IO a
ivToPtr :: forall iv a.
ByteArrayAccess iv =>
iv -> (Ptr Word8 -> IO a) -> IO a
ivToPtr iv
iv Ptr Word8 -> IO a
f = forall ba p a. ByteArrayAccess ba => ba -> (Ptr p -> IO a) -> IO a
withByteArray iv
iv (Ptr Word8 -> IO a
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. Ptr a -> Ptr b
castPtr)
ivCopyPtr :: IV AES -> (Ptr Word8 -> IO a) -> IO (a, IV AES)
ivCopyPtr :: forall a. IV AES -> (Ptr Word8 -> IO a) -> IO (a, IV AES)
ivCopyPtr (IV byteArray
iv) Ptr Word8 -> IO a
f = (\(a
x,byteArray
y) -> (a
x, forall c byteArray. ByteArray byteArray => byteArray -> IV c
IV byteArray
y)) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` forall ba a.
ByteArray ba =>
ba -> (Ptr Word8 -> IO a) -> IO (a, ba)
copyAndModify byteArray
iv Ptr Word8 -> IO a
f
where
copyAndModify :: ByteArray ba => ba -> (Ptr Word8 -> IO a) -> IO (a, ba)
copyAndModify :: forall ba a.
ByteArray ba =>
ba -> (Ptr Word8 -> IO a) -> IO (a, ba)
copyAndModify ba
ba Ptr Word8 -> IO a
f' = forall bs1 bs2 p a.
(ByteArrayAccess bs1, ByteArray bs2) =>
bs1 -> (Ptr p -> IO a) -> IO (a, bs2)
B.copyRet ba
ba Ptr Word8 -> IO a
f'
withKeyAndIV :: ByteArrayAccess iv => AES -> iv -> (Ptr AES -> Ptr Word8 -> IO a) -> IO a
withKeyAndIV :: forall iv a.
ByteArrayAccess iv =>
AES -> iv -> (Ptr AES -> Ptr Word8 -> IO a) -> IO a
withKeyAndIV AES
ctx iv
iv Ptr AES -> Ptr Word8 -> IO a
f = forall a. AES -> (Ptr AES -> IO a) -> IO a
keyToPtr AES
ctx forall a b. (a -> b) -> a -> b
$ \Ptr AES
kptr -> forall iv a.
ByteArrayAccess iv =>
iv -> (Ptr Word8 -> IO a) -> IO a
ivToPtr iv
iv forall a b. (a -> b) -> a -> b
$ \Ptr Word8
ivp -> Ptr AES -> Ptr Word8 -> IO a
f Ptr AES
kptr Ptr Word8
ivp
withKey2AndIV :: ByteArrayAccess iv => AES -> AES -> iv -> (Ptr AES -> Ptr AES -> Ptr Word8 -> IO a) -> IO a
withKey2AndIV :: forall iv a.
ByteArrayAccess iv =>
AES
-> AES -> iv -> (Ptr AES -> Ptr AES -> Ptr Word8 -> IO a) -> IO a
withKey2AndIV AES
key1 AES
key2 iv
iv Ptr AES -> Ptr AES -> Ptr Word8 -> IO a
f =
forall a. AES -> (Ptr AES -> IO a) -> IO a
keyToPtr AES
key1 forall a b. (a -> b) -> a -> b
$ \Ptr AES
kptr1 -> forall a. AES -> (Ptr AES -> IO a) -> IO a
keyToPtr AES
key2 forall a b. (a -> b) -> a -> b
$ \Ptr AES
kptr2 -> forall iv a.
ByteArrayAccess iv =>
iv -> (Ptr Word8 -> IO a) -> IO a
ivToPtr iv
iv forall a b. (a -> b) -> a -> b
$ \Ptr Word8
ivp -> Ptr AES -> Ptr AES -> Ptr Word8 -> IO a
f Ptr AES
kptr1 Ptr AES
kptr2 Ptr Word8
ivp
withGCMKeyAndCopySt :: AES -> AESGCM -> (Ptr AESGCM -> Ptr AES -> IO a) -> IO (a, AESGCM)
withGCMKeyAndCopySt :: forall a.
AES -> AESGCM -> (Ptr AESGCM -> Ptr AES -> IO a) -> IO (a, AESGCM)
withGCMKeyAndCopySt AES
aes (AESGCM ScrubbedBytes
gcmSt) Ptr AESGCM -> Ptr AES -> IO a
f =
forall a. AES -> (Ptr AES -> IO a) -> IO a
keyToPtr AES
aes forall a b. (a -> b) -> a -> b
$ \Ptr AES
aesPtr -> do
ScrubbedBytes
newSt <- forall bs1 bs2 p.
(ByteArrayAccess bs1, ByteArray bs2) =>
bs1 -> (Ptr p -> IO ()) -> IO bs2
B.copy ScrubbedBytes
gcmSt (\Ptr Any
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return ())
a
a <- forall ba p a. ByteArrayAccess ba => ba -> (Ptr p -> IO a) -> IO a
withByteArray ScrubbedBytes
newSt forall a b. (a -> b) -> a -> b
$ \Ptr Any
gcmStPtr -> Ptr AESGCM -> Ptr AES -> IO a
f (forall a b. Ptr a -> Ptr b
castPtr Ptr Any
gcmStPtr) Ptr AES
aesPtr
forall (m :: * -> *) a. Monad m => a -> m a
return (a
a, ScrubbedBytes -> AESGCM
AESGCM ScrubbedBytes
newSt)
withNewGCMSt :: AESGCM -> (Ptr AESGCM -> IO ()) -> IO AESGCM
withNewGCMSt :: AESGCM -> (Ptr AESGCM -> IO ()) -> IO AESGCM
withNewGCMSt (AESGCM ScrubbedBytes
gcmSt) Ptr AESGCM -> IO ()
f = forall bs1 bs2 p.
(ByteArrayAccess bs1, ByteArray bs2) =>
bs1 -> (Ptr p -> IO ()) -> IO bs2
B.copy ScrubbedBytes
gcmSt (Ptr AESGCM -> IO ()
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. Ptr a -> Ptr b
castPtr) forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \ScrubbedBytes
sm2 -> forall (m :: * -> *) a. Monad m => a -> m a
return (ScrubbedBytes -> AESGCM
AESGCM ScrubbedBytes
sm2)
withOCBKeyAndCopySt :: AES -> AESOCB -> (Ptr AESOCB -> Ptr AES -> IO a) -> IO (a, AESOCB)
withOCBKeyAndCopySt :: forall a.
AES -> AESOCB -> (Ptr AESOCB -> Ptr AES -> IO a) -> IO (a, AESOCB)
withOCBKeyAndCopySt AES
aes (AESOCB ScrubbedBytes
gcmSt) Ptr AESOCB -> Ptr AES -> IO a
f =
forall a. AES -> (Ptr AES -> IO a) -> IO a
keyToPtr AES
aes forall a b. (a -> b) -> a -> b
$ \Ptr AES
aesPtr -> do
ScrubbedBytes
newSt <- forall bs1 bs2 p.
(ByteArrayAccess bs1, ByteArray bs2) =>
bs1 -> (Ptr p -> IO ()) -> IO bs2
B.copy ScrubbedBytes
gcmSt (\Ptr Any
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return ())
a
a <- forall ba p a. ByteArrayAccess ba => ba -> (Ptr p -> IO a) -> IO a
withByteArray ScrubbedBytes
newSt forall a b. (a -> b) -> a -> b
$ \Ptr Any
gcmStPtr -> Ptr AESOCB -> Ptr AES -> IO a
f (forall a b. Ptr a -> Ptr b
castPtr Ptr Any
gcmStPtr) Ptr AES
aesPtr
forall (m :: * -> *) a. Monad m => a -> m a
return (a
a, ScrubbedBytes -> AESOCB
AESOCB ScrubbedBytes
newSt)
withCCMKeyAndCopySt :: AES -> AESCCM -> (Ptr AESCCM -> Ptr AES -> IO a) -> IO (a, AESCCM)
withCCMKeyAndCopySt :: forall a.
AES -> AESCCM -> (Ptr AESCCM -> Ptr AES -> IO a) -> IO (a, AESCCM)
withCCMKeyAndCopySt AES
aes (AESCCM ScrubbedBytes
ccmSt) Ptr AESCCM -> Ptr AES -> IO a
f =
forall a. AES -> (Ptr AES -> IO a) -> IO a
keyToPtr AES
aes forall a b. (a -> b) -> a -> b
$ \Ptr AES
aesPtr -> do
ScrubbedBytes
newSt <- forall bs1 bs2 p.
(ByteArrayAccess bs1, ByteArray bs2) =>
bs1 -> (Ptr p -> IO ()) -> IO bs2
B.copy ScrubbedBytes
ccmSt (\Ptr Any
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return ())
a
a <- forall ba p a. ByteArrayAccess ba => ba -> (Ptr p -> IO a) -> IO a
withByteArray ScrubbedBytes
newSt forall a b. (a -> b) -> a -> b
$ \Ptr Any
ccmStPtr -> Ptr AESCCM -> Ptr AES -> IO a
f (forall a b. Ptr a -> Ptr b
castPtr Ptr Any
ccmStPtr) Ptr AES
aesPtr
forall (m :: * -> *) a. Monad m => a -> m a
return (a
a, ScrubbedBytes -> AESCCM
AESCCM ScrubbedBytes
newSt)
initAES :: ByteArrayAccess key => key -> CryptoFailable AES
initAES :: forall key. ByteArrayAccess key => key -> CryptoFailable AES
initAES key
k
| Int
len forall a. Eq a => a -> a -> Bool
== Int
16 = forall a. a -> CryptoFailable a
CryptoPassed forall a b. (a -> b) -> a -> b
$ Int -> AES
initWithRounds Int
10
| Int
len forall a. Eq a => a -> a -> Bool
== Int
24 = forall a. a -> CryptoFailable a
CryptoPassed forall a b. (a -> b) -> a -> b
$ Int -> AES
initWithRounds Int
12
| Int
len forall a. Eq a => a -> a -> Bool
== Int
32 = forall a. a -> CryptoFailable a
CryptoPassed forall a b. (a -> b) -> a -> b
$ Int -> AES
initWithRounds Int
14
| Bool
otherwise = forall a. CryptoError -> CryptoFailable a
CryptoFailed CryptoError
CryptoError_KeySizeInvalid
where len :: Int
len = forall ba. ByteArrayAccess ba => ba -> Int
B.length key
k
initWithRounds :: Int -> AES
initWithRounds Int
nbR = ScrubbedBytes -> AES
AES forall a b. (a -> b) -> a -> b
$ forall a p. ByteArray a => Int -> (Ptr p -> IO ()) -> a
B.allocAndFreeze (Int
16forall a. Num a => a -> a -> a
+Int
2forall a. Num a => a -> a -> a
*Int
2forall a. Num a => a -> a -> a
*Int
16forall a. Num a => a -> a -> a
*Int
nbR) forall {a}. Ptr a -> IO ()
aesInit
aesInit :: Ptr a -> IO ()
aesInit Ptr a
ptr = forall ba p a. ByteArrayAccess ba => ba -> (Ptr p -> IO a) -> IO a
withByteArray key
k forall a b. (a -> b) -> a -> b
$ \Ptr Any
ikey ->
Ptr AES -> CString -> CUInt -> IO ()
c_aes_init (forall a b. Ptr a -> Ptr b
castPtr Ptr a
ptr) (forall a b. Ptr a -> Ptr b
castPtr Ptr Any
ikey) (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len)
{-# NOINLINE encryptECB #-}
encryptECB :: ByteArray ba => AES -> ba -> ba
encryptECB :: forall ba. ByteArray ba => AES -> ba -> ba
encryptECB = forall ba b.
ByteArray ba =>
(Ptr b -> Ptr AES -> CString -> CUInt -> IO ()) -> AES -> ba -> ba
doECB CString -> Ptr AES -> CString -> CUInt -> IO ()
c_aes_encrypt_ecb
{-# NOINLINE encryptCBC #-}
encryptCBC :: ByteArray ba
=> AES
-> IV AES
-> ba
-> ba
encryptCBC :: forall ba. ByteArray ba => AES -> IV AES -> ba -> ba
encryptCBC = forall ba b.
ByteArray ba =>
(Ptr b -> Ptr AES -> Ptr Word8 -> CString -> CUInt -> IO ())
-> AES -> IV AES -> ba -> ba
doCBC CString -> Ptr AES -> Ptr Word8 -> CString -> CUInt -> IO ()
c_aes_encrypt_cbc
{-# NOINLINE genCTR #-}
genCTR :: ByteArray ba
=> AES
-> IV AES
-> Int
-> ba
genCTR :: forall ba. ByteArray ba => AES -> IV AES -> Int -> ba
genCTR AES
ctx (IV byteArray
iv) Int
len
| Int
len forall a. Ord a => a -> a -> Bool
<= Int
0 = forall a. ByteArray a => a
B.empty
| Bool
otherwise = forall a p. ByteArray a => Int -> (Ptr p -> IO ()) -> a
B.allocAndFreeze (Int
nbBlocks forall a. Num a => a -> a -> a
* Int
16) forall {a}. Ptr a -> IO ()
generate
where generate :: Ptr a -> IO ()
generate Ptr a
o = forall iv a.
ByteArrayAccess iv =>
AES -> iv -> (Ptr AES -> Ptr Word8 -> IO a) -> IO a
withKeyAndIV AES
ctx byteArray
iv forall a b. (a -> b) -> a -> b
$ \Ptr AES
k Ptr Word8
i -> CString -> Ptr AES -> Ptr Word8 -> CUInt -> IO ()
c_aes_gen_ctr (forall a b. Ptr a -> Ptr b
castPtr Ptr a
o) Ptr AES
k Ptr Word8
i (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
nbBlocks)
(Int
nbBlocks',Int
r) = Int
len forall a. Integral a => a -> a -> (a, a)
`quotRem` Int
16
nbBlocks :: Int
nbBlocks = if Int
r forall a. Eq a => a -> a -> Bool
== Int
0 then Int
nbBlocks' else Int
nbBlocks' forall a. Num a => a -> a -> a
+ Int
1
{-# NOINLINE genCounter #-}
genCounter :: ByteArray ba
=> AES
-> IV AES
-> Int
-> (ba, IV AES)
genCounter :: forall ba. ByteArray ba => AES -> IV AES -> Int -> (ba, IV AES)
genCounter AES
ctx IV AES
iv Int
len
| Int
len forall a. Ord a => a -> a -> Bool
<= Int
0 = (forall a. ByteArray a => a
B.empty, IV AES
iv)
| Bool
otherwise = forall a. IO a -> a
unsafeDoIO forall a b. (a -> b) -> a -> b
$
forall a. AES -> (Ptr AES -> IO a) -> IO a
keyToPtr AES
ctx forall a b. (a -> b) -> a -> b
$ \Ptr AES
k ->
forall a. IV AES -> (Ptr Word8 -> IO a) -> IO (a, IV AES)
ivCopyPtr IV AES
iv forall a b. (a -> b) -> a -> b
$ \Ptr Word8
i ->
forall ba p. ByteArray ba => Int -> (Ptr p -> IO ()) -> IO ba
B.alloc Int
outputLength forall a b. (a -> b) -> a -> b
$ \Ptr Any
o -> do
CString -> Ptr AES -> Ptr Word8 -> CUInt -> IO ()
c_aes_gen_ctr_cont (forall a b. Ptr a -> Ptr b
castPtr Ptr Any
o) Ptr AES
k Ptr Word8
i (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
nbBlocks)
where
(Int
nbBlocks',Int
r) = Int
len forall a. Integral a => a -> a -> (a, a)
`quotRem` Int
16
nbBlocks :: Int
nbBlocks = if Int
r forall a. Eq a => a -> a -> Bool
== Int
0 then Int
nbBlocks' else Int
nbBlocks' forall a. Num a => a -> a -> a
+ Int
1
outputLength :: Int
outputLength = Int
nbBlocks forall a. Num a => a -> a -> a
* Int
16
{-# NOINLINE encryptCTR #-}
encryptCTR :: ByteArray ba
=> AES
-> IV AES
-> ba
-> ba
encryptCTR :: forall ba. ByteArray ba => AES -> IV AES -> ba -> ba
encryptCTR AES
ctx IV AES
iv ba
input
| Int
len forall a. Ord a => a -> a -> Bool
<= Int
0 = forall a. ByteArray a => a
B.empty
| forall ba. ByteArrayAccess ba => ba -> Int
B.length IV AES
iv forall a. Eq a => a -> a -> Bool
/= Int
16 = forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ String
"AES error: IV length must be block size (16). Its length is: " forall a. [a] -> [a] -> [a]
++ (forall a. Show a => a -> String
show forall a b. (a -> b) -> a -> b
$ forall ba. ByteArrayAccess ba => ba -> Int
B.length IV AES
iv)
| Bool
otherwise = forall a p. ByteArray a => Int -> (Ptr p -> IO ()) -> a
B.allocAndFreeze Int
len forall {a}. Ptr a -> IO ()
doEncrypt
where doEncrypt :: Ptr a -> IO ()
doEncrypt Ptr a
o = forall iv a.
ByteArrayAccess iv =>
AES -> iv -> (Ptr AES -> Ptr Word8 -> IO a) -> IO a
withKeyAndIV AES
ctx IV AES
iv forall a b. (a -> b) -> a -> b
$ \Ptr AES
k Ptr Word8
v -> forall ba p a. ByteArrayAccess ba => ba -> (Ptr p -> IO a) -> IO a
withByteArray ba
input forall a b. (a -> b) -> a -> b
$ \CString
i ->
CString -> Ptr AES -> Ptr Word8 -> CString -> CUInt -> IO ()
c_aes_encrypt_ctr (forall a b. Ptr a -> Ptr b
castPtr Ptr a
o) Ptr AES
k Ptr Word8
v CString
i (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len)
len :: Int
len = forall ba. ByteArrayAccess ba => ba -> Int
B.length ba
input
{-# NOINLINE encryptXTS #-}
encryptXTS :: ByteArray ba
=> (AES,AES)
-> IV AES
-> Word32
-> ba
-> ba
encryptXTS :: forall ba.
ByteArray ba =>
(AES, AES) -> IV AES -> DataUnitOffset -> ba -> ba
encryptXTS = forall ba b.
ByteArray ba =>
(Ptr b
-> Ptr AES
-> Ptr AES
-> Ptr Word8
-> CUInt
-> CString
-> CUInt
-> IO ())
-> (AES, AES) -> IV AES -> DataUnitOffset -> ba -> ba
doXTS CString
-> Ptr AES
-> Ptr AES
-> Ptr Word8
-> CUInt
-> CString
-> CUInt
-> IO ()
c_aes_encrypt_xts
{-# NOINLINE decryptECB #-}
decryptECB :: ByteArray ba => AES -> ba -> ba
decryptECB :: forall ba. ByteArray ba => AES -> ba -> ba
decryptECB = forall ba b.
ByteArray ba =>
(Ptr b -> Ptr AES -> CString -> CUInt -> IO ()) -> AES -> ba -> ba
doECB CString -> Ptr AES -> CString -> CUInt -> IO ()
c_aes_decrypt_ecb
{-# NOINLINE decryptCBC #-}
decryptCBC :: ByteArray ba => AES -> IV AES -> ba -> ba
decryptCBC :: forall ba. ByteArray ba => AES -> IV AES -> ba -> ba
decryptCBC = forall ba b.
ByteArray ba =>
(Ptr b -> Ptr AES -> Ptr Word8 -> CString -> CUInt -> IO ())
-> AES -> IV AES -> ba -> ba
doCBC CString -> Ptr AES -> Ptr Word8 -> CString -> CUInt -> IO ()
c_aes_decrypt_cbc
decryptCTR :: ByteArray ba
=> AES
-> IV AES
-> ba
-> ba
decryptCTR :: forall ba. ByteArray ba => AES -> IV AES -> ba -> ba
decryptCTR = forall ba. ByteArray ba => AES -> IV AES -> ba -> ba
encryptCTR
{-# NOINLINE decryptXTS #-}
decryptXTS :: ByteArray ba
=> (AES,AES)
-> IV AES
-> Word32
-> ba
-> ba
decryptXTS :: forall ba.
ByteArray ba =>
(AES, AES) -> IV AES -> DataUnitOffset -> ba -> ba
decryptXTS = forall ba b.
ByteArray ba =>
(Ptr b
-> Ptr AES
-> Ptr AES
-> Ptr Word8
-> CUInt
-> CString
-> CUInt
-> IO ())
-> (AES, AES) -> IV AES -> DataUnitOffset -> ba -> ba
doXTS CString
-> Ptr AES
-> Ptr AES
-> Ptr Word8
-> CUInt
-> CString
-> CUInt
-> IO ()
c_aes_decrypt_xts
{-# NOINLINE combineC32 #-}
combineC32 :: ByteArray ba
=> AES
-> IV AES
-> ba
-> ba
combineC32 :: forall ba. ByteArray ba => AES -> IV AES -> ba -> ba
combineC32 AES
ctx IV AES
iv ba
input
| Int
len forall a. Ord a => a -> a -> Bool
<= Int
0 = forall a. ByteArray a => a
B.empty
| forall ba. ByteArrayAccess ba => ba -> Int
B.length IV AES
iv forall a. Eq a => a -> a -> Bool
/= Int
16 = forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ String
"AES error: IV length must be block size (16). Its length is: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (forall ba. ByteArrayAccess ba => ba -> Int
B.length IV AES
iv)
| Bool
otherwise = forall a p. ByteArray a => Int -> (Ptr p -> IO ()) -> a
B.allocAndFreeze Int
len forall {a}. Ptr a -> IO ()
doEncrypt
where doEncrypt :: Ptr a -> IO ()
doEncrypt Ptr a
o = forall iv a.
ByteArrayAccess iv =>
AES -> iv -> (Ptr AES -> Ptr Word8 -> IO a) -> IO a
withKeyAndIV AES
ctx IV AES
iv forall a b. (a -> b) -> a -> b
$ \Ptr AES
k Ptr Word8
v -> forall ba p a. ByteArrayAccess ba => ba -> (Ptr p -> IO a) -> IO a
withByteArray ba
input forall a b. (a -> b) -> a -> b
$ \CString
i ->
CString -> Ptr AES -> Ptr Word8 -> CString -> CUInt -> IO ()
c_aes_encrypt_c32 (forall a b. Ptr a -> Ptr b
castPtr Ptr a
o) Ptr AES
k Ptr Word8
v CString
i (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len)
len :: Int
len = forall ba. ByteArrayAccess ba => ba -> Int
B.length ba
input
{-# INLINE doECB #-}
doECB :: ByteArray ba
=> (Ptr b -> Ptr AES -> CString -> CUInt -> IO ())
-> AES -> ba -> ba
doECB :: forall ba b.
ByteArray ba =>
(Ptr b -> Ptr AES -> CString -> CUInt -> IO ()) -> AES -> ba -> ba
doECB Ptr b -> Ptr AES -> CString -> CUInt -> IO ()
f AES
ctx ba
input
| Int
len forall a. Eq a => a -> a -> Bool
== Int
0 = forall a. ByteArray a => a
B.empty
| Int
r forall a. Eq a => a -> a -> Bool
/= Int
0 = forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ String
"Encryption error: input length must be a multiple of block size (16). Its length is: " forall a. [a] -> [a] -> [a]
++ (forall a. Show a => a -> String
show Int
len)
| Bool
otherwise =
forall a p. ByteArray a => Int -> (Ptr p -> IO ()) -> a
B.allocAndFreeze Int
len forall a b. (a -> b) -> a -> b
$ \Ptr Any
o ->
forall a. AES -> (Ptr AES -> IO a) -> IO a
keyToPtr AES
ctx forall a b. (a -> b) -> a -> b
$ \Ptr AES
k ->
forall ba p a. ByteArrayAccess ba => ba -> (Ptr p -> IO a) -> IO a
withByteArray ba
input forall a b. (a -> b) -> a -> b
$ \CString
i ->
Ptr b -> Ptr AES -> CString -> CUInt -> IO ()
f (forall a b. Ptr a -> Ptr b
castPtr Ptr Any
o) Ptr AES
k CString
i (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
nbBlocks)
where (Int
nbBlocks, Int
r) = Int
len forall a. Integral a => a -> a -> (a, a)
`quotRem` Int
16
len :: Int
len = forall ba. ByteArrayAccess ba => ba -> Int
B.length ba
input
{-# INLINE doCBC #-}
doCBC :: ByteArray ba
=> (Ptr b -> Ptr AES -> Ptr Word8 -> CString -> CUInt -> IO ())
-> AES -> IV AES -> ba -> ba
doCBC :: forall ba b.
ByteArray ba =>
(Ptr b -> Ptr AES -> Ptr Word8 -> CString -> CUInt -> IO ())
-> AES -> IV AES -> ba -> ba
doCBC Ptr b -> Ptr AES -> Ptr Word8 -> CString -> CUInt -> IO ()
f AES
ctx (IV byteArray
iv) ba
input
| Int
len forall a. Eq a => a -> a -> Bool
== Int
0 = forall a. ByteArray a => a
B.empty
| Int
r forall a. Eq a => a -> a -> Bool
/= Int
0 = forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ String
"Encryption error: input length must be a multiple of block size (16). Its length is: " forall a. [a] -> [a] -> [a]
++ (forall a. Show a => a -> String
show Int
len)
| Bool
otherwise = forall a p. ByteArray a => Int -> (Ptr p -> IO ()) -> a
B.allocAndFreeze Int
len forall a b. (a -> b) -> a -> b
$ \Ptr Any
o ->
forall iv a.
ByteArrayAccess iv =>
AES -> iv -> (Ptr AES -> Ptr Word8 -> IO a) -> IO a
withKeyAndIV AES
ctx byteArray
iv forall a b. (a -> b) -> a -> b
$ \Ptr AES
k Ptr Word8
v ->
forall ba p a. ByteArrayAccess ba => ba -> (Ptr p -> IO a) -> IO a
withByteArray ba
input forall a b. (a -> b) -> a -> b
$ \CString
i ->
Ptr b -> Ptr AES -> Ptr Word8 -> CString -> CUInt -> IO ()
f (forall a b. Ptr a -> Ptr b
castPtr Ptr Any
o) Ptr AES
k Ptr Word8
v CString
i (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
nbBlocks)
where (Int
nbBlocks, Int
r) = Int
len forall a. Integral a => a -> a -> (a, a)
`quotRem` Int
16
len :: Int
len = forall ba. ByteArrayAccess ba => ba -> Int
B.length ba
input
{-# INLINE doXTS #-}
doXTS :: ByteArray ba
=> (Ptr b -> Ptr AES -> Ptr AES -> Ptr Word8 -> CUInt -> CString -> CUInt -> IO ())
-> (AES, AES)
-> IV AES
-> Word32
-> ba
-> ba
doXTS :: forall ba b.
ByteArray ba =>
(Ptr b
-> Ptr AES
-> Ptr AES
-> Ptr Word8
-> CUInt
-> CString
-> CUInt
-> IO ())
-> (AES, AES) -> IV AES -> DataUnitOffset -> ba -> ba
doXTS Ptr b
-> Ptr AES
-> Ptr AES
-> Ptr Word8
-> CUInt
-> CString
-> CUInt
-> IO ()
f (AES
key1,AES
key2) IV AES
iv DataUnitOffset
spoint ba
input
| Int
len forall a. Eq a => a -> a -> Bool
== Int
0 = forall a. ByteArray a => a
B.empty
| Int
r forall a. Eq a => a -> a -> Bool
/= Int
0 = forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ String
"Encryption error: input length must be a multiple of block size (16) for now. Its length is: " forall a. [a] -> [a] -> [a]
++ (forall a. Show a => a -> String
show Int
len)
| Bool
otherwise = forall a p. ByteArray a => Int -> (Ptr p -> IO ()) -> a
B.allocAndFreeze Int
len forall a b. (a -> b) -> a -> b
$ \Ptr Any
o -> forall iv a.
ByteArrayAccess iv =>
AES
-> AES -> iv -> (Ptr AES -> Ptr AES -> Ptr Word8 -> IO a) -> IO a
withKey2AndIV AES
key1 AES
key2 IV AES
iv forall a b. (a -> b) -> a -> b
$ \Ptr AES
k1 Ptr AES
k2 Ptr Word8
v -> forall ba p a. ByteArrayAccess ba => ba -> (Ptr p -> IO a) -> IO a
withByteArray ba
input forall a b. (a -> b) -> a -> b
$ \CString
i ->
Ptr b
-> Ptr AES
-> Ptr AES
-> Ptr Word8
-> CUInt
-> CString
-> CUInt
-> IO ()
f (forall a b. Ptr a -> Ptr b
castPtr Ptr Any
o) Ptr AES
k1 Ptr AES
k2 Ptr Word8
v (forall a b. (Integral a, Num b) => a -> b
fromIntegral DataUnitOffset
spoint) CString
i (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
nbBlocks)
where (Int
nbBlocks, Int
r) = Int
len forall a. Integral a => a -> a -> (a, a)
`quotRem` Int
16
len :: Int
len = forall ba. ByteArrayAccess ba => ba -> Int
B.length ba
input
{-# NOINLINE gcmInit #-}
gcmInit :: ByteArrayAccess iv => AES -> iv -> AESGCM
gcmInit :: forall iv. ByteArrayAccess iv => AES -> iv -> AESGCM
gcmInit AES
ctx iv
iv = forall a. IO a -> a
unsafeDoIO forall a b. (a -> b) -> a -> b
$ do
ScrubbedBytes
sm <- forall ba p. ByteArray ba => Int -> (Ptr p -> IO ()) -> IO ba
B.alloc Int
sizeGCM forall a b. (a -> b) -> a -> b
$ \Ptr Any
gcmStPtr ->
forall iv a.
ByteArrayAccess iv =>
AES -> iv -> (Ptr AES -> Ptr Word8 -> IO a) -> IO a
withKeyAndIV AES
ctx iv
iv forall a b. (a -> b) -> a -> b
$ \Ptr AES
k Ptr Word8
v ->
Ptr AESGCM -> Ptr AES -> Ptr Word8 -> CUInt -> IO ()
c_aes_gcm_init (forall a b. Ptr a -> Ptr b
castPtr Ptr Any
gcmStPtr) Ptr AES
k Ptr Word8
v (forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ forall ba. ByteArrayAccess ba => ba -> Int
B.length iv
iv)
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ ScrubbedBytes -> AESGCM
AESGCM ScrubbedBytes
sm
{-# NOINLINE gcmAppendAAD #-}
gcmAppendAAD :: ByteArrayAccess aad => AESGCM -> aad -> AESGCM
gcmAppendAAD :: forall ba. ByteArrayAccess ba => AESGCM -> ba -> AESGCM
gcmAppendAAD AESGCM
gcmSt aad
input = forall a. IO a -> a
unsafeDoIO IO AESGCM
doAppend
where doAppend :: IO AESGCM
doAppend =
AESGCM -> (Ptr AESGCM -> IO ()) -> IO AESGCM
withNewGCMSt AESGCM
gcmSt forall a b. (a -> b) -> a -> b
$ \Ptr AESGCM
gcmStPtr ->
forall ba p a. ByteArrayAccess ba => ba -> (Ptr p -> IO a) -> IO a
withByteArray aad
input forall a b. (a -> b) -> a -> b
$ \CString
i ->
Ptr AESGCM -> CString -> CUInt -> IO ()
c_aes_gcm_aad Ptr AESGCM
gcmStPtr CString
i (forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ forall ba. ByteArrayAccess ba => ba -> Int
B.length aad
input)
{-# NOINLINE gcmAppendEncrypt #-}
gcmAppendEncrypt :: ByteArray ba => AES -> AESGCM -> ba -> (ba, AESGCM)
gcmAppendEncrypt :: forall ba. ByteArray ba => AES -> AESGCM -> ba -> (ba, AESGCM)
gcmAppendEncrypt AES
ctx AESGCM
gcm ba
input = forall a. IO a -> a
unsafeDoIO forall a b. (a -> b) -> a -> b
$ forall a.
AES -> AESGCM -> (Ptr AESGCM -> Ptr AES -> IO a) -> IO (a, AESGCM)
withGCMKeyAndCopySt AES
ctx AESGCM
gcm forall {ba}. ByteArray ba => Ptr AESGCM -> Ptr AES -> IO ba
doEnc
where len :: Int
len = forall ba. ByteArrayAccess ba => ba -> Int
B.length ba
input
doEnc :: Ptr AESGCM -> Ptr AES -> IO ba
doEnc Ptr AESGCM
gcmStPtr Ptr AES
aesPtr =
forall ba p. ByteArray ba => Int -> (Ptr p -> IO ()) -> IO ba
B.alloc Int
len forall a b. (a -> b) -> a -> b
$ \Ptr Any
o ->
forall ba p a. ByteArrayAccess ba => ba -> (Ptr p -> IO a) -> IO a
withByteArray ba
input forall a b. (a -> b) -> a -> b
$ \CString
i ->
CString -> Ptr AESGCM -> Ptr AES -> CString -> CUInt -> IO ()
c_aes_gcm_encrypt (forall a b. Ptr a -> Ptr b
castPtr Ptr Any
o) Ptr AESGCM
gcmStPtr Ptr AES
aesPtr CString
i (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len)
{-# NOINLINE gcmAppendDecrypt #-}
gcmAppendDecrypt :: ByteArray ba => AES -> AESGCM -> ba -> (ba, AESGCM)
gcmAppendDecrypt :: forall ba. ByteArray ba => AES -> AESGCM -> ba -> (ba, AESGCM)
gcmAppendDecrypt AES
ctx AESGCM
gcm ba
input = forall a. IO a -> a
unsafeDoIO forall a b. (a -> b) -> a -> b
$ forall a.
AES -> AESGCM -> (Ptr AESGCM -> Ptr AES -> IO a) -> IO (a, AESGCM)
withGCMKeyAndCopySt AES
ctx AESGCM
gcm forall {ba}. ByteArray ba => Ptr AESGCM -> Ptr AES -> IO ba
doDec
where len :: Int
len = forall ba. ByteArrayAccess ba => ba -> Int
B.length ba
input
doDec :: Ptr AESGCM -> Ptr AES -> IO ba
doDec Ptr AESGCM
gcmStPtr Ptr AES
aesPtr =
forall ba p. ByteArray ba => Int -> (Ptr p -> IO ()) -> IO ba
B.alloc Int
len forall a b. (a -> b) -> a -> b
$ \Ptr Any
o ->
forall ba p a. ByteArrayAccess ba => ba -> (Ptr p -> IO a) -> IO a
withByteArray ba
input forall a b. (a -> b) -> a -> b
$ \CString
i ->
CString -> Ptr AESGCM -> Ptr AES -> CString -> CUInt -> IO ()
c_aes_gcm_decrypt (forall a b. Ptr a -> Ptr b
castPtr Ptr Any
o) Ptr AESGCM
gcmStPtr Ptr AES
aesPtr CString
i (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len)
{-# NOINLINE gcmFinish #-}
gcmFinish :: AES -> AESGCM -> Int -> AuthTag
gcmFinish :: AES -> AESGCM -> Int -> AuthTag
gcmFinish AES
ctx AESGCM
gcm Int
taglen = Bytes -> AuthTag
AuthTag forall a b. (a -> b) -> a -> b
$ forall bs. ByteArray bs => Int -> bs -> bs
B.take Int
taglen Bytes
computeTag
where computeTag :: Bytes
computeTag = forall a p. ByteArray a => Int -> (Ptr p -> IO ()) -> a
B.allocAndFreeze Int
16 forall a b. (a -> b) -> a -> b
$ \Ptr Any
t ->
forall a.
AES -> AESGCM -> (Ptr AESGCM -> Ptr AES -> IO a) -> IO (a, AESGCM)
withGCMKeyAndCopySt AES
ctx AESGCM
gcm (CString -> Ptr AESGCM -> Ptr AES -> IO ()
c_aes_gcm_finish (forall a b. Ptr a -> Ptr b
castPtr Ptr Any
t)) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return ()
{-# NOINLINE ocbInit #-}
ocbInit :: ByteArrayAccess iv => AES -> iv -> AESOCB
ocbInit :: forall iv. ByteArrayAccess iv => AES -> iv -> AESOCB
ocbInit AES
ctx iv
iv = forall a. IO a -> a
unsafeDoIO forall a b. (a -> b) -> a -> b
$ do
ScrubbedBytes
sm <- forall ba p. ByteArray ba => Int -> (Ptr p -> IO ()) -> IO ba
B.alloc Int
sizeOCB forall a b. (a -> b) -> a -> b
$ \Ptr Any
ocbStPtr ->
forall iv a.
ByteArrayAccess iv =>
AES -> iv -> (Ptr AES -> Ptr Word8 -> IO a) -> IO a
withKeyAndIV AES
ctx iv
iv forall a b. (a -> b) -> a -> b
$ \Ptr AES
k Ptr Word8
v ->
Ptr AESOCB -> Ptr AES -> Ptr Word8 -> CUInt -> IO ()
c_aes_ocb_init (forall a b. Ptr a -> Ptr b
castPtr Ptr Any
ocbStPtr) Ptr AES
k Ptr Word8
v (forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ forall ba. ByteArrayAccess ba => ba -> Int
B.length iv
iv)
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ ScrubbedBytes -> AESOCB
AESOCB ScrubbedBytes
sm
{-# NOINLINE ocbAppendAAD #-}
ocbAppendAAD :: ByteArrayAccess aad => AES -> AESOCB -> aad -> AESOCB
ocbAppendAAD :: forall aad. ByteArrayAccess aad => AES -> AESOCB -> aad -> AESOCB
ocbAppendAAD AES
ctx AESOCB
ocb aad
input = forall a. IO a -> a
unsafeDoIO (forall a b. (a, b) -> b
snd forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` forall a.
AES -> AESOCB -> (Ptr AESOCB -> Ptr AES -> IO a) -> IO (a, AESOCB)
withOCBKeyAndCopySt AES
ctx AESOCB
ocb Ptr AESOCB -> Ptr AES -> IO ()
doAppend)
where doAppend :: Ptr AESOCB -> Ptr AES -> IO ()
doAppend Ptr AESOCB
ocbStPtr Ptr AES
aesPtr =
forall ba p a. ByteArrayAccess ba => ba -> (Ptr p -> IO a) -> IO a
withByteArray aad
input forall a b. (a -> b) -> a -> b
$ \CString
i ->
Ptr AESOCB -> Ptr AES -> CString -> CUInt -> IO ()
c_aes_ocb_aad Ptr AESOCB
ocbStPtr Ptr AES
aesPtr CString
i (forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ forall ba. ByteArrayAccess ba => ba -> Int
B.length aad
input)
{-# NOINLINE ocbAppendEncrypt #-}
ocbAppendEncrypt :: ByteArray ba => AES -> AESOCB -> ba -> (ba, AESOCB)
ocbAppendEncrypt :: forall ba. ByteArray ba => AES -> AESOCB -> ba -> (ba, AESOCB)
ocbAppendEncrypt AES
ctx AESOCB
ocb ba
input = forall a. IO a -> a
unsafeDoIO forall a b. (a -> b) -> a -> b
$ forall a.
AES -> AESOCB -> (Ptr AESOCB -> Ptr AES -> IO a) -> IO (a, AESOCB)
withOCBKeyAndCopySt AES
ctx AESOCB
ocb forall {ba}. ByteArray ba => Ptr AESOCB -> Ptr AES -> IO ba
doEnc
where len :: Int
len = forall ba. ByteArrayAccess ba => ba -> Int
B.length ba
input
doEnc :: Ptr AESOCB -> Ptr AES -> IO ba
doEnc Ptr AESOCB
ocbStPtr Ptr AES
aesPtr =
forall ba p. ByteArray ba => Int -> (Ptr p -> IO ()) -> IO ba
B.alloc Int
len forall a b. (a -> b) -> a -> b
$ \Ptr Any
o ->
forall ba p a. ByteArrayAccess ba => ba -> (Ptr p -> IO a) -> IO a
withByteArray ba
input forall a b. (a -> b) -> a -> b
$ \CString
i ->
CString -> Ptr AESOCB -> Ptr AES -> CString -> CUInt -> IO ()
c_aes_ocb_encrypt (forall a b. Ptr a -> Ptr b
castPtr Ptr Any
o) Ptr AESOCB
ocbStPtr Ptr AES
aesPtr CString
i (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len)
{-# NOINLINE ocbAppendDecrypt #-}
ocbAppendDecrypt :: ByteArray ba => AES -> AESOCB -> ba -> (ba, AESOCB)
ocbAppendDecrypt :: forall ba. ByteArray ba => AES -> AESOCB -> ba -> (ba, AESOCB)
ocbAppendDecrypt AES
ctx AESOCB
ocb ba
input = forall a. IO a -> a
unsafeDoIO forall a b. (a -> b) -> a -> b
$ forall a.
AES -> AESOCB -> (Ptr AESOCB -> Ptr AES -> IO a) -> IO (a, AESOCB)
withOCBKeyAndCopySt AES
ctx AESOCB
ocb forall {ba}. ByteArray ba => Ptr AESOCB -> Ptr AES -> IO ba
doDec
where len :: Int
len = forall ba. ByteArrayAccess ba => ba -> Int
B.length ba
input
doDec :: Ptr AESOCB -> Ptr AES -> IO ba
doDec Ptr AESOCB
ocbStPtr Ptr AES
aesPtr =
forall ba p. ByteArray ba => Int -> (Ptr p -> IO ()) -> IO ba
B.alloc Int
len forall a b. (a -> b) -> a -> b
$ \Ptr Any
o ->
forall ba p a. ByteArrayAccess ba => ba -> (Ptr p -> IO a) -> IO a
withByteArray ba
input forall a b. (a -> b) -> a -> b
$ \CString
i ->
CString -> Ptr AESOCB -> Ptr AES -> CString -> CUInt -> IO ()
c_aes_ocb_decrypt (forall a b. Ptr a -> Ptr b
castPtr Ptr Any
o) Ptr AESOCB
ocbStPtr Ptr AES
aesPtr CString
i (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len)
{-# NOINLINE ocbFinish #-}
ocbFinish :: AES -> AESOCB -> Int -> AuthTag
ocbFinish :: AES -> AESOCB -> Int -> AuthTag
ocbFinish AES
ctx AESOCB
ocb Int
taglen = Bytes -> AuthTag
AuthTag forall a b. (a -> b) -> a -> b
$ forall bs. ByteArray bs => Int -> bs -> bs
B.take Int
taglen Bytes
computeTag
where computeTag :: Bytes
computeTag = forall a p. ByteArray a => Int -> (Ptr p -> IO ()) -> a
B.allocAndFreeze Int
16 forall a b. (a -> b) -> a -> b
$ \Ptr Any
t ->
forall a.
AES -> AESOCB -> (Ptr AESOCB -> Ptr AES -> IO a) -> IO (a, AESOCB)
withOCBKeyAndCopySt AES
ctx AESOCB
ocb (CString -> Ptr AESOCB -> Ptr AES -> IO ()
c_aes_ocb_finish (forall a b. Ptr a -> Ptr b
castPtr Ptr Any
t)) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return ()
ccmGetM :: CCM_M -> Int
ccmGetL :: CCM_L -> Int
ccmGetM :: CCM_M -> Int
ccmGetM CCM_M
m = case CCM_M
m of
CCM_M
CCM_M4 -> Int
4
CCM_M
CCM_M6 -> Int
6
CCM_M
CCM_M8 -> Int
8
CCM_M
CCM_M10 -> Int
10
CCM_M
CCM_M12 -> Int
12
CCM_M
CCM_M14 -> Int
14
CCM_M
CCM_M16 -> Int
16
ccmGetL :: CCM_L -> Int
ccmGetL CCM_L
l = case CCM_L
l of
CCM_L
CCM_L2 -> Int
2
CCM_L
CCM_L3 -> Int
3
CCM_L
CCM_L4 -> Int
4
{-# NOINLINE ccmInit #-}
ccmInit :: ByteArrayAccess iv => AES -> iv -> Int -> CCM_M -> CCM_L -> CryptoFailable AESCCM
ccmInit :: forall iv.
ByteArrayAccess iv =>
AES -> iv -> Int -> CCM_M -> CCM_L -> CryptoFailable AESCCM
ccmInit AES
ctx iv
iv Int
n CCM_M
m CCM_L
l
| Int
15 forall a. Num a => a -> a -> a
- Int
li forall a. Eq a => a -> a -> Bool
/= forall ba. ByteArrayAccess ba => ba -> Int
B.length iv
iv = forall a. CryptoError -> CryptoFailable a
CryptoFailed CryptoError
CryptoError_IvSizeInvalid
| Bool
otherwise = forall a. IO a -> a
unsafeDoIO forall a b. (a -> b) -> a -> b
$ do
ScrubbedBytes
sm <- forall ba p. ByteArray ba => Int -> (Ptr p -> IO ()) -> IO ba
B.alloc Int
sizeCCM forall a b. (a -> b) -> a -> b
$ \Ptr Any
ccmStPtr ->
forall iv a.
ByteArrayAccess iv =>
AES -> iv -> (Ptr AES -> Ptr Word8 -> IO a) -> IO a
withKeyAndIV AES
ctx iv
iv forall a b. (a -> b) -> a -> b
$ \Ptr AES
k Ptr Word8
v ->
Ptr AESCCM
-> Ptr AES -> Ptr Word8 -> CUInt -> CUInt -> CInt -> CInt -> IO ()
c_aes_ccm_init (forall a b. Ptr a -> Ptr b
castPtr Ptr Any
ccmStPtr) Ptr AES
k Ptr Word8
v (forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ forall ba. ByteArrayAccess ba => ba -> Int
B.length iv
iv) (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n) (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
mi) (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
li)
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> CryptoFailable a
CryptoPassed (ScrubbedBytes -> AESCCM
AESCCM ScrubbedBytes
sm)
where
mi :: Int
mi = CCM_M -> Int
ccmGetM CCM_M
m
li :: Int
li = CCM_L -> Int
ccmGetL CCM_L
l
{-# NOINLINE ccmAppendAAD #-}
ccmAppendAAD :: ByteArrayAccess aad => AES -> AESCCM -> aad -> AESCCM
ccmAppendAAD :: forall aad. ByteArrayAccess aad => AES -> AESCCM -> aad -> AESCCM
ccmAppendAAD AES
ctx AESCCM
ccm aad
input = forall a. IO a -> a
unsafeDoIO forall a b. (a -> b) -> a -> b
$ forall a b. (a, b) -> b
snd forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a.
AES -> AESCCM -> (Ptr AESCCM -> Ptr AES -> IO a) -> IO (a, AESCCM)
withCCMKeyAndCopySt AES
ctx AESCCM
ccm Ptr AESCCM -> Ptr AES -> IO ()
doAppend
where doAppend :: Ptr AESCCM -> Ptr AES -> IO ()
doAppend Ptr AESCCM
ccmStPtr Ptr AES
aesPtr =
forall ba p a. ByteArrayAccess ba => ba -> (Ptr p -> IO a) -> IO a
withByteArray aad
input forall a b. (a -> b) -> a -> b
$ \CString
i -> Ptr AESCCM -> Ptr AES -> CString -> CUInt -> IO ()
c_aes_ccm_aad Ptr AESCCM
ccmStPtr Ptr AES
aesPtr CString
i (forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ forall ba. ByteArrayAccess ba => ba -> Int
B.length aad
input)
{-# NOINLINE ccmEncrypt #-}
ccmEncrypt :: ByteArray ba => AES -> AESCCM -> ba -> (ba, AESCCM)
ccmEncrypt :: forall ba. ByteArray ba => AES -> AESCCM -> ba -> (ba, AESCCM)
ccmEncrypt AES
ctx AESCCM
ccm ba
input = forall a. IO a -> a
unsafeDoIO forall a b. (a -> b) -> a -> b
$ forall a.
AES -> AESCCM -> (Ptr AESCCM -> Ptr AES -> IO a) -> IO (a, AESCCM)
withCCMKeyAndCopySt AES
ctx AESCCM
ccm forall {ba}. ByteArray ba => Ptr AESCCM -> Ptr AES -> IO ba
cbcmacAndIv
where len :: Int
len = forall ba. ByteArrayAccess ba => ba -> Int
B.length ba
input
cbcmacAndIv :: Ptr AESCCM -> Ptr AES -> IO ba
cbcmacAndIv Ptr AESCCM
ccmStPtr Ptr AES
aesPtr =
forall ba p. ByteArray ba => Int -> (Ptr p -> IO ()) -> IO ba
B.alloc Int
len forall a b. (a -> b) -> a -> b
$ \Ptr Any
o ->
forall ba p a. ByteArrayAccess ba => ba -> (Ptr p -> IO a) -> IO a
withByteArray ba
input forall a b. (a -> b) -> a -> b
$ \CString
i ->
CString -> Ptr AESCCM -> Ptr AES -> CString -> CUInt -> IO ()
c_aes_ccm_encrypt (forall a b. Ptr a -> Ptr b
castPtr Ptr Any
o) Ptr AESCCM
ccmStPtr Ptr AES
aesPtr CString
i (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len)
{-# NOINLINE ccmDecrypt #-}
ccmDecrypt :: ByteArray ba => AES -> AESCCM -> ba -> (ba, AESCCM)
ccmDecrypt :: forall ba. ByteArray ba => AES -> AESCCM -> ba -> (ba, AESCCM)
ccmDecrypt AES
ctx AESCCM
ccm ba
input = forall a. IO a -> a
unsafeDoIO forall a b. (a -> b) -> a -> b
$ forall a.
AES -> AESCCM -> (Ptr AESCCM -> Ptr AES -> IO a) -> IO (a, AESCCM)
withCCMKeyAndCopySt AES
ctx AESCCM
ccm forall {ba}. ByteArray ba => Ptr AESCCM -> Ptr AES -> IO ba
cbcmacAndIv
where len :: Int
len = forall ba. ByteArrayAccess ba => ba -> Int
B.length ba
input
cbcmacAndIv :: Ptr AESCCM -> Ptr AES -> IO ba
cbcmacAndIv Ptr AESCCM
ccmStPtr Ptr AES
aesPtr =
forall ba p. ByteArray ba => Int -> (Ptr p -> IO ()) -> IO ba
B.alloc Int
len forall a b. (a -> b) -> a -> b
$ \Ptr Any
o ->
forall ba p a. ByteArrayAccess ba => ba -> (Ptr p -> IO a) -> IO a
withByteArray ba
input forall a b. (a -> b) -> a -> b
$ \CString
i ->
CString -> Ptr AESCCM -> Ptr AES -> CString -> CUInt -> IO ()
c_aes_ccm_decrypt (forall a b. Ptr a -> Ptr b
castPtr Ptr Any
o) Ptr AESCCM
ccmStPtr Ptr AES
aesPtr CString
i (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len)
{-# NOINLINE ccmFinish #-}
ccmFinish :: AES -> AESCCM -> Int -> AuthTag
ccmFinish :: AES -> AESCCM -> Int -> AuthTag
ccmFinish AES
ctx AESCCM
ccm Int
taglen = Bytes -> AuthTag
AuthTag forall a b. (a -> b) -> a -> b
$ forall bs. ByteArray bs => Int -> bs -> bs
B.take Int
taglen Bytes
computeTag
where computeTag :: Bytes
computeTag = forall a p. ByteArray a => Int -> (Ptr p -> IO ()) -> a
B.allocAndFreeze Int
16 forall a b. (a -> b) -> a -> b
$ \Ptr Any
t ->
forall a.
AES -> AESCCM -> (Ptr AESCCM -> Ptr AES -> IO a) -> IO (a, AESCCM)
withCCMKeyAndCopySt AES
ctx AESCCM
ccm (CString -> Ptr AESCCM -> Ptr AES -> IO ()
c_aes_ccm_finish (forall a b. Ptr a -> Ptr b
castPtr Ptr Any
t)) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return ()
foreign import ccall "crypton_aes.h crypton_aes_initkey"
c_aes_init :: Ptr AES -> CString -> CUInt -> IO ()
foreign import ccall "crypton_aes.h crypton_aes_encrypt_ecb"
c_aes_encrypt_ecb :: CString -> Ptr AES -> CString -> CUInt -> IO ()
foreign import ccall "crypton_aes.h crypton_aes_decrypt_ecb"
c_aes_decrypt_ecb :: CString -> Ptr AES -> CString -> CUInt -> IO ()
foreign import ccall "crypton_aes.h crypton_aes_encrypt_cbc"
c_aes_encrypt_cbc :: CString -> Ptr AES -> Ptr Word8 -> CString -> CUInt -> IO ()
foreign import ccall "crypton_aes.h crypton_aes_decrypt_cbc"
c_aes_decrypt_cbc :: CString -> Ptr AES -> Ptr Word8 -> CString -> CUInt -> IO ()
foreign import ccall "crypton_aes.h crypton_aes_encrypt_xts"
c_aes_encrypt_xts :: CString -> Ptr AES -> Ptr AES -> Ptr Word8 -> CUInt -> CString -> CUInt -> IO ()
foreign import ccall "crypton_aes.h crypton_aes_decrypt_xts"
c_aes_decrypt_xts :: CString -> Ptr AES -> Ptr AES -> Ptr Word8 -> CUInt -> CString -> CUInt -> IO ()
foreign import ccall "crypton_aes.h crypton_aes_gen_ctr"
c_aes_gen_ctr :: CString -> Ptr AES -> Ptr Word8 -> CUInt -> IO ()
foreign import ccall unsafe "crypton_aes.h crypton_aes_gen_ctr_cont"
c_aes_gen_ctr_cont :: CString -> Ptr AES -> Ptr Word8 -> CUInt -> IO ()
foreign import ccall "crypton_aes.h crypton_aes_encrypt_ctr"
c_aes_encrypt_ctr :: CString -> Ptr AES -> Ptr Word8 -> CString -> CUInt -> IO ()
foreign import ccall "crypton_aes.h crypton_aes_encrypt_c32"
c_aes_encrypt_c32 :: CString -> Ptr AES -> Ptr Word8 -> CString -> CUInt -> IO ()
foreign import ccall "crypton_aes.h crypton_aes_gcm_init"
c_aes_gcm_init :: Ptr AESGCM -> Ptr AES -> Ptr Word8 -> CUInt -> IO ()
foreign import ccall "crypton_aes.h crypton_aes_gcm_aad"
c_aes_gcm_aad :: Ptr AESGCM -> CString -> CUInt -> IO ()
foreign import ccall "crypton_aes.h crypton_aes_gcm_encrypt"
c_aes_gcm_encrypt :: CString -> Ptr AESGCM -> Ptr AES -> CString -> CUInt -> IO ()
foreign import ccall "crypton_aes.h crypton_aes_gcm_decrypt"
c_aes_gcm_decrypt :: CString -> Ptr AESGCM -> Ptr AES -> CString -> CUInt -> IO ()
foreign import ccall "crypton_aes.h crypton_aes_gcm_finish"
c_aes_gcm_finish :: CString -> Ptr AESGCM -> Ptr AES -> IO ()
foreign import ccall "crypton_aes.h crypton_aes_ocb_init"
c_aes_ocb_init :: Ptr AESOCB -> Ptr AES -> Ptr Word8 -> CUInt -> IO ()
foreign import ccall "crypton_aes.h crypton_aes_ocb_aad"
c_aes_ocb_aad :: Ptr AESOCB -> Ptr AES -> CString -> CUInt -> IO ()
foreign import ccall "crypton_aes.h crypton_aes_ocb_encrypt"
c_aes_ocb_encrypt :: CString -> Ptr AESOCB -> Ptr AES -> CString -> CUInt -> IO ()
foreign import ccall "crypton_aes.h crypton_aes_ocb_decrypt"
c_aes_ocb_decrypt :: CString -> Ptr AESOCB -> Ptr AES -> CString -> CUInt -> IO ()
foreign import ccall "crypton_aes.h crypton_aes_ocb_finish"
c_aes_ocb_finish :: CString -> Ptr AESOCB -> Ptr AES -> IO ()
foreign import ccall "crypton_aes.h crypton_aes_ccm_init"
c_aes_ccm_init :: Ptr AESCCM -> Ptr AES -> Ptr Word8 -> CUInt -> CUInt -> CInt -> CInt -> IO ()
foreign import ccall "crypton_aes.h crypton_aes_ccm_aad"
c_aes_ccm_aad :: Ptr AESCCM -> Ptr AES -> CString -> CUInt -> IO ()
foreign import ccall "crypton_aes.h crypton_aes_ccm_encrypt"
c_aes_ccm_encrypt :: CString -> Ptr AESCCM -> Ptr AES -> CString -> CUInt -> IO ()
foreign import ccall "crypton_aes.h crypton_aes_ccm_decrypt"
c_aes_ccm_decrypt :: CString -> Ptr AESCCM -> Ptr AES -> CString -> CUInt -> IO ()
foreign import ccall "crypton_aes.h crypton_aes_ccm_finish"
c_aes_ccm_finish :: CString -> Ptr AESCCM -> Ptr AES -> IO ()