1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
|
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE CApiFFI #-}
-- | PRNG services
-- See <http://www.openssl.org/docs/crypto/rand.html>
-- For random Integer generation, see "OpenSSL.BN"
module OpenSSL.Random
( -- * Random byte generation
randBytes
, prandBytes
, add
) where
import Foreign
import Foreign.C.Types
import qualified Data.ByteString as BS
import OpenSSL.Utils
foreign import capi unsafe "openssl/rand.h RAND_bytes"
_RAND_bytes :: Ptr CChar -> CInt -> IO CInt
foreign import capi unsafe "openssl/rand.h RAND_pseudo_bytes"
_RAND_pseudo_bytes :: Ptr CChar -> CInt -> IO ()
foreign import capi unsafe "openssl/rand.h RAND_add"
_RAND_add :: Ptr CChar -> CInt -> CInt -> IO ()
-- | Return a bytestring consisting of the given number of strongly random
-- bytes
randBytes :: Int -- ^ the number of bytes requested
-> IO BS.ByteString
randBytes n =
allocaArray n $ \bufPtr ->
do _RAND_bytes bufPtr (fromIntegral n) >>= failIf_ (/= 1)
BS.packCStringLen (bufPtr, n)
-- | Return a bytestring consisting of the given number of pseudo random
-- bytes
prandBytes :: Int -- ^ the number of bytes requested
-> IO BS.ByteString
prandBytes n =
allocaArray n $ \bufPtr ->
do _RAND_pseudo_bytes bufPtr (fromIntegral n)
BS.packCStringLen (bufPtr, n)
-- | Add data to the entropy pool. It's safe to add sensitive information
-- (e.g. user passwords etc) to the pool. Also, adding data with an entropy
-- of 0 can never hurt.
add :: BS.ByteString -- ^ random data to be added to the pool
-> Int -- ^ the number of bits of entropy in the first argument
-> IO ()
add bs entropy =
BS.useAsCStringLen bs $ \(ptr, len) ->
_RAND_add ptr (fromIntegral len) (fromIntegral entropy)
|