module Crypto.Cipher.TripleDES (
DES_EEE3,
DES_EDE3,
DES_EEE2,
DES_EDE2,
) where
import Crypto.Cipher.DES.Primitive
import Crypto.Cipher.Types
import Crypto.Error
import Crypto.Internal.ByteArray (ByteArrayAccess, ScrubbedBytes)
import qualified Crypto.Internal.ByteArray as B
data DES_EEE3 = DES_EEE3 Schedule Schedule
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
$c== :: DES_EEE3 -> DES_EEE3 -> Bool
== :: DES_EEE3 -> DES_EEE3 -> Bool
$c/= :: DES_EEE3 -> DES_EEE3 -> Bool
/= :: DES_EEE3 -> DES_EEE3 -> Bool
Eq)
data DES_EDE3 = DES_EDE3 Schedule Schedule
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
$c== :: DES_EDE3 -> DES_EDE3 -> Bool
== :: DES_EDE3 -> DES_EDE3 -> Bool
$c/= :: DES_EDE3 -> DES_EDE3 -> Bool
/= :: DES_EDE3 -> DES_EDE3 -> Bool
Eq)
data DES_EEE2 = DES_EEE2 Schedule Schedule
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
$c== :: DES_EEE2 -> DES_EEE2 -> Bool
== :: DES_EEE2 -> DES_EEE2 -> Bool
$c/= :: DES_EEE2 -> DES_EEE2 -> Bool
/= :: DES_EEE2 -> DES_EEE2 -> Bool
Eq)
data DES_EDE2 = DES_EDE2 Schedule Schedule
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
$c== :: DES_EDE2 -> DES_EDE2 -> Bool
== :: DES_EDE2 -> DES_EDE2 -> Bool
$c/= :: DES_EDE2 -> DES_EDE2 -> Bool
/= :: 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 :: forall key. ByteArray key => key -> CryptoFailable DES_EEE3
cipherInit key
k = (Schedule -> Schedule -> DES_EEE3)
-> Direction -> key -> CryptoFailable DES_EEE3
forall key a.
ByteArrayAccess key =>
(Schedule -> Schedule -> a) -> Direction -> key -> CryptoFailable a
init3DES Schedule -> Schedule -> DES_EEE3
DES_EEE3 Direction
Encrypt 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 :: forall key. ByteArray key => key -> CryptoFailable DES_EDE3
cipherInit key
k = (Schedule -> Schedule -> DES_EDE3)
-> Direction -> key -> CryptoFailable DES_EDE3
forall key a.
ByteArrayAccess key =>
(Schedule -> Schedule -> a) -> Direction -> key -> CryptoFailable a
init3DES Schedule -> Schedule -> DES_EDE3
DES_EDE3 Direction
Decrypt 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 :: forall key. ByteArray key => key -> CryptoFailable DES_EDE2
cipherInit key
k = (Schedule -> Schedule -> DES_EDE2)
-> Direction -> key -> CryptoFailable DES_EDE2
forall key a.
ByteArrayAccess key =>
(Schedule -> Schedule -> a) -> Direction -> key -> CryptoFailable a
init2DES Schedule -> Schedule -> DES_EDE2
DES_EDE2 Direction
Decrypt 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 :: forall key. ByteArray key => key -> CryptoFailable DES_EEE2
cipherInit key
k = (Schedule -> Schedule -> DES_EEE2)
-> Direction -> key -> CryptoFailable DES_EEE2
forall key a.
ByteArrayAccess key =>
(Schedule -> Schedule -> a) -> Direction -> key -> CryptoFailable a
init2DES Schedule -> Schedule -> DES_EEE2
DES_EEE2 Direction
Encrypt key
k
instance BlockCipher DES_EEE3 where
blockSize :: DES_EEE3 -> Int
blockSize DES_EEE3
_ = Int
8
ecbEncrypt :: forall ba. ByteArray ba => DES_EEE3 -> ba -> ba
ecbEncrypt (DES_EEE3 Schedule
enc Schedule
_) = Schedule -> ba -> ba
forall ba. ByteArray ba => Schedule -> ba -> ba
ecb Schedule
enc
ecbDecrypt :: forall ba. ByteArray ba => DES_EEE3 -> ba -> ba
ecbDecrypt (DES_EEE3 Schedule
_ Schedule
dec) = Schedule -> ba -> ba
forall ba. ByteArray ba => Schedule -> ba -> ba
ecb Schedule
dec
instance BlockCipher DES_EDE3 where
blockSize :: DES_EDE3 -> Int
blockSize DES_EDE3
_ = Int
8
ecbEncrypt :: forall ba. ByteArray ba => DES_EDE3 -> ba -> ba
ecbEncrypt (DES_EDE3 Schedule
enc Schedule
_) = Schedule -> ba -> ba
forall ba. ByteArray ba => Schedule -> ba -> ba
ecb Schedule
enc
ecbDecrypt :: forall ba. ByteArray ba => DES_EDE3 -> ba -> ba
ecbDecrypt (DES_EDE3 Schedule
_ Schedule
dec) = Schedule -> ba -> ba
forall ba. ByteArray ba => Schedule -> ba -> ba
ecb Schedule
dec
instance BlockCipher DES_EEE2 where
blockSize :: DES_EEE2 -> Int
blockSize DES_EEE2
_ = Int
8
ecbEncrypt :: forall ba. ByteArray ba => DES_EEE2 -> ba -> ba
ecbEncrypt (DES_EEE2 Schedule
enc Schedule
_) = Schedule -> ba -> ba
forall ba. ByteArray ba => Schedule -> ba -> ba
ecb Schedule
enc
ecbDecrypt :: forall ba. ByteArray ba => DES_EEE2 -> ba -> ba
ecbDecrypt (DES_EEE2 Schedule
_ Schedule
dec) = Schedule -> ba -> ba
forall ba. ByteArray ba => Schedule -> ba -> ba
ecb Schedule
dec
instance BlockCipher DES_EDE2 where
blockSize :: DES_EDE2 -> Int
blockSize DES_EDE2
_ = Int
8
ecbEncrypt :: forall ba. ByteArray ba => DES_EDE2 -> ba -> ba
ecbEncrypt (DES_EDE2 Schedule
enc Schedule
_) = Schedule -> ba -> ba
forall ba. ByteArray ba => Schedule -> ba -> ba
ecb Schedule
enc
ecbDecrypt :: forall ba. ByteArray ba => DES_EDE2 -> ba -> ba
ecbDecrypt (DES_EDE2 Schedule
_ Schedule
dec) = Schedule -> ba -> ba
forall ba. ByteArray ba => Schedule -> ba -> ba
ecb Schedule
dec
stages
:: ByteArrayAccess key
=> Direction
-> (key, key, key)
-> (Schedule, Schedule)
stages :: forall key.
ByteArrayAccess key =>
Direction -> (key, key, key) -> (Schedule, Schedule)
stages Direction
mid (key
k1, key
k2, key
k3) =
( [(Direction, key)] -> Schedule
forall key. ByteArrayAccess key => [(Direction, key)] -> Schedule
schedule [(Direction
Encrypt, key
k1), (Direction
mid, key
k2), (Direction
Encrypt, key
k3)]
, [(Direction, key)] -> Schedule
forall key. ByteArrayAccess key => [(Direction, key)] -> Schedule
schedule [(Direction
Decrypt, key
k3), (Direction -> Direction
opposite Direction
mid, key
k2), (Direction
Decrypt, key
k1)]
)
where
opposite :: Direction -> Direction
opposite Direction
Encrypt = Direction
Decrypt
opposite Direction
Decrypt = Direction
Encrypt
init3DES
:: ByteArrayAccess key
=> (Schedule -> Schedule -> a) -> Direction -> key -> CryptoFailable a
init3DES :: forall key a.
ByteArrayAccess key =>
(Schedule -> Schedule -> a) -> Direction -> key -> CryptoFailable a
init3DES Schedule -> Schedule -> a
constr Direction
mid key
k
| key -> Int
forall ba. ByteArrayAccess ba => ba -> Int
B.length key
k 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
$ (Schedule -> Schedule -> a) -> (Schedule, Schedule) -> a
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Schedule -> Schedule -> a
constr ((Schedule, Schedule) -> a) -> (Schedule, Schedule) -> a
forall a b. (a -> b) -> a -> b
$ Direction
-> (ScrubbedBytes, ScrubbedBytes, ScrubbedBytes)
-> (Schedule, Schedule)
forall key.
ByteArrayAccess key =>
Direction -> (key, key, key) -> (Schedule, Schedule)
stages Direction
mid (Int -> ScrubbedBytes
part Int
0, Int -> ScrubbedBytes
part Int
8, Int -> ScrubbedBytes
part Int
16)
| Bool
otherwise = CryptoError -> CryptoFailable a
forall a. CryptoError -> CryptoFailable a
CryptoFailed CryptoError
CryptoError_KeySizeInvalid
where
part :: Int -> ScrubbedBytes
part = key -> Int -> ScrubbedBytes
forall key. ByteArrayAccess key => key -> Int -> ScrubbedBytes
keyPart key
k
init2DES
:: ByteArrayAccess key
=> (Schedule -> Schedule -> a) -> Direction -> key -> CryptoFailable a
init2DES :: forall key a.
ByteArrayAccess key =>
(Schedule -> Schedule -> a) -> Direction -> key -> CryptoFailable a
init2DES Schedule -> Schedule -> a
constr Direction
mid key
k
| key -> Int
forall ba. ByteArrayAccess ba => ba -> Int
B.length key
k 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
$ (Schedule -> Schedule -> a) -> (Schedule, Schedule) -> a
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Schedule -> Schedule -> a
constr ((Schedule, Schedule) -> a) -> (Schedule, Schedule) -> a
forall a b. (a -> b) -> a -> b
$ Direction
-> (ScrubbedBytes, ScrubbedBytes, ScrubbedBytes)
-> (Schedule, Schedule)
forall key.
ByteArrayAccess key =>
Direction -> (key, key, key) -> (Schedule, Schedule)
stages Direction
mid (Int -> ScrubbedBytes
part Int
0, Int -> ScrubbedBytes
part Int
8, Int -> ScrubbedBytes
part Int
0)
| Bool
otherwise = CryptoError -> CryptoFailable a
forall a. CryptoError -> CryptoFailable a
CryptoFailed CryptoError
CryptoError_KeySizeInvalid
where
part :: Int -> ScrubbedBytes
part = key -> Int -> ScrubbedBytes
forall key. ByteArrayAccess key => key -> Int -> ScrubbedBytes
keyPart key
k
keyPart :: ByteArrayAccess key => key -> Int -> ScrubbedBytes
keyPart :: forall key. ByteArrayAccess key => key -> Int -> ScrubbedBytes
keyPart key
k Int
i = Int -> ScrubbedBytes -> ScrubbedBytes
forall bs. ByteArray bs => Int -> bs -> bs
B.take Int
8 (ScrubbedBytes -> ScrubbedBytes) -> ScrubbedBytes -> ScrubbedBytes
forall a b. (a -> b) -> a -> b
$ Int -> ScrubbedBytes -> ScrubbedBytes
forall bs. ByteArray bs => Int -> bs -> bs
B.drop Int
i (key -> ScrubbedBytes
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
B.convert key
k :: ScrubbedBytes)