Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
ae8355b
Add interruptible Crypto API operations
athoelke Jul 23, 2026
c61c37c
Add missing 'time' to 'bounded execution' text
athoelke Aug 4, 2026
a91f03d
Clarified wording on IOP usage
athoelke Aug 4, 2026
fd26d45
Add custom parameters for interruptible key generation
athoelke Aug 4, 2026
b2c08bd
Add support for contexts in interruptible signature and verify operat…
athoelke Aug 4, 2026
b9bdcfd
Clarify interruptible setup failure state
athoelke Aug 4, 2026
4c3a074
Clarify interruptible signature input states
athoelke Aug 4, 2026
6b109ed
Clarify interruptible completion summaries
athoelke Aug 4, 2026
d99722f
Use key agreement in interruptible operations example
athoelke Aug 4, 2026
52931b6
Allow empty messages in interruptible signatures
athoelke Aug 4, 2026
0f8b4fe
Clarify interruptible operation completion flows
athoelke Aug 4, 2026
df47928
Specify single-fragment interruptible signature errors
athoelke Aug 4, 2026
03a32a1
Clarify incomplete key-agreement output
athoelke Aug 4, 2026
e895c1b
Clarify persistent key collision timing
athoelke Aug 6, 2026
e5f75cf
Clarify key-agreement collision timing
athoelke Aug 6, 2026
059483d
Clarify single-fragment signature update errors
athoelke Aug 6, 2026
03f7eb1
Add deferred-signature interruptible verification
athoelke Aug 6, 2026
9ad0eb5
Clarify deferred verification flow setup
athoelke Aug 7, 2026
607c0e1
Editorial polishing
athoelke Aug 7, 2026
d61460e
Rename interruptible operation starts
athoelke Aug 7, 2026
93fe0ea
Clarify interruptible key-generation sequencing
athoelke Aug 11, 2026
12264c7
Clarify interruptible operation limits
athoelke Aug 11, 2026
db37ca2
Clarify interruptible start failure states
athoelke Aug 12, 2026
85cb388
Define key-creation APIs
athoelke Aug 14, 2026
a8d7690
Document interruptible key creation
athoelke Aug 14, 2026
65b21df
Clarify interruptible operation state errors
athoelke Aug 17, 2026
39d17de
Defer interruptible signature validation
athoelke Aug 19, 2026
31894e4
Classify interruptible signature state errors
athoelke Aug 19, 2026
c244864
Check interruptible signature permissions at setup
athoelke Aug 19, 2026
48de10f
Revise interruptible verification signature flow
athoelke Sep 8, 2026
8cdff16
Add GlobalPlatform copyright notices
athoelke Sep 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions doc/crypto/about/terms
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.. SPDX-FileCopyrightText: Copyright 2020-2022 Arm Limited and/or its affiliates
.. SPDX-FileCopyrightText: Copyright 2026 GlobalPlatform
.. SPDX-License-Identifier: CC-BY-SA-4.0 AND LicenseRef-Patent-license

.. term:: Algorithm
Expand All @@ -16,6 +17,12 @@

Application Programming Interface.

.. term:: Key-creation API

An API that creates a key. A key-creation API is either a key-creation function or an interruptible key-creation operation.

See :secref:`key-creation`.

.. term:: Cipher

