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 Plaintext ciphertext :: ByteString
ciphertext _ = ByteString -> Either String ByteString
forall (m :: * -> *) a. Monad m => a -> m a
return ByteString
ciphertext
decryptOpenPGPCfb sa :: SymmetricAlgorithm
sa ciphertext :: ByteString
ciphertext keydata :: ByteString
keydata =
SymmetricAlgorithm
-> ByteString -> HOCipher ByteString -> Either String ByteString
forall a.
SymmetricAlgorithm -> ByteString -> HOCipher a -> Either String a
withSymmetricCipher SymmetricAlgorithm
sa ByteString
keydata (HOCipher ByteString -> Either String ByteString)
-> HOCipher ByteString -> Either String ByteString
forall a b. (a -> b) -> a -> b
$ \bc :: 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 (m :: * -> *) a. Monad m => a -> m a
return ByteString
cleartext
else String -> Either String ByteString
forall a b. a -> Either a b
Left "Session key quickcheck failed"
where
decrypt1 ::
HOBlockCipher cipher
=> B.ByteString
-> cipher
-> Either String B.ByteString
decrypt1 :: ByteString -> cipher -> Either String ByteString
decrypt1 ct :: ByteString
ct cipher :: 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) 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
+ 2) ByteString
ct)
decrypt2 ::
HOBlockCipher cipher
=> B.ByteString
-> cipher
-> Either String B.ByteString
decrypt2 :: ByteString -> cipher -> Either String ByteString
decrypt2 ct :: ByteString
ct cipher :: 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 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
+ 2) ByteString
ct)
decrypt ::
SymmetricAlgorithm
-> B.ByteString
-> B.ByteString
-> Either String B.ByteString
decrypt :: SymmetricAlgorithm
-> ByteString -> ByteString -> Either String ByteString
decrypt x :: SymmetricAlgorithm
x y :: ByteString
y z :: 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 Plaintext ciphertext :: ByteString
ciphertext _ = (ByteString, ByteString) -> Either String (ByteString, ByteString)
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString
forall a. Monoid a => a
mempty, ByteString
ciphertext)
decryptPreservingNonce sa :: SymmetricAlgorithm
sa ciphertext :: ByteString
ciphertext keydata :: ByteString
keydata =
SymmetricAlgorithm
-> ByteString
-> HOCipher (ByteString, ByteString)
-> Either String (ByteString, ByteString)
forall a.
SymmetricAlgorithm -> ByteString -> HOCipher a -> Either String a
withSymmetricCipher SymmetricAlgorithm
sa ByteString
keydata (HOCipher (ByteString, ByteString)
-> Either String (ByteString, ByteString))
-> HOCipher (ByteString, ByteString)
-> Either String (ByteString, ByteString)
forall a b. (a -> b) -> a -> b
$ \bc :: cipher
bc -> do
(nonce :: ByteString
nonce, cleartext :: ByteString
cleartext) <-
(ByteString -> (ByteString, ByteString))
-> Either String ByteString
-> Either String (ByteString, ByteString)
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
+ 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 (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 "Session key quickcheck failed"
where
decrypt' ::
HOBlockCipher cipher
=> B.ByteString
-> cipher
-> Either String B.ByteString
decrypt' :: ByteString -> cipher -> Either String ByteString
decrypt' ct :: ByteString
ct cipher :: 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) 0) ByteString
ct
decryptNoNonce ::
SymmetricAlgorithm
-> IV
-> B.ByteString
-> B.ByteString
-> Either String B.ByteString
decryptNoNonce :: SymmetricAlgorithm
-> IV -> ByteString -> ByteString -> Either String ByteString
decryptNoNonce Plaintext _ ciphertext :: ByteString
ciphertext _ = ByteString -> Either String ByteString
forall (m :: * -> *) a. Monad m => a -> m a
return ByteString
ciphertext
decryptNoNonce sa :: SymmetricAlgorithm
sa iv :: IV
iv ciphertext :: ByteString
ciphertext keydata :: ByteString
keydata =
SymmetricAlgorithm
-> ByteString -> HOCipher 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' :: ByteString -> cipher -> Either String ByteString
decrypt' ct :: ByteString
ct cipher :: 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 :: cipher -> ByteString -> Bool
nonceCheck bc :: 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 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
- 2) (ByteString -> ByteString -> Bool)
-> (ByteString -> ByteString) -> ByteString -> Bool
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 Plaintext _ _ payload :: ByteString
payload _ = ByteString -> Either String ByteString
forall (m :: * -> *) a. Monad m => a -> m a
return ByteString
payload
encryptNoNonce sa :: SymmetricAlgorithm
sa s2k :: S2K
s2k iv :: IV
iv payload :: ByteString
payload keydata :: ByteString
keydata =
SymmetricAlgorithm
-> ByteString -> HOCipher 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' :: ByteString -> cipher -> Either String ByteString
encrypt' ct :: ByteString
ct cipher :: 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