@@ -16,9 +16,8 @@ module System.Entropy
16 , closeHandle
16 , closeHandle
19−import Control.Monad (liftM)
19+import Control.Monad (liftM, when)
20import Data.ByteString as B
20import Data.ByteString as B
21−import Data.ByteString.Lazy as L
22import System.IO (openFile, hClose, IOMode(..), Handle, withBinaryFile)
21import System.IO (openFile, hClose, IOMode(..), Handle, withBinaryFile)
24#if defined(isWindows)
23#if defined(isWindows)
@@ -114,6 +113,12 @@ hGetEntropy :: CryptHandle -> Int -> IO B.ByteString
114hGetEntropy (CH h) = cryptGenRandom h
113hGetEntropy (CH h) = cryptGenRandom h
116+{- Not windows, assuming nix with a /dev/urandom -}
117+import Foreign.C.Types
119+import Data.ByteString.Internal as B
117source = "/dev/urandom"
122source = "/dev/urandom"
119-- |Handle for manual resource mangement
124-- |Handle for manual resource mangement
@@ -131,6 +136,17 @@ closeHandle (CH h) = hClose h
131hGetEntropy :: CryptHandle -> Int -> IO B.ByteString
136hGetEntropy :: CryptHandle -> Int -> IO B.ByteString
132hGetEntropy (CH h) = B.hGet h
137hGetEntropy (CH h) = B.hGet h
140+foreign import ccall unsafe "cpu_has_rdrand"
141+ c_cpu_has_rdrand :: IO CInt
143+foreign import ccall unsafe "get_rand_bytes"
144+ c_get_rand_bytes :: Ptr CUChar -> CSize -> IO CInt
146+cpuHasRdRand :: IO Bool
147+cpuHasRdRand = (/= 0) `fmap` c_cpu_has_rdrand
134-- |Inefficiently get a specific number of bytes of cryptographically
150-- |Inefficiently get a specific number of bytes of cryptographically
135-- secure random data using the system-specific facilities.
151-- secure random data using the system-specific facilities.
@@ -138,6 +154,17 @@ hGetEntropy (CH h) = B.hGet h
138-- this entropy is considered "cryptographically secure" but not true
154-- this entropy is considered "cryptographically secure" but not true
139-- entropy.
155-- entropy.
140getEntropy :: Int -> IO B.ByteString
156getEntropy :: Int -> IO B.ByteString
160+ if b then B.create n $ \ptr -> do
161+ r <- c_get_rand_bytes (castPtr ptr) (fromIntegral n)
163+ (fail "RDRand failed to gather entropy")
141−getEntropy n = withBinaryFile source ReadMode (`B.hGet` n)
167+ withBinaryFile source ReadMode (`B.hGet` n)