Created
June 5, 2014 02:55
-
-
Save rnons/3d952c60549f9424feb2 to your computer and use it in GitHub Desktop.
HsOpenSSL cipher result different from OpenSSL?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Run with | |
* gcc -o cipher cipher.c -lcrypto | |
* ./cipher | |
*/ | |
#include <string.h> | |
#include <openssl/evp.h> | |
int main() | |
{ | |
EVP_CIPHER_CTX ctx; | |
EVP_CIPHER *method; | |
char out[1024]; | |
char key[] = "\x90\x01\x50\x98\x3c\xd2\x4f\xb0\xd6\x96\x3f\x7d\x28\xe1\x7f\x72"; | |
char iv[] = "\xcc\x88\xa5\x26\x85\xaf\x7f\x8d"; | |
char str[] = "abcd"; | |
int i; | |
OpenSSL_add_all_ciphers(); | |
method = EVP_get_cipherbyname("bf-cfb"); | |
EVP_CipherInit(&ctx, method, key, iv, 1); | |
EVP_CipherUpdate(&ctx, out, &i, str, strlen(str)); | |
out[i] = 0; | |
printf("%s\n", out); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Scrapped from https://github.com/phonohawk/HsOpenSSL | |
-- Run with | |
-- hsc2hs cipher.hsc | |
-- ghci cipher.hs -lcrypto -lssl | |
-- main | |
-- | |
{-# LANGUAGE OverloadedStrings #-} | |
{-# LANGUAGE CPP #-} | |
{-# LANGUAGE ForeignFunctionInterface #-} | |
#include <openssl/evp.h> | |
import Control.Applicative ((<$>)) | |
import Control.Exception (mask_) | |
import qualified Data.ByteString.Internal as B8 | |
import qualified Data.ByteString.Unsafe as B8 | |
import Data.Maybe (fromJust) | |
import Foreign.C | |
import Foreign.C.Types | |
import Foreign.ForeignPtr | |
import Foreign.Marshal.Alloc (alloca) | |
import Foreign.Ptr | |
import Foreign.Storable (Storable(..)) | |
foreign import ccall unsafe "EVP_CIPHER_CTX_init" | |
_cipher_ctx_init :: Ptr EVP_CIPHER_CTX -> IO () | |
foreign import ccall unsafe "&EVP_CIPHER_CTX_cleanup" | |
_cipher_ctx_cleanup :: FunPtr (Ptr EVP_CIPHER_CTX -> IO ()) | |
foreign import ccall unsafe "EVP_CIPHER_CTX_block_size" | |
_cipher_ctx_block_size :: Ptr EVP_CIPHER_CTX -> CInt | |
foreign import ccall unsafe "OpenSSL_add_all_ciphers" | |
addAllCiphers :: IO () | |
foreign import ccall unsafe "EVP_get_cipherbyname" | |
_get_cipherbyname :: CString -> IO (Ptr EVP_CIPHER) | |
foreign import ccall unsafe "EVP_CipherInit" | |
_CipherInit :: Ptr EVP_CIPHER_CTX -> Ptr EVP_CIPHER -> CString -> CString -> CInt -> IO CInt | |
foreign import ccall unsafe "EVP_CipherUpdate" | |
_CipherUpdate :: Ptr EVP_CIPHER_CTX -> Ptr CChar -> Ptr CInt | |
-> Ptr CChar -> CInt -> IO CInt | |
newtype Cipher = Cipher (Ptr EVP_CIPHER) | |
data EVP_CIPHER | |
newtype CipherCtx = CipherCtx (ForeignPtr EVP_CIPHER_CTX) | |
data EVP_CIPHER_CTX | |
newCipherCtx :: IO CipherCtx | |
newCipherCtx = do | |
ctx <- mallocForeignPtrBytes (#size EVP_CIPHER_CTX) | |
mask_ $ do | |
withForeignPtr ctx _cipher_ctx_init | |
addForeignPtrFinalizer _cipher_ctx_cleanup ctx | |
return $ CipherCtx ctx | |
withCipherCtxPtr :: CipherCtx -> (Ptr EVP_CIPHER_CTX -> IO a) -> IO a | |
withCipherCtxPtr (CipherCtx ctx) = withForeignPtr ctx | |
-- |@'getCipherByName' name@ returns a symmetric cipher algorithm | |
-- whose name is @name@. If no algorithms are found, the result is | |
-- @Nothing@. | |
getCipherByName :: String -> IO (Maybe Cipher) | |
getCipherByName name | |
= withCString name $ \ namePtr -> | |
do ptr <- _get_cipherbyname namePtr | |
if ptr == nullPtr then | |
return Nothing | |
else | |
return $ Just $ Cipher ptr | |
data CryptoMode = Encrypt | Decrypt | |
cryptoModeToInt :: CryptoMode -> CInt | |
cryptoModeToInt Encrypt = 1 | |
cryptoModeToInt Decrypt = 0 | |
cipherInit :: Cipher -> String -> String -> CryptoMode -> IO CipherCtx | |
cipherInit (Cipher c) key iv mode | |
= do ctx <- newCipherCtx | |
withCipherCtxPtr ctx $ \ ctxPtr -> | |
withCString key $ \ keyPtr -> | |
withCString iv $ \ ivPtr -> | |
_CipherInit ctxPtr c keyPtr ivPtr (cryptoModeToInt mode) | |
>>= failIf_ (/= 1) | |
return ctx | |
cipherUpdateBS :: CipherCtx -> B8.ByteString -> IO B8.ByteString | |
cipherUpdateBS ctx inBS = | |
withCipherCtxPtr ctx $ \ctxPtr -> | |
B8.unsafeUseAsCStringLen inBS $ \(inBuf, inLen) -> | |
let len = inLen + fromIntegral (_cipher_ctx_block_size ctxPtr) - 1 in | |
B8.createAndTrim len $ \outBuf -> | |
alloca $ \outLenPtr -> | |
_CipherUpdate ctxPtr (castPtr outBuf) outLenPtr inBuf | |
(fromIntegral inLen) | |
>>= failIf (/= 1) | |
>> fromIntegral <$> peek outLenPtr | |
failIf :: (a -> Bool) -> a -> IO a | |
failIf f a | |
| f a = error "error" | |
| otherwise = return a | |
failIf_ :: (a -> Bool) -> a -> IO () | |
failIf_ f a | |
= failIf f a >> return () | |
main :: IO () | |
main = do | |
addAllCiphers | |
method <- fmap fromJust $ getCipherByName "bf-cfb" | |
ctx <- cipherInit method "\x90\x01\x50\x98\x3c\xd2\x4f\xb0\xd6\x96\x3f\x7d\x28\xe1\x7f\x72" "\xcc\x88\xa5\x26\x85\xaf\x7f\x8d" Encrypt | |
ciphered <- cipherUpdateBS ctx "abcd" | |
print ciphered |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment