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

Data.SensitiveBytes.Internal

Description

The sensitive data type internals.

Synopsis

Documentation

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.

data SodiumInitialised Source #

A trivial proof that sodium_init has been called.

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).

Constructors

SensitiveBytes 

Fields

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 () #

allocate Source #

Arguments

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

Size of the array (in bytes).

-> m (SensitiveBytes s) 

Allocate bytes in a protected memory region.

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

free :: forall s m. (MonadIO m, WithSecureMemory) => SensitiveBytes s -> m () Source #

Free bytes previously allocated in a protected memory region.

unsafePtr :: SensitiveBytes s -> Ptr () Source #

Get the underlying data pointer.

This function is unsafe, because it discards the second-order context and thus can allow the pointer to escape its scope and be used after free.

resized Source #

Arguments

:: forall s. Int

New data size.

-> SensitiveBytes s

What to resize.

-> SensitiveBytes s 

Rewrite the recorded size of the data.

This is a very dangerous internal-only function. It is essentially a hack that allows other functions exported from this library to efficiently read data of unknown size by first allocating a large buffer and then tweaking the ByteArrayAccess instance to return the size that is smaller than what was actually allocated.

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.