packages feed

clientsession 0.6.0 → 0.7.0

raw patch · 5 files changed

+67/−724 lines, 5 filesdep +base64-bytestringdep +crypto-apidep +cryptocipherdep −randomdep −template-haskelldep −test-frameworkPVP ok

version bump matches the API change (PVP)

Dependencies added: base64-bytestring, crypto-api, cryptocipher, hspec

Dependencies removed: random, template-haskell, test-framework, test-framework-hunit, test-framework-quickcheck2

API changes (from Hackage documentation)

- Web.ClientSession: embedDefaultKey :: Q Exp
- Web.ClientSession: embedKey :: FilePath -> Q Exp
- Web.ClientSession: type Key = ByteString
+ Web.ClientSession: data IV
+ Web.ClientSession: data Key :: *
+ Web.ClientSession: encryptIO :: Key -> ByteString -> IO ByteString
+ Web.ClientSession: instance Show IV
+ Web.ClientSession: mkIV :: ByteString -> Maybe IV
+ Web.ClientSession: randomIV :: IO IV
- Web.ClientSession: decrypt :: ByteString -> ByteString -> Maybe ByteString
+ Web.ClientSession: decrypt :: Key -> ByteString -> Maybe ByteString
- Web.ClientSession: encrypt :: ByteString -> ByteString -> ByteString
+ Web.ClientSession: encrypt :: Key -> IV -> ByteString -> ByteString

Files

