git.iko.soy/typeable/entropy
on main help sign in
HaLVM support, sort of.
3bda5dfThomas M. DuBuisson
README.md+2
@@ -3,3 +3,5 @@
3This package allows Haskell users to easily acquire entropy for use in
3This package allows Haskell users to easily acquire entropy for use in
4critical security applications by calling out to either windows crypto api,
4critical security applications by calling out to either windows crypto api,
5unix/linux's `/dev/urandom`, or the RDRAND instruction.
5unix/linux's `/dev/urandom`, or the RDRAND instruction.
6+
7+This package supports Windows, {li,u}nix, QNX, and has preliminary support for HaLVM.
System/Entropy.hs+42−14
@@ -4,22 +4,32 @@
4 Stability: beta
4 Stability: beta
5 Portability: portable
5 Portability: portable
6
6
7− Obtain entropy from system sources.
7+ Obtain entropy from system sources or x86 RDRAND when available.
8+
9+ Currently supporting:
10+
11+ - Windows via CryptoAPO
8− Currently, windows and *nix systems with a @/dev/urandom@ are supported.
12+ - *nix systems via @\/dev\/urandom@
13+ - QNX
14+ - Xen only when RDRAND is available.
9-}
15-}
10
16
11module System.Entropy
17module System.Entropy
12− ( getEntropy
18+ ( getEntropy
13− , CryptHandle
19+ , CryptHandle
14− , openHandle
20+ , openHandle
15− , hGetEntropy
21+ , hGetEntropy
16− , closeHandle
22+ , closeHandle
17− ) where
23+ ) where
18−
24+
25+#ifndef XEN
19−import Control.Monad (liftM)
26+import Control.Monad (liftM, when)
20−import Data.ByteString as B
21import System.IO.Error (mkIOError, eofErrorType, ioeSetErrorString)
27import System.IO.Error (mkIOError, eofErrorType, ioeSetErrorString)
22import Foreign (allocaBytes)
28import Foreign (allocaBytes)
29+#else
30+import Control.Monad (when)
31+#endif
32+import Data.ByteString as B
23
33
24#if defined(isWindows)
34#if defined(isWindows)
25{- C example for windows rng - taken from a blog, can't recall which one but thank you!
35{- C example for windows rng - taken from a blog, can't recall which one but thank you!
@@ -149,8 +159,13 @@ hGetEntropy UseRdRand =
149
159
150#else
160#else
151{- Not windows, assuming nix with a /dev/urandom -}
161{- Not windows, assuming nix with a /dev/urandom -}
152−import System.Posix (openFd, closeFd, fdReadBuf, OpenMode(..), defaultFileFlags, Fd)
153import Foreign.Ptr
162import Foreign.Ptr
163+import Foreign.C.Types
164+import Data.ByteString.Internal as B
165+#ifdef XEN
166+data CryptHandle = UseRdRand -- or die trying
167+#else
168+import System.Posix (openFd, closeFd, fdReadBuf, OpenMode(..), defaultFileFlags, Fd)
154
169
155source :: FilePath
170source :: FilePath
156source = "/dev/urandom"
171source = "/dev/urandom"
@@ -161,6 +176,7 @@ data CryptHandle
161#ifdef HAVE_RDRAND
176#ifdef HAVE_RDRAND
162 | UseRdRand
177 | UseRdRand
163#endif
178#endif
179+#endif
164
180
165-- |Open a `CryptHandle`
181-- |Open a `CryptHandle`
166openHandle :: IO CryptHandle
182openHandle :: IO CryptHandle
@@ -170,15 +186,22 @@ openHandle = do
170 if b then return UseRdRand
186 if b then return UseRdRand
171 else do
187 else do
172#endif
188#endif
189+#ifdef XEN
190+ error "entropy: On halvm there is no entropy other than RDRAND."
191+#else
173− liftM CH (openFd source ReadOnly Nothing defaultFileFlags)
192+ liftM CH (openFd source ReadOnly Nothing defaultFileFlags)
193+#endif
174
194
175-- |Close the `CryptHandle`
195-- |Close the `CryptHandle`
176closeHandle :: CryptHandle -> IO ()
196closeHandle :: CryptHandle -> IO ()
197+#ifndef XEN
177closeHandle (CH h) = closeFd h
198closeHandle (CH h) = closeFd h
199+#endif
178#ifdef HAVE_RDRAND
200#ifdef HAVE_RDRAND
179closeHandle UseRdRand = return ()
201closeHandle UseRdRand = return ()
180#endif
202#endif
181
203
204+#ifndef XEN
182fdReadBS :: Fd -> Int -> IO B.ByteString
205fdReadBS :: Fd -> Int -> IO B.ByteString
183fdReadBS fd n = do
206fdReadBS fd n = do
184 allocaBytes n $ \buf -> do
207 allocaBytes n $ \buf -> do
@@ -186,10 +209,13 @@ fdReadBS fd n = do
186 case rc of
209 case rc of
187 0 -> ioError (ioeSetErrorString (mkIOError eofErrorType "fdRead" Nothing Nothing) "EOF")
210 0 -> ioError (ioeSetErrorString (mkIOError eofErrorType "fdRead" Nothing Nothing) "EOF")
188 n' -> B.packCStringLen (castPtr buf, fromIntegral n')
211 n' -> B.packCStringLen (castPtr buf, fromIntegral n')
212+#endif
189
213
190-- |Read random data from a `CryptHandle`
214-- |Read random data from a `CryptHandle`
191hGetEntropy :: CryptHandle -> Int -> IO B.ByteString
215hGetEntropy :: CryptHandle -> Int -> IO B.ByteString
216+#ifndef XEN
192hGetEntropy (CH h) = fdReadBS h
217hGetEntropy (CH h) = fdReadBS h
218+#else
193#ifdef HAVE_RDRAND
219#ifdef HAVE_RDRAND
194hGetEntropy UseRdRand = \n -> do
220hGetEntropy UseRdRand = \n -> do
195 B.create n $ \ptr -> do
221 B.create n $ \ptr -> do
@@ -197,6 +223,8 @@ hGetEntropy UseRdRand = \n -> do
197 when (r /= 0)
223 when (r /= 0)
198 (fail "RDRand failed to gather entropy")
224 (fail "RDRand failed to gather entropy")
199#endif
225#endif
226+#endif
227+{- XEN -}
200
228
201#ifdef HAVE_RDRAND
229#ifdef HAVE_RDRAND
202foreign import ccall unsafe "cpu_has_rdrand"
230foreign import ccall unsafe "cpu_has_rdrand"
@@ -213,7 +241,7 @@ cpuHasRdRand = (/= 0) `fmap` c_cpu_has_rdrand
213-- secure random data using the system-specific facilities.
241-- secure random data using the system-specific facilities.
214--
242--
215-- Use '/dev/urandom' on *nix and CryptAPI when on Windows. In short,
243-- Use '/dev/urandom' on *nix and CryptAPI when on Windows. In short,
216−-- this entropy is considered "cryptographically secure" but not true
244+-- this entropy is considered cryptographically secure but not true
217-- entropy.
245-- entropy.
218getEntropy :: Int -> IO B.ByteString
246getEntropy :: Int -> IO B.ByteString
219getEntropy n = do
247getEntropy n = do
entropy.cabal+15−5
@@ -1,5 +1,5 @@
1name: entropy
1name: entropy
2−version: 0.2.2.4
2+version: 0.3
3description: A platform independent method to obtain cryptographically strong entropy
3description: A platform independent method to obtain cryptographically strong entropy
4 (urandom on Linux, CryptAPI on Windows, patches welcome).
4 (urandom on Linux, CryptAPI on Windows, patches welcome).
5 Users looking for cryptographically strong (number-theoretically
5 Users looking for cryptographically strong (number-theoretically
@@ -14,20 +14,29 @@ category: Data, Cryptography
14homepage: https://github.com/TomMD/entropy
14homepage: https://github.com/TomMD/entropy
15bug-reports: https://github.com/TomMD/entropy/issues
15bug-reports: https://github.com/TomMD/entropy/issues
16stability: stable
16stability: stable
17+-- build-type: Simple
18+-- ^^ Used for HaLVM
17build-type: Custom
19build-type: Custom
20+-- ^^ Test for RDRAND support using 'ghc'
18−cabal-version: >=1.10
21+cabal-version: >=1.10
19tested-with: GHC == 7.6.3
22tested-with: GHC == 7.6.3
20-- data-files:
23-- data-files:
21extra-source-files: ./cbits/rdrand.c, ./cbits/rdrand.h, README.md
24extra-source-files: ./cbits/rdrand.c, ./cbits/rdrand.h, README.md
22
25
26+-- Notice to compile with HaLVM the above 'build-type' must be changed
27+-- to 'Simple' instead of 'Custom'. The current build system naively
28+-- runs GHC to determine if the compiler supports RDRAND before proceeding.
29+flag halvm
30+ description: Build for the HaLVM
31+
23library
32library
24 ghc-options: -Wall -O2
33 ghc-options: -Wall -O2
25 exposed-modules: System.Entropy
34 exposed-modules: System.Entropy
26 other-extensions: CPP, ForeignFunctionInterface, BangPatterns, ScopedTypeVariables
35 other-extensions: CPP, ForeignFunctionInterface, BangPatterns, ScopedTypeVariables
27 build-depends: base == 4.*, bytestring
36 build-depends: base == 4.*, bytestring
28− -- hs-source-dirs:
29− -- other-modules:
30 default-language: Haskell2010
37 default-language: Haskell2010
38+ if(flag(halvm))
39+ cpp-options: -DXEN -DHAVE_RDRAND
31 if arch(x86_64)
40 if arch(x86_64)
32 cpp-options: -Darch_x86_64
41 cpp-options: -Darch_x86_64
33 c-sources: cbits/rdrand.c
42 c-sources: cbits/rdrand.c
@@ -36,7 +45,8 @@ library
36 cpp-options: -DisWindows
45 cpp-options: -DisWindows
37 extra-libraries: advapi32
46 extra-libraries: advapi32
38 else
47 else
48+ if !flag(halvm)
39− Build-Depends: unix
49+ Build-Depends: unix
40
50
41source-repository head
51source-repository head
42 type: git
52 type: git