packages feed

SimpleAES 0.2 → 0.3

raw patch · 3 files changed

+47/−15 lines, 3 filesdep +binaryPVP ok

version bump matches the API change (PVP)

Dependencies added: binary

API changes (from Hackage documentation)

+ Codec.Crypto.SimpleAES: decryptMsg :: Mode -> Key -> ByteString -> ByteString
+ Codec.Crypto.SimpleAES: encryptMsg :: Mode -> Key -> ByteString -> IO ByteString
+ Codec.Crypto.SimpleAES: encryptMsg' :: Mode -> Key -> IV -> ByteString -> ByteString

Files

SimpleAES.cabal view
@@ -1,7 +1,7 @@ Name: SimpleAES Synopsis: Fast AES encryption/decryption for bytestrings Description: A simplified binding to Brian Gladman's AES implementation, including a copy of that implementation-Version: 0.2+Version: 0.3 License: BSD3 License-file: COPYING Copyright: Copyright (c) 2009 University of Tromsø, 2009 David Himmelstrup@@ -18,7 +18,7 @@  Library   Build-Depends:-        base >= 4 && < 5 , bytestring, mwc-random >= 0.4.1.1+        base >= 4 && < 5 , bytestring, mwc-random >= 0.4.1.1, binary   Extensions:         ForeignFunctionInterface,         ViewPatterns,
src/Codec/Crypto/AES/IO.hsc view
@@ -30,11 +30,6 @@  data Direction = Encrypt | Decrypt --- | Modes ECB and CBC can only handle full 16-byte frames. This means--- the length of every strict bytestring passed in must be a multiple--- of 16; when using lazy bytestrings, its /component/ strict--- bytestrings must all satisfy this.--- data Mode = ECB | CBC --  CFB  | OFB  | CTR  -- Other modes can handle bytestrings of any length. However,
src/Codec/Crypto/SimpleAES.hs view
@@ -1,7 +1,11 @@ -- | A pure interface to AES-module Codec.Crypto.SimpleAES(-  Mode(..), Direction(..), Key, IV, newIV, randomKey, crypt-  ) where+module Codec.Crypto.SimpleAES+    ( Mode(..)+    , Direction(..)+    , Key, IV+    , newIV, randomKey, crypt+    , encryptMsg, encryptMsg', decryptMsg+    ) where  import qualified Codec.Crypto.AES.IO as AES import Codec.Crypto.AES.IO(Mode(..), Direction(..))@@ -10,6 +14,7 @@ import Control.Monad import System.IO.Unsafe import Control.Monad.ST+import Data.Binary  import System.Random.MWC @@ -19,9 +24,12 @@ type Key = B.ByteString type IV = B.ByteString +ivLength :: Num a => a+ivLength = 16+ newIV :: IO IV newIV = do seed <- newSeed-           let (iv, seed') = randomByteString seed 16+           let (iv, seed') = randomByteString seed ivLength            return iv  randomKey :: IO Key@@ -29,19 +37,48 @@                let (key, seed') = randomByteString seed 32                return key -{-+ -- Properties: --   decryptMsg mode key . encryptMsg mode key == id --   x == y => encryptMsg mode key x == encryptMsg mode key y+-- | Encrypt a bytestring using a random seed (IV). Since the+--   seed is random, this function is tainted by IO. encryptMsg :: Mode -> Key -> BL.ByteString -> IO BL.ByteString encryptMsg mode key bs     = do iv <- newIV-         cxt <- AES.newCtx mode key iv Encrypt+         return $ encryptMsg' mode key iv bs++-- | Encrypt a ByteString using a given seed (IV).+--   The resulting ByteString contains both the seed and the original+--   length of the input (before padding).+encryptMsg' :: Mode -> Key -> IV -> BL.ByteString -> BL.ByteString+encryptMsg' mode key iv bs+    = unsafePerformIO $+      do ctx <- AES.newCtx mode key iv Encrypt          chunks <- unsafeInterleaveIO $ lazyCrypt ctx (repack bs)--}+         let encrypted = BL.fromChunks chunks+         return $ BL.concat [ BL.fromChunks [iv]+                            , encode (BL.length bs)+                            , encrypted ] +decryptMsg :: Mode -> Key -> BL.ByteString -> BL.ByteString+decryptMsg mode key bs+    = unsafePerformIO $+      do when (BL.length iv /= ivLength)  $ error "Codec.Crypto.SimpleAES.decryptMsg: Invalid IV length. Message garbled."+         when (BL.length lenStr /= 8)     $ error "Codec.Crypto.SimpleAES.decryptMsg: Invalid encoding. Message garbled."+         when (BL.length encrypted < len) $ error "Codec.Crypto.SimpleAES.decryptMsg: Invalid size. Message garbled."+         when (BL.length encrypted `mod` 16 /= 0) $ error "Codec.Crypto.SimpleAES.decryptMsg: Invalid padding. Message garbled."+         ctx <- AES.newCtx mode key (B.concat $ BL.toChunks iv) Decrypt+         chunks <- unsafeInterleaveIO $ lazyCrypt ctx (repack encrypted)+         return $ BL.take len (BL.fromChunks chunks)+    where (iv, bs') = BL.splitAt ivLength bs+          (lenStr,encrypted) = BL.splitAt 8 bs'+          len = decode lenStr --- | Encryption/decryption for lazy bytestrings++-- | Encryption/decryption for lazy bytestrings. The input string is zero-padded to+--   a multiple of 16. It is your obligation to separate encode the length of the string.+-- --   Properties: --     x == y => crypt mode key iv dir x == crypt mode key iv dir y --     take (length x) (crypt mode key iv Decrypt (crypt mode key iv Encrypt x)) == x