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 +54/−83
- c/aestable.c +0/−400
- c/helper.c +0/−166
- clientsession.cabal +13/−20
- runtests.hs +0/−55
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