module Crypto.Random.Entropy.Unsafe
( replenish
, module Crypto.Random.Entropy.Backend
) where
import Data.Word (Word8)
import Foreign.Ptr (Ptr, plusPtr)
import Crypto.Random.Entropy.Backend
replenish :: Int -> [EntropyBackend] -> Ptr Word8 -> IO ()
replenish :: Int -> [EntropyBackend] -> Ptr Word8 -> IO ()
replenish Int
_ [] Ptr Word8
_ = String -> IO ()
forall a. String -> IO a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"crypton: random: cannot get any source of entropy on this system"
replenish Int
poolSize [EntropyBackend]
backends Ptr Word8
ptr = Int -> [EntropyBackend] -> Ptr Word8 -> Int -> IO ()
loop Int
0 [EntropyBackend]
backends Ptr Word8
ptr Int
poolSize
where loop :: Int -> [EntropyBackend] -> Ptr Word8 -> Int -> IO ()
loop :: Int -> [EntropyBackend] -> Ptr Word8 -> Int -> IO ()
loop Int
_ [EntropyBackend]
_ Ptr Word8
_ Int
0 = () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
loop Int
retry [] Ptr Word8
p Int
n | Int
retry Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
3 = String -> IO ()
forall a. HasCallStack => String -> a
error String
"crypton: random: cannot fully replenish"
| Bool
otherwise = Int -> [EntropyBackend] -> Ptr Word8 -> Int -> IO ()
loop (Int
retryInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) [EntropyBackend]
backends Ptr Word8
p Int
n
loop Int
retry (EntropyBackend
b:[EntropyBackend]
bs) Ptr Word8
p Int
n = do
Int
r <- EntropyBackend -> Ptr Word8 -> Int -> IO Int
gatherBackend EntropyBackend
b Ptr Word8
p Int
n
Int -> [EntropyBackend] -> Ptr Word8 -> Int -> IO ()
loop Int
retry [EntropyBackend]
bs (Ptr Word8
p Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
r) (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
r)