Skip to content

Security Model

github-actions[bot] edited this page Sep 22, 2026 · 2 revisions

Security Model

wolfTrust protects Secure services from application domains through the isolation mechanisms supplied by an architecture and target port. This page documents the current STM32H563 reference security profile, which uses Armv8-M TrustZone and STM32 GTZC attribution for its Secure boundary and guest RAM isolation. Its security properties come from the authenticated boot chain, hardware attribution, SPM-owned identity, copied IPC, and service-specific policy.

Trusted computing base

The reference trusted computing base includes:

  • wolfBoot and its verification key
  • the wolfTrust Secure image and generated manifest
  • wolfCrypt, wolfHSM, wolfHAL, and wolfCOSE code linked into that image
  • Armv8-M exception, TrustZone, and MPU behavior
  • STM32H563 GTZC and flash option-byte configuration
  • privileged wolfTrust SVC and fault handlers
  • the target entropy and flash implementations

Non-secure guest kernels and applications are not trusted. A Secure Partition is trusted for the resources its manifest domain can access, but it is not trusted to access arbitrary SPM or peer-partition writable state.

Enforced boundaries

Boundary Enforcement
Non-secure to Secure SAU/IDAU attribution and exactly five CMSE FF-M gateway veneers
Guest RAM to guest RAM GTZC MPCBB attribution closes the shared guest-RAM extent and opens only the scheduled guest's writable SRAM blocks
Guest request memory CMSE security checks, active-guest range checks, overflow checks, vector-count limits, and copied transfers
Guest to service Manifest service policy, connection ownership, generated handles, and SPM-stamped client identity
Secure Partition writable state Unprivileged Secure threads and a per-partition Secure MPU table
Secure Partition to hardware backend Operation-specific SVC gates pinned to the expected partition identity
Persistent objects Vault ownership tuple, checked wolfHSM NVM operations, and key/storage type separation

The only Non-secure entry path

The linked Secure image exports exactly these Non-secure-callable functions:

  • WolfTrust_FFM_FrameworkVersion
  • WolfTrust_FFM_ServiceVersion
  • WolfTrust_FFM_Connect
  • WolfTrust_FFM_Call
  • WolfTrust_FFM_Close

The link rule records symbols with nm and rejects any extra or missing __acle_se_* entry. Service-specific operations ride psa_call rather than adding more veneers.

For a call, the gateway:

  1. obtains the active guest ID from monitor state;
  2. converts guest N to PSA client ID -(N + 1);
  3. checks and copies the veneer vector structure once;
  4. validates input and output counts;
  5. validates each range as Non-secure and within that guest's declared readable or writable memory; and
  6. copies request bytes into SPM-owned buffers before service dispatch.

A guest cannot choose its PSA identity. A racing write to the original vector descriptor cannot alter the copied descriptor used by the SPM.

Handles and service policy

Connections and messages carry an owner, type, generation, and state. The SPM rejects stale handles, wrong-owner handles, invalid transitions, and accesses disallowed by the manifest. Secure Partition dependencies are also checked: for example, ITS and Protected Storage may connect to the Secure-only vault, while a Non-secure client may not.

Each copied call is bounded to four vectors total across input and output and to the SPM transfer budget. Individual services impose smaller protocol bounds where needed.

Guest isolation

Only the selected guest's Non-secure RAM is attributed Non-secure by the GTZC curtain. The monitor also installs that guest's Non-secure MPU regions and interrupt mask before returning to it. Reference guests currently run privileged Non-secure code and can reprogram their MPU and Non-secure NVIC state, so those controls are scheduling policy rather than adversarial boundaries. Guest RAM windows are non-overlapping and hardware-isolated by GTZC.

Guest flash windows are non-overlapping but share one Non-secure attribution window and remain mutually readable. WRP plus WT_GUEST_FLASH_WRP=1 protects their integrity, not confidentiality. A hostile guest can also reach peripherals left Non-secure by the boot chain; manifest resource lists do not independently enforce peripheral ownership in the current port.

On a guest fault, wolfTrust captures the reason, masks its interrupts, and applies the bounded restart policy. If restart is allowed, it clears RAM marked for restart and reconstructs the initial context. The image is verified again before the guest runs; failed verification or an exhausted restart budget leaves the guest quarantined.

