remove all the byteArray prefix from byteArray function.
instead expect module import to be qualified for functions.
This commit is contained in:
parent
e52a75af75
commit
ec4e0c4ed9
@ -58,18 +58,19 @@ module Crypto.Cipher.AES.Primitive
|
||||
, ocbFinish
|
||||
) where
|
||||
|
||||
import Data.Word
|
||||
import Foreign.Ptr
|
||||
import Foreign.C.Types
|
||||
import Foreign.C.String
|
||||
import Data.ByteString.Internal
|
||||
import qualified Data.ByteString as B
|
||||
import Data.Word
|
||||
import Foreign.Ptr
|
||||
import Foreign.C.Types
|
||||
import Foreign.C.String
|
||||
import qualified Data.ByteString.Internal as BS
|
||||
import qualified Data.ByteString as BS
|
||||
|
||||
import Crypto.Error
|
||||
import Crypto.Cipher.Types
|
||||
import Crypto.Cipher.Types.Block (IV(..))
|
||||
import Crypto.Internal.Compat
|
||||
import Crypto.Internal.ByteArray
|
||||
import Crypto.Error
|
||||
import Crypto.Cipher.Types
|
||||
import Crypto.Cipher.Types.Block (IV(..))
|
||||
import Crypto.Internal.Compat
|
||||
import Crypto.Internal.ByteArray (ByteArray, ByteArrayAccess, SecureBytes, withByteArray)
|
||||
import qualified Crypto.Internal.ByteArray as B
|
||||
|
||||
instance Cipher AES where
|
||||
cipherName _ = "AES"
|
||||
@ -133,7 +134,7 @@ ivCopyPtr :: IV AES -> (Ptr Word8 -> IO a) -> IO (a, IV AES)
|
||||
ivCopyPtr (IV iv) f = (\(x,y) -> (x, IV y)) `fmap` copyAndModify iv f
|
||||
where
|
||||
copyAndModify :: ByteArray ba => ba -> (Ptr Word8 -> IO a) -> IO (a, ba)
|
||||
copyAndModify ba f' = byteArrayCopyRet ba f'
|
||||
copyAndModify ba f' = B.copyRet ba f'
|
||||
|
||||
withKeyAndIV :: ByteArrayAccess iv => AES -> iv -> (Ptr AES -> Ptr Word8 -> IO a) -> IO a
|
||||
withKeyAndIV ctx iv f = keyToPtr ctx $ \kptr -> ivToPtr iv $ \ivp -> f kptr ivp
|
||||
@ -145,17 +146,17 @@ withKey2AndIV key1 key2 iv f =
|
||||
withGCMKeyAndCopySt :: AES -> AESGCM -> (Ptr AESGCM -> Ptr AES -> IO a) -> IO (a, AESGCM)
|
||||
withGCMKeyAndCopySt aes (AESGCM gcmSt) f =
|
||||
keyToPtr aes $ \aesPtr -> do
|
||||
newSt <- byteArrayCopy gcmSt (\_ -> return ())
|
||||
newSt <- B.copy gcmSt (\_ -> return ())
|
||||
a <- withByteArray newSt $ \gcmStPtr -> f (castPtr gcmStPtr) aesPtr
|
||||
return (a, AESGCM newSt)
|
||||
|
||||
withNewGCMSt :: AESGCM -> (Ptr AESGCM -> IO ()) -> IO AESGCM
|
||||
withNewGCMSt (AESGCM gcmSt) f = byteArrayCopy gcmSt (f . castPtr) >>= \sm2 -> return (AESGCM sm2)
|
||||
withNewGCMSt (AESGCM gcmSt) f = B.copy gcmSt (f . castPtr) >>= \sm2 -> return (AESGCM sm2)
|
||||
|
||||
withOCBKeyAndCopySt :: AES -> AESOCB -> (Ptr AESOCB -> Ptr AES -> IO a) -> IO (a, AESOCB)
|
||||
withOCBKeyAndCopySt aes (AESOCB gcmSt) f =
|
||||
keyToPtr aes $ \aesPtr -> do
|
||||
newSt <- byteArrayCopy gcmSt (\_ -> return ())
|
||||
newSt <- B.copy gcmSt (\_ -> return ())
|
||||
a <- withByteArray newSt $ \gcmStPtr -> f (castPtr gcmStPtr) aesPtr
|
||||
return (a, AESOCB newSt)
|
||||
|
||||
@ -168,8 +169,8 @@ initAES k
|
||||
| len == 24 = CryptoPassed $ initWithRounds 12
|
||||
| len == 32 = CryptoPassed $ initWithRounds 14
|
||||
| otherwise = CryptoFailed CryptoError_KeySizeInvalid
|
||||
where len = byteArrayLength k
|
||||
initWithRounds nbR = AES $ byteArrayAllocAndFreeze (16+2*2*16*nbR) aesInit
|
||||
where len = B.length k
|
||||
initWithRounds nbR = AES $ B.allocAndFreeze (16+2*2*16*nbR) aesInit
|
||||
aesInit ptr = withByteArray k $ \ikey ->
|
||||
c_aes_init (castPtr ptr) (castPtr ikey) (fromIntegral len)
|
||||
|
||||
@ -200,8 +201,8 @@ genCTR :: ByteArray ba
|
||||
-> Int -- ^ length of bytes required.
|
||||
-> ba
|
||||
genCTR ctx (IV iv) len
|
||||
| len <= 0 = empty
|
||||
| otherwise = byteArrayAllocAndFreeze (nbBlocks * 16) generate
|
||||
| len <= 0 = B.empty
|
||||
| otherwise = B.allocAndFreeze (nbBlocks * 16) generate
|
||||
where generate o = withKeyAndIV ctx iv $ \k i -> c_aes_gen_ctr (castPtr o) k i (fromIntegral nbBlocks)
|
||||
(nbBlocks',r) = len `quotRem` 16
|
||||
nbBlocks = if r == 0 then nbBlocks' else nbBlocks' + 1
|
||||
@ -221,11 +222,11 @@ genCounter :: ByteArray ba
|
||||
-> Int
|
||||
-> (ba, IV AES)
|
||||
genCounter ctx iv len
|
||||
| len <= 0 = (empty, iv)
|
||||
| len <= 0 = (B.empty, iv)
|
||||
| otherwise = unsafeDoIO $
|
||||
keyToPtr ctx $ \k ->
|
||||
ivCopyPtr iv $ \i ->
|
||||
byteArrayAlloc outputLength $ \o -> do
|
||||
B.alloc outputLength $ \o -> do
|
||||
c_aes_gen_ctr_cont (castPtr o) k i (fromIntegral nbBlocks)
|
||||
where
|
||||
(nbBlocks',r) = len `quotRem` 16
|
||||
@ -246,12 +247,12 @@ encryptCTR :: ByteArray ba
|
||||
-> ba -- ^ plaintext input
|
||||
-> ba -- ^ ciphertext output
|
||||
encryptCTR ctx iv input
|
||||
| len <= 0 = empty
|
||||
| byteArrayLength iv /= 16 = error $ "AES error: IV length must be block size (16). Its length is: " ++ (show $ byteArrayLength iv)
|
||||
| otherwise = byteArrayAllocAndFreeze len doEncrypt
|
||||
| len <= 0 = B.empty
|
||||
| B.length iv /= 16 = error $ "AES error: IV length must be block size (16). Its length is: " ++ (show $ B.length iv)
|
||||
| otherwise = B.allocAndFreeze len doEncrypt
|
||||
where doEncrypt o = withKeyAndIV ctx iv $ \k v -> withByteArray input $ \i ->
|
||||
c_aes_encrypt_ctr (castPtr o) k v i (fromIntegral len)
|
||||
len = byteArrayLength input
|
||||
len = B.length input
|
||||
|
||||
-- | encrypt using Galois counter mode (GCM)
|
||||
-- return the encrypted bytestring and the tag associated
|
||||
@ -347,26 +348,26 @@ doECB :: ByteArray ba
|
||||
-> AES -> ba -> ba
|
||||
doECB f ctx input
|
||||
| r /= 0 = error $ "Encryption error: input length must be a multiple of block size (16). Its length is: " ++ (show len)
|
||||
| otherwise = byteArrayAllocAndFreeze len $ \o ->
|
||||
| otherwise = B.allocAndFreeze len $ \o ->
|
||||
keyToPtr ctx $ \k ->
|
||||
withByteArray input $ \i ->
|
||||
f (castPtr o) k i (fromIntegral nbBlocks)
|
||||
where (nbBlocks, r) = len `quotRem` 16
|
||||
len = byteArrayLength input
|
||||
len = B.length input
|
||||
|
||||
{-# INLINE doCBC #-}
|
||||
doCBC :: ByteArray ba
|
||||
=> (Ptr b -> Ptr AES -> Ptr Word8 -> CString -> CUInt -> IO ())
|
||||
-> AES -> IV AES -> ba -> ba
|
||||
doCBC f ctx (IV iv) input
|
||||
| len == 0 = empty
|
||||
| len == 0 = B.empty
|
||||
| r /= 0 = error $ "Encryption error: input length must be a multiple of block size (16). Its length is: " ++ (show len)
|
||||
| otherwise = byteArrayAllocAndFreeze len $ \o ->
|
||||
| otherwise = B.allocAndFreeze len $ \o ->
|
||||
withKeyAndIV ctx iv $ \k v ->
|
||||
withByteArray input $ \i ->
|
||||
f (castPtr o) k v i (fromIntegral nbBlocks)
|
||||
where (nbBlocks, r) = len `quotRem` 16
|
||||
len = byteArrayLength input
|
||||
len = B.length input
|
||||
|
||||
{-# INLINE doXTS #-}
|
||||
doXTS :: ByteArray ba
|
||||
@ -377,12 +378,12 @@ doXTS :: ByteArray ba
|
||||
-> ba
|
||||
-> ba
|
||||
doXTS f (key1,key2) iv spoint input
|
||||
| len == 0 = empty
|
||||
| len == 0 = B.empty
|
||||
| r /= 0 = error $ "Encryption error: input length must be a multiple of block size (16) for now. Its length is: " ++ (show len)
|
||||
| otherwise = byteArrayAllocAndFreeze len $ \o -> withKey2AndIV key1 key2 iv $ \k1 k2 v -> withByteArray input $ \i ->
|
||||
| otherwise = B.allocAndFreeze len $ \o -> withKey2AndIV key1 key2 iv $ \k1 k2 v -> withByteArray input $ \i ->
|
||||
f (castPtr o) k1 k2 v (fromIntegral spoint) i (fromIntegral nbBlocks)
|
||||
where (nbBlocks, r) = len `quotRem` 16
|
||||
len = byteArrayLength input
|
||||
len = B.length input
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- GCM
|
||||
@ -406,9 +407,9 @@ doGCM f ctx iv aad input = (output, tag)
|
||||
{-# NOINLINE gcmInit #-}
|
||||
gcmInit :: ByteArrayAccess iv => AES -> iv -> AESGCM
|
||||
gcmInit ctx iv = unsafeDoIO $ do
|
||||
sm <- byteArrayAlloc sizeGCM $ \gcmStPtr ->
|
||||
sm <- B.alloc sizeGCM $ \gcmStPtr ->
|
||||
withKeyAndIV ctx iv $ \k v ->
|
||||
c_aes_gcm_init (castPtr gcmStPtr) k v (fromIntegral $ byteArrayLength iv)
|
||||
c_aes_gcm_init (castPtr gcmStPtr) k v (fromIntegral $ B.length iv)
|
||||
return $ AESGCM sm
|
||||
|
||||
-- | append data which is going to just be authentified to the GCM context.
|
||||
@ -420,7 +421,7 @@ gcmAppendAAD gcmSt input = unsafeDoIO doAppend
|
||||
where doAppend =
|
||||
withNewGCMSt gcmSt $ \gcmStPtr ->
|
||||
withByteArray input $ \i ->
|
||||
c_aes_gcm_aad gcmStPtr i (fromIntegral $ byteArrayLength input)
|
||||
c_aes_gcm_aad gcmStPtr i (fromIntegral $ B.length input)
|
||||
|
||||
-- | append data to encrypt and append to the GCM context
|
||||
--
|
||||
@ -429,9 +430,9 @@ gcmAppendAAD gcmSt input = unsafeDoIO doAppend
|
||||
{-# NOINLINE gcmAppendEncrypt #-}
|
||||
gcmAppendEncrypt :: ByteArray ba => AES -> AESGCM -> ba -> (ba, AESGCM)
|
||||
gcmAppendEncrypt ctx gcm input = unsafeDoIO $ withGCMKeyAndCopySt ctx gcm doEnc
|
||||
where len = byteArrayLength input
|
||||
where len = B.length input
|
||||
doEnc gcmStPtr aesPtr =
|
||||
byteArrayAlloc len $ \o ->
|
||||
B.alloc len $ \o ->
|
||||
withByteArray input $ \i ->
|
||||
c_aes_gcm_encrypt (castPtr o) gcmStPtr aesPtr i (fromIntegral len)
|
||||
|
||||
@ -442,17 +443,17 @@ gcmAppendEncrypt ctx gcm input = unsafeDoIO $ withGCMKeyAndCopySt ctx gcm doEnc
|
||||
{-# NOINLINE gcmAppendDecrypt #-}
|
||||
gcmAppendDecrypt :: ByteArray ba => AES -> AESGCM -> ba -> (ba, AESGCM)
|
||||
gcmAppendDecrypt ctx gcm input = unsafeDoIO $ withGCMKeyAndCopySt ctx gcm doDec
|
||||
where len = byteArrayLength input
|
||||
where len = B.length input
|
||||
doDec gcmStPtr aesPtr =
|
||||
byteArrayAlloc len $ \o ->
|
||||
B.alloc len $ \o ->
|
||||
withByteArray input $ \i ->
|
||||
c_aes_gcm_decrypt (castPtr o) gcmStPtr aesPtr i (fromIntegral len)
|
||||
|
||||
-- | Generate the Tag from GCM context
|
||||
{-# NOINLINE gcmFinish #-}
|
||||
gcmFinish :: AES -> AESGCM -> Int -> AuthTag
|
||||
gcmFinish ctx gcm taglen = AuthTag $ B.take taglen computeTag
|
||||
where computeTag = unsafeCreate 16 $ \t ->
|
||||
gcmFinish ctx gcm taglen = AuthTag $ BS.take taglen computeTag
|
||||
where computeTag = BS.unsafeCreate 16 $ \t ->
|
||||
withGCMKeyAndCopySt ctx gcm (c_aes_gcm_finish (castPtr t)) >> return ()
|
||||
|
||||
------------------------------------------------------------------------
|
||||
@ -477,9 +478,9 @@ doOCB f ctx iv aad input = (output, tag)
|
||||
{-# NOINLINE ocbInit #-}
|
||||
ocbInit :: ByteArrayAccess iv => AES -> iv -> AESOCB
|
||||
ocbInit ctx iv = unsafeDoIO $ do
|
||||
sm <- byteArrayAlloc sizeOCB $ \ocbStPtr ->
|
||||
sm <- B.alloc sizeOCB $ \ocbStPtr ->
|
||||
withKeyAndIV ctx iv $ \k v ->
|
||||
c_aes_ocb_init (castPtr ocbStPtr) k v (fromIntegral $ byteArrayLength iv)
|
||||
c_aes_ocb_init (castPtr ocbStPtr) k v (fromIntegral $ B.length iv)
|
||||
return $ AESOCB sm
|
||||
|
||||
-- | append data which is going to just be authentified to the OCB context.
|
||||
@ -490,7 +491,7 @@ ocbAppendAAD :: ByteArrayAccess aad => AES -> AESOCB -> aad -> AESOCB
|
||||
ocbAppendAAD ctx ocb input = unsafeDoIO (snd `fmap` withOCBKeyAndCopySt ctx ocb doAppend)
|
||||
where doAppend ocbStPtr aesPtr =
|
||||
withByteArray input $ \i ->
|
||||
c_aes_ocb_aad ocbStPtr aesPtr i (fromIntegral $ byteArrayLength input)
|
||||
c_aes_ocb_aad ocbStPtr aesPtr i (fromIntegral $ B.length input)
|
||||
|
||||
-- | append data to encrypt and append to the OCB context
|
||||
--
|
||||
@ -499,9 +500,9 @@ ocbAppendAAD ctx ocb input = unsafeDoIO (snd `fmap` withOCBKeyAndCopySt ctx ocb
|
||||
{-# NOINLINE ocbAppendEncrypt #-}
|
||||
ocbAppendEncrypt :: ByteArray ba => AES -> AESOCB -> ba -> (ba, AESOCB)
|
||||
ocbAppendEncrypt ctx ocb input = unsafeDoIO $ withOCBKeyAndCopySt ctx ocb doEnc
|
||||
where len = byteArrayLength input
|
||||
where len = B.length input
|
||||
doEnc ocbStPtr aesPtr =
|
||||
byteArrayAlloc len $ \o ->
|
||||
B.alloc len $ \o ->
|
||||
withByteArray input $ \i ->
|
||||
c_aes_ocb_encrypt (castPtr o) ocbStPtr aesPtr i (fromIntegral len)
|
||||
|
||||
@ -512,17 +513,17 @@ ocbAppendEncrypt ctx ocb input = unsafeDoIO $ withOCBKeyAndCopySt ctx ocb doEnc
|
||||
{-# NOINLINE ocbAppendDecrypt #-}
|
||||
ocbAppendDecrypt :: ByteArray ba => AES -> AESOCB -> ba -> (ba, AESOCB)
|
||||
ocbAppendDecrypt ctx ocb input = unsafeDoIO $ withOCBKeyAndCopySt ctx ocb doDec
|
||||
where len = byteArrayLength input
|
||||
where len = B.length input
|
||||
doDec ocbStPtr aesPtr =
|
||||
byteArrayAlloc len $ \o ->
|
||||
B.alloc len $ \o ->
|
||||
withByteArray input $ \i ->
|
||||
c_aes_ocb_decrypt (castPtr o) ocbStPtr aesPtr i (fromIntegral len)
|
||||
|
||||
-- | Generate the Tag from OCB context
|
||||
{-# NOINLINE ocbFinish #-}
|
||||
ocbFinish :: AES -> AESOCB -> Int -> AuthTag
|
||||
ocbFinish ctx ocb taglen = AuthTag $ B.take taglen computeTag
|
||||
where computeTag = unsafeCreate 16 $ \t ->
|
||||
ocbFinish ctx ocb taglen = AuthTag $ BS.take taglen computeTag
|
||||
where computeTag = BS.unsafeCreate 16 $ \t ->
|
||||
withOCBKeyAndCopySt ctx ocb (c_aes_ocb_finish (castPtr t)) >> return ()
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
@ -18,16 +18,17 @@ module Crypto.Cipher.Blowfish.Primitive
|
||||
, decrypt
|
||||
) where
|
||||
|
||||
import Control.Monad (forM_, when)
|
||||
import Data.Bits
|
||||
import Data.Word
|
||||
import Control.Monad (forM_, when)
|
||||
import Data.Bits
|
||||
import Data.Word
|
||||
|
||||
import Crypto.Error
|
||||
import Crypto.Internal.Compat
|
||||
import Crypto.Internal.ByteArray
|
||||
import Crypto.Internal.Words
|
||||
import Crypto.Internal.WordArray
|
||||
import Crypto.Cipher.Blowfish.Box
|
||||
import Crypto.Error
|
||||
import Crypto.Internal.Compat
|
||||
import Crypto.Internal.ByteArray (ByteArrayAccess, ByteArray)
|
||||
import qualified Crypto.Internal.ByteArray as B
|
||||
import Crypto.Internal.Words
|
||||
import Crypto.Internal.WordArray
|
||||
import Crypto.Cipher.Blowfish.Box
|
||||
|
||||
-- | variable keyed blowfish state
|
||||
data Context = BF (Int -> Word32) -- p
|
||||
@ -45,15 +46,15 @@ decryptContext (BF p s0 s1 s2 s3) = BF (\i -> p (17-i)) s0 s1 s2 s3
|
||||
|
||||
cipher :: ByteArray ba => Context -> ba -> ba
|
||||
cipher ctx b
|
||||
| byteArrayLength b == 0 = empty
|
||||
| byteArrayLength b `mod` 8 /= 0 = error "invalid data length"
|
||||
| otherwise = byteArrayMapAsWord64 (coreCrypto ctx) b
|
||||
| B.length b == 0 = B.empty
|
||||
| B.length b `mod` 8 /= 0 = error "invalid data length"
|
||||
| otherwise = B.mapAsWord64 (coreCrypto ctx) b
|
||||
|
||||
initBlowfish :: ByteArray key => key -> CryptoFailable Context
|
||||
initBlowfish :: ByteArrayAccess key => key -> CryptoFailable Context
|
||||
initBlowfish key
|
||||
| len > (448 `div` 8) = CryptoFailed $ CryptoError_KeySizeInvalid
|
||||
| otherwise = CryptoPassed $ makeKeySchedule key
|
||||
where len = byteArrayLength key
|
||||
where len = B.length key
|
||||
|
||||
coreCrypto :: Context -> Word64 -> Word64
|
||||
coreCrypto (BF p s0 s1 s2 s3) input = doRound input 0
|
||||
@ -76,16 +77,16 @@ coreCrypto (BF p s0 s1 s2 s3) input = doRound input 0
|
||||
d = s3 (fromIntegral $ t .&. 0xff)
|
||||
in fromIntegral (((a + b) `xor` c) + d) `shiftL` 32
|
||||
|
||||
makeKeySchedule :: ByteArray key => key -> Context
|
||||
makeKeySchedule :: ByteArrayAccess key => key -> Context
|
||||
makeKeySchedule key =
|
||||
let v = unsafeDoIO $ do
|
||||
let len = byteArrayLength key
|
||||
let len = B.length key
|
||||
mv <- createKeySchedule
|
||||
when (len > 0) $ forM_ [0..17] $ \i -> do
|
||||
let a = byteArrayIndex key ((i * 4 + 0) `mod` len)
|
||||
b = byteArrayIndex key ((i * 4 + 1) `mod` len)
|
||||
c = byteArrayIndex key ((i * 4 + 2) `mod` len)
|
||||
d = byteArrayIndex key ((i * 4 + 3) `mod` len)
|
||||
let a = B.index key ((i * 4 + 0) `mod` len)
|
||||
b = B.index key ((i * 4 + 1) `mod` len)
|
||||
c = B.index key ((i * 4 + 2) `mod` len)
|
||||
d = B.index key ((i * 4 + 3) `mod` len)
|
||||
k = (fromIntegral a `shiftL` 24) .|.
|
||||
(fromIntegral b `shiftL` 16) .|.
|
||||
(fromIntegral c `shiftL` 8) .|.
|
||||
|
||||
@ -16,15 +16,16 @@ module Crypto.Cipher.Camellia.Primitive
|
||||
, decrypt
|
||||
) where
|
||||
|
||||
import Data.Word
|
||||
import Data.Bits
|
||||
import qualified Data.ByteString as B
|
||||
import Data.Word
|
||||
import Data.Bits
|
||||
import qualified Data.ByteString as B hiding (length)
|
||||
import qualified Data.ByteString.Unsafe as B
|
||||
|
||||
import Crypto.Error
|
||||
import Crypto.Internal.ByteArray
|
||||
import Crypto.Internal.Words
|
||||
import Crypto.Internal.WordArray
|
||||
import Crypto.Error
|
||||
import Crypto.Internal.ByteArray (ByteArrayAccess, ByteArray)
|
||||
import qualified Crypto.Internal.ByteArray as B
|
||||
import Crypto.Internal.Words
|
||||
import Crypto.Internal.WordArray
|
||||
|
||||
data Mode = Decrypt | Encrypt
|
||||
|
||||
@ -115,9 +116,9 @@ data Camellia = Camellia
|
||||
, ke :: Array64
|
||||
}
|
||||
|
||||
setKeyInterim :: ByteArray key => key -> (Word128, Word128, Word128, Word128)
|
||||
setKeyInterim :: ByteArrayAccess key => key -> (Word128, Word128, Word128, Word128)
|
||||
setKeyInterim keyseed = (w64tow128 kL, w64tow128 kR, w64tow128 kA, w64tow128 kB)
|
||||
where kL = (byteArrayToW64BE keyseed 0, byteArrayToW64BE keyseed 8)
|
||||
where kL = (B.toW64BE keyseed 0, B.toW64BE keyseed 8)
|
||||
kR = (0, 0)
|
||||
|
||||
kA = let d1 = (fst kL `xor` fst kR)
|
||||
@ -144,8 +145,8 @@ initCamellia :: ByteArray key
|
||||
=> key -- ^ The key to create the camellia context
|
||||
-> CryptoFailable Camellia
|
||||
initCamellia key
|
||||
| byteArrayLength key /= 16 = CryptoFailed $ CryptoError_KeySizeInvalid
|
||||
| otherwise =
|
||||
| B.length key /= 16 = CryptoFailed $ CryptoError_KeySizeInvalid
|
||||
| otherwise =
|
||||
let (kL, _, kA, _) = setKeyInterim key in
|
||||
|
||||
let (Word128 kw1 kw2) = (kL `rotl128` 0) in
|
||||
@ -274,11 +275,11 @@ encrypt :: ByteArray ba
|
||||
=> Camellia -- ^ The key to use
|
||||
-> ba -- ^ The data to encrypt
|
||||
-> ba
|
||||
encrypt key = byteArrayMapAsWord128 (encryptBlock key)
|
||||
encrypt key = B.mapAsWord128 (encryptBlock key)
|
||||
|
||||
-- | Decrypts the given ByteString using the given Key
|
||||
decrypt :: ByteArray ba
|
||||
=> Camellia -- ^ The key to use
|
||||
-> ba -- ^ The data to decrypt
|
||||
-> ba
|
||||
decrypt key = byteArrayMapAsWord128 (decryptBlock key)
|
||||
decrypt key = B.mapAsWord128 (decryptBlock key)
|
||||
|
||||
@ -17,18 +17,18 @@ module Crypto.Cipher.ChaCha
|
||||
, StateSimple
|
||||
) where
|
||||
|
||||
import Data.ByteString (ByteString)
|
||||
import qualified Data.ByteString.Internal as B
|
||||
import qualified Data.ByteString as B
|
||||
import Crypto.Internal.ByteArray
|
||||
import Crypto.Internal.Compat
|
||||
import Crypto.Internal.Imports
|
||||
import Data.Byteable
|
||||
import Data.Bits (xor)
|
||||
import Foreign.Ptr
|
||||
import Foreign.ForeignPtr
|
||||
import Foreign.C.Types
|
||||
import Foreign.Storable
|
||||
import Data.ByteString (ByteString)
|
||||
import qualified Data.ByteString as BS
|
||||
import qualified Data.ByteString.Internal as BS
|
||||
import Crypto.Internal.ByteArray (ByteArrayAccess, ByteArray, SecureBytes, withByteArray)
|
||||
import qualified Crypto.Internal.ByteArray as B
|
||||
import Crypto.Internal.Compat
|
||||
import Crypto.Internal.Imports
|
||||
import Data.Bits (xor)
|
||||
import Foreign.Ptr
|
||||
import Foreign.ForeignPtr
|
||||
import Foreign.C.Types
|
||||
import Foreign.Storable
|
||||
|
||||
-- | ChaCha context
|
||||
data State = State Int -- number of rounds
|
||||
@ -57,12 +57,12 @@ initialize nbRounds key nonce
|
||||
| not (nonceLen `elem` [8,12]) = error "ChaCha: nonce length should be 64 or 96 bits"
|
||||
| not (nbRounds `elem` [8,12,20]) = error "ChaCha: rounds should be 8, 12 or 20"
|
||||
| otherwise = unsafeDoIO $ do
|
||||
stPtr <- byteArrayAlloc 64 $ \stPtr ->
|
||||
stPtr <- B.alloc 64 $ \stPtr ->
|
||||
withByteArray nonce $ \noncePtr ->
|
||||
withByteArray key $ \keyPtr ->
|
||||
ccryptonite_chacha_init (castPtr stPtr) kLen keyPtr nonceLen noncePtr
|
||||
return $ State nbRounds stPtr B.empty
|
||||
where kLen = byteArrayLength key
|
||||
where kLen = B.length key
|
||||
nonceLen = B.length nonce
|
||||
|
||||
-- | Initialize simple ChaCha State
|
||||
@ -72,12 +72,12 @@ initializeSimple :: ByteArray seed
|
||||
initializeSimple seed
|
||||
| sLen /= 40 = error "ChaCha Random: seed length should be 40 bytes"
|
||||
| otherwise = unsafeDoIO $ do
|
||||
stPtr <- byteArrayAlloc 64 $ \stPtr ->
|
||||
stPtr <- B.alloc 64 $ \stPtr ->
|
||||
withByteArray seed $ \seedPtr ->
|
||||
ccryptonite_chacha_init (castPtr stPtr) 32 seedPtr 8 (seedPtr `plusPtr` 32)
|
||||
return $ StateSimple stPtr
|
||||
where
|
||||
sLen = byteArrayLength seed
|
||||
sLen = B.length seed
|
||||
|
||||
-- | Combine the chacha output and an arbitrary message with a xor,
|
||||
-- and return the combined output and the new state.
|
||||
@ -89,8 +89,8 @@ combine prev@(State nbRounds prevSt prevOut) src
|
||||
| outputLen <= prevBufLen =
|
||||
-- we have enough byte in the previous buffer to complete the query
|
||||
-- without having to generate any extra bytes
|
||||
let (b1,b2) = B.splitAt outputLen prevOut
|
||||
in (B.pack $ B.zipWith xor b1 src, State nbRounds prevSt b2)
|
||||
let (b1,b2) = BS.splitAt outputLen prevOut
|
||||
in (BS.pack $ BS.zipWith xor b1 src, State nbRounds prevSt b2)
|
||||
| otherwise = unsafeDoIO $ do
|
||||
-- adjusted len is the number of bytes lefts to generate after
|
||||
-- copying from the previous buffer.
|
||||
@ -98,15 +98,15 @@ combine prev@(State nbRounds prevSt prevOut) src
|
||||
(roundedAlready, newBytesToGenerate) = round64 adjustedLen
|
||||
nextBufLen = newBytesToGenerate - adjustedLen
|
||||
|
||||
fptr <- B.mallocByteString (newBytesToGenerate + prevBufLen)
|
||||
fptr <- BS.mallocByteString (newBytesToGenerate + prevBufLen)
|
||||
newSt <- withForeignPtr fptr $ \dstPtr ->
|
||||
withByteArray src $ \srcPtr -> do
|
||||
-- copy the previous buffer by xor if any
|
||||
withBytePtr prevOut $ \prevPtr ->
|
||||
withByteArray prevOut $ \prevPtr ->
|
||||
loopXor dstPtr srcPtr prevPtr prevBufLen
|
||||
|
||||
-- then create a new mutable copy of state
|
||||
st <- byteArrayCopy prevSt (\_ -> return ())
|
||||
st <- B.copy prevSt (\_ -> return ())
|
||||
withByteArray st $ \stPtr ->
|
||||
ccryptonite_chacha_combine nbRounds
|
||||
(dstPtr `plusPtr` prevBufLen)
|
||||
@ -115,8 +115,8 @@ combine prev@(State nbRounds prevSt prevOut) src
|
||||
(fromIntegral newBytesToGenerate)
|
||||
return st
|
||||
-- return combined byte
|
||||
return ( B.PS fptr 0 outputLen
|
||||
, State nbRounds newSt (if roundedAlready then B.empty else B.PS fptr outputLen nextBufLen))
|
||||
return ( BS.PS fptr 0 outputLen
|
||||
, State nbRounds newSt (if roundedAlready then BS.empty else BS.PS fptr outputLen nextBufLen))
|
||||
where
|
||||
outputLen = B.length src
|
||||
prevBufLen = B.length prevOut
|
||||
@ -133,7 +133,7 @@ combine prev@(State nbRounds prevSt prevOut) src
|
||||
generate :: State -- ^ the current ChaCha state
|
||||
-> Int -- ^ the length of data to generate
|
||||
-> (ByteString, State)
|
||||
generate st len = combine st (B.replicate len 0)
|
||||
generate st len = combine st (BS.replicate len 0)
|
||||
|
||||
-- | similar to 'generate' but assume certains values
|
||||
generateSimple :: ByteArray ba
|
||||
@ -141,8 +141,8 @@ generateSimple :: ByteArray ba
|
||||
-> Int
|
||||
-> (ba, StateSimple)
|
||||
generateSimple (StateSimple prevSt) nbBytes = unsafeDoIO $ do
|
||||
newSt <- byteArrayCopy prevSt (\_ -> return ())
|
||||
output <- byteArrayAlloc nbBytes $ \dstPtr ->
|
||||
newSt <- B.copy prevSt (\_ -> return ())
|
||||
output <- B.alloc nbBytes $ \dstPtr ->
|
||||
withByteArray newSt $ \stPtr ->
|
||||
ccryptonite_chacha_random 8 dstPtr (castPtr stPtr) (fromIntegral nbBytes)
|
||||
return (output, StateSimple newSt)
|
||||
|
||||
@ -9,11 +9,12 @@ module Crypto.Cipher.DES
|
||||
( DES
|
||||
) where
|
||||
|
||||
import Data.Word
|
||||
import Crypto.Error
|
||||
import Crypto.Cipher.Types
|
||||
import Crypto.Cipher.DES.Primitive
|
||||
import Crypto.Internal.ByteArray
|
||||
import Data.Word
|
||||
import Crypto.Error
|
||||
import Crypto.Cipher.Types
|
||||
import Crypto.Cipher.DES.Primitive
|
||||
import Crypto.Internal.ByteArray (ByteArrayAccess)
|
||||
import qualified Crypto.Internal.ByteArray as B
|
||||
|
||||
-- | DES Context
|
||||
data DES = DES Word64
|
||||
@ -26,12 +27,12 @@ instance Cipher DES where
|
||||
|
||||
instance BlockCipher DES where
|
||||
blockSize _ = 8
|
||||
ecbEncrypt (DES key) = byteArrayMapAsWord64 (unBlock . encrypt key . Block)
|
||||
ecbDecrypt (DES key) = byteArrayMapAsWord64 (unBlock . decrypt key . Block)
|
||||
ecbEncrypt (DES key) = B.mapAsWord64 (unBlock . encrypt key . Block)
|
||||
ecbDecrypt (DES key) = B.mapAsWord64 (unBlock . decrypt key . Block)
|
||||
|
||||
initDES :: ByteArray key => key -> CryptoFailable DES
|
||||
initDES :: ByteArrayAccess key => key -> CryptoFailable DES
|
||||
initDES k
|
||||
| len == 8 = CryptoPassed $ DES key
|
||||
| otherwise = CryptoFailed $ CryptoError_KeySizeInvalid
|
||||
where len = byteArrayLength k
|
||||
key = byteArrayToW64BE k 0
|
||||
where len = B.length k
|
||||
key = B.toW64BE k 0
|
||||
|
||||
@ -14,10 +14,10 @@ module Crypto.Cipher.DES.Serialization
|
||||
import qualified Data.ByteString as B
|
||||
import Crypto.Cipher.DES.Primitive (Block(..))
|
||||
|
||||
import Crypto.Internal.ByteArray
|
||||
import qualified Crypto.Internal.ByteArray as B
|
||||
import Crypto.Internal.Endian
|
||||
|
||||
import Foreign.Storable
|
||||
|
||||
toBS :: Block -> B.ByteString
|
||||
toBS (Block w) = byteArrayAllocAndFreeze 8 $ \ptr -> poke ptr (toBE64 w)
|
||||
toBS (Block w) = B.allocAndFreeze 8 $ \ptr -> poke ptr (toBE64 w)
|
||||
|
||||
@ -11,11 +11,12 @@ module Crypto.Cipher.TripleDES
|
||||
, DES_EDE2
|
||||
) where
|
||||
|
||||
import Data.Word
|
||||
import Crypto.Error
|
||||
import Crypto.Cipher.Types
|
||||
import Crypto.Cipher.DES.Primitive
|
||||
import Crypto.Internal.ByteArray
|
||||
import Data.Word
|
||||
import Crypto.Error
|
||||
import Crypto.Cipher.Types
|
||||
import Crypto.Cipher.DES.Primitive
|
||||
import Crypto.Internal.ByteArray (ByteArrayAccess)
|
||||
import qualified Crypto.Internal.ByteArray as B
|
||||
|
||||
-- | 3DES with 3 different keys used all in the same direction
|
||||
data DES_EEE3 = DES_EEE3 Word64 Word64 Word64
|
||||
@ -55,34 +56,34 @@ instance Cipher DES_EEE2 where
|
||||
|
||||
instance BlockCipher DES_EEE3 where
|
||||
blockSize _ = 8
|
||||
ecbEncrypt (DES_EEE3 k1 k2 k3) = byteArrayMapAsWord64 (unBlock . (encrypt k3 . encrypt k2 . encrypt k1) . Block)
|
||||
ecbDecrypt (DES_EEE3 k1 k2 k3) = byteArrayMapAsWord64 (unBlock . (decrypt k1 . decrypt k2 . decrypt k3) . Block)
|
||||
ecbEncrypt (DES_EEE3 k1 k2 k3) = B.mapAsWord64 (unBlock . (encrypt k3 . encrypt k2 . encrypt k1) . Block)
|
||||
ecbDecrypt (DES_EEE3 k1 k2 k3) = B.mapAsWord64 (unBlock . (decrypt k1 . decrypt k2 . decrypt k3) . Block)
|
||||
|
||||
instance BlockCipher DES_EDE3 where
|
||||
blockSize _ = 8
|
||||
ecbEncrypt (DES_EDE3 k1 k2 k3) = byteArrayMapAsWord64 (unBlock . (encrypt k3 . decrypt k2 . encrypt k1) . Block)
|
||||
ecbDecrypt (DES_EDE3 k1 k2 k3) = byteArrayMapAsWord64 (unBlock . (decrypt k1 . encrypt k2 . decrypt k3) . Block)
|
||||
ecbEncrypt (DES_EDE3 k1 k2 k3) = B.mapAsWord64 (unBlock . (encrypt k3 . decrypt k2 . encrypt k1) . Block)
|
||||
ecbDecrypt (DES_EDE3 k1 k2 k3) = B.mapAsWord64 (unBlock . (decrypt k1 . encrypt k2 . decrypt k3) . Block)
|
||||
|
||||
instance BlockCipher DES_EEE2 where
|
||||
blockSize _ = 8
|
||||
ecbEncrypt (DES_EEE2 k1 k2) = byteArrayMapAsWord64 (unBlock . (encrypt k1 . encrypt k2 . encrypt k1) . Block)
|
||||
ecbDecrypt (DES_EEE2 k1 k2) = byteArrayMapAsWord64 (unBlock . (decrypt k1 . decrypt k2 . decrypt k1) . Block)
|
||||
ecbEncrypt (DES_EEE2 k1 k2) = B.mapAsWord64 (unBlock . (encrypt k1 . encrypt k2 . encrypt k1) . Block)
|
||||
ecbDecrypt (DES_EEE2 k1 k2) = B.mapAsWord64 (unBlock . (decrypt k1 . decrypt k2 . decrypt k1) . Block)
|
||||
|
||||
instance BlockCipher DES_EDE2 where
|
||||
blockSize _ = 8
|
||||
ecbEncrypt (DES_EDE2 k1 k2) = byteArrayMapAsWord64 (unBlock . (encrypt k1 . decrypt k2 . encrypt k1) . Block)
|
||||
ecbDecrypt (DES_EDE2 k1 k2) = byteArrayMapAsWord64 (unBlock . (decrypt k1 . encrypt k2 . decrypt k1) . Block)
|
||||
ecbEncrypt (DES_EDE2 k1 k2) = B.mapAsWord64 (unBlock . (encrypt k1 . decrypt k2 . encrypt k1) . Block)
|
||||
ecbDecrypt (DES_EDE2 k1 k2) = B.mapAsWord64 (unBlock . (decrypt k1 . encrypt k2 . decrypt k1) . Block)
|
||||
|
||||
init3DES :: ByteArray key => (Word64 -> Word64 -> Word64 -> a) -> key -> CryptoFailable a
|
||||
init3DES :: ByteArrayAccess key => (Word64 -> Word64 -> Word64 -> a) -> key -> CryptoFailable a
|
||||
init3DES constr k
|
||||
| len == 24 = CryptoPassed $ constr k1 k2 k3
|
||||
| otherwise = CryptoFailed CryptoError_KeySizeInvalid
|
||||
where len = byteArrayLength k
|
||||
(k1, k2, k3) = (byteArrayToW64BE k 0, byteArrayToW64BE k 8, byteArrayToW64BE k 16)
|
||||
where len = B.length k
|
||||
(k1, k2, k3) = (B.toW64BE k 0, B.toW64BE k 8, B.toW64BE k 16)
|
||||
|
||||
init2DES :: ByteArray key => (Word64 -> Word64 -> a) -> key -> CryptoFailable a
|
||||
init2DES :: ByteArrayAccess key => (Word64 -> Word64 -> a) -> key -> CryptoFailable a
|
||||
init2DES constr k
|
||||
| len == 16 = CryptoPassed $ constr k1 k2
|
||||
| otherwise = CryptoFailed CryptoError_KeySizeInvalid
|
||||
where len = byteArrayLength k
|
||||
(k1, k2) = (byteArrayToW64BE k 0, byteArrayToW64BE k 8)
|
||||
where len = B.length k
|
||||
(k1, k2) = (B.toW64BE k 0, B.toW64BE k 8)
|
||||
|
||||
@ -11,9 +11,10 @@
|
||||
{-# LANGUAGE Rank2Types #-}
|
||||
module Crypto.Cipher.Types.AEAD where
|
||||
|
||||
import Crypto.Cipher.Types.Base
|
||||
import Crypto.Internal.ByteArray
|
||||
import Crypto.Internal.Imports
|
||||
import Crypto.Cipher.Types.Base
|
||||
import Crypto.Internal.ByteArray (ByteArrayAccess, ByteArray)
|
||||
import qualified Crypto.Internal.ByteArray as B
|
||||
import Crypto.Internal.Imports
|
||||
|
||||
data AEADModeImpl st = AEADModeImpl
|
||||
{ aeadImplAppendHeader :: forall ba . ByteArrayAccess ba => st -> ba -> st
|
||||
@ -64,5 +65,5 @@ aeadSimpleDecrypt aeadIni header input authTag
|
||||
| otherwise = Nothing
|
||||
where aead = aeadAppendHeader aeadIni header
|
||||
(output, aeadFinal) = aeadDecrypt aead input
|
||||
tag = aeadFinalize aeadFinal (byteArrayLength authTag)
|
||||
tag = aeadFinalize aeadFinal (B.length authTag)
|
||||
|
||||
|
||||
@ -17,11 +17,12 @@ module Crypto.Cipher.Types.Base
|
||||
, DataUnitOffset
|
||||
) where
|
||||
|
||||
import Data.Word
|
||||
import Data.ByteString (ByteString)
|
||||
import Data.Word
|
||||
import Data.ByteString (ByteString)
|
||||
|
||||
import Crypto.Internal.ByteArray
|
||||
import Crypto.Error
|
||||
import Crypto.Internal.ByteArray (ByteArrayAccess, ByteArray, SecureBytes, withByteArray)
|
||||
import qualified Crypto.Internal.ByteArray as B
|
||||
import Crypto.Error
|
||||
|
||||
-- | Different specifier for key size in bytes
|
||||
data KeySizeSpecifier =
|
||||
@ -38,7 +39,7 @@ newtype AuthTag = AuthTag { unAuthTag :: ByteString }
|
||||
deriving (Show, ByteArrayAccess)
|
||||
|
||||
instance Eq AuthTag where
|
||||
(AuthTag a) == (AuthTag b) = byteArrayConstEq a b
|
||||
(AuthTag a) == (AuthTag b) = B.constEq a b
|
||||
|
||||
-- | AEAD Mode
|
||||
data AEADMode =
|
||||
|
||||
@ -36,27 +36,28 @@ module Crypto.Cipher.Types.Block
|
||||
--, cfb8Decrypt
|
||||
) where
|
||||
|
||||
import Data.Byteable
|
||||
import Data.Word
|
||||
import Crypto.Error
|
||||
import Crypto.Cipher.Types.Base
|
||||
import Crypto.Cipher.Types.GF
|
||||
import Crypto.Cipher.Types.AEAD
|
||||
import Crypto.Cipher.Types.Utils
|
||||
import Data.Byteable
|
||||
import Data.Word
|
||||
import Crypto.Error
|
||||
import Crypto.Cipher.Types.Base
|
||||
import Crypto.Cipher.Types.GF
|
||||
import Crypto.Cipher.Types.AEAD
|
||||
import Crypto.Cipher.Types.Utils
|
||||
|
||||
import Crypto.Internal.ByteArray
|
||||
import Crypto.Internal.ByteArray (ByteArrayAccess, ByteArray, withByteArray, Bytes)
|
||||
import qualified Crypto.Internal.ByteArray as B
|
||||
|
||||
import Foreign.Ptr
|
||||
import Foreign.Storable
|
||||
import Foreign.Ptr
|
||||
import Foreign.Storable
|
||||
|
||||
-- | an IV parametrized by the cipher
|
||||
data IV c = forall byteArray . ByteArray byteArray => IV byteArray
|
||||
|
||||
instance BlockCipher c => ByteArrayAccess (IV c) where
|
||||
withByteArray (IV z) f = withByteArray z f
|
||||
byteArrayLength (IV z) = byteArrayLength z
|
||||
length (IV z) = B.length z
|
||||
instance Eq (IV c) where
|
||||
(IV a) == (IV b) = byteArrayEq a b
|
||||
(IV a) == (IV b) = B.eq a b
|
||||
|
||||
type XTS ba cipher = (cipher, cipher)
|
||||
-> IV cipher -- ^ Usually represent the Data Unit (e.g. disk sector)
|
||||
@ -157,7 +158,7 @@ makeIV b = toIV undefined
|
||||
nullIV :: BlockCipher c => IV c
|
||||
nullIV = toIV undefined
|
||||
where toIV :: BlockCipher c => c -> IV c
|
||||
toIV cipher = IV (byteArrayZero (blockSize cipher) :: Bytes)
|
||||
toIV cipher = IV (B.zero (blockSize cipher) :: Bytes)
|
||||
|
||||
-- | Increment an IV by a number.
|
||||
--
|
||||
@ -165,9 +166,9 @@ nullIV = toIV undefined
|
||||
ivAdd :: BlockCipher c => IV c -> Int -> IV c
|
||||
ivAdd (IV b) i = IV $ copy b
|
||||
where copy :: ByteArray bs => bs -> bs
|
||||
copy bs = byteArrayCopyAndFreeze bs $ \p -> do
|
||||
copy bs = B.copyAndFreeze bs $ \p -> do
|
||||
let until0 accu = do
|
||||
r <- loop accu (byteArrayLength bs - 1) p
|
||||
r <- loop accu (B.length bs - 1) p
|
||||
case r of
|
||||
0 -> return ()
|
||||
_ -> until0 r
|
||||
@ -185,42 +186,42 @@ ivAdd (IV b) i = IV $ copy b
|
||||
else loop hi (ofs - 1) p
|
||||
|
||||
cbcEncryptGeneric :: (ByteArray ba, BlockCipher cipher) => cipher -> IV cipher -> ba -> ba
|
||||
cbcEncryptGeneric cipher ivini input = byteArrayConcat $ doEnc ivini $ chunk (blockSize cipher) input
|
||||
cbcEncryptGeneric cipher ivini input = B.concat $ doEnc ivini $ chunk (blockSize cipher) input
|
||||
where doEnc _ [] = []
|
||||
doEnc iv (i:is) =
|
||||
let o = ecbEncrypt cipher $ byteArrayXor iv i
|
||||
let o = ecbEncrypt cipher $ B.xor iv i
|
||||
in o : doEnc (IV o) is
|
||||
|
||||
cbcDecryptGeneric :: (ByteArray ba, BlockCipher cipher) => cipher -> IV cipher -> ba -> ba
|
||||
cbcDecryptGeneric cipher ivini input = byteArrayConcat $ doDec ivini $ chunk (blockSize cipher) input
|
||||
cbcDecryptGeneric cipher ivini input = B.concat $ doDec ivini $ chunk (blockSize cipher) input
|
||||
where
|
||||
doDec _ [] = []
|
||||
doDec iv (i:is) =
|
||||
let o = byteArrayXor iv $ ecbDecrypt cipher i
|
||||
let o = B.xor iv $ ecbDecrypt cipher i
|
||||
in o : doDec (IV i) is
|
||||
|
||||
cfbEncryptGeneric :: (ByteArray ba, BlockCipher cipher) => cipher -> IV cipher -> ba -> ba
|
||||
cfbEncryptGeneric cipher ivini input = byteArrayConcat $ doEnc ivini $ chunk (blockSize cipher) input
|
||||
cfbEncryptGeneric cipher ivini input = B.concat $ doEnc ivini $ chunk (blockSize cipher) input
|
||||
where
|
||||
doEnc _ [] = []
|
||||
doEnc (IV iv) (i:is) =
|
||||
let o = byteArrayXor i $ ecbEncrypt cipher iv
|
||||
let o = B.xor i $ ecbEncrypt cipher iv
|
||||
in o : doEnc (IV o) is
|
||||
|
||||
cfbDecryptGeneric :: (ByteArray ba, BlockCipher cipher) => cipher -> IV cipher -> ba -> ba
|
||||
cfbDecryptGeneric cipher ivini input = byteArrayConcat $ doDec ivini $ chunk (blockSize cipher) input
|
||||
cfbDecryptGeneric cipher ivini input = B.concat $ doDec ivini $ chunk (blockSize cipher) input
|
||||
where
|
||||
doDec _ [] = []
|
||||
doDec (IV iv) (i:is) =
|
||||
let o = byteArrayXor i $ ecbEncrypt cipher iv
|
||||
let o = B.xor i $ ecbEncrypt cipher iv
|
||||
in o : doDec (IV i) is
|
||||
|
||||
ctrCombineGeneric :: (ByteArray ba, BlockCipher cipher) => cipher -> IV cipher -> ba -> ba
|
||||
ctrCombineGeneric cipher ivini input = byteArrayConcat $ doCnt ivini $ chunk (blockSize cipher) input
|
||||
ctrCombineGeneric cipher ivini input = B.concat $ doCnt ivini $ chunk (blockSize cipher) input
|
||||
where doCnt _ [] = []
|
||||
doCnt iv@(IV ivd) (i:is) =
|
||||
let ivEnc = ecbEncrypt cipher ivd
|
||||
in byteArrayXor i ivEnc : doCnt (ivAdd iv 1) is
|
||||
in B.xor i ivEnc : doCnt (ivAdd iv 1) is
|
||||
|
||||
xtsEncryptGeneric :: (ByteArray ba, BlockCipher128 cipher) => XTS ba cipher
|
||||
xtsEncryptGeneric = xtsGeneric ecbEncrypt
|
||||
@ -236,19 +237,19 @@ xtsGeneric :: (ByteArray ba, BlockCipher128 cipher)
|
||||
-> ba
|
||||
-> ba
|
||||
xtsGeneric f (cipher, tweakCipher) (IV iv) sPoint input =
|
||||
byteArrayConcat $ doXts iniTweak $ chunk (blockSize cipher) input
|
||||
B.concat $ doXts iniTweak $ chunk (blockSize cipher) input
|
||||
where encTweak = ecbEncrypt tweakCipher iv
|
||||
iniTweak = iterate xtsGFMul encTweak !! fromIntegral sPoint
|
||||
doXts _ [] = []
|
||||
doXts tweak (i:is) =
|
||||
let o = byteArrayXor (f cipher $ byteArrayXor i tweak) tweak
|
||||
let o = B.xor (f cipher $ B.xor i tweak) tweak
|
||||
in o : doXts (xtsGFMul tweak) is
|
||||
|
||||
{-
|
||||
-- | Encrypt using CFB mode in 8 bit output
|
||||
--
|
||||
-- Effectively turn a Block cipher in CFB mode into a Stream cipher
|
||||
cfb8Encrypt :: BlockCipher a => a -> IV a -> B.ByteString -> B.ByteString
|
||||
cfb8Encrypt :: BlockCipher a => a -> IV a -> B.byteString -> B.byteString
|
||||
cfb8Encrypt ctx origIv msg = B.unsafeCreate (B.length msg) $ \dst -> loop dst origIv msg
|
||||
where loop d iv@(IV i) m
|
||||
| B.null m = return ()
|
||||
@ -263,7 +264,7 @@ cfb8Encrypt ctx origIv msg = B.unsafeCreate (B.length msg) $ \dst -> loop dst or
|
||||
-- | Decrypt using CFB mode in 8 bit output
|
||||
--
|
||||
-- Effectively turn a Block cipher in CFB mode into a Stream cipher
|
||||
cfb8Decrypt :: BlockCipher a => a -> IV a -> B.ByteString -> B.ByteString
|
||||
cfb8Decrypt :: BlockCipher a => a -> IV a -> B.byteString -> B.byteString
|
||||
cfb8Decrypt ctx origIv msg = B.unsafeCreate (B.length msg) $ \dst -> loop dst origIv msg
|
||||
where loop d iv@(IV i) m
|
||||
| B.null m = return ()
|
||||
|
||||
@ -13,12 +13,13 @@ module Crypto.Cipher.Types.GF
|
||||
xtsGFMul
|
||||
) where
|
||||
|
||||
import Control.Applicative
|
||||
import Crypto.Internal.ByteArray
|
||||
import Foreign.Storable
|
||||
import Foreign.Ptr
|
||||
import Data.Word
|
||||
import Data.Bits
|
||||
import Control.Applicative
|
||||
import Crypto.Internal.ByteArray (ByteArray, withByteArray)
|
||||
import qualified Crypto.Internal.ByteArray as B
|
||||
import Foreign.Storable
|
||||
import Foreign.Ptr
|
||||
import Data.Word
|
||||
import Data.Bits
|
||||
|
||||
-- block size need to be 128 bits.
|
||||
--
|
||||
@ -26,8 +27,8 @@ import Data.Bits
|
||||
xtsGFMul :: ByteArray ba => ba -> ba
|
||||
xtsGFMul b
|
||||
| len == 16 =
|
||||
byteArrayAllocAndFreeze len $ \dst ->
|
||||
withByteArray b $ \src -> do
|
||||
B.allocAndFreeze len $ \dst ->
|
||||
withByteArray b $ \src -> do
|
||||
(hi,lo) <- gf <$> peek (castPtr src) <*> peek (castPtr src `plusPtr` 8)
|
||||
poke (castPtr dst) lo
|
||||
poke (castPtr dst `plusPtr` 8) hi
|
||||
@ -39,7 +40,7 @@ xtsGFMul b
|
||||
)
|
||||
where carryHi = srcHi `testBit` 63
|
||||
carryLo = srcLo `testBit` 63
|
||||
len = byteArrayLength b
|
||||
len = B.length b
|
||||
{-
|
||||
const uint64_t gf_mask = cpu_to_le64(0x8000000000000000ULL);
|
||||
uint64_t r = ((a->q[1] & gf_mask) ? cpu_to_le64(0x87) : 0);
|
||||
|
||||
@ -9,11 +9,12 @@
|
||||
--
|
||||
module Crypto.Cipher.Types.Utils where
|
||||
|
||||
import Crypto.Internal.ByteArray
|
||||
import Crypto.Internal.ByteArray (ByteArray)
|
||||
import qualified Crypto.Internal.ByteArray as B
|
||||
|
||||
chunk :: ByteArray b => Int -> b -> [b]
|
||||
chunk sz bs = split bs
|
||||
where split b | byteArrayLength b <= sz = [b]
|
||||
where split b | B.length b <= sz = [b]
|
||||
| otherwise =
|
||||
let (b1, b2) = byteArraySplit sz b
|
||||
let (b1, b2) = B.split sz b
|
||||
in b1 : split b2
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
{-# LANGUAGE BangPatterns #-}
|
||||
{-# LANGUAGE MagicHash #-}
|
||||
{-# LANGUAGE UnboxedTuples #-}
|
||||
{-# LANGUAGE NoImplicitPrelude #-}
|
||||
module Crypto.Internal.ByteArray
|
||||
(
|
||||
ByteArray(..)
|
||||
@ -18,26 +19,26 @@ module Crypto.Internal.ByteArray
|
||||
, Bytes
|
||||
, SecureBytes
|
||||
-- * methods
|
||||
, byteArrayAlloc
|
||||
, byteArrayAllocAndFreeze
|
||||
, alloc
|
||||
, allocAndFreeze
|
||||
, empty
|
||||
, byteArrayZero
|
||||
, byteArrayCopy
|
||||
, byteArrayConvert
|
||||
, byteArrayCopyRet
|
||||
, byteArrayCopyAndFreeze
|
||||
, byteArraySplit
|
||||
, byteArrayXor
|
||||
, byteArrayEq
|
||||
, byteArrayIndex
|
||||
, byteArrayConstEq
|
||||
, byteArrayConcat
|
||||
, byteArrayToBS
|
||||
, byteArrayFromBS
|
||||
, byteArrayToW64BE
|
||||
, byteArrayToW64LE
|
||||
, byteArrayMapAsWord64
|
||||
, byteArrayMapAsWord128
|
||||
, zero
|
||||
, copy
|
||||
, convert
|
||||
, copyRet
|
||||
, copyAndFreeze
|
||||
, split
|
||||
, xor
|
||||
, eq
|
||||
, index
|
||||
, constEq
|
||||
, concat
|
||||
, toBS
|
||||
, fromBS
|
||||
, toW64BE
|
||||
, toW64LE
|
||||
, mapAsWord64
|
||||
, mapAsWord128
|
||||
) where
|
||||
|
||||
import Data.SecureMem
|
||||
@ -54,118 +55,120 @@ import Data.ByteString (ByteString)
|
||||
import qualified Data.ByteString as B (length)
|
||||
import qualified Data.ByteString.Internal as B
|
||||
|
||||
import Prelude (flip, return, div, (-), ($), (==), (/=), (<=), (>=), Int, Bool(..), IO, otherwise, sum, map, fmap, snd, (.), min)
|
||||
|
||||
class ByteArrayAccess ba where
|
||||
byteArrayLength :: ba -> Int
|
||||
withByteArray :: ba -> (Ptr p -> IO a) -> IO a
|
||||
length :: ba -> Int
|
||||
withByteArray :: ba -> (Ptr p -> IO a) -> IO a
|
||||
|
||||
class ByteArrayAccess ba => ByteArray ba where
|
||||
byteArrayAllocRet :: Int -> (Ptr p -> IO a) -> IO (a, ba)
|
||||
allocRet :: Int -> (Ptr p -> IO a) -> IO (a, ba)
|
||||
|
||||
byteArrayAlloc :: ByteArray ba => Int -> (Ptr p -> IO ()) -> IO ba
|
||||
byteArrayAlloc n f = snd `fmap` byteArrayAllocRet n f
|
||||
alloc :: ByteArray ba => Int -> (Ptr p -> IO ()) -> IO ba
|
||||
alloc n f = snd `fmap` allocRet n f
|
||||
|
||||
instance ByteArrayAccess Bytes where
|
||||
byteArrayLength = bytesLength
|
||||
withByteArray = withBytes
|
||||
length = bytesLength
|
||||
withByteArray = withBytes
|
||||
instance ByteArray Bytes where
|
||||
byteArrayAllocRet = bytesAllocRet
|
||||
allocRet = bytesAllocRet
|
||||
|
||||
instance ByteArrayAccess ByteString where
|
||||
byteArrayLength = B.length
|
||||
length = B.length
|
||||
withByteArray b f = withForeignPtr fptr $ \ptr -> f (ptr `plusPtr` off)
|
||||
where (fptr, off, _) = B.toForeignPtr b
|
||||
instance ByteArray ByteString where
|
||||
byteArrayAllocRet sz f = do
|
||||
allocRet sz f = do
|
||||
fptr <- B.mallocByteString sz
|
||||
r <- withForeignPtr fptr (f . castPtr)
|
||||
return (r, B.PS fptr 0 sz)
|
||||
|
||||
instance ByteArrayAccess SecureMem where
|
||||
byteArrayLength = secureMemGetSize
|
||||
length = secureMemGetSize
|
||||
withByteArray b f = withSecureMemPtr b (f . castPtr)
|
||||
instance ByteArray SecureMem where
|
||||
byteArrayAllocRet sz f = do
|
||||
allocRet sz f = do
|
||||
out <- allocateSecureMem sz
|
||||
r <- withSecureMemPtr out (f . castPtr)
|
||||
return (r, out)
|
||||
|
||||
byteArrayAllocAndFreeze :: ByteArray a => Int -> (Ptr p -> IO ()) -> a
|
||||
byteArrayAllocAndFreeze sz f = unsafeDoIO (byteArrayAlloc sz f)
|
||||
allocAndFreeze :: ByteArray a => Int -> (Ptr p -> IO ()) -> a
|
||||
allocAndFreeze sz f = unsafeDoIO (alloc sz f)
|
||||
|
||||
empty :: ByteArray a => a
|
||||
empty = unsafeDoIO (byteArrayAlloc 0 $ \_ -> return ())
|
||||
empty = unsafeDoIO (alloc 0 $ \_ -> return ())
|
||||
|
||||
-- | Create a xor of bytes between a and b.
|
||||
--
|
||||
-- the returns byte array is the size of the smallest input.
|
||||
byteArrayXor :: (ByteArrayAccess a, ByteArrayAccess b, ByteArray c) => a -> b -> c
|
||||
byteArrayXor a b =
|
||||
byteArrayAllocAndFreeze n $ \pc ->
|
||||
withByteArray a $ \pa ->
|
||||
withByteArray b $ \pb ->
|
||||
xor :: (ByteArrayAccess a, ByteArrayAccess b, ByteArray c) => a -> b -> c
|
||||
xor a b =
|
||||
allocAndFreeze n $ \pc ->
|
||||
withByteArray a $ \pa ->
|
||||
withByteArray b $ \pb ->
|
||||
bufXor pc pa pb n
|
||||
where
|
||||
n = min la lb
|
||||
la = byteArrayLength a
|
||||
lb = byteArrayLength b
|
||||
la = length a
|
||||
lb = length b
|
||||
|
||||
byteArrayIndex :: ByteArrayAccess a => a -> Int -> Word8
|
||||
byteArrayIndex b i = unsafeDoIO $ withByteArray b $ \p -> peek (p `plusPtr` i)
|
||||
index :: ByteArrayAccess a => a -> Int -> Word8
|
||||
index b i = unsafeDoIO $ withByteArray b $ \p -> peek (p `plusPtr` i)
|
||||
|
||||
byteArraySplit :: ByteArray bs => Int -> bs -> (bs, bs)
|
||||
byteArraySplit n bs
|
||||
split :: ByteArray bs => Int -> bs -> (bs, bs)
|
||||
split n bs
|
||||
| n <= 0 = (empty, bs)
|
||||
| n >= len = (bs, empty)
|
||||
| otherwise = unsafeDoIO $ do
|
||||
withByteArray bs $ \p -> do
|
||||
b1 <- byteArrayAlloc n $ \r -> bufCopy r p n
|
||||
b2 <- byteArrayAlloc (len - n) $ \r -> bufCopy r (p `plusPtr` n) (len - n)
|
||||
b1 <- alloc n $ \r -> bufCopy r p n
|
||||
b2 <- alloc (len - n) $ \r -> bufCopy r (p `plusPtr` n) (len - n)
|
||||
return (b1, b2)
|
||||
where len = byteArrayLength bs
|
||||
where len = length bs
|
||||
|
||||
byteArrayConcat :: ByteArray bs => [bs] -> bs
|
||||
byteArrayConcat [] = empty
|
||||
byteArrayConcat allBs = byteArrayAllocAndFreeze total (loop allBs)
|
||||
concat :: ByteArray bs => [bs] -> bs
|
||||
concat [] = empty
|
||||
concat allBs = allocAndFreeze total (loop allBs)
|
||||
where
|
||||
total = sum $ map byteArrayLength allBs
|
||||
total = sum $ map length allBs
|
||||
|
||||
loop [] _ = return ()
|
||||
loop (b:bs) dst = do
|
||||
let sz = byteArrayLength b
|
||||
let sz = length b
|
||||
withByteArray b $ \p -> bufCopy dst p sz
|
||||
loop bs (dst `plusPtr` sz)
|
||||
|
||||
byteArrayCopy :: (ByteArrayAccess bs1, ByteArray bs2) => bs1 -> (Ptr p -> IO ()) -> IO bs2
|
||||
byteArrayCopy bs f =
|
||||
byteArrayAlloc (byteArrayLength bs) $ \d -> do
|
||||
withByteArray bs $ \s -> bufCopy d s (byteArrayLength bs)
|
||||
copy :: (ByteArrayAccess bs1, ByteArray bs2) => bs1 -> (Ptr p -> IO ()) -> IO bs2
|
||||
copy bs f =
|
||||
alloc (length bs) $ \d -> do
|
||||
withByteArray bs $ \s -> bufCopy d s (length bs)
|
||||
f (castPtr d)
|
||||
|
||||
byteArrayCopyRet :: (ByteArrayAccess bs1, ByteArray bs2) => bs1 -> (Ptr p -> IO a) -> IO (a, bs2)
|
||||
byteArrayCopyRet bs f =
|
||||
byteArrayAllocRet (byteArrayLength bs) $ \d -> do
|
||||
withByteArray bs $ \s -> bufCopy d s (byteArrayLength bs)
|
||||
copyRet :: (ByteArrayAccess bs1, ByteArray bs2) => bs1 -> (Ptr p -> IO a) -> IO (a, bs2)
|
||||
copyRet bs f =
|
||||
allocRet (length bs) $ \d -> do
|
||||
withByteArray bs $ \s -> bufCopy d s (length bs)
|
||||
f (castPtr d)
|
||||
|
||||
byteArrayCopyAndFreeze :: (ByteArrayAccess bs1, ByteArray bs2) => bs1 -> (Ptr p -> IO ()) -> bs2
|
||||
byteArrayCopyAndFreeze bs f =
|
||||
byteArrayAllocAndFreeze (byteArrayLength bs) $ \d -> do
|
||||
withByteArray bs $ \s -> bufCopy d s (byteArrayLength bs)
|
||||
copyAndFreeze :: (ByteArrayAccess bs1, ByteArray bs2) => bs1 -> (Ptr p -> IO ()) -> bs2
|
||||
copyAndFreeze bs f =
|
||||
allocAndFreeze (length bs) $ \d -> do
|
||||
withByteArray bs $ \s -> bufCopy d s (length bs)
|
||||
f (castPtr d)
|
||||
|
||||
byteArrayZero :: ByteArray ba => Int -> ba
|
||||
byteArrayZero n = byteArrayAllocAndFreeze n $ \ptr -> bufSet ptr 0 n
|
||||
zero :: ByteArray ba => Int -> ba
|
||||
zero n = allocAndFreeze n $ \ptr -> bufSet ptr 0 n
|
||||
|
||||
byteArrayEq :: (ByteArrayAccess bs1, ByteArrayAccess bs2) => bs1 -> bs2 -> Bool
|
||||
byteArrayEq b1 b2
|
||||
eq :: (ByteArrayAccess bs1, ByteArrayAccess bs2) => bs1 -> bs2 -> Bool
|
||||
eq b1 b2
|
||||
| l1 /= l2 = False
|
||||
| otherwise = unsafeDoIO $
|
||||
withByteArray b1 $ \p1 ->
|
||||
withByteArray b2 $ \p2 ->
|
||||
loop l1 p1 p2
|
||||
where
|
||||
l1 = byteArrayLength b1
|
||||
l2 = byteArrayLength b2
|
||||
l1 = length b1
|
||||
l2 = length b2
|
||||
loop :: Int -> Ptr Word8 -> Ptr Word8 -> IO Bool
|
||||
loop 0 _ _ = return True
|
||||
loop i p1 p2 = do
|
||||
@ -180,16 +183,16 @@ byteArrayEq b1 b2
|
||||
-- compared to == , this function will go over all the bytes
|
||||
-- present before yielding a result even when knowing the
|
||||
-- overall result early in the processing.
|
||||
byteArrayConstEq :: (ByteArrayAccess bs1, ByteArrayAccess bs2) => bs1 -> bs2 -> Bool
|
||||
byteArrayConstEq b1 b2
|
||||
constEq :: (ByteArrayAccess bs1, ByteArrayAccess bs2) => bs1 -> bs2 -> Bool
|
||||
constEq b1 b2
|
||||
| l1 /= l2 = False
|
||||
| otherwise = unsafeDoIO $
|
||||
withByteArray b1 $ \p1 ->
|
||||
withByteArray b2 $ \p2 ->
|
||||
loop l1 True p1 p2
|
||||
where
|
||||
l1 = byteArrayLength b1
|
||||
l2 = byteArrayLength b2
|
||||
l1 = length b1
|
||||
l2 = length b2
|
||||
loop :: Int -> Bool -> Ptr Word8 -> Ptr Word8 -> IO Bool
|
||||
loop 0 !ret _ _ = return ret
|
||||
loop i !ret p1 p2 = do
|
||||
@ -203,25 +206,25 @@ byteArrayConstEq b1 b2
|
||||
False &&! True = False
|
||||
False &&! False = False
|
||||
|
||||
byteArrayToBS :: ByteArray bs => bs -> ByteString
|
||||
byteArrayToBS bs = byteArrayCopyAndFreeze bs (\_ -> return ())
|
||||
toBS :: ByteArray bs => bs -> ByteString
|
||||
toBS bs = copyAndFreeze bs (\_ -> return ())
|
||||
|
||||
byteArrayFromBS :: ByteArray bs => ByteString -> bs
|
||||
byteArrayFromBS bs = byteArrayCopyAndFreeze bs (\_ -> return ())
|
||||
fromBS :: ByteArray bs => ByteString -> bs
|
||||
fromBS bs = copyAndFreeze bs (\_ -> return ())
|
||||
|
||||
byteArrayToW64BE :: ByteArrayAccess bs => bs -> Int -> Word64
|
||||
byteArrayToW64BE bs ofs = unsafeDoIO $ withByteArray bs $ \p -> fromBE64 <$> peek (p `plusPtr` ofs)
|
||||
toW64BE :: ByteArrayAccess bs => bs -> Int -> Word64
|
||||
toW64BE bs ofs = unsafeDoIO $ withByteArray bs $ \p -> fromBE64 <$> peek (p `plusPtr` ofs)
|
||||
|
||||
byteArrayToW64LE :: ByteArrayAccess bs => bs -> Int -> Word64
|
||||
byteArrayToW64LE bs ofs = unsafeDoIO $ withByteArray bs $ \p -> fromLE64 <$> peek (p `plusPtr` ofs)
|
||||
toW64LE :: ByteArrayAccess bs => bs -> Int -> Word64
|
||||
toW64LE bs ofs = unsafeDoIO $ withByteArray bs $ \p -> fromLE64 <$> peek (p `plusPtr` ofs)
|
||||
|
||||
byteArrayMapAsWord128 :: ByteArray bs => (Word128 -> Word128) -> bs -> bs
|
||||
byteArrayMapAsWord128 f bs =
|
||||
byteArrayAllocAndFreeze len $ \dst ->
|
||||
withByteArray bs $ \src ->
|
||||
mapAsWord128 :: ByteArray bs => (Word128 -> Word128) -> bs -> bs
|
||||
mapAsWord128 f bs =
|
||||
allocAndFreeze len $ \dst ->
|
||||
withByteArray bs $ \src ->
|
||||
loop (len `div` 16) dst src
|
||||
where
|
||||
len = byteArrayLength bs
|
||||
len = length bs
|
||||
loop 0 _ _ = return ()
|
||||
loop i d s = do
|
||||
w1 <- peek s
|
||||
@ -231,13 +234,13 @@ byteArrayMapAsWord128 f bs =
|
||||
poke (d `plusPtr` 8) (toBE64 r2)
|
||||
loop (i-1) (d `plusPtr` 16) (s `plusPtr` 16)
|
||||
|
||||
byteArrayMapAsWord64 :: ByteArray bs => (Word64 -> Word64) -> bs -> bs
|
||||
byteArrayMapAsWord64 f bs =
|
||||
byteArrayAllocAndFreeze len $ \dst ->
|
||||
mapAsWord64 :: ByteArray bs => (Word64 -> Word64) -> bs -> bs
|
||||
mapAsWord64 f bs =
|
||||
allocAndFreeze len $ \dst ->
|
||||
withByteArray bs $ \src ->
|
||||
loop (len `div` 8) dst src
|
||||
where
|
||||
len = byteArrayLength bs
|
||||
len = length bs
|
||||
loop 0 _ _ = return ()
|
||||
loop i d s = do
|
||||
w <- peek s
|
||||
@ -245,5 +248,5 @@ byteArrayMapAsWord64 f bs =
|
||||
poke d (toBE64 r)
|
||||
loop (i-1) (d `plusPtr` 8) (s `plusPtr` 8)
|
||||
|
||||
byteArrayConvert :: (ByteArrayAccess bin, ByteArray bout) => bin -> bout
|
||||
byteArrayConvert = flip byteArrayCopyAndFreeze (\_ -> return ())
|
||||
convert :: (ByteArrayAccess bin, ByteArray bout) => bin -> bout
|
||||
convert = flip copyAndFreeze (\_ -> return ())
|
||||
|
||||
@ -27,7 +27,8 @@ import Foreign.Ptr
|
||||
|
||||
import Crypto.Internal.Compat
|
||||
import Crypto.Internal.Imports
|
||||
import Crypto.Internal.ByteArray
|
||||
import Crypto.Internal.ByteArray (ByteArrayAccess, SecureBytes, withByteArray)
|
||||
import qualified Crypto.Internal.ByteArray as B
|
||||
import Data.ByteString (ByteString)
|
||||
|
||||
-- | A Curve25519 Secret key
|
||||
@ -46,17 +47,17 @@ newtype DhSecret = DhSecret SecureBytes
|
||||
-- | Try to build a public key from a bytearray
|
||||
publicKey :: ByteArrayAccess bs => bs -> Either String PublicKey
|
||||
publicKey bs
|
||||
| byteArrayLength bs == 32 = Right $ PublicKey $ byteArrayCopyAndFreeze bs (\_ -> return ())
|
||||
| B.length bs == 32 = Right $ PublicKey $ B.copyAndFreeze bs (\_ -> return ())
|
||||
| otherwise = Left "invalid public key size"
|
||||
|
||||
-- | Try to build a secret key from a bytearray
|
||||
secretKey :: ByteArrayAccess bs => bs -> Either String SecretKey
|
||||
secretKey bs
|
||||
| byteArrayLength bs == 32 = unsafeDoIO $ do
|
||||
| B.length bs == 32 = unsafeDoIO $ do
|
||||
withByteArray bs $ \inp -> do
|
||||
valid <- isValidPtr inp
|
||||
if valid
|
||||
then Right . SecretKey <$> byteArrayCopy bs (\_ -> return ())
|
||||
then Right . SecretKey <$> B.copy bs (\_ -> return ())
|
||||
else return $ Left "invalid secret key"
|
||||
| otherwise = Left "secret key invalid size"
|
||||
where
|
||||
@ -81,8 +82,8 @@ secretKey bs
|
||||
-- | Create a DhSecret from a bytearray object
|
||||
dhSecret :: ByteArrayAccess b => b -> Either String DhSecret
|
||||
dhSecret bs
|
||||
| byteArrayLength bs == 32 = Right $ DhSecret $ byteArrayCopyAndFreeze bs (\_ -> return ())
|
||||
| otherwise = Left "invalid dh secret size"
|
||||
| B.length bs == 32 = Right $ DhSecret $ B.copyAndFreeze bs (\_ -> return ())
|
||||
| otherwise = Left "invalid dh secret size"
|
||||
|
||||
basePoint :: PublicKey
|
||||
basePoint = PublicKey "\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
@ -90,7 +91,7 @@ basePoint = PublicKey "\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
-- | Compute the Diffie Hellman secret from a public key and a secret key
|
||||
dh :: PublicKey -> SecretKey -> DhSecret
|
||||
dh (PublicKey pub) (SecretKey sec) = DhSecret <$>
|
||||
byteArrayAllocAndFreeze 32 $ \result ->
|
||||
B.allocAndFreeze 32 $ \result ->
|
||||
withByteArray sec $ \psec ->
|
||||
withByteArray pub $ \ppub ->
|
||||
ccryptonite_curve25519 result psec ppub
|
||||
@ -99,7 +100,7 @@ dh (PublicKey pub) (SecretKey sec) = DhSecret <$>
|
||||
-- | Create a public key from a secret key
|
||||
toPublic :: SecretKey -> PublicKey
|
||||
toPublic (SecretKey sec) = PublicKey <$>
|
||||
byteArrayAllocAndFreeze 32 $ \result ->
|
||||
B.allocAndFreeze 32 $ \result ->
|
||||
withByteArray sec $ \psec ->
|
||||
withByteArray basePoint $ \pbase ->
|
||||
ccryptonite_curve25519 result psec pbase
|
||||
|
||||
@ -31,7 +31,8 @@ import Foreign.C.Types
|
||||
import Crypto.Internal.Compat
|
||||
import Crypto.Internal.Imports
|
||||
import Crypto.Internal.Memory
|
||||
import Crypto.Internal.ByteArray
|
||||
import Crypto.Internal.ByteArray (ByteArrayAccess, withByteArray)
|
||||
import qualified Crypto.Internal.ByteArray as B
|
||||
import Crypto.Error
|
||||
|
||||
-- | An Ed25519 Secret key
|
||||
@ -49,19 +50,19 @@ newtype Signature = Signature Bytes
|
||||
-- | Try to build a public key from a bytearray
|
||||
publicKey :: ByteArrayAccess ba => ba -> CryptoFailable PublicKey
|
||||
publicKey bs
|
||||
| byteArrayLength bs == publicKeySize =
|
||||
CryptoPassed $ PublicKey $ byteArrayCopyAndFreeze bs (\_ -> return ())
|
||||
| B.length bs == publicKeySize =
|
||||
CryptoPassed $ PublicKey $ B.copyAndFreeze bs (\_ -> return ())
|
||||
| otherwise =
|
||||
CryptoFailed $ CryptoError_PublicKeySizeInvalid
|
||||
|
||||
-- | Try to build a secret key from a bytearray
|
||||
secretKey :: ByteArrayAccess ba => ba -> CryptoFailable SecretKey
|
||||
secretKey bs
|
||||
| byteArrayLength bs == secretKeySize = unsafeDoIO $ do
|
||||
| B.length bs == secretKeySize = unsafeDoIO $ do
|
||||
withByteArray bs $ \inp -> do
|
||||
valid <- isValidPtr inp
|
||||
if valid
|
||||
then CryptoPassed . SecretKey <$> byteArrayCopy bs (\_ -> return ())
|
||||
then CryptoPassed . SecretKey <$> B.copy bs (\_ -> return ())
|
||||
else return $ CryptoFailed CryptoError_SecretKeyStructureInvalid
|
||||
| otherwise = CryptoFailed CryptoError_SecretKeyStructureInvalid
|
||||
where
|
||||
@ -73,15 +74,15 @@ secretKey bs
|
||||
-- | Try to build a signature from a bytearray
|
||||
signature :: ByteArrayAccess ba => ba -> CryptoFailable Signature
|
||||
signature bs
|
||||
| byteArrayLength bs == signatureSize =
|
||||
CryptoPassed $ Signature $ byteArrayCopyAndFreeze bs (\_ -> return ())
|
||||
| B.length bs == signatureSize =
|
||||
CryptoPassed $ Signature $ B.copyAndFreeze bs (\_ -> return ())
|
||||
| otherwise =
|
||||
CryptoFailed CryptoError_SecretKeyStructureInvalid
|
||||
|
||||
-- | Create a public key from a secret key
|
||||
toPublic :: SecretKey -> PublicKey
|
||||
toPublic (SecretKey sec) = PublicKey <$>
|
||||
byteArrayAllocAndFreeze publicKeySize $ \result ->
|
||||
B.allocAndFreeze publicKeySize $ \result ->
|
||||
withByteArray sec $ \psec ->
|
||||
ccryptonite_ed25519_publickey psec result
|
||||
{-# NOINLINE toPublic #-}
|
||||
@ -89,13 +90,13 @@ toPublic (SecretKey sec) = PublicKey <$>
|
||||
-- | Sign a message using the key pair
|
||||
sign :: ByteArrayAccess ba => SecretKey -> PublicKey -> ba -> Signature
|
||||
sign secret public message =
|
||||
Signature $ byteArrayAllocAndFreeze signatureSize $ \sig ->
|
||||
Signature $ B.allocAndFreeze signatureSize $ \sig ->
|
||||
withByteArray secret $ \sec ->
|
||||
withByteArray public $ \pub ->
|
||||
withByteArray message $ \msg ->
|
||||
ccryptonite_ed25519_sign msg (fromIntegral msgLen) sec pub sig
|
||||
where
|
||||
!msgLen = byteArrayLength message
|
||||
!msgLen = B.length message
|
||||
|
||||
-- | Verify a message
|
||||
verify :: ByteArrayAccess ba => PublicKey -> ba -> Signature -> Bool
|
||||
@ -106,7 +107,7 @@ verify public message signatureVal = unsafeDoIO $
|
||||
r <- ccryptonite_ed25519_sign_open msg (fromIntegral msgLen) pub sig
|
||||
return (r == 0)
|
||||
where
|
||||
!msgLen = byteArrayLength message
|
||||
!msgLen = B.length message
|
||||
|
||||
publicKeySize :: Int
|
||||
publicKeySize = 32
|
||||
|
||||
@ -11,11 +11,11 @@ module Crypto.Random.ChaChaDRG
|
||||
, initializeWords
|
||||
) where
|
||||
|
||||
import Crypto.Random.Types
|
||||
import Crypto.Internal.ByteArray
|
||||
import Data.SecureMem
|
||||
import Data.Word
|
||||
import Foreign.Storable (pokeElemOff)
|
||||
import Crypto.Random.Types
|
||||
import Crypto.Internal.ByteArray (ByteArray, SecureBytes)
|
||||
import qualified Crypto.Internal.ByteArray as B
|
||||
import Data.Word
|
||||
import Foreign.Storable (pokeElemOff)
|
||||
|
||||
import qualified Crypto.Cipher.ChaCha as C
|
||||
|
||||
@ -35,10 +35,10 @@ initialize seed = ChaChaDRG $ C.initializeSimple seed
|
||||
-- | Initialize a new ChaCha context from 5-tuple of words64.
|
||||
-- This interface is useful when creating a RNG out of tests generators (e.g. QuickCheck).
|
||||
initializeWords :: (Word64, Word64, Word64, Word64, Word64) -> ChaChaDRG
|
||||
initializeWords (a,b,c,d,e) = initialize (byteArrayAllocAndFreeze 40 fill :: SecureMem)
|
||||
initializeWords (a,b,c,d,e) = initialize (B.allocAndFreeze 40 fill :: SecureBytes)
|
||||
where fill s = mapM_ (uncurry (pokeElemOff s)) [(0,a), (1,b), (2,c), (3,d), (4,e)]
|
||||
|
||||
generate :: ByteArray byteArray => Int -> ChaChaDRG -> (byteArray, ChaChaDRG)
|
||||
generate :: ByteArray output => Int -> ChaChaDRG -> (output, ChaChaDRG)
|
||||
generate nbBytes st@(ChaChaDRG prevSt)
|
||||
| nbBytes <= 0 = (empty, st)
|
||||
| nbBytes <= 0 = (B.empty, st)
|
||||
| otherwise = let (output, newSt) = C.generateSimple prevSt nbBytes in (output, ChaChaDRG newSt)
|
||||
|
||||
@ -9,13 +9,14 @@ module Crypto.Random.Entropy
|
||||
( getEntropy
|
||||
) where
|
||||
|
||||
import Data.Maybe (catMaybes)
|
||||
import Crypto.Internal.ByteArray
|
||||
import Data.Maybe (catMaybes)
|
||||
import Crypto.Internal.ByteArray (ByteArray)
|
||||
import qualified Crypto.Internal.ByteArray as B
|
||||
|
||||
import Crypto.Random.Entropy.Unsafe
|
||||
import Crypto.Random.Entropy.Unsafe
|
||||
|
||||
-- | Get some entropy from the system source of entropy
|
||||
getEntropy :: ByteArray byteArray => Int -> IO byteArray
|
||||
getEntropy n = do
|
||||
backends <- catMaybes `fmap` sequence supportedBackends
|
||||
byteArrayAlloc n (replenish n backends)
|
||||
B.alloc n (replenish n backends)
|
||||
|
||||
@ -12,14 +12,15 @@ module Crypto.Random.EntropyPool
|
||||
, getEntropyFrom
|
||||
) where
|
||||
|
||||
import Control.Concurrent.MVar
|
||||
import Crypto.Random.Entropy.Unsafe
|
||||
import Crypto.Internal.ByteArray
|
||||
import Data.SecureMem
|
||||
import Data.Word (Word8)
|
||||
import Data.Maybe (catMaybes)
|
||||
import Foreign.Marshal.Utils (copyBytes)
|
||||
import Foreign.Ptr (plusPtr, Ptr)
|
||||
import Control.Concurrent.MVar
|
||||
import Crypto.Random.Entropy.Unsafe
|
||||
import Crypto.Internal.ByteArray (ByteArray)
|
||||
import qualified Crypto.Internal.ByteArray as B
|
||||
import Data.SecureMem
|
||||
import Data.Word (Word8)
|
||||
import Data.Maybe (catMaybes)
|
||||
import Foreign.Marshal.Utils (copyBytes)
|
||||
import Foreign.Ptr (plusPtr, Ptr)
|
||||
|
||||
-- | Pool of Entropy. contains a self mutating pool of entropy,
|
||||
-- that is always guarantee to contains data.
|
||||
@ -67,4 +68,4 @@ getEntropyPtr (EntropyPool backends posM sm) n outPtr =
|
||||
|
||||
-- | Grab a chunk of entropy from the entropy pool.
|
||||
getEntropyFrom :: ByteArray byteArray => EntropyPool -> Int -> IO byteArray
|
||||
getEntropyFrom pool n = byteArrayAlloc n (getEntropyPtr pool n)
|
||||
getEntropyFrom pool n = B.alloc n (getEntropyPtr pool n)
|
||||
|
||||
@ -12,11 +12,11 @@ module BlockCipher
|
||||
, CipherInfo
|
||||
) where
|
||||
|
||||
import Imports
|
||||
import Data.Maybe
|
||||
import Crypto.Error
|
||||
import Crypto.Cipher.Types
|
||||
import Crypto.Internal.ByteArray
|
||||
import Imports
|
||||
import Data.Maybe
|
||||
import Crypto.Error
|
||||
import Crypto.Cipher.Types
|
||||
import Crypto.Internal.ByteArray as B
|
||||
import qualified Data.ByteString as B
|
||||
|
||||
------------------------------------------------------------------------
|
||||
@ -405,7 +405,7 @@ testBlockCipherAEAD cipher =
|
||||
(dText, aeadD) = aeadDecrypt aead eText
|
||||
eTag = aeadFinalize aeadE (blockSize ctx)
|
||||
dTag = aeadFinalize aeadD (blockSize ctx)
|
||||
in (plaintext `assertEq` dText) && (eTag `byteArrayEq` dTag)
|
||||
in (plaintext `assertEq` dText) && (eTag `B.eq` dTag)
|
||||
CryptoFailed err
|
||||
| err == CryptoError_AEADModeNotSupported -> True
|
||||
| otherwise -> error ("testProperty_AEAD: " ++ show err)
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
module KAT_Curve25519 ( tests ) where
|
||||
|
||||
import qualified Crypto.PubKey.Curve25519 as Curve25519
|
||||
import Crypto.Internal.ByteArray
|
||||
import Crypto.Internal.ByteArray as B
|
||||
import Imports
|
||||
|
||||
alicePrivate = either error id $ Curve25519.secretKey ("\x77\x07\x6d\x0a\x73\x18\xa5\x7d\x3c\x16\xc1\x72\x51\xb2\x66\x45\xdf\x4c\x2f\x87\xeb\xc0\x99\x2a\xb1\x77\xfb\xa5\x1d\xb9\x2c\x2a" :: ByteString)
|
||||
@ -13,8 +13,8 @@ aliceMultBob = "\x4a\x5d\x9d\x5b\xa4\xce\x2d\xe1\x72\x8e\x3b\xf4\x80\x35\x0f\x25
|
||||
|
||||
katTests :: [TestTree]
|
||||
katTests =
|
||||
[ testCase "0" (aliceMultBob @=? byteArrayConvert (Curve25519.dh alicePublic bobPrivate))
|
||||
, testCase "1" (aliceMultBob @=? byteArrayConvert (Curve25519.dh bobPublic alicePrivate))
|
||||
[ testCase "0" (aliceMultBob @=? B.convert (Curve25519.dh alicePublic bobPrivate))
|
||||
, testCase "1" (aliceMultBob @=? B.convert (Curve25519.dh bobPublic alicePrivate))
|
||||
]
|
||||
|
||||
tests = testGroup "Curve25519"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user