Web/ClientSession.hs view
@@ -17,32 +17,35 @@ module Web.ClientSession     ( -- * Automatic key generation       Key+    , IV+    , randomIV+    , mkIV     , getKey-    , embedKey     , defaultKeyFile     , getDefaultKey-    , embedDefaultKey       -- * Actual encryption/decryption     , encrypt+    , encryptIO     , decrypt     ) where -import System.Directory+import System.Directory (doesFileExist) import qualified Data.ByteString as S-import qualified Data.ByteString.Char8 as B--import System.Random+import qualified Crypto.Cipher.AES as A+import Crypto.Cipher.AES (Key)+import qualified Data.ByteString.Base64 as B+import Crypto.Random (newGenIO, genBytes, SystemRandom) -import Data.ByteString.Unsafe+newtype IV = IV S.ByteString+    deriving Show -import Foreign.C-import Foreign.Ptr-import Foreign.Marshal.Alloc-import Foreign.Storable-import System.IO.Unsafe-import Language.Haskell.TH+mkIV :: S.ByteString -> Maybe IV+mkIV bs+    | S.length bs == 16 = Just $ IV bs+    | otherwise = Nothing -type Key = S.ByteString+randomIV :: IO IV+randomIV = fmap IV $ randomBytes 16  -- | The default key file. defaultKeyFile :: String@@ -52,10 +55,6 @@ getDefaultKey :: IO Key getDefaultKey = getKey defaultKeyFile --- | Simply calls 'embedKey' 'defaultKeyFile'.-embedDefaultKey :: Q Exp-embedDefaultKey = embedKey defaultKeyFile- -- | Get a key from the given text file. -- -- If the file does not exist a random key will be generated and stored in that@@ -65,81 +64,53 @@ getKey keyFile = do     exists <- doesFileExist keyFile     if exists-        then do-            key <- S.readFile keyFile-            if S.length key < minKeyLength-                then newKey-                else return key+        then S.readFile keyFile >>= either (const newKey) return . A.initKey256         else newKey   where     newKey = do-        key' <- randomKey-        S.writeFile keyFile key'+        (bs, key') <- randomKey+        S.writeFile keyFile bs         return key' --- | Embed a key from the given text file into haskell source.------ Eliminates overhead of reading key file with each request.-embedKey :: FilePath -> Q Exp-embedKey keyFile = do-  k <- runIO $ getKey keyFile-  let cs = B.unpack k-  [| B.pack |] `appE` (litE $ stringL cs)--minKeyLength :: Int-minKeyLength = 16+randomBytes :: Int -> IO S.ByteString+randomBytes len = do+    g <- newGenIO+    either (error . show) (return . fst) $ genBytes len (g :: SystemRandom) -randomKey :: IO Key+randomKey :: IO (S.ByteString, Key) randomKey = do-    g <- newStdGen-    let (nums, _) =-            foldr-                (\_ (n, g') -> let (n', g'') = next g' in (n' : n, g''))-                ([], g)-                [1..minKeyLength]-    return $ S.pack $ map fromIntegral nums+    bs <- randomBytes 32+    case A.initKey256 bs of+        Left e -> error e -- should never happen+        Right key -> return (bs, key) -encrypt :: S.ByteString -- ^ key+encryptIO :: Key -> S.ByteString -> IO S.ByteString+encryptIO key x = do+    iv <- randomIV+    return $ encrypt key iv x++encrypt :: Key+        -> IV         -> S.ByteString -- ^ data         -> S.ByteString-encrypt keyBS dataBS = unsafePerformIO $-    unsafeUseAsCString keyBS $ \keyPtr ->-        unsafeUseAsCStringLen dataBS $ \(dataPtr, dataLen) -> do-            let keyPtr' = castPtr keyPtr-                dataPtr' = castPtr dataPtr-                dataLen' = fromIntegral dataLen-            allocaBytes 4 $ \lenp -> do-                newPtr <- c_encrypt dataLen' dataPtr' keyPtr' lenp-                let newPtr' = castPtr newPtr-                len <- peek lenp-                let len' = fromIntegral len-                unsafePackCStringFinalizer newPtr' len' $ free newPtr'+encrypt key (IV iv) x =+    B.encode $ iv `S.append` A.encryptCBC key iv y+  where+    toPad = 16 - S.length x `mod` 16+    pad = S.replicate toPad $ fromIntegral toPad+    y = pad `S.append` x -decrypt :: S.ByteString -- ^ key+decrypt :: Key -- ^ key         -> S.ByteString -- ^ data         -> Maybe S.ByteString-decrypt keyBS dataBS = unsafePerformIO $-    unsafeUseAsCString keyBS $ \keyPtr ->-        unsafeUseAsCStringLen dataBS $ \(dataPtr, dataLen) -> do-            let keyPtr' = castPtr keyPtr-                dataPtr' = castPtr dataPtr-                dataLen' = fromIntegral dataLen-            allocaBytes 4 $ \lenp -> do-                newPtr <- c_decrypt dataLen' dataPtr' keyPtr' lenp-                if newPtr == nullPtr-                    then return Nothing-                    else do-                        let newPtr' = castPtr newPtr-                        len <- peek lenp-                        let len' = fromIntegral len-                        bs <- unsafePackCStringFinalizer newPtr' len'-                            $ free newPtr'-                        return $ Just bs--foreign import ccall unsafe "encrypt"-    c_encrypt :: CUInt -> Ptr CUChar -> Ptr CUChar -> Ptr CUInt-              -> IO (Ptr CChar)--foreign import ccall unsafe "decrypt"-    c_decrypt :: CUInt -> Ptr CChar -> Ptr CUChar -> Ptr CUInt-              -> IO (Ptr CUChar)+decrypt key dataBS64 = do+    dataBS <- either (const Nothing) Just $ B.decode dataBS64+    if S.length dataBS `mod` 16 /= 0 || S.length dataBS < 16+        then Nothing+        else do+            let (iv, encrypted) = S.splitAt 16 dataBS+            let x = A.decryptCBC key iv encrypted+            (td, _) <- S.uncons x+            if td > 0 && td <= 16+                then Just $ S.drop (fromIntegral td) x+                else Nothing
− c/aestable.c
@@ -1,400 +0,0 @@-// advanced encryption standard
-// author: karl malbrain, malbrain@yahoo.com
-/*
-This work, including the source code, documentation
-and related data, is placed into the public domain.
-
-The orginal author is Karl Malbrain.
-
-THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY
-OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF
-MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE,
-ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE
-RESULTING FROM THE USE, MODIFICATION, OR
-REDISTRIBUTION OF THIS SOFTWARE.
-*/
-
-typedef unsigned char uchar;
-#include <string.h>
-#include <memory.h>
-
-// AES only supports Nb=4
-#define Nb 4			// number of columns in the state & expanded key
-
-#define Nk 4			// number of columns in a key
-#define Nr 10			// number of rounds in encryption
-
-uchar Sbox[256] = {		// forward s-box
-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};
-
-uchar InvSbox[256] = {	// inverse s-box
-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};
-
-// combined Xtimes2[Sbox[]]
-uchar Xtime2Sbox[256] = {
-0xc6, 0xf8, 0xee, 0xf6, 0xff, 0xd6, 0xde, 0x91, 0x60, 0x02, 0xce, 0x56, 0xe7, 0xb5, 0x4d, 0xec, 
-0x8f, 0x1f, 0x89, 0xfa, 0xef, 0xb2, 0x8e, 0xfb, 0x41, 0xb3, 0x5f, 0x45, 0x23, 0x53, 0xe4, 0x9b, 
-0x75, 0xe1, 0x3d, 0x4c, 0x6c, 0x7e, 0xf5, 0x83, 0x68, 0x51, 0xd1, 0xf9, 0xe2, 0xab, 0x62, 0x2a, 
-0x08, 0x95, 0x46, 0x9d, 0x30, 0x37, 0x0a, 0x2f, 0x0e, 0x24, 0x1b, 0xdf, 0xcd, 0x4e, 0x7f, 0xea, 
-0x12, 0x1d, 0x58, 0x34, 0x36, 0xdc, 0xb4, 0x5b, 0xa4, 0x76, 0xb7, 0x7d, 0x52, 0xdd, 0x5e, 0x13, 
-0xa6, 0xb9, 0x00, 0xc1, 0x40, 0xe3, 0x79, 0xb6, 0xd4, 0x8d, 0x67, 0x72, 0x94, 0x98, 0xb0, 0x85, 
-0xbb, 0xc5, 0x4f, 0xed, 0x86, 0x9a, 0x66, 0x11, 0x8a, 0xe9, 0x04, 0xfe, 0xa0, 0x78, 0x25, 0x4b, 
-0xa2, 0x5d, 0x80, 0x05, 0x3f, 0x21, 0x70, 0xf1, 0x63, 0x77, 0xaf, 0x42, 0x20, 0xe5, 0xfd, 0xbf, 
-0x81, 0x18, 0x26, 0xc3, 0xbe, 0x35, 0x88, 0x2e, 0x93, 0x55, 0xfc, 0x7a, 0xc8, 0xba, 0x32, 0xe6, 
-0xc0, 0x19, 0x9e, 0xa3, 0x44, 0x54, 0x3b, 0x0b, 0x8c, 0xc7, 0x6b, 0x28, 0xa7, 0xbc, 0x16, 0xad, 
-0xdb, 0x64, 0x74, 0x14, 0x92, 0x0c, 0x48, 0xb8, 0x9f, 0xbd, 0x43, 0xc4, 0x39, 0x31, 0xd3, 0xf2, 
-0xd5, 0x8b, 0x6e, 0xda, 0x01, 0xb1, 0x9c, 0x49, 0xd8, 0xac, 0xf3, 0xcf, 0xca, 0xf4, 0x47, 0x10, 
-0x6f, 0xf0, 0x4a, 0x5c, 0x38, 0x57, 0x73, 0x97, 0xcb, 0xa1, 0xe8, 0x3e, 0x96, 0x61, 0x0d, 0x0f, 
-0xe0, 0x7c, 0x71, 0xcc, 0x90, 0x06, 0xf7, 0x1c, 0xc2, 0x6a, 0xae, 0x69, 0x17, 0x99, 0x3a, 0x27, 
-0xd9, 0xeb, 0x2b, 0x22, 0xd2, 0xa9, 0x07, 0x33, 0x2d, 0x3c, 0x15, 0xc9, 0x87, 0xaa, 0x50, 0xa5, 
-0x03, 0x59, 0x09, 0x1a, 0x65, 0xd7, 0x84, 0xd0, 0x82, 0x29, 0x5a, 0x1e, 0x7b, 0xa8, 0x6d, 0x2c 
-};
-
-// combined Xtimes3[Sbox[]]
-uchar Xtime3Sbox[256] = {
-0xa5, 0x84, 0x99, 0x8d, 0x0d, 0xbd, 0xb1, 0x54, 0x50, 0x03, 0xa9, 0x7d, 0x19, 0x62, 0xe6, 0x9a, 
-0x45, 0x9d, 0x40, 0x87, 0x15, 0xeb, 0xc9, 0x0b, 0xec, 0x67, 0xfd, 0xea, 0xbf, 0xf7, 0x96, 0x5b, 
-0xc2, 0x1c, 0xae, 0x6a, 0x5a, 0x41, 0x02, 0x4f, 0x5c, 0xf4, 0x34, 0x08, 0x93, 0x73, 0x53, 0x3f, 
-0x0c, 0x52, 0x65, 0x5e, 0x28, 0xa1, 0x0f, 0xb5, 0x09, 0x36, 0x9b, 0x3d, 0x26, 0x69, 0xcd, 0x9f, 
-0x1b, 0x9e, 0x74, 0x2e, 0x2d, 0xb2, 0xee, 0xfb, 0xf6, 0x4d, 0x61, 0xce, 0x7b, 0x3e, 0x71, 0x97, 
-0xf5, 0x68, 0x00, 0x2c, 0x60, 0x1f, 0xc8, 0xed, 0xbe, 0x46, 0xd9, 0x4b, 0xde, 0xd4, 0xe8, 0x4a, 
-0x6b, 0x2a, 0xe5, 0x16, 0xc5, 0xd7, 0x55, 0x94, 0xcf, 0x10, 0x06, 0x81, 0xf0, 0x44, 0xba, 0xe3, 
-0xf3, 0xfe, 0xc0, 0x8a, 0xad, 0xbc, 0x48, 0x04, 0xdf, 0xc1, 0x75, 0x63, 0x30, 0x1a, 0x0e, 0x6d, 
-0x4c, 0x14, 0x35, 0x2f, 0xe1, 0xa2, 0xcc, 0x39, 0x57, 0xf2, 0x82, 0x47, 0xac, 0xe7, 0x2b, 0x95, 
-0xa0, 0x98, 0xd1, 0x7f, 0x66, 0x7e, 0xab, 0x83, 0xca, 0x29, 0xd3, 0x3c, 0x79, 0xe2, 0x1d, 0x76, 
-0x3b, 0x56, 0x4e, 0x1e, 0xdb, 0x0a, 0x6c, 0xe4, 0x5d, 0x6e, 0xef, 0xa6, 0xa8, 0xa4, 0x37, 0x8b, 
-0x32, 0x43, 0x59, 0xb7, 0x8c, 0x64, 0xd2, 0xe0, 0xb4, 0xfa, 0x07, 0x25, 0xaf, 0x8e, 0xe9, 0x18, 
-0xd5, 0x88, 0x6f, 0x72, 0x24, 0xf1, 0xc7, 0x51, 0x23, 0x7c, 0x9c, 0x21, 0xdd, 0xdc, 0x86, 0x85, 
-0x90, 0x42, 0xc4, 0xaa, 0xd8, 0x05, 0x01, 0x12, 0xa3, 0x5f, 0xf9, 0xd0, 0x91, 0x58, 0x27, 0xb9, 
-0x38, 0x13, 0xb3, 0x33, 0xbb, 0x70, 0x89, 0xa7, 0xb6, 0x22, 0x92, 0x20, 0x49, 0xff, 0x78, 0x7a, 
-0x8f, 0xf8, 0x80, 0x17, 0xda, 0x31, 0xc6, 0xb8, 0xc3, 0xb0, 0x77, 0x11, 0xcb, 0xfc, 0xd6, 0x3a 
-};
-
-// modular multiplication tables
-// based on:
-
-// Xtime2[x] = (x & 0x80 ? 0x1b : 0) ^ (x + x)
-// Xtime3[x] = x^Xtime2[x];
-
-uchar Xtime2[256] = {
-0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, 
-0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, 
-0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e, 
-0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e, 
-0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e, 
-0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe, 
-0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, 
-0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe, 
-0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05, 
-0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25, 
-0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45, 
-0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65, 
-0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85, 
-0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5, 
-0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5, 
-0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5}; 
-
-uchar Xtime9[256] = {
-0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77, 
-0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf, 0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7, 
-0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04, 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c, 
-0xab, 0xa2, 0xb9, 0xb0, 0x8f, 0x86, 0x9d, 0x94, 0xe3, 0xea, 0xf1, 0xf8, 0xc7, 0xce, 0xd5, 0xdc, 
-0x76, 0x7f, 0x64, 0x6d, 0x52, 0x5b, 0x40, 0x49, 0x3e, 0x37, 0x2c, 0x25, 0x1a, 0x13, 0x08, 0x01, 
-0xe6, 0xef, 0xf4, 0xfd, 0xc2, 0xcb, 0xd0, 0xd9, 0xae, 0xa7, 0xbc, 0xb5, 0x8a, 0x83, 0x98, 0x91, 
-0x4d, 0x44, 0x5f, 0x56, 0x69, 0x60, 0x7b, 0x72, 0x05, 0x0c, 0x17, 0x1e, 0x21, 0x28, 0x33, 0x3a, 
-0xdd, 0xd4, 0xcf, 0xc6, 0xf9, 0xf0, 0xeb, 0xe2, 0x95, 0x9c, 0x87, 0x8e, 0xb1, 0xb8, 0xa3, 0xaa, 
-0xec, 0xe5, 0xfe, 0xf7, 0xc8, 0xc1, 0xda, 0xd3, 0xa4, 0xad, 0xb6, 0xbf, 0x80, 0x89, 0x92, 0x9b, 
-0x7c, 0x75, 0x6e, 0x67, 0x58, 0x51, 0x4a, 0x43, 0x34, 0x3d, 0x26, 0x2f, 0x10, 0x19, 0x02, 0x0b, 
-0xd7, 0xde, 0xc5, 0xcc, 0xf3, 0xfa, 0xe1, 0xe8, 0x9f, 0x96, 0x8d, 0x84, 0xbb, 0xb2, 0xa9, 0xa0, 
-0x47, 0x4e, 0x55, 0x5c, 0x63, 0x6a, 0x71, 0x78, 0x0f, 0x06, 0x1d, 0x14, 0x2b, 0x22, 0x39, 0x30, 
-0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5, 0xd2, 0xdb, 0xc0, 0xc9, 0xf6, 0xff, 0xe4, 0xed, 
-0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35, 0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d, 
-0xa1, 0xa8, 0xb3, 0xba, 0x85, 0x8c, 0x97, 0x9e, 0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6, 
-0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62, 0x5d, 0x54, 0x4f, 0x46};
-
-uchar XtimeB[256] = {
-0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, 0x62, 0x69, 
-0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81, 0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9, 
-0x7b, 0x70, 0x6d, 0x66, 0x57, 0x5c, 0x41, 0x4a, 0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12, 
-0xcb, 0xc0, 0xdd, 0xd6, 0xe7, 0xec, 0xf1, 0xfa, 0x93, 0x98, 0x85, 0x8e, 0xbf, 0xb4, 0xa9, 0xa2, 
-0xf6, 0xfd, 0xe0, 0xeb, 0xda, 0xd1, 0xcc, 0xc7, 0xae, 0xa5, 0xb8, 0xb3, 0x82, 0x89, 0x94, 0x9f, 
-0x46, 0x4d, 0x50, 0x5b, 0x6a, 0x61, 0x7c, 0x77, 0x1e, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2f, 
-0x8d, 0x86, 0x9b, 0x90, 0xa1, 0xaa, 0xb7, 0xbc, 0xd5, 0xde, 0xc3, 0xc8, 0xf9, 0xf2, 0xef, 0xe4, 
-0x3d, 0x36, 0x2b, 0x20, 0x11, 0x1a, 0x07, 0x0c, 0x65, 0x6e, 0x73, 0x78, 0x49, 0x42, 0x5f, 0x54, 
-0xf7, 0xfc, 0xe1, 0xea, 0xdb, 0xd0, 0xcd, 0xc6, 0xaf, 0xa4, 0xb9, 0xb2, 0x83, 0x88, 0x95, 0x9e, 
-0x47, 0x4c, 0x51, 0x5a, 0x6b, 0x60, 0x7d, 0x76, 0x1f, 0x14, 0x09, 0x02, 0x33, 0x38, 0x25, 0x2e, 
-0x8c, 0x87, 0x9a, 0x91, 0xa0, 0xab, 0xb6, 0xbd, 0xd4, 0xdf, 0xc2, 0xc9, 0xf8, 0xf3, 0xee, 0xe5, 
-0x3c, 0x37, 0x2a, 0x21, 0x10, 0x1b, 0x06, 0x0d, 0x64, 0x6f, 0x72, 0x79, 0x48, 0x43, 0x5e, 0x55, 
-0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30, 0x59, 0x52, 0x4f, 0x44, 0x75, 0x7e, 0x63, 0x68, 
-0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80, 0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8, 
-0x7a, 0x71, 0x6c, 0x67, 0x56, 0x5d, 0x40, 0x4b, 0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13, 
-0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f, 0xbe, 0xb5, 0xa8, 0xa3}; 
-
-uchar XtimeD[256] = {
-0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f, 0x5c, 0x51, 0x46, 0x4b, 
-0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3, 0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b, 
-0xbb, 0xb6, 0xa1, 0xac, 0x8f, 0x82, 0x95, 0x98, 0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0, 
-0x6b, 0x66, 0x71, 0x7c, 0x5f, 0x52, 0x45, 0x48, 0x03, 0x0e, 0x19, 0x14, 0x37, 0x3a, 0x2d, 0x20, 
-0x6d, 0x60, 0x77, 0x7a, 0x59, 0x54, 0x43, 0x4e, 0x05, 0x08, 0x1f, 0x12, 0x31, 0x3c, 0x2b, 0x26, 
-0xbd, 0xb0, 0xa7, 0xaa, 0x89, 0x84, 0x93, 0x9e, 0xd5, 0xd8, 0xcf, 0xc2, 0xe1, 0xec, 0xfb, 0xf6, 
-0xd6, 0xdb, 0xcc, 0xc1, 0xe2, 0xef, 0xf8, 0xf5, 0xbe, 0xb3, 0xa4, 0xa9, 0x8a, 0x87, 0x90, 0x9d, 
-0x06, 0x0b, 0x1c, 0x11, 0x32, 0x3f, 0x28, 0x25, 0x6e, 0x63, 0x74, 0x79, 0x5a, 0x57, 0x40, 0x4d, 
-0xda, 0xd7, 0xc0, 0xcd, 0xee, 0xe3, 0xf4, 0xf9, 0xb2, 0xbf, 0xa8, 0xa5, 0x86, 0x8b, 0x9c, 0x91, 
-0x0a, 0x07, 0x10, 0x1d, 0x3e, 0x33, 0x24, 0x29, 0x62, 0x6f, 0x78, 0x75, 0x56, 0x5b, 0x4c, 0x41, 
-0x61, 0x6c, 0x7b, 0x76, 0x55, 0x58, 0x4f, 0x42, 0x09, 0x04, 0x13, 0x1e, 0x3d, 0x30, 0x27, 0x2a, 
-0xb1, 0xbc, 0xab, 0xa6, 0x85, 0x88, 0x9f, 0x92, 0xd9, 0xd4, 0xc3, 0xce, 0xed, 0xe0, 0xf7, 0xfa, 
-0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94, 0xdf, 0xd2, 0xc5, 0xc8, 0xeb, 0xe6, 0xf1, 0xfc, 
-0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44, 0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c, 
-0x0c, 0x01, 0x16, 0x1b, 0x38, 0x35, 0x22, 0x2f, 0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47, 
-0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3, 0x80, 0x8d, 0x9a, 0x97}; 
-
-uchar XtimeE[256] = {
-0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a, 
-0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca, 0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba, 
-0xdb, 0xd5, 0xc7, 0xc9, 0xe3, 0xed, 0xff, 0xf1, 0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81, 
-0x3b, 0x35, 0x27, 0x29, 0x03, 0x0d, 0x1f, 0x11, 0x4b, 0x45, 0x57, 0x59, 0x73, 0x7d, 0x6f, 0x61, 
-0xad, 0xa3, 0xb1, 0xbf, 0x95, 0x9b, 0x89, 0x87, 0xdd, 0xd3, 0xc1, 0xcf, 0xe5, 0xeb, 0xf9, 0xf7, 
-0x4d, 0x43, 0x51, 0x5f, 0x75, 0x7b, 0x69, 0x67, 0x3d, 0x33, 0x21, 0x2f, 0x05, 0x0b, 0x19, 0x17, 
-0x76, 0x78, 0x6a, 0x64, 0x4e, 0x40, 0x52, 0x5c, 0x06, 0x08, 0x1a, 0x14, 0x3e, 0x30, 0x22, 0x2c, 
-0x96, 0x98, 0x8a, 0x84, 0xae, 0xa0, 0xb2, 0xbc, 0xe6, 0xe8, 0xfa, 0xf4, 0xde, 0xd0, 0xc2, 0xcc, 
-0x41, 0x4f, 0x5d, 0x53, 0x79, 0x77, 0x65, 0x6b, 0x31, 0x3f, 0x2d, 0x23, 0x09, 0x07, 0x15, 0x1b, 
-0xa1, 0xaf, 0xbd, 0xb3, 0x99, 0x97, 0x85, 0x8b, 0xd1, 0xdf, 0xcd, 0xc3, 0xe9, 0xe7, 0xf5, 0xfb, 
-0x9a, 0x94, 0x86, 0x88, 0xa2, 0xac, 0xbe, 0xb0, 0xea, 0xe4, 0xf6, 0xf8, 0xd2, 0xdc, 0xce, 0xc0, 
-0x7a, 0x74, 0x66, 0x68, 0x42, 0x4c, 0x5e, 0x50, 0x0a, 0x04, 0x16, 0x18, 0x32, 0x3c, 0x2e, 0x20, 
-0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6, 0x9c, 0x92, 0x80, 0x8e, 0xa4, 0xaa, 0xb8, 0xb6, 
-0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26, 0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56, 
-0x37, 0x39, 0x2b, 0x25, 0x0f, 0x01, 0x13, 0x1d, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d, 
-0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d}; 
-
-// exchanges columns in each of 4 rows
-// row0 - unchanged, row1- shifted left 1, 
-// row2 - shifted left 2 and row3 - shifted left 3
-void ShiftRows (uchar *state)
-{
-uchar tmp;
-
-	// just substitute row 0
-	state[0] = Sbox[state[0]], state[4] = Sbox[state[4]];
-	state[8] = Sbox[state[8]], state[12] = Sbox[state[12]];
-
-	// rotate row 1
-	tmp = Sbox[state[1]], state[1] = Sbox[state[5]];
-	state[5] = Sbox[state[9]], state[9] = Sbox[state[13]], state[13] = tmp;
-
-	// rotate row 2
-	tmp = Sbox[state[2]], state[2] = Sbox[state[10]], state[10] = tmp;
-	tmp = Sbox[state[6]], state[6] = Sbox[state[14]], state[14] = tmp;
-
-	// rotate row 3
-	tmp = Sbox[state[15]], state[15] = Sbox[state[11]];
-	state[11] = Sbox[state[7]], state[7] = Sbox[state[3]], state[3] = tmp;
-}
-
-// restores columns in each of 4 rows
-// row0 - unchanged, row1- shifted right 1, 
-// row2 - shifted right 2 and row3 - shifted right 3
-void InvShiftRows (uchar *state)
-{
-uchar tmp;
-
-	// restore row 0
-	state[0] = InvSbox[state[0]], state[4] = InvSbox[state[4]];
-	state[8] = InvSbox[state[8]], state[12] = InvSbox[state[12]];
-
-	// restore row 1
-	tmp = InvSbox[state[13]], state[13] = InvSbox[state[9]];
-	state[9] = InvSbox[state[5]], state[5] = InvSbox[state[1]], state[1] = tmp;
-
-	// restore row 2
-	tmp = InvSbox[state[2]], state[2] = InvSbox[state[10]], state[10] = tmp;
-	tmp = InvSbox[state[6]], state[6] = InvSbox[state[14]], state[14] = tmp;
-
-	// restore row 3
-	tmp = InvSbox[state[3]], state[3] = InvSbox[state[7]];
-	state[7] = InvSbox[state[11]], state[11] = InvSbox[state[15]], state[15] = tmp;
-}
-
-// recombine and mix each row in a column
-void MixSubColumns (uchar *state)
-{
-uchar tmp[4 * Nb];
-
-	// mixing column 0
-	tmp[0] = Xtime2Sbox[state[0]] ^ Xtime3Sbox[state[5]] ^ Sbox[state[10]] ^ Sbox[state[15]];
-	tmp[1] = Sbox[state[0]] ^ Xtime2Sbox[state[5]] ^ Xtime3Sbox[state[10]] ^ Sbox[state[15]];
-	tmp[2] = Sbox[state[0]] ^ Sbox[state[5]] ^ Xtime2Sbox[state[10]] ^ Xtime3Sbox[state[15]];
-	tmp[3] = Xtime3Sbox[state[0]] ^ Sbox[state[5]] ^ Sbox[state[10]] ^ Xtime2Sbox[state[15]];
-
-	// mixing column 1
-	tmp[4] = Xtime2Sbox[state[4]] ^ Xtime3Sbox[state[9]] ^ Sbox[state[14]] ^ Sbox[state[3]];
-	tmp[5] = Sbox[state[4]] ^ Xtime2Sbox[state[9]] ^ Xtime3Sbox[state[14]] ^ Sbox[state[3]];
-	tmp[6] = Sbox[state[4]] ^ Sbox[state[9]] ^ Xtime2Sbox[state[14]] ^ Xtime3Sbox[state[3]];
-	tmp[7] = Xtime3Sbox[state[4]] ^ Sbox[state[9]] ^ Sbox[state[14]] ^ Xtime2Sbox[state[3]];
-
-	// mixing column 2
-	tmp[8] = Xtime2Sbox[state[8]] ^ Xtime3Sbox[state[13]] ^ Sbox[state[2]] ^ Sbox[state[7]];
-	tmp[9] = Sbox[state[8]] ^ Xtime2Sbox[state[13]] ^ Xtime3Sbox[state[2]] ^ Sbox[state[7]];
-	tmp[10]  = Sbox[state[8]] ^ Sbox[state[13]] ^ Xtime2Sbox[state[2]] ^ Xtime3Sbox[state[7]];
-	tmp[11]  = Xtime3Sbox[state[8]] ^ Sbox[state[13]] ^ Sbox[state[2]] ^ Xtime2Sbox[state[7]];
-
-	// mixing column 3
-	tmp[12] = Xtime2Sbox[state[12]] ^ Xtime3Sbox[state[1]] ^ Sbox[state[6]] ^ Sbox[state[11]];
-	tmp[13] = Sbox[state[12]] ^ Xtime2Sbox[state[1]] ^ Xtime3Sbox[state[6]] ^ Sbox[state[11]];
-	tmp[14] = Sbox[state[12]] ^ Sbox[state[1]] ^ Xtime2Sbox[state[6]] ^ Xtime3Sbox[state[11]];
-	tmp[15] = Xtime3Sbox[state[12]] ^ Sbox[state[1]] ^ Sbox[state[6]] ^ Xtime2Sbox[state[11]];
-
-	memcpy (state, tmp, sizeof(tmp));
-}
-
-// restore and un-mix each row in a column
-void InvMixSubColumns (uchar *state)
-{
-uchar tmp[4 * Nb];
-int i;
-
-	// restore column 0
-	tmp[0] = XtimeE[state[0]] ^ XtimeB[state[1]] ^ XtimeD[state[2]] ^ Xtime9[state[3]];
-	tmp[5] = Xtime9[state[0]] ^ XtimeE[state[1]] ^ XtimeB[state[2]] ^ XtimeD[state[3]];
-	tmp[10] = XtimeD[state[0]] ^ Xtime9[state[1]] ^ XtimeE[state[2]] ^ XtimeB[state[3]];
-	tmp[15] = XtimeB[state[0]] ^ XtimeD[state[1]] ^ Xtime9[state[2]] ^ XtimeE[state[3]];
-
-	// restore column 1
-	tmp[4] = XtimeE[state[4]] ^ XtimeB[state[5]] ^ XtimeD[state[6]] ^ Xtime9[state[7]];
-	tmp[9] = Xtime9[state[4]] ^ XtimeE[state[5]] ^ XtimeB[state[6]] ^ XtimeD[state[7]];
-	tmp[14] = XtimeD[state[4]] ^ Xtime9[state[5]] ^ XtimeE[state[6]] ^ XtimeB[state[7]];
-	tmp[3] = XtimeB[state[4]] ^ XtimeD[state[5]] ^ Xtime9[state[6]] ^ XtimeE[state[7]];
-
-	// restore column 2
-	tmp[8] = XtimeE[state[8]] ^ XtimeB[state[9]] ^ XtimeD[state[10]] ^ Xtime9[state[11]];
-	tmp[13] = Xtime9[state[8]] ^ XtimeE[state[9]] ^ XtimeB[state[10]] ^ XtimeD[state[11]];
-	tmp[2]  = XtimeD[state[8]] ^ Xtime9[state[9]] ^ XtimeE[state[10]] ^ XtimeB[state[11]];
-	tmp[7]  = XtimeB[state[8]] ^ XtimeD[state[9]] ^ Xtime9[state[10]] ^ XtimeE[state[11]];
-
-	// restore column 3
-	tmp[12] = XtimeE[state[12]] ^ XtimeB[state[13]] ^ XtimeD[state[14]] ^ Xtime9[state[15]];
-	tmp[1] = Xtime9[state[12]] ^ XtimeE[state[13]] ^ XtimeB[state[14]] ^ XtimeD[state[15]];
-	tmp[6] = XtimeD[state[12]] ^ Xtime9[state[13]] ^ XtimeE[state[14]] ^ XtimeB[state[15]];
-	tmp[11] = XtimeB[state[12]] ^ XtimeD[state[13]] ^ Xtime9[state[14]] ^ XtimeE[state[15]];
-
-	for( i=0; i < 4 * Nb; i++ )
-		state[i] = InvSbox[tmp[i]];
-}
-
-// encrypt/decrypt columns of the key
-// n.b. you can replace this with
-//      byte-wise xor if you wish.
-
-void AddRoundKey (unsigned *state, unsigned *key)
-{
-int idx;
-
-	for( idx = 0; idx < 4; idx++ )
-		state[idx] ^= key[idx];
-}
-
-uchar Rcon[11] = {
-0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};
-
-// produce Nb bytes for each round
-void ExpandKey (uchar *key, uchar *expkey)
-{
-uchar tmp0, tmp1, tmp2, tmp3, tmp4;
-unsigned idx;
-
-	memcpy (expkey, key, Nk * 4);
-
-	for( idx = Nk; idx < Nb * (Nr + 1); idx++ ) {
-		tmp0 = expkey[4*idx - 4];
-		tmp1 = expkey[4*idx - 3];
-		tmp2 = expkey[4*idx - 2];
-		tmp3 = expkey[4*idx - 1];
-		if( !(idx % Nk) ) {
-			tmp4 = tmp3;
-			tmp3 = Sbox[tmp0];
-			tmp0 = Sbox[tmp1] ^ Rcon[idx/Nk];
-			tmp1 = Sbox[tmp2];
-			tmp2 = Sbox[tmp4];
-		} else if( Nk > 6 && idx % Nk == 4 ) {
-			tmp0 = Sbox[tmp0];
-			tmp1 = Sbox[tmp1];
-			tmp2 = Sbox[tmp2];
-			tmp3 = Sbox[tmp3];
-		}
-
-		expkey[4*idx+0] = expkey[4*idx - 4*Nk + 0] ^ tmp0;
-		expkey[4*idx+1] = expkey[4*idx - 4*Nk + 1] ^ tmp1;
-		expkey[4*idx+2] = expkey[4*idx - 4*Nk + 2] ^ tmp2;
-		expkey[4*idx+3] = expkey[4*idx - 4*Nk + 3] ^ tmp3;
-	}
-}
-
-// encrypt one 128 bit block
-void Encrypt (uchar *in, uchar *expkey, uchar *out)
-{
-uchar state[Nb * 4];
-unsigned round;
-
-	memcpy (state, in, Nb * 4);
-	AddRoundKey ((unsigned *)state, (unsigned *)expkey);
-
-	for( round = 1; round < Nr + 1; round++ ) {
-		if( round < Nr )
-			MixSubColumns (state);
-		else
-			ShiftRows (state);
-
-		AddRoundKey ((unsigned *)state, (unsigned *)expkey + round * Nb);
-	}
-
-	memcpy (out, state, sizeof(state));
-}
-
-void Decrypt (uchar *in, uchar *expkey, uchar *out)
-{
-uchar state[Nb * 4];
-unsigned round;
-
-	memcpy (state, in, sizeof(state));
-
-	AddRoundKey ((unsigned *)state, (unsigned *)expkey + Nr * Nb);
-	InvShiftRows(state);
-
-	for( round = Nr; round--; )
-	{
-		AddRoundKey ((unsigned *)state, (unsigned *)expkey + round * Nb);
-		if( round )
-			InvMixSubColumns (state);
-	} 
-
-	memcpy (out, state, sizeof(state));
-}
− c/helper.c
@@ -1,166 +0,0 @@-#include <stdlib.h>-#include <stdint.h>-#include <string.h>--typedef unsigned char uchar;-typedef unsigned int uint;-#define Nb 4			// number of columns in the state & expanded key-#define Nr 10			// number of rounds in encryption--void ExpandKey(uchar *key, uchar *expkey);-void Encrypt (uchar *in, uchar *expkey, uchar *out);-void Decrypt (uchar *in, uchar *expkey, uchar *out);--void get_hash(uint *out, uchar *in, uint len)-{-	uint32_t hash = 0;--	for (; len--; ++in) {-		hash = (hash >> 1) + ((hash & 1) << 31);-		hash += *in;-	}--	*out = hash;-}--/* http://base64.sourceforge.net/b64.c.  LICENCE:        Copyright (c) 2001- * Bob Trower, Trantor Standard Systems Inc. */--static const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";--void base64_enc(char *out, uchar *in, uint len)-{-	while (len) {-		uchar buffin[3];-		buffin[0] = *(in++);-		if (--len) {-			buffin[1] = *(in++);-			if (--len) {-				buffin[2] = *(in++);-				--len;-			} else {-				buffin[2] = 0;-			}-		} else {-			buffin[1] = 0;-			buffin[2] = 0;-		}--		*(out++) = cb64[buffin[0] >> 2];-		*(out++) = cb64[ (buffin[0] & 0x03) << 4-			       | (buffin[1] & 0xf0) >> 4];-		*(out++) = cb64[ (buffin[1] & 0x0f) << 2-			       | (buffin[2] & 0xc0) >> 6];-		*(out++) = cb64[buffin[2] & 0x3f];-	}-}--int parse_char(uchar *out, char in)-{-	if ('A' <= in && in <= 'Z') {-		*out = in - 'A';-	} else if ('a' <= in && in <= 'z') {-		*out = in - 'a' + 26;-	} else if ('0' <= in && in <= '9') {-		*out = in - '0' + 52;-	} else if (in == '+') {-		*out = 62;-	} else if (in == '/') {-		*out = 63;-	} else {-		return 0;-	}-	return 1;-}--int base64_dec(uchar *out, char *in, uint len)-{-	for (; len; in += 4, out += 3, len -= 4) {-		uchar tmp[4];-		int i = 0;-		for (i = 0; i < 4; ++i) {-			if (! parse_char(tmp + i, in[i])) return 0;-		}-		out[0] = tmp[0] << 2 | tmp[1] >> 4;-		out[1] = tmp[1] << 4 | tmp[2] >> 2;-		out[2] = ((tmp[2] << 6) & 0xc0) | tmp[3];-	}-	return 1;-}--char * encrypt(uint32_t len, uchar *in, uchar *key, uint *outlen)-{-	uchar expkey[4 * Nb * (Nr + 1)];-	uchar *out;-	uint i;-	uint totlen, encoded_len;-	uchar *tmp;-	uchar buff[16];--	/* 4 bytes for the hash, 4 bytes for the length, then the string.-	 * Need to align to 16 bytes.-	 */-	totlen = len + 8;-	totlen += (- totlen) % 16;-	tmp = alloca(totlen);-	bzero(tmp, totlen);-	get_hash((uint*) tmp, in, len);-	memcpy(tmp + 4, &len, 4);-	memcpy(tmp + 8, in, len);--	ExpandKey(key, expkey);-	for (i = 0; i < totlen; i += 16) {-		Encrypt(tmp + i, expkey, buff);--		memcpy(tmp + i, buff, 16);-	}--	encoded_len = ((totlen + 2) / 3) * 4;-	out = malloc(encoded_len + 1);-	out[encoded_len] = 0;-	base64_enc(out, tmp, totlen);--	*outlen = encoded_len;-	return out;-}--uchar * decrypt(uint len, char *in, uchar *key, uint *out_len)-{-	uchar expkey[4 * Nb * (Nr + 1)];-	uchar *out;-	uint i;-	uchar buff[16];-	uint outlen;-	uint hash, orig_hash;-	uint32_t orig_len;--	if (! len % 4) return 0;-	outlen = len / 4 * 3;-	out = alloca(outlen + (- outlen) % 16);--	if (! base64_dec(out, in, len)) {-		return 0;-	}--	ExpandKey(key, expkey);--	for (i = 0; i < outlen; i += 16) {-		Decrypt(out + i, expkey, buff);-		memcpy(out + i, buff, 16);-	}--	orig_hash = *((uint*) out);-	orig_len = *((uint32_t*) (out + 4));-	if (orig_len > outlen) return 0;-	get_hash(&hash, out + 8, orig_len);-	if (orig_hash != hash) {-		return 0;-	}--	uchar *realout = malloc(orig_len + 1);-	realout[orig_len] = 0;-	memcpy(realout, out + 8, orig_len);--	*out_len = orig_len;-	return realout;-}
clientsession.cabal view
@@ -1,5 +1,5 @@ name:            clientsession-version:         0.6.0+version:         0.7.0 license:         BSD3 license-file:    LICENSE author:          Michael Snoyman <michael@snoyman.com>@@ -9,7 +9,7 @@                  Uses base64 encoding to avoid any issues with characters. category:        Web stability:       stable-cabal-version:   >= 1.6+cabal-version:   >= 1.8 build-type:      Simple homepage:        http://github.com/snoyberg/clientsession/tree/master @@ -18,29 +18,22 @@   default: False  library-    build-depends:   base >=4 && <5,-                     bytestring >= 0.9 && < 0.10,-                     directory >= 1 && < 1.2,-                     random >= 1.0.0.2 && < 1.1,-                     template-haskell+    build-depends:   base                >=4           && < 5+                   , bytestring          >= 0.9        && < 0.10+                   , directory           >= 1          && < 1.2+                   , crypto-api          >= 0.6.4      && < 0.7+                   , cryptocipher        >= 0.2.5      && < 0.3+                   , base64-bytestring   >= 0.1.0.3    && < 0.2     exposed-modules: Web.ClientSession     ghc-options:     -Wall-    c-sources:       c/aestable.c c/helper.c -executable             runtests-    if flag(test)-        Buildable: True-        cpp-options:   -DTEST-        build-depends: test-framework,-                       test-framework-quickcheck2,-                       test-framework-hunit,-                       QuickCheck >= 2 && < 3,-                       HUnit-    else-        Buildable: False+test-suite runtests+    type: exitcode-stdio-1.0+    build-depends: hspec      == 0.6.*+                 , QuickCheck >= 2 && < 3+                 , HUnit     ghc-options:     -Wall     main-is:         runtests.hs-    c-sources:       c/aestable.c c/helper.c  source-repository head   type:     git
− runtests.hs
@@ -1,55 +0,0 @@-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# OPTIONS_GHC -fno-warn-orphans #-}-import Test.Framework (defaultMain)-import Test.QuickCheck-import Test.Framework.Providers.QuickCheck2-import Test.Framework.Providers.HUnit-import Test.HUnit--import qualified Data.ByteString as S-import qualified Data.ByteString.Char8 as S8--import Web.ClientSession-import System.IO.Unsafe-import qualified Data.Ascii as A--main :: IO ()-main = defaultMain-    [ testProperty "encrypt/decrypt success" propEncDec-    , testProperty "encrypt/decrypt failure" propEncDecFailure-    , testProperty "AES encrypt/decrypt success" propAES-    , testProperty "AES encryption changes bs" propAESChanges-    , testCase "specific values" caseSpecific-    ]--propEncDec :: S.ByteString -> Bool-propEncDec bs = unsafePerformIO $ do-    key <- getDefaultKey-    let s = encrypt key bs-    let bs' = decrypt key s-    return $ Just bs == bs'--propEncDecFailure :: S.ByteString -> Bool-propEncDecFailure bs = unsafePerformIO $ do-    key <- getDefaultKey-    let s = A.toByteString $ encrypt key bs-    let bs' = decrypt key $ A.unsafeFromByteString $ (S.head s + 1) `S.cons` S.drop 1 s-    return $ Just bs /= bs'--propAES :: S.ByteString -> S.ByteString -> Bool-propAES key bs = decrypt key (encrypt key bs) == Just bs--propAESChanges :: S.ByteString -> S.ByteString -> Bool-propAESChanges key bs = A.toByteString (encrypt key bs) /= bs--caseSpecific :: Assertion-caseSpecific = do-    let s = S8.pack $ show [("lo\ENQ\143XAq","\DC2\207\226\DC1;.z56|\203\222"),("\USnu#\139\ETXB\201 ","l"),("\RS\b,zM2U\184\191F)\EOT\220S\NUL","O\\\GSd\247\246\n\EOT\SYN\182U2G"),("\219\NAK\217\CAN\252","ym\STX\188\232?\\\145"),("\239k","\vRZP\a\DC2F>"),("\FS\180P &\RS\174zSL\\?@","p\170\237vZ|\GS>\SYNk\176n\r"),("","\199D\DC3\200m)"),("6\152tVhB\246)9","\ENQdfU\SUB"),("I\ACK\181\NUL","\129\&6s\130q\US)oR1\197\FSp\US\SYN0"),("\183\200<\250","\211  \131g4\207N\155"),("\248O6k\CANK\135\234.","`\205!+&Z&9\DLE\244\214HP\SI\161"),("\"I'\ACK\149 \CAN\197","\141N\201\SO\204\\o.\128\148")]-    key <- getDefaultKey-    Just s @=? decrypt key (encrypt key s)-    let s' = S.concat $ replicate 500 s-    Just s' @=? decrypt key (encrypt key s')--instance Arbitrary S.ByteString where-    arbitrary = S.pack `fmap` arbitrary