packages feed

crypto-cipher-tests 0.0.10 → 0.0.11

raw patch · 5 files changed

+148/−71 lines, 5 filesdep ~crypto-cipher-types

Dependency ranges changed: crypto-cipher-types

Files

Crypto/Cipher/Tests.hs view
@@ -9,6 +9,7 @@ {-# LANGUAGE ViewPatterns #-} module Crypto.Cipher.Tests     ( testBlockCipher+    , testBlockCipherIO     , testStreamCipher     -- * KATs     , defaultKATs@@ -26,6 +27,7 @@ import Test.Framework (Test, testGroup)  import Crypto.Cipher.Types+import Crypto.Cipher.Types.Unsafe import Crypto.Cipher.Tests.KATs import Crypto.Cipher.Tests.Properties @@ -34,6 +36,13 @@ testBlockCipher kats cipher = testGroup (cipherName cipher)     (  (if kats == defaultKATs  then [] else [testKATs kats cipher])     ++ testModes cipher+    )++-- | Return test for a specific blockcipher and a list of KATs+testBlockCipherIO :: BlockCipherIO a => KATs -> a -> Test+testBlockCipherIO _ cipher = testGroup ("mutable " ++ cipherName cipher)+    ( []+    ++ testIOModes cipher     )  -- | Return tests for a specific streamcipher and a list of KATs
Crypto/Cipher/Tests/KATs.hs view
@@ -95,7 +95,10 @@ defaultStreamKATs = []  -- | tests related to KATs-testKATs :: BlockCipher cipher => KATs -> cipher -> Test+testKATs :: BlockCipher cipher+         => KATs+         -> cipher+         -> Test testKATs kats cipher = testGroup "KAT"     (   maybeGroup makeECBTest "ECB" (kat_ECB kats)      ++ maybeGroup makeCBCTest "CBC" (kat_CBC kats)@@ -149,9 +152,6 @@                 etag = aeadFinalize aeadEFinal (aeadTaglen d)                 dtag = aeadFinalize aeadDFinal (aeadTaglen d)                -        cipherMakeIV :: BlockCipher cipher => cipher -> ByteString -> IV cipher-        cipherMakeIV _ bs = fromJust $ makeIV bs- testStreamKATs :: StreamCipher cipher => [KAT_Stream] -> cipher -> Test testStreamKATs kats cipher = testGroup "KAT" $ maybeGroup makeStreamTest "Stream" kats   where makeStreamTest i d =@@ -164,6 +164,10 @@ cipherMakeKey c bs = case makeKey bs of                         Left e -> error ("invalid key " ++ show bs ++ " for " ++ show (cipherName c) ++ " " ++ show e)                         Right k  -> k++cipherMakeIV :: BlockCipher cipher => cipher -> ByteString -> IV cipher+cipherMakeIV _ bs = fromJust $ makeIV bs+  maybeGroup :: (String -> t -> [Test]) -> TestName -> [t] -> [Test] maybeGroup mkTest groupName l
Crypto/Cipher/Tests/Properties.hs view
@@ -10,39 +10,56 @@ import Test.QuickCheck  import Crypto.Cipher.Types+import Crypto.Cipher.Types.Unsafe import qualified Data.ByteString as B+import qualified Data.ByteString.Internal as B import Data.Byteable import Data.Maybe +-- | any sized bytestring+newtype Plaintext a = Plaintext B.ByteString+    deriving (Show,Eq)++instance Byteable (Plaintext a) where+    toBytes (Plaintext b) = b++-- | A multiple of blocksize bytestring+newtype PlaintextBS a = PlaintextBS B.ByteString+    deriving (Show,Eq)++instance Byteable (PlaintextBS a) where+    toBytes (PlaintextBS b) = b+ -- | a ECB unit test-data ECBUnit a = ECBUnit (Key a) B.ByteString+data ECBUnit a = ECBUnit (Key a) (PlaintextBS a)     deriving (Eq)  -- | a CBC unit test-data CBCUnit a = CBCUnit (Key a) (IV a) B.ByteString+data CBCUnit a = CBCUnit (Key a) (IV a) (PlaintextBS a)     deriving (Eq)  -- | a CBC unit test-data CFBUnit a = CFBUnit (Key a) (IV a) B.ByteString+data CFBUnit a = CFBUnit (Key a) (IV a) (PlaintextBS a)     deriving (Eq)  -- | a CFB unit test-data CFB8Unit a = CFB8Unit (Key a) (IV a) B.ByteString+data CFB8Unit a = CFB8Unit (Key a) (IV a) (Plaintext a)     deriving (Eq)  -- | a CTR unit test-data CTRUnit a = CTRUnit (Key a) (IV a) B.ByteString+data CTRUnit a = CTRUnit (Key a) (IV a) (Plaintext a)     deriving (Eq)  -- | a XTS unit test-data XTSUnit a = XTSUnit (Key a) (Key a) (IV a) B.ByteString+data XTSUnit a = XTSUnit (Key a) (Key a) (IV a) (PlaintextBS a)     deriving (Eq)  -- | a AEAD unit test-data AEADUnit a = AEADUnit (Key a) B.ByteString B.ByteString B.ByteString+data AEADUnit a = AEADUnit (Key a) B.ByteString (Plaintext a) (Plaintext a)     deriving (Eq) -data StreamUnit a = StreamUnit (Key a) B.ByteString+-- | Stream cipher unit test+data StreamUnit a = StreamUnit (Key a) (Plaintext a)     deriving (Eq)  instance Show (ECBUnit a) where@@ -83,27 +100,27 @@ generateIvAEAD :: Gen B.ByteString generateIvAEAD = choose (12,90) >>= \sz -> (B.pack <$> replicateM sz arbitrary) --- | Generate a plaintext multiple of 16 bytes. TODO replace by one function that use the blockSize--- cipher instance-generatePlaintextMultiple16 :: Gen B.ByteString-generatePlaintextMultiple16 = choose (1,128) >>= \size -> replicateM (size*16) arbitrary >>= return . B.pack+-- | Generate a plaintext multiple of blocksize bytes+generatePlaintextMultipleBS :: BlockCipher a => Gen (PlaintextBS a)+generatePlaintextMultipleBS = choose (1,128) >>= \size -> replicateM (size * 16) arbitrary >>= return . PlaintextBS . B.pack -generatePlaintext :: Gen B.ByteString-generatePlaintext = choose (0,324) >>= \size -> replicateM size arbitrary >>= return . B.pack+-- | Generate any sized plaintext+generatePlaintext :: Gen (Plaintext a)+generatePlaintext = choose (0,324) >>= \size -> replicateM size arbitrary >>= return . Plaintext . B.pack  instance BlockCipher a => Arbitrary (ECBUnit a) where     arbitrary = ECBUnit <$> generateKey-                        <*> generatePlaintextMultiple16+                        <*> generatePlaintextMultipleBS  instance BlockCipher a => Arbitrary (CBCUnit a) where     arbitrary = CBCUnit <$> generateKey                         <*> generateIv-                        <*> generatePlaintextMultiple16+                        <*> generatePlaintextMultipleBS  instance BlockCipher a => Arbitrary (CFBUnit a) where     arbitrary = CFBUnit <$> generateKey                         <*> generateIv-                        <*> generatePlaintextMultiple16+                        <*> generatePlaintextMultipleBS  instance BlockCipher a => Arbitrary (CFB8Unit a) where     arbitrary = CFB8Unit <$> generateKey <*> generateIv <*> generatePlaintext@@ -117,7 +134,7 @@     arbitrary = XTSUnit <$> generateKey                         <*> generateKey                         <*> generateIv-                        <*> generatePlaintextMultiple16+                        <*> generatePlaintextMultipleBS  instance BlockCipher a => Arbitrary (AEADUnit a) where     arbitrary = AEADUnit <$> generateKey@@ -129,62 +146,54 @@     arbitrary = StreamUnit <$> generateKey                            <*> generatePlaintext --- | Test a generic block cipher for properties--- related to block cipher modes.-testModes :: BlockCipher a => a -> [Test]-testModes cipher =-    [ testGroup "decrypt.encrypt==id"-        [ testProperty "ECB" ecbProp-        , testProperty "CBC" cbcProp-        , testProperty "CFB" cfbProp-        , testProperty "CFB8" cfb8Prop-        , testProperty "CTR" ctrProp-        , testProperty "XTS" xtsProp-        , testProperty "OCB" (aeadProp AEAD_OCB)-        , testProperty "CCM" (aeadProp AEAD_CCM)-        , testProperty "EAX" (aeadProp AEAD_EAX)-        , testProperty "CWC" (aeadProp AEAD_CWC)-        , testProperty "GCM" (aeadProp AEAD_GCM)-        ]+testBlockCipherBasic :: BlockCipher a => a -> [Test]+testBlockCipherBasic cipher = [ testProperty "ECB" ecbProp ]+  where ecbProp = toTests cipher+        toTests :: BlockCipher a => a -> (ECBUnit a -> Bool)+        toTests _ = testProperty_ECB+        testProperty_ECB (ECBUnit (cipherInit -> ctx) (toBytes -> plaintext)) =+            plaintext `assertEq` ecbDecrypt ctx (ecbEncrypt ctx plaintext)++testBlockCipherModes :: BlockCipher a => a -> [Test]+testBlockCipherModes cipher =+    [ testProperty "CBC" cbcProp+    , testProperty "CFB" cfbProp+    , testProperty "CFB8" cfb8Prop+    , testProperty "CTR" ctrProp     ]-  where (ecbProp,cbcProp,cfbProp,cfb8Prop,ctrProp,xtsProp,aeadProp) = toTests cipher+  where (cbcProp,cfbProp,cfb8Prop,ctrProp) = toTests cipher         toTests :: BlockCipher a                 => a-                -> ((ECBUnit a -> Bool),-                    (CBCUnit a -> Bool),-                    (CFBUnit a -> Bool),-                    (CFB8Unit a -> Bool),-                    (CTRUnit a -> Bool),-                    (XTSUnit a -> Bool),-                    (AEADMode -> AEADUnit a -> Bool))-        toTests _ = (testProperty_ECB-                    ,testProperty_CBC+                -> ((CBCUnit a -> Bool), (CFBUnit a -> Bool), (CFB8Unit a -> Bool), (CTRUnit a -> Bool))+        toTests _ = (testProperty_CBC                     ,testProperty_CFB                     ,testProperty_CFB8                     ,testProperty_CTR-                    ,testProperty_XTS-                    ,testProperty_AEAD                     )-        testProperty_ECB (ECBUnit (cipherInit -> ctx) plaintext) =-            plaintext `assertEq` ecbDecrypt ctx (ecbEncrypt ctx plaintext)--        testProperty_CBC (CBCUnit (cipherInit -> ctx) testIV plaintext) =+        testProperty_CBC (CBCUnit (cipherInit -> ctx) testIV (toBytes -> plaintext)) =             plaintext `assertEq` cbcDecrypt ctx testIV (cbcEncrypt ctx testIV plaintext) -        testProperty_CFB (CFBUnit (cipherInit -> ctx) testIV plaintext) =+        testProperty_CFB (CFBUnit (cipherInit -> ctx) testIV (toBytes -> plaintext)) =             plaintext `assertEq` cfbDecrypt ctx testIV (cfbEncrypt ctx testIV plaintext) -        testProperty_CFB8 (CFB8Unit (cipherInit -> ctx) testIV plaintext) =+        testProperty_CFB8 (CFB8Unit (cipherInit -> ctx) testIV (toBytes -> plaintext)) =             plaintext `assertEq` cfb8Decrypt ctx testIV (cfb8Encrypt ctx testIV plaintext) -        testProperty_CTR (CTRUnit (cipherInit -> ctx) testIV plaintext) =+        testProperty_CTR (CTRUnit (cipherInit -> ctx) testIV (toBytes -> plaintext)) =             plaintext `assertEq` ctrCombine ctx testIV (ctrCombine ctx testIV plaintext) -        testProperty_XTS (XTSUnit (cipherInit -> ctx1) (cipherInit -> ctx2) testIV plaintext)-            | blockSize ctx1 == 16 = plaintext `assertEq` xtsDecrypt (ctx1, ctx2) testIV 0 (xtsEncrypt (ctx1, ctx2) testIV 0 plaintext)-            | otherwise            = True--        testProperty_AEAD mode (AEADUnit (cipherInit -> ctx) testIV aad plaintext) =+testBlockCipherAEAD :: BlockCipher a => a -> [Test]+testBlockCipherAEAD cipher =+    [ testProperty "OCB" (aeadProp AEAD_OCB)+    , testProperty "CCM" (aeadProp AEAD_CCM)+    , testProperty "EAX" (aeadProp AEAD_EAX)+    , testProperty "CWC" (aeadProp AEAD_CWC)+    , testProperty "GCM" (aeadProp AEAD_GCM)+    ]+  where aeadProp = toTests cipher+        toTests :: BlockCipher a => a -> (AEADMode -> AEADUnit a -> Bool)+        toTests _ = testProperty_AEAD+        testProperty_AEAD mode (AEADUnit (cipherInit -> ctx) testIV (toBytes -> aad) (toBytes -> plaintext)) =             case aeadInit mode ctx testIV of                 Just iniAead ->                     let aead           = aeadAppendHeader iniAead aad@@ -195,10 +204,54 @@                      in (plaintext `assertEq` dText) && (toBytes eTag `assertEq` toBytes dTag)                 Nothing -> True +testBlockCipherXTS :: BlockCipher a => a -> [Test]+testBlockCipherXTS cipher = [testProperty "XTS" xtsProp]+  where xtsProp = toTests cipher+        toTests :: BlockCipher a => a -> (XTSUnit a -> Bool)+        toTests _ = testProperty_XTS++        testProperty_XTS (XTSUnit (cipherInit -> ctx1) (cipherInit -> ctx2) testIV (toBytes -> plaintext))+            | blockSize ctx1 == 16 = plaintext `assertEq` xtsDecrypt (ctx1, ctx2) testIV 0 (xtsEncrypt (ctx1, ctx2) testIV 0 plaintext)+            | otherwise            = True++-- | Test a generic block cipher for properties+-- related to block cipher modes.+testModes :: BlockCipher a => a -> [Test]+testModes cipher =+    [ testGroup "decrypt.encrypt==id"+        (testBlockCipherBasic cipher ++ testBlockCipherModes cipher ++ testBlockCipherAEAD cipher ++ testBlockCipherXTS cipher)+    ]++-- | Test a generic block cipher for properties+-- related to BlockCipherIO cipher modes.+testIOModes :: BlockCipherIO a => a -> [Test]+testIOModes cipher =+    [ testGroup "mutable"+        [ testProperty "ECB" (testProperty_ECB cipher)+        , testProperty "CBC" (testProperty_CBC cipher) ]+    ]+  where testProperty_ECB :: BlockCipherIO a => a -> (ECBUnit a) -> Bool+        testProperty_ECB _ (ECBUnit (cipherInit -> ctx) (toBytes -> plaintext)) =+            plaintext == B.unsafeCreate (B.length plaintext) encryptDecryptMutable+          where encryptDecryptMutable buf = withBytePtr plaintext $ \src -> do+                    ecbEncryptMutable ctx buf src (fromIntegral $ B.length plaintext)+                    ecbDecryptMutable ctx buf buf (fromIntegral $ B.length plaintext)++        testProperty_CBC :: BlockCipherIO a => a -> (CBCUnit a) -> Bool+        testProperty_CBC _ (CBCUnit (cipherInit -> ctx) testIV (toBytes -> plaintext)) =+            plaintext == B.unsafeCreate (B.length plaintext) encryptDecryptMutable+          where encryptDecryptMutable buf =+                    void $ B.create (B.length plaintext) $ \tmp ->+                    withBytePtr plaintext $ \src ->+                    withBytePtr testIV $ \iv -> do+                        cbcEncryptMutable ctx iv tmp src (fromIntegral $ B.length plaintext)+                        cbcDecryptMutable ctx iv buf tmp (fromIntegral $ B.length plaintext)+                    +-- | Test stream mode testStream :: StreamCipher a => a -> [Test] testStream cipher = [testProperty "combine.combine==id" (testStreamUnit cipher)]   where testStreamUnit :: StreamCipher a => a -> (StreamUnit a -> Bool)-        testStreamUnit _ (StreamUnit (cipherInit -> ctx) plaintext) =+        testStreamUnit _ (StreamUnit (cipherInit -> ctx) (toBytes -> plaintext)) =             let cipherText = fst $ streamCombine ctx plaintext              in fst (streamCombine ctx cipherText) `assertEq` plaintext 
crypto-cipher-tests.cabal view
@@ -1,5 +1,5 @@ Name:                crypto-cipher-tests-Version:             0.0.10+Version:             0.0.11 Synopsis:            Generic cryptography cipher tests Description:         Generic cryptography cipher tests License:             BSD3@@ -27,7 +27,7 @@                    , bytestring                    , byteable >= 0.1.1 && < 0.2                    , securemem >= 0.1.1 && < 0.2-                   , crypto-cipher-types >= 0.0.7 && < 0.1+                   , crypto-cipher-types >= 0.0.8 && < 0.1   ghc-options:       -Wall -fwarn-tabs  Test-Suite test-crypto-cipher-dummy@@ -37,7 +37,7 @@   Build-Depends:     base >= 3 && < 5                    , bytestring                    , byteable-                   , crypto-cipher-types >= 0.0.7+                   , crypto-cipher-types                    , crypto-cipher-tests                    , mtl                    , QuickCheck >= 2
tests/Tests.hs view
@@ -3,6 +3,7 @@  import Test.Framework (defaultMain) import Crypto.Cipher.Types+import Crypto.Cipher.Types.Unsafe import Crypto.Cipher.Tests import qualified Data.ByteString as B import Data.Bits (xor)@@ -18,15 +19,25 @@  instance BlockCipher XorCipher where     blockSize  _   = 16-    ecbEncrypt _ b = B.pack $ B.zipWith xor (B.replicate (B.length b) 0xa5) b-    ecbDecrypt _ b = B.pack $ B.zipWith xor (B.replicate (B.length b) 0xa5) b+    ecbEncrypt _ s = xorBS s+    ecbDecrypt _ s = xorBS s +instance BlockCipherIO XorCipher where+    ecbEncryptMutable cipher d s len = onBlock cipher xorBS d s len+    ecbDecryptMutable cipher d s len = onBlock cipher xorBS d s len+ instance StreamCipher XorCipher where     streamCombine _ b = (B.pack $ B.zipWith xor (B.replicate (B.length b) 0x12) b, XorCipher) +xorBS :: B.ByteString -> B.ByteString+xorBS b = B.pack $ B.zipWith xor (B.replicate (B.length b) 0xa5) b+ tests =-    [ testBlockCipher defaultKATs (undefined :: XorCipher)-    , testStreamCipher defaultStreamKATs (undefined :: XorCipher)+    [ testBlockCipher defaultKATs cipher+    , testBlockCipherIO defaultKATs cipher+    , testStreamCipher defaultStreamKATs cipher     ]+  where cipher :: XorCipher+        cipher = undefined  main = defaultMain tests