-- | -- Module : Crypto.Cipher.TripleDES -- License : BSD-style -- Stability : experimental -- Portability : ??? module Crypto.Cipher.TripleDES ( DES_EEE3 , DES_EDE3 , DES_EEE2 , DES_EDE2 ) where import Data.Word import Crypto.Error import Crypto.Cipher.Types import Crypto.Cipher.DES.Primitive import Crypto.Internal.ByteArray (ByteArrayAccess) import qualified Crypto.Internal.ByteArray as B import Data.Memory.Endian -- | 3DES with 3 different keys used all in the same direction data DES_EEE3 = DES_EEE3 Word64 Word64 Word64 deriving (Eq) -- | 3DES with 3 different keys used in alternative direction data DES_EDE3 = DES_EDE3 Word64 Word64 Word64 deriving (Eq) -- | 3DES where the first and third keys are equal, used in the same direction data DES_EEE2 = DES_EEE2 Word64 Word64 -- key1 and key3 are equal deriving (Eq) -- | 3DES where the first and third keys are equal, used in alternative direction data DES_EDE2 = DES_EDE2 Word64 Word64 -- key1 and key3 are equal deriving (Eq) instance Cipher DES_EEE3 where cipherName _ = "3DES_EEE" cipherKeySize _ = KeySizeFixed 24 cipherInit k = init3DES DES_EEE3 k instance Cipher DES_EDE3 where cipherName _ = "3DES_EDE" cipherKeySize _ = KeySizeFixed 24 cipherInit k = init3DES DES_EDE3 k instance Cipher DES_EDE2 where cipherName _ = "2DES_EDE" cipherKeySize _ = KeySizeFixed 16 cipherInit k = init2DES DES_EDE2 k instance Cipher DES_EEE2 where cipherName _ = "2DES_EEE" cipherKeySize _ = KeySizeFixed 16 cipherInit k = init2DES DES_EEE2 k instance BlockCipher DES_EEE3 where blockSize _ = 8 ecbEncrypt (DES_EEE3 k1 k2 k3) = B.mapAsWord64 (unBlock . (encrypt k3 . encrypt k2 . encrypt k1) . Block) ecbDecrypt (DES_EEE3 k1 k2 k3) = B.mapAsWord64 (unBlock . (decrypt k1 . decrypt k2 . decrypt k3) . Block) instance BlockCipher DES_EDE3 where blockSize _ = 8 ecbEncrypt (DES_EDE3 k1 k2 k3) = B.mapAsWord64 (unBlock . (encrypt k3 . decrypt k2 . encrypt k1) . Block) ecbDecrypt (DES_EDE3 k1 k2 k3) = B.mapAsWord64 (unBlock . (decrypt k1 . encrypt k2 . decrypt k3) . Block) instance BlockCipher DES_EEE2 where blockSize _ = 8 ecbEncrypt (DES_EEE2 k1 k2) = B.mapAsWord64 (unBlock . (encrypt k1 . encrypt k2 . encrypt k1) . Block) ecbDecrypt (DES_EEE2 k1 k2) = B.mapAsWord64 (unBlock . (decrypt k1 . decrypt k2 . decrypt k1) . Block) instance BlockCipher DES_EDE2 where blockSize _ = 8 ecbEncrypt (DES_EDE2 k1 k2) = B.mapAsWord64 (unBlock . (encrypt k1 . decrypt k2 . encrypt k1) . Block) ecbDecrypt (DES_EDE2 k1 k2) = B.mapAsWord64 (unBlock . (decrypt k1 . encrypt k2 . decrypt k1) . Block) init3DES :: ByteArrayAccess key => (Word64 -> Word64 -> Word64 -> a) -> key -> CryptoFailable a init3DES constr k | len == 24 = CryptoPassed $ constr k1 k2 k3 | otherwise = CryptoFailed CryptoError_KeySizeInvalid where len = B.length k (k1, k2, k3) = (fromBE $ B.toW64BE k 0, fromBE $ B.toW64BE k 8, fromBE $ B.toW64BE k 16) init2DES :: ByteArrayAccess key => (Word64 -> Word64 -> a) -> key -> CryptoFailable a init2DES constr k | len == 16 = CryptoPassed $ constr k1 k2 | otherwise = CryptoFailed CryptoError_KeySizeInvalid where len = B.length k (k1, k2) = (fromBE $ B.toW64BE k 0, fromBE $ B.toW64BE k 8)