cipher-aes128 (empty) → 0.1
raw patch · 16 files changed
+1883/−0 lines, 16 filesdep +basedep +bytestringdep +cerealbuild-type:Customsetup-changed
Dependencies added: base, bytestring, cereal, crypto-api, tagged
Files
- AUTHORS +4/−0
- Crypto/Cipher/AES128.hs +46/−0
- Crypto/Cipher/AES128/Internal.hs +126/−0
- LICENSE +30/−0
- Setup.hs +74/−0
- cbits/aes/LICENSE +29/−0
- cbits/aes/aes.c +365/−0
- cbits/aes/generic/aes_generic.c +442/−0
- cbits/aes/ni/aes_x86ni.c +271/−0
- cbits/include/aes.h +24/−0
- cbits/include/aes_generic.h +36/−0
- cbits/include/aes_types.h +25/−0
- cbits/include/aes_x86ni.h +53/−0
- cbits/include/bitfn.h +232/−0
- cbits/include/block128.h +87/−0
- cipher-aes128.cabal +39/−0
+ AUTHORS view
@@ -0,0 +1,4 @@+Vincent Hanquez implemented, in C, the AES routines.++Thomas M. DuBuisson is the original author of the implementation selection+routines in cbits/aes/aes.c and Haskell bindings.
+ Crypto/Cipher/AES128.hs view
@@ -0,0 +1,46 @@+module Crypto.Cipher.AES128+ ( AESKey+ ) where++import Crypto.Cipher.AES128.Internal+import Crypto.Classes+import Data.Serialize+import Data.Tagged+import Foreign.Ptr+import System.IO.Unsafe+import qualified Data.ByteString as B+import qualified Data.ByteString.Internal as B+import qualified Data.ByteString.Unsafe as B++instance Serialize AESKey where+ put k = do+ let RKey l h = (rawKey k)+ putWord64be h+ putWord64be l++ get = do+ b <- getByteString 16+ case buildKey b of+ Nothing -> fail "Invalid key on 'get'"+ Just k -> return k++instance BlockCipher AESKey where+ blockSize = Tagged 128+ keyLength = Tagged 128+ buildKey bs + | B.length bs >= 16 = unsafePerformIO $+ B.unsafeUseAsCString bs $ \ptr -> do+ k <- generateKey (castPtr ptr)+ return (Just k)+ | otherwise = Nothing+ encryptBlock k b = unsafePerformIO $ do+ B.unsafeUseAsCStringLen b $ \(inP,len) -> do+ B.create (B.length b) $ \outP -> do+ encryptECB k (castPtr outP) (castPtr inP) (len`div`blkSize)+ decryptBlock k b = unsafePerformIO $ do+ B.unsafeUseAsCStringLen b $ \(inP,len) -> do+ B.create (B.length b) $ \outP -> do+ decryptECB k (castPtr outP) (castPtr inP) (len`div`blkSize)++blkSize :: Int+blkSize = 16
+ Crypto/Cipher/AES128/Internal.hs view
@@ -0,0 +1,126 @@+{-# LANGUAGE ForeignFunctionInterface, EmptyDataDecls #-}+module Crypto.Cipher.AES128.Internal+ ( AESKey(..), RawKey(..)+ , generateKey+ , encryptECB+ , decryptECB+ , encryptGCM+ , decryptGCM+ ) where++import Foreign.Ptr+import Foreign.ForeignPtr+import Foreign.Storable+import Data.Word+import Data.Bits (shiftL, (.|.))++-- AES Bindings+data AESKeyStruct+type AESKeyPtr = Ptr AESKeyStruct+data RawKey = RKey { lowK,highK :: {-# UNPACK #-} !Word64 }+data AESKey = AESKey { rawKey :: !RawKey+ , expandedKey :: ForeignPtr AESKeyStruct }++foreign import ccall unsafe "aes/aes.h generate_key128"+ c_generate_key128 :: AESKeyPtr -> Ptr Word8 -> IO ()++foreign import ccall unsafe "aes/aes.h allocate_key128"+ c_allocate_key128 :: IO AESKeyPtr++foreign import ccall unsafe "aes/aes.h &free_key128"+ c_free_key128 :: FunPtr (AESKeyPtr -> IO ())++foreign import ccall unsafe "aes/aes.h encrypt_ecb"+ c_encrypt_ecb :: AESKeyPtr -> Ptr Word8 -> Ptr Word8 -> Word32 -> IO ()++foreign import ccall unsafe "aes/aes.h decrypt_ecb"+ c_decrypt_ecb :: AESKeyPtr -> Ptr Word8 -> Ptr Word8 -> Word32 -> IO ()++foreign import ccall unsafe "aes/aes.h aes_gcm_full_encrypt"+ c_encrypt_gcm :: AESKeyPtr+ -> Ptr Word8 -> Word32 -- ^ IV and length+ -> Ptr Word8 -> Word32 -- ^ AAD and length+ -> Ptr Word8 -> Word32 -- ^ PT and length+ -> Ptr Word8 -> Ptr Word8 -- ^ Result CT and TAG+ -> IO ()++foreign import ccall unsafe "aes/aes.h aes_gcm_full_decrypt"+ c_decrypt_gcm :: AESKeyPtr+ -> Ptr Word8 -> Word32 -- ^ IV and length+ -> Ptr Word8 -> Word32 -- ^ AAD and length+ -> Ptr Word8 -> Word32 -- ^ CT and length+ -> Ptr Word8 -> Ptr Word8 -- ^ Result PT and TAG+ -> IO ()++blkSzC :: Word32+blkSzC = 16++-- Given a 16 byte buffer, allocate and return an AESKey+generateKey :: Ptr Word64 -- ^ Buffer of 16 bytes of key material+ -> IO AESKey+generateKey keyPtr = do+ k <- c_allocate_key128+ c_generate_key128 k (castPtr keyPtr)+ raw <- do+ a <- peekLE (castPtr keyPtr)+ let keyPtr2 = (castPtr keyPtr) `plusPtr` sizeOf a+ b <- peekLE keyPtr2+ return (RKey a b)+ fmap (AESKey raw) (newForeignPtr c_free_key128 k)+ where+ peekLE p = do+ a1 <- peekElemOff p 0+ a2 <- peekElemOff p 1+ a3 <- peekElemOff p 2+ a4 <- peekElemOff p 3+ a5 <- peekElemOff p 4+ a6 <- peekElemOff p 5+ a7 <- peekElemOff p 6+ a8 <- peekElemOff p 7+ let a = (a1 `shiftL` 56) .|. (a2 `shiftL` 48) .|. (a3 `shiftL` 40) .|.+ (a4 `shiftL` 32) .|. (a5 `shiftL` 24) .|. (a6 `shiftL` 16) .|.+ (a7 `shiftL` 8) .|. a8+ return a+{-# INLINE generateKey #-}++-- An encrypt function that can handle up to blks < maxBound `div` 16 :: Word32+-- simultaneous blocks.+encryptECB :: AESKey -- ^ The key+ -> Ptr Word8 -- ^ The result buffer+ -> Ptr Word8 -- ^ The source buffer+ -> Int -- ^ The input size in blocks+ -> IO ()+encryptECB (AESKey _ k) dst src blks = withForeignPtr k $ \p -> c_encrypt_ecb p dst src (fromIntegral blks)+{-# INLINE encryptECB #-}++decryptECB :: AESKey -- ^ The key+ -> Ptr Word8 -- ^ The result buffer+ -> Ptr Word8 -- ^ The source buffer+ -> Int -- ^ The input size in blocks+ -> IO ()+decryptECB (AESKey _ k) dst src blks+ | blks > fromIntegral (maxBound `div` blkSzC :: Word32) = error "Can not decrypt so many blocks at once"+ | otherwise = withForeignPtr k $ \p -> c_decrypt_ecb p dst src (fromIntegral blks)+{-# INLINE decryptECB #-}++encryptGCM :: AESKey+ -> Ptr Word8 -> Int -- IV+ -> Ptr Word8 -> Int -- AAD+ -> Ptr Word8 -> Int -- PT+ -> Ptr Word8 -- CT (output)+ -> Ptr Word8 -- Tag (output)+ -> IO ()+encryptGCM (AESKey _ k) iv ivLen aad aadLen pt ptLen ct tag = withForeignPtr k $ \p -> do+ c_encrypt_gcm p iv (fromIntegral ivLen) aad (fromIntegral aadLen) pt (fromIntegral ptLen) ct tag+{-# INLINE encryptGCM #-}++decryptGCM :: AESKey+ -> Ptr Word8 -> Int -- IV+ -> Ptr Word8 -> Int -- AAD+ -> Ptr Word8 -> Int -- CT+ -> Ptr Word8 -- PT (output)+ -> Ptr Word8 -- Tag (output)+ -> IO ()+decryptGCM (AESKey _ k) iv ivLen aad aadLen ct ctLen pt tag = withForeignPtr k $ \p -> do+ c_decrypt_gcm p iv (fromIntegral ivLen) aad (fromIntegral aadLen) ct (fromIntegral ctLen) pt tag+{-# INLINE decryptGCM #-}
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) Thomas DuBuisson++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met:++1. Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++2. Redistributions in binary form must reproduce the above copyright+ notice, this list of conditions and the following disclaimer in the+ documentation and/or other materials provided with the distribution.++3. Neither the name of the author nor the names of his contributors+ may be used to endorse or promote products derived from this software+ without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE+POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,74 @@+import Distribution.Simple+import Distribution.Simple.Setup+import Distribution.PackageDescription+import Distribution.Simple.Utils+import Distribution.Simple.Program+import Distribution.Verbosity+import System.Process+import System.Directory+import System.Exit++main = defaultMainWithHooks hk+ where+ hk = simpleUserHooks { preBuild = \as fs -> do+ b <- (preBuild simpleUserHooks) as fs+ checkAndAddAES fs b }++checkAndAddAES :: BuildFlags -> HookedBuildInfo -> IO HookedBuildInfo+checkAndAddAES fs x@(m,as) = do+ b <- canUseAesIntrinsicsFlag fs+ b2 <- haveNIInstrs fs+ let bi = maybe emptyBuildInfo id m+ op = if b && b2 then addNIintrinsicOpt else id+ return (Just (op emptyBuildInfo), as)++addNIintrinsicOpt :: BuildInfo -> BuildInfo+addNIintrinsicOpt bi = bi { ccOptions = ccOptions bi ++ ["-maes", "-mssse3", "-DHAVE_AES_INTRINSICS", "-DHAVE_NI"] }++-- Detect if we have AES NI instructions for acceleration on x86 CPUs+haveNIInstrs :: BuildFlags -> IO Bool+haveNIInstrs cf = do+ -- FIXME cf is always empty, how do we ensure we're testing the right C compiler?+ -- TODO: I am hooking Cabal at the wrong spot, need to hook one stage+ -- later!+ let prog = lookup "cc" (buildProgramPaths cf)+ cc = maybe "gcc" id prog+ withTempDirectory normal "" "testNI" $ \tmpDir -> do+ writeFile (tmpDir ++ "/testNI.c")+ (unlines ["#include <stdint.h>",+ "/**",+ " * Returns zero if false, non-zero otherwise",+ " */",+ "int cpu_has_ni()",+ "{",+ "uint32_t ax,bx,cx,dx,func=1;",+ "uint32_t regs[4];",+ "asm volatile (\"cpuid\":",+ "\"=a\" (ax), \"=b\" (bx), \"=c\" (cx), \"=d\" (dx) : \"a\" (func));",+ "return (cx & 0x2000000);",+ "}",+ "int main()",+ "{",+ " if(cpu_has_ni()) return 0; else return -1;",+ "}"]+ )+ ec <- rawSystemExitCode normal cc ["-maes",tmpDir ++ "/testNI.c"]+ notice normal $ "Result of AES NI Test: " ++ show (ec == ExitSuccess)+ return (ec == ExitSuccess)++canUseAesIntrinsicsFlag :: BuildFlags -> IO Bool+canUseAesIntrinsicsFlag cf = do+ -- FIXME cf is always empty, how do we ensure we're testing the right C compiler?+ -- TODO: I am hooking Cabal at the wrong spot, need to hook one stage+ -- later!+ let prog = lookup "cc" (buildProgramPaths cf)+ cc = maybe "gcc" id prog+ withTempDirectory normal "" "testIntrinsic" $ \tmpDir -> do+ writeFile (tmpDir ++ "/testIntrinsic.c")+ (unlines [ "#include <wmmintrin.h>"+ , "int main() {"+ , "return 0; }"+ ])+ ec <- rawSystemExitCode normal cc ["-maes",tmpDir ++ "/testIntrinsic.c"]+ notice normal $ "Result of NI Intrinsics Test: " ++ show (ec == ExitSuccess)+ return (ec == ExitSuccess)
+ cbits/aes/LICENSE view
@@ -0,0 +1,29 @@+This license applies to the ni/* generic/* source code and associated header files.++Copyright (c) 2010-2011 Vincent Hanquez <vincent@snarc.org>++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met:+1. Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.+2. Redistributions in binary form must reproduce the above copyright+ notice, this list of conditions and the following disclaimer in the+ documentation and/or other materials provided with the distribution.+3. Neither the name of the author nor the names of his contributors+ may be used to endorse or promote products derived from this software+ without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF+SUCH DAMAGE.
+ cbits/aes/aes.c view
@@ -0,0 +1,365 @@+#include "aes_generic.h"+#include "aes.h"+#include <string.h>+#include <stdlib.h>++/* The "HAVE_NI" macro is also defined (or not) but we no longer need that+ * since we're doing a runtime detection... again. */+#if (defined(__i386__) || defined(__x86_64__)) && defined(HAVE_AES_INTRINSICS) && !defined(AVOID_NI)+#define TRY_NI+#include "aes_x86ni.h"+#endif+#include "bitfn.h"+void gf_mul(block128 *a, block128 *b);++#ifdef TRY_NI+/**+ * Returns zero if false, non-zero otherwise+ */+int cpu_has_ni()+{+ uint32_t ax,bx,cx,dx,func=1;++ __asm__ volatile ("cpuid":\+ "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx) : "a" (func));+ return (cx & 0x2000000);+}+#endif++/* Allocation */+AESKey *allocate_key128()+{+ void *k=NULL;+ k = (void *)malloc(sizeof(aes_key));+ return k;+}++/* Generate Key */+#ifdef TRY_NI+void detect_and_generate_key128(AESKey *k, const uint8_t *bytes);+void (*generate_key128_ptr)(AESKey *,const uint8_t *) = &detect_and_generate_key128;++/**+ * Expand a 128 bit AES key.+ */+void generate_key128(AESKey *k, const uint8_t *bytes)+{+ (*generate_key128_ptr)(k,bytes);+}++void generate_key128_generic(AESKey *k, const uint8_t *bytes)+{+ aes_generic_init(k, bytes, 16);+}++void generate_key128_ni(AESKey *k, const uint8_t *bytes)+{+ aes_ni_init((aes_key *)k, bytes, 16);+}++void detect_and_generate_key128(AESKey *k, const uint8_t *bytes)+{+ if(cpu_has_ni()) {+ generate_key128_ptr = &generate_key128_ni;+ } else {+ generate_key128_ptr = &generate_key128_generic;+ }+ (*generate_key128_ptr)(k,bytes);+}++#else+void generate_key128(AESKey *k, const uint8_t *bytes)+{+ aes_generic_init(k, bytes, 16);+}+#endif++void free_key128(AESKey *k)+{+ memset(k, 0, sizeof(AESKey));+ free(k);+}++/* ECB Encrypt */+#ifdef TRY_NI+void detect_and_encrypt_ecb(const AESKey *k, uint8_t *dst, const uint8_t *src, const uint32_t nr);+void (*encrypt_ecb_ptr)(const AESKey *, uint8_t *, const uint8_t *, const uint32_t) = &detect_and_encrypt_ecb;++void encrypt_ecb_ni(const AESKey *k, uint8_t *dst, const uint8_t *src, const uint32_t nr)+{+ aes_ni_encrypt_ecb(dst, (aes_key *)k, src, nr);+}++void encrypt_ecb_generic(const AESKey *k, uint8_t *dst, const uint8_t *src, const uint32_t nr)+{+ int i;+ for(i = 0; i<nr*16; i+=16) {+ aes_generic_encrypt_block+ ( (aes_block*) dst+i+ , k+ , (const aes_block*)src+i);+ }+}++void encrypt_ecb(const AESKey *k, uint8_t *dst, const uint8_t *src, const uint32_t nr)+{+ (*encrypt_ecb_ptr)(k,dst,src,nr);+}++void detect_and_encrypt_ecb(const AESKey *k, uint8_t *dst, const uint8_t *src, const uint32_t nr)+{+ if(cpu_has_ni()) encrypt_ecb_ptr = &encrypt_ecb_ni;+ else encrypt_ecb_ptr = &encrypt_ecb_generic;+ (*encrypt_ecb_ptr)(k,dst,src,nr);+}+#else+void encrypt_ecb(const AESKey *k, uint8_t *dst, const uint8_t *src, const uint32_t nr)+{+ int i;+ for(i = 0; i<nr*16; i+=16) {+ aes_generic_encrypt_block+ ( (aes_block*) dst+i+ , k+ , (const aes_block*)src+i);+ }+}+#endif++/* ECB Decrypt */+#ifdef TRY_NI+void detect_and_decrypt_ecb(const AESKey *k, uint8_t *dst, const uint8_t *src, const uint32_t nr);+void (*decrypt_ecb_ptr)(const AESKey *k, uint8_t *dst, const uint8_t *src, const uint32_t nr) = &detect_and_decrypt_ecb;++void decrypt_ecb(const AESKey *k, uint8_t *dst, const uint8_t *src, const uint32_t nr)+{+ (*decrypt_ecb_ptr)(k,dst,src,nr);+}++void decrypt_ecb_ni(const AESKey *k, uint8_t *dst, const uint8_t *src, const uint32_t nr)+{+ aes_ni_decrypt_ecb(dst, (aes_key *)k, src, nr);+}++void decrypt_ecb_generic(const AESKey *k, uint8_t *dst, const uint8_t *src, const uint32_t nr)+{+ int i;+ for(i = 0; i<nr*16; i+=16) {+ aes_generic_decrypt_block ( (aes_block*) dst+i+ , k+ , (const aes_block*)src+i);+ }+}++void detect_and_decrypt_ecb(const AESKey *k, uint8_t *dst, const uint8_t *src, const uint32_t nr)+{+ if(cpu_has_ni()) decrypt_ecb_ptr = &decrypt_ecb_ni;+ else decrypt_ecb_ptr = &decrypt_ecb_generic;+ (*decrypt_ecb_ptr)(k,dst,src,nr);+}+#else+void decrypt_ecb(const AESKey *k, uint8_t *dst, const uint8_t *src, const uint32_t nr)+{+ int i;+ for(i = 0; i<nr*16; i+=16) {+ aes_generic_decrypt_block ( (aes_block*) dst+i+ , k+ , (const aes_block*)src+i);+ }+}+#endif+++/* GCM */+static void gcm_ghash_add(aes_gcm *gcm, block128 *b)+{+ block128_xor(&gcm->tag, b);+ gf_mul(&gcm->tag, &gcm->h);+}++void aes_gcm_init(aes_gcm *gcm, const aes_key *key, uint8_t *iv, uint32_t len)+{+ gcm->length_aad = 0;+ gcm->length_input = 0;++ block128_zero(&gcm->h);+ block128_zero(&gcm->tag);+ block128_zero(&gcm->iv);++ memcpy(&gcm->key, key, sizeof(aes_key));++ /* prepare H : encrypt_K(0^128) */+ encrypt_ecb(key, (uint8_t *)&gcm->h, (const uint8_t *)&gcm->h, 1);++ if (len == 12) {+ block128_copy_bytes(&gcm->iv, iv, 12);+ gcm->iv.b[15] = 0x01;+ } else {+ uint32_t origlen = len << 3;+ int i;+ for (; len >= 16; len -= 16, iv += 16) {+ block128_xor(&gcm->iv, (block128 *) iv);+ gf_mul(&gcm->iv, &gcm->h);+ }+ if (len > 0) {+ block128_xor_bytes(&gcm->iv, iv, len);+ gf_mul(&gcm->iv, &gcm->h);+ }+ for (i = 15; origlen; --i, origlen >>= 8)+ gcm->iv.b[i] ^= (uint8_t) origlen;+ gf_mul(&gcm->iv, &gcm->h);+ }++ block128_copy(&gcm->civ, &gcm->iv);+}++void aes_gcm_aad(aes_gcm *gcm, uint8_t *input, uint32_t length)+{+ gcm->length_aad += length;+ for (; length >= 16; input += 16, length -= 16) {+ gcm_ghash_add(gcm, (block128 *) input);+ }+ if (length > 0) {+ aes_block tmp;+ block128_zero(&tmp);+ block128_copy_bytes(&tmp, input, length);+ gcm_ghash_add(gcm, &tmp);+ }++}++void aes_gcm_encrypt(uint8_t *output, aes_gcm *gcm, uint8_t *input, uint32_t length)+{+ aes_block out;++ gcm->length_input += length;+ for (; length >= 16; input += 16, output += 16, length -= 16) {+ block128_inc_be(&gcm->civ);++ encrypt_ecb(&gcm->key, (uint8_t *)&out, (const uint8_t *)&gcm->civ, 1);+ block128_xor(&out, (block128 *) input);+ gcm_ghash_add(gcm, &out);+ block128_copy((block128 *) output, &out);+ }+ if (length > 0) {+ aes_block tmp;+ int i;++ block128_inc_be(&gcm->civ);+ /* create e(civ) in out */+ encrypt_ecb(&gcm->key, (uint8_t *)&out, (const uint8_t *)&gcm->civ, 1);+ /* initialize a tmp as input and xor it to e(civ) */+ block128_zero(&tmp);+ block128_copy_bytes(&tmp, input, length);+ block128_xor_bytes(&tmp, out.b, length); ++ gcm_ghash_add(gcm, &tmp);++ for (i = 0; i < length; i++) {+ output[i] = tmp.b[i];+ }+ }+}++void aes_gcm_decrypt(uint8_t *output, aes_gcm *gcm, uint8_t *input, uint32_t length)+{+ aes_block out;++ gcm->length_input += length;+ for (; length >= 16; input += 16, output += 16, length -= 16) {+ block128_inc_be(&gcm->civ);++ encrypt_ecb(&gcm->key, (uint8_t *)&out, (const uint8_t *)&gcm->civ, 1);+ gcm_ghash_add(gcm, (block128 *) input);+ block128_xor(&out, (block128 *) input);+ block128_copy((block128 *) output, &out);+ }+ if (length > 0) {+ aes_block tmp;+ int i;++ block128_inc_be(&gcm->civ);++ block128_zero(&tmp);+ block128_copy_bytes(&tmp, input, length);+ gcm_ghash_add(gcm, &tmp);++ encrypt_ecb(&gcm->key, (uint8_t *)&out, (const uint8_t *)&gcm->civ, 1);+ block128_xor_bytes(&tmp, out.b, length); ++ for (i = 0; i < length; i++) {+ output[i] = tmp.b[i];+ }+ }+}++void aes_gcm_finish(uint8_t *tag, aes_gcm *gcm)+{+ aes_block lblock;+ int i;++ /* tag = (tag-1 xor (lenbits(a) | lenbits(c)) ) . H */+ lblock.q[0] = cpu_to_be64(gcm->length_aad << 3);+ lblock.q[1] = cpu_to_be64(gcm->length_input << 3);+ gcm_ghash_add(gcm, &lblock);++ encrypt_ecb(&gcm->key, (uint8_t *)&lblock, (const uint8_t*)&gcm->iv, 1);+ block128_xor(&gcm->tag, &lblock);++ for (i = 0; i < 16; i++) {+ tag[i] = gcm->tag.b[i];+ }+}++void aes_gcm_full_encrypt( const AESKey *k+ , uint8_t *iv, uint32_t ivLen+ , uint8_t *aad, uint32_t aadLen+ , uint8_t *pt, uint32_t ptLen+ , uint8_t *ct, uint8_t *tag)+{+ aes_gcm gcm;+ aes_gcm_init(&gcm, k, iv, ivLen);+ aes_gcm_aad(&gcm, aad, aadLen);+ aes_gcm_encrypt(ct, &gcm, pt, ptLen);+ aes_gcm_finish(tag, &gcm);+}++void aes_gcm_full_decrypt( const AESKey *k+ , uint8_t *iv, uint32_t ivLen+ , uint8_t *aad, uint32_t aadLen+ , uint8_t *ct, uint32_t ctLen+ , uint8_t *pt, uint8_t *tag)+{+ aes_gcm gcm;+ aes_gcm_init(&gcm, k, iv, ivLen);+ aes_gcm_aad(&gcm, aad, aadLen);+ aes_gcm_decrypt(pt, &gcm, ct, ctLen);+ aes_gcm_finish(tag, &gcm);+}+++/* this is a really inefficient way to GF multiply.+ * the alternative without hw accel is building small tables+ * to speed up the multiplication.+ * TODO: optimise with tables+ */+void gf_mul(block128 *a, block128 *b)+{+ uint64_t a0, a1, v0, v1;+ int i, j;++ a0 = a1 = 0;+ v0 = cpu_to_be64(a->q[0]);+ v1 = cpu_to_be64(a->q[1]);++ for (i = 0; i < 16; i++)+ for (j = 0x80; j != 0; j >>= 1) {+ uint8_t x = b->b[i] & j;+ a0 ^= x ? v0 : 0;+ a1 ^= x ? v1 : 0;+ x = (uint8_t) v1 & 1;+ v1 = (v1 >> 1) | (v0 << 63);+ v0 = (v0 >> 1) ^ (x ? (0xe1ULL << 56) : 0);+ }+ a->q[0] = cpu_to_be64(a0);+ a->q[1] = cpu_to_be64(a1);+}
+ cbits/aes/generic/aes_generic.c view
@@ -0,0 +1,442 @@+/*+ * Copyright (C) 2008 Vincent Hanquez <vincent@snarc.org>+ *+ * All rights reserved.+ * + * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ * 1. Redistributions of source code must retain the above copyright+ * notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ * notice, this list of conditions and the following disclaimer in the+ * documentation and/or other materials provided with the distribution.+ * 3. Neither the name of the author nor the names of his contributors+ * may be used to endorse or promote products derived from this software+ * without specific prior written permission.+ * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF+ * SUCH DAMAGE.+ *+ * AES implementation+ */++#include <stdint.h>+#include <stdlib.h>+#include "aes_types.h"+#include "bitfn.h"++static uint8_t sbox[256] = {+ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe,+ 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4,+ 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7,+ 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3,+ 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 0x09,+ 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3,+ 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe,+ 0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,+ 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92,+ 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c,+ 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19,+ 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14,+ 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2,+ 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5,+ 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 0xba, 0x78, 0x25,+ 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,+ 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86,+ 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e,+ 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42,+ 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16+};++static uint8_t rsbox[256] = {+ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81,+ 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e,+ 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23,+ 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 0x08, 0x2e, 0xa1, 0x66,+ 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 0x72,+ 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65,+ 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46,+ 0x57, 0xa7, 0x8d, 0x9d, 0x84, 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,+ 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca,+ 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91,+ 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6,+ 0x73, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8,+ 0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f,+ 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2,+ 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, 0x1f, 0xdd, 0xa8,+ 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,+ 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93,+ 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb,+ 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6,+ 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d+};++static uint8_t Rcon[] = {+ 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,+ 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,+ 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,+ 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb,+};++#define G(a,b,c,d,e,f) { a,b,c,d,e,f }+uint8_t gmtab[256][6] =+{+ G(0x00, 0x00, 0x00, 0x00, 0x00, 0x00), G(0x02, 0x03, 0x09, 0x0b, 0x0d, 0x0e),+ G(0x04, 0x06, 0x12, 0x16, 0x1a, 0x1c), G(0x06, 0x05, 0x1b, 0x1d, 0x17, 0x12),+ G(0x08, 0x0c, 0x24, 0x2c, 0x34, 0x38), G(0x0a, 0x0f, 0x2d, 0x27, 0x39, 0x36),+ G(0x0c, 0x0a, 0x36, 0x3a, 0x2e, 0x24), G(0x0e, 0x09, 0x3f, 0x31, 0x23, 0x2a),+ G(0x10, 0x18, 0x48, 0x58, 0x68, 0x70), G(0x12, 0x1b, 0x41, 0x53, 0x65, 0x7e),+ G(0x14, 0x1e, 0x5a, 0x4e, 0x72, 0x6c), G(0x16, 0x1d, 0x53, 0x45, 0x7f, 0x62),+ G(0x18, 0x14, 0x6c, 0x74, 0x5c, 0x48), G(0x1a, 0x17, 0x65, 0x7f, 0x51, 0x46),+ G(0x1c, 0x12, 0x7e, 0x62, 0x46, 0x54), G(0x1e, 0x11, 0x77, 0x69, 0x4b, 0x5a),+ G(0x20, 0x30, 0x90, 0xb0, 0xd0, 0xe0), G(0x22, 0x33, 0x99, 0xbb, 0xdd, 0xee),+ G(0x24, 0x36, 0x82, 0xa6, 0xca, 0xfc), G(0x26, 0x35, 0x8b, 0xad, 0xc7, 0xf2),+ G(0x28, 0x3c, 0xb4, 0x9c, 0xe4, 0xd8), G(0x2a, 0x3f, 0xbd, 0x97, 0xe9, 0xd6),+ G(0x2c, 0x3a, 0xa6, 0x8a, 0xfe, 0xc4), G(0x2e, 0x39, 0xaf, 0x81, 0xf3, 0xca),+ G(0x30, 0x28, 0xd8, 0xe8, 0xb8, 0x90), G(0x32, 0x2b, 0xd1, 0xe3, 0xb5, 0x9e),+ G(0x34, 0x2e, 0xca, 0xfe, 0xa2, 0x8c), G(0x36, 0x2d, 0xc3, 0xf5, 0xaf, 0x82),+ G(0x38, 0x24, 0xfc, 0xc4, 0x8c, 0xa8), G(0x3a, 0x27, 0xf5, 0xcf, 0x81, 0xa6),+ G(0x3c, 0x22, 0xee, 0xd2, 0x96, 0xb4), G(0x3e, 0x21, 0xe7, 0xd9, 0x9b, 0xba),+ G(0x40, 0x60, 0x3b, 0x7b, 0xbb, 0xdb), G(0x42, 0x63, 0x32, 0x70, 0xb6, 0xd5),+ G(0x44, 0x66, 0x29, 0x6d, 0xa1, 0xc7), G(0x46, 0x65, 0x20, 0x66, 0xac, 0xc9),+ G(0x48, 0x6c, 0x1f, 0x57, 0x8f, 0xe3), G(0x4a, 0x6f, 0x16, 0x5c, 0x82, 0xed),+ G(0x4c, 0x6a, 0x0d, 0x41, 0x95, 0xff), G(0x4e, 0x69, 0x04, 0x4a, 0x98, 0xf1),+ G(0x50, 0x78, 0x73, 0x23, 0xd3, 0xab), G(0x52, 0x7b, 0x7a, 0x28, 0xde, 0xa5),+ G(0x54, 0x7e, 0x61, 0x35, 0xc9, 0xb7), G(0x56, 0x7d, 0x68, 0x3e, 0xc4, 0xb9),+ G(0x58, 0x74, 0x57, 0x0f, 0xe7, 0x93), G(0x5a, 0x77, 0x5e, 0x04, 0xea, 0x9d),+ G(0x5c, 0x72, 0x45, 0x19, 0xfd, 0x8f), G(0x5e, 0x71, 0x4c, 0x12, 0xf0, 0x81),+ G(0x60, 0x50, 0xab, 0xcb, 0x6b, 0x3b), G(0x62, 0x53, 0xa2, 0xc0, 0x66, 0x35),+ G(0x64, 0x56, 0xb9, 0xdd, 0x71, 0x27), G(0x66, 0x55, 0xb0, 0xd6, 0x7c, 0x29),+ G(0x68, 0x5c, 0x8f, 0xe7, 0x5f, 0x03), G(0x6a, 0x5f, 0x86, 0xec, 0x52, 0x0d),+ G(0x6c, 0x5a, 0x9d, 0xf1, 0x45, 0x1f), G(0x6e, 0x59, 0x94, 0xfa, 0x48, 0x11),+ G(0x70, 0x48, 0xe3, 0x93, 0x03, 0x4b), G(0x72, 0x4b, 0xea, 0x98, 0x0e, 0x45),+ G(0x74, 0x4e, 0xf1, 0x85, 0x19, 0x57), G(0x76, 0x4d, 0xf8, 0x8e, 0x14, 0x59),+ G(0x78, 0x44, 0xc7, 0xbf, 0x37, 0x73), G(0x7a, 0x47, 0xce, 0xb4, 0x3a, 0x7d),+ G(0x7c, 0x42, 0xd5, 0xa9, 0x2d, 0x6f), G(0x7e, 0x41, 0xdc, 0xa2, 0x20, 0x61),+ G(0x80, 0xc0, 0x76, 0xf6, 0x6d, 0xad), G(0x82, 0xc3, 0x7f, 0xfd, 0x60, 0xa3),+ G(0x84, 0xc6, 0x64, 0xe0, 0x77, 0xb1), G(0x86, 0xc5, 0x6d, 0xeb, 0x7a, 0xbf),+ G(0x88, 0xcc, 0x52, 0xda, 0x59, 0x95), G(0x8a, 0xcf, 0x5b, 0xd1, 0x54, 0x9b),+ G(0x8c, 0xca, 0x40, 0xcc, 0x43, 0x89), G(0x8e, 0xc9, 0x49, 0xc7, 0x4e, 0x87),+ G(0x90, 0xd8, 0x3e, 0xae, 0x05, 0xdd), G(0x92, 0xdb, 0x37, 0xa5, 0x08, 0xd3),+ G(0x94, 0xde, 0x2c, 0xb8, 0x1f, 0xc1), G(0x96, 0xdd, 0x25, 0xb3, 0x12, 0xcf),+ G(0x98, 0xd4, 0x1a, 0x82, 0x31, 0xe5), G(0x9a, 0xd7, 0x13, 0x89, 0x3c, 0xeb),+ G(0x9c, 0xd2, 0x08, 0x94, 0x2b, 0xf9), G(0x9e, 0xd1, 0x01, 0x9f, 0x26, 0xf7),+ G(0xa0, 0xf0, 0xe6, 0x46, 0xbd, 0x4d), G(0xa2, 0xf3, 0xef, 0x4d, 0xb0, 0x43),+ G(0xa4, 0xf6, 0xf4, 0x50, 0xa7, 0x51), G(0xa6, 0xf5, 0xfd, 0x5b, 0xaa, 0x5f),+ G(0xa8, 0xfc, 0xc2, 0x6a, 0x89, 0x75), G(0xaa, 0xff, 0xcb, 0x61, 0x84, 0x7b),+ G(0xac, 0xfa, 0xd0, 0x7c, 0x93, 0x69), G(0xae, 0xf9, 0xd9, 0x77, 0x9e, 0x67),+ G(0xb0, 0xe8, 0xae, 0x1e, 0xd5, 0x3d), G(0xb2, 0xeb, 0xa7, 0x15, 0xd8, 0x33),+ G(0xb4, 0xee, 0xbc, 0x08, 0xcf, 0x21), G(0xb6, 0xed, 0xb5, 0x03, 0xc2, 0x2f),+ G(0xb8, 0xe4, 0x8a, 0x32, 0xe1, 0x05), G(0xba, 0xe7, 0x83, 0x39, 0xec, 0x0b),+ G(0xbc, 0xe2, 0x98, 0x24, 0xfb, 0x19), G(0xbe, 0xe1, 0x91, 0x2f, 0xf6, 0x17),+ G(0xc0, 0xa0, 0x4d, 0x8d, 0xd6, 0x76), G(0xc2, 0xa3, 0x44, 0x86, 0xdb, 0x78),+ G(0xc4, 0xa6, 0x5f, 0x9b, 0xcc, 0x6a), G(0xc6, 0xa5, 0x56, 0x90, 0xc1, 0x64),+ G(0xc8, 0xac, 0x69, 0xa1, 0xe2, 0x4e), G(0xca, 0xaf, 0x60, 0xaa, 0xef, 0x40),+ G(0xcc, 0xaa, 0x7b, 0xb7, 0xf8, 0x52), G(0xce, 0xa9, 0x72, 0xbc, 0xf5, 0x5c),+ G(0xd0, 0xb8, 0x05, 0xd5, 0xbe, 0x06), G(0xd2, 0xbb, 0x0c, 0xde, 0xb3, 0x08),+ G(0xd4, 0xbe, 0x17, 0xc3, 0xa4, 0x1a), G(0xd6, 0xbd, 0x1e, 0xc8, 0xa9, 0x14),+ G(0xd8, 0xb4, 0x21, 0xf9, 0x8a, 0x3e), G(0xda, 0xb7, 0x28, 0xf2, 0x87, 0x30),+ G(0xdc, 0xb2, 0x33, 0xef, 0x90, 0x22), G(0xde, 0xb1, 0x3a, 0xe4, 0x9d, 0x2c),+ G(0xe0, 0x90, 0xdd, 0x3d, 0x06, 0x96), G(0xe2, 0x93, 0xd4, 0x36, 0x0b, 0x98),+ G(0xe4, 0x96, 0xcf, 0x2b, 0x1c, 0x8a), G(0xe6, 0x95, 0xc6, 0x20, 0x11, 0x84),+ G(0xe8, 0x9c, 0xf9, 0x11, 0x32, 0xae), G(0xea, 0x9f, 0xf0, 0x1a, 0x3f, 0xa0),+ G(0xec, 0x9a, 0xeb, 0x07, 0x28, 0xb2), G(0xee, 0x99, 0xe2, 0x0c, 0x25, 0xbc),+ G(0xf0, 0x88, 0x95, 0x65, 0x6e, 0xe6), G(0xf2, 0x8b, 0x9c, 0x6e, 0x63, 0xe8),+ G(0xf4, 0x8e, 0x87, 0x73, 0x74, 0xfa), G(0xf6, 0x8d, 0x8e, 0x78, 0x79, 0xf4),+ G(0xf8, 0x84, 0xb1, 0x49, 0x5a, 0xde), G(0xfa, 0x87, 0xb8, 0x42, 0x57, 0xd0),+ G(0xfc, 0x82, 0xa3, 0x5f, 0x40, 0xc2), G(0xfe, 0x81, 0xaa, 0x54, 0x4d, 0xcc),+ G(0x1b, 0x9b, 0xec, 0xf7, 0xda, 0x41), G(0x19, 0x98, 0xe5, 0xfc, 0xd7, 0x4f),+ G(0x1f, 0x9d, 0xfe, 0xe1, 0xc0, 0x5d), G(0x1d, 0x9e, 0xf7, 0xea, 0xcd, 0x53),+ G(0x13, 0x97, 0xc8, 0xdb, 0xee, 0x79), G(0x11, 0x94, 0xc1, 0xd0, 0xe3, 0x77),+ G(0x17, 0x91, 0xda, 0xcd, 0xf4, 0x65), G(0x15, 0x92, 0xd3, 0xc6, 0xf9, 0x6b),+ G(0x0b, 0x83, 0xa4, 0xaf, 0xb2, 0x31), G(0x09, 0x80, 0xad, 0xa4, 0xbf, 0x3f),+ G(0x0f, 0x85, 0xb6, 0xb9, 0xa8, 0x2d), G(0x0d, 0x86, 0xbf, 0xb2, 0xa5, 0x23),+ G(0x03, 0x8f, 0x80, 0x83, 0x86, 0x09), G(0x01, 0x8c, 0x89, 0x88, 0x8b, 0x07),+ G(0x07, 0x89, 0x92, 0x95, 0x9c, 0x15), G(0x05, 0x8a, 0x9b, 0x9e, 0x91, 0x1b),+ G(0x3b, 0xab, 0x7c, 0x47, 0x0a, 0xa1), G(0x39, 0xa8, 0x75, 0x4c, 0x07, 0xaf),+ G(0x3f, 0xad, 0x6e, 0x51, 0x10, 0xbd), G(0x3d, 0xae, 0x67, 0x5a, 0x1d, 0xb3),+ G(0x33, 0xa7, 0x58, 0x6b, 0x3e, 0x99), G(0x31, 0xa4, 0x51, 0x60, 0x33, 0x97),+ G(0x37, 0xa1, 0x4a, 0x7d, 0x24, 0x85), G(0x35, 0xa2, 0x43, 0x76, 0x29, 0x8b),+ G(0x2b, 0xb3, 0x34, 0x1f, 0x62, 0xd1), G(0x29, 0xb0, 0x3d, 0x14, 0x6f, 0xdf),+ G(0x2f, 0xb5, 0x26, 0x09, 0x78, 0xcd), G(0x2d, 0xb6, 0x2f, 0x02, 0x75, 0xc3),+ G(0x23, 0xbf, 0x10, 0x33, 0x56, 0xe9), G(0x21, 0xbc, 0x19, 0x38, 0x5b, 0xe7),+ G(0x27, 0xb9, 0x02, 0x25, 0x4c, 0xf5), G(0x25, 0xba, 0x0b, 0x2e, 0x41, 0xfb),+ G(0x5b, 0xfb, 0xd7, 0x8c, 0x61, 0x9a), G(0x59, 0xf8, 0xde, 0x87, 0x6c, 0x94),+ G(0x5f, 0xfd, 0xc5, 0x9a, 0x7b, 0x86), G(0x5d, 0xfe, 0xcc, 0x91, 0x76, 0x88),+ G(0x53, 0xf7, 0xf3, 0xa0, 0x55, 0xa2), G(0x51, 0xf4, 0xfa, 0xab, 0x58, 0xac),+ G(0x57, 0xf1, 0xe1, 0xb6, 0x4f, 0xbe), G(0x55, 0xf2, 0xe8, 0xbd, 0x42, 0xb0),+ G(0x4b, 0xe3, 0x9f, 0xd4, 0x09, 0xea), G(0x49, 0xe0, 0x96, 0xdf, 0x04, 0xe4),+ G(0x4f, 0xe5, 0x8d, 0xc2, 0x13, 0xf6), G(0x4d, 0xe6, 0x84, 0xc9, 0x1e, 0xf8),+ G(0x43, 0xef, 0xbb, 0xf8, 0x3d, 0xd2), G(0x41, 0xec, 0xb2, 0xf3, 0x30, 0xdc),+ G(0x47, 0xe9, 0xa9, 0xee, 0x27, 0xce), G(0x45, 0xea, 0xa0, 0xe5, 0x2a, 0xc0),+ G(0x7b, 0xcb, 0x47, 0x3c, 0xb1, 0x7a), G(0x79, 0xc8, 0x4e, 0x37, 0xbc, 0x74),+ G(0x7f, 0xcd, 0x55, 0x2a, 0xab, 0x66), G(0x7d, 0xce, 0x5c, 0x21, 0xa6, 0x68),+ G(0x73, 0xc7, 0x63, 0x10, 0x85, 0x42), G(0x71, 0xc4, 0x6a, 0x1b, 0x88, 0x4c),+ G(0x77, 0xc1, 0x71, 0x06, 0x9f, 0x5e), G(0x75, 0xc2, 0x78, 0x0d, 0x92, 0x50),+ G(0x6b, 0xd3, 0x0f, 0x64, 0xd9, 0x0a), G(0x69, 0xd0, 0x06, 0x6f, 0xd4, 0x04),+ G(0x6f, 0xd5, 0x1d, 0x72, 0xc3, 0x16), G(0x6d, 0xd6, 0x14, 0x79, 0xce, 0x18),+ G(0x63, 0xdf, 0x2b, 0x48, 0xed, 0x32), G(0x61, 0xdc, 0x22, 0x43, 0xe0, 0x3c),+ G(0x67, 0xd9, 0x39, 0x5e, 0xf7, 0x2e), G(0x65, 0xda, 0x30, 0x55, 0xfa, 0x20),+ G(0x9b, 0x5b, 0x9a, 0x01, 0xb7, 0xec), G(0x99, 0x58, 0x93, 0x0a, 0xba, 0xe2),+ G(0x9f, 0x5d, 0x88, 0x17, 0xad, 0xf0), G(0x9d, 0x5e, 0x81, 0x1c, 0xa0, 0xfe),+ G(0x93, 0x57, 0xbe, 0x2d, 0x83, 0xd4), G(0x91, 0x54, 0xb7, 0x26, 0x8e, 0xda),+ G(0x97, 0x51, 0xac, 0x3b, 0x99, 0xc8), G(0x95, 0x52, 0xa5, 0x30, 0x94, 0xc6),+ G(0x8b, 0x43, 0xd2, 0x59, 0xdf, 0x9c), G(0x89, 0x40, 0xdb, 0x52, 0xd2, 0x92),+ G(0x8f, 0x45, 0xc0, 0x4f, 0xc5, 0x80), G(0x8d, 0x46, 0xc9, 0x44, 0xc8, 0x8e),+ G(0x83, 0x4f, 0xf6, 0x75, 0xeb, 0xa4), G(0x81, 0x4c, 0xff, 0x7e, 0xe6, 0xaa),+ G(0x87, 0x49, 0xe4, 0x63, 0xf1, 0xb8), G(0x85, 0x4a, 0xed, 0x68, 0xfc, 0xb6),+ G(0xbb, 0x6b, 0x0a, 0xb1, 0x67, 0x0c), G(0xb9, 0x68, 0x03, 0xba, 0x6a, 0x02),+ G(0xbf, 0x6d, 0x18, 0xa7, 0x7d, 0x10), G(0xbd, 0x6e, 0x11, 0xac, 0x70, 0x1e),+ G(0xb3, 0x67, 0x2e, 0x9d, 0x53, 0x34), G(0xb1, 0x64, 0x27, 0x96, 0x5e, 0x3a),+ G(0xb7, 0x61, 0x3c, 0x8b, 0x49, 0x28), G(0xb5, 0x62, 0x35, 0x80, 0x44, 0x26),+ G(0xab, 0x73, 0x42, 0xe9, 0x0f, 0x7c), G(0xa9, 0x70, 0x4b, 0xe2, 0x02, 0x72),+ G(0xaf, 0x75, 0x50, 0xff, 0x15, 0x60), G(0xad, 0x76, 0x59, 0xf4, 0x18, 0x6e),+ G(0xa3, 0x7f, 0x66, 0xc5, 0x3b, 0x44), G(0xa1, 0x7c, 0x6f, 0xce, 0x36, 0x4a),+ G(0xa7, 0x79, 0x74, 0xd3, 0x21, 0x58), G(0xa5, 0x7a, 0x7d, 0xd8, 0x2c, 0x56),+ G(0xdb, 0x3b, 0xa1, 0x7a, 0x0c, 0x37), G(0xd9, 0x38, 0xa8, 0x71, 0x01, 0x39),+ G(0xdf, 0x3d, 0xb3, 0x6c, 0x16, 0x2b), G(0xdd, 0x3e, 0xba, 0x67, 0x1b, 0x25),+ G(0xd3, 0x37, 0x85, 0x56, 0x38, 0x0f), G(0xd1, 0x34, 0x8c, 0x5d, 0x35, 0x01),+ G(0xd7, 0x31, 0x97, 0x40, 0x22, 0x13), G(0xd5, 0x32, 0x9e, 0x4b, 0x2f, 0x1d),+ G(0xcb, 0x23, 0xe9, 0x22, 0x64, 0x47), G(0xc9, 0x20, 0xe0, 0x29, 0x69, 0x49),+ G(0xcf, 0x25, 0xfb, 0x34, 0x7e, 0x5b), G(0xcd, 0x26, 0xf2, 0x3f, 0x73, 0x55),+ G(0xc3, 0x2f, 0xcd, 0x0e, 0x50, 0x7f), G(0xc1, 0x2c, 0xc4, 0x05, 0x5d, 0x71),+ G(0xc7, 0x29, 0xdf, 0x18, 0x4a, 0x63), G(0xc5, 0x2a, 0xd6, 0x13, 0x47, 0x6d),+ G(0xfb, 0x0b, 0x31, 0xca, 0xdc, 0xd7), G(0xf9, 0x08, 0x38, 0xc1, 0xd1, 0xd9),+ G(0xff, 0x0d, 0x23, 0xdc, 0xc6, 0xcb), G(0xfd, 0x0e, 0x2a, 0xd7, 0xcb, 0xc5),+ G(0xf3, 0x07, 0x15, 0xe6, 0xe8, 0xef), G(0xf1, 0x04, 0x1c, 0xed, 0xe5, 0xe1),+ G(0xf7, 0x01, 0x07, 0xf0, 0xf2, 0xf3), G(0xf5, 0x02, 0x0e, 0xfb, 0xff, 0xfd),+ G(0xeb, 0x13, 0x79, 0x92, 0xb4, 0xa7), G(0xe9, 0x10, 0x70, 0x99, 0xb9, 0xa9),+ G(0xef, 0x15, 0x6b, 0x84, 0xae, 0xbb), G(0xed, 0x16, 0x62, 0x8f, 0xa3, 0xb5),+ G(0xe3, 0x1f, 0x5d, 0xbe, 0x80, 0x9f), G(0xe1, 0x1c, 0x54, 0xb5, 0x8d, 0x91),+ G(0xe7, 0x19, 0x4f, 0xa8, 0x9a, 0x83), G(0xe5, 0x1a, 0x46, 0xa3, 0x97, 0x8d),+};+#undef G++static void expand_key(uint8_t *expandedKey, const uint8_t *key, int size, size_t expandedKeySize)+{+ int csz;+ int i;+ uint8_t t[4] = { 0 };++ for (i = 0; i < size; i++)+ expandedKey[i] = key[i];+ csz = size;++ i = 1;+ while (csz < expandedKeySize) {+ t[0] = expandedKey[(csz - 4) + 0];+ t[1] = expandedKey[(csz - 4) + 1];+ t[2] = expandedKey[(csz - 4) + 2];+ t[3] = expandedKey[(csz - 4) + 3];++ if (csz % size == 0) {+ uint8_t tmp;++ tmp = t[0];+ t[0] = sbox[t[1]] ^ Rcon[i++ % sizeof(Rcon)];+ t[1] = sbox[t[2]];+ t[2] = sbox[t[3]];+ t[3] = sbox[tmp];+ }++ if (size == 32 && ((csz % size) == 16)) {+ t[0] = sbox[t[0]];+ t[1] = sbox[t[1]];+ t[2] = sbox[t[2]];+ t[3] = sbox[t[3]];+ }++ expandedKey[csz] = expandedKey[csz - size] ^ t[0]; csz++;+ expandedKey[csz] = expandedKey[csz - size] ^ t[1]; csz++;+ expandedKey[csz] = expandedKey[csz - size] ^ t[2]; csz++;+ expandedKey[csz] = expandedKey[csz - size] ^ t[3]; csz++;+ }+}++static void shift_rows(uint8_t *state)+{+ uint32_t *s32;+ int i;++ for (i = 0; i < 16; i++)+ state[i] = sbox[state[i]];+ s32 = (uint32_t *) state;+ s32[1] = rol32_be(s32[1], 8);+ s32[2] = rol32_be(s32[2], 16);+ s32[3] = rol32_be(s32[3], 24);+}++static void add_round_key(uint8_t *state, uint8_t *rk)+{+ uint32_t *s32, *r32;++ s32 = (uint32_t *) state;+ r32 = (uint32_t *) rk;+ s32[0] ^= r32[0];+ s32[1] ^= r32[1];+ s32[2] ^= r32[2];+ s32[3] ^= r32[3];+}++#define gm1(a) (a)+#define gm2(a) gmtab[a][0]+#define gm3(a) gmtab[a][1]+#define gm9(a) gmtab[a][2]+#define gm11(a) gmtab[a][3]+#define gm13(a) gmtab[a][4]+#define gm14(a) gmtab[a][5]++static void mix_columns(uint8_t *state)+{+ int i;+ uint8_t cpy[4];++ for (i = 0; i < 4; i++) {+ cpy[0] = state[0 * 4 + i];+ cpy[1] = state[1 * 4 + i];+ cpy[2] = state[2 * 4 + i];+ cpy[3] = state[3 * 4 + i];+ state[i] = gm2(cpy[0]) ^ gm1(cpy[3]) ^ gm1(cpy[2]) ^ gm3(cpy[1]);+ state[4+i] = gm2(cpy[1]) ^ gm1(cpy[0]) ^ gm1(cpy[3]) ^ gm3(cpy[2]);+ state[8+i] = gm2(cpy[2]) ^ gm1(cpy[1]) ^ gm1(cpy[0]) ^ gm3(cpy[3]);+ state[12+i] = gm2(cpy[3]) ^ gm1(cpy[2]) ^ gm1(cpy[1]) ^ gm3(cpy[0]);+ }+}++static void create_round_key(const uint8_t *expandedKey, uint8_t *rk)+{+ int i,j;+ for (i = 0; i < 4; i++)+ for (j = 0; j < 4; j++)+ rk[i + j * 4] = expandedKey[i * 4 + j];+}++static void aes_main(const aes_key *key, uint8_t *state)+{+ int i = 0;+ uint8_t rk[16];++ create_round_key(key->data, rk);+ add_round_key(state, rk);++ for (i = 1; i < key->nbr; i++) {+ create_round_key(key->data + 16 * i, rk);+ shift_rows(state);+ mix_columns(state);+ add_round_key(state, rk);+ }++ create_round_key(key->data + 16 * key->nbr, rk);+ shift_rows(state);+ add_round_key(state, rk);+}++static void shift_rows_inv(uint8_t *state)+{+ uint32_t *s32;+ int i;++ s32 = (uint32_t *) state;+ s32[1] = ror32_be(s32[1], 8);+ s32[2] = ror32_be(s32[2], 16);+ s32[3] = ror32_be(s32[3], 24);+ for (i = 0; i < 16; i++)+ state[i] = rsbox[state[i]];+}++static void mix_columns_inv(uint8_t *state)+{+ int i;+ uint8_t cpy[4];++ for (i = 0; i < 4; i++) {+ cpy[0] = state[0 * 4 + i];+ cpy[1] = state[1 * 4 + i];+ cpy[2] = state[2 * 4 + i];+ cpy[3] = state[3 * 4 + i];+ state[i] = gm14(cpy[0]) ^ gm9(cpy[3]) ^ gm13(cpy[2]) ^ gm11(cpy[1]);+ state[4+i] = gm14(cpy[1]) ^ gm9(cpy[0]) ^ gm13(cpy[3]) ^ gm11(cpy[2]);+ state[8+i] = gm14(cpy[2]) ^ gm9(cpy[1]) ^ gm13(cpy[0]) ^ gm11(cpy[3]);+ state[12+i] = gm14(cpy[3]) ^ gm9(cpy[2]) ^ gm13(cpy[1]) ^ gm11(cpy[0]);+ }+}++static void aes_main_inv(const aes_key *key, uint8_t *state)+{+ int i = 0;+ uint8_t rk[16];++ create_round_key(key->data + 16 * key->nbr, rk);+ add_round_key(state, rk);++ for (i = key->nbr - 1; i > 0; i--) {+ create_round_key(key->data + 16 * i, rk);+ shift_rows_inv(state);+ add_round_key(state, rk);+ mix_columns_inv(state);+ }++ create_round_key(key->data, rk);+ shift_rows_inv(state);+ add_round_key(state, rk);+}++/* Set the block values, for the block:+ * a0,0 a0,1 a0,2 a0,3+ * a1,0 a1,1 a1,2 a1,3 -> a0,0 a1,0 a2,0 a3,0 a0,1 a1,1 ... a2,3 a3,3+ * a2,0 a2,1 a2,2 a2,3+ * a3,0 a3,1 a3,2 a3,3+ */+#define swap_block(t, f) \+ t[0] = f[0]; t[4] = f[1]; t[8] = f[2]; t[12] = f[3]; \+ t[1] = f[4]; t[5] = f[5]; t[9] = f[6]; t[13] = f[7]; \+ t[2] = f[8]; t[6] = f[9]; t[10] = f[10]; t[14] = f[11]; \+ t[3] = f[12]; t[7] = f[13]; t[11] = f[14]; t[15] = f[15]++void aes_generic_encrypt_block(aes_block *output, const aes_key *key, const aes_block *input)+{+ uint8_t block[16];+ uint8_t *iptr, *optr;++ iptr = (uint8_t *) input;+ optr = (uint8_t *) output;+ swap_block(block, iptr);+ aes_main(key, block);+ swap_block(optr, block);+}++void aes_generic_decrypt_block(aes_block *output, const aes_key *key, const aes_block *input)+{+ uint8_t block[16];+ uint8_t *iptr, *optr;++ iptr = (uint8_t *) input;+ optr = (uint8_t *) output;+ swap_block(block, iptr);+ aes_main_inv(key, block);+ swap_block(optr, block);+}++void aes_generic_init(aes_key *key, const uint8_t *origkey, uint8_t size)+{+ int esz;++ switch (size) {+ case 16: key->nbr = 10; esz = 176; break;+ case 24: key->nbr = 12; esz = 208; break;+ case 32: key->nbr = 14; esz = 240; break;+ default: return;+ }+ expand_key(key->data, origkey, size, esz);+ return;+}
+ cbits/aes/ni/aes_x86ni.c view
@@ -0,0 +1,271 @@+/*+ * Copyright (c) 2012 Vincent Hanquez <vincent@snarc.org>+ * + * All rights reserved.+ * + * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ * 1. Redistributions of source code must retain the above copyright+ * notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ * notice, this list of conditions and the following disclaimer in the+ * documentation and/or other materials provided with the distribution.+ * 3. Neither the name of the author nor the names of his contributors+ * may be used to endorse or promote products derived from this software+ * without specific prior written permission.+ * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF+ * SUCH DAMAGE.+ */++#include <wmmintrin.h>+#include <tmmintrin.h>+#include "aes.h"+#include "aes_x86ni.h"+// #include "cpu.h"++#if (defined(__i386__) || defined(__x86_64__))+#define ALIGN_UP(addr, size) (((addr) + ((size) - 1)) & (~((size) - 1)))+#define ALIGNMENT(n) __attribute__((aligned(n)))++static __m128i aes_128_key_expansion(__m128i key, __m128i keygened)+{+ keygened = _mm_shuffle_epi32(keygened, _MM_SHUFFLE(3,3,3,3));+ key = _mm_xor_si128(key, _mm_slli_si128(key, 4));+ key = _mm_xor_si128(key, _mm_slli_si128(key, 4));+ key = _mm_xor_si128(key, _mm_slli_si128(key, 4));+ return _mm_xor_si128(key, keygened);+}++static void aes_generate_key128(aes_key *key, const uint8_t *ikey)+{+ __m128i k[20];+ uint64_t *out = (uint64_t *) key->data;+ int i;++ k[0] = _mm_loadu_si128((const __m128i*) ikey);++#define AES_128_key_exp(K, RCON) aes_128_key_expansion(K, _mm_aeskeygenassist_si128(K, RCON))+ k[1] = AES_128_key_exp(k[0], 0x01);+ k[2] = AES_128_key_exp(k[1], 0x02);+ k[3] = AES_128_key_exp(k[2], 0x04);+ k[4] = AES_128_key_exp(k[3], 0x08);+ k[5] = AES_128_key_exp(k[4], 0x10);+ k[6] = AES_128_key_exp(k[5], 0x20);+ k[7] = AES_128_key_exp(k[6], 0x40);+ k[8] = AES_128_key_exp(k[7], 0x80);+ k[9] = AES_128_key_exp(k[8], 0x1B);+ k[10] = AES_128_key_exp(k[9], 0x36);++ /* generate decryption keys in reverse order.+ * k[10] is shared by last encryption and first decryption rounds+ * k[20] is shared by first encryption round (and is the original user key) */+ k[11] = _mm_aesimc_si128(k[9]);+ k[12] = _mm_aesimc_si128(k[8]);+ k[13] = _mm_aesimc_si128(k[7]);+ k[14] = _mm_aesimc_si128(k[6]);+ k[15] = _mm_aesimc_si128(k[5]);+ k[16] = _mm_aesimc_si128(k[4]);+ k[17] = _mm_aesimc_si128(k[3]);+ k[18] = _mm_aesimc_si128(k[2]);+ k[19] = _mm_aesimc_si128(k[1]);++ for (i = 0; i < 20; i++)+ _mm_storeu_si128(((__m128i *) out) + i, k[i]);+}++void aes_ni_init(aes_key *key, const uint8_t *origkey, uint8_t size)+{+ switch (size) {+ case 16: aes_generate_key128(key, origkey); break;+ default: break;+ }+}+++#define PRELOAD_ENC_KEYS(k) \+ __m128i K0 = _mm_loadu_si128(((__m128i *) k)+0); \+ __m128i K1 = _mm_loadu_si128(((__m128i *) k)+1); \+ __m128i K2 = _mm_loadu_si128(((__m128i *) k)+2); \+ __m128i K3 = _mm_loadu_si128(((__m128i *) k)+3); \+ __m128i K4 = _mm_loadu_si128(((__m128i *) k)+4); \+ __m128i K5 = _mm_loadu_si128(((__m128i *) k)+5); \+ __m128i K6 = _mm_loadu_si128(((__m128i *) k)+6); \+ __m128i K7 = _mm_loadu_si128(((__m128i *) k)+7); \+ __m128i K8 = _mm_loadu_si128(((__m128i *) k)+8); \+ __m128i K9 = _mm_loadu_si128(((__m128i *) k)+9); \+ __m128i K10 = _mm_loadu_si128(((__m128i *) k)+10);++#define DO_ENC_BLOCK(m) \+ m = _mm_xor_si128(m, K0); \+ m = _mm_aesenc_si128(m, K1); \+ m = _mm_aesenc_si128(m, K2); \+ m = _mm_aesenc_si128(m, K3); \+ m = _mm_aesenc_si128(m, K4); \+ m = _mm_aesenc_si128(m, K5); \+ m = _mm_aesenc_si128(m, K6); \+ m = _mm_aesenc_si128(m, K7); \+ m = _mm_aesenc_si128(m, K8); \+ m = _mm_aesenc_si128(m, K9); \+ m = _mm_aesenclast_si128(m, K10);++#define PRELOAD_DEC_KEYS(k) \+ __m128i K0 = _mm_loadu_si128(((__m128i *) k)+10+0); \+ __m128i K1 = _mm_loadu_si128(((__m128i *) k)+10+1); \+ __m128i K2 = _mm_loadu_si128(((__m128i *) k)+10+2); \+ __m128i K3 = _mm_loadu_si128(((__m128i *) k)+10+3); \+ __m128i K4 = _mm_loadu_si128(((__m128i *) k)+10+4); \+ __m128i K5 = _mm_loadu_si128(((__m128i *) k)+10+5); \+ __m128i K6 = _mm_loadu_si128(((__m128i *) k)+10+6); \+ __m128i K7 = _mm_loadu_si128(((__m128i *) k)+10+7); \+ __m128i K8 = _mm_loadu_si128(((__m128i *) k)+10+8); \+ __m128i K9 = _mm_loadu_si128(((__m128i *) k)+10+9); \+ __m128i K10 = _mm_loadu_si128(((__m128i *) k)+0);++#define DO_DEC_BLOCK(m) \+ m = _mm_xor_si128(m, K0); \+ m = _mm_aesdec_si128(m, K1); \+ m = _mm_aesdec_si128(m, K2); \+ m = _mm_aesdec_si128(m, K3); \+ m = _mm_aesdec_si128(m, K4); \+ m = _mm_aesdec_si128(m, K5); \+ m = _mm_aesdec_si128(m, K6); \+ m = _mm_aesdec_si128(m, K7); \+ m = _mm_aesdec_si128(m, K8); \+ m = _mm_aesdec_si128(m, K9); \+ m = _mm_aesdeclast_si128(m, K10);++void aes_ni_encrypt_ecb(uint8_t *out, aes_key *key, const uint8_t *in, uint32_t blocks)+{+ __m128i *k = (__m128i *) key->data;++ PRELOAD_ENC_KEYS(k);++ while (blocks-- > 0) {+ __m128i m = _mm_loadu_si128((__m128i *) in);++ DO_ENC_BLOCK(m);++ _mm_storeu_si128((__m128i *) out, m);+ in += 16;+ out += 16;+ }+}++void aes_ni_decrypt_ecb(uint8_t *out, aes_key *key, const uint8_t *in, uint32_t blocks)+{+ __m128i *k = (__m128i *) key->data;++ PRELOAD_DEC_KEYS(k);++ while (blocks-- > 0) {+ __m128i m = _mm_loadu_si128((__m128i *) in);++ DO_DEC_BLOCK(m);++ _mm_storeu_si128((__m128i *) out, m);+ in += 16;+ out += 16;+ }+}++void aes_ni_encrypt_cbc(uint8_t *out, aes_key *key, uint8_t *_iv, uint8_t *in, uint32_t blocks)+{+ __m128i *k = (__m128i *) key->data;+ __m128i iv = _mm_loadu_si128((__m128i *) _iv);++ PRELOAD_ENC_KEYS(k);++ while (blocks-- > 0) {+ __m128i m = _mm_loadu_si128((__m128i *) in);+ m = _mm_xor_si128(m, iv);++ DO_ENC_BLOCK(m);++ _mm_storeu_si128((__m128i *) out, m);+ iv = m;++ in += 16;+ out += 16;+ }+}++void aes_ni_decrypt_cbc(uint8_t *out, aes_key *key, uint8_t *_iv, uint8_t *in, uint32_t blocks)+{+ __m128i *k = (__m128i *) key->data;+ __m128i iv = _mm_loadu_si128((__m128i *) _iv);++ PRELOAD_DEC_KEYS(k);++ while (blocks-- > 0) {+ __m128i m = _mm_loadu_si128((__m128i *) in);+ __m128i ivnext = m;++ DO_DEC_BLOCK(m);+ m = _mm_xor_si128(m, iv);++ _mm_storeu_si128((__m128i *) out, m);+ iv = ivnext;++ in += 16;+ out += 16;+ }+}++/* TO OPTIMISE: use pcmulqdq... or some faster code.+ * this is the lamest way of doing it, but i'm out of time.+ * this is basically a copy of gf_mulx in gf.c */+static __m128i gfmulx(__m128i v)+{+ uint64_t v_[2] ALIGNMENT(16);+ const uint64_t gf_mask = 0x8000000000000000;++ _mm_store_si128((__m128i *) v_, v);+ uint64_t r = ((v_[1] & gf_mask) ? 0x87 : 0);+ v_[1] = (v_[1] << 1) | (v_[0] & gf_mask ? 1 : 0);+ v_[0] = (v_[0] << 1) ^ r;+ v = _mm_load_si128((__m128i *) v_);+ return v;+}++void aes_ni_encrypt_xts(uint8_t *out, aes_key *key1, aes_key *key2,+ uint8_t *_tweak, uint32_t spoint, uint8_t *in, uint32_t blocks)+{+ __m128i tweak = _mm_loadu_si128((__m128i *) _tweak);++ do {+ __m128i *k2 = (__m128i *) key2->data;+ PRELOAD_ENC_KEYS(k2);+ DO_ENC_BLOCK(tweak);++ while (spoint-- > 0)+ tweak = gfmulx(tweak);+ } while (0) ;++ do {+ __m128i *k1 = (__m128i *) key1->data;+ PRELOAD_ENC_KEYS(k1);++ for ( ; blocks-- > 0; in += 16, out += 16, tweak = gfmulx(tweak)) {+ __m128i m = _mm_loadu_si128((__m128i *) in);++ m = _mm_xor_si128(m, tweak);+ DO_ENC_BLOCK(m);+ m = _mm_xor_si128(m, tweak);++ _mm_storeu_si128((__m128i *) out, m);+ }+ } while (0);+}++#endif /* x86 */
+ cbits/include/aes.h view
@@ -0,0 +1,24 @@+#ifndef AES_AES_H+#define AES_AES_H++#include <stdint.h>+#include "aes_types.h"++typedef aes_key AESKey;+AESKey *allocate_key128();+void generate_key128(AESKey *k, const uint8_t *bytes);+void free_key128(AESKey *k);+void encrypt_ecb(const AESKey *k, uint8_t *dst, const uint8_t *src, const uint32_t nr);+void decrypt_ecb(const AESKey *k, uint8_t *dst, const uint8_t *src, const uint32_t nr);+void aes_gcm_full_encrypt( const AESKey *k+ , uint8_t *iv, uint32_t ivLen+ , uint8_t *aad, uint32_t aadLen+ , uint8_t *pt, uint32_t ptLen+ , uint8_t *ct, uint8_t *tag);+void aes_gcm_full_decrypt( const AESKey *k+ , uint8_t *iv, uint32_t ivLen+ , uint8_t *aad, uint32_t aadLen+ , uint8_t *ct, uint32_t ctLen+ , uint8_t *pt, uint8_t *tag);++#endif
+ cbits/include/aes_generic.h view
@@ -0,0 +1,36 @@+/*+ * Copyright (c) 2012 Vincent Hanquez <vincent@snarc.org>+ *+ * All rights reserved.+ *+ * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ * 1. Redistributions of source code must retain the above copyright+ * notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ * notice, this list of conditions and the following disclaimer in the+ * documentation and/or other materials provided with the distribution.+ * 3. Neither the name of the author nor the names of his contributors+ * may be used to endorse or promote products derived from this software+ * without specific prior written permission.+ *+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF+ * SUCH DAMAGE.+ */+#include "aes_types.h"+#include "block128.h"+#include <stdint.h>++void aes_generic_encrypt_block(aes_block *output, const aes_key *key, const aes_block *input);+void aes_generic_decrypt_block(aes_block *output, const aes_key *key, const aes_block *input);+void aes_generic_init(aes_key *key, const uint8_t *origkey, uint8_t size);
+ cbits/include/aes_types.h view
@@ -0,0 +1,25 @@+#ifndef AES_TYPES_H+#define AES_TYPES_H+#include <stdint.h>+#include "block128.h"++typedef block128 aes_block;++typedef struct {+ uint8_t nbr;+ uint8_t _padding[7];+ uint8_t data[16*14*2];+} aes_key;++/* size = 4*16+2*8+aes_key=456 = 536 */+typedef struct {+ aes_block tag;+ aes_block h;+ aes_block iv;+ aes_block civ;+ uint64_t length_aad;+ uint64_t length_input;+ aes_key key;+} aes_gcm;++#endif
+ cbits/include/aes_x86ni.h view
@@ -0,0 +1,53 @@+/*+ * Copyright (c) 2012 Vincent Hanquez <vincent@snarc.org>+ * + * All rights reserved.+ * + * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ * 1. Redistributions of source code must retain the above copyright+ * notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ * notice, this list of conditions and the following disclaimer in the+ * documentation and/or other materials provided with the distribution.+ * 3. Neither the name of the author nor the names of his contributors+ * may be used to endorse or promote products derived from this software+ * without specific prior written permission.+ * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF+ * SUCH DAMAGE.+ */++#ifndef AES_X86NI_H+#define AES_X86NI_H++#if defined(__i386__) || defined(__x86_64__)++#include <wmmintrin.h>+#include <tmmintrin.h>+#include "aes_types.h"+#include "block128.h"++void aes_ni_init(aes_key *key, const uint8_t *origkey, uint8_t size);+void aes_ni_encrypt_ecb(uint8_t *out, aes_key *key, const uint8_t *in, uint32_t blocks);+void aes_ni_decrypt_ecb(uint8_t *out, aes_key *key, const uint8_t *in, uint32_t blocks);+void aes_ni_encrypt_cbc(uint8_t *out, aes_key *key, uint8_t *_iv, uint8_t *in, uint32_t blocks);+void aes_ni_decrypt_cbc(uint8_t *out, aes_key *key, uint8_t *_iv, uint8_t *in, uint32_t blocks);+void aes_ni_encrypt_xts(uint8_t *out, aes_key *key1, aes_key *key2,+ uint8_t *_tweak, uint32_t spoint, uint8_t *in, uint32_t blocks);++void gf_mul_x86ni(block128 *res, block128 *a_, block128 *b_);++#endif++#endif
+ cbits/include/bitfn.h view
@@ -0,0 +1,232 @@+/*+ * Copyright (C) 2006-2009 Vincent Hanquez <vincent@snarc.org>+ *+ * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ * 1. Redistributions of source code must retain the above copyright+ * notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ * notice, this list of conditions and the following disclaimer in the+ * documentation and/or other materials provided with the distribution.+ *+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+ */++#ifndef BITFN_H+#define BITFN_H+#include <stdint.h>++#ifndef NO_INLINE_ASM+/**********************************************************/+# if (defined(__i386__))+# define ARCH_HAS_SWAP32+static inline uint32_t bitfn_swap32(uint32_t a)+{+ asm ("bswap %0" : "=r" (a) : "0" (a));+ return a;+}+/**********************************************************/+# elif (defined(__arm__))+# define ARCH_HAS_SWAP32+static inline uint32_t bitfn_swap32(uint32_t a)+{+ uint32_t tmp = a;+ asm volatile ("eor %1, %0, %0, ror #16\n"+ "bic %1, %1, #0xff0000\n"+ "mov %0, %0, ror #8\n"+ "eor %0, %0, %1, lsr #8\n"+ : "=r" (a), "=r" (tmp) : "0" (a), "1" (tmp));+ return a;+}+/**********************************************************/+# elif defined(__x86_64__)+# define ARCH_HAS_SWAP32+# define ARCH_HAS_SWAP64+static inline uint32_t bitfn_swap32(uint32_t a)+{+ asm ("bswap %0" : "=r" (a) : "0" (a));+ return a;+}++static inline uint64_t bitfn_swap64(uint64_t a)+{+ asm ("bswap %0" : "=r" (a) : "0" (a));+ return a;+}++# endif+#endif /* NO_INLINE_ASM */+/**********************************************************/++#ifndef ARCH_HAS_ROL32+static inline uint32_t rol32(uint32_t word, uint32_t shift)+{+ return (word << shift) | (word >> (32 - shift));+}+#endif++#ifndef ARCH_HAS_ROR32+static inline uint32_t ror32(uint32_t word, uint32_t shift)+{+ return (word >> shift) | (word << (32 - shift));+}+#endif++#ifndef ARCH_HAS_ROL64+static inline uint64_t rol64(uint64_t word, uint32_t shift)+{+ return (word << shift) | (word >> (64 - shift));+}+#endif++#ifndef ARCH_HAS_ROR64+static inline uint64_t ror64(uint64_t word, uint32_t shift)+{+ return (word >> shift) | (word << (64 - shift));+}+#endif++#ifndef ARCH_HAS_SWAP32+static inline uint32_t bitfn_swap32(uint32_t a)+{+ return (a << 24) | ((a & 0xff00) << 8) | ((a >> 8) & 0xff00) | (a >> 24);+}+#endif++#ifndef ARCH_HAS_ARRAY_SWAP32+static inline void array_swap32(uint32_t *d, uint32_t *s, uint32_t nb)+{+ while (nb--)+ *d++ = bitfn_swap32(*s++);+}+#endif++#ifndef ARCH_HAS_SWAP64+static inline uint64_t bitfn_swap64(uint64_t a)+{+ return ((uint64_t) bitfn_swap32((uint32_t) (a >> 32))) |+ (((uint64_t) bitfn_swap32((uint32_t) a)) << 32);+}+#endif++#ifndef ARCH_HAS_ARRAY_SWAP64+static inline void array_swap64(uint64_t *d, uint64_t *s, uint32_t nb)+{+ while (nb--)+ *d++ = bitfn_swap64(*s++);+}+#endif++#ifndef ARCH_HAS_MEMORY_ZERO+static inline void memory_zero(void *ptr, uint32_t len)+{+ uint32_t *ptr32 = ptr;+ uint8_t *ptr8;+ int i;++ for (i = 0; i < len / 4; i++)+ *ptr32++ = 0;+ if (len % 4) {+ ptr8 = (uint8_t *) ptr32;+ for (i = len % 4; i >= 0; i--)+ ptr8[i] = 0;+ }+}+#endif++#ifndef ARCH_HAS_ARRAY_COPY32+static inline void array_copy32(uint32_t *d, uint32_t *s, uint32_t nb)+{+ while (nb--) *d++ = *s++;+}+#endif++#ifndef ARCH_HAS_ARRAY_COPY64+static inline void array_copy64(uint64_t *d, uint64_t *s, uint32_t nb)+{+ while (nb--) *d++ = *s++;+}+#endif++#ifdef __MINGW32__+ # define LITTLE_ENDIAN 1234+ # define BYTE_ORDER LITTLE_ENDIAN+#elif defined(__FreeBSD__) || defined(__DragonFly__)+ # include <sys/endian.h>+#elif defined(__OpenBSD__) || defined(__SVR4)+ # include <sys/types.h>+#elif defined(__APPLE__)+ # include <machine/endian.h>+#elif defined( BSD ) && ( BSD >= 199103 )+ # include <machine/endian.h>+#else+ # include <endian.h>+#endif+/* big endian to cpu */+#if LITTLE_ENDIAN == BYTE_ORDER++# define be32_to_cpu(a) bitfn_swap32(a)+# define cpu_to_be32(a) bitfn_swap32(a)+# define le32_to_cpu(a) (a)+# define cpu_to_le32(a) (a)+# define be64_to_cpu(a) bitfn_swap64(a)+# define cpu_to_be64(a) bitfn_swap64(a)+# define le64_to_cpu(a) (a)+# define cpu_to_le64(a) (a)++# define cpu_to_le32_array(d, s, l) array_copy32(d, s, l)+# define le32_to_cpu_array(d, s, l) array_copy32(d, s, l)+# define cpu_to_be32_array(d, s, l) array_swap32(d, s, l)+# define be32_to_cpu_array(d, s, l) array_swap32(d, s, l)++# define cpu_to_le64_array(d, s, l) array_copy64(d, s, l)+# define le64_to_cpu_array(d, s, l) array_copy64(d, s, l)+# define cpu_to_be64_array(d, s, l) array_swap64(d, s, l)+# define be64_to_cpu_array(d, s, l) array_swap64(d, s, l)++# define ror32_be(a, s) rol32(a, s)+# define rol32_be(a, s) ror32(a, s)++# define ARCH_IS_LITTLE_ENDIAN++#elif BIG_ENDIAN == BYTE_ORDER++# define be32_to_cpu(a) (a)+# define cpu_to_be32(a) (a)+# define be64_to_cpu(a) (a)+# define cpu_to_be64(a) (a)+# define le64_to_cpu(a) bitfn_swap64(a)+# define cpu_to_le64(a) bitfn_swap64(a)+# define le32_to_cpu(a) bitfn_swap32(a)+# define cpu_to_le32(a) bitfn_swap32(a)++# define cpu_to_le32_array(d, s, l) array_swap32(d, s, l)+# define le32_to_cpu_array(d, s, l) array_swap32(d, s, l)+# define cpu_to_be32_array(d, s, l) array_copy32(d, s, l)+# define be32_to_cpu_array(d, s, l) array_copy32(d, s, l)++# define cpu_to_le64_array(d, s, l) array_swap64(d, s, l)+# define le64_to_cpu_array(d, s, l) array_swap64(d, s, l)+# define cpu_to_be64_array(d, s, l) array_copy64(d, s, l)+# define be64_to_cpu_array(d, s, l) array_copy64(d, s, l)++# define ror32_be(a, s) ror32(a, s)+# define rol32_be(a, s) rol32(a, s)++# define ARCH_IS_BIG_ENDIAN++#else+# error "endian not supported"+#endif++#endif /* !BITFN_H */
+ cbits/include/block128.h view
@@ -0,0 +1,87 @@+/*+ * Copyright (c) 2012 Vincent Hanquez <vincent@snarc.org>+ * + * All rights reserved.+ * + * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ * 1. Redistributions of source code must retain the above copyright+ * notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ * notice, this list of conditions and the following disclaimer in the+ * documentation and/or other materials provided with the distribution.+ * 3. Neither the name of the author nor the names of his contributors+ * may be used to endorse or promote products derived from this software+ * without specific prior written permission.+ * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF+ * SUCH DAMAGE.+ */++#ifndef BLOCK128_H+#define BLOCK128_H++#include "bitfn.h"++typedef union {+ uint64_t q[2];+ uint32_t d[4];+ uint16_t w[8];+ uint8_t b[16];+} block128;++static inline void block128_copy_bytes(block128 *block, uint8_t *src, uint32_t len)+{+ int i;+ for (i = 0; i < len; i++) block->b[i] = src[i];+}++static inline void block128_copy(block128 *d, block128 *s)+{+ d->q[0] = s->q[0]; d->q[1] = s->q[1];+}++static inline void block128_zero(block128 *d)+{+ d->q[0] = 0; d->q[1] = 0;+}++static inline void block128_xor(block128 *d, block128 *s)+{+ d->q[0] ^= s->q[0];+ d->q[1] ^= s->q[1];+}++static inline void block128_vxor(block128 *d, block128 *s1, block128 *s2)+{+ d->q[0] = s1->q[0] ^ s2->q[0];+ d->q[1] = s1->q[1] ^ s2->q[1];+}++static inline void block128_xor_bytes(block128 *block, uint8_t *src, uint32_t len)+{+ int i;+ for (i = 0; i < len; i++) block->b[i] ^= src[i];+}++static inline void block128_inc_be(block128 *b)+{+ uint64_t v = be64_to_cpu(b->q[1]);+ if (++v == 0) {+ b->q[0] = cpu_to_be64(be64_to_cpu(b->q[0]) + 1);+ b->q[1] = 0;+ } else+ b->q[1] = cpu_to_be64(v);+}++#endif
+ cipher-aes128.cabal view
@@ -0,0 +1,39 @@+-- Initial cipher.cabal generated by cabal init. For further +-- documentation, see http://haskell.org/cabal/users-guide/++name: cipher-aes128+version: 0.1+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+license-file: LICENSE+author: Thomas M. DuBuisson, Vincent Hanquez (See AUTHORS file)+maintainer: thomas.dubuisson@gmail.com+copyright: Thomas M. DuBuisson+category: Cryptography+build-type: Custom+cabal-version: >=1.12++extra-source-files: ./cbits/include/aes.h+ , ./cbits/include/aes_generic.h+ , ./cbits/include/aes_types.h+ , ./cbits/include/aes_x86ni.h+ , ./cbits/include/bitfn.h+ , ./cbits/include/block128.h+ , ./cbits/aes/LICENSE+ , AUTHORS+library+ default-language: Haskell2010+ exposed-modules: Crypto.Cipher.AES128, Crypto.Cipher.AES128.Internal+ build-depends: base >=4.5 && < 5,+ bytestring,+ crypto-api,+ tagged,+ cereal+ ghc-options: -Wall -O2++ c-sources: ./cbits/aes/aes.c+ , ./cbits/aes/ni/aes_x86ni.c+ , ./cbits/aes/generic/aes_generic.c+ include-dirs: cbits/include+ cc-options: -O3