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
_ = forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"cryptonite: 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 = forall (m :: * -> *) a. Monad m => a -> m a
return ()
loop Int
retry [] Ptr Word8
p Int
n | Int
retry forall a. Eq a => a -> a -> Bool
== Int
3 = forall a. HasCallStack => String -> a
error String
"cryptonite: random: cannot fully replenish"
| Bool
otherwise = Int -> [EntropyBackend] -> Ptr Word8 -> Int -> IO ()
loop (Int
retryforall 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 forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
r) (Int
n forall a. Num a => a -> a -> a
- Int
r)