176 Commits

Author SHA1 Message Date
Gilles Peskine
11cac75449 Simplify and explain the overflow check for maximum slice length
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2024-08-22 10:55:40 +02:00
David Horstmann
9183ba1179 Add overflow check for maximum key slot length
Signed-off-by: David Horstmann <david.horstmann@arm.com>
2024-08-21 17:05:37 +01:00
David Horstmann
43124912c5 Tweak macro check to allow 3 extra key slices
We are technically allowed to use all possible values of key slice index
that will fit into the bit width we have allocated, so allow all values.

Signed-off-by: David Horstmann <david.horstmann@arm.com>
2024-08-21 15:18:28 +01:00
David Horstmann
a8e13d7c2a Fix incorrect comments on slice numbering
The persistent key cache slice is the last slice (not the first as
previously stated). Update the numbering-related comments accordingly.

Signed-off-by: David Horstmann <david.horstmann@arm.com>
2024-08-21 14:41:06 +01:00
Gilles Peskine
ac43de0e52 Make integer downsizing explicit
Reassure both humans and compilers that the places where we assign an
integer to a smaller type are safe.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2024-08-09 13:55:05 +02:00
Gilles Peskine
3bc9d2b5b9 Dynamic key store: make full-key-store tests work effectively
Add a practical way to fill the dynamic key store by artificially limiting
the slice length through a test hook.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2024-08-09 13:54:54 +02:00
Gilles Peskine
a81282ce30 Microoptimizations when MBEDTLS_PSA_KEY_STORE_DYNAMIC is disabled
Compensate some of the code size increase from implementing dynamic key slots.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2024-08-09 13:54:19 +02:00
Gilles Peskine
e8199f574c Dynamic key store: implementation
When MBEDTLS_PSA_KEY_STORE_DYNAMIC is enabled, key slots are now organized in
multiple slices. The slices are allocated on demand, which allows the key
store to grow. The size of slices grows exponentially, which allows reaching
a large number of slots with a small (static) number of slices without too
much overhead.

Maintain a linked list of free slots in each slice. This way, allocating a
slot takes O(1) time unless a slice needs to be allocated.

In this commit, slices are only ever freed when deinitializing the key
store. This should be improved in the future to free empty slices.

To avoid growing the persistent key cache without control, the persistent
key cache has a fixed size (reusing MBEDTLS_PSA_KEY_SLOT_COUNT to avoid
creating yet another option).

When MBEDTLS_PSA_KEY_STORE_DYNAMIC is disabled. no semantic change and
minimal changes to the code.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2024-08-09 13:52:56 +02:00
Gilles Peskine
47ad2f7484 psa_key_slot_t: different fields in free vs occupied slots
Place some fields of psa_key_slot_t in a union, to prepare for a new field
in free slots that should not require extra memory.

For occupied slots, place only the registered_readers field in the union,
not other fields, to minimize textual changes. All fields could move to the
union except state (also needed in free slots) and attr (which must stay
first to reduce the code size, because it is accessed at many call sites).

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2024-08-09 13:52:54 +02:00
Gilles Peskine
5064af62b6 Dynamic key store: preparatory refactoring
Add some abstractions around code that traverses the key store, in
preparation for adding support for MBEDTLS_PSA_KEY_STORE_DYNAMIC.

No intended behavior change. The generated machine code should be
almost the same with an optimizing compiler (in principle, it could be the
same with sufficient constant folding and inlining, but in practice it will
likely be a few byes larger),

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2024-08-09 13:52:33 +02:00
Gilles Peskine
5eca4029c2 Fix inverted assertion message
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2024-08-07 20:08:23 +02:00
Gilles Peskine
708ec09e30 Assert that the key ID range for volatile keys is large enough
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2024-07-17 12:21:21 +02:00
Gilles Peskine
b6bf370159 Assert that key ID ranges don't overlap
Ensure that a key ID can't be in range for more than one of volatile keys,
persistent (i.e. user-chosen) keys or built-in keys.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2024-07-17 12:21:21 +02:00
Ryan Everett
1a3573e226 Clarify psa_get_and_lock_key_slot return behaviour
Signed-off-by: Ryan Everett <ryan.everett@arm.com>
2024-04-30 14:09:43 +01:00
Ryan Everett
d4ea40de44 Fix potential non-NULL slot return on failure
If psa_get_and_lock_key_slot fails, the slot must be wiped.
This fixes a bug where a pointer to some valid key slot can
be incorrectly returned

Signed-off-by: Ryan Everett <ryan.everett@arm.com>
2024-04-30 14:09:43 +01:00
Paul Elliott
78279962d6 Fix minor style issues
Signed-off-by: Paul Elliott <paul.elliott@arm.com>
2024-03-15 13:34:01 +00:00
Paul Elliott
838886da64 Protect the key slot management initialised flag
Use the global data mutex, as the key slot mutex has to be held in some
of the functions where we are testing the flag, and we already hold the
global data mutex when calling the functions where the flag is set.