An algorithm used for encryption or decryption with a :term:`symmetric` key.
Expand Down
86 changes: 86 additions & 0 deletions doc/crypto/api.db/psa/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ typedef uint32_t psa_algorithm_t;
typedef /* implementation-defined type */ psa_cipher_operation_t;
typedef uint8_t psa_dh_family_t;
typedef uint8_t psa_ecc_family_t;
typedef /* implementation-defined type */ psa_export_public_key_iop_t;
typedef /* implementation-defined type */ psa_generate_key_iop_t;
typedef /* implementation-defined type */ psa_hash_operation_t;
typedef /* implementation-defined type */ psa_key_agreement_iop_t;
typedef /* implementation-defined type */ psa_key_attributes_t;
typedef /* implementation-defined type */ psa_key_derivation_operation_t;
typedef uint16_t psa_key_derivation_step_t;
Expand All @@ -24,8 +27,10 @@ typedef uint32_t psa_pake_primitive_t;
typedef uint8_t psa_pake_primitive_type_t;
typedef uint8_t psa_pake_role_t;
typedef uint8_t psa_pake_step_t;
typedef /* implementation-defined type */ psa_sign_iop_t;
typedef /* implementation-defined type */ psa_sign_operation_t;
typedef uint8_t psa_slh_dsa_family_t;
typedef /* implementation-defined type */ psa_verify_iop_t;
typedef /* implementation-defined type */ psa_verify_operation_t;
typedef /* implementation-defined type */ psa_xof_operation_t;
typedef struct psa_custom_key_parameters_t {
Expand Down Expand Up @@ -219,6 +224,8 @@ typedef struct psa_custom_key_parameters_t {
#define PSA_ALG_SHA_512_224 ((psa_algorithm_t)0x0200000c)
#define PSA_ALG_SHA_512_256 ((psa_algorithm_t)0x0200000d)
#define PSA_ALG_SIGN_SUPPORTS_CONTEXT(alg) /* implementation-defined value */
#define PSA_ALG_SIGN_SUPPORTS_DEFERRED_SIGNATURE(alg) \
/* implementation-defined value */
#define PSA_ALG_SLH_DSA ((psa_algorithm_t) 0x06004000)
#define PSA_ALG_SM3 ((psa_algorithm_t)0x02000014)
#define PSA_ALG_SP800_108_COUNTER_CMAC ((psa_algorithm_t)0x08000800)
Expand Down Expand Up @@ -294,9 +301,11 @@ typedef struct psa_custom_key_parameters_t {
#define PSA_EXPORT_KEY_OUTPUT_SIZE(key_type, key_bits) \
/* implementation-defined value */
#define PSA_EXPORT_KEY_PAIR_MAX_SIZE /* implementation-defined value */
#define PSA_EXPORT_PUBLIC_KEY_IOP_INIT /* implementation-defined value */
#define PSA_EXPORT_PUBLIC_KEY_MAX_SIZE /* implementation-defined value */
#define PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(key_type, key_bits) \
/* implementation-defined value */
#define PSA_GENERATE_KEY_IOP_INIT /* implementation-defined value */
#define PSA_HASH_BLOCK_LENGTH(alg) /* implementation-defined value */
#define PSA_HASH_LENGTH(alg) /* implementation-defined value */
#define PSA_HASH_MAX_SIZE /* implementation-defined value */
Expand All @@ -308,6 +317,8 @@ typedef struct psa_custom_key_parameters_t {
/* specification-defined value */
#define PSA_HASH_SUSPEND_OUTPUT_MAX_SIZE /* implementation-defined value */
#define PSA_HASH_SUSPEND_OUTPUT_SIZE(alg) /* specification-defined value */
#define PSA_IOP_MAX_OPS_UNLIMITED UINT32_MAX
#define PSA_KEY_AGREEMENT_IOP_INIT /* implementation-defined value */
#define PSA_KEY_ATTRIBUTES_INIT /* implementation-defined value */
#define PSA_KEY_DERIVATION_INPUT_CONTEXT /* implementation-defined value */
#define PSA_KEY_DERIVATION_INPUT_COST /* implementation-defined value */
Expand Down Expand Up @@ -473,6 +484,7 @@ typedef struct psa_custom_key_parameters_t {
#define PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(key_type, key_bits) \
/* implementation-defined value */
#define PSA_SIGNATURE_MAX_SIZE /* implementation-defined value */
#define PSA_SIGN_IOP_INIT /* implementation-defined value */
#define PSA_SIGN_OPERATION_INIT /* implementation-defined value */
#define PSA_SIGN_OUTPUT_SIZE(key_type, key_bits, alg) \
/* implementation-defined value */
Expand All @@ -482,6 +494,7 @@ typedef struct psa_custom_key_parameters_t {
#define PSA_SLH_DSA_FAMILY_SHAKE_S ((psa_slh_dsa_family_t) 0x0b)
#define PSA_TLS12_ECJPAKE_TO_PMS_OUTPUT_SIZE 32
#define PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE /* implementation-defined value */
#define PSA_VERIFY_IOP_INIT /* implementation-defined value */
#define PSA_VERIFY_OPERATION_INIT /* implementation-defined value */
#define PSA_WRAP_KEY_OUTPUT_SIZE(wrap_key_type, alg, key_type, key_bits) \
/* implementation-defined value */
Expand Down Expand Up @@ -639,13 +652,33 @@ psa_status_t psa_export_public_key(psa_key_id_t key,
uint8_t * data,
size_t data_size,
size_t * data_length);
psa_status_t psa_export_public_key_iop_abort(psa_export_public_key_iop_t * operation);
psa_status_t psa_export_public_key_iop_complete(psa_export_public_key_iop_t * operation,
uint8_t * data,
size_t data_size,
size_t * data_length);
uint32_t psa_export_public_key_iop_get_num_ops(psa_export_public_key_iop_t * operation);
psa_export_public_key_iop_t psa_export_public_key_iop_init(void);
psa_status_t psa_export_public_key_iop_start(psa_export_public_key_iop_t * operation,
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_generate_key_custom(const psa_key_attributes_t * attributes,
const psa_custom_key_parameters_t * custom,
const uint8_t * custom_data,
size_t custom_data_length,
psa_key_id_t * key);
psa_status_t psa_generate_key_iop_abort(psa_generate_key_iop_t * operation);
psa_status_t psa_generate_key_iop_complete(psa_generate_key_iop_t * operation,
psa_key_id_t * key);
psa_status_t psa_generate_key_iop_custom(psa_generate_key_iop_t * operation,
const psa_custom_key_parameters_t * custom,
const uint8_t * custom_data,
size_t custom_data_length);
uint32_t psa_generate_key_iop_get_num_ops(psa_generate_key_iop_t * operation);
psa_generate_key_iop_t psa_generate_key_iop_init(void);
psa_status_t psa_generate_key_iop_start(psa_generate_key_iop_t * operation,
const psa_key_attributes_t * attributes);
psa_status_t psa_generate_random(uint8_t * output,
size_t output_size);
psa_algorithm_t psa_get_key_algorithm(const psa_key_attributes_t * attributes);
Expand Down Expand Up @@ -694,12 +727,25 @@ 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);
uint32_t psa_iop_get_max_ops(void);
void psa_iop_set_max_ops(uint32_t max_ops);
psa_status_t psa_key_agreement(psa_key_id_t private_key,
const uint8_t * peer_key,
size_t peer_key_length,
psa_algorithm_t alg,
const psa_key_attributes_t * attributes,
psa_key_id_t * key);
psa_status_t psa_key_agreement_iop_abort(psa_key_agreement_iop_t * operation);
psa_status_t psa_key_agreement_iop_complete(psa_key_agreement_iop_t * operation,
psa_key_id_t * key);
uint32_t psa_key_agreement_iop_get_num_ops(psa_key_agreement_iop_t * operation);
psa_key_agreement_iop_t psa_key_agreement_iop_init(void);
psa_status_t psa_key_agreement_iop_start(psa_key_agreement_iop_t * operation,
psa_key_id_t private_key,
const uint8_t * peer_key,
size_t peer_key_length,
psa_algorithm_t alg,
const psa_key_attributes_t * attributes);
psa_key_attributes_t psa_key_attributes_init(void);
psa_status_t psa_key_derivation_abort(psa_key_derivation_operation_t * operation);
psa_status_t psa_key_derivation_get_capacity(const psa_key_derivation_operation_t * operation,
Expand Down Expand Up @@ -852,6 +898,26 @@ psa_status_t psa_sign_hash_with_context(psa_key_id_t key,
uint8_t * signature,
size_t signature_size,
size_t * signature_length);
psa_status_t psa_sign_iop_abort(psa_sign_iop_t * operation);
psa_status_t psa_sign_iop_complete(psa_sign_iop_t * operation,
uint8_t * signature,
size_t signature_size,
size_t * signature_length);
uint32_t psa_sign_iop_get_num_ops(psa_sign_iop_t * operation);
psa_status_t psa_sign_iop_hash(psa_sign_iop_t * operation,
const uint8_t * hash,
size_t hash_length);
psa_sign_iop_t psa_sign_iop_init(void);
psa_status_t psa_sign_iop_set_context(psa_sign_iop_t * operation,
const uint8_t * context,
size_t context_length);
psa_status_t psa_sign_iop_setup_complete(psa_sign_iop_t * operation);
psa_status_t psa_sign_iop_setup_start(psa_sign_iop_t * operation,
psa_key_id_t key,
psa_algorithm_t alg);
psa_status_t psa_sign_iop_update(psa_sign_iop_t * operation,
const uint8_t * input,
size_t input_length);
Comment thread
athoelke marked this conversation as resolved.
psa_status_t psa_sign_message(psa_key_id_t key,
psa_algorithm_t alg,
const uint8_t * input,
Expand Down Expand Up @@ -900,6 +966,26 @@ psa_status_t psa_verify_hash_with_context(psa_key_id_t key,
size_t context_length,
const uint8_t * signature,
size_t signature_length);
psa_status_t psa_verify_iop_abort(psa_verify_iop_t * operation);
psa_status_t psa_verify_iop_complete(psa_verify_iop_t * operation);
uint32_t psa_verify_iop_get_num_ops(psa_verify_iop_t * operation);
psa_status_t psa_verify_iop_hash(psa_verify_iop_t * operation,
const uint8_t * hash,
size_t hash_length);
psa_verify_iop_t psa_verify_iop_init(void);
psa_status_t psa_verify_iop_set_context(psa_verify_iop_t * operation,
const uint8_t * context,
size_t context_length);
psa_status_t psa_verify_iop_set_signature(psa_verify_iop_t * operation,
const uint8_t * signature,
size_t signature_length);
psa_status_t psa_verify_iop_setup_complete(psa_verify_iop_t * operation);
psa_status_t psa_verify_iop_setup_start(psa_verify_iop_t * operation,
psa_key_id_t key,
psa_algorithm_t alg);
psa_status_t psa_verify_iop_update(psa_verify_iop_t * operation,
const uint8_t * input,
size_t input_length);
psa_status_t psa_verify_message(psa_key_id_t key,
psa_algorithm_t alg,
const uint8_t * input,
Expand Down
3 changes: 2 additions & 1 deletion doc/crypto/api/keys/attributes.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.. SPDX-FileCopyrightText: Copyright 2018-2025 Arm Limited and/or its affiliates
.. SPDX-FileCopyrightText: Copyright 2026 GlobalPlatform
.. SPDX-License-Identifier: CC-BY-SA-4.0 AND LicenseRef-Patent-license

.. header:: psa/crypto
Expand Down Expand Up @@ -113,7 +114,7 @@ Managing key attributes
#. Set the key policy with `psa_set_key_usage_flags()` and `psa_set_key_algorithm()`.
#. Set the key type with `psa_set_key_type()`. Skip this step if copying an existing key with `psa_copy_key()`.
#. When generating a random key with `psa_generate_key()` or `psa_generate_key_custom()`, or deriving a key with `psa_key_derivation_output_key()` or `psa_key_derivation_output_key_custom()`, set the desired key size with `psa_set_key_bits()`.
#. Call a key creation function: `psa_import_key()`, `psa_generate_key()`, `psa_generate_key_custom()`, `psa_key_derivation_output_key()`, `psa_key_derivation_output_key_custom()`, `psa_key_agreement()`, `psa_encapsulate()`, `psa_decapsulate()`, `psa_pake_get_shared_key()`, `psa_copy_key()`, or `psa_attach_key()`. This function reads the attribute object, creates a key with these attributes, and outputs an identifier for the newly created key.
#. Call a :term:`key-creation API`. A key-creation function reads the attribute object, creates a key with these attributes, and outputs its identifier. An interruptible key-creation operation takes the attributes in its start function and outputs the identifier when its completion function succeeds. See :secref:`key-creation`.
#. Optionally call `psa_reset_key_attributes()`, now that the attribute object is no longer needed. Currently this call is not required as the attributes defined in this specification do not require additional resources beyond the object itself.

A typical sequence to query a key's attributes is as follows:
Expand Down
5 changes: 3 additions & 2 deletions doc/crypto/api/keys/ids.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.. SPDX-FileCopyrightText: Copyright 2018-2025 Arm Limited and/or its affiliates
.. SPDX-FileCopyrightText: Copyright 2026 GlobalPlatform
.. SPDX-License-Identifier: CC-BY-SA-4.0 AND LicenseRef-Patent-license

.. _key-identifiers:
Expand All @@ -17,7 +18,7 @@ Key identifiers are integral values that act as permanent names for persistent k

Key identifiers outside these ranges are reserved for future use.

Key identifiers are output from a successful call to one of the key creation functions. For persistent keys, this is the same identifier as the one specified in the key attributes used to create the key. The key identifier remains valid until it is invalidated by passing it to `psa_destroy_key()`. A volatile key identifier must not be used after it has been invalidated.
Key identifiers are output when a :term:`key-creation API` successfully creates a key. For persistent keys, this is the same identifier as the one specified in the key attributes used to create the key. The key identifier remains valid until it is invalidated by passing it to `psa_destroy_key()`. A volatile key identifier must not be used after it has been invalidated.

If an invalid key identifier is provided as a parameter in any function, the function will return :code:`PSA_ERROR_INVALID_HANDLE`; except for the special case of calling :code:`psa_destroy_key(PSA_KEY_ID_NULL)`, which has no effect and always returns :code:`PSA_SUCCESS`.

Expand Down Expand Up @@ -92,7 +93,7 @@ Attribute accessors

If the attribute object currently declares the key as volatile, this function sets the persistence level in the lifetime attribute to `PSA_KEY_PERSISTENCE_DEFAULT` without changing the key location. See :secref:`key-lifetimes`.

This function does not access storage, it merely stores the given value in the attribute object. The persistent key will be written to storage when the attribute object is passed to a key creation function such as `psa_import_key()`, `psa_generate_key()`, `psa_generate_key_custom()`, `psa_key_derivation_output_key()`, `psa_key_derivation_output_key_custom()`, `psa_key_agreement()`, `psa_encapsulate()`, `psa_decapsulate()`, `psa_pake_get_shared_key()`, or `psa_copy_key()`.
This function does not access storage, it merely stores the given value in the attribute object. The persistent key will be written to storage when a :term:`key-creation API` successfully creates the key. For an interruptible key-creation operation, this occurs when its completion function returns successfully.

.. admonition:: Implementation note

Expand Down
6 changes: 3 additions & 3 deletions doc/crypto/api/keys/lifetimes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ To create a volatile key:

1. Populate a `psa_key_attributes_t` object with the required type, size, policy and other key attributes.
#. If a non-default storage location is being used, set the key lifetime in the attributes object.
#. Create the key with one of the key creation functions. If successful, these functions output a transient `key identifier <key-identifiers>`.
#. Create the key with a :term:`key-creation API`. If the key is successfully created, the API outputs a transient `key identifier <key-identifiers>`.

To destroy a volatile key: call `psa_destroy_key()` with the key identifier. There must be a matching call to `psa_destroy_key()` for each successful call to a create a volatile key.

Expand All @@ -54,7 +54,7 @@ To create a persistent key:

1. Populate a `psa_key_attributes_t` object with the key’s type, size, policy and other attributes.
#. In the attributes object, set the desired lifetime and persistent identifier for the key.
#. Create the key with one of the key creation functions. If successful, these functions output the `key identifier <key-identifiers>` that was specified by the application in step 2.
#. Create the key with a :term:`key-creation API`. If the key is successfully created, the API outputs the `key identifier <key-identifiers>` that was specified by the application in step 2.

To access an existing persistent key: use the key identifier in any API that requires a key.

Expand Down Expand Up @@ -280,7 +280,7 @@ Attribute accessors

To make a key persistent, give it a persistent key identifier by using `psa_set_key_id()`. By default, a key that has a persistent identifier is stored in the default storage area identifier by `PSA_KEY_LIFETIME_PERSISTENT`. Call this function to choose a specific storage area, or to explicitly declare the key as volatile.

This function does not access storage, it merely stores the given value in the attribute object. The persistent key will be written to storage when the attribute object is passed to a key creation function such as `psa_import_key()`, `psa_generate_key()`, `psa_generate_key_custom()`, `psa_key_derivation_output_key()`, `psa_key_derivation_output_key_custom()`, `psa_key_agreement()`, `psa_encapsulate()`, `psa_decapsulate()`, `psa_pake_get_shared_key()`, or `psa_copy_key()`.
This function does not access storage, it merely stores the given value in the attribute object. The persistent key will be written to storage when a :term:`key-creation API` successfully creates the key. For an interruptible key-creation operation, this occurs when its completion function returns successfully.

.. admonition:: Implementation note

Expand Down
Loading