From 7d418ec92426a7e23bee0fe8946b7682be3d6e9b Mon Sep 17 00:00:00 2001 From: Marcus Streets Date: Tue, 16 Jan 2024 11:13:49 +0000 Subject: [PATCH 1/8] Added the iterator and rename commands to Protected storage. Signed-off-by: Marcus Streets --- doc/storage/about.rst | 6 + doc/storage/api/api.rst | 236 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 229 insertions(+), 13 deletions(-) diff --git a/doc/storage/about.rst b/doc/storage/about.rst index 00b21fc5..d93eb4fd 100644 --- a/doc/storage/about.rst +++ b/doc/storage/about.rst @@ -41,6 +41,12 @@ Provide a Security Risk Assessment. +.. release:: 1.1.0 + :date: January 2024 + :confidentiality: Non-confidential + + Added rename and iteration + .. release-info:: :extend: diff --git a/doc/storage/api/api.rst b/doc/storage/api/api.rst index 378798f2..25dccb6b 100644 --- a/doc/storage/api/api.rst +++ b/doc/storage/api/api.rst @@ -63,7 +63,19 @@ These definitions must be defined in the header file :file:`psa/storage_common.h .. field:: psa_storage_create_flags_t flags The flags set when the ``uid`` was create +.. struct:: psa_storage_iterator_t + .. summary:: + An implementation-defined opaque structure containing the context for an iterator. + The structure MUST contain all all the state required by the iterator. + That is, further state MUST NOT be retained by the implementation. + + The structure is initilaised by the `ps_iterator_start()` function. + It is modified by the `ps_iterator_next()` function. + + the caller can discard or reuse the iterator object once it has finished using it. This can be before, or after, the iterator has reached the end of the iteration. + + The header file is only required to define this structure if PSA_STORAGE_SUPPORT_ITERATION is true. .. typedef:: uint32_t psa_storage_create_flags_t @@ -97,11 +109,35 @@ These definitions must be defined in the header file :file:`psa/storage_common.h The data associated with the ``uid`` does not require replay protection. This can permit faster storage --- but it permits an attacker with physical access to revert to an earlier version of the data. +.. macro:: PSA_STORAGE_FLAG_REPLACE + (1u << 3) + + Flag instructing the `psa_ps_rename()` function to replace existing stored data. + .. macro:: PSA_STORAGE_SUPPORT_SET_EXTENDED (1u << 0) Flag indicating that `psa_ps_create()` and `psa_ps_set_extended()` are supported. + +.. macro:: PSA_STORAGE_SUPPORT_RENAME + (1u << 1) + + Flag indicating that `psa_ps_rename()` is supported. + +.. macro:: PSA_STORAGE_SUPPORT_ITERATION + (1u << 2) + + Flag indicating that `psa_ps_iterator_start()` and `psa_ps_iterator_next()` are supported. + +.. macro:: PSA_STORAGE_ITERATOR_CTX__SIZE + :definition: /* implementation-defined value */ + + .. summary:: + A sufficient buffer size for a iterator context, in bytes. + This macro is only required if PSA_STORAGE_SUPPORT_ITERATION is true + + .. _ITS-API: Internal Trusted Storage API @@ -181,7 +217,7 @@ These definitions must be defined in the header file :file:`psa/internal_trusted * The ``uid`` value must not be zero. - * If ``uid`` exists it must not have been created as with `PSA_STORAGE_FLAG_WRITE_ONCE` --- would result in ``PSA_ERROR_NOT_PERMITTED`` + * If ``uid`` exists it must not have been created as with `PSA_STORAGE_FLAG_WRITE_ONCE` --- would result in `PSA_ERROR_NOT_PERMITTED` * The caller must have access all memory from ``p_data`` to ``p_data + data_length``. @@ -235,9 +271,9 @@ These definitions must be defined in the header file :file:`psa/internal_trusted * The value of ``data_offset`` must be less than or equal to the length of ``uid``. - * If ``data_ffset`` is greater than ``uid.size``, no data is retrieved and the functions returns PSA_INVALID_ARGUMENT. + * If ``data_offset`` is greater than ``uid.size``, no data is retrieved and the functions returns PSA_INVALID_ARGUMENT. - * If ``data_size`` is not zero, ``p_data`` must mot be ``NULL``. + * If ``data_size`` is not zero, ``p_data`` must not be ``NULL``. * The call must have access to the memory from ``p_data`` to ``p_data + data_size - 1``. @@ -353,14 +389,14 @@ These definitions must be defined in the header file :file:`psa/protected_storag .. function:: psa_ps_set .. summary:: - Set the data associated with the specified ``uid``. + Set the data associated with the specified ``uid``, replacing any previous data. .. param:: psa_storage_uid_t uid The identifier for the data. .. param:: size_t data_length The size in bytes of the data in ``p_data``. If ``data_length == 0`` the implementation will create a zero-length asset associated with the ``uid``. - While no data can be stored in such an asset, a call to `psa_ps_get_info()` will return ``PSA_SUCCESS``. + While no data can be stored in such an asset, a call to `psa_ps_get_info()` will return `PSA_SUCCESS`. .. param:: const void * p_data A buffer containing the data. .. param:: psa_storage_create_flags_t create_flags @@ -379,6 +415,9 @@ These definitions must be defined in the header file :file:`psa/protected_storag * The ``uid`` is ``0``. * The operation failed because caller cannot access some or all of the memory in the range [``p_data``, ``p_data + data_length - 1``]. + + * the uid exists and ``data_length`` is greater then ```capacity`` + .. retval:: PSA_ERROR_NOT_SUPPORTED The operation failed because one or more of the flags provided in ``create_flags`` is not supported or is not valid. .. retval:: PSA_ERROR_INSUFFICIENT_STORAGE @@ -388,8 +427,9 @@ These definitions must be defined in the header file :file:`psa/protected_storag .. retval:: PSA_ERROR_GENERIC_ERROR The operation failed because of an unspecified internal failure. - The newly created asset has a capacity and size that are equal to ``data_length``. + If ``uid`` does not already exist, creates a new asset, the newly created asset has a capacity and size that are equal to ``data_length``. + If ``uid`` exists and was not created with `PSA_STORAGE_FLAG_WRITE_ONCE`, replaces the existing contents with ``p_data``. ``uid.size`` is set to ``data_length``. If ``data_length`` is greater than ``uid.capcity``, ``uid.capcity`` is set to ``data_length``. * The ``uid`` value must not be zero. @@ -454,7 +494,7 @@ These definitions must be defined in the header file :file:`psa/protected_storag * If ``data_offset`` is greater than ``uid.size`` the function retrieves no data and returns ``PSA_ERROR_INVALID_ARGUMENT`` - * If ``data_size`` is not zero, ``p_data`` must mot be ``NULL``. + * If ``data_size`` is not zero, ``p_data`` must not be ``NULL``. * The call must have access to the memory from ``p_data`` to ``p_data + data_size - 1``. @@ -508,6 +548,7 @@ These definitions must be defined in the header file :file:`psa/protected_storag * Even if all parameters are correct, the function can fail in the case of a storage failure. + .. function:: psa_ps_remove .. summary:: @@ -542,6 +583,7 @@ These definitions must be defined in the header file :file:`psa/protected_storag * Even if all parameters are correct, the function can fail in the case of a storage failure. + .. function:: psa_ps_create .. summary:: @@ -594,7 +636,7 @@ These definitions must be defined in the header file :file:`psa/protected_storag .. function:: psa_ps_set_extended .. summary:: - Overwrite part of the data of the specified ``uid``. + Overwrite part of the data of the specified ``uid``, leaving remaining data unchanged. .. param:: psa_storage_uid_t uid The unique identifier for the asset. @@ -638,13 +680,13 @@ These definitions must be defined in the header file :file:`psa/protected_storag Calling this function with ``data_length == 0`` is permitted. This makes no change to the stored data. - This function can overwrite existing data and/or extend it up to the capacity for the ``uid`` specified in `psa_ps_create()` but cannot create gaps. + This function can overwrite existing data and/or extend it up to the capacity for the ``uid`` specified in ``psa_ps_create()`` but cannot create gaps. - This function is optional. Consult the platform documentation to determine if it is implemented or perform a call to `psa_ps_get_support()`. This function must be implemented if `psa_ps_get_support()` returns `PSA_STORAGE_SUPPORT_SET_EXTENDED`. + This function is optional. Consult the platform documentation to determine if it is implemented or perform a call to ``psa_ps_get_support()``. This function must be implemented if ``psa_ps_get_support()`` returns ``PSA_STORAGE_SUPPORT_SET_EXTENDED``. * The ``uid`` value must not be zero. - * If ``uid`` exists it must not have been created as with `PSA_STORAGE_FLAG_WRITE_ONCE` - would result in ``PSA_ERROR_NOT_PERMITTED`` + * If ``uid`` exists it must not have been created as with ``PSA_STORAGE_FLAG_WRITE_ONCE`` - would result in ``PSA_ERROR_NOT_PERMITTED`` * ``data_offset <= size`` @@ -658,11 +700,175 @@ These definitions must be defined in the header file :file:`psa/protected_storag * ``capacity`` unchanged. + * Data in the ranges 0 to ``data_offset`` is not modified. + * If ``data_offset + data_length < size`` then data in the range ``data_offset + data_length` to `size`` is not modified. -.. function:: psa_ps_get_support - .. return:: uint32_t + +.. function:: psa_ps_rename + + .. summary:: + Atomically renames the storage location with the specified ``uid`` to a ``uid_new``. + + .. param:: psa_storage_uid_t uid + The current identifier for the data. + + .. param:: psa_storage_uid_t uid_new + The new identifier for the data. + + .. param:: psa_storage_rename_flags_t rename_flags + The flags must be either ``PSA_STORAGE_FLAG_NONE`` or ``PSA_STORAGE_FLAG_REPLACE`` + + .. return:: psa_status_t + A status indicating the success or failure of the operation. + + .. retval:: PSA_SUCCESS + The operation completed successfully. + + .. retval:: PSA_ERROR_ALREADY_EXISTS + Storage with the specified ``uid_new`` already exists and ``rename_flags`` is `PSA_STORAGE_FLAG_NONE` + + .. retval:: PSA_ERROR_DOES_NOT_EXIST + Storage with the specified ``uid`` does not exist. + + .. retval:: PSA_ERROR_GENERIC_ERROR + The operation failed because of an unspecified internal failure. + + .. retval:: PSA_ERROR_INVALID_ARGUMENT + The operation failed because either: + + * ``uid`` is ``0``. + * ``uid_new`` is ``0`` + * the ``psa_storage_rename_flags_t`` has a value set other than `PSA_STORAGE_FLAG_REPLACE` + + .. retval:: PSA_ERROR_NOT_PERMITTED + The operation failed because ``uid_new`` exists and was created with `PSA_STORAGE_FLAG_WRITE_ONCE`. + + .. retval:: PSA_ERROR_NOT_SUPPORTED + The implementation does not support the operation. + + .. retval:: PSA_ERROR_STORAGE_FAILURE + The operation failed because the physical storage has failed (Fatal error). + + + The function renames ``uid`` to ``uid_new`` retaining the storage flags that ``uid`` was created with. + + If the caller specifies `PSA_STORAGE_FLAG_REPLACE` the operation atomically replaces the exisitng contents of ```uid_new`` with those of ``uid``. + + Except in the case of ``PSA_ERROR_STORAGE_FAILURE``, in which case no guarantees can be made, the operation shall either succeed or leave storage unchanged. + + +.. function:: psa_ps_iterator_start + + .. summary:: + Initialises an iterator that can be used to return a list of uids in the Protected Storage . + + .. param:: psa_storage_iterator_t* context + A pointer to a context for this iterator. The pointer may be NULL. This is set to a new value on success and is undefined on error. The content of the iterator is implementation defined. + + .. param:: psa_storage_uid_t filter + A value used to filter the results included in this iteration. + + .. param:: int_t filter_length + A length of the filter to use, this must be a value ``0 < filter_lemngth < 63``. + + .. param:: psa_storage_uid_t *result + A pointer to the location in which to store ``uid``. On success the contents of this location will be updated with the first matching ``uid``. On error, the contents are undefined. + + .. return:: psa_status_t + A status indicating the success or failure of the operation. + + .. retval:: PSA_SUCCESS + The operation completed successfully. + + .. retval:: PSA_ERROR_DOES_NOT_EXIST + No ``uid`` matches this iteration. + + .. retval:: PSA_ERROR_STORAGE_FAILURE + The operation failed because the physical storage has failed (Fatal error). + + The iterator returns those values where the ``filter_length`` bits of the ``uid`` matches the left most bits in ``filter``. + + The iterator will only returns those ``uid`` that were created by the caller. It MUST not return any ``uid`` created by a different user. + + An iterator is not required to return uids in any specific order, but MUST return them in a consistent order each time it is called. For example, if an implementation returns entries in numerical order, it should not arbitrarily change to returning them in creation order. However, the caller should not make assumptions as to the order in which entries are returned, except that each ``uid`` will be returned only once in each iteration. + + Changes to storage by other users MUST NOT affect any open iterations. + + A caller may initialize multiple iteration contexts at the same time. Each iteration shall be independent. Calling ``psa_ps_iterator_next()`` on one iterator MUST not effect any other open iteration. + + An iterator MUST return all data objects whose ``uid`` matches the filter that are extant when the filter was created, unless these are deleted or renamed before the iteration would return them, or the caller stops before all matching objects have been returned. + + A caller may delete a ``uid`` with `psa_ps_remove(uid)` without invalidating the iteration context. the iterator MUST never return a ``uid`` that has been deleted. However, if the caller is multi-threaded it ia possible another thread may delete a ``uid``. + + A caller may read the contents of any ``uid`` with `psa_ps_get()` or write with `psa_ps_set(` or `psa_ps_set_extended()` without invalidating the iteration context. + + A caller may create a ``uid`` with `psa_ps_set()` or `psa_ps_create()` without invalidating the iteration context. However, the iterator is NOT guaranteed to return the new object, ``uid``, the behavior is dependent on both implementation and identity. In particular, the iterator is not expected to return ``uid`` if the iteration is already past the point at which it would naturally be returned. + + A caller may call `psa_ps_rename(uid, uid_new)` without invalidating the iteration context. The iterator must not return ``uid``. The iterator is not guaranteed to return ``uid_new``, the behavior is dependent on both implementation and identity. + + The following code snippet uses a linked list to store the matching files before iterating over that list and removing them. + + .. code-block:: c + + my_context = NULL + my_filter = 0x1111 0000 0000 0000 + my_length = 0x0020 + my_result = NULL + if psa_ps_iterator_start(my_context, my_filter, my-length, my_result) == PSA_SUCCESS + { + do + { + // do something with my_result + psa_ps_iterator_next(my_context, my_result) + // we will get an does not exist error when we reach the last item, any other error is a storage failure + if my_reult <> PSA_ERROR_DOES_NOT_EXIST + { + /* deal with storage failure */ + } + } + while my_result == PSA_SUCCES ; + }; + + + + +.. function:: psa_ps_iterator_next + + .. summary:: + + Returns the next ``uid`` in this iteration. + + .. param:: psa_storage_iterator_t* context + A pointer to a context for this iterator as returned by `psa_ps_iterator_start()` or updated by a previous call to `psa_ps_iterator_next()`. The content of the iterator will change on success and is undefined on error. + + .. param:: psa_storage_uid_t *result + A pointer to the location in which to store ``uid``. On success the contents of this location will be updated with the next matching ``uid``. On error, the contents are undefined. + + .. return:: psa_status_t + A status indicating the success or failure of the operation. + + .. retval:: PSA_SUCCESS + The operation completed successfully. + + .. retval:: PSA_ERROR_DOES_NOT_EXIST + The iterator has returned all the uids that match this iteration. + + .. retval:: PSA_ERROR_STORAGE_FAILURE + The operation failed because the physical storage has failed (Fatal error). + + .. retval:: PSA_ERROR_DATA_CORRUPT + The operation failed because the contents of the iteration have changed. That is a ``uid`` matching the filter has either been created or deleted. + + .. retval:: PSA_ERROR_INVALID_ARGUMENT + The operation failed because either: + + * The provided context is not valid. + + * The caller cannot access the memory at `result` + +.. function:: psa_ps_get_support .. summary:: Returns a bitmask with flags set for the optional features supported by the implementation. @@ -670,3 +876,7 @@ These definitions must be defined in the header file :file:`psa/protected_storag Currently defined flags are limited to: * `PSA_STORAGE_SUPPORT_SET_EXTENDED` + * `PSA_STORAGE_SUPPORT_RENAME` + * `PSA_STORAGE_SUPPORT_ITERATION` + + .. return:: uint32_t From 64146f394833562409cf4b655bec83d9e3130462 Mon Sep 17 00:00:00 2001 From: Marcus Streets Date: Fri, 19 Apr 2024 13:14:09 +0100 Subject: [PATCH 2/8] Fixing build errors Adding SP800-30 to references. Signed-off-by: Marcus Streets --- doc/storage/about.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/storage/about.rst b/doc/storage/about.rst index d93eb4fd..e72362c7 100644 --- a/doc/storage/about.rst +++ b/doc/storage/about.rst @@ -1,4 +1,4 @@ -.. SPDX-FileCopyrightText: Copyright 2018-2019, 2022-2024 Arm Limited and/or its affiliates +.. SPDX-FileCopyrightText: Copyright 2018-2019, 2022-2023 Arm Limited and/or its affiliates .. SPDX-License-Identifier: CC-BY-SA-4.0 AND LicenseRef-Patent-license .. Releases of this specification @@ -39,13 +39,13 @@ :date: January 2024 :confidentiality: Non-confidential - Provide a Security Risk Assessment. + Added draft SRA. .. release:: 1.1.0 :date: January 2024 :confidentiality: Non-confidential - Added rename and iteration + Added rename and iteration .. release-info:: :extend: @@ -70,16 +70,16 @@ :doc_no: ARM IHI 0097 :url: arm-software.github.io/psa-api/status-code -.. reference:: PSA-FFM +.. reference:: PSA-FF-M :title: ArmĀ® Platform Security Architecture Firmware Framework :doc_no: ARM DEN 0063 - :url: developer.arm.com/documentation/den0063 + :url: pages.arm.com/psa-apis .. reference:: SP800-30 :title: NIST Special Publication 800-30 Revision 1: Guide for Conducting Risk Assessments :author: NIST :publication: September 2012 - :url: doi.org/10.6028/NIST.SP.800-30r1 + :url: doi.org/10.6028/NIST.SP.800-30r1 .. Glossary terms used in this specification From b52daa292898ac88329ff2cad1e30882326dae6a Mon Sep 17 00:00:00 2001 From: Marcus Streets Date: Fri, 19 Apr 2024 13:15:15 +0100 Subject: [PATCH 3/8] Adding iterator to its Signed-off-by: Marcus Streets --- doc/storage/api/api.rst | 195 ++++++++++++++++++++++++++++++++++------ 1 file changed, 169 insertions(+), 26 deletions(-) diff --git a/doc/storage/api/api.rst b/doc/storage/api/api.rst index 25dccb6b..c1f696fe 100644 --- a/doc/storage/api/api.rst +++ b/doc/storage/api/api.rst @@ -1,4 +1,4 @@ -.. SPDX-FileCopyrightText: Copyright 2018-2019, 2022-2023 Arm Limited and/or its affiliates +.. SPDX-FileCopyrightText: Copyright 2018-2019, 2022-2024 Arm Limited and/or its affiliates .. SPDX-License-Identifier: CC-BY-SA-4.0 AND LicenseRef-Patent-license API Reference @@ -9,7 +9,7 @@ Status codes The |API| uses the status code definitions that are shared with the other PSA Certified APIs. -The following elements are defined in :file:`psa/error.h` from :cite-title:`PSA-STAT` (previously defined in :cite:`PSA-FFM`): +The following elements are defined in :file:`psa/error.h` from :cite-title:`PSA-STAT` (previously defined in :cite:`PSA-FF-M`): .. code-block:: xref @@ -63,15 +63,29 @@ These definitions must be defined in the header file :file:`psa/storage_common.h .. field:: psa_storage_create_flags_t flags The flags set when the ``uid`` was create -.. struct:: psa_storage_iterator_t +.. struct:: psa_its_storage_iterator_t .. summary:: An implementation-defined opaque structure containing the context for an iterator. The structure MUST contain all all the state required by the iterator. That is, further state MUST NOT be retained by the implementation. - The structure is initilaised by the `ps_iterator_start()` function. - It is modified by the `ps_iterator_next()` function. + The structure is initilaised by the ``ps_iterator_start()`` function. + It is modified by the ``ps_iterator_next()`` function. + + the caller can discard or reuse the iterator object once it has finished using it. This can be before, or after, the iterator has reached the end of the iteration. + + The header file is only required to define this structure if PSA_STORAGE_SUPPORT_ITERATION is true. + +.. struct:: psa_ps_storage_iterator_t + + .. summary:: + An implementation-defined opaque structure containing the context for an iterator. + The structure MUST contain all all the state required by the iterator. + That is, further state MUST NOT be retained by the implementation. + + The structure is initilaised by the ``ps_iterator_start()`` function. + It is modified by the ``ps_iterator_next()`` function. the caller can discard or reuse the iterator object once it has finished using it. This can be before, or after, the iterator has reached the end of the iteration. @@ -128,14 +142,7 @@ These definitions must be defined in the header file :file:`psa/storage_common.h .. macro:: PSA_STORAGE_SUPPORT_ITERATION (1u << 2) - Flag indicating that `psa_ps_iterator_start()` and `psa_ps_iterator_next()` are supported. - -.. macro:: PSA_STORAGE_ITERATOR_CTX__SIZE - :definition: /* implementation-defined value */ - - .. summary:: - A sufficient buffer size for a iterator context, in bytes. - This macro is only required if PSA_STORAGE_SUPPORT_ITERATION is true + Flag indicating that `psa_its_iterator_start()`, `psa_its_iterator_next()` `psa_ps_iterator_start` and `psa_ps_iterator_next` are supported. .. _ITS-API: @@ -217,7 +224,7 @@ These definitions must be defined in the header file :file:`psa/internal_trusted * The ``uid`` value must not be zero. - * If ``uid`` exists it must not have been created as with `PSA_STORAGE_FLAG_WRITE_ONCE` --- would result in `PSA_ERROR_NOT_PERMITTED` + * If ``uid`` exists it must not have been created as with `PSA_STORAGE_FLAG_WRITE_ONCE` --- would result in ``PSA_ERROR_NOT_PERMITTED``. * The caller must have access all memory from ``p_data`` to ``p_data + data_length``. @@ -349,6 +356,133 @@ These definitions must be defined in the header file :file:`psa/internal_trusted * Even if all parameters are correct, the function can fail in the case of a storage failure. +.. function:: psa_its_iterator_start + + .. summary:: + Initialises an iterator that can be used to return a list of uids in the Internal Trusted Storage. + This function must be fully defined if `PSA_STORAGE_SUPPORT_ITERATION` is true. + If `PSA_STORAGE_SUPPORT_ITERATION` is false, then this function SHALL always return ``PSA_ERROR_NOT_SUPPORTED`` + + + .. param:: psa_its_storage_iterator_t* context + A pointer to a context for this iterator. The pointer may be NULL. This is set to a new value on success and is undefined on error. The content of the iterator is implementation defined. + + .. param:: psa_storage_uid_t filter + A value used to filter the results included in this iteration. + + .. param:: int_t filter_length + A length of the filter to use, this must be a value ``0 < filter_lemngth < 63``. + + .. param:: psa_storage_uid_t *result + A pointer to the location in which to store ``uid``. On success the contents of this location will be updated with the first matching ``uid``. On error, the contents are undefined. + + .. return:: psa_status_t + A status indicating the success or failure of the operation. + + .. retval:: PSA_SUCCESS + The operation completed successfully. + + .. retval:: PSA_ERROR_DOES_NOT_EXIST + No ``uid`` matches this iteration. + + .. retval:: PSA_ERROR_STORAGE_FAILURE + The operation failed because the physical storage has failed (Fatal error). + + The iterator returns those values where the ``filter_length`` bits of the ``uid`` matches the left most bits in ``filter``. + + The iterator will only returns those ``uid`` that were created by the caller. It MUST not return any ``uid`` created by a different user. + + An iterator is not required to return uids in any specific order, but MUST return them in a consistent order each time it is called. For example, if an implementation returns entries in numerical order, it should not arbitrarily change to returning them in creation order. However, the caller should not make assumptions as to the order in which entries are returned, except that each ``uid`` will be returned only once in each iteration. + + Changes to storage by other users MUST NOT affect any open iterations. + + A caller may initialize multiple iteration contexts at the same time. Each iteration shall be independent. Calling ``psa_its_iterator_next()`` on one iterator MUST not effect any other open iteration. + + An iterator MUST return all data objects whose ``uid`` matches the filter that are extant when the filter was created, unless these are deleted or renamed before the iteration would return them, or the caller stops before all matching objects have been returned. + + A caller may delete a ``uid`` with `psa_its_remove()` without invalidating the iteration context. the iterator MUST never return a ``uid`` that has been deleted. However, if the caller is multi-threaded it ia possible another thread may delete a ``uid``. + + A caller may read the contents of any ``uid`` with `psa_its_get()` or write with `psa_its_set` without invalidating the iteration context. + + A caller may create a ``uid`` with `psa_its_set()` without invalidating the iteration context. However, the iterator is NOT guaranteed to return the new object, ``uid``, the behavior is dependent on both implementation and identity. In particular, the iterator is not expected to return ``uid`` if the iteration is already past the point at which it would naturally be returned. + + A caller may call ``psa_its_rename(uid, uid_new)`` without invalidating the iteration context. The iterator must not return ``uid``. The iterator is not guaranteed to return ``uid_new``, the behavior is dependent on both implementation and identity. + + The following code snippet uses a linked list to store the matching files before iterating over that list and removing them. + + .. code-block:: c + + my_context = NULL + my_filter = 0x1111 0000 0000 0000 + my_length = 0x0020 + my_result = NULL + if psa_its_iterator_start(my_context, my_filter, my-length, my_result) == PSA_SUCCESS + { + do + { + // do something with my_result + psa_its_iterator_next(my_context, my_result) + // we will get an does not exist error when we reach the last item, any other error is a storage failure + if my_reult <> PSA_ERROR_DOES_NOT_EXIST + { + /* deal with storage failure */ + } + } + while my_result == PSA_SUCCESS ; + }; + + + + +.. function:: psa_its_iterator_next + + .. summary:: + + Returns the next ``uid`` in this iteration. + This function must be fully defined if `PSA_STORAGE_SUPPORT_ITERATION` is true. + If `PSA_STORAGE_SUPPORT_ITERATION` is false, then this function SHALL always return ``PSA_ERROR_NOT_SUPPORTED`` + + + .. param:: psa_its_storage_iterator_t* context + A pointer to a context for this iterator as returned by `psa_its_iterator_start()` or updated by a previous call to `psa_its_iterator_next()`. The content of the iterator will change on success and is undefined on error. + + .. param:: psa_storage_uid_t *result + A pointer to the location in which to store ``uid``. On success the contents of this location will be updated with the next matching ``uid``. On error, the contents are undefined. + + .. return:: psa_status_t + A status indicating the success or failure of the operation. + + .. retval:: PSA_SUCCESS + The operation completed successfully. + + .. retval:: PSA_ERROR_DOES_NOT_EXIST + The iterator has returned all the uids that match this iteration. + + .. retval:: PSA_ERROR_STORAGE_FAILURE + The operation failed because the physical storage has failed (Fatal error). + + .. retval:: PSA_ERROR_DATA_CORRUPT + The operation failed because the contents of the iteration have changed. That is a ``uid`` matching the filter has either been created or deleted. + + .. retval:: PSA_ERROR_INVALID_ARGUMENT + The operation failed because either: + + * The provided context is not valid. + + * The caller cannot access the memory at ``result`` + +.. function:: psa_its_get_support + + .. summary:: + Returns a bitmask with flags set for the optional features supported by the implementation. + + Currently defined flags are limited to: + + * `PSA_STORAGE_SUPPORT_ITERATION` + + .. return:: uint32_t + + .. _PS-API: Protected Storage API @@ -396,7 +530,7 @@ These definitions must be defined in the header file :file:`psa/protected_storag .. param:: size_t data_length The size in bytes of the data in ``p_data``. If ``data_length == 0`` the implementation will create a zero-length asset associated with the ``uid``. - While no data can be stored in such an asset, a call to `psa_ps_get_info()` will return `PSA_SUCCESS`. + While no data can be stored in such an asset, a call to `psa_ps_get_info()` will return ``PSA_SUCCESS``. .. param:: const void * p_data A buffer containing the data. .. param:: psa_storage_create_flags_t create_flags @@ -637,6 +771,8 @@ These definitions must be defined in the header file :file:`psa/protected_storag .. summary:: Overwrite part of the data of the specified ``uid``, leaving remaining data unchanged. + This function must be fully defined if `PSA_STORAGE_SUPPORT_SET_EXTENDED` is true. + If `PSA_STORAGE_SUPPORT_SET_EXTENDED` is false, then this function SHALL always return ``PSA_ERROR_NOT_SUPPORTED``. .. param:: psa_storage_uid_t uid The unique identifier for the asset. @@ -709,7 +845,9 @@ These definitions must be defined in the header file :file:`psa/protected_storag .. function:: psa_ps_rename .. summary:: - Atomically renames the storage location with the specified ``uid`` to a ``uid_new``. + Atomically renames the storage location with the specified ``uid`` to a ``uid_new``. + This function must be fully defined if `PSA_STORAGE_SUPPORT_RENAME` is true. + If `PSA_STORAGE_SUPPORT_RENAME` is false, then this function SHALL always return ``PSA_ERROR_NOT_SUPPORTED``. .. param:: psa_storage_uid_t uid The current identifier for the data. @@ -762,9 +900,12 @@ These definitions must be defined in the header file :file:`psa/protected_storag .. function:: psa_ps_iterator_start .. summary:: - Initialises an iterator that can be used to return a list of uids in the Protected Storage . + Initialises an iterator that can be used to return a list of uids in the Protected Storage. + This function must be fully defined if `PSA_STORAGE_SUPPORT_ITERATION` is true. + If `PSA_STORAGE_SUPPORT_ITERATION` is false, then this function SHALL always return ``PSA_ERROR_NOT_SUPPORTED`` - .. param:: psa_storage_iterator_t* context + + .. param:: psa_ps_storage_iterator_t* context A pointer to a context for this iterator. The pointer may be NULL. This is set to a new value on success and is undefined on error. The content of the iterator is implementation defined. .. param:: psa_storage_uid_t filter @@ -796,17 +937,17 @@ These definitions must be defined in the header file :file:`psa/protected_storag Changes to storage by other users MUST NOT affect any open iterations. - A caller may initialize multiple iteration contexts at the same time. Each iteration shall be independent. Calling ``psa_ps_iterator_next()`` on one iterator MUST not effect any other open iteration. + A caller may initialize multiple iteration contexts at the same time. Each iteration shall be independent. Calling ``psa_ps_iterator_next`` on one iterator MUST not effect any other open iteration. An iterator MUST return all data objects whose ``uid`` matches the filter that are extant when the filter was created, unless these are deleted or renamed before the iteration would return them, or the caller stops before all matching objects have been returned. - A caller may delete a ``uid`` with `psa_ps_remove(uid)` without invalidating the iteration context. the iterator MUST never return a ``uid`` that has been deleted. However, if the caller is multi-threaded it ia possible another thread may delete a ``uid``. + A caller may delete a ``uid`` with `psa_ps_remove()` without invalidating the iteration context. the iterator MUST never return a ``uid`` that has been deleted. However, if the caller is multi-threaded it ia possible another thread may delete a ``uid``. - A caller may read the contents of any ``uid`` with `psa_ps_get()` or write with `psa_ps_set(` or `psa_ps_set_extended()` without invalidating the iteration context. + A caller may read the contents of any ``uid`` with `psa_ps_get()` or write with `psa_ps_set()` or `psa_ps_set_extended()` without invalidating the iteration context. A caller may create a ``uid`` with `psa_ps_set()` or `psa_ps_create()` without invalidating the iteration context. However, the iterator is NOT guaranteed to return the new object, ``uid``, the behavior is dependent on both implementation and identity. In particular, the iterator is not expected to return ``uid`` if the iteration is already past the point at which it would naturally be returned. - A caller may call `psa_ps_rename(uid, uid_new)` without invalidating the iteration context. The iterator must not return ``uid``. The iterator is not guaranteed to return ``uid_new``, the behavior is dependent on both implementation and identity. + A caller may call ``psa_ps_rename(uid, uid_new)`` without invalidating the iteration context. The iterator must not return ``uid``. The iterator is not guaranteed to return ``uid_new``, the behavior is dependent on both implementation and identity. The following code snippet uses a linked list to store the matching files before iterating over that list and removing them. @@ -837,11 +978,12 @@ These definitions must be defined in the header file :file:`psa/protected_storag .. function:: psa_ps_iterator_next .. summary:: - Returns the next ``uid`` in this iteration. + This function must be fully defined if `PSA_STORAGE_SUPPORT_ITERATION` is true. + If `PSA_STORAGE_SUPPORT_ITERATION` is false, then this function SHALL always return ``PSA_ERROR_NOT_SUPPORTED`` - .. param:: psa_storage_iterator_t* context - A pointer to a context for this iterator as returned by `psa_ps_iterator_start()` or updated by a previous call to `psa_ps_iterator_next()`. The content of the iterator will change on success and is undefined on error. + .. param:: psa_ps_storage_iterator_t* context + A pointer to a context for this iterator as returned by `psa_ps_iterator_start` or updated by a previous call to `psa_ps_iterator_next`. The content of the iterator will change on success and is undefined on error. .. param:: psa_storage_uid_t *result A pointer to the location in which to store ``uid``. On success the contents of this location will be updated with the next matching ``uid``. On error, the contents are undefined. @@ -866,7 +1008,7 @@ These definitions must be defined in the header file :file:`psa/protected_storag * The provided context is not valid. - * The caller cannot access the memory at `result` + * The caller cannot access the memory at ``result`` .. function:: psa_ps_get_support @@ -880,3 +1022,4 @@ These definitions must be defined in the header file :file:`psa/protected_storag * `PSA_STORAGE_SUPPORT_ITERATION` .. return:: uint32_t + From 087695f7c122aa39d4475a7f66e9a223008a201e Mon Sep 17 00:00:00 2001 From: Marcus Streets Date: Fri, 19 Apr 2024 13:30:58 +0100 Subject: [PATCH 4/8] Spellcheck Signed-off-by: Marcus Streets --- doc/storage/api/api.rst | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/doc/storage/api/api.rst b/doc/storage/api/api.rst index c1f696fe..1cad71e5 100644 --- a/doc/storage/api/api.rst +++ b/doc/storage/api/api.rst @@ -70,7 +70,7 @@ These definitions must be defined in the header file :file:`psa/storage_common.h The structure MUST contain all all the state required by the iterator. That is, further state MUST NOT be retained by the implementation. - The structure is initilaised by the ``ps_iterator_start()`` function. + The structure is initialized by the ``ps_iterator_start()`` function. It is modified by the ``ps_iterator_next()`` function. the caller can discard or reuse the iterator object once it has finished using it. This can be before, or after, the iterator has reached the end of the iteration. @@ -359,8 +359,10 @@ These definitions must be defined in the header file :file:`psa/internal_trusted .. function:: psa_its_iterator_start .. summary:: - Initialises an iterator that can be used to return a list of uids in the Internal Trusted Storage. + Initializes an iterator that can be used to return a list of ``uid`` values in the Internal Trusted Storage. + This function must be fully defined if `PSA_STORAGE_SUPPORT_ITERATION` is true. + If `PSA_STORAGE_SUPPORT_ITERATION` is false, then this function SHALL always return ``PSA_ERROR_NOT_SUPPORTED`` @@ -371,7 +373,7 @@ These definitions must be defined in the header file :file:`psa/internal_trusted A value used to filter the results included in this iteration. .. param:: int_t filter_length - A length of the filter to use, this must be a value ``0 < filter_lemngth < 63``. + A length of the filter to use, this must be a value ``0 < filter_length < 63``. .. param:: psa_storage_uid_t *result A pointer to the location in which to store ``uid``. On success the contents of this location will be updated with the first matching ``uid``. On error, the contents are undefined. @@ -400,7 +402,7 @@ These definitions must be defined in the header file :file:`psa/internal_trusted An iterator MUST return all data objects whose ``uid`` matches the filter that are extant when the filter was created, unless these are deleted or renamed before the iteration would return them, or the caller stops before all matching objects have been returned. - A caller may delete a ``uid`` with `psa_its_remove()` without invalidating the iteration context. the iterator MUST never return a ``uid`` that has been deleted. However, if the caller is multi-threaded it ia possible another thread may delete a ``uid``. + A caller may delete a ``uid`` with `psa_its_remove()` without invalidating the iteration context. the iterator MUST never return a ``uid`` that has been deleted. However, if the caller is multi-threaded it is possible another thread may delete a ``uid``. A caller may read the contents of any ``uid`` with `psa_its_get()` or write with `psa_its_set` without invalidating the iteration context. @@ -412,10 +414,10 @@ These definitions must be defined in the header file :file:`psa/internal_trusted .. code-block:: c - my_context = NULL - my_filter = 0x1111 0000 0000 0000 - my_length = 0x0020 - my_result = NULL + my_context = NULL; + my_filter = 0x1111 0000 0000 0000; + my_length = 0x0020; + my_result = NULL; if psa_its_iterator_start(my_context, my_filter, my-length, my_result) == PSA_SUCCESS { do @@ -892,7 +894,7 @@ These definitions must be defined in the header file :file:`psa/protected_storag The function renames ``uid`` to ``uid_new`` retaining the storage flags that ``uid`` was created with. - If the caller specifies `PSA_STORAGE_FLAG_REPLACE` the operation atomically replaces the exisitng contents of ```uid_new`` with those of ``uid``. + If the caller specifies `PSA_STORAGE_FLAG_REPLACE` the operation atomically replaces the existing contents of ```uid_new`` with those of ``uid``. Except in the case of ``PSA_ERROR_STORAGE_FAILURE``, in which case no guarantees can be made, the operation shall either succeed or leave storage unchanged. @@ -900,7 +902,7 @@ These definitions must be defined in the header file :file:`psa/protected_storag .. function:: psa_ps_iterator_start .. summary:: - Initialises an iterator that can be used to return a list of uids in the Protected Storage. + Initializes an iterator that can be used to return a list of uids in the Protected Storage. This function must be fully defined if `PSA_STORAGE_SUPPORT_ITERATION` is true. If `PSA_STORAGE_SUPPORT_ITERATION` is false, then this function SHALL always return ``PSA_ERROR_NOT_SUPPORTED`` @@ -912,7 +914,7 @@ These definitions must be defined in the header file :file:`psa/protected_storag A value used to filter the results included in this iteration. .. param:: int_t filter_length - A length of the filter to use, this must be a value ``0 < filter_lemngth < 63``. + A length of the filter to use, this must be a value ``0 < filter_length < 63``. .. param:: psa_storage_uid_t *result A pointer to the location in which to store ``uid``. On success the contents of this location will be updated with the first matching ``uid``. On error, the contents are undefined. @@ -941,7 +943,7 @@ These definitions must be defined in the header file :file:`psa/protected_storag An iterator MUST return all data objects whose ``uid`` matches the filter that are extant when the filter was created, unless these are deleted or renamed before the iteration would return them, or the caller stops before all matching objects have been returned. - A caller may delete a ``uid`` with `psa_ps_remove()` without invalidating the iteration context. the iterator MUST never return a ``uid`` that has been deleted. However, if the caller is multi-threaded it ia possible another thread may delete a ``uid``. + A caller may delete a ``uid`` with `psa_ps_remove()` without invalidating the iteration context. the iterator MUST never return a ``uid`` that has been deleted. However, if the caller is multi-threaded it is possible another thread may delete a ``uid``. A caller may read the contents of any ``uid`` with `psa_ps_get()` or write with `psa_ps_set()` or `psa_ps_set_extended()` without invalidating the iteration context. @@ -953,23 +955,23 @@ These definitions must be defined in the header file :file:`psa/protected_storag .. code-block:: c - my_context = NULL - my_filter = 0x1111 0000 0000 0000 - my_length = 0x0020 - my_result = NULL + my_context = NULL; + my_filter = 0x1111 0000 0000 0000; + my_length = 0x0020; + my_result = NULL; if psa_ps_iterator_start(my_context, my_filter, my-length, my_result) == PSA_SUCCESS { do { // do something with my_result psa_ps_iterator_next(my_context, my_result) - // we will get an does not exist error when we reach the last item, any other error is a storage failure + // we will get an 'does not exist error' when we reach the last item, any other error is a storage failure if my_reult <> PSA_ERROR_DOES_NOT_EXIST { /* deal with storage failure */ } } - while my_result == PSA_SUCCES ; + while my_result == PSA_SUCCESS ; }; From 460d6f2bf06f8ad53ab8a5d4dad1d00d29b22f2c Mon Sep 17 00:00:00 2001 From: Marcus Streets Date: Thu, 18 Jul 2024 16:13:42 +0100 Subject: [PATCH 5/8] Add files via upload Signed-off-by: Marcus Streets --- doc/storage/api/api.rst | 201 +++++++++++++++++++++------------------- 1 file changed, 104 insertions(+), 97 deletions(-) diff --git a/doc/storage/api/api.rst b/doc/storage/api/api.rst index 1cad71e5..1334cd37 100644 --- a/doc/storage/api/api.rst +++ b/doc/storage/api/api.rst @@ -9,7 +9,7 @@ Status codes The |API| uses the status code definitions that are shared with the other PSA Certified APIs. -The following elements are defined in :file:`psa/error.h` from :cite-title:`PSA-STAT` (previously defined in :cite:`PSA-FF-M`): +The following elements are defined in :file:`psa/error.h` from :cite-title:`PSA-STAT` (previously defined in :cite:`PSA-FFM`): .. code-block:: xref @@ -63,34 +63,6 @@ These definitions must be defined in the header file :file:`psa/storage_common.h .. field:: psa_storage_create_flags_t flags The flags set when the ``uid`` was create -.. struct:: psa_its_storage_iterator_t - - .. summary:: - An implementation-defined opaque structure containing the context for an iterator. - The structure MUST contain all all the state required by the iterator. - That is, further state MUST NOT be retained by the implementation. - - The structure is initialized by the ``ps_iterator_start()`` function. - It is modified by the ``ps_iterator_next()`` function. - - the caller can discard or reuse the iterator object once it has finished using it. This can be before, or after, the iterator has reached the end of the iteration. - - The header file is only required to define this structure if PSA_STORAGE_SUPPORT_ITERATION is true. - -.. struct:: psa_ps_storage_iterator_t - - .. summary:: - An implementation-defined opaque structure containing the context for an iterator. - The structure MUST contain all all the state required by the iterator. - That is, further state MUST NOT be retained by the implementation. - - The structure is initilaised by the ``ps_iterator_start()`` function. - It is modified by the ``ps_iterator_next()`` function. - - the caller can discard or reuse the iterator object once it has finished using it. This can be before, or after, the iterator has reached the end of the iteration. - - The header file is only required to define this structure if PSA_STORAGE_SUPPORT_ITERATION is true. - .. typedef:: uint32_t psa_storage_create_flags_t .. summary:: @@ -133,18 +105,11 @@ These definitions must be defined in the header file :file:`psa/storage_common.h Flag indicating that `psa_ps_create()` and `psa_ps_set_extended()` are supported. - .. macro:: PSA_STORAGE_SUPPORT_RENAME (1u << 1) Flag indicating that `psa_ps_rename()` is supported. -.. macro:: PSA_STORAGE_SUPPORT_ITERATION - (1u << 2) - - Flag indicating that `psa_its_iterator_start()`, `psa_its_iterator_next()` `psa_ps_iterator_start` and `psa_ps_iterator_next` are supported. - - .. _ITS-API: Internal Trusted Storage API @@ -183,6 +148,24 @@ These definitions must be defined in the header file :file:`psa/internal_trusted It will be incremented in small updates that are unlikely to include breaking changes. +.. macro:: PSA_ITS_SUPPORT_ITERATION + (1u << 2) + + Flag indicating that `psa_its_iterator_start()` and `psa_its_iterator_next()` are supported. + +.. struct:: psa_its_storage_iterator_t + + .. summary:: + An implementation-defined opaque structure containing the context for an iterator. + The structure MUST contain all all the state required by the iterator. + That is, further state MUST NOT be retained by the implementation. + + The structure is initialized by the ``ps_iterator_start()`` function. + It is modified by the ``ps_iterator_next()`` function. + + the caller can discard or reuse the iterator object once it has finished using it. This can be before, or after, the iterator has reached the end of the iteration. + + The header file is only required to define this structure if PSA_STORAGE_SUPPORT_ITERATION is true. .. function:: psa_its_set @@ -361,13 +344,14 @@ These definitions must be defined in the header file :file:`psa/internal_trusted .. summary:: Initializes an iterator that can be used to return a list of ``uid`` values in the Internal Trusted Storage. - This function must be fully defined if `PSA_STORAGE_SUPPORT_ITERATION` is true. + This function must be fully defined if iteration is supported. - If `PSA_STORAGE_SUPPORT_ITERATION` is false, then this function SHALL always return ``PSA_ERROR_NOT_SUPPORTED`` - + If iteration is not supported, then this function SHALL be defined in the header - potentially as an inline function - but SHALL return ``PSA_ERROR_NOT_SUPPORTED`` - .. param:: psa_its_storage_iterator_t* context - A pointer to a context for this iterator. The pointer may be NULL. This is set to a new value on success and is undefined on error. The content of the iterator is implementation defined. + .. param:: psa_its_storage_iterator_t *context + The location in which the function should store a pointer to the newly created context for this iterator. + This is set to a new value on success and is undefined on error. + The content of the iterator is implementation defined. .. param:: psa_storage_uid_t filter A value used to filter the results included in this iteration. @@ -387,9 +371,50 @@ These definitions must be defined in the header file :file:`psa/internal_trusted .. retval:: PSA_ERROR_DOES_NOT_EXIST No ``uid`` matches this iteration. + .. retval:: PSA_ERROR_INSUFFICIENT_STORAGE + The operation failed because there was insufficient space on the storage medium to create a new context. + + .. retval:: PSA_ERROR_STORAGE_FAILURE + The operation failed because the physical storage has failed (Fatal error). + + +.. function:: psa_its_iterator_next + + .. summary:: + + Returns the next ``uid`` in this iteration. + This function must be fully defined if iteration is supported. + If iteration is not supported, then this function SHALL be defined in the header - potentially as an inline function - but SHALL return ``PSA_ERROR_NOT_SUPPORTED`` + + + .. param:: psa_its_storage_iterator_t* context + A pointer to a context for this iterator as returned by `psa_its_iterator_start()` or updated by a previous call to `psa_its_iterator_next()`. The content of the iterator will change on success and is undefined on error. + + .. param:: psa_storage_uid_t *result + A pointer to the location in which to store ``uid``. On success the contents of this location will be updated with the next matching ``uid``. On error, the contents are undefined. + + .. return:: psa_status_t + A status indicating the success or failure of the operation. + + .. retval:: PSA_SUCCESS + The operation completed successfully. + + .. retval:: PSA_ERROR_DOES_NOT_EXIST + The iterator has returned all the uids that match this iteration. + .. retval:: PSA_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error). + .. retval:: PSA_ERROR_DATA_CORRUPT + The operation failed because the contents of the iteration have changed. That is a ``uid`` matching the filter has either been created or deleted. + + .. retval:: PSA_ERROR_INVALID_ARGUMENT + The operation failed because either: + + * The provided context is not valid. + + * The caller cannot access the memory at ``result`` + The iterator returns those values where the ``filter_length`` bits of the ``uid`` matches the left most bits in ``filter``. The iterator will only returns those ``uid`` that were created by the caller. It MUST not return any ``uid`` created by a different user. @@ -412,13 +437,14 @@ These definitions must be defined in the header file :file:`psa/internal_trusted The following code snippet uses a linked list to store the matching files before iterating over that list and removing them. + .. code-block:: c my_context = NULL; my_filter = 0x1111 0000 0000 0000; my_length = 0x0020; my_result = NULL; - if psa_its_iterator_start(my_context, my_filter, my-length, my_result) == PSA_SUCCESS + if psa_its_iterator_start(my_context*, my_filter, my-length, my_result) == PSA_SUCCESS { do { @@ -433,56 +459,17 @@ These definitions must be defined in the header file :file:`psa/internal_trusted while my_result == PSA_SUCCESS ; }; - - - -.. function:: psa_its_iterator_next - - .. summary:: - - Returns the next ``uid`` in this iteration. - This function must be fully defined if `PSA_STORAGE_SUPPORT_ITERATION` is true. - If `PSA_STORAGE_SUPPORT_ITERATION` is false, then this function SHALL always return ``PSA_ERROR_NOT_SUPPORTED`` - - - .. param:: psa_its_storage_iterator_t* context - A pointer to a context for this iterator as returned by `psa_its_iterator_start()` or updated by a previous call to `psa_its_iterator_next()`. The content of the iterator will change on success and is undefined on error. - - .. param:: psa_storage_uid_t *result - A pointer to the location in which to store ``uid``. On success the contents of this location will be updated with the next matching ``uid``. On error, the contents are undefined. - - .. return:: psa_status_t - A status indicating the success or failure of the operation. - - .. retval:: PSA_SUCCESS - The operation completed successfully. - - .. retval:: PSA_ERROR_DOES_NOT_EXIST - The iterator has returned all the uids that match this iteration. - - .. retval:: PSA_ERROR_STORAGE_FAILURE - The operation failed because the physical storage has failed (Fatal error). - - .. retval:: PSA_ERROR_DATA_CORRUPT - The operation failed because the contents of the iteration have changed. That is a ``uid`` matching the filter has either been created or deleted. - - .. retval:: PSA_ERROR_INVALID_ARGUMENT - The operation failed because either: - - * The provided context is not valid. - - * The caller cannot access the memory at ``result`` - .. function:: psa_its_get_support .. summary:: Returns a bitmask with flags set for the optional features supported by the implementation. - Currently defined flags are limited to: + .. return:: uint32_t + + Currently the defined flags are limited to: - * `PSA_STORAGE_SUPPORT_ITERATION` + * `PSA_ITS_SUPPORT_ITERATION` - .. return:: uint32_t .. _PS-API: @@ -522,6 +509,25 @@ These definitions must be defined in the header file :file:`psa/protected_storag It will be incremented in small updates that are unlikely to include breaking changes. +.. macro:: PSA_PS_SUPPORT_ITERATION + (1u << 2) + + Flag indicating that `psa_ps_iterator_start` and `psa_ps_iterator_next` are supported. + +.. struct:: psa_ps_storage_iterator_t + + .. summary:: + An implementation-defined opaque structure containing the context for an iterator. + The structure MUST contain all all the state required by the iterator. + That is, further state MUST NOT be retained by the implementation. + + The structure is initilaised by the ``ps_iterator_start()`` function. + It is modified by the ``ps_iterator_next()`` function. + + the caller can discard or reuse the iterator object once it has finished using it. This can be before, or after, the iterator has reached the end of the iteration. + + The header file is only required to define this structure if PSA_STORAGE_SUPPORT_ITERATION is true. + .. function:: psa_ps_set .. summary:: @@ -552,8 +558,6 @@ These definitions must be defined in the header file :file:`psa/protected_storag * The operation failed because caller cannot access some or all of the memory in the range [``p_data``, ``p_data + data_length - 1``]. - * the uid exists and ``data_length`` is greater then ```capacity`` - .. retval:: PSA_ERROR_NOT_SUPPORTED The operation failed because one or more of the flags provided in ``create_flags`` is not supported or is not valid. .. retval:: PSA_ERROR_INSUFFICIENT_STORAGE @@ -774,7 +778,7 @@ These definitions must be defined in the header file :file:`psa/protected_storag .. summary:: Overwrite part of the data of the specified ``uid``, leaving remaining data unchanged. This function must be fully defined if `PSA_STORAGE_SUPPORT_SET_EXTENDED` is true. - If `PSA_STORAGE_SUPPORT_SET_EXTENDED` is false, then this function SHALL always return ``PSA_ERROR_NOT_SUPPORTED``. + If `PSA_STORAGE_SUPPORT_SET_EXTENDED` is false, then this function SHALL be defined in the header - potentially as an inline function - but SHALL return ``PSA_ERROR_NOT_SUPPORTED``. .. param:: psa_storage_uid_t uid The unique identifier for the asset. @@ -820,7 +824,7 @@ These definitions must be defined in the header file :file:`psa/protected_storag This function can overwrite existing data and/or extend it up to the capacity for the ``uid`` specified in ``psa_ps_create()`` but cannot create gaps. - This function is optional. Consult the platform documentation to determine if it is implemented or perform a call to ``psa_ps_get_support()``. This function must be implemented if ``psa_ps_get_support()`` returns ``PSA_STORAGE_SUPPORT_SET_EXTENDED``. + This function is optional. Consult the platform documentation to determine if it is implemented or perform a call to ``psa_ps_get_support()``. This function must be implemented if ``psa_ps_get_support()`` returns ``PSA_STORAGE_SUPPORT_SET_EXTENDED``. * The ``uid`` value must not be zero. @@ -849,7 +853,7 @@ These definitions must be defined in the header file :file:`psa/protected_storag .. summary:: Atomically renames the storage location with the specified ``uid`` to a ``uid_new``. This function must be fully defined if `PSA_STORAGE_SUPPORT_RENAME` is true. - If `PSA_STORAGE_SUPPORT_RENAME` is false, then this function SHALL always return ``PSA_ERROR_NOT_SUPPORTED``. + If `PSA_STORAGE_SUPPORT_RENAME` is false, then this function SHALL be defined in the header - potentially as an inline function - but SHALL return ``PSA_ERROR_NOT_SUPPORTED``. .. param:: psa_storage_uid_t uid The current identifier for the data. @@ -899,16 +903,19 @@ These definitions must be defined in the header file :file:`psa/protected_storag Except in the case of ``PSA_ERROR_STORAGE_FAILURE``, in which case no guarantees can be made, the operation shall either succeed or leave storage unchanged. + .. function:: psa_ps_iterator_start .. summary:: Initializes an iterator that can be used to return a list of uids in the Protected Storage. - This function must be fully defined if `PSA_STORAGE_SUPPORT_ITERATION` is true. - If `PSA_STORAGE_SUPPORT_ITERATION` is false, then this function SHALL always return ``PSA_ERROR_NOT_SUPPORTED`` + This function must be fully defined if iteration is supported. + If iteration is not supported, then this function SHALL be defined in the header - potentially as an inline function - but SHALL return ``PSA_ERROR_NOT_SUPPORTED`` - .. param:: psa_ps_storage_iterator_t* context - A pointer to a context for this iterator. The pointer may be NULL. This is set to a new value on success and is undefined on error. The content of the iterator is implementation defined. + .. param:: psa_ps_storage_iterator_t *context + The location in which the function should store a pointer to the newly created context for this iterator. + This is set to a new value on success and is undefined on error. + The content of the iterator is implementation defined. .. param:: psa_storage_uid_t filter A value used to filter the results included in this iteration. @@ -981,8 +988,8 @@ These definitions must be defined in the header file :file:`psa/protected_storag .. summary:: Returns the next ``uid`` in this iteration. - This function must be fully defined if `PSA_STORAGE_SUPPORT_ITERATION` is true. - If `PSA_STORAGE_SUPPORT_ITERATION` is false, then this function SHALL always return ``PSA_ERROR_NOT_SUPPORTED`` + This function must be fully defined if iteration is supported. + If iteration is not supported, then this function SHALL be defined in the header - potentially as an inline function - but SHALL return ``PSA_ERROR_NOT_SUPPORTED`` .. param:: psa_ps_storage_iterator_t* context A pointer to a context for this iterator as returned by `psa_ps_iterator_start` or updated by a previous call to `psa_ps_iterator_next`. The content of the iterator will change on success and is undefined on error. @@ -1021,7 +1028,7 @@ These definitions must be defined in the header file :file:`psa/protected_storag * `PSA_STORAGE_SUPPORT_SET_EXTENDED` * `PSA_STORAGE_SUPPORT_RENAME` - * `PSA_STORAGE_SUPPORT_ITERATION` + * `PSA_PS_SUPPORT_ITERATION` .. return:: uint32_t From 280170679ddef11d077917151b4b20439e8600fd Mon Sep 17 00:00:00 2001 From: Marcus Streets Date: Wed, 24 Jul 2024 15:15:24 +0100 Subject: [PATCH 6/8] Fixing some errors due to a stale copy in my local repository Signed-off-by: Marcus Streets --- doc/storage/about.rst | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/doc/storage/about.rst b/doc/storage/about.rst index e72362c7..0ee51574 100644 --- a/doc/storage/about.rst +++ b/doc/storage/about.rst @@ -1,4 +1,4 @@ -.. SPDX-FileCopyrightText: Copyright 2018-2019, 2022-2023 Arm Limited and/or its affiliates +.. SPDX-FileCopyrightText: Copyright 2018-2019, 2022-2024 Arm Limited and/or its affiliates .. SPDX-License-Identifier: CC-BY-SA-4.0 AND LicenseRef-Patent-license .. Releases of this specification @@ -39,14 +39,13 @@ :date: January 2024 :confidentiality: Non-confidential - Added draft SRA. + Provide a Security Risk Assessment. .. release:: 1.1.0 - :date: January 2024 + :date: July 2024 :confidentiality: Non-confidential Added rename and iteration - .. release-info:: :extend: @@ -70,16 +69,16 @@ :doc_no: ARM IHI 0097 :url: arm-software.github.io/psa-api/status-code -.. reference:: PSA-FF-M +.. reference:: PSA-FFM :title: ArmĀ® Platform Security Architecture Firmware Framework :doc_no: ARM DEN 0063 - :url: pages.arm.com/psa-apis + :url: developer.arm.com/documentation/den0063 .. reference:: SP800-30 :title: NIST Special Publication 800-30 Revision 1: Guide for Conducting Risk Assessments :author: NIST :publication: September 2012 - :url: doi.org/10.6028/NIST.SP.800-30r1 + :url: doi.org/10.6028/NIST.SP.800-30r1 .. Glossary terms used in this specification @@ -142,4 +141,4 @@ interfaces defined in this specification will only be included in a new major or minor version of the specification. -.. about:: +.. about:: \ No newline at end of file From 4a9979dc6c41056d51ae84308d4f46703a49376c Mon Sep 17 00:00:00 2001 From: Marcus Streets Date: Thu, 25 Jul 2024 13:20:40 +0100 Subject: [PATCH 7/8] Update beased on Andrew T's comments Added Rename to ITS Added "Introduced in 1.1" where relevant Updated words on optionality. A few other minor fixes as noted by Andrew. Signed-off-by: Marcus Streets --- doc/storage/api/api.rst | 257 ++++++++++++++++++++++------------------ 1 file changed, 141 insertions(+), 116 deletions(-) diff --git a/doc/storage/api/api.rst b/doc/storage/api/api.rst index 1334cd37..1f5a2527 100644 --- a/doc/storage/api/api.rst +++ b/doc/storage/api/api.rst @@ -52,6 +52,7 @@ General Definitions These definitions must be defined in the header file :file:`psa/storage_common.h`. .. struct:: psa_storage_info_t + :type: .. summary:: A container for metadata associated with a specific ``uid``. @@ -105,10 +106,11 @@ These definitions must be defined in the header file :file:`psa/storage_common.h Flag indicating that `psa_ps_create()` and `psa_ps_set_extended()` are supported. -.. macro:: PSA_STORAGE_SUPPORT_RENAME +.. macro:: PSA_STORAGE_SUPPORT_ITERATION (1u << 1) - Flag indicating that `psa_ps_rename()` is supported. + Flag indicating that iteration is supported on the specified storage. + Interation may be defined on the Interal Trusted Storage, the Protected Sotage, both or neither. .. _ITS-API: @@ -148,25 +150,24 @@ These definitions must be defined in the header file :file:`psa/internal_trusted It will be incremented in small updates that are unlikely to include breaking changes. -.. macro:: PSA_ITS_SUPPORT_ITERATION - (1u << 2) - - Flag indicating that `psa_its_iterator_start()` and `psa_its_iterator_next()` are supported. - .. struct:: psa_its_storage_iterator_t - + :type: + .. summary:: An implementation-defined opaque structure containing the context for an iterator. - The structure MUST contain all all the state required by the iterator. - That is, further state MUST NOT be retained by the implementation. - - The structure is initialized by the ``ps_iterator_start()`` function. - It is modified by the ``ps_iterator_next()`` function. - - the caller can discard or reuse the iterator object once it has finished using it. This can be before, or after, the iterator has reached the end of the iteration. + + Introduced in Version 1.1. + + The structure MUST contain all all the state required by the iterator. + That is, further state MUST NOT be retained by the implementation. - The header file is only required to define this structure if PSA_STORAGE_SUPPORT_ITERATION is true. + The structure is initialized by the ``psa_its_iterator_start()`` function. + It is modified by the ``psa_its_iterator_next()`` function. + The caller can discard or reuse the iterator object once it has finished using it. This can be before, or after, the iterator has reached the end of the iteration. + + The structure must be defined, but if iteration is not supported it can be empty. + .. function:: psa_its_set .. summary:: @@ -331,7 +332,11 @@ These definitions must be defined in the header file :file:`psa/internal_trusted .. retval:: PSA_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error). - Deletes the data from internal storage. + Introduced in Version 1.1. + + Code that is written to be portable, should check the version of storage using the ``PSA_ITS_VERSION_MAJOR`` and ``PSA_ITS_VERSION_MINOR`` macros to determine whether the function is defined. + + Deletes the data from internal storage. * The ``uid`` value must not be zero. @@ -339,17 +344,78 @@ These definitions must be defined in the header file :file:`psa/internal_trusted * Even if all parameters are correct, the function can fail in the case of a storage failure. + +.. function:: psa_its_rename + + .. summary:: + Atomically renames the storage location with the specified ``uid`` to a ``uid_new``. + + .. param:: psa_storage_uid_t uid + The current identifier for the data. + + .. param:: psa_storage_uid_t uid_new + The new identifier for the data. + + .. param:: psa_storage_rename_flags_t rename_flags + The flags must be either ``PSA_STORAGE_FLAG_NONE`` or ``PSA_STORAGE_FLAG_REPLACE`` + + .. return:: psa_status_t + A status indicating the success or failure of the operation. + + .. retval:: PSA_SUCCESS + The operation completed successfully. + + .. retval:: PSA_ERROR_ALREADY_EXISTS + Storage with the specified ``uid_new`` already exists and ``rename_flags`` is `PSA_STORAGE_FLAG_NONE` + + .. retval:: PSA_ERROR_DOES_NOT_EXIST + Storage with the specified ``uid`` does not exist. + + .. retval:: PSA_ERROR_GENERIC_ERROR + The operation failed because of an unspecified internal failure. + + .. retval:: PSA_ERROR_INVALID_ARGUMENT + The operation failed because either: + + * ``uid`` is ``0``. + * ``uid_new`` is ``0`` + * the ``psa_storage_rename_flags_t`` has a value set other than `PSA_STORAGE_FLAG_REPLACE` + + .. retval:: PSA_ERROR_NOT_PERMITTED + The operation failed because ``uid_new`` exists and was created with `PSA_STORAGE_FLAG_WRITE_ONCE`. + + .. retval:: PSA_ERROR_NOT_SUPPORTED + The implementation does not support the operation. + + .. retval:: PSA_ERROR_STORAGE_FAILURE + The operation failed because the physical storage has failed (Fatal error). + + Introduced in Version 1.1. + + Code that is written to be portable, should check the version of storage using the ``PSA_ITS_VERSION_MAJOR`` and ``PSA_ITS_VERSION_MINOR`` macros to determine whether the function is defined. + + The function renames ``uid`` to ``uid_new`` retaining the storage flags that ``uid`` was created with. + + If the caller specifies `PSA_STORAGE_FLAG_REPLACE` the operation atomically replaces the existing contents of ```uid_new`` with those of ``uid``. + + Except in the case of ``PSA_ERROR_STORAGE_FAILURE``, in which case no guarantees can be made, the operation shall either succeed or leave storage unchanged. + + .. function:: psa_its_iterator_start .. summary:: Initializes an iterator that can be used to return a list of ``uid`` values in the Internal Trusted Storage. - This function must be fully defined if iteration is supported. + Introduced in Version 1.1. + + Code that is written to be portable, should check the version of storage using the ``PSA_ITS_VERSION_MAJOR`` and ``PSA_ITS_VERSION_MINOR`` macros to determine whether the function is defined. Then use the ``psa_its_get_support`` function to determine at run time if iteration is supported. + + It must be fully defined if iteration is supported. If iteration is not supported, then this function SHALL be defined in the header - potentially as an inline function - but SHALL return ``PSA_ERROR_NOT_SUPPORTED`` .. param:: psa_its_storage_iterator_t *context - The location in which the function should store a pointer to the newly created context for this iterator. + The location in which the function stores the iteration context. This is set to a new value on success and is undefined on error. The content of the iterator is implementation defined. @@ -371,13 +437,35 @@ These definitions must be defined in the header file :file:`psa/internal_trusted .. retval:: PSA_ERROR_DOES_NOT_EXIST No ``uid`` matches this iteration. - .. retval:: PSA_ERROR_INSUFFICIENT_STORAGE - The operation failed because there was insufficient space on the storage medium to create a new context. + .. retval:: PSA_ERROR_INVALID_ARGUMENT + The operation failed because either: + + * The caller cannot access the memory at ``context`` or ``result`` .. retval:: PSA_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error). + The iterator returns those values where the ``filter_length`` bits of the ``uid`` matches the left most bits in ``filter``. + + The iterator will only returns those ``uid`` that were created by the caller. It MUST not return any ``uid`` created by a different user. + + An iterator is not required to return uids in any specific order, but MUST return them in a consistent order each time it is called. For example, if an implementation returns entries in numerical order, it should not arbitrarily change to returning them in creation order. However, the caller should not make assumptions as to the order in which entries are returned, except that each ``uid`` will be returned only once in each iteration. + + Changes to storage by other users MUST NOT affect any open iterations. + + A caller may initialize multiple iteration contexts at the same time. Each iteration shall be independent. Calling ``psa_its_iterator_next()`` on one iterator MUST not effect any other open iteration. + + An iterator MUST return all data objects whose ``uid`` matches the filter that are extant when the filter was created, unless these are deleted or renamed before the iteration would return them, or the caller stops before all matching objects have been returned. + + A caller may delete a ``uid`` with `psa_its_remove()` without invalidating the iteration context. the iterator MUST never return a ``uid`` that has been deleted. However, if the caller is multi-threaded it is possible another thread may delete a ``uid``. + + A caller may read the contents of any ``uid`` with `psa_its_get()` or write with `psa_its_set` without invalidating the iteration context. + + A caller may create a ``uid`` with `psa_its_set()` without invalidating the iteration context. However, the iterator is NOT guaranteed to return the new object, ``uid``, the behavior is dependent on both implementation and identity. In particular, the iterator is not expected to return ``uid`` if the iteration is already past the point at which it would naturally be returned. + + A caller may call ``psa_its_rename(uid, uid_new)`` without invalidating the iteration context. The iterator must not return ``uid``. The iterator is not guaranteed to return ``uid_new``, the behavior is dependent on both implementation and identity. + .. function:: psa_its_iterator_next .. summary:: @@ -405,9 +493,6 @@ These definitions must be defined in the header file :file:`psa/internal_trusted .. retval:: PSA_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error). - .. retval:: PSA_ERROR_DATA_CORRUPT - The operation failed because the contents of the iteration have changed. That is a ``uid`` matching the filter has either been created or deleted. - .. retval:: PSA_ERROR_INVALID_ARGUMENT The operation failed because either: @@ -415,49 +500,9 @@ These definitions must be defined in the header file :file:`psa/internal_trusted * The caller cannot access the memory at ``result`` - The iterator returns those values where the ``filter_length`` bits of the ``uid`` matches the left most bits in ``filter``. - - The iterator will only returns those ``uid`` that were created by the caller. It MUST not return any ``uid`` created by a different user. - - An iterator is not required to return uids in any specific order, but MUST return them in a consistent order each time it is called. For example, if an implementation returns entries in numerical order, it should not arbitrarily change to returning them in creation order. However, the caller should not make assumptions as to the order in which entries are returned, except that each ``uid`` will be returned only once in each iteration. - - Changes to storage by other users MUST NOT affect any open iterations. - - A caller may initialize multiple iteration contexts at the same time. Each iteration shall be independent. Calling ``psa_its_iterator_next()`` on one iterator MUST not effect any other open iteration. - - An iterator MUST return all data objects whose ``uid`` matches the filter that are extant when the filter was created, unless these are deleted or renamed before the iteration would return them, or the caller stops before all matching objects have been returned. - - A caller may delete a ``uid`` with `psa_its_remove()` without invalidating the iteration context. the iterator MUST never return a ``uid`` that has been deleted. However, if the caller is multi-threaded it is possible another thread may delete a ``uid``. - - A caller may read the contents of any ``uid`` with `psa_its_get()` or write with `psa_its_set` without invalidating the iteration context. - - A caller may create a ``uid`` with `psa_its_set()` without invalidating the iteration context. However, the iterator is NOT guaranteed to return the new object, ``uid``, the behavior is dependent on both implementation and identity. In particular, the iterator is not expected to return ``uid`` if the iteration is already past the point at which it would naturally be returned. - - A caller may call ``psa_its_rename(uid, uid_new)`` without invalidating the iteration context. The iterator must not return ``uid``. The iterator is not guaranteed to return ``uid_new``, the behavior is dependent on both implementation and identity. - - The following code snippet uses a linked list to store the matching files before iterating over that list and removing them. - - - .. code-block:: c - - my_context = NULL; - my_filter = 0x1111 0000 0000 0000; - my_length = 0x0020; - my_result = NULL; - if psa_its_iterator_start(my_context*, my_filter, my-length, my_result) == PSA_SUCCESS - { - do - { - // do something with my_result - psa_its_iterator_next(my_context, my_result) - // we will get an does not exist error when we reach the last item, any other error is a storage failure - if my_reult <> PSA_ERROR_DOES_NOT_EXIST - { - /* deal with storage failure */ - } - } - while my_result == PSA_SUCCESS ; - }; + Introduced in Version 1.1. + + This function takes an iterator that was returned by the `psa_its_iterator_start` function and searches the storage for the next ``uid`` that matches the filters defined in that function call. If a ``uid`` matching the filter exists, the function updates the ``result`` and ``context`` parameters and retursn PSA_SUCCESS. If not it reruns an error. .. function:: psa_its_get_support @@ -466,9 +511,13 @@ These definitions must be defined in the header file :file:`psa/internal_trusted .. return:: uint32_t - Currently the defined flags are limited to: + Introduced in Version 1.1. + + Code that is written to be portable, should check the version of storage using the ``PSA_ITS_VERSION_MAJOR`` and ``PSA_ITS_VERSION_MINOR`` macros to determine whether the function is defined. + + Currently the defined flags are limited to: - * `PSA_ITS_SUPPORT_ITERATION` + * `PSA_STORAGE_SUPPORT_ITERATION` @@ -509,24 +558,23 @@ These definitions must be defined in the header file :file:`psa/protected_storag It will be incremented in small updates that are unlikely to include breaking changes. -.. macro:: PSA_PS_SUPPORT_ITERATION - (1u << 2) - - Flag indicating that `psa_ps_iterator_start` and `psa_ps_iterator_next` are supported. - .. struct:: psa_ps_storage_iterator_t + :type: .. summary:: An implementation-defined opaque structure containing the context for an iterator. - The structure MUST contain all all the state required by the iterator. - That is, further state MUST NOT be retained by the implementation. + + Introduced in Version 1.1. + + The structure MUST contain all all the state required by the iterator. + That is, further state MUST NOT be retained by the implementation. - The structure is initilaised by the ``ps_iterator_start()`` function. - It is modified by the ``ps_iterator_next()`` function. + The structure is initilaised by the ``ps_iterator_start()`` function. + It is modified by the ``ps_iterator_next()`` function. - the caller can discard or reuse the iterator object once it has finished using it. This can be before, or after, the iterator has reached the end of the iteration. + The caller can discard or reuse the iterator object once it has finished using it. This can be before, or after, the iterator has reached the end of the iteration. - The header file is only required to define this structure if PSA_STORAGE_SUPPORT_ITERATION is true. + The header file is required to define this structure, however is iteration is not supported it can be empty. .. function:: psa_ps_set @@ -847,13 +895,10 @@ These definitions must be defined in the header file :file:`psa/protected_storag * If ``data_offset + data_length < size`` then data in the range ``data_offset + data_length` to `size`` is not modified. - .. function:: psa_ps_rename .. summary:: Atomically renames the storage location with the specified ``uid`` to a ``uid_new``. - This function must be fully defined if `PSA_STORAGE_SUPPORT_RENAME` is true. - If `PSA_STORAGE_SUPPORT_RENAME` is false, then this function SHALL be defined in the header - potentially as an inline function - but SHALL return ``PSA_ERROR_NOT_SUPPORTED``. .. param:: psa_storage_uid_t uid The current identifier for the data. @@ -895,6 +940,9 @@ These definitions must be defined in the header file :file:`psa/protected_storag .. retval:: PSA_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error). + Introduced in Version 1.1. + + Code that is written to be portable, should check the version of storage using the ``PSA_PS_VERSION_MAJOR`` and ``PSA_PS_VERSION_MINOR`` macros to determine whether the function is defined. The function renames ``uid`` to ``uid_new`` retaining the storage flags that ``uid`` was created with. @@ -903,7 +951,6 @@ These definitions must be defined in the header file :file:`psa/protected_storag Except in the case of ``PSA_ERROR_STORAGE_FAILURE``, in which case no guarantees can be made, the operation shall either succeed or leave storage unchanged. - .. function:: psa_ps_iterator_start .. summary:: @@ -913,7 +960,7 @@ These definitions must be defined in the header file :file:`psa/protected_storag .. param:: psa_ps_storage_iterator_t *context - The location in which the function should store a pointer to the newly created context for this iterator. + The location in which the function stores the iteration context. This is set to a new value on success and is undefined on error. The content of the iterator is implementation defined. @@ -938,6 +985,10 @@ These definitions must be defined in the header file :file:`psa/protected_storag .. retval:: PSA_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error). + Introduced in Version 1.1. + + Code that is written to be portable, should check the version of storage using the ``PSA_PS_VERSION_MAJOR`` and ``PSA_PS_VERSION_MINOR`` macros to determine whether the function is defined. Then use the ``psa_its_get_support`` function to determine at run time if iteration is supported. + The iterator returns those values where the ``filter_length`` bits of the ``uid`` matches the left most bits in ``filter``. The iterator will only returns those ``uid`` that were created by the caller. It MUST not return any ``uid`` created by a different user. @@ -958,32 +1009,6 @@ These definitions must be defined in the header file :file:`psa/protected_storag A caller may call ``psa_ps_rename(uid, uid_new)`` without invalidating the iteration context. The iterator must not return ``uid``. The iterator is not guaranteed to return ``uid_new``, the behavior is dependent on both implementation and identity. - The following code snippet uses a linked list to store the matching files before iterating over that list and removing them. - - .. code-block:: c - - my_context = NULL; - my_filter = 0x1111 0000 0000 0000; - my_length = 0x0020; - my_result = NULL; - if psa_ps_iterator_start(my_context, my_filter, my-length, my_result) == PSA_SUCCESS - { - do - { - // do something with my_result - psa_ps_iterator_next(my_context, my_result) - // we will get an 'does not exist error' when we reach the last item, any other error is a storage failure - if my_reult <> PSA_ERROR_DOES_NOT_EXIST - { - /* deal with storage failure */ - } - } - while my_result == PSA_SUCCESS ; - }; - - - - .. function:: psa_ps_iterator_next .. summary:: @@ -1009,9 +1034,6 @@ These definitions must be defined in the header file :file:`psa/protected_storag .. retval:: PSA_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error). - .. retval:: PSA_ERROR_DATA_CORRUPT - The operation failed because the contents of the iteration have changed. That is a ``uid`` matching the filter has either been created or deleted. - .. retval:: PSA_ERROR_INVALID_ARGUMENT The operation failed because either: @@ -1019,6 +1041,10 @@ These definitions must be defined in the header file :file:`psa/protected_storag * The caller cannot access the memory at ``result`` + Introduced in Version 1.1. + + This function takes an iterator that was returned by the `psa_ps_iterator_start` function and searches the storage for the next ``uid`` that matches the filters defined in that function call. If a ``uid`` matching the filter exists, the function updates the ``result`` and ``context`` parameters and retursn PSA_SUCCESS. If not it reruns an error. + .. function:: psa_ps_get_support .. summary:: @@ -1027,8 +1053,7 @@ These definitions must be defined in the header file :file:`psa/protected_storag Currently defined flags are limited to: * `PSA_STORAGE_SUPPORT_SET_EXTENDED` - * `PSA_STORAGE_SUPPORT_RENAME` - * `PSA_PS_SUPPORT_ITERATION` + * `PSA_STORAGE_SUPPORT_ITERATION` .. return:: uint32_t From d2c1b86ed8766c4f372a0a474a65f41dc432daa0 Mon Sep 17 00:00:00 2001 From: Marcus Streets Date: Mon, 29 Jul 2024 16:38:21 +0100 Subject: [PATCH 8/8] deleting three incorrect commts --- doc/crypto/api/keys/policy.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/crypto/api/keys/policy.rst b/doc/crypto/api/keys/policy.rst index fdbbe250..32f0bf0d 100644 --- a/doc/crypto/api/keys/policy.rst +++ b/doc/crypto/api/keys/policy.rst @@ -285,3 +285,4 @@ The usage flags are encoded in a bitmask, which has the type `psa_key_usage_t`. .. admonition:: Implementation note This is a simple accessor function that is not required to validate its inputs. It can be efficiently implemented as a ``static inline`` function or a function-like-macro. +