ProtoCore v0.0.1
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
secure.h File Reference

Secure pool accessor - borrows that hold key material. More...

#include "protocore_config.h"
#include "shared_primitives/span.h"
#include <stddef.h>
#include <stdint.h>

Go to the source code of this file.

Classes

class  SecureBorrow
 A secure borrow whose acquire and release are one call each. More...
 
class  SecureScope
 RAII scope guard for secure borrows - marks on entry, wipes and reclaims on every exit. More...
 

Functions

void * pc_secure_alloc (size_t n, size_t align)
 Borrow n bytes of secure storage, aligned to align.
 
pc_span pc_secure_span (size_t n, size_t align)
 Borrow n secure bytes as a span whose capacity is bound to the allocation.
 
size_t pc_secure_mark (void)
 Capture the current position, to be handed to pc_secure_release().
 
void pc_secure_release (size_t mark)
 Wipe and reclaim everything borrowed since mark.
 
void pc_secure_reset (void)
 Wipe and reclaim the whole slot.
 
size_t pc_secure_used (void)
 Bytes currently handed out.
 
size_t pc_secure_high_water (void)
 Peak bytes ever handed out, for sizing PC_SECURE_ARENA_SIZE.
 
size_t pc_secure_capacity (void)
 Total per-slot capacity in bytes (PC_SECURE_ARENA_SIZE).
 
bool pc_secure_owns (const void *p)
 True if p points inside the secure pool.
 
int pc_secure_slot_of (const void *p)
 Which secure slot owns p, or -1 if p is not in the secure pool.
 

Detailed Description

Secure pool accessor - borrows that hold key material.

The same pool mechanism as the plaintext side (pc_arena, mmgr/arena), instantiated a second time. The resource and its mechanics are identical - one instance per worker slot, compile-time sized, double-ended, fail-closed, high-water reported. What differs is the access and control layer, and the difference is security:

  • Release wipes. pc_secure_release() and pc_secure_reset() zero the region being reclaimed before it becomes available again. On the plaintext side reclaiming is just an offset move; a secret must not outlive its borrow, so here the wipe IS the release. That makes the rule structural instead of a discipline every caller has to remember on every return path - the form that had already been missed on two of the SSH key-exchange error paths.
  • Disjoint region. The two pools occupy different addresses, so pc_secure_owns() and pc_scratch_owns() are mutually exclusive by construction. A secure borrow can never be accepted where a plaintext one is expected, or the reverse, with no tagging and no metadata.

What belongs here. Anything whose bytes are key material: shared secrets, private scalars, derived keys, and the working state of an operation over them. Public wire values (a peer's public point, a ciphertext about to be transmitted, a staging buffer for an outbound frame) belong in the plaintext pool - putting them here only shrinks the room left for real secrets.

Lifetime is not the axis. Both pools carry long-lived and ephemeral allocations; the pool a borrow comes from is decided by whether its contents are secret, nothing else.

Author
Douglas Quigg (dstroy0)
Date
2026

Definition in file secure.h.

Function Documentation

◆ pc_secure_alloc()

void * pc_secure_alloc ( size_t  n,
size_t  align 
)

Borrow n bytes of secure storage, aligned to align.

Returns uninitialized memory (the pool wipes on release, not on hand-out). Returns nullptr if the request does not fit - callers MUST handle null and fail closed.

Parameters
nbytes requested.
alignrequired alignment in bytes, a power of two (0 selects the platform default).

Definition at line 134 of file secure.cpp.

References pc_arena_scratch_alloc_aligned().

Referenced by pc_secure_span().

◆ pc_secure_span()

pc_span pc_secure_span ( size_t  n,
size_t  align 
)

Borrow n secure bytes as a span whose capacity is bound to the allocation.

The preferred form: one argument sets both fields, so the capacity cannot drift from what was reserved. An over-budget request yields an empty span, so an omitted pc_span_ok() check writes nothing rather than dereferencing null.

Definition at line 142 of file secure.cpp.

References pc_secure_alloc(), and pc_span_from().

Referenced by pc_md_wants().

◆ pc_secure_mark()

size_t pc_secure_mark ( void  )

Capture the current position, to be handed to pc_secure_release().

Definition at line 147 of file secure.cpp.

References pc_arena_scratch_mark().

◆ pc_secure_release()

void pc_secure_release ( size_t  mark)

Wipe and reclaim everything borrowed since mark.

The wipe happens BEFORE the position moves, so the bytes are already zero at the instant they become available again - there is no window in which a subsequent borrow could be handed memory still holding the previous tenant's key material. Use SecureScope rather than calling this by hand, so no return path can skip it.

Definition at line 154 of file secure.cpp.

Referenced by SecureScope::~SecureScope().

◆ pc_secure_reset()

void pc_secure_reset ( void  )

Wipe and reclaim the whole slot.

Definition at line 161 of file secure.cpp.

References pc_arena::size.

◆ pc_secure_used()

size_t pc_secure_used ( void  )

Bytes currently handed out.

Definition at line 172 of file secure.cpp.

References pc_arena_scratch_used().

◆ pc_secure_high_water()

size_t pc_secure_high_water ( void  )

Peak bytes ever handed out, for sizing PC_SECURE_ARENA_SIZE.

Definition at line 178 of file secure.cpp.

References PC_SCRATCH_SLOTS, and pc_arena::scratch_hw.

◆ pc_secure_capacity()

size_t pc_secure_capacity ( void  )

Total per-slot capacity in bytes (PC_SECURE_ARENA_SIZE).

Definition at line 192 of file secure.cpp.

References PC_SECURE_ARENA_SIZE.

◆ pc_secure_owns()

bool pc_secure_owns ( const void *  p)

True if p points inside the secure pool.

One unsigned subtract and compare: the slot count and slot size are compile-time, so the pool is one region of known extent. Mutually exclusive with pc_scratch_owns() because the regions are disjoint - which is the whole access control, with no per-allocation bookkeeping.

Definition at line 197 of file secure.cpp.

◆ pc_secure_slot_of()

int pc_secure_slot_of ( const void *  p)

Which secure slot owns p, or -1 if p is not in the secure pool.

Definition at line 202 of file secure.cpp.

References PC_SECURE_ARENA_SIZE.