1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
|
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
-- | Test vectors from RFC 3217.
module KeyWrap.RC2 (rc2kwTests) where
import Data.ByteString (ByteString)
import qualified Data.ByteString as B
import Crypto.Cipher.Types
import Crypto.Error
import Test.Tasty
import Test.Tasty.HUnit
import Test.Tasty.QuickCheck
import Crypto.Store.Cipher.RC2
import Crypto.Store.Error
import Crypto.Store.KeyWrap.RC2
import X509.Instances () -- for instance MonadRandom Gen
import Util
newtype Message = Message ByteString deriving (Show, Eq)
instance Arbitrary Message where
arbitrary = Message . B.pack <$> (choose (0, 255) >>= vector)
data Vector = Vector
{ vecEKL :: Int
, vecKey :: ByteString
, vecPad :: ByteString
, vecIV :: ByteString
, vecPlaintext :: ByteString
, vecCiphertext :: ByteString
}
vectors :: [Vector]
vectors =
[ Vector
{ vecEKL = 40
, vecKey = "\xfd\x04\xfd\x08\x06\x07\x07\xfb\x00\x03\xfe\xff\xfd\x02\xfe\x05"
, vecPad = "\x48\x45\xcc\xe7\xfd\x12\x50"
, vecIV = "\xc7\xd9\x00\x59\xb2\x9e\x97\xf7"
, vecPlaintext = "\xb7\x0a\x25\xfb\xc9\xd8\x6a\x86\x05\x0c\xe0\xd7\x11\xea\xd4\xd9"
, vecCiphertext = "\x70\xe6\x99\xfb\x57\x01\xf7\x83\x33\x30\xfb\x71\xe8\x7c\x85\xa4\x20\xbd\xc9\x9a\xf0\x5d\x22\xaf\x5a\x0e\x48\xd3\x5f\x31\x38\x98\x6c\xba\xaf\xb4\xb2\x8d\x4f\x35"
}
, Vector
{ vecEKL = 128 -- from RFC Errata
, vecKey = "\xfd\x04\xfd\x08\x06\x07\x07\xfb\x00\x03\xfe\xff\xfd\x02\xfe\x05"
, vecPad = "\x48\x45\xcc\xe7\xfd\x12\x50"
, vecIV = "\xc7\xd9\x00\x59\xb2\x9e\x97\xf7"
, vecPlaintext = "\xb7\x0a\x25\xfb\xc9\xd8\x6a\x86\x05\x0c\xe0\xd7\x11\xea\xd4\xd9"
, vecCiphertext = "\xf4\xd8\x02\x1c\x1e\xa4\x63\xd2\x17\xa9\xeb\x69\x29\xff\xa5\x77\x36\xd3\xe2\x03\x86\xc9\x09\x93\x83\x5b\x4b\xe4\xad\x8d\x8a\x1b\xc6\x3b\x25\xde\x2b\xf7\x79\x93"
}
]
rc2kwTests :: TestTree
rc2kwTests =
testGroup "KeyWrap.RC2"
[ testGroup "properties"
[ testProperty "unwrap . wrap == id" wrapUnwrapProperty
]
, testGroup "vectors" (zipWith makeTest [1..] vectors)
]
where
initCipher :: Int -> ByteString -> RC2
initCipher ekl k = throwCryptoError (rc2WithEffectiveKeyLength ekl k)
wrapUnwrapProperty :: TestKey RC2 -> TestIV RC2 -> Message -> Gen Property
wrapUnwrapProperty (Key key) (IV ivBs) (Message msg) = do
ekl <- choose (1, 1024)
let ctx = initCipher ekl key
wrapped <- wrap ctx iv msg
return $ (wrapped >>= unwrap ctx) === Right msg
where Just iv = makeIV ivBs
makeTest :: Integer -> Vector -> TestTree
makeTest i Vector{..} =
testGroup (show i)
[ testCase "Wrap" (doWrap ctx iv vecPlaintext @?= Right vecCiphertext)
, testCase "Unwrap" (unwrap ctx vecCiphertext @?= Right vecPlaintext)
]
where ctx = initCipher vecEKL vecKey
Just iv = makeIV vecIV
doWrap = wrap' Left withRandomPad
withRandomPad f len
| B.length vecPad /= len = Left (InvalidInput "unexpected length")
| otherwise = Right (f vecPad)
|