Simple interface for Mbed Cloud Client
Embed:
(wiki syntax)
Show/hide line numbers
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 "fcc_sotp.h" 00019 #include "key_config_manager.h" 00020 #include "pv_error_handling.h" 00021 #include "fcc_verification.h" 00022 #include "storage.h" 00023 #include "fcc_defs.h" 00024 #include "fcc_malloc.h" 00025 #include "common_utils.h" 00026 #include "pal.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 00076 fcc_status_e fcc_init(void) 00077 { 00078 palStatus_t pal_status; 00079 00080 SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS(); 00081 00082 if (g_is_fcc_initialized) { 00083 // No need for second initialization 00084 return FCC_STATUS_SUCCESS; 00085 } 00086 00087 pal_status = pal_init(); 00088 SA_PV_ERR_RECOVERABLE_RETURN_IF((pal_status != PAL_SUCCESS), FCC_STATUS_ERROR, "Failed initializing PAL (%" PRIu32 ")", pal_status); 00089 00090 //Initialize output info handler 00091 fcc_init_output_info_handler(); 00092 00093 g_is_fcc_initialized = true; 00094 00095 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00096 00097 return FCC_STATUS_SUCCESS; 00098 } 00099 00100 fcc_status_e fcc_finalize(void) 00101 { 00102 fcc_status_e fcc_status = FCC_STATUS_SUCCESS; 00103 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00104 00105 SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS(); 00106 00107 SA_PV_ERR_RECOVERABLE_RETURN_IF((!g_is_fcc_initialized), FCC_STATUS_NOT_INITIALIZED, "FCC not initialized"); 00108 00109 //FIXME: add relevant error handling - general task for all APIs. 00110 //It is okay to finalize KCM here since it's already initialized beforehand. 00111 kcm_status = kcm_finalize(); 00112 if (kcm_status != KCM_STATUS_SUCCESS) { 00113 fcc_status = FCC_STATUS_ERROR; 00114 SA_PV_LOG_ERR("Failed finalizing KCM"); 00115 } 00116 00117 //Finalize output info handler 00118 fcc_clean_output_info_handler(); 00119 00120 //Finalize PAL 00121 pal_destroy(); 00122 00123 g_is_fcc_initialized = false; 00124 00125 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00126 00127 return fcc_status; 00128 } 00129 00130 fcc_status_e fcc_storage_delete() 00131 { 00132 kcm_status_e status = KCM_STATUS_SUCCESS; 00133 sotp_result_e sotp_status = SOTP_SUCCESS; 00134 00135 SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS(); 00136 00137 SA_PV_ERR_RECOVERABLE_RETURN_IF((!g_is_fcc_initialized), FCC_STATUS_NOT_INITIALIZED, "FCC not initialized"); 00138 00139 status = storage_reset(); 00140 SA_PV_ERR_RECOVERABLE_RETURN_IF((status == KCM_STATUS_ESFS_ERROR), FCC_STATUS_KCM_STORAGE_ERROR, "Failed in storage_reset. got ESFS error"); 00141 SA_PV_ERR_RECOVERABLE_RETURN_IF((status != KCM_STATUS_SUCCESS), FCC_STATUS_ERROR, "Failed storage reset"); 00142 00143 sotp_status = sotp_reset(); 00144 SA_PV_ERR_RECOVERABLE_RETURN_IF((sotp_status != SOTP_SUCCESS), FCC_STATUS_STORE_ERROR, "Failed to reset sotp storage "); 00145 00146 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00147 return FCC_STATUS_SUCCESS; 00148 } 00149 00150 fcc_output_info_s* fcc_get_error_and_warning_data(void) 00151 { 00152 SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS(); 00153 00154 SA_PV_ERR_RECOVERABLE_RETURN_IF((!g_is_fcc_initialized), NULL, "FCC not initialized"); 00155 00156 return get_output_info(); 00157 } 00158 00159 fcc_status_e fcc_verify_device_configured_4mbed_cloud(void) 00160 { 00161 fcc_status_e fcc_status = FCC_STATUS_SUCCESS; 00162 bool use_bootstrap = false; 00163 bool success = false; 00164 00165 SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS(); 00166 00167 SA_PV_ERR_RECOVERABLE_RETURN_IF((!g_is_fcc_initialized), FCC_STATUS_NOT_INITIALIZED, "FCC not initialized"); 00168 00169 /*Initialize fcc_output_info_s structure. 00170 In case output indo struct is not empty in the beginning of the verify process we will clean it.*/ 00171 fcc_clean_output_info_handler(); 00172 00173 //Check entropy initialization 00174 success = fcc_is_entropy_initialized(); 00175 SA_PV_ERR_RECOVERABLE_RETURN_IF((success != true), fcc_status = FCC_STATUS_ENTROPY_ERROR, "Entropy is not initialized"); 00176 00177 //Check time synchronization 00178 fcc_status = fcc_check_time_synchronization(); 00179 SA_PV_ERR_RECOVERABLE_RETURN_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status, "Failed to check time synhronization"); 00180 00181 //Get bootstrap mode 00182 fcc_status = fcc_get_bootstrap_mode(&use_bootstrap); 00183 SA_PV_ERR_RECOVERABLE_RETURN_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status, "Failed to get bootstrap mode"); 00184 00185 // Check general info 00186 fcc_status = fcc_check_device_general_info(); 00187 SA_PV_ERR_RECOVERABLE_RETURN_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status, "Failed to check general info"); 00188 00189 //Check device meta-data 00190 fcc_status = fcc_check_device_meta_data(); 00191 SA_PV_ERR_RECOVERABLE_RETURN_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status, "Failed to check configuration parameters"); 00192 00193 //Check device security objects 00194 fcc_status = fcc_check_device_security_objects(use_bootstrap); 00195 SA_PV_ERR_RECOVERABLE_RETURN_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status, "Failed to check device security objects"); 00196 00197 //Check firmware integrity 00198 fcc_status = fcc_check_firmware_update_integrity(); 00199 SA_PV_ERR_RECOVERABLE_RETURN_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status, "Failed to check device security objects"); 00200 00201 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00202 00203 return fcc_status; 00204 } 00205 00206 fcc_status_e fcc_entropy_set(const uint8_t *buf, size_t buf_size) 00207 { 00208 fcc_status_e fcc_status; 00209 SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS(); 00210 00211 SA_PV_ERR_RECOVERABLE_RETURN_IF((!g_is_fcc_initialized), FCC_STATUS_NOT_INITIALIZED, "FCC not initialized"); 00212 00213 fcc_status = fcc_sotp_data_store(buf, buf_size, SOTP_TYPE_RANDOM_SEED); 00214 SA_PV_ERR_RECOVERABLE_RETURN_IF((fcc_status == FCC_STATUS_INTERNAL_ITEM_ALREADY_EXIST), FCC_STATUS_ENTROPY_ERROR, "Entropy already exist in storage"); 00215 SA_PV_ERR_RECOVERABLE_RETURN_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status, "Failed to set entropy"); 00216 00217 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00218 return FCC_STATUS_SUCCESS; 00219 } 00220 00221 fcc_status_e fcc_rot_set(const uint8_t *buf, size_t buf_size) 00222 { 00223 fcc_status_e fcc_status; 00224 SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS(); 00225 00226 SA_PV_ERR_RECOVERABLE_RETURN_IF((!g_is_fcc_initialized), FCC_STATUS_NOT_INITIALIZED, "FCC not initialized"); 00227 00228 fcc_status = fcc_sotp_data_store(buf, buf_size, SOTP_TYPE_ROT); 00229 SA_PV_ERR_RECOVERABLE_RETURN_IF((fcc_status == FCC_STATUS_INTERNAL_ITEM_ALREADY_EXIST), FCC_STATUS_ROT_ERROR, "RoT already exist in storage"); 00230 SA_PV_ERR_RECOVERABLE_RETURN_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status, "Failed to set RoT"); 00231 00232 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00233 return FCC_STATUS_SUCCESS; 00234 } 00235 00236 fcc_status_e fcc_time_set(uint64_t time) 00237 { 00238 palStatus_t pal_status; 00239 00240 SA_PV_ERR_RECOVERABLE_RETURN_IF((!g_is_fcc_initialized), FCC_STATUS_NOT_INITIALIZED, "FCC not initialized"); 00241 00242 pal_status = pal_osSetStrongTime(time); 00243 SA_PV_ERR_RECOVERABLE_RETURN_IF((pal_status != PAL_SUCCESS), FCC_STATUS_ERROR, "Failed to set new EPOCH time (pal_status = %" PRIu32 ")", pal_status); 00244 00245 return FCC_STATUS_SUCCESS; 00246 } 00247 00248 fcc_status_e fcc_is_factory_disabled(bool *is_factory_disabled) 00249 { 00250 fcc_status_e fcc_status; 00251 int64_t factory_disable_flag = 0; 00252 size_t data_actual_size_out = 0; 00253 00254 SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS(); 00255 SA_PV_ERR_RECOVERABLE_RETURN_IF((!g_is_fcc_initialized), FCC_STATUS_NOT_INITIALIZED, "FCC not initialized"); 00256 SA_PV_ERR_RECOVERABLE_RETURN_IF((is_factory_disabled == NULL), FCC_STATUS_INVALID_PARAMETER, "Invalid param is_factory_disabled"); 00257 00258 fcc_status = fcc_sotp_data_retrieve((uint8_t *)(&factory_disable_flag), sizeof(factory_disable_flag), &data_actual_size_out, SOTP_TYPE_FACTORY_DONE); 00259 SA_PV_LOG_INFO("fcc_status: %d, factory_disable_flag:%" PRIuMAX "\n", fcc_status, factory_disable_flag); 00260 SA_PV_ERR_RECOVERABLE_RETURN_IF((fcc_status != FCC_STATUS_SUCCESS && fcc_status != FCC_STATUS_ITEM_NOT_EXIST), fcc_status, "Failed for fcc_sotp_buffer_retrieve"); 00261 SA_PV_ERR_RECOVERABLE_RETURN_IF(((factory_disable_flag != 0) && (factory_disable_flag != 1)), FCC_STATUS_FACTORY_DISABLED_ERROR, "Failed for fcc_sotp_buffer_retrieve"); 00262 00263 // If we get here - it must be either "0" or "1" 00264 *is_factory_disabled = (factory_disable_flag == 1) ? true : false; 00265 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00266 return FCC_STATUS_SUCCESS; 00267 } 00268 00269 00270 fcc_status_e fcc_factory_disable(void) 00271 { 00272 fcc_status_e fcc_status; 00273 int64_t factory_disable_flag = 1; 00274 00275 SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS(); 00276 00277 SA_PV_ERR_RECOVERABLE_RETURN_IF((!g_is_fcc_initialized), FCC_STATUS_NOT_INITIALIZED, "FCC not initialized"); 00278 00279 fcc_status = fcc_sotp_data_store((uint8_t *)(&factory_disable_flag), sizeof(factory_disable_flag), SOTP_TYPE_FACTORY_DONE); 00280 SA_PV_ERR_RECOVERABLE_RETURN_IF((fcc_status == FCC_STATUS_INTERNAL_ITEM_ALREADY_EXIST), FCC_STATUS_FACTORY_DISABLED_ERROR, "FCC already disabled in storage"); 00281 SA_PV_ERR_RECOVERABLE_RETURN_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status, "Failed for fcc_sotp_buffer_store"); 00282 00283 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00284 return FCC_STATUS_SUCCESS; 00285 } 00286 00287 00288 fcc_status_e fcc_trust_ca_cert_id_set(void) 00289 { 00290 fcc_status_e fcc_status = FCC_STATUS_SUCCESS; 00291 fcc_status_e output_info_fcc_status = FCC_STATUS_SUCCESS; 00292 uint8_t attribute_data[PAL_CERT_ID_SIZE] = {0}; 00293 size_t size_of_attribute_data = 0; 00294 bool use_bootstrap = false; 00295 00296 SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS(); 00297 00298 SA_PV_ERR_RECOVERABLE_RETURN_IF((!g_is_fcc_initialized), FCC_STATUS_NOT_INITIALIZED, "FCC not initialized"); 00299 00300 fcc_status = fcc_get_bootstrap_mode(&use_bootstrap); 00301 SA_PV_ERR_RECOVERABLE_RETURN_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status, "Failed to get bootstrap mode"); 00302 00303 00304 //For now this API relevant only for bootstrap certificate. 00305 if (use_bootstrap == true) { 00306 fcc_status = fcc_get_certificate_attribute_by_name((const uint8_t*)g_fcc_bootstrap_server_ca_certificate_name, 00307 (size_t)(strlen(g_fcc_bootstrap_server_ca_certificate_name)), 00308 CS_CERT_ID_ATTR, 00309 attribute_data, 00310 sizeof(attribute_data), 00311 &size_of_attribute_data); 00312 SA_PV_ERR_RECOVERABLE_GOTO_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status = fcc_status, exit, "Failed to get ca id"); 00313 00314 fcc_status = fcc_sotp_data_store(attribute_data, size_of_attribute_data, SOTP_TYPE_TRUSTED_TIME_SRV_ID); 00315 SA_PV_ERR_RECOVERABLE_GOTO_IF((fcc_status == FCC_STATUS_INTERNAL_ITEM_ALREADY_EXIST), (fcc_status = FCC_STATUS_CA_ERROR), exit, "CA already exist in storage"); 00316 SA_PV_ERR_RECOVERABLE_GOTO_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status = fcc_status, exit, "Failed to set ca id"); 00317 } 00318 00319 exit: 00320 if (fcc_status != FCC_STATUS_SUCCESS) { 00321 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); 00322 SA_PV_ERR_RECOVERABLE_RETURN_IF((output_info_fcc_status != FCC_STATUS_SUCCESS), 00323 fcc_status = FCC_STATUS_OUTPUT_INFO_ERROR, 00324 "Failed to set ca identifier error %d", 00325 fcc_status); 00326 } 00327 00328 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00329 return fcc_status; 00330 }
Generated on Tue Jul 12 2022 19:01:34 by 1.7.2