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.
Dependencies: FXAS21002 FXOS8700Q
fcc_bundle_common_utils.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 #include "fcc_bundle_handler.h" 00017 #include "cn-cbor.h" 00018 #include "pv_error_handling.h" 00019 #include "fcc_bundle_utils.h" 00020 #include "fcc_malloc.h" 00021 #include "general_utils.h" 00022 #include "fcc_utils.h" 00023 #include "factory_configurator_client.h" 00024 #include "storage.h" 00025 00026 #define FCC_MAX_SIZE_OF_STRING 512 00027 00028 /** Gets name from cbor struct. 00029 * 00030 * @param text_cb[in] The cbor text structure 00031 * @param name_out[out] The out buffer for string data 00032 * @param name_len_out[out] The actual size of output buffer 00033 * 00034 * @return 00035 * true for success, false otherwise. 00036 */ 00037 static bool get_data_name(const cn_cbor *text_cb, uint8_t **name_out, size_t *name_len_out) 00038 { 00039 SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS(); 00040 SA_PV_ERR_RECOVERABLE_RETURN_IF((text_cb == NULL), false, "Cbor pointer is NULL"); 00041 SA_PV_ERR_RECOVERABLE_RETURN_IF((name_out == NULL), false, "Invalid pointer for name"); 00042 SA_PV_ERR_RECOVERABLE_RETURN_IF((name_len_out == NULL), false, "Invalid pointer for name_len"); 00043 00044 *name_out = (uint8_t*)fcc_malloc((size_t)(text_cb->length)); 00045 SA_PV_ERR_RECOVERABLE_RETURN_IF((*name_out == NULL), false, "Failed to allocate buffer for name"); 00046 00047 memcpy(*name_out, text_cb->v.bytes, (size_t)text_cb->length); 00048 *name_len_out = (size_t)text_cb->length; 00049 SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS(); 00050 00051 return true; 00052 } 00053 00054 /** Gets data format from cbor struct 00055 * 00056 * The function goes over all formats and compares it with format from cbor structure. 00057 * 00058 * @param data_cb[in] The cbor text structure 00059 * @param data_format[out] The format of data 00060 * 00061 * @return 00062 * true for success, false otherwise. 00063 */ 00064 static bool get_data_format(const cn_cbor *data_cb, fcc_bundle_data_format_e *data_format) 00065 { 00066 00067 int data_format_index; 00068 bool res; 00069 00070 SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS(); 00071 SA_PV_ERR_RECOVERABLE_RETURN_IF((data_cb == NULL), false, "data_cb is null"); 00072 SA_PV_ERR_RECOVERABLE_RETURN_IF((data_format == NULL), false, "data_format is null"); 00073 SA_PV_ERR_RECOVERABLE_RETURN_IF((*data_format != FCC_INVALID_DATA_FORMAT), false, "wrong data format value"); 00074 00075 for (data_format_index = 0; data_format_index < FCC_MAX_DATA_FORMAT - 1; data_format_index++) { 00076 res = is_memory_equal(fcc_bundle_data_format_lookup_table[data_format_index].data_format_name, 00077 strlen(fcc_bundle_data_format_lookup_table[data_format_index].data_format_name), 00078 data_cb->v.bytes, 00079 (size_t)(data_cb->length)); 00080 if (res) { 00081 *data_format = fcc_bundle_data_format_lookup_table[data_format_index].data_format_type; 00082 return true; 00083 } 00084 } 00085 SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS(); 00086 return false; 00087 } 00088 00089 bool get_data_buffer_from_cbor(const cn_cbor *data_cb, uint8_t **out_data_buffer, size_t *out_size) 00090 { 00091 00092 cn_cbor_type cb_type; 00093 00094 SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS(); 00095 SA_PV_ERR_RECOVERABLE_RETURN_IF((data_cb == NULL), false, "key_data_cb is null"); 00096 SA_PV_ERR_RECOVERABLE_RETURN_IF((out_size == NULL), false, "Size buffer is null "); 00097 SA_PV_ERR_RECOVERABLE_RETURN_IF((out_data_buffer == NULL), false, "Data buffer is null"); 00098 cb_type = data_cb->type; 00099 00100 switch (cb_type) { 00101 case CN_CBOR_TAG: 00102 *out_data_buffer = (uint8_t*)data_cb->first_child->v.bytes; 00103 *out_size = (size_t)data_cb->first_child->length; 00104 break; 00105 case CN_CBOR_TEXT: 00106 case CN_CBOR_BYTES: 00107 *out_data_buffer = (uint8_t*)data_cb->v.bytes; 00108 *out_size = (size_t)(data_cb->length); 00109 break; 00110 case CN_CBOR_UINT: 00111 *out_data_buffer = (uint8_t*)(&(data_cb->v.uint)); 00112 *out_size = (size_t)(data_cb->length); 00113 break; 00114 case CN_CBOR_INT: 00115 *out_data_buffer = (uint8_t*)(&(data_cb->v.sint)); 00116 *out_size = (size_t)(data_cb->length); 00117 break; 00118 default: 00119 SA_PV_LOG_ERR("Invalid cbor data type (%u)!", data_cb->type); 00120 return false; 00121 } 00122 SA_PV_LOG_TRACE_FUNC_EXIT("out_size=%" PRIu32 "", (uint32_t)*out_size); 00123 return true; 00124 } 00125 /** Frees all allocated memory of data parameter struct and sets initial values. 00126 * 00127 * @param data_param[in/out] The data parameter structure 00128 */ 00129 void fcc_bundle_clean_and_free_data_param(fcc_bundle_data_param_s *data_param) 00130 { 00131 SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS(); 00132 00133 if (data_param->name != NULL) { 00134 fcc_free(data_param->name); 00135 data_param->name = NULL; 00136 } 00137 00138 if (data_param->private_key_name != NULL) { 00139 fcc_free(data_param->private_key_name); 00140 data_param->private_key_name = NULL; 00141 } 00142 00143 data_param->array_cn = NULL; 00144 00145 //FIXME - in case we will support pem, add additional pointer data_der, that will point to allocated 00146 // memory and will always released in case not NULL nad data pointer will relate to user buffer allways. 00147 /*if (data_param->data_der != NULL) { 00148 fcc_stats_free(data_param->data_der); 00149 data_param->data_der = NULL; 00150 }*/ 00151 00152 memset(data_param, 0, sizeof(fcc_bundle_data_param_s)); 00153 SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS(); 00154 00155 } 00156 bool fcc_bundle_get_data_param(const cn_cbor *data_param_cb, fcc_bundle_data_param_s *data_param) 00157 { 00158 bool status = false; 00159 int data_param_index = 0; 00160 cn_cbor *data_param_value_cb; 00161 fcc_bundle_data_param_type_e data_param_type; 00162 00163 SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS(); 00164 00165 //Prepare key struct 00166 fcc_bundle_clean_and_free_data_param(data_param); 00167 00168 //Go over all key's parameters and extract it to appropriate key struct member 00169 for (data_param_index = FCC_BUNDLE_DATA_PARAM_NAME_TYPE; data_param_index < FCC_BUNDLE_DATA_PARAM_MAX_TYPE; data_param_index++) { 00170 00171 //Get value of parameter 00172 data_param_value_cb = cn_cbor_mapget_string(data_param_cb, fcc_bundle_data_param_lookup_table[data_param_index].data_param_name); 00173 00174 if (data_param_value_cb != NULL) { 00175 //Get type of parameter 00176 data_param_type = fcc_bundle_data_param_lookup_table[data_param_index].data_param_type; 00177 00178 switch (data_param_type) { 00179 case FCC_BUNDLE_DATA_PARAMETER_PRIVATE_KEY_NAME_TYPE: 00180 status = get_data_name(data_param_value_cb, &(data_param->private_key_name), &(data_param->private_key_name_len)); 00181 SA_PV_ERR_RECOVERABLE_GOTO_IF((status != true), status = false, error_exit, "Failed to get private key name"); 00182 break; 00183 00184 case FCC_BUNDLE_DATA_PARAM_NAME_TYPE: 00185 status = get_data_name(data_param_value_cb, &(data_param->name), &(data_param->name_len)); 00186 SA_PV_ERR_RECOVERABLE_GOTO_IF((status != true), status = false, error_exit, "Failed to get data parameter name"); 00187 break; 00188 00189 case FCC_BUNDLE_DATA_PARAM_SCHEME_TYPE: 00190 status = fcc_bundle_get_key_type(data_param_value_cb, (fcc_bundle_key_type_e*)&(data_param->type)); 00191 SA_PV_ERR_RECOVERABLE_GOTO_IF((status != true), status = false, error_exit, "Failed to get parameter type"); 00192 break; 00193 00194 case FCC_BUNDLE_DATA_PARAM_FORMAT_TYPE: 00195 status = get_data_format(data_param_value_cb, (fcc_bundle_data_format_e*)&(data_param->format)); 00196 SA_PV_ERR_RECOVERABLE_GOTO_IF((status != true), status = false, error_exit, "Failed to get key format"); 00197 break; 00198 00199 case FCC_BUNDLE_DATA_PARAM_DATA_TYPE: 00200 status = get_data_buffer_from_cbor(data_param_value_cb, &(data_param->data), &(data_param->data_size)); 00201 data_param->data_type = FCC_EXTERNAL_BUFFER_TYPE; 00202 SA_PV_ERR_RECOVERABLE_GOTO_IF((status != true), status = false, error_exit, "Failed to get parameter data"); 00203 break; 00204 case FCC_BUNDLE_DATA_PARAM_ARRAY_TYPE: 00205 data_param->array_cn = data_param_value_cb; 00206 break; 00207 case FCC_BUNDLE_DATA_PARAM_ACL_TYPE: 00208 status = get_data_buffer_from_cbor(data_param_value_cb, &(data_param->acl), &data_param->acl_size); 00209 SA_PV_ERR_RECOVERABLE_GOTO_IF((status != true), status = false, error_exit, "Failed to get acl data"); 00210 break; 00211 default: 00212 SA_PV_ERR_RECOVERABLE_GOTO_IF((true), status = false, error_exit, "Parameter's field name is illegal"); 00213 }//switch 00214 }//if 00215 }//for 00216 00217 //FIXME: should be uncommented if PEM format is supported. 00218 /* 00219 if (data_param->format == FCC_PEM_DATA_FORMAT) { 00220 //status = convert_certificate_from_pem_to_der((uint8_t**)&(data_param->data), &(data_param->data_size)); 00221 SA_PV_ERR_RECOVERABLE_GOTO_IF((status != true), status = false, error_exit, "Failed to convert the key from pem to der"); 00222 //key->data_type = FCC_INTERNAL_BUFFER_TYPE; 00223 } 00224 */ 00225 00226 SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS(); 00227 return status; 00228 00229 error_exit: 00230 fcc_bundle_clean_and_free_data_param(data_param); 00231 SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS(); 00232 return false; 00233 } 00234 00235 fcc_status_e fcc_bundle_process_buffer(cn_cbor *cbor_bytes,const char *rbp_item_name, fcc_bundle_data_buffer_type_e buffer_type) 00236 { 00237 uint8_t *buf; 00238 size_t buf_size; 00239 fcc_status_e fcc_status = FCC_STATUS_SUCCESS; 00240 bool status; 00241 00242 SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS(); 00243 00244 status = get_data_buffer_from_cbor(cbor_bytes, &buf, &buf_size); 00245 SA_PV_ERR_RECOVERABLE_GOTO_IF((status == false), fcc_status = FCC_STATUS_BUNDLE_ERROR, exit, "Unable to retrieve data from cn_cbor"); 00246 00247 00248 switch (buffer_type) { 00249 case(FCC_BUNDLE_BUFFER_TYPE_ROT): 00250 fcc_status = fcc_rot_set(buf, buf_size); 00251 break; 00252 case(FCC_BUNDLE_BUFFER_TYPE_ENTROPY): 00253 fcc_status = fcc_entropy_set(buf, buf_size); 00254 break; 00255 default: 00256 fcc_status = FCC_STATUS_ERROR; // Internal error should not happens. If it does, there is a bug in the code 00257 break; 00258 } 00259 00260 SA_PV_ERR_RECOVERABLE_GOTO_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status = fcc_status, exit, "Unable to store data"); 00261 00262 exit: 00263 if (fcc_status != FCC_STATUS_SUCCESS) { 00264 // In case of fcc_store_error_info failure we would still rather return the previous caught error. 00265 (void)fcc_store_error_info((const uint8_t*)rbp_item_name, strlen(rbp_item_name), fcc_status); 00266 } 00267 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00268 return fcc_status; 00269 } 00270 00271 fcc_status_e bundle_process_status_field(const cn_cbor *cbor_blob, char *cbor_group_name, size_t cbor_group_name_size, bool *fcc_field_status) 00272 { 00273 uint8_t *buff = NULL; 00274 size_t buff_size; 00275 uint32_t fcc_field_value; 00276 bool status; 00277 fcc_status_e fcc_status = FCC_STATUS_SUCCESS; 00278 00279 SA_PV_ERR_RECOVERABLE_GOTO_IF((cbor_blob == NULL), fcc_status = FCC_STATUS_INVALID_PARAMETER, exit, "Invalid param cbor_blob"); 00280 SA_PV_ERR_RECOVERABLE_GOTO_IF((cbor_blob->type != CN_CBOR_UINT), fcc_status = FCC_STATUS_BUNDLE_ERROR, exit, "Unexpected CBOR type"); 00281 00282 status = get_data_buffer_from_cbor(cbor_blob, &buff, &buff_size); 00283 SA_PV_ERR_RECOVERABLE_GOTO_IF((!status), fcc_status = FCC_STATUS_BUNDLE_ERROR, exit, "Unable to retrieve data from cn_cbor"); 00284 SA_PV_ERR_RECOVERABLE_GOTO_IF((buff_size != sizeof(fcc_field_value)), fcc_status = FCC_STATUS_BUNDLE_ERROR, exit, "Incorrect buffer size for field value"); 00285 00286 memcpy(&fcc_field_value, buff, buff_size); 00287 SA_PV_ERR_RECOVERABLE_GOTO_IF(((fcc_field_value != 0) && (fcc_field_value != 1)), fcc_status = FCC_STATUS_BUNDLE_ERROR, exit,"Unexpected value, should be either 0 or 1"); 00288 00289 if (fcc_field_value == 1) { 00290 *fcc_field_status = true; 00291 } 00292 else { 00293 *fcc_field_status = false; 00294 } 00295 00296 exit: 00297 if (fcc_status != FCC_STATUS_SUCCESS) 00298 { 00299 // In case of fcc_store_error_info failure we would still rather return the previous caught error. 00300 (void)fcc_store_error_info((const uint8_t*)cbor_group_name, cbor_group_name_size, fcc_status); 00301 } 00302 return fcc_status; 00303 } 00304 00305 00306 fcc_status_e fcc_bundle_factory_disable( void ) 00307 { 00308 00309 fcc_status_e fcc_status = FCC_STATUS_SUCCESS; 00310 00311 fcc_status = fcc_factory_disable(); 00312 SA_PV_ERR_RECOVERABLE_GOTO_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status = fcc_status, exit, "Failed to set factory disable flag"); 00313 00314 exit: 00315 if (fcc_status != FCC_STATUS_SUCCESS) { 00316 // In case of fcc_store_error_info failure we would still rather return the previous caught error. 00317 (void)fcc_store_error_info((const uint8_t*)STORAGE_RBP_FACTORY_DONE_NAME, strlen(STORAGE_RBP_FACTORY_DONE_NAME), fcc_status); 00318 } 00319 return fcc_status; 00320 }
Generated on Tue Jul 12 2022 20:20:59 by
