git.iko.soy/typeable/entropy
on main help sign in
Initial move of pkg to github.
commitf5b8563abb816abec4c41d8fa4de3cd3ed59a6f0 authorThomas M. DuBuisson <tommd@galois.com> dateSun 12 May 2013, 12:21 (13 years ago)
4 files changed+206
LICENSE+30 Setup.hs+2 System/Entropy.hs+143 entropy.cabal+31
LICENSEnew file+30
@@ -0,0 +1,30 @@
1+Copyright (c) Thomas DuBuisson
2+
3+All rights reserved.
4+
5+Redistribution and use in source and binary forms, with or without
6+modification, are permitted provided that the following conditions
7+are met:
8+
9+1. Redistributions of source code must retain the above copyright
10+ notice, this list of conditions and the following disclaimer.
11+
12+2. Redistributions in binary form must reproduce the above copyright
13+ notice, this list of conditions and the following disclaimer in the
14+ documentation and/or other materials provided with the distribution.
15+
16+3. Neither the name of the author nor the names of his contributors
17+ may be used to endorse or promote products derived from this software
18+ without specific prior written permission.
19+
20+THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
21+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23+DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
24+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30+POSSIBILITY OF SUCH DAMAGE.
Setup.hsnew file+2
@@ -0,0 +1,2 @@
1+import Distribution.Simple
2+main = defaultMain
System/Entropy.hsnew file+143
@@ -0,0 +1,143 @@
1+{-# LANGUAGE CPP, ForeignFunctionInterface, BangPatterns, ScopedTypeVariables #-}
2+{-|
3+ Maintainer: Thomas.DuBuisson@gmail.com
4+ Stability: beta
5+ Portability: portable
6+
7+ Obtain entropy from system sources.
8+ Currently, windows and *nix systems with a /dev/urandom are supported.
9+-}
10+
11+module System.Entropy
12+ ( getEntropy
13+ , CryptHandle
14+ , openHandle
15+ , hGetEntropy
16+ , closeHandle
17+ ) where
18+
19+import Control.Monad (liftM)
20+import Data.ByteString as B
21+import Data.ByteString.Lazy as L
22+import System.IO (openFile, hClose, IOMode(..), Handle, withBinaryFile)
23+
24+#if defined(isWindows)
25+{- C example for windows rng - taken from a blog, can't recall which one but thank you!
26+ #include <Windows.h>
27+ #include <Wincrypt.h>
28+ ...
29+ //
30+ // DISCLAIMER: Don't forget to check your error codes!!
31+ // I am not checking as to make the example simple...
32+ //
33+ HCRYPTPROV hCryptCtx = NULL;
34+ BYTE randomArray[128];
35+
36+ CryptAcquireContext(&hCryptCtx, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
37+ CryptGenRandom(hCryptCtx, 128, randomArray);
38+ CryptReleaseContext(hCryptCtx, 0);
39+-}
40+
41+import Data.ByteString.Internal as BI
42+import Data.Int (Int32)
43+import Data.Word (Word32, Word8)
44+import Foreign.C.String (CString, withCString)
45+import Foreign.Ptr (Ptr, nullPtr)
46+import Foreign.Marshal.Alloc (alloca)
47+import Foreign.Marshal.Utils (toBool)
48+import Foreign.Storable (peek)
49+
50+newtype CryptHandle = CH Word32
51+
52+-- Define the constants we need from WinCrypt.h
53+msDefProv :: String
54+msDefProv = "Microsoft Base Cryptographic Provider v1.0"
55+provRSAFull :: Word32
56+provRSAFull = fromIntegral 1
57+cryptVerifyContext :: Word32
58+cryptVerifyContext = fromIntegral 0xF0000000
59+
60+-- Declare the required CryptoAPI imports
61+foreign import stdcall unsafe "CryptAcquireContextA"
62+ c_cryptAcquireCtx :: Ptr Word32 -> CString -> CString -> Word32 -> Word32 -> IO Int32
63+foreign import stdcall unsafe "CryptGenRandom"
64+ c_cryptGenRandom :: Word32 -> Word32 -> Ptr Word8 -> IO Int32
65+foreign import stdcall unsafe "CryptReleaseContext"
66+ c_cryptReleaseCtx :: Word32 -> Word32 -> IO Int32
67+
68+cryptAcquireCtx :: IO Word32
69+cryptAcquireCtx =
70+ alloca $ \handlePtr ->
71+ withCString msDefProv $ \provName -> do
72+ stat <- c_cryptAcquireCtx handlePtr nullPtr provName (fromIntegral 1) (fromIntegral cryptVerifyContext)
73+ if (toBool stat)
74+ then peek handlePtr
75+ else fail "c_cryptAcquireCtx"
76+
77+cryptGenRandom :: Word32 -> Int -> IO B.ByteString
78+cryptGenRandom h i =
79+ BI.create i $ \c_buffer -> do
80+ stat <- c_cryptGenRandom (fromIntegral h) (fromIntegral i) c_buffer
81+ if (toBool stat)
82+ then return ()
83+ else fail "c_cryptGenRandom"
84+
85+cryptReleaseCtx :: Word32 -> IO ()
86+cryptReleaseCtx h = do
87+ stat <- c_cryptReleaseCtx h 0
88+ if (toBool stat)
89+ then return ()
90+ else fail "c_cryptReleaseCtx"
91+
92+-- |Inefficiently get a specific number of bytes of cryptographically
93+-- secure random data using the system-specific facilities.
94+--
95+-- This function will return zero bytes
96+-- on platforms without a secure RNG!
97+getEntropy :: Int -> IO B.ByteString
98+getEntropy n = do
99+ h <- cryptAcquireCtx
100+ bs <- cryptGenRandom h n
101+ let !bs' = bs
102+ cryptReleaseCtx h
103+ return bs'
104+
105+-- |Open a handle from which random data can be read
106+openHandle :: IO CryptHandle
107+openHandle = liftM CH cryptAcquireCtx
108+
109+-- |Close the `CryptHandle`
110+closeHandle (CH h) = cryptReleaseCtx h
111+
112+-- |Read from `CryptHandle`
113+hGetEntropy :: CryptHandle -> Int -> IO B.ByteString
114+hGetEntropy (CH h) = cryptGenRandom h
115+
116+#else
117+source = "/dev/urandom"
118+
119+-- |Handle for manual resource mangement
120+newtype CryptHandle = CH Handle
121+
122+-- |Open a `CryptHandle`
123+openHandle :: IO CryptHandle
124+openHandle = liftM CH (openFile source ReadMode)
125+
126+-- |Close the `CryptHandle`
127+closeHandle :: CryptHandle -> IO ()
128+closeHandle (CH h) = hClose h
129+
130+-- |Read random data from a `CryptHandle`
131+hGetEntropy :: CryptHandle -> Int -> IO B.ByteString
132+hGetEntropy (CH h) = B.hGet h
133+
134+-- |Inefficiently get a specific number of bytes of cryptographically
135+-- secure random data using the system-specific facilities.
136+--
137+-- Use '/dev/urandom' on *nix and CryptAPI when on Windows. In short,
138+-- this entropy is considered "cryptographically secure" but not true
139+-- entropy.
140+getEntropy :: Int -> IO B.ByteString
141+getEntropy n = withBinaryFile source ReadMode (`B.hGet` n)
142+#endif
143+
entropy.cabalnew file+31
@@ -0,0 +1,31 @@
1+name: entropy
2+version: 0.2.1
3+license: BSD3
4+license-file: LICENSE
5+copyright: Thomas DuBuisson <thomas.dubuisson@gmail.com>
6+author: Thomas DuBuisson <thomas.dubuisson@gmail.com>
7+maintainer: Thomas DuBuisson <thomas.dubuisson@gmail.com>
8+description: A platform independent method to obtain cryptographically strong entropy
9+ (urandom on Linux, CryptAPI on Windows, patches welcome).
10+ Users looking for cryptographically strong (number-theoretically
11+ sound) PRNGs should see the 'DRBG' package too!
12+synopsis: A platform independent entropy source
13+category: Data, Cryptography
14+homepage: http://trac.haskell.org/crypto-api/wiki
15+bug-reports: http://trac.haskell.org/crypto-api/report/1
16+stability: stable
17+build-type: Simple
18+cabal-version: >= 1.6
19+tested-with: GHC == 6.12.1
20+data-files:
21+extra-source-files:
22+
23+Library
24+ Build-Depends: base == 4.*, bytestring
25+ ghc-options:
26+ hs-source-dirs:
27+ exposed-modules: System.Entropy
28+ other-modules:
29+ if os(windows)
30+ cpp-options: -DisWindows
31+ extra-libraries: advapi32