packages feed

cipher-aes128 0.5 → 0.6

raw patch · 31 files changed

+2885/−1822 lines, 31 filesdep +cipher-aesdep +cipher-aes128dep +crypto-api-testsdep ~basedep ~crypto-apisetup-changednew-component:exe:aes128_test

Dependencies added: cipher-aes, cipher-aes128, crypto-api-tests, test-framework

Dependency ranges changed: base, crypto-api

Files

AUTHORS view
@@ -1,2 +1,2 @@-Thomas DuBuisson: AES trampolines, Haskell code-Vincent Hanquez: AES algorithms for x86 and NI+Thomas DuBuisson: Haskell code, refactoring of aes C code (extract mutable portion of GCM struct)+Vincent Hanquez: C AES implementations for x86 and NI
Benchmark/bench.hs view
@@ -1,6 +1,7 @@ import Crypto.Cipher.AES128 import Crypto.Cipher.AES import Crypto.Classes+import Crypto.Types import Crypto.Modes (zeroIV) import Criterion import Criterion.Main@@ -9,12 +10,14 @@ import qualified Data.ByteString as B  main = do-    let iv = zeroIV-        ivV = IV (B.replicate 16 0)-    pt <- getEntropy (2^12)-    k  <- buildKeyIO :: IO AESKey-    let kV = initKey (B.pack [0..15])+    let iv  = zeroIV+        ivV = B.replicate 16 0+    pt <- getEntropy (2^16)+    k  <- buildKeyIO :: IO AESKey128+    let kV = initAES (B.pack [0..15])     defaultMain-        [ bench "aes-ctr cipher-aes128" $ nf (fst . ctr k iv) pt-        , bench "aes-ctr cipher-aes" $ nf (encryptCTR kV ivV) pt-        , bench "aes-gcm cipher-aes" $ nf (encryptGCM kV ivV B.empty) pt]+        [ bench "aes-ecb cipher-aes128" $ nf (encryptBlock k) pt+        , bench "aes-ctr cipher-aes128" $ nf (fst . ctr k iv) pt+        , bench "aes-ecb cipher-aes"    $ nf (encryptECB kV) pt+        , bench "aes-ctr cipher-aes"    $ nf (encryptCTR kV ivV) pt+        , bench "aes-gcm cipher-aes"    $ nf (fst . encryptGCM kV ivV B.empty) pt]
Crypto/Cipher/AES128.hs view
@@ -1,11 +1,11 @@ {-# OPTIONS_GHC -fno-warn-orphans #-} module Crypto.Cipher.AES128-  ( AESKey+  ( AESKey128, AESKey192, AESKey256+  , BlockCipher(..), buildKeyIO, zeroIV   ) where  import Crypto.Cipher.AES128.Internal import Crypto.Classes-import Crypto.Types import Control.Monad (when) import Data.Serialize import Data.Tagged@@ -16,9 +16,9 @@ import qualified Data.ByteString.Internal as B import qualified Data.ByteString.Unsafe as B -instance Serialize AESKey where+instance Serialize AESKey128 where     put k = do-        let RKey l h = (rawKey k)+        let RKey128 l h = (rawKey128 k)         putWord64be h         putWord64be l @@ -28,14 +28,39 @@             Nothing -> fail "Invalid key on 'get'"             Just k  -> return k -instance BlockCipher AESKey where+instance Serialize AESKey192 where+    put k = do+        let RKey192 a b c = (rawKey192 k)+        putWord64be c+        putWord64be b+        putWord64be a++    get = do+        b <- getByteString 24+        case buildKey b of+            Nothing -> fail "Invalid key on 'get'"+            Just k  -> return k++instance Serialize AESKey256 where+    put k = do+        let RKey256 a b c d = (rawKey256 k)+        putWord64be d+        putWord64be c+        putWord64be b+        putWord64be a++    get = do+        b <- getByteString 32+        case buildKey b of+            Nothing -> fail "Invalid key on 'get'"+            Just k  -> return k++instance BlockCipher AESKey128 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)+          B.unsafeUseAsCString bs (\p -> generateKey128 (castPtr p))       | otherwise = Nothing     encryptBlock k b = unsafePerformIO $ do         B.unsafeUseAsCStringLen b $ \(inP,len) -> do@@ -45,6 +70,8 @@         B.unsafeUseAsCStringLen b $ \(inP,len) -> do          B.create (B.length b) $ \outP -> do             decryptECB k (castPtr outP) (castPtr inP) (len`div`blkSize)+    ecb   = encryptBlock+    unEcb = decryptBlock     ctr k (IV bs) pt = unsafePerformIO $ do         B.unsafeUseAsCStringLen pt $ \(inP, len) -> do          B.unsafeUseAsCStringLen bs $ \(ivP, ivLen) -> do@@ -55,7 +82,68 @@                 encryptCTR k (castPtr ivP) (castPtr newIVP) (castPtr outP) (castPtr inP) len             let newIV = B.fromForeignPtr newIVFP 0 ivLen             return (ct,IV newIV)+    {-# INLINE ctr #-}     unCtr = ctr  blkSize :: Int blkSize = 16++instance BlockCipher AESKey192 where+    blockSize = Tagged 128+    keyLength = Tagged 192+    buildKey bs+      | B.length bs >= 16 = unsafePerformIO $+          B.unsafeUseAsCString bs (\p -> generateKey192 (castPtr p))+      | 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)+    ecb   = encryptBlock+    unEcb = decryptBlock+    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)+    {-# INLINE ctr #-}+    unCtr = ctr++instance BlockCipher AESKey256 where+    blockSize = Tagged 128+    keyLength = Tagged 256+    buildKey bs+      | B.length bs >= 16 = unsafePerformIO $+          B.unsafeUseAsCString bs (\p -> generateKey256 (castPtr p))+      | 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)+    ecb   = encryptBlock+    unEcb = decryptBlock+    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)+    {-# INLINE ctr #-}+    unCtr = ctr
Crypto/Cipher/AES128/Internal.hs view
@@ -1,14 +1,17 @@-{-# LANGUAGE ForeignFunctionInterface, EmptyDataDecls #-}+{-# LANGUAGE ForeignFunctionInterface, EmptyDataDecls, ViewPatterns #-} module Crypto.Cipher.AES128.Internal-        ( AESKey(..), RawKey(..), GCM(..)-        , generateKey, generateGCM+        ( AESKey128(..), AESKey192(..), AESKey256(..), RawKey128(..), RawKey192(..), RawKey256(..), GCM(..)+        , generateKey128, generateKey192, generateKey256+        , generateGCM         , encryptECB         , decryptECB-        , encryptGCM-        , decryptGCM-        , finishGCM         , encryptCTR         , decryptCTR+        , encryptGCM, decryptGCM+        -- * Piece-meal functions+        , cipherOnlyGCM+        , decipherOnlyGCM+        , finishGCM, aadGCM         ) where  import Foreign.Ptr@@ -21,81 +24,152 @@ -- AES Bindings data AESKeyStruct type AESKeyPtr = Ptr AESKeyStruct-data RawKey = RKey { lowK,highK :: {-# UNPACK #-} !Word64 }-data AESKey = AESKey { rawKey      :: !RawKey-                     , expandedKey :: ForeignPtr AESKeyStruct } +data RawKey128 = RKey128 { lowK128,highK128 :: {-# UNPACK #-} !Word64 }+data AESKey128 = AESKey128 { rawKey128      :: !RawKey128+                           , expandedKey128 :: ForeignPtr AESKeyStruct }++data RawKey192 = RKey192 { lowK192,midK192,highK192 :: {-# UNPACK #-} !Word64 }+data AESKey192 = AESKey192 { rawKey192      :: !RawKey192+                           , expandedKey192 :: ForeignPtr AESKeyStruct }++data RawKey256 = RKey256 { aK256,bK256,cK256,dK256 :: {-# UNPACK #-} !Word64 }+data AESKey256 = AESKey256 { rawKey256      :: !RawKey256+                           , expandedKey256 :: ForeignPtr AESKeyStruct }++class GetExpanded a where+    expandedKey :: a -> ForeignPtr AESKeyStruct++instance GetExpanded AESKey256 where+    expandedKey = expandedKey256+instance GetExpanded AESKey192 where+    expandedKey = expandedKey192+instance GetExpanded AESKey128 where+    expandedKey = expandedKey128+ type AESGcmPtr = Ptr GCMStruct data GCMStruct-data GCM = GCM { _gcmFP  :: ForeignPtr GCMStruct }+data GCM k = GCM { _gcmFP   :: GCMpc+                 , _keyFP   :: k+                 , _ctxFP2  :: ForeignPtr CTXStruct+                 } -foreign import ccall unsafe "aes/aes.h generate_key128"-        c_generate_key128 :: AESKeyPtr -> Ptr Word8 -> IO ()+newtype GCMpc = GCMpc { unGCMpc :: ForeignPtr GCMStruct } -foreign import ccall unsafe "aes/aes.h allocate_key128"-        c_allocate_key128 :: IO AESKeyPtr+type AESCtxPtr = Ptr CTXStruct+data CTXStruct+-- data CTX = CTX { _ctxFP :: ForeignPtr CTXStruct } -foreign import ccall unsafe "aes/aes.h &free_key128"-        c_free_key128 :: FunPtr (AESKeyPtr -> IO ())+foreign import ccall unsafe "aes.h tmd_aes_initkey"+        c_aes_initkey :: AESKeyPtr -> Ptr Word8 -> Word8 -> IO () -foreign import ccall unsafe "aes/aes.h free_key128"-        c_key128_free :: AESKeyPtr -> IO ()+foreign import ccall unsafe "aes.h tmd_allocatekey"+        c_allocate_key :: IO AESKeyPtr -foreign import ccall unsafe "aes/aes.h encrypt_ecb"-        c_encrypt_ecb :: AESKeyPtr -> Ptr Word8 -> Ptr Word8 -> Word32 -> IO ()+foreign import ccall unsafe "aes.h &tmd_freekey"+        c_free_key :: FunPtr (AESKeyPtr -> 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.h tmd_freekey"+--         c_key_free :: AESKeyPtr -> IO () -foreign import ccall unsafe "aes/aes.h allocate_gcm"-    c_gcm_allocate :: IO AESGcmPtr+foreign import ccall unsafe "aes.h tmd_allocatectx"+        c_allocate_ctx :: IO AESCtxPtr -foreign import ccall unsafe "aes/aes.h aes_gcm_init"+foreign import ccall unsafe "aes.h &tmd_freectx"+        c_free_ctx :: FunPtr (AESCtxPtr -> IO ())++-- foreign import ccall unsafe "aes.h tmd_freectx"+--         c_ctx_free :: AESCtxPtr -> IO ()++foreign import ccall unsafe "aes.h tmd_allocategcm"+        c_allocate_gcm :: IO AESGcmPtr++foreign import ccall unsafe "aes.h &tmd_freegcm"+        c_free_gcm :: FunPtr (AESGcmPtr -> IO ())++-- foreign import ccall unsafe "aes.h tmd_freegcm"+--         c_gcm_free :: AESGcmPtr -> IO ()++foreign import ccall unsafe "aes.h tmd_aes_gcm_init"     c_gcm_init :: AESGcmPtr                -> AESKeyPtr+               -> IO ()++foreign import ccall unsafe "aes.h tmd_aes_ctx_init"+    c_ctx_init :: AESGcmPtr+               -> AESCtxPtr+               -> AESKeyPtr                -> Ptr Word8 -> Word32 -- ^ IV and length                -> IO () -foreign import ccall unsafe "aes/aes.h aes_gcm_enc_finish"-    c_gcm_encrypt :: Ptr Word8           -- Output-                  -> Ptr Word8           -- Tag++foreign import ccall unsafe "aes.h tmd_aes_encrypt_ecb"+        c_encrypt_ecb :: Ptr Word8 -> AESKeyPtr -> Ptr Word8 -> Word32 -> IO ()++foreign import ccall unsafe "aes.h tmd_aes_decrypt_ecb"+        c_decrypt_ecb :: Ptr Word8 -> AESKeyPtr -> Ptr Word8 -> Word32 -> IO ()+++foreign import ccall unsafe "aes.h tmd_aes_gcm_finish"+    c_gcm_finish  :: Ptr Word8           -- Tag                   -> AESGcmPtr-                  -> Ptr Word8 -> Word32 -- IV and length-                  -> Ptr Word8 -> Word32 -- PT and length-                  -> Ptr Word8 -> Word32 -- AAD and length+                  -> AESKeyPtr           -- Key+                  -> AESCtxPtr           -- Context                   -> IO () -foreign import ccall unsafe "aes/aes.h aes_gcm_dec_finish"+foreign import ccall unsafe "aes.h tmd_aes_gcm_aad"+    c_gcm_aad     :: AESGcmPtr+                  -> AESCtxPtr+                  -> Ptr Word8 -> Word32 -- AAD, len+                  -> IO ()++foreign import ccall unsafe "aes.h tmd_aes_gcm_decrypt"     c_gcm_decrypt :: Ptr Word8           -- Output-                  -> Ptr Word8           -- Tag                   -> AESGcmPtr-                  -> Ptr Word8 -> Word32 -- IV and length-                  -> Ptr Word8 -> Word32 -- PT and length-                  -> Ptr Word8 -> Word32 -- AAD and length+                  -> AESCtxPtr+                  -> AESKeyPtr+                  -> Ptr Word8 -> Word32 -- CT and length                   -> IO () -foreign import ccall unsafe "aes/aes.h allocate_gcm"-    c_gcm_finish :: Ptr Word8 -> AESGcmPtr -> IO ()+foreign import ccall unsafe "aes.h tmd_aes_gcm_encrypt"+    c_gcm_encrypt :: Ptr Word8           -- Output+                  -> AESGcmPtr+                  -> AESCtxPtr+                  -> AESKeyPtr+                  -> Ptr Word8 -> Word32 -- PT and length+                  -> IO () -foreign import ccall unsafe "aes/aes.h &free_gcm"-    c_free_gcm :: FunPtr (AESGcmPtr -> IO ())+foreign import ccall unsafe "aes.h tmd_aes_gcm_full_encrypt"+    c_gcm_full_encrypt :: AESKeyPtr -> AESGcmPtr+                       -> Ptr Word8 -> Word32           -- IV, IVLen+                       -> Ptr Word8 -> Word32           -- AAD, AADLen+                       -> Ptr Word8 -> Word32           -- PT, PTLen+                       -> Ptr Word8                     -- CT+                       -> Ptr Word8                     -- Tag+                       -> IO () -foreign import ccall unsafe "aes/aes.h free_gcm"-    _c_gcm_free :: AESGcmPtr -> IO ()+foreign import ccall unsafe "aes.h tmd_aes_gcm_full_decrypt"+    c_gcm_full_decrypt :: AESKeyPtr -> AESGcmPtr+                       -> Ptr Word8 -> Word32           -- IV, IVLen+                       -> Ptr Word8 -> Word32           -- AAD, AADLen+                       -> Ptr Word8 -> Word32           -- PT, PTLen+                       -> Ptr Word8                     -- CT+                       -> Ptr Word8                     -- Tag+                       -> IO () -foreign import ccall unsafe "aes/aes.h encrypt_ctr"-    c_encrypt_ctr :: AESKeyPtr+foreign import ccall unsafe "aes.h tmd_aes_encrypt_ctr"+    c_encrypt_ctr :: Ptr Word8 -- ^ Output+                  -> AESKeyPtr                   -> Ptr Word8 -- ^ 128 bit IV                   -> Ptr Word8 -- ^ 128 bit new IV-                  -> Ptr Word8 -- ^ Result                   -> Ptr Word8 -- ^ Input                   -> Word32    -- ^ Input length in bytes                   -> IO () -c_decrypt_ctr :: AESKeyPtr+c_decrypt_ctr :: Ptr Word8 -- ^ Result+              -> AESKeyPtr               -> Ptr Word8 -- ^ 128 bit IV               -> Ptr Word8 -- ^ 128 bit new IV-              -> Ptr Word8 -- ^ Result               -> Ptr Word8 -- ^ Input               -> Word32    -- ^ Input length in bytes               -> IO ()@@ -105,17 +179,18 @@ 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+generateKey128 :: Ptr Word64+            -- ^ Buffer of 16 bytes of key material+            -> IO (Maybe AESKey128)+generateKey128 keyPtr = do     raw <- do             a <- peekLE (castPtr keyPtr)             let keyPtr2 = (castPtr keyPtr) `plusPtr` sizeOf a             b <- peekLE keyPtr2-            return (RKey b a)-    k <- c_allocate_key128-    c_generate_key128 k (castPtr keyPtr)-    fmap (AESKey raw) (newForeignPtr c_free_key128 k)+            return (RKey128 b a)+    k <- c_allocate_key+    c_aes_initkey k (castPtr keyPtr) 16+    fmap (Just . AESKey128 raw) (newForeignPtr c_free_key k)  where      peekLE :: Ptr Word8 -> IO Word64      peekLE p = do@@ -132,92 +207,197 @@                 (f a4 32) .|. (f a5 24) .|. (f a6 16) .|.                 (f a7 8)  .|. fromIntegral a8         return a-{-# INLINE generateKey #-}+{-# INLINE generateKey128 #-} +-- Given a 16 byte buffer, allocate and return an AESKey+generateKey192 :: Ptr Word64+            -- ^ Buffer of 16 bytes of key material+            -> IO (Maybe AESKey192)+generateKey192 keyPtr = do+    raw <- do+            a <- peekLE (castPtr keyPtr)+            let keyPtr2 = (castPtr keyPtr) `plusPtr` sizeOf a+            b <- peekLE keyPtr2+            let keyPtr3 = (castPtr keyPtr) `plusPtr` sizeOf a `plusPtr` sizeOf b+            c <- peekLE keyPtr3+            return (RKey192 c b a)+    k <- c_allocate_key+    c_aes_initkey k (castPtr keyPtr) 24+    fmap (Just . AESKey192 raw) (newForeignPtr c_free_key k)+ where+     peekLE :: Ptr Word8 -> IO Word64+     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 f n s = fromIntegral n `shiftL` s+        let a = (f a1 56) .|. (f a2 48) .|. (f a3 40) .|.+                (f a4 32) .|. (f a5 24) .|. (f a6 16) .|.+                (f a7 8)  .|. fromIntegral a8+        return a+{-# INLINE generateKey192 #-}++-- Given a 16 byte buffer, allocate and return an AESKey+generateKey256 :: Ptr Word64+            -- ^ Buffer of 16 bytes of key material+            -> IO (Maybe AESKey256)+generateKey256 keyPtr = do+    raw <- do+            a <- peekLE (castPtr keyPtr)+            let keyPtr2 = (castPtr keyPtr) `plusPtr` sizeOf a+            b <- peekLE keyPtr2+            let keyPtr3 = (castPtr keyPtr) `plusPtr` sizeOf a `plusPtr` sizeOf b+            c <- peekLE keyPtr3+            let keyPtr4 = (castPtr keyPtr) `plusPtr` sizeOf a `plusPtr` sizeOf b `plusPtr` sizeOf c+            d <- peekLE keyPtr4+            return (RKey256 d c b a)+    k <- c_allocate_key+    c_aes_initkey k (castPtr keyPtr) 32+    fmap (Just . AESKey256 raw) (newForeignPtr c_free_key k)+ where+     peekLE :: Ptr Word8 -> IO Word64+     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 f n s = fromIntegral n `shiftL` s+        let a = (f a1 56) .|. (f a2 48) .|. (f a3 40) .|.+                (f a4 32) .|. (f a5 24) .|. (f a6 16) .|.+                (f a7 8)  .|. fromIntegral a8+        return a+{-# INLINE generateKey256 #-}+ -- Given a 16 byte buffer, allocate and return an key expansion useful for -- GCM-generateGCM :: Ptr Word64 -- ^ Buffer of 16 bytes of key material-            -> IO GCM-generateGCM keyPtr  = do-    g <- c_gcm_allocate-    k <- c_allocate_key128-    c_generate_key128 k (castPtr keyPtr)-    allocaBytes 12 $ \ivPtr -> do-        mapM_ (\i -> pokeElemOff ivPtr i (0::Word8)) [0..11]-        c_gcm_init g k ivPtr 12-    c_key128_free k-    fmap GCM (newForeignPtr c_free_gcm g)+generateGCM :: GetExpanded k+            => k+            -> IO (Maybe (GCM k))+generateGCM keyStruct+    | otherwise                   = do+    withForeignPtr (expandedKey keyStruct) $ \k -> do+      g <- c_allocate_gcm+      c <- c_allocate_ctx+      allocaBytes 12 $ \ivPtr -> do+          mapM_ (\i -> pokeElemOff ivPtr i (0::Word8)) [0..11]+          c_gcm_init g k+          c_ctx_init g c k ivPtr 12+      gFP <- newForeignPtr c_free_gcm g+      cFP <- newForeignPtr c_free_ctx c+      return (Just $ GCM (GCMpc gFP) keyStruct cFP) {-# INLINE generateGCM #-}  -- An encrypt function that can handle up to blks < maxBound `div` 16 :: Word32 -- simultaneous blocks.-encryptECB :: AESKey    -- ^ The key+encryptECB :: GetExpanded k+           => k         -- ^ 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)+encryptECB (expandedKey -> k) dst src blks = withForeignPtr k $ \p -> c_encrypt_ecb dst p src (fromIntegral blks) {-# INLINE encryptECB #-} -decryptECB :: AESKey    -- ^ The key+decryptECB :: GetExpanded k+           => k         -- ^ 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+decryptECB (expandedKey -> 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)+  | otherwise = withForeignPtr k $ \p -> c_decrypt_ecb dst p src (fromIntegral blks) {-# INLINE decryptECB #-} -encryptGCM :: GCM-           -> Ptr Word8 -> Int  -- IV and length-           -> Ptr Word8 -> Int  -- PT and length-           -> Ptr Word8 -> Int  -- AAD and length-           -> Ptr Word8         -- CT  (length assumed to match PT)-           -> Ptr Word8         -- Tag (length assumed to match blocksize)-           -> IO ()-encryptGCM (GCM k) iv ivlen pt ptlen aad aadlen ct tg = withForeignPtr k $ \g ->-    c_gcm_encrypt ct tg g iv  (fromIntegral ivlen)-                          pt  (fromIntegral ptlen)-                          aad (fromIntegral aadlen)+aadGCM :: GetExpanded k => GCM k -> Ptr Word8 -> Int -> IO ()+aadGCM gcm aad aadLen = withForeignGCM gcm $ \(g,_k,c) ->+    c_gcm_aad g c aad (fromIntegral aadLen) -decryptGCM :: GCM-           -> Ptr Word8 -> Int  -- IV and length-           -> Ptr Word8 -> Int  -- CT and length-           -> Ptr Word8 -> Int  -- AAD and length-           -> Ptr Word8         -- PT (length assumed to match PT)-           -> Ptr Word8         -- Tag (length assumed to match blocksize)-           -> IO ()-decryptGCM (GCM k) iv ivlen ct ctlen aad aadlen pt tg = withForeignPtr k $ \g ->-    c_gcm_decrypt pt tg g-                       iv  (fromIntegral ivlen)-                       ct  (fromIntegral ctlen)-                       aad (fromIntegral aadlen)+cipherOnlyGCM :: GetExpanded k+              => GCM k+              -> Ptr Word8         -- CT  (length assumed to match PT)+              -> Ptr Word8 -> Int  -- PT and length+              -> IO ()+cipherOnlyGCM gcm ct pt ptlen = withForeignGCM gcm $ \(g,k,c) ->+    c_gcm_encrypt ct g c k pt  (fromIntegral ptlen) -finishGCM :: GCM+decipherOnlyGCM :: GetExpanded k+                => GCM k+                -> Ptr Word8         -- PT (length assumed to match CT)+                -> Ptr Word8 -> Int  -- CT and length+                -> IO ()+decipherOnlyGCM gcm pt ct ctlen = withForeignGCM gcm $ \(g,k,c) ->+    c_gcm_decrypt pt g c k ct (fromIntegral ctlen)++finishGCM :: GetExpanded k+          => GCM k           -> Ptr Word8 -- Tag, must point to 16 byte buffer (or larger)           -> IO ()-finishGCM (GCM k) tagPtr = withForeignPtr k $ \g -> c_gcm_finish tagPtr g+finishGCM gcm tagPtr =+    withForeignGCM gcm $ \(gp,kp,cp) -> c_gcm_finish tagPtr gp kp cp -encryptCTR :: AESKey+withForeignGCM :: GetExpanded k => GCM k -> ((AESGcmPtr, AESKeyPtr, AESCtxPtr) -> IO a) -> IO a+withForeignGCM (GCM g k c) f =+    withForeignPtr (unGCMpc g) $ \gp -> withForeignPtr (expandedKey k) $ \kp -> withForeignPtr c $ \cp -> f (gp,kp,cp)++encryptCTR :: GetExpanded k+           => k            -> Ptr Word8 -- ^ IV            -> Ptr Word8 -- ^ NEW IV            -> Ptr Word8 -- ^ CT            -> Ptr Word8 -- ^ PT            -> Int       -- ^ Length in bytes            -> IO ()-encryptCTR (AESKey _ k) iv niv ct pt len = withForeignPtr k $ \p -> do-    c_encrypt_ctr p iv niv ct pt (fromIntegral len)+encryptCTR (expandedKey -> k) iv niv ct pt len = withForeignPtr k $ \p -> do+    c_encrypt_ctr ct p iv niv pt (fromIntegral len) {-# INLINE encryptCTR #-} -decryptCTR :: AESKey+decryptCTR :: GetExpanded k+           => k            -> Ptr Word8 -- ^ IV            -> Ptr Word8 -- ^ NEW IV-           -> Ptr Word8 -- ^ CT            -> Ptr Word8 -- ^ PT+           -> Ptr Word8 -- ^ CT            -> Int       -- ^ Length in bytes            -> IO ()+decryptCTR (expandedKey -> k) iv niv pt ct len = withForeignPtr k $ \p -> do+    c_decrypt_ctr pt p iv niv ct (fromIntegral len) -decryptCTR (AESKey _ k) iv niv ct pt len = withForeignPtr k $ \p -> do-    c_decrypt_ctr p iv niv ct pt (fromIntegral len)+encryptGCM :: GetExpanded k+           => k+           -> GCMpc+           -> Ptr Word8 -> Word32 -- IV+           -> Ptr Word8 -> Word32 -- AAD+           -> Ptr Word8 -> Word32 -- PT+           -> Ptr Word8 -- CT+           -> Ptr Word8 -- Tag+           -> IO ()+encryptGCM (expandedKey -> k) (GCMpc g) iv ivLen aad aadLen pt ptLen ct tag =+    withForeignPtr k $ \kp ->+      withForeignPtr g $ \gp ->+       c_gcm_full_encrypt kp gp iv ivLen aad aadLen pt ptLen ct tag++decryptGCM :: GetExpanded k+           => k+           -> GCMpc+           -> Ptr Word8 -> Word32 -- IV+           -> Ptr Word8 -> Word32 -- AAD+           -> Ptr Word8 -> Word32 -- CT+           -> Ptr Word8 -- PT+           -> Ptr Word8 -- Tag+           -> IO ()+decryptGCM (expandedKey -> k) (GCMpc g) iv ivLen aad aadLen ct ctLen pt tag =+    withForeignPtr k $ \kp ->+      withForeignPtr g $ \gp ->+       c_gcm_full_decrypt kp gp iv ivLen aad aadLen ct ctLen pt tag+ {-# INLINE decryptCTR #-}
Setup.hs view
@@ -13,10 +13,13 @@  where  hk = simpleUserHooks { buildHook = \pd lbi uh bf -> do                                         let ccProg = Program "gcc" undefined undefined undefined-                                            mConf = lookupProgram ccProg (withPrograms lbi)+                                            hcProg = Program "ghc" undefined undefined undefined+                                            mConf  = lookupProgram ccProg (withPrograms lbi)+                                            hcConf = lookupProgram hcProg (withPrograms lbi)                                             err = error "Could not determine C compiler"-                                            cc = locationPath . programLocation  . maybe err id $ mConf-                                        b <- canUseAesIntrinsicsFlag cc+                                            cc  = locationPath . programLocation  . maybe err id $ mConf+                                            hc  = locationPath . programLocation  . maybe err id $ hcConf+                                        b <- canUseAesIntrinsicsFlag hc                                         let newWithPrograms1 = userSpecifyArgs "gcc" aesArgs (withPrograms lbi)                                             newWithPrograms  = userSpecifyArgs "ghc" aesArgsHC newWithPrograms1                                             lbiNew = if b then (lbi {withPrograms = newWithPrograms }) else lbi@@ -24,7 +27,7 @@                       }  aesArgs :: [String]-aesArgs = ["-maes", "-mssse3", "-DHAVE_AES_INTRINSICS"]+aesArgs = ["-mpclmul", "-maes", "-mssse3", "-DHAVE_AES_INTRINSICS", "-DWITH_AESNI"]  aesArgsHC :: [String] aesArgsHC = map ("-optc" ++) aesArgs@@ -34,9 +37,9 @@         withTempDirectory normal "" "testIntrinsic" $ \tmpDir -> do         writeFile (tmpDir ++ "/testIntrinsic.c")                 (unlines        [ "#include <wmmintrin.h>"-                                , "int main() {"+                                , "int real_main() {"                                 , "return 0; }"                                 ])-        ec <- rawSystemExitCode normal cc ["-maes",tmpDir ++ "/testIntrinsic.c"]+        ec <- rawSystemExitCode normal cc (aesArgsHC ++ ["-c", tmpDir ++ "/testIntrinsic.c"])         notice normal $ "Result of NI Intrinsics Test: " ++ show (ec == ExitSuccess)         return (ec == ExitSuccess)
+ Test/test.hs view
@@ -0,0 +1,9 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE PackageImports #-}+import Test.AES+import Crypto.Cipher.AES128+import "test-framework" Test.Framework++main = do+    ts <- makeAESTests (undefined :: AESKey128)+    defaultMain ts
+ cbits/LICENSE view
@@ -0,0 +1,27 @@+Copyright (c) 2008-2013 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.c view
@@ -0,0 +1,591 @@+/*+ * 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 "cpu.h"+#include "aes.h"+#include "aes_generic.h"+#include "bitfn.h"+#include <string.h>+#include <stdio.h>++#include "gf.h"+#include "aes_x86ni.h"++void tmd_aes_generic_encrypt_ecb(aes_block *output, aes_key *key, aes_block *input, uint32_t nb_blocks);+void tmd_aes_generic_decrypt_ecb(aes_block *output, aes_key *key, aes_block *input, uint32_t nb_blocks);+void tmd_aes_generic_encrypt_cbc(aes_block *output, aes_key *key, aes_block *iv, aes_block *input, uint32_t nb_blocks);+void tmd_aes_generic_decrypt_cbc(aes_block *output, aes_key *key, aes_block *iv, aes_block *input, uint32_t nb_blocks);+void tmd_aes_generic_encrypt_ctr(uint8_t *output, aes_key *key, aes_block *iv, aes_block *newIV, uint8_t *input, uint32_t length);+void tmd_aes_generic_encrypt_xts(aes_block *output, aes_key *k1, aes_key *k2, aes_block *dataunit,+                             uint32_t spoint, aes_block *input, uint32_t nb_blocks);+void tmd_aes_generic_decrypt_xts(aes_block *output, aes_key *k1, aes_key *k2, aes_block *dataunit,+                             uint32_t spoint, aes_block *input, uint32_t nb_blocks);+void tmd_aes_generic_gcm_encrypt(uint8_t *output, aes_gcm *gcm, aes_ctx *ctx, aes_key *key, uint8_t *input, uint32_t length);+void tmd_aes_generic_gcm_decrypt(uint8_t *output, aes_gcm *gcm, aes_ctx *ctx, aes_key *key, uint8_t *input, uint32_t length);++enum {+        /* init */+        INIT_128, INIT_192, INIT_256,+        /* single block */+        ENCRYPT_BLOCK_128, ENCRYPT_BLOCK_192, ENCRYPT_BLOCK_256,+        DECRYPT_BLOCK_128, DECRYPT_BLOCK_192, DECRYPT_BLOCK_256,+        /* ecb */+        ENCRYPT_ECB_128, ENCRYPT_ECB_192, ENCRYPT_ECB_256,+        DECRYPT_ECB_128, DECRYPT_ECB_192, DECRYPT_ECB_256,+        /* cbc */+        ENCRYPT_CBC_128, ENCRYPT_CBC_192, ENCRYPT_CBC_256,+        DECRYPT_CBC_128, DECRYPT_CBC_192, DECRYPT_CBC_256,+        /* ctr */+        ENCRYPT_CTR_128, ENCRYPT_CTR_192, ENCRYPT_CTR_256,+        /* xts */+        ENCRYPT_XTS_128, ENCRYPT_XTS_192, ENCRYPT_XTS_256,+        DECRYPT_XTS_128, DECRYPT_XTS_192, DECRYPT_XTS_256,+        /* xts */+        ENCRYPT_GCM_128, ENCRYPT_GCM_192, ENCRYPT_GCM_256,+        DECRYPT_GCM_128, DECRYPT_GCM_192, DECRYPT_GCM_256,+};++void *tmd_branch_table[] = {+        /* INIT */+        [INIT_128]          = tmd_aes_generic_init,+        [INIT_192]          = tmd_aes_generic_init,+        [INIT_256]          = tmd_aes_generic_init,+        /* BLOCK */+        [ENCRYPT_BLOCK_128] = tmd_aes_generic_encrypt_block,+        [ENCRYPT_BLOCK_192] = tmd_aes_generic_encrypt_block,+        [ENCRYPT_BLOCK_256] = tmd_aes_generic_encrypt_block,+        [DECRYPT_BLOCK_128] = tmd_aes_generic_decrypt_block,+        [DECRYPT_BLOCK_192] = tmd_aes_generic_decrypt_block,+        [DECRYPT_BLOCK_256] = tmd_aes_generic_decrypt_block,+        /* ECB */+        [ENCRYPT_ECB_128]   = tmd_aes_generic_encrypt_ecb,+        [ENCRYPT_ECB_192]   = tmd_aes_generic_encrypt_ecb,+        [ENCRYPT_ECB_256]   = tmd_aes_generic_encrypt_ecb,+        [DECRYPT_ECB_128]   = tmd_aes_generic_decrypt_ecb,+        [DECRYPT_ECB_192]   = tmd_aes_generic_decrypt_ecb,+        [DECRYPT_ECB_256]   = tmd_aes_generic_decrypt_ecb,+        /* CBC */+        [ENCRYPT_CBC_128]   = tmd_aes_generic_encrypt_cbc,+        [ENCRYPT_CBC_192]   = tmd_aes_generic_encrypt_cbc,+        [ENCRYPT_CBC_256]   = tmd_aes_generic_encrypt_cbc,+        [DECRYPT_CBC_128]   = tmd_aes_generic_decrypt_cbc,+        [DECRYPT_CBC_192]   = tmd_aes_generic_decrypt_cbc,+        [DECRYPT_CBC_256]   = tmd_aes_generic_decrypt_cbc,+        /* CTR */+        [ENCRYPT_CTR_128]   = tmd_aes_generic_encrypt_ctr,+        [ENCRYPT_CTR_192]   = tmd_aes_generic_encrypt_ctr,+        [ENCRYPT_CTR_256]   = tmd_aes_generic_encrypt_ctr,+        /* XTS */+        [ENCRYPT_XTS_128]   = tmd_aes_generic_encrypt_xts,+        [ENCRYPT_XTS_192]   = tmd_aes_generic_encrypt_xts,+        [ENCRYPT_XTS_256]   = tmd_aes_generic_encrypt_xts,+        [DECRYPT_XTS_128]   = tmd_aes_generic_decrypt_xts,+        [DECRYPT_XTS_192]   = tmd_aes_generic_decrypt_xts,+        [DECRYPT_XTS_256]   = tmd_aes_generic_decrypt_xts,+        /* GCM */+        [ENCRYPT_GCM_128]   = tmd_aes_generic_gcm_encrypt,+        [ENCRYPT_GCM_192]   = tmd_aes_generic_gcm_encrypt,+        [ENCRYPT_GCM_256]   = tmd_aes_generic_gcm_encrypt,+        [DECRYPT_GCM_128]   = tmd_aes_generic_gcm_decrypt,+        [DECRYPT_GCM_192]   = tmd_aes_generic_gcm_decrypt,+        [DECRYPT_GCM_256]   = tmd_aes_generic_gcm_decrypt,+};++typedef void (*init_f)(aes_key *, uint8_t *, uint8_t);+typedef void (*ecb_f)(aes_block *output, aes_key *key, aes_block *input, uint32_t nb_blocks);+typedef void (*cbc_f)(aes_block *output, aes_key *key, aes_block *iv, aes_block *input, uint32_t nb_blocks);+typedef void (*ctr_f)(uint8_t *output, aes_key *key, aes_block *iv, aes_block *niv, uint8_t *input, uint32_t length);+typedef void (*xts_f)(aes_block *output, aes_key *k1, aes_key *k2, aes_block *dataunit, uint32_t spoint, aes_block *input, uint32_t nb_blocks);+typedef void (*gcm_crypt_f)(uint8_t *output, aes_gcm *gcm, aes_ctx *ctx, aes_key *key, uint8_t *input, uint32_t length);+typedef void (*block_f)(aes_block *output, aes_key *key, aes_block *input);++#ifdef WITH_AESNI+#define GET_INIT(strength) \+        ((init_f) (tmd_branch_table[INIT_128 + strength]))+#define GET_ECB_ENCRYPT(strength) \+        ((ecb_f) (tmd_branch_table[ENCRYPT_ECB_128 + strength]))+#define GET_ECB_DECRYPT(strength) \+        ((ecb_f) (tmd_branch_table[DECRYPT_ECB_128 + strength]))+#define GET_CBC_ENCRYPT(strength) \+        ((cbc_f) (tmd_branch_table[ENCRYPT_CBC_128 + strength]))+#define GET_CBC_DECRYPT(strength) \+        ((cbc_f) (tmd_branch_table[DECRYPT_CBC_128 + strength]))+#define GET_CTR_ENCRYPT(strength) \+        ((ctr_f) (tmd_branch_table[ENCRYPT_CTR_128 + strength]))+#define GET_XTS_ENCRYPT(strength) \+        ((xts_f) (tmd_branch_table[ENCRYPT_XTS_128 + strength]))+#define GET_XTS_DECRYPT(strength) \+        ((xts_f) (tmd_branch_table[DECRYPT_XTS_128 + strength]))+#define GET_GCM_ENCRYPT(strength) \+        ((gcm_crypt_f) (tmd_branch_table[ENCRYPT_GCM_128 + strength]))+#define GET_GCM_DECRYPT(strength) \+        ((gcm_crypt_f) (tmd_branch_table[DECRYPT_GCM_128 + strength]))+#define aes_encrypt_block(o,k,i) \+        (((block_f) (tmd_branch_table[ENCRYPT_BLOCK_128 + k->strength]))(o,k,i))+#define aes_decrypt_block(o,k,i) \+        (((block_f) (tmd_branch_table[DECRYPT_BLOCK_128 + k->strength]))(o,k,i))+#else+#define GET_INIT(strenght) tmd_aes_generic_init+#define GET_ECB_ENCRYPT(strength) tmd_aes_generic_encrypt_ecb+#define GET_ECB_DECRYPT(strength) tmd_aes_generic_decrypt_ecb+#define GET_CBC_ENCRYPT(strength) tmd_aes_generic_encrypt_cbc+#define GET_CBC_DECRYPT(strength) tmd_aes_generic_decrypt_cbc+#define GET_CTR_ENCRYPT(strength) tmd_aes_generic_encrypt_ctr+#define GET_XTS_ENCRYPT(strength) tmd_aes_generic_encrypt_xts+#define GET_XTS_DECRYPT(strength) tmd_aes_generic_decrypt_xts+#define GET_GCM_ENCRYPT(strength) tmd_aes_generic_gcm_encrypt+#define GET_GCM_DECRYPT(strength) tmd_aes_generic_gcm_decrypt+#define aes_encrypt_block(o,k,i) tmd_aes_generic_encrypt_block(o,k,i)+#define aes_decrypt_block(o,k,i) tmd_aes_generic_decrypt_block(o,k,i)+#endif++#if defined(ARCH_X86) && defined(WITH_AESNI)+void tmd_initialize_table_ni(int aesni, int pclmul)+{+        if (!aesni)+                return;+        tmd_branch_table[INIT_128] = tmd_aes_ni_init;+        tmd_branch_table[INIT_256] = tmd_aes_ni_init;++        tmd_branch_table[ENCRYPT_BLOCK_128] = tmd_aes_ni_encrypt_block128;+        tmd_branch_table[DECRYPT_BLOCK_128] = tmd_aes_ni_decrypt_block128;+        tmd_branch_table[ENCRYPT_BLOCK_256] = tmd_aes_ni_encrypt_block256;+        tmd_branch_table[DECRYPT_BLOCK_256] = tmd_aes_ni_decrypt_block256;+        /* ECB */+        tmd_branch_table[ENCRYPT_ECB_128] = tmd_aes_ni_encrypt_ecb128;+        tmd_branch_table[DECRYPT_ECB_128] = tmd_aes_ni_decrypt_ecb128;+        tmd_branch_table[ENCRYPT_ECB_256] = tmd_aes_ni_encrypt_ecb256;+        tmd_branch_table[DECRYPT_ECB_256] = tmd_aes_ni_decrypt_ecb256;+        /* CBC */+        tmd_branch_table[ENCRYPT_CBC_128] = tmd_aes_ni_encrypt_cbc128;+        tmd_branch_table[DECRYPT_CBC_128] = tmd_aes_ni_decrypt_cbc128;+        tmd_branch_table[ENCRYPT_CBC_256] = tmd_aes_ni_encrypt_cbc256;+        tmd_branch_table[DECRYPT_CBC_256] = tmd_aes_ni_decrypt_cbc256;+        /* CTR */+        tmd_branch_table[ENCRYPT_CTR_128] = tmd_aes_ni_encrypt_ctr128;+        tmd_branch_table[ENCRYPT_CTR_256] = tmd_aes_ni_encrypt_ctr256;+        /* XTS */+        tmd_branch_table[ENCRYPT_XTS_128] = tmd_aes_ni_encrypt_xts128;+        tmd_branch_table[ENCRYPT_XTS_256] = tmd_aes_ni_encrypt_xts256;+        /* GCM */+        tmd_branch_table[ENCRYPT_GCM_128] = tmd_aes_ni_gcm_encrypt128;+        tmd_branch_table[ENCRYPT_GCM_256] = tmd_aes_ni_gcm_encrypt256;+}+#endif++aes_key *tmd_allocatekey()+{+    aes_key *res = (aes_key *)malloc(sizeof(aes_key));+    return res;+}++aes_ctx *tmd_allocatectx()+{+    aes_ctx *res = (aes_ctx *)malloc(sizeof(aes_ctx));+    return res;+}++aes_gcm *tmd_allocategcm()+{+    aes_gcm *res = (aes_gcm *)malloc(sizeof(aes_gcm));+    return res;+}++void tmd_freekey(aes_key *k)+{+    free(k);+}++void tmd_freectx(aes_ctx *c)+{+    free(c);+}++void tmd_freegcm(aes_gcm *g)+{+    free(g);+}++void tmd_aes_initkey(aes_key *key, uint8_t *origkey, uint8_t size)+{+        switch (size) {+        case 16: key->nbr = 10; key->strength = 0; break;+        case 24: key->nbr = 12; key->strength = 1; break;+        case 32: key->nbr = 14; key->strength = 2; break;+        }+#if defined(ARCH_X86) && defined(WITH_AESNI)+        initialize_hw(tmd_initialize_table_ni);+#endif+        init_f _init = GET_INIT(key->strength);+        _init(key, origkey, size);+}++void tmd_aes_encrypt_ecb(aes_block *output, aes_key *key, aes_block *input, uint32_t nb_blocks)+{+        ecb_f e = GET_ECB_ENCRYPT(key->strength);+        e(output, key, input, nb_blocks);+}++void tmd_aes_decrypt_ecb(aes_block *output, aes_key *key, aes_block *input, uint32_t nb_blocks)+{+        ecb_f d = GET_ECB_DECRYPT(key->strength);+        d(output, key, input, nb_blocks);+}++void tmd_aes_encrypt_cbc(aes_block *output, aes_key *key, aes_block *iv, aes_block *input, uint32_t nb_blocks)+{+        cbc_f e = GET_CBC_ENCRYPT(key->strength);+        e(output, key, iv, input, nb_blocks);+}++void tmd_aes_decrypt_cbc(aes_block *output, aes_key *key, aes_block *iv, aes_block *input, uint32_t nb_blocks)+{+        cbc_f d = GET_CBC_DECRYPT(key->strength);+        d(output, key, iv, input, nb_blocks);+}++void tmd_aes_gen_ctr(aes_block *output, aes_key *key, aes_block *iv, uint32_t nb_blocks)+{+        aes_block block;++        /* preload IV in block */+        block128_copy(&block, iv);++        for ( ; nb_blocks-- > 0; output++, block128_inc_be(&block)) {+                aes_encrypt_block(output, key, &block);+        }+}++void tmd_aes_encrypt_ctr(uint8_t *output, aes_key *key, aes_block *iv, aes_block *newIV, uint8_t *input, uint32_t len)+{+        ctr_f e = GET_CTR_ENCRYPT(key->strength);+        e(output, key, iv, newIV, input, len);+}++void tmd_aes_encrypt_xts(aes_block *output, aes_key *k1, aes_key *k2, aes_block *dataunit,+                     uint32_t spoint, aes_block *input, uint32_t nb_blocks)+{+        xts_f e = GET_XTS_ENCRYPT(k1->strength);+        e(output, k1, k2, dataunit, spoint, input, nb_blocks);+}++void tmd_aes_decrypt_xts(aes_block *output, aes_key *k1, aes_key *k2, aes_block *dataunit,+                     uint32_t spoint, aes_block *input, uint32_t nb_blocks)+{+        tmd_aes_generic_decrypt_xts(output, k1, k2, dataunit, spoint, input, nb_blocks);+}++void tmd_aes_gcm_encrypt(uint8_t *output, aes_gcm *gcm, aes_ctx *ctx, aes_key *key, uint8_t *input, uint32_t length)+{+        gcm_crypt_f e = GET_GCM_ENCRYPT(key->strength);+        e(output, gcm, ctx, key, input, length);+}++void tmd_aes_gcm_decrypt(uint8_t *output, aes_gcm *gcm, aes_ctx *ctx, aes_key *key, uint8_t *input, uint32_t length)+{+        gcm_crypt_f d = GET_GCM_DECRYPT(key->strength);+        d(output, gcm, ctx, key, input, length);+}++static void gcm_ghash_add(aes_gcm *gcm, aes_ctx *ctx, block128 *b)+{+        block128_xor(&ctx->tag, b);+        gf_mul(&ctx->tag, &gcm->h);+}++void tmd_aes_gcm_init(aes_gcm *gcm, aes_key *key)+{+        block128_zero(&gcm->h);+        /* prepare H : encrypt_K(0^128) */+        aes_encrypt_block(&gcm->h, key, &gcm->h);+}++void tmd_aes_ctx_init(const aes_gcm *gcm, aes_ctx *ctx, const aes_key *key, uint8_t *iv, uint32_t len)+{+        ctx->length_aad = 0;+        ctx->length_input = 0;++        block128_zero(&ctx->tag);+        block128_zero(&ctx->iv);++        if (len == 12) {+                block128_copy_bytes(&ctx->iv, iv, 12);+                ctx->iv.b[15] = 0x01;+        } else {+                uint32_t origlen = len << 3;+                int i;+                for (; len >= 16; len -= 16, iv += 16) {+                        block128_xor(&ctx->iv, (block128 *) iv);+                        gf_mul(&ctx->iv, &gcm->h);+                }+                if (len > 0) {+                        block128_xor_bytes(&ctx->iv, iv, len);+                        gf_mul(&ctx->iv, &gcm->h);+                }+                for (i = 15; origlen; --i, origlen >>= 8)+                        ctx->iv.b[i] ^= (uint8_t) origlen;+                gf_mul(&ctx->iv, &gcm->h);+        }++        block128_copy(&ctx->civ, &ctx->iv);+}++void tmd_aes_gcm_aad(aes_gcm *gcm, aes_ctx *ctx, uint8_t *input, uint32_t length)+{+        ctx->length_aad += length;+        for (; length >= 16; input += 16, length -= 16) {+                gcm_ghash_add(gcm, ctx, (block128 *) input);+        }+        if (length > 0) {+                aes_block tmp;+                block128_zero(&tmp);+                block128_copy_bytes(&tmp, input, length);+                gcm_ghash_add(gcm, ctx, &tmp);+        }++}++void tmd_aes_gcm_finish(uint8_t *tag, aes_gcm *gcm, aes_key *key, aes_ctx *ctx)+{+        aes_block lblock;+        int i;++        /* tag = (tag-1 xor (lenbits(a) | lenbits(c)) ) . H */+        lblock.q[0] = cpu_to_be64(ctx->length_aad << 3);+        lblock.q[1] = cpu_to_be64(ctx->length_input << 3);+        gcm_ghash_add(gcm, ctx, &lblock);++        aes_encrypt_block(&lblock, key, &ctx->iv);+        block128_xor(&ctx->tag, &lblock);++        for (i = 0; i < 16; i++) {+                tag[i] = ctx->tag.b[i];+        }+}++void tmd_aes_gcm_full_encrypt(aes_key *key, aes_gcm *gcm+                             , 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_ctx ctx;+    tmd_aes_ctx_init(gcm, &ctx, key, iv, ivLen);+    tmd_aes_gcm_encrypt(ct, gcm, &ctx, key, pt, ptLen);+    tmd_aes_gcm_aad(gcm, &ctx, aad, aadLen);+    tmd_aes_gcm_finish(tag, gcm, key, &ctx);+}++void tmd_aes_gcm_full_decrypt(aes_key *key, aes_gcm *gcm+                             , 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_ctx ctx;+    tmd_aes_ctx_init(gcm, &ctx, key, iv, ivLen);+    tmd_aes_gcm_decrypt(pt, gcm, &ctx, key, ct, ctLen);+    tmd_aes_gcm_aad(gcm, &ctx, aad, aadLen);+    tmd_aes_gcm_finish(tag, gcm, key, &ctx);+}++void tmd_aes_generic_encrypt_ecb(aes_block *output, aes_key *key, aes_block *input, uint32_t nb_blocks)+{+        for ( ; nb_blocks-- > 0; input++, output++) {+                tmd_aes_generic_encrypt_block(output, key, input);+        }+}++void tmd_aes_generic_decrypt_ecb(aes_block *output, aes_key *key, aes_block *input, uint32_t nb_blocks)+{+        for ( ; nb_blocks-- > 0; input++, output++) {+                tmd_aes_generic_decrypt_block(output, key, input);+        }+}++void tmd_aes_generic_encrypt_cbc(aes_block *output, aes_key *key, aes_block *iv, aes_block *input, uint32_t nb_blocks)+{+        aes_block block;++        /* preload IV in block */+        block128_copy(&block, iv);+        for ( ; nb_blocks-- > 0; input++, output++) {+                block128_xor(&block, (block128 *) input);+                tmd_aes_generic_encrypt_block(&block, key, &block);+                block128_copy((block128 *) output, &block);+        }+}++void tmd_aes_generic_decrypt_cbc(aes_block *output, aes_key *key, aes_block *ivini, aes_block *input, uint32_t nb_blocks)+{+        aes_block block, blocko;+        aes_block iv;++        /* preload IV in block */+        block128_copy(&iv, ivini);+        for ( ; nb_blocks-- > 0; input++, output++) {+                block128_copy(&block, (block128 *) input);+                tmd_aes_generic_decrypt_block(&blocko, key, &block);+                block128_vxor((block128 *) output, &blocko, &iv);+                block128_copy(&iv, &block);+        }+}++void tmd_aes_generic_encrypt_ctr(uint8_t *output, aes_key *key, aes_block *iv, aes_block *newIV, uint8_t *input, uint32_t len)+{+        aes_block block, o;+        uint32_t nb_blocks = len / 16;+        int i;++        /* preload IV in block */+        block128_copy(&block, iv);++        for ( ; nb_blocks-- > 0; block128_inc_be(&block), output += 16, input += 16) {+                aes_encrypt_block(&o, key, &block);+                block128_vxor((block128 *) output, &o, (block128 *) input);+        }++        if ((len % 16) != 0) {+                aes_encrypt_block(&o, key, &block);+                for (i = 0; i < (len % 16); i++) {+                        *output = ((uint8_t *) &o)[i] ^ *input;+                        output++;+                        input++;+                }+        }+        if(NULL != newIV)+            block128_copy(newIV, &block);+}++void tmd_aes_generic_encrypt_xts(aes_block *output, aes_key *k1, aes_key *k2, aes_block *dataunit,+                             uint32_t spoint, aes_block *input, uint32_t nb_blocks)+{+        aes_block block, tweak;++        /* load IV and encrypt it using k2 as the tweak */+        block128_copy(&tweak, dataunit);+        aes_encrypt_block(&tweak, k2, &tweak);++        /* TO OPTIMISE: this is really inefficient way to do that */+        while (spoint-- > 0)+                gf_mulx(&tweak);++        for ( ; nb_blocks-- > 0; input++, output++, gf_mulx(&tweak)) {+                block128_vxor(&block, input, &tweak);+                aes_encrypt_block(&block, k1, &block);+                block128_vxor(output, &block, &tweak);+        }+}++void tmd_aes_generic_decrypt_xts(aes_block *output, aes_key *k1, aes_key *k2, aes_block *dataunit,+                             uint32_t spoint, aes_block *input, uint32_t nb_blocks)+{+        aes_block block, tweak;++        /* load IV and encrypt it using k2 as the tweak */+        block128_copy(&tweak, dataunit);+        aes_encrypt_block(&tweak, k2, &tweak);++        /* TO OPTIMISE: this is really inefficient way to do that */+        while (spoint-- > 0)+                gf_mulx(&tweak);++        for ( ; nb_blocks-- > 0; input++, output++, gf_mulx(&tweak)) {+                block128_vxor(&block, input, &tweak);+                aes_decrypt_block(&block, k1, &block);+                block128_vxor(output, &block, &tweak);+        }+}++void tmd_aes_generic_gcm_encrypt(uint8_t *output, aes_gcm *gcm, aes_ctx *ctx, aes_key *key, uint8_t *input, uint32_t length)+{+        aes_block out;++        ctx->length_input += length;+        for (; length >= 16; input += 16, output += 16, length -= 16) {+                block128_inc_be(&ctx->civ);++                aes_encrypt_block(&out, key, &ctx->civ);+                block128_xor(&out, (block128 *) input);+                gcm_ghash_add(gcm, ctx, &out);+                block128_copy((block128 *) output, &out);+        }+        if (length > 0) {+                aes_block tmp;+                int i;++                block128_inc_be(&ctx->civ);+                /* create e(civ) in out */+                aes_encrypt_block(&out, key, &ctx->civ);+                /* 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, ctx, &tmp);++                for (i = 0; i < length; i++) {+                        output[i] = tmp.b[i];+                }+        }+}++void tmd_aes_generic_gcm_decrypt(uint8_t *output, aes_gcm *gcm, aes_ctx *ctx, aes_key *key, uint8_t *input, uint32_t length)+{+        aes_block out;++        ctx->length_input += length;+        for (; length >= 16; input += 16, output += 16, length -= 16) {+                block128_inc_be(&ctx->civ);++                aes_encrypt_block(&out, key, &ctx->civ);+                gcm_ghash_add(gcm, ctx, (block128 *) input);+                block128_xor(&out, (block128 *) input);+                block128_copy((block128 *) output, &out);+        }+        if (length > 0) {+                aes_block tmp;+                int i;++                block128_inc_be(&ctx->civ);++                block128_zero(&tmp);+                block128_copy_bytes(&tmp, input, length);+                gcm_ghash_add(gcm, ctx, &tmp);++                aes_encrypt_block(&out, key, &ctx->civ);+                block128_xor_bytes(&tmp, out.b, length);++                for (i = 0; i < length; i++) {+                        output[i] = tmp.b[i];+                }+        }+}+
+ cbits/aes.h view
@@ -0,0 +1,95 @@+/*+ *	Copyright (C) 2008 Vincent Hanquez <tab@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+ */+#ifndef AES_H+#define AES_H++#include <stdint.h>+#include "block128.h"++typedef block128 aes_block;++/* size = 456 */+typedef struct {+	uint8_t nbr; /* number of rounds: 10 (128), 12 (192), 14 (256) */+	uint8_t strength; /* 128 = 0, 192 = 1, 256 = 2 */+	uint8_t _padding[6];+	uint8_t data[16*14*2];+} aes_key;++/* size = 4*16+2*8= 80 */+typedef struct {+	aes_block h;+} aes_gcm;++typedef struct {+	aes_block tag;+	aes_block iv;+	aes_block civ;+	uint64_t length_aad;+	uint64_t length_input;+} aes_ctx;++aes_key *tmd_allocatekey();+aes_ctx *tmd_allocatectx();+aes_gcm *tmd_allocategcm();+void tmd_freekey(aes_key *k);+void tmd_freectx(aes_ctx *c);+void tmd_freegcm(aes_gcm *g);++/* in bytes: either 16,24,32 */+void tmd_aes_initkey(aes_key *ctx, uint8_t *key, uint8_t size);++void tmd_aes_encrypt(aes_block *output, aes_key *key, aes_block *input);+void tmd_aes_decrypt(aes_block *output, aes_key *key, aes_block *input);++void tmd_aes_encrypt_ecb(aes_block *output, aes_key *key, aes_block *input, uint32_t nb_blocks);+void tmd_aes_decrypt_ecb(aes_block *output, aes_key *key, aes_block *input, uint32_t nb_blocks);++void tmd_aes_encrypt_cbc(aes_block *output, aes_key *key, aes_block *iv, aes_block *input, uint32_t nb_blocks);+void tmd_aes_decrypt_cbc(aes_block *output, aes_key *key, aes_block *iv, aes_block *input, uint32_t nb_blocks);++void tmd_aes_encrypt_ctr(uint8_t *output, aes_key *key, aes_block *iv, aes_block *newIV, uint8_t *input, uint32_t len);+void tmd_aes_gen_ctr(aes_block *output, aes_key *key, aes_block *iv, uint32_t nb_blocks);++void tmd_aes_encrypt_xts(aes_block *output, aes_key *key, aes_key *key2, aes_block *sector,+                     uint32_t spoint, aes_block *input, uint32_t nb_blocks);+void tmd_aes_decrypt_xts(aes_block *output, aes_key *key, aes_key *key2, aes_block *sector,+                     uint32_t spoint, aes_block *input, uint32_t nb_blocks);++void tmd_aes_gcm_init(aes_gcm *gcm, aes_key *key);+void tmd_aes_ctx_init(const aes_gcm *gcm, aes_ctx *ctx, const aes_key *key, uint8_t *iv, uint32_t len);+void tmd_aes_gcm_aad(aes_gcm *gcm, aes_ctx *ctx, uint8_t *input, uint32_t length);+void tmd_aes_gcm_encrypt(uint8_t *output, aes_gcm *gcm, aes_ctx *ctx, aes_key *key, uint8_t *input, uint32_t length);+void tmd_aes_gcm_decrypt(uint8_t *output, aes_gcm *gcm, aes_ctx *ctx, aes_key *key, uint8_t *input, uint32_t length);+void tmd_aes_gcm_finish(uint8_t *tag, aes_gcm *gcm, aes_key *key, aes_ctx *ctx);++#endif
− cbits/aes/LICENSE
@@ -1,29 +0,0 @@-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
@@ -1,441 +0,0 @@-#include "aes_generic.h"-#include "aes.h"-#include <string.h>-#include <stdlib.h>--#if (defined(__i386__) || defined(__x86_64__)) && defined(HAVE_AES_INTRINSICS) && !defined(AVOID_NI)-#define TRY_NI-#include "aes_x86ni.h"-#endif-#include "bitfn.h"-static void gf_mul(block128 *a, const block128 *b);--#ifdef TRY_NI-/**- * Returns zero if false, non-zero otherwise- */-static 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;-}--aes_gcm *allocate_gcm()-{-    void *g=NULL;-    g = (void *)malloc(sizeof(aes_gcm));-    return g;-}--/* Generate Key */-#ifdef TRY_NI-static void detect_and_generate_key128(AESKey *k, const uint8_t *bytes);-static 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);-}--static void generate_key128_generic(AESKey *k, const uint8_t *bytes)-{-    aes128_generic_init(k, bytes, 16);-}--static void generate_key128_ni(AESKey *k, const uint8_t *bytes)-{-    aes128_ni_init((aes_key *)k, bytes, 16);-}--static 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)-{-    aes128_generic_init(k, bytes, 16);-}-#endif--void free_key128(AESKey *k)-{-        memset(k, 0, sizeof(AESKey));-        free(k);-}--void free_gcm(aes_gcm *g)-{-        memset(g, 0, sizeof(aes_gcm));-        free(g);-}--/* ECB Encrypt */-#ifdef TRY_NI-static void detect_and_encrypt_ecb(const AESKey *k, uint8_t *dst, const uint8_t *src, const uint32_t nr);-static void (*encrypt_ecb_ptr)(const AESKey *, uint8_t *, const uint8_t *, const uint32_t) = &detect_and_encrypt_ecb;--static void encrypt_ecb_ni(const AESKey *k, uint8_t *dst, const uint8_t *src, const uint32_t nr)-{-        aes128_ni_encrypt_ecb(dst, (aes_key *)k, src, nr);-}--static 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) {-        aes128_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);-}--static 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) {-        aes128_generic_encrypt_block-                       ( (aes_block*) dst+i-                       , k-                       , (const aes_block*)src+i);-    }-}-#endif--/* ECB Decrypt */-#ifdef TRY_NI-static void detect_and_decrypt_ecb(const AESKey *k, uint8_t *dst, const uint8_t *src, const uint32_t nr);-static 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);-}--static void decrypt_ecb_ni(const AESKey *k, uint8_t *dst, const uint8_t *src, const uint32_t nr)-{-        aes128_ni_decrypt_ecb(dst, (aes_key *)k, src, nr);-}--static 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) {-        aes128_generic_decrypt_block ( (aes_block*) dst+i-                                  , k-                                  , (const aes_block*)src+i);-    }-}--static 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) {-        aes128_generic_decrypt_block ( (aes_block*) dst+i-                                  , k-                                  , (const aes_block*)src+i);-    }-}-#endif---/* GCM */-static void gcm_ghash_add(const aes_gcm *gcm, aes_gcm_ctx *ctx, block128 *b)-{-        block128_xor(&ctx->tag, b);-        gf_mul(&ctx->tag, &gcm->h);-}--void aes_gcm_ctx_init(aes_gcm_ctx *ctx, const aes_gcm *gcm, const uint8_t *iv, uint32_t len)-{-        ctx->length_aad = 0;-        ctx->length_input = 0;-        block128_zero(&ctx->tag);--        block128_zero(&ctx->iv);-        if (len == 12) {-                block128_copy_bytes(&ctx->iv, iv, 12);-                ctx->iv.b[15] = 0x01;-        } else {-                uint32_t origlen = len << 3;-                int i;-                for (; len >= 16; len -= 16, iv += 16) {-                        block128_xor(&ctx->iv, (block128 *) iv);-                        gf_mul(&ctx->iv, &gcm->h);-                }-                if (len > 0) {-                        block128_xor_bytes(&ctx->iv, iv, len);-                        gf_mul(&ctx->iv, &gcm->h);-                }-                for (i = 15; origlen; --i, origlen >>= 8)-                        ctx->iv.b[i] ^= (uint8_t) origlen;-                gf_mul(&ctx->iv, &gcm->h);-        }--        block128_copy(&ctx->civ, &ctx->iv);-}--void aes_gcm_init(aes_gcm *gcm, const aes_key *key)-{-        block128_zero(&gcm->h);--        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);-}--void aes_gcm_aad(const aes_gcm *gcm, aes_gcm_ctx *ctx, uint8_t *input, uint32_t length)-{-        ctx->length_aad += length;-        for (; length >= 16; input += 16, length -= 16) {-                gcm_ghash_add(gcm, ctx, (block128 *) input);-        }-        if (length > 0) {-                aes_block tmp;-                block128_zero(&tmp);-                block128_copy_bytes(&tmp, input, length);-                gcm_ghash_add(gcm, ctx, &tmp);-        }--}--void aes_gcm_enc_finish( uint8_t *output, uint8_t *tag-                       , const aes_gcm *gcm-                       , uint8_t *iv, uint32_t ivLen-                       , uint8_t *input, uint32_t inputLen-                       , uint8_t *aad, uint32_t aadLen)-{-    aes_gcm_ctx ctx;-    aes_gcm_ctx_init(&ctx, gcm, iv, ivLen);-    aes_gcm_encrypt(output, gcm, &ctx, input, inputLen);-    aes_gcm_aad(gcm, &ctx, aad, aadLen);-    aes_gcm_finish(tag, gcm, &ctx);-}--void aes_gcm_dec_finish( uint8_t *output, uint8_t *tag-                       , const aes_gcm *gcm-                       , uint8_t *iv, uint32_t ivLen-                       , uint8_t *input, uint32_t inputLen-                       , uint8_t *aad, uint32_t aadLen)-{-    aes_gcm_ctx ctx;-    aes_gcm_ctx_init(&ctx, gcm, iv, ivLen);-    aes_gcm_decrypt(output, gcm, &ctx, input, inputLen);-    aes_gcm_aad(gcm, &ctx, aad, aadLen);-    aes_gcm_finish(tag, gcm, &ctx);-}--void aes_gcm_encrypt(uint8_t *output, const aes_gcm *gcm, aes_gcm_ctx *ctx, const uint8_t *input, uint32_t length)-{-        aes_block out;--        ctx->length_input += length;-        for (; length >= 16; input += 16, output += 16, length -= 16) {-                block128_inc_be(&ctx->civ);--                encrypt_ecb(&gcm->key, (uint8_t *)&out, (const uint8_t *)&ctx->civ, 1);-                block128_xor(&out, (block128 *) input);-                gcm_ghash_add(gcm, ctx, &out);-                block128_copy((block128 *) output, &out);-        }-        if (length > 0) {-                aes_block tmp;-                int i;--                block128_inc_be(&ctx->civ);-                /* create e(civ) in out */-                encrypt_ecb(&gcm->key, (uint8_t *)&out, (const uint8_t *)&ctx->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, ctx, &tmp);--                for (i = 0; i < length; i++) {-                        output[i] = tmp.b[i];-                }-        }-}--void aes_gcm_decrypt(uint8_t *output, const aes_gcm *gcm, aes_gcm_ctx *ctx, const uint8_t *input, uint32_t length)-{-        aes_block out;--        ctx->length_input += length;-        for (; length >= 16; input += 16, output += 16, length -= 16) {-                block128_inc_be(&ctx->civ);--                encrypt_ecb(&gcm->key, (uint8_t *)&out, (const uint8_t *)&ctx->civ, 1);-                gcm_ghash_add(gcm, ctx, (block128 *) input);-                block128_xor(&out, (block128 *) input);-                block128_copy((block128 *) output, &out);-        }-        if (length > 0) {-                aes_block tmp;-                int i;--                block128_inc_be(&ctx->civ);--                block128_zero(&tmp);-                block128_copy_bytes(&tmp, input, length);-                gcm_ghash_add(gcm, ctx, &tmp);--                encrypt_ecb(&gcm->key, (uint8_t *)&out, (const uint8_t *)&ctx->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, const aes_gcm *gcm, aes_gcm_ctx *ctx)-{-        aes_block lblock;-        int i;--        /* tag = (tag-1 xor (lenbits(a) | lenbits(c)) ) . H */-        lblock.q[0] = cpu_to_be64(ctx->length_aad << 3);-        lblock.q[1] = cpu_to_be64(ctx->length_input << 3);-        gcm_ghash_add(gcm, ctx, &lblock);--        encrypt_ecb(&gcm->key, (uint8_t *)&lblock, (const uint8_t*)&ctx->iv, 1);-        block128_xor(&ctx->tag, &lblock);--        for (i = 0; i < 16; i++) {-                tag[i] = ctx->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_ctx ctx;-    aes_gcm gcm;-    aes_gcm_init(&gcm, k);-    aes_gcm_ctx_init(&ctx, &gcm, iv, ivLen);-    aes_gcm_aad(&gcm, &ctx, aad, aadLen);-    aes_gcm_encrypt(ct, &gcm, &ctx, pt, ptLen);-    aes_gcm_finish(tag, &gcm, &ctx);-}--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_ctx ctx;-    aes_gcm_init(&gcm, k);-    aes_gcm_ctx_init(&ctx, &gcm, iv, ivLen);-    aes_gcm_aad(&gcm, &ctx, aad, aadLen);-    aes_gcm_decrypt(pt, &gcm, &ctx, ct, ctLen);-    aes_gcm_finish(tag, &gcm, &ctx);-}---/* 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- */-static void gf_mul(block128 *a, const 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);-}--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;-        uint32_t nb_blocks = len / 16;-        int i;--        /* preload IV in block */-        if(NULL != newIV)-            block = (aes_block*) newIV;-        else-            block = alloca(sizeof(aes_block));--        block128_copy(block, (aes_block *)iv);--        for ( ; nb_blocks-- > 0; output += 16, input += 16) {-                encrypt_ecb(key, (uint8_t *)&o, (uint8_t *)block, 1);-                block128_vxor((block128 *) output, &o, (block128 *) input);-                block128_inc_be(block);-        }--        if ((len % 16) != 0) {-                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;-                        input += 1;-                }-                block128_inc_be(block);-        }-}-
− cbits/aes/generic/aes_generic.c
@@ -1,443 +0,0 @@-/*- * 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 }-static 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 aes128_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 aes128_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 aes128_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
@@ -1,274 +0,0 @@-/*- * 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.- */-#if defined(HAVE_AES_INTRINSICS) && !defined(AVOID_NI)--#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 aes128_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 aes128_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 aes128_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 aes128_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 aes128_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 aes128_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 */--#endif /* HAVE_AES_INTRINSICS */
+ cbits/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.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 }+static 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, 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(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(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(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 tmd_aes_generic_encrypt_block(aes_block *output, aes_key *key, 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 tmd_aes_generic_decrypt_block(aes_block *output, aes_key *key, 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 tmd_aes_generic_init(aes_key *key, 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_generic.h view
@@ -0,0 +1,34 @@+/*+ * 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.h"++void tmd_aes_generic_encrypt_block(aes_block *output, aes_key *key, aes_block *input);+void tmd_aes_generic_decrypt_block(aes_block *output, aes_key *key, aes_block *input);+void tmd_aes_generic_init(aes_key *key, uint8_t *origkey, uint8_t size);
+ cbits/aes_x86ni.c view
@@ -0,0 +1,331 @@+/*+ * Copyright (c) 2012-2013 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.+ */++#ifdef WITH_AESNI++#include <wmmintrin.h>+#include <tmmintrin.h>+#include <string.h>+#include "aes.h"+#include "aes_x86ni.h"+#include "block128.h"+#include "cpu.h"++#ifdef ARCH_X86+#define ALIGN_UP(addr, size) (((addr) + ((size) - 1)) & (~((size) - 1)))+#define ALIGNMENT(n) __attribute__((aligned(n)))++/* old GCC version doesn't cope with the shuffle parameters, that can take 2 values (0xff and 0xaa)+ * in our case, passed as argument despite being a immediate 8 bits constant anyway.+ * un-factorise aes_128_key_expansion into 2 version that have the shuffle parameter explicitly set */+static __m128i aes_128_key_expansion_ff(__m128i key, __m128i keygened)+{+	keygened = _mm_shuffle_epi32(keygened, 0xff);+	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 __m128i aes_128_key_expansion_aa(__m128i key, __m128i keygened)+{+	keygened = _mm_shuffle_epi32(keygened, 0xaa);+	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);+}++void tmd_aes_ni_init(aes_key *key, uint8_t *ikey, uint8_t size)+{+	__m128i k[28];+	uint64_t *out = (uint64_t *) key->data;+	int i;++	switch (size) {+	case 16:+		k[0] = _mm_loadu_si128((const __m128i*) ikey);++		#define AES_128_key_exp(K, RCON) aes_128_key_expansion_ff(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]);+		break;+	case 32:+#define AES_256_key_exp_1(K1, K2, RCON) aes_128_key_expansion_ff(K1, _mm_aeskeygenassist_si128(K2, RCON))+#define AES_256_key_exp_2(K1, K2)       aes_128_key_expansion_aa(K1, _mm_aeskeygenassist_si128(K2, 0x00))+		k[0]  = _mm_loadu_si128((const __m128i*) ikey);+		k[1]  = _mm_loadu_si128((const __m128i*) (ikey+16));+		k[2]  = AES_256_key_exp_1(k[0], k[1], 0x01);+		k[3]  = AES_256_key_exp_2(k[1], k[2]);+		k[4]  = AES_256_key_exp_1(k[2], k[3], 0x02);+		k[5]  = AES_256_key_exp_2(k[3], k[4]);+		k[6]  = AES_256_key_exp_1(k[4], k[5], 0x04);+		k[7]  = AES_256_key_exp_2(k[5], k[6]);+		k[8]  = AES_256_key_exp_1(k[6], k[7], 0x08);+		k[9]  = AES_256_key_exp_2(k[7], k[8]);+		k[10] = AES_256_key_exp_1(k[8], k[9], 0x10);+		k[11] = AES_256_key_exp_2(k[9], k[10]);+		k[12] = AES_256_key_exp_1(k[10], k[11], 0x20);+		k[13] = AES_256_key_exp_2(k[11], k[12]);+		k[14] = AES_256_key_exp_1(k[12], k[13], 0x40);++		k[15] = _mm_aesimc_si128(k[13]);+		k[16] = _mm_aesimc_si128(k[12]);+		k[17] = _mm_aesimc_si128(k[11]);+		k[18] = _mm_aesimc_si128(k[10]);+		k[19] = _mm_aesimc_si128(k[9]);+		k[20] = _mm_aesimc_si128(k[8]);+		k[21] = _mm_aesimc_si128(k[7]);+		k[22] = _mm_aesimc_si128(k[6]);+		k[23] = _mm_aesimc_si128(k[5]);+		k[24] = _mm_aesimc_si128(k[4]);+		k[25] = _mm_aesimc_si128(k[3]);+		k[26] = _mm_aesimc_si128(k[2]);+		k[27] = _mm_aesimc_si128(k[1]);+		for (i = 0; i < 28; i++)+			_mm_storeu_si128(((__m128i *) out) + i, k[i]);+		break;+	default:+		break;+	}+}++/* 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;+}++static void unopt_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);+}++static __m128i ghash_add(__m128i tag, __m128i h, __m128i m)+{+	aes_block _t, _h;+	tag = _mm_xor_si128(tag, m);++	_mm_store_si128((__m128i *) &_t, tag);+	_mm_store_si128((__m128i *) &_h, h);+	unopt_gf_mul(&_t, &_h);+	tag = _mm_load_si128((__m128i *) &_t);+	return tag;+}++#define PRELOAD_ENC_KEYS128(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 PRELOAD_ENC_KEYS256(k) \+	PRELOAD_ENC_KEYS128(k) \+	__m128i K11 = _mm_loadu_si128(((__m128i *) k)+11); \+	__m128i K12 = _mm_loadu_si128(((__m128i *) k)+12); \+	__m128i K13 = _mm_loadu_si128(((__m128i *) k)+13); \+	__m128i K14 = _mm_loadu_si128(((__m128i *) k)+14);++#define DO_ENC_BLOCK128(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 DO_ENC_BLOCK256(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_aesenc_si128(m, K10); \+	m = _mm_aesenc_si128(m, K11); \+	m = _mm_aesenc_si128(m, K12); \+	m = _mm_aesenc_si128(m, K13); \+	m = _mm_aesenclast_si128(m, K14);++/* load K0 at K9 from index 'at' */+#define PRELOAD_DEC_KEYS_AT(k, at) \+	__m128i K0  = _mm_loadu_si128(((__m128i *) k)+at+0); \+	__m128i K1  = _mm_loadu_si128(((__m128i *) k)+at+1); \+	__m128i K2  = _mm_loadu_si128(((__m128i *) k)+at+2); \+	__m128i K3  = _mm_loadu_si128(((__m128i *) k)+at+3); \+	__m128i K4  = _mm_loadu_si128(((__m128i *) k)+at+4); \+	__m128i K5  = _mm_loadu_si128(((__m128i *) k)+at+5); \+	__m128i K6  = _mm_loadu_si128(((__m128i *) k)+at+6); \+	__m128i K7  = _mm_loadu_si128(((__m128i *) k)+at+7); \+	__m128i K8  = _mm_loadu_si128(((__m128i *) k)+at+8); \+	__m128i K9  = _mm_loadu_si128(((__m128i *) k)+at+9); \++#define PRELOAD_DEC_KEYS128(k) \+	PRELOAD_DEC_KEYS_AT(k, 10) \+	__m128i K10 = _mm_loadu_si128(((__m128i *) k)+0);++#define PRELOAD_DEC_KEYS256(k) \+	PRELOAD_DEC_KEYS_AT(k, 14) \+	__m128i K10 = _mm_loadu_si128(((__m128i *) k)+14+10); \+	__m128i K11 = _mm_loadu_si128(((__m128i *) k)+14+11); \+	__m128i K12 = _mm_loadu_si128(((__m128i *) k)+14+12); \+	__m128i K13 = _mm_loadu_si128(((__m128i *) k)+14+13); \+	__m128i K14 = _mm_loadu_si128(((__m128i *) k)+0);++#define DO_DEC_BLOCK128(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);++#define DO_DEC_BLOCK256(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_aesdec_si128(m, K10); \+	m = _mm_aesdec_si128(m, K11); \+	m = _mm_aesdec_si128(m, K12); \+	m = _mm_aesdec_si128(m, K13); \+	m = _mm_aesdeclast_si128(m, K14);++#define SIZE 128+#define SIZED(m) m##128+#define PRELOAD_ENC PRELOAD_ENC_KEYS128+#define DO_ENC_BLOCK DO_ENC_BLOCK128+#define PRELOAD_DEC PRELOAD_DEC_KEYS128+#define DO_DEC_BLOCK DO_DEC_BLOCK128+#include "aes_x86ni_impl.c"++#undef SIZE+#undef SIZED+#undef PRELOAD_ENC+#undef PRELOAD_DEC+#undef DO_ENC_BLOCK+#undef DO_DEC_BLOCK++#define SIZED(m) m##256+#define SIZE 256+#define PRELOAD_ENC PRELOAD_ENC_KEYS256+#define DO_ENC_BLOCK DO_ENC_BLOCK256+#define PRELOAD_DEC PRELOAD_DEC_KEYS256+#define DO_DEC_BLOCK DO_DEC_BLOCK256+#include "aes_x86ni_impl.c"++#undef SIZE+#undef SIZED+#undef PRELOAD_ENC+#undef PRELOAD_DEC+#undef DO_ENC_BLOCK+#undef DO_DEC_BLOCK++#endif++#endif
+ cbits/aes_x86ni.h view
@@ -0,0 +1,81 @@+/*+ * 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++#ifdef WITH_AESNI++#if defined(__i386__) || defined(__x86_64__)++#include <wmmintrin.h>+#include <tmmintrin.h>+#include "aes.h"+#include "block128.h"++#ifdef IMPL_DEBUG+static void block128_sse_print(__m128i m)+{+	block128 b;+	_mm_storeu_si128((__m128i *) &b.b, m);+	block128_print(&b);+}+#endif++void tmd_aes_ni_init(aes_key *key, uint8_t *origkey, uint8_t size);+void tmd_aes_ni_encrypt_block128(aes_block *out, aes_key *key, aes_block *in);+void tmd_aes_ni_encrypt_block256(aes_block *out, aes_key *key, aes_block *in);+void tmd_aes_ni_decrypt_block128(aes_block *out, aes_key *key, aes_block *in);+void tmd_aes_ni_decrypt_block256(aes_block *out, aes_key *key, aes_block *in);+void tmd_aes_ni_encrypt_ecb128(aes_block *out, aes_key *key, aes_block *in, uint32_t blocks);+void tmd_aes_ni_encrypt_ecb256(aes_block *out, aes_key *key, aes_block *in, uint32_t blocks);+void tmd_aes_ni_decrypt_ecb128(aes_block *out, aes_key *key, aes_block *in, uint32_t blocks);+void tmd_aes_ni_decrypt_ecb256(aes_block *out, aes_key *key, aes_block *in, uint32_t blocks);+void tmd_aes_ni_encrypt_cbc128(aes_block *out, aes_key *key, aes_block *_iv, aes_block *in, uint32_t blocks);+void tmd_aes_ni_encrypt_cbc256(aes_block *out, aes_key *key, aes_block *_iv, aes_block *in, uint32_t blocks);+void tmd_aes_ni_decrypt_cbc128(aes_block *out, aes_key *key, aes_block *_iv, aes_block *in, uint32_t blocks);+void tmd_aes_ni_decrypt_cbc256(aes_block *out, aes_key *key, aes_block *_iv, aes_block *in, uint32_t blocks);+void tmd_aes_ni_encrypt_ctr128(uint8_t *out, aes_key *key, aes_block *_iv, aes_block *niv, uint8_t *in, uint32_t length);+void tmd_aes_ni_encrypt_ctr256(uint8_t *out, aes_key *key, aes_block *_iv, aes_block *niv, uint8_t *in, uint32_t length);+void tmd_aes_ni_encrypt_xts128(aes_block *out, aes_key *key1, aes_key *key2,+                               aes_block *_tweak, uint32_t spoint, aes_block *in, uint32_t blocks);+void tmd_aes_ni_encrypt_xts256(aes_block *out, aes_key *key1, aes_key *key2,+                               aes_block *_tweak, uint32_t spoint, aes_block *in, uint32_t blocks);++void tmd_aes_ni_gcm_encrypt128(uint8_t *out, aes_gcm *gcm, aes_ctx *ctx, aes_key *key, uint8_t *in, uint32_t length, aes_ctx *newCTX);+void tmd_aes_ni_gcm_encrypt256(uint8_t *out, aes_gcm *gcm, aes_ctx *ctx, aes_key *key, uint8_t *in, uint32_t length, aes_ctx *newCTX);++void tmd_gf_mul_x86ni(block128 *res, block128 *a_, block128 *b_);++#endif++#endif++#endif
+ cbits/aes_x86ni_impl.c view
@@ -0,0 +1,266 @@+/*+ * Copyright (c) 2012-2013 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.+ */++void SIZED(tmd_aes_ni_encrypt_block)(aes_block *out, aes_key *key, aes_block *in)+{+        __m128i *k = (__m128i *) key->data;+        PRELOAD_ENC(k);+        __m128i m = _mm_loadu_si128((__m128i *) in);+        DO_ENC_BLOCK(m);+        _mm_storeu_si128((__m128i *) out, m);+}++void SIZED(tmd_aes_ni_decrypt_block)(aes_block *out, aes_key *key, aes_block *in)+{+        __m128i *k = (__m128i *) key->data;+        PRELOAD_DEC(k);+        __m128i m = _mm_loadu_si128((__m128i *) in);+        DO_DEC_BLOCK(m);+        _mm_storeu_si128((__m128i *) out, m);+}++void SIZED(tmd_aes_ni_encrypt_ecb)(aes_block *out, aes_key *key, aes_block *in, uint32_t blocks)+{+        __m128i *k = (__m128i *) key->data;++        PRELOAD_ENC(k);+        for (; blocks-- > 0; in += 1, out += 1) {+                __m128i m = _mm_loadu_si128((__m128i *) in);+                DO_ENC_BLOCK(m);+                _mm_storeu_si128((__m128i *) out, m);+        }+}++void SIZED(tmd_aes_ni_decrypt_ecb)(aes_block *out, aes_key *key, aes_block *in, uint32_t blocks)+{+        __m128i *k = (__m128i *) key->data;++        PRELOAD_DEC(k);++        for (; blocks-- > 0; in += 1, out += 1) {+                __m128i m = _mm_loadu_si128((__m128i *) in);+                DO_DEC_BLOCK(m);+                _mm_storeu_si128((__m128i *) out, m);+        }+}++void SIZED(tmd_aes_ni_encrypt_cbc)(aes_block *out, aes_key *key, aes_block *_iv, aes_block *in, uint32_t blocks)+{+        __m128i *k = (__m128i *) key->data;+        __m128i iv = _mm_loadu_si128((__m128i *) _iv);++        PRELOAD_ENC(k);++        for (; blocks-- > 0; in += 1, out += 1) {+                __m128i m = _mm_loadu_si128((__m128i *) in);+                m = _mm_xor_si128(m, iv);+                DO_ENC_BLOCK(m);+                iv = m;+                _mm_storeu_si128((__m128i *) out, m);+        }+}++void SIZED(tmd_aes_ni_decrypt_cbc)(aes_block *out, aes_key *key, aes_block *_iv, aes_block *in, uint32_t blocks)+{+        __m128i *k = (__m128i *) key->data;+        __m128i iv = _mm_loadu_si128((__m128i *) _iv);++        PRELOAD_DEC(k);++        for (; blocks-- > 0; in += 1, out += 1) {+                __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;+        }+}++void SIZED(tmd_aes_ni_encrypt_ctr)(uint8_t *output, aes_key *key, aes_block *_iv, aes_block *newIV, uint8_t *input, uint32_t len)+{+        __m128i *k = (__m128i *) key->data;+        __m128i bswap_mask = _mm_setr_epi8(7,6,5,4,3,2,1,0,15,14,13,12,11,10,9,8);+        __m128i one        = _mm_set_epi32(0,1,0,0);+        uint32_t nb_blocks = len / 16;+        uint32_t part_block_len = len % 16;++        /* get the IV in little endian format */+        __m128i iv = _mm_loadu_si128((__m128i *) _iv);+        iv = _mm_shuffle_epi8(iv, bswap_mask);++        PRELOAD_ENC(k);++        for (; nb_blocks-- > 0; output += 16, input += 16) {+                /* put back the iv in big endian mode,+                 * encrypt it and and xor it the input block+                 */+                __m128i tmp = _mm_shuffle_epi8(iv, bswap_mask);+                DO_ENC_BLOCK(tmp);+                __m128i m = _mm_loadu_si128((__m128i *) input);+                m = _mm_xor_si128(m, tmp);++                _mm_storeu_si128((__m128i *) output, m);+                /* iv += 1 */+                iv = _mm_add_epi64(iv, one);+        }++        if (part_block_len != 0) {+                aes_block block;+                memset(&block.b, 0, 16);+                memcpy(&block.b, input, part_block_len);++                __m128i m = _mm_loadu_si128((__m128i *) &block);+                __m128i tmp = _mm_shuffle_epi8(iv, bswap_mask);++                DO_ENC_BLOCK(tmp);+                m = _mm_xor_si128(m, tmp);+                _mm_storeu_si128((__m128i *) &block.b, m);+                memcpy(output, &block.b, part_block_len);+                iv = _mm_add_epi64(iv, one);+        }+        __m128i tmpRet = _mm_shuffle_epi8(iv, bswap_mask);+        _mm_storeu_si128((__m128i *) newIV, tmpRet);++        return ;+}++void SIZED(tmd_aes_ni_encrypt_xts)(aes_block *out, aes_key *key1, aes_key *key2,+                               aes_block *_tweak, uint32_t spoint, aes_block *in, uint32_t blocks)+{+        __m128i tweak = _mm_loadu_si128((__m128i *) _tweak);++        do {+                __m128i *k2 = (__m128i *) key2->data;+                PRELOAD_ENC(k2);+                DO_ENC_BLOCK(tweak);++                while (spoint-- > 0)+                        tweak = gfmulx(tweak);+        } while (0) ;++        do {+                __m128i *k1 = (__m128i *) key1->data;+                PRELOAD_ENC(k1);++                for ( ; blocks-- > 0; in += 1, out += 1, 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);+}++void SIZED(tmd_aes_ni_gcm_encrypt)(uint8_t *output, aes_gcm *gcm, aes_ctx *ctx, aes_key *key, uint8_t *input, uint32_t length, aes_ctx *newCTX)+{+        __m128i *k = (__m128i *) key->data;+        __m128i bswap_mask = _mm_setr_epi8(7,6,5,4,3,2,1,0,15,14,13,12,11,10,9,8);+        __m128i one        = _mm_set_epi32(0,1,0,0);+        uint32_t nb_blocks = length / 16;+        uint32_t part_block_len = length % 16;++        ctx->length_input += length;++        __m128i h  = _mm_loadu_si128((__m128i *) &gcm->h);+        __m128i tag = _mm_loadu_si128((__m128i *) &ctx->tag);+        __m128i iv = _mm_loadu_si128((__m128i *) &ctx->civ);+        iv = _mm_shuffle_epi8(iv, bswap_mask);++        PRELOAD_ENC(k);++        for (; nb_blocks-- > 0; output += 16, input += 16) {+                /* iv += 1 */+                iv = _mm_add_epi64(iv, one);++                /* put back iv in big endian, encrypt it,+                 * and xor it to input */+                __m128i tmp = _mm_shuffle_epi8(iv, bswap_mask);+                DO_ENC_BLOCK(tmp);+                __m128i m = _mm_loadu_si128((__m128i *) input);+                m = _mm_xor_si128(m, tmp);++                tag = ghash_add(tag, h, m);++                /* store it out */+                _mm_storeu_si128((__m128i *) output, m);+        }+        if (part_block_len > 0) {+                __m128i mask;+                aes_block block;+                /* FIXME could do something a bit more clever (slli & sub & and maybe) ... */+                switch (part_block_len) {+                case 1: mask = _mm_setr_epi8(0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80); break;+                case 2: mask = _mm_setr_epi8(0,1,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80); break;+                case 3: mask = _mm_setr_epi8(0,1,2,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80); break;+                case 4: mask = _mm_setr_epi8(0,1,2,3,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80); break;+                case 5: mask = _mm_setr_epi8(0,1,2,3,4,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80); break;+                case 6: mask = _mm_setr_epi8(0,1,2,3,4,5,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80); break;+                case 7: mask = _mm_setr_epi8(0,1,2,3,4,5,6,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80); break;+                case 8: mask = _mm_setr_epi8(0,1,2,3,4,5,6,7,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80); break;+                case 9: mask = _mm_setr_epi8(0,1,2,3,4,5,6,7,8,0x80,0x80,0x80,0x80,0x80,0x80,0x80); break;+                case 10: mask = _mm_setr_epi8(0,1,2,3,4,5,6,7,8,9,0x80,0x80,0x80,0x80,0x80,0x80); break;+                case 11: mask = _mm_setr_epi8(0,1,2,3,4,5,6,7,8,9,10,0x80,0x80,0x80,0x80,0x80); break;+                case 12: mask = _mm_setr_epi8(0,1,2,3,4,5,6,7,8,9,10,11,0x80,0x80,0x80,0x80); break;+                case 13: mask = _mm_setr_epi8(0,1,2,3,4,5,6,7,8,9,10,11,12,0x80,0x80,0x80); break;+                case 14: mask = _mm_setr_epi8(0,1,2,3,4,5,6,7,8,9,10,11,12,13,0x80,0x80); break;+                case 15: mask = _mm_setr_epi8(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,0x80); break;+                default: mask = _mm_setr_epi8(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15); break;+                }+                memset(&block.b, 0, 16);+                memcpy(&block.b, input, part_block_len);++                /* iv += 1 */+                iv = _mm_add_epi64(iv, one);++                /* put back iv in big endian mode, encrypt it and xor it with input */+                __m128i tmp = _mm_shuffle_epi8(iv, bswap_mask);+                DO_ENC_BLOCK(tmp);++                __m128i m = _mm_loadu_si128((__m128i *) &block);+                m = _mm_xor_si128(m, tmp);+                m = _mm_shuffle_epi8(m, mask);++                tag = ghash_add(tag, h, m);++                /* make output */+                _mm_storeu_si128((__m128i *) &block.b, m);+                memcpy(output, &block.b, part_block_len);+        }+        /* store back IV & tag */+        __m128i tmp = _mm_shuffle_epi8(iv, bswap_mask);+        _mm_storeu_si128((__m128i *) &newCTX->civ, tmp);+        _mm_storeu_si128((__m128i *) &newCTX->tag, tag);+}
+ cbits/bitfn.h view
@@ -0,0 +1,238 @@+/*+ * 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__) || defined(__NetBSD__)+  # 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>+#elif defined( __QNXNTO__ ) && defined( __LITTLEENDIAN__ )+  # define LITTLE_ENDIAN 1234+  # define BYTE_ORDER    LITTLE_ENDIAN+#elif defined( __QNXNTO__ ) && defined( __BIGENDIAN__ )+  # define BIG_ENDIAN 1234+  # define BYTE_ORDER    BIG_ENDIAN+#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/block128.h view
@@ -0,0 +1,99 @@+/*+ * 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);+}++#ifdef IMPL_DEBUG+#include <stdio.h>+static inline void block128_print(block128 *b)+{+	int i;+	for (i = 0; i < 16; i++) {+		printf("%02x ", b->b[i]);+	}+	printf("\n");+}+#endif++#endif
+ cbits/cpu.c view
@@ -0,0 +1,75 @@+/*+ *	Copyright (C) 2012 Vincent Hanquez <tab@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 "cpu.h"+#include <stdint.h>++#ifdef ARCH_X86+static void cpuid(uint32_t info, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)+{+	*eax = info;+	asm volatile+		(+#ifdef __x86_64__+		 "mov %%rbx, %%rdi;"+#else+		 "mov %%ebx, %%edi;"+#endif+		 "cpuid;"+		 "mov %%ebx, %%esi;"+#ifdef __x86_64__+		 "mov %%rdi, %%rbx;"+#else+		 "mov %%edi, %%ebx;"+#endif+		 :"+a" (*eax), "=S" (*ebx), "=c" (*ecx), "=d" (*edx)+		 : :"edi");+}++#ifdef USE_AESNI+void initialize_hw(void (*init_table)(int, int))+{+	static int inited = 0;+	if (inited == 0) {+		uint32_t eax, ebx, ecx, edx;+		int aesni, pclmul;++		inited = 1;+		cpuid(1, &eax, &ebx, &ecx, &edx);+		aesni = (ecx & 0x02000000);+		pclmul = (ecx & 0x00000001);+		init_table(aesni, pclmul);+	}+}+#else+#define initialize_hw(init_table) 	(0)+#endif++#endif
+ cbits/cpu.h view
@@ -0,0 +1,45 @@+/*+ *	Copyright (C) 2012 Vincent Hanquez <tab@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 CPU_H+#define CPU_H++#if defined(__i386__) || defined(__x86_64__)+#define ARCH_X86+#define USE_AESNI+#endif++#ifdef USE_AESNI+void initialize_hw(void (*init_table)(int, int));+#else+#define initialize_hw(init_table) 	(0)+#endif++#endif
+ cbits/gf.c view
@@ -0,0 +1,72 @@+/*+ * 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 <stdio.h>+#include <stdint.h>+#include "cpu.h"+#include "gf.h"+#include "aes_x86ni.h"++/* 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, const 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);+}++/* inplace GFMUL for xts mode */+void gf_mulx(block128 *a)+{+	const uint64_t gf_mask = cpu_to_le64(0x8000000000000000ULL);+	uint64_t r = ((a->q[1] & gf_mask) ? cpu_to_le64(0x87) : 0);+	a->q[1] = cpu_to_le64((le64_to_cpu(a->q[1]) << 1) | (a->q[0] & gf_mask ? 1 : 0));+	a->q[0] = cpu_to_le64(le64_to_cpu(a->q[0]) << 1) ^ r;+}+
+ cbits/gf.h view
@@ -0,0 +1,38 @@+/*
+ * 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 _GF128MUL_H
+#define _GF128MUL_H
+
+#include "block128.h"
+
+void gf_mul(block128 *a, const block128 *b);
+void gf_mulx(block128 *a);
+
+#endif
− cbits/include/aes.h
@@ -1,49 +0,0 @@-#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);-void free_gcm(aes_gcm *g);-aes_gcm *allocate_gcm();-void aes_gcm_init(aes_gcm *gcm, const aes_key *key);-void aes_gcm_init_ctx(aes_gcm_ctx *ctx, const aes_gcm *gcm, uint8_t *iv, uint32_t len);-void aes_gcm_encrypt(uint8_t *output, const aes_gcm *gcm, aes_gcm_ctx *ctx, const uint8_t *input, uint32_t length);-void aes_gcm_decrypt(uint8_t *output, const aes_gcm *gcm, aes_gcm_ctx *ctx, const uint8_t *input, uint32_t length);-void aes_gcm_aad(const aes_gcm *gcm, aes_gcm_ctx *ctx, uint8_t *input, uint32_t length);-void aes_gcm_finish(uint8_t *tag, const aes_gcm *gcm, aes_gcm_ctx *ctx);-void aes_gcm_enc_finish( uint8_t *output, uint8_t *tag-                       , const aes_gcm *gcm-                       , uint8_t *iv, uint32_t ivLen-                       , uint8_t *input, uint32_t inputLen-                       , uint8_t *aad, uint32_t aadLen);-void aes_gcm_dec_finish( uint8_t *output, uint8_t *tag-                       , const aes_gcm *gcm-                       , uint8_t *iv, uint32_t ivLen-                       , uint8_t *input, uint32_t inputLen-                       , uint8_t *aad, uint32_t aadLen);--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
− cbits/include/aes_generic.h
@@ -1,36 +0,0 @@-/*- * 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 aes128_generic_encrypt_block(aes_block *output, const aes_key *key, const aes_block *input);-void aes128_generic_decrypt_block(aes_block *output, const aes_key *key, const aes_block *input);-void aes128_generic_init(aes_key *key, const uint8_t *origkey, uint8_t size);
− cbits/include/aes_types.h
@@ -1,28 +0,0 @@-#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 h;        // init-    aes_key key;-} aes_gcm;--typedef struct {-    aes_block iv;-    aes_block civ;-    aes_block tag;      // finish, aad, encrypt,decrypt-    uint64_t length_input;-    uint64_t length_aad;-} aes_gcm_ctx;--#endif
− cbits/include/aes_x86ni.h
@@ -1,51 +0,0 @@-/*- * 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 aes128_ni_init(aes_key *key, const uint8_t *origkey, uint8_t size);-void aes128_ni_encrypt_ecb(uint8_t *out, aes_key *key, const uint8_t *in, uint32_t blocks);-void aes128_ni_decrypt_ecb(uint8_t *out, aes_key *key, const uint8_t *in, uint32_t blocks);-void aes128_ni_encrypt_cbc(uint8_t *out, aes_key *key, uint8_t *_iv, uint8_t *in, uint32_t blocks);-void aes128_ni_decrypt_cbc(uint8_t *out, aes_key *key, uint8_t *_iv, uint8_t *in, uint32_t blocks);-void aes128_ni_encrypt_xts(uint8_t *out, aes_key *key1, aes_key *key2,-                           uint8_t *_tweak, uint32_t spoint, uint8_t *in, uint32_t blocks);--#endif--#endif
− cbits/include/bitfn.h
@@ -1,232 +0,0 @@-/*- * 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
@@ -1,87 +0,0 @@-/*- * 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, const 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, const 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
@@ -2,11 +2,13 @@ -- documentation, see http://haskell.org/cabal/users-guide/  name:                cipher-aes128-version:             0.5-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?)+version:             0.6+synopsis:            AES and common modes using AES-NI when available.+description:         Cipher-aes128 is an implementation of AES and common modes of operation.  It borrows Hanquez's C AES code (see 'cipher-aes') but+                     is unique due to including compile-time detection of+                     NI compiler support, a slightly more functional interface+                     for GCM operations, exposure of 'Ptr' based operations via the .Internal module, and build-in crypto-api support.+                     Cipher-aes128 was originally developed as "'cipher-aes' plus trampolines", which has since been adopted into cipher-aes. license:             BSD3 license-file:        LICENSE author:              Thomas M. DuBuisson, Vincent Hanquez (See AUTHORS file)@@ -18,29 +20,30 @@ 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+extra-source-files:       ./cbits/*.h, ./cbits/*.c                         , AUTHORS+                        , cbits/LICENSE+flag test+  description: Build a program to test the AES implementation+  default: False+ library   default-language:    Haskell2010   exposed-modules:     Crypto.Cipher.AES128, Crypto.Cipher.AES128.Internal-  build-depends:       base >=4.5 && < 5,+  build-depends:       base >=4.2 && < 5,                        bytestring,-                       crypto-api >= 0.11,+                       crypto-api >= 0.13,                        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+  c-sources:           ./cbits/aes.c+                     , ./cbits/aes_generic.c+                     , ./cbits/aes_x86ni.c+                     , ./cbits/cpu.c+                     , ./cbits/gf.c+  include-dirs:        cbits/+  -- None by default cc-options:          -mssse3 -maes -mpclmul  source-repository head   type:         git@@ -50,10 +53,23 @@   type:         exitcode-stdio-1.0   hs-source-dirs:       . Benchmark   main-is:              bench.hs-  build-depends:        base < 5, criterion, crypto-api, entropy, bytestring, tagged, cereal+  build-depends:        base < 5, criterion, crypto-api, entropy, bytestring, tagged, cereal, cipher-aes   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+  include-dirs:        cbits+  c-sources:           ./cbits/aes.c+                     , ./cbits/aes_generic.c+                     , ./cbits/aes_x86ni.c+                     , ./cbits/cpu.c+                     , ./cbits/gf.c+  cc-options:          -mssse3 -maes -mpclmul++Executable aes128_test+  if !flag(test)+    buildable: False+  main-is: Test/test.hs+  if flag(test)+    build-depends:    base+                    , crypto-api-tests+                    , test-framework+                    , cipher-aes128+                    , bytestring, tagged, cereal, crypto-api