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 +2/−2
- src/Codec/Crypto/AES/IO.hsc +0/−5
- src/Codec/Crypto/SimpleAES.hs +45/−8
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