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 +2/−2
- Benchmark/bench.hs +11/−8
- Crypto/Cipher/AES128.hs +96/−8
- Crypto/Cipher/AES128/Internal.hs +283/−103
- Setup.hs +9/−6
- Test/test.hs +9/−0
- cbits/LICENSE +27/−0
- cbits/aes.c +591/−0
- cbits/aes.h +95/−0
- cbits/aes/LICENSE +0/−29
- cbits/aes/aes.c +0/−441
- cbits/aes/generic/aes_generic.c +0/−443
- cbits/aes/ni/aes_x86ni.c +0/−274
- cbits/aes_generic.c +442/−0
- cbits/aes_generic.h +34/−0
- cbits/aes_x86ni.c +331/−0
- cbits/aes_x86ni.h +81/−0
- cbits/aes_x86ni_impl.c +266/−0
- cbits/bitfn.h +238/−0
- cbits/block128.h +99/−0
- cbits/cpu.c +75/−0
- cbits/cpu.h +45/−0
- cbits/gf.c +72/−0
- cbits/gf.h +38/−0
- cbits/include/aes.h +0/−49
- cbits/include/aes_generic.h +0/−36
- cbits/include/aes_types.h +0/−28
- cbits/include/aes_x86ni.h +0/−51
- cbits/include/bitfn.h +0/−232
- cbits/include/block128.h +0/−87
- cipher-aes128.cabal +41/−25
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