remove further deprecated modules and such

This commit is contained in:
Vincent Hanquez 2015-04-20 10:56:39 +01:00
parent 0f7557edf2
commit 61ee498643
4 changed files with 43 additions and 48 deletions

View File

@ -1,8 +1,6 @@
{-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE ViewPatterns #-} {-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE BangPatterns #-} {-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}
-- | -- |
-- Module : Crypto.Cipher.AES.Primitive -- Module : Crypto.Cipher.AES.Primitive
@ -66,15 +64,12 @@ import Foreign.C.Types
import Foreign.C.String import Foreign.C.String
import Data.ByteString.Internal import Data.ByteString.Internal
import qualified Data.ByteString as B import qualified Data.ByteString as B
import System.IO.Unsafe (unsafePerformIO)
import Crypto.Error import Crypto.Error
import Crypto.Cipher.Types import Crypto.Cipher.Types
import Crypto.Internal.ByteArray
import Crypto.Internal.Memory
import Crypto.Cipher.Types.Block (IV(..)) import Crypto.Cipher.Types.Block (IV(..))
import Crypto.Internal.Compat
import Data.SecureMem import Crypto.Internal.ByteArray
instance Cipher AES where instance Cipher AES where
cipherName _ = "AES" cipherName _ = "AES"
@ -150,18 +145,18 @@ withKey2AndIV key1 key2 iv f =
withGCMKeyAndCopySt :: AES -> AESGCM -> (Ptr AESGCM -> Ptr AES -> IO a) -> IO (a, AESGCM) withGCMKeyAndCopySt :: AES -> AESGCM -> (Ptr AESGCM -> Ptr AES -> IO a) -> IO (a, AESGCM)
withGCMKeyAndCopySt aes (AESGCM gcmSt) f = withGCMKeyAndCopySt aes (AESGCM gcmSt) f =
keyToPtr aes $ \aesPtr -> do keyToPtr aes $ \aesPtr -> do
newSt <- secureMemCopy gcmSt newSt <- byteArrayCopy gcmSt (\_ -> return ())
a <- withSecureMemPtr newSt $ \gcmStPtr -> f (castPtr gcmStPtr) aesPtr a <- withByteArray newSt $ \gcmStPtr -> f (castPtr gcmStPtr) aesPtr
return (a, AESGCM newSt) return (a, AESGCM newSt)
withNewGCMSt :: AESGCM -> (Ptr AESGCM -> IO ()) -> IO AESGCM withNewGCMSt :: AESGCM -> (Ptr AESGCM -> IO ()) -> IO AESGCM
withNewGCMSt (AESGCM gcmSt) f = withSecureMemCopy gcmSt (f . castPtr) >>= \sm2 -> return (AESGCM sm2) withNewGCMSt (AESGCM gcmSt) f = byteArrayCopy gcmSt (f . castPtr) >>= \sm2 -> return (AESGCM sm2)
withOCBKeyAndCopySt :: AES -> AESOCB -> (Ptr AESOCB -> Ptr AES -> IO a) -> IO (a, AESOCB) withOCBKeyAndCopySt :: AES -> AESOCB -> (Ptr AESOCB -> Ptr AES -> IO a) -> IO (a, AESOCB)
withOCBKeyAndCopySt aes (AESOCB gcmSt) f = withOCBKeyAndCopySt aes (AESOCB gcmSt) f =
keyToPtr aes $ \aesPtr -> do keyToPtr aes $ \aesPtr -> do
newSt <- secureMemCopy gcmSt newSt <- byteArrayCopy gcmSt (\_ -> return ())
a <- withSecureMemPtr newSt $ \gcmStPtr -> f (castPtr gcmStPtr) aesPtr a <- withByteArray newSt $ \gcmStPtr -> f (castPtr gcmStPtr) aesPtr
return (a, AESOCB newSt) return (a, AESOCB newSt)
-- | Initialize a new context with a key -- | Initialize a new context with a key
@ -174,7 +169,7 @@ initAES k
| len == 32 = CryptoPassed $ initWithRounds 14 | len == 32 = CryptoPassed $ initWithRounds 14
| otherwise = CryptoFailed CryptoError_KeySizeInvalid | otherwise = CryptoFailed CryptoError_KeySizeInvalid
where len = byteArrayLength k where len = byteArrayLength k
initWithRounds nbR = AES $ unsafeCreateSecureMem (16+2*2*16*nbR) aesInit initWithRounds nbR = AES $ byteArrayAllocAndFreeze (16+2*2*16*nbR) aesInit
aesInit ptr = withByteArray k $ \ikey -> aesInit ptr = withByteArray k $ \ikey ->
c_aes_init (castPtr ptr) (castPtr ikey) (fromIntegral len) c_aes_init (castPtr ptr) (castPtr ikey) (fromIntegral len)
@ -227,7 +222,7 @@ genCounter :: ByteArray ba
-> (ba, IV AES) -> (ba, IV AES)
genCounter ctx iv len genCounter ctx iv len
| len <= 0 = (empty, iv) | len <= 0 = (empty, iv)
| otherwise = unsafePerformIO $ | otherwise = unsafeDoIO $
keyToPtr ctx $ \k -> keyToPtr ctx $ \k ->
ivCopyPtr iv $ \i -> ivCopyPtr iv $ \i ->
byteArrayAlloc outputLength $ \o -> do byteArrayAlloc outputLength $ \o -> do
@ -410,8 +405,8 @@ doGCM f ctx iv aad input = (output, tag)
-- | initialize a gcm context -- | initialize a gcm context
{-# NOINLINE gcmInit #-} {-# NOINLINE gcmInit #-}
gcmInit :: ByteArrayAccess iv => AES -> iv -> AESGCM gcmInit :: ByteArrayAccess iv => AES -> iv -> AESGCM
gcmInit ctx iv = unsafePerformIO $ do gcmInit ctx iv = unsafeDoIO $ do
sm <- createSecureMem sizeGCM $ \gcmStPtr -> sm <- byteArrayAlloc sizeGCM $ \gcmStPtr ->
withKeyAndIV ctx iv $ \k v -> 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 $ byteArrayLength iv)
return $ AESGCM sm return $ AESGCM sm
@ -421,7 +416,7 @@ gcmInit ctx iv = unsafePerformIO $ do
-- need to happen after initialization and before appending encryption/decryption data. -- need to happen after initialization and before appending encryption/decryption data.
{-# NOINLINE gcmAppendAAD #-} {-# NOINLINE gcmAppendAAD #-}
gcmAppendAAD :: ByteArrayAccess aad => AESGCM -> aad -> AESGCM gcmAppendAAD :: ByteArrayAccess aad => AESGCM -> aad -> AESGCM
gcmAppendAAD gcmSt input = unsafePerformIO doAppend gcmAppendAAD gcmSt input = unsafeDoIO doAppend
where doAppend = where doAppend =
withNewGCMSt gcmSt $ \gcmStPtr -> withNewGCMSt gcmSt $ \gcmStPtr ->
withByteArray input $ \i -> withByteArray input $ \i ->
@ -433,7 +428,7 @@ gcmAppendAAD gcmSt input = unsafePerformIO doAppend
-- need to happen after AAD appending, or after initialization if no AAD data. -- need to happen after AAD appending, or after initialization if no AAD data.
{-# NOINLINE gcmAppendEncrypt #-} {-# NOINLINE gcmAppendEncrypt #-}
gcmAppendEncrypt :: ByteArray ba => AES -> AESGCM -> ba -> (ba, AESGCM) gcmAppendEncrypt :: ByteArray ba => AES -> AESGCM -> ba -> (ba, AESGCM)
gcmAppendEncrypt ctx gcm input = unsafePerformIO $ withGCMKeyAndCopySt ctx gcm doEnc gcmAppendEncrypt ctx gcm input = unsafeDoIO $ withGCMKeyAndCopySt ctx gcm doEnc
where len = byteArrayLength input where len = byteArrayLength input
doEnc gcmStPtr aesPtr = doEnc gcmStPtr aesPtr =
byteArrayAlloc len $ \o -> byteArrayAlloc len $ \o ->
@ -446,7 +441,7 @@ gcmAppendEncrypt ctx gcm input = unsafePerformIO $ withGCMKeyAndCopySt ctx gcm d
-- need to happen after AAD appending, or after initialization if no AAD data. -- need to happen after AAD appending, or after initialization if no AAD data.
{-# NOINLINE gcmAppendDecrypt #-} {-# NOINLINE gcmAppendDecrypt #-}
gcmAppendDecrypt :: ByteArray ba => AES -> AESGCM -> ba -> (ba, AESGCM) gcmAppendDecrypt :: ByteArray ba => AES -> AESGCM -> ba -> (ba, AESGCM)
gcmAppendDecrypt ctx gcm input = unsafePerformIO $ withGCMKeyAndCopySt ctx gcm doDec gcmAppendDecrypt ctx gcm input = unsafeDoIO $ withGCMKeyAndCopySt ctx gcm doDec
where len = byteArrayLength input where len = byteArrayLength input
doDec gcmStPtr aesPtr = doDec gcmStPtr aesPtr =
byteArrayAlloc len $ \o -> byteArrayAlloc len $ \o ->
@ -481,8 +476,8 @@ doOCB f ctx iv aad input = (output, tag)
-- | initialize an ocb context -- | initialize an ocb context
{-# NOINLINE ocbInit #-} {-# NOINLINE ocbInit #-}
ocbInit :: ByteArrayAccess iv => AES -> iv -> AESOCB ocbInit :: ByteArrayAccess iv => AES -> iv -> AESOCB
ocbInit ctx iv = unsafePerformIO $ do ocbInit ctx iv = unsafeDoIO $ do
sm <- createSecureMem sizeOCB $ \ocbStPtr -> sm <- byteArrayAlloc sizeOCB $ \ocbStPtr ->
withKeyAndIV ctx iv $ \k v -> 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 $ byteArrayLength iv)
return $ AESOCB sm return $ AESOCB sm
@ -492,7 +487,7 @@ ocbInit ctx iv = unsafePerformIO $ do
-- need to happen after initialization and before appending encryption/decryption data. -- need to happen after initialization and before appending encryption/decryption data.
{-# NOINLINE ocbAppendAAD #-} {-# NOINLINE ocbAppendAAD #-}
ocbAppendAAD :: ByteArrayAccess aad => AES -> AESOCB -> aad -> AESOCB ocbAppendAAD :: ByteArrayAccess aad => AES -> AESOCB -> aad -> AESOCB
ocbAppendAAD ctx ocb input = unsafePerformIO (snd `fmap` withOCBKeyAndCopySt ctx ocb doAppend) ocbAppendAAD ctx ocb input = unsafeDoIO (snd `fmap` withOCBKeyAndCopySt ctx ocb doAppend)
where doAppend ocbStPtr aesPtr = where doAppend ocbStPtr aesPtr =
withByteArray input $ \i -> withByteArray input $ \i ->
c_aes_ocb_aad ocbStPtr aesPtr i (fromIntegral $ byteArrayLength input) c_aes_ocb_aad ocbStPtr aesPtr i (fromIntegral $ byteArrayLength input)
@ -503,7 +498,7 @@ ocbAppendAAD ctx ocb input = unsafePerformIO (snd `fmap` withOCBKeyAndCopySt ctx
-- need to happen after AAD appending, or after initialization if no AAD data. -- need to happen after AAD appending, or after initialization if no AAD data.
{-# NOINLINE ocbAppendEncrypt #-} {-# NOINLINE ocbAppendEncrypt #-}
ocbAppendEncrypt :: ByteArray ba => AES -> AESOCB -> ba -> (ba, AESOCB) ocbAppendEncrypt :: ByteArray ba => AES -> AESOCB -> ba -> (ba, AESOCB)
ocbAppendEncrypt ctx ocb input = unsafePerformIO $ withOCBKeyAndCopySt ctx ocb doEnc ocbAppendEncrypt ctx ocb input = unsafeDoIO $ withOCBKeyAndCopySt ctx ocb doEnc
where len = byteArrayLength input where len = byteArrayLength input
doEnc ocbStPtr aesPtr = doEnc ocbStPtr aesPtr =
byteArrayAlloc len $ \o -> byteArrayAlloc len $ \o ->
@ -516,7 +511,7 @@ ocbAppendEncrypt ctx ocb input = unsafePerformIO $ withOCBKeyAndCopySt ctx ocb d
-- need to happen after AAD appending, or after initialization if no AAD data. -- need to happen after AAD appending, or after initialization if no AAD data.
{-# NOINLINE ocbAppendDecrypt #-} {-# NOINLINE ocbAppendDecrypt #-}
ocbAppendDecrypt :: ByteArray ba => AES -> AESOCB -> ba -> (ba, AESOCB) ocbAppendDecrypt :: ByteArray ba => AES -> AESOCB -> ba -> (ba, AESOCB)
ocbAppendDecrypt ctx ocb input = unsafePerformIO $ withOCBKeyAndCopySt ctx ocb doDec ocbAppendDecrypt ctx ocb input = unsafeDoIO $ withOCBKeyAndCopySt ctx ocb doDec
where len = byteArrayLength input where len = byteArrayLength input
doDec ocbStPtr aesPtr = doDec ocbStPtr aesPtr =
byteArrayAlloc len $ \o -> byteArrayAlloc len $ \o ->

View File

@ -17,29 +17,26 @@ module Crypto.Cipher.ChaCha
, StateSimple , StateSimple
) where ) where
import Control.Applicative
import Data.SecureMem
import Data.ByteString (ByteString) import Data.ByteString (ByteString)
import qualified Data.ByteString.Internal as B import qualified Data.ByteString.Internal as B
import qualified Data.ByteString as B import qualified Data.ByteString as B
import Crypto.Internal.ByteArray import Crypto.Internal.ByteArray
import Crypto.Internal.Compat import Crypto.Internal.Compat
import Crypto.Internal.Imports
import Data.Byteable import Data.Byteable
import Data.Word
import Data.Bits (xor) import Data.Bits (xor)
import Foreign.Ptr import Foreign.Ptr
import Foreign.ForeignPtr import Foreign.ForeignPtr
import Foreign.C.Types import Foreign.C.Types
import Foreign.Storable import Foreign.Storable
import System.IO.Unsafe
-- | ChaCha context -- | ChaCha context
data State = State Int -- number of rounds data State = State Int -- number of rounds
SecureMem -- ChaCha's state SecureBytes -- ChaCha's state
ByteString -- previous generated chunk ByteString -- previous generated chunk
-- | ChaCha context for DRG purpose (see Crypto.Random.ChaChaDRG) -- | ChaCha context for DRG purpose (see Crypto.Random.ChaChaDRG)
newtype StateSimple = StateSimple SecureMem -- just ChaCha's state newtype StateSimple = StateSimple SecureBytes -- just ChaCha's state
round64 :: Int -> (Bool, Int) round64 :: Int -> (Bool, Int)
round64 len round64 len
@ -50,7 +47,7 @@ round64 len
-- | Initialize a new ChaCha context with the number of rounds, -- | Initialize a new ChaCha context with the number of rounds,
-- the key and the nonce associated. -- the key and the nonce associated.
initialize :: Byteable key initialize :: ByteArrayAccess key
=> Int -- ^ number of rounds (8,12,20) => Int -- ^ number of rounds (8,12,20)
-> key -- ^ the key (128 or 256 bits) -> key -- ^ the key (128 or 256 bits)
-> ByteString -- ^ the nonce (64 or 96 bits) -> ByteString -- ^ the nonce (64 or 96 bits)
@ -60,12 +57,12 @@ initialize nbRounds key nonce
| not (nonceLen `elem` [8,12]) = error "ChaCha: nonce length should be 64 or 96 bits" | 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" | not (nbRounds `elem` [8,12,20]) = error "ChaCha: rounds should be 8, 12 or 20"
| otherwise = unsafeDoIO $ do | otherwise = unsafeDoIO $ do
stPtr <- createSecureMem 64 $ \stPtr -> stPtr <- byteArrayAlloc 64 $ \stPtr ->
withBytePtr nonce $ \noncePtr -> withByteArray nonce $ \noncePtr ->
withBytePtr key $ \keyPtr -> withByteArray key $ \keyPtr ->
ccryptonite_chacha_init (castPtr stPtr) kLen keyPtr nonceLen noncePtr ccryptonite_chacha_init (castPtr stPtr) kLen keyPtr nonceLen noncePtr
return $ State nbRounds stPtr B.empty return $ State nbRounds stPtr B.empty
where kLen = byteableLength key where kLen = byteArrayLength key
nonceLen = B.length nonce nonceLen = B.length nonce
-- | Initialize simple ChaCha State -- | Initialize simple ChaCha State
@ -75,7 +72,7 @@ initializeSimple :: ByteArray seed
initializeSimple seed initializeSimple seed
| sLen /= 40 = error "ChaCha Random: seed length should be 40 bytes" | sLen /= 40 = error "ChaCha Random: seed length should be 40 bytes"
| otherwise = unsafeDoIO $ do | otherwise = unsafeDoIO $ do
stPtr <- createSecureMem 64 $ \stPtr -> stPtr <- byteArrayAlloc 64 $ \stPtr ->
withByteArray seed $ \seedPtr -> withByteArray seed $ \seedPtr ->
ccryptonite_chacha_init (castPtr stPtr) 32 seedPtr 8 (seedPtr `plusPtr` 32) ccryptonite_chacha_init (castPtr stPtr) 32 seedPtr 8 (seedPtr `plusPtr` 32)
return $ StateSimple stPtr return $ StateSimple stPtr
@ -94,7 +91,7 @@ combine prev@(State nbRounds prevSt prevOut) src
-- without having to generate any extra bytes -- without having to generate any extra bytes
let (b1,b2) = B.splitAt outputLen prevOut let (b1,b2) = B.splitAt outputLen prevOut
in (B.pack $ B.zipWith xor b1 src, State nbRounds prevSt b2) in (B.pack $ B.zipWith xor b1 src, State nbRounds prevSt b2)
| otherwise = unsafePerformIO $ do | otherwise = unsafeDoIO $ do
-- adjusted len is the number of bytes lefts to generate after -- adjusted len is the number of bytes lefts to generate after
-- copying from the previous buffer. -- copying from the previous buffer.
let adjustedLen = outputLen - prevBufLen let adjustedLen = outputLen - prevBufLen
@ -103,14 +100,14 @@ combine prev@(State nbRounds prevSt prevOut) src
fptr <- B.mallocByteString (newBytesToGenerate + prevBufLen) fptr <- B.mallocByteString (newBytesToGenerate + prevBufLen)
newSt <- withForeignPtr fptr $ \dstPtr -> newSt <- withForeignPtr fptr $ \dstPtr ->
withBytePtr src $ \srcPtr -> do withByteArray src $ \srcPtr -> do
-- copy the previous buffer by xor if any -- copy the previous buffer by xor if any
withBytePtr prevOut $ \prevPtr -> withBytePtr prevOut $ \prevPtr ->
loopXor dstPtr srcPtr prevPtr prevBufLen loopXor dstPtr srcPtr prevPtr prevBufLen
-- then create a new mutable copy of state -- then create a new mutable copy of state
st <- secureMemCopy prevSt st <- byteArrayCopy prevSt (\_ -> return ())
withSecureMemPtr st $ \stPtr -> withByteArray st $ \stPtr ->
ccryptonite_chacha_combine nbRounds ccryptonite_chacha_combine nbRounds
(dstPtr `plusPtr` prevBufLen) (dstPtr `plusPtr` prevBufLen)
(castPtr stPtr) (castPtr stPtr)
@ -144,9 +141,9 @@ generateSimple :: ByteArray ba
-> Int -> Int
-> (ba, StateSimple) -> (ba, StateSimple)
generateSimple (StateSimple prevSt) nbBytes = unsafeDoIO $ do generateSimple (StateSimple prevSt) nbBytes = unsafeDoIO $ do
newSt <- secureMemCopy prevSt newSt <- byteArrayCopy prevSt (\_ -> return ())
output <- byteArrayAlloc nbBytes $ \dstPtr -> output <- byteArrayAlloc nbBytes $ \dstPtr ->
withSecureMemPtr newSt $ \stPtr -> withByteArray newSt $ \stPtr ->
ccryptonite_chacha_random 8 dstPtr (castPtr stPtr) (fromIntegral nbBytes) ccryptonite_chacha_random 8 dstPtr (castPtr stPtr) (fromIntegral nbBytes)
return (output, StateSimple newSt) return (output, StateSimple newSt)

View File

@ -11,8 +11,13 @@
{-# LANGUAGE MagicHash #-} {-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedTuples #-} {-# LANGUAGE UnboxedTuples #-}
module Crypto.Internal.ByteArray module Crypto.Internal.ByteArray
( ByteArray(..) (
ByteArray(..)
, ByteArrayAccess(..) , ByteArrayAccess(..)
-- * Inhabitants
, Bytes
, SecureBytes
-- * methods
, byteArrayAlloc , byteArrayAlloc
, byteArrayAllocAndFreeze , byteArrayAllocAndFreeze
, empty , empty

View File

@ -21,9 +21,7 @@ import Crypto.Random.Types
import Crypto.Random.ChaChaDRG import Crypto.Random.ChaChaDRG
import Crypto.Random.Entropy import Crypto.Random.Entropy
import Crypto.Internal.Memory import Crypto.Internal.Memory
import Crypto.Internal.Imports
import Control.Applicative
import Data.Word (Word64)
drgNew :: IO ChaChaDRG drgNew :: IO ChaChaDRG
drgNew = initialize <$> (getEntropy 40 :: IO SecureBytes) drgNew = initialize <$> (getEntropy 40 :: IO SecureBytes)