@@ -122,19 +122,35 @@ source :: FilePath
122source = "/dev/urandom"
122source = "/dev/urandom"
124-- |Handle for manual resource mangement
124-- |Handle for manual resource mangement
125−newtype CryptHandle = CH Handle
125+data CryptHandle = CH Handle | UseRdRand
127-- |Open a `CryptHandle`
127-- |Open a `CryptHandle`
128openHandle :: IO CryptHandle
128openHandle :: IO CryptHandle
132+ if b then return UseRdRand
129−openHandle = liftM CH (openFile source ReadMode)
135+ liftM CH (openFile source ReadMode)
131-- |Close the `CryptHandle`
137-- |Close the `CryptHandle`
132closeHandle :: CryptHandle -> IO ()
138closeHandle :: CryptHandle -> IO ()
133closeHandle (CH h) = hClose h
139closeHandle (CH h) = hClose h
141+closeHandle UseRdRand = return ()
135-- |Read random data from a `CryptHandle`
144-- |Read random data from a `CryptHandle`
136hGetEntropy :: CryptHandle -> Int -> IO B.ByteString
145hGetEntropy :: CryptHandle -> Int -> IO B.ByteString
137hGetEntropy (CH h) = B.hGet h
146hGetEntropy (CH h) = B.hGet h
148+hGetEntropy UseRdRand = \n -> do
149+ B.create n $ \ptr -> do
150+ r <- c_get_rand_bytes (castPtr ptr) (fromIntegral n)
152+ (fail "RDRand failed to gather entropy")
139#ifdef arch_x86_64
155#ifdef arch_x86_64
140foreign import ccall unsafe "cpu_has_rdrand"
156foreign import ccall unsafe "cpu_has_rdrand"