1 /*
2  * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 /* This file describes the PSA Protected Storage API */
9 
10 #ifndef PROTECTED_STORAGE_H
11 #define PROTECTED_STORAGE_H
12 
13 #include <stddef.h>
14 #include <stdint.h>
15 
16 #include "psa/error.h"
17 #include "psa/storage_common.h"
18 
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
22 
23 #ifdef EXPORT_PUBLIC_INTERFACE_PSA_PS
24 #define PSA_PS_EXPORTED __attribute__((__visibility__("default")))
25 #else
26 #define PSA_PS_EXPORTED
27 #endif
28 
29 /**
30  * \brief PSA_PS_API_VERSION version
31  *
32  * Major and minor PSA_PS_API_VERSION numbers
33  */
34 #define PSA_PS_API_VERSION_MAJOR 1
35 #define PSA_PS_API_VERSION_MINOR 0
36 
37 // This version of the header file is associated with 1.0 final release
38 
39 /**
40  * \brief Create a new, or modify an existing, uid/value pair
41  *
42  * Stores data in the protected storage.
43  *
44  * \param[in] uid           The identifier for the data
45  * \param[in] data_length   The size in bytes of the data in `p_data`
46  * \param[in] p_data        A buffer containing the data
47  * \param[in] create_flags  The flags that the data will be stored with
48  *
49  * \return A status indicating the success/failure of the operation
50  *
51  * \retval PSA_SUCCESS                     The operation completed successfully
52  * \retval PSA_ERROR_NOT_PERMITTED         The operation failed because the
53  *                                         provided `uid` value was already
54  *                                         created with
55  *                                         PSA_STORAGE_FLAG_WRITE_ONCE
56  * \retval PSA_ERROR_INVALID_ARGUMENT      The operation failed because one
57  *                                         of the provided pointers(`p_data`)
58  *                                         is invalid, for example is `NULL` or
59  *                                         references memory the caller cannot
60  *                                         access
61  * \retval PSA_ERROR_NOT_SUPPORTED         The operation failed because one or
62  *                                         more of the flags provided in
63  *                                         `create_flags` is not supported or is
64  *                                         not valid
65  * \retval PSA_ERROR_INSUFFICIENT_STORAGE  The operation failed because there
66  *                                         was insufficient space on the
67  *                                         storage medium
68  * \retval PSA_ERROR_STORAGE_FAILURE       The operation failed because the
69  *                                         physical storage has failed (Fatal
70  *                                         error)
71  * \retval PSA_ERROR_GENERIC_ERROR         The operation failed because of an
72  *                                         unspecified internal failure
73  */
74 PSA_PS_EXPORTED psa_status_t psa_ps_set(psa_storage_uid_t uid, size_t data_length,
75 					const void *p_data,
76 					psa_storage_create_flags_t create_flags);
77 
78 /**
79  * \brief Retrieve data associated with a provided uid
80  *
81  * Retrieves up to `data_size` bytes of the data associated with `uid`, starting
82  * at `data_offset` bytes from the beginning of the data. Upon successful
83  * completion, the data will be placed in the `p_data` buffer, which must be at
84  * least `data_size` bytes in size. The length of the data returned will be in
85  * `p_data_length`. If `data_size` is 0, the contents of `p_data_length` will
86  * be set to zero.
87  *
88  * \param[in]  uid            The uid value
89  * \param[in]  data_offset    The starting offset of the data requested
90  * \param[in]  data_size      The amount of data requested
91  * \param[out] p_data         On success, the buffer where the data will
92  *                            be placed
93  * \param[out] p_data_length  On success, this will contain size of the data
94  *                            placed in `p_data`
95  *
96  * \return A status indicating the success/failure of the operation
97  *
98  * \retval PSA_SUCCESS                 The operation completed successfully
99  * \retval PSA_ERROR_INVALID_ARGUMENT  The operation failed because one of the
100  *                                     provided arguments (`p_data`,
101  *                                     `p_data_length`) is invalid, for example
102  *                                     is `NULL` or references memory the
103  *                                     caller cannot access. In addition, this
104  *                                     can also happen if `data_offset` is
105  *                                     larger than the size of the data
106  *                                     associated with `uid`
107  * \retval PSA_ERROR_DOES_NOT_EXIST    The operation failed because the
108  *                                     provided `uid` value was not found in
109  *                                     the storage
110  * \retval PSA_ERROR_STORAGE_FAILURE   The operation failed because the
111  *                                     physical storage has failed (Fatal
112  *                                     error)
113  * \retval PSA_ERROR_GENERIC_ERROR     The operation failed because of an
114  *                                     unspecified internal failure
115  * \retval PSA_ERROR_DATA_CORRUPT      The operation failed because the data
116  *                                     associated with the UID was corrupt
117  * \retval PSA_ERROR_INVALID_SIGNATURE The operation failed because the data
118  *                                     associated with the UID failed
119  *                                     authentication
120  */
121 PSA_PS_EXPORTED psa_status_t psa_ps_get(psa_storage_uid_t uid, size_t data_offset, size_t data_size,
122 					void *p_data, size_t *p_data_length);
123 
124 /**
125  * \brief Retrieve the metadata about the provided uid
126  *
127  * Retrieves the metadata stored for a given `uid`
128  *
129  * \param[in]  uid     The `uid` value
130  * \param[out] p_info  A pointer to the `psa_storage_info_t` struct that will
131  *                     be populated with the metadata
132  *
133  * \return A status indicating the success/failure of the operation
134  *
135  * \retval PSA_SUCCESS                 The operation completed successfully
136  * \retval PSA_ERROR_INVALID_ARGUMENT  The operation failed because one of the
137  *                                     provided pointers(`p_info`)
138  *                                     is invalid, for example is `NULL` or
139  *                                     references memory the caller cannot
140  *                                     access
141  * \retval PSA_ERROR_DOES_NOT_EXIST    The operation failed because the provided
142  *                                     uid value was not found in the storage
143  * \retval PSA_ERROR_STORAGE_FAILURE   The operation failed because the physical
144  *                                     storage has failed (Fatal error)
145  * \retval PSA_ERROR_GENERIC_ERROR     The operation failed because of an
146  *                                     unspecified internal failure
147  * \retval PSA_ERROR_DATA_CORRUPT      The operation failed because the data
148  *                                     associated with the UID was corrupt
149  */
150 PSA_PS_EXPORTED psa_status_t psa_ps_get_info(psa_storage_uid_t uid,
151 					     struct psa_storage_info_t *p_info);
152 
153 /**
154  * \brief Remove the provided uid and its associated data from the storage
155  *
156  * Removes previously stored data and any associated metadata,
157  * including rollback protection data.
158  *
159  * \param[in] uid  The `uid` value
160  *
161  * \return A status indicating the success/failure of the operation
162  *
163  * \retval PSA_SUCCESS                 The operation completed successfully
164  * \retval PSA_ERROR_INVALID_ARGUMENT  The operation failed because one or more
165  *                                     of the given arguments were invalid (null
166  *                                     pointer, wrong flags and so on)
167  * \retval PSA_ERROR_DOES_NOT_EXIST    The operation failed because the provided
168  *                                     uid value was not found in the storage
169  * \retval PSA_ERROR_NOT_PERMITTED     The operation failed because the provided
170  *                                     uid value was created with
171  *                                     PSA_STORAGE_FLAG_WRITE_ONCE
172  * \retval PSA_ERROR_STORAGE_FAILURE   The operation failed because the physical
173  *                                     storage has failed (Fatal error)
174  * \retval PSA_ERROR_GENERIC_ERROR     The operation failed because of an
175  *                                     unspecified internal failure
176  */
177 PSA_PS_EXPORTED psa_status_t psa_ps_remove(psa_storage_uid_t uid);
178 
179 /**
180  * \brief Reserves storage for the specified uid
181  *
182  * Upon success, the capacity of the storage will be capacity, and the size
183  * will be 0. It is only necessary to call this function for assets that will
184  * be written with the psa_ps_set_extended function. If only the psa_ps_set
185  * function is needed, calls to this function are redundant.
186  *
187  * \param[in] uid           The `uid` value
188  * \param[in] capacity      The capacity to be allocated in bytes
189  * \param[in] create_flags  Flags indicating properties of storage
190  *
191  * \return A status indicating the success/failure of the operation
192  *
193  * \retval PSA_SUCCESS                     The operation completed successfully
194  * \retval PSA_ERROR_STORAGE_FAILURE       The operation failed because the
195  *                                         physical storage has failed
196  *                                         (Fatal error)
197  * \retval PSA_ERROR_INSUFFICIENT_STORAGE  The operation failed because the
198  *                                         capacity is bigger than the current
199  *                                         available space
200  * \retval PSA_ERROR_NOT_SUPPORTED         The operation failed because the
201  *                                         function is not implemented or one
202  *                                         or more create_flags are not
203  *                                         supported.
204  * \retval PSA_ERROR_INVALID_ARGUMENT      The operation failed because uid was
205  *                                         0 or create_flags specified flags
206  *                                         that are not defined in the API.
207  * \retval PSA_ERROR_GENERIC_ERROR         The operation failed due to an
208  *                                         unspecified error
209  * \retval PSA_ERROR_ALREADY_EXISTS        Storage for the specified uid
210  *                                         already exists
211  */
212 PSA_PS_EXPORTED psa_status_t psa_ps_create(psa_storage_uid_t uid, size_t capacity,
213 					   psa_storage_create_flags_t create_flags);
214 
215 /**
216  * \brief Sets partial data into an asset
217  *
218  * Before calling this function, the storage must have been reserved with a call
219  * to psa_ps_create. It can also be used to overwrite data in an asset that was
220  * created with a call to psa_ps_set. Calling this function with data_length = 0
221  * is permitted, which will make no change to the stored data.This function can
222  * overwrite existing data and/or extend it up to the capacity for the uid
223  * specified in psa_ps_create, but cannot create gaps.
224  *
225  * That is, it has preconditions:
226  * - data_offset <= size
227  * - data_offset + data_length <= capacity
228  * and postconditions:
229  * - size = max(size, data_offset + data_length)
230  * - capacity unchanged.
231  *
232  * \param[in] uid          The `uid` value
233  * \param[in] data_offset  Offset within the asset to start the write
234  * \param[in] data_length  The size in bytes of the data in p_data to write
235  * \param[in] p_data       Pointer to a buffer which contains the data to write
236  *
237  * \return A status indicating the success/failure of the operation
238  *
239  * \retval PSA_SUCCESS                  The asset exists, the input parameters
240  *                                      are correct and the data is correctly
241  *                                      written in the physical storage.
242  * \retval PSA_ERROR_STORAGE_FAILURE    The data was not written correctly in
243  *                                      the physical storage
244  * \retval PSA_ERROR_INVALID_ARGUMENT   The operation failed because one or more
245  *                                      of the preconditions listed above
246  *                                      regarding data_offset, size, or
247  *                                      data_length was violated.
248  * \retval PSA_ERROR_DOES_NOT_EXIST     The specified uid was not found
249  * \retval PSA_ERROR_NOT_SUPPORTED      The implementation of the API does not
250  *                                      support this function
251  * \retval PSA_ERROR_GENERIC_ERROR      The operation failed due to an
252  *                                      unspecified error
253  * \retval PSA_ERROR_DATA_CORRUPT       The operation failed because the
254  *                                      existing data has been corrupted.
255  * \retval PSA_ERROR_INVALID_SIGNATURE  The operation failed because the
256  *                                      existing data failed authentication
257  *                                      (MAC check failed).
258  * \retval PSA_ERROR_NOT_PERMITTED      The operation failed because it was
259  *                                      attempted on an asset which was written
260  *                                      with the flag
261  *                                      PSA_STORAGE_FLAG_WRITE_ONCE
262  */
263 PSA_PS_EXPORTED psa_status_t psa_ps_set_extended(psa_storage_uid_t uid, size_t data_offset,
264 						 size_t data_length, const void *p_data);
265 
266 /**
267  * \brief Lists optional features.
268  *
269  * \return                              A bitmask with flags set for all of
270  *                                      the optional features supported by the
271  *                                      implementation.Currently defined flags
272  *                                      are limited to
273  *                                      PSA_STORAGE_SUPPORT_SET_EXTENDED
274  */
275 PSA_PS_EXPORTED uint32_t psa_ps_get_support(void);
276 
277 #ifdef __cplusplus
278 }
279 #endif
280 
281 #endif /* PROTECTED_STORAGE_H */
282