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
data DES_EEE3 = DES_EEE3 Word64 Word64 Word64
deriving (DES_EEE3 -> DES_EEE3 -> Bool
(DES_EEE3 -> DES_EEE3 -> Bool)
-> (DES_EEE3 -> DES_EEE3 -> Bool) -> Eq DES_EEE3
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DES_EEE3 -> DES_EEE3 -> Bool
$c/= :: DES_EEE3 -> DES_EEE3 -> Bool
== :: DES_EEE3 -> DES_EEE3 -> Bool
$c== :: DES_EEE3 -> DES_EEE3 -> Bool
Eq)
data DES_EDE3 = DES_EDE3 Word64 Word64 Word64
deriving (DES_EDE3 -> DES_EDE3 -> Bool
(DES_EDE3 -> DES_EDE3 -> Bool)
-> (DES_EDE3 -> DES_EDE3 -> Bool) -> Eq DES_EDE3
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DES_EDE3 -> DES_EDE3 -> Bool
$c/= :: DES_EDE3 -> DES_EDE3 -> Bool
== :: DES_EDE3 -> DES_EDE3 -> Bool
$c== :: DES_EDE3 -> DES_EDE3 -> Bool
Eq)
data DES_EEE2 = DES_EEE2 Word64 Word64
deriving (DES_EEE2 -> DES_EEE2 -> Bool
(DES_EEE2 -> DES_EEE2 -> Bool)
-> (DES_EEE2 -> DES_EEE2 -> Bool) -> Eq DES_EEE2
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DES_EEE2 -> DES_EEE2 -> Bool
$c/= :: DES_EEE2 -> DES_EEE2 -> Bool
== :: DES_EEE2 -> DES_EEE2 -> Bool
$c== :: DES_EEE2 -> DES_EEE2 -> Bool
Eq)
data DES_EDE2 = DES_EDE2 Word64 Word64
deriving (DES_EDE2 -> DES_EDE2 -> Bool
(DES_EDE2 -> DES_EDE2 -> Bool)
-> (DES_EDE2 -> DES_EDE2 -> Bool) -> Eq DES_EDE2
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DES_EDE2 -> DES_EDE2 -> Bool
$c/= :: DES_EDE2 -> DES_EDE2 -> Bool
== :: DES_EDE2 -> DES_EDE2 -> Bool
$c== :: DES_EDE2 -> DES_EDE2 -> Bool
Eq)
instance Cipher DES_EEE3 where
cipherName :: DES_EEE3 -> String
cipherName DES_EEE3
_ = String
"3DES_EEE"
cipherKeySize :: DES_EEE3 -> KeySizeSpecifier
cipherKeySize DES_EEE3
_ = Int -> KeySizeSpecifier
KeySizeFixed Int
24
cipherInit :: key -> CryptoFailable DES_EEE3
cipherInit key
k = (Word64 -> Word64 -> Word64 -> DES_EEE3)
-> key -> CryptoFailable DES_EEE3
forall key a.
ByteArrayAccess key =>
(Word64 -> Word64 -> Word64 -> a) -> key -> CryptoFailable a
init3DES Word64 -> Word64 -> Word64 -> DES_EEE3
DES_EEE3 key
k
instance Cipher DES_EDE3 where
cipherName :: DES_EDE3 -> String
cipherName DES_EDE3
_ = String
"3DES_EDE"
cipherKeySize :: DES_EDE3 -> KeySizeSpecifier
cipherKeySize DES_EDE3
_ = Int -> KeySizeSpecifier
KeySizeFixed Int
24
cipherInit :: key -> CryptoFailable DES_EDE3
cipherInit key
k = (Word64 -> Word64 -> Word64 -> DES_EDE3)
-> key -> CryptoFailable DES_EDE3
forall key a.
ByteArrayAccess key =>
(Word64 -> Word64 -> Word64 -> a) -> key -> CryptoFailable a
init3DES Word64 -> Word64 -> Word64 -> DES_EDE3
DES_EDE3 key
k
instance Cipher DES_EDE2 where
cipherName :: DES_EDE2 -> String
cipherName DES_EDE2
_ = String
"2DES_EDE"
cipherKeySize :: DES_EDE2 -> KeySizeSpecifier
cipherKeySize DES_EDE2
_ = Int -> KeySizeSpecifier
KeySizeFixed Int
16
cipherInit :: key -> CryptoFailable DES_EDE2
cipherInit key
k = (Word64 -> Word64 -> DES_EDE2) -> key -> CryptoFailable DES_EDE2
forall key a.
ByteArrayAccess key =>
(Word64 -> Word64 -> a) -> key -> CryptoFailable a
init2DES Word64 -> Word64 -> DES_EDE2
DES_EDE2 key
k
instance Cipher DES_EEE2 where
cipherName :: DES_EEE2 -> String
cipherName DES_EEE2
_ = String
"2DES_EEE"
cipherKeySize :: DES_EEE2 -> KeySizeSpecifier
cipherKeySize DES_EEE2
_ = Int -> KeySizeSpecifier
KeySizeFixed Int
16
cipherInit :: key -> CryptoFailable DES_EEE2
cipherInit key
k = (Word64 -> Word64 -> DES_EEE2) -> key -> CryptoFailable DES_EEE2
forall key a.
ByteArrayAccess key =>
(Word64 -> Word64 -> a) -> key -> CryptoFailable a
init2DES Word64 -> Word64 -> DES_EEE2
DES_EEE2 key
k
instance BlockCipher DES_EEE3 where
blockSize :: DES_EEE3 -> Int
blockSize DES_EEE3
_ = Int
8
ecbEncrypt :: DES_EEE3 -> ba -> ba
ecbEncrypt (DES_EEE3 Word64
k1 Word64
k2 Word64
k3) = (Word64 -> Word64) -> ba -> ba
forall bs. ByteArray bs => (Word64 -> Word64) -> bs -> bs
B.mapAsWord64 (Block -> Word64
unBlock (Block -> Word64) -> (Word64 -> Block) -> Word64 -> Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word64 -> Block -> Block
encrypt Word64
k3 (Block -> Block) -> (Block -> Block) -> Block -> Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Block -> Block
encrypt Word64
k2 (Block -> Block) -> (Block -> Block) -> Block -> Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Block -> Block
encrypt Word64
k1) (Block -> Block) -> (Word64 -> Block) -> Word64 -> Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Block
Block)
ecbDecrypt :: DES_EEE3 -> ba -> ba
ecbDecrypt (DES_EEE3 Word64
k1 Word64
k2 Word64
k3) = (Word64 -> Word64) -> ba -> ba
forall bs. ByteArray bs => (Word64 -> Word64) -> bs -> bs
B.mapAsWord64 (Block -> Word64
unBlock (Block -> Word64) -> (Word64 -> Block) -> Word64 -> Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word64 -> Block -> Block
decrypt Word64
k1 (Block -> Block) -> (Block -> Block) -> Block -> Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Block -> Block
decrypt Word64
k2 (Block -> Block) -> (Block -> Block) -> Block -> Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Block -> Block
decrypt Word64
k3) (Block -> Block) -> (Word64 -> Block) -> Word64 -> Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Block
Block)
instance BlockCipher DES_EDE3 where
blockSize :: DES_EDE3 -> Int
blockSize DES_EDE3
_ = Int
8
ecbEncrypt :: DES_EDE3 -> ba -> ba
ecbEncrypt (DES_EDE3 Word64
k1 Word64
k2 Word64
k3) = (Word64 -> Word64) -> ba -> ba
forall bs. ByteArray bs => (Word64 -> Word64) -> bs -> bs
B.mapAsWord64 (Block -> Word64
unBlock (Block -> Word64) -> (Word64 -> Block) -> Word64 -> Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word64 -> Block -> Block
encrypt Word64
k3 (Block -> Block) -> (Block -> Block) -> Block -> Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Block -> Block
decrypt Word64
k2 (Block -> Block) -> (Block -> Block) -> Block -> Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Block -> Block
encrypt Word64
k1) (Block -> Block) -> (Word64 -> Block) -> Word64 -> Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Block
Block)
ecbDecrypt :: DES_EDE3 -> ba -> ba
ecbDecrypt (DES_EDE3 Word64
k1 Word64
k2 Word64
k3) = (Word64 -> Word64) -> ba -> ba
forall bs. ByteArray bs => (Word64 -> Word64) -> bs -> bs
B.mapAsWord64 (Block -> Word64
unBlock (Block -> Word64) -> (Word64 -> Block) -> Word64 -> Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word64 -> Block -> Block
decrypt Word64
k1 (Block -> Block) -> (Block -> Block) -> Block -> Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Block -> Block
encrypt Word64
k2 (Block -> Block) -> (Block -> Block) -> Block -> Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Block -> Block
decrypt Word64
k3) (Block -> Block) -> (Word64 -> Block) -> Word64 -> Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Block
Block)
instance BlockCipher DES_EEE2 where
blockSize :: DES_EEE2 -> Int
blockSize DES_EEE2
_ = Int
8
ecbEncrypt :: DES_EEE2 -> ba -> ba
ecbEncrypt (DES_EEE2 Word64
k1 Word64
k2) = (Word64 -> Word64) -> ba -> ba
forall bs. ByteArray bs => (Word64 -> Word64) -> bs -> bs
B.mapAsWord64 (Block -> Word64
unBlock (Block -> Word64) -> (Word64 -> Block) -> Word64 -> Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word64 -> Block -> Block
encrypt Word64
k1 (Block -> Block) -> (Block -> Block) -> Block -> Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Block -> Block
encrypt Word64
k2 (Block -> Block) -> (Block -> Block) -> Block -> Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Block -> Block
encrypt Word64
k1) (Block -> Block) -> (Word64 -> Block) -> Word64 -> Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Block
Block)
ecbDecrypt :: DES_EEE2 -> ba -> ba
ecbDecrypt (DES_EEE2 Word64
k1 Word64
k2) = (Word64 -> Word64) -> ba -> ba
forall bs. ByteArray bs => (Word64 -> Word64) -> bs -> bs
B.mapAsWord64 (Block -> Word64
unBlock (Block -> Word64) -> (Word64 -> Block) -> Word64 -> Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word64 -> Block -> Block
decrypt Word64
k1 (Block -> Block) -> (Block -> Block) -> Block -> Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Block -> Block
decrypt Word64
k2 (Block -> Block) -> (Block -> Block) -> Block -> Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Block -> Block
decrypt Word64
k1) (Block -> Block) -> (Word64 -> Block) -> Word64 -> Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Block
Block)
instance BlockCipher DES_EDE2 where
blockSize :: DES_EDE2 -> Int
blockSize DES_EDE2
_ = Int
8
ecbEncrypt :: DES_EDE2 -> ba -> ba
ecbEncrypt (DES_EDE2 Word64
k1 Word64
k2) = (Word64 -> Word64) -> ba -> ba
forall bs. ByteArray bs => (Word64 -> Word64) -> bs -> bs
B.mapAsWord64 (Block -> Word64
unBlock (Block -> Word64) -> (Word64 -> Block) -> Word64 -> Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word64 -> Block -> Block
encrypt Word64
k1 (Block -> Block) -> (Block -> Block) -> Block -> Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Block -> Block
decrypt Word64
k2 (Block -> Block) -> (Block -> Block) -> Block -> Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Block -> Block
encrypt Word64
k1) (Block -> Block) -> (Word64 -> Block) -> Word64 -> Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Block
Block)
ecbDecrypt :: DES_EDE2 -> ba -> ba
ecbDecrypt (DES_EDE2 Word64
k1 Word64
k2) = (Word64 -> Word64) -> ba -> ba
forall bs. ByteArray bs => (Word64 -> Word64) -> bs -> bs
B.mapAsWord64 (Block -> Word64
unBlock (Block -> Word64) -> (Word64 -> Block) -> Word64 -> Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word64 -> Block -> Block
decrypt Word64
k1 (Block -> Block) -> (Block -> Block) -> Block -> Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Block -> Block
encrypt Word64
k2 (Block -> Block) -> (Block -> Block) -> Block -> Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Block -> Block
decrypt Word64
k1) (Block -> Block) -> (Word64 -> Block) -> Word64 -> Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Block
Block)
init3DES :: ByteArrayAccess key => (Word64 -> Word64 -> Word64 -> a) -> key -> CryptoFailable a
init3DES :: (Word64 -> Word64 -> Word64 -> a) -> key -> CryptoFailable a
init3DES Word64 -> Word64 -> Word64 -> a
constr key
k
| Int
len Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
24 = a -> CryptoFailable a
forall a. a -> CryptoFailable a
CryptoPassed (a -> CryptoFailable a) -> a -> CryptoFailable a
forall a b. (a -> b) -> a -> b
$ Word64 -> Word64 -> Word64 -> a
constr Word64
k1 Word64
k2 Word64
k3
| Bool
otherwise = CryptoError -> CryptoFailable a
forall a. CryptoError -> CryptoFailable a
CryptoFailed CryptoError
CryptoError_KeySizeInvalid
where len :: Int
len = key -> Int
forall ba. ByteArrayAccess ba => ba -> Int
B.length key
k
(Word64
k1, Word64
k2, Word64
k3) = (BE Word64 -> Word64
forall a. ByteSwap a => BE a -> a
fromBE (BE Word64 -> Word64) -> BE Word64 -> Word64
forall a b. (a -> b) -> a -> b
$ key -> Int -> BE Word64
forall bs. ByteArrayAccess bs => bs -> Int -> BE Word64
B.toW64BE key
k Int
0, BE Word64 -> Word64
forall a. ByteSwap a => BE a -> a
fromBE (BE Word64 -> Word64) -> BE Word64 -> Word64
forall a b. (a -> b) -> a -> b
$ key -> Int -> BE Word64
forall bs. ByteArrayAccess bs => bs -> Int -> BE Word64
B.toW64BE key
k Int
8, BE Word64 -> Word64
forall a. ByteSwap a => BE a -> a
fromBE (BE Word64 -> Word64) -> BE Word64 -> Word64
forall a b. (a -> b) -> a -> b
$ key -> Int -> BE Word64
forall bs. ByteArrayAccess bs => bs -> Int -> BE Word64
B.toW64BE key
k Int
16)
init2DES :: ByteArrayAccess key => (Word64 -> Word64 -> a) -> key -> CryptoFailable a
init2DES :: (Word64 -> Word64 -> a) -> key -> CryptoFailable a
init2DES Word64 -> Word64 -> a
constr key
k
| Int
len Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
16 = a -> CryptoFailable a
forall a. a -> CryptoFailable a
CryptoPassed (a -> CryptoFailable a) -> a -> CryptoFailable a
forall a b. (a -> b) -> a -> b
$ Word64 -> Word64 -> a
constr Word64
k1 Word64
k2
| Bool
otherwise = CryptoError -> CryptoFailable a
forall a. CryptoError -> CryptoFailable a
CryptoFailed CryptoError
CryptoError_KeySizeInvalid
where len :: Int
len = key -> Int
forall ba. ByteArrayAccess ba => ba -> Int
B.length key
k
(Word64
k1, Word64
k2) = (BE Word64 -> Word64
forall a. ByteSwap a => BE a -> a
fromBE (BE Word64 -> Word64) -> BE Word64 -> Word64
forall a b. (a -> b) -> a -> b
$ key -> Int -> BE Word64
forall bs. ByteArrayAccess bs => bs -> Int -> BE Word64
B.toW64BE key
k Int
0, BE Word64 -> Word64
forall a. ByteSwap a => BE a -> a
fromBE (BE Word64 -> Word64) -> BE Word64 -> Word64
forall a b. (a -> b) -> a -> b
$ key -> Int -> BE Word64
forall bs. ByteArrayAccess bs => bs -> Int -> BE Word64
B.toW64BE key
k Int
8)