{-# 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 (newForeignPtr_, withForeignPtr)
import Foreign.Marshal.Alloc (mallocBytes)
import Foreign.Marshal.Utils (copyBytes)
import Foreign.Ptr (Ptr, nullPtr, plusPtr)
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
forall a. Ptr a -> Ptr a -> Int -> IO ()
copyBytes 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