Toyomasa Watarai / simple-mbed-cloud-client

Dependents:  

Committer:
MACRUM
Date:
Mon Jul 02 06:30:39 2018 +0000
Revision:
0:276e7a263c35
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MACRUM 0:276e7a263c35 1 /*
MACRUM 0:276e7a263c35 2 * Copyright (c) 2016 ARM Limited. All rights reserved.
MACRUM 0:276e7a263c35 3 * SPDX-License-Identifier: Apache-2.0
MACRUM 0:276e7a263c35 4 * Licensed under the Apache License, Version 2.0 (the License); you may
MACRUM 0:276e7a263c35 5 * not use this file except in compliance with the License.
MACRUM 0:276e7a263c35 6 * You may obtain a copy of the License at
MACRUM 0:276e7a263c35 7 *
MACRUM 0:276e7a263c35 8 * http://www.apache.org/licenses/LICENSE-2.0
MACRUM 0:276e7a263c35 9 *
MACRUM 0:276e7a263c35 10 * Unless required by applicable law or agreed to in writing, software
MACRUM 0:276e7a263c35 11 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
MACRUM 0:276e7a263c35 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
MACRUM 0:276e7a263c35 13 * See the License for the specific language governing permissions and
MACRUM 0:276e7a263c35 14 * limitations under the License.
MACRUM 0:276e7a263c35 15 */
MACRUM 0:276e7a263c35 16
MACRUM 0:276e7a263c35 17
MACRUM 0:276e7a263c35 18
MACRUM 0:276e7a263c35 19 // ----------------------------------------------------------- Includes -----------------------------------------------------------
MACRUM 0:276e7a263c35 20
MACRUM 0:276e7a263c35 21 #ifdef MBED_CLOUD_CLIENT_USER_CONFIG_FILE
MACRUM 0:276e7a263c35 22 #include MBED_CLOUD_CLIENT_USER_CONFIG_FILE
MACRUM 0:276e7a263c35 23 #endif
MACRUM 0:276e7a263c35 24
MACRUM 0:276e7a263c35 25
MACRUM 0:276e7a263c35 26 #include "pal.h"
MACRUM 0:276e7a263c35 27 #include "esfs.h"
MACRUM 0:276e7a263c35 28 #include "esfs_file_name.h"
MACRUM 0:276e7a263c35 29
MACRUM 0:276e7a263c35 30 #include "mbed-trace/mbed_trace.h"
MACRUM 0:276e7a263c35 31
MACRUM 0:276e7a263c35 32
MACRUM 0:276e7a263c35 33 #include <string.h> // For memcmp and strncat
MACRUM 0:276e7a263c35 34
MACRUM 0:276e7a263c35 35
MACRUM 0:276e7a263c35 36
MACRUM 0:276e7a263c35 37 // --------------------------------------------------------- Definitions ----------------------------------------------------------
MACRUM 0:276e7a263c35 38
MACRUM 0:276e7a263c35 39
MACRUM 0:276e7a263c35 40 #define TRACE_GROUP "esfs" // Maximum 4 characters
MACRUM 0:276e7a263c35 41
MACRUM 0:276e7a263c35 42 // We do not really know what other uses (if any) the file system card will have.
MACRUM 0:276e7a263c35 43 // We will assume that it may contain other files and we will keep all ESFS files in one directory.
MACRUM 0:276e7a263c35 44 // A future enhancement could be to put files that are not to be removed at factory reset in a separate directory.
MACRUM 0:276e7a263c35 45 #if !defined(ESFS_WORKING_DIRECTORY)
MACRUM 0:276e7a263c35 46 #define ESFS_WORKING_DIRECTORY "WORKING"
MACRUM 0:276e7a263c35 47 #endif
MACRUM 0:276e7a263c35 48
MACRUM 0:276e7a263c35 49 #if !defined(ESFS_BACKUP_DIRECTORY)
MACRUM 0:276e7a263c35 50 #define ESFS_BACKUP_DIRECTORY "BACKUP"
MACRUM 0:276e7a263c35 51 #endif
MACRUM 0:276e7a263c35 52
MACRUM 0:276e7a263c35 53 #define FACTORY_RESET_DIR "FR"
MACRUM 0:276e7a263c35 54 #define FACTORY_RESET_FILE "fr_on"
MACRUM 0:276e7a263c35 55
MACRUM 0:276e7a263c35 56 // We choose a size that does not take up too much stack, but minimizes the number of reads.
MACRUM 0:276e7a263c35 57 #define ESFS_READ_CHUNK_SIZE_IN_BYTES (64)
MACRUM 0:276e7a263c35 58
MACRUM 0:276e7a263c35 59 #define ESFS_BITS_IN_BYTE (8)
MACRUM 0:276e7a263c35 60 #define ESFS_AES_BLOCK_SIZE_BYTES (16)
MACRUM 0:276e7a263c35 61 #define ESFS_AES_IV_SIZE_BYTES (16)
MACRUM 0:276e7a263c35 62 #define ESFS_AES_COUNTER_INDEX_IN_IV ESFS_AES_NONCE_SIZE_BYTES
MACRUM 0:276e7a263c35 63 #define ESFS_AES_COUNTER_SIZE_BYTES (8)
MACRUM 0:276e7a263c35 64 #define ESFS_AES_KEY_SIZE_BYTES (16)
MACRUM 0:276e7a263c35 65 #define ESFS_AES_KEY_SIZE_BITS (ESFS_AES_KEY_SIZE_BYTES * ESFS_BITS_IN_BYTE)
MACRUM 0:276e7a263c35 66
MACRUM 0:276e7a263c35 67 // Defines the size in bytes of buffers for AES encryption / decryption.
MACRUM 0:276e7a263c35 68 // In case we have to encrypt / decrypt a bigger amount of bytes, we loop over the buffer
MACRUM 0:276e7a263c35 69 // and encrypt / decrypt up to ESFS_AES_BUF_SIZE_BYTES bytes on each step
MACRUM 0:276e7a263c35 70 #define ESFS_AES_BUF_SIZE_BYTES (256)
MACRUM 0:276e7a263c35 71
MACRUM 0:276e7a263c35 72 // This should be incremented when the file format changes
MACRUM 0:276e7a263c35 73 #define ESFS_FILE_FORMAT_VERSION (1)
MACRUM 0:276e7a263c35 74
MACRUM 0:276e7a263c35 75 #define ESFS_FILE_COPY_CHUNK_SIZE (256)
MACRUM 0:276e7a263c35 76
MACRUM 0:276e7a263c35 77 #define MAX_FULL_PATH_SIZE (PAL_MAX_FOLDER_DEPTH_CHAR + 1 + PAL_MAX(sizeof(ESFS_BACKUP_DIRECTORY), sizeof(ESFS_WORKING_DIRECTORY)) + PAL_MAX(sizeof(FACTORY_RESET_DIR) + sizeof(FACTORY_RESET_FILE), ESFS_QUALIFIED_FILE_NAME_LENGTH))
MACRUM 0:276e7a263c35 78
MACRUM 0:276e7a263c35 79 static bool esfs_initialize = false;
MACRUM 0:276e7a263c35 80
MACRUM 0:276e7a263c35 81
MACRUM 0:276e7a263c35 82
MACRUM 0:276e7a263c35 83 // -------------------------------------------------- Functions Implementation ----------------------------------------------------
MACRUM 0:276e7a263c35 84
MACRUM 0:276e7a263c35 85
MACRUM 0:276e7a263c35 86 // ---------------------------------------------------------------
MACRUM 0:276e7a263c35 87 // Helper Functions
MACRUM 0:276e7a263c35 88 // ---------------------------------------------------------------
MACRUM 0:276e7a263c35 89
MACRUM 0:276e7a263c35 90
MACRUM 0:276e7a263c35 91 esfs_result_e esfs_init(void)
MACRUM 0:276e7a263c35 92 {
MACRUM 0:276e7a263c35 93 esfs_result_e result = ESFS_SUCCESS;
MACRUM 0:276e7a263c35 94 tr_info("esfs_init - enter");
MACRUM 0:276e7a263c35 95 if (!esfs_initialize)
MACRUM 0:276e7a263c35 96 {
MACRUM 0:276e7a263c35 97 palStatus_t pal_result = PAL_SUCCESS;
MACRUM 0:276e7a263c35 98 esfs_file_t file_handle = {0};
MACRUM 0:276e7a263c35 99 char dir_path[MAX_FULL_PATH_SIZE] = { 0 };
MACRUM 0:276e7a263c35 100
MACRUM 0:276e7a263c35 101 pal_result = pal_fsGetMountPoint(PAL_FS_PARTITION_PRIMARY, PAL_MAX_FOLDER_DEPTH_CHAR + 1, dir_path);
MACRUM 0:276e7a263c35 102 if (pal_result != PAL_SUCCESS)
MACRUM 0:276e7a263c35 103 {
MACRUM 0:276e7a263c35 104 tr_err("esfs_init() - pal_fsGetMountPoint() for working directory failed with pal_status = 0x%x", (unsigned int)pal_result);
MACRUM 0:276e7a263c35 105 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 106 goto errorExit;
MACRUM 0:276e7a263c35 107 }
MACRUM 0:276e7a263c35 108
MACRUM 0:276e7a263c35 109 strncat(dir_path, "/" ESFS_WORKING_DIRECTORY, sizeof(ESFS_WORKING_DIRECTORY));
MACRUM 0:276e7a263c35 110
MACRUM 0:276e7a263c35 111 //Looping on first file system operation to work around IOTMORF-914 - sd-driver initialization
MACRUM 0:276e7a263c35 112 for(int i=0 ; i<100; i++)
MACRUM 0:276e7a263c35 113 {
MACRUM 0:276e7a263c35 114 // Create the esfs subfolder working
MACRUM 0:276e7a263c35 115 pal_result = pal_fsMkDir(dir_path);
MACRUM 0:276e7a263c35 116 if ((pal_result == PAL_SUCCESS) || (pal_result == PAL_ERR_FS_NAME_ALREADY_EXIST))
MACRUM 0:276e7a263c35 117 break;
MACRUM 0:276e7a263c35 118 tr_err("esfs_init() %d", i);
MACRUM 0:276e7a263c35 119 pal_osDelay(50);
MACRUM 0:276e7a263c35 120
MACRUM 0:276e7a263c35 121 }
MACRUM 0:276e7a263c35 122
MACRUM 0:276e7a263c35 123 if ((pal_result != PAL_SUCCESS) && (pal_result != PAL_ERR_FS_NAME_ALREADY_EXIST))
MACRUM 0:276e7a263c35 124 {
MACRUM 0:276e7a263c35 125 tr_err("esfs_init() - pal_fsMkDir() for working directory failed with pal_status = 0x%x", (unsigned int)pal_result);
MACRUM 0:276e7a263c35 126 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 127 goto errorExit;
MACRUM 0:276e7a263c35 128 }
MACRUM 0:276e7a263c35 129
MACRUM 0:276e7a263c35 130 pal_result = pal_fsGetMountPoint(PAL_FS_PARTITION_SECONDARY, PAL_MAX_FOLDER_DEPTH_CHAR + 1, dir_path);
MACRUM 0:276e7a263c35 131 if (pal_result != PAL_SUCCESS)
MACRUM 0:276e7a263c35 132 {
MACRUM 0:276e7a263c35 133
MACRUM 0:276e7a263c35 134 tr_err("esfs_init() - pal_fsGetMountPoint() for backup directory failed with pal_status = 0x%x", (unsigned int)pal_result);
MACRUM 0:276e7a263c35 135 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 136 goto errorExit;
MACRUM 0:276e7a263c35 137 }
MACRUM 0:276e7a263c35 138
MACRUM 0:276e7a263c35 139 strncat(dir_path, "/" ESFS_BACKUP_DIRECTORY, sizeof(ESFS_BACKUP_DIRECTORY));
MACRUM 0:276e7a263c35 140
MACRUM 0:276e7a263c35 141 // Create the directory ESFS_BACKUP_DIRECTORY
MACRUM 0:276e7a263c35 142 pal_result = pal_fsMkDir(dir_path);
MACRUM 0:276e7a263c35 143 if (pal_result != PAL_SUCCESS)
MACRUM 0:276e7a263c35 144 {
MACRUM 0:276e7a263c35 145 // Any error apart from file exist returns error.
MACRUM 0:276e7a263c35 146 if (pal_result != PAL_ERR_FS_NAME_ALREADY_EXIST)
MACRUM 0:276e7a263c35 147 {
MACRUM 0:276e7a263c35 148 tr_err("esfs_init() - pal_fsMkDir() for backup directory failed with pal_status = 0x%x", (unsigned int)pal_result);
MACRUM 0:276e7a263c35 149 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 150 goto errorExit;
MACRUM 0:276e7a263c35 151 }
MACRUM 0:276e7a263c35 152 }
MACRUM 0:276e7a263c35 153
MACRUM 0:276e7a263c35 154 // create the correct path for factory reset file fr_on
MACRUM 0:276e7a263c35 155 strncat(dir_path, "/" FACTORY_RESET_DIR "/" FACTORY_RESET_FILE, sizeof(FACTORY_RESET_DIR) + sizeof(FACTORY_RESET_FILE));
MACRUM 0:276e7a263c35 156 pal_result = pal_fsFopen(dir_path, PAL_FS_FLAG_READONLY, &(file_handle.file));
MACRUM 0:276e7a263c35 157 // (res == PAL_SUCCESS) : flag file can be opened for reading --> file \FR\fr_on found
MACRUM 0:276e7a263c35 158 // previous factory reset failed during execution
MACRUM 0:276e7a263c35 159 // (res == PAL_ERR_FS_NO_FILE) : flag file was not found --> good scenario
MACRUM 0:276e7a263c35 160 // (res != PAL_ERR_FS_NO_FILE) : file system problem
MACRUM 0:276e7a263c35 161 if (pal_result == PAL_SUCCESS)
MACRUM 0:276e7a263c35 162 {
MACRUM 0:276e7a263c35 163 // Close the file before factory reset
MACRUM 0:276e7a263c35 164 pal_result = pal_fsFclose(&(file_handle.file));
MACRUM 0:276e7a263c35 165 if (pal_result != PAL_SUCCESS)
MACRUM 0:276e7a263c35 166 {
MACRUM 0:276e7a263c35 167 tr_err("esfs_init() - unexpected filesystem behavior pal_fsFclose() failed with pal_status = 0x%x", (unsigned int)pal_result);
MACRUM 0:276e7a263c35 168 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 169 goto errorExit;
MACRUM 0:276e7a263c35 170 }
MACRUM 0:276e7a263c35 171 // previous factory reset failed during execution - therefore we call this factory_reset again
MACRUM 0:276e7a263c35 172 result = esfs_factory_reset();
MACRUM 0:276e7a263c35 173 if (result != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 174 {
MACRUM 0:276e7a263c35 175 tr_err("esfs_init() - esfs_factory_reset() failed with esfs_result_e = 0x%x", result);
MACRUM 0:276e7a263c35 176 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 177 goto errorExit;
MACRUM 0:276e7a263c35 178 }
MACRUM 0:276e7a263c35 179 } else if (pal_result != PAL_ERR_FS_NO_FILE)
MACRUM 0:276e7a263c35 180 {
MACRUM 0:276e7a263c35 181 tr_err("esfs_init() - unexpected filesystem behavior pal_fsFopen() failed with pal_status = 0x%x", (unsigned int)pal_result);
MACRUM 0:276e7a263c35 182 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 183 goto errorExit;
MACRUM 0:276e7a263c35 184 }
MACRUM 0:276e7a263c35 185
MACRUM 0:276e7a263c35 186 esfs_initialize = true;
MACRUM 0:276e7a263c35 187 }
MACRUM 0:276e7a263c35 188 return ESFS_SUCCESS;
MACRUM 0:276e7a263c35 189
MACRUM 0:276e7a263c35 190 errorExit:
MACRUM 0:276e7a263c35 191 return result;
MACRUM 0:276e7a263c35 192
MACRUM 0:276e7a263c35 193 }
MACRUM 0:276e7a263c35 194
MACRUM 0:276e7a263c35 195 esfs_result_e esfs_finalize(void)
MACRUM 0:276e7a263c35 196 {
MACRUM 0:276e7a263c35 197 esfs_initialize = false;
MACRUM 0:276e7a263c35 198 tr_info("esfs_finalize - enter");
MACRUM 0:276e7a263c35 199 return ESFS_SUCCESS;
MACRUM 0:276e7a263c35 200 }
MACRUM 0:276e7a263c35 201
MACRUM 0:276e7a263c35 202 // Validate that a file handle has been initialized by create or open.
MACRUM 0:276e7a263c35 203 // Parameters : file_handle - [IN] A pointer to a file handle for which we calculate the size.
MACRUM 0:276e7a263c35 204 // Return : ESFS_SUCCESS on success. Error code otherwise
MACRUM 0:276e7a263c35 205 static esfs_result_e esfs_validate(esfs_file_t *file_handle)
MACRUM 0:276e7a263c35 206 {
MACRUM 0:276e7a263c35 207 if(file_handle && file_handle->blob_name_length > 0)
MACRUM 0:276e7a263c35 208 {
MACRUM 0:276e7a263c35 209 return ESFS_SUCCESS;
MACRUM 0:276e7a263c35 210 }
MACRUM 0:276e7a263c35 211 else
MACRUM 0:276e7a263c35 212 {
MACRUM 0:276e7a263c35 213 return ESFS_ERROR;
MACRUM 0:276e7a263c35 214 }
MACRUM 0:276e7a263c35 215 }
MACRUM 0:276e7a263c35 216
MACRUM 0:276e7a263c35 217
MACRUM 0:276e7a263c35 218 //Function : esfs_not_encrypted_file_header_size
MACRUM 0:276e7a263c35 219 //
MACRUM 0:276e7a263c35 220 //Description: This function returns the size in bytes of the file header without the metadata values part.
MACRUM 0:276e7a263c35 221 // This is actually the non-encrypted part of the file header.
MACRUM 0:276e7a263c35 222 // It is useful for calculation the file pointer position for AES encryption / decryption which starts only from the
MACRUM 0:276e7a263c35 223 // encrypted part of the file.
MACRUM 0:276e7a263c35 224 //
MACRUM 0:276e7a263c35 225 //Parameters : file_handle - [IN] A pointer to a file handle for which we calculate the size.
MACRUM 0:276e7a263c35 226 //
MACRUM 0:276e7a263c35 227 //Return : The size in bytes of the non-encrypted part of the file header
MACRUM 0:276e7a263c35 228 static size_t esfs_not_encrypted_file_header_size(esfs_file_t *file_handle)
MACRUM 0:276e7a263c35 229 {
MACRUM 0:276e7a263c35 230 esfs_tlv_properties_t *tlv_properties = &(file_handle->tlv_properties);
MACRUM 0:276e7a263c35 231
MACRUM 0:276e7a263c35 232 return ( file_handle->blob_name_length + // Name length field
MACRUM 0:276e7a263c35 233 sizeof(file_handle->blob_name_length) + // Name field
MACRUM 0:276e7a263c35 234 sizeof(uint16_t) + // Version field
MACRUM 0:276e7a263c35 235 sizeof(uint16_t) + // Mode field
MACRUM 0:276e7a263c35 236 (((file_handle->esfs_mode & ESFS_ENCRYPTED) != 0) ? ESFS_AES_NONCE_SIZE_BYTES : 0) + // Nonce field [non mandatory field]
MACRUM 0:276e7a263c35 237 sizeof(tlv_properties->number_of_items) + // Metadata number of elements field
MACRUM 0:276e7a263c35 238 (tlv_properties->number_of_items * sizeof(tlv_properties->tlv_items[0])) // Metadata tlv headers
MACRUM 0:276e7a263c35 239 );
MACRUM 0:276e7a263c35 240 }
MACRUM 0:276e7a263c35 241
MACRUM 0:276e7a263c35 242 // Returns the size in bytes of the file header.
MACRUM 0:276e7a263c35 243 // This can only be called after the header has been read.
MACRUM 0:276e7a263c35 244 // Parameters :
MACRUM 0:276e7a263c35 245 // file_handle - [IN] A pointer to a file handle for which we calculate the size.
MACRUM 0:276e7a263c35 246 static size_t esfs_file_header_size(esfs_file_t *file_handle)
MACRUM 0:276e7a263c35 247 {
MACRUM 0:276e7a263c35 248 size_t metadata_size = 0;
MACRUM 0:276e7a263c35 249 esfs_tlv_properties_t *tlv_properties = &file_handle->tlv_properties;
MACRUM 0:276e7a263c35 250
MACRUM 0:276e7a263c35 251 for(int i = 0; i < tlv_properties->number_of_items; i++)
MACRUM 0:276e7a263c35 252 {
MACRUM 0:276e7a263c35 253 metadata_size += tlv_properties->tlv_items[i].length_in_bytes;
MACRUM 0:276e7a263c35 254 }
MACRUM 0:276e7a263c35 255
MACRUM 0:276e7a263c35 256 return esfs_not_encrypted_file_header_size(file_handle) + metadata_size;
MACRUM 0:276e7a263c35 257 }
MACRUM 0:276e7a263c35 258
MACRUM 0:276e7a263c35 259 // Helper function to calculate the cmac on data that is written.
MACRUM 0:276e7a263c35 260 // Parameters :
MACRUM 0:276e7a263c35 261 // pbuf - [IN] A pointer to a buffer
MACRUM 0:276e7a263c35 262 // num_bytes [IN] number of bytes that we request to write.
MACRUM 0:276e7a263c35 263 // file_handle - [IN] A pointer to a file handle for which we calculate the size.
MACRUM 0:276e7a263c35 264 // Return : ESFS_SUCCESS on success. Error code otherwise
MACRUM 0:276e7a263c35 265 static esfs_result_e esfs_fwrite_and_calc_cmac(const void *pbuf, size_t num_bytes, esfs_file_t *file_handle)
MACRUM 0:276e7a263c35 266 {
MACRUM 0:276e7a263c35 267 palStatus_t res = pal_CMACUpdate(file_handle->signature_ctx, pbuf, num_bytes);
MACRUM 0:276e7a263c35 268 if(res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 269 {
MACRUM 0:276e7a263c35 270 tr_err("esfs_fwrite_and_calc_cmac() - pal_CMACUpdate failed with result = 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 271 return ESFS_ERROR;
MACRUM 0:276e7a263c35 272 }
MACRUM 0:276e7a263c35 273
MACRUM 0:276e7a263c35 274 size_t num_bytes_written;
MACRUM 0:276e7a263c35 275 res = pal_fsFwrite(&file_handle->file, pbuf, num_bytes, &num_bytes_written);
MACRUM 0:276e7a263c35 276 if(res != PAL_SUCCESS || num_bytes != num_bytes_written)
MACRUM 0:276e7a263c35 277 {
MACRUM 0:276e7a263c35 278 tr_err("esfs_fwrite_and_calc_cmac() - pal_fsFwrite failed, status = 0x%x, written bytes = %zu, expected = %zu",
MACRUM 0:276e7a263c35 279 (unsigned int)res, num_bytes_written, num_bytes);
MACRUM 0:276e7a263c35 280 return ESFS_ERROR;
MACRUM 0:276e7a263c35 281 }
MACRUM 0:276e7a263c35 282
MACRUM 0:276e7a263c35 283 return ESFS_SUCCESS;
MACRUM 0:276e7a263c35 284 }
MACRUM 0:276e7a263c35 285
MACRUM 0:276e7a263c35 286
MACRUM 0:276e7a263c35 287 // Helper function to start a cmac run.
MACRUM 0:276e7a263c35 288 // Moves the file position to the start of the file.
MACRUM 0:276e7a263c35 289 // Parameters :
MACRUM 0:276e7a263c35 290 // file_handle - [IN] A pointer to a file handle.
MACRUM 0:276e7a263c35 291 // If successful it creates a cmac context which must be destroyed with a call to esfs_cmac_finish
MACRUM 0:276e7a263c35 292 // Return : ESFS_SUCCESS on success. Error code otherwise.
MACRUM 0:276e7a263c35 293 static esfs_result_e esfs_cmac_start(esfs_file_t *file_handle)
MACRUM 0:276e7a263c35 294 {
MACRUM 0:276e7a263c35 295 unsigned char key[ESFS_CMAC_SIZE_IN_BYTES];
MACRUM 0:276e7a263c35 296
MACRUM 0:276e7a263c35 297 // Get CMAC key from PAL
MACRUM 0:276e7a263c35 298 palStatus_t res = pal_osGetDeviceKey(palOsStorageSignatureKey128Bit, &key[0], ESFS_CMAC_SIZE_IN_BYTES);
MACRUM 0:276e7a263c35 299 if(res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 300 {
MACRUM 0:276e7a263c35 301 tr_err("esfs_start_cmac() - pal_osGetDeviceKey() failed with pal_status = 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 302 return ESFS_ERROR;
MACRUM 0:276e7a263c35 303 }
MACRUM 0:276e7a263c35 304
MACRUM 0:276e7a263c35 305 // Start CMAC with the key. Initializes signature_ctx
MACRUM 0:276e7a263c35 306 res = pal_CMACStart(&file_handle->signature_ctx, &key[0], 128, PAL_CIPHER_ID_AES);
MACRUM 0:276e7a263c35 307 if(res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 308 {
MACRUM 0:276e7a263c35 309 tr_err("esfs_start_cmac() - pal_CMACStart() failed with pal_status = 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 310 return ESFS_ERROR;
MACRUM 0:276e7a263c35 311 }
MACRUM 0:276e7a263c35 312
MACRUM 0:276e7a263c35 313 // Seek to the start of the file
MACRUM 0:276e7a263c35 314 res = pal_fsFseek(&file_handle->file, 0, PAL_FS_OFFSET_SEEKSET);
MACRUM 0:276e7a263c35 315 if(res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 316 {
MACRUM 0:276e7a263c35 317 tr_err("esfs_start_cmac() - pal_fsFseek() failed with pal status 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 318
MACRUM 0:276e7a263c35 319 // Clean up the cmac context
MACRUM 0:276e7a263c35 320 size_t num_bytes;
MACRUM 0:276e7a263c35 321 // Ignore error. Sets file_handle->signature_ctx to 0 on success
MACRUM 0:276e7a263c35 322 (void)pal_CMACFinish(&file_handle->signature_ctx, &key[0], &num_bytes);
MACRUM 0:276e7a263c35 323 return ESFS_ERROR;
MACRUM 0:276e7a263c35 324 }
MACRUM 0:276e7a263c35 325
MACRUM 0:276e7a263c35 326 return ESFS_SUCCESS;
MACRUM 0:276e7a263c35 327 }
MACRUM 0:276e7a263c35 328
MACRUM 0:276e7a263c35 329 // Helper function to read and calculate the cmac on data that is read.
MACRUM 0:276e7a263c35 330 // The function will not update the cmac if there is no CMAC context in the file handle.
MACRUM 0:276e7a263c35 331 // Updates the file position.
MACRUM 0:276e7a263c35 332 // Parameters :
MACRUM 0:276e7a263c35 333 // file_handle - [IN] A pointer to a file handle for which we calculate the cmac.
MACRUM 0:276e7a263c35 334 // pbuf [OUT] A pointer to a buffer containing the data that is read.
MACRUM 0:276e7a263c35 335 // num_bytes [IN] number of bytes that we request to read.
MACRUM 0:276e7a263c35 336 // num_bytes_read[OUT] A pointer to a location in which will be written the number of bytes actually read.
MACRUM 0:276e7a263c35 337 // Return : ESFS_SUCCESS on success. Error code otherwise
MACRUM 0:276e7a263c35 338 static esfs_result_e esfs_cmac_read(esfs_file_t *file_handle, void *pbuf, size_t num_bytes, size_t *num_bytes_read)
MACRUM 0:276e7a263c35 339 {
MACRUM 0:276e7a263c35 340 palStatus_t res = pal_fsFread(&file_handle->file, pbuf, num_bytes, num_bytes_read);
MACRUM 0:276e7a263c35 341 if(res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 342 {
MACRUM 0:276e7a263c35 343 tr_err("esfs_cmac_read() - pal_fsFread failed with status = 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 344 return ESFS_ERROR;
MACRUM 0:276e7a263c35 345 }
MACRUM 0:276e7a263c35 346
MACRUM 0:276e7a263c35 347 // Update the CMAC only if there is a context. (It is allowed to read the file without calculating CMAC if
MACRUM 0:276e7a263c35 348 // it does not need to checked.)
MACRUM 0:276e7a263c35 349 if(file_handle->signature_ctx)
MACRUM 0:276e7a263c35 350 {
MACRUM 0:276e7a263c35 351 res = pal_CMACUpdate(file_handle->signature_ctx, pbuf, *num_bytes_read);
MACRUM 0:276e7a263c35 352 if(res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 353 {
MACRUM 0:276e7a263c35 354 tr_err("esfs_cmac_read() - pal_CMACUpdate failed with status = 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 355 return ESFS_ERROR;
MACRUM 0:276e7a263c35 356 }
MACRUM 0:276e7a263c35 357 }
MACRUM 0:276e7a263c35 358
MACRUM 0:276e7a263c35 359 return ESFS_SUCCESS;
MACRUM 0:276e7a263c35 360 }
MACRUM 0:276e7a263c35 361
MACRUM 0:276e7a263c35 362
MACRUM 0:276e7a263c35 363 // Helper function to skip past a part of the file while calculating the cmac on the skipped data.
MACRUM 0:276e7a263c35 364 // Updates the file position.
MACRUM 0:276e7a263c35 365 // Parameters :
MACRUM 0:276e7a263c35 366 // file_handle - [IN] A pointer to a file handle.
MACRUM 0:276e7a263c35 367 // to [IN] The absolute position from the start of the file to which skip.
MACRUM 0:276e7a263c35 368 // It must be greater than the current position and no longer that the file size.
MACRUM 0:276e7a263c35 369 // Return : ESFS_SUCCESS on success. Error code otherwise.
MACRUM 0:276e7a263c35 370 static esfs_result_e esfs_cmac_skip_to(esfs_file_t *file_handle, int32_t to)
MACRUM 0:276e7a263c35 371 {
MACRUM 0:276e7a263c35 372 // Get current position
MACRUM 0:276e7a263c35 373 int32_t current_pos;
MACRUM 0:276e7a263c35 374 palStatus_t res = pal_fsFtell(&file_handle->file, &current_pos);
MACRUM 0:276e7a263c35 375 if (res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 376 {
MACRUM 0:276e7a263c35 377 tr_err("esfs_cmac_skip_to() - pal_fsFtell() failed with pal_status = 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 378 return ESFS_ERROR;
MACRUM 0:276e7a263c35 379 }
MACRUM 0:276e7a263c35 380
MACRUM 0:276e7a263c35 381 // Iterate over the rest of file in chunks to calculate the cmac
MACRUM 0:276e7a263c35 382 // buffer will contain only data read form the file
MACRUM 0:276e7a263c35 383 for (int32_t i = to - current_pos; i > 0; i -= ESFS_READ_CHUNK_SIZE_IN_BYTES)
MACRUM 0:276e7a263c35 384 {
MACRUM 0:276e7a263c35 385 // Read a chunk
MACRUM 0:276e7a263c35 386 // Here we read the file as is - plain text or encrypted
MACRUM 0:276e7a263c35 387 uint8_t buffer[ESFS_READ_CHUNK_SIZE_IN_BYTES];
MACRUM 0:276e7a263c35 388 size_t num_bytes;
MACRUM 0:276e7a263c35 389 esfs_result_e res = esfs_cmac_read(file_handle, buffer, PAL_MIN(i, ESFS_READ_CHUNK_SIZE_IN_BYTES), &num_bytes);
MACRUM 0:276e7a263c35 390 if (res != ESFS_SUCCESS || num_bytes == 0)
MACRUM 0:276e7a263c35 391 {
MACRUM 0:276e7a263c35 392 tr_err("esfs_cmac_skip_to() failed num_bytes bytes = %zu", num_bytes);
MACRUM 0:276e7a263c35 393 return ESFS_ERROR;
MACRUM 0:276e7a263c35 394 }
MACRUM 0:276e7a263c35 395 }
MACRUM 0:276e7a263c35 396 return ESFS_SUCCESS;
MACRUM 0:276e7a263c35 397 }
MACRUM 0:276e7a263c35 398
MACRUM 0:276e7a263c35 399 // Helper function to terminate a cmac run and return the resulting cmac.
MACRUM 0:276e7a263c35 400 // Parameters :
MACRUM 0:276e7a263c35 401 // file_handle - [IN] A pointer to a file handle for which we calculate the cmac.
MACRUM 0:276e7a263c35 402 // pcmac [OUT] A pointer to a buffer into which the cmac will be written. It must be at least ESFS_CMAC_SIZE_IN_BYTES.
MACRUM 0:276e7a263c35 403 // Return : ESFS_SUCCESS on success. Error code otherwise
MACRUM 0:276e7a263c35 404 static esfs_result_e esfs_cmac_finish(esfs_file_t *file_handle, unsigned char *pcmac)
MACRUM 0:276e7a263c35 405 {
MACRUM 0:276e7a263c35 406 size_t num_bytes;
MACRUM 0:276e7a263c35 407
MACRUM 0:276e7a263c35 408 // Sets file_handle->signature_ctx to 0 on success
MACRUM 0:276e7a263c35 409 palStatus_t res = pal_CMACFinish(&file_handle->signature_ctx, pcmac, &num_bytes);
MACRUM 0:276e7a263c35 410 if(res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 411 {
MACRUM 0:276e7a263c35 412 tr_err("esfs_finish_cmac() - pal_CMACFinish() failed with pal_status = 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 413 return ESFS_ERROR;
MACRUM 0:276e7a263c35 414 }
MACRUM 0:276e7a263c35 415 return ESFS_SUCCESS;
MACRUM 0:276e7a263c35 416 }
MACRUM 0:276e7a263c35 417
MACRUM 0:276e7a263c35 418 // Helper function to compare the passed cmac against the one in the file and to the one in the file descriptor
MACRUM 0:276e7a263c35 419 // and then return the file position in the passed value.
MACRUM 0:276e7a263c35 420 // Updates the file position.
MACRUM 0:276e7a263c35 421 // Parameters :
MACRUM 0:276e7a263c35 422 // file_handle - [IN] A pointer to a file handle for which we check the cmac.
MACRUM 0:276e7a263c35 423 // pcmac [IN] A pointer to a buffer containing the cmac that will be compared. It must be at least ESFS_CMAC_SIZE_IN_BYTES.
MACRUM 0:276e7a263c35 424 // position [IN] The absolute position from the start of the file to which we restore the file position.
MACRUM 0:276e7a263c35 425 // Return : ESFS_SUCCESS on success. Error code otherwise.
MACRUM 0:276e7a263c35 426 static esfs_result_e esfs_cmac_check_and_restore(esfs_file_t *file_handle, unsigned char *pcmac, int32_t position)
MACRUM 0:276e7a263c35 427 {
MACRUM 0:276e7a263c35 428 // Read the signature from the file
MACRUM 0:276e7a263c35 429 unsigned char file_cmac[ESFS_CMAC_SIZE_IN_BYTES];
MACRUM 0:276e7a263c35 430 size_t num_bytes;
MACRUM 0:276e7a263c35 431 palStatus_t res = pal_fsFread(&file_handle->file, &file_cmac[0], ESFS_CMAC_SIZE_IN_BYTES, &num_bytes);
MACRUM 0:276e7a263c35 432 if (res != PAL_SUCCESS || num_bytes != ESFS_CMAC_SIZE_IN_BYTES)
MACRUM 0:276e7a263c35 433 {
MACRUM 0:276e7a263c35 434 tr_err("esfs_cmac_check_and_restore() - pal_fsFread() failed with pal result = 0x%x and num_bytes bytes = %zu", (unsigned int)res, num_bytes);
MACRUM 0:276e7a263c35 435 return ESFS_ERROR;
MACRUM 0:276e7a263c35 436 }
MACRUM 0:276e7a263c35 437 // Compare the cmac that we read from the file with the one that is passed and check it against
MACRUM 0:276e7a263c35 438 // the one recorded in esfs_open in order to verify that the file is the same as the one that was opened.
MACRUM 0:276e7a263c35 439 if(memcmp(&file_cmac[0], pcmac, ESFS_CMAC_SIZE_IN_BYTES) != 0 ||
MACRUM 0:276e7a263c35 440 memcmp(&file_cmac[0], &file_handle->cmac[0], ESFS_CMAC_SIZE_IN_BYTES) != 0)
MACRUM 0:276e7a263c35 441 {
MACRUM 0:276e7a263c35 442 tr_err("esfs_cmac_check_and_restore() - cmac that we read from the file does not match the one that we calculated");
MACRUM 0:276e7a263c35 443 return ESFS_CMAC_DOES_NOT_MATCH;
MACRUM 0:276e7a263c35 444 }
MACRUM 0:276e7a263c35 445
MACRUM 0:276e7a263c35 446 // Set the file position to the byte indicated by position.
MACRUM 0:276e7a263c35 447 res = pal_fsFseek(&file_handle->file, position, PAL_FS_OFFSET_SEEKSET);
MACRUM 0:276e7a263c35 448 if(res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 449 {
MACRUM 0:276e7a263c35 450 tr_err("esfs_cmac_check_and_restore() - pal_fsFseek() failed with pal status 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 451 return ESFS_ERROR;
MACRUM 0:276e7a263c35 452 }
MACRUM 0:276e7a263c35 453
MACRUM 0:276e7a263c35 454 return ESFS_SUCCESS;
MACRUM 0:276e7a263c35 455 }
MACRUM 0:276e7a263c35 456
MACRUM 0:276e7a263c35 457 //Function : esfs_memcpy_reverse
MACRUM 0:276e7a263c35 458 //
MACRUM 0:276e7a263c35 459 //Description: This function copies the first <len_bytes> bytes from input buffer <src_ptr> to output buffer <dest_ptr> in
MACRUM 0:276e7a263c35 460 // reversed order (e.g. '1' '2' '3' data array will be copied as '3' '2' '1').
MACRUM 0:276e7a263c35 461 // Note: The function assumes that the memory areas of the input buffers src_ptr and dest_ptr do not overlap.
MACRUM 0:276e7a263c35 462 //
MACRUM 0:276e7a263c35 463 //Parameters : dest_ptr - [IN / OUT] A pointer to the destination buffer to which bytes will be copied.
MACRUM 0:276e7a263c35 464 // src_ptr - [IN] A pointer to the source buffer from which bytes will be copied.
MACRUM 0:276e7a263c35 465 // len_bytes - [IN] Number of bytes to be copied.
MACRUM 0:276e7a263c35 466 //
MACRUM 0:276e7a263c35 467 //Return : A pointer to the output buffer <dest_ptr>
MACRUM 0:276e7a263c35 468 static void *esfs_memcpy_reverse(void *dest_ptr, const void *src_ptr, uint32_t len_bytes)
MACRUM 0:276e7a263c35 469 {
MACRUM 0:276e7a263c35 470 uint8_t *tmp_dest_ptr = (uint8_t *)dest_ptr;
MACRUM 0:276e7a263c35 471 const uint8_t *tmp_src_ptr = (const uint8_t *)src_ptr;
MACRUM 0:276e7a263c35 472
MACRUM 0:276e7a263c35 473
MACRUM 0:276e7a263c35 474 // Make the reverse copy
MACRUM 0:276e7a263c35 475 while(len_bytes > 0)
MACRUM 0:276e7a263c35 476 {
MACRUM 0:276e7a263c35 477 *(tmp_dest_ptr++) = *(tmp_src_ptr + len_bytes - 1);
MACRUM 0:276e7a263c35 478 len_bytes--;
MACRUM 0:276e7a263c35 479 }
MACRUM 0:276e7a263c35 480
MACRUM 0:276e7a263c35 481 return dest_ptr;
MACRUM 0:276e7a263c35 482 }
MACRUM 0:276e7a263c35 483
MACRUM 0:276e7a263c35 484 //Function : esfs_calc_file_pos_for_aes
MACRUM 0:276e7a263c35 485 //
MACRUM 0:276e7a263c35 486 //Description: This function calculates the file position for the purpose of AES encrypt / decrypt:
MACRUM 0:276e7a263c35 487 // The returned position is relative to the beginning of the encrypted data.
MACRUM 0:276e7a263c35 488 // The file is encrypted starting from the meta data part (the meta data values).
MACRUM 0:276e7a263c35 489 //
MACRUM 0:276e7a263c35 490 //Parameters : file_handle - [IN] A pointer to a file handle on which we calculate the position.
MACRUM 0:276e7a263c35 491 // position - [OUT] A pointer to size_t to be filled in with the returned position.
MACRUM 0:276e7a263c35 492 //
MACRUM 0:276e7a263c35 493 //Return : ESFS_SUCCESS on success. Error code otherwise
MACRUM 0:276e7a263c35 494 static esfs_result_e esfs_calc_file_pos_for_aes(esfs_file_t *file_handle, size_t *position)
MACRUM 0:276e7a263c35 495 {
MACRUM 0:276e7a263c35 496 palStatus_t pal_status = PAL_SUCCESS;
MACRUM 0:276e7a263c35 497
MACRUM 0:276e7a263c35 498 size_t non_encrypt_size = 0;
MACRUM 0:276e7a263c35 499
MACRUM 0:276e7a263c35 500
MACRUM 0:276e7a263c35 501 *position = 0;
MACRUM 0:276e7a263c35 502
MACRUM 0:276e7a263c35 503 // Get current position inside the file
MACRUM 0:276e7a263c35 504 pal_status = pal_fsFtell( &(file_handle->file), (int32_t *)position );
MACRUM 0:276e7a263c35 505
MACRUM 0:276e7a263c35 506 if(pal_status != PAL_SUCCESS)
MACRUM 0:276e7a263c35 507 {
MACRUM 0:276e7a263c35 508 tr_err("esfs_calc_file_pos_for_aes() - pal_fsFtell() failed with pal_status = 0x%x", (unsigned int)pal_status);
MACRUM 0:276e7a263c35 509 return ESFS_ERROR;
MACRUM 0:276e7a263c35 510 }
MACRUM 0:276e7a263c35 511
MACRUM 0:276e7a263c35 512 // Calculate non_encrypt_size to be subtracted from position
MACRUM 0:276e7a263c35 513 non_encrypt_size = esfs_not_encrypted_file_header_size(file_handle);
MACRUM 0:276e7a263c35 514
MACRUM 0:276e7a263c35 515 if(*position < non_encrypt_size)
MACRUM 0:276e7a263c35 516 {
MACRUM 0:276e7a263c35 517 tr_err("esfs_calc_file_pos_for_aes() - Error. Position is in non encrypted part.");
MACRUM 0:276e7a263c35 518 return ESFS_ERROR;
MACRUM 0:276e7a263c35 519 }
MACRUM 0:276e7a263c35 520
MACRUM 0:276e7a263c35 521
MACRUM 0:276e7a263c35 522 *position -= non_encrypt_size;
MACRUM 0:276e7a263c35 523
MACRUM 0:276e7a263c35 524
MACRUM 0:276e7a263c35 525 return ESFS_SUCCESS;
MACRUM 0:276e7a263c35 526 }
MACRUM 0:276e7a263c35 527
MACRUM 0:276e7a263c35 528
MACRUM 0:276e7a263c35 529 //Function : esfs_set_counter_in_iv_by_file_pos
MACRUM 0:276e7a263c35 530 //
MACRUM 0:276e7a263c35 531 //Description: This function fills in the last 8 bytes of the IV [iv128_arr] with the counter calculated according to
MACRUM 0:276e7a263c35 532 // the input position.
MACRUM 0:276e7a263c35 533 //
MACRUM 0:276e7a263c35 534 //Parameters : position - [IN] The position in the file when count starts from the encrypted data part (the meta data values).
MACRUM 0:276e7a263c35 535 // iv128_arr - [IN/OUT] A 16 bytes buffer holding the IV.
MACRUM 0:276e7a263c35 536 // First 8 bytes contain the NONCE, and last 8 bytes will be filled in with the counter.
MACRUM 0:276e7a263c35 537 //
MACRUM 0:276e7a263c35 538 //Return : ESFS_SUCCESS on success. Error code otherwise
MACRUM 0:276e7a263c35 539 static void esfs_set_counter_in_iv_by_file_pos(size_t position, uint8_t *iv128_arr)
MACRUM 0:276e7a263c35 540 {
MACRUM 0:276e7a263c35 541 uint64_t counter = 0;
MACRUM 0:276e7a263c35 542
MACRUM 0:276e7a263c35 543
MACRUM 0:276e7a263c35 544 // Calculate counter part of IV
MACRUM 0:276e7a263c35 545 counter = (uint64_t)(position / ESFS_AES_BLOCK_SIZE_BYTES);
MACRUM 0:276e7a263c35 546
MACRUM 0:276e7a263c35 547
MACRUM 0:276e7a263c35 548 // Copy the counter part to the IV
MACRUM 0:276e7a263c35 549 #if BIG__ENDIAN == 1
MACRUM 0:276e7a263c35 550 memcpy(iv128_arr + ESFS_AES_COUNTER_INDEX_IN_IV, &counter, ESFS_AES_COUNTER_SIZE_BYTES);
MACRUM 0:276e7a263c35 551 #else
MACRUM 0:276e7a263c35 552 esfs_memcpy_reverse(iv128_arr + ESFS_AES_COUNTER_INDEX_IN_IV, &counter, ESFS_AES_COUNTER_SIZE_BYTES);
MACRUM 0:276e7a263c35 553 #endif
MACRUM 0:276e7a263c35 554 }
MACRUM 0:276e7a263c35 555
MACRUM 0:276e7a263c35 556
MACRUM 0:276e7a263c35 557 //Function : esfs_aes_enc_dec_by_file_pos
MACRUM 0:276e7a263c35 558 //
MACRUM 0:276e7a263c35 559 //Description: This function encrypts / decrypts data using AES-CTR.
MACRUM 0:276e7a263c35 560 // This is the basic function used for AES encrypt / decrypt.
MACRUM 0:276e7a263c35 561 // Due to the nature of AES-CTR which works on blocks, special handling is required in case the data in the file is not
MACRUM 0:276e7a263c35 562 // on block boundaries. In this case we encrypt / decrypt this "partial block data" in a temporal buffer after copying
MACRUM 0:276e7a263c35 563 // the data to the corresponding index inside this buffer. The rest of the data is being encrypted / decrypted normally.
MACRUM 0:276e7a263c35 564 //
MACRUM 0:276e7a263c35 565 //Parameters : aes_ctx - [IN] The per-initiated AES context.
MACRUM 0:276e7a263c35 566 // buf_in - [IN] A buffer containing to data to be encrypted / decrypted.
MACRUM 0:276e7a263c35 567 // buf_out - [OUT] A buffer to be filled in with the encrypted / decrypted data.
MACRUM 0:276e7a263c35 568 // len_bytes - [IN] Number of bytes to encrypt / decrypt.
MACRUM 0:276e7a263c35 569 // position - [IN] The position in the file when count starts from the encrypted data part (the meta data values).
MACRUM 0:276e7a263c35 570 // nonce64_ptr - [IN] An 8 bytes buffer holding the NONCE part of the IV.
MACRUM 0:276e7a263c35 571 //
MACRUM 0:276e7a263c35 572 //Return : ESFS_SUCCESS on success. Error code otherwise
MACRUM 0:276e7a263c35 573 static esfs_result_e esfs_aes_enc_dec_by_file_pos( palAesHandle_t aes_ctx,
MACRUM 0:276e7a263c35 574 const uint8_t *buf_in,
MACRUM 0:276e7a263c35 575 uint8_t *buf_out,
MACRUM 0:276e7a263c35 576 size_t len_bytes,
MACRUM 0:276e7a263c35 577 size_t position,
MACRUM 0:276e7a263c35 578 uint8_t *nonce64_ptr
MACRUM 0:276e7a263c35 579 )
MACRUM 0:276e7a263c35 580 {
MACRUM 0:276e7a263c35 581 palStatus_t pal_status = PAL_SUCCESS;
MACRUM 0:276e7a263c35 582
MACRUM 0:276e7a263c35 583 uint8_t prev_remainder = 0; // Size in bytes of partial block PREVIOUSLY encrypted / decrypted
MACRUM 0:276e7a263c35 584 uint8_t partial_block_size = 0; // Size in bytes of partial block for NEXT encrypt / decrypt
MACRUM 0:276e7a263c35 585
MACRUM 0:276e7a263c35 586 uint8_t partial_block_size_temp = 0;
MACRUM 0:276e7a263c35 587
MACRUM 0:276e7a263c35 588 uint8_t partial_block_in[ESFS_AES_BLOCK_SIZE_BYTES] = {0}; // Will contain data for next partial encrypt / decrypt
MACRUM 0:276e7a263c35 589 uint8_t partial_block_out[ESFS_AES_BLOCK_SIZE_BYTES] = {0};
MACRUM 0:276e7a263c35 590
MACRUM 0:276e7a263c35 591 uint8_t iv_arr[ESFS_AES_IV_SIZE_BYTES] = {0}; // Will contain nonce [bytes 0 - 7] and counter [bytes 8 - 15]
MACRUM 0:276e7a263c35 592
MACRUM 0:276e7a263c35 593
MACRUM 0:276e7a263c35 594 // -------- partial_block_in: Size = block_size [16 bytes]
MACRUM 0:276e7a263c35 595 // |
MACRUM 0:276e7a263c35 596 // |
MACRUM 0:276e7a263c35 597 // \|/
MACRUM 0:276e7a263c35 598 //
MACRUM 0:276e7a263c35 599 // -----------------------------------------------------------------------------------------
MACRUM 0:276e7a263c35 600 // | | | |
MACRUM 0:276e7a263c35 601 // | 0 ... 0 | Data copied form buf_in | 0 ... 0 |
MACRUM 0:276e7a263c35 602 // | | | |
MACRUM 0:276e7a263c35 603 // -----------------------------------------------------------------------------------------
MACRUM 0:276e7a263c35 604 // ^ ^ ^
MACRUM 0:276e7a263c35 605 // | | |
MACRUM 0:276e7a263c35 606 // | | |
MACRUM 0:276e7a263c35 607 // | | |
MACRUM 0:276e7a263c35 608 // Size: prev_remainder | Size: might be 0
MACRUM 0:276e7a263c35 609 // |
MACRUM 0:276e7a263c35 610 // |
MACRUM 0:276e7a263c35 611 // Size: partial_block_size
MACRUM 0:276e7a263c35 612 // (might consume the buffer till its end)
MACRUM 0:276e7a263c35 613
MACRUM 0:276e7a263c35 614
MACRUM 0:276e7a263c35 615 prev_remainder = (position % ESFS_AES_BLOCK_SIZE_BYTES);
MACRUM 0:276e7a263c35 616
MACRUM 0:276e7a263c35 617 partial_block_size_temp = ESFS_AES_BLOCK_SIZE_BYTES - prev_remainder;
MACRUM 0:276e7a263c35 618 partial_block_size = PAL_MIN(partial_block_size_temp, len_bytes);
MACRUM 0:276e7a263c35 619
MACRUM 0:276e7a263c35 620 // Prepare partial_block_in: Copy data for next encrypt / decrypt from buf_in to partial_block_in
MACRUM 0:276e7a263c35 621 memcpy(partial_block_in + prev_remainder, buf_in, partial_block_size);
MACRUM 0:276e7a263c35 622
MACRUM 0:276e7a263c35 623 // Prepare iv_arr: Copy nonce into bytes [0 - 7] of IV buffer
MACRUM 0:276e7a263c35 624 memcpy(iv_arr, nonce64_ptr, ESFS_AES_NONCE_SIZE_BYTES);
MACRUM 0:276e7a263c35 625
MACRUM 0:276e7a263c35 626 // Prepare iv_arr: Set counter in bytes [8 - 15] of IV buffer
MACRUM 0:276e7a263c35 627 esfs_set_counter_in_iv_by_file_pos(position, iv_arr);
MACRUM 0:276e7a263c35 628
MACRUM 0:276e7a263c35 629
MACRUM 0:276e7a263c35 630 // Encrypt / decrypt partial block [run on entire block, and copy later only desired part)
MACRUM 0:276e7a263c35 631 pal_status = pal_aesCTRWithZeroOffset(aes_ctx, partial_block_in, partial_block_out, ESFS_AES_BLOCK_SIZE_BYTES, iv_arr);
MACRUM 0:276e7a263c35 632
MACRUM 0:276e7a263c35 633 if(pal_status != PAL_SUCCESS)
MACRUM 0:276e7a263c35 634 {
MACRUM 0:276e7a263c35 635 tr_err("esfs_aes_enc_dec_by_file_pos() - pal_aesCTRWithZeroOffset() failed with pal_status = 0x%x", (unsigned int)pal_status);
MACRUM 0:276e7a263c35 636 return ESFS_ERROR;
MACRUM 0:276e7a263c35 637 }
MACRUM 0:276e7a263c35 638
MACRUM 0:276e7a263c35 639 // Copy partial_block_out to buf_out
MACRUM 0:276e7a263c35 640 memcpy(buf_out, partial_block_out + prev_remainder, partial_block_size);
MACRUM 0:276e7a263c35 641
MACRUM 0:276e7a263c35 642
MACRUM 0:276e7a263c35 643 // Encrypt / decrypt the rest of the data
MACRUM 0:276e7a263c35 644 if(len_bytes > partial_block_size)
MACRUM 0:276e7a263c35 645 {
MACRUM 0:276e7a263c35 646 // Set updated counter in bytes [8 - 15] of IV buffer
MACRUM 0:276e7a263c35 647 esfs_set_counter_in_iv_by_file_pos(position + partial_block_size, iv_arr);
MACRUM 0:276e7a263c35 648
MACRUM 0:276e7a263c35 649 pal_status = pal_aesCTRWithZeroOffset(aes_ctx, buf_in + partial_block_size, buf_out + partial_block_size, len_bytes - partial_block_size, iv_arr);
MACRUM 0:276e7a263c35 650
MACRUM 0:276e7a263c35 651 if(pal_status != PAL_SUCCESS)
MACRUM 0:276e7a263c35 652 {
MACRUM 0:276e7a263c35 653 tr_err("esfs_aes_enc_dec_by_file_pos() - pal_aesCTRWithZeroOffset() failed with pal_status = 0x%x", (unsigned int)pal_status);
MACRUM 0:276e7a263c35 654 return ESFS_ERROR;
MACRUM 0:276e7a263c35 655 }
MACRUM 0:276e7a263c35 656 }
MACRUM 0:276e7a263c35 657
MACRUM 0:276e7a263c35 658
MACRUM 0:276e7a263c35 659 return ESFS_SUCCESS;
MACRUM 0:276e7a263c35 660 }
MACRUM 0:276e7a263c35 661
MACRUM 0:276e7a263c35 662
MACRUM 0:276e7a263c35 663 //Function : esfs_read_and_decrypt
MACRUM 0:276e7a263c35 664 //
MACRUM 0:276e7a263c35 665 //Description: This function reads encrypted data from a file, decrypts it, and writes it into a buffer.
MACRUM 0:276e7a263c35 666 //
MACRUM 0:276e7a263c35 667 //Parameters : file_handle - [IN] A pointer to a file handle from which we read data.
MACRUM 0:276e7a263c35 668 // buffer - [IN] The buffer to fill in with decrypted file data.
MACRUM 0:276e7a263c35 669 // bytes_to_read - [IN] Number of bytes to read from the file.
MACRUM 0:276e7a263c35 670 // read_bytes_ptr - [OUT] A pointer to size_t to be filled in with number of bytes actually read from the file.
MACRUM 0:276e7a263c35 671 //
MACRUM 0:276e7a263c35 672 //Return : ESFS_SUCCESS on success. Error code otherwise
MACRUM 0:276e7a263c35 673 static esfs_result_e esfs_read_and_decrypt(esfs_file_t *file_handle, void *buffer, size_t bytes_to_read, size_t *read_bytes_ptr)
MACRUM 0:276e7a263c35 674 {
MACRUM 0:276e7a263c35 675 esfs_result_e result = ESFS_SUCCESS;
MACRUM 0:276e7a263c35 676
MACRUM 0:276e7a263c35 677 size_t position = 0;
MACRUM 0:276e7a263c35 678
MACRUM 0:276e7a263c35 679
MACRUM 0:276e7a263c35 680 // Get file pointer position for AES - Must be done before calling pal_fsFread() which modifies the file pointer position
MACRUM 0:276e7a263c35 681 result = esfs_calc_file_pos_for_aes(file_handle, &position);
MACRUM 0:276e7a263c35 682
MACRUM 0:276e7a263c35 683 if(result != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 684 {
MACRUM 0:276e7a263c35 685 tr_err("esfs_read_and_decrypt() - esfs_calc_file_pos_for_aes() failed with status = 0x%x", result);
MACRUM 0:276e7a263c35 686 return result;
MACRUM 0:276e7a263c35 687 }
MACRUM 0:276e7a263c35 688
MACRUM 0:276e7a263c35 689
MACRUM 0:276e7a263c35 690 // Read file's encrypted data into buffer
MACRUM 0:276e7a263c35 691 result = esfs_cmac_read(file_handle, buffer, bytes_to_read, read_bytes_ptr );
MACRUM 0:276e7a263c35 692
MACRUM 0:276e7a263c35 693 if((result != ESFS_SUCCESS) || (*read_bytes_ptr != bytes_to_read))
MACRUM 0:276e7a263c35 694 {
MACRUM 0:276e7a263c35 695 tr_err("esfs_read_and_decrypt() - esfs_cmac_read() failed with ESFS_status = 0x%x", (unsigned int)result);
MACRUM 0:276e7a263c35 696 return ESFS_ERROR;
MACRUM 0:276e7a263c35 697 }
MACRUM 0:276e7a263c35 698
MACRUM 0:276e7a263c35 699
MACRUM 0:276e7a263c35 700 // AES decrypt in-place - decrypt the encrypted data inside buffer, into buffer [out parameter]
MACRUM 0:276e7a263c35 701 result = esfs_aes_enc_dec_by_file_pos(file_handle->aes_ctx, buffer, buffer, bytes_to_read, position, file_handle->nonce);
MACRUM 0:276e7a263c35 702
MACRUM 0:276e7a263c35 703 if(result != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 704 {
MACRUM 0:276e7a263c35 705 tr_err("esfs_read_and_decrypt() - esfs_aes_enc_dec_by_file_pos() failed with status = 0x%x", (unsigned int)result);
MACRUM 0:276e7a263c35 706 return result;
MACRUM 0:276e7a263c35 707 }
MACRUM 0:276e7a263c35 708
MACRUM 0:276e7a263c35 709
MACRUM 0:276e7a263c35 710 return ESFS_SUCCESS;
MACRUM 0:276e7a263c35 711 }
MACRUM 0:276e7a263c35 712
MACRUM 0:276e7a263c35 713
MACRUM 0:276e7a263c35 714 //Function : esfs_encrypt_fwrite_and_calc_cmac
MACRUM 0:276e7a263c35 715 //
MACRUM 0:276e7a263c35 716 //Description: This function takes a plain text buffer, encrypts it, writes the encrypted data to a file, and updates the
MACRUM 0:276e7a263c35 717 // CMAC signature.
MACRUM 0:276e7a263c35 718 //
MACRUM 0:276e7a263c35 719 // Since we cannot modify the data of the input buffer (const), this operation cannot be done in-place, so we need
MACRUM 0:276e7a263c35 720 // to use another buffer for the encryption result. In order to avoid dynamically allocation, we use a buffer
MACRUM 0:276e7a263c35 721 // of size ESFS_AES_BUF_SIZE_BYTES statically allocated on the stack. This forces us to encrypt and write in a loop -
MACRUM 0:276e7a263c35 722 // each iteration encrypts and writes maximum size of ESFS_AES_BUF_SIZE_BYTES bytes.
MACRUM 0:276e7a263c35 723 //
MACRUM 0:276e7a263c35 724 //Parameters : buffer - [IN] The buffer to encrypt and write to the file.
MACRUM 0:276e7a263c35 725 // bytes_to_write - [IN] The number of bytes to write.
MACRUM 0:276e7a263c35 726 // file_handle - [IN] A pointer to a file handle to which we write the data.
MACRUM 0:276e7a263c35 727 //
MACRUM 0:276e7a263c35 728 //Return : ESFS_SUCCESS on success. Error code otherwise
MACRUM 0:276e7a263c35 729 static esfs_result_e esfs_encrypt_fwrite_and_calc_cmac(const void *buffer, size_t bytes_to_write, esfs_file_t *file_handle)
MACRUM 0:276e7a263c35 730 {
MACRUM 0:276e7a263c35 731 esfs_result_e result = ESFS_SUCCESS;
MACRUM 0:276e7a263c35 732
MACRUM 0:276e7a263c35 733 size_t position = 0;
MACRUM 0:276e7a263c35 734 size_t remaining_bytes_to_write = bytes_to_write;
MACRUM 0:276e7a263c35 735
MACRUM 0:276e7a263c35 736 const uint8_t *buffer_tmp_ptr = (uint8_t *)buffer; // Will point to the next reading point in buffer as we read it
MACRUM 0:276e7a263c35 737
MACRUM 0:276e7a263c35 738 uint8_t encrypted_data[ESFS_AES_BUF_SIZE_BYTES] = {0}; // Will hold encrypted data to be written to the file
MACRUM 0:276e7a263c35 739
MACRUM 0:276e7a263c35 740
MACRUM 0:276e7a263c35 741 if(buffer == NULL)
MACRUM 0:276e7a263c35 742 {
MACRUM 0:276e7a263c35 743 tr_err("esfs_encrypt_fwrite_and_calc_cmac() - Bad arguments error. Input buffer is NULL.");
MACRUM 0:276e7a263c35 744 return ESFS_ERROR;
MACRUM 0:276e7a263c35 745 }
MACRUM 0:276e7a263c35 746
MACRUM 0:276e7a263c35 747
MACRUM 0:276e7a263c35 748 // Get file pointer position for AES - Must be done before calling esfs_fwrite_and_calc_cmac() which modifies the file pointer position
MACRUM 0:276e7a263c35 749 result = esfs_calc_file_pos_for_aes(file_handle, &position);
MACRUM 0:276e7a263c35 750
MACRUM 0:276e7a263c35 751 if(result != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 752 {
MACRUM 0:276e7a263c35 753 tr_err("esfs_encrypt_fwrite_and_calc_cmac() - esfs_calc_file_pos_for_aes failed with result=0x%x", result);
MACRUM 0:276e7a263c35 754 return result;
MACRUM 0:276e7a263c35 755 }
MACRUM 0:276e7a263c35 756
MACRUM 0:276e7a263c35 757
MACRUM 0:276e7a263c35 758 // On every iteration in the loop, encrypt ESFS_AES_BUF_SIZE_BYTES bytes, and write them to the file
MACRUM 0:276e7a263c35 759 while(remaining_bytes_to_write >= ESFS_AES_BUF_SIZE_BYTES)
MACRUM 0:276e7a263c35 760 {
MACRUM 0:276e7a263c35 761 // AES encrypt into encrypted_data
MACRUM 0:276e7a263c35 762 result = esfs_aes_enc_dec_by_file_pos(file_handle->aes_ctx, buffer_tmp_ptr, encrypted_data, ESFS_AES_BUF_SIZE_BYTES, position, file_handle->nonce);
MACRUM 0:276e7a263c35 763
MACRUM 0:276e7a263c35 764 if(result != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 765 {
MACRUM 0:276e7a263c35 766 tr_err("esfs_encrypt_fwrite_and_calc_cmac() - esfs_aes_enc_dec_by_file_pos failed with result=0x%x", result);
MACRUM 0:276e7a263c35 767 return result;
MACRUM 0:276e7a263c35 768 }
MACRUM 0:276e7a263c35 769
MACRUM 0:276e7a263c35 770 // Write the encrypted data to the file
MACRUM 0:276e7a263c35 771 result = esfs_fwrite_and_calc_cmac(encrypted_data, ESFS_AES_BUF_SIZE_BYTES, file_handle);
MACRUM 0:276e7a263c35 772
MACRUM 0:276e7a263c35 773 if((result != ESFS_SUCCESS))
MACRUM 0:276e7a263c35 774 {
MACRUM 0:276e7a263c35 775 tr_err("esfs_encrypt_fwrite_and_calc_cmac() - esfs_fwrite_and_calc_cmac() status = 0x%x", (unsigned int)result);
MACRUM 0:276e7a263c35 776
MACRUM 0:276e7a263c35 777 // esfs_fwrite_and_calc_cmac() failed so we cannot be sure of the state of the file - mark the file as invalid
MACRUM 0:276e7a263c35 778 file_handle->file_invalid = 1;
MACRUM 0:276e7a263c35 779
MACRUM 0:276e7a263c35 780 return ESFS_ERROR;
MACRUM 0:276e7a263c35 781 }
MACRUM 0:276e7a263c35 782
MACRUM 0:276e7a263c35 783 position += ESFS_AES_BUF_SIZE_BYTES;
MACRUM 0:276e7a263c35 784 buffer_tmp_ptr += ESFS_AES_BUF_SIZE_BYTES;
MACRUM 0:276e7a263c35 785
MACRUM 0:276e7a263c35 786 remaining_bytes_to_write -= ESFS_AES_BUF_SIZE_BYTES;
MACRUM 0:276e7a263c35 787 }
MACRUM 0:276e7a263c35 788
MACRUM 0:276e7a263c35 789
MACRUM 0:276e7a263c35 790 // AES encrypt the leftover of buffer
MACRUM 0:276e7a263c35 791 if(remaining_bytes_to_write > 0)
MACRUM 0:276e7a263c35 792 {
MACRUM 0:276e7a263c35 793 // AES encrypt into encrypted_data
MACRUM 0:276e7a263c35 794 result = esfs_aes_enc_dec_by_file_pos(file_handle->aes_ctx, buffer_tmp_ptr, encrypted_data, remaining_bytes_to_write, position, file_handle->nonce);
MACRUM 0:276e7a263c35 795
MACRUM 0:276e7a263c35 796 if(result != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 797 {
MACRUM 0:276e7a263c35 798 tr_err("esfs_encrypt_fwrite_and_calc_cmac() - esfs_aes_enc_dec_by_file_pos failed with result=0x%x", result);
MACRUM 0:276e7a263c35 799 return result;
MACRUM 0:276e7a263c35 800 }
MACRUM 0:276e7a263c35 801
MACRUM 0:276e7a263c35 802
MACRUM 0:276e7a263c35 803 // Write the encrypted data to the file
MACRUM 0:276e7a263c35 804 result = esfs_fwrite_and_calc_cmac(encrypted_data, remaining_bytes_to_write, file_handle);
MACRUM 0:276e7a263c35 805
MACRUM 0:276e7a263c35 806 if((result != ESFS_SUCCESS))
MACRUM 0:276e7a263c35 807 {
MACRUM 0:276e7a263c35 808 tr_err("esfs_encrypt_fwrite_and_calc_cmac() - esfs_fwrite_and_calc_cmac() status = 0x%x", (unsigned int)result);
MACRUM 0:276e7a263c35 809
MACRUM 0:276e7a263c35 810 // esfs_fwrite_and_calc_cmac() failed so we cannot be sure of the state of the file - mark the file as invalid
MACRUM 0:276e7a263c35 811 file_handle->file_invalid = 1;
MACRUM 0:276e7a263c35 812
MACRUM 0:276e7a263c35 813 return ESFS_ERROR;
MACRUM 0:276e7a263c35 814 }
MACRUM 0:276e7a263c35 815 }
MACRUM 0:276e7a263c35 816
MACRUM 0:276e7a263c35 817
MACRUM 0:276e7a263c35 818 return ESFS_SUCCESS;
MACRUM 0:276e7a263c35 819 }
MACRUM 0:276e7a263c35 820
MACRUM 0:276e7a263c35 821
MACRUM 0:276e7a263c35 822 esfs_result_e esfs_reset(void)
MACRUM 0:276e7a263c35 823 {
MACRUM 0:276e7a263c35 824 esfs_result_e result = ESFS_SUCCESS;
MACRUM 0:276e7a263c35 825 palStatus_t pal_result = PAL_SUCCESS;
MACRUM 0:276e7a263c35 826 char dir_path[MAX_FULL_PATH_SIZE] = { 0 };
MACRUM 0:276e7a263c35 827 tr_info("esfs_reset - enter");
MACRUM 0:276e7a263c35 828 pal_result = pal_fsGetMountPoint(PAL_FS_PARTITION_PRIMARY, PAL_MAX_FOLDER_DEPTH_CHAR + 1, dir_path);
MACRUM 0:276e7a263c35 829 if (pal_result != PAL_SUCCESS)
MACRUM 0:276e7a263c35 830 {
MACRUM 0:276e7a263c35 831 tr_err("esfs_reset() - pal_fsGetMountPoint() for working directory failed with pal_status = 0x%x", (unsigned int)pal_result);
MACRUM 0:276e7a263c35 832 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 833 goto errorExit;
MACRUM 0:276e7a263c35 834 }
MACRUM 0:276e7a263c35 835
MACRUM 0:276e7a263c35 836 strncat(dir_path, "/" ESFS_WORKING_DIRECTORY, sizeof(ESFS_WORKING_DIRECTORY));
MACRUM 0:276e7a263c35 837
MACRUM 0:276e7a263c35 838
MACRUM 0:276e7a263c35 839 // delete the files in working dir
MACRUM 0:276e7a263c35 840 pal_result = pal_fsRmFiles(dir_path);
MACRUM 0:276e7a263c35 841 // the use case is that esfs folder may not exist
MACRUM 0:276e7a263c35 842 if ((pal_result != PAL_SUCCESS) && (pal_result != PAL_ERR_FS_NO_FILE) && (pal_result != PAL_ERR_FS_NO_PATH))
MACRUM 0:276e7a263c35 843 {
MACRUM 0:276e7a263c35 844 tr_err("esfs_reset() - pal_fsRmFiles(ESFS_WORKING_DIRECTORY) failed with pal_status = 0x%x", (unsigned int)pal_result);
MACRUM 0:276e7a263c35 845 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 846 goto errorExit;
MACRUM 0:276e7a263c35 847 }
MACRUM 0:276e7a263c35 848
MACRUM 0:276e7a263c35 849 // delete working directory
MACRUM 0:276e7a263c35 850 pal_result = pal_fsRmDir(dir_path);
MACRUM 0:276e7a263c35 851 if (pal_result != PAL_SUCCESS)
MACRUM 0:276e7a263c35 852 {
MACRUM 0:276e7a263c35 853 // Any error apart from dir not exist returns error.
MACRUM 0:276e7a263c35 854 if ((pal_result != PAL_ERR_FS_NO_FILE) && (pal_result != PAL_ERR_FS_NO_PATH))
MACRUM 0:276e7a263c35 855 {
MACRUM 0:276e7a263c35 856 tr_err("esfs_reset() - pal_fsRmDir(ESFS_WORKING_DIRECTORY) failed with pal_status = 0x%x", (unsigned int)pal_result);
MACRUM 0:276e7a263c35 857 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 858 goto errorExit;
MACRUM 0:276e7a263c35 859 }
MACRUM 0:276e7a263c35 860 }
MACRUM 0:276e7a263c35 861
MACRUM 0:276e7a263c35 862 pal_result = pal_fsGetMountPoint(PAL_FS_PARTITION_SECONDARY, PAL_MAX_FOLDER_DEPTH_CHAR + 1, dir_path);
MACRUM 0:276e7a263c35 863 if (pal_result != PAL_SUCCESS)
MACRUM 0:276e7a263c35 864 {
MACRUM 0:276e7a263c35 865
MACRUM 0:276e7a263c35 866 tr_err("esfs_reset() - pal_fsGetMountPoint() for backup directory failed with pal_status = 0x%x", (unsigned int)pal_result);
MACRUM 0:276e7a263c35 867 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 868 goto errorExit;
MACRUM 0:276e7a263c35 869 }
MACRUM 0:276e7a263c35 870
MACRUM 0:276e7a263c35 871 strncat(dir_path, "/" ESFS_BACKUP_DIRECTORY, sizeof(ESFS_BACKUP_DIRECTORY));
MACRUM 0:276e7a263c35 872
MACRUM 0:276e7a263c35 873
MACRUM 0:276e7a263c35 874 // delete the files in backup dir
MACRUM 0:276e7a263c35 875 pal_result = pal_fsRmFiles(dir_path);
MACRUM 0:276e7a263c35 876 // the use case is that esfs folder may not exist
MACRUM 0:276e7a263c35 877 if ((pal_result != PAL_SUCCESS) && (pal_result != PAL_ERR_FS_NO_FILE) && (pal_result != PAL_ERR_FS_NO_PATH))
MACRUM 0:276e7a263c35 878 {
MACRUM 0:276e7a263c35 879 tr_err("esfs_reset() - pal_fsRmFiles(ESFS_BACKUP_DIRECTORY) failed with pal_status = 0x%x", (unsigned int)pal_result);
MACRUM 0:276e7a263c35 880 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 881 goto errorExit;
MACRUM 0:276e7a263c35 882 }
MACRUM 0:276e7a263c35 883
MACRUM 0:276e7a263c35 884 pal_result = pal_fsRmDir(dir_path);
MACRUM 0:276e7a263c35 885 if (pal_result != PAL_SUCCESS)
MACRUM 0:276e7a263c35 886 {
MACRUM 0:276e7a263c35 887 // Any error apart from dir not exist returns error.
MACRUM 0:276e7a263c35 888 if ((pal_result != PAL_ERR_FS_NO_FILE) && (pal_result != PAL_ERR_FS_NO_PATH))
MACRUM 0:276e7a263c35 889 {
MACRUM 0:276e7a263c35 890 tr_err("esfs_reset() - pal_fsRmDir(ESFS_BACKUP_DIRECTORY) failed with pal_status = 0x%x", (unsigned int)pal_result);
MACRUM 0:276e7a263c35 891 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 892 goto errorExit;
MACRUM 0:276e7a263c35 893 }
MACRUM 0:276e7a263c35 894 }
MACRUM 0:276e7a263c35 895
MACRUM 0:276e7a263c35 896 if (esfs_finalize() != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 897 {
MACRUM 0:276e7a263c35 898 tr_err("esfs_reset() - esfs_finalize() failed");
MACRUM 0:276e7a263c35 899 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 900 goto errorExit;
MACRUM 0:276e7a263c35 901 }
MACRUM 0:276e7a263c35 902
MACRUM 0:276e7a263c35 903 if (esfs_init() != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 904 {
MACRUM 0:276e7a263c35 905 tr_err("esfs_reset() - esfs_init() failed");
MACRUM 0:276e7a263c35 906 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 907 goto errorExit;
MACRUM 0:276e7a263c35 908 }
MACRUM 0:276e7a263c35 909
MACRUM 0:276e7a263c35 910 return ESFS_SUCCESS;
MACRUM 0:276e7a263c35 911
MACRUM 0:276e7a263c35 912 errorExit:
MACRUM 0:276e7a263c35 913 return result;
MACRUM 0:276e7a263c35 914 }
MACRUM 0:276e7a263c35 915
MACRUM 0:276e7a263c35 916
MACRUM 0:276e7a263c35 917 esfs_result_e esfs_factory_reset(void) {
MACRUM 0:276e7a263c35 918 palStatus_t pal_result = PAL_SUCCESS;
MACRUM 0:276e7a263c35 919 esfs_result_e result = ESFS_SUCCESS;
MACRUM 0:276e7a263c35 920 esfs_file_t file_handle = { 0 };
MACRUM 0:276e7a263c35 921 char working_dir_path[MAX_FULL_PATH_SIZE] = { 0 };
MACRUM 0:276e7a263c35 922 char full_path_backup_dir[MAX_FULL_PATH_SIZE] = { 0 };
MACRUM 0:276e7a263c35 923 bool is_single_partition = true;
MACRUM 0:276e7a263c35 924
MACRUM 0:276e7a263c35 925 tr_info("esfs_factory_reset - enter");
MACRUM 0:276e7a263c35 926 pal_result = pal_fsGetMountPoint(PAL_FS_PARTITION_SECONDARY, PAL_MAX_FOLDER_DEPTH_CHAR + 1, full_path_backup_dir);
MACRUM 0:276e7a263c35 927 if (pal_result != PAL_SUCCESS)
MACRUM 0:276e7a263c35 928 {
MACRUM 0:276e7a263c35 929 tr_err("esfs_factory_reset() - pal_fsGetMountPoint() for backup directory failed with pal_status = 0x%x", (unsigned int)pal_result);
MACRUM 0:276e7a263c35 930 return ESFS_ERROR;
MACRUM 0:276e7a263c35 931 }
MACRUM 0:276e7a263c35 932
MACRUM 0:276e7a263c35 933 strncat(full_path_backup_dir, "/" ESFS_BACKUP_DIRECTORY "/" FACTORY_RESET_DIR, sizeof(ESFS_BACKUP_DIRECTORY) + sizeof(FACTORY_RESET_DIR));
MACRUM 0:276e7a263c35 934 // Create the factory reset subfolder - FR
MACRUM 0:276e7a263c35 935 pal_result = pal_fsMkDir(full_path_backup_dir);
MACRUM 0:276e7a263c35 936 if (pal_result != PAL_SUCCESS)
MACRUM 0:276e7a263c35 937 {
MACRUM 0:276e7a263c35 938 // Any error apart from file exist returns error.
MACRUM 0:276e7a263c35 939 if (pal_result != PAL_ERR_FS_NAME_ALREADY_EXIST)
MACRUM 0:276e7a263c35 940 {
MACRUM 0:276e7a263c35 941 tr_err("esfs_factory_reset() - pal_fsMkDir(ESFS_BACKUP_DIRECTORY/FACTORY_RESET_DIR) failed with pal_status = 0x%x", (unsigned int)pal_result);
MACRUM 0:276e7a263c35 942 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 943 goto errorExit;
MACRUM 0:276e7a263c35 944 }
MACRUM 0:276e7a263c35 945 }
MACRUM 0:276e7a263c35 946
MACRUM 0:276e7a263c35 947 strncat(full_path_backup_dir, "/" FACTORY_RESET_FILE, sizeof(FACTORY_RESET_FILE));
MACRUM 0:276e7a263c35 948 // Create the fr_on flag file
MACRUM 0:276e7a263c35 949 pal_result = pal_fsFopen(full_path_backup_dir, PAL_FS_FLAG_READWRITEEXCLUSIVE, &(file_handle.file));
MACRUM 0:276e7a263c35 950
MACRUM 0:276e7a263c35 951 // (res == PAL_SUCCESS) : factory reset is called on the first time
MACRUM 0:276e7a263c35 952 // (res == PAL_ERR_FS_NAME_ALREADY_EXIST) : factory reset is called again after it was failed
MACRUM 0:276e7a263c35 953 // on the first time and therefore the file exists
MACRUM 0:276e7a263c35 954 if ((pal_result != PAL_SUCCESS) && (pal_result != PAL_ERR_FS_NAME_ALREADY_EXIST))
MACRUM 0:276e7a263c35 955 {
MACRUM 0:276e7a263c35 956 tr_err("esfs_factory_reset() - unexpected filesystem behavior pal_fsFopen() failed with pal_status = 0x%x", (unsigned int)pal_result);
MACRUM 0:276e7a263c35 957 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 958 goto errorExit;
MACRUM 0:276e7a263c35 959 }
MACRUM 0:276e7a263c35 960
MACRUM 0:276e7a263c35 961 // close the file only if we opened it
MACRUM 0:276e7a263c35 962 if (pal_result == PAL_SUCCESS)
MACRUM 0:276e7a263c35 963 {
MACRUM 0:276e7a263c35 964 pal_result = pal_fsFclose(&(file_handle.file));
MACRUM 0:276e7a263c35 965 if (pal_result != PAL_SUCCESS)
MACRUM 0:276e7a263c35 966 {
MACRUM 0:276e7a263c35 967 tr_err("esfs_factory_reset() - unexpected filesystem behavior pal_fsFclose() failed with pal_status = 0x%x", (unsigned int)pal_result);
MACRUM 0:276e7a263c35 968 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 969 goto errorExit;
MACRUM 0:276e7a263c35 970 }
MACRUM 0:276e7a263c35 971 }
MACRUM 0:276e7a263c35 972
MACRUM 0:276e7a263c35 973 pal_result = pal_fsGetMountPoint(PAL_FS_PARTITION_PRIMARY, PAL_MAX_FOLDER_DEPTH_CHAR + 1, working_dir_path);
MACRUM 0:276e7a263c35 974 if (pal_result != PAL_SUCCESS)
MACRUM 0:276e7a263c35 975 {
MACRUM 0:276e7a263c35 976 tr_err("esfs_factory_reset() - pal_fsGetMountPoint() for working directory failed with pal_status = 0x%x", (unsigned int)pal_result);
MACRUM 0:276e7a263c35 977 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 978 goto errorExit;
MACRUM 0:276e7a263c35 979 }
MACRUM 0:276e7a263c35 980
MACRUM 0:276e7a263c35 981 // Check if there is a single partition by comparing the primary and secondary mount points.
MACRUM 0:276e7a263c35 982 // This is the only reliable way to do it, since the logic that determines the number of partitions is
MACRUM 0:276e7a263c35 983 // hidden behind the PAL API.
MACRUM 0:276e7a263c35 984 pal_result = pal_fsGetMountPoint(PAL_FS_PARTITION_SECONDARY, PAL_MAX_FOLDER_DEPTH_CHAR + 1, full_path_backup_dir);
MACRUM 0:276e7a263c35 985 if (pal_result != PAL_SUCCESS)
MACRUM 0:276e7a263c35 986 {
MACRUM 0:276e7a263c35 987 tr_err("esfs_factory_reset() - pal_fsGetMountPoint() for backup directory failed with pal_status = 0x%x", (unsigned int)pal_result);
MACRUM 0:276e7a263c35 988 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 989 goto errorExit;
MACRUM 0:276e7a263c35 990 }
MACRUM 0:276e7a263c35 991 is_single_partition = (strcmp(working_dir_path,full_path_backup_dir) == 0);
MACRUM 0:276e7a263c35 992
MACRUM 0:276e7a263c35 993 strncat(working_dir_path, "/" ESFS_WORKING_DIRECTORY, sizeof(ESFS_WORKING_DIRECTORY));
MACRUM 0:276e7a263c35 994
MACRUM 0:276e7a263c35 995 // We can only format the working folder if it is dedicated for exclusive use of esfs and
MACRUM 0:276e7a263c35 996 // it is not the only partition that exists. The assumption here is that if it is the only partition,
MACRUM 0:276e7a263c35 997 // then the backup folder is also on that partition. In that case, formatting would remove the backup partition,
MACRUM 0:276e7a263c35 998 // which we do not want to do!
MACRUM 0:276e7a263c35 999 if (pal_fsIsPrivatePartition(PAL_FS_PARTITION_PRIMARY) && !is_single_partition)
MACRUM 0:276e7a263c35 1000 {
MACRUM 0:276e7a263c35 1001 pal_result = pal_fsFormat(PAL_FS_PARTITION_PRIMARY);
MACRUM 0:276e7a263c35 1002 if (pal_result != PAL_SUCCESS)
MACRUM 0:276e7a263c35 1003 {
MACRUM 0:276e7a263c35 1004 tr_err("esfs_factory_reset() - pal_fsFormat() for working directory failed with pal_status = 0x%x", (unsigned int)pal_result);
MACRUM 0:276e7a263c35 1005 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 1006 goto errorExit;
MACRUM 0:276e7a263c35 1007 }
MACRUM 0:276e7a263c35 1008 pal_result = pal_fsMkDir(working_dir_path);
MACRUM 0:276e7a263c35 1009 if (pal_result != PAL_SUCCESS)
MACRUM 0:276e7a263c35 1010 {
MACRUM 0:276e7a263c35 1011 tr_err("esfs_factory_reset() - pal_fsMkDir(ESFS_WORKING_DIRECTORY) failed with pal_status = 0x%x", (unsigned int)pal_result);
MACRUM 0:276e7a263c35 1012 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 1013 goto errorExit;
MACRUM 0:276e7a263c35 1014 }
MACRUM 0:276e7a263c35 1015 }
MACRUM 0:276e7a263c35 1016 else
MACRUM 0:276e7a263c35 1017 {
MACRUM 0:276e7a263c35 1018 // delete the files in working dir
MACRUM 0:276e7a263c35 1019 pal_result = pal_fsRmFiles(working_dir_path);
MACRUM 0:276e7a263c35 1020 // the use case is that esfs folder may not exist
MACRUM 0:276e7a263c35 1021 if ((pal_result != PAL_SUCCESS) && (pal_result != PAL_ERR_FS_NO_FILE) && (pal_result != PAL_ERR_FS_NO_PATH))
MACRUM 0:276e7a263c35 1022 {
MACRUM 0:276e7a263c35 1023 tr_err("esfs_factory_reset() - pal_fsRmFiles(ESFS_WORKING_DIRECTORY) failed with pal_status = 0x%x", (unsigned int)pal_result);
MACRUM 0:276e7a263c35 1024 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 1025 goto errorExit;
MACRUM 0:276e7a263c35 1026 }
MACRUM 0:276e7a263c35 1027 }
MACRUM 0:276e7a263c35 1028
MACRUM 0:276e7a263c35 1029
MACRUM 0:276e7a263c35 1030
MACRUM 0:276e7a263c35 1031
MACRUM 0:276e7a263c35 1032 pal_result = pal_fsGetMountPoint(PAL_FS_PARTITION_SECONDARY, PAL_MAX_FOLDER_DEPTH_CHAR + 1, full_path_backup_dir);
MACRUM 0:276e7a263c35 1033 if (pal_result != PAL_SUCCESS)
MACRUM 0:276e7a263c35 1034 {
MACRUM 0:276e7a263c35 1035 tr_err("esfs_factory_reset() - pal_fsGetMountPoint() for backup directory failed with pal_status = 0x%x", (unsigned int)pal_result);
MACRUM 0:276e7a263c35 1036 return ESFS_ERROR;
MACRUM 0:276e7a263c35 1037 }
MACRUM 0:276e7a263c35 1038 strncat(full_path_backup_dir, "/" ESFS_BACKUP_DIRECTORY, sizeof(ESFS_BACKUP_DIRECTORY));
MACRUM 0:276e7a263c35 1039
MACRUM 0:276e7a263c35 1040 pal_result = pal_fsCpFolder(full_path_backup_dir, working_dir_path);
MACRUM 0:276e7a263c35 1041
MACRUM 0:276e7a263c35 1042 if ((pal_result != PAL_SUCCESS) && (pal_result != PAL_ERR_FS_NO_FILE))
MACRUM 0:276e7a263c35 1043 {
MACRUM 0:276e7a263c35 1044 tr_err("esfs_factory_reset() - pal_fsCpFolder() from backup to working failed with pal_status = 0x%x", (unsigned int)pal_result);
MACRUM 0:276e7a263c35 1045 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 1046 goto errorExit;
MACRUM 0:276e7a263c35 1047 }
MACRUM 0:276e7a263c35 1048
MACRUM 0:276e7a263c35 1049 strncat(full_path_backup_dir, "/" FACTORY_RESET_DIR "/" FACTORY_RESET_FILE, sizeof(FACTORY_RESET_DIR) + sizeof(FACTORY_RESET_FILE));
MACRUM 0:276e7a263c35 1050 // delete the flag file because factory reset flow ended successfully
MACRUM 0:276e7a263c35 1051 pal_result = pal_fsUnlink(full_path_backup_dir);
MACRUM 0:276e7a263c35 1052 if (pal_result != PAL_SUCCESS)
MACRUM 0:276e7a263c35 1053 {
MACRUM 0:276e7a263c35 1054 tr_err("esfs_factory_reset() - pal_fsUnlink(ESFS_BACKUP_DIRECTORY/FACTORY_RESET_DIR/FACTORY_RESET_FILE) failed with pal_status = 0x%x", (unsigned int)pal_result);
MACRUM 0:276e7a263c35 1055 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 1056 goto errorExit;
MACRUM 0:276e7a263c35 1057 }
MACRUM 0:276e7a263c35 1058
MACRUM 0:276e7a263c35 1059 return ESFS_SUCCESS;
MACRUM 0:276e7a263c35 1060
MACRUM 0:276e7a263c35 1061 errorExit:
MACRUM 0:276e7a263c35 1062 return result;
MACRUM 0:276e7a263c35 1063 }
MACRUM 0:276e7a263c35 1064
MACRUM 0:276e7a263c35 1065 // Internal function to read header information and check its' validity.
MACRUM 0:276e7a263c35 1066 // Checks the name given against the name written in the file.
MACRUM 0:276e7a263c35 1067 // Checks the version.
MACRUM 0:276e7a263c35 1068 // Initializes some fields of file_handle: blob_name_length, esf_mode
MACRUM 0:276e7a263c35 1069 // Assumes that the read position is at the start of the file.
MACRUM 0:276e7a263c35 1070 // CMAC is calculated.
MACRUM 0:276e7a263c35 1071 // Parameters :
MACRUM 0:276e7a263c35 1072 // name [IN] A pointer to an array of binary data that uniquely identifies the file.
MACRUM 0:276e7a263c35 1073 // name_length [IN] size in bytes of the name. The minimum is 1 and the maximum is ESFS_MAX_NAME_LENGTH.
MACRUM 0:276e7a263c35 1074 // file_handle [IN] A pointer to a file handle on which we calculate the position.
MACRUM 0:276e7a263c35 1075 // return esf_success - name matches;
MACRUM 0:276e7a263c35 1076 // ESFS_HASH_CONFLICT - name does not match
MACRUM 0:276e7a263c35 1077 // ESFS_WRONG_FILE_VERSION - version does not match
MACRUM 0:276e7a263c35 1078 // ESFS_ERROR - other problem
MACRUM 0:276e7a263c35 1079 // On ESFS_SUCCESS or ESFS_HASH_CONFLICT the read position is set after the name.
MACRUM 0:276e7a263c35 1080 // On failure the position is undefined.
MACRUM 0:276e7a263c35 1081 static esfs_result_e esfs_check_file_validity(const uint8_t* name, size_t name_length, esfs_file_t *file_handle)
MACRUM 0:276e7a263c35 1082 {
MACRUM 0:276e7a263c35 1083 esfs_result_e result = ESFS_ERROR;
MACRUM 0:276e7a263c35 1084
MACRUM 0:276e7a263c35 1085 // Read the version
MACRUM 0:276e7a263c35 1086 uint16_t version;
MACRUM 0:276e7a263c35 1087 size_t num_bytes;
MACRUM 0:276e7a263c35 1088 result = esfs_cmac_read(file_handle, &version , sizeof(version), &num_bytes);
MACRUM 0:276e7a263c35 1089 if (result != ESFS_SUCCESS || num_bytes != sizeof(version))
MACRUM 0:276e7a263c35 1090 {
MACRUM 0:276e7a263c35 1091 tr_err("esfs_check_file_validity() - esfs_cmac_read() failed with ESFS result = 0x%x and num_bytes bytes = %zu",
MACRUM 0:276e7a263c35 1092 (unsigned int)result, num_bytes);
MACRUM 0:276e7a263c35 1093 goto errorExit;
MACRUM 0:276e7a263c35 1094 }
MACRUM 0:276e7a263c35 1095 // Check that the files version is the same as the source code version.
MACRUM 0:276e7a263c35 1096 if(version != ESFS_FILE_FORMAT_VERSION)
MACRUM 0:276e7a263c35 1097 {
MACRUM 0:276e7a263c35 1098 tr_err("esfs_check_file_validity() - invalid version: failed with version = %u instead of %u", (unsigned int)version, (unsigned int)ESFS_FILE_FORMAT_VERSION);
MACRUM 0:276e7a263c35 1099 result = ESFS_INVALID_FILE_VERSION;
MACRUM 0:276e7a263c35 1100 goto errorExit;
MACRUM 0:276e7a263c35 1101 }
MACRUM 0:276e7a263c35 1102
MACRUM 0:276e7a263c35 1103 // Read the mode
MACRUM 0:276e7a263c35 1104 result = esfs_cmac_read(file_handle, (void *)( &file_handle->esfs_mode ), sizeof(file_handle->esfs_mode), &num_bytes);
MACRUM 0:276e7a263c35 1105 if (result != ESFS_SUCCESS || num_bytes != sizeof(file_handle->esfs_mode))
MACRUM 0:276e7a263c35 1106 {
MACRUM 0:276e7a263c35 1107 tr_err("esfs_check_file_validity() mode - failed num_bytes bytes = %zu", num_bytes);
MACRUM 0:276e7a263c35 1108 goto errorExit;
MACRUM 0:276e7a263c35 1109 }
MACRUM 0:276e7a263c35 1110 // The mode is not used further in the opening process, so no further checks need be performed as cmac check will detect any
MACRUM 0:276e7a263c35 1111 // tampering.
MACRUM 0:276e7a263c35 1112
MACRUM 0:276e7a263c35 1113 // Read the name length
MACRUM 0:276e7a263c35 1114 result = esfs_cmac_read(file_handle, (void *)( &file_handle->blob_name_length ), sizeof(file_handle->blob_name_length), &num_bytes);
MACRUM 0:276e7a263c35 1115 if (result != ESFS_SUCCESS || num_bytes != sizeof(file_handle->blob_name_length))
MACRUM 0:276e7a263c35 1116 {
MACRUM 0:276e7a263c35 1117 tr_err("esfs_check_file_validity() name length- esfs_cmac_read() failed with result = 0x%x and num_bytes bytes = %zu",
MACRUM 0:276e7a263c35 1118 (unsigned int)result, num_bytes);
MACRUM 0:276e7a263c35 1119 goto errorExit;
MACRUM 0:276e7a263c35 1120 }
MACRUM 0:276e7a263c35 1121 // Check that the name in the file is the same length as the one given. It cannot be greater than ESFS_MAX_NAME_LENGTH
MACRUM 0:276e7a263c35 1122 // because that is checked on entry to the function.
MACRUM 0:276e7a263c35 1123 if (name_length != file_handle->blob_name_length)
MACRUM 0:276e7a263c35 1124 {
MACRUM 0:276e7a263c35 1125 tr_err("esfs_check_file_validity() - name length conflict");
MACRUM 0:276e7a263c35 1126 // The hash of the name conflicts with the hash of another name.
MACRUM 0:276e7a263c35 1127 result = ESFS_HASH_CONFLICT;
MACRUM 0:276e7a263c35 1128 goto errorExit;
MACRUM 0:276e7a263c35 1129 }
MACRUM 0:276e7a263c35 1130 // Check the name chunk by chunk
MACRUM 0:276e7a263c35 1131 for (int i = name_length; i > 0; i -= ESFS_READ_CHUNK_SIZE_IN_BYTES)
MACRUM 0:276e7a263c35 1132 {
MACRUM 0:276e7a263c35 1133 // Read a chunk
MACRUM 0:276e7a263c35 1134 char buffer[ESFS_READ_CHUNK_SIZE_IN_BYTES];
MACRUM 0:276e7a263c35 1135 result = esfs_cmac_read(file_handle, (void *)buffer, PAL_MIN(i, ESFS_READ_CHUNK_SIZE_IN_BYTES), &num_bytes);
MACRUM 0:276e7a263c35 1136 if (result != ESFS_SUCCESS || num_bytes == 0)
MACRUM 0:276e7a263c35 1137 {
MACRUM 0:276e7a263c35 1138 tr_err("esfs_check_file_validity() - read name failed with ESFS result = 0x%x and num_bytes bytes = %zu",
MACRUM 0:276e7a263c35 1139 (unsigned int)result, num_bytes);
MACRUM 0:276e7a263c35 1140 goto errorExit;
MACRUM 0:276e7a263c35 1141 }
MACRUM 0:276e7a263c35 1142 // Check that the chunk matches
MACRUM 0:276e7a263c35 1143 //tr_info("Comparing %s (%d bytes) name_length=%d", name, (int )num_bytes,(int )name_length);
MACRUM 0:276e7a263c35 1144 if (memcmp(buffer, name, num_bytes) != 0)
MACRUM 0:276e7a263c35 1145 {
MACRUM 0:276e7a263c35 1146 tr_err("esfs_check_file_validity() - esfs hash conflict : The hash of the name conflicts with the hash of another name");
MACRUM 0:276e7a263c35 1147 // The hash of the name conflicts with the hash of another name.
MACRUM 0:276e7a263c35 1148 result = ESFS_HASH_CONFLICT;
MACRUM 0:276e7a263c35 1149 goto errorExit;
MACRUM 0:276e7a263c35 1150 }
MACRUM 0:276e7a263c35 1151 // Advance past what we just checked.
MACRUM 0:276e7a263c35 1152 name += num_bytes;
MACRUM 0:276e7a263c35 1153 }
MACRUM 0:276e7a263c35 1154 return ESFS_SUCCESS;
MACRUM 0:276e7a263c35 1155 errorExit:
MACRUM 0:276e7a263c35 1156 return result;
MACRUM 0:276e7a263c35 1157 }
MACRUM 0:276e7a263c35 1158
MACRUM 0:276e7a263c35 1159 // Internal function to check the name against the name written in the file.
MACRUM 0:276e7a263c35 1160 // Assume that the read position is set to before the name length.
MACRUM 0:276e7a263c35 1161 // Parameters :
MACRUM 0:276e7a263c35 1162 // fd - [IN] A pointer to a file descriptor.
MACRUM 0:276e7a263c35 1163 // file_size [OUT] A pointer to a value into which the file size is returned.
MACRUM 0:276e7a263c35 1164 // return esf_success - name matches;
MACRUM 0:276e7a263c35 1165 // ESFS_HASH_CONFLICT - name does not match ;
MACRUM 0:276e7a263c35 1166 // ESFS_ERROR - other problem
MACRUM 0:276e7a263c35 1167 // On ESFS_SUCCESS or ESFS_HASH_CONFLICT the read position is set after the name.
MACRUM 0:276e7a263c35 1168 // On failure the position is undefined.
MACRUM 0:276e7a263c35 1169
MACRUM 0:276e7a263c35 1170 // Helper function
MACRUM 0:276e7a263c35 1171 // Restores current position unless it fails.
MACRUM 0:276e7a263c35 1172 // On failure the position is undefined.
MACRUM 0:276e7a263c35 1173 static palStatus_t esfs_get_physical_file_size(palFileDescriptor_t* fd, int32_t *file_size)
MACRUM 0:276e7a263c35 1174 {
MACRUM 0:276e7a263c35 1175 palStatus_t res;
MACRUM 0:276e7a263c35 1176
MACRUM 0:276e7a263c35 1177 // Get current position
MACRUM 0:276e7a263c35 1178 int32_t current_pos;
MACRUM 0:276e7a263c35 1179 res = pal_fsFtell(fd, &current_pos);
MACRUM 0:276e7a263c35 1180 if (res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 1181 {
MACRUM 0:276e7a263c35 1182 tr_err("esfs_get_physical_file_size() - pal_fsFtell() failed with pal_status = 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 1183 goto errorExit;
MACRUM 0:276e7a263c35 1184 }
MACRUM 0:276e7a263c35 1185 // Seek to end of file
MACRUM 0:276e7a263c35 1186 res = pal_fsFseek(fd, 0, PAL_FS_OFFSET_SEEKEND);
MACRUM 0:276e7a263c35 1187 if (res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 1188 {
MACRUM 0:276e7a263c35 1189 tr_err("esfs_get_physical_file_size() - pal_fsFseek() failed with pal_status = 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 1190 goto errorExit;
MACRUM 0:276e7a263c35 1191 }
MACRUM 0:276e7a263c35 1192 // Get new position
MACRUM 0:276e7a263c35 1193 res = pal_fsFtell(fd, file_size);
MACRUM 0:276e7a263c35 1194 if (res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 1195 {
MACRUM 0:276e7a263c35 1196 tr_err("esfs_get_physical_file_size() - pal_fsFtell() failed with pal_status = 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 1197 goto errorExit;
MACRUM 0:276e7a263c35 1198 }
MACRUM 0:276e7a263c35 1199 // Restore old position
MACRUM 0:276e7a263c35 1200 res = pal_fsFseek(fd, current_pos, PAL_FS_OFFSET_SEEKSET);
MACRUM 0:276e7a263c35 1201 if (res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 1202 {
MACRUM 0:276e7a263c35 1203 tr_err("esfs_get_physical_file_size() - pal_fsFseek() failed with pal_status = 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 1204 goto errorExit;
MACRUM 0:276e7a263c35 1205 }
MACRUM 0:276e7a263c35 1206
MACRUM 0:276e7a263c35 1207 errorExit:
MACRUM 0:276e7a263c35 1208 return res;
MACRUM 0:276e7a263c35 1209 }
MACRUM 0:276e7a263c35 1210
MACRUM 0:276e7a263c35 1211 // Copy one file to another.
MACRUM 0:276e7a263c35 1212 // Parameters :
MACRUM 0:276e7a263c35 1213 // src_file [IN] A pointer to a string containing the source file name.
MACRUM 0:276e7a263c35 1214 // src_file [IN] A pointer to a string containing the destination file name.
MACRUM 0:276e7a263c35 1215 // Return : ESFS_SUCCESS on success. Error code otherwise
MACRUM 0:276e7a263c35 1216 static esfs_result_e esfs_copy_file(const char *src_file, const char *dst_file)
MACRUM 0:276e7a263c35 1217 {
MACRUM 0:276e7a263c35 1218 bool is_src_file_opened = false;
MACRUM 0:276e7a263c35 1219 bool is_dst_file_opened = false;
MACRUM 0:276e7a263c35 1220 esfs_file_t file_handle = { 0 };
MACRUM 0:276e7a263c35 1221 esfs_file_t file_handle_copy = { 0 };
MACRUM 0:276e7a263c35 1222 esfs_result_e result = ESFS_ERROR;
MACRUM 0:276e7a263c35 1223 palStatus_t res = PAL_SUCCESS;
MACRUM 0:276e7a263c35 1224 size_t bytes_to_read = ESFS_FILE_COPY_CHUNK_SIZE;
MACRUM 0:276e7a263c35 1225 size_t num_bytes_read = 0;
MACRUM 0:276e7a263c35 1226 size_t num_bytes_write = 0;
MACRUM 0:276e7a263c35 1227 uint8_t buffer[ESFS_FILE_COPY_CHUNK_SIZE] = {0};
MACRUM 0:276e7a263c35 1228 int32_t file_size = 0;
MACRUM 0:276e7a263c35 1229 int32_t copied_bytes = 0;
MACRUM 0:276e7a263c35 1230 // Open src file read only mode
MACRUM 0:276e7a263c35 1231 res = pal_fsFopen(src_file, PAL_FS_FLAG_READONLY, &(file_handle.file));
MACRUM 0:276e7a263c35 1232 if (res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 1233 {
MACRUM 0:276e7a263c35 1234 // File cannot be opened so return an error
MACRUM 0:276e7a263c35 1235 tr_err("esfs_copy_file() - pal_fsFopen() src file failed with pal_status = 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 1236 result = ESFS_NOT_EXISTS;
MACRUM 0:276e7a263c35 1237 goto errorExit;
MACRUM 0:276e7a263c35 1238 }
MACRUM 0:276e7a263c35 1239 is_src_file_opened = true;
MACRUM 0:276e7a263c35 1240 // Open for reading and writing exclusively, If the file already exists, trunced file
MACRUM 0:276e7a263c35 1241 res = pal_fsFopen(dst_file, PAL_FS_FLAG_READWRITETRUNC, &(file_handle_copy.file));
MACRUM 0:276e7a263c35 1242 if (res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 1243 {
MACRUM 0:276e7a263c35 1244 // File cannot be opened so return an error
MACRUM 0:276e7a263c35 1245 tr_err("esfs_copy_file() - pal_fsFopen() dst file failed with pal_status = 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 1246 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 1247 goto errorExit;
MACRUM 0:276e7a263c35 1248 }
MACRUM 0:276e7a263c35 1249 is_dst_file_opened = true;
MACRUM 0:276e7a263c35 1250
MACRUM 0:276e7a263c35 1251 res = esfs_get_physical_file_size(&(file_handle.file), &file_size);
MACRUM 0:276e7a263c35 1252 if (res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 1253 {
MACRUM 0:276e7a263c35 1254 tr_err("esfs_copy_file() - esfs_get_physical_file_size() failed with pal_status = 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 1255 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 1256 goto errorExit;
MACRUM 0:276e7a263c35 1257 }
MACRUM 0:276e7a263c35 1258 while (copied_bytes < file_size)
MACRUM 0:276e7a263c35 1259 {
MACRUM 0:276e7a263c35 1260 if (copied_bytes + (int32_t)bytes_to_read > file_size)
MACRUM 0:276e7a263c35 1261 {
MACRUM 0:276e7a263c35 1262 bytes_to_read = file_size - copied_bytes;
MACRUM 0:276e7a263c35 1263 }
MACRUM 0:276e7a263c35 1264 res = pal_fsFread(&(file_handle.file), buffer, bytes_to_read, &num_bytes_read);
MACRUM 0:276e7a263c35 1265 if (res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 1266 {
MACRUM 0:276e7a263c35 1267 tr_err("esfs_copy_file() - pal_fsFread() failed with pal_status = 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 1268 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 1269 goto errorExit;
MACRUM 0:276e7a263c35 1270 }
MACRUM 0:276e7a263c35 1271
MACRUM 0:276e7a263c35 1272 res = pal_fsFwrite(&(file_handle_copy.file), buffer, bytes_to_read, &num_bytes_write);
MACRUM 0:276e7a263c35 1273 if ((res != PAL_SUCCESS) || (num_bytes_write != bytes_to_read))
MACRUM 0:276e7a263c35 1274 {
MACRUM 0:276e7a263c35 1275 tr_err("esfs_copy_file() - pal_fsFwrite() failed with pal result = 0x%x and num_bytes_write bytes = %zu",
MACRUM 0:276e7a263c35 1276 (unsigned int)res, num_bytes_write);
MACRUM 0:276e7a263c35 1277 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 1278 goto errorExit;
MACRUM 0:276e7a263c35 1279 }
MACRUM 0:276e7a263c35 1280
MACRUM 0:276e7a263c35 1281 copied_bytes += bytes_to_read;
MACRUM 0:276e7a263c35 1282
MACRUM 0:276e7a263c35 1283 }
MACRUM 0:276e7a263c35 1284
MACRUM 0:276e7a263c35 1285
MACRUM 0:276e7a263c35 1286 res = pal_fsFclose(&(file_handle.file));
MACRUM 0:276e7a263c35 1287 if (res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 1288 {
MACRUM 0:276e7a263c35 1289 tr_err("esfs_copy_file() - pal_fsFclose() for src file failed with pal_status = 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 1290 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 1291 goto errorExit;
MACRUM 0:276e7a263c35 1292 }
MACRUM 0:276e7a263c35 1293 res = pal_fsFclose(&(file_handle_copy.file));
MACRUM 0:276e7a263c35 1294 if (res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 1295 {
MACRUM 0:276e7a263c35 1296 tr_err("esfs_copy_file() - pal_fsFclose() for dst file failed with pal_status = 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 1297 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 1298 goto errorExit;
MACRUM 0:276e7a263c35 1299 }
MACRUM 0:276e7a263c35 1300 return ESFS_SUCCESS;
MACRUM 0:276e7a263c35 1301
MACRUM 0:276e7a263c35 1302 errorExit:
MACRUM 0:276e7a263c35 1303 if (is_src_file_opened)
MACRUM 0:276e7a263c35 1304 {
MACRUM 0:276e7a263c35 1305 // we will not delete the src file
MACRUM 0:276e7a263c35 1306 pal_fsFclose(&(file_handle.file));
MACRUM 0:276e7a263c35 1307 }
MACRUM 0:276e7a263c35 1308
MACRUM 0:276e7a263c35 1309 if (is_dst_file_opened)
MACRUM 0:276e7a263c35 1310 {
MACRUM 0:276e7a263c35 1311 pal_fsFclose(&(file_handle_copy.file));
MACRUM 0:276e7a263c35 1312 // Clean up if possible. Ignore return value.
MACRUM 0:276e7a263c35 1313 (void)pal_fsUnlink(dst_file);
MACRUM 0:276e7a263c35 1314 }
MACRUM 0:276e7a263c35 1315 return result;
MACRUM 0:276e7a263c35 1316 }
MACRUM 0:276e7a263c35 1317
MACRUM 0:276e7a263c35 1318
MACRUM 0:276e7a263c35 1319
MACRUM 0:276e7a263c35 1320
MACRUM 0:276e7a263c35 1321 // Internal function to create a new file and open it for writing.
MACRUM 0:276e7a263c35 1322 // Does not return error if file exists.
MACRUM 0:276e7a263c35 1323 // Keep all the conditions that allow the file creation in a single function, esfs_create, while the
MACRUM 0:276e7a263c35 1324 // esfs_create_internal will concentrate on file creation mechanics.
MACRUM 0:276e7a263c35 1325 // Parameters:
MACRUM 0:276e7a263c35 1326 // name [IN] A pointer to an array of binary data that uniquely identifies the file.
MACRUM 0:276e7a263c35 1327 // name_length [IN] size in bytes of the name. The minimum is 1 and the maximum is ESFS_MAX_NAME_LENGTH.
MACRUM 0:276e7a263c35 1328 // meta_data [IN] A pointer to an array of TLVs structures with meta_data_qty members
MACRUM 0:276e7a263c35 1329 // meta_data_qty[IN] number of tlvs in the array pointed by meta_data parameter. Minimum is 0 maximum is ESFS_MAX_TYPE_LENGTH_VALUES
MACRUM 0:276e7a263c35 1330 // esfs_mode [IN] a bit map combination of values from enum EsfsMode.
MACRUM 0:276e7a263c35 1331 // file_handle [IN/OUT] Pointer to the handle data structure into which to write the new handle.
MACRUM 0:276e7a263c35 1332 // returns ESFS_SUCCESS The file handle can be used in other esfs functions. It must be closed to release it.
MACRUM 0:276e7a263c35 1333 // ESFS_ERROR - other problem
MACRUM 0:276e7a263c35 1334 static esfs_result_e esfs_create_internal( const uint8_t *name,
MACRUM 0:276e7a263c35 1335 size_t name_length,
MACRUM 0:276e7a263c35 1336 const esfs_tlv_item_t *meta_data,
MACRUM 0:276e7a263c35 1337 size_t meta_data_qty,
MACRUM 0:276e7a263c35 1338 uint16_t esfs_mode,
MACRUM 0:276e7a263c35 1339 esfs_file_t *file_handle,
MACRUM 0:276e7a263c35 1340 const char* full_path_to_create
MACRUM 0:276e7a263c35 1341 )
MACRUM 0:276e7a263c35 1342 {
MACRUM 0:276e7a263c35 1343 esfs_result_e result = ESFS_ERROR;
MACRUM 0:276e7a263c35 1344
MACRUM 0:276e7a263c35 1345 int32_t position = 0;
MACRUM 0:276e7a263c35 1346 size_t i;
MACRUM 0:276e7a263c35 1347 uint16_t file_created = 0;
MACRUM 0:276e7a263c35 1348 uint16_t cmac_created = 0;
MACRUM 0:276e7a263c35 1349 uint16_t u16 = ESFS_FILE_FORMAT_VERSION;
MACRUM 0:276e7a263c35 1350
MACRUM 0:276e7a263c35 1351
MACRUM 0:276e7a263c35 1352 // Create the file.
MACRUM 0:276e7a263c35 1353 // Note that we always overwrite any previous file.
MACRUM 0:276e7a263c35 1354 palStatus_t res = pal_fsFopen(full_path_to_create, PAL_FS_FLAG_READWRITETRUNC, &file_handle->file);
MACRUM 0:276e7a263c35 1355 if(res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 1356 {
MACRUM 0:276e7a263c35 1357 // more informative message will be written after hash conflict will be implemented
MACRUM 0:276e7a263c35 1358 tr_err("esfs_create_internal() - pal_fsFopen() failed with status 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 1359 goto errorExit;
MACRUM 0:276e7a263c35 1360 }
MACRUM 0:276e7a263c35 1361 file_created = 1;
MACRUM 0:276e7a263c35 1362
MACRUM 0:276e7a263c35 1363 if(esfs_cmac_start(file_handle) != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 1364 {
MACRUM 0:276e7a263c35 1365 goto errorExit;
MACRUM 0:276e7a263c35 1366 }
MACRUM 0:276e7a263c35 1367 cmac_created = 1;
MACRUM 0:276e7a263c35 1368
MACRUM 0:276e7a263c35 1369 // Write the version
MACRUM 0:276e7a263c35 1370 if(esfs_fwrite_and_calc_cmac(&u16, sizeof(u16), file_handle) != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 1371 {
MACRUM 0:276e7a263c35 1372 tr_err("esfs_create_internal() - esfs_fwrite_and_calc_cmac() for esfs version failed");
MACRUM 0:276e7a263c35 1373 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 1374 goto errorExit;
MACRUM 0:276e7a263c35 1375 }
MACRUM 0:276e7a263c35 1376
MACRUM 0:276e7a263c35 1377 // Write the mode
MACRUM 0:276e7a263c35 1378 if(esfs_fwrite_and_calc_cmac(&esfs_mode, sizeof(esfs_mode), file_handle) != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 1379 {
MACRUM 0:276e7a263c35 1380 tr_err("esfs_create_internal() - esfs_fwrite_and_calc_cmac() for esfs_mode failed");
MACRUM 0:276e7a263c35 1381 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 1382 goto errorExit;
MACRUM 0:276e7a263c35 1383 }
MACRUM 0:276e7a263c35 1384
MACRUM 0:276e7a263c35 1385 // Header
MACRUM 0:276e7a263c35 1386 // Write the name length
MACRUM 0:276e7a263c35 1387 u16 = (uint16_t)name_length;
MACRUM 0:276e7a263c35 1388 if(esfs_fwrite_and_calc_cmac(&u16, sizeof(u16), file_handle) != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 1389 {
MACRUM 0:276e7a263c35 1390 tr_err("esfs_create_internal() - esfs_fwrite_and_calc_cmac() for name_length failed");
MACRUM 0:276e7a263c35 1391 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 1392 goto errorExit;
MACRUM 0:276e7a263c35 1393 }
MACRUM 0:276e7a263c35 1394
MACRUM 0:276e7a263c35 1395 // Write the name
MACRUM 0:276e7a263c35 1396 if(esfs_fwrite_and_calc_cmac(name, name_length, file_handle) != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 1397 {
MACRUM 0:276e7a263c35 1398 tr_err("esfs_create_internal() - esfs_fwrite_and_calc_cmac() for name failed.");
MACRUM 0:276e7a263c35 1399 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 1400 goto errorExit;
MACRUM 0:276e7a263c35 1401 }
MACRUM 0:276e7a263c35 1402
MACRUM 0:276e7a263c35 1403 // Write the AES nonce, whether the file is encrypted or not. This ensures that the file format is the same
MACRUM 0:276e7a263c35 1404 // whether encrypted or not.
MACRUM 0:276e7a263c35 1405 if ((file_handle->esfs_mode & ESFS_ENCRYPTED) != 0)
MACRUM 0:276e7a263c35 1406 {
MACRUM 0:276e7a263c35 1407 if(esfs_fwrite_and_calc_cmac((void *)(file_handle->nonce), ESFS_AES_NONCE_SIZE_BYTES, file_handle) != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 1408 {
MACRUM 0:276e7a263c35 1409 tr_err("esfs_create_internal() - esfs_fwrite_and_calc_cmac() for AES nonce failed");
MACRUM 0:276e7a263c35 1410 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 1411 goto errorExit;
MACRUM 0:276e7a263c35 1412 }
MACRUM 0:276e7a263c35 1413 }
MACRUM 0:276e7a263c35 1414
MACRUM 0:276e7a263c35 1415 // Write the Metadata header
MACRUM 0:276e7a263c35 1416 // Write the number of items of meta data
MACRUM 0:276e7a263c35 1417 u16 = (uint16_t)meta_data_qty;
MACRUM 0:276e7a263c35 1418 if(esfs_fwrite_and_calc_cmac(&u16,sizeof(u16), file_handle) != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 1419 {
MACRUM 0:276e7a263c35 1420 tr_err("esfs_create_internal() - esfs_fwrite_and_calc_cmac() for number of items of meta data failed");
MACRUM 0:276e7a263c35 1421 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 1422 goto errorExit;
MACRUM 0:276e7a263c35 1423 }
MACRUM 0:276e7a263c35 1424
MACRUM 0:276e7a263c35 1425 // If there is meta data
MACRUM 0:276e7a263c35 1426 if(meta_data_qty != 0)
MACRUM 0:276e7a263c35 1427 {
MACRUM 0:276e7a263c35 1428 res = pal_fsFtell(&file_handle->file, &position);
MACRUM 0:276e7a263c35 1429 if(res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 1430 {
MACRUM 0:276e7a263c35 1431 tr_err("esfs_create_internal() - pal_fsFtell() failed with pal_status = 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 1432 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 1433 goto errorExit;
MACRUM 0:276e7a263c35 1434 }
MACRUM 0:276e7a263c35 1435 position += (sizeof(file_handle->tlv_properties.tlv_items[0]) * meta_data_qty);
MACRUM 0:276e7a263c35 1436 for(i = 0; i < meta_data_qty; i++ )
MACRUM 0:276e7a263c35 1437 {
MACRUM 0:276e7a263c35 1438 file_handle->tlv_properties.tlv_items[i].type = meta_data[i].type;
MACRUM 0:276e7a263c35 1439 file_handle->tlv_properties.tlv_items[i].length_in_bytes = meta_data[i].length_in_bytes;
MACRUM 0:276e7a263c35 1440 file_handle->tlv_properties.tlv_items[i].position = (uint16_t)position;
MACRUM 0:276e7a263c35 1441 // Increment position for next iteration
MACRUM 0:276e7a263c35 1442 position += meta_data[i].length_in_bytes;
MACRUM 0:276e7a263c35 1443 }
MACRUM 0:276e7a263c35 1444
MACRUM 0:276e7a263c35 1445 // Write the metadata items
MACRUM 0:276e7a263c35 1446 result = esfs_fwrite_and_calc_cmac(&file_handle->tlv_properties.tlv_items[0], sizeof(file_handle->tlv_properties.tlv_items[0])*meta_data_qty, file_handle);
MACRUM 0:276e7a263c35 1447 if(result != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 1448 {
MACRUM 0:276e7a263c35 1449 tr_err("esfs_create_internal() - esfs_fwrite_and_calc_cmac() for meta data items failed with esfs result = 0x%x", result);
MACRUM 0:276e7a263c35 1450 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 1451 goto errorExit;
MACRUM 0:276e7a263c35 1452 }
MACRUM 0:276e7a263c35 1453
MACRUM 0:276e7a263c35 1454 // Set the number_of_items field here since it is in use later in this function
MACRUM 0:276e7a263c35 1455 // when we calculate the file header size
MACRUM 0:276e7a263c35 1456 file_handle->tlv_properties.number_of_items = meta_data_qty;
MACRUM 0:276e7a263c35 1457
MACRUM 0:276e7a263c35 1458 // Write the Metadata data values
MACRUM 0:276e7a263c35 1459 // If encrypted esfs is requested (by the esfs_mode argument), then this part should be encrypted
MACRUM 0:276e7a263c35 1460 for(i = 0; i < meta_data_qty; i++ )
MACRUM 0:276e7a263c35 1461 {
MACRUM 0:276e7a263c35 1462 if((file_handle->esfs_mode & ESFS_ENCRYPTED) != 0)
MACRUM 0:276e7a263c35 1463 {
MACRUM 0:276e7a263c35 1464 result = esfs_encrypt_fwrite_and_calc_cmac(meta_data[i].value, meta_data[i].length_in_bytes, file_handle);
MACRUM 0:276e7a263c35 1465 }
MACRUM 0:276e7a263c35 1466 else
MACRUM 0:276e7a263c35 1467 {
MACRUM 0:276e7a263c35 1468 result = esfs_fwrite_and_calc_cmac(meta_data[i].value, meta_data[i].length_in_bytes, file_handle);
MACRUM 0:276e7a263c35 1469 }
MACRUM 0:276e7a263c35 1470
MACRUM 0:276e7a263c35 1471 if(result != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 1472 {
MACRUM 0:276e7a263c35 1473 tr_err("esfs_create_internal() - esfs_fwrite_and_calc_cmac() for meta data item values failed with esfs result = 0x%x", result);
MACRUM 0:276e7a263c35 1474 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 1475 goto errorExit;
MACRUM 0:276e7a263c35 1476 }
MACRUM 0:276e7a263c35 1477 }
MACRUM 0:276e7a263c35 1478 }
MACRUM 0:276e7a263c35 1479
MACRUM 0:276e7a263c35 1480 file_handle->file_flag = ESFS_WRITE;
MACRUM 0:276e7a263c35 1481
MACRUM 0:276e7a263c35 1482 return ESFS_SUCCESS;
MACRUM 0:276e7a263c35 1483
MACRUM 0:276e7a263c35 1484 errorExit:
MACRUM 0:276e7a263c35 1485
MACRUM 0:276e7a263c35 1486 if(file_created)
MACRUM 0:276e7a263c35 1487 {
MACRUM 0:276e7a263c35 1488 pal_fsFclose(&file_handle->file);
MACRUM 0:276e7a263c35 1489 // Clean up if possible. Ignore return value.
MACRUM 0:276e7a263c35 1490 (void)pal_fsUnlink(full_path_to_create);
MACRUM 0:276e7a263c35 1491 }
MACRUM 0:276e7a263c35 1492 if(cmac_created)
MACRUM 0:276e7a263c35 1493 {
MACRUM 0:276e7a263c35 1494 uint8_t key[ESFS_CMAC_SIZE_IN_BYTES];
MACRUM 0:276e7a263c35 1495 // Clean up cmac. Ignore error.
MACRUM 0:276e7a263c35 1496 (void)esfs_cmac_finish(file_handle, &key[0]);
MACRUM 0:276e7a263c35 1497 }
MACRUM 0:276e7a263c35 1498
MACRUM 0:276e7a263c35 1499 return result;
MACRUM 0:276e7a263c35 1500 }
MACRUM 0:276e7a263c35 1501
MACRUM 0:276e7a263c35 1502 // ---------------------------------------------------------------
MACRUM 0:276e7a263c35 1503 // API Functions
MACRUM 0:276e7a263c35 1504 // ---------------------------------------------------------------
MACRUM 0:276e7a263c35 1505
MACRUM 0:276e7a263c35 1506
MACRUM 0:276e7a263c35 1507 esfs_result_e esfs_create(const uint8_t *name, size_t name_length, const esfs_tlv_item_t *meta_data, size_t meta_data_qty, uint16_t esfs_mode, esfs_file_t *file_handle)
MACRUM 0:276e7a263c35 1508 {
MACRUM 0:276e7a263c35 1509
MACRUM 0:276e7a263c35 1510 palStatus_t res = PAL_SUCCESS;
MACRUM 0:276e7a263c35 1511 esfs_result_e result = ESFS_ERROR;
MACRUM 0:276e7a263c35 1512
MACRUM 0:276e7a263c35 1513 bool is_aes_ctx_created = false;
MACRUM 0:276e7a263c35 1514
MACRUM 0:276e7a263c35 1515
MACRUM 0:276e7a263c35 1516 // Verify that the structure is always packed to six bytes, since we read and write it as a whole.
MACRUM 0:276e7a263c35 1517 PAL_ASSERT_STATIC(sizeof(esfs_tlvItem_t) == 6);
MACRUM 0:276e7a263c35 1518
MACRUM 0:276e7a263c35 1519 // Verify that the array is always packed without padding, since we read and write it as a whole.
MACRUM 0:276e7a263c35 1520 PAL_ASSERT_STATIC(sizeof(esfs_tlvItem_t[ESFS_MAX_TYPE_LENGTH_VALUES]) == ESFS_MAX_TYPE_LENGTH_VALUES * sizeof(esfs_tlvItem_t));
MACRUM 0:276e7a263c35 1521
MACRUM 0:276e7a263c35 1522 tr_info("esfs_create - enter");
MACRUM 0:276e7a263c35 1523
MACRUM 0:276e7a263c35 1524 // Check parameters
MACRUM 0:276e7a263c35 1525 if (!file_handle || !name || name_length == 0 || name_length > ESFS_MAX_NAME_LENGTH || meta_data_qty > ESFS_MAX_TYPE_LENGTH_VALUES)
MACRUM 0:276e7a263c35 1526 {
MACRUM 0:276e7a263c35 1527 tr_err("esfs_create() failed with bad parameters");
MACRUM 0:276e7a263c35 1528 result = ESFS_INVALID_PARAMETER;
MACRUM 0:276e7a263c35 1529 goto errorExit;
MACRUM 0:276e7a263c35 1530 }
MACRUM 0:276e7a263c35 1531
MACRUM 0:276e7a263c35 1532 // Check the metadata parameter
MACRUM 0:276e7a263c35 1533 for(size_t meta_data_index = 0; meta_data_index < meta_data_qty; meta_data_index++ )
MACRUM 0:276e7a263c35 1534 {
MACRUM 0:276e7a263c35 1535 if ((!meta_data[meta_data_index].value) || (meta_data[meta_data_index].length_in_bytes == 0))
MACRUM 0:276e7a263c35 1536 {
MACRUM 0:276e7a263c35 1537 tr_err("esfs_create() failed with bad parameters for metadata");
MACRUM 0:276e7a263c35 1538 result = ESFS_INVALID_PARAMETER;
MACRUM 0:276e7a263c35 1539 goto errorExit;
MACRUM 0:276e7a263c35 1540 }
MACRUM 0:276e7a263c35 1541 }
MACRUM 0:276e7a263c35 1542
MACRUM 0:276e7a263c35 1543 // If esfs is in encryption mode, make the required initializations
MACRUM 0:276e7a263c35 1544 if((esfs_mode & ESFS_ENCRYPTED) != 0)
MACRUM 0:276e7a263c35 1545 {
MACRUM 0:276e7a263c35 1546 // ** Create AES context for AES encryption
MACRUM 0:276e7a263c35 1547 res = pal_initAes( &(file_handle->aes_ctx) );
MACRUM 0:276e7a263c35 1548
MACRUM 0:276e7a263c35 1549 if(res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 1550 {
MACRUM 0:276e7a263c35 1551 tr_err("esfs_create() - pal_initAes() failed with pal status 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 1552 result = ESFS_ERROR ;
MACRUM 0:276e7a263c35 1553 goto errorExit;
MACRUM 0:276e7a263c35 1554 }
MACRUM 0:276e7a263c35 1555
MACRUM 0:276e7a263c35 1556 is_aes_ctx_created = true;
MACRUM 0:276e7a263c35 1557
MACRUM 0:276e7a263c35 1558 // ** Get AES key from PAL
MACRUM 0:276e7a263c35 1559 // Note: On each call, PAL should return the same 128 bits key
MACRUM 0:276e7a263c35 1560 uint8_t aes_key[ESFS_AES_KEY_SIZE_BYTES]; // For AES encryption
MACRUM 0:276e7a263c35 1561 res = pal_osGetDeviceKey(palOsStorageEncryptionKey128Bit, aes_key, ESFS_AES_KEY_SIZE_BYTES);
MACRUM 0:276e7a263c35 1562
MACRUM 0:276e7a263c35 1563 if(res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 1564 {
MACRUM 0:276e7a263c35 1565 tr_err("esfs_create() - pal_osGetDeviceKey() failed with pal status 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 1566 result = ESFS_ERROR ;
MACRUM 0:276e7a263c35 1567 goto errorExit;
MACRUM 0:276e7a263c35 1568 }
MACRUM 0:276e7a263c35 1569
MACRUM 0:276e7a263c35 1570 // ** Assign generated AES key to AES context
MACRUM 0:276e7a263c35 1571 res = pal_setAesKey( file_handle->aes_ctx,
MACRUM 0:276e7a263c35 1572 aes_key,
MACRUM 0:276e7a263c35 1573 ESFS_AES_KEY_SIZE_BITS,
MACRUM 0:276e7a263c35 1574 PAL_KEY_TARGET_ENCRYPTION
MACRUM 0:276e7a263c35 1575 );
MACRUM 0:276e7a263c35 1576
MACRUM 0:276e7a263c35 1577 if(res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 1578 {
MACRUM 0:276e7a263c35 1579 tr_err("esfs_create() - pal_setAesKey() failed with pal status 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 1580 result = ESFS_ERROR ;
MACRUM 0:276e7a263c35 1581 goto errorExit;
MACRUM 0:276e7a263c35 1582 }
MACRUM 0:276e7a263c35 1583
MACRUM 0:276e7a263c35 1584 // ** Generate the AES nonce for AES usage
MACRUM 0:276e7a263c35 1585 res = pal_osRandomBuffer(file_handle->nonce, ESFS_AES_NONCE_SIZE_BYTES);
MACRUM 0:276e7a263c35 1586
MACRUM 0:276e7a263c35 1587 if(res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 1588 {
MACRUM 0:276e7a263c35 1589 tr_err("esfs_create() - pal_osRandomBuffer() failed with pal status 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 1590 result = ESFS_ERROR ;
MACRUM 0:276e7a263c35 1591 goto errorExit;
MACRUM 0:276e7a263c35 1592 }
MACRUM 0:276e7a263c35 1593 }
MACRUM 0:276e7a263c35 1594
MACRUM 0:276e7a263c35 1595 // We set the blob_name_length field here because it is in use later in this function when we calculate the file header size.
MACRUM 0:276e7a263c35 1596 // Since this field is also used to check the file handle validity [ esfs_validate() ] we set it to zero on an error exit.
MACRUM 0:276e7a263c35 1597 file_handle->blob_name_length = name_length;
MACRUM 0:276e7a263c35 1598
MACRUM 0:276e7a263c35 1599 file_handle->esfs_mode = esfs_mode;
MACRUM 0:276e7a263c35 1600
MACRUM 0:276e7a263c35 1601 file_handle->file_invalid = 0;
MACRUM 0:276e7a263c35 1602
MACRUM 0:276e7a263c35 1603 file_handle->tlv_properties.number_of_items = 0;
MACRUM 0:276e7a263c35 1604
MACRUM 0:276e7a263c35 1605 // Indicate that there is not a signature context yet.
MACRUM 0:276e7a263c35 1606 file_handle->signature_ctx = 0;
MACRUM 0:276e7a263c35 1607
MACRUM 0:276e7a263c35 1608 file_handle->data_size = 0;
MACRUM 0:276e7a263c35 1609
MACRUM 0:276e7a263c35 1610 if (esfs_get_name_from_blob(name, name_length, file_handle->short_file_name, ESFS_FILE_NAME_LENGTH) != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 1611 {
MACRUM 0:276e7a263c35 1612 tr_err("esfs_create() - esfs_get_name_from_blob() failed");
MACRUM 0:276e7a263c35 1613 goto errorExit;
MACRUM 0:276e7a263c35 1614 }
MACRUM 0:276e7a263c35 1615
MACRUM 0:276e7a263c35 1616 // Put working file name in file_full_path
MACRUM 0:276e7a263c35 1617 char file_full_path[MAX_FULL_PATH_SIZE];
MACRUM 0:276e7a263c35 1618 res = pal_fsGetMountPoint(PAL_FS_PARTITION_PRIMARY, PAL_MAX_FOLDER_DEPTH_CHAR + 1, file_full_path);
MACRUM 0:276e7a263c35 1619 if (res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 1620 {
MACRUM 0:276e7a263c35 1621 tr_err("esfs_create() - pal_fsGetMountPoint() for working directory failed with pal_status = 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 1622 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 1623 goto errorExit;
MACRUM 0:276e7a263c35 1624 }
MACRUM 0:276e7a263c35 1625 strncat(file_full_path, "/" ESFS_WORKING_DIRECTORY "/", sizeof(ESFS_WORKING_DIRECTORY) + 1);
MACRUM 0:276e7a263c35 1626 strncat(file_full_path, file_handle->short_file_name, ESFS_QUALIFIED_FILE_NAME_LENGTH - 1);
MACRUM 0:276e7a263c35 1627
MACRUM 0:276e7a263c35 1628
MACRUM 0:276e7a263c35 1629 // Check if the file exists in the working directory (not acceptable)
MACRUM 0:276e7a263c35 1630 // Note that this is just a check. We will only actually open the file later (in esfs_create_internal()).
MACRUM 0:276e7a263c35 1631 res = pal_fsFopen(file_full_path, PAL_FS_FLAG_READONLY, &file_handle->file);
MACRUM 0:276e7a263c35 1632 if (res == PAL_SUCCESS)
MACRUM 0:276e7a263c35 1633 {
MACRUM 0:276e7a263c35 1634 result = ESFS_EXISTS;
MACRUM 0:276e7a263c35 1635 file_handle->esfs_mode = 0;
MACRUM 0:276e7a263c35 1636 // result can be ESFS_HASH_CONFLICT or ESFS_WRONG_FILE_VERSION
MACRUM 0:276e7a263c35 1637 // Check if there is a different name in the file
MACRUM 0:276e7a263c35 1638 // Check that the name written inside the file is the same as that given. If not
MACRUM 0:276e7a263c35 1639 // you should choose a different name.
MACRUM 0:276e7a263c35 1640 esfs_result_e check_result = esfs_check_file_validity(name, name_length, file_handle);
MACRUM 0:276e7a263c35 1641 if (check_result == ESFS_HASH_CONFLICT || check_result == ESFS_INVALID_FILE_VERSION)
MACRUM 0:276e7a263c35 1642 {
MACRUM 0:276e7a263c35 1643 result = check_result;
MACRUM 0:276e7a263c35 1644 }
MACRUM 0:276e7a263c35 1645 pal_fsFclose(&file_handle->file);
MACRUM 0:276e7a263c35 1646 tr_err("esfs_create() - pal_fsFopen() for working dir file failed");
MACRUM 0:276e7a263c35 1647 goto errorExit;
MACRUM 0:276e7a263c35 1648 }
MACRUM 0:276e7a263c35 1649
MACRUM 0:276e7a263c35 1650 // If factory reset file then we make some checks
MACRUM 0:276e7a263c35 1651 if (esfs_mode & (uint16_t)ESFS_FACTORY_VAL)
MACRUM 0:276e7a263c35 1652 {
MACRUM 0:276e7a263c35 1653 // Put backup folder name in file_full_path
MACRUM 0:276e7a263c35 1654 res = pal_fsGetMountPoint(PAL_FS_PARTITION_SECONDARY, PAL_MAX_FOLDER_DEPTH_CHAR + 1, file_full_path);
MACRUM 0:276e7a263c35 1655 if (res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 1656 {
MACRUM 0:276e7a263c35 1657 tr_err("esfs_create() - pal_fsGetMountPoint() for backup directory failed with pal_status = 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 1658 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 1659 goto errorExit;
MACRUM 0:276e7a263c35 1660 }
MACRUM 0:276e7a263c35 1661 strncat(file_full_path, "/" ESFS_BACKUP_DIRECTORY, sizeof(ESFS_BACKUP_DIRECTORY));
MACRUM 0:276e7a263c35 1662
MACRUM 0:276e7a263c35 1663 // Create the esfs subfolder for backup
MACRUM 0:276e7a263c35 1664 res = pal_fsMkDir(file_full_path);
MACRUM 0:276e7a263c35 1665 if (res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 1666 {
MACRUM 0:276e7a263c35 1667 // Any error apart from file exist returns error.
MACRUM 0:276e7a263c35 1668 if (res != PAL_ERR_FS_NAME_ALREADY_EXIST)
MACRUM 0:276e7a263c35 1669 {
MACRUM 0:276e7a263c35 1670 tr_err("esfs_create() - pal_fsMkDir() for backup dir failed with pal status 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 1671 goto errorExit;
MACRUM 0:276e7a263c35 1672 }
MACRUM 0:276e7a263c35 1673 }
MACRUM 0:276e7a263c35 1674
MACRUM 0:276e7a263c35 1675 // Put backup file name in file_full_path
MACRUM 0:276e7a263c35 1676 strcat(file_full_path, "/");
MACRUM 0:276e7a263c35 1677 strncat(file_full_path, file_handle->short_file_name, ESFS_QUALIFIED_FILE_NAME_LENGTH - 1);
MACRUM 0:276e7a263c35 1678
MACRUM 0:276e7a263c35 1679 // Check if the file exists in esfs backup directory (acceptable unless there is a hash conflict for the name)
MACRUM 0:276e7a263c35 1680 res = pal_fsFopen(file_full_path, PAL_FS_FLAG_READONLY, &file_handle->file);
MACRUM 0:276e7a263c35 1681 if (res == PAL_SUCCESS)
MACRUM 0:276e7a263c35 1682 {
MACRUM 0:276e7a263c35 1683 file_handle->esfs_mode = 0;
MACRUM 0:276e7a263c35 1684 // result can be ESFS_HASH_CONFLICT or ESFS_WRONG_FILE_VERSION
MACRUM 0:276e7a263c35 1685 // Check if there is a different name in the file
MACRUM 0:276e7a263c35 1686 // Check that the name written inside the file is the same as that given. If not
MACRUM 0:276e7a263c35 1687 // you should choose a different name.
MACRUM 0:276e7a263c35 1688 esfs_result_e check_result = esfs_check_file_validity(name, name_length, file_handle);
MACRUM 0:276e7a263c35 1689
MACRUM 0:276e7a263c35 1690 // Close the file.
MACRUM 0:276e7a263c35 1691 pal_fsFclose(&file_handle->file);
MACRUM 0:276e7a263c35 1692
MACRUM 0:276e7a263c35 1693 if (check_result == ESFS_HASH_CONFLICT || check_result == ESFS_INVALID_FILE_VERSION)
MACRUM 0:276e7a263c35 1694 {
MACRUM 0:276e7a263c35 1695 tr_err("esfs_create() - esfs_check_file_validity() failed with status 0x%x", check_result);
MACRUM 0:276e7a263c35 1696 result = check_result;
MACRUM 0:276e7a263c35 1697 goto errorExit;
MACRUM 0:276e7a263c35 1698 }
MACRUM 0:276e7a263c35 1699 // It is OK for it to exist, so continue.
MACRUM 0:276e7a263c35 1700 }
MACRUM 0:276e7a263c35 1701 }
MACRUM 0:276e7a263c35 1702
MACRUM 0:276e7a263c35 1703 // Now we actually create the new file.
MACRUM 0:276e7a263c35 1704 // file_full_path contains the correct location (working/backup)
MACRUM 0:276e7a263c35 1705 result = esfs_create_internal(
MACRUM 0:276e7a263c35 1706 name,
MACRUM 0:276e7a263c35 1707 name_length,
MACRUM 0:276e7a263c35 1708 meta_data,
MACRUM 0:276e7a263c35 1709 meta_data_qty,
MACRUM 0:276e7a263c35 1710 esfs_mode,
MACRUM 0:276e7a263c35 1711 file_handle,
MACRUM 0:276e7a263c35 1712 // Working or backup
MACRUM 0:276e7a263c35 1713 file_full_path
MACRUM 0:276e7a263c35 1714 );
MACRUM 0:276e7a263c35 1715 if(result != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 1716 {
MACRUM 0:276e7a263c35 1717 goto errorExit;
MACRUM 0:276e7a263c35 1718 }
MACRUM 0:276e7a263c35 1719
MACRUM 0:276e7a263c35 1720 return ESFS_SUCCESS;
MACRUM 0:276e7a263c35 1721
MACRUM 0:276e7a263c35 1722 errorExit:
MACRUM 0:276e7a263c35 1723
MACRUM 0:276e7a263c35 1724 // Invalidate blob_name_length filed since it is used to check the file handle validity [ esfs_validate() ]
MACRUM 0:276e7a263c35 1725 if(file_handle != NULL)
MACRUM 0:276e7a263c35 1726 {
MACRUM 0:276e7a263c35 1727 file_handle->blob_name_length = 0;
MACRUM 0:276e7a263c35 1728 }
MACRUM 0:276e7a263c35 1729
MACRUM 0:276e7a263c35 1730 if(is_aes_ctx_created)
MACRUM 0:276e7a263c35 1731 {
MACRUM 0:276e7a263c35 1732 pal_freeAes( &(file_handle->aes_ctx) );
MACRUM 0:276e7a263c35 1733 }
MACRUM 0:276e7a263c35 1734 return result;
MACRUM 0:276e7a263c35 1735 }
MACRUM 0:276e7a263c35 1736
MACRUM 0:276e7a263c35 1737 esfs_result_e esfs_open(const uint8_t *name, size_t name_length, uint16_t *esfs_mode, esfs_file_t *file_handle)
MACRUM 0:276e7a263c35 1738 {
MACRUM 0:276e7a263c35 1739 esfs_result_e result = ESFS_ERROR;
MACRUM 0:276e7a263c35 1740 uint16_t file_opened = 0;
MACRUM 0:276e7a263c35 1741 uint16_t cmac_created = 0;
MACRUM 0:276e7a263c35 1742 bool is_aes_ctx_created = false;
MACRUM 0:276e7a263c35 1743 palStatus_t res = PAL_SUCCESS;
MACRUM 0:276e7a263c35 1744
MACRUM 0:276e7a263c35 1745 tr_info("esfs_open - enter");
MACRUM 0:276e7a263c35 1746 // Check parameters
MACRUM 0:276e7a263c35 1747 if(!file_handle || !name || name_length == 0 || name_length > ESFS_MAX_NAME_LENGTH)
MACRUM 0:276e7a263c35 1748 {
MACRUM 0:276e7a263c35 1749 tr_err("esfs_open() failed with bad parameters");
MACRUM 0:276e7a263c35 1750 result = ESFS_INVALID_PARAMETER;
MACRUM 0:276e7a263c35 1751 goto errorExit;
MACRUM 0:276e7a263c35 1752 }
MACRUM 0:276e7a263c35 1753
MACRUM 0:276e7a263c35 1754 char working_dir_path[MAX_FULL_PATH_SIZE];
MACRUM 0:276e7a263c35 1755 res = pal_fsGetMountPoint(PAL_FS_PARTITION_PRIMARY, PAL_MAX_FOLDER_DEPTH_CHAR + 1, working_dir_path);
MACRUM 0:276e7a263c35 1756 if (res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 1757 {
MACRUM 0:276e7a263c35 1758 tr_err("esfs_open() - pal_fsGetMountPoint() for working directory failed with pal_status = 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 1759 return ESFS_ERROR;
MACRUM 0:276e7a263c35 1760 }
MACRUM 0:276e7a263c35 1761
MACRUM 0:276e7a263c35 1762 strncat(working_dir_path, "/" ESFS_WORKING_DIRECTORY "/", sizeof(ESFS_WORKING_DIRECTORY) + 1);
MACRUM 0:276e7a263c35 1763
MACRUM 0:276e7a263c35 1764 // This is used to esfs_validate the file handle so we set it to zero here and only when open
MACRUM 0:276e7a263c35 1765 // succeeds to the real value.
MACRUM 0:276e7a263c35 1766 file_handle->blob_name_length = 0;
MACRUM 0:276e7a263c35 1767
MACRUM 0:276e7a263c35 1768 file_handle->file_invalid = 0;
MACRUM 0:276e7a263c35 1769
MACRUM 0:276e7a263c35 1770 memset(&file_handle->cmac[0], 0, sizeof(file_handle->cmac));
MACRUM 0:276e7a263c35 1771
MACRUM 0:276e7a263c35 1772 if(esfs_get_name_from_blob(name, name_length, file_handle->short_file_name, ESFS_FILE_NAME_LENGTH) != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 1773 {
MACRUM 0:276e7a263c35 1774 tr_err("esfs_open() - esfs_get_name_from_blob() failed");
MACRUM 0:276e7a263c35 1775 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 1776 goto errorExit;
MACRUM 0:276e7a263c35 1777 }
MACRUM 0:276e7a263c35 1778
MACRUM 0:276e7a263c35 1779 strncat(working_dir_path, file_handle->short_file_name, ESFS_QUALIFIED_FILE_NAME_LENGTH - 1);
MACRUM 0:276e7a263c35 1780
MACRUM 0:276e7a263c35 1781 // Open the file read only
MACRUM 0:276e7a263c35 1782 res = pal_fsFopen(working_dir_path, PAL_FS_FLAG_READONLY, &file_handle->file);
MACRUM 0:276e7a263c35 1783 if(res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 1784 {
MACRUM 0:276e7a263c35 1785 // tr_err("esfs_open() - pal_fsFopen() for working dir file failed with pal_status = 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 1786 // File cannot be opened so return an error
MACRUM 0:276e7a263c35 1787 result = ESFS_NOT_EXISTS;
MACRUM 0:276e7a263c35 1788 goto errorExit;
MACRUM 0:276e7a263c35 1789 }
MACRUM 0:276e7a263c35 1790
MACRUM 0:276e7a263c35 1791 file_opened = 1;
MACRUM 0:276e7a263c35 1792
MACRUM 0:276e7a263c35 1793 if(esfs_cmac_start(file_handle) != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 1794 {
MACRUM 0:276e7a263c35 1795 goto errorExit;
MACRUM 0:276e7a263c35 1796 }
MACRUM 0:276e7a263c35 1797 cmac_created = 1;
MACRUM 0:276e7a263c35 1798
MACRUM 0:276e7a263c35 1799 // Check that the name written inside the file is the same as that given
MACRUM 0:276e7a263c35 1800 // Note: After this call, the read position will be set to the point after the "Name Blob"
MACRUM 0:276e7a263c35 1801 result = esfs_check_file_validity(name, name_length, file_handle);
MACRUM 0:276e7a263c35 1802 if(result != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 1803 {
MACRUM 0:276e7a263c35 1804 // the requested file not exists, but exists file with the same short name
MACRUM 0:276e7a263c35 1805 if (result == ESFS_HASH_CONFLICT)
MACRUM 0:276e7a263c35 1806 {
MACRUM 0:276e7a263c35 1807 result = ESFS_NOT_EXISTS;
MACRUM 0:276e7a263c35 1808 }
MACRUM 0:276e7a263c35 1809 tr_err("esfs_open() - esfs_check_file_validity() failed with status = 0x%x", result);
MACRUM 0:276e7a263c35 1810 // File cannot be opened so return an error
MACRUM 0:276e7a263c35 1811 goto errorExit;
MACRUM 0:276e7a263c35 1812 }
MACRUM 0:276e7a263c35 1813
MACRUM 0:276e7a263c35 1814 if (esfs_mode)
MACRUM 0:276e7a263c35 1815 {
MACRUM 0:276e7a263c35 1816 *esfs_mode = file_handle->esfs_mode; // file_handle->esfs_mode was set by esfs_check_file_validity()
MACRUM 0:276e7a263c35 1817 }
MACRUM 0:276e7a263c35 1818
MACRUM 0:276e7a263c35 1819 // If esfs is in encryption mode, make the required initializations
MACRUM 0:276e7a263c35 1820 if((file_handle->esfs_mode & ESFS_ENCRYPTED) != 0)
MACRUM 0:276e7a263c35 1821 {
MACRUM 0:276e7a263c35 1822 // ** Create AES context for AES decryption
MACRUM 0:276e7a263c35 1823 res = pal_initAes( &(file_handle->aes_ctx) );
MACRUM 0:276e7a263c35 1824
MACRUM 0:276e7a263c35 1825 if(res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 1826 {
MACRUM 0:276e7a263c35 1827 tr_err("esfs_open() - pal_initAes() failed with status 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 1828 result = ESFS_ERROR ;
MACRUM 0:276e7a263c35 1829 goto errorExit;
MACRUM 0:276e7a263c35 1830 }
MACRUM 0:276e7a263c35 1831
MACRUM 0:276e7a263c35 1832 is_aes_ctx_created = true;
MACRUM 0:276e7a263c35 1833
MACRUM 0:276e7a263c35 1834 // ** Get AES key from PAL
MACRUM 0:276e7a263c35 1835 // Note: On each call, PAL should return the same 128 bits key
MACRUM 0:276e7a263c35 1836 uint8_t aes_key[ESFS_AES_KEY_SIZE_BYTES];
MACRUM 0:276e7a263c35 1837 res = pal_osGetDeviceKey(palOsStorageEncryptionKey128Bit, aes_key, ESFS_AES_KEY_SIZE_BYTES);
MACRUM 0:276e7a263c35 1838
MACRUM 0:276e7a263c35 1839 if(res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 1840 {
MACRUM 0:276e7a263c35 1841 tr_err("esfs_open() - pal_osGetDeviceKey() failed with status 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 1842 result = ESFS_ERROR ;
MACRUM 0:276e7a263c35 1843 goto errorExit;
MACRUM 0:276e7a263c35 1844 }
MACRUM 0:276e7a263c35 1845
MACRUM 0:276e7a263c35 1846 // ** Assign generated AES key to AES context
MACRUM 0:276e7a263c35 1847 res = pal_setAesKey( file_handle->aes_ctx,
MACRUM 0:276e7a263c35 1848 aes_key,
MACRUM 0:276e7a263c35 1849 ESFS_AES_KEY_SIZE_BITS,
MACRUM 0:276e7a263c35 1850 PAL_KEY_TARGET_ENCRYPTION
MACRUM 0:276e7a263c35 1851 );
MACRUM 0:276e7a263c35 1852
MACRUM 0:276e7a263c35 1853 if(res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 1854 {
MACRUM 0:276e7a263c35 1855 tr_err("esfs_open() - pal_setAesKey() failed with status 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 1856 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 1857 goto errorExit;
MACRUM 0:276e7a263c35 1858 }
MACRUM 0:276e7a263c35 1859
MACRUM 0:276e7a263c35 1860 }
MACRUM 0:276e7a263c35 1861
MACRUM 0:276e7a263c35 1862 size_t num_bytes;
MACRUM 0:276e7a263c35 1863
MACRUM 0:276e7a263c35 1864 // ** Read the AES nonce into file_handle->nonce
MACRUM 0:276e7a263c35 1865 if ((file_handle->esfs_mode & ESFS_ENCRYPTED) != 0)
MACRUM 0:276e7a263c35 1866 {
MACRUM 0:276e7a263c35 1867 result = esfs_cmac_read(file_handle, &file_handle->nonce[0], ESFS_AES_NONCE_SIZE_BYTES, &num_bytes);
MACRUM 0:276e7a263c35 1868 if((result != ESFS_SUCCESS) || (num_bytes != ESFS_AES_NONCE_SIZE_BYTES))
MACRUM 0:276e7a263c35 1869 {
MACRUM 0:276e7a263c35 1870 tr_err("esfs_open() - esfs_cmac_read() (AES nonce) failed with ESFS result = 0x%x and num_bytes bytes = %zu",
MACRUM 0:276e7a263c35 1871 (unsigned int)result, num_bytes);
MACRUM 0:276e7a263c35 1872 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 1873 goto errorExit;
MACRUM 0:276e7a263c35 1874 }
MACRUM 0:276e7a263c35 1875 }
MACRUM 0:276e7a263c35 1876
MACRUM 0:276e7a263c35 1877 file_handle->tlv_properties.number_of_items = 0;
MACRUM 0:276e7a263c35 1878
MACRUM 0:276e7a263c35 1879 // Read the number of items of meta data
MACRUM 0:276e7a263c35 1880 uint16_t meta_data_qty;
MACRUM 0:276e7a263c35 1881 result = esfs_cmac_read(file_handle, (void *)( &meta_data_qty ), sizeof(meta_data_qty), &num_bytes);
MACRUM 0:276e7a263c35 1882 if(result != ESFS_SUCCESS || num_bytes != sizeof(meta_data_qty) || meta_data_qty > ESFS_MAX_TYPE_LENGTH_VALUES)
MACRUM 0:276e7a263c35 1883 {
MACRUM 0:276e7a263c35 1884 tr_err("esfs_open() - esfs_cmac_read() (number of items of meta data) failed with ESFS result = 0x%x and num_bytes bytes = %zu",
MACRUM 0:276e7a263c35 1885 (unsigned int)result, num_bytes);
MACRUM 0:276e7a263c35 1886 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 1887 goto errorExit;
MACRUM 0:276e7a263c35 1888 }
MACRUM 0:276e7a263c35 1889
MACRUM 0:276e7a263c35 1890 // Read the metadata properties if there are any
MACRUM 0:276e7a263c35 1891 if(meta_data_qty != 0)
MACRUM 0:276e7a263c35 1892 {
MACRUM 0:276e7a263c35 1893 result = esfs_cmac_read( file_handle,
MACRUM 0:276e7a263c35 1894 (void *) ( &(file_handle->tlv_properties.tlv_items[0]) ),
MACRUM 0:276e7a263c35 1895 (sizeof(file_handle->tlv_properties.tlv_items[0]) * meta_data_qty),
MACRUM 0:276e7a263c35 1896 &num_bytes
MACRUM 0:276e7a263c35 1897 );
MACRUM 0:276e7a263c35 1898
MACRUM 0:276e7a263c35 1899 if(result != ESFS_SUCCESS || num_bytes != sizeof(file_handle->tlv_properties.tlv_items[0])*meta_data_qty)
MACRUM 0:276e7a263c35 1900 {
MACRUM 0:276e7a263c35 1901 tr_err("esfs_open() - esfs_cmac_read() (metadata properties) failed with ESFS result = 0x%x and num_bytes bytes = %zu",
MACRUM 0:276e7a263c35 1902 (unsigned int)result, num_bytes);
MACRUM 0:276e7a263c35 1903 goto errorExit;
MACRUM 0:276e7a263c35 1904 }
MACRUM 0:276e7a263c35 1905
MACRUM 0:276e7a263c35 1906 // Skip to the start of the data by calculating the last metadata position plus its length
MACRUM 0:276e7a263c35 1907 esfs_tlvItem_t *ptypeLengthValueItem = &file_handle->tlv_properties.tlv_items[meta_data_qty - 1];
MACRUM 0:276e7a263c35 1908
MACRUM 0:276e7a263c35 1909 if(esfs_cmac_skip_to(file_handle, ptypeLengthValueItem->position + ptypeLengthValueItem->length_in_bytes) != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 1910 {
MACRUM 0:276e7a263c35 1911 tr_err("esfs_open() - esfs_cmac_skip_to() failed.");
MACRUM 0:276e7a263c35 1912 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 1913 goto errorExit;
MACRUM 0:276e7a263c35 1914 }
MACRUM 0:276e7a263c35 1915 }
MACRUM 0:276e7a263c35 1916
MACRUM 0:276e7a263c35 1917 file_handle->tlv_properties.number_of_items = meta_data_qty;
MACRUM 0:276e7a263c35 1918
MACRUM 0:276e7a263c35 1919 // We are at the start of the data section
MACRUM 0:276e7a263c35 1920 file_handle->current_read_pos = 0;
MACRUM 0:276e7a263c35 1921
MACRUM 0:276e7a263c35 1922 // Get current position
MACRUM 0:276e7a263c35 1923 int32_t current_pos;
MACRUM 0:276e7a263c35 1924 res = pal_fsFtell(&file_handle->file, &current_pos);
MACRUM 0:276e7a263c35 1925 if (res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 1926 {
MACRUM 0:276e7a263c35 1927 tr_err("esfs_open() - pal_fsFtell() failed with pal_status = 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 1928 goto errorExit;
MACRUM 0:276e7a263c35 1929 }
MACRUM 0:276e7a263c35 1930
MACRUM 0:276e7a263c35 1931 // get the whole file size and store it in the handle
MACRUM 0:276e7a263c35 1932 res = esfs_get_physical_file_size(&file_handle->file, &file_handle->file_size);
MACRUM 0:276e7a263c35 1933 if (res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 1934 {
MACRUM 0:276e7a263c35 1935 tr_err("esfs_open() - esfs_open() failed with status 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 1936 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 1937 goto errorExit;
MACRUM 0:276e7a263c35 1938 }
MACRUM 0:276e7a263c35 1939
MACRUM 0:276e7a263c35 1940 // Skip to the end of the file while calculating the cmac
MACRUM 0:276e7a263c35 1941 if(esfs_cmac_skip_to(file_handle, file_handle->file_size - ESFS_CMAC_SIZE_IN_BYTES) != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 1942 {
MACRUM 0:276e7a263c35 1943 tr_err("esfs_open() - esfs_cmac_skip_to() failed.");
MACRUM 0:276e7a263c35 1944 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 1945 goto errorExit;
MACRUM 0:276e7a263c35 1946 }
MACRUM 0:276e7a263c35 1947
MACRUM 0:276e7a263c35 1948 // Terminate cmac calculation and get it.
MACRUM 0:276e7a263c35 1949 unsigned char cmac[ESFS_CMAC_SIZE_IN_BYTES];
MACRUM 0:276e7a263c35 1950 if(esfs_cmac_finish(file_handle, &cmac[0]) != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 1951 {
MACRUM 0:276e7a263c35 1952 tr_err("esfs_open() - esfs_finish_cmac() failed");
MACRUM 0:276e7a263c35 1953 goto errorExit;
MACRUM 0:276e7a263c35 1954 }
MACRUM 0:276e7a263c35 1955 cmac_created = 0;
MACRUM 0:276e7a263c35 1956
MACRUM 0:276e7a263c35 1957 // save the CMAC in the file descriptor. We will use this to check that the file has not
MACRUM 0:276e7a263c35 1958 // changed when esfs_read() or read_meta_data() is called.
MACRUM 0:276e7a263c35 1959 memcpy(&file_handle->cmac[0],&cmac[0],sizeof(file_handle->cmac));
MACRUM 0:276e7a263c35 1960
MACRUM 0:276e7a263c35 1961 // Check the cmac and set the file position to the start of the data
MACRUM 0:276e7a263c35 1962 if(esfs_cmac_check_and_restore(file_handle, &cmac[0], current_pos) != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 1963 {
MACRUM 0:276e7a263c35 1964 tr_err("esfs_open() - cmac that we read from the file does not match the one that we calculated");
MACRUM 0:276e7a263c35 1965 result = ESFS_CMAC_DOES_NOT_MATCH;
MACRUM 0:276e7a263c35 1966 goto errorExit;
MACRUM 0:276e7a263c35 1967 }
MACRUM 0:276e7a263c35 1968
MACRUM 0:276e7a263c35 1969 // Calculate the size of the data only, by getting the file size and deducting the header and cmac
MACRUM 0:276e7a263c35 1970 file_handle->data_size = file_handle->file_size - esfs_file_header_size(file_handle);
MACRUM 0:276e7a263c35 1971
MACRUM 0:276e7a263c35 1972 // We deduct the cmac bytes at the end of the file since they are not part of the data
MACRUM 0:276e7a263c35 1973 file_handle->data_size -= ESFS_CMAC_SIZE_IN_BYTES;
MACRUM 0:276e7a263c35 1974
MACRUM 0:276e7a263c35 1975 file_handle->file_flag = ESFS_READ;
MACRUM 0:276e7a263c35 1976 file_handle->blob_name_length = name_length;
MACRUM 0:276e7a263c35 1977
MACRUM 0:276e7a263c35 1978 return ESFS_SUCCESS;
MACRUM 0:276e7a263c35 1979
MACRUM 0:276e7a263c35 1980 errorExit:
MACRUM 0:276e7a263c35 1981 if(file_opened)
MACRUM 0:276e7a263c35 1982 {
MACRUM 0:276e7a263c35 1983 pal_fsFclose(&file_handle->file);
MACRUM 0:276e7a263c35 1984 }
MACRUM 0:276e7a263c35 1985 if(is_aes_ctx_created)
MACRUM 0:276e7a263c35 1986 {
MACRUM 0:276e7a263c35 1987 pal_freeAes( &(file_handle->aes_ctx) );
MACRUM 0:276e7a263c35 1988 }
MACRUM 0:276e7a263c35 1989 if(cmac_created)
MACRUM 0:276e7a263c35 1990 {
MACRUM 0:276e7a263c35 1991 // Clean up cmac. Ignore error.
MACRUM 0:276e7a263c35 1992 (void)esfs_cmac_finish(file_handle, &cmac[0]);
MACRUM 0:276e7a263c35 1993 }
MACRUM 0:276e7a263c35 1994
MACRUM 0:276e7a263c35 1995 return result;
MACRUM 0:276e7a263c35 1996 }
MACRUM 0:276e7a263c35 1997
MACRUM 0:276e7a263c35 1998 esfs_result_e esfs_write(esfs_file_t *file_handle, const void *buffer, size_t bytes_to_write)
MACRUM 0:276e7a263c35 1999 {
MACRUM 0:276e7a263c35 2000 esfs_result_e result = ESFS_ERROR;
MACRUM 0:276e7a263c35 2001
MACRUM 0:276e7a263c35 2002 tr_info("esfs_write - enter");
MACRUM 0:276e7a263c35 2003 if((esfs_validate(file_handle) != ESFS_SUCCESS) || (!buffer) || (bytes_to_write == 0))
MACRUM 0:276e7a263c35 2004 {
MACRUM 0:276e7a263c35 2005 tr_err("esfs_write() failed with bad parameters");
MACRUM 0:276e7a263c35 2006 return ESFS_INVALID_PARAMETER;
MACRUM 0:276e7a263c35 2007 }
MACRUM 0:276e7a263c35 2008
MACRUM 0:276e7a263c35 2009 if(file_handle->file_flag == ESFS_READ)
MACRUM 0:276e7a263c35 2010 {
MACRUM 0:276e7a263c35 2011 tr_err("esfs_write() write failed - file is opened for read only");
MACRUM 0:276e7a263c35 2012 result = ESFS_FILE_OPEN_FOR_READ;
MACRUM 0:276e7a263c35 2013 goto errorExit;
MACRUM 0:276e7a263c35 2014 }
MACRUM 0:276e7a263c35 2015 else
MACRUM 0:276e7a263c35 2016 {
MACRUM 0:276e7a263c35 2017 // Write data
MACRUM 0:276e7a263c35 2018 // If encrypted esfs is requested (file_handle->esfs_mode), then this part should be encrypted
MACRUM 0:276e7a263c35 2019
MACRUM 0:276e7a263c35 2020 // The data should be encrypted if the encrypted esfs is requested by the esfs_mode argument
MACRUM 0:276e7a263c35 2021 if((file_handle->esfs_mode & ESFS_ENCRYPTED) != 0)
MACRUM 0:276e7a263c35 2022 {
MACRUM 0:276e7a263c35 2023 result = esfs_encrypt_fwrite_and_calc_cmac(buffer, bytes_to_write, file_handle);
MACRUM 0:276e7a263c35 2024 }
MACRUM 0:276e7a263c35 2025 else
MACRUM 0:276e7a263c35 2026 {
MACRUM 0:276e7a263c35 2027 result = esfs_fwrite_and_calc_cmac(buffer, bytes_to_write, file_handle);
MACRUM 0:276e7a263c35 2028 }
MACRUM 0:276e7a263c35 2029
MACRUM 0:276e7a263c35 2030 if(result != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 2031 {
MACRUM 0:276e7a263c35 2032 tr_err("esfs_write() - esfs_fwrite_and_calc_cmac()/esfs_encrypt_fwrite_and_calc_cmac() for data failed with esfs result = 0x%x", result);
MACRUM 0:276e7a263c35 2033 // Since the write failed, we cannot be sure of the state of the file, so we mark it as invalid.
MACRUM 0:276e7a263c35 2034 file_handle->file_invalid = 1;
MACRUM 0:276e7a263c35 2035 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 2036 goto errorExit;
MACRUM 0:276e7a263c35 2037 }
MACRUM 0:276e7a263c35 2038 }
MACRUM 0:276e7a263c35 2039
MACRUM 0:276e7a263c35 2040 file_handle->data_size += bytes_to_write;
MACRUM 0:276e7a263c35 2041
MACRUM 0:276e7a263c35 2042 return ESFS_SUCCESS;
MACRUM 0:276e7a263c35 2043
MACRUM 0:276e7a263c35 2044 errorExit:
MACRUM 0:276e7a263c35 2045 return result;
MACRUM 0:276e7a263c35 2046 }
MACRUM 0:276e7a263c35 2047
MACRUM 0:276e7a263c35 2048 esfs_result_e esfs_read(esfs_file_t *file_handle, void *buffer, size_t bytes_to_read, size_t *read_bytes)
MACRUM 0:276e7a263c35 2049 {
MACRUM 0:276e7a263c35 2050 esfs_result_e result = ESFS_ERROR;
MACRUM 0:276e7a263c35 2051 uint16_t cmac_created = 0;
MACRUM 0:276e7a263c35 2052 size_t remaining_bytes = 0;
MACRUM 0:276e7a263c35 2053 palStatus_t res = PAL_SUCCESS;
MACRUM 0:276e7a263c35 2054
MACRUM 0:276e7a263c35 2055 tr_info("esfs_read - enter");
MACRUM 0:276e7a263c35 2056 if(esfs_validate(file_handle) != ESFS_SUCCESS || read_bytes == NULL || !buffer)
MACRUM 0:276e7a263c35 2057 {
MACRUM 0:276e7a263c35 2058 result = ESFS_INVALID_PARAMETER;
MACRUM 0:276e7a263c35 2059 goto errorExit;
MACRUM 0:276e7a263c35 2060 }
MACRUM 0:276e7a263c35 2061
MACRUM 0:276e7a263c35 2062 if(file_handle->file_flag != ESFS_READ)
MACRUM 0:276e7a263c35 2063 {
MACRUM 0:276e7a263c35 2064 result = ESFS_FILE_OPEN_FOR_WRITE;
MACRUM 0:276e7a263c35 2065 goto errorExit;
MACRUM 0:276e7a263c35 2066 }
MACRUM 0:276e7a263c35 2067 // Save file position
MACRUM 0:276e7a263c35 2068 int32_t position;
MACRUM 0:276e7a263c35 2069 res = pal_fsFtell(&file_handle->file, &position);
MACRUM 0:276e7a263c35 2070 if(res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 2071 {
MACRUM 0:276e7a263c35 2072 tr_err("esfs_read() - pal_fsFtell() failed with pal status 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 2073 goto errorExit;
MACRUM 0:276e7a263c35 2074 }
MACRUM 0:276e7a263c35 2075
MACRUM 0:276e7a263c35 2076 // Limit how many bytes we can actually read depending on the size of the data section.
MACRUM 0:276e7a263c35 2077 remaining_bytes = file_handle->data_size - file_handle->current_read_pos;
MACRUM 0:276e7a263c35 2078 bytes_to_read = PAL_MIN(remaining_bytes, bytes_to_read);
MACRUM 0:276e7a263c35 2079
MACRUM 0:276e7a263c35 2080 if(esfs_cmac_start(file_handle) != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 2081 {
MACRUM 0:276e7a263c35 2082 goto errorExit;
MACRUM 0:276e7a263c35 2083 }
MACRUM 0:276e7a263c35 2084 cmac_created = 1;
MACRUM 0:276e7a263c35 2085
MACRUM 0:276e7a263c35 2086 if(esfs_cmac_skip_to(file_handle, position) != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 2087 {
MACRUM 0:276e7a263c35 2088 goto errorExit;
MACRUM 0:276e7a263c35 2089 }
MACRUM 0:276e7a263c35 2090
MACRUM 0:276e7a263c35 2091 // Read data
MACRUM 0:276e7a263c35 2092 // If required according to esfs_mode, the read data will be decrypted
MACRUM 0:276e7a263c35 2093 size_t num_bytes;
MACRUM 0:276e7a263c35 2094 if((file_handle->esfs_mode & ESFS_ENCRYPTED) != 0)
MACRUM 0:276e7a263c35 2095 {
MACRUM 0:276e7a263c35 2096 if(esfs_read_and_decrypt(file_handle, buffer, bytes_to_read, &num_bytes) != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 2097 {
MACRUM 0:276e7a263c35 2098 goto errorExit;
MACRUM 0:276e7a263c35 2099 }
MACRUM 0:276e7a263c35 2100 }
MACRUM 0:276e7a263c35 2101 else
MACRUM 0:276e7a263c35 2102 {
MACRUM 0:276e7a263c35 2103 if(esfs_cmac_read(file_handle, buffer, bytes_to_read, &num_bytes ) != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 2104 {
MACRUM 0:276e7a263c35 2105 goto errorExit;
MACRUM 0:276e7a263c35 2106 }
MACRUM 0:276e7a263c35 2107 }
MACRUM 0:276e7a263c35 2108
MACRUM 0:276e7a263c35 2109 *read_bytes = num_bytes;
MACRUM 0:276e7a263c35 2110
MACRUM 0:276e7a263c35 2111 if(esfs_cmac_skip_to(file_handle ,file_handle->file_size - ESFS_CMAC_SIZE_IN_BYTES) != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 2112 {
MACRUM 0:276e7a263c35 2113 goto errorExit;
MACRUM 0:276e7a263c35 2114 }
MACRUM 0:276e7a263c35 2115
MACRUM 0:276e7a263c35 2116 unsigned char cmac[ESFS_CMAC_SIZE_IN_BYTES];
MACRUM 0:276e7a263c35 2117 if(esfs_cmac_finish(file_handle, &cmac[0]) != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 2118 {
MACRUM 0:276e7a263c35 2119 tr_err("esfs_read() - esfs_finish_cmac() failed");
MACRUM 0:276e7a263c35 2120 goto errorExit;
MACRUM 0:276e7a263c35 2121 }
MACRUM 0:276e7a263c35 2122 cmac_created = 0;
MACRUM 0:276e7a263c35 2123
MACRUM 0:276e7a263c35 2124 // Check the cmac and set to the byte after the end of the data being read.
MACRUM 0:276e7a263c35 2125 if(esfs_cmac_check_and_restore(file_handle, &cmac[0], position + num_bytes) != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 2126 {
MACRUM 0:276e7a263c35 2127 tr_err("esfs_read() - cmac that we read from the file does not match the one that we calculated");
MACRUM 0:276e7a263c35 2128 result = ESFS_CMAC_DOES_NOT_MATCH;
MACRUM 0:276e7a263c35 2129 goto errorExit;
MACRUM 0:276e7a263c35 2130 }
MACRUM 0:276e7a263c35 2131
MACRUM 0:276e7a263c35 2132 // Update the current position
MACRUM 0:276e7a263c35 2133 file_handle->current_read_pos += num_bytes;
MACRUM 0:276e7a263c35 2134
MACRUM 0:276e7a263c35 2135 return ESFS_SUCCESS;
MACRUM 0:276e7a263c35 2136
MACRUM 0:276e7a263c35 2137 errorExit:
MACRUM 0:276e7a263c35 2138 tr_err("esfs_read errorExit result=0x%x", result);
MACRUM 0:276e7a263c35 2139 if(cmac_created)
MACRUM 0:276e7a263c35 2140 {
MACRUM 0:276e7a263c35 2141 // Clean up cmac. Ignore error and resulting cmac.
MACRUM 0:276e7a263c35 2142 (void)esfs_cmac_finish(file_handle, &cmac[0]);
MACRUM 0:276e7a263c35 2143 }
MACRUM 0:276e7a263c35 2144
MACRUM 0:276e7a263c35 2145 return result;
MACRUM 0:276e7a263c35 2146 }
MACRUM 0:276e7a263c35 2147
MACRUM 0:276e7a263c35 2148 esfs_result_e esfs_seek(esfs_file_t *file_handle, int32_t offset, esfs_seek_origin_e whence, uint32_t *position)
MACRUM 0:276e7a263c35 2149 {
MACRUM 0:276e7a263c35 2150 esfs_result_e result = ESFS_ERROR;
MACRUM 0:276e7a263c35 2151 palStatus_t res = PAL_SUCCESS;
MACRUM 0:276e7a263c35 2152 tr_info("esfs_seek - enter");
MACRUM 0:276e7a263c35 2153 if(esfs_validate(file_handle) != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 2154 {
MACRUM 0:276e7a263c35 2155 tr_err("esfs_seek() failed with bad parameters");
MACRUM 0:276e7a263c35 2156 return ESFS_INVALID_PARAMETER;
MACRUM 0:276e7a263c35 2157 }
MACRUM 0:276e7a263c35 2158
MACRUM 0:276e7a263c35 2159 if(file_handle->file_flag != ESFS_READ)
MACRUM 0:276e7a263c35 2160 {
MACRUM 0:276e7a263c35 2161 tr_err("esfs_seek() seek failed - file is opened for write only");
MACRUM 0:276e7a263c35 2162 result = ESFS_FILE_OPEN_FOR_WRITE;
MACRUM 0:276e7a263c35 2163 goto errorExit;
MACRUM 0:276e7a263c35 2164 }
MACRUM 0:276e7a263c35 2165 pal_fsOffset_t pal_whence;
MACRUM 0:276e7a263c35 2166 // ESFS whence enum values are in sync with those of pal
MACRUM 0:276e7a263c35 2167 if(whence == ESFS_SEEK_SET)
MACRUM 0:276e7a263c35 2168 {
MACRUM 0:276e7a263c35 2169 if(offset > (int32_t)file_handle->data_size || offset < 0)
MACRUM 0:276e7a263c35 2170 {
MACRUM 0:276e7a263c35 2171 tr_err("esfs_seek() failed with bad parameters in offset calculation : ESFS_SEEK_SET");
MACRUM 0:276e7a263c35 2172 result = ESFS_INVALID_PARAMETER;
MACRUM 0:276e7a263c35 2173 goto errorExit;
MACRUM 0:276e7a263c35 2174 }
MACRUM 0:276e7a263c35 2175 // Add the offset to the start of the data
MACRUM 0:276e7a263c35 2176 offset += esfs_file_header_size(file_handle);
MACRUM 0:276e7a263c35 2177 pal_whence = PAL_FS_OFFSET_SEEKSET;
MACRUM 0:276e7a263c35 2178 }
MACRUM 0:276e7a263c35 2179 else if(whence == ESFS_SEEK_END)
MACRUM 0:276e7a263c35 2180 {
MACRUM 0:276e7a263c35 2181 if(offset < -(int32_t)file_handle->data_size || offset > 0)
MACRUM 0:276e7a263c35 2182 {
MACRUM 0:276e7a263c35 2183 tr_err("esfs_seek() failed with bad parameters in offset calculation : ESFS_SEEK_END");
MACRUM 0:276e7a263c35 2184 result = ESFS_INVALID_PARAMETER;
MACRUM 0:276e7a263c35 2185 goto errorExit;
MACRUM 0:276e7a263c35 2186 }
MACRUM 0:276e7a263c35 2187 // Deduct the cmac size from the offset because it is located after the data section.
MACRUM 0:276e7a263c35 2188 offset -= ESFS_CMAC_SIZE_IN_BYTES;
MACRUM 0:276e7a263c35 2189 pal_whence = PAL_FS_OFFSET_SEEKEND;
MACRUM 0:276e7a263c35 2190 }
MACRUM 0:276e7a263c35 2191 else if(whence == ESFS_SEEK_CUR)
MACRUM 0:276e7a263c35 2192 {
MACRUM 0:276e7a263c35 2193 if(offset + file_handle->current_read_pos > (int32_t)file_handle->data_size || offset + (int32_t)file_handle->current_read_pos < 0)
MACRUM 0:276e7a263c35 2194 {
MACRUM 0:276e7a263c35 2195 tr_err("esfs_seek() failed with bad parameters in offset calculation : ESFS_SEEK_CUR");
MACRUM 0:276e7a263c35 2196 result = ESFS_INVALID_PARAMETER;
MACRUM 0:276e7a263c35 2197 goto errorExit;
MACRUM 0:276e7a263c35 2198 }
MACRUM 0:276e7a263c35 2199 pal_whence = PAL_FS_OFFSET_SEEKCUR;
MACRUM 0:276e7a263c35 2200 }
MACRUM 0:276e7a263c35 2201 else
MACRUM 0:276e7a263c35 2202 {
MACRUM 0:276e7a263c35 2203 tr_err("esfs_seek() failed with bad parameters - wrong whence");
MACRUM 0:276e7a263c35 2204 result = ESFS_INVALID_PARAMETER;
MACRUM 0:276e7a263c35 2205 goto errorExit;
MACRUM 0:276e7a263c35 2206 }
MACRUM 0:276e7a263c35 2207 res = pal_fsFseek(&file_handle->file, offset, pal_whence);
MACRUM 0:276e7a263c35 2208 if(res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 2209 {
MACRUM 0:276e7a263c35 2210 tr_err("esfs_seek() - pal_fsFseek() failed with pal status 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 2211 goto errorExit;
MACRUM 0:276e7a263c35 2212 }
MACRUM 0:276e7a263c35 2213 // Get current position if position is not NULL
MACRUM 0:276e7a263c35 2214 if(position)
MACRUM 0:276e7a263c35 2215 {
MACRUM 0:276e7a263c35 2216 res = pal_fsFtell(&file_handle->file, (int32_t *)position);
MACRUM 0:276e7a263c35 2217 if(res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 2218 {
MACRUM 0:276e7a263c35 2219 tr_err("esfs_seek() - pal_fsFtell() failed with pal status 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 2220 goto errorExit;
MACRUM 0:276e7a263c35 2221 }
MACRUM 0:276e7a263c35 2222
MACRUM 0:276e7a263c35 2223 // Ignore the file header data
MACRUM 0:276e7a263c35 2224 *position -= esfs_file_header_size(file_handle);
MACRUM 0:276e7a263c35 2225
MACRUM 0:276e7a263c35 2226 // Update the current position
MACRUM 0:276e7a263c35 2227 file_handle->current_read_pos = *position;
MACRUM 0:276e7a263c35 2228 }
MACRUM 0:276e7a263c35 2229
MACRUM 0:276e7a263c35 2230 return ESFS_SUCCESS;
MACRUM 0:276e7a263c35 2231
MACRUM 0:276e7a263c35 2232 errorExit:
MACRUM 0:276e7a263c35 2233 return result;
MACRUM 0:276e7a263c35 2234 }
MACRUM 0:276e7a263c35 2235
MACRUM 0:276e7a263c35 2236
MACRUM 0:276e7a263c35 2237 esfs_result_e esfs_file_size(esfs_file_t *file_handle, size_t *size_in_bytes)
MACRUM 0:276e7a263c35 2238 {
MACRUM 0:276e7a263c35 2239 esfs_result_e result = ESFS_ERROR;
MACRUM 0:276e7a263c35 2240
MACRUM 0:276e7a263c35 2241 tr_info("esfs_file_size - enter");
MACRUM 0:276e7a263c35 2242 if((esfs_validate(file_handle) != ESFS_SUCCESS) || (!size_in_bytes))
MACRUM 0:276e7a263c35 2243 {
MACRUM 0:276e7a263c35 2244 tr_err("esfs_file_size() failed with bad parameters");
MACRUM 0:276e7a263c35 2245 result = ESFS_INVALID_PARAMETER;
MACRUM 0:276e7a263c35 2246 goto errorExit;
MACRUM 0:276e7a263c35 2247 }
MACRUM 0:276e7a263c35 2248
MACRUM 0:276e7a263c35 2249 *size_in_bytes = file_handle->data_size;
MACRUM 0:276e7a263c35 2250
MACRUM 0:276e7a263c35 2251 return ESFS_SUCCESS;
MACRUM 0:276e7a263c35 2252
MACRUM 0:276e7a263c35 2253 errorExit:
MACRUM 0:276e7a263c35 2254 return result;
MACRUM 0:276e7a263c35 2255 }
MACRUM 0:276e7a263c35 2256
MACRUM 0:276e7a263c35 2257 esfs_result_e esfs_close(esfs_file_t *file_handle)
MACRUM 0:276e7a263c35 2258 {
MACRUM 0:276e7a263c35 2259 uint16_t failed_to_write_CMAC = 0;
MACRUM 0:276e7a263c35 2260 uint16_t file_esfs_mode = 0;
MACRUM 0:276e7a263c35 2261 esfs_file_flag_e esfs_file_flag = 0;
MACRUM 0:276e7a263c35 2262 char esfs_short_file_name[ESFS_QUALIFIED_FILE_NAME_LENGTH] = {0};
MACRUM 0:276e7a263c35 2263 esfs_result_e result = ESFS_ERROR;
MACRUM 0:276e7a263c35 2264 char full_path_working_dir[MAX_FULL_PATH_SIZE];
MACRUM 0:276e7a263c35 2265 palStatus_t res = PAL_SUCCESS;
MACRUM 0:276e7a263c35 2266
MACRUM 0:276e7a263c35 2267 tr_info("esfs_close - enter");
MACRUM 0:276e7a263c35 2268 if(esfs_validate(file_handle) != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 2269 {
MACRUM 0:276e7a263c35 2270 tr_err("esfs_close() failed with bad parameters");
MACRUM 0:276e7a263c35 2271 result = ESFS_INVALID_PARAMETER;
MACRUM 0:276e7a263c35 2272 goto errorExit;
MACRUM 0:276e7a263c35 2273 }
MACRUM 0:276e7a263c35 2274
MACRUM 0:276e7a263c35 2275 res = pal_fsGetMountPoint(PAL_FS_PARTITION_PRIMARY, PAL_MAX_FOLDER_DEPTH_CHAR + 1, full_path_working_dir);
MACRUM 0:276e7a263c35 2276 if (res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 2277 {
MACRUM 0:276e7a263c35 2278 tr_err("esfs_close() - pal_fsGetMountPoint() for working directory failed with pal_status = 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 2279 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 2280 goto errorExit;
MACRUM 0:276e7a263c35 2281 }
MACRUM 0:276e7a263c35 2282
MACRUM 0:276e7a263c35 2283 strncat(full_path_working_dir, "/" ESFS_WORKING_DIRECTORY "/", sizeof(ESFS_WORKING_DIRECTORY) + 1);
MACRUM 0:276e7a263c35 2284
MACRUM 0:276e7a263c35 2285
MACRUM 0:276e7a263c35 2286 // Close AES context if needed
MACRUM 0:276e7a263c35 2287 if((file_handle->esfs_mode & ESFS_ENCRYPTED) != 0)
MACRUM 0:276e7a263c35 2288 {
MACRUM 0:276e7a263c35 2289 pal_freeAes( &(file_handle->aes_ctx) );
MACRUM 0:276e7a263c35 2290 }
MACRUM 0:276e7a263c35 2291
MACRUM 0:276e7a263c35 2292 esfs_file_flag = file_handle->file_flag;
MACRUM 0:276e7a263c35 2293 file_esfs_mode = file_handle->esfs_mode;
MACRUM 0:276e7a263c35 2294 strncpy(esfs_short_file_name, file_handle->short_file_name, ESFS_QUALIFIED_FILE_NAME_LENGTH - 1);
MACRUM 0:276e7a263c35 2295
MACRUM 0:276e7a263c35 2296 if(file_handle->file_flag == ESFS_WRITE)
MACRUM 0:276e7a263c35 2297 {
MACRUM 0:276e7a263c35 2298 unsigned char cmac[ESFS_CMAC_SIZE_IN_BYTES];
MACRUM 0:276e7a263c35 2299 // Finish signature calculation
MACRUM 0:276e7a263c35 2300 if(esfs_cmac_finish(file_handle, &cmac[0]) != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 2301 {
MACRUM 0:276e7a263c35 2302 tr_err("esfs_close() - esfs_cmac_finish() failed");
MACRUM 0:276e7a263c35 2303 goto errorExit;
MACRUM 0:276e7a263c35 2304 }
MACRUM 0:276e7a263c35 2305 // Write signature
MACRUM 0:276e7a263c35 2306 size_t bytes_written;
MACRUM 0:276e7a263c35 2307 res = pal_fsFwrite(&file_handle->file, &cmac[0], sizeof(cmac), &bytes_written);
MACRUM 0:276e7a263c35 2308 if(res != PAL_SUCCESS || sizeof(cmac) != bytes_written)
MACRUM 0:276e7a263c35 2309 {
MACRUM 0:276e7a263c35 2310 tr_err("esfs_close() - pal_fsFwrite() (signature) failed with pal result = 0x%x and bytes_written bytes = %zu",
MACRUM 0:276e7a263c35 2311 (unsigned int)res, bytes_written);
MACRUM 0:276e7a263c35 2312 // mark the file invalid on a failed write
MACRUM 0:276e7a263c35 2313 file_handle->file_invalid = 1;
MACRUM 0:276e7a263c35 2314 // Continue so that we delete the file, but we should return failure later
MACRUM 0:276e7a263c35 2315 failed_to_write_CMAC = 1;
MACRUM 0:276e7a263c35 2316 }
MACRUM 0:276e7a263c35 2317 }
MACRUM 0:276e7a263c35 2318
MACRUM 0:276e7a263c35 2319 res = pal_fsFclose(&file_handle->file);
MACRUM 0:276e7a263c35 2320 if(res == PAL_SUCCESS)
MACRUM 0:276e7a263c35 2321 {
MACRUM 0:276e7a263c35 2322 // Remove a file that is invalid. It may have become invalid due to a failed write.
MACRUM 0:276e7a263c35 2323 if(file_handle->file_invalid)
MACRUM 0:276e7a263c35 2324 {
MACRUM 0:276e7a263c35 2325 strncat(full_path_working_dir,file_handle->short_file_name, ESFS_QUALIFIED_FILE_NAME_LENGTH - 1);
MACRUM 0:276e7a263c35 2326
MACRUM 0:276e7a263c35 2327 res = pal_fsUnlink(full_path_working_dir);
MACRUM 0:276e7a263c35 2328 if(res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 2329 {
MACRUM 0:276e7a263c35 2330 tr_err("esfs_close() - pal_fsUnlink() failed with pal status 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 2331 goto errorExit;
MACRUM 0:276e7a263c35 2332 }
MACRUM 0:276e7a263c35 2333 }
MACRUM 0:276e7a263c35 2334 }
MACRUM 0:276e7a263c35 2335 else
MACRUM 0:276e7a263c35 2336 {
MACRUM 0:276e7a263c35 2337 tr_err("esfs_close() - pal_fsFclose() failed with pal status 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 2338 goto errorExit;
MACRUM 0:276e7a263c35 2339 }
MACRUM 0:276e7a263c35 2340
MACRUM 0:276e7a263c35 2341 if(failed_to_write_CMAC)
MACRUM 0:276e7a263c35 2342 {
MACRUM 0:276e7a263c35 2343 goto errorExit;
MACRUM 0:276e7a263c35 2344 }
MACRUM 0:276e7a263c35 2345
MACRUM 0:276e7a263c35 2346
MACRUM 0:276e7a263c35 2347 if ((file_esfs_mode & ESFS_FACTORY_VAL) && (esfs_file_flag == ESFS_WRITE) && !(file_handle->file_invalid))
MACRUM 0:276e7a263c35 2348 {
MACRUM 0:276e7a263c35 2349 char full_path_backup_dir[MAX_FULL_PATH_SIZE] = { 0 };
MACRUM 0:276e7a263c35 2350
MACRUM 0:276e7a263c35 2351 res = pal_fsGetMountPoint(PAL_FS_PARTITION_SECONDARY, PAL_MAX_FOLDER_DEPTH_CHAR + 1, full_path_backup_dir);
MACRUM 0:276e7a263c35 2352 if (res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 2353 {
MACRUM 0:276e7a263c35 2354 tr_err("esfs_close() - pal_fsGetMountPoint() for backup directory failed with pal_status = 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 2355 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 2356 goto errorExit;
MACRUM 0:276e7a263c35 2357 }
MACRUM 0:276e7a263c35 2358
MACRUM 0:276e7a263c35 2359 strncat(full_path_backup_dir, "/" ESFS_BACKUP_DIRECTORY "/", sizeof(ESFS_BACKUP_DIRECTORY) + 1);
MACRUM 0:276e7a263c35 2360
MACRUM 0:276e7a263c35 2361 strncat(full_path_working_dir, esfs_short_file_name, ESFS_QUALIFIED_FILE_NAME_LENGTH -1);
MACRUM 0:276e7a263c35 2362 strncat(full_path_backup_dir, esfs_short_file_name, ESFS_QUALIFIED_FILE_NAME_LENGTH - 1);
MACRUM 0:276e7a263c35 2363
MACRUM 0:276e7a263c35 2364 if (esfs_copy_file(full_path_backup_dir, full_path_working_dir) != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 2365 {
MACRUM 0:276e7a263c35 2366 tr_err("esfs_close() - esfs_copy_file() failed");
MACRUM 0:276e7a263c35 2367 goto errorExit;
MACRUM 0:276e7a263c35 2368 }
MACRUM 0:276e7a263c35 2369 }
MACRUM 0:276e7a263c35 2370
MACRUM 0:276e7a263c35 2371 return ESFS_SUCCESS;
MACRUM 0:276e7a263c35 2372 errorExit:
MACRUM 0:276e7a263c35 2373 return result;
MACRUM 0:276e7a263c35 2374 }
MACRUM 0:276e7a263c35 2375
MACRUM 0:276e7a263c35 2376 esfs_result_e esfs_delete(const uint8_t *name, size_t name_length)
MACRUM 0:276e7a263c35 2377 {
MACRUM 0:276e7a263c35 2378
MACRUM 0:276e7a263c35 2379 palStatus_t pal_result = PAL_SUCCESS;
MACRUM 0:276e7a263c35 2380 char working_dir_path[MAX_FULL_PATH_SIZE] = { 0 };
MACRUM 0:276e7a263c35 2381 char short_file_name[ESFS_QUALIFIED_FILE_NAME_LENGTH];
MACRUM 0:276e7a263c35 2382 esfs_result_e result = ESFS_ERROR;
MACRUM 0:276e7a263c35 2383
MACRUM 0:276e7a263c35 2384 tr_info("esfs_delete - enter");
MACRUM 0:276e7a263c35 2385 // Check parameters
MACRUM 0:276e7a263c35 2386 if(!name || name_length == 0)
MACRUM 0:276e7a263c35 2387 {
MACRUM 0:276e7a263c35 2388 tr_err("esfs_delete() failed with bad parameters");
MACRUM 0:276e7a263c35 2389 result = ESFS_INVALID_PARAMETER;
MACRUM 0:276e7a263c35 2390 goto errorExit;
MACRUM 0:276e7a263c35 2391 }
MACRUM 0:276e7a263c35 2392 if(esfs_get_name_from_blob(name, name_length, short_file_name, ESFS_FILE_NAME_LENGTH ) != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 2393 {
MACRUM 0:276e7a263c35 2394 tr_err("esfs_delete() - esfs_get_name_from_blob() failed");
MACRUM 0:276e7a263c35 2395 goto errorExit;
MACRUM 0:276e7a263c35 2396 }
MACRUM 0:276e7a263c35 2397 tr_info("esfs_delete %s", short_file_name);
MACRUM 0:276e7a263c35 2398
MACRUM 0:276e7a263c35 2399 pal_result = pal_fsGetMountPoint(PAL_FS_PARTITION_PRIMARY, PAL_MAX_FOLDER_DEPTH_CHAR + 1, working_dir_path);
MACRUM 0:276e7a263c35 2400 if (pal_result != PAL_SUCCESS)
MACRUM 0:276e7a263c35 2401 {
MACRUM 0:276e7a263c35 2402 tr_err("esfs_delete() - pal_fsGetMountPoint() for working directory failed with pal_status = 0x%x", (unsigned int)pal_result);
MACRUM 0:276e7a263c35 2403 result = ESFS_ERROR;
MACRUM 0:276e7a263c35 2404 goto errorExit;
MACRUM 0:276e7a263c35 2405 }
MACRUM 0:276e7a263c35 2406
MACRUM 0:276e7a263c35 2407 strncat(working_dir_path, "/" ESFS_WORKING_DIRECTORY "/", sizeof(ESFS_WORKING_DIRECTORY) + 1);
MACRUM 0:276e7a263c35 2408
MACRUM 0:276e7a263c35 2409 // We do not verify that name is the actual name in the file because currently we do not allow the situation of hash
MACRUM 0:276e7a263c35 2410 // clash to arise.
MACRUM 0:276e7a263c35 2411
MACRUM 0:276e7a263c35 2412 strncat(working_dir_path,short_file_name, ESFS_QUALIFIED_FILE_NAME_LENGTH - 1);
MACRUM 0:276e7a263c35 2413
MACRUM 0:276e7a263c35 2414 tr_info("esfs_delete %s", working_dir_path);
MACRUM 0:276e7a263c35 2415 pal_result = pal_fsUnlink(working_dir_path);
MACRUM 0:276e7a263c35 2416
MACRUM 0:276e7a263c35 2417 if ((pal_result == PAL_ERR_FS_NO_FILE) || (pal_result == PAL_ERR_FS_NO_PATH))
MACRUM 0:276e7a263c35 2418 {
MACRUM 0:276e7a263c35 2419 tr_err("esfs_delete() - pal_fsUnlink() failed with pal status 0x%x", (unsigned int)pal_result);
MACRUM 0:276e7a263c35 2420 result = ESFS_NOT_EXISTS;
MACRUM 0:276e7a263c35 2421 goto errorExit;
MACRUM 0:276e7a263c35 2422 }
MACRUM 0:276e7a263c35 2423 else if (pal_result != PAL_SUCCESS)
MACRUM 0:276e7a263c35 2424 {
MACRUM 0:276e7a263c35 2425 tr_err("esfs_delete() - pal_fsUnlink() failed with pal status 0x%x", (unsigned int)pal_result);
MACRUM 0:276e7a263c35 2426 goto errorExit;
MACRUM 0:276e7a263c35 2427 }
MACRUM 0:276e7a263c35 2428
MACRUM 0:276e7a263c35 2429 return ESFS_SUCCESS;
MACRUM 0:276e7a263c35 2430 errorExit:
MACRUM 0:276e7a263c35 2431 return result;
MACRUM 0:276e7a263c35 2432 }
MACRUM 0:276e7a263c35 2433
MACRUM 0:276e7a263c35 2434 esfs_result_e esfs_get_meta_data_properties(esfs_file_t *file_handle, esfs_tlv_properties_t **meta_data_properties)
MACRUM 0:276e7a263c35 2435 {
MACRUM 0:276e7a263c35 2436 esfs_result_e result = ESFS_ERROR;
MACRUM 0:276e7a263c35 2437 tr_info("esfs_get_meta_data_properties - enter");
MACRUM 0:276e7a263c35 2438 if((esfs_validate(file_handle) != ESFS_SUCCESS) || (!meta_data_properties))
MACRUM 0:276e7a263c35 2439 {
MACRUM 0:276e7a263c35 2440 tr_err("esfs_get_meta_data_properties() failed with bad parameters");
MACRUM 0:276e7a263c35 2441 result = ESFS_INVALID_PARAMETER;
MACRUM 0:276e7a263c35 2442 goto errorExit;
MACRUM 0:276e7a263c35 2443 }
MACRUM 0:276e7a263c35 2444
MACRUM 0:276e7a263c35 2445 if (file_handle->file_flag != ESFS_READ)
MACRUM 0:276e7a263c35 2446 {
MACRUM 0:276e7a263c35 2447 tr_err("esfs_get_meta_data_properties() failed - file is opened for write only");
MACRUM 0:276e7a263c35 2448 result = ESFS_FILE_OPEN_FOR_WRITE;
MACRUM 0:276e7a263c35 2449 goto errorExit;
MACRUM 0:276e7a263c35 2450 }
MACRUM 0:276e7a263c35 2451
MACRUM 0:276e7a263c35 2452 *meta_data_properties = &file_handle->tlv_properties;
MACRUM 0:276e7a263c35 2453 return ESFS_SUCCESS;
MACRUM 0:276e7a263c35 2454 errorExit:
MACRUM 0:276e7a263c35 2455 return result;
MACRUM 0:276e7a263c35 2456 }
MACRUM 0:276e7a263c35 2457
MACRUM 0:276e7a263c35 2458
MACRUM 0:276e7a263c35 2459 esfs_result_e esfs_read_meta_data(esfs_file_t *file_handle, uint32_t index, esfs_tlv_item_t *meta_data)
MACRUM 0:276e7a263c35 2460 {
MACRUM 0:276e7a263c35 2461 esfs_result_e result = ESFS_ERROR;
MACRUM 0:276e7a263c35 2462 bool is_read_error = false;
MACRUM 0:276e7a263c35 2463 uint16_t cmac_created = 0;
MACRUM 0:276e7a263c35 2464 int32_t offset_to_restore = 0;
MACRUM 0:276e7a263c35 2465 palStatus_t res = PAL_SUCCESS;
MACRUM 0:276e7a263c35 2466
MACRUM 0:276e7a263c35 2467 tr_info("esfs_read_meta_data - enter");
MACRUM 0:276e7a263c35 2468 if(esfs_validate(file_handle) != ESFS_SUCCESS || index >= ESFS_MAX_TYPE_LENGTH_VALUES || !meta_data || (file_handle->tlv_properties.tlv_items[index].length_in_bytes == 0))
MACRUM 0:276e7a263c35 2469 {
MACRUM 0:276e7a263c35 2470 tr_err("esfs_read_meta_data() failed with bad parameters");
MACRUM 0:276e7a263c35 2471 result = ESFS_INVALID_PARAMETER;
MACRUM 0:276e7a263c35 2472 goto errorExit;
MACRUM 0:276e7a263c35 2473 }
MACRUM 0:276e7a263c35 2474
MACRUM 0:276e7a263c35 2475 if(file_handle->file_flag != ESFS_READ)
MACRUM 0:276e7a263c35 2476 {
MACRUM 0:276e7a263c35 2477 tr_err("esfs_read_meta_data() failed - file is opened for write only");
MACRUM 0:276e7a263c35 2478 result = ESFS_FILE_OPEN_FOR_WRITE;
MACRUM 0:276e7a263c35 2479 goto errorExit;
MACRUM 0:276e7a263c35 2480 }
MACRUM 0:276e7a263c35 2481 // Get current file position
MACRUM 0:276e7a263c35 2482 int32_t current_pos;
MACRUM 0:276e7a263c35 2483 res = pal_fsFtell(&file_handle->file, &current_pos);
MACRUM 0:276e7a263c35 2484 if(res != PAL_SUCCESS)
MACRUM 0:276e7a263c35 2485 {
MACRUM 0:276e7a263c35 2486 tr_err("esfs_read_meta_data() - pal_fsFtell() failed with pal status 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 2487 goto errorExit;
MACRUM 0:276e7a263c35 2488 }
MACRUM 0:276e7a263c35 2489
MACRUM 0:276e7a263c35 2490 // Start the cmac calculation and position to the start of the file
MACRUM 0:276e7a263c35 2491 if(esfs_cmac_start(file_handle) != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 2492 {
MACRUM 0:276e7a263c35 2493 goto errorExit;
MACRUM 0:276e7a263c35 2494 }
MACRUM 0:276e7a263c35 2495 cmac_created = 1;
MACRUM 0:276e7a263c35 2496
MACRUM 0:276e7a263c35 2497 // Skip to the meta-data position while calculating the cmac
MACRUM 0:276e7a263c35 2498 if(esfs_cmac_skip_to(file_handle, file_handle->tlv_properties.tlv_items[index].position) != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 2499 {
MACRUM 0:276e7a263c35 2500 tr_err("esfs_read_meta_data() - pal_fsFseek() failed with pal status 0x%x", (unsigned int)res);
MACRUM 0:276e7a263c35 2501 goto errorExit;
MACRUM 0:276e7a263c35 2502 }
MACRUM 0:276e7a263c35 2503
MACRUM 0:276e7a263c35 2504 // Read data
MACRUM 0:276e7a263c35 2505 // If required according to esfs_mode, the read data will be decrypted
MACRUM 0:276e7a263c35 2506 size_t num_bytes;
MACRUM 0:276e7a263c35 2507 if((file_handle->esfs_mode & ESFS_ENCRYPTED) != 0)
MACRUM 0:276e7a263c35 2508 {
MACRUM 0:276e7a263c35 2509 if(esfs_read_and_decrypt( file_handle,
MACRUM 0:276e7a263c35 2510 meta_data->value,
MACRUM 0:276e7a263c35 2511 file_handle->tlv_properties.tlv_items[index].length_in_bytes,
MACRUM 0:276e7a263c35 2512 &num_bytes
MACRUM 0:276e7a263c35 2513 ) != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 2514 {
MACRUM 0:276e7a263c35 2515 is_read_error = true;
MACRUM 0:276e7a263c35 2516 }
MACRUM 0:276e7a263c35 2517 }
MACRUM 0:276e7a263c35 2518 else
MACRUM 0:276e7a263c35 2519 {
MACRUM 0:276e7a263c35 2520 if(esfs_cmac_read(file_handle, meta_data->value, file_handle->tlv_properties.tlv_items[index].length_in_bytes, &num_bytes ) != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 2521 {
MACRUM 0:276e7a263c35 2522 is_read_error = true;
MACRUM 0:276e7a263c35 2523 }
MACRUM 0:276e7a263c35 2524 }
MACRUM 0:276e7a263c35 2525
MACRUM 0:276e7a263c35 2526 if(is_read_error || (num_bytes != file_handle->tlv_properties.tlv_items[index].length_in_bytes))
MACRUM 0:276e7a263c35 2527 {
MACRUM 0:276e7a263c35 2528 tr_err("esfs_read_meta_data() - read data failed is_read_error = %s and num_bytes = %zu",
MACRUM 0:276e7a263c35 2529 is_read_error ? "true" : "false", num_bytes);
MACRUM 0:276e7a263c35 2530 goto errorExit;
MACRUM 0:276e7a263c35 2531 }
MACRUM 0:276e7a263c35 2532
MACRUM 0:276e7a263c35 2533 // Skip to the end of the data section of the file.
MACRUM 0:276e7a263c35 2534 if(esfs_cmac_skip_to(file_handle ,file_handle->file_size - ESFS_CMAC_SIZE_IN_BYTES) != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 2535 {
MACRUM 0:276e7a263c35 2536 goto errorExit;
MACRUM 0:276e7a263c35 2537 }
MACRUM 0:276e7a263c35 2538
MACRUM 0:276e7a263c35 2539 // Return the cmac
MACRUM 0:276e7a263c35 2540 unsigned char cmac[ESFS_CMAC_SIZE_IN_BYTES];
MACRUM 0:276e7a263c35 2541 if(esfs_cmac_finish(file_handle, &cmac[0]) != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 2542 {
MACRUM 0:276e7a263c35 2543 tr_err("esfs_read() - esfs_finish_cmac() failed");
MACRUM 0:276e7a263c35 2544 goto errorExit;
MACRUM 0:276e7a263c35 2545 }
MACRUM 0:276e7a263c35 2546 cmac_created = 0;
MACRUM 0:276e7a263c35 2547
MACRUM 0:276e7a263c35 2548 // Before restoring old position, make sure offset_to_restore is not a negative number
MACRUM 0:276e7a263c35 2549 offset_to_restore = current_pos;
MACRUM 0:276e7a263c35 2550 if(offset_to_restore < 0)
MACRUM 0:276e7a263c35 2551 {
MACRUM 0:276e7a263c35 2552 tr_err("esfs_read_meta_data() failed - current_pos is negative");
MACRUM 0:276e7a263c35 2553 goto errorExit;
MACRUM 0:276e7a263c35 2554 }
MACRUM 0:276e7a263c35 2555
MACRUM 0:276e7a263c35 2556 // Check the cmac and restore the file position to the saved position
MACRUM 0:276e7a263c35 2557 if(esfs_cmac_check_and_restore(file_handle, &cmac[0], offset_to_restore) != ESFS_SUCCESS)
MACRUM 0:276e7a263c35 2558 {
MACRUM 0:276e7a263c35 2559 tr_err("esfs_read_meta_data() - cmac that we read from the file does not match the one that we calculated");
MACRUM 0:276e7a263c35 2560 result = ESFS_CMAC_DOES_NOT_MATCH;
MACRUM 0:276e7a263c35 2561 goto errorExit;
MACRUM 0:276e7a263c35 2562 }
MACRUM 0:276e7a263c35 2563
MACRUM 0:276e7a263c35 2564 // Update meta_data fields
MACRUM 0:276e7a263c35 2565 meta_data->type = file_handle->tlv_properties.tlv_items[index].type;
MACRUM 0:276e7a263c35 2566 meta_data->length_in_bytes = file_handle->tlv_properties.tlv_items[index].length_in_bytes;
MACRUM 0:276e7a263c35 2567
MACRUM 0:276e7a263c35 2568 return ESFS_SUCCESS;
MACRUM 0:276e7a263c35 2569
MACRUM 0:276e7a263c35 2570 errorExit:
MACRUM 0:276e7a263c35 2571 if(cmac_created)
MACRUM 0:276e7a263c35 2572 {
MACRUM 0:276e7a263c35 2573 // Clean up cmac. Ignore error.
MACRUM 0:276e7a263c35 2574 (void)esfs_cmac_finish(file_handle, &cmac[0]);
MACRUM 0:276e7a263c35 2575 }
MACRUM 0:276e7a263c35 2576 return result;
MACRUM 0:276e7a263c35 2577 }