Toyomasa Watarai
/
Mbed-example-WS-W27
Mbed Cloud example program for workshop in W27 2018.
Embed:
(wiki syntax)
Show/hide line numbers
fcc_sotp.c
00001 // ---------------------------------------------------------------------------- 00002 // Copyright 2016-2017 ARM Ltd. 00003 // 00004 // Licensed under the Apache License, Version 2.0 (the "License"); 00005 // you may not use this file except in compliance with the License. 00006 // You may obtain a copy of the License at 00007 // 00008 // http://www.apache.org/licenses/LICENSE-2.0 00009 // 00010 // Unless required by applicable law or agreed to in writing, software 00011 // distributed under the License is distributed on an "AS IS" BASIS, 00012 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 // See the License for the specific language governing permissions and 00014 // limitations under the License. 00015 // ---------------------------------------------------------------------------- 00016 00017 #include <string.h> 00018 #include "fcc_sotp.h" 00019 #include "pv_error_handling.h" 00020 00021 00022 static bool get_sotp_type(fcc_sotp_type_e sotp_type, size_t *required_size_out) 00023 { 00024 size_t required_size; 00025 00026 switch (sotp_type) { 00027 case FCC_SOTP_TYPE_ROT: 00028 required_size = FCC_ROT_SIZE; 00029 break; 00030 case FCC_SOTP_TYPE_FACTORY_DISABLE: 00031 required_size = FCC_FACTORY_DISABLE_FLAG_SIZE; 00032 break; 00033 case FCC_SOTP_TYPE_ENTROPY: 00034 required_size = FCC_ENTROPY_SIZE; 00035 break; 00036 default: 00037 SA_PV_LOG_ERR("Non existant sotp_type provided"); 00038 return false; 00039 } 00040 00041 // Success 00042 *required_size_out = required_size; 00043 00044 return true; 00045 } 00046 00047 fcc_status_e fcc_sotp_data_store(const uint8_t *data, size_t data_size, fcc_sotp_type_e sotp_type) 00048 { 00049 bool success; 00050 size_t required_size = 0; 00051 int64_t aligned_8_bytes_buffer[MAX_SOTP_BUFFER_SIZE / 8]; 00052 00053 SA_PV_LOG_INFO_FUNC_ENTER("data_size = %" PRIu32 " sotp_type = %d", (uint32_t)data_size, (int)sotp_type); 00054 00055 SA_PV_ERR_RECOVERABLE_RETURN_IF((data == NULL), FCC_STATUS_INVALID_PARAMETER, "Invalid param data"); 00056 00057 success = get_sotp_type(sotp_type, &required_size); 00058 SA_PV_ERR_RECOVERABLE_RETURN_IF((!success), FCC_STATUS_ERROR, "Failed for get_sotp_type()"); 00059 00060 // Assert that buffer provided is of correct size 00061 SA_PV_ERR_RECOVERABLE_RETURN_IF((data_size != required_size), FCC_STATUS_ERROR, "Wrong buf_size provided. Must be size of exactly %" PRIu32 " bytes", (uint32_t)required_size); 00062 00063 // Write buf to SOTP. Cast is OK since size must be divisible by 8 00064 00065 /* 00066 * Copy from data (uint8_t*) to aligned_8_bytes_buffer (uint64_t*) to make sure that data is 8 byte aligned. 00067 * Since SOTP_Set() gets a pointer to int64_t, if it is not aligned, and we just cast it to uint8_t*, 00068 * ARMCC functions like memcpy will assume 8 byte alignment resulting in possible access of unallocated memory. 00069 */ 00070 memcpy(aligned_8_bytes_buffer, data, data_size); 00071 00072 success = SOTP_Set((uint8_t)sotp_type, (data_size >> 3), aligned_8_bytes_buffer); 00073 00074 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00075 00076 // FIXME: When SOTP returns real status - we must translate the error 00077 return success ? FCC_STATUS_SUCCESS : FCC_STATUS_ERROR; 00078 } 00079 00080 fcc_status_e fcc_sotp_data_retrieve(uint8_t *data_out, size_t data_size_max, size_t *data_actual_size_out, fcc_sotp_type_e sotp_type) 00081 { 00082 bool success; 00083 size_t required_size = 0; 00084 int64_t aligned_8_bytes_buffer[MAX_SOTP_BUFFER_SIZE / 8]; 00085 00086 uint8_t data_size_as_array_of_int64; /* store as array of int64_t */ 00087 00088 SA_PV_LOG_INFO_FUNC_ENTER("data_out = %" PRIu32 " sotp_type = %d", (uint32_t)data_size_max, (int)sotp_type); 00089 00090 SA_PV_ERR_RECOVERABLE_RETURN_IF((data_out == NULL), FCC_STATUS_INVALID_PARAMETER, "invalid param data_out"); 00091 00092 success = get_sotp_type(sotp_type, &required_size); 00093 SA_PV_ERR_RECOVERABLE_RETURN_IF((!success), FCC_STATUS_ERROR, "Failed for get_sotp_type()"); 00094 00095 // Assert that buffer provided is of correct size 00096 SA_PV_ERR_RECOVERABLE_RETURN_IF((data_size_max < required_size), FCC_STATUS_ERROR, "Wrong data_size provided. Must be size of exactly %" PRIu32 " bytes", (uint32_t)required_size); 00097 00098 // Retrieve buf from SOTP. Cast is OK since size must be multiple of 8 00099 // FIXME: When SOTP returns real status - we must translate the error 00100 success = SOTP_Get((uint8_t)sotp_type, aligned_8_bytes_buffer, &data_size_as_array_of_int64); 00101 SA_PV_ERR_RECOVERABLE_RETURN_IF((!success), FCC_STATUS_ERROR, "SOTP_Get failed"); 00102 00103 // Copy from aligned buffer to callers uint8_t* buffer 00104 memcpy(data_out, aligned_8_bytes_buffer, data_size_as_array_of_int64 * sizeof(int64_t)); 00105 00106 // Convert back to bytes 00107 *data_actual_size_out = (size_t)(data_size_as_array_of_int64 << 3); 00108 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00109 00110 // FIXME: When SOTP returns real status - we must translate the error 00111 return FCC_STATUS_SUCCESS; 00112 } 00113 00114 00115 00116 00117 00118 00119 00120 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00121 // FIXME: All code from here on should be removed once SOTP APIs are implemented 00122 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00123 00124 /* 00125 * These globals mock the SOTP storage. 00126 * Should be removed once SOTP is implemented. 00127 */ 00128 sotp_entree_s g_sotp_rot = { 0 }; 00129 sotp_entree_s g_sotp_factory_disabled = { 0 }; 00130 sotp_entree_s g_sotp_entropy = { 0 }; 00131 00132 // API that mocks future SOTP_Set() 00133 bool SOTP_Set(uint8_t type, uint8_t size, const int64_t *data) 00134 { 00135 sotp_entree_s entree; 00136 00137 entree.data_size_in_bytes = (size << 3); 00138 memcpy(entree.data, data, entree.data_size_in_bytes); 00139 entree.type = type; 00140 entree.write_disabled = true; 00141 00142 switch (type) { 00143 case FCC_SOTP_TYPE_ENTROPY: 00144 if (!g_sotp_entropy.write_disabled) { 00145 g_sotp_entropy = entree; 00146 } else { 00147 return false; 00148 } 00149 break; 00150 case FCC_SOTP_TYPE_ROT: 00151 if (!g_sotp_rot.write_disabled) { 00152 g_sotp_rot = entree; 00153 } else { 00154 return false; 00155 } 00156 break; 00157 case FCC_SOTP_TYPE_FACTORY_DISABLE: 00158 if (!g_sotp_factory_disabled.write_disabled) { 00159 g_sotp_factory_disabled = entree; 00160 } else { 00161 return false; 00162 } 00163 break; 00164 default: 00165 return false; 00166 } 00167 00168 return true; 00169 } 00170 00171 // API that mocks future SOTP_Get() 00172 bool SOTP_Get(uint8_t type, int64_t *data_out, uint8_t *data_size_out) 00173 { 00174 switch (type) { 00175 case FCC_SOTP_TYPE_ENTROPY: 00176 *data_size_out = g_sotp_entropy.data_size_in_bytes >> 3; 00177 memcpy(data_out, g_sotp_entropy.data, g_sotp_entropy.data_size_in_bytes); 00178 break; 00179 case FCC_SOTP_TYPE_ROT: 00180 *data_size_out = g_sotp_rot.data_size_in_bytes >> 3; 00181 memcpy(data_out, g_sotp_rot.data, g_sotp_rot.data_size_in_bytes); 00182 break; 00183 case FCC_SOTP_TYPE_FACTORY_DISABLE: 00184 *data_size_out = g_sotp_factory_disabled.data_size_in_bytes >> 3; 00185 memcpy(data_out, g_sotp_factory_disabled.data, g_sotp_factory_disabled.data_size_in_bytes); 00186 break; 00187 default: 00188 return false; 00189 } 00190 00191 return true; 00192 } 00193 00194 void SOTP_TestOnly_reset() 00195 { 00196 memset(&g_sotp_entropy, 0, sizeof(g_sotp_entropy)); 00197 memset(&g_sotp_rot, 0, sizeof(g_sotp_rot)); 00198 memset(&g_sotp_factory_disabled, 0, sizeof(g_sotp_factory_disabled)); 00199 }
Generated on Tue Jul 12 2022 16:22:05 by 1.7.2