krypteia-memory 0.2.0

TLSF-based memory allocator for the krypteia cryptographic workspace, configurable between platform malloc/free (os-alloc) and a self-managed heap over a caller-provided RAM block (self-alloc) for embedded targets.
Documentation
// SPDX-License-Identifier: Apache-2.0
// Copyright 2026 Cédric Mesnil <cslashm@pm.me>

//! Shared memory allocator for the krypteia cryptographic workspace.
//!
//! This crate provides the workspace allocator — a TLSF heap over a
//! caller-provided RAM block, or a thin shim over the platform
//! `malloc`/`free`. On targets without an OS heap it is registered as
//! the `#[global_allocator]` (via the `global-alloc` feature) by
//! `arcana_ffi` and `tessera_ffi`. `quantica_ffi` does not depend on
//! this crate — the post-quantum FFI performs no heap allocation of
//! its own.
//!
//! # Feature flags
//!
//! | Feature        | Behaviour                                                          |
//! |----------------|--------------------------------------------------------------------|
//! | `os-alloc`     | The platform provides `malloc`/`free`. Init is a no-op. Default.    |
//! | `self-alloc`   | TLSF allocator over a caller-provided RAM block (`no_std`).         |
//! | `global-alloc` | Implies `self-alloc` and registers it as `#[global_allocator]` for the FFI crates. |
//!
//! Enable **exactly one** allocator backend. `os-alloc` (the default)
//! and `self-alloc` are mutually exclusive (enforced by a
//! `compile_error!` below); `global-alloc` is a superset of
//! `self-alloc`.
//!
//! # Usage from C (bare-metal)
//!
//! ```c
//! #include "krypteia.h"
//!
//! static uint8_t heap[8192];
//!
//! int main(void) {
//!     krypteia_init(heap, sizeof(heap));
//!     // … use arcana or quantica APIs …
//! }
//! ```

#![cfg_attr(feature = "self-alloc", no_std)]

#[cfg(all(feature = "self-alloc", feature = "os-alloc"))]
compile_error!("features `os-alloc` and `self-alloc` are mutually exclusive");

// ====================================================================
// os-alloc: the platform already has malloc/free — nothing to do
// ====================================================================

#[cfg(feature = "os-alloc")]
mod os_alloc {
    /// Memory allocation statistics.
    #[derive(Clone, Copy, Debug, Default)]
    pub struct MemStats {
        /// Bytes currently allocated.
        pub used: usize,
        /// Bytes still available.
        pub free: usize,
        /// High-water mark since init.
        pub peak: usize,
    }

    /// No-op initialiser for `os-alloc` mode (the platform heap needs no
    /// setup).
    ///
    /// # Parameters
    /// - `_base`: ignored (the OS owns the heap region).
    /// - `_size`: ignored.
    ///
    /// # Returns
    /// Always `0` (success), matching the `self-alloc` `krypteia_init`
    /// contract (`0` = ok, `-1` = failure) so FFI callers can treat both
    /// backends identically.
    ///
    /// # Safety
    ///
    /// Always safe; arguments are ignored.
    pub unsafe fn krypteia_init(_base: *mut u8, _size: usize) -> i32 {
        0
    }

    /// Returns zeroed stats in `os-alloc` mode (the OS tracks its
    /// own heap; we have no visibility).
    pub fn memory_stats() -> MemStats {
        MemStats::default()
    }
}

#[cfg(feature = "os-alloc")]
pub use os_alloc::*;

// ====================================================================
// self-alloc: TLSF allocator over a caller-provided RAM block
// ====================================================================

#[cfg(feature = "self-alloc")]
mod self_alloc;

#[cfg(feature = "self-alloc")]
pub use self_alloc::*;