{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Network.QUIC.Crypto.Nite (
niteEncrypt
, niteEncrypt'
, niteDecrypt
, niteDecrypt'
, protectionMask
, aes128gcmEncrypt
, makeNonce
, makeNiteEncrypt
, makeNiteDecrypt
, makeNiteProtector
) where
import Crypto.Cipher.AES
import Crypto.Cipher.Types hiding (Cipher, IV)
import Crypto.Error (maybeCryptoError)
import qualified Data.ByteArray as Byte (convert)
import qualified Data.ByteString as BS
import qualified Data.ByteString.Internal as BS
import Foreign.ForeignPtr (withForeignPtr, newForeignPtr_)
import Foreign.Marshal.Alloc (mallocBytes)
import Foreign.Ptr (Ptr, plusPtr, nullPtr)
import Foreign.Storable (peek, poke)
import Network.TLS hiding (Version)
import Network.TLS.Extra.Cipher
import Network.QUIC.Crypto.Types
import Network.QUIC.Imports
import Network.QUIC.Types
cipherEncrypt :: Cipher -> Key -> Nonce -> PlainText -> AssDat -> Maybe (CipherText,CipherText)
cipherEncrypt :: Cipher
-> Key
-> Nonce
-> ByteString
-> AssDat
-> Maybe (ByteString, ByteString)
cipherEncrypt Cipher
cipher
| Cipher
cipher forall a. Eq a => a -> a -> Bool
== Cipher
cipher_TLS13_AES128GCM_SHA256 = Key
-> Nonce -> ByteString -> AssDat -> Maybe (ByteString, ByteString)
aes128gcmEncrypt
| Cipher
cipher forall a. Eq a => a -> a -> Bool
== Cipher
cipher_TLS13_AES128CCM_SHA256 = forall a. HasCallStack => [Char] -> a
error [Char]
"cipher_TLS13_AES128CCM_SHA256"
| Cipher
cipher forall a. Eq a => a -> a -> Bool
== Cipher
cipher_TLS13_AES256GCM_SHA384 = Key
-> Nonce -> ByteString -> AssDat -> Maybe (ByteString, ByteString)
aes256gcmEncrypt
| Bool
otherwise = forall a. HasCallStack => [Char] -> a
error [Char]
"cipherEncrypt"
cipherDecrypt :: Cipher -> Key -> Nonce -> CipherText -> AssDat -> Maybe PlainText
cipherDecrypt :: Cipher -> Key -> Nonce -> ByteString -> AssDat -> Maybe ByteString
cipherDecrypt Cipher
cipher
| Cipher
cipher forall a. Eq a => a -> a -> Bool
== Cipher
cipher_TLS13_AES128GCM_SHA256 = Key -> Nonce -> ByteString -> AssDat -> Maybe ByteString
aes128gcmDecrypt
| Cipher
cipher forall a. Eq a => a -> a -> Bool
== Cipher
cipher_TLS13_AES128CCM_SHA256 = forall a. HasCallStack => [Char] -> a
error [Char]
"cipher_TLS13_AES128CCM_SHA256"
| Cipher
cipher forall a. Eq a => a -> a -> Bool
== Cipher
cipher_TLS13_AES256GCM_SHA384 = Key -> Nonce -> ByteString -> AssDat -> Maybe ByteString
aes256gcmDecrypt
| Bool
otherwise = forall a. HasCallStack => [Char] -> a
error [Char]
"cipherDecrypt"
aes128gcmEncrypt :: Key -> (Nonce -> PlainText -> AssDat -> Maybe (CipherText,CipherText))
aes128gcmEncrypt :: Key
-> Nonce -> ByteString -> AssDat -> Maybe (ByteString, ByteString)
aes128gcmEncrypt (Key ByteString
key) = case forall a. CryptoFailable a -> Maybe a
maybeCryptoError forall a b. (a -> b) -> a -> b
$ forall cipher key.
(Cipher cipher, ByteArray key) =>
key -> CryptoFailable cipher
cipherInit ByteString
key of
Maybe AES128
Nothing -> \Nonce
_ ByteString
_ AssDat
_ -> forall a. Maybe a
Nothing
Just (AES128
aes :: AES128) -> \(Nonce ByteString
nonce) ByteString
plaintext (AssDat ByteString
ad) ->
case forall a. CryptoFailable a -> Maybe a
maybeCryptoError forall a b. (a -> b) -> a -> b
$ forall cipher iv.
(BlockCipher cipher, ByteArrayAccess iv) =>
AEADMode -> cipher -> iv -> CryptoFailable (AEAD cipher)
aeadInit AEADMode
AEAD_GCM AES128
aes ByteString
nonce of
Maybe (AEAD AES128)
Nothing -> forall a. Maybe a
Nothing
Just AEAD AES128
aead ->
let (AuthTag Bytes
tag0, ByteString
ciphertext) = forall aad ba a.
(ByteArrayAccess aad, ByteArray ba) =>
AEAD a -> aad -> ba -> Int -> (AuthTag, ba)
aeadSimpleEncrypt AEAD AES128
aead ByteString
ad ByteString
plaintext Int
16
tag :: ByteString
tag = forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
Byte.convert Bytes
tag0
in forall a. a -> Maybe a
Just (ByteString
ciphertext,ByteString
tag)
aes128gcmDecrypt :: Key -> (Nonce -> CipherText -> AssDat -> Maybe PlainText)
aes128gcmDecrypt :: Key -> Nonce -> ByteString -> AssDat -> Maybe ByteString
aes128gcmDecrypt (Key ByteString
key) = case forall a. CryptoFailable a -> Maybe a
maybeCryptoError forall a b. (a -> b) -> a -> b
$ forall cipher key.
(Cipher cipher, ByteArray key) =>
key -> CryptoFailable cipher
cipherInit ByteString
key of
Maybe AES128
Nothing -> \Nonce
_ ByteString
_ AssDat
_ -> forall a. Maybe a
Nothing
Just (AES128
aes :: AES128) -> \(Nonce ByteString
nonce) ByteString
ciphertag (AssDat ByteString
ad) ->
case forall a. CryptoFailable a -> Maybe a
maybeCryptoError forall a b. (a -> b) -> a -> b
$ forall cipher iv.
(BlockCipher cipher, ByteArrayAccess iv) =>
AEADMode -> cipher -> iv -> CryptoFailable (AEAD cipher)
aeadInit AEADMode
AEAD_GCM AES128
aes ByteString
nonce of
Maybe (AEAD AES128)
Nothing -> forall a. Maybe a
Nothing
Just AEAD AES128
aead ->
let (ByteString
ciphertext, ByteString
tag) = Int -> ByteString -> (ByteString, ByteString)
BS.splitAt (ByteString -> Int
BS.length ByteString
ciphertag forall a. Num a => a -> a -> a
- Int
16) ByteString
ciphertag
authtag :: AuthTag
authtag = Bytes -> AuthTag
AuthTag forall a b. (a -> b) -> a -> b
$ forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
Byte.convert ByteString
tag
in forall aad ba a.
(ByteArrayAccess aad, ByteArray ba) =>
AEAD a -> aad -> ba -> AuthTag -> Maybe ba
aeadSimpleDecrypt AEAD AES128
aead ByteString
ad ByteString
ciphertext AuthTag
authtag
aes256gcmEncrypt :: Key -> (Nonce -> PlainText -> AssDat -> Maybe (CipherText,CipherText))
aes256gcmEncrypt :: Key
-> Nonce -> ByteString -> AssDat -> Maybe (ByteString, ByteString)
aes256gcmEncrypt (Key ByteString
key) = case forall a. CryptoFailable a -> Maybe a
maybeCryptoError forall a b. (a -> b) -> a -> b
$ forall cipher key.
(Cipher cipher, ByteArray key) =>
key -> CryptoFailable cipher
cipherInit ByteString
key of
Maybe AES256
Nothing -> \Nonce
_ ByteString
_ AssDat
_ -> forall a. Maybe a
Nothing
Just (AES256
aes :: AES256) -> \(Nonce ByteString
nonce) ByteString
plaintext (AssDat ByteString
ad) ->
case forall a. CryptoFailable a -> Maybe a
maybeCryptoError forall a b. (a -> b) -> a -> b
$ forall cipher iv.
(BlockCipher cipher, ByteArrayAccess iv) =>
AEADMode -> cipher -> iv -> CryptoFailable (AEAD cipher)
aeadInit AEADMode
AEAD_GCM AES256
aes ByteString
nonce of
Maybe (AEAD AES256)
Nothing -> forall a. Maybe a
Nothing
Just AEAD AES256
aead ->
let (AuthTag Bytes
tag0, ByteString
ciphertext) = forall aad ba a.
(ByteArrayAccess aad, ByteArray ba) =>
AEAD a -> aad -> ba -> Int -> (AuthTag, ba)
aeadSimpleEncrypt AEAD AES256
aead ByteString
ad ByteString
plaintext Int
16
tag :: ByteString
tag = forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
Byte.convert Bytes
tag0
in forall a. a -> Maybe a
Just (ByteString
ciphertext,ByteString
tag)
aes256gcmDecrypt :: Key -> (Nonce -> CipherText -> AssDat -> Maybe PlainText)
aes256gcmDecrypt :: Key -> Nonce -> ByteString -> AssDat -> Maybe ByteString
aes256gcmDecrypt (Key ByteString
key) = case forall a. CryptoFailable a -> Maybe a
maybeCryptoError forall a b. (a -> b) -> a -> b
$ forall cipher key.
(Cipher cipher, ByteArray key) =>
key -> CryptoFailable cipher
cipherInit ByteString
key of
Maybe AES256
Nothing -> \Nonce
_ ByteString
_ AssDat
_ -> forall a. Maybe a
Nothing
Just (AES256
aes :: AES256) -> \(Nonce ByteString
nonce) ByteString
ciphertag (AssDat ByteString
ad) ->
case forall a. CryptoFailable a -> Maybe a
maybeCryptoError forall a b. (a -> b) -> a -> b
$ forall cipher iv.
(BlockCipher cipher, ByteArrayAccess iv) =>
AEADMode -> cipher -> iv -> CryptoFailable (AEAD cipher)
aeadInit AEADMode
AEAD_GCM AES256
aes ByteString
nonce of
Maybe (AEAD AES256)
Nothing -> forall a. Maybe a
Nothing
Just AEAD AES256
aead ->
let (ByteString
ciphertext, ByteString
tag) = Int -> ByteString -> (ByteString, ByteString)
BS.splitAt (ByteString -> Int
BS.length ByteString
ciphertag forall a. Num a => a -> a -> a
- Int
16) ByteString
ciphertag
authtag :: AuthTag
authtag = Bytes -> AuthTag
AuthTag forall a b. (a -> b) -> a -> b
$ forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
Byte.convert ByteString
tag
in forall aad ba a.
(ByteArrayAccess aad, ByteArray ba) =>
AEAD a -> aad -> ba -> AuthTag -> Maybe ba
aeadSimpleDecrypt AEAD AES256
aead ByteString
ad ByteString
ciphertext AuthTag
authtag
makeNonce :: IV -> ByteString -> Nonce
makeNonce :: IV -> ByteString -> Nonce
makeNonce (IV ByteString
iv) ByteString
pn = ByteString -> Nonce
Nonce ByteString
nonce
where
nonce :: ByteString
nonce = ByteString -> ByteString -> ByteString
bsXORpad ByteString
iv ByteString
pn
bsXORpad :: ByteString -> ByteString -> ByteString
bsXORpad :: ByteString -> ByteString -> ByteString
bsXORpad (PS ForeignPtr Word8
fp0 Int
off0 Int
len0) (PS ForeignPtr Word8
fp1 Int
off1 Int
len1)
| Int
len0 forall a. Ord a => a -> a -> Bool
< Int
len1 = forall a. HasCallStack => [Char] -> a
error [Char]
"bsXORpad"
| Bool
otherwise = Int -> (Ptr Word8 -> IO ()) -> ByteString
BS.unsafeCreate Int
len0 forall a b. (a -> b) -> a -> b
$ \Ptr Word8
dst ->
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Word8
fp0 forall a b. (a -> b) -> a -> b
$ \Ptr Word8
p0 ->
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Word8
fp1 forall a b. (a -> b) -> a -> b
$ \Ptr Word8
p1 -> do
let src0 :: Ptr b
src0 = Ptr Word8
p0 forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
off0
let src1 :: Ptr b
src1 = Ptr Word8
p1 forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
off1
let diff :: Int
diff = Int
len0 forall a. Num a => a -> a -> a
- Int
len1
Ptr Word8 -> Ptr Word8 -> Int -> IO ()
BS.memcpy Ptr Word8
dst forall {b}. Ptr b
src0 Int
diff
Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> Int -> IO ()
loop (Ptr Word8
dst forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
diff) (forall {b}. Ptr b
src0 forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
diff) forall {b}. Ptr b
src1 Int
len1
where
loop :: Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> Int -> IO ()
loop :: Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> Int -> IO ()
loop Ptr Word8
_ Ptr Word8
_ Ptr Word8
_ Int
0 = forall (m :: * -> *) a. Monad m => a -> m a
return ()
loop Ptr Word8
dst Ptr Word8
src0 Ptr Word8
src1 Int
len = do
Word8
w1 <- forall a. Storable a => Ptr a -> IO a
peek Ptr Word8
src0
Word8
w2 <- forall a. Storable a => Ptr a -> IO a
peek Ptr Word8
src1
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr Word8
dst (Word8
w1 forall a. Bits a => a -> a -> a
`xor` Word8
w2)
Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> Int -> IO ()
loop (Ptr Word8
dst forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
1) (Ptr Word8
src0 forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
1) (Ptr Word8
src1 forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
1) (Int
len forall a. Num a => a -> a -> a
- Int
1)
type NiteEncrypt = Buffer -> PlainText -> AssDat -> PacketNumber -> IO Int
makeNiteEncrypt :: Cipher -> Key -> IV -> NiteEncrypt
makeNiteEncrypt :: Cipher -> Key -> IV -> NiteEncrypt
makeNiteEncrypt Cipher
cipher Key
key IV
iv = (ByteString -> AssDat -> Int -> Maybe (ByteString, ByteString))
-> NiteEncrypt
niteEncryptWrapper (Cipher
-> Key
-> IV
-> ByteString
-> AssDat
-> Int
-> Maybe (ByteString, ByteString)
niteEncrypt Cipher
cipher Key
key IV
iv)
niteEncryptWrapper :: (PlainText -> AssDat -> PacketNumber -> Maybe (CipherText,CipherText)) -> NiteEncrypt
niteEncryptWrapper :: (ByteString -> AssDat -> Int -> Maybe (ByteString, ByteString))
-> NiteEncrypt
niteEncryptWrapper ByteString -> AssDat -> Int -> Maybe (ByteString, ByteString)
enc Ptr Word8
dst ByteString
plaintext AssDat
ad Int
pn = case ByteString -> AssDat -> Int -> Maybe (ByteString, ByteString)
enc ByteString
plaintext AssDat
ad Int
pn of
Maybe (ByteString, ByteString)
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return (-Int
1)
Just (ByteString
hdr,ByteString
bdy) -> do
Int
len <- Ptr Word8 -> ByteString -> IO Int
copyBS Ptr Word8
dst ByteString
hdr
let dst' :: Ptr b
dst' = Ptr Word8
dst forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
len
Int
len' <- Ptr Word8 -> ByteString -> IO Int
copyBS forall {b}. Ptr b
dst' ByteString
bdy
forall (m :: * -> *) a. Monad m => a -> m a
return (Int
len forall a. Num a => a -> a -> a
+ Int
len')
niteEncrypt :: Cipher -> Key -> IV
-> PlainText -> AssDat -> PacketNumber -> Maybe (CipherText,CipherText)
niteEncrypt :: Cipher
-> Key
-> IV
-> ByteString
-> AssDat
-> Int
-> Maybe (ByteString, ByteString)
niteEncrypt Cipher
cipher Key
key IV
iv =
let enc :: Nonce -> ByteString -> AssDat -> Maybe (ByteString, ByteString)
enc = Cipher
-> Key
-> Nonce
-> ByteString
-> AssDat
-> Maybe (ByteString, ByteString)
cipherEncrypt Cipher
cipher Key
key
mk :: ByteString -> Nonce
mk = IV -> ByteString -> Nonce
makeNonce IV
iv
in \ByteString
plaintext AssDat
header Int
pn -> let bytePN :: ByteString
bytePN = Word64 -> ByteString
bytestring64 forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
pn
nonce :: Nonce
nonce = ByteString -> Nonce
mk ByteString
bytePN
in Nonce -> ByteString -> AssDat -> Maybe (ByteString, ByteString)
enc Nonce
nonce ByteString
plaintext AssDat
header
niteEncrypt' :: Cipher -> Key -> Nonce -> PlainText -> AssDat -> Maybe (CipherText,CipherText)
niteEncrypt' :: Cipher
-> Key
-> Nonce
-> ByteString
-> AssDat
-> Maybe (ByteString, ByteString)
niteEncrypt' Cipher
cipher Key
key Nonce
nonce ByteString
plaintext AssDat
header =
Cipher
-> Key
-> Nonce
-> ByteString
-> AssDat
-> Maybe (ByteString, ByteString)
cipherEncrypt Cipher
cipher Key
key Nonce
nonce ByteString
plaintext AssDat
header
type NiteDecrypt = Buffer -> CipherText -> AssDat -> PacketNumber -> IO Int
makeNiteDecrypt :: Cipher -> Key -> IV -> NiteDecrypt
makeNiteDecrypt :: Cipher -> Key -> IV -> NiteEncrypt
makeNiteDecrypt Cipher
cipher Key
key IV
iv = (ByteString -> AssDat -> Int -> Maybe ByteString) -> NiteEncrypt
niteDecryptWrapper (Cipher
-> Key -> IV -> ByteString -> AssDat -> Int -> Maybe ByteString
niteDecrypt Cipher
cipher Key
key IV
iv)
niteDecryptWrapper :: (CipherText -> AssDat -> PacketNumber -> Maybe PlainText) -> NiteDecrypt
niteDecryptWrapper :: (ByteString -> AssDat -> Int -> Maybe ByteString) -> NiteEncrypt
niteDecryptWrapper ByteString -> AssDat -> Int -> Maybe ByteString
dec Ptr Word8
dst ByteString
ciphertext AssDat
ad Int
pn = case ByteString -> AssDat -> Int -> Maybe ByteString
dec ByteString
ciphertext AssDat
ad Int
pn of
Maybe ByteString
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return (-Int
1)
Just ByteString
bs -> Ptr Word8 -> ByteString -> IO Int
copyBS Ptr Word8
dst ByteString
bs
niteDecrypt :: Cipher -> Key -> IV
-> CipherText -> AssDat -> PacketNumber -> Maybe PlainText
niteDecrypt :: Cipher
-> Key -> IV -> ByteString -> AssDat -> Int -> Maybe ByteString
niteDecrypt Cipher
cipher Key
key IV
iv =
let dec :: Nonce -> ByteString -> AssDat -> Maybe ByteString
dec = Cipher -> Key -> Nonce -> ByteString -> AssDat -> Maybe ByteString
cipherDecrypt Cipher
cipher Key
key
mk :: ByteString -> Nonce
mk = IV -> ByteString -> Nonce
makeNonce IV
iv
in \ByteString
ciphertext AssDat
header Int
pn -> let bytePN :: ByteString
bytePN = Word64 -> ByteString
bytestring64 (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
pn)
nonce :: Nonce
nonce = ByteString -> Nonce
mk ByteString
bytePN
in Nonce -> ByteString -> AssDat -> Maybe ByteString
dec Nonce
nonce ByteString
ciphertext AssDat
header
niteDecrypt' :: Cipher -> Key -> Nonce -> CipherText -> AssDat -> Maybe PlainText
niteDecrypt' :: Cipher -> Key -> Nonce -> ByteString -> AssDat -> Maybe ByteString
niteDecrypt' Cipher
cipher Key
key Nonce
nonce ByteString
ciphertext AssDat
header =
Cipher -> Key -> Nonce -> ByteString -> AssDat -> Maybe ByteString
cipherDecrypt Cipher
cipher Key
key Nonce
nonce ByteString
ciphertext AssDat
header
protectionMask :: Cipher -> Key -> (Sample -> Mask)
protectionMask :: Cipher -> Key -> Sample -> Mask
protectionMask Cipher
cipher Key
key =
let f :: Sample -> Mask
f = Cipher -> Key -> Sample -> Mask
cipherHeaderProtection Cipher
cipher Key
key
in \Sample
sample -> Sample -> Mask
f Sample
sample
cipherHeaderProtection :: Cipher -> Key -> (Sample -> Mask)
Cipher
cipher Key
key
| Cipher
cipher forall a. Eq a => a -> a -> Bool
== Cipher
cipher_TLS13_AES128GCM_SHA256 = Key -> Sample -> Mask
aes128ecbEncrypt Key
key
| Cipher
cipher forall a. Eq a => a -> a -> Bool
== Cipher
cipher_TLS13_AES128CCM_SHA256 = forall a. HasCallStack => [Char] -> a
error [Char]
"cipher_TLS13_AES128CCM_SHA256"
| Cipher
cipher forall a. Eq a => a -> a -> Bool
== Cipher
cipher_TLS13_AES256GCM_SHA384 = Key -> Sample -> Mask
aes256ecbEncrypt Key
key
| Bool
otherwise = forall a. HasCallStack => [Char] -> a
error [Char]
"cipherHeaderProtection"
aes128ecbEncrypt :: Key -> (Sample -> Mask)
aes128ecbEncrypt :: Key -> Sample -> Mask
aes128ecbEncrypt (Key ByteString
key) = case forall a. CryptoFailable a -> Maybe a
maybeCryptoError forall a b. (a -> b) -> a -> b
$ forall cipher key.
(Cipher cipher, ByteArray key) =>
key -> CryptoFailable cipher
cipherInit ByteString
key of
Maybe AES128
Nothing -> \Sample
_ -> ByteString -> Mask
Mask ByteString
"0123456789012345"
Just (AES128
aes :: AES128) ->
let encrypt :: ByteString -> ByteString
encrypt = forall cipher ba.
(BlockCipher cipher, ByteArray ba) =>
cipher -> ba -> ba
ecbEncrypt AES128
aes
in \(Sample ByteString
sample) -> let mask :: ByteString
mask = ByteString -> ByteString
encrypt ByteString
sample
in ByteString -> Mask
Mask ByteString
mask
aes256ecbEncrypt :: Key -> (Sample -> Mask)
aes256ecbEncrypt :: Key -> Sample -> Mask
aes256ecbEncrypt (Key ByteString
key) = case forall a. CryptoFailable a -> Maybe a
maybeCryptoError forall a b. (a -> b) -> a -> b
$ forall cipher key.
(Cipher cipher, ByteArray key) =>
key -> CryptoFailable cipher
cipherInit ByteString
key of
Maybe AES256
Nothing -> \Sample
_ -> ByteString -> Mask
Mask ByteString
"0123456789012345"
Just (AES256
aes :: AES256) ->
let encrypt :: ByteString -> ByteString
encrypt = forall cipher ba.
(BlockCipher cipher, ByteArray ba) =>
cipher -> ba -> ba
ecbEncrypt AES256
aes
in \(Sample ByteString
sample) -> let mask :: ByteString
mask = ByteString -> ByteString
encrypt ByteString
sample
in ByteString -> Mask
Mask ByteString
mask
makeNiteProtector :: Cipher -> Key -> IO (Buffer -> IO (), IO Buffer)
makeNiteProtector :: Cipher -> Key -> IO (Ptr Word8 -> IO (), IO (Ptr Word8))
makeNiteProtector Cipher
cipher Key
key = do
IORef (Ptr Word8)
ref <- forall a. a -> IO (IORef a)
newIORef forall {b}. Ptr b
nullPtr
Ptr Word8
dstbuf <- forall a. Int -> IO (Ptr a)
mallocBytes Int
32
forall (m :: * -> *) a. Monad m => a -> m a
return (IORef (Ptr Word8) -> Ptr Word8 -> IO ()
niteSetSample IORef (Ptr Word8)
ref, IORef (Ptr Word8)
-> Int -> (Sample -> Mask) -> Ptr Word8 -> IO (Ptr Word8)
niteGetMask IORef (Ptr Word8)
ref Int
samplelen Sample -> Mask
mkMask Ptr Word8
dstbuf)
where
samplelen :: Int
samplelen = Int
16
mkMask :: Sample -> Mask
mkMask = Cipher -> Key -> Sample -> Mask
protectionMask Cipher
cipher Key
key
niteSetSample :: IORef Buffer -> Buffer -> IO ()
niteSetSample :: IORef (Ptr Word8) -> Ptr Word8 -> IO ()
niteSetSample = forall a. IORef a -> a -> IO ()
writeIORef
niteGetMask :: IORef Buffer -> Int -> (Sample -> Mask) -> Buffer -> IO Buffer
niteGetMask :: IORef (Ptr Word8)
-> Int -> (Sample -> Mask) -> Ptr Word8 -> IO (Ptr Word8)
niteGetMask IORef (Ptr Word8)
ref Int
samplelen Sample -> Mask
mkMask Ptr Word8
dstbuf = do
Ptr Word8
srcbuf <- forall a. IORef a -> IO a
readIORef IORef (Ptr Word8)
ref
ByteString
sample <- do
ForeignPtr Word8
fptr <- forall a. Ptr a -> IO (ForeignPtr a)
newForeignPtr_ Ptr Word8
srcbuf
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ ForeignPtr Word8 -> Int -> Int -> ByteString
PS ForeignPtr Word8
fptr Int
0 Int
samplelen
let Mask ByteString
mask = Sample -> Mask
mkMask forall a b. (a -> b) -> a -> b
$ ByteString -> Sample
Sample ByteString
sample
Int
_len <- Ptr Word8 -> ByteString -> IO Int
copyBS Ptr Word8
dstbuf ByteString
mask
forall (m :: * -> *) a. Monad m => a -> m a
return Ptr Word8
dstbuf