diff options
Diffstat (limited to 'Data/OpenPGP/Util/Decrypt.hs')
-rw-r--r-- | Data/OpenPGP/Util/Decrypt.hs | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/Data/OpenPGP/Util/Decrypt.hs b/Data/OpenPGP/Util/Decrypt.hs new file mode 100644 index 0000000..84bead5 --- /dev/null +++ b/Data/OpenPGP/Util/Decrypt.hs | |||
@@ -0,0 +1,53 @@ | |||
1 | {-# LANGUAGE RankNTypes, CPP #-} | ||
2 | module Data.OpenPGP.Util.Decrypt where | ||
3 | |||
4 | import qualified Data.ByteString.Lazy as LZ | ||
5 | import Crypto.Error | ||
6 | import qualified Crypto.Cipher.AES as Vincent | ||
7 | import qualified Crypto.Cipher.Blowfish as Vincent | ||
8 | import qualified Crypto.Cipher.Types as Vincent | ||
9 | import Crypto.Cipher.Cast5 (CAST5_128) | ||
10 | import Crypto.Cipher.ThomasToVincent | ||
11 | import qualified Data.OpenPGP as OpenPGP | ||
12 | import Data.OpenPGP.Util.Base | ||
13 | |||
14 | |||
15 | -- decryption codec for withS2K | ||
16 | simpleUnCFB :: (Vincent.BlockCipher k) => k -> Vincent.IV k -> LZ.ByteString -> LZ.ByteString | ||
17 | simpleUnCFB k iv = padThenUnpad k (toLazyBS . Vincent.cfbDecrypt k iv . toStrictBS) | ||
18 | |||
19 | withS2K' :: OpenPGP.SymmetricAlgorithm -> Maybe OpenPGP.S2K -> LZ.ByteString | ||
20 | -> (forall b. Vincent.BlockCipher b => b -> x) -> x | ||
21 | withS2K' OpenPGP.AES128 s2k s f = f (string2key s2k s :: Vincent.AES128) | ||
22 | withS2K' OpenPGP.AES192 s2k s f = f (string2key s2k s :: Vincent.AES192) | ||
23 | withS2K' OpenPGP.AES256 s2k s f = f (string2key s2k s :: Vincent.AES256) | ||
24 | withS2K' OpenPGP.Blowfish s2k s f = f (string2key s2k s :: Vincent.Blowfish128) | ||
25 | withS2K' OpenPGP.CAST5 s2k s f = f (string2key s2k s :: ThomasToVincent CAST5_128) | ||
26 | |||
27 | string2key :: (Vincent.BlockCipher k) => Maybe OpenPGP.S2K -> LZ.ByteString -> k | ||
28 | string2key ms2k s = cipher | ||
29 | where | ||
30 | #if defined(VERSION_cryptonite) | ||
31 | CryptoPassed cipher = Vincent.cipherInit k | ||
32 | k = toStrictBS $ LZ.take ksize $ maybe s (\s2k -> OpenPGP.string2key hashBySymbol s2k s) ms2k | ||
33 | #else | ||
34 | cipher = Vincent.cipherInit k | ||
35 | Right k = Vincent.makeKey $ toStrictBS $ | ||
36 | LZ.take ksize $ maybe s (\s2k -> OpenPGP.string2key hashBySymbol s2k s) ms2k | ||
37 | #endif | ||
38 | ksize = case Vincent.cipherKeySize cipher of | ||
39 | Vincent.KeySizeFixed n -> fromIntegral n | ||
40 | Vincent.KeySizeEnum xs -> error $ "Unknown key size in string2key" | ||
41 | Vincent.KeySizeRange min max -> error $ "Unknown key size range in string2key" | ||
42 | |||
43 | -- Apply a function f to a zero-padded bytestring s to a multiple | ||
44 | -- of the blocksize for cyper k. | ||
45 | -- Then drop the same number of bytes from the result of f. | ||
46 | padThenUnpad :: (Vincent.BlockCipher k) => k -> (LZ.ByteString -> LZ.ByteString) -> LZ.ByteString -> LZ.ByteString | ||
47 | padThenUnpad k f s = dropPadEnd (f padded) | ||
48 | where | ||
49 | dropPadEnd s = LZ.take (LZ.length s - padAmount) s | ||
50 | padded = s `LZ.append` LZ.replicate padAmount 0 | ||
51 | padAmount = blksize - (LZ.length s `mod` blksize) | ||
52 | blksize = fromIntegral $ Vincent.blockSize k | ||
53 | |||