Copyright | (c) Piyush P Kurur 2016 |
---|---|
License | Apache-2.0 OR BSD-3-Clause |
Maintainer | Piyush P Kurur <ppk@iitpkd.ac.in> |
Stability | experimental |
Safe Haskell | None |
Language | Haskell2010 |
Synopsis
- data RandomState
- withRandomState :: (RandomState -> IO a) -> IO a
- randomByteString :: LengthUnit l => l -> RandomState -> IO ByteString
- class Random a where
- random :: RandomState -> IO a
- randomiseMemory :: WriteAccessible mem => mem -> RandomState -> IO ()
- withRandomisedMemory :: WriteAccessible mem => (mem -> IO a) -> IO a
- withSecureRandomisedMemory :: WriteAccessible mem => (mem -> IO a) -> IO a
- withSecureRandomState :: Memory mem => (mem -> RandomState -> IO a) -> IO a
- fillRandomBytes :: (LengthUnit l, Pointer ptr) => l -> Dest (ptr a) -> RandomState -> IO ()
- class Storable a => RandomStorable a where
- fillRandomElements :: Int -> Ptr a -> RandomState -> IO ()
- fillRandom :: (RandomStorable a, Pointer ptr) => Int -> ptr a -> RandomState -> IO ()
- unsafeFillRandomElements :: Storable a => Int -> Ptr a -> RandomState -> IO ()
- reseed :: RandomState -> IO ()
- entropySource :: String
- csprgName :: String
- csprgDescription :: String
Cryptographically secure randomness.
This module provides cryptographically secure pseudo-random
bytes. The state of the csprg is kept track in the memory element
RandomState
and should be run using withRandomState
.
data RandomState #
Instances
WriteAccessible RandomState | |
Defined in PRGenerator writeAccess :: RandomState -> [Access] afterWriteAdjustment :: RandomState -> IO () | |
ByteSource RandomState | |
Defined in PRGenerator fillBytes :: BYTES Int -> RandomState -> Ptr a -> IO (FillResult RandomState) | |
Memory RandomState | |
Defined in PRGenerator memoryAlloc :: Alloc RandomState unsafeToPointer :: RandomState -> Ptr Word8 |
:: (RandomState -> IO a) | The action that requires csprg state. |
-> IO a |
Execute an action that takes the CSPRG state.
randomByteString :: LengthUnit l => l -> RandomState -> IO ByteString Source #
Generate a random byteString.
Elements that can be randomly generated.
Nothing
random :: RandomState -> IO a Source #
default random :: RandomStorable a => RandomState -> IO a Source #
Instances
Generating sensitive data
Sensitive data like long term asymmetric keys need to be handled
with care as they may be inadvertently leaked into permanent
storage when memory is swapped out. Most of the time such keys are
generated using cryptographically pseudo-random bytes. However, a
direct approach, namely using random
, to generate them hides a
subtle bug. For example the code below is unsafe.
-- WARNING: Not safe from swapping main :: withSecureRandomState myAction myAction :: MySecretMem -> RandomState -> IO () myAction mySecMem rstate = do secret <- random rstate -- the pure value secret is in -- the haskell heap and therefore -- escapes locking initialise secret mysecmem doSomething
The random
interface gives a pure Haskell value and is stored in
the Haskell heap. Although memory locking is often available on
modern operating systems, it is impossible to lock this value as
the garbage collector keeps moving values around.
How can we work around this problem ? The intention of the programmer when using the above code was to randomise the contents of the mySecMem memory element. We recommend converting the above code to the following
main = withSecureRandomisedMemory action myAction :: MySecretMem -> RandomState -> IO () myAction mySecMem rstate = do randomiseMemory mySecMem doSomething
The above code, though correct, is fragile as missing out on the
randomiseMemory call can jeopardise the safety of the code. Often
the randomisation is required only at the beginning of the task and
in this case it is better to use the safer alternative
withSecureRandomisedMemory
randomiseMemory :: WriteAccessible mem => mem -> RandomState -> IO () Source #
Randomise the contents of an accessible memory.
Run a memory action which is passed a memory cell whose contents are randomised with cryptographically secure pseudo-random bytes.
withSecureRandomisedMemory Source #
Similar to withRandomisedMemory
but all memory allocation is
locked. Use this when the randomised content is to be protected
from swapping.
withSecureRandomState Source #
:: Memory mem | |
=> (mem -> RandomState -> IO a) | The action that requires random state |
-> IO a |
Execute an action that takes a memory element and random state such that all the memory allocated for both of them is locked.
Low level code
fillRandomBytes :: (LengthUnit l, Pointer ptr) => l -> Dest (ptr a) -> RandomState -> IO () #
class Storable a => RandomStorable a where Source #
Subclass of Storable
which can be randomly generated. It might
appear that all instances of the class Storable
should be
be instances of this class, after all we know the size of the
element, why not write that many random bytes. In fact, this module
provides an unsafeFillRandomElements
which does that. However, we
do not give a blanket definition for all storables because for
certain refinements of a given type, like for example, Word8's
modulo 10, unsafeFillRandomElements
introduces unacceptable
skews.
:: Int | number of elements to fill |
-> Ptr a | The buffer to fill |
-> RandomState | |
-> IO () |
Fill the buffer with so many random elements of type a.
Instances
fillRandom :: (RandomStorable a, Pointer ptr) => Int -> ptr a -> RandomState -> IO () Source #
Fill the given generalised pointer buffer with random elements.
unsafeFillRandomElements :: Storable a => Int -> Ptr a -> RandomState -> IO () Source #
This is a helper function that has been exported to simplify the
definition of a RandomStorable
instance for Storable
types. However, there is a reason why we do not give a blanket
instance for all instances of the Storable
class and why this
function is unsafe. This function generates a random element of
type a
by generating n
random bytes where n
is the size of
the elements of a
. For instances that range the entire n
byte
space this is fine. However, if the type is actually a refinement
of such a type, (consider a
modulo Word8
10
for example) this
function might generate unacceptable skew in the
distribution. Hence this function is prefixed unsafe.
reseed :: RandomState -> IO () #
Information
entropySource :: String #