Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
psa_its_file.c
00001 /* 00002 * PSA ITS simulator over stdio files. 00003 */ 00004 /* Copyright (C) 2018, ARM Limited, All Rights Reserved 00005 * SPDX-License-Identifier: Apache-2.0 00006 * 00007 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00008 * not use this file except in compliance with the License. 00009 * You may obtain a copy of the License at 00010 * 00011 * http://www.apache.org/licenses/LICENSE-2.0 00012 * 00013 * Unless required by applicable law or agreed to in writing, software 00014 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00015 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00016 * See the License for the specific language governing permissions and 00017 * limitations under the License. 00018 * 00019 * This file is part of mbed TLS (https://tls.mbed.org) 00020 */ 00021 00022 #if defined(MBEDTLS_CONFIG_FILE) 00023 #include MBEDTLS_CONFIG_FILE 00024 #else 00025 #include "mbedtls/config.h" 00026 #endif 00027 00028 #if defined(MBEDTLS_PSA_ITS_FILE_C) 00029 00030 #if defined(MBEDTLS_PLATFORM_C) 00031 #include "mbedtls/platform.h" 00032 #else 00033 #define mbedtls_snprintf snprintf 00034 #endif 00035 00036 #if defined(_WIN32) 00037 #include <windows.h> 00038 #endif 00039 00040 #include "psa_crypto_its.h" 00041 00042 #include <limits.h> 00043 #include <stdint.h> 00044 #include <stdio.h> 00045 #include <string.h> 00046 00047 #if !defined(PSA_ITS_STORAGE_PREFIX) 00048 #define PSA_ITS_STORAGE_PREFIX "" 00049 #endif 00050 00051 #define PSA_ITS_STORAGE_FILENAME_PATTERN "%08lx%08lx" 00052 #define PSA_ITS_STORAGE_SUFFIX ".psa_its" 00053 #define PSA_ITS_STORAGE_FILENAME_LENGTH \ 00054 ( sizeof( PSA_ITS_STORAGE_PREFIX ) - 1 + /*prefix without terminating 0*/ \ 00055 16 + /*UID (64-bit number in hex)*/ \ 00056 sizeof( PSA_ITS_STORAGE_SUFFIX ) - 1 + /*suffix without terminating 0*/ \ 00057 1 /*terminating null byte*/ ) 00058 #define PSA_ITS_STORAGE_TEMP \ 00059 PSA_ITS_STORAGE_PREFIX "tempfile" PSA_ITS_STORAGE_SUFFIX 00060 00061 /* The maximum value of psa_storage_info_t.size */ 00062 #define PSA_ITS_MAX_SIZE 0xffffffff 00063 00064 #define PSA_ITS_MAGIC_STRING "PSA\0ITS\0" 00065 #define PSA_ITS_MAGIC_LENGTH 8 00066 00067 /* As rename fails on Windows if the new filepath already exists, 00068 * use MoveFileExA with the MOVEFILE_REPLACE_EXISTING flag instead. 00069 * Returns 0 on success, nonzero on failure. */ 00070 #if defined(_WIN32) 00071 #define rename_replace_existing( oldpath, newpath ) \ 00072 ( ! MoveFileExA( oldpath, newpath, MOVEFILE_REPLACE_EXISTING ) ) 00073 #else 00074 #define rename_replace_existing( oldpath, newpath ) rename( oldpath, newpath ) 00075 #endif 00076 00077 typedef struct 00078 { 00079 uint8_t magic[PSA_ITS_MAGIC_LENGTH]; 00080 uint8_t size[sizeof( uint32_t )]; 00081 uint8_t flags[sizeof( psa_storage_create_flags_t )]; 00082 } psa_its_file_header_t; 00083 00084 static void psa_its_fill_filename( psa_storage_uid_t uid, char *filename ) 00085 { 00086 /* Break up the UID into two 32-bit pieces so as not to rely on 00087 * long long support in snprintf. */ 00088 mbedtls_snprintf( filename, PSA_ITS_STORAGE_FILENAME_LENGTH, 00089 "%s" PSA_ITS_STORAGE_FILENAME_PATTERN "%s", 00090 PSA_ITS_STORAGE_PREFIX, 00091 (unsigned long) ( uid >> 32 ), 00092 (unsigned long) ( uid & 0xffffffff ), 00093 PSA_ITS_STORAGE_SUFFIX ); 00094 } 00095 00096 static psa_status_t psa_its_read_file( psa_storage_uid_t uid, 00097 struct psa_storage_info_t *p_info, 00098 FILE **p_stream ) 00099 { 00100 char filename[PSA_ITS_STORAGE_FILENAME_LENGTH]; 00101 psa_its_file_header_t header; 00102 size_t n; 00103 00104 *p_stream = NULL; 00105 psa_its_fill_filename( uid, filename ); 00106 *p_stream = fopen( filename, "rb" ); 00107 if( *p_stream == NULL ) 00108 return( PSA_ERROR_DOES_NOT_EXIST ); 00109 00110 n = fread( &header, 1, sizeof( header ), *p_stream ); 00111 if( n != sizeof( header ) ) 00112 return( PSA_ERROR_DATA_CORRUPT ); 00113 if( memcmp( header.magic, PSA_ITS_MAGIC_STRING, 00114 PSA_ITS_MAGIC_LENGTH ) != 0 ) 00115 return( PSA_ERROR_DATA_CORRUPT ); 00116 00117 p_info->size = ( header.size[0] | 00118 header.size[1] << 8 | 00119 header.size[2] << 16 | 00120 header.size[3] << 24 ); 00121 p_info->flags = ( header.flags[0] | 00122 header.flags[1] << 8 | 00123 header.flags[2] << 16 | 00124 header.flags[3] << 24 ); 00125 return( PSA_SUCCESS ); 00126 } 00127 00128 psa_status_t psa_its_get_info( psa_storage_uid_t uid, 00129 struct psa_storage_info_t *p_info ) 00130 { 00131 psa_status_t status; 00132 FILE *stream = NULL; 00133 status = psa_its_read_file( uid, p_info, &stream ); 00134 if( stream != NULL ) 00135 fclose( stream ); 00136 return( status ); 00137 } 00138 00139 psa_status_t psa_its_get( psa_storage_uid_t uid, 00140 uint32_t data_offset, 00141 uint32_t data_length, 00142 void *p_data, 00143 size_t *p_data_length ) 00144 { 00145 psa_status_t status; 00146 FILE *stream = NULL; 00147 size_t n; 00148 struct psa_storage_info_t info; 00149 00150 status = psa_its_read_file( uid, &info, &stream ); 00151 if( status != PSA_SUCCESS ) 00152 goto exit; 00153 status = PSA_ERROR_INVALID_ARGUMENT; 00154 if( data_offset + data_length < data_offset ) 00155 goto exit; 00156 #if SIZE_MAX < 0xffffffff 00157 if( data_offset + data_length > SIZE_MAX ) 00158 goto exit; 00159 #endif 00160 if( data_offset + data_length > info.size ) 00161 goto exit; 00162 00163 status = PSA_ERROR_STORAGE_FAILURE; 00164 #if LONG_MAX < 0xffffffff 00165 while( data_offset > LONG_MAX ) 00166 { 00167 if( fseek( stream, LONG_MAX, SEEK_CUR ) != 0 ) 00168 goto exit; 00169 data_offset -= LONG_MAX; 00170 } 00171 #endif 00172 if( fseek( stream, data_offset, SEEK_CUR ) != 0 ) 00173 goto exit; 00174 n = fread( p_data, 1, data_length, stream ); 00175 if( n != data_length ) 00176 goto exit; 00177 status = PSA_SUCCESS; 00178 if( p_data_length != NULL ) 00179 *p_data_length = n; 00180 00181 exit: 00182 if( stream != NULL ) 00183 fclose( stream ); 00184 return( status ); 00185 } 00186 00187 psa_status_t psa_its_set( psa_storage_uid_t uid, 00188 uint32_t data_length, 00189 const void *p_data, 00190 psa_storage_create_flags_t create_flags ) 00191 { 00192 psa_status_t status = PSA_ERROR_STORAGE_FAILURE; 00193 char filename[PSA_ITS_STORAGE_FILENAME_LENGTH]; 00194 FILE *stream = NULL; 00195 psa_its_file_header_t header; 00196 size_t n; 00197 00198 memcpy( header.magic, PSA_ITS_MAGIC_STRING, PSA_ITS_MAGIC_LENGTH ); 00199 header.size[0] = data_length & 0xff; 00200 header.size[1] = ( data_length >> 8 ) & 0xff; 00201 header.size[2] = ( data_length >> 16 ) & 0xff; 00202 header.size[3] = ( data_length >> 24 ) & 0xff; 00203 header.flags[0] = create_flags & 0xff; 00204 header.flags[1] = ( create_flags >> 8 ) & 0xff; 00205 header.flags[2] = ( create_flags >> 16 ) & 0xff; 00206 header.flags[3] = ( create_flags >> 24 ) & 0xff; 00207 00208 psa_its_fill_filename( uid, filename ); 00209 stream = fopen( PSA_ITS_STORAGE_TEMP, "wb" ); 00210 if( stream == NULL ) 00211 goto exit; 00212 00213 status = PSA_ERROR_INSUFFICIENT_STORAGE; 00214 n = fwrite( &header, 1, sizeof( header ), stream ); 00215 if( n != sizeof( header ) ) 00216 goto exit; 00217 if( data_length != 0 ) 00218 { 00219 n = fwrite( p_data, 1, data_length, stream ); 00220 if( n != data_length ) 00221 goto exit; 00222 } 00223 status = PSA_SUCCESS; 00224 00225 exit: 00226 if( stream != NULL ) 00227 { 00228 int ret = fclose( stream ); 00229 if( status == PSA_SUCCESS && ret != 0 ) 00230 status = PSA_ERROR_INSUFFICIENT_STORAGE; 00231 } 00232 if( status == PSA_SUCCESS ) 00233 { 00234 if( rename_replace_existing( PSA_ITS_STORAGE_TEMP, filename ) != 0 ) 00235 status = PSA_ERROR_STORAGE_FAILURE; 00236 } 00237 remove( PSA_ITS_STORAGE_TEMP ); 00238 return( status ); 00239 } 00240 00241 psa_status_t psa_its_remove( psa_storage_uid_t uid ) 00242 { 00243 char filename[PSA_ITS_STORAGE_FILENAME_LENGTH]; 00244 FILE *stream; 00245 psa_its_fill_filename( uid, filename ); 00246 stream = fopen( filename, "rb" ); 00247 if( stream == NULL ) 00248 return( PSA_ERROR_DOES_NOT_EXIST ); 00249 fclose( stream ); 00250 if( remove( filename ) != 0 ) 00251 return( PSA_ERROR_STORAGE_FAILURE ); 00252 return( PSA_SUCCESS ); 00253 } 00254 00255 #endif /* MBEDTLS_PSA_ITS_FILE_C */
Generated on Tue Jul 12 2022 13:54:46 by
