git.iko.soy/typeable/entropy
on main help sign in
use RDRand for long-running (CryptHandle) requests.
406e8aeThomas M. DuBuisson
System/Entropy.hs+18−2
@@ -122,19 +122,35 @@ source :: FilePath
122source = "/dev/urandom"
122source = "/dev/urandom"
123
123
124-- |Handle for manual resource mangement
124-- |Handle for manual resource mangement
125−newtype CryptHandle = CH Handle
125+data CryptHandle = CH Handle | UseRdRand
126
126
127-- |Open a `CryptHandle`
127-- |Open a `CryptHandle`
128openHandle :: IO CryptHandle
128openHandle :: IO CryptHandle
129+openHandle = do
130+#ifdef arch_x86_64
131+ b <- cpuHasRdRand
132+ if b then return UseRdRand
133+ else do
134+#endif
129−openHandle = liftM CH (openFile source ReadMode)
135+ liftM CH (openFile source ReadMode)
130
136
131-- |Close the `CryptHandle`
137-- |Close the `CryptHandle`
132closeHandle :: CryptHandle -> IO ()
138closeHandle :: CryptHandle -> IO ()
133closeHandle (CH h) = hClose h
139closeHandle (CH h) = hClose h
140+#ifdef arch_x86_64
141+closeHandle UseRdRand = return ()
142+#endif
134
143
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
147+#ifdef arch_x86_64
148+hGetEntropy UseRdRand = \n -> do
149+ B.create n $ \ptr -> do
150+ r <- c_get_rand_bytes (castPtr ptr) (fromIntegral n)
151+ when (r /= 0)
152+ (fail "RDRand failed to gather entropy")
153+#endif
138
154
139#ifdef arch_x86_64
155#ifdef arch_x86_64
140foreign import ccall unsafe "cpu_has_rdrand"
156foreign import ccall unsafe "cpu_has_rdrand"