{-# OPTIONS_HADDOCK hide #-}
{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FlexibleContexts #-}

module Crypto.Nettle.Ciphers.Internal
	( NettleCipher(..)
	, NettleBlockCipher(..)
	, NettleStreamCipher(..)
	, NettleBlockedStreamCipher(..)
	, NettleGCM
	, nettle_cipherInit
	, nettle_cipherInit'
	, nettle_ecbEncrypt
	, nettle_ecbDecrypt
	, nettle_cbcEncrypt
	, nettle_cbcDecrypt
	, nettle_cfbEncrypt
	, nettle_cfbDecrypt
	, nettle_ctrCombine
	, nettle_streamCombine
	, nettle_streamSetNonce
	, nettle_blockedStreamCombine
	, nettle_blockedStreamSetNonce
	, nettle_gcm_aeadInit
	, nettle_gcm_aeadStateAppendHeader
	, nettle_gcm_aeadStateEncrypt
	, nettle_gcm_aeadStateDecrypt
	, nettle_gcm_aeadStateFinalize
	) where

import Crypto.Cipher.Types as T

import Data.Tagged
import Data.Byteable (Byteable(..))
import Data.SecureMem
import qualified Data.ByteString as B
import qualified Data.ByteString.Internal as B
import Data.Bits (xor)

import Nettle.Utils
import Crypto.Nettle.Ciphers.ForeignImports

-- internal functions are not camelCase on purpose
{-# ANN module "HLint: ignore Use camelCase" #-}

class NettleCipher c where
	-- | pointer to new context, key length, (const) key pointer
	nc_cipherInit    :: Tagged c (Ptr Word8 -> Word -> Ptr Word8 -> IO())
	nc_cipherName    :: Tagged c String
	nc_cipherKeySize :: Tagged c T.KeySizeSpecifier
	nc_ctx_size      :: Tagged c Int
	nc_ctx           :: c -> SecureMem
	nc_Ctx           :: SecureMem -> c
class NettleCipher c => NettleBlockCipher c where
	nbc_blockSize          :: Tagged c Int
	nbc_encrypt_ctx_offset :: Tagged c (Ptr Word8 -> Ptr Word8)
	nbc_encrypt_ctx_offset = (Ptr Word8 -> Ptr Word8) -> Tagged c (Ptr Word8 -> Ptr Word8)
forall k (s :: k) b. b -> Tagged s b
Tagged Ptr Word8 -> Ptr Word8
forall a. a -> a
id
	nbc_decrypt_ctx_offset :: Tagged c (Ptr Word8 -> Ptr Word8)
	nbc_decrypt_ctx_offset = (Ptr Word8 -> Ptr Word8) -> Tagged c (Ptr Word8 -> Ptr Word8)
forall k (s :: k) b. b -> Tagged s b
Tagged Ptr Word8 -> Ptr Word8
forall a. a -> a
id
	nbc_ecb_encrypt        :: Tagged c NettleCryptFunc
	nbc_ecb_decrypt        :: Tagged c NettleCryptFunc
	nbc_fun_encrypt        :: Tagged c (FunPtr NettleCryptFunc)
	nbc_fun_decrypt        :: Tagged c (FunPtr NettleCryptFunc)
class NettleCipher c => NettleStreamCipher c where
	nsc_streamCombine      :: Tagged c NettleCryptFunc
	nsc_nonceSize          :: Tagged c T.KeySizeSpecifier
	nsc_nonceSize          = KeySizeSpecifier -> Tagged c KeySizeSpecifier
forall k (s :: k) b. b -> Tagged s b
Tagged (KeySizeSpecifier -> Tagged c KeySizeSpecifier)
-> KeySizeSpecifier -> Tagged c KeySizeSpecifier
forall a b. (a -> b) -> a -> b
$ [Int] -> KeySizeSpecifier
T.KeySizeEnum []
	nsc_setNonce           :: Tagged c (Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ()))
	nsc_setNonce           = Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
-> Tagged c (Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ()))
forall k (s :: k) b. b -> Tagged s b
Tagged Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
forall a. Maybe a
Nothing

-- stream cipher based on generating (large) blocks to XOR with input,
-- but don't keep incomplete blocks in the state, so we have to do that here
class NettleCipher c => NettleBlockedStreamCipher c where
	nbsc_blockSize          :: Tagged c Int
	-- set new incomplete state
	nbsc_IncompleteState    :: c -> B.ByteString -> c
	nbsc_incompleteState    :: c -> B.ByteString
	nbsc_streamCombine      :: Tagged c NettleCryptFunc
	nbsc_nonceSize          :: Tagged c T.KeySizeSpecifier
	nbsc_nonceSize          = KeySizeSpecifier -> Tagged c KeySizeSpecifier
forall k (s :: k) b. b -> Tagged s b
Tagged (KeySizeSpecifier -> Tagged c KeySizeSpecifier)
-> KeySizeSpecifier -> Tagged c KeySizeSpecifier
forall a b. (a -> b) -> a -> b
$ [Int] -> KeySizeSpecifier
T.KeySizeEnum []
	nbsc_setNonce           :: Tagged c (Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ()))
	nbsc_setNonce           = Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
-> Tagged c (Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ()))
forall k (s :: k) b. b -> Tagged s b
Tagged Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
forall a. Maybe a
Nothing

