Skip to content

Commit c931176

Browse files
authored
Merge pull request #261 from athoelke/crypto-attach-key
Define `psa_attach_key()` to register existing key material with a key id and policy
2 parents 2ac70ae + 020a923 commit c931176

File tree

5 files changed

+136
-9
lines changed

5 files changed

+136
-9
lines changed

doc/crypto/api.db/psa/crypto.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ typedef struct psa_custom_key_parameters_t {
210210
#define PSA_CIPHER_UPDATE_OUTPUT_SIZE(key_type, alg, input_length) \
211211
/* implementation-defined value */
212212
#define PSA_CRYPTO_API_VERSION_MAJOR 1
213-
#define PSA_CRYPTO_API_VERSION_MINOR 3
213+
#define PSA_CRYPTO_API_VERSION_MINOR 4
214214
#define PSA_CUSTOM_KEY_PARAMETERS_INIT { 0 }
215215
#define PSA_DH_FAMILY_RFC7919 ((psa_dh_family_t) 0x03)
216216
#define PSA_ECC_FAMILY_BRAINPOOL_P_R1 ((psa_ecc_family_t) 0x30)
@@ -460,6 +460,10 @@ psa_status_t psa_asymmetric_encrypt(psa_key_id_t key,
460460
uint8_t * output,
461461
size_t output_size,
462462
size_t * output_length);
463+
psa_status_t psa_attach_key(const psa_key_attributes_t * attributes,
464+
const uint8_t * label,
465+
size_t label_length,
466+
psa_key_id_t * key);
463467
psa_status_t psa_cipher_abort(psa_cipher_operation_t * operation);
464468
psa_status_t psa_cipher_decrypt(psa_key_id_t key,
465469
psa_algorithm_t alg,

doc/crypto/api/keys/attributes.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,11 @@ Managing key attributes
109109

110110
1. Create and initialize an attribute object.
111111
#. If the key is persistent, call `psa_set_key_id()`. Also call `psa_set_key_lifetime()` to place the key in a non-default location.
112+
#. If the key is volatile in a non-default location, call `psa_set_key_lifetime()` to specify the location.
112113
#. Set the key policy with `psa_set_key_usage_flags()` and `psa_set_key_algorithm()`.
113114
#. Set the key type with `psa_set_key_type()`. Skip this step if copying an existing key with `psa_copy_key()`.
114115
#. 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()`.
115-
#. 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()`, or `psa_copy_key()`. This function reads the attribute object, creates a key with these attributes, and outputs an identifier for the newly created key.
116+
#. 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.
116117
#. 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.
117118

118119
A typical sequence to query a key's attributes is as follows:

doc/crypto/api/keys/management.rst

Lines changed: 126 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ New keys can be created in the following ways:
2121
* `psa_encapsulate()` and `psa_decapsulate()` create a shared secret key using a key-encapsulation mechanism.
2222
* `psa_pake_get_shared_key()` creates a key from the shared secret result of a password-authenticated key exchange. See :secref:`pake`.
2323
* `psa_copy_key()` duplicates an existing key with a different lifetime or with a more restrictive usage policy.
24+
* `psa_attach_key()` registers implementation-provided key material for use as a volatile key.
2425

2526
When creating a key, the attributes for the new key are specified in a `psa_key_attributes_t` object. Each key creation function defines how it uses the attributes.
2627

@@ -412,6 +413,121 @@ When creating a key, the attributes for the new key are specified in a `psa_key_
412413

413414
The effect of this function on implementation-defined attributes is implementation-defined.
414415

416+
.. function:: psa_attach_key
417+
418+
.. summary::
419+
Register implementation-provided key material with a volatile key identifier and key policy.
420+
421+
.. versionadded:: 1.4
422+
423+
.. param:: const psa_key_attributes_t * attributes
424+
The attributes for the key to be registered.
425+
426+
Some of the attributes can be provided by the implementation.
427+
It is :scterm:`implementation defined`, and possibly key-specific, which attributes are provided by the implementation and which must be supplied by the application.
428+
429+
The following attributes must always be provided by the application:
430+
431+
* The key lifetime must specify a volatile key, and the storage location of the implementation-provided key.
432+
See :secref:`key-lifetimes`.
433+
434+
The following attributes must be provided by either the application or the implementation. If provided by both, they must be identical:
435+
436+
* The key type.
437+
* The key size.
438+
439+
The following attributes must be set for keys used in cryptographic operations:
440+
441+
* The key permitted-algorithm policy, see :secref:`permitted-algorithms`.
442+
* The key usage flags, see :secref:`key-usage-flags`.
443+
444+
These attributes are combined with any policy that is provided by the implementation, so that both sets of restrictions apply.
445+
.. param:: const uint8_t * label
446+
Buffer containing a label that identifies the implementation-provided key to be registered.
447+
448+
The contents of this label are interpreted by the implementation and may correspond to a pre-provisioned, securely stored, or deterministically derived key within the location specified in ``attributes``.
449+
.. param:: size_t label_length
450+
Size of the ``label`` buffer in bytes.
451+
.. param:: psa_key_id_t * key
452+
On success, an identifier for the newly created key.
453+
`PSA_KEY_ID_NULL` on failure.
454+
455+
.. return:: psa_status_t
456+
.. retval:: PSA_SUCCESS
457+
Success.
458+
.. retval:: PSA_ERROR_DOES_NOT_EXIST
459+
``label`` does not refer to key material within the location specified in ``attributes``.
460+
.. retval:: PSA_ERROR_NOT_SUPPORTED
461+
The key attributes, as a whole, are not supported, either by the implementation in general or in the specified storage location.
462+
.. retval:: PSA_ERROR_INVALID_ARGUMENT
463+
The following conditions can result in this error:
464+
465+
* The key type is invalid.
466+
* The key size is nonzero, and is incompatible with the implementation-provided key.
467+
* The key lifetime specifies a non-volatile persistence level.
468+
* The key lifetime specifies an invalid storage location.
469+
* The key usage flags include invalid values.
470+
* The key's permitted-usage algorithm is invalid.
471+
* The key attributes, as a whole, are invalid.
472+
* The implementation-provided key material is incompatible with the provided key attributes.
473+
.. retval:: PSA_ERROR_NOT_PERMITTED
474+
The implementation does not permit creating a key with the specified attributes due to some implementation-specific policy.
475+
.. retval:: PSA_ERROR_INSUFFICIENT_MEMORY
476+
.. retval:: PSA_ERROR_COMMUNICATION_FAILURE
477+
.. retval:: PSA_ERROR_STORAGE_FAILURE
478+
.. retval:: PSA_ERROR_DATA_CORRUPT
479+
.. retval:: PSA_ERROR_DATA_INVALID
480+
.. retval:: PSA_ERROR_CORRUPTION_DETECTED
481+
.. retval:: PSA_ERROR_BAD_STATE
482+
The library requires initializing by a call to `psa_crypto_init()`.
483+
484+
This function allows applications to register implementation-provided key material.
485+
The key material can come from different sources, for example:
486+
487+
* Keys that are provisioned outside the |API|, such as during manufacturing or by a secure element.
488+
* Keys that are deterministically derived from a secret within the implementation.
489+
490+
After registering the key, the application has a volatile key identifier that can be used in cryptographic operations permitted by its usage flags and algorithm policy.
491+
492+
The key material is identified by its location, specified in the provided attributes ``lifetime`` value, and the ``label`` parameter.
493+
The format of the label is specific to the implementation and storage location.
494+
Typically, the label is used as a location-specific identifier for the key material, or can provide input for deriving the key material from an internal secret.
495+
496+
This function can only be used to create a volatile key.
497+
That is, a key with a lifetime persistence level of `PSA_KEY_PERSISTENCE_VOLATILE`.
498+
499+
Depending on the key being registered, the implementation can provide some or all of the key type, size, and policy.
500+
For example:
501+
502+
* Provisioned key material has a fixed size.
503+
The implementation might permit the application to define the key type and policy, as long as these are compatible with the key material.
504+
* An implementation-specific derived key can require the application to provide a key type and size, using these in the derivation process.
505+
* An implementation-provided key can be fully defined by the implementation, with a fixed type, size, and policy.
506+
The call to `psa_attach_key()` needs to specify the location and label of the key, and a matching policy, in order to obtain a key id.
507+
508+
Calling `psa_destroy_key()` with a key identifier returned by `psa_attach_key()` will remove the key identifier and policy from the key store, but any implementation-provided key material remains within the implementation.
509+
A subsequent call to `psa_attach_key()` with the same parameters will return a new key identifier for the same key.
510+
511+
It is :scterm:`implementation defined` whether the same implementation-provided key can be attached to multiple key identifiers concurrently.
512+
513+
.. note::
514+
515+
This function is intended for scenarios where key material is provided outside the |API|, and the application needs to use such keys within the |API| framework.
516+
517+
The function only allows registering key material that is provided by the implementation.
518+
To import new key material, use `psa_import_key()`.
519+
520+
Although the implementation verifies that the application-supplied attributes are compatible with the implementation-provided key; it is the application's responsibility to ensure correctness for attributes that are provided by the implementation.
521+
522+
To create a persistent key from pre-existing key material, the implementation might permit a key returned by `psa_attach_key()` to be copied to a persistent key using `psa_copy_key()`.
523+
524+
.. admonition:: Implementation note
525+
526+
Implementations may impose restrictions on which keys can be registered, depending on their storage architecture and security policies.
527+
528+
The behavior of a call `psa_attach_key()` with a persistent key-lifetime might be specified in a future version of the |API|.
529+
At present, it is recommended that such a call returns :code:`PSA_ERROR_INVALID_ARGUMENT`, and does not provide implementation-specific behavior.
530+
415531
.. _key-destruction:
416532

417533
Key destruction
@@ -420,17 +536,19 @@ Key destruction
420536
.. function:: psa_destroy_key
421537

422538
.. summary::
423-
Destroy a key.
539+
Destroy or unregister a key.
424540

425541
.. param:: psa_key_id_t key
426542
Identifier of the key to erase.
427543
If this is `PSA_KEY_ID_NULL`, do nothing and return :code:`PSA_SUCCESS`.
428544

429545
.. return:: psa_status_t
430546
.. retval:: PSA_SUCCESS
431-
Success.
432-
If ``key`` was a valid key identifier, then the key material that it referred to has been erased.
433-
Alternatively, ``key`` was `PSA_KEY_ID_NULL`.
547+
Success:
548+
549+
* If ``key`` was a valid key identifier that was not the result of a call to `psa_attach_key()`, then material that it referred to has been erased.
550+
* If ``key`` was a valid key identifier that was returned by `psa_attach_key()`, then the key identifier is detached from the implementation-provided key.
551+
* Alternatively, ``key`` was `PSA_KEY_ID_NULL`.
434552
.. retval:: PSA_ERROR_NOT_PERMITTED
435553
The key cannot be erased because it is read-only, either due to a policy or due to physical restrictions.
436554
.. retval:: PSA_ERROR_INVALID_HANDLE
@@ -447,7 +565,10 @@ Key destruction
447565
.. retval:: PSA_ERROR_BAD_STATE
448566
The library requires initializing by a call to `psa_crypto_init()`.
449567

450-
This function destroys a key from both volatile memory and, if applicable, non-volatile storage. Implementations must make a best effort to ensure that that the key material cannot be recovered.
568+
For key identifiers that resulted from registering an implementation-provided key using `psa_attach_key()`, this function detaches the key identifier from the implementation-provided key.
569+
570+
For other keys, this function destroys a key from both volatile memory and, if applicable, non-volatile storage.
571+
Implementations must make a best effort to ensure that that the key material cannot be recovered.
451572

452573
This function also erases any metadata such as policies and frees resources associated with the key.
453574

doc/crypto/appendix/history.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Changes between *1.3.1* and *1.4.0*
1717
Changes to the API
1818
~~~~~~~~~~~~~~~~~~
1919

20-
* TBD
20+
* Added `psa_attach_key()` to register existing key material as a volatile key within the implementation.
2121

2222
Clarifications and fixes
2323
~~~~~~~~~~~~~~~~~~~~~~~~

doc/crypto/overview/functionality.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.. SPDX-FileCopyrightText: Copyright 2018-2024 Arm Limited and/or its affiliates <[email protected]>
1+
.. SPDX-FileCopyrightText: Copyright 2018-2025 Arm Limited and/or its affiliates <[email protected]>
22
.. SPDX-License-Identifier: CC-BY-SA-4.0 AND LicenseRef-Patent-license
33
44
.. _functionality-overview:
@@ -45,6 +45,7 @@ Keys are created using one of the *key creation functions*:
4545
* `psa_decapsulate()`
4646
* `psa_pake_get_shared_key()`
4747
* `psa_copy_key()`
48+
* `psa_attach_key()`
4849

4950
These output the key identifier, that is used to access the key in all other parts of the API.
5051

0 commit comments

Comments
 (0)