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