git.iko.soy/typeable/entropy
on main help sign in
Add build-time configuration to check for RDRAND support.
commit7d267f347db22f1ab094d9107ca79135e4545490 authorThomas M. DuBuisson <tommd@galois.com> dateTue 14 May 2013, 19:40 (13 years ago) parent295e05d
5 files changed+65−14
Setup.hs+47−1 System/Entropy.hs+11−12 cbits/rdrand.c+4 cbits/rdrand.h+2 entropy.cabal+1−1
Setup.hs+47−1
@@ -1,2 +1,48 @@
11import Distribution.Simple
2−main = defaultMain
2+import Distribution.Simple.LocalBuildInfo
3+import Distribution.Simple.Setup
4+import Distribution.PackageDescription
5+import Distribution.Simple.Utils
6+import Distribution.Simple.Program
7+import Distribution.Verbosity
8+import System.Process
9+import System.Directory
10+import System.FilePath
11+import System.Exit
12+
13+main = defaultMainWithHooks hk
14+ where
15+ hk = simpleUserHooks { buildHook = \pd lbi uh bf -> do
16+ let ccProg = Program "gcc" undefined undefined undefined
17+ mConf = lookupProgram ccProg (withPrograms lbi)
18+ err = error "Could not determine C compiler"
19+ cc = locationPath . programLocation . maybe err id $ mConf
20+ b <- canUseRDRAND cc
21+ let newWithPrograms1 = userSpecifyArgs "gcc" cArgs (withPrograms lbi)
22+ newWithPrograms = userSpecifyArgs "ghc" cArgsHC newWithPrograms1
23+ lbiNew = if b then (lbi {withPrograms = newWithPrograms }) else lbi
24+ buildHook simpleUserHooks pd lbiNew uh bf
25+ }
26+
27+cArgs :: [String]
28+cArgs = ["-DHAVE_RDRAND"]
29+
30+cArgsHC :: [String]
31+cArgsHC = map ("-optc" ++) cArgs
32+
33+canUseRDRAND :: FilePath -> IO Bool
34+canUseRDRAND cc = do
35+ withTempDirectory normal "" "testRDRAND" $ \tmpDir -> do
36+ writeFile (tmpDir ++ "/testRDRAND.c")
37+ (unlines [ "#include <stdint.h>"
38+ , "int main() {"
39+ , " uint64_t therand;"
40+ , " unsigned char err;"
41+ , " asm volatile(\"rdrand %0 ; setc %1\""
42+ , " : \"=r\" (therand), \"=qm\" (err));"
43+ , " return (!err);"
44+ , "}"
45+ ])
46+ ec <- rawSystemExitCode normal cc [tmpDir </> "testRDRAND.c", "-o" ++ tmpDir ++ "/a.out"]
47+ notice normal $ "Result of RDRAND Test: " ++ show (ec == ExitSuccess)
48+ return (ec == ExitSuccess)
System/Entropy.hs+11−12
@@ -47,7 +47,7 @@ import Foreign.Marshal.Alloc (alloca)
4747import Foreign.Marshal.Utils (toBool)
4848import Foreign.Storable (peek)
4949
50−#ifdef arch_x86_64
50+#ifdef HAVE_RDRAND
5151foreign import ccall unsafe "cpu_has_rdrand"
5252 c_cpu_has_rdrand :: IO CInt
5353
@@ -60,7 +60,7 @@ cpuHasRdRand = (/= 0) `fmap` c_cpu_has_rdrand
6060
6161data CryptHandle
6262 = CH Word32
63−#ifdef arch_x86_64
63+#ifdef HAVE_RDRAND
6464 | UseRdRand
6565#endif
6666
@@ -111,7 +111,7 @@ cryptReleaseCtx h = do
111111-- on platforms without a secure RNG!
112112getEntropy :: Int -> IO B.ByteString
113113getEntropy n = do
114−#ifdef arch_x86_64
114+#ifdef HAVE_RDRAND
115115 b <- cpuHasRdRand
116116 if b then hGetEntropy UseRdRand n
117117 else do
@@ -125,7 +125,7 @@ getEntropy n = do
125125-- |Open a handle from which random data can be read
126126openHandle :: IO CryptHandle
127127openHandle = do
128−#ifdef arch_x86_64
128+#ifdef HAVE_RDRAND
129129 b <- cpuHasRdRand
130130 if b then return UseRdRand
131131 else do
@@ -138,7 +138,7 @@ closeHandle (CH h) = cryptReleaseCtx h
138138-- |Read from `CryptHandle`
139139hGetEntropy :: CryptHandle -> Int -> IO B.ByteString
140140hGetEntropy (CH h) = cryptGenRandom h
141−#ifdef arch_x86_64
141+#ifdef HAVE_RDRAND
142142hGetEntropy UseRdRand =
143143 B.create n $ \ptr -> do
144144 r <- c_get_rand_bytes (castPtr ptr) (fromIntegral n)
@@ -150,7 +150,6 @@ hGetEntropy UseRdRand =
150150{- Not windows, assuming nix with a /dev/urandom -}
151151import Foreign.C.Types
152152import Foreign.Ptr
153−import Data.ByteString.Internal as B
154153
155154source :: FilePath
156155source = "/dev/urandom"
@@ -158,14 +157,14 @@ source = "/dev/urandom"
158157-- |Handle for manual resource mangement
159158data CryptHandle
160159 = CH Handle
161−#ifdef arch_x86_64
160+#ifdef HAVE_RDRAND
162161 | UseRdRand
163162#endif
164163
165164-- |Open a `CryptHandle`
166165openHandle :: IO CryptHandle
167166openHandle = do
168−#ifdef arch_x86_64
167+#ifdef HAVE_RDRAND
169168 b <- cpuHasRdRand
170169 if b then return UseRdRand
171170 else do
@@ -175,14 +174,14 @@ openHandle = do
175174-- |Close the `CryptHandle`
176175closeHandle :: CryptHandle -> IO ()
177176closeHandle (CH h) = hClose h
178−#ifdef arch_x86_64
177+#ifdef HAVE_RDRAND
179178closeHandle UseRdRand = return ()
180179#endif
181180
182181-- |Read random data from a `CryptHandle`
183182hGetEntropy :: CryptHandle -> Int -> IO B.ByteString
184183hGetEntropy (CH h) = B.hGet h
185−#ifdef arch_x86_64
184+#ifdef HAVE_RDRAND
186185hGetEntropy UseRdRand = \n -> do
187186 B.create n $ \ptr -> do
188187 r <- c_get_rand_bytes (castPtr ptr) (fromIntegral n)
@@ -190,7 +189,7 @@ hGetEntropy UseRdRand = \n -> do
190189 (fail "RDRand failed to gather entropy")
191190#endif
192191
193−#ifdef arch_x86_64
192+#ifdef HAVE_RDRAND
194193foreign import ccall unsafe "cpu_has_rdrand"
195194 c_cpu_has_rdrand :: IO CInt
196195
@@ -209,7 +208,7 @@ cpuHasRdRand = (/= 0) `fmap` c_cpu_has_rdrand
209208-- entropy.
210209getEntropy :: Int -> IO B.ByteString
211210getEntropy n = do
212−#if arch_x86_64
211+#ifdef HAVE_RDRAND
213212 b <- cpuHasRdRand
214213 if b then hGetEntropy UseRdRand n
215214 else do
cbits/rdrand.c+4
@@ -1,3 +1,5 @@
1+#ifdef HAVE_RDRAND
2+
13#include <stdint.h>
24#include <stdlib.h>
35
@@ -49,3 +51,5 @@ int get_rand_bytes(uint8_t *therand, size_t len)
4951 }
5052 return fail;
5153}
54+
55+#endif // RDRAND
cbits/rdrand.h+2
@@ -1,4 +1,5 @@
11#ifndef rdrand_h
2+#ifdef HAVE_RDRAND
23#include <stdint.h>
34
45#ifdef arch_x86_64
@@ -7,4 +8,5 @@ int cpu_has_rdrand()
78// Returns 0 on success, non-zero on failure.
89int get_rand_bytes(uint8_t *therand, size_t len)
910#endif /* arch_x86_64 */
11+#endif // HAVE_RDRAND
1012#endif // rdrand_h
entropy.cabal+1−1
@@ -14,7 +14,7 @@ category: Data, Cryptography
1414homepage: https://github.com/TomMD/entropy
1515bug-reports: https://github.com/TomMD/entropy/issues
1616stability: stable
17−build-type: Simple
17+build-type: Custom
1818cabal-version: >= 1.6
1919tested-with: GHC == 6.12.1
2020data-files: