{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PackageImports #-}
{-# LANGUAGE UndecidableInstances #-}
module Codec.Encryption.OpenPGP.Internal.Cryptonite
( HOWrappedCCT(..)
) where
import Control.Error.Util (note)
import qualified "cryptonite" Crypto.Cipher.Types as CCT
import qualified Crypto.Error as CE
import Data.Bifunctor (bimap)
import qualified Data.ByteString as B
import Codec.Encryption.OpenPGP.Internal.HOBlockCipher
newtype HOWrappedCCT a =
HWCCT a
instance CCT.BlockCipher cipher => HOBlockCipher (HOWrappedCCT cipher) where
cipherInit :: ByteString -> Either String (HOWrappedCCT cipher)
cipherInit = (CryptoError -> String)
-> (cipher -> HOWrappedCCT cipher)
-> Either CryptoError cipher
-> Either String (HOWrappedCCT cipher)
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap CryptoError -> String
forall a. Show a => a -> String
show cipher -> HOWrappedCCT cipher
forall a. a -> HOWrappedCCT a
HWCCT (Either CryptoError cipher -> Either String (HOWrappedCCT cipher))
-> (ByteString -> Either CryptoError cipher)
-> ByteString
-> Either String (HOWrappedCCT cipher)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CryptoFailable cipher -> Either CryptoError cipher
forall a. CryptoFailable a -> Either CryptoError a
CE.eitherCryptoError (CryptoFailable cipher -> Either CryptoError cipher)
-> (ByteString -> CryptoFailable cipher)
-> ByteString
-> Either CryptoError cipher
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> CryptoFailable cipher
forall cipher key.
(Cipher cipher, ByteArray key) =>
key -> CryptoFailable cipher
CCT.cipherInit
cipherName :: HOWrappedCCT cipher -> String
cipherName (HWCCT c :: cipher
c) = cipher -> String
forall cipher. Cipher cipher => cipher -> String
CCT.cipherName cipher
c
cipherKeySize :: HOWrappedCCT cipher -> KeySizeSpecifier
cipherKeySize (HWCCT c :: cipher
c) = cipher -> KeySizeSpecifier
forall cipher. Cipher cipher => cipher -> KeySizeSpecifier
CCT.cipherKeySize cipher
c
blockSize :: HOWrappedCCT cipher -> Int
blockSize (HWCCT c :: cipher
c) = cipher -> Int
forall cipher. BlockCipher cipher => cipher -> Int
CCT.blockSize cipher
c
cfbEncrypt :: HOWrappedCCT cipher
-> ByteString -> ByteString -> Either String ByteString
cfbEncrypt (HWCCT c :: cipher
c) iv :: ByteString
iv bs :: ByteString
bs =
ByteString -> Either String (IV cipher)
forall cipher.
BlockCipher cipher =>
ByteString -> Either String (IV cipher)
hammerIV ByteString
iv Either String (IV cipher)
-> (IV cipher -> Either String ByteString)
-> Either String ByteString
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \i :: IV cipher
i -> ByteString -> Either String ByteString
forall (m :: * -> *) a. Monad m => a -> m a
return (cipher -> IV cipher -> ByteString -> ByteString
forall cipher ba.
(BlockCipher cipher, ByteArray ba) =>
cipher -> IV cipher -> ba -> ba
CCT.cfbEncrypt cipher
c IV cipher
i ByteString
bs)
cfbDecrypt :: HOWrappedCCT cipher
-> ByteString -> ByteString -> Either String ByteString
cfbDecrypt (HWCCT c :: cipher
c) iv :: ByteString
iv bs :: ByteString
bs =
ByteString -> Either String (IV cipher)
forall cipher.
BlockCipher cipher =>
ByteString -> Either String (IV cipher)
hammerIV ByteString
iv Either String (IV cipher)
-> (IV cipher -> Either String ByteString)
-> Either String ByteString
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \i :: IV cipher
i -> ByteString -> Either String ByteString
forall (m :: * -> *) a. Monad m => a -> m a
return (cipher -> IV cipher -> ByteString -> ByteString
forall cipher ba.
(BlockCipher cipher, ByteArray ba) =>
cipher -> IV cipher -> ba -> ba
CCT.cfbDecrypt cipher
c IV cipher
i ByteString
bs)
hammerIV ::
CCT.BlockCipher cipher => B.ByteString -> Either String (CCT.IV cipher)
hammerIV :: ByteString -> Either String (IV cipher)
hammerIV = String -> Maybe (IV cipher) -> Either String (IV cipher)
forall a b. a -> Maybe b -> Either a b
note "cryptonite bad IV" (Maybe (IV cipher) -> Either String (IV cipher))
-> (ByteString -> Maybe (IV cipher))
-> ByteString
-> Either String (IV cipher)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Maybe (IV cipher)
forall b c. (ByteArrayAccess b, BlockCipher c) => b -> Maybe (IV c)
CCT.makeIV