diff --git a/automotive-cse.cabal b/automotive-cse.cabal
--- a/automotive-cse.cabal
+++ b/automotive-cse.cabal
@@ -1,6 +1,6 @@
 
 name:                automotive-cse
-version:             0.1.4.0
+version:             0.1.5.0
 synopsis:            Automotive CSE emulation
 description:         This package includes Cryptography Security Engine (CSE)
                      codec emulation for automotive things.
diff --git a/src/Codec/Automotive/CSE/Internal.hs b/src/Codec/Automotive/CSE/Internal.hs
--- a/src/Codec/Automotive/CSE/Internal.hs
+++ b/src/Codec/Automotive/CSE/Internal.hs
@@ -1,8 +1,8 @@
 
 -- CSE (Cryptographic Service Engine) emulation implementation
 module Codec.Automotive.CSE.Internal (
-  M1, unM1, makeM1, extractM1,
-  M2, unM2, makeM2, extractM2,
+  M1, unM1, makeM1, extractM1, refineM1,
+  M2, unM2, makeM2, extractM2, refineM2,
   M3, unM3, makeM3,
   M4, unM4, makeM4, extractM4, makeM4', extractM4',
   M5, unM5, makeM5,
@@ -187,15 +187,15 @@
 instance Show M1 where
   show (M1 s) = unwords ["M1", hdump s]
 
+unM1 :: M1 -> ByteString
+unM1 (M1 m1) = m1
+
 makeM1 :: UID        -- ^ UID          - 15 octet
        -> Word8      -- ^ Key ID       -  4 bit
        -> Word8      -- ^ Auth key ID  -  4 bit
        -> M1
 makeM1 uid kid akid = M1 $ unUID uid <> BS.singleton (kid `shiftL` 4 .|. akid)
 
-unM1 :: M1 -> ByteString
-unM1 (M1 m1) = m1
-
 extractM1 :: M1 -> (UID, Word8, Word8)
 extractM1 (M1 m1) = (UID $ Short.toShort uid, lw `shiftR` 4, lw .&. 0x0F)
   where
@@ -203,11 +203,21 @@
     lw = head $ BS.unpack x
     -- assume refined M1
 
+refineM1 :: MonadPlus m => ByteString -> m (M1, (UID, Word8, Word8))
+refineM1 s = do
+  let m1 = M1 s
+      ps@(uid, kid, akid) = extractM1 m1
+  guard $ makeM1 uid kid akid == m1
+  return (m1, ps)
+
 newtype M2 = M2 ByteString deriving Eq
 
 instance Show M2 where
   show (M2 s) = unwords ["M2", hdump s]
 
+unM2 :: M2 -> ByteString
+unM2 (M2 m2) = m2
+
 makeM2 :: K1                 -- ^ K1 value
        -> Word32             -- ^ Counter   - 28 bit
        -> Word8              -- ^ Key Flag  -  6 bit
@@ -224,9 +234,6 @@
                 putWord64be 0)
             <> unKeyAuthUse keyData
 
-unM2 :: M2 -> ByteString
-unM2 (M2 m2) = m2
-
 extractM2 :: K1
           -> M2
           -> (Word32, Word8, KeyAuthUse NotAuth)
@@ -239,25 +246,39 @@
     b64 = either (error . ("extractM2: " ++)) id $ runGet getWord64be dbits
     key =  maybe (error "extractM2: wrong M2 length?") id $ makeKeyAuthUse rawKey
 
+refineM2 :: MonadPlus m
+         => K1
+         -> ByteString
+         -> m (M2, (Word32, Word8, KeyAuthUse NotAuth))
+refineM2 k1 s = do
+  guard $ BS.length s == 32
+  let m2 = M2 s
+      ps@(counter, flags, key) = extractM2 k1 m2
+  guard $ makeM2 k1 counter flags key == m2
+  return (m2, ps)
+
 newtype M3 = M3 ByteString deriving Eq
 
 instance Show M3 where
   show (M3 s) = unwords ["M3", hdump s]
 
+unM3 :: M3 -> ByteString
+unM3 (M3 m3) = m3
+
 makeM3 :: K2
        -> M1
        -> M2
        -> M3
 makeM3 (DerivedCipher k2) (M1 m1) (M2 m2) = M3 . B.convert . cmacGetBytes . cmac k2 $ m1 <> m2
 
-unM3 :: M3 -> ByteString
-unM3 (M3 m3) = m3
-
 newtype M4 = M4 ByteString deriving Eq
 
 instance Show M4 where
   show (M4 s) = unwords ["M4", hdump s]
 
+unM4 :: M4 -> ByteString
+unM4 (M4 m4) = m4
+
 makeM4' :: K3
         -> M1
         -> Word32
@@ -280,9 +301,6 @@
 makeM4 k3 uid kid akid counter =
   makeM4' k3 (makeM1 uid kid akid) counter
 
-unM4 :: M4 -> ByteString
-unM4 (M4 m4) = m4
-
 extractM4' :: K3 -> M4 -> (M1, Word32)
 extractM4' (DerivedCipher k3) (M4 m4) = (M1 m1, fromIntegral $ w64 `shiftR` 36)
   where
@@ -299,10 +317,10 @@
 instance Show M5 where
   show (M5 s) = unwords ["M5", hdump s]
 
+unM5 :: M5 -> ByteString
+unM5 (M5 m4) = m4
+
 makeM5 :: K4
        -> M4
        -> M5
 makeM5 (DerivedCipher k4) (M4 m4) = M5 . B.convert . cmacGetBytes $ cmac k4 m4
