Skip to content

Commit f771c80

Browse files
committed
WASI: implement in terms of getentropy
This isn't really WASI-specific; it should work for any platform that has `getentropy`.
1 parent 98dd0cf commit f771c80

File tree

3 files changed

+46
-2
lines changed

3 files changed

+46
-2
lines changed

System/Entropy.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ module System.Entropy
2727
import System.EntropyGhcjs
2828
#elif defined(isWindows)
2929
import System.EntropyWindows
30+
#elif wasi_HOST_OS
31+
import System.EntropyWasi
3032
#else
3133
import System.EntropyNix
3234
#endif

System/EntropyWasi.hs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{-# LANGUAGE CApiFFI #-}
2+
3+
module System.EntropyWasi where
4+
5+
import Control.Monad (when)
6+
import Data.ByteString (ByteString)
7+
import Data.ByteString.Internal as B
8+
import Data.Word (Word8)
9+
import Foreign.C.Types
10+
import Foreign.Ptr
11+
12+
data CryptHandle = BogusCryptHandle
13+
14+
openHandle :: IO CryptHandle
15+
openHandle = pure BogusCryptHandle
16+
17+
hGetEntropy :: CryptHandle -> Int -> IO ByteString
18+
hGetEntropy BogusCryptHandle = \n -> B.create n $ go (fromIntegral n)
19+
where
20+
go :: CSize -> Ptr Word8 -> IO ()
21+
go n ptr
22+
| n <= 256 = getentropy' ptr n
23+
| otherwise = do
24+
getentropy' ptr 256
25+
go (n - 256) (ptr `plusPtr` 256)
26+
27+
getentropy' ptr n = do
28+
res <- getentropy ptr n
29+
when (res /= 0) $
30+
fail "getentropy failed"
31+
32+
foreign import capi safe "unistd.h getentropy"
33+
getentropy :: Ptr Word8 -> CSize -> IO CInt
34+
35+
closeHandle :: CryptHandle -> IO ()
36+
closeHandle BogusCryptHandle = pure ()
37+
38+
hardwareRandom :: Int -> IO (Maybe ByteString)
39+
hardwareRandom _ = pure Nothing

entropy.cabal

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
cabal-version: >=1.10
1+
cabal-version: 3.8
22
name: entropy
33
version: 0.4.1.10
44
x-revision: 2
@@ -7,7 +7,7 @@ description: A mostly platform independent method to obtain cryptographically
77
Users looking for cryptographically strong (number-theoretically
88
sound) PRNGs should see the 'DRBG' package too.
99
synopsis: A platform independent entropy source
10-
license: BSD3
10+
license: BSD-3-Clause
1111
license-file: LICENSE
1212
copyright: Thomas DuBuisson <[email protected]>
1313
author: Thomas DuBuisson <[email protected]>
@@ -61,6 +61,8 @@ library
6161
else {
6262
if os(windows)
6363
other-modules: System.EntropyWindows
64+
elif os(wasi)
65+
other-modules: System.EntropyWasi
6466
else {
6567
other-modules: System.EntropyNix
6668
}
@@ -90,6 +92,7 @@ library
9092
cpp-options: -DisWindows
9193
cc-options: -DisWindows
9294
extra-libraries: advapi32
95+
elif os(wasi)
9396
else
9497
Build-Depends: unix
9598
c-sources: cbits/getrandom.c cbits/random_initialized.c

0 commit comments

Comments
 (0)