Signed-off-by: Paul Elliott <paul.elliott@arm.com>
2024-03-13 12:39:02 +00:00
Gilles Peskine
7fad3ef3b5 Switch key slots to psa_key_attributes_t
Switch `psa_key_slot_t` to the full `psa_key_attributes_t`, now that this
structure only has psa_core_key_attributes_t`.

To minimize the diff without breaking the build much, temporarily make
`psa_key_attributes_t` contain either the `core` field or all the fields.
This allows both things like `slot->attr.core.type` and `slot->attr.type`
to exist. The build breaks with compilers that don't support anonymous
unions and structs, which are only standard C since C11.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2024-02-28 01:30:24 +01:00
Ryan Everett
e110a4c900 Make psa_open_key threadsafe
This is a simple case of register then unregister

Signed-off-by: Ryan Everett <ryan.everett@arm.com>
2024-02-22 10:43:24 +00:00
Paul Elliott
d237190f04
Merge pull request #8773 from Ryan-Everett-arm/threadsafe-key-locking
Make key locking and one-shot operations thread safe
2024-02-21 13:55:12 +00:00
Ryan Everett
91ce792253 Fix return code error when locking mutex
Signed-off-by: Ryan Everett <ryan.everett@arm.com>
2024-02-12 12:17:28 +00:00
Ryan Everett
9dc076b4f4 Fix issue with lock failures returning CORRUPTION_DETECTED
Signed-off-by: Ryan Everett <ryan.everett@arm.com>
2024-02-09 14:20:09 +00:00
Ryan Everett
a76a0011ab Remove mutex calls in psa_wipe_all_key_slots
Code size and code style improvement, these calls aren't needed.

Signed-off-by: Ryan Everett <ryan.everett@arm.com>
2024-02-06 16:45:54 +00:00
Ryan Everett
eb1722a2b9 Add a wrapper function for psa_unregister_read
There are at least 20 occurences in the current code where
we will need this pattern of code, so I thought it best to
put this in a function

Signed-off-by: Ryan Everett <ryan.everett@arm.com>
2024-01-31 13:36:39 +00:00
Ryan Everett
2f1f17201d Make psa_get_and_lock_key_slot threadsafe
Signed-off-by: Ryan Everett <ryan.everett@arm.com>
2024-01-31 13:31:00 +00:00
Ryan Everett
6ad1fd133f Update psa_get_and_lock_key_slot_in_memory
Document that callers must hold the key slot mutex.
Change the volatile key checking behaviour so that it
doesn't read the contents of non-FULL slots.

Signed-off-by: Ryan Everett <ryan.everett@arm.com>
2024-01-31 13:21:33 +00:00
Ryan Everett
5c5210f7e1 Remove state transitions in psa_load_X_key_into_slot
These calls otherwise don't abide by our assertions about changing the slot.
psa_get_and_lock_key_slot, the only caller to these, handles the state
transitions already. It also changes the contents of the slot after these calls.

Signed-off-by: Ryan Everett <ryan.everett@arm.com>
2024-01-30 18:27:16 +00:00
Ryan Everett
3af9bc18f3 Wrap get_and_lock_key_slot_in_memory calls in mutex
It is useful to do this for the call in get_and_lock_key_slot.
Documenting that get_and_lock_key_slot_in_memory requires the mutex
is not part of this PR

Signed-off-by: Ryan Everett <ryan.everett@arm.com>
2024-01-30 17:21:57 +00:00
Ryan Everett
16abd59a62 Update psa_wipe_all_key_slots and document non-thread safety
This function, and mbedtls_psa_crypto_free, are not thread safe as they wipe slots
regardless of state. They are not part of the PSA Crypto API, untrusted applications
cannot call these functions in a crypto service.
In a service intergration, mbedtls_psa_crypto_free on the client cuts the communication
with the crypto service.

Signed-off-by: Ryan Everett <ryan.everett@arm.com>
2024-01-29 13:14:50 +00:00
Ryan Everett
b0821959ae Make psa_purge_key thread safe
Relies on get_and_lock_X being thread safe.
There are two mutex locks here, one in psa_get_and_lock...
Linearization point is the final unlock (or first lock on failure).

Signed-off-by: Ryan Everett <ryan.everett@arm.com>
2024-01-29 13:14:50 +00:00
Ryan Everett
f23336e040 Make psa_close_key thread safe
There are two mutex locks here, the one performed in get_and_lock.. and the one performed outside.
Linearizes at the final unlock.
(This function is deprecated)
Signed-off-by: Ryan Everett <ryan.everett@arm.com>
2024-01-29 13:13:15 +00:00
Ryan Everett
558da2ffd3 Move key_slot_mutex to threading.h
Make this a global mutex so that we don't have to init and free it.
Also rename the mutex to follow the convention

Signed-off-by: Ryan Everett <ryan.everett@arm.com>
2024-01-19 12:59:28 +00:00
Ryan Everett
846889355c Initialize and free the key slot mutex
Signed-off-by: Ryan Everett <ryan.everett@arm.com>
2024-01-18 10:47:05 +00:00
Ryan Everett
491f7e5ac3 Define key_slot_mutex
Signed-off-by: Ryan Everett <ryan.everett@arm.com>
2024-01-18 10:21:38 +00:00
Ryan Everett
709120a9ce Revert change to return behaviour in psa_reserve_free_key_slot
This change was a mistake, we still need to wipe the pointers here.

Signed-off-by: Ryan Everett <ryan.everett@arm.com>
2024-01-15 11:20:50 +00:00
Ryan Everett
dfe8bf86a8 Return CORRUPTION_DETECTED instead of BAD_SLOT when the slot's state is wrong
These error codes are only returned if the program has been tampered with,
so they should be CORRUPTION_DETECTED.

Signed-off-by: Ryan Everett <ryan.everett@arm.com>
2024-01-15 11:20:50 +00:00
Ryan Everett
4755e6bda4 Relax psa_wipe_key_slot to allow states other than SLOT_PENDING_DELETION
psa_wipe_key_slot can now be called on a slot in any state, if the slot's state
is PSA_SLOT_FULL or PSA_SLOT_PENDING_DELETION then there must be exactly 1 registered
reader.

Remove the state changing calls that are no longer necessary.

Signed-off-by: Ryan Everett <ryan.everett@arm.com>
2024-01-15 11:20:35 +00:00
Ryan Everett
6a9c14b918 Update mbedtls_psa_get_stats
Uses readers to report "locked_slots",
and slot state empty to report "empty_slots".

Signed-off-by: Ryan Everett <ryan.everett@arm.com>
2024-01-04 16:57:48 +00:00
Ryan Everett
6cd2b8db96 Update psa_wipe_all_key_slots
This will still wipe the slot regardless of state/readers.

Signed-off-by: Ryan Everett <ryan.everett@arm.com>
2024-01-04 16:57:48 +00:00
Ryan Everett
1b70a07eca Replace psa_unlock_key_slot calls in operations which act on FULL slots
Replaces calls to psa_unlock_key_slot with calls to psa_unregister_read.

All instances follow a pattern of a call to psa_get_and_lock_key_slot_X,
followed by some code which reads from a slot, followed by a call to psa_unregister_read.

Signed-off-by: Ryan Everett <ryan.everett@arm.com>
2024-01-04 16:57:48 +00:00
Ryan Everett
eb27dc0f3a Update psa_load_X_key_into_slot
These functions (on success) take a slot from PSA_SLOT_FILLING to PSA_SLOT_FULL.

Signed-off-by: Ryan Everett <ryan.everett@arm.com>
2024-01-04 16:57:48 +00:00
Ryan Everett
c70ce576bd Update psa_destroy_key, psa_purge_key and psa_close_key
This does not yet implement destruction while a key is in use for psa_destroy_key;
that will be implemented in a separate pr.
(I am not sure if I am allowed to change the documentation in the include files.)

Signed-off-by: Ryan Everett <ryan.everett@arm.com>
2024-01-04 16:57:48 +00:00
Ryan Everett
098c6659ad Update psa_get_and_lock_key_slot_X functions
Signed-off-by: Ryan Everett <ryan.everett@arm.com>
2024-01-04 16:57:48 +00:00
Ryan Everett
2afb516011 Update and rename psa_get_empty_key_slot
Rename to psa_reserve_free_key_slot, as this function reserves a slot which is
free (not always empty) for filling.
Implement necessary state transitions and state checks.
Rename unlocked_persistent_key_slot to unused_persistent_key_slot.

Signed-off-by: Ryan Everett <ryan.everett@arm.com>
2024-01-04 16:57:48 +00:00
Ryan Everett
39cc9d755e Implement psa_register_read and psa_unregister_read
Replaces psa_lock_key_slot and psa_unlock_key_slot.
Future commits will remove the calls to locking/unlocking functions,
and add calls to registering/unregistering functions.

Signed-off-by: Ryan Everett <ryan.everett@arm.com>
2024-01-04 16:57:48 +00:00
Ryan Everett
2a0d4e2995 Revert "Refactor psa_load_persistent_key_into_slot to remove bad goto"
This reverts commit d69f4017fbf949ab3aceca178b034b73e6e43dbc.

Signed-off-by: Ryan Everett <ryan.everett@arm.com>
2023-11-23 16:34:35 +00:00
Ryan Everett
d69f4017fb Refactor psa_load_persistent_key_into_slot to remove bad goto
Merges the two calls to `psa_copy_key_material_into_slot.

Signed-off-by: Ryan Everett <ryan.everett@arm.com>
2023-11-23 16:20:45 +00:00
Ryan Everett
9f176a2766 Fix status assignments when loading persistent keys
Signed-off-by: Ryan Everett <ryan.everett@arm.com>
2023-11-21 11:49:57 +00:00
Ryan Everett
975d411d92 Only set slot to OCCUPIED on successful key loading
Signed-off-by: Ryan Everett <ryan.everett@arm.com>
2023-11-16 13:37:51 +00:00
Ryan Everett
5567e3a34b Make empty key slots explicit
Add new status field to key slots, and use it.

Signed-off-by: Ryan Everett <ryan.everett@arm.com>
2023-11-08 13:28:20 +00:00