{-# LINE 1 "lib/Crypto/G3P/BCrypt.hsc" #-}
{-# LANGUAGE CApiFFI, ViewPatterns #-}
module Crypto.G3P.BCrypt
( bcryptRaw
, bcryptRaw_maxInputLength
, bcryptRaw_outputLength
) where
import Data.ByteString(ByteString)
import qualified Data.ByteString as B
import qualified Data.ByteString.Unsafe as B
import Data.Word
import Foreign.C.String
import System.IO.Unsafe
foreign import capi "bcrypt_raw.h bcrypt_raw" c_bcrypt_raw :: CString -> Word32 -> CString -> Word32 -> CString -> Word32 -> IO ()
bcryptRaw_maxInputLength :: Int
bcryptRaw_maxInputLength :: Int
bcryptRaw_maxInputLength = (Int
72)
{-# LINE 57 "lib/Crypto/G3P/BCrypt.hsc" #-}
bcryptRaw_outputLength :: Int
bcryptRaw_outputLength :: Int
bcryptRaw_outputLength = (Int
24)
{-# LINE 62 "lib/Crypto/G3P/BCrypt.hsc" #-}
bcryptRaw :: ByteString -> ByteString -> Word32 -> ByteString
bcryptRaw :: ByteString -> ByteString -> Word32 -> ByteString
bcryptRaw (ByteString -> ByteString
f -> ByteString
key) (ByteString -> ByteString
f -> ByteString
salt) Word32
rounds
= IO ByteString -> ByteString
forall a. IO a -> a
unsafePerformIO (IO ByteString -> ByteString) -> IO ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ do
ByteString -> (CString -> IO ByteString) -> IO ByteString
forall a. ByteString -> (CString -> IO a) -> IO a
B.unsafeUseAsCString ByteString
key ((CString -> IO ByteString) -> IO ByteString)
-> (CString -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \CString
keyPtr -> do
ByteString -> (CString -> IO ByteString) -> IO ByteString
forall a. ByteString -> (CString -> IO a) -> IO a
B.unsafeUseAsCString ByteString
salt ((CString -> IO ByteString) -> IO ByteString)
-> (CString -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \CString
saltPtr -> do
let output :: ByteString
output = Int -> Word8 -> ByteString
B.replicate Int
bcryptRaw_outputLength (CString
saltPtr CString -> Word8 -> Word8
forall a b. a -> b -> b
`seq` Word8
0)
ByteString -> (CString -> IO ByteString) -> IO ByteString
forall a. ByteString -> (CString -> IO a) -> IO a
B.unsafeUseAsCString ByteString
output ((CString -> IO ByteString) -> IO ByteString)
-> (CString -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \CString
outPtr -> do
CString
-> Word32 -> CString -> Word32 -> CString -> Word32 -> IO ()
c_bcrypt_raw CString
keyPtr (ByteString -> Word32
forall {b}. Num b => ByteString -> b
len ByteString
key) CString
saltPtr (ByteString -> Word32
forall {b}. Num b => ByteString -> b
len ByteString
salt) CString
outPtr Word32
rounds
ByteString -> IO ByteString
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ByteString
output
where
len :: ByteString -> b
len ByteString
x = Int -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
bcryptRaw_maxInputLength (ByteString -> Int
B.length ByteString
x))
f :: ByteString -> ByteString
f :: ByteString -> ByteString
f ByteString
key = if ByteString -> Bool
B.null ByteString
key then Int -> Word8 -> ByteString
B.replicate Int
bcryptRaw_maxInputLength Word8
0 else ByteString
key