1 /*
2  * Copyright (c) 2021, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #ifndef __STORAGE_BACKEND_H__
9 #define __STORAGE_BACKEND_H__
10 
11 #include <stdint.h>
12 #include <stddef.h>
13 #include <psa/storage_common.h>
14 
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18 
19 /**
20  * \brief Common storage backend interface
21  *
22  * A concrete storage backend provides an implementation of this
23  * interface.
24  */
25 struct storage_backend_interface
26 {
27     /**
28      * \brief Create a new, or modify an existing, uid/value pair
29      *
30      * Stores data in the storage backend.
31      *
32      * \param[in] context       The concrete backend context
33      * \param[in] client_id     Identifier of the asset's owner (client)
34      * \param[in] uid           The identifier for the data
35      * \param[in] data_length   The size in bytes of the data in `p_data`
36      * \param[in] create_flags  The flags that the data will be stored with
37      *
38      * \return A status indicating the success/failure of the operation
39      *
40      * \retval PSA_SUCCESS                     The operation completed successfully
41      * \retval PSA_ERROR_NOT_PERMITTED         The operation failed because the
42      *                                         provided `uid` value was already
43      *                                         created with
44      *                                         PSA_STORAGE_FLAG_WRITE_ONCE
45      * \retval PSA_ERROR_NOT_SUPPORTED         The operation failed because one or
46      *                                         more of the flags provided in
47      *                                         `create_flags` is not supported or is
48      *                                         not valid
49      * \retval PSA_ERROR_INSUFFICIENT_STORAGE  The operation failed because there
50      *                                         was insufficient space on the
51      *                                         storage medium
52      * \retval PSA_ERROR_STORAGE_FAILURE       The operation failed because the
53      *                                         physical storage has failed (Fatal
54      *                                         error)
55      * \retval PSA_ERROR_INVALID_ARGUMENT      The operation failed because one
56      *                                         of the provided pointers (`p_data`)
57      *                                         is invalid, for example is `NULL` or
58      *                                         references memory the caller cannot
59      *                                         access
60      */
61     psa_status_t (*set)(void *context,
62                             uint32_t client_id,
63                             uint64_t uid,
64                             size_t data_length,
65                             const void *p_data,
66                             uint32_t create_flags);
67 
68     /**
69      * \brief Retrieve data associated with a provided UID
70      *
71      * Retrieves up to `data_size` bytes of the data associated with `uid`, starting
72      * at `data_offset` bytes from the beginning of the data. Upon successful
73      * completion, the data will be placed in the `p_data` buffer, which must be at
74      * least `data_size` bytes in size. The length of the data returned will be in
75      * `p_data_length`. If `data_size` is 0, the contents of `p_data_length` will
76      * be set to zero.
77      *
78      * \param[in]  context        The concrete backend context
79      * \param[in]  client_id      Identifier of the asset's owner (client)
80      * \param[in]  uid            The uid value
81      * \param[in]  data_offset    The starting offset of the data requested
82      * \param[in]  data_size      The amount of data requested
83      * \param[out] p_data_length  On success, this will contain size of the data
84      *                            placed in `p_data`.
85      *
86      * \return A status indicating the success/failure of the operation
87      *
88      * \retval PSA_SUCCESS                 The operation completed successfully
89      * \retval PSA_ERROR_DOES_NOT_EXIST    The operation failed because the
90      *                                     provided `uid` value was not found in
91      *                                     the storage
92      * \retval PSA_ERROR_STORAGE_FAILURE   The operation failed because the
93      *                                     physical storage has failed (Fatal
94      *                                     error)
95      * \retval PSA_ERROR_INVALID_ARGUMENT  The operation failed because one of the
96      *                                     provided arguments (`p_data`,
97      *                                     `p_data_length`) is invalid, for example
98      *                                     is `NULL` or references memory the
99      *                                     caller cannot access. In addition, this
100      *                                     can also happen if `data_offset` is
101      *                                     larger than the size of the data
102      *                                     associated with `uid`.
103      */
104     psa_status_t (*get)(void *context,
105                             uint32_t client_id,
106                             uint64_t uid,
107                             size_t data_offset,
108                             size_t data_size,
109                             void *p_data,
110                             size_t *p_data_length);
111 
112     /**
113      * \brief Retrieve the metadata about the provided uid
114      *
115      * Retrieves the metadata stored for a given `uid` as a `secure_storage_response_get_info`
116      * structure.
117      *
118      * \param[in]  context    The concrete backend context
119      * \param[in]  client_id  Identifier of the asset's owner (client)
120      * \param[in]  uid        The `uid` value
121      * \param[out] p_info     A pointer to the `psa_storage_info_t` struct that will
122      *                        be populated with the metadata
123      *
124      * \return A status indicating the success/failure of the operation
125      *
126      * \retval PSA_SUCCESS                 The operation completed successfully
127      * \retval PSA_ERROR_DOES_NOT_EXIST    The operation failed because the provided
128      *                                     uid value was not found in the storage
129      * \retval PSA_ERROR_STORAGE_FAILURE   The operation failed because the physical
130      *                                     storage has failed (Fatal error)
131      * \retval PSA_ERROR_INVALID_ARGUMENT  The operation failed because one of the
132      *                                     provided pointers(`p_info`)
133      *                                     is invalid, for example is `NULL` or
134      *                                     references memory the caller cannot
135      *                                     access
136      */
137     psa_status_t (*get_info)(void *context,
138                                 uint32_t client_id,
139                                 uint64_t uid,
140                                 struct psa_storage_info_t *p_info);
141 
142     /**
143      * \brief Remove the specified asset from the storage
144      *
145      * Deletes the data from storage backend.
146      *
147      * \param[in] context    The concrete backend context
148      * \param[in] client_id  Identifier of the asset's owner (client)
149      * \param[in] uid        The `uid` value
150      *
151      * \return A status indicating the success/failure of the operation
152      *
153      * \retval PSA_SUCCESS                 The operation completed successfully
154      * \retval PSA_ERROR_INVALID_ARGUMENT  The operation failed because one or more
155      *                                     of the given arguments were invalid (null
156      *                                     pointer, wrong flags and so on)
157      * \retval PSA_ERROR_DOES_NOT_EXIST    The operation failed because the provided
158      *                                     uid value was not found in the storage
159      * \retval PSA_ERROR_NOT_PERMITTED     The operation failed because the provided
160      *                                     uid value was created with
161      *                                     PSA_STORAGE_FLAG_WRITE_ONCE
162      * \retval PSA_ERROR_STORAGE_FAILURE   The operation failed because the physical
163      *                                     storage has failed (Fatal error)
164      */
165     psa_status_t (*remove)(void *context,
166                                 uint32_t client_id,
167                                 uint64_t uid);
168 
169     /**
170      * \brief Reserves storage for a new asset
171      *
172      * Creates a new asset of length zero but with the specified space reserved.
173      *
174      * \param[in] context       The concrete backend context
175      * \param[in] client_id     Identifier of the asset's owner (client)
176      * \param[in] uid           The identifier for the data
177      * \param[in] capacity      The space to reserve
178      * \param[in] create_flags  The flags that the data will be stored with
179      *
180      * \return A status indicating the success/failure of the operation
181      *
182      * \retval PSA_SUCCESS                     The operation completed successfully
183      * \retval PSA_ERROR_NOT_SUPPORTED         The operation failed because one or
184      *                                         more of the flags provided in
185      *                                         `create_flags` is not supported or is
186      *                                         not valid
187      * \retval PSA_ERROR_INSUFFICIENT_STORAGE  The operation failed because there
188      *                                         was insufficient space on the
189      *                                         storage medium
190      * \retval PSA_ERROR_STORAGE_FAILURE       The operation failed because the
191      *                                         physical storage has failed (Fatal
192      *                                         error)
193      * \retval PSA_ERROR_INVALID_ARGUMENT      The operation failed because one
194      *                                         of the provided pointers (`p_data`)
195      *                                         is invalid, for example is `NULL` or
196      *                                         references memory the caller cannot
197      *                                         access
198      * \retval PSA_ERROR_ALREADY_EXISTS        The specified uuid already exists
199      */
200     psa_status_t (*create)(void *context,
201                             uint32_t client_id,
202                             uint64_t uid,
203                             size_t capacity,
204                             uint32_t create_flags);
205 
206     /**
207      * \brief Set partial data for an existing asset
208      *
209      * \param[in] context       The concrete backend context
210      * \param[in] client_id     Identifier of the asset's owner (client)
211      * \param[in] uid           The identifier for the data
212      * \param[in] data_offset   Offset into asset for start of write
213      * \param[in] data_length   The size in bytes of the data in `p_data`
214      *
215      * \return A status indicating the success/failure of the operation
216      *
217      * \retval PSA_SUCCESS                     The operation completed successfully
218      *
219      * \retval PSA_ERROR_NOT_PERMITTED         The operation failed because the
220      *                                         provided `uid` value was already
221      *                                         created with
222      *                                         PSA_STORAGE_FLAG_WRITE_ONCE
223      * \retval PSA_ERROR_NOT_SUPPORTED         The operation failed because one or
224      *                                         more of the flags provided in
225      *                                         `create_flags` is not supported or is
226      *                                         not valid
227      * \retval PSA_ERROR_STORAGE_FAILURE       The operation failed because the
228      *                                         physical storage has failed (Fatal
229      *                                         error)
230      * \retval PSA_ERROR_INVALID_ARGUMENT      The operation failed because one
231      *                                         of the provided pointers (`p_data`)
232      *                                         is invalid, for example is `NULL` or
233      *                                         references memory the caller cannot
234      *                                         access
235      * \retval PSA_ERROR_DOES_NOT_EXIST        The specified uuid was not found
236      * \retval PSA_ERROR_DOES_DATA_CORRUPT     Existing data is corrupted
237      * \retval PSA_ERROR_INVALID_SIGNATURE     MAC check failed on existing data
238      */
239     psa_status_t (*set_extended)(void *context,
240                             uint32_t client_id,
241                             uint64_t uid,
242                             size_t data_offset,
243                             size_t data_length,
244                             const void *p_data);
245 
246     /**
247      * \brief Get supported features
248      *
249      * Returns a bit map of optional features supported by the backend
250      *
251      * \param[in] context       The concrete backend context
252      * \param[in] client_id     Identifier of the asset's owner (client)
253      *
254      * \return Bit map of supported features (defined in psa/storage_common.h)
255      */
256     uint32_t (*get_support)(void *context,
257                             uint32_t client_id);
258 };
259 
260 /**
261  * \brief Common storage backend instance
262  *
263  * Used by a storage frontend to make an association with a backend.
264  */
265 struct storage_backend
266 {
267     /**
268      * \brief The backend context
269      *
270      * Points to bandend specific instance data.
271      */
272     void *context;
273 
274     /**
275      * \brief The backend interface
276      *
277      * A concrete backend provides an implementation of this interface.
278      */
279     const struct storage_backend_interface *interface;
280 };
281 
282 #ifdef __cplusplus
283 }
284 #endif
285 
286 #endif /* __STORAGE_BACKEND_H__ */
287