cipher-aes (empty) → 0.1.0
raw patch · 22 files changed
+2866/−0 lines, 22 filesdep +QuickCheckdep +basedep +bytestringsetup-changed
Dependencies added: QuickCheck, base, bytestring, cereal, cipher-aes, criterion, crypto-api, ghc-prim, mtl, primitive, tagged, test-framework, test-framework-quickcheck2
Files
- Benchmarks/Benchmarks.hs +102/−0
- Crypto/Cipher/AES.hs +303/−0
- LICENSE +27/−0
- Setup.hs +2/−0
- Tests/KATCBC.hs +119/−0
- Tests/KATECB.hs +160/−0
- Tests/KATGCM.hs +65/−0
- Tests/KATXTS.hs +69/−0
- Tests/Tests.hs +138/−0
- cbits/aes.c +383/−0
- cbits/aes.h +81/−0
- cbits/aes_generic.c +442/−0
- cbits/aes_generic.h +34/−0
- cbits/aes_x86ni.c +270/−0
- cbits/aes_x86ni.h +52/−0
- cbits/bitfn.h +232/−0
- cbits/block128.h +87/−0
- cbits/cpu.c +71/−0
- cbits/cpu.h +45/−0
- cbits/gf.c +72/−0
- cbits/gf.h +38/−0
- cipher-aes.cabal +74/−0
+ Benchmarks/Benchmarks.hs view
@@ -0,0 +1,102 @@+{-# LANGUAGE CPP #-}+import Criterion+import Criterion.Environment+import Criterion.Config+import Criterion.Monad+import Criterion.Analysis+import Criterion.Measurement++import Text.Printf++import Control.Monad.Trans++import qualified Data.ByteString as B+import qualified Data.ByteString.Lazy as L++import qualified Crypto.Cipher.AES as AES++key128 = AES.initKey $ B.replicate 16 0+key192 = AES.initKey $ B.replicate 24 0+key256 = AES.initKey $ B.replicate 32 0++nullIV = AES.IV $ B.replicate 16 0+nullIVGCM = AES.IV $ B.replicate 12 0++aesEncrypt128 = AES.encryptECB key128+aesEncrypt128CBC = AES.encryptCBC key128 nullIV+aesEncrypt128CTR = AES.encryptCTR key128 nullIV+aesEncrypt128XTS = AES.encryptXTS (key128,key128) nullIV 0+aesEncrypt128GCM = fst . AES.encryptGCM key128 nullIVGCM B.empty++aesEncrypt192 = AES.encryptECB key192+aesEncrypt192CBC = AES.encryptCBC key192 nullIV+aesEncrypt192CTR = AES.encryptCTR key192 nullIV+aesEncrypt192GCM = fst . AES.encryptGCM key192 nullIVGCM B.empty+aesEncrypt256 = AES.encryptECB key256+aesEncrypt256CBC = AES.encryptCBC key256 nullIV+aesEncrypt256CTR = AES.encryptCTR key256 nullIV+aesEncrypt256XTS = AES.encryptXTS (key256,key256) nullIV 0+aesEncrypt256GCM = fst . AES.encryptGCM key256 nullIVGCM B.empty++b16 f = whnf f $ B.replicate 16 0+b32 f = whnf f $ B.replicate 32 0+b128 f = whnf f $ B.replicate 128 0+b512 f = whnf f $ B.replicate 512 0+b1024 f = whnf f $ B.replicate 1024 0+b4096 f = whnf f $ B.replicate 4096 0+b16384 f = whnf f $ B.replicate 16384 0++doCipher env f = do+ mean16 <- runBenchmark env (b16 f) >>= \sample -> analyseMean sample 100+ mean32 <- runBenchmark env (b32 f) >>= \sample -> analyseMean sample 100+ mean128 <- runBenchmark env (b128 f) >>= \sample -> analyseMean sample 100+ mean512 <- runBenchmark env (b512 f) >>= \sample -> analyseMean sample 100+ mean1024 <- runBenchmark env (b1024 f) >>= \sample -> analyseMean sample 100+ mean4096 <- runBenchmark env (b4096 f) >>= \sample -> analyseMean sample 100+ mean16384 <- runBenchmark env (b16384 f) >>= \sample -> analyseMean sample 100+ return (mean16, mean32, mean128, mean512, mean1024, mean4096, mean16384)++norm :: Int -> Double -> Double+norm n time+ | n < 1024 = 1.0 / (time * (1024 / fromIntegral n))+ | n == 1024 = 1.0 / time+ | n > 1024 = 1.0 / (time / (fromIntegral n / 1024))++pn :: Int -> Double -> String+pn n time+ | val > (10 * 1024) = printf "%.1f M/s" (val / 1024)+ | otherwise = printf "%.1f K/s" val+ where val = norm n time++doOne env (cipherName, f) = do+ (mean16, mean32, mean128, mean512, mean1024, mean4096, mean16384) <- doCipher env f+ let s = printf "%12s: %12s %12s %12s %12s %12s %12s %12s\n %12s %12s %12s %12s %12s %12s %12s"+ cipherName+ (secs mean16) (secs mean32) (secs mean128)+ (secs mean512) (secs mean1024) (secs mean4096) (secs mean16384)+ (pn 16 mean16) (pn 32 mean32) (pn 128 mean128)+ (pn 512 mean512) (pn 1024 mean1024) (pn 4096 mean4096) (pn 16384 mean16384)+ return s++main = withConfig defaultConfig $ do+ env <- measureEnvironment+ l <- mapM (doOne env)+ [ ("AES128" , aesEncrypt128)+ , ("AES128-CBC" , aesEncrypt128CBC)+ , ("AES128-CTR" , aesEncrypt128CTR)+ , ("AES128-XTS" , aesEncrypt128XTS)+ , ("AES128-GCM" , aesEncrypt128GCM)+ , ("AES192" , aesEncrypt192)+ , ("AES192-CBC" , aesEncrypt192CBC)+ , ("AES192-CTR" , aesEncrypt192CTR)+ , ("AES192-GCM" , aesEncrypt192GCM)+ , ("AES256" , aesEncrypt256)+ , ("AES256-CBC" , aesEncrypt256CBC)+ , ("AES256-CTR" , aesEncrypt256CTR)+ , ("AES256-XTS" , aesEncrypt256XTS)+ , ("AES256-GCM" , aesEncrypt256GCM)+ ]+ liftIO $ printf "%12s| %12s %12s %12s %12s %12s %12s %12s\n"+ "cipher" "16 bytes" "32 bytes" "64 bytes" "512 bytes" "1024 bytes" "4096 bytes" "16384 bytes"+ liftIO $ printf "===================================================================================================\n"+ mapM_ (liftIO . putStrLn) l
+ Crypto/Cipher/AES.hs view
@@ -0,0 +1,303 @@+{-# LANGUAGE ForeignFunctionInterface #-}+{-# LANGUAGE ViewPatterns #-}+module Crypto.Cipher.AES+ (+ -- * data types+ Key+ , IV(..)++ -- * creation+ , initKey++ -- * misc+ , genCTR++ -- * encryption+ , encryptECB+ , encryptCBC+ , encryptCTR+ , encryptXTS+ , encryptGCM++ -- * decryption+ , decryptECB+ , decryptCBC+ , decryptCTR+ , decryptXTS+ , decryptGCM+ ) where++-- import Data.ByteString (ByteString)+import Data.Word+import Foreign.Ptr+import Foreign.ForeignPtr+import Foreign.Storable+import Foreign.C.Types+import Foreign.C.String+import Foreign.Marshal.Alloc+import Data.ByteString.Internal+import Data.ByteString.Unsafe+import qualified Data.ByteString as B+import System.IO.Unsafe (unsafePerformIO)++-- | AES Key+newtype Key = Key ByteString++-- | AES IV+newtype IV = IV ByteString++-- | GCM Context+newtype GCM = GCM ByteString++sizeGCM :: Int+sizeGCM = 540++instance Storable GCM where+ sizeOf _ = sizeGCM+ alignment _ = 16+ poke ptr (GCM b) = unsafeUseAsCString b (\cs -> memcpy (castPtr ptr) (castPtr cs) (fromIntegral sizeGCM))+ peek ptr = create sizeGCM (\bptr -> memcpy bptr (castPtr ptr) (fromIntegral sizeGCM)) >>= return . GCM++keyToPtr :: Key -> (Ptr Key -> IO a) -> IO a+keyToPtr (Key b) f = unsafeUseAsCString b (f . castPtr)++ivToPtr :: IV -> (Ptr IV -> IO a) -> IO a+ivToPtr (IV b) f = unsafeUseAsCString b (f . castPtr)++withKeyAndIV :: Key -> IV -> (Ptr Key -> Ptr IV -> IO a) -> IO a+withKeyAndIV key iv f = keyToPtr key $ \kptr -> ivToPtr iv $ \ivp -> f kptr ivp++withKey2AndIV :: Key -> Key -> IV -> (Ptr Key -> Ptr Key -> Ptr IV -> IO a) -> IO a+withKey2AndIV key1 key2 iv f =+ keyToPtr key1 $ \kptr1 -> keyToPtr key2 $ \kptr2 -> ivToPtr iv $ \ivp -> f kptr1 kptr2 ivp++-- | initialize key+{-# NOINLINE initKey #-}+initKey :: ByteString -> Key+initKey b@(B.length -> len)+ | len == 16 = doInit 10+ | len == 24 = doInit 12+ | len == 32 = doInit 14+ | otherwise = error "wrong key size: need to be 16, 24 or 32 bytes."+ where doInit nbR = unsafePerformIO $ unsafeUseAsCString b (allocAndFill nbR)+ allocAndFill nbR ikey = do+ ptr <- mallocBytes (16+2*2*16*nbR)+ c_aes_init ptr (castPtr ikey) (fromIntegral len)+ fptr <- newForeignPtr c_free_finalizer (castPtr ptr)+ return $ Key $ fromForeignPtr fptr 0 (16+2*2*16*nbR)++-- | encrypt using Electronic Code Book (ECB)+{-# NOINLINE encryptECB #-}+encryptECB :: Key -> ByteString -> ByteString+encryptECB = doECB c_aes_encrypt_ecb++-- | encrypt using Cipher Block Chaining (CBC)+{-# NOINLINE encryptCBC #-}+encryptCBC :: Key -> IV -> ByteString -> ByteString+encryptCBC = doCBC c_aes_encrypt_cbc++-- | generate a counter mode pad. this is generally xor-ed to an input+-- to make the standard counter mode block operations.+--+-- if the length requested is not a multiple of the block cipher size,+-- more data will be returned, so that the returned bytestring is+-- a multiple of the block cipher size.+{-# NOINLINE genCTR #-}+genCTR :: Key -- ^ Cipher Key.+ -> IV -- ^ usually a 128 bit integer.+ -> Int -- ^ length of bytes required.+ -> ByteString+genCTR key iv len = unsafeCreate (nbBlocks * 16) generate+ where+ generate o = withKeyAndIV key iv $ \k i -> c_aes_gen_ctr (castPtr o) k i (fromIntegral nbBlocks)+ (nbBlocks',r) = len `divMod` 16+ nbBlocks = if r == 0 then nbBlocks' else nbBlocks' + 1++-- | encrypt using Counter mode (CTR)+--+-- in CTR mode encryption and decryption is the same operation.+{-# NOINLINE encryptCTR #-}+encryptCTR :: Key -> IV -> ByteString -> ByteString+encryptCTR key iv input = unsafeCreate len doEncrypt+ where doEncrypt o = withKeyAndIV key iv $ \k v -> unsafeUseAsCString input $ \i ->+ c_aes_encrypt_ctr (castPtr o) k v i (fromIntegral len)+ len = B.length input++-- | encrypt using Galois counter mode (GCM)+-- return the encrypted bytestring and the tag associated+--+-- note: encrypted data is identical to CTR mode in GCM, however+-- a tag is also computed.+encryptGCM :: Key -- ^ Key+ -> IV -- ^ initial vector+ -> ByteString -- ^ data to authenticate (AAD)+ -> ByteString -- ^ data to encrypt+ -> (ByteString, ByteString) -- ^ ciphertext and tag+encryptGCM = doGCM gcmAppendEncrypt++-- | encrypt using XTS+--+-- the first key is the normal block encryption key+-- the second key is used for the initial block tweak+{-# NOINLINE encryptXTS #-}+encryptXTS :: (Key,Key) -> IV -> Word32 -> ByteString -> ByteString+encryptXTS = doXTS c_aes_encrypt_xts++-- | decrypt using Electronic Code Book (ECB)+{-# NOINLINE decryptECB #-}+decryptECB :: Key -> ByteString -> ByteString+decryptECB = doECB c_aes_decrypt_ecb++-- | decrypt using Cipher block chaining (CBC)+{-# NOINLINE decryptCBC #-}+decryptCBC :: Key -> IV -> ByteString -> ByteString+decryptCBC = doCBC c_aes_decrypt_cbc++-- | decrypt using Counter mode (CTR).+--+-- in CTR mode encryption and decryption is the same operation.+decryptCTR :: Key -> IV -> ByteString -> ByteString+decryptCTR = encryptCTR++-- | decrypt using XTS+{-# NOINLINE decryptXTS #-}+decryptXTS :: (Key,Key) -> IV -> Word32 -> ByteString -> ByteString+decryptXTS = doXTS c_aes_decrypt_xts++-- | decrypt using Galois Counter Mode (GCM)+{-# NOINLINE decryptGCM #-}+decryptGCM :: Key -> IV -> ByteString -> ByteString -> (ByteString, ByteString)+decryptGCM = doGCM gcmAppendDecrypt++{-# INLINE doECB #-}+doECB :: (Ptr b -> Ptr Key -> CString -> CUInt -> IO ())+ -> Key -> ByteString -> ByteString+doECB f key input+ | r /= 0 = error "cannot use with non multiple of block size"+ | otherwise = unsafeCreate len $ \o -> keyToPtr key $ \k -> unsafeUseAsCString input $ \i ->+ f (castPtr o) k i (fromIntegral nbBlocks)+ where (nbBlocks, r) = len `divMod` 16+ len = (B.length input)+++{-# INLINE doCBC #-}+doCBC :: (Ptr b -> Ptr Key -> Ptr IV -> CString -> CUInt -> IO ())+ -> Key -> IV -> ByteString -> ByteString+doCBC f key iv input+ | r /= 0 = error "cannot use with non multiple of block size"+ | otherwise = unsafeCreate len $ \o -> withKeyAndIV key iv $ \k v -> unsafeUseAsCString input $ \i ->+ f (castPtr o) k v i (fromIntegral nbBlocks)+ where (nbBlocks, r) = len `divMod` 16+ len = (B.length input)++{-# INLINE doXTS #-}+doXTS :: (Ptr b -> Ptr Key -> Ptr Key -> Ptr IV -> CUInt -> CString -> CUInt -> IO ())+ -> (Key, Key) -> IV -> Word32 -> ByteString -> ByteString+doXTS f (key1,key2) iv spoint input+ | r /= 0 = error "cannot use with non multiple of block size (yet)"+ | otherwise = unsafeCreate len $ \o -> withKey2AndIV key1 key2 iv $ \k1 k2 v -> unsafeUseAsCString input $ \i ->+ f (castPtr o) k1 k2 v (fromIntegral spoint) i (fromIntegral nbBlocks)+ where (nbBlocks, r) = len `divMod` 16+ len = (B.length input)++{-# INLINE doGCM #-}+doGCM :: (GCM -> ByteString -> (ByteString, GCM)) -> Key -> IV -> ByteString -> ByteString -> (ByteString, ByteString)+doGCM f key iv aad input = (cipher, tag)+ where+ tag = gcmFinish after 16+ (cipher, after) = f afterAAD input+ afterAAD = gcmAppendAAD ini aad+ ini = gcmInit key iv++allocaFrom :: Storable a => a -> (Ptr a -> IO b) -> IO b+allocaFrom z f = alloca $ \ptr -> poke ptr z >> f ptr++-- | initialize a gcm context+{-# NOINLINE gcmInit #-}+gcmInit :: Key -> IV -> GCM+gcmInit key iv@(IV b) = unsafePerformIO $ alloca doInit+ where doInit gcm = withKeyAndIV key iv (\k v -> c_aes_gcm_init gcm k v (fromIntegral $ B.length b)) >> peek gcm++-- | append data which is going to just be authentified to the GCM context.+--+-- need to happen after initialization and before appending encryption/decryption data.+{-# NOINLINE gcmAppendAAD #-}+gcmAppendAAD :: GCM -> ByteString -> GCM+gcmAppendAAD gcm input = unsafePerformIO $ allocaFrom gcm doAppend+ where doAppend p = do+ unsafeUseAsCString input $ \i -> c_aes_gcm_aad p i (fromIntegral $ B.length input) + peek p++-- | append data to encrypt and append to the GCM context+--+-- bytestring need to be multiple of AES block size, unless it's the last call to this function.+-- need to happen after AAD appending, or after initialization if no AAD data.+{-# NOINLINE gcmAppendEncrypt #-}+gcmAppendEncrypt :: GCM -> ByteString -> (ByteString, GCM)+gcmAppendEncrypt gcm input = unsafePerformIO $ allocaFrom gcm doEnc+ where len = B.length input+ doEnc p = do+ output <- create len $ \o -> unsafeUseAsCString input $ \i -> c_aes_gcm_encrypt (castPtr o) p i (fromIntegral len)+ ngcm <- peek p+ return (output, ngcm)++-- | append data to decrypt and append to the GCM context+--+-- bytestring need to be multiple of AES block size, unless it's the last call to this function.+-- need to happen after AAD appending, or after initialization if no AAD data.+{-# NOINLINE gcmAppendDecrypt #-}+gcmAppendDecrypt :: GCM -> ByteString -> (ByteString, GCM)+gcmAppendDecrypt gcm input = unsafePerformIO $ allocaFrom gcm doDec+ where len = B.length input+ doDec p = do+ output <- create len $ \o -> unsafeUseAsCString input $ \i -> c_aes_gcm_decrypt (castPtr o) p i (fromIntegral len)+ ngcm <- peek p+ return (output, ngcm)++-- | Generate the Tag from GCM context+{-# NOINLINE gcmFinish #-}+gcmFinish :: GCM -> Int -> ByteString+gcmFinish gcm taglen = B.take taglen (unsafeCreate 16 $ \t -> allocaFrom gcm (finish t))+ where finish t p = c_aes_gcm_finish (castPtr t) p++foreign import ccall "aes.h aes_initkey"+ c_aes_init :: Ptr Key -> CString -> CUInt -> IO ()++foreign import ccall "aes.h aes_encrypt_ecb"+ c_aes_encrypt_ecb :: CString -> Ptr Key -> CString -> CUInt -> IO ()++foreign import ccall "aes.h aes_decrypt_ecb"+ c_aes_decrypt_ecb :: CString -> Ptr Key -> CString -> CUInt -> IO ()++foreign import ccall "aes.h aes_encrypt_cbc"+ c_aes_encrypt_cbc :: CString -> Ptr Key -> Ptr IV -> CString -> CUInt -> IO ()++foreign import ccall "aes.h aes_decrypt_cbc"+ c_aes_decrypt_cbc :: CString -> Ptr Key -> Ptr IV -> CString -> CUInt -> IO ()++foreign import ccall "aes.h aes_encrypt_xts"+ c_aes_encrypt_xts :: CString -> Ptr Key -> Ptr Key -> Ptr IV -> CUInt -> CString -> CUInt -> IO ()++foreign import ccall "aes.h aes_decrypt_xts"+ c_aes_decrypt_xts :: CString -> Ptr Key -> Ptr Key -> Ptr IV -> CUInt -> CString -> CUInt -> IO ()++foreign import ccall "aes.h aes_gen_ctr"+ c_aes_gen_ctr :: CString -> Ptr Key -> Ptr IV -> CUInt -> IO ()++foreign import ccall "aes.h aes_encrypt_ctr"+ c_aes_encrypt_ctr :: CString -> Ptr Key -> Ptr IV -> CString -> CUInt -> IO ()++foreign import ccall "aes.h aes_gcm_init"+ c_aes_gcm_init :: Ptr GCM -> Ptr Key -> Ptr IV -> CUInt -> IO ()++foreign import ccall "aes.h aes_gcm_aad"+ c_aes_gcm_aad :: Ptr GCM -> CString -> CUInt -> IO ()++foreign import ccall "aes.h aes_gcm_encrypt"+ c_aes_gcm_encrypt :: CString -> Ptr GCM -> CString -> CUInt -> IO ()++foreign import ccall "aes.h aes_gcm_decrypt"+ c_aes_gcm_decrypt :: CString -> Ptr GCM -> CString -> CUInt -> IO ()++foreign import ccall "aes.h aes_gcm_finish"+ c_aes_gcm_finish :: CString -> Ptr GCM -> IO ()
+ LICENSE view
@@ -0,0 +1,27 @@+Copyright (c) 2008-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.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ Tests/KATCBC.hs view
@@ -0,0 +1,119 @@+{-# LANGUAGE OverloadedStrings #-}+module KATCBC (vectors_encrypt, vectors_decrypt) where++import qualified Data.ByteString as B+import Data.ByteString.Char8 ()++type KATCBC = (B.ByteString, B.ByteString, B.ByteString, B.ByteString)++vectors_aes128_enc, vectors_aes128_dec+ , vectors_aes192_enc, vectors_aes192_dec+ , vectors_aes256_enc, vectors_aes256_dec :: [KATCBC]+vectors_aes128_enc =+ [+ ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x66\xe9\x4b\xd4\xef\x8a\x2c\x3b\x88\x4c\xfa\x59\xca\x34\x2b\x2e")+ , ("\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\xb6\xae\xaf\xfa\x75\x2d\xc0\x8b\x51\x63\x97\x31\x76\x1a\xed\x00")+ , ("\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\xcb\x64\xcf\x3f\x42\x2a\xe8\x4b\xb9\x0e\x3a\xb4\xdb\xa7\xbd\x86")+ , ("\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\xe5\xb5\x07\x7f\x93\x46\x46\x2c\x62\xa0\x75\xc0\xc7\x08\xee\x96")+ , ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\xe1\x4d\x5d\x0e\xe2\x77\x15\xdf\x08\xb4\x15\x2b\xa2\x3d\xa8\xe0")+ , ("\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x5e\x77\xe5\x9f\x8f\x85\x94\x34\x89\xa2\x41\x49\xc7\x5f\x4e\xc9")+ , ("\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x8f\x42\xc2\x4b\xee\x6e\x63\x47\x2b\x16\x5a\xa9\x41\x31\x2f\x7c")+ , ("\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\xb0\xea\x4a\xc0\xd2\x5c\xcd\x7c\x82\xcb\x8a\x30\x68\xc6\xfe\x2e")+ , ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\xe1\x4d\x5d\x0e\xe2\x77\x15\xdf\x08\xb4\x15\x2b\xa2\x3d\xa8\xe0")+ , ("\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x17\xd6\x14\xf3\x79\xa9\x35\x90\x77\xe9\x55\x77\xfd\x31\xc2\x0a")+ , ("\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x8f\x42\xc2\x4b\xee\x6e\x63\x47\x2b\x16\x5a\xa9\x41\x31\x2f\x7c")+ , ("\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\xe5\xb5\x07\x7f\x93\x46\x46\x2c\x62\xa0\x75\xc0\xc7\x08\xee\x96")+ ]++vectors_aes192_enc =+ [+ ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\xaa\xe0\x69\x92\xac\xbf\x52\xa3\xe8\xf4\xa9\x6e\xc9\x30\x0b\xd7")+ , ("\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x5f\x88\xef\x3f\xbd\xeb\xf2\xe4\xe2\x66\x65\x12\xd3\xbc\xb7\x0f")+ , ("\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\xdb\x42\xf5\x1c\xd2\x0e\xca\xd2\x9e\xb0\x13\x2b\x0f\xaa\x4b\x85")+ , ("\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\xda\xb4\x01\x5f\x98\x70\x25\xeb\xb8\xa8\x5f\x3c\x7f\x73\x70\x19")+ , ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\xcf\x1e\xce\x3c\x44\xb0\x78\xfb\x27\xcb\x0a\x3e\x07\x1b\x08\x20")+ , ("\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x98\xb8\x95\xa1\x45\xca\x4e\x0b\xf8\x3e\x69\x32\x81\xc1\xa0\x97")+ , ("\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\xf2\xf0\xae\xd8\xcd\xc9\x21\xca\x4b\x55\x84\x5d\xa4\x15\x21\xc2")+ , ("\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x5e\xea\x4b\x13\xdd\xd9\x17\x12\xb0\x14\xe2\x82\x2d\x18\x76\xfb")+ , ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\xcf\x1e\xce\x3c\x44\xb0\x78\xfb\x27\xcb\x0a\x3e\x07\x1b\x08\x20")+ , ("\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\xeb\x8c\x17\x30\x90\xc7\x5b\x77\xd6\x72\xb4\x57\xa7\x78\xd9\xd0")+ , ("\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\xf2\xf0\xae\xd8\xcd\xc9\x21\xca\x4b\x55\x84\x5d\xa4\x15\x21\xc2")+ , ("\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\xda\xb4\x01\x5f\x98\x70\x25\xeb\xb8\xa8\x5f\x3c\x7f\x73\x70\x19")++ ]++vectors_aes256_enc =+ [+ ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\xdc\x95\xc0\x78\xa2\x40\x89\x89\xad\x48\xa2\x14\x92\x84\x20\x87")+ , ("\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x72\x98\xca\xa5\x65\x03\x1e\xad\xc6\xce\x23\xd2\x3e\xa6\x63\x78")+ , ("\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\xf4\x35\xa1\x11\xa3\xe4\xa1\x94\x49\x19\xf9\x12\xc5\xa2\x41\xde")+ , ("\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x91\xc0\x87\x62\x87\x6d\xcc\xf9\xba\x20\x4a\x33\x76\x8f\xa5\xfe")+ , ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x7b\xc3\x02\x6c\xd7\x37\x10\x3e\x62\x90\x2b\xcd\x18\xfb\x01\x63")+ , ("\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x9c\xac\x94\xc6\xb4\x85\x61\xf8\xff\xaa\xa7\x86\x16\xba\x48\x92")+ , ("\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\xf9\xc7\x44\x4b\xb0\xcc\x80\x6c\x7c\x39\xee\x22\x11\xf1\x46")+ , ("\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x6d\xed\xd0\xa3\xe6\x94\xa0\xde\x65\x1d\x68\xa6\xb5\x5a\x64\xa2")+ , ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x7b\xc3\x02\x6c\xd7\x37\x10\x3e\x62\x90\x2b\xcd\x18\xfb\x01\x63")+ , ("\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x62\xae\x12\xf3\x24\xbf\xea\x08\xd5\xf6\x75\xb5\x13\x02\x6b\xbf")+ , ("\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x00\xf9\xc7\x44\x4b\xb0\xcc\x80\x6c\x7c\x39\xee\x22\x11\xf1\x46")+ , ("\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x91\xc0\x87\x62\x87\x6d\xcc\xf9\xba\x20\x4a\x33\x76\x8f\xa5\xfe")+ ]++vectors_aes128_dec =+ [+ ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x14\x0f\x0f\x10\x11\xb5\x22\x3d\x79\x58\x77\x17\xff\xd9\xec\x3a")+ , ("\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x33\x08\x32\x40\xd6\x5c\xbc\x72\xaa\x0b\x44\xf3\xe1\x9e\xa9\x5a")+ , ("\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x65\x0a\x42\xa0\x3c\x4b\x93\xa4\xb7\x43\xdc\x9e\x9c\xf4\xc0\x9b")+ , ("\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x80\xcd\x20\xe1\xbd\x89\x3c\x5e\xe4\x20\x76\x85\xb0\x9a\x0e\x3e")+ , ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x15\x0e\x0e\x11\x10\xb4\x23\x3c\x78\x59\x76\x16\xfe\xd8\xed\x3b")+ , ("\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x32\x09\x33\x41\xd7\x5d\xbd\x73\xab\x0a\x45\xf2\xe0\x9f\xa8\x5b")+ , ("\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x64\x0b\x43\xa1\x3d\x4a\x92\xa5\xb6\x42\xdd\x9f\x9d\xf5\xc1\x9a")+ , ("\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x81\xcc\x21\xe0\xbc\x88\x3d\x5f\xe5\x21\x77\x84\xb1\x9b\x0f\x3f")+ , ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\xf5\x06\x41\x7e\x6a\x8f\xbc\x32\xdd\xa5\x52\x73\xbf\x9f\x4d\x5c")+ , ("\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\xbf\x6d\x28\xac\x20\xc9\x1d\x65\xa9\xd4\xb0\x96\xc2\xd5\xa5\x09")+ , ("\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x5f\x2a\x46\xab\x8d\xb9\x5b\x22\x15\xfe\x1a\xa4\xdd\x69\x59\x26")+ , ("\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x71\x9b\x21\xb5\x39\x7c\x2f\x16\x7c\x8b\x45\x22\xb5\x20\xec\x2e")+ ]++vectors_aes192_dec =+ [+ ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x13\x46\x0e\x87\xa8\xfc\x02\x3e\xf2\x50\x1a\xfe\x7f\xf5\x1c\x51")+ , ("\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x91\x75\x27\xfc\xd4\xa0\x6f\x32\x27\x29\x90\x14\xca\xde\xd4\x1a")+ , ("\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x29\x64\x80\xb6\xa5\xd6\xcf\xb3\x78\x3f\x21\x6b\x80\x31\x3d\xb3")+ , ("\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\xbc\xa5\x06\x07\xd0\x67\x30\x85\x2d\x3a\x50\x4b\x68\x0a\x19\xcc")+ , ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x12\x47\x0f\x86\xa9\xfd\x03\x3f\xf3\x51\x1b\xff\x7e\xf4\x1d\x50")+ , ("\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x90\x74\x26\xfd\xd5\xa1\x6e\x33\x26\x28\x91\x15\xcb\xdf\xd5\x1b")+ , ("\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x28\x65\x81\xb7\xa4\xd7\xce\xb2\x79\x3e\x20\x6a\x81\x30\x3c\xb2")+ , ("\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\xbd\xa4\x07\x06\xd1\x66\x31\x84\x2c\x3b\x51\x4a\x69\x0b\x18\xcd")+ , ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x38\xf9\xf9\xd1\x7e\x2c\x82\xaf\xdc\xed\x68\x03\xb6\x31\x46\x3e")+ , ("\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x35\x4e\xc1\x01\x0f\x17\x50\x5e\x63\x37\x40\x4b\x9a\xf2\xc0\x5c")+ , ("\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\xa7\x7c\xc9\xd1\x4f\x44\xf7\xf7\xcc\x45\x80\x83\x19\xb7\xa4\x71")+ , ("\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\xf9\x1d\xb1\x13\x0b\xd1\xc0\x66\x9f\xfa\xc2\x0e\xbe\xdd\xcb\xca")+ ]++vectors_aes256_dec =+ [+ ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x67\x67\x1c\xe1\xfa\x91\xdd\xeb\x0f\x8f\xbb\xb3\x66\xb5\x31\xb4")+ , ("\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x7b\xd3\xfb\x90\x65\x56\x9f\x39\x8b\x09\xcb\x93\x4b\x1e\x01\x23")+ , ("\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\xda\xa8\xbf\x5c\xde\x2e\x52\x45\x5f\xa3\xb3\xfe\x33\x32\x47\xca")+ , ("\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x83\x24\xdc\xb4\x30\x12\x73\x6c\xed\x58\xab\x8f\x4b\x05\xca\x0b")+ , ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x66\x66\x1d\xe0\xfb\x90\xdc\xea\x0e\x8e\xba\xb2\x67\xb4\x30\xb5")+ , ("\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x7a\xd2\xfa\x91\x64\x57\x9e\x38\x8a\x08\xca\x92\x4a\x1f\x00\x22")+ , ("\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\xdb\xa9\xbe\x5d\xdf\x2f\x53\x44\x5e\xa2\xb2\xff\x32\x33\x46\xcb")+ , ("\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x82\x25\xdd\xb5\x31\x13\x72\x6d\xec\x59\xaa\x8e\x4a\x04\xcb\x0a")+ , ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x68\xe9\x07\x16\xe3\x66\x1b\x1d\xb1\x89\x74\xb0\x9c\x46\x47\xe4")+ , ("\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x7f\xb9\xeb\xa4\xd3\x5f\x70\x40\xab\x52\xec\xd2\x3b\x48\xb7\x6e")+ , ("\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x6c\x58\x0f\x41\x82\x36\xbc\xff\x64\x1d\xac\xa7\x3e\x34\x11\x18")+ , ("\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x3f\x62\xd6\x8c\xb1\xf7\x62\x28\xa4\xc3\x82\x4f\x8b\x24\xe7\x4b")+ ]++vectors_encrypt =+ [ ("AES 128 Enc", vectors_aes128_enc)+ , ("AES 192 Enc", vectors_aes192_enc)+ , ("AES 256 Enc", vectors_aes256_enc)+ ]++vectors_decrypt =+ [ ("AES 128 Dec", vectors_aes128_dec)+ , ("AES 192 Dec", vectors_aes192_dec)+ , ("AES 256 Dec", vectors_aes256_dec)+ ]
+ Tests/KATECB.hs view
@@ -0,0 +1,160 @@+module KATECB (vectors_encrypt, vectors_decrypt) where++import qualified Data.ByteString as B++vectors_aes128_enc =+ [+ ( B.pack [0x10, 0xa5, 0x88, 0x69, 0xd7, 0x4b, 0xe5, 0xa3,0x74,0xcf,0x86,0x7c,0xfb,0x47,0x38,0x59]+ , B.replicate 16 0+ , B.pack [0x6d,0x25,0x1e,0x69,0x44,0xb0,0x51,0xe0,0x4e,0xaa,0x6f,0xb4,0xdb,0xf7,0x84,0x65]+ )+ , ( B.replicate 16 0+ , B.replicate 16 0+ , B.pack [0x66,0xe9,0x4b,0xd4,0xef,0x8a,0x2c,0x3b,0x88,0x4c,0xfa,0x59,0xca,0x34,0x2b,0x2e]+ )+ , ( B.replicate 16 0+ , B.replicate 16 1+ , B.pack [0xe1,0x4d,0x5d,0x0e,0xe2,0x77,0x15,0xdf,0x08,0xb4,0x15,0x2b,0xa2,0x3d,0xa8,0xe0]+ )+ , ( B.replicate 16 1+ , B.replicate 16 2+ , B.pack [0x17,0xd6,0x14,0xf3,0x79,0xa9,0x35,0x90,0x77,0xe9,0x55,0x77,0xfd,0x31,0xc2,0x0a]+ )+ , ( B.replicate 16 2+ , B.replicate 16 1+ , B.pack [0x8f,0x42,0xc2,0x4b,0xee,0x6e,0x63,0x47,0x2b,0x16,0x5a,0xa9,0x41,0x31,0x2f,0x7c]+ )+ , ( B.replicate 16 3+ , B.replicate 16 2+ , B.pack [0x90,0x98,0x85,0xe4,0x77,0xbc,0x20,0xf5,0x8a,0x66,0x97,0x1d,0xa0,0xbc,0x75,0xe3]+ )+ ]++vectors_aes192_enc =+ [+ ( B.replicate 24 0+ , B.replicate 16 0+ , B.pack [0xaa,0xe0,0x69,0x92,0xac,0xbf,0x52,0xa3,0xe8,0xf4,0xa9,0x6e,0xc9,0x30,0x0b,0xd7]+ )+ , ( B.replicate 24 0+ , B.replicate 16 1+ , B.pack [0xcf,0x1e,0xce,0x3c,0x44,0xb0,0x78,0xfb,0x27,0xcb,0x0a,0x3e,0x07,0x1b,0x08,0x20]+ )+ , ( B.replicate 24 1+ , B.replicate 16 2+ , B.pack [0xeb,0x8c,0x17,0x30,0x90,0xc7,0x5b,0x77,0xd6,0x72,0xb4,0x57,0xa7,0x78,0xd9,0xd0]+ )+ , ( B.replicate 24 2+ , B.replicate 16 1+ , B.pack [0xf2,0xf0,0xae,0xd8,0xcd,0xc9,0x21,0xca,0x4b,0x55,0x84,0x5d,0xa4,0x15,0x21,0xc2]+ )+ , ( B.replicate 24 3+ , B.replicate 16 2+ , B.pack [0xca,0xcc,0x30,0x79,0xe4,0xb7,0x95,0x27,0x63,0xd2,0x55,0xd6,0x34,0x10,0x46,0x14]+ )+ ]++vectors_aes256_enc =+ [ ( B.replicate 32 0+ , B.replicate 16 0+ , B.pack [0xdc,0x95,0xc0,0x78,0xa2,0x40,0x89,0x89,0xad,0x48,0xa2,0x14,0x92,0x84,0x20,0x87]+ )+ , ( B.replicate 32 0+ , B.replicate 16 1+ , B.pack [0x7b,0xc3,0x02,0x6c,0xd7,0x37,0x10,0x3e,0x62,0x90,0x2b,0xcd,0x18,0xfb,0x01,0x63]+ )+ , ( B.replicate 32 1+ , B.replicate 16 2+ , B.pack [0x62,0xae,0x12,0xf3,0x24,0xbf,0xea,0x08,0xd5,0xf6,0x75,0xb5,0x13,0x02,0x6b,0xbf]+ )+ , ( B.replicate 32 2+ , B.replicate 16 1+ , B.pack [0x00,0xf9,0xc7,0x44,0x4b,0xb0,0xcc,0x80,0x6c,0x7c,0x39,0xee,0x22,0x11,0xf1,0x46]+ )+ , ( B.replicate 32 3+ , B.replicate 16 2+ , B.pack [0xb4,0x05,0x87,0x3e,0xa0,0x76,0x1b,0x9c,0xa9,0x9f,0x70,0xb0,0x16,0x16,0xce,0xb1]+ )+ ]++vectors_aes128_dec =+ [ ( B.replicate 16 0+ , B.replicate 16 0+ , B.pack [0x14,0x0f,0x0f,0x10,0x11,0xb5,0x22,0x3d,0x79,0x58,0x77,0x17,0xff,0xd9,0xec,0x3a]+ )+ , ( B.replicate 16 0+ , B.replicate 16 1+ , B.pack [0x15,0x6d,0x0f,0x85,0x75,0xd5,0x33,0x07,0x52,0xf8,0x4a,0xf2,0x72,0xff,0x30,0x50]+ )+ , ( B.replicate 16 1+ , B.replicate 16 2+ , B.pack [0x34,0x37,0xd6,0xe2,0x31,0xd7,0x02,0x41,0x9b,0x51,0xb4,0x94,0x72,0x71,0xb6,0x11]+ )+ , ( B.replicate 16 2+ , B.replicate 16 1+ , B.pack [0xe3,0xcd,0xe2,0x37,0xc8,0xf2,0xd9,0x7b,0x8d,0x79,0xf9,0x17,0x1d,0x4b,0xda,0xc1]+ )+ , ( B.replicate 16 3+ , B.replicate 16 2+ , B.pack [0x5b,0x94,0xaa,0xed,0xd7,0x83,0x99,0x8c,0xd5,0x15,0x35,0x35,0x18,0xcc,0x45,0xe2]+ )+ ]++vectors_aes192_dec =+ [+ ( B.replicate 24 0+ , B.replicate 16 0+ , B.pack [0x13,0x46,0x0e,0x87,0xa8,0xfc,0x02,0x3e,0xf2,0x50,0x1a,0xfe,0x7f,0xf5,0x1c,0x51]+ )+ , ( B.replicate 24 0+ , B.replicate 16 1+ , B.pack [0x92,0x17,0x07,0xc3,0x3d,0x1c,0xc5,0x96,0x7d,0xa5,0x1d,0xbb,0xb0,0x66,0xb2,0x6c]+ )+ , ( B.replicate 24 1+ , B.replicate 16 2+ , B.pack [0xee,0x92,0x97,0xc6,0xba,0xe8,0x26,0x4d,0xff,0x08,0x0e,0xbb,0x1e,0x74,0x11,0xc1]+ )+ , ( B.replicate 24 2+ , B.replicate 16 1+ , B.pack [0x49,0x67,0xdf,0x70,0xd2,0x9e,0x9a,0x7f,0x5d,0x7c,0xb9,0xc1,0x20,0xc3,0x8a,0x71]+ )+ , ( B.replicate 24 3+ , B.replicate 16 2+ , B.pack [0x74,0x38,0x62,0x42,0x6b,0x56,0x7f,0xd5,0xf0,0x1d,0x1b,0x59,0x56,0x01,0x26,0x29]+ )+ ]++vectors_aes256_dec =+ [ ( B.replicate 32 0+ , B.replicate 16 0+ , B.pack [0x67,0x67,0x1c,0xe1,0xfa,0x91,0xdd,0xeb,0x0f,0x8f,0xbb,0xb3,0x66,0xb5,0x31,0xb4]+ )+ , ( B.replicate 32 0+ , B.replicate 16 1+ , B.pack [0xcc,0x09,0x21,0xa3,0xc5,0xca,0x17,0xf7,0x48,0xb7,0xc2,0x7b,0x73,0xba,0x87,0xa2]+ )+ , ( B.replicate 32 1+ , B.replicate 16 2+ , B.pack [0xc0,0x4b,0x27,0x90,0x1a,0x50,0xcf,0xfa,0xf1,0xbb,0x88,0x9f,0xc0,0x92,0x5e,0x14]+ )+ , ( B.replicate 32 2+ , B.replicate 16 1+ , B.pack [0x24,0x61,0x53,0x5d,0x16,0x1c,0x15,0x39,0x88,0x32,0x77,0x29,0xc5,0x8c,0xc0,0x3a]+ )+ , ( B.replicate 32 3+ , B.replicate 16 2+ , B.pack [0x30,0xc9,0x1c,0xce,0xfe,0x89,0x30,0xcf,0xff,0x31,0xdb,0xcc,0xfc,0x11,0xc5,0x23]+ )+ ]++vectors_encrypt =+ [ ("AES 128 Enc", vectors_aes128_enc)+ , ("AES 192 Enc", vectors_aes192_enc)+ , ("AES 256 Enc", vectors_aes256_enc)+ ]++vectors_decrypt =+ [ ("AES 128 Dec", vectors_aes128_dec)+ , ("AES 192 Dec", vectors_aes192_dec)+ , ("AES 256 Dec", vectors_aes256_dec)+ ]
+ Tests/KATGCM.hs view
@@ -0,0 +1,65 @@+{-# LANGUAGE OverloadedStrings #-}+module KATGCM (vectors_encrypt, vectors_decrypt) where++import qualified Data.ByteString as B+import Data.ByteString.Char8 ()++-- (key, iv, aad, input, out, taglen, tag)+type KATGCM = (B.ByteString, B.ByteString, B.ByteString, B.ByteString, B.ByteString, Int, B.ByteString)++vectors_aes128_enc :: [KATGCM]+vectors_aes128_enc =+ [ -- vectors 0+ ( {-key = -}"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"+ , {-iv = -}"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"+ , {-aad = -}""+ , {-input = -}""+ , {-out = -}""+ , {-taglen = -}16+ , {-tag = -}"\x58\xe2\xfc\xce\xfa\x7e\x30\x61\x36\x7f\x1d\x57\xa4\xe7\x45\x5a")+ -- vectors 1+ , ( {-key = -}"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"+ , {-iv = -}"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"+ , {-aad = -}"\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"+ , {-input = -}"\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a"+ , {-out = -}"\x09\x82\xd0\xc4\x6a\xbc\xa9\x98\xf9\x22\xc8\xb3\x7b\xb8\xf4\x72\xfd\x9f\xa0\xa1\x43\x41\x53\x29\xfd\xf7\x83\xf5\x9e\x81\xcb\xea"+ , {-taglen = -}16+ , {-tag = -}"\x28\x50\x64\x2f\xa8\x8b\xab\x21\x2a\x67\x1a\x97\x48\x69\xa5\x6c")++ -- vectors 2+ , ( {-key = -}"\x01\x02\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"+ , {-iv = -}"\xff\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"+ , {-aad = -}"\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"+ , {-input = -}"\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a"+ , {-out = -}"\x1c\xa3\xb5\x41\x39\x6f\x19\x7a\x91\x2d\x27\x15\x70\xd1\xf5\x76\xde\xf1\xbe\x84\x42\x2a\xbb\xbe\x0b\x2d\x91\x21\x82\xbf\x7f\x17"+ , {-taglen = -}16+ , {-tag = -}"\x15\x2a\x05\xbb\x7e\x13\x5d\xbe\x93\x7f\xa0\x54\x7a\x8e\x74\xb6")+ -- vectors 3+ , ( {-key = -}"\x01\x02\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"+ , {-iv = -}"\xff\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"+ , {-aad = -}"\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"+ , {-input = -}"\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a"+ , {-out = -}"\xda\x35\xf6\x0a\x65\xc2\xa4\x6c\xb6\x6e\xb6\xf8\x1f\x0b\x9c\x74\x53\x4c\x97\x70\x36\xf7\xdf\x05\x6d\x00\xfe\xbf\xb4\xcb\xf5\x27"+ , {-taglen = -}16+ , {-tag = -}"\xb7\x76\x7c\x3b\x9e\xf1\xe2\xcb\xc9\x11\xf1\x9a\xdc\xfa\x35\x0d")+ , ( {-key = -}"\x01\x02\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"+ , {-iv = -}"\xff\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"+ , {-aad = -}"\x76\x76\x76\x76\x76\x76\x76\x76\x76\x76\x76\x76\x76\x76\x76\x76"+ , {-input = -}"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"+ , {-out = -}"\xe4\x42\xf8\xc4\xc6\x67\x84\x86\x4a\x5a\x6e\xc7\xe0\xca\x68\xac\x16\xbc\x5b\xbf\xf7\xd5\xf3\xfa\xf3\xb2\xcb\xb0\xa2\x14\xa1\x81"+ , {-taglen = -}16+ , {-tag = -}"\x5f\x63\xb8\xeb\x1d\x6f\xa8\x7a\xeb\x39\xa5\xf6\xd7\xed\xc3\x13")+ , ( {-key = -}"\x01\x02\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"+ , {-iv = -}"\xff\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"+ , {-aad = -}"\x76\x76\x76\x76\x76\x76\x76\x76\x76\x76\x76\x76\x76"+ , {-input = -}"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"+ , {-out = -}"\xe4\x42\xf8\xc4\xc6\x67\x84\x86\x4a\x5a\x6e\xc7\xe0\xca\x68\xac\x16\xbc\x5b\xbf\xf7\xd5\xf3\xfa\xf3\xb2\xcb\xb0\xa2\x14\xa1"+ , {-taglen = -}16+ , {-tag = -}"\x94\xd1\x47\xc3\xa2\xca\x93\xe9\x66\x93\x1e\x3b\xb3\xbb\x67\x01")+ ]++vectors_encrypt =+ [ ("AES128 Enc", vectors_aes128_enc)+ ]++vectors_decrypt = []
+ Tests/KATXTS.hs view
@@ -0,0 +1,69 @@+{-# LANGUAGE OverloadedStrings #-}+module KATXTS (vectors_encrypt, vectors_decrypt) where++import qualified Data.ByteString as B+import Data.ByteString.Char8 ()++type KATXTS = (B.ByteString, B.ByteString, B.ByteString, B.ByteString, B.ByteString, B.ByteString)++vectors_aes128_enc, vectors_aes128_dec, vectors_aes256_enc, vectors_aes256_dec :: [KATXTS]+vectors_aes128_enc =+ [+ ( "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"+ , "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"+ , "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"+ , "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"+ , "\x66\xe9\x4b\xd4\xef\x8a\x2c\x3b\x88\x4c\xfa\x59\xca\x34\x2b\x2e\xcc\xd2\x97\xa8\xdf\x15\x59\x76\x10\x99\xf4\xb3\x94\x69\x56\x5c"+ , "\x91\x7c\xf6\x9e\xbd\x68\xb2\xec\x9b\x9f\xe9\xa3\xea\xdd\xa6\x92\xcd\x43\xd2\xf5\x95\x98\xed\x85\x8c\x02\xc2\x65\x2f\xbf\x92\x2e"+ )+ ,+ ( "\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11"+ , "\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22"+ , "\x33\x33\x33\x33\x33\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"+ , "\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44"+ , "\x3f\x80\x3b\xcd\x0d\x7f\xd2\xb3\x75\x58\x41\x9f\x59\xd5\xcd\xa6\xf9\x00\x77\x9a\x1b\xfe\xa4\x67\xeb\xb0\x82\x3e\xb3\xaa\x9b\x4d"+ , "\xc4\x54\x18\x5e\x6a\x16\x93\x6e\x39\x33\x40\x38\xac\xef\x83\x8b\xfb\x18\x6f\xff\x74\x80\xad\xc4\x28\x93\x82\xec\xd6\xd3\x94\xf0"+ )+ ,+ ( "\xff\xfe\xfd\xfc\xfb\xfa\xf9\xf8\xf7\xf6\xf5\xf4\xf3\xf2\xf1\xf0"+ , "\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22"+ , "\x33\x33\x33\x33\x33\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"+ , "\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44"+ , "\x3f\x80\x3b\xcd\x0d\x7f\xd2\xb3\x75\x58\x41\x9f\x59\xd5\xcd\xa6\xf9\x00\x77\x9a\x1b\xfe\xa4\x67\xeb\xb0\x82\x3e\xb3\xaa\x9b\x4d"+ , "\xaf\x85\x33\x6b\x59\x7a\xfc\x1a\x90\x0b\x2e\xb2\x1e\xc9\x49\xd2\x92\xdf\x4c\x04\x7e\x0b\x21\x53\x21\x86\xa5\x97\x1a\x22\x7a\x89"+ )+ ,+ ( "\x27\x18\x28\x18\x28\x45\x90\x45\x23\x53\x60\x28\x74\x71\x35\x26"+ , "\x31\x41\x59\x26\x53\x58\x97\x93\x23\x84\x62\x64\x33\x83\x27\x95"+ , "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"+ , "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"+ , ""+ , "\x27\xa7\x47\x9b\xef\xa1\xd4\x76\x48\x9f\x30\x8c\xd4\xcf\xa6\xe2\xa9\x6e\x4b\xbe\x32\x08\xff\x25\x28\x7d\xd3\x81\x96\x16\xe8\x9c\xc7\x8c\xf7\xf5\xe5\x43\x44\x5f\x83\x33\xd8\xfa\x7f\x56\x00\x00\x05\x27\x9f\xa5\xd8\xb5\xe4\xad\x40\xe7\x36\xdd\xb4\xd3\x54\x12\x32\x80\x63\xfd\x2a\xab\x53\xe5\xea\x1e\x0a\x9f\x33\x25\x00\xa5\xdf\x94\x87\xd0\x7a\x5c\x92\xcc\x51\x2c\x88\x66\xc7\xe8\x60\xce\x93\xfd\xf1\x66\xa2\x49\x12\xb4\x22\x97\x61\x46\xae\x20\xce\x84\x6b\xb7\xdc\x9b\xa9\x4a\x76\x7a\xae\xf2\x0c\x0d\x61\xad\x02\x65\x5e\xa9\x2d\xc4\xc4\xe4\x1a\x89\x52\xc6\x51\xd3\x31\x74\xbe\x51\xa1\x0c\x42\x11\x10\xe6\xd8\x15\x88\xed\xe8\x21\x03\xa2\x52\xd8\xa7\x50\xe8\x76\x8d\xef\xff\xed\x91\x22\x81\x0a\xae\xb9\x9f\x91\x72\xaf\x82\xb6\x04\xdc\x4b\x8e\x51\xbc\xb0\x82\x35\xa6\xf4\x34\x13\x32\xe4\xca\x60\x48\x2a\x4b\xa1\xa0\x3b\x3e\x65\x00\x8f\xc5\xda\x76\xb7\x0b\xf1\x69\x0d\xb4\xea\xe2\x9c\x5f\x1b\xad\xd0\x3c\x5c\xcf\x2a\x55\xd7\x05\xdd\xcd\x86\xd4\x49\x51\x1c\xeb\x7e\xc3\x0b\xf1\x2b\x1f\xa3\x5b\x91\x3f\x9f\x74\x7a\x8a\xfd\x1b\x13\x0e\x94\xbf\xf9\x4e\xff\xd0\x1a\x91\x73\x5c\xa1\x72\x6a\xcd\x0b\x19\x7c\x4e\x5b\x03\x39\x36\x97\xe1\x26\x82\x6f\xb6\xbb\xde\x8e\xcc\x1e\x08\x29\x85\x16\xe2\xc9\xed\x03\xff\x3c\x1b\x78\x60\xf6\xde\x76\xd4\xce\xcd\x94\xc8\x11\x98\x55\xef\x52\x97\xca\x67\xe9\xf3\xe7\xff\x72\xb1\xe9\x97\x85\xca\x0a\x7e\x77\x20\xc5\xb3\x6d\xc6\xd7\x2c\xac\x95\x74\xc8\xcb\xbc\x2f\x80\x1e\x23\xe5\x6f\xd3\x44\xb0\x7f\x22\x15\x4b\xeb\xa0\xf0\x8c\xe8\x89\x1e\x64\x3e\xd9\x95\xc9\x4d\x9a\x69\xc9\xf1\xb5\xf4\x99\x02\x7a\x78\x57\x2a\xee\xbd\x74\xd2\x0c\xc3\x98\x81\xc2\x13\xee\x77\x0b\x10\x10\xe4\xbe\xa7\x18\x84\x69\x77\xae\x11\x9f\x7a\x02\x3a\xb5\x8c\xca\x0a\xd7\x52\xaf\xe6\x56\xbb\x3c\x17\x25\x6a\x9f\x6e\x9b\xf1\x9f\xdd\x5a\x38\xfc\x82\xbb\xe8\x72\xc5\x53\x9e\xdb\x60\x9e\xf4\xf7\x9c\x20\x3e\xbb\x14\x0f\x2e\x58\x3c\xb2\xad\x15\xb4\xaa\x5b\x65\x50\x16\xa8\x44\x92\x77\xdb\xd4\x77\xef\x2c\x8d\x6c\x01\x7d\xb7\x38\xb1\x8d\xeb\x4a\x42\x7d\x19\x23\xce\x3f\xf2\x62\x73\x57\x79\xa4\x18\xf2\x0a\x28\x2d\xf9\x20\x14\x7b\xea\xbe\x42\x1e\xe5\x31\x9d\x05\x68"+ )+ ]++vectors_aes128_dec =+ []++vectors_aes256_enc =+ [+ ( "\x27\x18\x28\x18\x28\x45\x90\x45\x23\x53\x60\x28\x74\x71\x35\x26\x62\x49\x77\x57\x24\x70\x93\x69\x99\x59\x57\x49\x66\x96\x76\x27"+ , "\x31\x41\x59\x26\x53\x58\x97\x93\x23\x84\x62\x64\x33\x83\x27\x95\x02\x88\x41\x97\x16\x93\x99\x37\x51\x05\x82\x09\x74\x94\x45\x92"+ , "\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"+ , "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"+ , ""+ , "\x1c\x3b\x3a\x10\x2f\x77\x03\x86\xe4\x83\x6c\x99\xe3\x70\xcf\x9b\xea\x00\x80\x3f\x5e\x48\x23\x57\xa4\xae\x12\xd4\x14\xa3\xe6\x3b\x5d\x31\xe2\x76\xf8\xfe\x4a\x8d\x66\xb3\x17\xf9\xac\x68\x3f\x44\x68\x0a\x86\xac\x35\xad\xfc\x33\x45\xbe\xfe\xcb\x4b\xb1\x88\xfd\x57\x76\x92\x6c\x49\xa3\x09\x5e\xb1\x08\xfd\x10\x98\xba\xec\x70\xaa\xa6\x69\x99\xa7\x2a\x82\xf2\x7d\x84\x8b\x21\xd4\xa7\x41\xb0\xc5\xcd\x4d\x5f\xff\x9d\xac\x89\xae\xba\x12\x29\x61\xd0\x3a\x75\x71\x23\xe9\x87\x0f\x8a\xcf\x10\x00\x02\x08\x87\x89\x14\x29\xca\x2a\x3e\x7a\x7d\x7d\xf7\xb1\x03\x55\x16\x5c\x8b\x9a\x6d\x0a\x7d\xe8\xb0\x62\xc4\x50\x0d\xc4\xcd\x12\x0c\x0f\x74\x18\xda\xe3\xd0\xb5\x78\x1c\x34\x80\x3f\xa7\x54\x21\xc7\x90\xdf\xe1\xde\x18\x34\xf2\x80\xd7\x66\x7b\x32\x7f\x6c\x8c\xd7\x55\x7e\x12\xac\x3a\x0f\x93\xec\x05\xc5\x2e\x04\x93\xef\x31\xa1\x2d\x3d\x92\x60\xf7\x9a\x28\x9d\x6a\x37\x9b\xc7\x0c\x50\x84\x14\x73\xd1\xa8\xcc\x81\xec\x58\x3e\x96\x45\xe0\x7b\x8d\x96\x70\x65\x5b\xa5\xbb\xcf\xec\xc6\xdc\x39\x66\x38\x0a\xd8\xfe\xcb\x17\xb6\xba\x02\x46\x9a\x02\x0a\x84\xe1\x8e\x8f\x84\x25\x20\x70\xc1\x3e\x9f\x1f\x28\x9b\xe5\x4f\xbc\x48\x14\x57\x77\x8f\x61\x60\x15\xe1\x32\x7a\x02\xb1\x40\xf1\x50\x5e\xb3\x09\x32\x6d\x68\x37\x8f\x83\x74\x59\x5c\x84\x9d\x84\xf4\xc3\x33\xec\x44\x23\x88\x51\x43\xcb\x47\xbd\x71\xc5\xed\xae\x9b\xe6\x9a\x2f\xfe\xce\xb1\xbe\xc9\xde\x24\x4f\xbe\x15\x99\x2b\x11\xb7\x7c\x04\x0f\x12\xbd\x8f\x6a\x97\x5a\x44\xa0\xf9\x0c\x29\xa9\xab\xc3\xd4\xd8\x93\x92\x72\x84\xc5\x87\x54\xcc\xe2\x94\x52\x9f\x86\x14\xdc\xd2\xab\xa9\x91\x92\x5f\xed\xc4\xae\x74\xff\xac\x6e\x33\x3b\x93\xeb\x4a\xff\x04\x79\xda\x9a\x41\x0e\x44\x50\xe0\xdd\x7a\xe4\xc6\xe2\x91\x09\x00\x57\x5d\xa4\x01\xfc\x07\x05\x9f\x64\x5e\x8b\x7e\x9b\xfd\xef\x33\x94\x30\x54\xff\x84\x01\x14\x93\xc2\x7b\x34\x29\xea\xed\xb4\xed\x53\x76\x44\x1a\x77\xed\x43\x85\x1a\xd7\x7f\x16\xf5\x41\xdf\xd2\x69\xd5\x0d\x6a\x5f\x14\xfb\x0a\xab\x1c\xbb\x4c\x15\x50\xbe\x97\xf7\xab\x40\x66\x19\x3c\x4c\xaa\x77\x3d\xad\x38\x01\x4b\xd2\x09\x2f\xa7\x55\xc8\x24\xbb\x5e\x54\xc4\xf3\x6f\xfd\xa9\xfc\xea\x70\xb9\xc6\xe6\x93\xe1\x48\xc1\x51"+ )+ ]++vectors_aes256_dec = []++vectors_encrypt =+ [ ("AES 128 Enc", vectors_aes128_enc)+ , ("AES 256 Enc", vectors_aes256_enc)+ ]++vectors_decrypt =+ [ ("AES 128 Dec", vectors_aes128_dec)+ , ("AES 256 Dec", vectors_aes256_dec)+ ]
+ Tests/Tests.hs view
@@ -0,0 +1,138 @@+{-# LANGUAGE ViewPatterns #-}+module Main where++import Control.Applicative+import Control.Monad++import Test.Framework (Test, defaultMain, testGroup)+import Test.Framework.Providers.QuickCheck2 (testProperty)++import Test.QuickCheck+import Test.QuickCheck.Test+import Test.Framework.Providers.QuickCheck2 (testProperty)++import qualified Data.ByteString as B+import qualified Crypto.Cipher.AES as AES++import qualified KATECB+import qualified KATCBC+import qualified KATXTS+import qualified KATGCM++encryptBlock initF encryptF key plaintext =+ B.unpack $ encryptF (initF (B.pack key)) plaintext++katECBTests vectors f = concatMap makeTests vectors+ where makeTests (name, v) = map (\(z,i) -> testProperty (name ++ " " ++ show i) $ makeTest z) $ zip v [0..]+ where makeTest (AES.initKey -> key,plaintext,expected) = assertEq expected $ f key plaintext++katCBCTests vectors f = concatMap makeTests vectors+ where makeTests (name, v) = map (\(z,i) -> testProperty (name ++ " " ++ show i) $ makeTest z) $ zip v [0..]+ where makeTest (AES.initKey -> key,AES.IV -> iv,plaintext,expected) = assertEq expected $ f key iv plaintext++katXTSTests vectors f = concatMap makeTests vectors+ where makeTests (name, v) = map (\(z,i) -> testProperty (name ++ " " ++ show i) $ makeTest z) $ zip v [0..]+ where makeTest (AES.initKey -> key1,AES.initKey -> key2, AES.IV -> iv,plaintext,_,expected) =+ (assertEq expected $ f (key1,key2) iv 0 plaintext)++katGCMTests vectors f = concatMap makeTests vectors+ where makeTests (name, v) = map (\(z,i) -> testProperty (name ++ " " ++ show i) $ makeTest z) $ zip v [0..]+ where makeTest (AES.initKey -> key, AES.IV -> iv, aad, plaintext, expectedOutput, taglen, expectedTag) =+ let (output,tag) = f key iv aad plaintext in+ assertEq expectedOutput output && (assertEq tag expectedTag)+++data ECBUnit = ECBUnit B.ByteString B.ByteString+ deriving (Show,Eq)+data CBCUnit = CBCUnit B.ByteString B.ByteString B.ByteString+ deriving (Show,Eq)+data CTRUnit = CTRUnit B.ByteString B.ByteString B.ByteString+ deriving (Show,Eq)+data XTSUnit = XTSUnit B.ByteString B.ByteString B.ByteString B.ByteString+ deriving (Show,Eq)+data GCMUnit = GCMUnit B.ByteString B.ByteString B.ByteString B.ByteString+ deriving (Show,Eq)++generateKeyOf size = B.pack <$> replicateM size arbitrary+generateKey = elements [16,24,32] >>= generateKeyOf++generateIv = B.pack <$> replicateM 16 arbitrary+generateIvGCM = choose (12,90) >>= \sz -> (B.pack <$> replicateM sz arbitrary)++generatePlaintextMultiple16 = choose (1,128) >>= \size -> replicateM (size*16) arbitrary >>= return . B.pack++generatePlaintext = choose (0,324) >>= \size -> replicateM size arbitrary >>= return . B.pack++instance Arbitrary ECBUnit where+ arbitrary = ECBUnit <$> generateKey+ <*> generatePlaintextMultiple16++instance Arbitrary CBCUnit where+ arbitrary = CBCUnit <$> generateKey+ <*> generateIv+ <*> generatePlaintextMultiple16++instance Arbitrary CTRUnit where+ arbitrary = CTRUnit <$> generateKey+ <*> generateIv+ <*> generatePlaintext++instance Arbitrary GCMUnit where+ arbitrary = GCMUnit <$> generateKey+ <*> generateIvGCM+ <*> generatePlaintext+ <*> generatePlaintext++instance Arbitrary XTSUnit where+ arbitrary = do+ size <- elements [16,32]+ XTSUnit <$> generateKeyOf size+ <*> generateKeyOf size+ <*> generateIv+ <*> generatePlaintextMultiple16++idECBTests (ECBUnit (AES.initKey -> key) plaintext) =+ plaintext `assertEq` AES.decryptECB key (AES.encryptECB key plaintext)++idCBCTests (CBCUnit (AES.initKey -> key) (AES.IV -> iv) plaintext) =+ plaintext `assertEq` AES.decryptCBC key iv (AES.encryptCBC key iv plaintext)++idCTRTests (CTRUnit (AES.initKey -> key) (AES.IV -> iv) plaintext) =+ plaintext `assertEq` AES.decryptCTR key iv (AES.encryptCTR key iv plaintext)++idXTSTests (XTSUnit (AES.initKey -> key1) (AES.initKey -> key2) (AES.IV -> iv) plaintext) =+ plaintext `assertEq` AES.decryptXTS (key1, key2) iv 0 (AES.encryptXTS (key1, key2) iv 0 plaintext)++idGCMTests (GCMUnit (AES.initKey -> key) (AES.IV -> iv) aad plaintext) =+ let (cipherText, tag) = AES.encryptGCM key iv aad plaintext in+ let (plaintext2, tag2) = AES.decryptGCM key iv aad cipherText in+ (plaintext `assertEq` plaintext2) && (tag == tag2)++assertEq expected got+ | expected == got = True+ | otherwise = error ("expected: " ++ showhex expected ++ " got: " ++ showhex got)+ where showhex = concatMap toHex . B.unpack+ toHex b = let (l,r) = b `divMod` 16 in map (toHexChar . fromIntegral) [l,r]+ toHexChar c+ | c >= 0 && c <= 9 = toEnum (c + fromEnum '0')+ | c >= 10 && c <= 16 = toEnum (c + fromEnum 'a')+ | otherwise = '_'++tests =+ [ testGroup "KAT-ECB-Encrypt" $ katECBTests KATECB.vectors_encrypt AES.encryptECB+ , testGroup "KAT-ECB-Decrypt" $ katECBTests KATECB.vectors_decrypt AES.decryptECB+ , testGroup "KAT-CBC-Encrypt" $ katCBCTests KATCBC.vectors_encrypt AES.encryptCBC+ , testGroup "KAT-CBC-Decrypt" $ katCBCTests KATCBC.vectors_decrypt AES.decryptCBC+ , testGroup "KAT-XTS-Encrypt" $ katXTSTests KATXTS.vectors_encrypt AES.encryptXTS+ , testGroup "KAT-XTS-Decrypt" $ katXTSTests KATXTS.vectors_decrypt AES.decryptXTS+ , testGroup "KAT-GCM-Encrypt" $ katGCMTests KATGCM.vectors_encrypt AES.encryptGCM+ , testGroup "decrypt-encrypt-is-ID"+ [ testProperty "ECB" idECBTests+ , testProperty "CBC" idCBCTests+ , testProperty "CTR" idCTRTests+ , testProperty "XTS" idXTSTests+ , testProperty "GCM" idGCMTests+ ]+ ]++main = defaultMain tests
+ cbits/aes.c view
@@ -0,0 +1,383 @@+/*+ * 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 aes_encrypt_block(aes_block *output, aes_key *key, aes_block *input)+{+#ifdef ARCH_X86+ if (have_aesni() && key->nbr == 10)+ return aes_ni_encrypt_ecb((uint8_t *) output, key, (uint8_t *) input, 1);+#endif+ aes_generic_encrypt_block(output, key, input);+}++void aes_decrypt_block(aes_block *output, aes_key *key, aes_block *input)+{+#ifdef ARCH_X86+ if (have_aesni() && key->nbr == 10)+ return aes_ni_decrypt_ecb((uint8_t *) output, key, (uint8_t *) input, 1);+#endif+ aes_generic_decrypt_block(output, key, input);+}++void aes_initkey(aes_key *key, uint8_t *origkey, uint8_t size)+{+ switch (size) {+ case 16: key->nbr = 10; break;+ case 24: key->nbr = 12; break;+ case 32: key->nbr = 14; break;+ }+#ifdef ARCH_X86+ if (have_aesni() && size == 16)+ return aes_ni_init(key, origkey, size);+#endif+ aes_generic_init(key, origkey, size);+}++void aes_encrypt_ecb(uint8_t *output, aes_key *key, uint8_t *input, uint32_t nb_blocks)+{+ if (!nb_blocks)+ return;++#ifdef ARCH_X86+ if (have_aesni() && key->nbr == 10)+ return aes_ni_encrypt_ecb(output, key, input, nb_blocks);+#endif++ for ( ; nb_blocks-- > 0; input += 16, output += 16) {+ aes_encrypt_block((block128 *) output, key, (block128 *) input);+ }+}++void aes_decrypt_ecb(uint8_t *output, aes_key *key, uint8_t *input, uint32_t nb_blocks)+{+ if (!nb_blocks)+ return;++#ifdef ARCH_X86+ if (have_aesni() && key->nbr == 10)+ return aes_ni_decrypt_ecb(output, key, input, nb_blocks);+#endif++ for ( ; nb_blocks-- > 0; input += 16, output += 16) {+ aes_decrypt_block((block128 *) output, key, (block128 *) input);+ }+}++void aes_encrypt_cbc(uint8_t *output, aes_key *key, aes_block *iv, uint8_t *input, uint32_t nb_blocks)+{+ aes_block block;++ if (!nb_blocks)+ return;+#ifdef ARCH_X86+ if (have_aesni() && key->nbr == 10)+ return aes_ni_encrypt_cbc(output, key, (uint8_t *) iv, input, nb_blocks);+#endif++ /* preload IV in block */+ block128_copy(&block, iv);++ for ( ; nb_blocks-- > 0; input += 16, output += 16) {+ block128_xor(&block, (block128 *) input);++ aes_encrypt_block(&block, key, &block);++ block128_copy((block128 *) output, &block);+ }+}++void aes_decrypt_cbc(uint8_t *output, aes_key *key, aes_block *ivini, uint8_t *input, uint32_t nb_blocks)+{+ aes_block block,blocko;+ aes_block iv;++ if (!nb_blocks)+ return;+#ifdef ARCH_X86+ if (have_aesni() && key->nbr == 10) {+ return aes_ni_decrypt_cbc(output, key, (uint8_t *) ivini, input, nb_blocks);+ }+#endif++ /* preload IV in block */+ block128_copy(&iv, ivini);++ aes_decrypt_block(&block, key, &block);++ for ( ;nb_blocks-- > 0; input += 16, output += 16) {+ block128_copy(&block, (block128 *) input);++ aes_decrypt_block(&blocko, key, &block);++ block128_vxor((block128 *) output, &blocko, &iv);+ block128_copy(&iv, &block);+ }+}++void aes_gen_ctr(uint8_t *output, aes_key *key, aes_block *iv, uint32_t nb_blocks)+{+ aes_block block;++ if (!nb_blocks)+ return;+ /* preload IV in block */+ block128_copy(&block, iv);++ for ( ; nb_blocks-- > 0; output += 16, block128_inc_be(&block)) {+ aes_encrypt_block((block128 *) output, key, &block);+ }+}++void aes_encrypt_ctr(uint8_t *output, aes_key *key, aes_block *iv, 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 += 1;+ input += 1;+ }+ }+}++void aes_encrypt_xts(uint8_t *output, aes_key *k1, aes_key *k2, aes_block *dataunit,+ uint32_t spoint, uint8_t *input, uint32_t nb_blocks)+{+ aes_block block, tweak;++ if (!nb_blocks)+ return;++#ifdef ARCH_X86+ if (have_aesni() && k1->nbr == 10) {+ aes_ni_encrypt_xts(output, k1, k2, (uint8_t *) dataunit, spoint, input, nb_blocks);+ return;+ }+#endif++ /* 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 += 16, output += 16, gf_mulx(&tweak)) {+ block128_vxor(&block, (block128 *) input, &tweak);+ aes_encrypt_block(&block, k1, &block);+ block128_vxor((block128 *) output, &block, &tweak);+ }+}++void aes_decrypt_xts(uint8_t *output, aes_key *k1, aes_key *k2, aes_block *dataunit,+ uint32_t spoint, uint8_t *input, uint32_t nb_blocks)+{+ aes_block block, tweak;++ if (!nb_blocks)+ return;++ /* 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 += 16, output += 16, gf_mulx(&tweak)) {+ block128_vxor(&block, (block128 *) input, &tweak);+ aes_decrypt_block(&block, k1, &block);+ block128_vxor((block128 *) output, &block, &tweak);+ }+}++static void gcm_ghash_add(aes_gcm *gcm, block128 *b)+{+ block128_xor(&gcm->tag, b);+ gf_mul(&gcm->tag, &gcm->h);+}++void aes_gcm_init(aes_gcm *gcm, aes_key *key, uint8_t *iv, uint32_t len)+{+ gcm->length_aad = 0;+ gcm->length_input = 0;++ block128_zero(&gcm->h);+ block128_zero(&gcm->tag);+ block128_zero(&gcm->iv);++ memcpy(&gcm->key, key, sizeof(aes_key));++ /* prepare H : encrypt_K(0^128) */+ aes_encrypt_block(&gcm->h, key, &gcm->h);++ if (len == 12) {+ block128_copy_bytes(&gcm->iv, iv, 12);+ gcm->iv.b[15] = 0x01;+ } else {+ uint32_t origlen = len << 3;+ int i;+ for (; len >= 16; len -= 16, iv += 16) {+ block128_xor(&gcm->iv, (block128 *) iv);+ gf_mul(&gcm->iv, &gcm->h);+ }+ if (len > 0) {+ block128_xor_bytes(&gcm->iv, iv, len);+ gf_mul(&gcm->iv, &gcm->h);+ }+ for (i = 15; origlen; --i, origlen >>= 8)+ gcm->iv.b[i] ^= (uint8_t) origlen;+ gf_mul(&gcm->iv, &gcm->h);+ }++ block128_copy(&gcm->civ, &gcm->iv);+}++void aes_gcm_aad(aes_gcm *gcm, uint8_t *input, uint32_t length)+{+ gcm->length_aad += length;+ for (; length >= 16; input += 16, length -= 16) {+ gcm_ghash_add(gcm, (block128 *) input);+ }+ if (length > 0) {+ aes_block tmp;+ block128_zero(&tmp);+ block128_copy_bytes(&tmp, input, length);+ gcm_ghash_add(gcm, &tmp);+ }++}++void aes_gcm_encrypt(uint8_t *output, aes_gcm *gcm, uint8_t *input, uint32_t length)+{+ aes_block out;++ gcm->length_input += length;+ for (; length >= 16; input += 16, output += 16, length -= 16) {+ block128_inc_be(&gcm->civ);++ aes_encrypt_block(&out, &gcm->key, &gcm->civ);+ block128_xor(&out, (block128 *) input);+ gcm_ghash_add(gcm, &out);+ block128_copy((block128 *) output, &out);+ }+ if (length > 0) {+ aes_block tmp;+ int i;++ block128_inc_be(&gcm->civ);+ /* create e(civ) in out */+ aes_encrypt_block(&out, &gcm->key, &gcm->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, &tmp);++ for (i = 0; i < length; i++) {+ output[i] = tmp.b[i];+ }+ }+}++void aes_gcm_decrypt(uint8_t *output, aes_gcm *gcm, uint8_t *input, uint32_t length)+{+ aes_block out;++ gcm->length_input += length;+ for (; length >= 16; input += 16, output += 16, length -= 16) {+ block128_inc_be(&gcm->civ);++ aes_encrypt_block(&out, &gcm->key, &gcm->civ);+ gcm_ghash_add(gcm, (block128 *) input);+ block128_xor(&out, (block128 *) input);+ block128_copy((block128 *) output, &out);+ }+ if (length > 0) {+ aes_block tmp;+ int i;++ block128_inc_be(&gcm->civ);++ block128_zero(&tmp);+ block128_copy_bytes(&tmp, input, length);+ gcm_ghash_add(gcm, &tmp);++ aes_encrypt_block(&out, &gcm->key, &gcm->civ);+ block128_xor_bytes(&tmp, out.b, length); ++ for (i = 0; i < length; i++) {+ output[i] = tmp.b[i];+ }+ }+}++void aes_gcm_finish(uint8_t *tag, aes_gcm *gcm)+{+ aes_block lblock;+ int i;++ /* tag = (tag-1 xor (lenbits(a) | lenbits(c)) ) . H */+ lblock.q[0] = cpu_to_be64(gcm->length_aad << 3);+ lblock.q[1] = cpu_to_be64(gcm->length_input << 3);+ gcm_ghash_add(gcm, &lblock);++ aes_encrypt_block(&lblock, &gcm->key, &gcm->iv);+ block128_xor(&gcm->tag, &lblock);++ for (i = 0; i < 16; i++) {+ tag[i] = gcm->tag.b[i];+ }+}
+ cbits/aes.h view
@@ -0,0 +1,81 @@+/*+ * 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;++typedef struct {+ uint8_t nbr; /* number of rounds: 10 (128), 12 (192), 14 (256) */+ uint8_t _padding[7];+ uint8_t data[16*14*2];+} aes_key;++/* size = 4*16+2*8+aes_key=456 = 536 */+typedef struct {+ aes_block tag;+ aes_block h;+ aes_block iv;+ aes_block civ;+ uint64_t length_aad;+ uint64_t length_input;+ aes_key key;+} aes_gcm;++/* in bytes: either 16,24,32 */+void aes_initkey(aes_key *ctx, uint8_t *key, uint8_t size);++void aes_encrypt(aes_block *output, aes_key *key, aes_block *input);+void aes_decrypt(aes_block *output, aes_key *key, aes_block *input);++void aes_encrypt_ecb(uint8_t *output, aes_key *key, uint8_t *input, uint32_t nb_blocks);+void aes_decrypt_ecb(uint8_t *output, aes_key *key, uint8_t *input, uint32_t nb_blocks);++void aes_encrypt_cbc(uint8_t *output, aes_key *key, aes_block *iv, uint8_t *input, uint32_t nb_blocks);+void aes_decrypt_cbc(uint8_t *output, aes_key *key, aes_block *iv, uint8_t *input, uint32_t nb_blocks);++void aes_gen_ctr(uint8_t *output, aes_key *key, aes_block *iv, uint32_t nb_blocks);++void aes_encrypt_xts(uint8_t *output, aes_key *key, aes_key *key2, aes_block *sector,+ uint32_t spoint, uint8_t *input, uint32_t nb_blocks);+void aes_decrypt_xts(uint8_t *output, aes_key *key, aes_key *key2, aes_block *sector,+ uint32_t spoint, uint8_t *input, uint32_t nb_blocks);++void aes_gcm_init(aes_gcm *gcm, aes_key *key, uint8_t *iv, uint32_t len);+void aes_gcm_aad(aes_gcm *gcm, uint8_t *input, uint32_t length);+void aes_gcm_encrypt(uint8_t *output, aes_gcm *gcm, uint8_t *input, uint32_t length);+void aes_gcm_finish(uint8_t *tag, aes_gcm *gcm);++#endif
+ 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 }+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 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 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 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 aes_generic_encrypt_block(aes_block *output, aes_key *key, aes_block *input);+void aes_generic_decrypt_block(aes_block *output, aes_key *key, aes_block *input);+void aes_generic_init(aes_key *key, uint8_t *origkey, uint8_t size);
+ cbits/aes_x86ni.c view
@@ -0,0 +1,270 @@+/*+ * Copyright (c) 2012 Vincent Hanquez <vincent@snarc.org>+ * + * All rights reserved.+ * + * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ * 1. Redistributions of source code must retain the above copyright+ * notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ * notice, this list of conditions and the following disclaimer in the+ * documentation and/or other materials provided with the distribution.+ * 3. Neither the name of the author nor the names of his contributors+ * may be used to endorse or promote products derived from this software+ * without specific prior written permission.+ * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF+ * SUCH DAMAGE.+ */+#include <wmmintrin.h>+#include <tmmintrin.h>+#include "aes.h"+#include "aes_x86ni.h"+#include "cpu.h"++#ifdef ARCH_X86+#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, uint8_t *ikey)+{+ __m128i k[20];+ uint64_t *out = (uint64_t *) key->data;+ int i;++ k[0] = _mm_loadu_si128((const __m128i*) ikey);++#define AES_128_key_exp(K, RCON) aes_128_key_expansion(K, _mm_aeskeygenassist_si128(K, RCON))+ k[1] = AES_128_key_exp(k[0], 0x01);+ k[2] = AES_128_key_exp(k[1], 0x02);+ k[3] = AES_128_key_exp(k[2], 0x04);+ k[4] = AES_128_key_exp(k[3], 0x08);+ k[5] = AES_128_key_exp(k[4], 0x10);+ k[6] = AES_128_key_exp(k[5], 0x20);+ k[7] = AES_128_key_exp(k[6], 0x40);+ k[8] = AES_128_key_exp(k[7], 0x80);+ k[9] = AES_128_key_exp(k[8], 0x1B);+ k[10] = AES_128_key_exp(k[9], 0x36);++ /* generate decryption keys in reverse order.+ * k[10] is shared by last encryption and first decryption rounds+ * k[20] is shared by first encryption round (and is the original user key) */+ k[11] = _mm_aesimc_si128(k[9]);+ k[12] = _mm_aesimc_si128(k[8]);+ k[13] = _mm_aesimc_si128(k[7]);+ k[14] = _mm_aesimc_si128(k[6]);+ k[15] = _mm_aesimc_si128(k[5]);+ k[16] = _mm_aesimc_si128(k[4]);+ k[17] = _mm_aesimc_si128(k[3]);+ k[18] = _mm_aesimc_si128(k[2]);+ k[19] = _mm_aesimc_si128(k[1]);++ for (i = 0; i < 20; i++)+ _mm_storeu_si128(((__m128i *) out) + i, k[i]);+}++void aes_ni_init(aes_key *key, uint8_t *origkey, uint8_t size)+{+ switch (size) {+ case 16: aes_generate_key128(key, origkey); break;+ default: break;+ }+}+++#define PRELOAD_ENC_KEYS(k) \+ __m128i K0 = _mm_loadu_si128(((__m128i *) k)+0); \+ __m128i K1 = _mm_loadu_si128(((__m128i *) k)+1); \+ __m128i K2 = _mm_loadu_si128(((__m128i *) k)+2); \+ __m128i K3 = _mm_loadu_si128(((__m128i *) k)+3); \+ __m128i K4 = _mm_loadu_si128(((__m128i *) k)+4); \+ __m128i K5 = _mm_loadu_si128(((__m128i *) k)+5); \+ __m128i K6 = _mm_loadu_si128(((__m128i *) k)+6); \+ __m128i K7 = _mm_loadu_si128(((__m128i *) k)+7); \+ __m128i K8 = _mm_loadu_si128(((__m128i *) k)+8); \+ __m128i K9 = _mm_loadu_si128(((__m128i *) k)+9); \+ __m128i K10 = _mm_loadu_si128(((__m128i *) k)+10);++#define DO_ENC_BLOCK(m) \+ m = _mm_xor_si128(m, K0); \+ m = _mm_aesenc_si128(m, K1); \+ m = _mm_aesenc_si128(m, K2); \+ m = _mm_aesenc_si128(m, K3); \+ m = _mm_aesenc_si128(m, K4); \+ m = _mm_aesenc_si128(m, K5); \+ m = _mm_aesenc_si128(m, K6); \+ m = _mm_aesenc_si128(m, K7); \+ m = _mm_aesenc_si128(m, K8); \+ m = _mm_aesenc_si128(m, K9); \+ m = _mm_aesenclast_si128(m, K10);++#define PRELOAD_DEC_KEYS(k) \+ __m128i K0 = _mm_loadu_si128(((__m128i *) k)+10+0); \+ __m128i K1 = _mm_loadu_si128(((__m128i *) k)+10+1); \+ __m128i K2 = _mm_loadu_si128(((__m128i *) k)+10+2); \+ __m128i K3 = _mm_loadu_si128(((__m128i *) k)+10+3); \+ __m128i K4 = _mm_loadu_si128(((__m128i *) k)+10+4); \+ __m128i K5 = _mm_loadu_si128(((__m128i *) k)+10+5); \+ __m128i K6 = _mm_loadu_si128(((__m128i *) k)+10+6); \+ __m128i K7 = _mm_loadu_si128(((__m128i *) k)+10+7); \+ __m128i K8 = _mm_loadu_si128(((__m128i *) k)+10+8); \+ __m128i K9 = _mm_loadu_si128(((__m128i *) k)+10+9); \+ __m128i K10 = _mm_loadu_si128(((__m128i *) k)+0);++#define DO_DEC_BLOCK(m) \+ m = _mm_xor_si128(m, K0); \+ m = _mm_aesdec_si128(m, K1); \+ m = _mm_aesdec_si128(m, K2); \+ m = _mm_aesdec_si128(m, K3); \+ m = _mm_aesdec_si128(m, K4); \+ m = _mm_aesdec_si128(m, K5); \+ m = _mm_aesdec_si128(m, K6); \+ m = _mm_aesdec_si128(m, K7); \+ m = _mm_aesdec_si128(m, K8); \+ m = _mm_aesdec_si128(m, K9); \+ m = _mm_aesdeclast_si128(m, K10);++void aes_ni_encrypt_ecb(uint8_t *out, aes_key *key, uint8_t *in, uint32_t blocks)+{+ __m128i *k = (__m128i *) key->data;++ PRELOAD_ENC_KEYS(k);++ while (blocks-- > 0) {+ __m128i m = _mm_loadu_si128((__m128i *) in);++ DO_ENC_BLOCK(m);++ _mm_storeu_si128((__m128i *) out, m);+ in += 16;+ out += 16;+ }+}++void aes_ni_decrypt_ecb(uint8_t *out, aes_key *key, uint8_t *in, uint32_t blocks)+{+ __m128i *k = (__m128i *) key->data;++ PRELOAD_DEC_KEYS(k);++ while (blocks-- > 0) {+ __m128i m = _mm_loadu_si128((__m128i *) in);++ DO_DEC_BLOCK(m);++ _mm_storeu_si128((__m128i *) out, m);+ in += 16;+ out += 16;+ }+}++void aes_ni_encrypt_cbc(uint8_t *out, aes_key *key, uint8_t *_iv, uint8_t *in, uint32_t blocks)+{+ __m128i *k = (__m128i *) key->data;+ __m128i iv = _mm_loadu_si128((__m128i *) _iv);++ PRELOAD_ENC_KEYS(k);++ while (blocks-- > 0) {+ __m128i m = _mm_loadu_si128((__m128i *) in);+ m = _mm_xor_si128(m, iv);++ DO_ENC_BLOCK(m);++ _mm_storeu_si128((__m128i *) out, m);+ iv = m;++ in += 16;+ out += 16;+ }+}++void aes_ni_decrypt_cbc(uint8_t *out, aes_key *key, uint8_t *_iv, uint8_t *in, uint32_t blocks)+{+ __m128i *k = (__m128i *) key->data;+ __m128i iv = _mm_loadu_si128((__m128i *) _iv);++ PRELOAD_DEC_KEYS(k);++ while (blocks-- > 0) {+ __m128i m = _mm_loadu_si128((__m128i *) in);+ __m128i ivnext = m;++ DO_DEC_BLOCK(m);+ m = _mm_xor_si128(m, iv);++ _mm_storeu_si128((__m128i *) out, m);+ iv = ivnext;++ in += 16;+ out += 16;+ }+}++/* TO OPTIMISE: use pcmulqdq... or some faster code.+ * this is the lamest way of doing it, but i'm out of time.+ * this is basically a copy of gf_mulx in gf.c */+static __m128i gfmulx(__m128i v)+{+ uint64_t v_[2] ALIGNMENT(16);+ const uint64_t gf_mask = 0x8000000000000000;++ _mm_store_si128((__m128i *) v_, v);+ uint64_t r = ((v_[1] & gf_mask) ? 0x87 : 0);+ v_[1] = (v_[1] << 1) | (v_[0] & gf_mask ? 1 : 0);+ v_[0] = (v_[0] << 1) ^ r;+ v = _mm_load_si128((__m128i *) v_);+ return v;+}++void aes_ni_encrypt_xts(uint8_t *out, aes_key *key1, aes_key *key2,+ uint8_t *_tweak, uint32_t spoint, uint8_t *in, uint32_t blocks)+{+ __m128i tweak = _mm_loadu_si128((__m128i *) _tweak);++ do {+ __m128i *k2 = (__m128i *) key2->data;+ PRELOAD_ENC_KEYS(k2);+ DO_ENC_BLOCK(tweak);++ while (spoint-- > 0)+ tweak = gfmulx(tweak);+ } while (0) ;++ do {+ __m128i *k1 = (__m128i *) key1->data;+ PRELOAD_ENC_KEYS(k1);++ for ( ; blocks-- > 0; in += 16, out += 16, tweak = gfmulx(tweak)) {+ __m128i m = _mm_loadu_si128((__m128i *) in);++ m = _mm_xor_si128(m, tweak);+ DO_ENC_BLOCK(m);+ m = _mm_xor_si128(m, tweak);++ _mm_storeu_si128((__m128i *) out, m);+ }+ } while (0);+}++#endif
+ cbits/aes_x86ni.h view
@@ -0,0 +1,52 @@+/*+ * 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.h"++void aes_ni_init(aes_key *key, uint8_t *origkey, uint8_t size);+void aes_ni_encrypt_ecb(uint8_t *out, aes_key *key, uint8_t *in, uint32_t blocks);+void aes_ni_decrypt_ecb(uint8_t *out, aes_key *key, uint8_t *in, uint32_t blocks);+void aes_ni_encrypt_cbc(uint8_t *out, aes_key *key, uint8_t *_iv, uint8_t *in, uint32_t blocks);+void aes_ni_decrypt_cbc(uint8_t *out, aes_key *key, uint8_t *_iv, uint8_t *in, uint32_t blocks);+void aes_ni_encrypt_xts(uint8_t *out, aes_key *key1, aes_key *key2,+ uint8_t *_tweak, uint32_t spoint, uint8_t *in, uint32_t blocks);++void gf_mul_x86ni(block128 *res, block128 *a_, block128 *b_);++#endif++#endif
+ cbits/bitfn.h view
@@ -0,0 +1,232 @@+/*+ * Copyright (C) 2006-2009 Vincent Hanquez <vincent@snarc.org>+ *+ * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ * 1. Redistributions of source code must retain the above copyright+ * notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ * notice, this list of conditions and the following disclaimer in the+ * documentation and/or other materials provided with the distribution.+ *+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+ */++#ifndef BITFN_H+#define BITFN_H+#include <stdint.h>++#ifndef NO_INLINE_ASM+/**********************************************************/+# if (defined(__i386__))+# define ARCH_HAS_SWAP32+static inline uint32_t bitfn_swap32(uint32_t a)+{+ asm ("bswap %0" : "=r" (a) : "0" (a));+ return a;+}+/**********************************************************/+# elif (defined(__arm__))+# define ARCH_HAS_SWAP32+static inline uint32_t bitfn_swap32(uint32_t a)+{+ uint32_t tmp = a;+ asm volatile ("eor %1, %0, %0, ror #16\n"+ "bic %1, %1, #0xff0000\n"+ "mov %0, %0, ror #8\n"+ "eor %0, %0, %1, lsr #8\n"+ : "=r" (a), "=r" (tmp) : "0" (a), "1" (tmp));+ return a;+}+/**********************************************************/+# elif defined(__x86_64__)+# define ARCH_HAS_SWAP32+# define ARCH_HAS_SWAP64+static inline uint32_t bitfn_swap32(uint32_t a)+{+ asm ("bswap %0" : "=r" (a) : "0" (a));+ return a;+}++static inline uint64_t bitfn_swap64(uint64_t a)+{+ asm ("bswap %0" : "=r" (a) : "0" (a));+ return a;+}++# endif+#endif /* NO_INLINE_ASM */+/**********************************************************/++#ifndef ARCH_HAS_ROL32+static inline uint32_t rol32(uint32_t word, uint32_t shift)+{+ return (word << shift) | (word >> (32 - shift));+}+#endif++#ifndef ARCH_HAS_ROR32+static inline uint32_t ror32(uint32_t word, uint32_t shift)+{+ return (word >> shift) | (word << (32 - shift));+}+#endif++#ifndef ARCH_HAS_ROL64+static inline uint64_t rol64(uint64_t word, uint32_t shift)+{+ return (word << shift) | (word >> (64 - shift));+}+#endif++#ifndef ARCH_HAS_ROR64+static inline uint64_t ror64(uint64_t word, uint32_t shift)+{+ return (word >> shift) | (word << (64 - shift));+}+#endif++#ifndef ARCH_HAS_SWAP32+static inline uint32_t bitfn_swap32(uint32_t a)+{+ return (a << 24) | ((a & 0xff00) << 8) | ((a >> 8) & 0xff00) | (a >> 24);+}+#endif++#ifndef ARCH_HAS_ARRAY_SWAP32+static inline void array_swap32(uint32_t *d, uint32_t *s, uint32_t nb)+{+ while (nb--)+ *d++ = bitfn_swap32(*s++);+}+#endif++#ifndef ARCH_HAS_SWAP64+static inline uint64_t bitfn_swap64(uint64_t a)+{+ return ((uint64_t) bitfn_swap32((uint32_t) (a >> 32))) |+ (((uint64_t) bitfn_swap32((uint32_t) a)) << 32);+}+#endif++#ifndef ARCH_HAS_ARRAY_SWAP64+static inline void array_swap64(uint64_t *d, uint64_t *s, uint32_t nb)+{+ while (nb--)+ *d++ = bitfn_swap64(*s++);+}+#endif++#ifndef ARCH_HAS_MEMORY_ZERO+static inline void memory_zero(void *ptr, uint32_t len)+{+ uint32_t *ptr32 = ptr;+ uint8_t *ptr8;+ int i;++ for (i = 0; i < len / 4; i++)+ *ptr32++ = 0;+ if (len % 4) {+ ptr8 = (uint8_t *) ptr32;+ for (i = len % 4; i >= 0; i--)+ ptr8[i] = 0;+ }+}+#endif++#ifndef ARCH_HAS_ARRAY_COPY32+static inline void array_copy32(uint32_t *d, uint32_t *s, uint32_t nb)+{+ while (nb--) *d++ = *s++;+}+#endif++#ifndef ARCH_HAS_ARRAY_COPY64+static inline void array_copy64(uint64_t *d, uint64_t *s, uint32_t nb)+{+ while (nb--) *d++ = *s++;+}+#endif++#ifdef __MINGW32__+ # define LITTLE_ENDIAN 1234+ # define BYTE_ORDER LITTLE_ENDIAN+#elif defined(__FreeBSD__) || defined(__DragonFly__)+ # include <sys/endian.h>+#elif defined(__OpenBSD__) || defined(__SVR4)+ # include <sys/types.h>+#elif defined(__APPLE__)+ # include <machine/endian.h>+#elif defined( BSD ) && ( BSD >= 199103 )+ # include <machine/endian.h>+#else+ # include <endian.h>+#endif+/* big endian to cpu */+#if LITTLE_ENDIAN == BYTE_ORDER++# define be32_to_cpu(a) bitfn_swap32(a)+# define cpu_to_be32(a) bitfn_swap32(a)+# define le32_to_cpu(a) (a)+# define cpu_to_le32(a) (a)+# define be64_to_cpu(a) bitfn_swap64(a)+# define cpu_to_be64(a) bitfn_swap64(a)+# define le64_to_cpu(a) (a)+# define cpu_to_le64(a) (a)++# define cpu_to_le32_array(d, s, l) array_copy32(d, s, l)+# define le32_to_cpu_array(d, s, l) array_copy32(d, s, l)+# define cpu_to_be32_array(d, s, l) array_swap32(d, s, l)+# define be32_to_cpu_array(d, s, l) array_swap32(d, s, l)++# define cpu_to_le64_array(d, s, l) array_copy64(d, s, l)+# define le64_to_cpu_array(d, s, l) array_copy64(d, s, l)+# define cpu_to_be64_array(d, s, l) array_swap64(d, s, l)+# define be64_to_cpu_array(d, s, l) array_swap64(d, s, l)++# define ror32_be(a, s) rol32(a, s)+# define rol32_be(a, s) ror32(a, s)++# define ARCH_IS_LITTLE_ENDIAN++#elif BIG_ENDIAN == BYTE_ORDER++# define be32_to_cpu(a) (a)+# define cpu_to_be32(a) (a)+# define be64_to_cpu(a) (a)+# define cpu_to_be64(a) (a)+# define le64_to_cpu(a) bitfn_swap64(a)+# define cpu_to_le64(a) bitfn_swap64(a)+# define le32_to_cpu(a) bitfn_swap32(a)+# define cpu_to_le32(a) bitfn_swap32(a)++# define cpu_to_le32_array(d, s, l) array_swap32(d, s, l)+# define le32_to_cpu_array(d, s, l) array_swap32(d, s, l)+# define cpu_to_be32_array(d, s, l) array_copy32(d, s, l)+# define be32_to_cpu_array(d, s, l) array_copy32(d, s, l)++# define cpu_to_le64_array(d, s, l) array_swap64(d, s, l)+# define le64_to_cpu_array(d, s, l) array_swap64(d, s, l)+# define cpu_to_be64_array(d, s, l) array_copy64(d, s, l)+# define be64_to_cpu_array(d, s, l) array_copy64(d, s, l)++# define ror32_be(a, s) ror32(a, s)+# define rol32_be(a, s) rol32(a, s)++# define ARCH_IS_BIG_ENDIAN++#else+# error "endian not supported"+#endif++#endif /* !BITFN_H */
+ cbits/block128.h view
@@ -0,0 +1,87 @@+/*+ * Copyright (c) 2012 Vincent Hanquez <vincent@snarc.org>+ * + * All rights reserved.+ * + * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ * 1. Redistributions of source code must retain the above copyright+ * notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ * notice, this list of conditions and the following disclaimer in the+ * documentation and/or other materials provided with the distribution.+ * 3. Neither the name of the author nor the names of his contributors+ * may be used to endorse or promote products derived from this software+ * without specific prior written permission.+ * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF+ * SUCH DAMAGE.+ */++#ifndef BLOCK128_H+#define BLOCK128_H++#include "bitfn.h"++typedef union {+ uint64_t q[2];+ uint32_t d[4];+ uint16_t w[8];+ uint8_t b[16];+} block128;++static inline void block128_copy_bytes(block128 *block, uint8_t *src, uint32_t len)+{+ int i;+ for (i = 0; i < len; i++) block->b[i] = src[i];+}++static inline void block128_copy(block128 *d, block128 *s)+{+ d->q[0] = s->q[0]; d->q[1] = s->q[1];+}++static inline void block128_zero(block128 *d)+{+ d->q[0] = 0; d->q[1] = 0;+}++static inline void block128_xor(block128 *d, block128 *s)+{+ d->q[0] ^= s->q[0];+ d->q[1] ^= s->q[1];+}++static inline void block128_vxor(block128 *d, block128 *s1, block128 *s2)+{+ d->q[0] = s1->q[0] ^ s2->q[0];+ d->q[1] = s1->q[1] ^ s2->q[1];+}++static inline void block128_xor_bytes(block128 *block, uint8_t *src, uint32_t len)+{+ int i;+ for (i = 0; i < len; i++) block->b[i] ^= src[i];+}++static inline void block128_inc_be(block128 *b)+{+ uint64_t v = be64_to_cpu(b->q[1]);+ if (++v == 0) {+ b->q[0] = cpu_to_be64(be64_to_cpu(b->q[0]) + 1);+ b->q[1] = 0;+ } else+ b->q[1] = cpu_to_be64(v);+}++#endif
+ cbits/cpu.c view
@@ -0,0 +1,71 @@+/*+ * 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+int have_aesni(void)+{+ static int v = -1;+ if (v == -1) {+ uint32_t eax, ebx, ecx, edx;+ cpuid(1, &eax, &ebx, &ecx, &edx);+ v = (ecx & 0x02000000);+ }+ return v;+}+#else+#define have_aesni() (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+int have_aesni(void);+#else+#define have_aesni() (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, 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 = 0x8000000000000000ULL;+ uint64_t r = ((a->q[1] & gf_mask) ? 0x87 : 0);+ a->q[1] = (a->q[1] << 1) | (a->q[0] & gf_mask ? 1 : 0);+ a->q[0] = (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, block128 *b); +void gf_mulx(block128 *a); + +#endif
+ cipher-aes.cabal view
@@ -0,0 +1,74 @@+Name: cipher-aes+Version: 0.1.0+Description: Fast AES cipher implementation with advanced mode of operations+License: BSD3+License-file: LICENSE+Copyright: Vincent Hanquez <vincent@snarc.org>+Author: Vincent Hanquez <vincent@snarc.org>+Maintainer: Vincent Hanquez <vincent@snarc.org>+Synopsis: Fast AES cipher implementation with advanced mode of operations+Category: Cryptography+Build-Type: Simple+Homepage: http://github.com/vincenthz/hs-cipher-aes+Cabal-Version: >=1.8+Extra-Source-Files: Tests/*.hs+ cbits/*.h++Flag benchmark+ Description: Build benchmarks+ Default: False++Library+ Build-Depends: base >= 4 && < 5+ , bytestring+ , ghc-prim+ , primitive+ , crypto-api >= 0.5+ , tagged+ , cereal+ Exposed-modules: Crypto.Cipher.AES+ ghc-options: -Wall+ C-sources: cbits/aes_generic.c+ cbits/aes.c+ cbits/gf.c+ cbits/aes_x86ni.c+ cbits/cpu.c+ if arch(i386) || arch(x86_64)+ CC-options: -mssse3 -maes -mpclmul++Test-Suite test-cipher-aes+ type: exitcode-stdio-1.0+ hs-source-dirs: Tests+ Main-Is: Tests.hs+ Build-depends: base >= 4 && < 5+ , crypto-api >= 0.5+ , cipher-aes+ , bytestring+ , QuickCheck >= 2+ , test-framework >= 0.3.3 && < 0.7+ , test-framework-quickcheck2 >= 0.2.9 && < 0.3++Executable Benchmarks+ hs-source-dirs: Benchmarks+ Main-Is: Benchmarks.hs+ if flag(benchmark)+ Buildable: True+ Build-depends: base >= 4 && < 5+ , bytestring+ , crypto-api+ , cipher-aes+ , criterion+ , mtl+ else+ Buildable: False+ C-sources: cbits/aes_generic.c+ cbits/aes.c+ cbits/gf.c+ cbits/aes_x86ni.c+ cbits/cpu.c+ if arch(i386) || arch(x86_64)+ CC-options: -mssse3 -maes -mpclmul++source-repository head+ type: git+ location: git://github.com/vincenthz/hs-cipher-aes