1{-# LANGUAGE CPP, ForeignFunctionInterface, BangPatterns, ScopedTypeVariables #-}
3 Maintainer: Thomas.DuBuisson@gmail.com
7 Obtain entropy from system sources or x86 RDRAND when available.
11module System.EntropyNix
18import Control.Monad (liftM, when)
19import Data.ByteString as B
20import System.IO.Error (mkIOError, eofErrorType, ioeSetErrorString)
22import Foreign (allocaBytes)
25import Data.ByteString.Internal as B
28-- See .cabal wrt GCC 4.8.2 asm compilation bug
34#error "The entropy package requires RDRAND support when using the halvm/Xen"
36data CryptHandle = UseRdRand -- or die trying
39import System.Posix (openFd, closeFd, fdReadBuf, OpenMode(..), defaultFileFlags, Fd)
42source = "/dev/urandom"
44-- |Handle for manual resource mangement
52-- |Open a `CryptHandle`
53openHandle :: IO CryptHandle
57 if b then return UseRdRand
64 nonRDRandHandle :: IO CryptHandle
65 nonRDRandHandle = error "entropy: On halvm there is no entropy other than RDRAND."
67 nonRDRandHandle :: IO CryptHandle
68 nonRDRandHandle = liftM CH (openFd source ReadOnly Nothing defaultFileFlags)
71-- |Close the `CryptHandle`
72closeHandle :: CryptHandle -> IO ()
74closeHandle (CH h) = closeFd h
77closeHandle UseRdRand = return ()
80-- |Read random data from a `CryptHandle`
82hGetEntropy :: CryptHandle -> Int -> IO B.ByteString
83hGetEntropy UseRdRand = \n -> do
84 B.create n $ \ptr -> do
85 r <- c_get_rand_bytes (castPtr ptr) (fromIntegral n)
87 (fail "RDRand failed to gather entropy")
89hGetEntropy :: CryptHandle -> Int -> IO B.ByteString
90hGetEntropy (CH h) = fdReadBS h
92hGetEntropy UseRdRand = \n -> do
93 B.create n $ \ptr -> do
94 r <- c_get_rand_bytes (castPtr ptr) (fromIntegral n)
96 (fail "RDRand failed to gather entropy")
99fdReadBS :: Fd -> Int -> IO B.ByteString
101 allocaBytes n $ \buf -> do
102 rc <- fdReadBuf fd buf (fromIntegral n)
104 0 -> ioError (ioeSetErrorString (mkIOError eofErrorType "fdRead" Nothing Nothing) "EOF")
105 n' -> B.packCStringLen (castPtr buf, fromIntegral n')
110foreign import ccall unsafe "cpu_has_rdrand"
111 c_cpu_has_rdrand :: IO CInt
113foreign import ccall unsafe "get_rand_bytes"
114 c_get_rand_bytes :: Ptr CUChar -> CSize -> IO CInt
116cpuHasRdRand :: IO Bool
117cpuHasRdRand = (/= 0) `fmap` c_cpu_has_rdrand
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list