module Codec.Encryption.OpenPGP.CFB
( decrypt
, decryptPreservingNonce
, decryptNoNonce
, decryptOpenPGPCfb
, encryptNoNonce
) where
import Codec.Encryption.OpenPGP.BlockCipher (withSymmetricCipher)
import Codec.Encryption.OpenPGP.Internal.HOBlockCipher
import Codec.Encryption.OpenPGP.Types
import qualified Data.ByteString as B
decryptOpenPGPCfb ::
SymmetricAlgorithm
-> B.ByteString
-> B.ByteString
-> Either String B.ByteString
decryptOpenPGPCfb :: SymmetricAlgorithm
-> ByteString -> ByteString -> Either String ByteString
decryptOpenPGPCfb SymmetricAlgorithm
Plaintext ByteString
ciphertext ByteString
_ = ByteString -> Either String ByteString
forall a. a -> Either String a
forall (m :: * -> *) a. Monad m => a -> m a
return ByteString
ciphertext
decryptOpenPGPCfb SymmetricAlgorithm
sa ByteString
ciphertext ByteString
keydata =
SymmetricAlgorithm
-> ByteString
-> (forall {cipher}.
HOBlockCipher cipher =>
cipher -> Either String ByteString)
-> Either String ByteString
forall a.
SymmetricAlgorithm -> ByteString -> HOCipher a -> Either String a
withSymmetricCipher SymmetricAlgorithm
sa ByteString
keydata ((forall {cipher}.
HOBlockCipher cipher =>
cipher -> Either String ByteString)
-> Either String ByteString)
-> (forall {cipher}.
HOBlockCipher cipher =>
cipher -> Either String ByteString)
-> Either String ByteString
forall a b. (a -> b) -> a -> b
$ \cipher
bc -> do
ByteString
nonce <- ByteString -> cipher -> Either String ByteString
forall cipher.
HOBlockCipher cipher =>
ByteString -> cipher -> Either String ByteString
decrypt1 ByteString
ciphertext cipher
bc
ByteString
cleartext <- ByteString -> cipher -> Either String ByteString
forall cipher.
HOBlockCipher cipher =>
ByteString -> cipher -> Either String ByteString
decrypt2 ByteString
ciphertext cipher
bc
if cipher -> ByteString -> Bool
forall cipher. HOBlockCipher cipher => cipher -> ByteString -> Bool
nonceCheck cipher
bc ByteString
nonce
then ByteString -> Either String ByteString
forall a. a -> Either String a
forall (m :: * -> *) a. Monad m => a -> m a
return ByteString
cleartext
else String -> Either String ByteString
forall a b. a -> Either a b
Left String
"Session key quickcheck failed"
where
decrypt1 ::
HOBlockCipher cipher
=> B.ByteString
-> cipher
-> Either String B.ByteString
decrypt1 :: forall cipher.
HOBlockCipher cipher =>
ByteString -> cipher -> Either String ByteString
decrypt1 ByteString
ct cipher
cipher =
cipher -> ByteString -> ByteString -> Either String ByteString
forall cipher.
HOBlockCipher cipher =>
cipher -> ByteString -> ByteString -> Either String ByteString
paddedCfbDecrypt
cipher
cipher
(Int -> Word8 -> ByteString
B.replicate (cipher -> Int
forall cipher. HOBlockCipher cipher => cipher -> Int
blockSize cipher
cipher) Word8
0)
(Int -> ByteString -> ByteString
B.take (cipher -> Int
forall cipher. HOBlockCipher cipher => cipher -> Int
blockSize cipher
cipher Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2) ByteString
ct)
decrypt2 ::
HOBlockCipher cipher
=> B.ByteString
-> cipher
-> Either String B.ByteString
decrypt2 :: forall cipher.
HOBlockCipher cipher =>
ByteString -> cipher -> Either String ByteString
decrypt2 ByteString
ct cipher
cipher =
let i :: ByteString
i = Int -> ByteString -> ByteString
B.take (cipher -> Int
forall cipher. HOBlockCipher cipher => cipher -> Int
blockSize cipher
cipher) (Int -> ByteString -> ByteString
B.drop Int
2 ByteString
ct)
in cipher -> ByteString -> ByteString -> Either String ByteString
forall cipher.
HOBlockCipher cipher =>
cipher -> ByteString -> ByteString -> Either String ByteString
paddedCfbDecrypt cipher
cipher ByteString
i (Int -> ByteString -> ByteString
B.drop (cipher -> Int
forall cipher. HOBlockCipher cipher => cipher -> Int
blockSize cipher
cipher Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2) ByteString
ct)
decrypt ::
SymmetricAlgorithm
-> B.ByteString
-> B.ByteString
-> Either String B.ByteString
decrypt :: SymmetricAlgorithm
-> ByteString -> ByteString -> Either String ByteString
decrypt SymmetricAlgorithm
x ByteString
y ByteString
z = (ByteString, ByteString) -> ByteString
forall a b. (a, b) -> b
snd ((ByteString, ByteString) -> ByteString)
-> Either String (ByteString, ByteString)
-> Either String ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (SymmetricAlgorithm
-> ByteString
-> ByteString
-> Either String (ByteString, ByteString)
decryptPreservingNonce SymmetricAlgorithm
x ByteString
y ByteString
z)
decryptPreservingNonce ::
SymmetricAlgorithm
-> B.ByteString
-> B.ByteString
-> Either String (B.ByteString, B.ByteString)
decryptPreservingNonce :: SymmetricAlgorithm
-> ByteString
-> ByteString
-> Either String (ByteString, ByteString)
decryptPreservingNonce SymmetricAlgorithm
Plaintext ByteString
ciphertext ByteString
_ = (ByteString, ByteString) -> Either String (ByteString, ByteString)
forall a. a -> Either String a
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString
forall a. Monoid a => a
mempty, ByteString
ciphertext)
decryptPreservingNonce SymmetricAlgorithm
sa ByteString
ciphertext ByteString
keydata =
SymmetricAlgorithm
-> ByteString
-> (forall {cipher}.
HOBlockCipher cipher =>
cipher -> Either String (ByteString, ByteString))
-> Either String (ByteString, ByteString)
forall a.
SymmetricAlgorithm -> ByteString -> HOCipher a -> Either String a
withSymmetricCipher SymmetricAlgorithm
sa ByteString
keydata ((forall {cipher}.
HOBlockCipher cipher =>
cipher -> Either String (ByteString, ByteString))
-> Either String (ByteString, ByteString))
-> (forall {cipher}.
HOBlockCipher cipher =>
cipher -> Either String (ByteString, ByteString))
-> Either String (ByteString, ByteString)
forall a b. (a -> b) -> a -> b
$ \cipher
bc -> do
(ByteString
nonce, ByteString
cleartext) <-
(ByteString -> (ByteString, ByteString))
-> Either String ByteString
-> Either String (ByteString, ByteString)
forall a b. (a -> b) -> Either String a -> Either String b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int -> ByteString -> (ByteString, ByteString)
B.splitAt (cipher -> Int
forall cipher. HOBlockCipher cipher => cipher -> Int
blockSize cipher
bc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2)) (ByteString -> cipher -> Either String ByteString
forall cipher.
HOBlockCipher cipher =>
ByteString -> cipher -> Either String ByteString
decrypt' ByteString
ciphertext cipher
bc)
if cipher -> ByteString -> Bool
forall cipher. HOBlockCipher cipher => cipher -> ByteString -> Bool
nonceCheck cipher
bc ByteString
nonce
then (ByteString, ByteString) -> Either String (ByteString, ByteString)
forall a. a -> Either String a
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString
nonce, ByteString
cleartext)
else String -> Either String (ByteString, ByteString)
forall a b. a -> Either a b
Left String
"Session key quickcheck failed"
where
decrypt' ::
HOBlockCipher cipher
=> B.ByteString
-> cipher
-> Either String B.ByteString
decrypt' :: forall cipher.
HOBlockCipher cipher =>
ByteString -> cipher -> Either String ByteString
decrypt' ByteString
ct cipher
cipher =
cipher -> ByteString -> ByteString -> Either String ByteString
forall cipher.
HOBlockCipher cipher =>
cipher -> ByteString -> ByteString -> Either String ByteString
paddedCfbDecrypt cipher
cipher (Int -> Word8 -> ByteString
B.replicate (cipher -> Int
forall cipher. HOBlockCipher cipher => cipher -> Int
blockSize cipher
cipher) Word8
0) ByteString
ct
decryptNoNonce ::
SymmetricAlgorithm
-> IV
-> B.ByteString
-> B.ByteString
-> Either String B.ByteString
decryptNoNonce :: SymmetricAlgorithm
-> IV -> ByteString -> ByteString -> Either String ByteString
decryptNoNonce SymmetricAlgorithm
Plaintext IV
_ ByteString
ciphertext ByteString
_ = ByteString -> Either String ByteString
forall a. a -> Either String a
forall (m :: * -> *) a. Monad m => a -> m a
return ByteString
ciphertext
decryptNoNonce SymmetricAlgorithm
sa IV
iv ByteString
ciphertext ByteString
keydata =
SymmetricAlgorithm
-> ByteString
-> (forall {cipher}.
HOBlockCipher cipher =>
cipher -> Either String ByteString)
-> Either String ByteString
forall a.
SymmetricAlgorithm -> ByteString -> HOCipher a -> Either String a
withSymmetricCipher SymmetricAlgorithm
sa ByteString
keydata (ByteString -> cipher -> Either String ByteString
forall cipher.
HOBlockCipher cipher =>
ByteString -> cipher -> Either String ByteString
decrypt' ByteString
ciphertext)
where
decrypt' ::
HOBlockCipher cipher
=> B.ByteString
-> cipher
-> Either String B.ByteString
decrypt' :: forall cipher.
HOBlockCipher cipher =>
ByteString -> cipher -> Either String ByteString
decrypt' ByteString
ct cipher
cipher = cipher -> ByteString -> ByteString -> Either String ByteString
forall cipher.
HOBlockCipher cipher =>
cipher -> ByteString -> ByteString -> Either String ByteString
paddedCfbDecrypt cipher
cipher (IV -> ByteString
unIV IV
iv) ByteString
ct
nonceCheck :: HOBlockCipher cipher => cipher -> B.ByteString -> Bool
nonceCheck :: forall cipher. HOBlockCipher cipher => cipher -> ByteString -> Bool
nonceCheck cipher
bc =
ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
(==) (ByteString -> ByteString -> Bool)
-> (ByteString -> ByteString) -> ByteString -> ByteString -> Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> ByteString -> ByteString
B.take Int
2 (ByteString -> ByteString)
-> (ByteString -> ByteString) -> ByteString -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ByteString -> ByteString
B.drop (cipher -> Int
forall cipher. HOBlockCipher cipher => cipher -> Int
blockSize cipher
bc Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
2) (ByteString -> ByteString -> Bool)
-> (ByteString -> ByteString) -> ByteString -> Bool
forall a b.
(ByteString -> a -> b) -> (ByteString -> a) -> ByteString -> b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> ByteString -> ByteString
B.drop (cipher -> Int
forall cipher. HOBlockCipher cipher => cipher -> Int
blockSize cipher
bc)
encryptNoNonce ::
SymmetricAlgorithm
-> S2K
-> IV
-> B.ByteString
-> B.ByteString
-> Either String B.ByteString
encryptNoNonce :: SymmetricAlgorithm
-> S2K
-> IV
-> ByteString
-> ByteString
-> Either String ByteString
encryptNoNonce SymmetricAlgorithm
Plaintext S2K
_ IV
_ ByteString
payload ByteString
_ = ByteString -> Either String ByteString
forall a. a -> Either String a
forall (m :: * -> *) a. Monad m => a -> m a
return ByteString
payload
encryptNoNonce SymmetricAlgorithm
sa S2K
s2k IV
iv ByteString
payload ByteString
keydata =
SymmetricAlgorithm
-> ByteString
-> (forall {cipher}.
HOBlockCipher cipher =>
cipher -> Either String ByteString)
-> Either String ByteString
forall a.
SymmetricAlgorithm -> ByteString -> HOCipher a -> Either String a
withSymmetricCipher SymmetricAlgorithm
sa ByteString
keydata (ByteString -> cipher -> Either String ByteString
forall cipher.
HOBlockCipher cipher =>
ByteString -> cipher -> Either String ByteString
encrypt' ByteString
payload)
where
encrypt' ::
HOBlockCipher cipher
=> B.ByteString
-> cipher
-> Either String B.ByteString
encrypt' :: forall cipher.
HOBlockCipher cipher =>
ByteString -> cipher -> Either String ByteString
encrypt' ByteString
ct cipher
cipher = cipher -> ByteString -> ByteString -> Either String ByteString
forall cipher.
HOBlockCipher cipher =>
cipher -> ByteString -> ByteString -> Either String ByteString
paddedCfbEncrypt cipher
cipher (IV -> ByteString
unIV IV
iv) ByteString
ct