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
28data CryptHandle = UseRdRand -- or die trying
31import System.Posix (openFd, closeFd, fdReadBuf, OpenMode(..), defaultFileFlags, Fd)
34source = "/dev/urandom"
36-- |Handle for manual resource mangement
44-- |Open a `CryptHandle`
45openHandle :: IO CryptHandle
49 if b then return UseRdRand
56 nonRDRandHandle :: IO CryptHandle
57 nonRDRandHandle = error "entropy: On halvm there is no entropy other than RDRAND."
59 nonRDRandHandle :: IO CryptHandle
60 nonRDRandHandle = liftM CH (openFd source ReadOnly Nothing defaultFileFlags)
63-- |Close the `CryptHandle`
64closeHandle :: CryptHandle -> IO ()
66closeHandle (CH h) = closeFd h
69closeHandle UseRdRand = return ()
72-- |Read random data from a `CryptHandle`
74hGetEntropy :: CryptHandle -> Int -> IO B.ByteString
75hGetEntropy UseRdRand = \n -> do
76 B.create n $ \ptr -> do
77 r <- c_get_rand_bytes (castPtr ptr) (fromIntegral n)
79 (fail "RDRand failed to gather entropy")
81hGetEntropy :: CryptHandle -> Int -> IO B.ByteString
82hGetEntropy (CH h) = fdReadBS h
84hGetEntropy UseRdRand = \n -> do
85 B.create n $ \ptr -> do
86 r <- c_get_rand_bytes (castPtr ptr) (fromIntegral n)
88 (fail "RDRand failed to gather entropy")
91fdReadBS :: Fd -> Int -> IO B.ByteString
93 allocaBytes n $ \buf -> do
94 rc <- fdReadBuf fd buf (fromIntegral n)
96 0 -> ioError (ioeSetErrorString (mkIOError eofErrorType "fdRead" Nothing Nothing) "EOF")
97 n' -> B.packCStringLen (castPtr buf, fromIntegral n')
102foreign import ccall unsafe "cpu_has_rdrand"
103 c_cpu_has_rdrand :: IO CInt
105foreign import ccall unsafe "get_rand_bytes"
106 c_get_rand_bytes :: Ptr CUChar -> CSize -> IO CInt
108cpuHasRdRand :: IO Bool
109cpuHasRdRand = (/= 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