module Crypto.Simple.Cipher where import Data.Monoid ((<>)) import Data.ByteString (ByteString) import Crypto.Cipher.AES (AES256) import Crypto.Random.Entropy (getEntropy) import Crypto.Cipher.Types (BlockCipher(..), Cipher(..), IV) import Crypto.Error (CryptoFailable(..)) import qualified Data.ByteString as B newtype Key a = Key ByteString deriving (Show,Eq) blockLength :: Int blockLength = 16 maxKeyLength :: Int maxKeyLength = 32 data CipherMode = CBCencrypt | CBCdecrypt | CTR -- | key must be 32 bytes in length encrypt' :: CipherMode -> ByteString -> Maybe (IV AES256) -> ByteString -> ByteString encrypt' mode key iv = cipherEncrypt ctx iv' where cipherEncrypt = case mode of CBCencrypt -> cbcEncrypt CBCdecrypt -> cbcDecrypt CTR -> ctrCombine ctx = cipherInitNoErr blockCipher iv' = maybe (error $ "IV length must be " <> show blockLength <> " bytes") id iv blockCipher = cipherMakeKey (undefined :: AES256) key cipherInitNoErr :: BlockCipher c => Key c -> c cipherInitNoErr (Key k) = case cipherInit k of CryptoPassed a -> a CryptoFailed e -> error (show e) cipherMakeKey :: Cipher cipher => cipher -> ByteString -> Key cipher cipherMakeKey _ = Key decrypt' :: CipherMode -> ByteString -> Maybe (IV AES256) -> ByteString -> ByteString decrypt' = encrypt'