{-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE EmptyDataDecls #-} module Crypto.OpenSSL.AES.Foreign where #include #include #if OPENSSL_VERSION_NUMBER > 0x10001000 #define OPENSSL_HAS_PBKDF2 #define OPENSSL_HAS_GCM #endif import Foreign.Ptr import Foreign.C.Types import Data.Word gcmTagLength :: Int gcmTagLength = 16 sizeofEVP :: Int sizeofEVP = (#const sizeof(EVP_CIPHER_CTX)) data ENGINE data EVP_CIPHER data EVP_CIPHER_CTX type KeyBuf = Ptr Word8 type IvBuf = Ptr Word8 type DataBuf = Ptr Word8 type OutputOffset = Ptr CInt type InputLength = CInt foreign import ccall unsafe "EVP_CIPHER_CTX_init" ssl_c_cipher_ctx_init :: Ptr EVP_CIPHER_CTX -> IO () foreign import ccall unsafe "&EVP_CIPHER_CTX_free" ssl_c_cipher_ctx_free :: FunPtr (Ptr EVP_CIPHER_CTX -> IO ()) foreign import ccall unsafe "&EVP_CIPHER_CTX_cleanup" ssl_c_cipher_ctx_cleanup :: FunPtr (Ptr EVP_CIPHER_CTX -> IO ()) foreign import ccall unsafe "EVP_CIPHER_CTX_ctrl" ssl_c_cipher_ctx_ctrl :: Ptr EVP_CIPHER_CTX -> CInt -> CInt -> Ptr a -> IO CInt foreign import ccall unsafe "EVP_CIPHER_CTX_set_padding" ssl_c_cipher_ctx_set_padding :: Ptr EVP_CIPHER_CTX -> CInt -> IO CInt foreign import ccall unsafe "EVP_CIPHER_CTX_set_key_length" ssl_c_cipher_ctx_set_key_length :: Ptr EVP_CIPHER_CTX -> CInt -> IO CInt foreign import ccall unsafe "EVP_EncryptInit_ex" ssl_c_encryptinit_ex :: Ptr EVP_CIPHER_CTX -> Ptr EVP_CIPHER -> Ptr ENGINE -> KeyBuf -> IvBuf -> IO CInt foreign import ccall unsafe "EVP_DecryptInit_ex" ssl_c_decryptinit_ex :: Ptr EVP_CIPHER_CTX -> Ptr EVP_CIPHER -> Ptr ENGINE -> KeyBuf -> IvBuf -> IO CInt foreign import ccall unsafe "EVP_EncryptUpdate" ssl_c_encryptupdate :: Ptr EVP_CIPHER_CTX -> DataBuf -> OutputOffset -> DataBuf -> InputLength -> IO CInt foreign import ccall unsafe "EVP_DecryptUpdate" ssl_c_decryptupdate :: Ptr EVP_CIPHER_CTX -> DataBuf -> OutputOffset -> DataBuf -> InputLength -> IO CInt foreign import ccall unsafe "EVP_EncryptFinal_ex" ssl_c_encryptfinal_ex :: Ptr EVP_CIPHER_CTX -> DataBuf -> OutputOffset -> IO CInt foreign import ccall unsafe "EVP_DecryptFinal_ex" ssl_c_decryptfinal_ex :: Ptr EVP_CIPHER_CTX -> DataBuf -> OutputOffset -> IO CInt #ifdef OPENSSL_HAS_GCM foreign import ccall unsafe "EVP_aes_256_gcm" ssl_c_aes_256_gcm :: IO (Ptr EVP_CIPHER) #else ssl_c_aes_256_gcm :: IO (Ptr EVP_CIPHER) ssl_c_aes_256_gcm = return nullPtr #endif ctrl_GCM_SET_IVLEN, ctrl_GCM_GET_TAG, ctrl_GCM_SET_TAG :: CInt #ifdef OPENSSL_HAS_GCM ctrl_GCM_SET_IVLEN = (#const EVP_CTRL_GCM_SET_IVLEN) ctrl_GCM_GET_TAG = (#const EVP_CTRL_GCM_GET_TAG) ctrl_GCM_SET_TAG = (#const EVP_CTRL_GCM_SET_TAG) #else -- not sure if this is a good idea to hardcode it. ctrl_GCM_SET_IVLEN = 0x9 ctrl_GCM_GET_TAG = 0x10 ctrl_GCM_SET_TAG = 0x11 #endif