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.
key_config_manager.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 <stdbool.h> 00017 #include "key_config_manager.h" 00018 #include "storage.h" 00019 #include "pv_error_handling.h" 00020 #include "kcm_file_prefix_defs.h" 00021 #include "cs_der_certs.h" 00022 #include "cs_der_keys.h" 00023 #include "fcc_malloc.h" 00024 00025 00026 typedef enum { 00027 KCM_PRIVATE_KEY_DATA, 00028 KCM_PUBLIC_KEY_DATA, 00029 KCM_SYMMETRIC_KEY_DATA, 00030 KCM_CERTIFICATE_DATA, 00031 KCM_CONFIG_DATA, 00032 } kcm_data_type; 00033 00034 static bool kcm_initialized = false; 00035 00036 static kcm_status_e kcm_add_prefix_to_name(const uint8_t *kcm_name, size_t kcm_name_len, const char *prefix, uint8_t **kcm_buffer_out, size_t *kcm_buffer_size_allocated_out) 00037 { 00038 size_t prefix_length; 00039 00040 SA_PV_LOG_TRACE_FUNC_ENTER("name len=%" PRIu32 "", (uint32_t)kcm_name_len); 00041 00042 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_buffer_out == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid kcm_buffer_out parameter"); 00043 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_buffer_size_allocated_out == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid kcm_buffer_size_allocated_out parameter"); 00044 00045 prefix_length = strlen(prefix); 00046 00047 *kcm_buffer_out = (uint8_t *)fcc_malloc(kcm_name_len + prefix_length); 00048 SA_PV_ERR_RECOVERABLE_RETURN_IF((*kcm_buffer_out == NULL), KCM_STATUS_OUT_OF_MEMORY, "Failed allocating kcm_buffer_out"); 00049 00050 /* Append prefix and name to allocated buffer */ 00051 memcpy(*kcm_buffer_out, (uint8_t *)prefix, prefix_length); 00052 memcpy(*kcm_buffer_out + prefix_length, kcm_name, kcm_name_len); 00053 00054 *kcm_buffer_size_allocated_out = kcm_name_len + prefix_length; 00055 00056 SA_PV_LOG_TRACE_FUNC_EXIT("kcm_buffer_size_allocated_out= %" PRIu32 "", (uint32_t)*kcm_buffer_size_allocated_out); 00057 return KCM_STATUS_SUCCESS; 00058 } 00059 00060 00061 static kcm_status_e kcm_item_name_get_prefix(kcm_item_type_e kcm_item_type, const char** prefix) 00062 { 00063 kcm_status_e status = KCM_STATUS_SUCCESS; 00064 00065 switch (kcm_item_type) { 00066 case KCM_PRIVATE_KEY_ITEM: 00067 *prefix = KCM_FILE_PREFIX_PRIVATE_KEY; 00068 break; 00069 case KCM_PUBLIC_KEY_ITEM: 00070 *prefix = KCM_FILE_PREFIX_PUBLIC_KEY; 00071 break; 00072 case KCM_SYMMETRIC_KEY_ITEM: 00073 *prefix = KCM_FILE_PREFIX_SYMMETRIC_KEY; 00074 break; 00075 case KCM_CERTIFICATE_ITEM: 00076 *prefix = KCM_FILE_PREFIX_CERTIFICATE; 00077 break; 00078 case KCM_CONFIG_ITEM: 00079 *prefix = KCM_FILE_PREFIX_CONFIG_PARAM; 00080 break; 00081 case KCM_CERTIFICATE_CHAIN_ITEM: 00082 *prefix = KCM_FILE_PREFIX_CERTIFICATE_CHAIN; 00083 break; 00084 default: 00085 status = KCM_STATUS_INVALID_PARAMETER; 00086 break; 00087 } 00088 return status; 00089 } 00090 00091 kcm_status_e kcm_init(void) 00092 { 00093 kcm_status_e status = KCM_STATUS_SUCCESS; 00094 00095 SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS(); 00096 00097 if (!kcm_initialized) { 00098 status = storage_init(); 00099 SA_PV_ERR_RECOVERABLE_RETURN_IF((status != KCM_STATUS_SUCCESS), status, "Failed initializing storage\n"); 00100 kcm_initialized = true; 00101 } 00102 00103 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00104 00105 return status; 00106 } 00107 00108 kcm_status_e kcm_finalize(void) 00109 { 00110 kcm_status_e status = KCM_STATUS_SUCCESS; 00111 00112 SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS(); 00113 00114 if (kcm_initialized) { 00115 status = storage_finalize(); 00116 SA_PV_ERR_RECOVERABLE_RETURN_IF((status != KCM_STATUS_SUCCESS), status, "Failed finalizing storage\n"); 00117 kcm_initialized = false; 00118 } 00119 00120 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00121 00122 return status; 00123 } 00124 00125 kcm_status_e kcm_item_store(const uint8_t * kcm_item_name, size_t kcm_item_name_len, kcm_item_type_e kcm_item_type, bool kcm_item_is_factory, const uint8_t * kcm_item_data, size_t kcm_item_data_size, const kcm_security_desc_s security_desc) 00126 { 00127 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00128 kcm_ctx_s ctx; 00129 uint8_t *kcm_complete_name = NULL; // Filename including prefix 00130 size_t kcm_complete_name_size; 00131 const char *prefix; 00132 bool kcm_item_is_encrypted = true; //encrypt by default 00133 00134 SA_PV_LOG_INFO_FUNC_ENTER("item name = %.*s len=%" PRIu32 ", data size=%" PRIu32 "", (int)kcm_item_name_len, (char*)kcm_item_name, (uint32_t)kcm_item_name_len, (uint32_t)kcm_item_data_size); 00135 00136 // Check if KCM initialized, if not initialize it 00137 if (!kcm_initialized) { 00138 kcm_status = kcm_init(); 00139 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "KCM initialization failed\n"); 00140 } 00141 00142 00143 // Validate function parameters 00144 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_item_name == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid kcm_item_name"); 00145 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_item_name_len == 0), KCM_STATUS_INVALID_PARAMETER, "Invalid kcm_item_name_len"); 00146 SA_PV_ERR_RECOVERABLE_RETURN_IF(((kcm_item_data == NULL) && (kcm_item_data_size > 0)), KCM_STATUS_INVALID_PARAMETER, "Provided kcm_item_data NULL and kcm_item_data_size greater than 0"); 00147 00148 //temporary check that security descriptor is NULL 00149 SA_PV_ERR_RECOVERABLE_RETURN_IF((security_desc != NULL), KCM_STATUS_INVALID_PARAMETER, "Security descriptor is not NULL!"); 00150 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_item_type != KCM_CONFIG_ITEM && kcm_item_data_size == 0), KCM_STATUS_ITEM_IS_EMPTY, "The data of current item is empty!"); 00151 00152 switch (kcm_item_type) { 00153 case KCM_PRIVATE_KEY_ITEM: 00154 kcm_status = cs_der_priv_key_verify(kcm_item_data, kcm_item_data_size); 00155 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Private key validation failed"); 00156 break; 00157 case KCM_PUBLIC_KEY_ITEM: 00158 kcm_status = cs_der_public_key_verify(kcm_item_data, kcm_item_data_size); 00159 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Public key validation failed"); 00160 kcm_item_is_encrypted = false; //do not encrypt public key 00161 break; 00162 case KCM_SYMMETRIC_KEY_ITEM: 00163 //currently possible to write a symmetric key of size 0 since we do not check format 00164 break; 00165 case KCM_CERTIFICATE_ITEM: 00166 kcm_status = cs_parse_der_x509_cert(kcm_item_data, kcm_item_data_size); 00167 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Certificate validation failed"); 00168 kcm_item_is_encrypted = false; //do not encrypt certificates 00169 break; 00170 case KCM_CONFIG_ITEM: 00171 break; 00172 default: 00173 SA_PV_ERR_RECOVERABLE_RETURN_IF((true), KCM_STATUS_INVALID_PARAMETER, "Invalid kcm_item_type"); 00174 } 00175 00176 kcm_status = kcm_item_name_get_prefix(kcm_item_type, &prefix); 00177 SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS), (kcm_status = kcm_status), Exit, "Failed during kcm_item_name_get_prefix"); 00178 00179 kcm_status = kcm_add_prefix_to_name(kcm_item_name, kcm_item_name_len, prefix, &kcm_complete_name, &kcm_complete_name_size); 00180 SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS), (kcm_status = kcm_status), Exit, "Failed during kcm_add_prefix_to_name"); 00181 00182 kcm_status = storage_file_write(&ctx, kcm_complete_name, kcm_complete_name_size, kcm_item_data, kcm_item_data_size, kcm_item_is_factory, kcm_item_is_encrypted); 00183 SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS), (kcm_status = kcm_status), Exit, "Failed writing file to storage"); 00184 00185 Exit: 00186 fcc_free(kcm_complete_name); 00187 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00188 00189 return kcm_status; 00190 } 00191 00192 00193 kcm_status_e kcm_item_get_data_size(const uint8_t *kcm_item_name, size_t kcm_item_name_len, kcm_item_type_e kcm_item_type, size_t *kcm_item_data_size_out) 00194 { 00195 kcm_status_e status = KCM_STATUS_SUCCESS; 00196 uint8_t *kcm_complete_name = NULL; // Filename including prefix 00197 size_t kcm_complete_name_size; 00198 kcm_ctx_s ctx; 00199 size_t kcm_data_size = 0; 00200 const char *prefix; 00201 00202 SA_PV_LOG_INFO_FUNC_ENTER("item name = %.*s len=%" PRIu32 "", (int)kcm_item_name_len, (char*)kcm_item_name, (uint32_t)kcm_item_name_len); 00203 00204 // Check if KCM initialized, if not initialize it 00205 if (!kcm_initialized) { 00206 status = kcm_init(); 00207 SA_PV_ERR_RECOVERABLE_RETURN_IF((status != KCM_STATUS_SUCCESS), status, "KCM initialization failed\n"); 00208 } 00209 00210 // Validate function parameters 00211 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_item_name == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid kcm_item_name"); 00212 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_item_name_len == 0), KCM_STATUS_INVALID_PARAMETER, "Invalid kcm_item_name_len"); 00213 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_item_type >= KCM_LAST_ITEM), KCM_STATUS_INVALID_PARAMETER, "Invalid kcm_item_type"); 00214 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_item_data_size_out == NULL), KCM_STATUS_INVALID_PARAMETER, "Kcm size out pointer is NULL"); 00215 00216 status = kcm_item_name_get_prefix(kcm_item_type, &prefix); 00217 SA_PV_ERR_RECOVERABLE_GOTO_IF((status != KCM_STATUS_SUCCESS), (status = status), Exit, "Failed during kcm_item_name_get_prefix"); 00218 00219 status = kcm_add_prefix_to_name(kcm_item_name, kcm_item_name_len, prefix, &kcm_complete_name, &kcm_complete_name_size); 00220 SA_PV_ERR_RECOVERABLE_GOTO_IF((status != KCM_STATUS_SUCCESS), (status = status), Exit, "Failed during kcm_add_prefix_to_name"); 00221 00222 status = storage_file_size_get(&ctx, kcm_complete_name, kcm_complete_name_size, &kcm_data_size); 00223 SA_PV_ERR_RECOVERABLE_GOTO_IF((status != KCM_STATUS_SUCCESS), (status = status), Exit, "Failed in getting file size"); 00224 00225 *kcm_item_data_size_out = kcm_data_size; 00226 SA_PV_LOG_INFO_FUNC_EXIT("kcm data size = %" PRIu32 "", (uint32_t)*kcm_item_data_size_out); 00227 Exit: 00228 fcc_free(kcm_complete_name); 00229 00230 return status; 00231 } 00232 00233 00234 kcm_status_e kcm_item_get_data(const uint8_t * kcm_item_name, size_t kcm_item_name_len, kcm_item_type_e kcm_item_type, uint8_t * kcm_item_data_out, size_t kcm_item_data_max_size, size_t * kcm_item_data_act_size_out) 00235 { 00236 kcm_status_e status = KCM_STATUS_SUCCESS; 00237 uint8_t *kcm_complete_name = NULL; // Filename including prefix 00238 size_t kcm_complete_name_size; 00239 kcm_ctx_s ctx; 00240 const char *prefix; 00241 00242 SA_PV_LOG_INFO_FUNC_ENTER("item name = %.*s len = %" PRIu32 ", data max size = %" PRIu32 "", (int)kcm_item_name_len, (char*)kcm_item_name, (uint32_t)kcm_item_name_len, (uint32_t)kcm_item_data_max_size); 00243 00244 // Check if KCM initialized, if not initialize it 00245 if (!kcm_initialized) { 00246 status = kcm_init(); 00247 SA_PV_ERR_RECOVERABLE_RETURN_IF((status != KCM_STATUS_SUCCESS), status, "KCM initialization failed\n"); 00248 } 00249 00250 // Validate function parameters 00251 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_item_name == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid kcm_item_name"); 00252 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_item_name_len == 0), KCM_STATUS_INVALID_PARAMETER, "Invalid kcm_item_name_len"); 00253 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_item_type >= KCM_LAST_ITEM), KCM_STATUS_INVALID_PARAMETER, "Invalid kcm_item_type"); 00254 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_item_data_act_size_out == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid kcm_item_data_act_size_out"); 00255 SA_PV_ERR_RECOVERABLE_RETURN_IF(((kcm_item_data_out == NULL) && (kcm_item_data_max_size > 0)), KCM_STATUS_INVALID_PARAMETER, "Provided kcm_item_data NULL and kcm_item_data_size greater than 0"); 00256 00257 memset(&ctx, 0, sizeof(ctx)); 00258 status = kcm_item_name_get_prefix(kcm_item_type, &prefix); 00259 SA_PV_ERR_RECOVERABLE_GOTO_IF((status != KCM_STATUS_SUCCESS), (status = status), Exit, "Failed during kcm_item_name_get_prefix"); 00260 00261 status = kcm_add_prefix_to_name(kcm_item_name, kcm_item_name_len, prefix, &kcm_complete_name, &kcm_complete_name_size); 00262 SA_PV_ERR_RECOVERABLE_GOTO_IF((status != KCM_STATUS_SUCCESS), (status = status), Exit, "Failed during kcm_add_prefix_to_name"); 00263 00264 status = storage_file_read(&ctx, kcm_complete_name, kcm_complete_name_size, kcm_item_data_out, kcm_item_data_max_size, kcm_item_data_act_size_out); 00265 SA_PV_ERR_RECOVERABLE_GOTO_IF((status != KCM_STATUS_SUCCESS), (status = status), Exit, "Failed reading file from storage (%d)", status); 00266 00267 SA_PV_LOG_INFO_FUNC_EXIT("kcm data size = %" PRIu32 "", (uint32_t)*kcm_item_data_act_size_out); 00268 Exit: 00269 fcc_free(kcm_complete_name); 00270 00271 return status; 00272 } 00273 00274 00275 kcm_status_e kcm_item_delete(const uint8_t * kcm_item_name, size_t kcm_item_name_len, kcm_item_type_e kcm_item_type) 00276 { 00277 kcm_status_e status = KCM_STATUS_SUCCESS; 00278 uint8_t *kcm_complete_name = NULL; // Filename including prefix 00279 size_t kcm_complete_name_size; 00280 kcm_ctx_s ctx; // FIXME - Currently not implemented 00281 const char *prefix; 00282 00283 SA_PV_LOG_INFO_FUNC_ENTER("item name = %.*s len = %" PRIu32 "", (int)kcm_item_name_len, (char*)kcm_item_name, (uint32_t)kcm_item_name_len); 00284 00285 // Check if KCM initialized, if not initialize it 00286 if (!kcm_initialized) { 00287 status = kcm_init(); 00288 SA_PV_ERR_RECOVERABLE_RETURN_IF((status != KCM_STATUS_SUCCESS), status, "KCM initialization failed\n"); 00289 } 00290 00291 // Validate function parameters 00292 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_item_name == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid kcm_item_name"); 00293 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_item_name_len == 0), KCM_STATUS_INVALID_PARAMETER, "Invalid kcm_item_name_len"); 00294 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_item_type >= KCM_LAST_ITEM), KCM_STATUS_INVALID_PARAMETER, "Invalid kcm_item_type"); 00295 00296 status = kcm_item_name_get_prefix(kcm_item_type, &prefix); 00297 SA_PV_ERR_RECOVERABLE_GOTO_IF((status != KCM_STATUS_SUCCESS), (status = status), Exit, "Failed during kcm_item_name_get_prefix"); 00298 00299 status = kcm_add_prefix_to_name(kcm_item_name, kcm_item_name_len, prefix, &kcm_complete_name, &kcm_complete_name_size); 00300 SA_PV_ERR_RECOVERABLE_GOTO_IF((status != KCM_STATUS_SUCCESS), (status = status), Exit, "Failed during kcm_add_prefix_to_name"); 00301 00302 status = storage_file_delete(&ctx, kcm_complete_name, kcm_complete_name_size); 00303 SA_PV_ERR_RECOVERABLE_GOTO_IF((status != KCM_STATUS_SUCCESS), (status = status), Exit, "Failed deleting kcm data"); 00304 00305 Exit: 00306 fcc_free(kcm_complete_name); 00307 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00308 00309 return status; 00310 } 00311 00312 kcm_status_e kcm_factory_reset(void) 00313 { 00314 kcm_status_e status = KCM_STATUS_SUCCESS; 00315 00316 SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS(); 00317 00318 // Check if KCM initialized, if not initialize it 00319 if (!kcm_initialized) { 00320 status = kcm_init(); 00321 SA_PV_ERR_RECOVERABLE_RETURN_IF((status != KCM_STATUS_SUCCESS), status, "KCM initialization failed\n"); 00322 } 00323 00324 status = storage_factory_reset(); 00325 SA_PV_ERR_RECOVERABLE_GOTO_IF((status != KCM_STATUS_SUCCESS), (status = status), Exit, "Failed perform factory reset"); 00326 00327 Exit: 00328 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00329 return status; 00330 } 00331
Generated on Tue Jul 12 2022 16:22:06 by
1.7.2