module Z.Crypto.Cipher
(
BlockCipherType(..), KeySpec(..)
, BlockCipher, blockCipherName, blockCipherKeySpec, blockCipherSize
, newBlockCipher, setBlockCipherKey, clearBlockCipher
, encryptBlocks, decryptBlocks
, StreamCipherType(..), newStreamCipher
, CipherMode(..), CipherDirection(..)
, Cipher, cipherName, cipherUpdateGranularity
, cipherKeySpec, cipherTagLength, defaultNonceLength
, newCipher
, setCipherKey, clearCipher, resetCipher, setAssociatedData
, startCipher, updateCipher, finishCipher, cipherBIO
, blockCipherTypeToCBytes
, withBlockCipher
, withCipher
) where
import Control.Monad
import Data.IORef
import GHC.Generics
import Z.Botan.Exception
import Z.Botan.FFI
import Z.Crypto.Hash
import Z.Data.CBytes as CB
import Z.Data.JSON (JSON)
import qualified Z.Data.Text as T
import qualified Z.Data.Vector.Base as V
import qualified Z.Data.Vector.Extra as V
import Z.Foreign
import Z.IO.BIO
data BlockCipherType
= AES128
| AES192
| AES256
| ARIA128
| ARIA192
| ARIA256
| Blowfish
| Camellia128
| Camellia192
| Camellia256
| Cascade BlockCipherType BlockCipherType
| CAST128
| CAST256
| DES
| DESX
| TripleDES
| IDEA
| KASUMI
| Lion HashType StreamCipherType Int
| MISTY1
| Noekeon
| SEED
| Serpent
| SHACAL2
| Twofish
| SM4
| Threefish512
| XTEA
deriving (Int -> BlockCipherType -> ShowS
[BlockCipherType] -> ShowS
BlockCipherType -> String
(Int -> BlockCipherType -> ShowS)
-> (BlockCipherType -> String)
-> ([BlockCipherType] -> ShowS)
-> Show BlockCipherType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BlockCipherType] -> ShowS
$cshowList :: [BlockCipherType] -> ShowS
show :: BlockCipherType -> String
$cshow :: BlockCipherType -> String
showsPrec :: Int -> BlockCipherType -> ShowS
$cshowsPrec :: Int -> BlockCipherType -> ShowS
Show, ReadPrec [BlockCipherType]
ReadPrec BlockCipherType
Int -> ReadS BlockCipherType
ReadS [BlockCipherType]
(Int -> ReadS BlockCipherType)
-> ReadS [BlockCipherType]
-> ReadPrec BlockCipherType
-> ReadPrec [BlockCipherType]
-> Read BlockCipherType
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [BlockCipherType]
$creadListPrec :: ReadPrec [BlockCipherType]
readPrec :: ReadPrec BlockCipherType
$creadPrec :: ReadPrec BlockCipherType
readList :: ReadS [BlockCipherType]
$creadList :: ReadS [BlockCipherType]
readsPrec :: Int -> ReadS BlockCipherType
$creadsPrec :: Int -> ReadS BlockCipherType
Read, BlockCipherType -> BlockCipherType -> Bool
(BlockCipherType -> BlockCipherType -> Bool)
-> (BlockCipherType -> BlockCipherType -> Bool)
-> Eq BlockCipherType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: BlockCipherType -> BlockCipherType -> Bool
$c/= :: BlockCipherType -> BlockCipherType -> Bool
== :: BlockCipherType -> BlockCipherType -> Bool
$c== :: BlockCipherType -> BlockCipherType -> Bool
Eq, Eq BlockCipherType
Eq BlockCipherType
-> (BlockCipherType -> BlockCipherType -> Ordering)
-> (BlockCipherType -> BlockCipherType -> Bool)
-> (BlockCipherType -> BlockCipherType -> Bool)
-> (BlockCipherType -> BlockCipherType -> Bool)
-> (BlockCipherType -> BlockCipherType -> Bool)
-> (BlockCipherType -> BlockCipherType -> BlockCipherType)
-> (BlockCipherType -> BlockCipherType -> BlockCipherType)
-> Ord BlockCipherType
BlockCipherType -> BlockCipherType -> Bool
BlockCipherType -> BlockCipherType -> Ordering
BlockCipherType -> BlockCipherType -> BlockCipherType
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: BlockCipherType -> BlockCipherType -> BlockCipherType
$cmin :: BlockCipherType -> BlockCipherType -> BlockCipherType
max :: BlockCipherType -> BlockCipherType -> BlockCipherType
$cmax :: BlockCipherType -> BlockCipherType -> BlockCipherType
>= :: BlockCipherType -> BlockCipherType -> Bool
$c>= :: BlockCipherType -> BlockCipherType -> Bool
> :: BlockCipherType -> BlockCipherType -> Bool
$c> :: BlockCipherType -> BlockCipherType -> Bool
<= :: BlockCipherType -> BlockCipherType -> Bool
$c<= :: BlockCipherType -> BlockCipherType -> Bool
< :: BlockCipherType -> BlockCipherType -> Bool
$c< :: BlockCipherType -> BlockCipherType -> Bool
compare :: BlockCipherType -> BlockCipherType -> Ordering
$ccompare :: BlockCipherType -> BlockCipherType -> Ordering
$cp1Ord :: Eq BlockCipherType
Ord, (forall x. BlockCipherType -> Rep BlockCipherType x)
-> (forall x. Rep BlockCipherType x -> BlockCipherType)
-> Generic BlockCipherType
forall x. Rep BlockCipherType x -> BlockCipherType
forall x. BlockCipherType -> Rep BlockCipherType x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep BlockCipherType x -> BlockCipherType
$cfrom :: forall x. BlockCipherType -> Rep BlockCipherType x
Generic)
deriving anyclass (Int -> BlockCipherType -> Builder ()
(Int -> BlockCipherType -> Builder ()) -> Print BlockCipherType
forall a. (Int -> a -> Builder ()) -> Print a
toUTF8BuilderP :: Int -> BlockCipherType -> Builder ()
$ctoUTF8BuilderP :: Int -> BlockCipherType -> Builder ()
T.Print, Value -> Converter BlockCipherType
BlockCipherType -> Value
BlockCipherType -> Builder ()
(Value -> Converter BlockCipherType)
-> (BlockCipherType -> Value)
-> (BlockCipherType -> Builder ())
-> JSON BlockCipherType
forall a.
(Value -> Converter a)
-> (a -> Value) -> (a -> Builder ()) -> JSON a
encodeJSON :: BlockCipherType -> Builder ()
$cencodeJSON :: BlockCipherType -> Builder ()
toValue :: BlockCipherType -> Value
$ctoValue :: BlockCipherType -> Value
fromValue :: Value -> Converter BlockCipherType
$cfromValue :: Value -> Converter BlockCipherType
JSON)
blockCipherTypeToCBytes :: BlockCipherType -> CBytes
blockCipherTypeToCBytes :: BlockCipherType -> CBytes
blockCipherTypeToCBytes BlockCipherType
b = case BlockCipherType
b of
BlockCipherType
AES128 -> CBytes
"AES-128"
BlockCipherType
AES192 -> CBytes
"AES-192"
BlockCipherType
AES256 -> CBytes
"AES-256"
BlockCipherType
ARIA128 -> CBytes
"ARIA-128"
BlockCipherType
ARIA192 -> CBytes
"ARIA-192"
BlockCipherType
ARIA256 -> CBytes
"ARIA-256"
BlockCipherType
Serpent -> CBytes
"Serpent"
BlockCipherType
SHACAL2 -> CBytes
"SHACAL2"
BlockCipherType
Twofish -> CBytes
"Twofish"
BlockCipherType
Threefish512 -> CBytes
"Threefish-512"
BlockCipherType
Blowfish -> CBytes
"Blowfish"
BlockCipherType
Camellia128 -> CBytes
"Camellia-128"
BlockCipherType
Camellia192 -> CBytes
"Camellia-192"
BlockCipherType
Camellia256 -> CBytes
"Camellia-256"
BlockCipherType
DES -> CBytes
"DES"
BlockCipherType
DESX -> CBytes
"DESX"
BlockCipherType
TripleDES -> CBytes
"TripleDES"
BlockCipherType
Noekeon -> CBytes
"Noekeon"
BlockCipherType
CAST128 -> CBytes
"CAST-128"
BlockCipherType
CAST256 -> CBytes
"CAST-256"
BlockCipherType
IDEA -> CBytes
"IDEA"
BlockCipherType
KASUMI -> CBytes
"KASUMI"
BlockCipherType
MISTY1 -> CBytes
"MISTY1"
BlockCipherType
SEED -> CBytes
"SEED"
BlockCipherType
SM4 -> CBytes
"SM4"
BlockCipherType
XTEA -> CBytes
"XTEA"
Cascade BlockCipherType
b1 BlockCipherType
b2 -> [CBytes] -> CBytes
CB.concat [ CBytes
"Cascade("
, BlockCipherType -> CBytes
blockCipherTypeToCBytes BlockCipherType
b1
, CBytes
","
, BlockCipherType -> CBytes
blockCipherTypeToCBytes BlockCipherType
b2
, CBytes
")"]
Lion HashType
hasht StreamCipherType
st Int
siz -> [CBytes] -> CBytes
CB.concat [ CBytes
"Lion("
, HashType -> CBytes
hashTypeToCBytes HashType
hasht
, CBytes
","
, StreamCipherType -> CBytes
streamCipherTypeToCBytes StreamCipherType
st
, CBytes
","
, Text -> CBytes
CB.fromText (Int -> Text
forall a. Print a => a -> Text
T.toText Int
siz)
, CBytes
")"]
data BlockCipher = BlockCipher
{ BlockCipher -> BotanStruct
blockCipher :: {-# UNPACK #-} !BotanStruct
, BlockCipher -> CBytes
blockCipherName :: {-# UNPACK #-} !CBytes
, BlockCipher -> Int
blockCipherSize :: {-# UNPACK #-} !Int
, BlockCipher -> KeySpec
blockCipherKeySpec :: {-# UNPACK #-} !KeySpec
}
deriving (Int -> BlockCipher -> ShowS
[BlockCipher] -> ShowS
BlockCipher -> String
(Int -> BlockCipher -> ShowS)
-> (BlockCipher -> String)
-> ([BlockCipher] -> ShowS)
-> Show BlockCipher
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BlockCipher] -> ShowS
$cshowList :: [BlockCipher] -> ShowS
show :: BlockCipher -> String
$cshow :: BlockCipher -> String
showsPrec :: Int -> BlockCipher -> ShowS
$cshowsPrec :: Int -> BlockCipher -> ShowS
Show, (forall x. BlockCipher -> Rep BlockCipher x)
-> (forall x. Rep BlockCipher x -> BlockCipher)
-> Generic BlockCipher
forall x. Rep BlockCipher x -> BlockCipher
forall x. BlockCipher -> Rep BlockCipher x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep BlockCipher x -> BlockCipher
$cfrom :: forall x. BlockCipher -> Rep BlockCipher x
Generic)
deriving anyclass Int -> BlockCipher -> Builder ()
(Int -> BlockCipher -> Builder ()) -> Print BlockCipher
forall a. (Int -> a -> Builder ()) -> Print a
toUTF8BuilderP :: Int -> BlockCipher -> Builder ()
$ctoUTF8BuilderP :: Int -> BlockCipher -> Builder ()
T.Print
withBlockCipher :: HasCallStack => BlockCipher -> (BotanStructT -> IO r) -> IO r
withBlockCipher :: BlockCipher -> (BotanStructT -> IO r) -> IO r
withBlockCipher (BlockCipher BotanStruct
bc CBytes
_ Int
_ KeySpec
_) = BotanStruct -> (BotanStructT -> IO r) -> IO r
forall a. BotanStruct -> (BotanStructT -> IO a) -> IO a
withBotanStruct BotanStruct
bc
data KeySpec = KeySpec
{ KeySpec -> Int
keyLenMin :: {-# UNPACK #-} !Int
, KeySpec -> Int
keyLenMax :: {-# UNPACK #-} !Int
, KeySpec -> Int
keyLenMod :: {-# UNPACK #-} !Int
}
deriving (KeySpec -> KeySpec -> Bool
(KeySpec -> KeySpec -> Bool)
-> (KeySpec -> KeySpec -> Bool) -> Eq KeySpec
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: KeySpec -> KeySpec -> Bool
$c/= :: KeySpec -> KeySpec -> Bool
== :: KeySpec -> KeySpec -> Bool
$c== :: KeySpec -> KeySpec -> Bool
Eq, Eq KeySpec
Eq KeySpec
-> (KeySpec -> KeySpec -> Ordering)
-> (KeySpec -> KeySpec -> Bool)
-> (KeySpec -> KeySpec -> Bool)
-> (KeySpec -> KeySpec -> Bool)
-> (KeySpec -> KeySpec -> Bool)
-> (KeySpec -> KeySpec -> KeySpec)
-> (KeySpec -> KeySpec -> KeySpec)
-> Ord KeySpec
KeySpec -> KeySpec -> Bool
KeySpec -> KeySpec -> Ordering
KeySpec -> KeySpec -> KeySpec
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: KeySpec -> KeySpec -> KeySpec
$cmin :: KeySpec -> KeySpec -> KeySpec
max :: KeySpec -> KeySpec -> KeySpec
$cmax :: KeySpec -> KeySpec -> KeySpec
>= :: KeySpec -> KeySpec -> Bool
$c>= :: KeySpec -> KeySpec -> Bool
> :: KeySpec -> KeySpec -> Bool
$c> :: KeySpec -> KeySpec -> Bool
<= :: KeySpec -> KeySpec -> Bool
$c<= :: KeySpec -> KeySpec -> Bool
< :: KeySpec -> KeySpec -> Bool
$c< :: KeySpec -> KeySpec -> Bool
compare :: KeySpec -> KeySpec -> Ordering
$ccompare :: KeySpec -> KeySpec -> Ordering
$cp1Ord :: Eq KeySpec
Ord, Int -> KeySpec -> ShowS
[KeySpec] -> ShowS
KeySpec -> String
(Int -> KeySpec -> ShowS)
-> (KeySpec -> String) -> ([KeySpec] -> ShowS) -> Show KeySpec
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [KeySpec] -> ShowS
$cshowList :: [KeySpec] -> ShowS
show :: KeySpec -> String
$cshow :: KeySpec -> String
showsPrec :: Int -> KeySpec -> ShowS
$cshowsPrec :: Int -> KeySpec -> ShowS
Show, (forall x. KeySpec -> Rep KeySpec x)
-> (forall x. Rep KeySpec x -> KeySpec) -> Generic KeySpec
forall x. Rep KeySpec x -> KeySpec
forall x. KeySpec -> Rep KeySpec x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep KeySpec x -> KeySpec
$cfrom :: forall x. KeySpec -> Rep KeySpec x
Generic)
deriving anyclass Int -> KeySpec -> Builder ()
(Int -> KeySpec -> Builder ()) -> Print KeySpec
forall a. (Int -> a -> Builder ()) -> Print a
toUTF8BuilderP :: Int -> KeySpec -> Builder ()
$ctoUTF8BuilderP :: Int -> KeySpec -> Builder ()
T.Print
newBlockCipher :: HasCallStack => BlockCipherType -> IO BlockCipher
newBlockCipher :: BlockCipherType -> IO BlockCipher
newBlockCipher BlockCipherType
typ = do
let name :: CBytes
name = BlockCipherType -> CBytes
blockCipherTypeToCBytes BlockCipherType
typ
BotanStruct
bc <- (MBA# BotanStructT -> IO CInt)
-> FunPtr (BotanStructT -> IO ()) -> IO BotanStruct
forall a.
HasCallStack =>
(MBA# BotanStructT -> IO CInt)
-> FunPtr (BotanStructT -> IO a) -> IO BotanStruct
newBotanStruct
(\ MBA# BotanStructT
bts -> CBytes -> (BA# Word8 -> IO CInt) -> IO CInt
forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
withCBytesUnsafe CBytes
name (MBA# BotanStructT -> BA# Word8 -> IO CInt
botan_block_cipher_init MBA# BotanStructT
bts))
FunPtr (BotanStructT -> IO ())
botan_block_cipher_destroy
CInt
bsiz <- BotanStruct -> (BotanStructT -> IO CInt) -> IO CInt
forall a. BotanStruct -> (BotanStructT -> IO a) -> IO a
withBotanStruct BotanStruct
bc BotanStructT -> IO CInt
botan_block_cipher_block_size
(Int
a, (Int
b, (Int
c, ()
_))) <- BotanStruct
-> (BotanStructT -> IO (Int, (Int, (Int, ()))))
-> IO (Int, (Int, (Int, ())))
forall a. BotanStruct -> (BotanStructT -> IO a) -> IO a
withBotanStruct BotanStruct
bc ((BotanStructT -> IO (Int, (Int, (Int, ()))))
-> IO (Int, (Int, (Int, ()))))
-> (BotanStructT -> IO (Int, (Int, (Int, ()))))
-> IO (Int, (Int, (Int, ())))
forall a b. (a -> b) -> a -> b
$ \ BotanStructT
pbc ->
(MBA# BotanStructT -> IO (Int, (Int, ())))
-> IO (Int, (Int, (Int, ())))
forall a b. Prim a => (MBA# BotanStructT -> IO b) -> IO (a, b)
allocPrimUnsafe ((MBA# BotanStructT -> IO (Int, (Int, ())))
-> IO (Int, (Int, (Int, ()))))
-> (MBA# BotanStructT -> IO (Int, (Int, ())))
-> IO (Int, (Int, (Int, ())))
forall a b. (a -> b) -> a -> b
$ \ MBA# BotanStructT
pa ->
(MBA# BotanStructT -> IO (Int, ())) -> IO (Int, (Int, ()))
forall a b. Prim a => (MBA# BotanStructT -> IO b) -> IO (a, b)
allocPrimUnsafe ((MBA# BotanStructT -> IO (Int, ())) -> IO (Int, (Int, ())))
-> (MBA# BotanStructT -> IO (Int, ())) -> IO (Int, (Int, ()))
forall a b. (a -> b) -> a -> b
$ \ MBA# BotanStructT
pb ->
(MBA# BotanStructT -> IO ()) -> IO (Int, ())
forall a b. Prim a => (MBA# BotanStructT -> IO b) -> IO (a, b)
allocPrimUnsafe ((MBA# BotanStructT -> IO ()) -> IO (Int, ()))
-> (MBA# BotanStructT -> IO ()) -> IO (Int, ())
forall a b. (a -> b) -> a -> b
$ \ MBA# BotanStructT
pc ->
IO CInt -> IO ()
forall a. (HasCallStack, Integral a) => IO a -> IO ()
throwBotanIfMinus_
(BotanStructT
-> MBA# BotanStructT
-> MBA# BotanStructT
-> MBA# BotanStructT
-> IO CInt
botan_block_cipher_get_keyspec BotanStructT
pbc MBA# BotanStructT
pa MBA# BotanStructT
pb MBA# BotanStructT
pc)
BlockCipher -> IO BlockCipher
forall (m :: * -> *) a. Monad m => a -> m a
return (BotanStruct -> CBytes -> Int -> KeySpec -> BlockCipher
BlockCipher BotanStruct
bc CBytes
name (CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CInt
bsiz) (Int -> Int -> Int -> KeySpec
KeySpec Int
a Int
b Int
c))
setBlockCipherKey :: HasCallStack => BlockCipher -> V.Bytes -> IO ()
setBlockCipherKey :: BlockCipher -> Bytes -> IO ()
setBlockCipherKey (BlockCipher BotanStruct
bc CBytes
_ Int
_ KeySpec
_) Bytes
key =
BotanStruct -> (BotanStructT -> IO ()) -> IO ()
forall a. BotanStruct -> (BotanStructT -> IO a) -> IO a
withBotanStruct BotanStruct
bc ((BotanStructT -> IO ()) -> IO ())
-> (BotanStructT -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ BotanStructT
pbc -> do
Bytes -> (BA# Word8 -> Int -> Int -> IO ()) -> IO ()
forall a b.
Prim a =>
PrimVector a -> (BA# Word8 -> Int -> Int -> IO b) -> IO b
withPrimVectorUnsafe Bytes
key ((BA# Word8 -> Int -> Int -> IO ()) -> IO ())
-> (BA# Word8 -> Int -> Int -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ BA# Word8
pkey Int
key_off Int
key_len -> do
IO CInt -> IO ()
forall a. (HasCallStack, Integral a) => IO a -> IO ()
throwBotanIfMinus_ (BotanStructT -> BA# Word8 -> Int -> Int -> IO CInt
hs_botan_block_cipher_set_key
BotanStructT
pbc BA# Word8
pkey Int
key_off Int
key_len)
clearBlockCipher :: HasCallStack => BlockCipher -> IO ()
clearBlockCipher :: BlockCipher -> IO ()
clearBlockCipher (BlockCipher BotanStruct
bc CBytes
_ Int
_ KeySpec
_) =
BotanStruct -> (BotanStructT -> IO ()) -> IO ()
forall a. BotanStruct -> (BotanStructT -> IO a) -> IO a
withBotanStruct BotanStruct
bc (IO CInt -> IO ()
forall a. (HasCallStack, Integral a) => IO a -> IO ()
throwBotanIfMinus_ (IO CInt -> IO ())
-> (BotanStructT -> IO CInt) -> BotanStructT -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BotanStructT -> IO CInt
botan_block_cipher_clear)
encryptBlocks :: HasCallStack
=> BlockCipher
-> V.Bytes
-> Int
-> IO V.Bytes
encryptBlocks :: BlockCipher -> Bytes -> Int -> IO Bytes
encryptBlocks (BlockCipher BotanStruct
bc CBytes
_ Int
blockSiz KeySpec
_) Bytes
blocks Int
n = do
let inputLen :: Int
inputLen = Bytes -> Int
forall (v :: * -> *) a. Vec v a => v a -> Int
V.length Bytes
blocks
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
inputLen Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
blockSiz Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
n) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
CInt -> IO ()
forall x. HasCallStack => CInt -> IO x
throwBotanError CInt
BOTAN_FFI_ERROR_INVALID_INPUT
BotanStruct -> (BotanStructT -> IO Bytes) -> IO Bytes
forall a. BotanStruct -> (BotanStructT -> IO a) -> IO a
withBotanStruct BotanStruct
bc ((BotanStructT -> IO Bytes) -> IO Bytes)
-> (BotanStructT -> IO Bytes) -> IO Bytes
forall a b. (a -> b) -> a -> b
$ \ BotanStructT
pbc -> do
Bytes -> (BA# Word8 -> Int -> Int -> IO Bytes) -> IO Bytes
forall a b.
Prim a =>
PrimVector a -> (BA# Word8 -> Int -> Int -> IO b) -> IO b
withPrimVectorUnsafe Bytes
blocks ((BA# Word8 -> Int -> Int -> IO Bytes) -> IO Bytes)
-> (BA# Word8 -> Int -> Int -> IO Bytes) -> IO Bytes
forall a b. (a -> b) -> a -> b
$ \ BA# Word8
pb Int
pboff Int
_ ->
(Bytes, ()) -> Bytes
forall a b. (a, b) -> a
fst ((Bytes, ()) -> Bytes) -> IO (Bytes, ()) -> IO Bytes
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> (MBA# BotanStructT -> IO ()) -> IO (Bytes, ())
forall a b.
Prim a =>
Int -> (MBA# BotanStructT -> IO b) -> IO (PrimVector a, b)
allocPrimVectorUnsafe Int
inputLen (\ MBA# BotanStructT
pbuf ->
IO CInt -> IO ()
forall a. (HasCallStack, Integral a) => IO a -> IO ()
throwBotanIfMinus_ (BotanStructT
-> BA# Word8 -> Int -> MBA# BotanStructT -> Int -> IO CInt
hs_botan_block_cipher_encrypt_blocks
BotanStructT
pbc BA# Word8
pb Int
pboff MBA# BotanStructT
pbuf Int
n))
decryptBlocks :: HasCallStack
=> BlockCipher
-> V.Bytes
-> Int
-> IO V.Bytes
decryptBlocks :: BlockCipher -> Bytes -> Int -> IO Bytes
decryptBlocks (BlockCipher BotanStruct
bc CBytes
_ Int
blockSiz KeySpec
_) Bytes
blocks Int
n = do
let inputLen :: Int
inputLen = Bytes -> Int
forall (v :: * -> *) a. Vec v a => v a -> Int
V.length Bytes
blocks
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
inputLen Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
blockSiz Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
n) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
CInt -> IO ()
forall x. HasCallStack => CInt -> IO x
throwBotanError CInt
BOTAN_FFI_ERROR_INVALID_INPUT
BotanStruct -> (BotanStructT -> IO Bytes) -> IO Bytes
forall a. BotanStruct -> (BotanStructT -> IO a) -> IO a
withBotanStruct BotanStruct
bc ((BotanStructT -> IO Bytes) -> IO Bytes)
-> (BotanStructT -> IO Bytes) -> IO Bytes
forall a b. (a -> b) -> a -> b
$ \ BotanStructT
pbc -> do
Bytes -> (BA# Word8 -> Int -> Int -> IO Bytes) -> IO Bytes
forall a b.
Prim a =>
PrimVector a -> (BA# Word8 -> Int -> Int -> IO b) -> IO b
withPrimVectorUnsafe Bytes
blocks ((BA# Word8 -> Int -> Int -> IO Bytes) -> IO Bytes)
-> (BA# Word8 -> Int -> Int -> IO Bytes) -> IO Bytes
forall a b. (a -> b) -> a -> b
$ \ BA# Word8
pb Int
pboff Int
_ ->
(Bytes, ()) -> Bytes
forall a b. (a, b) -> a
fst ((Bytes, ()) -> Bytes) -> IO (Bytes, ()) -> IO Bytes
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> (MBA# BotanStructT -> IO ()) -> IO (Bytes, ())
forall a b.
Prim a =>
Int -> (MBA# BotanStructT -> IO b) -> IO (PrimVector a, b)
allocPrimVectorUnsafe Int
inputLen (\ MBA# BotanStructT
pbuf ->
IO CInt -> IO ()
forall a. (HasCallStack, Integral a) => IO a -> IO ()
throwBotanIfMinus_ (BotanStructT
-> BA# Word8 -> Int -> MBA# BotanStructT -> Int -> IO CInt
hs_botan_block_cipher_decrypt_blocks
BotanStructT
pbc BA# Word8
pb Int
pboff MBA# BotanStructT
pbuf Int
n))
data StreamCipherType
= CTR_BE BlockCipherType
| OFB BlockCipherType
| ChaCha8
| ChaCha12
| ChaCha20
| Salsa20
| SHAKE128'
| RC4
deriving (Int -> StreamCipherType -> ShowS
[StreamCipherType] -> ShowS
StreamCipherType -> String
(Int -> StreamCipherType -> ShowS)
-> (StreamCipherType -> String)
-> ([StreamCipherType] -> ShowS)
-> Show StreamCipherType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [StreamCipherType] -> ShowS
$cshowList :: [StreamCipherType] -> ShowS
show :: StreamCipherType -> String
$cshow :: StreamCipherType -> String
showsPrec :: Int -> StreamCipherType -> ShowS
$cshowsPrec :: Int -> StreamCipherType -> ShowS
Show, ReadPrec [StreamCipherType]
ReadPrec StreamCipherType
Int -> ReadS StreamCipherType
ReadS [StreamCipherType]
(Int -> ReadS StreamCipherType)
-> ReadS [StreamCipherType]
-> ReadPrec StreamCipherType
-> ReadPrec [StreamCipherType]
-> Read StreamCipherType
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [StreamCipherType]
$creadListPrec :: ReadPrec [StreamCipherType]
readPrec :: ReadPrec StreamCipherType
$creadPrec :: ReadPrec StreamCipherType
readList :: ReadS [StreamCipherType]
$creadList :: ReadS [StreamCipherType]
readsPrec :: Int -> ReadS StreamCipherType
$creadsPrec :: Int -> ReadS StreamCipherType
Read, StreamCipherType -> StreamCipherType -> Bool
(StreamCipherType -> StreamCipherType -> Bool)
-> (StreamCipherType -> StreamCipherType -> Bool)
-> Eq StreamCipherType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: StreamCipherType -> StreamCipherType -> Bool
$c/= :: StreamCipherType -> StreamCipherType -> Bool
== :: StreamCipherType -> StreamCipherType -> Bool
$c== :: StreamCipherType -> StreamCipherType -> Bool
Eq, Eq StreamCipherType
Eq StreamCipherType
-> (StreamCipherType -> StreamCipherType -> Ordering)
-> (StreamCipherType -> StreamCipherType -> Bool)
-> (StreamCipherType -> StreamCipherType -> Bool)
-> (StreamCipherType -> StreamCipherType -> Bool)
-> (StreamCipherType -> StreamCipherType -> Bool)
-> (StreamCipherType -> StreamCipherType -> StreamCipherType)
-> (StreamCipherType -> StreamCipherType -> StreamCipherType)
-> Ord StreamCipherType
StreamCipherType -> StreamCipherType -> Bool
StreamCipherType -> StreamCipherType -> Ordering
StreamCipherType -> StreamCipherType -> StreamCipherType
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: StreamCipherType -> StreamCipherType -> StreamCipherType
$cmin :: StreamCipherType -> StreamCipherType -> StreamCipherType
max :: StreamCipherType -> StreamCipherType -> StreamCipherType
$cmax :: StreamCipherType -> StreamCipherType -> StreamCipherType
>= :: StreamCipherType -> StreamCipherType -> Bool
$c>= :: StreamCipherType -> StreamCipherType -> Bool
> :: StreamCipherType -> StreamCipherType -> Bool
$c> :: StreamCipherType -> StreamCipherType -> Bool
<= :: StreamCipherType -> StreamCipherType -> Bool
$c<= :: StreamCipherType -> StreamCipherType -> Bool
< :: StreamCipherType -> StreamCipherType -> Bool
$c< :: StreamCipherType -> StreamCipherType -> Bool
compare :: StreamCipherType -> StreamCipherType -> Ordering
$ccompare :: StreamCipherType -> StreamCipherType -> Ordering
$cp1Ord :: Eq StreamCipherType
Ord, (forall x. StreamCipherType -> Rep StreamCipherType x)
-> (forall x. Rep StreamCipherType x -> StreamCipherType)
-> Generic StreamCipherType
forall x. Rep StreamCipherType x -> StreamCipherType
forall x. StreamCipherType -> Rep StreamCipherType x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep StreamCipherType x -> StreamCipherType
$cfrom :: forall x. StreamCipherType -> Rep StreamCipherType x
Generic)
deriving anyclass (Int -> StreamCipherType -> Builder ()
(Int -> StreamCipherType -> Builder ()) -> Print StreamCipherType
forall a. (Int -> a -> Builder ()) -> Print a
toUTF8BuilderP :: Int -> StreamCipherType -> Builder ()
$ctoUTF8BuilderP :: Int -> StreamCipherType -> Builder ()
T.Print, Value -> Converter StreamCipherType
StreamCipherType -> Value
StreamCipherType -> Builder ()
(Value -> Converter StreamCipherType)
-> (StreamCipherType -> Value)
-> (StreamCipherType -> Builder ())
-> JSON StreamCipherType
forall a.
(Value -> Converter a)
-> (a -> Value) -> (a -> Builder ()) -> JSON a
encodeJSON :: StreamCipherType -> Builder ()
$cencodeJSON :: StreamCipherType -> Builder ()
toValue :: StreamCipherType -> Value
$ctoValue :: StreamCipherType -> Value
fromValue :: Value -> Converter StreamCipherType
$cfromValue :: Value -> Converter StreamCipherType
JSON)
streamCipherTypeToCBytes :: StreamCipherType -> CBytes
streamCipherTypeToCBytes :: StreamCipherType -> CBytes
streamCipherTypeToCBytes StreamCipherType
s = case StreamCipherType
s of
CTR_BE BlockCipherType
b -> [CBytes] -> CBytes
CB.concat [CBytes
"CTR-BE(", BlockCipherType -> CBytes
blockCipherTypeToCBytes BlockCipherType
b, CBytes
")"]
OFB BlockCipherType
b -> [CBytes] -> CBytes
CB.concat [CBytes
"OFB(", BlockCipherType -> CBytes
blockCipherTypeToCBytes BlockCipherType
b, CBytes
")"]
StreamCipherType
ChaCha8 -> CBytes
"ChaCha(8)"
StreamCipherType
ChaCha12 -> CBytes
"ChaCha(12)"
StreamCipherType
ChaCha20 -> CBytes
"ChaCha(20)"
StreamCipherType
Salsa20 -> CBytes
"Salsa20"
StreamCipherType
SHAKE128' -> CBytes
"SHAKE-128"
StreamCipherType
RC4 -> CBytes
"RC4"
newStreamCipher :: HasCallStack => StreamCipherType -> CipherDirection -> IO Cipher
newStreamCipher :: StreamCipherType -> CipherDirection -> IO Cipher
newStreamCipher StreamCipherType
typ CipherDirection
dir = do
let name :: CBytes
name = StreamCipherType -> CBytes
streamCipherTypeToCBytes StreamCipherType
typ
BotanStruct
ci <- (MBA# BotanStructT -> IO CInt)
-> FunPtr (BotanStructT -> IO ()) -> IO BotanStruct
forall a.
HasCallStack =>
(MBA# BotanStructT -> IO CInt)
-> FunPtr (BotanStructT -> IO a) -> IO BotanStruct
newBotanStruct
(\ MBA# BotanStructT
bts -> CBytes -> (BA# Word8 -> IO CInt) -> IO CInt
forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
withCBytesUnsafe CBytes
name ((BA# Word8 -> IO CInt) -> IO CInt)
-> (BA# Word8 -> IO CInt) -> IO CInt
forall a b. (a -> b) -> a -> b
$ \ BA# Word8
pb ->
MBA# BotanStructT -> BA# Word8 -> Word32 -> IO CInt
botan_cipher_init MBA# BotanStructT
bts BA# Word8
pb (CipherDirection -> Word32
cipherDirectionToFlag CipherDirection
dir))
FunPtr (BotanStructT -> IO ())
botan_cipher_destroy
BotanStruct -> (BotanStructT -> IO Cipher) -> IO Cipher
forall a. BotanStruct -> (BotanStructT -> IO a) -> IO a
withBotanStruct BotanStruct
ci ((BotanStructT -> IO Cipher) -> IO Cipher)
-> (BotanStructT -> IO Cipher) -> IO Cipher
forall a b. (a -> b) -> a -> b
$ \ BotanStructT
pci -> do
(Int
g, CInt
_) <- (MBA# BotanStructT -> IO CInt) -> IO (Int, CInt)
forall a b. Prim a => (MBA# BotanStructT -> IO b) -> IO (a, b)
allocPrimUnsafe ((MBA# BotanStructT -> IO CInt) -> IO (Int, CInt))
-> (MBA# BotanStructT -> IO CInt) -> IO (Int, CInt)
forall a b. (a -> b) -> a -> b
$ \ MBA# BotanStructT
pg ->
BotanStructT -> MBA# BotanStructT -> IO CInt
botan_cipher_get_update_granularity BotanStructT
pci MBA# BotanStructT
pg
(Int
a, (Int
b, (Int
c, ()
_))) <- (MBA# BotanStructT -> IO (Int, (Int, ())))
-> IO (Int, (Int, (Int, ())))
forall a b. Prim a => (MBA# BotanStructT -> IO b) -> IO (a, b)
allocPrimUnsafe ((MBA# BotanStructT -> IO (Int, (Int, ())))
-> IO (Int, (Int, (Int, ()))))
-> (MBA# BotanStructT -> IO (Int, (Int, ())))
-> IO (Int, (Int, (Int, ())))
forall a b. (a -> b) -> a -> b
$ \ MBA# BotanStructT
pa ->
(MBA# BotanStructT -> IO (Int, ())) -> IO (Int, (Int, ()))
forall a b. Prim a => (MBA# BotanStructT -> IO b) -> IO (a, b)
allocPrimUnsafe ((MBA# BotanStructT -> IO (Int, ())) -> IO (Int, (Int, ())))
-> (MBA# BotanStructT -> IO (Int, ())) -> IO (Int, (Int, ()))
forall a b. (a -> b) -> a -> b
$ \ MBA# BotanStructT
pb ->
(MBA# BotanStructT -> IO ()) -> IO (Int, ())
forall a b. Prim a => (MBA# BotanStructT -> IO b) -> IO (a, b)
allocPrimUnsafe ((MBA# BotanStructT -> IO ()) -> IO (Int, ()))
-> (MBA# BotanStructT -> IO ()) -> IO (Int, ())
forall a b. (a -> b) -> a -> b
$ \ MBA# BotanStructT
pc ->
IO CInt -> IO ()
forall a. (HasCallStack, Integral a) => IO a -> IO ()
throwBotanIfMinus_
(BotanStructT
-> MBA# BotanStructT
-> MBA# BotanStructT
-> MBA# BotanStructT
-> IO CInt
botan_cipher_get_keyspec BotanStructT
pci MBA# BotanStructT
pa MBA# BotanStructT
pb MBA# BotanStructT
pc)
(Int
t, CInt
_) <- (MBA# BotanStructT -> IO CInt) -> IO (Int, CInt)
forall a b. Prim a => (MBA# BotanStructT -> IO b) -> IO (a, b)
allocPrimUnsafe ((MBA# BotanStructT -> IO CInt) -> IO (Int, CInt))
-> (MBA# BotanStructT -> IO CInt) -> IO (Int, CInt)
forall a b. (a -> b) -> a -> b
$ \ MBA# BotanStructT
pt ->
BotanStructT -> MBA# BotanStructT -> IO CInt
botan_cipher_get_tag_length BotanStructT
pci MBA# BotanStructT
pt
(Int
n, CInt
_) <- (MBA# BotanStructT -> IO CInt) -> IO (Int, CInt)
forall a b. Prim a => (MBA# BotanStructT -> IO b) -> IO (a, b)
allocPrimUnsafe ((MBA# BotanStructT -> IO CInt) -> IO (Int, CInt))
-> (MBA# BotanStructT -> IO CInt) -> IO (Int, CInt)
forall a b. (a -> b) -> a -> b
$ \ MBA# BotanStructT
pn ->
BotanStructT -> MBA# BotanStructT -> IO CInt
botan_cipher_get_default_nonce_length BotanStructT
pci MBA# BotanStructT
pn
Cipher -> IO Cipher
forall (m :: * -> *) a. Monad m => a -> m a
return (BotanStruct -> CBytes -> Int -> KeySpec -> Int -> Int -> Cipher
Cipher BotanStruct
ci CBytes
name Int
g (Int -> Int -> Int -> KeySpec
KeySpec Int
a Int
b Int
c) Int
t Int
n)
data CipherMode
= ChaCha20Poly1305
| GCM BlockCipherType
| OCB BlockCipherType
| EAX BlockCipherType
| SIV BlockCipherType
| CCM BlockCipherType
| CFB BlockCipherType Int
| XTS BlockCipherType
| CBC_PKCS7 BlockCipherType
| CBC_OneAndZeros BlockCipherType
| CBC_X9'23 BlockCipherType
| CBC_ESP BlockCipherType
| CBC_CTS BlockCipherType
| CBC_NoPadding BlockCipherType
deriving (Int -> CipherMode -> ShowS
[CipherMode] -> ShowS
CipherMode -> String
(Int -> CipherMode -> ShowS)
-> (CipherMode -> String)
-> ([CipherMode] -> ShowS)
-> Show CipherMode
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CipherMode] -> ShowS
$cshowList :: [CipherMode] -> ShowS
show :: CipherMode -> String
$cshow :: CipherMode -> String
showsPrec :: Int -> CipherMode -> ShowS
$cshowsPrec :: Int -> CipherMode -> ShowS
Show, ReadPrec [CipherMode]
ReadPrec CipherMode
Int -> ReadS CipherMode
ReadS [CipherMode]
(Int -> ReadS CipherMode)
-> ReadS [CipherMode]
-> ReadPrec CipherMode
-> ReadPrec [CipherMode]
-> Read CipherMode
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [CipherMode]
$creadListPrec :: ReadPrec [CipherMode]
readPrec :: ReadPrec CipherMode
$creadPrec :: ReadPrec CipherMode
readList :: ReadS [CipherMode]
$creadList :: ReadS [CipherMode]
readsPrec :: Int -> ReadS CipherMode
$creadsPrec :: Int -> ReadS CipherMode
Read, CipherMode -> CipherMode -> Bool
(CipherMode -> CipherMode -> Bool)
-> (CipherMode -> CipherMode -> Bool) -> Eq CipherMode
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CipherMode -> CipherMode -> Bool
$c/= :: CipherMode -> CipherMode -> Bool
== :: CipherMode -> CipherMode -> Bool
$c== :: CipherMode -> CipherMode -> Bool
Eq, Eq CipherMode
Eq CipherMode
-> (CipherMode -> CipherMode -> Ordering)
-> (CipherMode -> CipherMode -> Bool)
-> (CipherMode -> CipherMode -> Bool)
-> (CipherMode -> CipherMode -> Bool)
-> (CipherMode -> CipherMode -> Bool)
-> (CipherMode -> CipherMode -> CipherMode)
-> (CipherMode -> CipherMode -> CipherMode)
-> Ord CipherMode
CipherMode -> CipherMode -> Bool
CipherMode -> CipherMode -> Ordering
CipherMode -> CipherMode -> CipherMode
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: CipherMode -> CipherMode -> CipherMode
$cmin :: CipherMode -> CipherMode -> CipherMode
max :: CipherMode -> CipherMode -> CipherMode
$cmax :: CipherMode -> CipherMode -> CipherMode
>= :: CipherMode -> CipherMode -> Bool
$c>= :: CipherMode -> CipherMode -> Bool
> :: CipherMode -> CipherMode -> Bool
$c> :: CipherMode -> CipherMode -> Bool
<= :: CipherMode -> CipherMode -> Bool
$c<= :: CipherMode -> CipherMode -> Bool
< :: CipherMode -> CipherMode -> Bool
$c< :: CipherMode -> CipherMode -> Bool
compare :: CipherMode -> CipherMode -> Ordering
$ccompare :: CipherMode -> CipherMode -> Ordering
$cp1Ord :: Eq CipherMode
Ord, (forall x. CipherMode -> Rep CipherMode x)
-> (forall x. Rep CipherMode x -> CipherMode) -> Generic CipherMode
forall x. Rep CipherMode x -> CipherMode
forall x. CipherMode -> Rep CipherMode x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep CipherMode x -> CipherMode
$cfrom :: forall x. CipherMode -> Rep CipherMode x
Generic)
deriving anyclass (Int -> CipherMode -> Builder ()
(Int -> CipherMode -> Builder ()) -> Print CipherMode
forall a. (Int -> a -> Builder ()) -> Print a
toUTF8BuilderP :: Int -> CipherMode -> Builder ()
$ctoUTF8BuilderP :: Int -> CipherMode -> Builder ()
T.Print, Value -> Converter CipherMode
CipherMode -> Value
CipherMode -> Builder ()
(Value -> Converter CipherMode)
-> (CipherMode -> Value)
-> (CipherMode -> Builder ())
-> JSON CipherMode
forall a.
(Value -> Converter a)
-> (a -> Value) -> (a -> Builder ()) -> JSON a
encodeJSON :: CipherMode -> Builder ()
$cencodeJSON :: CipherMode -> Builder ()
toValue :: CipherMode -> Value
$ctoValue :: CipherMode -> Value
fromValue :: Value -> Converter CipherMode
$cfromValue :: Value -> Converter CipherMode
JSON)
cipherTypeToCBytes :: CipherMode -> CBytes
cipherTypeToCBytes :: CipherMode -> CBytes
cipherTypeToCBytes CipherMode
ct = case CipherMode
ct of
CipherMode
ChaCha20Poly1305 -> CBytes
"ChaCha20Poly1305"
GCM BlockCipherType
bct -> BlockCipherType -> CBytes
blockCipherTypeToCBytes BlockCipherType
bct CBytes -> CBytes -> CBytes
forall a. Semigroup a => a -> a -> a
<> CBytes
"/GCM"
OCB BlockCipherType
bct -> BlockCipherType -> CBytes
blockCipherTypeToCBytes BlockCipherType
bct CBytes -> CBytes -> CBytes
forall a. Semigroup a => a -> a -> a
<> CBytes
"/OCB"
EAX BlockCipherType
bct -> BlockCipherType -> CBytes
blockCipherTypeToCBytes BlockCipherType
bct CBytes -> CBytes -> CBytes
forall a. Semigroup a => a -> a -> a
<> CBytes
"/EAX"
SIV BlockCipherType
bct -> BlockCipherType -> CBytes
blockCipherTypeToCBytes BlockCipherType
bct CBytes -> CBytes -> CBytes
forall a. Semigroup a => a -> a -> a
<> CBytes
"/SIV"
CCM BlockCipherType
bct -> BlockCipherType -> CBytes
blockCipherTypeToCBytes BlockCipherType
bct CBytes -> CBytes -> CBytes
forall a. Semigroup a => a -> a -> a
<> CBytes
"/CCM"
CFB BlockCipherType
bct Int
0 -> BlockCipherType -> CBytes
blockCipherTypeToCBytes BlockCipherType
bct CBytes -> CBytes -> CBytes
forall a. Semigroup a => a -> a -> a
<> CBytes
"/CFB"
CFB BlockCipherType
bct Int
x -> [CBytes] -> CBytes
CB.concat [ BlockCipherType -> CBytes
blockCipherTypeToCBytes BlockCipherType
bct
, CBytes
"/CFB("
, Text -> CBytes
CB.fromText (Int -> Text
forall a. Print a => a -> Text
T.toText Int
x)
, CBytes
")"
]
XTS BlockCipherType
bct -> BlockCipherType -> CBytes
blockCipherTypeToCBytes BlockCipherType
bct CBytes -> CBytes -> CBytes
forall a. Semigroup a => a -> a -> a
<> CBytes
"/XTS"
CBC_PKCS7 BlockCipherType
bct -> BlockCipherType -> CBytes
blockCipherTypeToCBytes BlockCipherType
bct CBytes -> CBytes -> CBytes
forall a. Semigroup a => a -> a -> a
<> CBytes
"/CBC/PKCS7"
CBC_OneAndZeros BlockCipherType
bct -> BlockCipherType -> CBytes
blockCipherTypeToCBytes BlockCipherType
bct CBytes -> CBytes -> CBytes
forall a. Semigroup a => a -> a -> a
<> CBytes
"/CBC/OneAndZeros"
CBC_X9'23 BlockCipherType
bct -> BlockCipherType -> CBytes
blockCipherTypeToCBytes BlockCipherType
bct CBytes -> CBytes -> CBytes
forall a. Semigroup a => a -> a -> a
<> CBytes
"/CBC/X9.23"
CBC_ESP BlockCipherType
bct -> BlockCipherType -> CBytes
blockCipherTypeToCBytes BlockCipherType
bct CBytes -> CBytes -> CBytes
forall a. Semigroup a => a -> a -> a
<> CBytes
"/CBC/ESP"
CBC_CTS BlockCipherType
bct -> BlockCipherType -> CBytes
blockCipherTypeToCBytes BlockCipherType
bct CBytes -> CBytes -> CBytes
forall a. Semigroup a => a -> a -> a
<> CBytes
"/CBC/CTS"
CBC_NoPadding BlockCipherType
bct -> BlockCipherType -> CBytes
blockCipherTypeToCBytes BlockCipherType
bct CBytes -> CBytes -> CBytes
forall a. Semigroup a => a -> a -> a
<> CBytes
"/CBC/NoPadding"
data Cipher = Cipher
{ Cipher -> BotanStruct
cipher :: {-# UNPACK #-} !BotanStruct
, Cipher -> CBytes
cipherName :: {-# UNPACK #-} !CBytes
, Cipher -> Int
cipherUpdateGranularity :: {-# UNPACK #-} !Int
, Cipher -> KeySpec
cipherKeySpec :: {-# UNPACK #-} !KeySpec
, Cipher -> Int
cipherTagLength :: {-# UNPACK #-} !Int
, Cipher -> Int
defaultNonceLength :: {-# UNPACK #-} !Int
}
deriving (Int -> Cipher -> ShowS
[Cipher] -> ShowS
Cipher -> String
(Int -> Cipher -> ShowS)
-> (Cipher -> String) -> ([Cipher] -> ShowS) -> Show Cipher
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Cipher] -> ShowS
$cshowList :: [Cipher] -> ShowS
show :: Cipher -> String
$cshow :: Cipher -> String
showsPrec :: Int -> Cipher -> ShowS
$cshowsPrec :: Int -> Cipher -> ShowS
Show, (forall x. Cipher -> Rep Cipher x)
-> (forall x. Rep Cipher x -> Cipher) -> Generic Cipher
forall x. Rep Cipher x -> Cipher
forall x. Cipher -> Rep Cipher x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Cipher x -> Cipher
$cfrom :: forall x. Cipher -> Rep Cipher x
Generic)
deriving anyclass Int -> Cipher -> Builder ()
(Int -> Cipher -> Builder ()) -> Print Cipher
forall a. (Int -> a -> Builder ()) -> Print a
toUTF8BuilderP :: Int -> Cipher -> Builder ()
$ctoUTF8BuilderP :: Int -> Cipher -> Builder ()
T.Print
withCipher :: HasCallStack => Cipher -> (BotanStructT -> IO r) -> IO r
withCipher :: Cipher -> (BotanStructT -> IO r) -> IO r
withCipher (Cipher BotanStruct
c CBytes
_ Int
_ KeySpec
_ Int
_ Int
_) = BotanStruct -> (BotanStructT -> IO r) -> IO r
forall a. BotanStruct -> (BotanStructT -> IO a) -> IO a
withBotanStruct BotanStruct
c
newCipher :: HasCallStack => CipherMode -> CipherDirection -> IO Cipher
newCipher :: CipherMode -> CipherDirection -> IO Cipher
newCipher CipherMode
typ CipherDirection
dir = do
let name :: CBytes
name = CipherMode -> CBytes
cipherTypeToCBytes CipherMode
typ
BotanStruct
ci <- (MBA# BotanStructT -> IO CInt)
-> FunPtr (BotanStructT -> IO ()) -> IO BotanStruct
forall a.
HasCallStack =>
(MBA# BotanStructT -> IO CInt)
-> FunPtr (BotanStructT -> IO a) -> IO BotanStruct
newBotanStruct
(\ MBA# BotanStructT
bts -> CBytes -> (BA# Word8 -> IO CInt) -> IO CInt
forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
withCBytesUnsafe CBytes
name ((BA# Word8 -> IO CInt) -> IO CInt)
-> (BA# Word8 -> IO CInt) -> IO CInt
forall a b. (a -> b) -> a -> b
$ \ BA# Word8
pb ->
MBA# BotanStructT -> BA# Word8 -> Word32 -> IO CInt
botan_cipher_init MBA# BotanStructT
bts BA# Word8
pb (CipherDirection -> Word32
cipherDirectionToFlag CipherDirection
dir))
FunPtr (BotanStructT -> IO ())
botan_cipher_destroy
BotanStruct -> (BotanStructT -> IO Cipher) -> IO Cipher
forall a. BotanStruct -> (BotanStructT -> IO a) -> IO a
withBotanStruct BotanStruct
ci ((BotanStructT -> IO Cipher) -> IO Cipher)
-> (BotanStructT -> IO Cipher) -> IO Cipher
forall a b. (a -> b) -> a -> b
$ \ BotanStructT
pci -> do
(Int
g, CInt
_) <- (MBA# BotanStructT -> IO CInt) -> IO (Int, CInt)
forall a b. Prim a => (MBA# BotanStructT -> IO b) -> IO (a, b)
allocPrimUnsafe ((MBA# BotanStructT -> IO CInt) -> IO (Int, CInt))
-> (MBA# BotanStructT -> IO CInt) -> IO (Int, CInt)
forall a b. (a -> b) -> a -> b
$ \ MBA# BotanStructT
pg ->
BotanStructT -> MBA# BotanStructT -> IO CInt
botan_cipher_get_update_granularity BotanStructT
pci MBA# BotanStructT
pg
(Int
a, (Int
b, (Int
c, ()
_))) <- (MBA# BotanStructT -> IO (Int, (Int, ())))
-> IO (Int, (Int, (Int, ())))
forall a b. Prim a => (MBA# BotanStructT -> IO b) -> IO (a, b)
allocPrimUnsafe ((MBA# BotanStructT -> IO (Int, (Int, ())))
-> IO (Int, (Int, (Int, ()))))
-> (MBA# BotanStructT -> IO (Int, (Int, ())))
-> IO (Int, (Int, (Int, ())))
forall a b. (a -> b) -> a -> b
$ \ MBA# BotanStructT
pa ->
(MBA# BotanStructT -> IO (Int, ())) -> IO (Int, (Int, ()))
forall a b. Prim a => (MBA# BotanStructT -> IO b) -> IO (a, b)
allocPrimUnsafe ((MBA# BotanStructT -> IO (Int, ())) -> IO (Int, (Int, ())))
-> (MBA# BotanStructT -> IO (Int, ())) -> IO (Int, (Int, ()))
forall a b. (a -> b) -> a -> b
$ \ MBA# BotanStructT
pb ->
(MBA# BotanStructT -> IO ()) -> IO (Int, ())
forall a b. Prim a => (MBA# BotanStructT -> IO b) -> IO (a, b)
allocPrimUnsafe ((MBA# BotanStructT -> IO ()) -> IO (Int, ()))
-> (MBA# BotanStructT -> IO ()) -> IO (Int, ())
forall a b. (a -> b) -> a -> b
$ \ MBA# BotanStructT
pc ->
IO CInt -> IO ()
forall a. (HasCallStack, Integral a) => IO a -> IO ()
throwBotanIfMinus_
(BotanStructT
-> MBA# BotanStructT
-> MBA# BotanStructT
-> MBA# BotanStructT
-> IO CInt
botan_cipher_get_keyspec BotanStructT
pci MBA# BotanStructT
pa MBA# BotanStructT
pb MBA# BotanStructT
pc)
(Int
t, CInt
_) <- (MBA# BotanStructT -> IO CInt) -> IO (Int, CInt)
forall a b. Prim a => (MBA# BotanStructT -> IO b) -> IO (a, b)
allocPrimUnsafe ((MBA# BotanStructT -> IO CInt) -> IO (Int, CInt))
-> (MBA# BotanStructT -> IO CInt) -> IO (Int, CInt)
forall a b. (a -> b) -> a -> b
$ \ MBA# BotanStructT
pt ->
BotanStructT -> MBA# BotanStructT -> IO CInt
botan_cipher_get_tag_length BotanStructT
pci MBA# BotanStructT
pt
(Int
n, CInt
_) <- (MBA# BotanStructT -> IO CInt) -> IO (Int, CInt)
forall a b. Prim a => (MBA# BotanStructT -> IO b) -> IO (a, b)
allocPrimUnsafe ((MBA# BotanStructT -> IO CInt) -> IO (Int, CInt))
-> (MBA# BotanStructT -> IO CInt) -> IO (Int, CInt)
forall a b. (a -> b) -> a -> b
$ \ MBA# BotanStructT
pn ->
BotanStructT -> MBA# BotanStructT -> IO CInt
botan_cipher_get_default_nonce_length BotanStructT
pci MBA# BotanStructT
pn
Cipher -> IO Cipher
forall (m :: * -> *) a. Monad m => a -> m a
return (BotanStruct -> CBytes -> Int -> KeySpec -> Int -> Int -> Cipher
Cipher BotanStruct
ci CBytes
name Int
g (Int -> Int -> Int -> KeySpec
KeySpec Int
a Int
b Int
c) Int
t Int
n)
clearCipher :: HasCallStack => Cipher -> IO ()
clearCipher :: Cipher -> IO ()
clearCipher (Cipher BotanStruct
ci CBytes
_ Int
_ KeySpec
_ Int
_ Int
_) =
BotanStruct -> (BotanStructT -> IO ()) -> IO ()
forall a. BotanStruct -> (BotanStructT -> IO a) -> IO a
withBotanStruct BotanStruct
ci (IO CInt -> IO ()
forall a. (HasCallStack, Integral a) => IO a -> IO ()
throwBotanIfMinus_ (IO CInt -> IO ())
-> (BotanStructT -> IO CInt) -> BotanStructT -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BotanStructT -> IO CInt
botan_cipher_clear)
resetCipher :: HasCallStack => Cipher -> IO ()
resetCipher :: Cipher -> IO ()
resetCipher (Cipher BotanStruct
ci CBytes
_ Int
_ KeySpec
_ Int
_ Int
_) =
BotanStruct -> (BotanStructT -> IO ()) -> IO ()
forall a. BotanStruct -> (BotanStructT -> IO a) -> IO a
withBotanStruct BotanStruct
ci (IO CInt -> IO ()
forall a. (HasCallStack, Integral a) => IO a -> IO ()
throwBotanIfMinus_ (IO CInt -> IO ())
-> (BotanStructT -> IO CInt) -> BotanStructT -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BotanStructT -> IO CInt
botan_cipher_reset)
setCipherKey :: HasCallStack => Cipher -> V.Bytes -> IO ()
setCipherKey :: Cipher -> Bytes -> IO ()
setCipherKey (Cipher BotanStruct
ci CBytes
_ Int
_ KeySpec
_ Int
_ Int
_) Bytes
key =
BotanStruct -> (BotanStructT -> IO ()) -> IO ()
forall a. BotanStruct -> (BotanStructT -> IO a) -> IO a
withBotanStruct BotanStruct
ci ((BotanStructT -> IO ()) -> IO ())
-> (BotanStructT -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ BotanStructT
pci -> do
Bytes -> (BA# Word8 -> Int -> Int -> IO ()) -> IO ()
forall a b.
Prim a =>
PrimVector a -> (BA# Word8 -> Int -> Int -> IO b) -> IO b
withPrimVectorUnsafe Bytes
key ((BA# Word8 -> Int -> Int -> IO ()) -> IO ())
-> (BA# Word8 -> Int -> Int -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ BA# Word8
pkey Int
key_off Int
key_len -> do
IO CInt -> IO ()
forall a. (HasCallStack, Integral a) => IO a -> IO ()
throwBotanIfMinus_ (BotanStructT -> BA# Word8 -> Int -> Int -> IO CInt
hs_botan_cipher_set_key
BotanStructT
pci BA# Word8
pkey Int
key_off Int
key_len)
setAssociatedData :: HasCallStack => Cipher -> V.Bytes -> IO ()
setAssociatedData :: Cipher -> Bytes -> IO ()
setAssociatedData (Cipher BotanStruct
ci CBytes
_ Int
_ KeySpec
_ Int
_ Int
_) Bytes
ad =
BotanStruct -> (BotanStructT -> IO ()) -> IO ()
forall a. BotanStruct -> (BotanStructT -> IO a) -> IO a
withBotanStruct BotanStruct
ci ((BotanStructT -> IO ()) -> IO ())
-> (BotanStructT -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ BotanStructT
pci -> do
Bytes -> (BA# Word8 -> Int -> Int -> IO ()) -> IO ()
forall a b.
Prim a =>
PrimVector a -> (BA# Word8 -> Int -> Int -> IO b) -> IO b
withPrimVectorUnsafe Bytes
ad ((BA# Word8 -> Int -> Int -> IO ()) -> IO ())
-> (BA# Word8 -> Int -> Int -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ BA# Word8
pad Int
ad_off Int
ad_len -> do
IO CInt -> IO ()
forall a. (HasCallStack, Integral a) => IO a -> IO ()
throwBotanIfMinus_ (BotanStructT -> BA# Word8 -> Int -> Int -> IO CInt
hs_botan_cipher_set_associated_data
BotanStructT
pci BA# Word8
pad Int
ad_off Int
ad_len)
startCipher :: HasCallStack
=> Cipher
-> V.Bytes
-> IO ()
startCipher :: Cipher -> Bytes -> IO ()
startCipher (Cipher BotanStruct
ci CBytes
_ Int
_ KeySpec
_ Int
_ Int
_) Bytes
nonce =
BotanStruct -> (BotanStructT -> IO ()) -> IO ()
forall a. BotanStruct -> (BotanStructT -> IO a) -> IO a
withBotanStruct BotanStruct
ci ((BotanStructT -> IO ()) -> IO ())
-> (BotanStructT -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ BotanStructT
pci -> do
Bytes -> (BA# Word8 -> Int -> Int -> IO ()) -> IO ()
forall a b.
Prim a =>
PrimVector a -> (BA# Word8 -> Int -> Int -> IO b) -> IO b
withPrimVectorUnsafe Bytes
nonce ((BA# Word8 -> Int -> Int -> IO ()) -> IO ())
-> (BA# Word8 -> Int -> Int -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ BA# Word8
pnonce Int
nonce_off Int
nonce_len -> do
IO CInt -> IO ()
forall a. (HasCallStack, Integral a) => IO a -> IO ()
throwBotanIfMinus_ (BotanStructT -> BA# Word8 -> Int -> Int -> IO CInt
hs_botan_cipher_start
BotanStructT
pci BA# Word8
pnonce Int
nonce_off Int
nonce_len)
updateCipher :: HasCallStack
=> Cipher
-> V.Bytes
-> IO (V.Bytes, V.Bytes)
updateCipher :: Cipher -> Bytes -> IO (Bytes, Bytes)
updateCipher (Cipher BotanStruct
ci CBytes
_ Int
_ KeySpec
_ Int
_ Int
_) Bytes
input =
BotanStruct
-> (BotanStructT -> IO (Bytes, Bytes)) -> IO (Bytes, Bytes)
forall a. BotanStruct -> (BotanStructT -> IO a) -> IO a
withBotanStruct BotanStruct
ci ((BotanStructT -> IO (Bytes, Bytes)) -> IO (Bytes, Bytes))
-> (BotanStructT -> IO (Bytes, Bytes)) -> IO (Bytes, Bytes)
forall a b. (a -> b) -> a -> b
$ \ BotanStructT
pci -> do
Bytes
-> (BA# Word8 -> Int -> Int -> IO (Bytes, Bytes))
-> IO (Bytes, Bytes)
forall a b.
Prim a =>
PrimVector a -> (BA# Word8 -> Int -> Int -> IO b) -> IO b
withPrimVectorUnsafe Bytes
input ((BA# Word8 -> Int -> Int -> IO (Bytes, Bytes))
-> IO (Bytes, Bytes))
-> (BA# Word8 -> Int -> Int -> IO (Bytes, Bytes))
-> IO (Bytes, Bytes)
forall a b. (a -> b) -> a -> b
$ \ BA# Word8
in_p Int
in_off Int
in_len -> do
(Bytes
out, Int
r) <- Int -> (MBA# BotanStructT -> IO Int) -> IO (Bytes, Int)
forall a b.
Prim a =>
Int -> (MBA# BotanStructT -> IO b) -> IO (PrimVector a, b)
allocPrimVectorUnsafe Int
in_len ((MBA# BotanStructT -> IO Int) -> IO (Bytes, Int))
-> (MBA# BotanStructT -> IO Int) -> IO (Bytes, Int)
forall a b. (a -> b) -> a -> b
$ \ MBA# BotanStructT
out_p ->
IO Int -> IO Int
forall a. (HasCallStack, Integral a) => IO a -> IO a
throwBotanIfMinus (BotanStructT
-> MBA# BotanStructT -> BA# Word8 -> Int -> Int -> IO Int
hs_botan_cipher_update BotanStructT
pci
MBA# BotanStructT
out_p BA# Word8
in_p Int
in_off Int
in_len)
(Bytes, Bytes) -> IO (Bytes, Bytes)
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> Bytes -> Bytes
forall (v :: * -> *) a. Vec v a => Int -> v a -> v a
V.unsafeDrop Int
r Bytes
input, Int -> Bytes -> Bytes
forall (v :: * -> *) a. Vec v a => Int -> v a -> v a
V.unsafeTake Int
r Bytes
out)
finishCipher :: HasCallStack
=> Cipher
-> V.Bytes
-> IO V.Bytes
finishCipher :: Cipher -> Bytes -> IO Bytes
finishCipher (Cipher BotanStruct
ci CBytes
_ Int
ug KeySpec
_ Int
tag_len Int
_) Bytes
input =
BotanStruct -> (BotanStructT -> IO Bytes) -> IO Bytes
forall a. BotanStruct -> (BotanStructT -> IO a) -> IO a
withBotanStruct BotanStruct
ci ((BotanStructT -> IO Bytes) -> IO Bytes)
-> (BotanStructT -> IO Bytes) -> IO Bytes
forall a b. (a -> b) -> a -> b
$ \ BotanStructT
pci -> do
Bytes -> (BA# Word8 -> Int -> Int -> IO Bytes) -> IO Bytes
forall a b.
Prim a =>
PrimVector a -> (BA# Word8 -> Int -> Int -> IO b) -> IO b
withPrimVectorUnsafe Bytes
input ((BA# Word8 -> Int -> Int -> IO Bytes) -> IO Bytes)
-> (BA# Word8 -> Int -> Int -> IO Bytes) -> IO Bytes
forall a b. (a -> b) -> a -> b
$ \ BA# Word8
in_p Int
in_off Int
in_len -> do
let !out_len :: Int
out_len = Int
in_len Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
ug Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
tag_len
(PrimArray Word8
pa, Int
r) <- Int -> (MBA# BotanStructT -> IO Int) -> IO (PrimArray Word8, Int)
forall a b.
Prim a =>
Int -> (MBA# BotanStructT -> IO b) -> IO (PrimArray a, b)
allocPrimArrayUnsafe Int
out_len ((MBA# BotanStructT -> IO Int) -> IO (PrimArray Word8, Int))
-> (MBA# BotanStructT -> IO Int) -> IO (PrimArray Word8, Int)
forall a b. (a -> b) -> a -> b
$ \ MBA# BotanStructT
out_p -> do
IO Int -> IO Int
forall a. (HasCallStack, Integral a) => IO a -> IO a
throwBotanIfMinus (BotanStructT
-> MBA# BotanStructT -> Int -> BA# Word8 -> Int -> Int -> IO Int
hs_botan_cipher_finish BotanStructT
pci
MBA# BotanStructT
out_p Int
out_len BA# Word8
in_p Int
in_off Int
in_len)
MutablePrimArray RealWorld Word8
mpa <- PrimArray Word8 -> IO (MutablePrimArray (PrimState IO) Word8)
forall (m :: * -> *) a.
PrimMonad m =>
PrimArray a -> m (MutablePrimArray (PrimState m) a)
unsafeThawPrimArray PrimArray Word8
pa
MutablePrimArray (PrimState IO) Word8 -> Int -> IO ()
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
MutablePrimArray (PrimState m) a -> Int -> m ()
shrinkMutablePrimArray MutablePrimArray RealWorld Word8
MutablePrimArray (PrimState IO) Word8
mpa Int
r
PrimArray Word8
pa' <- MutablePrimArray (PrimState IO) Word8 -> IO (PrimArray Word8)
forall (m :: * -> *) a.
PrimMonad m =>
MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreezePrimArray MutablePrimArray RealWorld Word8
MutablePrimArray (PrimState IO) Word8
mpa
Bytes -> IO Bytes
forall (m :: * -> *) a. Monad m => a -> m a
return (PrimArray Word8 -> Int -> Int -> Bytes
forall a. PrimArray a -> Int -> Int -> PrimVector a
V.PrimVector PrimArray Word8
pa' Int
0 Int
r)
cipherBIO :: HasCallStack => Cipher -> IO (BIO V.Bytes V.Bytes)
cipherBIO :: Cipher -> IO (BIO Bytes Bytes)
cipherBIO Cipher
c = do
IORef Bytes
trailingRef <- Bytes -> IO (IORef Bytes)
forall a. a -> IO (IORef a)
newIORef Bytes
forall (v :: * -> *) a. Vec v a => v a
V.empty
BIO Bytes Bytes -> IO (BIO Bytes Bytes)
forall (m :: * -> *) a. Monad m => a -> m a
return (BIO Bytes Bytes -> IO (BIO Bytes Bytes))
-> BIO Bytes Bytes -> IO (BIO Bytes Bytes)
forall a b. (a -> b) -> a -> b
$ \ Maybe Bytes -> IO ()
k Maybe Bytes
mbs -> case Maybe Bytes
mbs of
Just Bytes
bs -> do
Bytes
trailing <- IORef Bytes -> IO Bytes
forall a. IORef a -> IO a
readIORef IORef Bytes
trailingRef
let chunk :: Bytes
chunk = Bytes
trailing Bytes -> Bytes -> Bytes
forall (v :: * -> *) a. Vec v a => v a -> v a -> v a
`V.append` Bytes
bs
(Bytes
rest, Bytes
out) <- HasCallStack => Cipher -> Bytes -> IO (Bytes, Bytes)
Cipher -> Bytes -> IO (Bytes, Bytes)
updateCipher Cipher
c Bytes
chunk
IORef Bytes -> Bytes -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef Bytes
trailingRef Bytes
rest
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Bytes -> Bool
forall (v :: * -> *) a. Vec v a => v a -> Bool
V.null Bytes
out) (Maybe Bytes -> IO ()
k (Bytes -> Maybe Bytes
forall a. a -> Maybe a
Just Bytes
out))
Maybe Bytes
_ -> do
Bytes
trailing <- IORef Bytes -> IO Bytes
forall a. IORef a -> IO a
readIORef IORef Bytes
trailingRef
Bytes
bs <- HasCallStack => Cipher -> Bytes -> IO Bytes
Cipher -> Bytes -> IO Bytes
finishCipher Cipher
c Bytes
trailing
if Bytes -> Bool
forall (v :: * -> *) a. Vec v a => v a -> Bool
V.null Bytes
bs
then Maybe Bytes -> IO ()
k (Bytes -> Maybe Bytes
forall a. a -> Maybe a
Just Bytes
bs) IO () -> IO () -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Maybe Bytes -> IO ()
k Maybe Bytes
forall a. Maybe a
EOF
else Maybe Bytes -> IO ()
k Maybe Bytes
forall a. Maybe a
EOF