entropy-0.2.1/0000755000000000000000000000000011606117324011401 5ustar0000000000000000entropy-0.2.1/entropy.cabal0000644000000000000000000000215511606117324014070 0ustar0000000000000000name: entropy version: 0.2.1 license: BSD3 license-file: LICENSE copyright: Thomas DuBuisson author: Thomas DuBuisson maintainer: Thomas DuBuisson description: A platform independent method to obtain cryptographically strong entropy (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 entropy-0.2.1/LICENSE0000644000000000000000000000266311606117324012415 0ustar0000000000000000Copyright (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. entropy-0.2.1/Setup.hs0000644000000000000000000000005611606117324013036 0ustar0000000000000000import Distribution.Simple main = defaultMain entropy-0.2.1/System/0000755000000000000000000000000011606117324012665 5ustar0000000000000000entropy-0.2.1/System/Entropy.hs0000644000000000000000000001044311606117324014663 0ustar0000000000000000{-# 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.Monad (liftM) import Data.ByteString as B import Data.ByteString.Lazy as L import System.IO (openFile, hClose, IOMode(..), Handle, withBinaryFile) #if defined(isWindows) {- C example for windows rng - taken from a blog, can't recall which one but thank you! #include #include ... // // 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 = BI.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 h <- cryptAcquireCtx bs <- cryptGenRandom h n let !bs' = bs cryptReleaseCtx h return bs' -- |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 = withBinaryFile source ReadMode (`B.hGet` n) #endif