import Test.QuickCheck.Simple (Test, boolTest, defaultMain) import Codec.Automotive.CSE (M1(M1), makeM1, M2(M2), makeM2, M3(M3), makeM3, M4(M4), makeM4, M5(M5), makeM5, KeyAuthUse (..), Auth, NotAuth, derivedCipher, makeK1, makeK2, makeK3, makeK4) import Numeric (showHex, showInt) import Data.ByteString (ByteString) import qualified Data.ByteString as BS import Data.Char (digitToInt) import Data.Word (Word8, Word32) import Crypto.Error (CryptoError) testAuthKey :: KeyAuthUse Auth testAuthKey = KeyAuthUse $ hxs "00010203_04050607_08090a0b_0c0d0e0f" testKey :: KeyAuthUse NotAuth testKey = KeyAuthUse $ hxs "0f0e0d0c_0b0a0908_07060504_03020100" testAuthKeyID :: Word8 testAuthKeyID = 1 testKeyID :: Word8 testKeyID = 4 testUID :: ByteString testUID = hxs "000000000000000000000000000001" testCounter :: Word32 testCounter = 1 testFlags :: Word8 testFlags = 0 testM1 :: M1 testM1 = makeM1 testUID testKeyID testAuthKeyID expectM1 :: Bool expectM1 = testM1 == M1 (hxs "00000000000000000000000000000141") testM2 :: Either CryptoError M2 testM2 = do k1 <- derivedCipher $ makeK1 testAuthKey return $ makeM2 k1 testCounter testFlags testKey expectM2 :: Bool expectM2 = testM2 == Right (M2 $ hxs "2b111e2d93f486566bcbba1d7f7a9797_c94643b050fc5d4d7de14cff682203c3") testM3 :: Either CryptoError M3 testM3 = do k2 <- derivedCipher $ makeK2 testAuthKey m2 <- testM2 return $ makeM3 k2 testM1 m2 expectM3 :: Bool expectM3 = testM3 == Right (M3 $ hxs "b9d745e5ace7d41860bc63c2b9f5bb46") testM4 :: Either CryptoError M4 testM4 = do k3 <- derivedCipher $ makeK3 testKey return $ makeM4 testUID testKeyID testAuthKeyID k3 testCounter expectM4 :: Bool expectM4 = testM4 == Right (M4 $ hxs "00000000000000000000000000000141_b472e8d8727d70d57295e74849a27917") testM5 :: Either CryptoError M5 testM5 = do k4 <- derivedCipher $ makeK4 testKey m4 <- testM4 return $ makeM5 k4 m4 expectM5 :: Bool expectM5 = testM5 == Right (M5 $ hxs "820d8d95dc11b4668878160cb2a4e23e") hxs :: String -> ByteString hxs = BS.pack . rec' where dtoW8 = fromIntegral . digitToInt rec' (' ':xs) = rec' xs rec' ('_':xs) = rec' xs rec' (x:y:xs) = dtoW8 x * 16 + dtoW8 y : rec' xs rec' [_] = error "hxs: invalid hex pattern." rec' [] = [] _dump :: ByteString -> String _dump = (`rec'` []) . BS.unpack where rec' [] = id rec' (w:ws) = (if w < 16 then ('0' :) . showHex w else showHex w) . rec' ws _dumpD :: ByteString -> String _dumpD = (`rec'` []) . BS.unpack where rec' [] = id rec' (w:ws) = showInt w . ("," ++) . rec' ws tests :: [Test] tests = [ boolTest "M1" expectM1 , boolTest "M2" expectM2 , boolTest "M3" expectM3 , boolTest "M4" expectM4 , boolTest "M5" expectM5 ] main :: IO () main = defaultMain tests