packages feed

entropy (empty) → 0.1

raw patch · 4 files changed

+215/−0 lines, 4 filesdep +basedep +bytestringsetup-changed

Dependencies added: base, bytestring

Files

+ 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