packages feed

crypto-cipher-tests (empty) → 0.0.1

raw patch · 6 files changed

+372/−0 lines, 6 filesdep +HUnitdep +QuickCheckdep +basesetup-changed

Dependencies added: HUnit, QuickCheck, base, byteable, bytestring, crypto-cipher-types, mtl, securemem, test-framework, test-framework-hunit, test-framework-quickcheck2

Files

+ Crypto/Cipher/Tests.hs view
@@ -0,0 +1,33 @@+-- |+-- Module      : Crypto.Cipher.Tests+-- License     : BSD-style+-- Maintainer  : Vincent Hanquez <vincent@snarc.org>+-- Stability   : Stable+-- Portability : Excellent+--++{-# LANGUAGE ViewPatterns #-}+module Crypto.Cipher.Tests+    ( testBlockCipher+    -- * KATs+    , defaultKATs+    , KATs(..)+    , KAT_ECB(..)+    , KAT_CBC(..)+    , KAT_CTR(..)+    , KAT_XTS(..)+    , KAT_AEAD(..)+    ) where++import Test.Framework (Test, testGroup)++import Crypto.Cipher.Types+import Crypto.Cipher.Tests.KATs+import Crypto.Cipher.Tests.Properties++-- | Return tests for a specific blockcipher and a list of KATs+testBlockCipher :: BlockCipher a => KATs -> a -> Test+testBlockCipher kats cipher = testGroup (cipherName cipher)+    (  (if kats == defaultKATs  then [] else [testKATs kats cipher])+    ++ testModes cipher+    )
+ Crypto/Cipher/Tests/KATs.hs view
@@ -0,0 +1,130 @@+module Crypto.Cipher.Tests.KATs+    where++import Data.ByteString (ByteString)++import Test.Framework (Test, testGroup)+import Test.Framework.Providers.HUnit (testCase)+import Test.HUnit ((@?=))+import Crypto.Cipher.Types+import Data.Maybe++-- | ECB KAT+data KAT_ECB = KAT_ECB+    { ecbKey        :: ByteString+    , ecbPlaintext  :: ByteString+    , ecbCiphertext :: ByteString+    } deriving (Show,Eq)++-- | CBC KAT+data KAT_CBC = KAT_CBC+    { cbcKey        :: ByteString+    , cbcIV         :: ByteString+    , cbcPlaintext  :: ByteString+    , cbcCiphertext :: ByteString+    } deriving (Show,Eq)++-- | CTR KAT+data KAT_CTR = KAT_CTR+    { ctrKey        :: ByteString+    , ctrIV         :: ByteString+    , ctrPlaintext  :: ByteString+    , ctrCiphertext :: ByteString+    } deriving (Show,Eq)++-- | XTS KAT+data KAT_XTS = KAT_XTS+    { xtsKey1       :: ByteString+    , xtsKey2       :: ByteString+    , xtsIV         :: ByteString+    , xtsPlaintext  :: ByteString+    , xtsCiphertext :: ByteString+    } deriving (Show,Eq)++-- | AEAD KAT+data KAT_AEAD = KAT_AEAD+    { aeadMode       :: AEADMode   -- ^ AEAD mode to use+    , aeadKey        :: ByteString -- ^ Key+    , aeadIV         :: ByteString -- ^ IV for initialization+    , aeadHeader     :: ByteString -- ^ Authentificated Header+    , aeadPlaintext  :: ByteString -- ^ Plaintext+    , aeadCiphertext :: ByteString -- ^ Ciphertext+    , aeadTaglen     :: Int        -- ^ aead tag len+    , aeadTag        :: AuthTag    -- ^ expected tag+    } deriving (Show,Eq)++data KATs = KATs+    { kat_ECB  :: [KAT_ECB]+    , kat_CBC  :: [KAT_CBC]+    , kat_CTR  :: [KAT_CTR]+    , kat_XTS  :: [KAT_XTS]+    , kat_AEAD :: [KAT_AEAD]+    } deriving (Show,Eq)++defaultKATs :: KATs+defaultKATs = KATs+    { kat_ECB  = []+    , kat_CBC  = []+    , kat_CTR  = []+    , kat_XTS  = []+    , kat_AEAD = []+    }++testKATs :: BlockCipher cipher => KATs -> cipher -> Test+testKATs kats cipher = testGroup "KAT"+    (   maybeGroup makeECBTest "ECB" (kat_ECB kats)+     ++ maybeGroup makeCBCTest "CBC" (kat_CBC kats)+     ++ maybeGroup makeCTRTest "CTR" (kat_CTR kats)+     ++ maybeGroup makeXTSTest "XTS" (kat_XTS kats)+     ++ maybeGroup makeAEADTest "AEAD" (kat_AEAD kats)+    )+  where makeECBTest i d =+            [ testCase ("E" ++ i) (ecbEncrypt ctx (ecbPlaintext d) @?= ecbCiphertext d)+            , testCase ("D" ++ i) (ecbDecrypt ctx (ecbCiphertext d) @?= ecbPlaintext d)+            ]+          where ctx = cipherInit (cipherMakeKey cipher $ ecbKey d)+        makeCBCTest i d =+            [ testCase ("E" ++ i) (cbcEncrypt ctx iv (cbcPlaintext d) @?= cbcCiphertext d)+            , testCase ("D" ++ i) (cbcDecrypt ctx iv (cbcCiphertext d) @?= cbcPlaintext d)+            ]+          where ctx = cipherInit (cipherMakeKey cipher $ cbcKey d)+                iv  = cipherMakeIV cipher $ cbcIV d+        makeCTRTest i d =+            [ testCase ("E" ++ i) (ctrCombine ctx iv (ctrPlaintext d) @?= ctrCiphertext d)+            , testCase ("D" ++ i) (ctrCombine ctx iv (ctrCiphertext d) @?= ctrPlaintext d)+            ]+          where ctx = cipherInit (cipherMakeKey cipher $ ctrKey d)+                iv  = cipherMakeIV cipher $ ctrIV d+        makeXTSTest i d  =+            [ testCase ("E" ++ i) (xtsEncrypt ctx iv 0 (xtsPlaintext d) @?= xtsCiphertext d)+            , testCase ("D" ++ i) (xtsDecrypt ctx iv 0 (xtsCiphertext d) @?= xtsPlaintext d)+            ]+          where ctx1 = cipherInit (cipherMakeKey cipher $ xtsKey1 d)+                ctx2 = cipherInit (cipherMakeKey cipher $ xtsKey2 d)+                ctx  = (ctx1, ctx2)+                iv   = cipherMakeIV cipher $ xtsIV d+        makeAEADTest i d =+            [ testCase ("AE" ++ i) (etag @?= aeadTag d)+            , testCase ("AD" ++ i) (dtag @?= aeadTag d)+            , testCase ("E" ++ i)  (ebs @?= aeadCiphertext d)+            , testCase ("D" ++ i)  (dbs @?= aeadPlaintext d)+            ]+          where ctx  = cipherInit (cipherMakeKey cipher $ aeadKey d)+                (Just aead) = aeadInit (aeadMode d) ctx (aeadIV d)+                aeadHeaded     = aeadAppendHeader aead (aeadHeader d)+                (ebs,aeadEFinal) = aeadEncrypt aeadHeaded (aeadPlaintext d)+                (dbs,aeadDFinal) = aeadDecrypt aeadHeaded (aeadCiphertext d)+                etag = aeadFinalize aeadEFinal (aeadTaglen d)+                dtag = aeadFinalize aeadDFinal (aeadTaglen d)+               +        maybeGroup mkTest groupName l+            | null l    = []+            | otherwise = [testGroup groupName (concatMap (\(i, d) -> mkTest (show i) d) $ zip nbs l)]+        nbs :: [Int]+        nbs = [0..]+        +        cipherMakeKey :: BlockCipher cipher => cipher -> ByteString -> Key cipher+        cipherMakeKey _ bs = fromJust $ makeKey bs++        cipherMakeIV :: BlockCipher cipher => cipher -> ByteString -> IV cipher+        cipherMakeIV _ bs = fromJust $ makeIV bs
+ Crypto/Cipher/Tests/Properties.hs view
@@ -0,0 +1,144 @@+{-# LANGUAGE ViewPatterns #-}+module Crypto.Cipher.Tests.Properties+    where++import Control.Applicative+import Control.Monad++import Test.Framework (Test, testGroup)+import Test.Framework.Providers.QuickCheck2 (testProperty)+import Test.QuickCheck++import Crypto.Cipher.Types+import qualified Data.ByteString as B+import Data.Byteable+import Data.Maybe++-- | a ECB unit test+data ECBUnit a = ECBUnit (Key a) B.ByteString+    deriving (Eq)++-- | a CBC unit test+data CBCUnit a = CBCUnit (Key a) (IV a) B.ByteString+    deriving (Eq)++-- | a CTR unit test+data CTRUnit a = CTRUnit (Key a) (IV a) B.ByteString+    deriving (Eq)++-- | a XTS unit test+data XTSUnit a = XTSUnit (Key a) (Key a) (IV a) B.ByteString+    deriving (Eq)++-- | a AEAD unit test+data AEADUnit a = AEADUnit (Key a) B.ByteString B.ByteString B.ByteString+    deriving (Eq)++instance Show (ECBUnit a) where+    show (ECBUnit key b) = "ECB(key=" ++ show (toBytes key) ++ ",input=" ++ show b ++ ")"+instance Show (CBCUnit a) where+    show (CBCUnit key iv b) = "CBC(key=" ++ show (toBytes key) ++ ",iv=" ++ show (toBytes iv) ++ ",input=" ++ show b ++ ")"+instance Show (CTRUnit a) where+    show (CTRUnit key iv b) = "CTR(key=" ++ show (toBytes key) ++ ",iv=" ++ show (toBytes iv) ++ ",input=" ++ show b ++ ")"+instance Show (XTSUnit a) where+    show (XTSUnit key1 key2 iv b) = "XTS(key1=" ++ show (toBytes key1) ++ ",key2=" ++ show (toBytes key2) ++ ",iv=" ++ show (toBytes iv) ++ ",input=" ++ show b ++ ")"+instance Show (AEADUnit a) where+    show (AEADUnit key iv aad b) = "AEAD(key=" ++ show (toBytes key) ++ ",iv=" ++ show iv ++ ",aad=" ++ show (toBytes aad) ++ ",input=" ++ show b ++ ")"++generateKey :: BlockCipher a => Gen (Key a)+generateKey = keyFromCipher undefined+  where keyFromCipher :: BlockCipher a => a -> Gen (Key a)+        keyFromCipher cipher = case cipherKeySize cipher of+                                Just sz -> fromJust . makeKey . B.pack <$> replicateM sz arbitrary+                                Nothing -> fromJust . makeKey . B.pack <$> (choose (1,66) >>= \sz -> replicateM sz arbitrary)++generateIv :: BlockCipher a => Gen (IV a)+generateIv = ivFromCipher undefined+  where ivFromCipher :: BlockCipher a => a -> Gen (IV a)+        ivFromCipher cipher = fromJust . makeIV . B.pack <$> replicateM (blockSize cipher) arbitrary++generateIvAEAD :: Gen B.ByteString+generateIvAEAD = choose (12,90) >>= \sz -> (B.pack <$> replicateM sz arbitrary)++generatePlaintextMultiple16 :: Gen B.ByteString+generatePlaintextMultiple16 = choose (1,128) >>= \size -> replicateM (size*16) arbitrary >>= return . B.pack++generatePlaintext :: Gen B.ByteString+generatePlaintext = choose (0,324) >>= \size -> replicateM size arbitrary >>= return . B.pack++instance BlockCipher a => Arbitrary (ECBUnit a) where+    arbitrary = ECBUnit <$> generateKey+                        <*> generatePlaintextMultiple16++instance BlockCipher a => Arbitrary (CBCUnit a) where+    arbitrary = CBCUnit <$> generateKey+                        <*> generateIv+                        <*> generatePlaintextMultiple16++instance BlockCipher a => Arbitrary (CTRUnit a) where+    arbitrary = CTRUnit <$> generateKey+                        <*> generateIv+                        <*> generatePlaintext++instance BlockCipher a => Arbitrary (XTSUnit a) where+    arbitrary = XTSUnit <$> generateKey+                        <*> generateKey+                        <*> generateIv+                        <*> generatePlaintextMultiple16++instance BlockCipher a => Arbitrary (AEADUnit a) where+    arbitrary = AEADUnit <$> generateKey+                         <*> generateIvAEAD+                         <*> generatePlaintext+                         <*> generatePlaintext++testModes :: BlockCipher a => a -> [Test]+testModes cipher =+    [ testGroup "decrypt.encrypt==id"+        [ testProperty "ECB" ecbProp+        , testProperty "CBC" cbcProp+        , 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)+        ]+    ]+  where (ecbProp,cbcProp,ctrProp,xtsProp,aeadProp) = toTests cipher+        toTests :: BlockCipher a+                => a+                -> ((ECBUnit a -> Bool), (CBCUnit a -> Bool), (CTRUnit a -> Bool), (XTSUnit a -> Bool), (AEADMode -> AEADUnit a -> Bool))+        toTests _ = (testProperty_ECB+                    ,testProperty_CBC+                    ,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) =+            plaintext `assertEq` cbcDecrypt ctx testIV (cbcEncrypt ctx testIV plaintext)++        testProperty_CTR (CTRUnit (cipherInit -> ctx) testIV plaintext) =+            plaintext `assertEq` ctrCombine ctx testIV (ctrCombine ctx testIV plaintext)++        testProperty_XTS (XTSUnit (cipherInit -> ctx1) (cipherInit -> ctx2) testIV plaintext) =+            plaintext `assertEq` xtsDecrypt (ctx1, ctx2) testIV 0 (xtsEncrypt (ctx1, ctx2) testIV 0 plaintext)++        testProperty_AEAD mode (AEADUnit (cipherInit -> ctx) testIV aad plaintext) =+            case aeadInit mode ctx testIV of+                Just iniAead ->+                    let aead           = aeadAppendHeader iniAead aad+                        (eText, aeadE) = aeadEncrypt aead plaintext+                        (dText, aeadD) = aeadDecrypt aead eText+                        eTag           = aeadFinalize aeadE (blockSize ctx)+                        dTag           = aeadFinalize aeadD (blockSize ctx)+                     in (plaintext `assertEq` dText) && (toBytes eTag `assertEq` toBytes dTag)+                Nothing -> True++assertEq :: B.ByteString -> B.ByteString -> Bool+assertEq b1 b2 | b1 /= b2  = error ("b1: " ++ show b1 ++ " b2: " ++ show b2)+               | otherwise = True
+ LICENSE view
@@ -0,0 +1,27 @@+Copyright (c) 2013 Vincent Hanquez <vincent@snarc.org>++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met:+1. Redistributions of source code must retain the above copyright+   notice, this list of conditions and the following disclaimer.+2. Redistributions in binary form must reproduce the above copyright+   notice, this list of conditions and the following disclaimer in the+   documentation and/or other materials provided with the distribution.+3. Neither the name of the author nor the names of his contributors+   may be used to endorse or promote products derived from this software+   without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS AS IS'' AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF+SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ crypto-cipher-tests.cabal view
@@ -0,0 +1,36 @@+Name:                crypto-cipher-tests+Version:             0.0.1+Synopsis:            Generic cryptography cipher tests+Description:         Generic cryptography cipher tests+License:             BSD3+License-file:        LICENSE+Copyright:           Vincent Hanquez <vincent@snarc.org>+Author:              Vincent Hanquez <vincent@snarc.org>+Maintainer:          vincent@snarc.org+Category:            Cryptography+Stability:           experimental+Build-Type:          Simple+Homepage:            http://github.com/vincenthz/hs-crypto-cipher+Cabal-Version:       >=1.8++Library+  Exposed-modules:   Crypto.Cipher.Tests+  Other-modules:     Crypto.Cipher.Tests.KATs+                     Crypto.Cipher.Tests.Properties+  Build-depends:     base >= 3 && < 5+                   , QuickCheck >= 2+                   , mtl+                   , HUnit+                   , test-framework+                   , test-framework-quickcheck2+                   , test-framework-hunit+                   , bytestring+                   , byteable >= 0.1.1+                   , securemem >= 0.1.1+                   , crypto-cipher-types+  ghc-options:       -Wall -fwarn-tabs++source-repository head+  type: git+  location: git://github.com/vincenthz/hs-crypto-cipher+  subdir: tests