entropy 0.3.2 → 0.3.3
raw patch · 6 files changed
+120/−58 lines, 6 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- README.md +2/−0
- System/Entropy.hs +13/−7
- System/EntropyNix.hs +15/−37
- System/EntropyWindows.hs +15/−9
- System/EntropyXen.hs +66/−0
- entropy.cabal +9/−5
README.md view
@@ -5,3 +5,5 @@ unix/linux's `/dev/urandom`, or the RDRAND instruction. This package supports Windows, {li,u}nix, QNX, and has preliminary support for HaLVM.++[](https://travis-ci.org/TomMD/entropy)
System/Entropy.hs view
@@ -8,10 +8,10 @@ Currently supporting: - - Windows via CryptoAPO+ - Windows via CryptoAPI - *nix systems via @\/dev\/urandom@- - QNX- - Xen only when RDRAND is available.+ - Includes QNX+ - Xen (only when RDRAND is available) -} module System.Entropy@@ -21,19 +21,25 @@ ) where import System.EntropyWindows #else+#ifdef XEN+ module System.EntropyXen+ ) where+import System.EntropyXen+#else module System.EntropyNix ) where import System.EntropyNix #endif+#endif import qualified Data.ByteString as B --- |Inefficiently get a specific number of bytes of cryptographically+-- |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.+-- Use RDRAND if available and XOR with '/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 = do h <- openHandle
System/EntropyNix.hs view
@@ -18,6 +18,7 @@ import Control.Monad (liftM, when) import Data.ByteString as B import System.IO.Error (mkIOError, eofErrorType, ioeSetErrorString)+import Data.Bits (xor) import Foreign (allocaBytes) import Foreign.Ptr@@ -29,13 +30,6 @@ #undef HAVE_RDRAND #endif -#ifdef XEN-#ifndef HAVE_RDRAND-#error "The entropy package requires RDRAND support when using the halvm/Xen"-#endif-data CryptHandle = UseRdRand -- or die trying-#else- import System.Posix (openFd, closeFd, fdReadBuf, OpenMode(..), defaultFileFlags, Fd) source :: FilePath@@ -45,8 +39,7 @@ data CryptHandle = CH Fd #ifdef HAVE_RDRAND- | UseRdRand-#endif+ | UseRdRand Fd #endif -- |Open a `CryptHandle`@@ -54,46 +47,33 @@ openHandle = do #ifdef HAVE_RDRAND b <- cpuHasRdRand- if b then return UseRdRand- else nonRDRandHandle+ if b then UseRdRand `fmap` nonRDRandHandle+ else CH `fmap` nonRDRandHandle #else- nonRDRandHandle+ CH `fmap` nonRDRandHandle #endif where-#ifdef XEN- nonRDRandHandle :: IO CryptHandle- nonRDRandHandle = error "entropy: On halvm there is no entropy other than RDRAND."-#else- nonRDRandHandle :: IO CryptHandle- nonRDRandHandle = liftM CH (openFd source ReadOnly Nothing defaultFileFlags)-#endif+ nonRDRandHandle :: IO Fd+ nonRDRandHandle = openFd source ReadOnly Nothing defaultFileFlags -- |Close the `CryptHandle` closeHandle :: CryptHandle -> IO ()-#ifndef XEN closeHandle (CH h) = closeFd h-#endif #ifdef HAVE_RDRAND-closeHandle UseRdRand = return ()+closeHandle (UseRdRand h) = closeFd h #endif -- |Read random data from a `CryptHandle`-#ifdef XEN hGetEntropy :: CryptHandle -> Int -> IO B.ByteString-hGetEntropy UseRdRand = \n -> do- B.create n $ \ptr -> do- r <- c_get_rand_bytes (castPtr ptr) (fromIntegral n)- when (r /= 0)- (fail "RDRand failed to gather entropy")-#else-hGetEntropy :: CryptHandle -> Int -> IO B.ByteString hGetEntropy (CH h) = fdReadBS h #ifdef HAVE_RDRAND-hGetEntropy UseRdRand = \n -> do- B.create n $ \ptr -> do- r <- c_get_rand_bytes (castPtr ptr) (fromIntegral n)- when (r /= 0)- (fail "RDRand failed to gather entropy")+hGetEntropy (UseRdRand h) = \n ->+ do bsURandom <- fdReadBS h n+ bsRDRAND <- B.create n $ \ptr -> do+ r <- c_get_rand_bytes (castPtr ptr) (fromIntegral n)+ when (r /= 0)+ (fail "RDRand failed to gather entropy")+ return $ B.pack $ B.zipWith xor bsURandom bsRDRAND #endif fdReadBS :: Fd -> Int -> IO B.ByteString@@ -103,8 +83,6 @@ case rc of 0 -> ioError (ioeSetErrorString (mkIOError eofErrorType "fdRead" Nothing Nothing) "EOF") n' -> B.packCStringLen (castPtr buf, fromIntegral n')-#endif- #ifdef HAVE_RDRAND foreign import ccall unsafe "cpu_has_rdrand"
System/EntropyWindows.hs view
@@ -20,6 +20,7 @@ import Data.ByteString as B import Data.ByteString.Internal as BI import Data.Int (Int32)+import Data.Bits (xor) import Data.Word (Word32, Word8) import Foreign.C.String (CString, withCString) import Foreign.C.Types@@ -59,7 +60,7 @@ data CryptHandle = CH Word32 #ifdef HAVE_RDRAND- | UseRdRand+ | UseRdRand Word32 #endif -- Define the constants we need from WinCrypt.h @@ -107,22 +108,27 @@ openHandle = do #ifdef HAVE_RDRAND b <- cpuHasRdRand- if b then return UseRdRand+ if b then UseRdRand `fmap` cryptAcquireCtx else do #endif- liftM CH cryptAcquireCtx+ CH `fmap` cryptAcquireCtx -- |Close the `CryptHandle` closeHandle :: CryptHandle -> IO ()-closeHandle (CH h) = cryptReleaseCtx h+closeHandle (CH h) = cryptReleaseCtx h+#ifdef HAVE_RDRAND+closeHandle (UseRdRand h) = cryptReleaseCtx h+#endif -- |Read from `CryptHandle` hGetEntropy :: CryptHandle -> Int -> IO B.ByteString hGetEntropy (CH h) n = cryptGenRandom h n #ifdef HAVE_RDRAND-hGetEntropy UseRdRand n =- BI.create n $ \ptr -> do- r <- c_get_rand_bytes (castPtr ptr) (fromIntegral n)- when (r /= 0)- (fail "RDRand failed to gather entropy")+hGetEntropy (UseRdRand h) n =+ do bsRDRAND <- BI.create n $ \ptr -> do+ r <- c_get_rand_bytes (castPtr ptr) (fromIntegral n)+ when (r /= 0)+ (fail "RDRand failed to gather entropy")+ bsWinCrypt <- cryptGenRandom h n+ return $ B.pack $ B.zipWith xor bsRDRAND bsWinCrypt #endif
+ System/EntropyXen.hs view
@@ -0,0 +1,66 @@+{-# LANGUAGE CPP, ForeignFunctionInterface, BangPatterns, ScopedTypeVariables #-}+{-|+ Maintainer: Thomas.DuBuisson@gmail.com+ Stability: beta+ Portability: portable++ Obtain entropy from system sources or x86 RDRAND when available.++-}++module System.EntropyXen+ ( CryptHandle+ , openHandle+ , hGetEntropy+ , closeHandle+ ) where++import Control.Monad (liftM, when)+import Data.ByteString as B+import System.IO.Error (mkIOError, eofErrorType, ioeSetErrorString)++import Foreign (allocaBytes)+import Foreign.Ptr+import Foreign.C.Types+import Data.ByteString.Internal as B++#ifdef arch_i386+-- See .cabal wrt GCC 4.8.2 asm compilation bug+#undef HAVE_RDRAND+#endif++#ifndef HAVE_RDRAND+#error "The entropy package requires RDRAND support when using the halvm/Xen"+#endif+data CryptHandle = UseRdRand -- or die trying++-- |Open a `CryptHandle`+openHandle :: IO CryptHandle+openHandle = do+ b <- cpuHasRdRand+ if b then return UseRdRand+ else nonRDRandHandle+ where+ nonRDRandHandle :: IO CryptHandle+ nonRDRandHandle = error "entropy: On halvm there is no entropy other than RDRAND."++-- |Close the `CryptHandle`+closeHandle :: CryptHandle -> IO ()+closeHandle UseRdRand = return ()++-- |Read random data from a `CryptHandle`+hGetEntropy :: CryptHandle -> Int -> IO B.ByteString+hGetEntropy UseRdRand = \n -> do+ B.create n $ \ptr -> do+ r <- c_get_rand_bytes (castPtr ptr) (fromIntegral n)+ when (r /= 0)+ (fail "RDRand failed to gather entropy")++foreign import ccall unsafe "cpu_has_rdrand"+ c_cpu_has_rdrand :: IO CInt++foreign import ccall unsafe "get_rand_bytes"+ c_get_rand_bytes :: Ptr CUChar -> CSize -> IO CInt++cpuHasRdRand :: IO Bool+cpuHasRdRand = (/= 0) `fmap` c_cpu_has_rdrand
entropy.cabal view
@@ -1,5 +1,5 @@ name: entropy-version: 0.3.2+version: 0.3.3 description: A platform independent method to obtain cryptographically strong entropy (RDRAND when available anywhere, urandom on nix, CryptAPI on Windows, patches welcome). Users looking for cryptographically strong (number-theoretically@@ -35,12 +35,16 @@ exposed-modules: System.Entropy if os(windows) other-modules: System.EntropyWindows- else- other-modules: System.EntropyNix+ else {+ if os(halvm)+ other-modules: System.EntropyXen+ else+ other-modules: System.EntropyNix+ } other-extensions: CPP, ForeignFunctionInterface, BangPatterns, ScopedTypeVariables build-depends: base == 4.*, bytestring default-language: Haskell2010- if(flag(halvm))+ if(os(halvm)) cpp-options: -DXEN -DHAVE_RDRAND cc-options: -DXEN -DHAVE_RDRAND if arch(x86_64)@@ -57,7 +61,7 @@ cc-options: -DisWindows extra-libraries: advapi32 else- if !flag(halvm)+ if !os(halvm) Build-Depends: unix source-repository head