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.
factory_configurator_client.c
00001 // ---------------------------------------------------------------------------- 00002 // Copyright 2016-2018 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 "factory_configurator_client.h" 00018 #include "key_config_manager.h" 00019 #include "pv_error_handling.h" 00020 #include "fcc_verification.h" 00021 #include "storage.h" 00022 #include "fcc_defs.h" 00023 #include "fcc_malloc.h" 00024 #include "common_utils.h" 00025 #include "pal.h" 00026 #include "fcc_utils.h" 00027 00028 /** 00029 * Device general info 00030 */ 00031 const char g_fcc_use_bootstrap_parameter_name[] = "mbed.UseBootstrap"; 00032 const char g_fcc_endpoint_parameter_name[] = "mbed.EndpointName"; 00033 const char g_fcc_account_id_parameter_name[] = "mbed.AccountID"; 00034 const char g_fcc_first_to_claim_parameter_name[] = "mbed.FirstToClaim"; 00035 00036 /** 00037 * Device meta data 00038 */ 00039 const char g_fcc_manufacturer_parameter_name[] = "mbed.Manufacturer"; 00040 const char g_fcc_model_number_parameter_name[] = "mbed.ModelNumber"; 00041 const char g_fcc_device_type_parameter_name[] = "mbed.DeviceType"; 00042 const char g_fcc_hardware_version_parameter_name[] = "mbed.HardwareVersion"; 00043 const char g_fcc_memory_size_parameter_name[] = "mbed.MemoryTotalKB"; 00044 const char g_fcc_device_serial_number_parameter_name[] = "mbed.SerialNumber"; 00045 /** 00046 * Time Synchronization 00047 */ 00048 const char g_fcc_current_time_parameter_name[] = "mbed.CurrentTime"; 00049 const char g_fcc_device_time_zone_parameter_name[] = "mbed.Timezone"; 00050 const char g_fcc_offset_from_utc_parameter_name[] = "mbed.UTCOffset"; 00051 /** 00052 * Bootstrap configuration 00053 */ 00054 const char g_fcc_bootstrap_server_ca_certificate_name[] = "mbed.BootstrapServerCACert"; 00055 const char g_fcc_bootstrap_server_crl_name[] = "mbed.BootstrapServerCRL"; 00056 const char g_fcc_bootstrap_server_uri_name[] = "mbed.BootstrapServerURI"; 00057 const char g_fcc_bootstrap_device_certificate_name[] = "mbed.BootstrapDeviceCert"; 00058 const char g_fcc_bootstrap_device_private_key_name[] = "mbed.BootstrapDevicePrivateKey"; 00059 /** 00060 * LWm2m configuration 00061 */ 00062 const char g_fcc_lwm2m_server_ca_certificate_name[] = "mbed.LwM2MServerCACert"; 00063 const char g_fcc_lwm2m_server_crl_name[] = "mbed.LwM2MServerCRL"; 00064 const char g_fcc_lwm2m_server_uri_name[] = "mbed.LwM2MServerURI"; 00065 const char g_fcc_lwm2m_device_certificate_name[] = "mbed.LwM2MDeviceCert"; 00066 const char g_fcc_lwm2m_device_private_key_name[] = "mbed.LwM2MDevicePrivateKey"; 00067 /** 00068 * Firmware update 00069 */ 00070 const char g_fcc_update_authentication_certificate_name[] = "mbed.UpdateAuthCert"; 00071 const char g_fcc_class_id_name[] = "mbed.ClassId"; 00072 const char g_fcc_vendor_id_name[] = "mbed.VendorId"; 00073 00074 static bool g_is_fcc_initialized = false; 00075 bool g_is_session_finished = true; 00076 00077 fcc_status_e fcc_init(void) 00078 { 00079 palStatus_t pal_status; 00080 00081 SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS(); 00082 00083 if (g_is_fcc_initialized) { 00084 // No need for second initialization 00085 return FCC_STATUS_SUCCESS; 00086 } 00087 00088 pal_status = pal_init(); 00089 SA_PV_ERR_RECOVERABLE_RETURN_IF((pal_status == PAL_ERR_INIT_SOTP_FAILED ), FCC_STATUS_STORE_ERROR, "Failed initializing internal storage (%" PRIu32 ")", pal_status); 00090 SA_PV_ERR_RECOVERABLE_RETURN_IF((pal_status != PAL_SUCCESS), FCC_STATUS_ERROR, "Failed initializing PAL (%" PRIu32 ")", pal_status); 00091 00092 //Initialize output info handler 00093 fcc_init_output_info_handler(); 00094 00095 g_is_fcc_initialized = true; 00096 00097 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00098 00099 return FCC_STATUS_SUCCESS; 00100 } 00101 00102 fcc_status_e fcc_finalize(void) 00103 { 00104 fcc_status_e fcc_status = FCC_STATUS_SUCCESS; 00105 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00106 00107 SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS(); 00108 00109 SA_PV_ERR_RECOVERABLE_RETURN_IF((!g_is_fcc_initialized), FCC_STATUS_NOT_INITIALIZED, "FCC not initialized"); 00110 00111 //FIXME: add relevant error handling - general task for all APIs. 00112 //It is okay to finalize KCM here since it's already initialized beforehand. 00113 kcm_status = kcm_finalize(); 00114 if (kcm_status != KCM_STATUS_SUCCESS) { 00115 fcc_status = FCC_STATUS_ERROR; 00116 SA_PV_LOG_ERR("Failed finalizing KCM"); 00117 } 00118 00119 //Finalize output info handler 00120 fcc_clean_output_info_handler(); 00121 00122 //Finalize PAL 00123 pal_destroy(); 00124 00125 g_is_fcc_initialized = false; 00126 g_is_session_finished = true; 00127 00128 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00129 00130 return fcc_status; 00131 } 00132 00133 fcc_status_e fcc_storage_delete() 00134 { 00135 kcm_status_e status = KCM_STATUS_SUCCESS; 00136 00137 SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS(); 00138 00139 //when using SST don't check this since we want to delete storage before initialization 00140 #ifndef MBED_CONF_MBED_CLOUD_CLIENT_EXTERNAL_SST_SUPPORT 00141 SA_PV_ERR_RECOVERABLE_RETURN_IF((!g_is_fcc_initialized), FCC_STATUS_NOT_INITIALIZED, "FCC not initialized"); 00142 #endif 00143 status = storage_reset(); 00144 SA_PV_ERR_RECOVERABLE_RETURN_IF((status == KCM_STATUS_ESFS_ERROR), FCC_STATUS_KCM_STORAGE_ERROR, "Failed in storage_reset. got ESFS error"); 00145 SA_PV_ERR_RECOVERABLE_RETURN_IF((status != KCM_STATUS_SUCCESS), FCC_STATUS_ERROR, "Failed storage reset"); 00146 00147 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00148 return FCC_STATUS_SUCCESS; 00149 } 00150 00151 fcc_output_info_s* fcc_get_error_and_warning_data(void) 00152 { 00153 SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS(); 00154 00155 SA_PV_ERR_RECOVERABLE_RETURN_IF((!g_is_fcc_initialized), NULL, "FCC not initialized"); 00156 00157 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00158 00159 return get_output_info(); 00160 } 00161 00162 bool fcc_is_session_finished(void) 00163 { 00164 SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS(); 00165 00166 return g_is_session_finished; 00167 } 00168 00169 fcc_status_e fcc_verify_device_configured_4mbed_cloud(void) 00170 { 00171 fcc_status_e fcc_status = FCC_STATUS_SUCCESS; 00172 bool use_bootstrap = false; 00173 bool success = false; 00174 00175 SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS(); 00176 00177 SA_PV_ERR_RECOVERABLE_RETURN_IF((!g_is_fcc_initialized), FCC_STATUS_NOT_INITIALIZED, "FCC not initialized"); 00178 00179 /*Initialize fcc_output_info_s structure. 00180 In case output indo struct is not empty in the beginning of the verify process we will clean it.*/ 00181 fcc_clean_output_info_handler(); 00182 00183 //Check entropy initialization 00184 success = fcc_is_entropy_initialized(); 00185 SA_PV_ERR_RECOVERABLE_RETURN_IF((success != true), fcc_status = FCC_STATUS_ENTROPY_ERROR, "Entropy is not initialized"); 00186 00187 //Check time synchronization 00188 fcc_status = fcc_check_time_synchronization(); 00189 SA_PV_ERR_RECOVERABLE_RETURN_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status, "Failed to check time synhronization"); 00190 00191 //Get bootstrap mode 00192 fcc_status = fcc_get_bootstrap_mode(&use_bootstrap); 00193 SA_PV_ERR_RECOVERABLE_RETURN_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status, "Failed to get bootstrap mode"); 00194 00195 // Check general info 00196 fcc_status = fcc_check_device_general_info(); 00197 SA_PV_ERR_RECOVERABLE_RETURN_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status, "Failed to check general info"); 00198 00199 //Check device meta-data 00200 fcc_status = fcc_check_device_meta_data(); 00201 SA_PV_ERR_RECOVERABLE_RETURN_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status, "Failed to check configuration parameters"); 00202 00203 //Check device security objects 00204 fcc_status = fcc_check_device_security_objects(use_bootstrap); 00205 SA_PV_ERR_RECOVERABLE_RETURN_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status, "Failed to check device security objects"); 00206 00207 //Check firmware integrity 00208 fcc_status = fcc_check_firmware_update_integrity(); 00209 SA_PV_ERR_RECOVERABLE_RETURN_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status, "Failed to check device security objects"); 00210 00211 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00212 00213 return fcc_status; 00214 } 00215 00216 fcc_status_e fcc_entropy_set(const uint8_t *buf, size_t buf_size) 00217 { 00218 palStatus_t pal_status; 00219 SA_PV_LOG_INFO_FUNC_ENTER("buf_size = %" PRIu32, (uint32_t)buf_size); 00220 00221 SA_PV_ERR_RECOVERABLE_RETURN_IF((!g_is_fcc_initialized), FCC_STATUS_NOT_INITIALIZED, "FCC not initialized"); 00222 SA_PV_ERR_RECOVERABLE_RETURN_IF(buf_size != FCC_ENTROPY_SIZE, FCC_STATUS_INVALID_PARAMETER, "Size of entropy provided is %" PRIu32 ", Should be %" PRIu32 , (uint32_t)buf_size, (uint32_t)FCC_ENTROPY_SIZE); 00223 00224 pal_status = pal_osEntropyInject(buf, buf_size); 00225 SA_PV_ERR_RECOVERABLE_RETURN_IF((pal_status != PAL_SUCCESS), fcc_convert_pal_to_fcc_status(pal_status), "Failed to set entropy, pal status =%" PRId32, pal_status); 00226 00227 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00228 return FCC_STATUS_SUCCESS; 00229 } 00230 00231 fcc_status_e fcc_rot_set(const uint8_t *buf, size_t buf_size) 00232 { 00233 fcc_status_e fcc_status = FCC_STATUS_SUCCESS; 00234 palStatus_t pal_status = PAL_SUCCESS; 00235 00236 SA_PV_LOG_INFO_FUNC_ENTER("buf_size = %" PRIu32 , (uint32_t)buf_size); 00237 00238 SA_PV_ERR_RECOVERABLE_RETURN_IF((!g_is_fcc_initialized), FCC_STATUS_NOT_INITIALIZED, "FCC not initialized"); 00239 SA_PV_ERR_RECOVERABLE_RETURN_IF((buf == NULL || buf_size != FCC_ROT_SIZE), FCC_STATUS_INVALID_PARAMETER, "Invalid params"); 00240 00241 pal_status = pal_osSetRoT((uint8_t*)buf, buf_size); 00242 00243 SA_PV_ERR_RECOVERABLE_RETURN_IF((pal_status == PAL_ERR_ITEM_EXIST ), fcc_status = FCC_STATUS_ROT_ERROR, "RoT already exist in storage"); 00244 SA_PV_ERR_RECOVERABLE_RETURN_IF((pal_status == PAL_ERR_INVALID_ARGUMENT ), fcc_status = FCC_STATUS_INVALID_PARAMETER, "Failed to set RoT"); 00245 SA_PV_ERR_RECOVERABLE_RETURN_IF((pal_status != PAL_SUCCESS), fcc_status = FCC_STATUS_ROT_ERROR, "Failed to set RoT"); 00246 00247 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00248 return fcc_status; 00249 } 00250 00251 fcc_status_e fcc_time_set(uint64_t time) 00252 { 00253 palStatus_t pal_status; 00254 00255 SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS(); 00256 SA_PV_ERR_RECOVERABLE_RETURN_IF((!g_is_fcc_initialized), FCC_STATUS_NOT_INITIALIZED, "FCC not initialized"); 00257 00258 pal_status = pal_osSetStrongTime(time); 00259 SA_PV_ERR_RECOVERABLE_RETURN_IF((pal_status != PAL_SUCCESS), FCC_STATUS_ERROR, "Failed to set new EPOCH time (pal_status = %" PRIu32 ")", pal_status); 00260 00261 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00262 return FCC_STATUS_SUCCESS; 00263 } 00264 00265 fcc_status_e fcc_is_factory_disabled(bool *is_factory_disabled) 00266 { 00267 00268 int64_t factory_disable_flag = 0; 00269 size_t data_actual_size_out = 0; 00270 palStatus_t pal_status = PAL_SUCCESS; 00271 00272 SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS(); 00273 SA_PV_ERR_RECOVERABLE_RETURN_IF((!g_is_fcc_initialized), FCC_STATUS_NOT_INITIALIZED, "FCC not initialized"); 00274 SA_PV_ERR_RECOVERABLE_RETURN_IF((is_factory_disabled == NULL), FCC_STATUS_INVALID_PARAMETER, "Invalid param is_factory_disabled"); 00275 00276 pal_status = storage_rbp_read(STORAGE_RBP_FACTORY_DONE_NAME, (uint8_t *)(&factory_disable_flag), sizeof(factory_disable_flag), &data_actual_size_out); 00277 SA_PV_LOG_INFO("pal_status:%" PRId32", factory_disable_flag:%" PRIuMAX "\n", pal_status, factory_disable_flag); 00278 SA_PV_ERR_RECOVERABLE_RETURN_IF((pal_status != PAL_SUCCESS && pal_status != PAL_ERR_ITEM_NOT_EXIST ), fcc_convert_pal_to_fcc_status(pal_status), "Failed for storage_rbp_read"); 00279 SA_PV_ERR_RECOVERABLE_RETURN_IF(((factory_disable_flag != 0) && (factory_disable_flag != 1)), FCC_STATUS_FACTORY_DISABLED_ERROR, "Failed for storage_rbp_read"); 00280 00281 // If we get here - it must be either "0" or "1" 00282 *is_factory_disabled = (factory_disable_flag == 1) ? true : false; 00283 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00284 return FCC_STATUS_SUCCESS; 00285 } 00286 00287 00288 fcc_status_e fcc_factory_disable(void) 00289 { 00290 palStatus_t pal_status = PAL_SUCCESS; 00291 int64_t factory_disable_flag = 1; 00292 size_t data_actual_size_out = 0; 00293 00294 SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS(); 00295 00296 SA_PV_ERR_RECOVERABLE_RETURN_IF((!g_is_fcc_initialized), FCC_STATUS_NOT_INITIALIZED, "FCC not initialized"); 00297 00298 pal_status = storage_rbp_write(STORAGE_RBP_FACTORY_DONE_NAME, (uint8_t *)(&factory_disable_flag), sizeof(factory_disable_flag), true); 00299 SA_PV_ERR_RECOVERABLE_RETURN_IF((pal_status == PAL_ERR_ITEM_EXIST ), FCC_STATUS_FACTORY_DISABLED_ERROR, "FCC already disabled in storage"); 00300 SA_PV_ERR_RECOVERABLE_RETURN_IF((pal_status == PAL_ERR_INVALID_ARGUMENT ), FCC_STATUS_INVALID_PARAMETER, "Failed to set storage_rbp_write"); 00301 SA_PV_ERR_RECOVERABLE_RETURN_IF((pal_status != PAL_SUCCESS), fcc_convert_pal_to_fcc_status(pal_status), "Failed to set storage_rbp_write"); 00302 00303 //Check FACTORY_DONE written correctly 00304 pal_status = storage_rbp_read(STORAGE_RBP_FACTORY_DONE_NAME, (uint8_t *)(&factory_disable_flag), sizeof(factory_disable_flag), &data_actual_size_out); 00305 SA_PV_ERR_RECOVERABLE_RETURN_IF((pal_status != PAL_SUCCESS || data_actual_size_out != sizeof(factory_disable_flag)), FCC_STATUS_FACTORY_DISABLED_ERROR, "Failed to set storage_rbp_write"); 00306 00307 00308 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00309 return FCC_STATUS_SUCCESS; 00310 } 00311 00312 00313 fcc_status_e fcc_trust_ca_cert_id_set(void) 00314 { 00315 fcc_status_e fcc_status = FCC_STATUS_SUCCESS; 00316 palStatus_t pal_status = PAL_SUCCESS; 00317 fcc_status_e output_info_fcc_status = FCC_STATUS_SUCCESS; 00318 uint8_t attribute_data[PAL_CERT_ID_SIZE] __attribute__((aligned(4))) = { 0 }; 00319 size_t size_of_attribute_data = 0; 00320 bool use_bootstrap = false; 00321 00322 SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS(); 00323 00324 SA_PV_ERR_RECOVERABLE_RETURN_IF((!g_is_fcc_initialized), FCC_STATUS_NOT_INITIALIZED, "FCC not initialized"); 00325 00326 fcc_status = fcc_get_bootstrap_mode(&use_bootstrap); 00327 SA_PV_ERR_RECOVERABLE_RETURN_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status, "Failed to get bootstrap mode"); 00328 00329 00330 //For now this API relevant only for bootstrap certificate. 00331 if (use_bootstrap == true) { 00332 fcc_status = fcc_get_certificate_attribute_by_name((const uint8_t*)g_fcc_bootstrap_server_ca_certificate_name, 00333 (size_t)(strlen(g_fcc_bootstrap_server_ca_certificate_name)), 00334 CS_CERT_ID_ATTR, 00335 attribute_data, 00336 sizeof(attribute_data), 00337 &size_of_attribute_data); 00338 SA_PV_ERR_RECOVERABLE_GOTO_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status = fcc_status, exit, "Failed to get ca id"); 00339 00340 pal_status = storage_rbp_write(STORAGE_RBP_TRUSTED_TIME_SRV_ID_NAME, attribute_data, size_of_attribute_data, true); 00341 SA_PV_ERR_RECOVERABLE_GOTO_IF((pal_status == PAL_ERR_ITEM_EXIST ), (fcc_status = FCC_STATUS_CA_ERROR), exit, "CA already exist in storage"); 00342 SA_PV_ERR_RECOVERABLE_GOTO_IF((pal_status == PAL_ERR_INVALID_ARGUMENT ), fcc_status = FCC_STATUS_INVALID_PARAMETER, exit, "Failed to set ca id"); 00343 SA_PV_ERR_RECOVERABLE_GOTO_IF((pal_status != PAL_SUCCESS), fcc_status = fcc_convert_pal_to_fcc_status(pal_status), exit, "Failed to setca id"); 00344 } 00345 00346 exit: 00347 if (fcc_status != FCC_STATUS_SUCCESS) { 00348 output_info_fcc_status = fcc_store_error_info((const uint8_t*)g_fcc_bootstrap_server_ca_certificate_name, strlen(g_fcc_bootstrap_server_ca_certificate_name), fcc_status); 00349 SA_PV_ERR_RECOVERABLE_RETURN_IF((output_info_fcc_status != FCC_STATUS_SUCCESS), 00350 fcc_status = FCC_STATUS_OUTPUT_INFO_ERROR, 00351 "Failed to set ca identifier error %d", 00352 fcc_status); 00353 } 00354 00355 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00356 return fcc_status; 00357 } 00358 00359 bool fcc_is_initialized() 00360 { 00361 return g_is_fcc_initialized; 00362 }
Generated on Mon Aug 29 2022 19:53:39 by
