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