Skip to content

Commit a4b7323

Browse files
committed
crypto: provide incremental by-subsystem initialization for the library
1 parent 29bf009 commit a4b7323

File tree

14 files changed

+253
-78
lines changed

14 files changed

+253
-78
lines changed

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
typedef /* implementation-defined type */ psa_aead_operation_t;
55
typedef uint32_t psa_algorithm_t;
66
typedef /* implementation-defined type */ psa_cipher_operation_t;
7+
typedef uint32_t psa_crypto_subsystem_t;
78
typedef uint8_t psa_dh_family_t;
89
typedef uint8_t psa_ecc_family_t;
910
typedef /* implementation-defined type */ psa_hash_operation_t;
@@ -207,8 +208,16 @@ typedef struct psa_custom_key_parameters_t {
207208
/* implementation-defined value */
208209
#define PSA_CIPHER_UPDATE_OUTPUT_SIZE(key_type, alg, input_length) \
209210
/* implementation-defined value */
211+
#define PSA_CRYPTO_ALL_SUBSYSTEMS /* implementation-defined value */
210212
#define PSA_CRYPTO_API_VERSION_MAJOR 1
211213
#define PSA_CRYPTO_API_VERSION_MINOR 3
214+
#define PSA_CRYPTO_SUBSYSTEM_ACCELERATORS /* implementation-defined value */
215+
#define PSA_CRYPTO_SUBSYSTEM_BUILTIN_KEYS /* implementation-defined value */
216+
#define PSA_CRYPTO_SUBSYSTEM_COMMUNICATION /* implementation-defined value */
217+
#define PSA_CRYPTO_SUBSYSTEM_KEYS /* implementation-defined value */
218+
#define PSA_CRYPTO_SUBSYSTEM_RANDOM /* implementation-defined value */
219+
#define PSA_CRYPTO_SUBSYSTEM_SECURE_ELEMENTS /* implementation-defined value */
220+
#define PSA_CRYPTO_SUBSYSTEM_STORAGE /* implementation-defined value */
212221
#define PSA_CUSTOM_KEY_PARAMETERS_INIT { 0 }
213222
#define PSA_DH_FAMILY_RFC7919 ((psa_dh_family_t) 0x03)
214223
#define PSA_ECC_FAMILY_BRAINPOOL_P_R1 ((psa_ecc_family_t) 0x30)
@@ -498,6 +507,7 @@ psa_status_t psa_copy_key(psa_key_id_t source_key,
498507
const psa_key_attributes_t * attributes,
499508
psa_key_id_t * target_key);
500509
psa_status_t psa_crypto_init(void);
510+
psa_status_t psa_crypto_init_subsystem(psa_crypto_subsystem_t subsystem);
501511
psa_status_t psa_destroy_key(psa_key_id_t key);
502512
psa_status_t psa_export_key(psa_key_id_t key,
503513
uint8_t * data,

doc/crypto/api/keys/attributes.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ Managing key attributes
159159
.. retval:: PSA_ERROR_DATA_CORRUPT
160160
.. retval:: PSA_ERROR_DATA_INVALID
161161
.. retval:: PSA_ERROR_BAD_STATE
162-
The library requires initializing by a call to `psa_crypto_init()`.
162+
The library requires initializing. See :secref:`library-init`.
163163

164164
This function first resets the attribute object as with `psa_reset_key_attributes()`. It then copies the attributes of the given key into the given attribute object.
165165

doc/crypto/api/keys/management.rst

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ When creating a key, the attributes for the new key are specified in a `psa_key_
9999
.. retval:: PSA_ERROR_DATA_INVALID
100100
.. retval:: PSA_ERROR_CORRUPTION_DETECTED
101101
.. retval:: PSA_ERROR_BAD_STATE
102-
The library requires initializing by a call to `psa_crypto_init()`.
102+
The library requires initializing, see :secref:`library-init`.
103103

104104
The key is extracted from the provided ``data`` buffer. Its location, policy, and type are taken from ``attributes``.
105105

@@ -219,7 +219,7 @@ When creating a key, the attributes for the new key are specified in a `psa_key_
219219
.. retval:: PSA_ERROR_DATA_CORRUPT
220220
.. retval:: PSA_ERROR_DATA_INVALID
221221
.. retval:: PSA_ERROR_BAD_STATE
222-
The library requires initializing by a call to `psa_crypto_init()`.
222+
The library requires initializing, see :secref:`library-init`.
223223

224224
The key is generated randomly. Its location, policy, type and size are taken from ``attributes``.
225225

@@ -384,7 +384,7 @@ When creating a key, the attributes for the new key are specified in a `psa_key_
384384
.. retval:: PSA_ERROR_DATA_INVALID
385385
.. retval:: PSA_ERROR_CORRUPTION_DETECTED
386386
.. retval:: PSA_ERROR_BAD_STATE
387-
The library requires initializing by a call to `psa_crypto_init()`.
387+
The library requires initializing, see :secref:`library-init`.
388388

389389
Copy key material from one location to another. Its location is taken from ``attributes``, its policy is the intersection of the policy in ``attributes`` and the source key policy, and its type and size are taken from the source key.
390390

@@ -438,7 +438,7 @@ Key destruction
438438
.. retval:: PSA_ERROR_CORRUPTION_DETECTED
439439
An unexpected condition which is not a storage corruption or a communication failure occurred. The cryptoprocessor might have been compromised.
440440
.. retval:: PSA_ERROR_BAD_STATE
441-
The library requires initializing by a call to `psa_crypto_init()`.
441+
The library requires initializing, see :secref:`library-init`.
442442

443443
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.
444444

@@ -468,7 +468,7 @@ Key destruction
468468
.. retval:: PSA_ERROR_DATA_INVALID
469469
.. retval:: PSA_ERROR_CORRUPTION_DETECTED
470470
.. retval:: PSA_ERROR_BAD_STATE
471-
The library requires initializing by a call to `psa_crypto_init()`.
471+
The library requires initializing, see :secref:`library-init`.
472472

473473
For keys that have been created with the `PSA_KEY_USAGE_CACHE` usage flag, an implementation is permitted to make additional copies of the key material that are not in storage and not for the purpose of ongoing operations.
474474

@@ -533,7 +533,7 @@ Key export
533533
.. retval:: PSA_ERROR_DATA_INVALID
534534
.. retval:: PSA_ERROR_INSUFFICIENT_MEMORY
535535
.. retval:: PSA_ERROR_BAD_STATE
536-
The library requires initializing by a call to `psa_crypto_init()`.
536+
The library requires initializing, see :secref:`library-init`.
537537

538538
The output of this function can be passed to `psa_import_key()` to create an equivalent object.
539539

@@ -585,7 +585,7 @@ Key export
585585
.. retval:: PSA_ERROR_DATA_INVALID
586586
.. retval:: PSA_ERROR_INSUFFICIENT_MEMORY
587587
.. retval:: PSA_ERROR_BAD_STATE
588-
The library requires initializing by a call to `psa_crypto_init()`.
588+
The library requires initializing, see :secref:`library-init`.
589589

590590
The output of this function can be passed to `psa_import_key()` to create an object that is equivalent to the public key.
591591

doc/crypto/api/library/library.rst

Lines changed: 173 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,37 @@ API version
4040
Library initialization
4141
----------------------
4242

43+
It is recommended that applications initialize the |API| implementation, before calling any other function, except as otherwise indicated.
44+
This is typically achieved by calling `psa_crypto_init()`.
45+
46+
Some implementations provide the ability to selectively initialize a subset of the functionality, using calls to `psa_crypto_init_subsystem()`.
47+
For example, this permits use cases such as early-stage bootloaders, that need to decrypt or authenticate firmware, where it is unnecessary to wait for an RNG to collect enough entropy.
48+
In these implementations, calling `psa_crypto_init()` is equivalent to calling `psa_crypto_init_subsystem()` for all available subsystems.
49+
50+
Applications are permitted to call these functions more than once.
51+
Once a subsystem is successfully initialized, subsequent calls to initialize the same subsystem are guaranteed to succeed.
52+
53+
If the application calls any function that returns a :code:`psa_status_t` result code before initializing the related subsystems, the following will occur:
54+
55+
* If initialization of the library is essential for secure operation of the function, the implementation must return :code:`PSA_ERROR_BAD_STATE` or other appropriate error.
56+
57+
* If failure to initialize the library does not compromise the security of the function, the implementation must either provide the expected result for the function, or return :code:`PSA_ERROR_BAD_STATE` or other appropriate error.
58+
59+
.. note::
60+
61+
The following scenarios are examples where an implementation can require that the library has been initialized:
62+
63+
* A client-server implementation, in which `psa_crypto_init()`, or :code:`psa_crypto_init_subsystem(PSA_CRYPTO_SUBSYSTEM_COMMUNICATION)`, establishes the communication with the server.
64+
No key management or cryptographic operation can be performed until this is done.
65+
66+
* An implementation in which `psa_crypto_init()`, or :code:`psa_crypto_init_subsystem(PSA_CRYPTO_SUBSYSTEM_RANDOM)`, initializes the random bit generator, and no operations that require the RNG can be performed until this is done.
67+
For example, random data, key, IV, or nonce generation; randomized signature or encryption; and algorithms that are implemented with blinding.
68+
69+
.. warning::
70+
71+
The set of functions that depend on successful initialization of specific subsystems, is :scterm:`IMPLEMENTATION DEFINED`.
72+
Applications that rely on calling functions before initializing the library might not be portable to other implementations.
73+
4374
.. function:: psa_crypto_init
4475

4576
.. summary::
@@ -52,24 +83,156 @@ Library initialization
5283
.. retval:: PSA_ERROR_COMMUNICATION_FAILURE
5384
.. retval:: PSA_ERROR_CORRUPTION_DETECTED
5485
.. retval:: PSA_ERROR_INSUFFICIENT_ENTROPY
86+
.. retval:: PSA_ERROR_INSUFFICIENT_STORAGE
87+
.. retval:: PSA_ERROR_HARDWARE_FAILURE
88+
.. retval:: PSA_ERROR_STORAGE_FAILURE
89+
.. retval:: PSA_ERROR_DATA_INVALID
90+
.. retval:: PSA_ERROR_DATA_CORRUPT
5591

56-
It is recommended that applications call this function before calling any other function in this module.
92+
It is recommended that applications call this function before calling any other function in this module, except as otherwise indicated.
5793

5894
Applications are permitted to call this function more than once. Once a call succeeds, subsequent calls are guaranteed to succeed.
5995

60-
If the application calls any function that returns a :code:`psa_status_t` result code before calling `psa_crypto_init()`, the following will occur:
96+
For finer control over initialization, see `psa_crypto_init_subsystem()`.
6197

62-
* If initialization of the library is essential for secure operation of the function, the implementation must return :code:`PSA_ERROR_BAD_STATE` or other appropriate error.
98+
See also :secref:`library-init`.
6399

64-
* If failure to initialize the library does not compromise the security of the function, the implementation must either provide the expected result for the function, or return :code:`PSA_ERROR_BAD_STATE` or other appropriate error.
100+
.. typedef:: uint32_t psa_crypto_subsystem_t
65101

66-
.. note::
102+
.. summary::
103+
Encoding of a subsystem of the |API| implementation.
104+
105+
This type is used to specify implementation subsystems in a call to `psa_crypto_init_subsystem()`.
106+
Values of this type are ``PSA_CRYPTO_SUBSYSTEM_xxx`` constants, or a bitwise-or of two or more of them.
107+
108+
.. admonition:: Implementation note
109+
110+
An implementation can define additional subsystem identifier values for use with `psa_crypto_init_subsystem()`.
111+
112+
.. macro:: PSA_CRYPTO_SUBSYSTEM_COMMUNICATION
113+
:definition: /* implementation-defined value */
114+
115+
.. summary::
116+
Crypto subsystem identifier for the communication with the server, if this is a client that communicates with a server where the key store is located.
117+
118+
In a client-server implementation, initializing this subsystem is necessary before any API function other than library initialization, deinitialization and functions accessing local data structures such as key attributes.
119+
120+
In a library implementation, initializing this subsystem has no effect, and always succeeds.
121+
122+
.. macro:: PSA_CRYPTO_SUBSYSTEM_KEYS
123+
:definition: /* implementation-defined value */
124+
125+
.. summary::
126+
Crypto subsystem identifier for the key store in memory.
127+
128+
Initializing this subsystem allows creating, accessing and destroying volatile keys in the default location, that is, keys with the lifetime `PSA_KEY_LIFETIME_VOLATILE`.
129+
130+
Persistent keys also require `PSA_CRYPTO_SUBSYSTEM_STORAGE`.
131+
Keys in other locations also require `PSA_CRYPTO_SUBSYSTEM_SECURE_ELEMENTS`.
67132

68-
The following scenarios are examples where an implementation can require that the library has been initialized by calling `psa_crypto_init()`:
69133

70-
* A client-server implementation, in which `psa_crypto_init()` establishes the communication with the server. No key management or cryptographic operation can be performed until this is done.
134+
.. macro:: PSA_CRYPTO_SUBSYSTEM_STORAGE
135+
:definition: /* implementation-defined value */
136+
137+
.. summary::
138+
Crypto subsystem identifier for access to keys in storage.
71139

72-
* An implementation in which `psa_crypto_init()` initializes the random bit generator, and no operations that require the RNG can be performed until this is done. For example, random data, key, IV, or nonce generation; randomized signature or encryption; and algorithms that are implemented with blinding.
140+
Initializing this subsystem and the `PSA_CRYPTO_SUBSYSTEM_KEYS` subsystem allows creating, accessing, and destroying persistent keys.
141+
142+
Persistent keys in secure elements also require `PSA_CRYPTO_SUBSYSTEM_SECURE_ELEMENTS`.
143+
144+
.. macro:: PSA_CRYPTO_SUBSYSTEM_ACCELERATORS
145+
:definition: /* implementation-defined value */
146+
147+
.. summary::
148+
Crypto subsystem identifier for accelerator drivers.
149+
150+
Initializing this subsystem results in initialization of all registered accelerator drivers.
151+
152+
Initializing this subsystem allows cryptographic operations that are implemented via an accelerator driver.
153+
154+
.. macro:: PSA_CRYPTO_SUBSYSTEM_SECURE_ELEMENTS
155+
:definition: /* implementation-defined value */
156+
157+
.. summary::
158+
Crypto subsystem identifier for secure element drivers.
159+
160+
Initializing this subsystem results in initialization of all registered secure element drivers.
161+
162+
Initializing this subsystem as well as `PSA_CRYPTO_SUBSYSTEM_KEYS` allows creating, accessing, and destroying keys in a secure element. That is, keys whose location is not `PSA_KEY_LOCATION_LOCAL_STORAGE`.
163+
164+
.. macro:: PSA_CRYPTO_SUBSYSTEM_RANDOM
165+
:definition: /* implementation-defined value */
166+
167+
.. summary::
168+
Crypto subsystem identifier for the random generator.
169+
170+
Initializing this subsystem initializes all registered entropy drivers, and accesses the registered entropy sources.
171+
172+
Initializing this subsystem is necessary for `psa_generate_random()`, `psa_generate_key()`, and some operations using private or secret keys.
173+
174+
It is guaranteed that the following operations do not to require this subsystem:
175+
176+
* Hash operations.
177+
* Signature verification operations.
178+
179+
Is it :scterm:`implementation defined` whether other operations require the initialization of this subsystem.
180+
181+
.. macro:: PSA_CRYPTO_SUBSYSTEM_BUILTIN_KEYS
182+
:definition: /* implementation-defined value */
183+
184+
.. summary::
185+
Crypto subsystem identifier for access to built-in keys.
186+
187+
Initializing this subsystem as well as `PSA_CRYPTO_SUBSYSTEM_KEYS` allows access to built-in keys.
188+
189+
.. macro:: PSA_CRYPTO_ALL_SUBSYSTEMS
190+
:definition: /* implementation-defined value */
191+
192+
.. summary::
193+
Crypto subsystem identifier for all available subsystems.
194+
195+
Using this value in a call to `psa_crypto_init_subsystem()` is equivalent to calling `psa_crypto_init()`.
196+
197+
.. function:: psa_crypto_init_subsystem
198+
199+
.. summary::
200+
Partial library initialization.
201+
202+
.. param:: psa_crypto_subsystem_t subsystem
203+
The subsystem, or set of subsystems, to initialize.
204+
This must be one of the ``PSA_CRYPTO_SUBSYSTEM_xxx`` values, one of the implementation-specific subsystem values, or a bitwise-or of them.
205+
206+
.. return:: psa_status_t
207+
.. retval:: PSA_SUCCESS
208+
Success.
209+
.. retval:: PSA_ERROR_INVALID_ARGUMENT
210+
``subsystem`` is not a bitwise-or of one or more of the crypto subsystem identifier values.
211+
These values can be defined in this specification or by the implementation.
212+
.. retval:: PSA_ERROR_INSUFFICIENT_MEMORY
213+
.. retval:: PSA_ERROR_COMMUNICATION_FAILURE
214+
.. retval:: PSA_ERROR_CORRUPTION_DETECTED
215+
.. retval:: PSA_ERROR_INSUFFICIENT_ENTROPY
216+
.. retval:: PSA_ERROR_INSUFFICIENT_STORAGE
217+
.. retval:: PSA_ERROR_HARDWARE_FAILURE
218+
.. retval:: PSA_ERROR_STORAGE_FAILURE
219+
.. retval:: PSA_ERROR_DATA_INVALID
220+
.. retval:: PSA_ERROR_DATA_CORRUPT
221+
222+
Applications may call this function on the same subsystem more than once.
223+
Once a call succeeds, subsequent calls with the same subsystem are guaranteed to succeed.
224+
225+
Initializing a subsystem may initialize other subsystems if the implementations needs them internally.
226+
For example, in a typical client-server implementation, `PSA_CRYPTO_SUBSYSTEM_COMMUNICATION` is required for all other subsystems, and therefore initializing any other subsystem also initializes `PSA_CRYPTO_SUBSYSTEM_COMMUNICATION`.
227+
228+
Calling `psa_crypto_init_subsystem()` with for a subsystem that is not used by the implementation must have no effect, and return :code:`PSA_SUCCESS`.
229+
In effect, this is indicating that there is no further initialization required for this subsystem.
230+
231+
Calling `psa_crypto_init()` is equivalent to calling :code:`psa_crypto_init_subsystem(PSA_CRYPTO_ALL_SUBSYSTEMS)`.
232+
233+
See also :secref:`library-init`.
234+
235+
.. note::
73236

74-
.. warning::
75-
The set of functions that depend on successful initialization of the library is :scterm:`IMPLEMENTATION DEFINED`. Applications that rely on calling functions before initializing the library might not be portable to other implementations.
237+
Multiple subsystems can be initialized in the same call by passing a bitwise-or of ``PSA_CRYPTO_SUBSYSTEM_xxx`` values.
238+
If the initialization of one subsystem fails, it is unspecified whether other requested subsystems are initialized or not.

0 commit comments

Comments
 (0)