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 "cs_der_certs.h" 00021 #include "cs_der_keys_and_csrs.h" 00022 #include "fcc_malloc.h" 00023 #include "pal.h" 00024 #include "cs_utils.h" 00025 #ifndef MBED_CONF_MBED_CLOUD_CLIENT_DISABLE_CERTIFICATE_ENROLLMENT 00026 #include "certificate_enrollment.h" 00027 #endif // MBED_CONF_MBED_CLOUD_CLIENT_DISABLE_CERTIFICATE_ENROLLMENT 00028 00029 00030 bool g_kcm_initialized = false; 00031 00032 kcm_status_e kcm_init(void) 00033 { 00034 kcm_status_e status = KCM_STATUS_SUCCESS; 00035 00036 SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS(); 00037 00038 if (!g_kcm_initialized) { 00039 palStatus_t pal_status; 00040 00041 //Initialize PAL 00042 pal_status = pal_init(); 00043 SA_PV_ERR_RECOVERABLE_RETURN_IF((pal_status != PAL_SUCCESS), KCM_STATUS_ERROR, "Failed initializing PAL (%" PRIu32 ")", pal_status); 00044 00045 /* 00046 * Do not initialize the time module inside pal_init since pal_initTime() uses storage functions. 00047 * At KCM init it is guaranteed that any entropy and RoT that should be injected - is already injected. 00048 */ 00049 pal_status = pal_initTime(); 00050 SA_PV_ERR_RECOVERABLE_RETURN_IF((pal_status != PAL_SUCCESS), KCM_STATUS_ERROR, "Failed PAL time module (%" PRIu32 ")", pal_status); 00051 00052 //Initialize back-end storage 00053 status = storage_init(); 00054 SA_PV_ERR_RECOVERABLE_RETURN_IF((status != KCM_STATUS_SUCCESS), status, "Failed initializing storage\n"); 00055 // Mark as "initialized" 00056 g_kcm_initialized = true; 00057 00058 #ifndef MBED_CONF_MBED_CLOUD_CLIENT_DISABLE_CERTIFICATE_ENROLLMENT 00059 //Check status of renewal process and restore backup items if needed 00060 ce_check_and_restore_backup_status(); 00061 #endif // MBED_CONF_MBED_CLOUD_CLIENT_DISABLE_CERTIFICATE_ENROLLMENT 00062 } 00063 00064 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00065 00066 return status; 00067 } 00068 00069 kcm_status_e kcm_finalize(void) 00070 { 00071 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00072 00073 SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS(); 00074 00075 if (g_kcm_initialized) { 00076 00077 kcm_status = storage_finalize(); 00078 if (kcm_status != KCM_STATUS_SUCCESS) { 00079 SA_PV_LOG_ERR("Failed finalizing storage\n"); 00080 } 00081 00082 //Finalize PAL 00083 pal_destroy(); 00084 00085 // Mark as "not initialized" 00086 g_kcm_initialized = false; 00087 } 00088 00089 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00090 00091 return kcm_status; 00092 } 00093 00094 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) 00095 { 00096 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00097 00098 SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS(); 00099 00100 // Check if KCM initialized, if not initialize it 00101 if (!g_kcm_initialized) { 00102 kcm_status = kcm_init(); 00103 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "KCM initialization failed\n"); 00104 } 00105 00106 // Validate function parameters 00107 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"); 00108 00109 //temporary check that security descriptor is NULL 00110 SA_PV_ERR_RECOVERABLE_RETURN_IF((security_desc != NULL), KCM_STATUS_INVALID_PARAMETER, "Security descriptor is not NULL!"); 00111 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!"); 00112 00113 switch (kcm_item_type) { 00114 case KCM_PRIVATE_KEY_ITEM: 00115 kcm_status = cs_der_priv_key_verify(kcm_item_data, kcm_item_data_size); 00116 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Private key validation failed"); 00117 break; 00118 case KCM_PUBLIC_KEY_ITEM: 00119 kcm_status = cs_der_public_key_verify(kcm_item_data, kcm_item_data_size); 00120 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Public key validation failed"); 00121 break; 00122 case KCM_SYMMETRIC_KEY_ITEM: 00123 //currently possible to write a symmetric key of size 0 since we do not check format 00124 break; 00125 case KCM_CERTIFICATE_ITEM: 00126 kcm_status = cs_check_der_x509_format(kcm_item_data, kcm_item_data_size); 00127 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Certificate validation failed"); 00128 break; 00129 case KCM_CONFIG_ITEM: 00130 break; 00131 default: 00132 SA_PV_ERR_RECOVERABLE_RETURN_IF((true), KCM_STATUS_INVALID_PARAMETER, "Invalid kcm_item_type"); 00133 } 00134 00135 kcm_status = storage_data_write(kcm_item_name, kcm_item_name_len, kcm_item_type, kcm_item_is_factory, KCM_ORIGINAL_ITEM, kcm_item_data, kcm_item_data_size); 00136 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Failed during storage_data_write"); 00137 00138 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00139 return kcm_status; 00140 } 00141 00142 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) 00143 { 00144 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00145 00146 kcm_status = storage_data_size_read(kcm_item_name, kcm_item_name_len, kcm_item_type, KCM_ORIGINAL_ITEM, kcm_item_data_size_out); 00147 if (kcm_status == KCM_STATUS_ITEM_NOT_FOUND) { 00148 return kcm_status; 00149 } 00150 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Failed during storage_data_size_read"); 00151 00152 return kcm_status; 00153 } 00154 00155 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) 00156 { 00157 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00158 00159 kcm_status = storage_data_read(kcm_item_name, kcm_item_name_len, kcm_item_type, KCM_ORIGINAL_ITEM, kcm_item_data_out, kcm_item_data_max_size, kcm_item_data_act_size_out); 00160 if (kcm_status == KCM_STATUS_ITEM_NOT_FOUND) { 00161 return kcm_status; 00162 } 00163 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Failed during storage_data_read"); 00164 00165 return kcm_status; 00166 } 00167 00168 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) 00169 { 00170 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00171 00172 kcm_status = storage_data_delete(kcm_item_name, kcm_item_name_len, kcm_item_type, KCM_ORIGINAL_ITEM); 00173 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Failed during storage_data_delete"); 00174 00175 return kcm_status; 00176 } 00177 00178 kcm_status_e kcm_factory_reset(void) 00179 { 00180 kcm_status_e status = KCM_STATUS_SUCCESS; 00181 00182 SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS(); 00183 00184 // Check if KCM initialized, if not initialize it 00185 if (!g_kcm_initialized) { 00186 status = kcm_init(); 00187 SA_PV_ERR_RECOVERABLE_RETURN_IF((status != KCM_STATUS_SUCCESS), status, "KCM initialization failed\n"); 00188 } 00189 00190 status = storage_factory_reset(); 00191 SA_PV_ERR_RECOVERABLE_GOTO_IF((status != KCM_STATUS_SUCCESS), (status = status), Exit, "Failed perform factory reset"); 00192 00193 Exit: 00194 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00195 return status; 00196 } 00197 00198 kcm_status_e kcm_cert_chain_create(kcm_cert_chain_handle *kcm_chain_handle, const uint8_t *kcm_chain_name, size_t kcm_chain_name_len, size_t kcm_chain_len, bool kcm_chain_is_factory) 00199 { 00200 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00201 00202 //Call internal storage_cert_chain_create 00203 kcm_status = storage_cert_chain_create(kcm_chain_handle, kcm_chain_name, kcm_chain_name_len, kcm_chain_len, kcm_chain_is_factory, KCM_ORIGINAL_ITEM); 00204 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Failed during storage_cert_chain_create"); 00205 00206 return kcm_status; 00207 } 00208 00209 kcm_status_e kcm_cert_chain_open(kcm_cert_chain_handle *kcm_chain_handle, const uint8_t *kcm_chain_name, size_t kcm_chain_name_len, size_t *kcm_chain_len_out) 00210 { 00211 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00212 00213 //Call internal storage_cert_chain_open 00214 kcm_status = storage_cert_chain_open(kcm_chain_handle, kcm_chain_name, kcm_chain_name_len, KCM_ORIGINAL_ITEM, kcm_chain_len_out); 00215 if (kcm_status == KCM_STATUS_ITEM_NOT_FOUND) { 00216 return kcm_status; 00217 } 00218 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Failed during storage_cert_chain_open"); 00219 00220 return kcm_status; 00221 } 00222 /* 00223 * If not first certificate in chain: 00224 * 1. Validate previously added certificate with the public key inside kcm_cert_data 00225 * 2. Set the chain_context->prev_cert_params to be the params of the current certificate so it can be validated with next call to this function. 00226 * 3. Store the current certificate 00227 * 4. Update the index of the chain handle iterator for next use of this function 00228 * If is first certificate in chain: 00229 * File already open - skip step 1 (no previous cert available). Note in this case the file should already be open so no need to reopen it 00230 */ 00231 kcm_status_e kcm_cert_chain_add_next(kcm_cert_chain_handle kcm_chain_handle, const uint8_t *kcm_cert_data, size_t kcm_cert_data_size) 00232 { 00233 kcm_cert_chain_context_int_s *chain_context = (kcm_cert_chain_context_int_s*)kcm_chain_handle; 00234 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00235 palX509Handle_t cert; 00236 00237 SA_PV_LOG_INFO_FUNC_ENTER("cert_data_size =%" PRIu32 "", (uint32_t)kcm_cert_data_size); 00238 00239 // Check if KCM initialized, if not initialize it 00240 if (!g_kcm_initialized) { 00241 kcm_status = kcm_init(); 00242 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "KCM initialization failed\n"); 00243 } 00244 00245 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_chain_handle == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid chain handle"); 00246 SA_PV_ERR_RECOVERABLE_RETURN_IF((chain_context->num_of_certificates_in_chain == 0), KCM_STATUS_INVALID_PARAMETER, "Invalid kcm context"); 00247 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_cert_data == NULL || kcm_cert_data_size == 0), KCM_STATUS_INVALID_PARAMETER, "Invalid kcm_cert_data or kcm_cert_data_size"); 00248 SA_PV_ERR_RECOVERABLE_RETURN_IF((chain_context->operation_type != KCM_CHAIN_OP_TYPE_CREATE), KCM_STATUS_INVALID_PARAMETER, "Invalid operation type"); 00249 SA_PV_ERR_RECOVERABLE_RETURN_IF((chain_context->current_cert_index >= chain_context->num_of_certificates_in_chain), KCM_STATUS_INVALID_NUM_OF_CERT_IN_CHAIN, "Invalid certificate index"); 00250 00251 // Parse the X509 and make sure it is of correct structure 00252 kcm_status = cs_create_handle_from_der_x509_cert(kcm_cert_data, kcm_cert_data_size, &cert); 00253 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Failed to parsing cert"); 00254 00255 if (chain_context->current_cert_index > 0) { 00256 // If not first certificate - validate based on params of previous certificate 00257 kcm_status = cs_x509_cert_verify_signature(cert, chain_context->prev_cert_params.htbs, 00258 chain_context->prev_cert_params.htbs_actual_size, 00259 chain_context->prev_cert_params.signature, 00260 chain_context->prev_cert_params.signature_actual_size); 00261 SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status == KCM_CRYPTO_STATUS_VERIFY_SIGNATURE_FAILED), (kcm_status = KCM_STATUS_CERTIFICATE_CHAIN_VERIFICATION_FAILED), Clean_X509, "Failed verifying child signature"); 00262 SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS), (kcm_status = kcm_status), Clean_X509, "Failed verifying child signature"); 00263 } 00264 00265 // Save params only if certificate is not last in chain 00266 if(chain_context->current_cert_index < chain_context->num_of_certificates_in_chain - 1) { 00267 // Get params needed for validation by the signer 00268 // These will be used to validate this certificate in the chain when parsing the next one 00269 kcm_status = cs_child_cert_params_get(cert, &chain_context->prev_cert_params); 00270 SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS), (kcm_status = kcm_status), Clean_X509, "Failed to retrieve child cert params"); 00271 } 00272 00273 //Call internal storage_chain_add_next 00274 kcm_status = storage_chain_add_next(kcm_chain_handle, kcm_cert_data, kcm_cert_data_size, KCM_ORIGINAL_ITEM); 00275 SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS), (kcm_status = kcm_status), Clean_X509, "Failed in storage_chain_add_next"); 00276 00277 Clean_X509: 00278 cs_close_handle_x509_cert(&cert); 00279 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00280 return kcm_status; 00281 } 00282 00283 00284 kcm_status_e kcm_cert_chain_delete(const uint8_t *kcm_chain_name, size_t kcm_chain_name_len) 00285 { 00286 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00287 00288 //Call internal storage_cert_chain_delete 00289 kcm_status = storage_cert_chain_delete(kcm_chain_name, kcm_chain_name_len, KCM_ORIGINAL_ITEM); 00290 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Failed during storage_cert_chain_delete"); 00291 00292 return kcm_status; 00293 } 00294 00295 00296 kcm_status_e kcm_cert_chain_get_next_size(kcm_cert_chain_handle kcm_chain_handle, size_t *kcm_cert_data_size) 00297 { 00298 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00299 00300 //Call internal storage_cert_chain_get_next_size 00301 kcm_status = storage_cert_chain_get_next_size(kcm_chain_handle, KCM_ORIGINAL_ITEM, kcm_cert_data_size ); 00302 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Failed during storage_cert_chain_get_next_size"); 00303 00304 return kcm_status; 00305 } 00306 00307 kcm_status_e kcm_cert_chain_get_next_data(kcm_cert_chain_handle kcm_chain_handle, uint8_t *kcm_cert_data, size_t kcm_max_cert_data_size, size_t *kcm_actual_cert_data_size) 00308 { 00309 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00310 00311 //Call internal storage_cert_chain_get_next_data 00312 kcm_status = storage_cert_chain_get_next_data(kcm_chain_handle, kcm_cert_data, kcm_max_cert_data_size, KCM_ORIGINAL_ITEM, kcm_actual_cert_data_size); 00313 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Failed during storage_cert_chain_get_next_data"); 00314 00315 return kcm_status; 00316 } 00317 00318 00319 kcm_status_e kcm_cert_chain_close(kcm_cert_chain_handle kcm_chain_handle) 00320 { 00321 00322 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00323 00324 //Call internal storage_cert_chain_close 00325 kcm_status = storage_cert_chain_close(kcm_chain_handle, KCM_ORIGINAL_ITEM); 00326 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Failed during storage_cert_chain_close") 00327 00328 return kcm_status; 00329 } 00330 00331 kcm_status_e kcm_key_pair_generate_and_store( 00332 const kcm_crypto_key_scheme_e key_scheme, 00333 const uint8_t *private_key_name, 00334 size_t private_key_name_len, 00335 const uint8_t *public_key_name, 00336 size_t public_key_name_len, 00337 bool kcm_item_is_factory, 00338 const kcm_security_desc_s *kcm_params) 00339 00340 { 00341 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00342 size_t actual_kcm_priv_key_size = 0; 00343 size_t actual_kcm_pub_key_size = 0; 00344 uint8_t priv_key_buffer[KCM_EC_SECP256R1_MAX_PRIV_KEY_DER_SIZE]; 00345 uint8_t pub_key_buffer[KCM_EC_SECP256R1_MAX_PUB_KEY_DER_SIZE]; 00346 bool pub_key_exists = false; 00347 00348 // Check if KCM initialized, if not initialize it 00349 if (!g_kcm_initialized) { 00350 kcm_status = kcm_init(); 00351 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "KCM initialization failed\n"); 00352 } 00353 00354 //temporary check that kcm_params is NULL 00355 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_params != NULL), KCM_STATUS_INVALID_PARAMETER, "kcm_params is not NULL!"); 00356 00357 //check input params 00358 SA_PV_ERR_RECOVERABLE_RETURN_IF((key_scheme != KCM_SCHEME_EC_SECP256R1), KCM_STATUS_INVALID_PARAMETER, "Invalid key_scheme"); 00359 SA_PV_ERR_RECOVERABLE_RETURN_IF((private_key_name == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid private_key_name"); 00360 SA_PV_ERR_RECOVERABLE_RETURN_IF((private_key_name_len == 0), KCM_STATUS_INVALID_PARAMETER, "Invalid private_key_name_len"); 00361 SA_PV_ERR_RECOVERABLE_RETURN_IF(((public_key_name != NULL) && (public_key_name_len == 0)), KCM_STATUS_INVALID_PARAMETER, "public_key_name is not NULL, but its size is 0"); 00362 SA_PV_ERR_RECOVERABLE_RETURN_IF(((public_key_name == NULL) && (public_key_name_len != 0)), KCM_STATUS_INVALID_PARAMETER, "public_key_name is NULL, but its size is not 0"); 00363 00364 SA_PV_LOG_INFO_FUNC_ENTER("priv_key_name = %.*s priv_key_len = %" PRIu32 ", pub_key_name = %.*s pub_key_len = %" PRIu32, 00365 (int)private_key_name_len, (char*)private_key_name, (uint32_t)private_key_name_len, (int)public_key_name_len, (char*)public_key_name, (uint32_t)public_key_name_len); 00366 00367 pub_key_exists = ((public_key_name != NULL) && (public_key_name_len != 0)); 00368 00369 //check private key existence 00370 kcm_status = kcm_item_get_data_size(private_key_name, private_key_name_len, KCM_PRIVATE_KEY_ITEM, 00371 &actual_kcm_priv_key_size); 00372 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status == KCM_STATUS_SUCCESS), KCM_STATUS_KEY_EXIST, "private key already exists"); 00373 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_ITEM_NOT_FOUND), kcm_status, "failed to check private key existence"); 00374 00375 //fetch public key if exists 00376 if (pub_key_exists) { 00377 kcm_status = kcm_item_get_data_size(public_key_name, public_key_name_len, KCM_PUBLIC_KEY_ITEM, 00378 &actual_kcm_pub_key_size); 00379 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status == KCM_STATUS_SUCCESS), KCM_STATUS_KEY_EXIST, "public key already exists"); 00380 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_ITEM_NOT_FOUND), kcm_status, "failed to check public key existence"); 00381 } 00382 00383 //generate key pair 00384 kcm_status = cs_key_pair_generate(key_scheme, priv_key_buffer, sizeof(priv_key_buffer), &actual_kcm_priv_key_size, pub_key_buffer, sizeof(pub_key_buffer), &actual_kcm_pub_key_size); 00385 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "failed to generate key pair"); 00386 00387 //store private key 00388 kcm_status = kcm_item_store(private_key_name, private_key_name_len, KCM_PRIVATE_KEY_ITEM, kcm_item_is_factory, priv_key_buffer, actual_kcm_priv_key_size, NULL); 00389 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "failed to store private key"); 00390 00391 //store public key if exists 00392 if (pub_key_exists) { 00393 kcm_status = kcm_item_store(public_key_name, public_key_name_len, KCM_PUBLIC_KEY_ITEM, kcm_item_is_factory, pub_key_buffer, actual_kcm_pub_key_size, NULL); 00394 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "failed to store public key"); 00395 } 00396 00397 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00398 00399 return kcm_status; 00400 } 00401 00402 00403 kcm_status_e kcm_csr_generate( 00404 const uint8_t *private_key_name, 00405 size_t private_key_name_len, 00406 const kcm_csr_params_s *csr_params, 00407 uint8_t *csr_buff_out, 00408 size_t csr_buff_max_size, 00409 size_t *csr_buff_act_size) 00410 { 00411 00412 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00413 size_t prv_key_size, actual_prv_key_size = 0; 00414 uint8_t priv_key_buffer[KCM_EC_SECP256R1_MAX_PRIV_KEY_DER_SIZE]; 00415 00416 // Check if KCM initialized, if not initialize it 00417 if (!g_kcm_initialized) { 00418 kcm_status = kcm_init(); 00419 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "KCM initialization failed\n"); 00420 } 00421 00422 SA_PV_ERR_RECOVERABLE_RETURN_IF((private_key_name == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid private_key_name"); 00423 SA_PV_ERR_RECOVERABLE_RETURN_IF((private_key_name_len == 0), KCM_STATUS_INVALID_PARAMETER, "Invalid private_key_name_len"); 00424 SA_PV_ERR_RECOVERABLE_RETURN_IF((csr_params == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid csr_params"); 00425 SA_PV_ERR_RECOVERABLE_RETURN_IF((csr_params->subject == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid subject name"); 00426 SA_PV_ERR_RECOVERABLE_RETURN_IF((csr_params->md_type == KCM_MD_NONE), KCM_STATUS_INVALID_PARAMETER, "Invalid md type"); 00427 SA_PV_ERR_RECOVERABLE_RETURN_IF((csr_buff_out == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid csr_buff_out"); 00428 SA_PV_ERR_RECOVERABLE_RETURN_IF((csr_buff_max_size == 0), KCM_STATUS_INVALID_PARAMETER, "Invalid csr_buff_max_size"); 00429 SA_PV_ERR_RECOVERABLE_RETURN_IF((csr_buff_act_size == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid csr_buff_act_size"); 00430 00431 SA_PV_LOG_INFO_FUNC_ENTER("priv_key_name = %.*s priv_key_len = %" PRIu32", csr_buff_max_size = %" PRIu32, 00432 (int)private_key_name_len, (char*)private_key_name, (uint32_t)private_key_name_len, (uint32_t)csr_buff_max_size); 00433 00434 //fetch private key size 00435 kcm_status = kcm_item_get_data_size(private_key_name, private_key_name_len, KCM_PRIVATE_KEY_ITEM, 00436 &prv_key_size); 00437 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "failed to get private key data size"); 00438 SA_PV_ERR_RECOVERABLE_RETURN_IF((prv_key_size == 0), kcm_status, "Size of private key is 0"); 00439 00440 //fetch private key 00441 kcm_status = kcm_item_get_data(private_key_name, private_key_name_len, KCM_PRIVATE_KEY_ITEM, priv_key_buffer, 00442 prv_key_size, &actual_prv_key_size); 00443 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "failed to get private key"); 00444 SA_PV_ERR_RECOVERABLE_RETURN_IF((actual_prv_key_size == 0), kcm_status = KCM_STATUS_ITEM_IS_EMPTY, "Size of private key is 0"); 00445 00446 //generate csr 00447 kcm_status = cs_csr_generate(priv_key_buffer, actual_prv_key_size, csr_params, csr_buff_out, csr_buff_max_size, csr_buff_act_size); 00448 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "failed to generate CSR"); 00449 00450 SA_PV_LOG_INFO_FUNC_EXIT("csr_buff_act_size = %" PRIu32 "", (uint32_t)*csr_buff_act_size); 00451 00452 return kcm_status; 00453 00454 } 00455 00456 00457 kcm_status_e kcm_generate_keys_and_csr( 00458 kcm_crypto_key_scheme_e key_scheme, 00459 const uint8_t *private_key_name, 00460 size_t private_key_name_len, 00461 const uint8_t *public_key_name, 00462 size_t public_key_name_len, 00463 bool kcm_item_is_factory, 00464 const kcm_csr_params_s *csr_params, 00465 uint8_t *csr_buff_out, 00466 size_t csr_buff_max_size, 00467 size_t *csr_buff_act_size_out, 00468 const kcm_security_desc_s *kcm_params) 00469 { 00470 00471 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00472 size_t actual_kcm_key_size = 0; 00473 size_t priv_key_act_size_out = 0; 00474 size_t pub_key_act_size_out = 0; 00475 uint8_t priv_key_buffer[KCM_EC_SECP256R1_MAX_PRIV_KEY_DER_SIZE]; 00476 uint8_t pub_key_buffer[KCM_EC_SECP256R1_MAX_PUB_KEY_DER_SIZE]; 00477 bool pub_key_exists = false; 00478 00479 // Check if KCM initialized, if not initialize it 00480 if (!g_kcm_initialized) { 00481 kcm_status = kcm_init(); 00482 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "KCM initialization failed\n"); 00483 } 00484 00485 //temporary check that kcm_params is NULL 00486 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_params != NULL), KCM_STATUS_INVALID_PARAMETER, "kcm_params is not NULL!"); 00487 00488 //check input params 00489 SA_PV_ERR_RECOVERABLE_RETURN_IF((key_scheme != KCM_SCHEME_EC_SECP256R1), KCM_STATUS_INVALID_PARAMETER, "Invalid key_scheme"); 00490 SA_PV_ERR_RECOVERABLE_RETURN_IF((private_key_name == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid private_key_name"); 00491 SA_PV_ERR_RECOVERABLE_RETURN_IF((private_key_name_len == 0), KCM_STATUS_INVALID_PARAMETER, "Invalid private_key_name_len"); 00492 SA_PV_ERR_RECOVERABLE_RETURN_IF(((public_key_name != NULL) && (public_key_name_len == 0)), KCM_STATUS_INVALID_PARAMETER, "public_key_name is not NULL, but its size is 0"); 00493 SA_PV_ERR_RECOVERABLE_RETURN_IF(((public_key_name == NULL) && (public_key_name_len != 0)), KCM_STATUS_INVALID_PARAMETER, "public_key_name is NULL, but its size is not 0"); 00494 SA_PV_ERR_RECOVERABLE_RETURN_IF((csr_params == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid csr_params"); 00495 SA_PV_ERR_RECOVERABLE_RETURN_IF((csr_params->subject == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid subject name"); 00496 SA_PV_ERR_RECOVERABLE_RETURN_IF((csr_params->md_type == KCM_MD_NONE), KCM_STATUS_INVALID_PARAMETER, "Invalid md type"); 00497 SA_PV_ERR_RECOVERABLE_RETURN_IF((csr_buff_out == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid csr_buff_out"); 00498 SA_PV_ERR_RECOVERABLE_RETURN_IF((csr_buff_max_size == 0), KCM_STATUS_INVALID_PARAMETER, "Invalid csr_buff_max_size"); 00499 SA_PV_ERR_RECOVERABLE_RETURN_IF((csr_buff_act_size_out == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid csr_buff_act_size"); 00500 00501 SA_PV_LOG_INFO_FUNC_ENTER("priv_key_name = %.*s priv_key_len = %" PRIu32 ", pub_key_name = %.*s pub_key_len = %" PRIu32, 00502 (int)private_key_name_len, (char*)private_key_name, (uint32_t)private_key_name_len, (int)public_key_name_len, (char*)public_key_name, (uint32_t)public_key_name_len); 00503 00504 pub_key_exists = ((public_key_name != NULL) && (public_key_name_len != 0)); 00505 00506 //check private key existence 00507 kcm_status = kcm_item_get_data_size(private_key_name, private_key_name_len, KCM_PRIVATE_KEY_ITEM, 00508 &actual_kcm_key_size); 00509 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status == KCM_STATUS_SUCCESS), KCM_STATUS_KEY_EXIST, "private key already exists"); 00510 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_ITEM_NOT_FOUND), kcm_status, "failed to check private key existence"); 00511 00512 //check public key existence 00513 if (pub_key_exists) { 00514 kcm_status = kcm_item_get_data_size(public_key_name, public_key_name_len, KCM_PUBLIC_KEY_ITEM, 00515 &actual_kcm_key_size); 00516 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status == KCM_STATUS_SUCCESS), KCM_STATUS_KEY_EXIST, "public key already exists"); 00517 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_ITEM_NOT_FOUND), kcm_status, "failed to check public key existence"); 00518 } 00519 00520 //generat keys and csr 00521 kcm_status = cs_generate_keys_and_csr(key_scheme, csr_params, priv_key_buffer, sizeof(priv_key_buffer), &priv_key_act_size_out, pub_key_buffer, sizeof(pub_key_buffer), &pub_key_act_size_out, csr_buff_out, csr_buff_max_size, csr_buff_act_size_out); 00522 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "failed to generate keys and csr"); 00523 00524 //store private key 00525 kcm_status = kcm_item_store(private_key_name, private_key_name_len, KCM_PRIVATE_KEY_ITEM, kcm_item_is_factory, priv_key_buffer, sizeof(priv_key_buffer), NULL); 00526 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "failed to store private key"); 00527 00528 //store public key 00529 if (pub_key_exists) { 00530 kcm_status = kcm_item_store(public_key_name, public_key_name_len, KCM_PUBLIC_KEY_ITEM, kcm_item_is_factory, pub_key_buffer, sizeof(pub_key_buffer), NULL); 00531 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "failed to store public key"); 00532 } 00533 00534 00535 SA_PV_LOG_INFO_FUNC_EXIT("csr_buff_act_size_out = %" PRIu32 "", (uint32_t)*csr_buff_act_size_out); 00536 return kcm_status; 00537 00538 } 00539 00540 kcm_status_e kcm_certificate_verify_with_private_key( 00541 const uint8_t * kcm_cert_data, 00542 size_t kcm_cert_data_size, 00543 const uint8_t * kcm_priv_key_name, 00544 size_t kcm_priv_key_name_len) 00545 { 00546 00547 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00548 size_t priv_key_data_size = 0; 00549 uint8_t *priv_key_data = NULL; 00550 size_t act_priv_key_data_size = 0; 00551 palX509Handle_t x509_cert; 00552 00553 // Check if KCM initialized, if not initialize it 00554 if (!g_kcm_initialized) { 00555 kcm_status = kcm_init(); 00556 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "KCM initialization failed\n"); 00557 } 00558 00559 //check input params 00560 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_cert_data == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid kcm_cert_data"); 00561 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_cert_data_size == 0), KCM_STATUS_INVALID_PARAMETER, "Invalid kcm_cert_data_size"); 00562 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_priv_key_name == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid kcm_priv_key_name"); 00563 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_priv_key_name_len == 0), KCM_STATUS_INVALID_PARAMETER, "Invalid kcm_priv_key_name_len"); 00564 SA_PV_LOG_INFO_FUNC_ENTER("priv key name = %.*s, cert size=%" PRIu32 "", (int)kcm_priv_key_name_len, (char*)kcm_priv_key_name,(uint32_t)kcm_cert_data_size); 00565 00566 //Get private key size 00567 kcm_status = kcm_item_get_data_size(kcm_priv_key_name, 00568 kcm_priv_key_name_len, 00569 KCM_PRIVATE_KEY_ITEM, 00570 &priv_key_data_size); 00571 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS || priv_key_data_size == 0), kcm_status, "Failed to get kcm private key size"); 00572 00573 //Allocate memory and get private key data 00574 priv_key_data = fcc_malloc(priv_key_data_size); 00575 SA_PV_ERR_RECOVERABLE_RETURN_IF((priv_key_data == NULL), kcm_status = KCM_STATUS_OUT_OF_MEMORY, "Failed to allocate buffer for private key data"); 00576 00577 //Get private key data 00578 kcm_status = kcm_item_get_data(kcm_priv_key_name, 00579 kcm_priv_key_name_len, 00580 KCM_PRIVATE_KEY_ITEM, 00581 priv_key_data, 00582 priv_key_data_size, 00583 &act_priv_key_data_size); 00584 SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS || act_priv_key_data_size != priv_key_data_size), (kcm_status = kcm_status), Exit, "Failed to get private key data"); 00585 00586 //Create certificate handle 00587 kcm_status = cs_create_handle_from_der_x509_cert(kcm_cert_data, kcm_cert_data_size, &x509_cert); 00588 SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS), (kcm_status = kcm_status), Exit, "Failed to create certificate handle"); 00589 00590 //Check current certificate against given private key 00591 kcm_status = cs_check_certifcate_public_key(x509_cert, priv_key_data, priv_key_data_size); 00592 SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS), (kcm_status = KCM_STATUS_SELF_GENERATED_CERTIFICATE_VERIFICATION_ERROR), Exit, "Certificate verification failed against private key"); 00593 00594 SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS(); 00595 Exit: 00596 00597 fcc_free(priv_key_data); 00598 cs_close_handle_x509_cert(&x509_cert); 00599 return kcm_status; 00600 00601 } 00602 00603
Generated on Mon Aug 29 2022 19:53:39 by
