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