-
Notifications
You must be signed in to change notification settings - Fork 1
API Reference
This page describes the public client and Secure Partition interfaces present in the repository. Header files are authoritative; algorithm availability in PSA Crypto also depends on the selected wolfPSA and wolfCrypt build configuration.
- Headers
- Data Structures
- FF-M Client API
- Secure Partition API
- PSA Crypto
- Internal Trusted Storage
- Protected Storage
- Firmware Update
- Initial Attestation
- Lifecycle
- FF-M Gateway Veneers
- Error Codes
| API | Header | Version |
|---|---|---|
| FF-M client | include/psa/client.h |
1.0 |
| Secure Partition | include/psa/service.h |
FF-M 1.0 IPC plus a wolfTrust-specific backport of psa_irq_enable() from Arm's FF-M 1.1 Extension Beta, Issue 0 |
| Common status | include/psa/error.h |
PSA status values used by wolfTrust |
| PSA Crypto | lib/wolfPSA/wolfpsa/psa/crypto.h |
1.4 |
| Internal Trusted Storage | include/psa/internal_trusted_storage.h |
1.0 |
| Protected Storage | include/psa/protected_storage.h |
1.0 |
| Firmware Update | include/psa/update.h |
1.0 |
| Initial Attestation | lib/wolfPSA/wolfpsa/psa/initial_attestation.h |
1.0 API operations; see TF-M Compatibility for API and token-profile deviations |
| Lifecycle | include/psa/lifecycle.h |
FF-M 1.0, Secure Partition only |
| Gateway vector ABI | include/wolftrust/ffm_veneer.h |
wolfTrust ABI |
typedef struct psa_invec {
const void* base;
size_t len;
} psa_invec;
typedef struct psa_outvec {
void* base;
size_t len;
} psa_outvec;An input vector identifies caller-owned read-only bytes. An output vector
identifies caller-owned writable storage; psa_call updates
len to the number of bytes returned.
The descriptor arrays can hold up to PSA_MAX_IOVEC (4) vectors of either
kind. The current SPM accepts at most four vectors total across input and
output.
typedef struct psa_msg_t {
int32_t type;
psa_handle_t handle;
psa_client_id_t client_id;
void* rhandle;
size_t in_size[PSA_MAX_IOVEC];
size_t out_size[PSA_MAX_IOVEC];
} psa_msg_t;type is PSA_IPC_CONNECT, a service call type,
or PSA_IPC_DISCONNECT. The SPM supplies
client_id; a service must not derive identity from request data.
typedef uint64_t psa_storage_uid_t;
typedef uint32_t psa_storage_create_flags_t;
struct psa_storage_info_t {
size_t capacity;
size_t size;
psa_storage_create_flags_t flags;
};Defined flags are PSA_STORAGE_FLAG_NONE,
PSA_STORAGE_FLAG_WRITE_ONCE,
PSA_STORAGE_FLAG_NO_CONFIDENTIALITY, and
PSA_STORAGE_FLAG_NO_REPLAY_PROTECTION.
typedef uint8_t psa_fwu_component_t;
typedef struct psa_fwu_image_version_t {
uint8_t major;
uint8_t minor;
uint16_t patch;
uint32_t build;
} psa_fwu_image_version_t;
typedef struct psa_fwu_impl_info_t {
uint32_t staged_size;
} psa_fwu_impl_info_t;
typedef struct psa_fwu_component_info_t {
uint8_t state;
psa_status_t error;
psa_fwu_image_version_t version;
uint32_t max_size;
uint32_t flags;
uint32_t location;
psa_fwu_impl_info_t impl;
} psa_fwu_component_info_t;wolfTrust exposes component 0. The public header defines a
16-byte write alignment and a maximum block size of 1008 bytes for the
STM32H563 service transport.
typedef struct wt_ffm_veneer_invec {
const void* base;
uint32_t len;
} wt_ffm_veneer_invec_t;
typedef struct wt_ffm_veneer_outvec {
void* base;
uint32_t len;
} wt_ffm_veneer_outvec_t;
typedef struct wt_ffm_veneer_iovec {
wt_ffm_veneer_invec_t in[WT_FFM_VENEER_IOVEC_MAX];
wt_ffm_veneer_outvec_t out[WT_FFM_VENEER_IOVEC_MAX];
uint32_t in_count;
uint32_t out_count;
} wt_ffm_veneer_iovec_t;This fixed-width descriptor crosses the CMSE boundary. The Secure gateway copies it before validating or using its fields.
uint32_t psa_framework_version(void);Returns PSA_FRAMEWORK_VERSION, currently 0x0100.
uint32_t psa_version(uint32_t sid);Returns the accessible service version, or PSA_VERSION_NONE when the
service is absent or not available to the caller.
psa_handle_t psa_connect(uint32_t sid, uint32_t version);Opens a connection-based service. A positive value is a valid handle; a non-positive value is an error status.
psa_status_t psa_call(psa_handle_t handle, int32_t type,
const psa_invec* in_vec, size_t in_len,
psa_outvec* out_vec, size_t out_len);Sends one synchronous copied-vector request. The reference target supports up to four vectors total across input and output.
void psa_close(psa_handle_t handle);Closes a valid connection and queues a disconnect message for its service.
These functions are for Secure Partition service loops, not Non-secure applications.
psa_signal_t psa_wait(psa_signal_t signal_mask, uint32_t timeout);
psa_status_t psa_get(psa_signal_t signal, psa_msg_t* msg);
void psa_set_rhandle(psa_handle_t msg_handle, void* rhandle);
size_t psa_read(psa_handle_t msg_handle, uint32_t invec_idx,
void* buffer, size_t num_bytes);
size_t psa_skip(psa_handle_t msg_handle, uint32_t invec_idx,
size_t num_bytes);
void psa_write(psa_handle_t msg_handle, uint32_t outvec_idx,
const void* buffer, size_t num_bytes);
void psa_reply(psa_handle_t msg_handle, psa_status_t status);
void psa_notify(int32_t partition_id);
void psa_clear(void);
void psa_eoi(psa_signal_t irq_signal);
void psa_irq_enable(psa_signal_t irq_signal);
void psa_panic(void) __attribute__((noreturn));psa_wait blocks the current Secure coroutine until a selected
service or interrupt signal is ready. psa_get pins one message;
psa_read and psa_write move copied data; and
psa_reply completes the call. Unsupported or invalid Secure-caller
use may panic only that partition, after which the recovery policy applies.
wolfTrust vendors wolfPSA's PSA Crypto 1.4 header. The header is the complete
API contract; the functions below show the principal signatures used by the
reference guests. Declarations in the header do not guarantee implementation
availability. The active user_settings.h controls which algorithms and
optional extensions are built.
psa_status_t psa_crypto_init(void);
psa_status_t psa_get_key_attributes(psa_key_id_t key,
psa_key_attributes_t* attributes);
void psa_reset_key_attributes(psa_key_attributes_t* attributes);
psa_status_t psa_import_key(const psa_key_attributes_t* attributes,
const uint8_t* data, size_t data_length,
psa_key_id_t* key);
psa_status_t psa_generate_key(const psa_key_attributes_t* attributes,
psa_key_id_t* key);
psa_status_t psa_destroy_key(psa_key_id_t key);
psa_status_t psa_export_key(psa_key_id_t key, uint8_t* data,
size_t data_size, size_t* data_length);
psa_status_t psa_export_public_key(psa_key_id_t key, uint8_t* data,
size_t data_size, size_t* data_length);Key attributes are configured with the inline accessors declared by
psa/crypto.h. Export remains subject to the key lifetime and usage
policy; protected private keys used by Secure services do not have a private
export path.
psa_status_t psa_hash_compute(psa_algorithm_t alg,
const uint8_t* input, size_t input_length,
uint8_t* hash, size_t hash_size,
size_t* hash_length);
psa_status_t psa_hash_compare(psa_algorithm_t alg,
const uint8_t* input, size_t input_length,
const uint8_t* hash, size_t hash_length);
psa_status_t psa_mac_compute(psa_key_id_t key, psa_algorithm_t alg,
const uint8_t* input, size_t input_length,
uint8_t* mac, size_t mac_size,
size_t* mac_length);
psa_status_t psa_mac_verify(psa_key_id_t key, psa_algorithm_t alg,
const uint8_t* input, size_t input_length,
const uint8_t* mac, size_t mac_length);The header also declares the standard multipart hash and MAC setup, update, finish, verify, clone, and abort calls.
psa_status_t psa_cipher_encrypt(psa_key_id_t key, psa_algorithm_t alg,
const uint8_t* input, size_t input_length,
uint8_t* output, size_t output_size,
size_t* output_length);
psa_status_t psa_cipher_decrypt(psa_key_id_t key, psa_algorithm_t alg,
const uint8_t* input, size_t input_length,
uint8_t* output, size_t output_size,
size_t* output_length);
psa_status_t psa_aead_encrypt(psa_key_id_t key, psa_algorithm_t alg,
const uint8_t* nonce, size_t nonce_length,
const uint8_t* additional_data,
size_t additional_data_length,
const uint8_t* plaintext,
size_t plaintext_length,
uint8_t* ciphertext, size_t ciphertext_size,
size_t* ciphertext_length);
psa_status_t psa_aead_decrypt(psa_key_id_t key, psa_algorithm_t alg,
const uint8_t* nonce, size_t nonce_length,
const uint8_t* additional_data,
size_t additional_data_length,
const uint8_t* ciphertext,
size_t ciphertext_length,
uint8_t* plaintext, size_t plaintext_size,
size_t* plaintext_length);Multipart cipher and AEAD operations are also declared in the wolfPSA header.
psa_status_t psa_sign_message(psa_key_id_t key, psa_algorithm_t alg,
const uint8_t* input, size_t input_length,
uint8_t* signature, size_t signature_size,
size_t* signature_length);
psa_status_t psa_verify_message(psa_key_id_t key, psa_algorithm_t alg,
const uint8_t* input, size_t input_length,
const uint8_t* signature,
size_t signature_length);
psa_status_t psa_sign_hash(psa_key_id_t key, psa_algorithm_t alg,
const uint8_t* hash, size_t hash_length,
uint8_t* signature, size_t signature_size,
size_t* signature_length);
psa_status_t psa_verify_hash(psa_key_id_t key, psa_algorithm_t alg,
const uint8_t* hash, size_t hash_length,
const uint8_t* signature,
size_t signature_length);
psa_status_t psa_raw_key_agreement(psa_algorithm_t alg,
psa_key_id_t private_key,
const uint8_t* peer_key,
size_t peer_key_length,
uint8_t* output, size_t output_size,
size_t* output_length);psa_status_t psa_key_derivation_setup(
psa_key_derivation_operation_t* operation, psa_algorithm_t alg);
psa_status_t psa_key_derivation_input_bytes(
psa_key_derivation_operation_t* operation,
psa_key_derivation_step_t step,
const uint8_t* data, size_t data_length);
psa_status_t psa_key_derivation_input_key(
psa_key_derivation_operation_t* operation,
psa_key_derivation_step_t step, psa_key_id_t key);
psa_status_t psa_key_derivation_output_bytes(
psa_key_derivation_operation_t* operation,
uint8_t* output, size_t output_length);
psa_status_t psa_key_derivation_output_key(
const psa_key_attributes_t* attributes,
psa_key_derivation_operation_t* operation,
psa_key_id_t* key);
psa_status_t psa_key_derivation_abort(
psa_key_derivation_operation_t* operation);
psa_status_t psa_generate_random(uint8_t* output, size_t output_size);psa_status_t psa_its_set(psa_storage_uid_t uid, size_t data_length,
const void* p_data,
psa_storage_create_flags_t create_flags);
psa_status_t psa_its_get(psa_storage_uid_t uid, size_t data_offset,
size_t data_size, void* p_data,
size_t* p_data_length);
psa_status_t psa_its_get_info(psa_storage_uid_t uid,
struct psa_storage_info_t* p_info);
psa_status_t psa_its_remove(psa_storage_uid_t uid);The public client shim limits each write, and therefore every ITS object it
creates, to 512 bytes. The underlying Secure vault uses a 1024-byte object
buffer, and its 24-byte request header caps one copied vault response at 1000
bytes. data_offset remains useful when the caller supplies an output buffer
smaller than the object. UID zero is invalid.
The current ITS and Protected Storage paths always enforce
PSA_STORAGE_FLAG_WRITE_ONCE, including during
PSA_ROT_PROVISIONING. PSA Secure Storage 1.0 requires that flag not to be
enforced in the provisioning lifecycle, so this is a known lifecycle deviation.
psa_status_t psa_ps_set(psa_storage_uid_t uid, size_t data_length,
const void* p_data,
psa_storage_create_flags_t create_flags);
psa_status_t psa_ps_get(psa_storage_uid_t uid, size_t data_offset,
size_t data_size, void* p_data,
size_t* p_data_length);
psa_status_t psa_ps_get_info(psa_storage_uid_t uid,
struct psa_storage_info_t* p_info);
psa_status_t psa_ps_remove(psa_storage_uid_t uid);
psa_status_t psa_ps_create(psa_storage_uid_t uid, size_t capacity,
psa_storage_create_flags_t create_flags);
psa_status_t psa_ps_set_extended(psa_storage_uid_t uid, size_t data_offset,
size_t data_length, const void* p_data);
uint32_t psa_ps_get_support(void);The current service returns 0 from psa_ps_get_support.
It returns PSA_ERROR_NOT_SUPPORTED for
psa_ps_create and psa_ps_set_extended. The core
set/get/get-info/remove calls are implemented.
Every Protected Storage object created through the public shim is likewise
limited to 512 bytes. The underlying Secure vault still uses a 1024-byte object
buffer and caps one copied vault response at 1000 bytes.
Objects remain sealed and counter-bound when callers request the
NO_CONFIDENTIALITY or NO_REPLAY_PROTECTION hints. The current
psa_ps_get_info behavior echoes those requested flags instead of reporting
the stronger protection actually applied.
psa_status_t psa_fwu_query(psa_fwu_component_t component,
psa_fwu_component_info_t* info);
psa_status_t psa_fwu_start(psa_fwu_component_t component,
const void* manifest, size_t manifest_size);
psa_status_t psa_fwu_write(psa_fwu_component_t component,
size_t image_offset,
const void* block, size_t block_size);
psa_status_t psa_fwu_finish(psa_fwu_component_t component);
psa_status_t psa_fwu_cancel(psa_fwu_component_t component);
psa_status_t psa_fwu_clean(psa_fwu_component_t component);
psa_status_t psa_fwu_install(void);
psa_status_t psa_fwu_request_reboot(void);
psa_status_t psa_fwu_reject(psa_status_t error);
psa_status_t psa_fwu_accept(void);psa_fwu_start accepts either NULL, 0, which binds the
version from the staged wolfBoot header at finish, or a four-byte detached
monotonic version. The current service supports one primary component and
commits installation at authenticated reboot. It does not offer a persistent
trial state, so psa_fwu_accept returns
PSA_ERROR_NOT_SUPPORTED.
Unlike PSA Firmware Update 1.0, the service rejects unaligned block sizes rather
than padding them and returns PSA_ERROR_INVALID_ARGUMENT for unknown
component IDs instead of PSA_ERROR_DOES_NOT_EXIST.
psa_status_t psa_initial_attest_get_token(
const uint8_t* auth_challenge, size_t challenge_size,
uint8_t* token_buf, size_t token_buf_size,
size_t* token_size);
psa_status_t psa_initial_attest_get_token_size(
size_t challenge_size, size_t* token_size);Accepted challenge sizes are 32, 48, and 64 bytes. The token is a tagged
COSE_Sign1 object using ES256. The implementation limit is 640 bytes, although
the vendored public header does not currently define
PSA_INITIAL_ATTEST_MAX_TOKEN_SIZE. The size query returns the exact encoded
size without producing a signature. A non-NULL token buffer with zero capacity
returns PSA_ERROR_INVALID_ARGUMENT; other undersized buffers return
PSA_ERROR_BUFFER_TOO_SMALL.
The token advertises tag:psacertified.org,2023:psa#tfm but has the
token-profile deviations listed in TF-M Compatibility and must not be
represented as conformant with that profile. The only working Non-secure
attestation adapter currently resides at
tests/firmware/zephyr-stm32h5/module/wolftrust-tee/src/wolftrust_attestation_client.c.
The vendored lib/wolfPSA/src/psa_attestation.c is a stub that returns
PSA_ERROR_NOT_SUPPORTED; do not link it instead of or alongside the Zephyr
adapter because both define the same public PSA symbols.
uint32_t psa_rot_lifecycle_state(void);This function is linked into the Secure image for scheduled Secure Partitions and returns the authenticated lifecycle value supplied by the boot handoff. There is no Non-secure client adapter or CMSE veneer for it. Defined PSA state values include:
| Define | Value |
|---|---|
PSA_LIFECYCLE_UNKNOWN |
0x0000 |
PSA_LIFECYCLE_ASSEMBLY_AND_TEST |
0x1000 |
PSA_LIFECYCLE_PSA_ROT_PROVISIONING |
0x2000 |
PSA_LIFECYCLE_SECURED |
0x3000 |
PSA_LIFECYCLE_NON_PSA_ROT_DEBUG |
0x4000 |
PSA_LIFECYCLE_RECOVERABLE_PSA_ROT_DEBUG |
0x5000 |
PSA_LIFECYCLE_DECOMMISSIONED |
0x6000 |
Applications should normally call the PSA client API. The generated CMSE import library binds those calls to these five target entry points:
uint32_t WolfTrust_FFM_FrameworkVersion(void);
uint32_t WolfTrust_FFM_ServiceVersion(uint32_t sid);
int32_t WolfTrust_FFM_Connect(uint32_t sid, uint32_t version);
int32_t WolfTrust_FFM_Call(int32_t handle, int32_t type,
wt_ffm_veneer_iovec_t* ns_iovec);
void WolfTrust_FFM_Close(int32_t handle);The definitions are in src/arch/armv8m/ffm_nsc.c. The shared
vector layout is in include/wolftrust/ffm_veneer.h, and
build/secure_cmse_implib.o is the Non-secure link import.
| Define | Value | Meaning |
|---|---|---|
PSA_SUCCESS |
0 | Operation completed |
PSA_ERROR_PROGRAMMER_ERROR |
-129 | Invalid client use requiring programmer correction |
PSA_ERROR_CONNECTION_REFUSED |
-130 | Service refused the connection |
PSA_ERROR_CONNECTION_BUSY |
-131 | Service cannot accept another connection |
PSA_ERROR_GENERIC_ERROR |
-132 | Unclassified failure |
PSA_ERROR_NOT_PERMITTED |
-133 | Policy denied the operation |
PSA_ERROR_NOT_SUPPORTED |
-134 | Interface or option is not implemented |
PSA_ERROR_INVALID_ARGUMENT |
-135 | Argument value is invalid |
PSA_ERROR_INVALID_HANDLE |
-136 | Handle is invalid for this call |
PSA_ERROR_BAD_STATE |
-137 | Operation is invalid in the current state |
PSA_ERROR_BUFFER_TOO_SMALL |
-138 | Output capacity is insufficient |
PSA_ERROR_ALREADY_EXISTS |
-139 | Object already exists |
PSA_ERROR_DOES_NOT_EXIST |
-140 | Object does not exist |
PSA_ERROR_INSUFFICIENT_MEMORY |
-141 | Volatile memory is insufficient |
PSA_ERROR_INSUFFICIENT_STORAGE |
-142 | Persistent storage is insufficient |
PSA_ERROR_INSUFFICIENT_DATA |
-143 | Input data is incomplete |
PSA_ERROR_SERVICE_FAILURE |
-144 | Service failed |
PSA_ERROR_COMMUNICATION_FAILURE |
-145 | Service communication failed |
PSA_ERROR_STORAGE_FAILURE |
-146 | Persistent storage operation failed |
PSA_ERROR_HARDWARE_FAILURE |
-147 | Hardware operation failed |
PSA_ERROR_INVALID_SIGNATURE |
-149 | Signature or authentication tag is invalid |
PSA_ERROR_CORRUPTION_DETECTED |
-151 | Corruption was detected |
PSA_ERROR_DATA_CORRUPT |
-152 | Stored data is corrupt |
PSA_ERROR_DATA_INVALID |
-153 | Supplied data is invalid |
PSA_OPERATION_INCOMPLETE |
-248 | Interruptible operation has more work |
| Define | Value | Meaning |
|---|---|---|
PSA_SUCCESS_REBOOT |
1 | Completion requires reboot |
PSA_SUCCESS_RESTART |
2 | Completion requires service restart |
PSA_ERROR_DEPENDENCY_NEEDED |
-156 | Another component is required |
PSA_ERROR_FLASH_ABUSE |
-160 | Flash use violates update policy |
PSA_ERROR_INSUFFICIENT_POWER |
-161 | Power is insufficient for the operation |
For service availability and deviations, see Services and TF-M Compatibility.