-
-unM5 :: M5 -> ByteString
-unM5 (M5 m4) = m4
diff --git a/test/Iso.hs b/test/Iso.hs
--- a/test/Iso.hs
+++ b/test/Iso.hs
@@ -7,8 +7,8 @@
 import Test.QuickCheck (Arbitrary (..), choose)
 
 import Codec.Automotive.CSE
-  (UID, makeUID, M1, makeM1, extractM1, M2, makeM2, extractM2, M4, makeM4, extractM4,
-   KeyAuthUse, makeKeyAuthUse, derivedCipher, K1, K1', makeK1, K3, K3', makeK3)
+  (UID, makeUID, KeyAuthUse, makeKeyAuthUse, derivedCipher, K1, K1', makeK1, K3, K3', makeK3,
+   M1, unM1, makeM1, extractM1, refineM1, M2, unM2, makeM2, extractM2, refineM2, M4, makeM4, extractM4)
 
 import Control.Applicative ((<$>), (<*>))
 import Control.Monad (replicateM)
@@ -34,12 +34,18 @@
 instance Arbitrary K3' where
   arbitrary = makeK3 <$> arbitrary
 
-instance Arbitrary M1 where
+newtype GenM1 = GenM1 M1
+
+instance Show GenM1 where
+  show (GenM1 m1) = unwords ["GenM1", show m1]
+
+instance Arbitrary GenM1 where
   arbitrary =
-    makeM1
-    <$> arbitrary
-    <*> (unKeyID <$> arbitrary)
-    <*> (unKeyID <$> arbitrary)
+    GenM1
+    <$> (makeM1
+         <$> arbitrary
+         <*> (unKeyID <$> arbitrary)
+         <*> (unKeyID <$> arbitrary))
 
 newtype GenM2 = GenM2 (K1 -> M2)
 
@@ -66,16 +72,26 @@
     c     <-  choose (0, 2^(28 :: Int) - 1)
     return . GenM4 $ \k3 -> makeM4 k3 uid kid akid c
 
-isoM1 :: M1 -> Bool
-isoM1 m1 = makeM1 uid kid akid == m1
+isoM1 :: GenM1 -> Bool
+isoM1 (GenM1 m1) = makeM1 uid kid akid == m1
   where (uid, kid, akid) = extractM1 m1
 
+isoRefineM1 :: GenM1 -> Bool
+isoRefineM1 (GenM1 m1) = refineM1 (unM1 m1) == Just (m1, t)
+  where t = extractM1 m1
+
 isoM2 :: K1' -> GenM2 -> Bool
 isoM2 k1' (GenM2 g) = makeM2 k1 c f key == m2
   where (c, f, key) = extractM2 k1 m2
         k1 = derivedCipher k1'
         m2 = g k1
 
+isoRefineM2 :: K1' -> GenM2 -> Bool
+isoRefineM2 k1' (GenM2 g) = refineM2 k1 (unM2 m2) == Just (m2, t)
+  where t = extractM2 k1 m2
+        k1 = derivedCipher k1'
+        m2 = g k1
+
 isoM4 :: K3' -> GenM4 -> Bool
 isoM4 k3' (GenM4 g) = makeM4 k3 uid kid akid c == m4
   where ((uid, kid, akid), c) = extractM4 k3 m4
@@ -85,6 +101,8 @@
 tests :: [Test]
 tests =
   [ qcTest "iso - M1 extract make" isoM1
+  , qcTest "iso - M1 refine extract" isoRefineM1
   , qcTest "iso - M2 extract make" isoM2
+  , qcTest "iso - M2 refine extract" isoRefineM2
   , qcTest "iso - M4 extract make" isoM4
   ]
diff --git a/test/TestVector.hs b/test/TestVector.hs
--- a/test/TestVector.hs
+++ b/test/TestVector.hs
@@ -4,13 +4,13 @@
 
 import Codec.Automotive.CSE
   (M1, unM1, makeM1, extractM1,
-   M2, unM2, makeM2,
+   M2, unM2, makeM2, extractM2,
    M3, unM3, makeM3,
    M4, unM4, makeM4, extractM4,
    M5, unM5, makeM5,
    UID, makeUID,
    KeyAuthUse, Auth, NotAuth, makeKeyAuthUse, derivedCipher,
-   K3, makeK1, makeK2, makeK3, makeK4)
+   K1, K3, makeK1, makeK2, makeK3, makeK4)
 
 import Numeric (showHex, showInt)
 import Data.Maybe (fromJust)
@@ -59,14 +59,20 @@
 expectE1 :: Bool
 expectE1 = extractM1 testM1 == (testUID, testKeyID, testAuthKeyID)
 
+testK1 :: K1
+testK1 = derivedCipher $ makeK1 testAuthKey
+
 testM2 :: M2
 testM2 =
-  makeM2 (derivedCipher $ makeK1 testAuthKey) testCounter testFlags testKey
+  makeM2 testK1 testCounter testFlags testKey
 
 expectM2 :: Bool
 expectM2 =
   unM2 testM2 == hxs "2b111e2d93f486566bcbba1d7f7a9797_c94643b050fc5d4d7de14cff682203c3"
 
+expectE2 :: Bool
+expectE2 = extractM2 testK1 testM2 == (testCounter, testFlags, testKey)
+
 testM3 :: M3
 testM3 =
   makeM3 (derivedCipher $ makeK2 testAuthKey) testM1 testM2
@@ -121,6 +127,7 @@
 tests = [ boolTest "M1" expectM1
         , boolTest "extract M1" expectE1
         , boolTest "M2" expectM2
+        , boolTest "extract M2" expectE2
         , boolTest "M3" expectM3
         , boolTest "M4" expectM4
         , boolTest "extract M4" expectE4