Secure Partition isolation

Every shipped service loop runs as a scheduled unprivileged Secure coroutine. Its Secure MPU view contains:

  • shared read/execute Secure image text;
  • read-only Secure image constants;
  • its private stack and declared writable resources; and
  • explicitly shared resources such as the keystore band where required.

Privileged handlers retain the SPM view. Flash, entropy, NVM lock, and reset operations are available only through narrow SVC operations that check the originating partition.

This is writable-state isolation inside one linked image. Shared executable text is not per-partition code isolation, and the HSM, vault, and attestation domains share the keystore data band required by their backends.

Per-guest cryptographic keys

The HSM service receives one copied wolfHSM request packet through FF-M IPC. The SPM-stamped negative client ID selects guest N, and the relay forces wolfHSM server client ID N + 1 before processing the packet. A client-provided communication ID therefore cannot select another guest's key namespace.

The guest-facing HSM relay rejects wolfHSM NVM message groups. Guests can use the intended cryptographic protocol but cannot directly reach vault objects, the firmware-version floor, the Protected Storage counter table, or the attestation key.

Storage protection

ITS and Protected Storage are front-end partitions. They forward every object operation to a vault service that is not available to Non-secure clients. The vault key is:

(front-end partition identity, SPM-stamped end-client identity, 64-bit UID)

ITS supports the core set/get/get-info/remove interface and the write-once flag. Protected Storage always adds sealing even when a caller supplies NO_CONFIDENTIALITY or NO_REPLAY_PROTECTION hints. The current psa_ps_get_info() implementation echoes those requested hint flags instead of reporting the stronger protection actually applied. Sealing uses AES-256-GCM with:

  • a device-local non-exportable key stored in wolfHSM NVM;
  • the object label as authenticated data;
  • a 12-byte nonce derived from a persisted per-write counter; and
  • a 16-byte authentication tag.

The counter is stored before ciphertext, preventing nonce reuse after an interrupted write. The live per-object counter also detects replay of a stale ciphertext unless an attacker can coherently roll back the counter store; see Threat Model.

Sealed replacement stages the authenticated prior object until the new counter mapping commits, then destroys the stage. An interrupted replacement restores that object without rolling back the global nonce counter. Replacing sealed data with unsealed data uses the same transaction and retires the old seal counter on commit. If the recovery copy is missing or invalid, the live object is kept only if it authenticates under the committed counter; otherwise that object is discarded and its counter retired. Other objects remain available. The vault requires wolfHSM's wh_NvmFlash backend, including its capacity and compaction callbacks, and rejects incompatible backends at initialization. The flash HAL may be supplied by the target port or the host RAM simulator.

Vault storage rejects its reserved key-object type. Guest cryptographic keys instead use the separate wolfHSM keystore behind SERVICE_HSM, where the relay binds operations to the caller's namespace.

Authenticated guest launch

The target image builder hashes the exact guest binary and records its guest ID, version, byte length, and SHA-256 digest in a slot inside wolfTrust. That slot is patched before wolfBoot signs the Secure image.

At boot, after initial guest-image validation and before any guest executes, wolfTrust checks the persistent Secure-image and recorded-guest version floors. Versions that pass the rollback check advance those floors.

During initial validation, immediately before a guest's first dispatch, and again after a restart, wolfTrust:

  • locates the guest's signed record;
  • rejects an empty or out-of-window image size;
  • checks the record version against the manifest minimum;
  • hashes exactly the recorded number of bytes and compares the digest in constant work.

When WT_GUEST_FLASH_WRP=1, launch also reads the STM32 WRP register and refuses the guest unless every flash group covering its full window is protected. This option is disabled in the generic default build because M33MU does not model WRP; enable it for the hardened STM32H563 image and provision the option bytes as described in STM32H5 Guide.

Static memory

The Secure wolfCrypt settings define both NO_WOLFSSL_MEMORY and WOLFSSL_NO_MALLOC. Stacks, IPC transfers, service state, HSM contexts, and cryptographic scratch space use fixed storage. Oversized requests fail instead of allocating.

Source anchors

See Threat Model for assumptions and residual risks.

Clone this wiki locally