+++ /dev/null
-#ifndef __HEADERS__
-#define __HEADERS__
-#include <stdint.h>
-#include <gmp.h>
-
-uint8_t* foleo_chacha20(uint8_t[32], uint8_t[12], uint32_t, size_t);
-uint8_t* foleo_chacha20_poly1305(uint8_t[32], uint8_t[12], uint8_t*, size_t);
-uint8_t* foleo_dhke(uint8_t*, uint8_t*);
-uint16_t foleo_dhke_modsize();
-
-uint8_t* foleo_poly1305(uint8_t[32], uint8_t*, size_t);
-#define FOLEO_RSA_PADDING_NONE 99
-#define FOLEO_RSA_PADDING_ENCRYPTION 1
-#define FOLEO_RSA_PADDING_SIGNATURE 2
-#define FOLEO_RSA_PADDING_OAEP 3
-#define FOLEO_RSA_PADDING_PSS 4
-#define FOLEO_RAND_MODE_DEVR 1
-#define FOLEO_RAND_MODE_DEV 2
-#ifdef ENABLE_X86
-#define FOLEO_RAND_MODE_X86 3
-#endif
-typedef struct
-{
- mpz_t n, k;
- uint8_t* label;
- uint16_t bitWidth;
-} rsakey_t;
-void foleo_rsa_import(rsakey_t*, uint8_t*);
-uint8_t* foleo_rsa_export(rsakey_t*);
-void foleo_rsa_free(rsakey_t*);
-void foleo_rsa_keygen(uint16_t, rsakey_t*, rsakey_t*);
-
-//The maximum message block size that can be used
-// for a particular padding scheme.
-uint16_t foleo_rsa_msgsize(rsakey_t*, uint8_t);
-
-//Size of the rsakey struct
-uint16_t foleo_rsa_keysize();
-
-//Size in bytes of RSA modulus, same thing as the number
-// of bytes the encrypt() function will return
-uint16_t foleo_rsa_modsize(rsakey_t*);
-
-uint8_t* foleo_rsa_encrypt(rsakey_t*, uint8_t, uint8_t*, uint16_t);
-uint8_t* foleo_rsa_decrypt(rsakey_t*, uint8_t, uint8_t*, uint16_t*);
-uint8_t* foleo_sha256(uint8_t*, uint32_t);
-
-#define FOLEO_SHA256 1
-uint8_t* foleo_hmac(uint8_t, uint8_t*, uint32_t, uint8_t*, uint32_t);
-uint8_t* foleo_hmac_hkdf(uint8_t, uint32_t, uint8_t*, uint32_t, uint8_t*, uint32_t, uint8_t*, uint32_t);
-uint8_t* foleo_hmac_prf(uint8_t, uint32_t, uint8_t*, uint32_t, uint8_t*, uint32_t, uint8_t*, uint32_t);
-
-uint8_t foleo_hash_size(uint8_t);
-
-void foleo_rand_mode(uint8_t, uint8_t*);
-
-uint8_t* foleo_decode_base64(uint8_t*, size_t*);
-uint8_t* foleo_decode_hex(uint8_t*);
-uint8_t* foleo_encode_hex(uint8_t*, size_t);
-uint8_t* foleo_encode_base64(uint8_t*, size_t);
-
-#endif
+++ /dev/null
-module CryptoFoleo
- (
- dhke,
- chacha20,
- poly1305,
- chacha20_poly1305,
-
- rsa_keygen,
- rsa_import,
- rsa_export,
- rsa_encrypt,
- rsa_decrypt,
-
- sha256,
- hash_sha256,
- hmac,
- hmac_prf,
- hmac_hkdf,
-
- rsa_padding_none,
- rsa_padding_encryption,
- rsa_padding_signature,
- rsa_padding_oaep,
- rsa_padding_pss,
-
- rand_mode,
- rand_mode_dev,
- rand_mode_devr,
- rand_mode_x86,
-
- byteStringToHexString,
- fromNumberFixedSize
- )
-where
-import System.IO as IO
-import Foreign
-import Foreign.C.Types
-import Foreign.C.String
-import Data.ByteString as BS
-import Data.ByteString.Internal
-import Data.Word
-import Data.ByteString.Unsafe
-import Control.Monad
-import qualified Data.ByteString.Internal as BI
-import qualified Foreign.Marshal.Utils as MU
-import qualified Data.ByteString.Char8 as C8
-
-foreign import ccall unsafe "foleo_rsa_keysize"
- c_rsa_keysize :: IO (CUShort)
-
-foreign import ccall unsafe "foleo_rsa_modsize"
- c_rsa_modsize :: Ptr () -> IO (CUShort)
-
-foreign import ccall unsafe "foleo_rsa_keygen"
- c_rsa_keygen :: CUShort -> Ptr () -> Ptr () -> IO ()
-
-foreign import ccall unsafe "foleo_rsa_export"
- c_rsa_export :: Ptr () -> IO (Ptr (CUChar))
-
-foreign import ccall unsafe "foleo_rsa_import"
- c_rsa_import :: Ptr (CUChar) -> Ptr () -> IO ()
-
-foreign import ccall unsafe "foleo_rsa_free"
- c_rsa_free :: Ptr () -> IO ()
-
-foreign import ccall unsafe "foleo_rsa_encrypt"
- c_rsa_encrypt :: Ptr () -> CUChar -> Ptr (CUChar) -> CUShort -> IO (Ptr (CUChar))
-
-foreign import ccall unsafe "foleo_rsa_decrypt"
- c_rsa_decrypt :: Ptr () -> CUChar -> Ptr (CUChar) -> Ptr (CUShort) -> IO (Ptr (CUChar))
-
-foreign import ccall unsafe "foleo_dhke_modsize"
- c_dhke_modsize :: IO (CUShort)
-
-foreign import ccall unsafe "foleo_dhke"
- c_dhke :: Ptr (CUChar) -> Ptr (CUChar) -> IO (Ptr (CUChar))
-
-foreign import ccall unsafe "foleo_sha256"
- c_sha256 :: Ptr (CUChar) -> Word32 -> IO (Ptr (CUChar))
-
-foreign import ccall unsafe "foleo_hash_size"
- c_hash_size :: CUChar -> IO (CUChar)
-
-foreign import ccall unsafe "foleo_hmac"
- c_hmac :: CUChar -> Ptr (CUChar) -> Word32 -> Ptr (CUChar) -> Word32 -> IO (Ptr (CUChar))
-
-foreign import ccall unsafe "foleo_hmac_prf"
- c_hmac_prf :: CUChar -> Word32 -> Ptr (CUChar) -> Word32 -> Ptr (CUChar) -> Word32 -> Ptr (CUChar) -> Word32 -> IO (Ptr (CUChar))
-
-foreign import ccall unsafe "foleo_hmac_hkdf"
- c_hmac_hkdf :: CUChar -> Word32 -> Ptr (CUChar) -> Word32 -> Ptr (CUChar) -> Word32 -> Ptr (CUChar) -> Word32 -> IO (Ptr (CUChar))
-
-foreign import ccall unsafe "foleo_chacha20"
- c_chacha20 :: Ptr (CUChar) -> Ptr (CUChar) -> Word32 -> CSize -> IO (Ptr (CUChar))
-
-foreign import ccall unsafe "foleo_poly1305"
- c_poly1305 :: Ptr (CUChar) -> Ptr (CUChar) -> CSize -> IO (Ptr (CUChar))
-
-foreign import ccall unsafe "foleo_chacha20_poly1305"
- c_chacha20_poly1305 :: Ptr (CUChar) -> Ptr (CUChar) -> Ptr (CUChar) -> CSize -> IO (Ptr (CUChar))
-
-foreign import ccall unsafe "foleo_rand_mode"
- c_foleo_rand_mode :: CUChar -> Ptr (CUChar) -> IO ()
-
-foreign import ccall unsafe "free"
- c_free :: Ptr a -> IO ()
-
-rsa_padding_none :: Int
-rsa_padding_none = 99
-
-rsa_padding_encryption :: Int
-rsa_padding_encryption = 1
-
-rsa_padding_signature :: Int
-rsa_padding_signature = 2
-
-rsa_padding_oaep :: Int
-rsa_padding_oaep = 3
-
-rsa_padding_pss :: Int
-rsa_padding_pss = 4
-
-hash_sha256 :: Int
-hash_sha256 = 1
-
-rand_mode_devr :: Int
-rand_mode_devr = 1
-
-rand_mode_dev :: Int
-rand_mode_dev = 2
-
-rand_mode_x86 :: Int
-rand_mode_x86 = 3
-
-rsa_encrypt :: ByteString -> Int -> ByteString-> IO (ByteString)
-rsa_encrypt keyBS padType ptBS = do
- useAsCString keyBS $ \keyPtr -> do
- useAsCString ptBS $ \ptPtr -> do
- sModSize <- c_rsa_modsize (castPtr keyPtr)
- ctPtr <- c_rsa_encrypt (castPtr keyPtr) (fromIntegral padType) (castPtr ptPtr) (fromIntegral (BS.length ptBS))
- ctBS <- BI.create (fromIntegral sModSize) (\ptr -> MU.copyBytes ptr (castPtr ctPtr) (fromIntegral sModSize))
- c_free ctPtr
- return ctBS
-
-rsa_decrypt :: ByteString -> Int -> ByteString -> IO (ByteString)
-rsa_decrypt keyBS padType ctBS = do
- useAsCString keyBS $ \keyPtr -> do
- useAsCString ctBS $ \ctPtr -> do
- sModSize <- c_rsa_modsize (castPtr keyPtr)
- allocaBytes 2 $ \sizePtr -> do
- ptPtr <- c_rsa_decrypt (castPtr keyPtr) (fromIntegral padType) (castPtr ctPtr) (castPtr sizePtr)
- if ptPtr == nullPtr then do
- return BS.empty
- else do
- ptSize <- peek sizePtr
- ptBS <- BI.create ptSize (\ptr -> MU.copyBytes ptr (castPtr ptPtr) ptSize)
- c_free ptPtr
- return ptBS
-
-rsa_keygen :: Word16 -> (ByteString -> ByteString -> IO ()) -> IO ()
-rsa_keygen n fn = do
- if n >= 64 then do
- sKeySize <- c_rsa_keysize
- let keySize :: Int
- keySize = fromIntegral sKeySize
- allocaBytes keySize $ \pubKeyPtr ->
- allocaBytes keySize $ \prvKeyPtr -> do
- c_rsa_keygen (fromIntegral n) pubKeyPtr prvKeyPtr
- pubKey <- BI.create keySize (\ptr -> MU.copyBytes ptr (castPtr pubKeyPtr) keySize)
- prvKey <- BI.create keySize (\ptr -> MU.copyBytes ptr (castPtr prvKeyPtr) keySize)
- fn prvKey pubKey
- rsa_free pubKey
- rsa_free prvKey
- else return ()
-
-rsa_import :: String -> (ByteString -> IO ()) -> IO ()
-rsa_import n fn = do
- sKeySize <- c_rsa_keysize
- let keySize :: Int
- keySize = fromIntegral sKeySize
- unsafeUseAsCStringLen (C8.pack n) $ \(bsPtr, len) -> do
- allocaBytes keySize $ \keyPtr -> do
- c_rsa_import keyPtr (castPtr bsPtr)
- key <- BI.create keySize (\ptr -> MU.copyBytes ptr (castPtr keyPtr) keySize)
- fn key
- rsa_free key
-
-rsa_export :: ByteString -> IO (String)
-rsa_export keyBS = do
- useAsCString keyBS $ \keyPtr -> do
- cStrPtr <- c_rsa_export (castPtr keyPtr)
- cStr <- peekCString (castPtr cStrPtr)
- c_free cStrPtr
- return cStr
-
-rsa_free :: ByteString -> IO()
-rsa_free blob = useAsCString blob $ \ptr -> c_rsa_free (castPtr ptr)
-
-dhke :: [ByteString] -> IO (ByteString)
-dhke v = do
- c_modSize <- c_dhke_modsize
- let modSize = fromIntegral c_modSize
- if Prelude.length v == 0 then do
- secretPtr <- c_dhke nullPtr nullPtr
- bsPtr <- BI.create modSize (\ptr -> MU.copyBytes ptr (castPtr secretPtr) modSize)
- c_free secretPtr
- return bsPtr
- else if Prelude.length v == 1 && (BS.length (v !! 0)) == modSize then do
- useAsCString (v !! 0) $ \secretPtr -> do
- sharePtr <- c_dhke (castPtr secretPtr) nullPtr
- bsPtr <- BI.create modSize (\ptr -> MU.copyBytes ptr (castPtr sharePtr) modSize)
- c_free sharePtr
- return bsPtr
- else if Prelude.length v == 2 && (BS.length (v !! 0)) == modSize && (BS.length (v !! 1)) == modSize then do
- useAsCString (v !! 0) $ \secretPtr -> do
- useAsCString (v !! 1) $ \sharePtr -> do
- keyPtr <- c_dhke (castPtr secretPtr) (castPtr sharePtr)
- bsPtr <- BI.create modSize (\ptr -> MU.copyBytes ptr (castPtr keyPtr) modSize)
- c_free keyPtr
- return bsPtr
- else return BS.empty
-
-sha256 :: ByteString -> IO (ByteString)
-sha256 ptBS = do
- let ptSize :: Word32
- ptSize = fromIntegral (BS.length ptBS)
- useAsCString ptBS $ \ptPtr -> do
- hPtr <- c_sha256 (castPtr ptPtr) (fromIntegral ptSize)
- hBS <- BI.create 32 (\ptr -> MU.copyBytes ptr (castPtr hPtr) 32)
- c_free hPtr
- return hBS
-
-hmac :: Int -> ByteString -> ByteString -> IO (ByteString)
-hmac h k m = do
- useAsCString k $ \kPtr -> do
- useAsCString m $ \mPtr -> do
- rPtr <- c_hmac (fromIntegral h) (castPtr kPtr) (fromIntegral (BS.length k)) (castPtr mPtr) (fromIntegral (BS.length m))
- if rPtr == nullPtr then do
- return BS.empty
- else do
- size <- c_hash_size (fromIntegral h)
- r <- BI.create (fromIntegral size) (\ptr -> MU.copyBytes ptr (castPtr rPtr) (fromIntegral size))
- c_free rPtr
- return r
-
-hmac_prf :: Int -> Int -> ByteString -> ByteString -> ByteString -> IO (ByteString)
-hmac_prf hf db sc lb sd = do
- useAsCString sc $ \scPtr -> do
- useAsCString lb $ \lbPtr -> do
- useAsCString sd $ \sdPtr -> do
- rPtr <- c_hmac_prf (fromIntegral hf) (fromIntegral db) (castPtr scPtr) (fromIntegral (BS.length sc)) (castPtr lbPtr) (fromIntegral (BS.length lb)) (castPtr sdPtr) (fromIntegral (BS.length sd))
- if rPtr == nullPtr then do
- return BS.empty
- else do
- r <- BI.create db (\ptr -> MU.copyBytes ptr (castPtr rPtr) db)
- c_free rPtr
- return r
-
-hmac_hkdf :: Int -> Int -> ByteString -> ByteString -> ByteString -> IO (ByteString)
-hmac_hkdf hf db sc lb sd = do
- useAsCString sc $ \scPtr -> do
- useAsCString lb $ \lbPtr -> do
- useAsCString sd $ \sdPtr -> do
- rPtr <- c_hmac_hkdf (fromIntegral hf) (fromIntegral db) (castPtr scPtr) (fromIntegral (BS.length sc)) (castPtr lbPtr) (fromIntegral (BS.length lb)) (castPtr sdPtr) (fromIntegral (BS.length sd))
- if rPtr == nullPtr then do
- return BS.empty
- else do
- r <- BI.create db (\ptr -> MU.copyBytes ptr (castPtr rPtr) db)
- c_free rPtr
- return r
-
-chacha20 :: ByteString -> Integer -> Int -> Int -> IO (ByteString)
-chacha20 key nonce block count = do
- let nonceBS :: BS.ByteString
- nonceBS = fromNumberFixedSize nonce 12
- if (BS.length key) /= 32 || (BS.length nonceBS) /= 12 || block < 0 || count < 0 then
- return BS.empty
- else
- useAsCString key $ \keyPtr -> do
- useAsCString nonceBS $ \noncePtr -> do
- rPtr <- c_chacha20 (castPtr keyPtr) (castPtr noncePtr) (fromIntegral block) (fromIntegral count)
- r <- BI.create count (\ptr -> MU.copyBytes ptr (castPtr rPtr) count)
- c_free rPtr
- return r
-
-poly1305 :: ByteString -> ByteString -> IO (ByteString)
-poly1305 k m = do
- if BS.length k /= 32 then
- return BS.empty
- else
- useAsCString k $ \kPtr -> do
- useAsCString m $ \mPtr -> do
- hPtr <- c_poly1305 (castPtr kPtr) (castPtr mPtr) (fromIntegral (BS.length m))
- h <- BI.create 16 (\ptr -> MU.copyBytes ptr (castPtr hPtr) 16)
- c_free hPtr
- return h
-
-chacha20_poly1305 :: ByteString -> Integer -> ByteString -> IO (ByteString)
-chacha20_poly1305 key nonce ctext = do
- let nonceBS :: BS.ByteString
- nonceBS = fromNumberFixedSize nonce 12
- if (BS.length key) /= 32 || (BS.length nonceBS) /= 12 then
- return BS.empty
- else
- useAsCString key $ \keyPtr -> do
- useAsCString nonceBS $ \noncePtr -> do
- useAsCString ctext $ \ctextPtr -> do
- rPtr <- c_chacha20_poly1305 (castPtr keyPtr) (castPtr noncePtr) (castPtr ctextPtr) (fromIntegral (BS.length ctext))
- r <- BI.create 16 (\ptr -> MU.copyBytes ptr (castPtr rPtr) 16)
- c_free rPtr
- return r
-
-rand_mode :: Int -> String -> IO ()
-rand_mode mode info = do
- useAsCString (C8.pack info) $ \infoPtr -> do
- c_foleo_rand_mode (fromIntegral mode) (castPtr infoPtr)
-
-byteToHexString :: Word8 -> String
-byteToHexString b = do
- case (div b 16) of
- 0 -> "0"
- 1 -> "1"
- 2 -> "2"
- 3 -> "3"
- 4 -> "4"
- 5 -> "5"
- 6 -> "6"
- 7 -> "7"
- 8 -> "8"
- 9 -> "9"
- 10 -> "a"
- 11 -> "b"
- 12 -> "c"
- 13 -> "d"
- 14 -> "e"
- 15 -> "f"
- _ -> "0"
- ++
- case (mod b 16) of
- 0 -> "0"
- 1 -> "1"
- 2 -> "2"
- 3 -> "3"
- 4 -> "4"
- 5 -> "5"
- 6 -> "6"
- 7 -> "7"
- 8 -> "8"
- 9 -> "9"
- 10 -> "a"
- 11 -> "b"
- 12 -> "c"
- 13 -> "d"
- 14 -> "e"
- 15 -> "f"
- _ -> "0"
-
-byteStringToByteList :: ByteString -> [Word8]
-byteStringToByteList b = BS.unpack b
-
-byteStringToHexString :: ByteString -> String
-byteStringToHexString b = Prelude.foldr (\i s -> (byteToHexString i) ++ s) "" (byteStringToByteList b)
-
-byteStringToInteger :: ByteString -> Integer
-byteStringToInteger = foldl' (\acc byte -> acc * 256 + fromIntegral byte) 0
-
-fromNumberFixedSize :: Integer -> Int -> BS.ByteString
-fromNumberFixedSize n p = do
- if n < 0 || p < 0 then BS.empty
- else do
- let fn :: Integer -> [Word8] -> [Word8]
- fn x r = if x == 0 then r else fn (div x 256) ([fromIntegral (mod x 256)] ++ r)
- pd :: [Word8] -> [Word8]
- pd x = if (Prelude.length x) < p then pd ([0] ++ x) else x
- rt = pd (fn n [])
- BS.pack $ if (Prelude.length rt) > p then Prelude.drop ((Prelude.length rt) - p) rt else rt