1 /* 2 * Copyright (c) 2018-2023, Arm Limited. All rights reserved. 3 * Copyright (c) 2020, Cypress Semiconductor Corporation. All rights reserved. 4 * 5 * SPDX-License-Identifier: BSD-3-Clause 6 * 7 */ 8 9 /** 10 * \file its_flash_fs.h 11 * 12 * \brief Internal Trusted Storage service filesystem abstraction APIs. 13 * The purpose of this abstraction is to have the ability to plug-in 14 * other filesystems or filesystem proxies (supplicant). 15 */ 16 17 #ifndef __ITS_FLASH_FS_H__ 18 #define __ITS_FLASH_FS_H__ 19 20 #include <stddef.h> 21 #include <stdint.h> 22 23 #include "its_flash_fs_mblock.h" 24 #include "psa/error.h" 25 26 #ifdef __cplusplus 27 extern "C" { 28 #endif 29 30 /* Space reserved for user-defined flags. These are stored in the file metadata 31 * and can be retrieved by getting the file info. 32 */ 33 #define ITS_FLASH_FS_USER_FLAGS_MASK ((1UL << 16) - 1) 34 35 /* Filesystem flags that can be provided when calling the write function */ 36 #define ITS_FLASH_FS_WRITE_FLAGS_MASK ((1UL << 24) - (1UL << 16)) 37 /* Create the file if it does not already exist */ 38 #define ITS_FLASH_FS_FLAG_CREATE (1UL << 16) 39 /* Remove existing file data if it exists */ 40 #define ITS_FLASH_FS_FLAG_TRUNCATE (1UL << 17) 41 42 /* Invalid block index */ 43 #define ITS_BLOCK_INVALID_ID 0xFFFFFFFFU 44 45 /** 46 * \struct its_flash_fs_config_t 47 * 48 * \brief Structure containing the flash filesystem configuration parameters. 49 */ 50 struct its_flash_fs_config_t { 51 const void *flash_dev; /**< Pointer to the flash device */ 52 uint32_t flash_area_addr; /**< Base address of the flash region */ 53 uint32_t sector_size; /**< Size of the flash device's physical erase 54 * unit 55 */ 56 uint32_t block_size; /**< Size of a logical filesystem erase unit, a 57 * multiple of sector_size. 58 */ 59 uint16_t num_blocks; /**< Number of logical erase blocks */ 60 uint16_t program_unit; /**< Minimum size of a program operation */ 61 uint16_t max_file_size; /**< Maximum file size */ 62 uint16_t max_num_files; /**< Maximum number of files */ 63 uint8_t erase_val; /**< Value of a byte after erase (usually 0xFF) */ 64 }; 65 66 /** 67 * \struct its_flash_fs_ops_t 68 * 69 * \brief Structure containing the filesystem flash operation parameters. 70 */ 71 struct its_flash_fs_ops_t { 72 /** 73 * \brief Initializes the flash device. 74 * 75 * \param[in] cfg Filesystem configuration 76 * 77 * \return Returns PSA_SUCCESS if the function is executed correctly. 78 * Otherwise, it returns PSA_ERROR_STORAGE_FAILURE. 79 */ 80 psa_status_t (*init)(const struct its_flash_fs_config_t *cfg); 81 82 /** 83 * \brief Reads block data from the position specified by block ID and 84 * offset. 85 * 86 * \param[in] cfg Filesystem configuration 87 * \param[in] block_id Block ID 88 * \param[out] buf Buffer pointer to store the data read 89 * \param[in] offset Offset position from the init of the block 90 * \param[in] size Number of bytes to read 91 * 92 * \note This function assumes all input values are valid. That is, the 93 * address range, based on block_id, offset and size, is a valid range 94 * in flash. 95 * 96 * \return Returns PSA_SUCCESS if the function is executed correctly. 97 * Otherwise, it returns PSA_ERROR_STORAGE_FAILURE. 98 */ 99 psa_status_t (*read)(const struct its_flash_fs_config_t *cfg, 100 uint32_t block_id, uint8_t *buf, size_t offset, 101 size_t size); 102 103 /** 104 * \brief Writes block data to the position specified by block ID and 105 * offset. 106 * 107 * \param[in] cfg Filesystem configuration 108 * \param[in] block_id Block ID 109 * \param[in] buf Buffer pointer to the write data 110 * \param[in] offset Offset position from the init of the block 111 * \param[in] size Number of bytes to write 112 * 113 * \note This function assumes all input values are valid. That is, the 114 * address range, based on block_id, offset and size, is a valid range 115 * in flash. 116 * 117 * \return Returns PSA_SUCCESS if the function is executed correctly. 118 * Otherwise, it returns PSA_ERROR_STORAGE_FAILURE. 119 */ 120 psa_status_t (*write)(const struct its_flash_fs_config_t *cfg, 121 uint32_t block_id, const uint8_t *buf, size_t offset, 122 size_t size); 123 124 /** 125 * \brief Flushes modifications to a block to flash. Must be called after a 126 * sequence of calls to write() (including via 127 * its_flash_block_to_block_move()) for one block ID, before any call 128 * to the same functions for a different block ID. 129 * 130 * \param[in] cfg Filesystem configuration 131 * 132 * \param[in] block_id Block ID 133 * 134 * \note It is permitted for write() to commit block updates immediately, in 135 * which case this function is a no-op. 136 * 137 * \return Returns PSA_SUCCESS if the function is executed correctly. 138 * Otherwise, it returns PSA_ERROR_STORAGE_FAILURE. 139 */ 140 psa_status_t (*flush)(const struct its_flash_fs_config_t *cfg, 141 uint32_t block_id); 142 143 /** 144 * \brief Erases block ID data. 145 * 146 * \param[in] cfg Filesystem configuration 147 * \param[in] block_id Block ID 148 * 149 * \note This function assumes the input value is valid. 150 * 151 * \return Returns PSA_SUCCESS if the function is executed correctly. 152 * Otherwise, it returns PSA_ERROR_STORAGE_FAILURE. 153 */ 154 psa_status_t (*erase)(const struct its_flash_fs_config_t *cfg, 155 uint32_t block_id); 156 }; 157 158 /** 159 * \brief ITS flash filesystem context type, used to maintain state across FS 160 * operations. 161 * 162 * \details The user should allocate a variable of this type, initialised to 163 * zero, before calling its_flash_fs_prepare, and then pass it to each 164 * subsequent FS operation. The contents are internal to the 165 * filesystem. 166 */ 167 typedef struct its_flash_fs_ctx_t its_flash_fs_ctx_t; 168 169 /*! 170 * \struct its_flash_fs_file_info_t 171 * 172 * \brief Structure containing file information. 173 * 174 * \details This structure is not written to the filesystem, it is used by the 175 * file system functions to simplify accessing the containing 176 * information. 177 */ 178 struct its_flash_fs_file_info_t { 179 size_t size_current; /*!< The current size of the file in bytes */ 180 size_t size_max; /*!< The maximum size of the file in bytes. */ 181 uint32_t flags; /*!< Flags set when the file was created */ 182 #ifdef ITS_ENCRYPTION 183 /*!< Additional authenticated data */ 184 uint8_t add[ITS_FILE_ID_SIZE + ITS_DATA_SIZE_FIELD_SIZE + ITS_FLAG_SIZE]; 185 uint8_t nonce[12];/*!< Nonce/IV for encrypted files */ 186 uint8_t tag[16]; /*!< Authentication tag */ 187 #endif 188 }; 189 190 /** 191 * \brief Initialises the filesystem context. Must be called successfully before 192 * any other filesystem API is called. 193 * 194 * \param[in,out] fs_ctx Filesystem context to initialise. Must have been 195 * allocated by the caller. 196 * \param[in] fs_cfg Filesystem configuration to associate with the 197 * context. 198 * \param[in] fs_ops Filesystem flash operations to associate with the 199 * context. 200 * 201 * \return Returns error code as specified in \ref psa_status_t 202 */ 203 psa_status_t its_flash_fs_init_ctx(its_flash_fs_ctx_t *fs_ctx, 204 const struct its_flash_fs_config_t *fs_cfg, 205 const struct its_flash_fs_ops_t *fs_ops); 206 207 /** 208 * \brief Prepares the filesystem to accept operations on the files. 209 * 210 * \param[in,out] fs_ctx Filesystem context to prepare. Must have been 211 * initialised by its_flash_fs_init_ctx(). 212 * 213 * \return Returns error code as specified in \ref psa_status_t 214 */ 215 psa_status_t its_flash_fs_prepare(its_flash_fs_ctx_t *fs_ctx); 216 217 /** 218 * \brief Wipes all files from the filesystem. 219 * 220 * \param[in,out] fs_ctx Filesystem context to wipe. Must be prepared again 221 * before further use. 222 * 223 * \return Returns error code as specified in \ref psa_status_t 224 */ 225 psa_status_t its_flash_fs_wipe_all(its_flash_fs_ctx_t *fs_ctx); 226 227 /** 228 * \brief Gets the file information referenced by the file ID. 229 * 230 * \param[in,out] fs_ctx Filesystem context 231 * \param[in] fid File ID 232 * \param[out] info Pointer to the file information 233 * structure \ref its_flash_fs_file_info_t 234 * 235 * \return Returns error code specified in \ref psa_status_t 236 */ 237 psa_status_t its_flash_fs_file_get_info(its_flash_fs_ctx_t *fs_ctx, 238 const uint8_t *fid, 239 struct its_flash_fs_file_info_t *info); 240 241 /** 242 * \brief Writes data to a file. 243 * 244 * \param[in,out] fs_ctx Filesystem context 245 * \param[in] fid File ID 246 * \param[in] finfo Pointer to \ref its_flash_fs_file_info_t 247 * \param[in] data_size Size of the incoming write data. 248 * \param[in] offset Offset in the file to write. Must be less than or 249 * equal to the current file size. 250 * \param[in] data Pointer to buffer containing data to be written 251 * 252 * \return Returns error code as specified in \ref psa_status_t 253 */ 254 psa_status_t its_flash_fs_file_write(its_flash_fs_ctx_t *fs_ctx, 255 const uint8_t *fid, 256 struct its_flash_fs_file_info_t *finfo, 257 size_t data_size, 258 size_t offset, 259 const uint8_t *data); 260 261 /** 262 * \brief Reads data from an existing file. 263 * 264 * \param[in,out] fs_ctx Filesystem context 265 * \param[in] fid File ID 266 * \param[in] size Size to be read 267 * \param[in] offset Offset in the file 268 * \param[out] data Pointer to buffer to store the data 269 * 270 * \return Returns error code as specified in \ref psa_status_t 271 */ 272 psa_status_t its_flash_fs_file_read(its_flash_fs_ctx_t *fs_ctx, 273 const uint8_t *fid, 274 size_t size, 275 size_t offset, 276 uint8_t *data); 277 278 /** 279 * \brief Deletes file referenced by the file ID. 280 * 281 * \param[in,out] fs_ctx Filesystem context 282 * \param[in] fid File ID 283 * 284 * \return Returns error code as specified in \ref psa_status_t 285 */ 286 psa_status_t its_flash_fs_file_delete(its_flash_fs_ctx_t *fs_ctx, 287 const uint8_t *fid); 288 289 #ifdef __cplusplus 290 } 291 #endif 292 293 #endif /* __ITS_FLASH_FS_H__ */ 294