secure-memory-0.0.0.1: Securely allocated and deallocated memory.
Safe HaskellNone
LanguageHaskell2010

Data.SensitiveBytes

Description

The sensitive data type.

A typical usage looks something like this:

import Data.SensitiveBytes (SensitiveBytes, withSecureMemory, withSensitiveBytes)

your_function = withSecureMemory $ do
 {- some optional initialisation -}
 withSensitiveBytes 128 $ sb -> do
   {- work with sb using its ByteArrayAccess instance -}

Note that withSensitiveBytes can only be called withing a code block passed to withSecureMemory and its type will prevent your from doing otherwise.

You will typically read sensitive data into SensitiveBytes using functions in Data.SensitiveBytes.IO and then pass to some other function that will work with it using the ByteArrayAccess instance. Just make sure the function you pass it to does not copy the data and does not convert it to some other insecure byte-array-like type.

Synopsis

Library initialisation

withSecureMemory Source #

Arguments

:: forall m r. MonadIO m 
=> (WithSecureMemory => m r)

Action to perform.

-> m r 

This function performs the initialisation steps required for allocating data in secure memory regions.

The basic usage is to call this function and provide to it a block of code that will be allocating memory for sensitive data. The type of withSensitiveBytes is such that it can only be called withing such a code block.

Ideally, you should call withSecureMemory only once and deal with all your sensitive data within this single code block, however it is not a requirement – you can call it as many times as you wish and the only downside to doing so is that it will incur a tiny performance penalty.

In some rare circumstances this function secure memory initialisation may fail, in which case this function will throw SecureMemoryInitException.

type WithSecureMemory = Given SodiumInitialised Source #

A constraint for functions that require access to secure memory. The only way to satisfy it is to call withSecureMemory.

Allocation

data SensitiveBytes s Source #

Bytes that will be allocated in a secure memory location such that they will never be moved by the garbage collector and, hopefully, never swapped out to the disk (if the operating system supports this kind of protection).

Instances

Instances details
ByteArrayAccess (SensitiveBytes s) Source # 
Instance details

Defined in Data.SensitiveBytes.Internal

Methods

length :: SensitiveBytes s -> Int #

withByteArray :: SensitiveBytes s -> (Ptr p -> IO a) -> IO a #

copyByteArrayToPtr :: SensitiveBytes s -> Ptr p -> IO () #

withSensitiveBytes Source #

Arguments

:: forall s m r. (MonadIO m, MonadMask m, WithSecureMemory) 
=> Int

Size of the array (in bytes).

-> (SensitiveBytes s -> m r)

Action to perform with memory allocated.

-> m r 

Allocate a byte array in a secure memory region.

This function guarantees that:

  1. The garbage collector will not touch the allocated memory and will not try to copy the sensitive data.
  2. The memory will be zeroed-out and freed as soon as the computation finishes.

Additionally, it will try its best (subject to the support from the operating system) to do the following:

  1. Allocate the buffer at the end of a page and make sure that the following page is not mapped, so trying to access past the end of the buffer will crash the program.
  2. Place a canary immediately before the buffer, check that it was not modified before deallocating the memory, and crash the program otherwise.
  3. mlock the memory to make sure it will not be paged to the disk.
  4. Ask the operating system not to include this memory in core dumps.

Just as with regular malloc, allocation can fail, for example, if there is not enough memory. In this case, the function will throw SensitiveBytesAllocException.