nettle_cipherInit :: NettleCipher c => Key c -> c
nettle_cipherInit :: Key c -> c
nettle_cipherInit k :: Key c
k = let ctx :: c
ctx = (Ptr Word8 -> Word -> Ptr Word8 -> IO ()) -> Key c -> c
forall c.
NettleCipher c =>
(Ptr Word8 -> Word -> Ptr Word8 -> IO ()) -> Key c -> c
nettle_cipherInit' (Tagged c (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
forall c.
NettleCipher c =>
Tagged c (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
nc_cipherInit Tagged c (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
-> c -> Ptr Word8 -> Word -> Ptr Word8 -> IO ()
forall a b. Tagged a b -> a -> b
`witness` c
ctx) Key c
k in c
ctx

nettle_cipherInit' :: NettleCipher c => (Ptr Word8 -> Word -> Ptr Word8 -> IO()) -> Key c -> c
nettle_cipherInit' :: (Ptr Word8 -> Word -> Ptr Word8 -> IO ()) -> Key c -> c
nettle_cipherInit' f :: Ptr Word8 -> Word -> Ptr Word8 -> IO ()
f k :: Key c
k = let ctx :: c
ctx = SecureMem -> c
forall c. NettleCipher c => SecureMem -> c
nc_Ctx (SecureMem -> c) -> SecureMem -> c
forall a b. (a -> b) -> a -> b
$ (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
-> Int -> Key c -> SecureMem
forall k.
ToSecureMem k =>
(Ptr Word8 -> Word -> Ptr Word8 -> IO ()) -> Int -> k -> SecureMem
key_init Ptr Word8 -> Word -> Ptr Word8 -> IO ()
f (Tagged c Int
forall c. NettleCipher c => Tagged c Int
nc_ctx_size Tagged c Int -> c -> Int
forall a b. Tagged a b -> a -> b
`witness` c
ctx) Key c
k in c
ctx

assert_blockSize :: NettleBlockCipher c => c -> B.ByteString -> a -> a
assert_blockSize :: c -> ByteString -> a -> a
assert_blockSize c :: c
c src :: ByteString
src result :: a
result = if 0 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= ByteString -> Int
B.length ByteString
src Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` (Tagged c Int
forall c. NettleBlockCipher c => Tagged c Int
nbc_blockSize Tagged c Int -> c -> Int
forall a b. Tagged a b -> a -> b
`witness` c
c) then [Char] -> a
forall a. HasCallStack => [Char] -> a
error "input not a multiple of blockSize" else a
result

nettle_ecbEncrypt :: NettleBlockCipher c => c -> B.ByteString -> B.ByteString
nettle_ecbEncrypt :: c -> ByteString -> ByteString
nettle_ecbEncrypt c :: c
c    src :: ByteString
src = c -> ByteString -> ByteString -> ByteString
forall c a. NettleBlockCipher c => c -> ByteString -> a -> a
assert_blockSize c
c ByteString
src (ByteString -> ByteString) -> ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ (Ptr Word8 -> Ptr Word8)
-> NettleCryptFunc -> SecureMem -> ByteString -> ByteString
c_run_crypt   (Tagged c (Ptr Word8 -> Ptr Word8)
forall c. NettleBlockCipher c => Tagged c (Ptr Word8 -> Ptr Word8)
nbc_encrypt_ctx_offset Tagged c (Ptr Word8 -> Ptr Word8) -> c -> Ptr Word8 -> Ptr Word8
forall a b. Tagged a b -> a -> b
`witness` c
c)               (Tagged c NettleCryptFunc
forall c. NettleBlockCipher c => Tagged c NettleCryptFunc
nbc_ecb_encrypt Tagged c NettleCryptFunc -> c -> NettleCryptFunc
forall a b. Tagged a b -> a -> b
`witness` c
c) (c -> SecureMem
forall c. NettleCipher c => c -> SecureMem
nc_ctx c
c) ByteString
src
nettle_ecbDecrypt :: NettleBlockCipher c => c -> B.ByteString -> B.ByteString
nettle_ecbDecrypt :: c -> ByteString -> ByteString
nettle_ecbDecrypt c :: c
c    src :: ByteString
src = c -> ByteString -> ByteString -> ByteString
forall c a. NettleBlockCipher c => c -> ByteString -> a -> a
assert_blockSize c
c ByteString
src (ByteString -> ByteString) -> ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ (Ptr Word8 -> Ptr Word8)
-> NettleCryptFunc -> SecureMem -> ByteString -> ByteString
c_run_crypt   (Tagged c (Ptr Word8 -> Ptr Word8)
forall c. NettleBlockCipher c => Tagged c (Ptr Word8 -> Ptr Word8)
nbc_decrypt_ctx_offset Tagged c (Ptr Word8 -> Ptr Word8) -> c -> Ptr Word8 -> Ptr Word8
forall a b. Tagged a b -> a -> b
`witness` c
c)               (Tagged c NettleCryptFunc
forall c. NettleBlockCipher c => Tagged c NettleCryptFunc
nbc_ecb_decrypt Tagged c NettleCryptFunc -> c -> NettleCryptFunc
forall a b. Tagged a b -> a -> b
`witness` c
c) (c -> SecureMem
forall c. NettleCipher c => c -> SecureMem
nc_ctx c
c) ByteString
src
nettle_cbcEncrypt :: NettleBlockCipher c => c -> IV c -> B.ByteString -> B.ByteString
nettle_cbcEncrypt :: c -> IV c -> ByteString -> ByteString
nettle_cbcEncrypt c :: c
c iv :: IV c
iv src :: ByteString
src = c -> ByteString -> ByteString -> ByteString
forall c a. NettleBlockCipher c => c -> ByteString -> a -> a
assert_blockSize c
c ByteString
src (ByteString -> ByteString) -> ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ (Ptr Word8 -> Ptr Word8)
-> NettleBlockMode
-> FunPtr NettleCryptFunc
-> SecureMem
-> IV c
-> ByteString
-> ByteString
forall iv.
Byteable iv =>
(Ptr Word8 -> Ptr Word8)
-> NettleBlockMode
-> FunPtr NettleCryptFunc
-> SecureMem
-> iv
-> ByteString
-> ByteString
blockmode_run (Tagged c (Ptr Word8 -> Ptr Word8)
forall c. NettleBlockCipher c => Tagged c (Ptr Word8 -> Ptr Word8)
nbc_encrypt_ctx_offset Tagged c (Ptr Word8 -> Ptr Word8) -> c -> Ptr Word8 -> Ptr Word8
forall a b. Tagged a b -> a -> b
`witness` c
c) NettleBlockMode
c_cbc_encrypt (Tagged c (FunPtr NettleCryptFunc)
forall c. NettleBlockCipher c => Tagged c (FunPtr NettleCryptFunc)
nbc_fun_encrypt Tagged c (FunPtr NettleCryptFunc) -> c -> FunPtr NettleCryptFunc
forall a b. Tagged a b -> a -> b
`witness` c
c) (c -> SecureMem
forall c. NettleCipher c => c -> SecureMem
nc_ctx c
c) IV c
iv ByteString
src
nettle_cbcDecrypt :: NettleBlockCipher c => c -> IV c -> B.ByteString -> B.ByteString
nettle_cbcDecrypt :: c -> IV c -> ByteString -> ByteString
nettle_cbcDecrypt c :: c
c iv :: IV c
iv src :: ByteString
src = c -> ByteString -> ByteString -> ByteString
forall c a. NettleBlockCipher c => c -> ByteString -> a -> a
assert_blockSize c
c ByteString
src (ByteString -> ByteString) -> ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ (Ptr Word8 -> Ptr Word8)
-> NettleBlockMode
-> FunPtr NettleCryptFunc
-> SecureMem
-> IV c
-> ByteString
-> ByteString
forall iv.
Byteable iv =>
(Ptr Word8 -> Ptr Word8)
-> NettleBlockMode
-> FunPtr NettleCryptFunc
-> SecureMem
-> iv
-> ByteString
-> ByteString
blockmode_run (Tagged c (Ptr Word8 -> Ptr Word8)
forall c. NettleBlockCipher c => Tagged c (Ptr Word8 -> Ptr Word8)
nbc_decrypt_ctx_offset Tagged c (Ptr Word8 -> Ptr Word8) -> c -> Ptr Word8 -> Ptr Word8
forall a b. Tagged a b -> a -> b
`witness` c
c) NettleBlockMode
c_cbc_decrypt (Tagged c (FunPtr NettleCryptFunc)
forall c. NettleBlockCipher c => Tagged c (FunPtr NettleCryptFunc)
nbc_fun_decrypt Tagged c (FunPtr NettleCryptFunc) -> c -> FunPtr NettleCryptFunc
forall a b. Tagged a b -> a -> b
`witness` c
c) (c -> SecureMem
forall c. NettleCipher c => c -> SecureMem
nc_ctx c
c) IV c
iv ByteString
src
nettle_cfbEncrypt :: NettleBlockCipher c => c -> IV c -> B.ByteString -> B.ByteString
nettle_cfbEncrypt :: c -> IV c -> ByteString -> ByteString
nettle_cfbEncrypt c :: c
c iv :: IV c
iv src :: ByteString
src = c -> ByteString -> ByteString -> ByteString
forall c a. NettleBlockCipher c => c -> ByteString -> a -> a
assert_blockSize c
c ByteString
src (ByteString -> ByteString) -> ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ (Ptr Word8 -> Ptr Word8)
-> NettleBlockMode
-> FunPtr NettleCryptFunc
-> SecureMem
-> IV c
-> ByteString
-> ByteString
forall iv.
Byteable iv =>
(Ptr Word8 -> Ptr Word8)
-> NettleBlockMode
-> FunPtr NettleCryptFunc
-> SecureMem
-> iv
-> ByteString
-> ByteString
blockmode_run (Tagged c (Ptr Word8 -> Ptr Word8)
forall c. NettleBlockCipher c => Tagged c (Ptr Word8 -> Ptr Word8)
nbc_encrypt_ctx_offset Tagged c (Ptr Word8 -> Ptr Word8) -> c -> Ptr Word8 -> Ptr Word8
forall a b. Tagged a b -> a -> b
`witness` c
c) NettleBlockMode
c_cfb_encrypt (Tagged c (FunPtr NettleCryptFunc)
forall c. NettleBlockCipher c => Tagged c (FunPtr NettleCryptFunc)
nbc_fun_encrypt Tagged c (FunPtr NettleCryptFunc) -> c -> FunPtr NettleCryptFunc
forall a b. Tagged a b -> a -> b
`witness` c
c) (c -> SecureMem
forall c. NettleCipher c => c -> SecureMem
nc_ctx c
c) IV c
iv ByteString
src
nettle_cfbDecrypt :: NettleBlockCipher c => c -> IV c -> B.ByteString -> B.ByteString
nettle_cfbDecrypt :: c -> IV c -> ByteString -> ByteString
nettle_cfbDecrypt c :: c
c iv :: IV c
iv src :: ByteString
src = c -> ByteString -> ByteString -> ByteString
forall c a. NettleBlockCipher c => c -> ByteString -> a -> a
assert_blockSize c
c ByteString
src (ByteString -> ByteString) -> ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ (Ptr Word8 -> Ptr Word8)
-> NettleBlockMode
-> FunPtr NettleCryptFunc
-> SecureMem
-> IV c
-> ByteString
-> ByteString
forall iv.
Byteable iv =>
(Ptr Word8 -> Ptr Word8)
-> NettleBlockMode
-> FunPtr NettleCryptFunc
-> SecureMem
-> iv
-> ByteString
-> ByteString
blockmode_run (Tagged c (Ptr Word8 -> Ptr Word8)
forall c. NettleBlockCipher c => Tagged c (Ptr Word8 -> Ptr Word8)
nbc_encrypt_ctx_offset Tagged c (Ptr Word8 -> Ptr Word8) -> c -> Ptr Word8 -> Ptr Word8
forall a b. Tagged a b -> a -> b
`witness` c
c) NettleBlockMode
c_cfb_decrypt (Tagged c (FunPtr NettleCryptFunc)
forall c. NettleBlockCipher c => Tagged c (FunPtr NettleCryptFunc)
nbc_fun_encrypt Tagged c (FunPtr NettleCryptFunc) -> c -> FunPtr NettleCryptFunc
forall a b. Tagged a b -> a -> b
`witness` c
c) (c -> SecureMem
forall c. NettleCipher c => c -> SecureMem
nc_ctx c
c) IV c
iv ByteString
src
nettle_ctrCombine :: NettleBlockCipher c => c -> IV c -> B.ByteString -> B.ByteString
nettle_ctrCombine :: c -> IV c -> ByteString -> ByteString
nettle_ctrCombine c :: c
c        =                          (Ptr Word8 -> Ptr Word8)
-> NettleBlockMode
-> FunPtr NettleCryptFunc
-> SecureMem
-> IV c
-> ByteString
-> ByteString
forall iv.
Byteable iv =>
(Ptr Word8 -> Ptr Word8)
-> NettleBlockMode
-> FunPtr NettleCryptFunc
-> SecureMem
-> iv
-> ByteString
-> ByteString
blockmode_run (Tagged c (Ptr Word8 -> Ptr Word8)
forall c. NettleBlockCipher c => Tagged c (Ptr Word8 -> Ptr Word8)
nbc_encrypt_ctx_offset Tagged c (Ptr Word8 -> Ptr Word8) -> c -> Ptr Word8 -> Ptr Word8
forall a b. Tagged a b -> a -> b
`witness` c
c) NettleBlockMode
c_ctr_crypt   (Tagged c (FunPtr NettleCryptFunc)
forall c. NettleBlockCipher c => Tagged c (FunPtr NettleCryptFunc)
nbc_fun_encrypt Tagged c (FunPtr NettleCryptFunc) -> c -> FunPtr NettleCryptFunc
forall a b. Tagged a b -> a -> b
`witness` c
c) (c -> SecureMem
forall c. NettleCipher c => c -> SecureMem
nc_ctx c
c)

nettle_streamCombine :: NettleStreamCipher c => c -> B.ByteString -> (B.ByteString, c)
nettle_streamCombine :: c -> ByteString -> (ByteString, c)
nettle_streamCombine c :: c
c indata :: ByteString
indata = let (r :: ByteString
r, c' :: SecureMem
c') = NettleCryptFunc
-> SecureMem -> ByteString -> (ByteString, SecureMem)
stream_crypt (Tagged c NettleCryptFunc
forall c. NettleStreamCipher c => Tagged c NettleCryptFunc
nsc_streamCombine Tagged c NettleCryptFunc -> c -> NettleCryptFunc
forall a b. Tagged a b -> a -> b
`witness` c
c) (c -> SecureMem
forall c. NettleCipher c => c -> SecureMem
nc_ctx c
c) ByteString
indata in (ByteString
r, SecureMem -> c
forall c. NettleCipher c => SecureMem -> c
nc_Ctx SecureMem
c')
nettle_streamSetNonce :: NettleStreamCipher c => c -> B.ByteString -> Maybe c
nettle_streamSetNonce :: c -> ByteString -> Maybe c
nettle_streamSetNonce c :: c
c nonce :: ByteString
nonce = case Tagged c (Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ()))
forall c.
NettleStreamCipher c =>
Tagged c (Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ()))
nsc_setNonce Tagged c (Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ()))
-> c -> Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
forall a b. Tagged a b -> a -> b
`witness` c
c of
	Nothing -> Maybe c
forall a. Maybe a
Nothing
	Just setnonce :: Ptr Word8 -> Word -> Ptr Word8 -> IO ()
setnonce -> IO (Maybe c) -> Maybe c
forall a. IO a -> a
unsafeDupablePerformIO (IO (Maybe c) -> Maybe c) -> IO (Maybe c) -> Maybe c
forall a b. (a -> b) -> a -> b
$
		SecureMem -> IO SecureMem
secureMemCopy (c -> SecureMem
forall c. NettleCipher c => c -> SecureMem
nc_ctx c
c) IO SecureMem -> (SecureMem -> IO (Maybe c)) -> IO (Maybe c)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \ctx' :: SecureMem
ctx' ->
		SecureMem -> (Ptr Word8 -> IO (Maybe c)) -> IO (Maybe c)
forall b. SecureMem -> (Ptr Word8 -> IO b) -> IO b
withSecureMemPtr SecureMem
ctx' ((Ptr Word8 -> IO (Maybe c)) -> IO (Maybe c))
-> (Ptr Word8 -> IO (Maybe c)) -> IO (Maybe c)
forall a b. (a -> b) -> a -> b
$ \ctxptr :: Ptr Word8
ctxptr ->
		ByteString -> (Word -> Ptr Word8 -> IO (Maybe c)) -> IO (Maybe c)
forall a. ByteString -> (Word -> Ptr Word8 -> IO a) -> IO a
withByteStringPtr ByteString
nonce ((Word -> Ptr Word8 -> IO (Maybe c)) -> IO (Maybe c))
-> (Word -> Ptr Word8 -> IO (Maybe c)) -> IO (Maybe c)
forall a b. (a -> b) -> a -> b
$ \noncelen :: Word
noncelen nonceptr :: Ptr Word8
nonceptr ->
		Ptr Word8 -> Word -> Ptr Word8 -> IO ()
setnonce Ptr Word8
ctxptr Word
noncelen Ptr Word8
nonceptr IO () -> IO (Maybe c) -> IO (Maybe c)
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
		Maybe c -> IO (Maybe c)
forall (m :: * -> *) a. Monad m => a -> m a
return (c -> Maybe c
forall a. a -> Maybe a
Just (c -> Maybe c) -> c -> Maybe c
forall a b. (a -> b) -> a -> b
$ SecureMem -> c
forall c. NettleCipher c => SecureMem -> c
nc_Ctx SecureMem
ctx')

nettle_blockedStreamCombine :: NettleBlockedStreamCipher c => c -> B.ByteString -> (B.ByteString, c)
nettle_blockedStreamCombine :: c -> ByteString -> (ByteString, c)
nettle_blockedStreamCombine c :: c
c indata :: ByteString
indata = if ByteString -> Int
B.length ByteString
indata Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 0 then (ByteString
indata, c
c) else
	let inc :: ByteString
inc = c -> ByteString
forall c. NettleBlockedStreamCipher c => c -> ByteString
nbsc_incompleteState c
c; blocksiz :: Int
blocksiz = Tagged c Int
forall c. NettleBlockedStreamCipher c => Tagged c Int
nbsc_blockSize Tagged c Int -> c -> Int
forall a b. Tagged a b -> a -> b
`witness` c
c in
	if ByteString -> Int
B.length ByteString
inc Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= 0
		then let
			-- first xor remaining block, then combine the rest
			(i1 :: ByteString
i1, i2 :: ByteString
i2) = Int -> ByteString -> (ByteString, ByteString)
B.splitAt (ByteString -> Int
B.length ByteString
inc) ByteString
indata
			(inc1 :: ByteString
inc1, inc2 :: ByteString
inc2) = Int -> ByteString -> (ByteString, ByteString)
B.splitAt (ByteString -> Int
B.length ByteString
indata) ByteString
inc
			r1 :: ByteString
r1 = [Word8] -> ByteString
B.pack ([Word8] -> ByteString) -> [Word8] -> ByteString
forall a b. (a -> b) -> a -> b
$ (Word8 -> Word8 -> Word8) -> ByteString -> ByteString -> [Word8]
forall a. (Word8 -> Word8 -> a) -> ByteString -> ByteString -> [a]
B.zipWith Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
xor ByteString
i1 ByteString
inc1
			c' :: c
c' = if ByteString -> Int
B.length ByteString
inc2 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 0 then SecureMem -> c
forall c. NettleCipher c => SecureMem -> c
nc_Ctx (SecureMem -> c) -> SecureMem -> c
forall a b. (a -> b) -> a -> b
$ c -> SecureMem
forall c. NettleCipher c => c -> SecureMem
nc_ctx c
c else c -> ByteString -> c
forall c. NettleBlockedStreamCipher c => c -> ByteString -> c
nbsc_IncompleteState c
c ByteString
inc2
			(r :: ByteString
r, c'' :: c
c'') = c -> ByteString -> (ByteString, c)
forall c.
NettleBlockedStreamCipher c =>
c -> ByteString -> (ByteString, c)
nettle_blockedStreamCombine c
c' ByteString
i2
			in (ByteString -> ByteString -> ByteString
B.append ByteString
r1 ByteString
r, c
c'')
		else if ByteString -> Int
B.length ByteString
indata Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
blocksiz Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= 0
			then let
				padding :: ByteString
padding = Int -> Word8 -> ByteString
B.replicate (Int
blocksiz Int -> Int -> Int
forall a. Num a => a -> a -> a
- (ByteString -> Int
B.length ByteString
indata Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
blocksiz)) 0
				(r' :: ByteString
r', c' :: SecureMem
c') = NettleCryptFunc
-> SecureMem -> ByteString -> (ByteString, SecureMem)
stream_crypt (Tagged c NettleCryptFunc
forall c. NettleBlockedStreamCipher c => Tagged c NettleCryptFunc
nbsc_streamCombine Tagged c NettleCryptFunc -> c -> NettleCryptFunc
forall a b. Tagged a b -> a -> b
`witness` c
c) (c -> SecureMem
forall c. NettleCipher c => c -> SecureMem
nc_ctx c
c) (ByteString -> ByteString -> ByteString
B.append ByteString
indata ByteString
padding)
				(r :: ByteString
r, inc' :: ByteString
inc') = Int -> ByteString -> (ByteString, ByteString)
B.splitAt (ByteString -> Int
B.length ByteString
indata) ByteString
r'
				in (ByteString
r, c -> ByteString -> c
forall c. NettleBlockedStreamCipher c => c -> ByteString -> c
nbsc_IncompleteState (SecureMem -> c
forall c. NettleCipher c => SecureMem -> c
nc_Ctx SecureMem
c') ByteString
inc')
			else
				let (r :: ByteString
r, c' :: SecureMem
c') = NettleCryptFunc
-> SecureMem -> ByteString -> (ByteString, SecureMem)
stream_crypt (Tagged c NettleCryptFunc
forall c. NettleBlockedStreamCipher c => Tagged c NettleCryptFunc
nbsc_streamCombine Tagged c NettleCryptFunc -> c -> NettleCryptFunc
forall a b. Tagged a b -> a -> b
`witness` c
c) (c -> SecureMem
forall c. NettleCipher c => c -> SecureMem
nc_ctx c
c) ByteString
indata in (ByteString
r, SecureMem -> c
forall c. NettleCipher c => SecureMem -> c
nc_Ctx SecureMem
c')
nettle_blockedStreamSetNonce :: NettleBlockedStreamCipher c => c -> B.ByteString -> Maybe c
nettle_blockedStreamSetNonce :: c -> ByteString -> Maybe c
nettle_blockedStreamSetNonce c :: c
c nonce :: ByteString
nonce = case Tagged c (Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ()))
forall c.
NettleBlockedStreamCipher c =>
Tagged c (Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ()))
nbsc_setNonce Tagged c (Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ()))
-> c -> Maybe (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
forall a b. Tagged a b -> a -> b
`witness` c
c of
	Nothing -> Maybe c
forall a. Maybe a
Nothing
	Just setnonce :: Ptr Word8 -> Word -> Ptr Word8 -> IO ()
setnonce -> IO (Maybe c) -> Maybe c
forall a. IO a -> a
unsafeDupablePerformIO (IO (Maybe c) -> Maybe c) -> IO (Maybe c) -> Maybe c
forall a b. (a -> b) -> a -> b
$
		SecureMem -> IO SecureMem
secureMemCopy (c -> SecureMem
forall c. NettleCipher c => c -> SecureMem
nc_ctx c
c) IO SecureMem -> (SecureMem -> IO (Maybe c)) -> IO (Maybe c)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \ctx' :: SecureMem
ctx' ->
		SecureMem -> (Ptr Word8 -> IO (Maybe c)) -> IO (Maybe c)
forall b. SecureMem -> (Ptr Word8 -> IO b) -> IO b
withSecureMemPtr SecureMem
ctx' ((Ptr Word8 -> IO (Maybe c)) -> IO (Maybe c))
-> (Ptr Word8 -> IO (Maybe c)) -> IO (Maybe c)
forall a b. (a -> b) -> a -> b
$ \ctxptr :: Ptr Word8
ctxptr ->
		ByteString -> (Word -> Ptr Word8 -> IO (Maybe c)) -> IO (Maybe c)
forall a. ByteString -> (Word -> Ptr Word8 -> IO a) -> IO a
withByteStringPtr ByteString
nonce ((Word -> Ptr Word8 -> IO (Maybe c)) -> IO (Maybe c))
-> (Word -> Ptr Word8 -> IO (Maybe c)) -> IO (Maybe c)
forall a b. (a -> b) -> a -> b
$ \noncelen :: Word
noncelen nonceptr :: Ptr Word8
nonceptr ->
		Ptr Word8 -> Word -> Ptr Word8 -> IO ()
setnonce Ptr Word8
ctxptr Word
noncelen Ptr Word8
nonceptr IO () -> IO (Maybe c) -> IO (Maybe c)
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
		Maybe c -> IO (Maybe c)
forall (m :: * -> *) a. Monad m => a -> m a
return (c -> Maybe c
forall a. a -> Maybe a
Just (c -> Maybe c) -> c -> Maybe c
forall a b. (a -> b) -> a -> b
$ SecureMem -> c
forall c. NettleCipher c => SecureMem -> c
nc_Ctx SecureMem
ctx')


nettle_gcm_aeadInit              :: (NettleBlockCipher c, AEADModeImpl c NettleGCM, Byteable iv) => c -> iv -> Maybe (AEAD c)
nettle_gcm_aeadInit :: c -> iv -> Maybe (AEAD c)
nettle_gcm_aeadInit          c :: c
c  iv :: iv
iv = if Tagged c Int
forall c. NettleBlockCipher c => Tagged c Int
nbc_blockSize Tagged c Int -> c -> Int
forall a b. Tagged a b -> a -> b
`witness` c
c Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 16 then AEAD c -> Maybe (AEAD c)
forall a. a -> Maybe a
Just (AEAD c -> Maybe (AEAD c)) -> AEAD c -> Maybe (AEAD c)
forall a b. (a -> b) -> a -> b
$ c -> AEADState c -> AEAD c
forall cipher. cipher -> AEADState cipher -> AEAD cipher
AEAD c
c (AEADState c -> AEAD c) -> AEADState c -> AEAD c
forall a b. (a -> b) -> a -> b
$ NettleGCM -> AEADState c
forall cipher st. AEADModeImpl cipher st => st -> AEADState cipher
AEADState (NettleGCM -> AEADState c) -> NettleGCM -> AEADState c
forall a b. (a -> b) -> a -> b
$ (Ptr Word8 -> Ptr Word8)
-> FunPtr NettleCryptFunc -> SecureMem -> iv -> NettleGCM
forall iv.
Byteable iv =>
(Ptr Word8 -> Ptr Word8)
-> FunPtr NettleCryptFunc -> SecureMem -> iv -> NettleGCM
gcm_init (Tagged c (Ptr Word8 -> Ptr Word8)
forall c. NettleBlockCipher c => Tagged c (Ptr Word8 -> Ptr Word8)
nbc_encrypt_ctx_offset Tagged c (Ptr Word8 -> Ptr Word8) -> c -> Ptr Word8 -> Ptr Word8
forall a b. Tagged a b -> a -> b
`witness` c
c) (Tagged c (FunPtr NettleCryptFunc)
forall c. NettleBlockCipher c => Tagged c (FunPtr NettleCryptFunc)
nbc_fun_encrypt Tagged c (FunPtr NettleCryptFunc) -> c -> FunPtr NettleCryptFunc
forall a b. Tagged a b -> a -> b
`witness` c
c) (c -> SecureMem
forall c. NettleCipher c => c -> SecureMem
nc_ctx c
c) iv
iv else Maybe (AEAD c)
forall a. Maybe a
Nothing
nettle_gcm_aeadStateAppendHeader :: t -> NettleGCM -> B.ByteString -> NettleGCM
nettle_gcm_aeadStateAppendHeader :: t -> NettleGCM -> ByteString -> NettleGCM
nettle_gcm_aeadStateAppendHeader _ = NettleGCM -> ByteString -> NettleGCM
gcm_update
nettle_gcm_aeadStateEncrypt      :: NettleBlockCipher c => c -> NettleGCM -> B.ByteString -> (B.ByteString, NettleGCM)
nettle_gcm_aeadStateEncrypt :: c -> NettleGCM -> ByteString -> (ByteString, NettleGCM)
nettle_gcm_aeadStateEncrypt      c :: c
c = NettleGCMMode
-> (Ptr Word8 -> Ptr Word8)
-> FunPtr NettleCryptFunc
-> SecureMem
-> NettleGCM
-> ByteString
-> (ByteString, NettleGCM)
gcm_crypt NettleGCMMode
c_gcm_encrypt (Tagged c (Ptr Word8 -> Ptr Word8)
forall c. NettleBlockCipher c => Tagged c (Ptr Word8 -> Ptr Word8)
nbc_encrypt_ctx_offset Tagged c (Ptr Word8 -> Ptr Word8) -> c -> Ptr Word8 -> Ptr Word8
forall a b. Tagged a b -> a -> b
`witness` c
c) (Tagged c (FunPtr NettleCryptFunc)
forall c. NettleBlockCipher c => Tagged c (FunPtr NettleCryptFunc)
nbc_fun_encrypt Tagged c (FunPtr NettleCryptFunc) -> c -> FunPtr NettleCryptFunc
forall a b. Tagged a b -> a -> b
`witness` c
c) (c -> SecureMem
forall c. NettleCipher c => c -> SecureMem
nc_ctx c
c)
nettle_gcm_aeadStateDecrypt      :: NettleBlockCipher c => c -> NettleGCM -> B.ByteString -> (B.ByteString, NettleGCM)
nettle_gcm_aeadStateDecrypt :: c -> NettleGCM -> ByteString -> (ByteString, NettleGCM)
nettle_gcm_aeadStateDecrypt      c :: c
c = NettleGCMMode
-> (Ptr Word8 -> Ptr Word8)
-> FunPtr NettleCryptFunc
-> SecureMem
-> NettleGCM
-> ByteString
-> (ByteString, NettleGCM)
gcm_crypt NettleGCMMode
c_gcm_decrypt (Tagged c (Ptr Word8 -> Ptr Word8)
forall c. NettleBlockCipher c => Tagged c (Ptr Word8 -> Ptr Word8)
nbc_encrypt_ctx_offset Tagged c (Ptr Word8 -> Ptr Word8) -> c -> Ptr Word8 -> Ptr Word8
forall a b. Tagged a b -> a -> b
`witness` c
c) (Tagged c (FunPtr NettleCryptFunc)
forall c. NettleBlockCipher c => Tagged c (FunPtr NettleCryptFunc)
nbc_fun_encrypt Tagged c (FunPtr NettleCryptFunc) -> c -> FunPtr NettleCryptFunc
forall a b. Tagged a b -> a -> b
`witness` c
c) (c -> SecureMem
forall c. NettleCipher c => c -> SecureMem
nc_ctx c
c)
nettle_gcm_aeadStateFinalize     :: NettleBlockCipher c => c -> NettleGCM -> Int -> AuthTag
nettle_gcm_aeadStateFinalize :: c -> NettleGCM -> Int -> AuthTag
nettle_gcm_aeadStateFinalize     c :: c
c = (Ptr Word8 -> Ptr Word8)
-> FunPtr NettleCryptFunc
-> SecureMem
-> NettleGCM
-> Int
-> AuthTag
gcm_digest              (Tagged c (Ptr Word8 -> Ptr Word8)
forall c. NettleBlockCipher c => Tagged c (Ptr Word8 -> Ptr Word8)
nbc_encrypt_ctx_offset Tagged c (Ptr Word8 -> Ptr Word8) -> c -> Ptr Word8 -> Ptr Word8
forall a b. Tagged a b -> a -> b
`witness` c
c) (Tagged c (FunPtr NettleCryptFunc)
forall c. NettleBlockCipher c => Tagged c (FunPtr NettleCryptFunc)
nbc_fun_encrypt Tagged c (FunPtr NettleCryptFunc) -> c -> FunPtr NettleCryptFunc
forall a b. Tagged a b -> a -> b
`witness` c
c) (c -> SecureMem
forall c. NettleCipher c => c -> SecureMem
nc_ctx c
c)



key_init
	:: ToSecureMem k
	=> (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
	-> Int -> k -> SecureMem
key_init :: (Ptr Word8 -> Word -> Ptr Word8 -> IO ()) -> Int -> k -> SecureMem
key_init initfun :: Ptr Word8 -> Word -> Ptr Word8 -> IO ()
initfun size :: Int
size k :: k
k = Int -> (Ptr Word8 -> IO ()) -> SecureMem
unsafeCreateSecureMem Int
size ((Ptr Word8 -> IO ()) -> SecureMem)
-> (Ptr Word8 -> IO ()) -> SecureMem
forall a b. (a -> b) -> a -> b
$ \ctxptr :: Ptr Word8
ctxptr ->
	SecureMem -> (Int -> Ptr Word8 -> IO ()) -> IO ()
forall b. SecureMem -> (Int -> Ptr Word8 -> IO b) -> IO b
withSecureMemPtrSz (k -> SecureMem
forall a. ToSecureMem a => a -> SecureMem
toSecureMem k
k) ((Int -> Ptr Word8 -> IO ()) -> IO ())
-> (Int -> Ptr Word8 -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ksize :: Int
ksize kptr :: Ptr Word8
kptr -> Ptr Word8 -> Word -> Ptr Word8 -> IO ()
initfun Ptr Word8
ctxptr (Int -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
ksize) Ptr Word8
kptr

-- run encryption/decryption with same length for in and output
c_run_crypt
	:: (Ptr Word8 -> Ptr Word8)
	-> NettleCryptFunc
	-> SecureMem -> B.ByteString -> B.ByteString
c_run_crypt :: (Ptr Word8 -> Ptr Word8)
-> NettleCryptFunc -> SecureMem -> ByteString -> ByteString
c_run_crypt ctxoffset :: Ptr Word8 -> Ptr Word8
ctxoffset cfun :: NettleCryptFunc
cfun ctx :: SecureMem
ctx indata :: ByteString
indata = IO ByteString -> ByteString
forall a. IO a -> a
unsafeDupablePerformIO (IO ByteString -> ByteString) -> IO ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ SecureMem -> (Ptr Word8 -> IO ByteString) -> IO ByteString
forall b. SecureMem -> (Ptr Word8 -> IO b) -> IO b
withSecureMemPtr SecureMem
ctx ((Ptr Word8 -> IO ByteString) -> IO ByteString)
-> (Ptr Word8 -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \ctxptr :: Ptr Word8
ctxptr ->
	ByteString -> (Word -> Ptr Word8 -> IO ByteString) -> IO ByteString
forall a. ByteString -> (Word -> Ptr Word8 -> IO a) -> IO a
withByteStringPtr ByteString
indata ((Word -> Ptr Word8 -> IO ByteString) -> IO ByteString)
-> (Word -> Ptr Word8 -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \indatalen :: Word
indatalen indataptr :: Ptr Word8
indataptr ->
	Int -> (Ptr Word8 -> IO ()) -> IO ByteString
B.create (ByteString -> Int
B.length ByteString
indata) ((Ptr Word8 -> IO ()) -> IO ByteString)
-> (Ptr Word8 -> IO ()) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \outptr :: Ptr Word8
outptr ->
	NettleCryptFunc
cfun (Ptr Word8 -> Ptr Word8
ctxoffset Ptr Word8
ctxptr) Word
indatalen Ptr Word8
outptr Ptr Word8
indataptr

blockmode_run
	:: (Byteable iv)
	=> (Ptr Word8 -> Ptr Word8)
	-> NettleBlockMode
	-> FunPtr NettleCryptFunc
	-> SecureMem -> iv -> B.ByteString -> B.ByteString
blockmode_run :: (Ptr Word8 -> Ptr Word8)
-> NettleBlockMode
-> FunPtr NettleCryptFunc
-> SecureMem
-> iv
-> ByteString
-> ByteString
blockmode_run ctxoffset :: Ptr Word8 -> Ptr Word8
ctxoffset mode :: NettleBlockMode
mode crypt :: FunPtr NettleCryptFunc
crypt ctx :: SecureMem
ctx iv :: iv
iv indata :: ByteString
indata = IO ByteString -> ByteString
forall a. IO a -> a
unsafeDupablePerformIO (IO ByteString -> ByteString) -> IO ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ SecureMem -> (Ptr Word8 -> IO ByteString) -> IO ByteString
forall b. SecureMem -> (Ptr Word8 -> IO b) -> IO b
withSecureMemPtr SecureMem
ctx ((Ptr Word8 -> IO ByteString) -> IO ByteString)
-> (Ptr Word8 -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \ctxptr :: Ptr Word8
ctxptr ->
	ByteString -> (Word -> Ptr Word8 -> IO ByteString) -> IO ByteString
forall a. ByteString -> (Word -> Ptr Word8 -> IO a) -> IO a
withByteStringPtr ByteString
indata ((Word -> Ptr Word8 -> IO ByteString) -> IO ByteString)
-> (Word -> Ptr Word8 -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \indatalen :: Word
indatalen indataptr :: Ptr Word8
indataptr ->
	SecureMem -> (Int -> Ptr Word8 -> IO ByteString) -> IO ByteString
forall b. SecureMem -> (Int -> Ptr Word8 -> IO b) -> IO b
withSecureMemPtrSz (ByteString -> SecureMem
forall a. ToSecureMem a => a -> SecureMem
toSecureMem (ByteString -> SecureMem) -> ByteString -> SecureMem
forall a b. (a -> b) -> a -> b
$ iv -> ByteString
forall a. Byteable a => a -> ByteString
toBytes iv
iv) ((Int -> Ptr Word8 -> IO ByteString) -> IO ByteString)
-> (Int -> Ptr Word8 -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \ivlen :: Int
ivlen ivptr :: Ptr Word8
ivptr -> -- copy IV, may get modified
	Int -> (Ptr Word8 -> IO ()) -> IO ByteString
B.create (ByteString -> Int
B.length ByteString
indata) ((Ptr Word8 -> IO ()) -> IO ByteString)
-> (Ptr Word8 -> IO ()) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \outptr :: Ptr Word8
outptr ->
	NettleBlockMode
mode (Ptr Word8 -> Ptr Word8
ctxoffset Ptr Word8
ctxptr) FunPtr NettleCryptFunc
crypt (Int -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
ivlen) Ptr Word8
ivptr Word
indatalen Ptr Word8
outptr Ptr Word8
indataptr

data NettleGCM = NettleGCM !SecureMem !SecureMem

gcm_init
	:: (Byteable iv)
	=> (Ptr Word8 -> Ptr Word8)
	-> FunPtr NettleCryptFunc
	-> SecureMem -> iv -> NettleGCM
gcm_init :: (Ptr Word8 -> Ptr Word8)
-> FunPtr NettleCryptFunc -> SecureMem -> iv -> NettleGCM
gcm_init encctxoffset :: Ptr Word8 -> Ptr Word8
encctxoffset encrypt :: FunPtr NettleCryptFunc
encrypt encctx :: SecureMem
encctx iv :: iv
iv = IO NettleGCM -> NettleGCM
forall a. IO a -> a
unsafeDupablePerformIO (IO NettleGCM -> NettleGCM) -> IO NettleGCM -> NettleGCM
forall a b. (a -> b) -> a -> b
$
	iv -> (Ptr Word8 -> IO NettleGCM) -> IO NettleGCM
forall a b. Byteable a => a -> (Ptr Word8 -> IO b) -> IO b
withBytePtr iv
iv ((Ptr Word8 -> IO NettleGCM) -> IO NettleGCM)
-> (Ptr Word8 -> IO NettleGCM) -> IO NettleGCM
forall a b. (a -> b) -> a -> b
$ \ivptr :: Ptr Word8
ivptr ->
	SecureMem -> (Ptr Word8 -> IO NettleGCM) -> IO NettleGCM
forall b. SecureMem -> (Ptr Word8 -> IO b) -> IO b
withSecureMemPtr SecureMem
encctx ((Ptr Word8 -> IO NettleGCM) -> IO NettleGCM)
-> (Ptr Word8 -> IO NettleGCM) -> IO NettleGCM
forall a b. (a -> b) -> a -> b
$ \encctxptr :: Ptr Word8
encctxptr -> do
	SecureMem
h <- Int -> (Ptr Word8 -> IO ()) -> IO SecureMem
createSecureMem Int
c_gcm_key_size ((Ptr Word8 -> IO ()) -> IO SecureMem)
-> (Ptr Word8 -> IO ()) -> IO SecureMem
forall a b. (a -> b) -> a -> b
$ \hptr :: Ptr Word8
hptr ->
		Ptr Word8 -> Ptr Word8 -> FunPtr NettleCryptFunc -> IO ()
c_gcm_set_key Ptr Word8
hptr (Ptr Word8 -> Ptr Word8
encctxoffset Ptr Word8
encctxptr) FunPtr NettleCryptFunc
encrypt
	SecureMem -> (Ptr Word8 -> IO NettleGCM) -> IO NettleGCM
forall b. SecureMem -> (Ptr Word8 -> IO b) -> IO b
withSecureMemPtr SecureMem
h ((Ptr Word8 -> IO NettleGCM) -> IO NettleGCM)
-> (Ptr Word8 -> IO NettleGCM) -> IO NettleGCM
forall a b. (a -> b) -> a -> b
$ \hptr :: Ptr Word8
hptr -> do
	SecureMem
ctx <- Int -> (Ptr Word8 -> IO ()) -> IO SecureMem
createSecureMem Int
c_gcm_ctx_size ((Ptr Word8 -> IO ()) -> IO SecureMem)
-> (Ptr Word8 -> IO ()) -> IO SecureMem
forall a b. (a -> b) -> a -> b
$ \ctxptr :: Ptr Word8
ctxptr ->
		Ptr Word8 -> Ptr Word8 -> Word -> Ptr Word8 -> IO ()
c_gcm_set_iv Ptr Word8
ctxptr Ptr Word8
hptr (Int -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word) -> Int -> Word
forall a b. (a -> b) -> a -> b
$ iv -> Int
forall a. Byteable a => a -> Int
byteableLength iv
iv) Ptr Word8
ivptr
	NettleGCM -> IO NettleGCM
forall (m :: * -> *) a. Monad m => a -> m a
return (SecureMem -> SecureMem -> NettleGCM
NettleGCM SecureMem
ctx SecureMem
h)

-- independent of cipher
gcm_update
	:: NettleGCM -> B.ByteString -> NettleGCM
gcm_update :: NettleGCM -> ByteString -> NettleGCM
gcm_update (NettleGCM ctx :: SecureMem
ctx h :: SecureMem
h) indata :: ByteString
indata = IO NettleGCM -> NettleGCM
forall a. IO a -> a
unsafeDupablePerformIO (IO NettleGCM -> NettleGCM) -> IO NettleGCM -> NettleGCM
forall a b. (a -> b) -> a -> b
$
	SecureMem -> IO SecureMem
secureMemCopy SecureMem
ctx IO SecureMem -> (SecureMem -> IO NettleGCM) -> IO NettleGCM
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \ctx' :: SecureMem
ctx' ->
	SecureMem -> (Ptr Word8 -> IO NettleGCM) -> IO NettleGCM
forall b. SecureMem -> (Ptr Word8 -> IO b) -> IO b
withSecureMemPtr SecureMem
ctx' ((Ptr Word8 -> IO NettleGCM) -> IO NettleGCM)
-> (Ptr Word8 -> IO NettleGCM) -> IO NettleGCM
forall a b. (a -> b) -> a -> b
$ \ctxptr :: Ptr Word8
ctxptr ->
	SecureMem -> (Ptr Word8 -> IO NettleGCM) -> IO NettleGCM
forall b. SecureMem -> (Ptr Word8 -> IO b) -> IO b
withSecureMemPtr SecureMem
h ((Ptr Word8 -> IO NettleGCM) -> IO NettleGCM)
-> (Ptr Word8 -> IO NettleGCM) -> IO NettleGCM
forall a b. (a -> b) -> a -> b
$ \hptr :: Ptr Word8
hptr ->
	ByteString -> (Word -> Ptr Word8 -> IO NettleGCM) -> IO NettleGCM
forall a. ByteString -> (Word -> Ptr Word8 -> IO a) -> IO a
withByteStringPtr ByteString
indata ((Word -> Ptr Word8 -> IO NettleGCM) -> IO NettleGCM)
-> (Word -> Ptr Word8 -> IO NettleGCM) -> IO NettleGCM
forall a b. (a -> b) -> a -> b
$ \indatalen :: Word
indatalen indataptr :: Ptr Word8
indataptr ->
	Ptr Word8 -> Ptr Word8 -> Word -> Ptr Word8 -> IO ()
c_gcm_update Ptr Word8
ctxptr Ptr Word8
hptr Word
indatalen Ptr Word8
indataptr IO () -> IO NettleGCM -> IO NettleGCM
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
	NettleGCM -> IO NettleGCM
forall (m :: * -> *) a. Monad m => a -> m a
return (SecureMem -> SecureMem -> NettleGCM
NettleGCM SecureMem
ctx' SecureMem
h)

gcm_crypt
	:: NettleGCMMode
	-> (Ptr Word8 -> Ptr Word8)
	-> FunPtr NettleCryptFunc
	-> SecureMem -> NettleGCM -> B.ByteString -> (B.ByteString, NettleGCM)
gcm_crypt :: NettleGCMMode
-> (Ptr Word8 -> Ptr Word8)
-> FunPtr NettleCryptFunc
-> SecureMem
-> NettleGCM
-> ByteString
-> (ByteString, NettleGCM)
gcm_crypt mode :: NettleGCMMode
mode encctxoffset :: Ptr Word8 -> Ptr Word8
encctxoffset encrypt :: FunPtr NettleCryptFunc
encrypt encctx :: SecureMem
encctx (NettleGCM ctx :: SecureMem
ctx h :: SecureMem
h) indata :: ByteString
indata = IO (ByteString, NettleGCM) -> (ByteString, NettleGCM)
forall a. IO a -> a
unsafeDupablePerformIO (IO (ByteString, NettleGCM) -> (ByteString, NettleGCM))
-> IO (ByteString, NettleGCM) -> (ByteString, NettleGCM)
forall a b. (a -> b) -> a -> b
$
	SecureMem -> IO SecureMem
secureMemCopy SecureMem
ctx IO SecureMem
-> (SecureMem -> IO (ByteString, NettleGCM))
-> IO (ByteString, NettleGCM)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \ctx' :: SecureMem
ctx' ->
	SecureMem
-> (Ptr Word8 -> IO (ByteString, NettleGCM))
-> IO (ByteString, NettleGCM)
forall b. SecureMem -> (Ptr Word8 -> IO b) -> IO b
withSecureMemPtr SecureMem
ctx' ((Ptr Word8 -> IO (ByteString, NettleGCM))
 -> IO (ByteString, NettleGCM))
-> (Ptr Word8 -> IO (ByteString, NettleGCM))
-> IO (ByteString, NettleGCM)
forall a b. (a -> b) -> a -> b
$ \ctxptr :: Ptr Word8
ctxptr ->
	SecureMem
-> (Ptr Word8 -> IO (ByteString, NettleGCM))
-> IO (ByteString, NettleGCM)
forall b. SecureMem -> (Ptr Word8 -> IO b) -> IO b
withSecureMemPtr SecureMem
h ((Ptr Word8 -> IO (ByteString, NettleGCM))
 -> IO (ByteString, NettleGCM))
-> (Ptr Word8 -> IO (ByteString, NettleGCM))
-> IO (ByteString, NettleGCM)
forall a b. (a -> b) -> a -> b
$ \hptr :: Ptr Word8
hptr ->
	SecureMem
-> (Ptr Word8 -> IO (ByteString, NettleGCM))
-> IO (ByteString, NettleGCM)
forall b. SecureMem -> (Ptr Word8 -> IO b) -> IO b
withSecureMemPtr SecureMem
encctx ((Ptr Word8 -> IO (ByteString, NettleGCM))
 -> IO (ByteString, NettleGCM))
-> (Ptr Word8 -> IO (ByteString, NettleGCM))
-> IO (ByteString, NettleGCM)
forall a b. (a -> b) -> a -> b
$ \encctxptr :: Ptr Word8
encctxptr ->
	ByteString
-> (Word -> Ptr Word8 -> IO (ByteString, NettleGCM))
-> IO (ByteString, NettleGCM)
forall a. ByteString -> (Word -> Ptr Word8 -> IO a) -> IO a
withByteStringPtr ByteString
indata ((Word -> Ptr Word8 -> IO (ByteString, NettleGCM))
 -> IO (ByteString, NettleGCM))
-> (Word -> Ptr Word8 -> IO (ByteString, NettleGCM))
-> IO (ByteString, NettleGCM)
forall a b. (a -> b) -> a -> b
$ \indatalen :: Word
indatalen indataptr :: Ptr Word8
indataptr -> do
	ByteString
outdata <- Int -> (Ptr Word8 -> IO ()) -> IO ByteString
B.create (ByteString -> Int
B.length ByteString
indata) ((Ptr Word8 -> IO ()) -> IO ByteString)
-> (Ptr Word8 -> IO ()) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \outptr :: Ptr Word8
outptr ->
		NettleGCMMode
mode Ptr Word8
ctxptr Ptr Word8
hptr (Ptr Word8 -> Ptr Word8
encctxoffset Ptr Word8
encctxptr) FunPtr NettleCryptFunc
encrypt Word
indatalen Ptr Word8
outptr Ptr Word8
indataptr
	(ByteString, NettleGCM) -> IO (ByteString, NettleGCM)
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString
outdata, SecureMem -> SecureMem -> NettleGCM
NettleGCM SecureMem
ctx' SecureMem
h)

gcm_digest
	:: (Ptr Word8 -> Ptr Word8)
	-> FunPtr NettleCryptFunc
	-> SecureMem -> NettleGCM -> Int -> AuthTag
gcm_digest :: (Ptr Word8 -> Ptr Word8)
-> FunPtr NettleCryptFunc
-> SecureMem
-> NettleGCM
-> Int
-> AuthTag
gcm_digest encctxoffset :: Ptr Word8 -> Ptr Word8
encctxoffset encrypt :: FunPtr NettleCryptFunc
encrypt encctx :: SecureMem
encctx (NettleGCM ctx :: SecureMem
ctx h :: SecureMem
h) taglen :: Int
taglen = IO AuthTag -> AuthTag
forall a. IO a -> a
unsafeDupablePerformIO (IO AuthTag -> AuthTag) -> IO AuthTag -> AuthTag
forall a b. (a -> b) -> a -> b
$
	SecureMem -> IO SecureMem
secureMemCopy SecureMem
ctx IO SecureMem -> (SecureMem -> IO AuthTag) -> IO AuthTag
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \ctx' :: SecureMem
ctx' ->
	SecureMem -> (Ptr Word8 -> IO AuthTag) -> IO AuthTag
forall b. SecureMem -> (Ptr Word8 -> IO b) -> IO b
withSecureMemPtr SecureMem
ctx' ((Ptr Word8 -> IO AuthTag) -> IO AuthTag)
-> (Ptr Word8 -> IO AuthTag) -> IO AuthTag
forall a b. (a -> b) -> a -> b
$ \ctxptr :: Ptr Word8
ctxptr ->
	SecureMem -> (Ptr Word8 -> IO AuthTag) -> IO AuthTag
forall b. SecureMem -> (Ptr Word8 -> IO b) -> IO b
withSecureMemPtr SecureMem
h ((Ptr Word8 -> IO AuthTag) -> IO AuthTag)
-> (Ptr Word8 -> IO AuthTag) -> IO AuthTag
forall a b. (a -> b) -> a -> b
$ \hptr :: Ptr Word8
hptr ->
	SecureMem -> (Ptr Word8 -> IO AuthTag) -> IO AuthTag
forall b. SecureMem -> (Ptr Word8 -> IO b) -> IO b
withSecureMemPtr SecureMem
encctx ((Ptr Word8 -> IO AuthTag) -> IO AuthTag)
-> (Ptr Word8 -> IO AuthTag) -> IO AuthTag
forall a b. (a -> b) -> a -> b
$ \encctxptr :: Ptr Word8
encctxptr -> do
	ByteString
tag <- Int -> (Ptr Word8 -> IO ()) -> IO ByteString
B.create (Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
taglen) ((Ptr Word8 -> IO ()) -> IO ByteString)
-> (Ptr Word8 -> IO ()) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \tagptr :: Ptr Word8
tagptr ->
		Ptr Word8
-> Ptr Word8
-> Ptr Word8
-> FunPtr NettleCryptFunc
-> Word
-> Ptr Word8
-> IO ()
c_gcm_digest Ptr Word8
ctxptr Ptr Word8
hptr (Ptr Word8 -> Ptr Word8
encctxoffset Ptr Word8
encctxptr) FunPtr NettleCryptFunc
encrypt (Int -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
taglen) Ptr Word8
tagptr
	AuthTag -> IO AuthTag
forall (m :: * -> *) a. Monad m => a -> m a
return (AuthTag -> IO AuthTag) -> AuthTag -> IO AuthTag
forall a b. (a -> b) -> a -> b
$ ByteString -> AuthTag
AuthTag ByteString
tag

stream_crypt
	:: NettleCryptFunc
	-> SecureMem -> B.ByteString -> (B.ByteString, SecureMem)
stream_crypt :: NettleCryptFunc
-> SecureMem -> ByteString -> (ByteString, SecureMem)
stream_crypt crypt :: NettleCryptFunc
crypt ctx :: SecureMem
ctx indata :: ByteString
indata = IO (ByteString, SecureMem) -> (ByteString, SecureMem)
forall a. IO a -> a
unsafeDupablePerformIO (IO (ByteString, SecureMem) -> (ByteString, SecureMem))
-> IO (ByteString, SecureMem) -> (ByteString, SecureMem)
forall a b. (a -> b) -> a -> b
$
	SecureMem -> IO SecureMem
secureMemCopy SecureMem
ctx IO SecureMem
-> (SecureMem -> IO (ByteString, SecureMem))
-> IO (ByteString, SecureMem)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \ctx' :: SecureMem
ctx' ->
	SecureMem
-> (Ptr Word8 -> IO (ByteString, SecureMem))
-> IO (ByteString, SecureMem)
forall b. SecureMem -> (Ptr Word8 -> IO b) -> IO b
withSecureMemPtr SecureMem
ctx' ((Ptr Word8 -> IO (ByteString, SecureMem))
 -> IO (ByteString, SecureMem))
-> (Ptr Word8 -> IO (ByteString, SecureMem))
-> IO (ByteString, SecureMem)
forall a b. (a -> b) -> a -> b
$ \ctxptr :: Ptr Word8
ctxptr ->
	ByteString
-> (Word -> Ptr Word8 -> IO (ByteString, SecureMem))
-> IO (ByteString, SecureMem)
forall a. ByteString -> (Word -> Ptr Word8 -> IO a) -> IO a
withByteStringPtr ByteString
indata ((Word -> Ptr Word8 -> IO (ByteString, SecureMem))
 -> IO (ByteString, SecureMem))
-> (Word -> Ptr Word8 -> IO (ByteString, SecureMem))
-> IO (ByteString, SecureMem)
forall a b. (a -> b) -> a -> b
$ \indatalen :: Word
indatalen indataptr :: Ptr Word8
indataptr -> do
	ByteString
outdata <- Int -> (Ptr Word8 -> IO ()) -> IO ByteString
B.create (ByteString -> Int
B.length ByteString
indata) ((Ptr Word8 -> IO ()) -> IO ByteString)
-> (Ptr Word8 -> IO ()) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \outptr :: Ptr Word8
outptr ->
		NettleCryptFunc
crypt Ptr Word8
ctxptr Word
indatalen Ptr Word8
outptr Ptr Word8
indataptr
	(ByteString, SecureMem) -> IO (ByteString, SecureMem)
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString
outdata, SecureMem
ctx')