packages feed

cipher-aes128 0.2.5 → 0.3

raw patch · 6 files changed

+66/−17 lines, 6 filesdep +criteriondep +entropydep ~basedep ~crypto-apiPVP ok

version bump matches the API change (PVP)

Dependencies added: criterion, entropy

Dependency ranges changed: base, crypto-api

API changes (from Hackage documentation)

- Crypto.Cipher.AES128.Internal: decryptCTR :: AESKey -> Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> Int -> IO ()
+ Crypto.Cipher.AES128.Internal: decryptCTR :: AESKey -> Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> Int -> IO ()
- Crypto.Cipher.AES128.Internal: encryptCTR :: AESKey -> Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> Int -> IO ()
+ Crypto.Cipher.AES128.Internal: encryptCTR :: AESKey -> Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> Int -> IO ()

Files

+ Benchmark/bench.hs view
@@ -0,0 +1,13 @@+import Crypto.Cipher.AES128+import Crypto.Classes+import Crypto.Modes (zeroIV)+import Criterion+import Criterion.Main+import System.Entropy++main = do+    let iv = zeroIV+    pt <- getEntropy (2^20)+    k  <- buildKeyIO :: IO AESKey+    defaultMain+        [ bench "aes-ctr" $ nf (fst . ctr k iv) pt ]
Crypto/Cipher/AES128.hs view
@@ -4,9 +4,12 @@  import Crypto.Cipher.AES128.Internal import Crypto.Classes+import Crypto.Types+import Control.Monad (when) import Data.Serialize import Data.Tagged import Foreign.Ptr+import Foreign.ForeignPtr import System.IO.Unsafe import qualified Data.ByteString as B import qualified Data.ByteString.Internal as B@@ -41,6 +44,17 @@         B.unsafeUseAsCStringLen b $ \(inP,len) -> do          B.create (B.length b) $ \outP -> do             decryptECB k (castPtr outP) (castPtr inP) (len`div`blkSize)+    ctr k (IV bs) pt = unsafePerformIO $ do+        B.unsafeUseAsCStringLen pt $ \(inP, len) -> do+         B.unsafeUseAsCStringLen bs $ \(ivP, ivLen) -> do+            when (ivLen /= (blockSizeBytes .::. k))+                (error "Cipher-AES128: IV wrong length!  They type system would have/should have caught this if you didn't use the IV constructor...")+            newIVFP <- B.mallocByteString ivLen+            ct <- B.create len $ \outP -> withForeignPtr newIVFP $ \newIVP -> do+                encryptCTR k (castPtr ivP) (castPtr newIVP) (castPtr outP) (castPtr inP) len+            let newIV = B.fromForeignPtr newIVFP 0 ivLen+            return (ct,IV newIV)+    unCtr = ctr  blkSize :: Int blkSize = 16
Crypto/Cipher/AES128/Internal.hs view
@@ -57,6 +57,7 @@ foreign import ccall unsafe "aes/aes.h encrypt_ctr"     c_encrypt_ctr :: AESKeyPtr                   -> Ptr Word8 -- ^ 128 bit IV+                  -> Ptr Word8 -- ^ 128 bit new IV                   -> Ptr Word8 -- ^ Result                   -> Ptr Word8 -- ^ Input                   -> Word32    -- ^ Input length in bytes@@ -64,6 +65,7 @@  c_decrypt_ctr :: AESKeyPtr               -> Ptr Word8 -- ^ 128 bit IV+              -> Ptr Word8 -- ^ 128 bit new IV               -> Ptr Word8 -- ^ Result               -> Ptr Word8 -- ^ Input               -> Word32    -- ^ Input length in bytes@@ -145,21 +147,23 @@  encryptCTR :: AESKey            -> Ptr Word8 -- ^ IV+           -> Ptr Word8 -- ^ NEW IV            -> Ptr Word8 -- ^ CT            -> Ptr Word8 -- ^ PT            -> Int       -- ^ Length in bytes            -> IO ()-encryptCTR (AESKey _ k) iv ct pt len = withForeignPtr k $ \p -> do-    c_encrypt_ctr p iv ct pt (fromIntegral len)+encryptCTR (AESKey _ k) iv niv ct pt len = withForeignPtr k $ \p -> do+    c_encrypt_ctr p iv niv ct pt (fromIntegral len) {-# INLINE encryptCTR #-}  decryptCTR :: AESKey            -> Ptr Word8 -- ^ IV+           -> Ptr Word8 -- ^ NEW IV            -> Ptr Word8 -- ^ CT            -> Ptr Word8 -- ^ PT            -> Int       -- ^ Length in bytes            -> IO () -decryptCTR (AESKey _ k) iv ct pt len = withForeignPtr k $ \p -> do-    c_decrypt_ctr p iv ct pt (fromIntegral len)+decryptCTR (AESKey _ k) iv niv ct pt len = withForeignPtr k $ \p -> do+    c_decrypt_ctr p iv niv ct pt (fromIntegral len) {-# INLINE decryptCTR #-}
cbits/aes/aes.c view
@@ -362,22 +362,27 @@         a->q[1] = cpu_to_be64(a1); } -void encrypt_ctr(AESKey *key, uint8_t *iv, uint8_t *output, uint8_t *input, uint32_t len)+void encrypt_ctr(const AESKey *key, const uint8_t *iv, uint8_t *newIV, uint8_t *output, const uint8_t *input, uint32_t len) {-        aes_block block, o;+        aes_block *block, o;         uint32_t nb_blocks = len / 16;         int i;          /* preload IV in block */-        block128_copy(&block, (aes_block *)iv);+        if(NULL != newIV)+            block = (aes_block*) newIV;+        else+            block = alloca(sizeof(aes_block)); -        for ( ; nb_blocks-- > 0; block128_inc_be(&block), output += 16, input += 16) {-                encrypt_ecb(key, (uint8_t *)&o, (uint8_t *)&block, 1);+        block128_copy(block, (aes_block *)iv);++        for ( ; nb_blocks-- > 0; block128_inc_be(block), output += 16, input += 16) {+                encrypt_ecb(key, (uint8_t *)&o, (uint8_t *)block, 1);                 block128_vxor((block128 *) output, &o, (block128 *) input);         }          if ((len % 16) != 0) {-                encrypt_ecb(key, (uint8_t *)&o, (uint8_t *)&block, 1);+                encrypt_ecb(key, (uint8_t *)&o, (uint8_t *)block, 1);                 for (i = 0; i < (len % 16); i++) {                         *output = ((uint8_t *) &o)[i] ^ *input;                         output += 1;
cbits/include/aes.h view
@@ -20,10 +20,11 @@                          , uint8_t *aad, uint32_t aadLen                          , uint8_t *ct, uint32_t ctLen                          , uint8_t *pt, uint8_t *tag);-void encrypt_ctr( AESKey *key-                    , uint8_t *iv-                    , uint8_t *dst-                    , uint8_t *src-                    , uint32_t nr);+void encrypt_ctr( const AESKey *key+                , const uint8_t *iv  /* 16 bytes buffer with the count */+                , uint8_t *newIV     /* the return buffer for the next IV (or NULL) */+                , uint8_t *dst       /* 'len' byte buffer for output */+                , const uint8_t *src /* 'len' bytes of input */+                , uint32_t len);     /* Length in bytes */  #endif
cipher-aes128.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/  name:                cipher-aes128-version:             0.2.5+version:             0.3 synopsis:            AES128 using AES-NI when available. description:         AES128 with crypto-api instances and a trampoline between Vincent Hanquez's C-based and x86 NI-based AES.  Patches welcome to add additional high-performance backends (ARM?) license:             BSD3@@ -29,7 +29,7 @@   exposed-modules:     Crypto.Cipher.AES128, Crypto.Cipher.AES128.Internal   build-depends:       base >=4.5 && < 5,                        bytestring,-                       crypto-api,+                       crypto-api >= 0.11,                        tagged,                        cereal   ghc-options:         -Wall -O2@@ -43,3 +43,15 @@ source-repository head   type:         git   location:     https://github.com/TomMD/cipher-aes128++benchmark bench+  type:         exitcode-stdio-1.0+  hs-source-dirs:       . Benchmark+  main-is:              bench.hs+  build-depends:        base < 5, criterion, crypto-api, entropy, bytestring, tagged, cereal+  ghc-options:          -O2+  include-dirs:        cbits/include+  c-sources:              ./cbits/aes/aes.c+                        , ./cbits/aes/ni/aes_x86ni.c+                        , ./cbits/aes/generic/aes_generic.c+  cc-options:          -O3