entropy (empty) → 0.1
raw patch · 4 files changed
+215/−0 lines, 4 filesdep +basedep +bytestringsetup-changed
Dependencies added: base, bytestring
Files
- LICENSE +30/−0
- Setup.hs +2/−0
- System/Entropy.hs +154/−0
- entropy.cabal +29/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) Thomas DuBuisson++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met:++1. Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++2. Redistributions in binary form must reproduce the above copyright+ notice, this list of conditions and the following disclaimer in the+ documentation and/or other materials provided with the distribution.++3. Neither the name of the author nor the names of his contributors+ may be used to endorse or promote products derived from this software+ without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE+POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ System/Entropy.hs view
@@ -0,0 +1,154 @@+{-# LANGUAGE CPP, ForeignFunctionInterface, BangPatterns, ScopedTypeVariables #-}+{-|+ Maintainer: Thomas.DuBuisson@gmail.com+ Stability: beta+ Portability: portable++ Obtain entropy from system sources.+ Currently, windows and *nix systems with a /dev/urandom are supported.+-}++module System.Entropy+ ( getEntropy+ , CryptHandle+ , openHandle+ , hGetEntropy+ , closeHandle+ ) where++import Control.Exception as X+import Control.Monad (liftM)+import Data.ByteString as B+import Data.ByteString.Lazy as L+import System.IO (openFile, hClose, IOMode(..), Handle)+import qualified Control.Exception as X++#if defined(isWindows)+{- C example for windows rng - taken from a blog, can't recall which one but thank you!+ #include <Windows.h>+ #include <Wincrypt.h>+ ...+ //+ // DISCLAIMER: Don't forget to check your error codes!!+ // I am not checking as to make the example simple...+ //+ HCRYPTPROV hCryptCtx = NULL;+ BYTE randomArray[128];++ CryptAcquireContext(&hCryptCtx, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);+ CryptGenRandom(hCryptCtx, 128, randomArray);+ CryptReleaseContext(hCryptCtx, 0);+-}++import Data.ByteString.Internal as BI+import Data.Int (Int32)+import Data.Word (Word32, Word8)+import Foreign.C.String (CString, withCString)+import Foreign.Ptr (Ptr, nullPtr)+import Foreign.Marshal.Alloc (alloca)+import Foreign.Marshal.Utils (toBool)+import Foreign.Storable (peek)++newtype CryptHandle = CH Word32++-- Define the constants we need from WinCrypt.h +msDefProv :: String+msDefProv = "Microsoft Base Cryptographic Provider v1.0"+provRSAFull :: Word32+provRSAFull = fromIntegral 1+cryptVerifyContext :: Word32+cryptVerifyContext = fromIntegral 0xF0000000++-- Declare the required CryptoAPI imports +foreign import stdcall unsafe "CryptAcquireContextA"+ c_cryptAcquireCtx :: Ptr Word32 -> CString -> CString -> Word32 -> Word32 -> IO Int32+foreign import stdcall unsafe "CryptGenRandom"+ c_cryptGenRandom :: Word32 -> Word32 -> Ptr Word8 -> IO Int32+foreign import stdcall unsafe "CryptReleaseContext"+ c_cryptReleaseCtx :: Word32 -> Word32 -> IO Int32++cryptAcquireCtx :: IO Word32+cryptAcquireCtx = + alloca $ \handlePtr -> + withCString msDefProv $ \provName -> do+ stat <- c_cryptAcquireCtx handlePtr nullPtr provName (fromIntegral 1) (fromIntegral cryptVerifyContext)+ if (toBool stat)+ then peek handlePtr+ else fail "c_cryptAcquireCtx"++cryptGenRandom :: Word32 -> Int -> IO B.ByteString+cryptGenRandom h i = + B.create i $ \c_buffer -> do+ stat <- c_cryptGenRandom (fromIntegral h) (fromIntegral i) c_buffer+ if (toBool stat)+ then return ()+ else fail "c_cryptGenRandom"++cryptReleaseCtx :: Word32 -> IO ()+cryptReleaseCtx h = do+ stat <- c_cryptReleaseCtx h 0+ if (toBool stat)+ then return ()+ else fail "c_cryptReleaseCtx"++-- |Inefficiently get a specific number of bytes of cryptographically+-- secure random data using the system-specific facilities.+--+-- This function will return zero bytes+-- on platforms without a secure RNG!+getEntropy :: Int -> IO B.ByteString+getEntropy n = do+ X.catch (do+ h <- cryptAcquireCtx+ bs <- cryptGenRandom h n+ let !bs' = bs+ cryptReleaseCtx h+ return bs')+ (\(e :: X.IOException) -> return B.empty)++-- |Open a handle from which random data can be read+openHandle :: IO CryptHandle+openHandle = liftM CH cryptAcquireCtx++-- |Close the `CryptHandle`+closeHandle (CH h) = cryptReleaseCtx h++-- |Read from `CryptHandle`+hGetEntropy :: CryptHandle -> Int -> IO B.ByteString +hGetEntropy (CH h) = cryptGenRandom h++#else+source = "/dev/urandom"++-- |Handle for manual resource mangement+newtype CryptHandle = CH Handle++-- |Open a `CryptHandle`+openHandle :: IO CryptHandle+openHandle = liftM CH (openFile source ReadMode)++-- |Close the `CryptHandle`+closeHandle :: CryptHandle -> IO ()+closeHandle (CH h) = hClose h++-- |Read random data from a `CryptHandle`+hGetEntropy :: CryptHandle -> Int -> IO B.ByteString +hGetEntropy (CH h) = B.hGet h++-- |Inefficiently get a specific number of bytes of cryptographically+-- secure random data using the system-specific facilities.+--+-- Use '/dev/urandom' on *nix and CryptAPI when on Windows. In short,+-- this entropy is considered "cryptographically secure" but not true+-- entropy.+getEntropy :: Int -> IO B.ByteString+getEntropy n = + X.catch (do+ h <- openFile source ReadMode+ bs <- B.hGet h n+ let !bs' = bs+ hClose h+ return bs')+ (\(e :: X.IOException) -> return B.empty)+#endif+
+ entropy.cabal view
@@ -0,0 +1,29 @@+name: entropy+version: 0.1+license: BSD3+license-file: LICENSE+copyright: Thomas DuBuisson <thomas.dubuisson@gmail.com>+author: Thomas DuBuisson <thomas.dubuisson@gmail.com>+maintainer: Thomas DuBuisson <thomas.dubuisson@gmail.com>+description: A platform independent method to obtain cryptographically strong entropy (/dev/urandom on Linux, CryptAPI on Windows, patches welcome)+ Users looking for cryptographically strong (number-theoretically sound) PRNGs should see the 'DRBG' package too!+synopsis: A platform independent entropy source+category: Data, Cryptography+homepage: http://trac.haskell.org/crypto-api/wiki+bug-reports: http://trac.haskell.org/crypto-api/report/1+stability: stable+build-type: Simple+cabal-version: >= 1.6+tested-with: GHC == 6.12.1+data-files:+extra-source-files:++Library+ Build-Depends: base == 4.*, bytestring+ ghc-options:+ hs-source-dirs:+ exposed-modules: System.Entropy+ other-modules:+ if os(windows)+ cpp-options: -DisWindows+ extra-libraries: advapi32