libsodium-bindings-0.0.1.0: FFI bindings to libsodium
Copyright(C) Hécate Moonlight 2022
LicenseBSD-3-Clause
MaintainerThe Haskell Cryptography Group
PortabilityGHC only
Safe HaskellSafe-Inferred
LanguageHaskell2010

LibSodium.Bindings.SecureMemory

Description

 
Synopsis

Introduction

This module provides bindings to the secure memory functions provided by Libsodium. It is intended to be qualified on import:

import qualified LibSodium.Bindings.SecureMemory as SecureMemory

It is recommended to disable swap partitions on machines processing sensitive data or, as a second choice, use encrypted swap partitions.

For similar reasons, on Unix systems, one should also disable core dumps when running crypto code outside a development environment. This can be achieved using a shell built-in such as ulimit or programmatically using setResourceLimit:

>>> setResourceLimit ResourceCoreFileSize (ResourceLimits 0 0)

On operating systems where this feature is implemented, kernel crash dumps should also be disabled.

The sodiumMlock function wraps mlock(2) and VirtualLock().

Note: Many systems place limits on the amount of memory that may be locked by a process. Care should be taken to raise those limits (e.g. Unix ulimits) where necessary.

Zeroing memory

sodiumMemZero Source #

Arguments

:: Ptr Word8

Start pointer

-> CSize

Length in bytes of the area to zero

-> IO () 

Overwrite the memory region starting at the pointer address with zeros.

memset() and hand-written code can be silently stripped out by an optimizing compiler or the linker.

This function tries to effectively zero the amount of bytes starting at the provided pointer, even if optimizations are being applied to the code.

See: sodium_memzero()

Since: 0.0.1.0

Locking memory

sodiumMlock Source #

Arguments

:: Ptr Word8

Start pointer

-> CSize

Size of the memory region to lock

-> IO CInt

Returns 0 on success, -1 if any system limit is reached.

Lock a memory region starting at the pointer address. This can help avoid swapping sensitive data to disk.

See: sodium_mlock()

Since: 0.0.1.0

sodiumMunlock Source #

Arguments

:: Ptr Word8

Start pointer

-> CSize

Size of the memory region to unlock

-> IO CInt 

Unlock the memory region by overwriting it with zeros and and flagging the pages as swappable again. Calling sodiumMemZero prior to sodiumMunlock is thus not required.

On systems where it is supported, sodiumMlock also wraps madvise(2) and advises the kernel not to include the locked memory in core dumps. The sodiumMunlock function also undoes this additional protection.

See: sodium_munlock()

Since: 0.0.1.0

Allocating memory

sodiumMalloc Source #

Arguments

:: forall a. CSize

Amount of memory to allocate

-> IO (Ptr a) 

This function takes an amount (called size) and returns a pointer from which exactly size contiguous bytes of memory can be accessed. The pointer may be nullPtr and there may be an error when allocating memory, through errno. Upon failure, errno will be set to eNOMEM

It is recommended that the caller use Foreign.C.Error to handle potential failure.

Moreover, sodiumInit must be called before using this function.

Explanation

The allocated region is placed at the end of a page boundary, immediately followed by a guard page (or an emulation, if unsupported by the platform). As a result, accessing memory past the end of the region will immediately terminate the application.

A canary is also placed right before the returned pointer. Modifications of this canary are detected when trying to free the allocated region with sodiumFree and cause the application to immediately terminate.

If supported by the platform, an additional guard page is placed before this canary to make it less likely for sensitive data to be accessible when reading past the end of an unrelated region. The allocated region is filled with 0xdb bytes to help catch bugs due to uninitialized data.

In addition, mlock(2) is called on the region to help avoid it being swapped to disk. Note however that mlock(2) may not be supported, may fail or may be a no-op, in which case sodiumMalloc will return the memory regardless, but it will not be locked. If you specifically need to rely on memory locking, consider calling sodiumMlock and checking its return value.

On operating systems supporting MAP_NOCORE or MADV_DONTDUMP, memory allocated this way will also not be part of core dumps. The returned address will not be aligned if the allocation size is not a multiple of the required alignment. For this reason, sodiumMalloc should not be used with packed or variable-length structures unless the size given to sodiumMalloc is rounded up to ensure proper alignment.

All the structures used by libsodium can safely be allocated using sodiumMalloc.

Allocating 0 bytes is a valid operation. It returns a pointer that can be successfully passed to sodiumFree.

⚠️ This is not a general-purpose allocation function, and requires 3 or 4 extra pages of virtual memory. Since it is very expensive, do not use it to allocate every-day memory.

See: sodium_malloc()

Since: 0.0.1.0

sodiumAllocArray Source #

Arguments

:: forall a. CSize

Amount of objects

-> CSize

Size of each objects

-> IO (Ptr a) 

This function takes an amount of objects and the size of each object, and returns a pointer from which this amount of objects that are of the specified size each can be accessed.

It provides the same guarantees as sodiumMalloc but also protects against arithmetic overflows when count * size exceeds SIZE_MAX.

See: sodium_allocarray()

Since: 0.0.1.0

sodiumFree :: forall a. Ptr a -> IO () Source #

Unlock and deallocate memory allocated using sodiumMalloc or sodiumAllocArray.

The memory region is filled with zeros before the deallocation.

See: sodium_free()

Since: 0.0.1.0

finalizerSodiumFree :: forall a. FinalizerPtr a Source #

Function pointer to use as ForeignPtr finalizer for sodium-allocated memory.

The memory region is filled with zeros before the deallocation.

See: sodium_free()

Since: 0.0.1.0