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
cs_der_keys_and_csrs.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 00017 #include "pv_error_handling.h" 00018 #include "cs_der_keys_and_csrs.h" 00019 #include "cs_der_certs.h" 00020 #include "pal.h" 00021 #include "cs_utils.h" 00022 #include "cs_hash.h" 00023 #include "pk.h" 00024 #include "fcc_malloc.h" 00025 00026 00027 /*! Frees key handle. 00028 * @param[in] grp curve handle 00029 * @param[in] key_handle key handle. 00030 * @void 00031 */ 00032 static kcm_status_e cs_free_pal_key_handle(palCurveHandle_t *grp, palECKeyHandle_t *key_handle) 00033 { 00034 //Free curve handler 00035 (void)pal_ECGroupFree(grp); 00036 //Free key handler 00037 (void)pal_ECKeyFree(key_handle); 00038 00039 SA_PV_ERR_RECOVERABLE_RETURN_IF((*grp != NULLPTR || *key_handle != NULLPTR), KCM_STATUS_ERROR, "Free handle failed "); 00040 00041 return KCM_STATUS_SUCCESS; 00042 } 00043 00044 00045 /*! Creates and initializes key handle according to passed parameters. 00046 * @param[in] key_data pointer to key buffer. 00047 * @param[in] key_data_size size of key buffer. 00048 * @param[in] key_type pal key type(public or private) 00049 * @param[in/out] grp curve handle 00050 * @param[in/out] key_handle key handle. 00051 * @returns 00052 * KCM_STATUS_SUCCESS in case of success or one of the `::kcm_status_e` errors otherwise. 00053 */ 00054 00055 static kcm_status_e cs_init_and_set_pal_key_handle(const uint8_t *key_data, size_t key_data_size, palKeyToCheck_t key_type, palCurveHandle_t *grp, palECKeyHandle_t *key_handle) 00056 { 00057 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00058 kcm_status_e kcm_free_status = KCM_STATUS_SUCCESS; 00059 palStatus_t pal_status = PAL_SUCCESS; 00060 palGroupIndex_t pal_grp_idx; 00061 00062 SA_PV_ERR_RECOVERABLE_RETURN_IF((key_data == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid key pointer"); 00063 SA_PV_ERR_RECOVERABLE_RETURN_IF((key_data_size == 0), KCM_STATUS_INVALID_PARAMETER, "Invalid key size"); 00064 SA_PV_ERR_RECOVERABLE_RETURN_IF((key_type != PAL_CHECK_PRIVATE_KEY && key_type != PAL_CHECK_PUBLIC_KEY), KCM_STATUS_INVALID_PARAMETER, "Invalid key type"); 00065 00066 //Create new key handler 00067 pal_status = pal_ECKeyNew(key_handle); 00068 SA_PV_ERR_RECOVERABLE_RETURN_IF((PAL_SUCCESS != pal_status), cs_error_handler(pal_status), "pal_ECKeyNew failed "); 00069 00070 if (key_type == PAL_CHECK_PRIVATE_KEY) 00071 { 00072 //Parse der private key 00073 pal_status = pal_parseECPrivateKeyFromDER(key_data, key_data_size, *key_handle); 00074 SA_PV_ERR_RECOVERABLE_GOTO_IF((PAL_SUCCESS != pal_status), kcm_status = cs_error_handler(pal_status), exit, "pal_parseECPrivateKeyFromDER failed "); 00075 } else { 00076 //Parse der public key 00077 pal_status = pal_parseECPublicKeyFromDER(key_data, key_data_size, *key_handle); 00078 SA_PV_ERR_RECOVERABLE_GOTO_IF((PAL_SUCCESS != pal_status), kcm_status = cs_error_handler(pal_status), exit, "pal_parseECPublicKeyFromDER failed "); 00079 } 00080 00081 //retrieve key curve from key handle 00082 pal_status = pal_ECKeyGetCurve(*key_handle, &pal_grp_idx); 00083 SA_PV_ERR_RECOVERABLE_GOTO_IF((PAL_SUCCESS != pal_status), kcm_status = cs_error_handler(pal_status), exit, "pal_ECKeyGetCurve failed "); 00084 00085 //Load the key curve 00086 pal_status = pal_ECGroupInitAndLoad(grp, pal_grp_idx); 00087 SA_PV_ERR_RECOVERABLE_GOTO_IF((PAL_SUCCESS != pal_status), kcm_status = cs_error_handler(pal_status), exit, "pal_ECGroupInitAndLoad failed "); 00088 00089 return kcm_status; 00090 00091 exit: 00092 //Free curve handler and key handle 00093 kcm_free_status = cs_free_pal_key_handle(grp, key_handle); 00094 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_free_status != KCM_STATUS_SUCCESS), kcm_free_status, "failed in cs_free_pal_key_handle"); 00095 00096 return kcm_status; 00097 } 00098 00099 //For now only EC keys supported!!! 00100 static kcm_status_e der_key_verify(const uint8_t *der_key, size_t der_key_length, palKeyToCheck_t key_type) 00101 { 00102 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00103 kcm_status_e kcm_free_status = KCM_STATUS_SUCCESS; 00104 palStatus_t pal_status = PAL_SUCCESS; 00105 palECKeyHandle_t key_handle = NULLPTR; 00106 palCurveHandle_t grp = NULLPTR; 00107 bool verified = false; 00108 00109 00110 SA_PV_ERR_RECOVERABLE_RETURN_IF((der_key == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid der_key pointer"); 00111 SA_PV_ERR_RECOVERABLE_RETURN_IF((der_key_length <= 0), KCM_STATUS_INVALID_PARAMETER, "Invalid der_key_length"); 00112 00113 //Create new key handler 00114 kcm_status = cs_init_and_set_pal_key_handle(der_key, der_key_length, key_type, &grp, &key_handle); 00115 SA_PV_ERR_RECOVERABLE_RETURN_IF((KCM_STATUS_SUCCESS != kcm_status), kcm_status = kcm_status, "cs_init_and_set_pal_key_handle failed "); 00116 00117 //Perform key verification 00118 pal_status = pal_ECCheckKey(grp, key_handle, key_type, &verified); 00119 SA_PV_ERR_RECOVERABLE_GOTO_IF(((PAL_SUCCESS != pal_status) || (verified != true)), kcm_status = cs_error_handler(pal_status), exit, "pal_ECCheckKey failed "); 00120 00121 00122 exit: 00123 //Free curve handler and key handle 00124 kcm_free_status = cs_free_pal_key_handle(&grp, &key_handle); 00125 SA_PV_ERR_RECOVERABLE_RETURN_IF((KCM_STATUS_SUCCESS != kcm_free_status), kcm_free_status, "failed in cs_free_pal_key_handle "); 00126 00127 return kcm_status; 00128 } 00129 00130 static kcm_status_e cs_key_pair_generate_int(palECKeyHandle_t key_handle, kcm_crypto_key_scheme_e curve_name, uint8_t *priv_key_out, size_t priv_key_max_size, 00131 size_t *priv_key_act_size_out, uint8_t *pub_key_out, size_t pub_key_max_size, size_t *pub_key_act_size_out) 00132 { 00133 palStatus_t pal_status = PAL_SUCCESS; 00134 palGroupIndex_t pal_group_id; 00135 00136 SA_PV_ERR_RECOVERABLE_RETURN_IF((priv_key_out == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid out private key buffer"); 00137 SA_PV_ERR_RECOVERABLE_RETURN_IF((priv_key_max_size == 0), KCM_STATUS_INVALID_PARAMETER, "Invalid max private key size"); 00138 SA_PV_ERR_RECOVERABLE_RETURN_IF((priv_key_act_size_out == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid out private key size"); 00139 if (pub_key_out != NULL) { 00140 SA_PV_ERR_RECOVERABLE_RETURN_IF((pub_key_max_size == 0), KCM_STATUS_INVALID_PARAMETER, "Invalid max public key size"); 00141 SA_PV_ERR_RECOVERABLE_RETURN_IF((pub_key_act_size_out == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid out public key size"); 00142 } 00143 00144 // convert curve_name to pal_group_id 00145 switch (curve_name) { 00146 case KCM_SCHEME_EC_SECP256R1: 00147 pal_group_id = PAL_ECP_DP_SECP256R1; 00148 break; 00149 default: 00150 SA_PV_ERR_RECOVERABLE_RETURN_IF(true, KCM_CRYPTO_STATUS_UNSUPPORTED_CURVE, "unsupported curve name"); 00151 } 00152 00153 // Generate keys 00154 pal_status = pal_ECKeyGenerateKey(pal_group_id, key_handle); 00155 SA_PV_ERR_RECOVERABLE_RETURN_IF((PAL_SUCCESS != pal_status), cs_error_handler(pal_status), "Failed to generate keys"); 00156 00157 // Save private key to out buffer 00158 pal_status = pal_writePrivateKeyToDer(key_handle, priv_key_out, priv_key_max_size, priv_key_act_size_out); 00159 SA_PV_ERR_RECOVERABLE_RETURN_IF((PAL_SUCCESS != pal_status), cs_error_handler(pal_status), "Failed to write private key to out buffer"); 00160 00161 if (pub_key_out != NULL) { 00162 // Save public key to out buffer 00163 pal_status = pal_writePublicKeyToDer(key_handle, pub_key_out, pub_key_max_size, pub_key_act_size_out); 00164 SA_PV_ERR_RECOVERABLE_RETURN_IF((PAL_SUCCESS != pal_status), cs_error_handler(pal_status), "Failed to write public key to out buffer"); 00165 } 00166 00167 return KCM_STATUS_SUCCESS; 00168 } 00169 //For now only EC SECP256R keys supported!!! 00170 kcm_status_e cs_get_pub_raw_key_from_der(const uint8_t *der_key, size_t der_key_length, uint8_t *raw_key_data_out, size_t raw_key_data_max_size, size_t *raw_key_data_act_size_out) 00171 { 00172 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00173 palStatus_t pal_status = PAL_SUCCESS; 00174 int mbdtls_result = 0; 00175 palECKeyHandle_t key_handle = NULLPTR; 00176 mbedtls_pk_context* localECKey; 00177 mbedtls_ecp_keypair *ecp_key_pair; 00178 00179 SA_PV_ERR_RECOVERABLE_RETURN_IF((der_key == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid der_key pointer"); 00180 SA_PV_ERR_RECOVERABLE_RETURN_IF((der_key_length != KCM_EC_SECP256R1_MAX_PUB_KEY_DER_SIZE), KCM_STATUS_INVALID_PARAMETER, "Invalid der_key_length"); 00181 SA_PV_ERR_RECOVERABLE_RETURN_IF((raw_key_data_out == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid raw_key_data_out"); 00182 SA_PV_ERR_RECOVERABLE_RETURN_IF((raw_key_data_act_size_out == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid raw_key_data_act_size_out pointer"); 00183 SA_PV_ERR_RECOVERABLE_RETURN_IF((raw_key_data_max_size < KCM_EC_SECP256R1_MAX_PUB_KEY_RAW_SIZE), KCM_STATUS_INVALID_PARAMETER, "Invalid raw_key_size_out value"); 00184 00185 //Create new key handler 00186 pal_status = pal_ECKeyNew(&key_handle); 00187 SA_PV_ERR_RECOVERABLE_RETURN_IF((PAL_SUCCESS != pal_status), cs_error_handler(pal_status), "pal_ECKeyNew failed "); 00188 00189 pal_status = pal_parseECPublicKeyFromDER(der_key, der_key_length, key_handle); 00190 SA_PV_ERR_RECOVERABLE_GOTO_IF((PAL_SUCCESS != pal_status), kcm_status = cs_error_handler(pal_status), exit, "pal_parseECPublicKeyFromDER failed "); 00191 00192 localECKey = (mbedtls_pk_context*)key_handle; 00193 ecp_key_pair = (mbedtls_ecp_keypair*)localECKey->pk_ctx; 00194 00195 //Get raw public key data 00196 mbdtls_result = mbedtls_ecp_point_write_binary(&ecp_key_pair->grp, &ecp_key_pair->Q, MBEDTLS_ECP_PF_UNCOMPRESSED, raw_key_data_act_size_out, raw_key_data_out, raw_key_data_max_size); 00197 SA_PV_ERR_RECOVERABLE_GOTO_IF((mbdtls_result != 0), kcm_status = KCM_CRYPTO_STATUS_INVALID_PK_PUBKEY, exit, "mbedtls_ecp_point_write_binary failed "); 00198 SA_PV_ERR_RECOVERABLE_GOTO_IF((raw_key_data_max_size != KCM_EC_SECP256R1_MAX_PUB_KEY_RAW_SIZE), kcm_status = KCM_CRYPTO_STATUS_INVALID_PK_PUBKEY, exit, "Wrong raw_key_data_max_size "); 00199 00200 exit: 00201 //Free key handler 00202 (void)pal_ECKeyFree(&key_handle); 00203 return kcm_status; 00204 } 00205 00206 00207 kcm_status_e cs_der_priv_key_verify(const uint8_t *key, size_t key_length) 00208 { 00209 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00210 00211 kcm_status = der_key_verify(key, key_length, PAL_CHECK_PRIVATE_KEY); 00212 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Private key verification failed"); 00213 00214 return kcm_status; 00215 } 00216 00217 kcm_status_e cs_der_public_key_verify(const uint8_t *der_key, size_t der_key_length) 00218 { 00219 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00220 00221 kcm_status = der_key_verify(der_key, der_key_length, PAL_CHECK_PUBLIC_KEY); 00222 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Public key verification failed"); 00223 00224 return kcm_status; 00225 } 00226 00227 00228 kcm_status_e cs_ecdsa_verify(const uint8_t *der_pub_key, size_t der_pub_key_len, const uint8_t *hash_dgst, size_t hash_dgst_len,const uint8_t *sign, size_t signature_size) 00229 { 00230 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00231 kcm_status_e kcm_free_status = KCM_STATUS_SUCCESS; 00232 palStatus_t pal_status = PAL_SUCCESS; 00233 palECKeyHandle_t key_handle = NULLPTR; 00234 palCurveHandle_t grp = NULLPTR; 00235 bool is_sign_verified = false; 00236 00237 SA_PV_ERR_RECOVERABLE_RETURN_IF((der_pub_key == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid public key pointer"); 00238 SA_PV_ERR_RECOVERABLE_RETURN_IF((der_pub_key_len <= 0), KCM_STATUS_INVALID_PARAMETER, "Invalid public key length"); 00239 SA_PV_ERR_RECOVERABLE_RETURN_IF((hash_dgst == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid hash digest pointer"); 00240 SA_PV_ERR_RECOVERABLE_RETURN_IF((hash_dgst_len != CS_SHA256_SIZE), KCM_STATUS_INVALID_PARAMETER, "Invalid hash digest size"); 00241 SA_PV_ERR_RECOVERABLE_RETURN_IF((sign == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid signature pointer"); 00242 SA_PV_ERR_RECOVERABLE_RETURN_IF((signature_size == 0), KCM_STATUS_INVALID_PARAMETER, "Invalid signature size"); 00243 00244 //Create public key pal handle 00245 kcm_status = cs_init_and_set_pal_key_handle(der_pub_key, der_pub_key_len, PAL_CHECK_PUBLIC_KEY, &grp, &key_handle); 00246 SA_PV_ERR_RECOVERABLE_RETURN_IF((KCM_STATUS_SUCCESS != kcm_status), kcm_status = kcm_status, "cs_init_and_set_pal_key_handle failed "); 00247 00248 //Verify the signature 00249 pal_status = pal_ECDSAVerify(key_handle, (unsigned char*)hash_dgst, (uint32_t)hash_dgst_len, (unsigned char*)sign, signature_size, &is_sign_verified); 00250 SA_PV_ERR_RECOVERABLE_GOTO_IF((PAL_SUCCESS != pal_status), kcm_status = cs_error_handler(pal_status), exit, "pal_ECDSAVerify failed "); 00251 SA_PV_ERR_RECOVERABLE_GOTO_IF((is_sign_verified != true), kcm_status = KCM_CRYPTO_STATUS_VERIFY_SIGNATURE_FAILED, exit, "pal_ECDSAVerify failed to verify signature "); 00252 00253 exit: 00254 //Free curve handler and key handle 00255 kcm_free_status = cs_free_pal_key_handle(&grp, &key_handle); 00256 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_free_status!= KCM_STATUS_SUCCESS), kcm_free_status, "failed in cs_free_pal_key_handle"); 00257 00258 return kcm_status; 00259 00260 } 00261 00262 kcm_status_e cs_ecdsa_sign(const uint8_t *der_priv_key, size_t der_priv_key_length, const uint8_t *hash_dgst, size_t hash_dgst_len, uint8_t *out_sign, size_t signature_data_max_size, size_t * signature_data_act_size_out) 00263 { 00264 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00265 kcm_status_e kcm_free_status = KCM_STATUS_SUCCESS; 00266 palStatus_t pal_status = PAL_SUCCESS; 00267 palECKeyHandle_t key_handle = NULLPTR; 00268 palCurveHandle_t grp = NULLPTR; 00269 palMDType_t md_type = PAL_SHA256; 00270 00271 SA_PV_ERR_RECOVERABLE_RETURN_IF((der_priv_key == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid private key pointer"); 00272 SA_PV_ERR_RECOVERABLE_RETURN_IF((der_priv_key_length <= 0), KCM_STATUS_INVALID_PARAMETER, "Invalid private key length"); 00273 SA_PV_ERR_RECOVERABLE_RETURN_IF((hash_dgst == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid hash digest pointer"); 00274 SA_PV_ERR_RECOVERABLE_RETURN_IF((hash_dgst_len != CS_SHA256_SIZE), KCM_STATUS_INVALID_PARAMETER, "Invalid hash digest size"); 00275 SA_PV_ERR_RECOVERABLE_RETURN_IF((out_sign == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid out signature pointer"); 00276 SA_PV_ERR_RECOVERABLE_RETURN_IF((signature_data_act_size_out == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid signature_data_act_size_out pointer"); 00277 SA_PV_ERR_RECOVERABLE_RETURN_IF((signature_data_max_size < KCM_ECDSA_SECP256R1_MAX_SIGNATURE_SIZE_IN_BYTES), KCM_STATUS_INVALID_PARAMETER, "Invalid size of signature buffer"); 00278 00279 //Create new key handler 00280 kcm_status = cs_init_and_set_pal_key_handle(der_priv_key, der_priv_key_length, PAL_CHECK_PRIVATE_KEY, &grp, &key_handle); 00281 SA_PV_ERR_RECOVERABLE_RETURN_IF((KCM_STATUS_SUCCESS != kcm_status), kcm_status , "cs_init_and_set_pal_key_handle failed "); 00282 00283 *signature_data_act_size_out = signature_data_max_size; 00284 //Sign on hash digest 00285 pal_status = pal_ECDSASign(grp, md_type, key_handle, (unsigned char*)hash_dgst, (uint32_t)hash_dgst_len, out_sign, signature_data_act_size_out); 00286 SA_PV_ERR_RECOVERABLE_GOTO_IF((PAL_SUCCESS != pal_status), kcm_status = cs_error_handler(pal_status), exit, "pal_ECDSASign failed "); 00287 00288 exit: 00289 //Free curve handler and key handle 00290 kcm_free_status = cs_free_pal_key_handle(&grp, &key_handle); 00291 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_free_status != KCM_STATUS_SUCCESS), kcm_free_status, "failed in cs_free_pal_key_handle"); 00292 00293 return kcm_status; 00294 } 00295 00296 kcm_status_e cs_verify_key_pair(const uint8_t *priv_key_data, size_t priv_key_data_size, const uint8_t *pub_key_data, size_t pub_key_data_size) 00297 { 00298 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00299 uint8_t out_sign[KCM_ECDSA_SECP256R1_MAX_SIGNATURE_SIZE_IN_BYTES] = { 0 }; 00300 size_t size_of_sign = sizeof(out_sign); 00301 size_t act_size_of_sign = 0; 00302 const uint8_t hash_digest[] = 00303 { 0x34, 0x70, 0xCD, 0x54, 0x7B, 0x0A, 0x11, 0x5F, 0xE0, 0x5C, 0xEB, 0xBC, 0x07, 0xBA, 0x91, 0x88, 00304 0x27, 0x20, 0x25, 0x6B, 0xB2, 0x7A, 0x66, 0x89, 0x1A, 0x4B, 0xB7, 0x17, 0x11, 0x04, 0x86, 0x6F }; 00305 00306 SA_PV_ERR_RECOVERABLE_RETURN_IF((priv_key_data == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid priv_key_data pointer"); 00307 SA_PV_ERR_RECOVERABLE_RETURN_IF((priv_key_data_size <= 0), KCM_STATUS_INVALID_PARAMETER, "Invalid private key length"); 00308 SA_PV_ERR_RECOVERABLE_RETURN_IF((pub_key_data == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid pub_key_data pointer"); 00309 SA_PV_ERR_RECOVERABLE_RETURN_IF((pub_key_data_size <= 0), KCM_STATUS_INVALID_PARAMETER, "Invalid pub_key length"); 00310 00311 //Sign on hash using private key 00312 kcm_status = cs_ecdsa_sign(priv_key_data, priv_key_data_size, hash_digest, sizeof(hash_digest), out_sign, size_of_sign, &act_size_of_sign); 00313 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "cs_ecdsa_sign failed"); 00314 00315 //Verify the signature with public key 00316 kcm_status = cs_ecdsa_verify(pub_key_data, pub_key_data_size, hash_digest, sizeof(hash_digest),(const uint8_t*)out_sign, act_size_of_sign); 00317 SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "cs_ecdsa_sign failed"); 00318 00319 return kcm_status; 00320 00321 } 00322 00323 kcm_status_e cs_key_pair_generate(kcm_crypto_key_scheme_e curve_name, uint8_t *priv_key_out, size_t priv_key_max_size, size_t *priv_key_act_size_out, uint8_t *pub_key_out, 00324 size_t pub_key_max_size, size_t *pub_key_act_size_out) 00325 { 00326 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00327 palStatus_t pal_status = PAL_SUCCESS; 00328 palECKeyHandle_t key_handle = NULLPTR; 00329 00330 // Create new key handler 00331 pal_status = pal_ECKeyNew(&key_handle); 00332 SA_PV_ERR_RECOVERABLE_RETURN_IF((PAL_SUCCESS != pal_status), cs_error_handler(pal_status), "pal_ECKeyNew failed"); 00333 00334 // Call to internal key_pair_generate 00335 kcm_status = cs_key_pair_generate_int(key_handle, curve_name, priv_key_out, priv_key_max_size, priv_key_act_size_out, 00336 pub_key_out, pub_key_max_size, pub_key_act_size_out); 00337 SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status = kcm_status, exit, "Failed to generate keys"); 00338 00339 exit: 00340 //Free key handler 00341 if (key_handle != NULLPTR) { 00342 pal_ECKeyFree(&key_handle); 00343 SA_PV_ERR_RECOVERABLE_RETURN_IF((key_handle != NULLPTR && kcm_status == KCM_STATUS_SUCCESS), KCM_STATUS_ERROR, "Free key handle failed "); 00344 } 00345 return kcm_status; 00346 } 00347 00348 static kcm_status_e cs_csr_generate_int(palECKeyHandle_t key_handle, const kcm_csr_params_s *csr_params, 00349 uint8_t *csr_buff_out, size_t csr_buff_max_size, size_t *csr_buff_act_size_out) 00350 { 00351 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00352 palStatus_t pal_status = PAL_SUCCESS; 00353 palx509CSRHandle_t x509CSR_handle = NULLPTR; 00354 palMDType_t pal_md_type; 00355 uint32_t pal_key_usage = 0; 00356 uint32_t pal_ext_key_usage = 0; 00357 uint32_t eku_all_bits = KCM_CSR_EXT_KU_ANY | KCM_CSR_EXT_KU_SERVER_AUTH | KCM_CSR_EXT_KU_CLIENT_AUTH | 00358 KCM_CSR_EXT_KU_CODE_SIGNING | KCM_CSR_EXT_KU_EMAIL_PROTECTION | KCM_CSR_EXT_KU_TIME_STAMPING | KCM_CSR_EXT_KU_OCSP_SIGNING; 00359 00360 SA_PV_ERR_RECOVERABLE_RETURN_IF((csr_params == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid csr_params pointer"); 00361 SA_PV_ERR_RECOVERABLE_RETURN_IF((csr_params->subject == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid subject pointer in csr_params"); 00362 SA_PV_ERR_RECOVERABLE_RETURN_IF((csr_buff_out == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid out csr buffer"); 00363 SA_PV_ERR_RECOVERABLE_RETURN_IF((csr_buff_max_size == 0), KCM_STATUS_INVALID_PARAMETER, "Invalid max csr buffer size"); 00364 SA_PV_ERR_RECOVERABLE_RETURN_IF((csr_buff_act_size_out == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid out csr buffer size"); 00365 SA_PV_ERR_RECOVERABLE_RETURN_IF((csr_params->ext_key_usage & (~eku_all_bits)), KCM_STATUS_INVALID_PARAMETER, "Invalid extended key usage options"); 00366 00367 // Initialize x509 CSR handle 00368 pal_status = pal_x509CSRInit(&x509CSR_handle); 00369 SA_PV_ERR_RECOVERABLE_RETURN_IF((PAL_SUCCESS != pal_status), cs_error_handler(pal_status), "Failed to initialize x509 CSR handle"); 00370 00371 // Set CSR Subject 00372 pal_status = pal_x509CSRSetSubject(x509CSR_handle, csr_params->subject); 00373 SA_PV_ERR_RECOVERABLE_GOTO_IF((PAL_SUCCESS != pal_status), kcm_status = cs_error_handler(pal_status), exit, "Failed to set CSR Subject"); 00374 00375 // Set MD algorithm to SHA256 for the signature 00376 switch (csr_params->md_type) { 00377 case KCM_MD_SHA256: 00378 pal_md_type = PAL_SHA256; 00379 break; 00380 default: 00381 SA_PV_ERR_RECOVERABLE_GOTO_IF(true, kcm_status = KCM_CRYPTO_STATUS_INVALID_MD_TYPE, exit, "MD type not supported"); 00382 } 00383 pal_status = pal_x509CSRSetMD(x509CSR_handle, pal_md_type); 00384 SA_PV_ERR_RECOVERABLE_GOTO_IF((PAL_SUCCESS != pal_status), kcm_status = cs_error_handler(pal_status), exit, "Failed to set MD algorithm"); 00385 00386 // Set keys into CSR 00387 pal_status = pal_x509CSRSetKey(x509CSR_handle, key_handle, NULLPTR); 00388 SA_PV_ERR_RECOVERABLE_GOTO_IF((PAL_SUCCESS != pal_status), kcm_status = cs_error_handler(pal_status), exit, "Failed to Set keys into CSR"); 00389 00390 // Set CSR key usage 00391 if (csr_params->key_usage != KCM_CSR_KU_NONE) { 00392 if (csr_params->key_usage & KCM_CSR_KU_DIGITAL_SIGNATURE) { 00393 pal_key_usage |= PAL_X509_KU_DIGITAL_SIGNATURE; 00394 } 00395 if (csr_params->key_usage & KCM_CSR_KU_NON_REPUDIATION) { 00396 pal_key_usage |= PAL_X509_KU_NON_REPUDIATION; 00397 } 00398 if (csr_params->key_usage & KCM_CSR_KU_KEY_CERT_SIGN) { 00399 pal_key_usage |= PAL_X509_KU_KEY_CERT_SIGN; 00400 } 00401 if (csr_params->key_usage & KCM_CSR_KU_KEY_AGREEMENT) { 00402 pal_key_usage |= PAL_X509_KU_KEY_AGREEMENT; 00403 } 00404 pal_status = pal_x509CSRSetKeyUsage(x509CSR_handle, pal_key_usage); 00405 SA_PV_ERR_RECOVERABLE_GOTO_IF((PAL_SUCCESS != pal_status), kcm_status = cs_error_handler(pal_status), exit, "Failed to set CSR key usage"); 00406 } 00407 00408 // Set CSR extended key usage 00409 if (csr_params->ext_key_usage != KCM_CSR_EXT_KU_NONE) { 00410 if (csr_params->ext_key_usage & KCM_CSR_EXT_KU_ANY) { 00411 pal_ext_key_usage |= PAL_X509_EXT_KU_ANY; 00412 } 00413 if (csr_params->ext_key_usage & KCM_CSR_EXT_KU_SERVER_AUTH) { 00414 pal_ext_key_usage |= PAL_X509_EXT_KU_SERVER_AUTH; 00415 } 00416 if (csr_params->ext_key_usage & KCM_CSR_EXT_KU_CLIENT_AUTH) { 00417 pal_ext_key_usage |= PAL_X509_EXT_KU_CLIENT_AUTH; 00418 } 00419 if (csr_params->ext_key_usage & KCM_CSR_EXT_KU_CODE_SIGNING) { 00420 pal_ext_key_usage |= PAL_X509_EXT_KU_CODE_SIGNING; 00421 } 00422 if (csr_params->ext_key_usage & KCM_CSR_EXT_KU_EMAIL_PROTECTION) { 00423 pal_ext_key_usage |= PAL_X509_EXT_KU_EMAIL_PROTECTION; 00424 } 00425 if (csr_params->ext_key_usage & KCM_CSR_EXT_KU_TIME_STAMPING) { 00426 pal_ext_key_usage |= PAL_X509_EXT_KU_TIME_STAMPING; 00427 } 00428 if (csr_params->ext_key_usage & KCM_CSR_EXT_KU_OCSP_SIGNING) { 00429 pal_ext_key_usage |= PAL_X509_EXT_KU_OCSP_SIGNING; 00430 } 00431 pal_status = pal_x509CSRSetExtendedKeyUsage(x509CSR_handle, pal_ext_key_usage); 00432 SA_PV_ERR_RECOVERABLE_GOTO_IF((PAL_SUCCESS != pal_status), kcm_status = cs_error_handler(pal_status), exit, "Failed to set CSR extended key usage"); 00433 } 00434 00435 // Write the CSR to out buffer in DER format 00436 pal_status = pal_x509CSRWriteDER(x509CSR_handle, csr_buff_out, csr_buff_max_size, csr_buff_act_size_out); 00437 SA_PV_ERR_RECOVERABLE_GOTO_IF((PAL_SUCCESS != pal_status), kcm_status = cs_error_handler(pal_status), exit, "Failed to write the CSR to out buffer"); 00438 00439 exit: 00440 //Free CSR handler 00441 if (x509CSR_handle != NULLPTR) { 00442 pal_x509CSRFree(&x509CSR_handle); 00443 SA_PV_ERR_RECOVERABLE_RETURN_IF((x509CSR_handle != NULLPTR && kcm_status == KCM_STATUS_SUCCESS), KCM_STATUS_ERROR, "Free CSR handle failed "); 00444 } 00445 00446 return kcm_status; 00447 } 00448 00449 kcm_status_e cs_csr_generate(const uint8_t *priv_key, size_t priv_key_size, const kcm_csr_params_s *csr_params, uint8_t *csr_buff_out, 00450 size_t csr_buff_max_size, size_t *csr_buff_act_size_out) 00451 { 00452 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00453 palStatus_t pal_status = PAL_SUCCESS; 00454 palECKeyHandle_t key_handle = NULLPTR; 00455 00456 SA_PV_ERR_RECOVERABLE_RETURN_IF((priv_key == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid private key pointer"); 00457 SA_PV_ERR_RECOVERABLE_RETURN_IF((priv_key_size == 0), KCM_STATUS_INVALID_PARAMETER, "Invalid private key size"); 00458 00459 // Create new key handler 00460 pal_status = pal_ECKeyNew(&key_handle); 00461 SA_PV_ERR_RECOVERABLE_RETURN_IF((PAL_SUCCESS != pal_status), cs_error_handler(pal_status), "pal_ECKeyNew failed"); 00462 00463 // Parse private key from DER format 00464 pal_status = pal_parseECPrivateKeyFromDER(priv_key, priv_key_size, key_handle); 00465 SA_PV_ERR_RECOVERABLE_GOTO_IF((PAL_SUCCESS != pal_status), kcm_status = cs_error_handler(pal_status), exit, "Failed to parse private key from DER format"); 00466 00467 // Call to internal csr_generate 00468 kcm_status = cs_csr_generate_int(key_handle, csr_params, csr_buff_out, csr_buff_max_size, csr_buff_act_size_out); 00469 SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status = kcm_status, exit, "Failed to generate csr"); 00470 00471 exit: 00472 //Free key handler 00473 if (key_handle != NULLPTR) { 00474 pal_ECKeyFree(&key_handle); 00475 SA_PV_ERR_RECOVERABLE_RETURN_IF((key_handle != NULLPTR && kcm_status == KCM_STATUS_SUCCESS), KCM_STATUS_ERROR, "Free key handle failed "); 00476 } 00477 return kcm_status; 00478 } 00479 kcm_status_e cs_generate_keys_and_csr(kcm_crypto_key_scheme_e curve_name, const kcm_csr_params_s *csr_params, uint8_t *priv_key_out, 00480 size_t priv_key_max_size, size_t *priv_key_act_size_out, uint8_t *pub_key_out, 00481 size_t pub_key_max_size, size_t *pub_key_act_size_out, uint8_t *csr_buff_out, 00482 const size_t csr_buff_max_size, size_t *csr_buff_act_size_out) 00483 { 00484 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00485 palStatus_t pal_status = PAL_SUCCESS; 00486 palECKeyHandle_t key_handle = NULLPTR; 00487 00488 // Create new key handler 00489 pal_status = pal_ECKeyNew(&key_handle); 00490 SA_PV_ERR_RECOVERABLE_RETURN_IF((PAL_SUCCESS != pal_status), cs_error_handler(pal_status), "pal_ECKeyNew failed"); 00491 00492 // Call to internal key_pair_generate 00493 kcm_status = cs_key_pair_generate_int(key_handle, curve_name, priv_key_out, priv_key_max_size, priv_key_act_size_out, pub_key_out, pub_key_max_size, pub_key_act_size_out); 00494 SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status = kcm_status, exit, "Failed to generate keys"); 00495 00496 // Call to internal csr_generate 00497 kcm_status = cs_csr_generate_int(key_handle, csr_params, csr_buff_out, csr_buff_max_size, csr_buff_act_size_out); 00498 SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status = kcm_status, exit, "Failed to generate csr"); 00499 00500 exit: 00501 //Free key handler 00502 if (key_handle != NULLPTR) { 00503 pal_ECKeyFree(&key_handle); 00504 SA_PV_ERR_RECOVERABLE_RETURN_IF((key_handle != NULLPTR && kcm_status == KCM_STATUS_SUCCESS), KCM_STATUS_ERROR, "Free key handle failed "); 00505 } 00506 return kcm_status; 00507 } 00508 00509 00510 kcm_status_e cs_verify_items_correlation(cs_key_handle_t crypto_handle, const uint8_t *certificate_data, size_t certificate_data_len) 00511 { 00512 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00513 kcm_status_e kcm_free_status = KCM_STATUS_SUCCESS; 00514 cs_ec_key_context_s *cs_ec_key_handle = NULL; 00515 palX509Handle_t x509_cert = NULLPTR; 00516 00517 00518 //Check parameters 00519 SA_PV_ERR_RECOVERABLE_RETURN_IF(((cs_ec_key_context_s *)crypto_handle == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid crypto_handle"); 00520 SA_PV_ERR_RECOVERABLE_RETURN_IF((certificate_data == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid certificate_data"); 00521 SA_PV_ERR_RECOVERABLE_RETURN_IF((certificate_data_len == 0), KCM_STATUS_INVALID_PARAMETER, "Invalid certificate_data_len"); 00522 cs_ec_key_handle = (cs_ec_key_context_s*)crypto_handle; 00523 00524 00525 //Create certificate handle 00526 kcm_status = cs_create_handle_from_der_x509_cert(certificate_data, certificate_data_len, &x509_cert); 00527 SA_PV_ERR_RECOVERABLE_RETURN_IF((KCM_STATUS_SUCCESS != kcm_status), kcm_status, "cs_create_handle_from_der_x509_cert failed"); 00528 00529 00530 //Check certificate and private key correlation 00531 kcm_status = cs_check_certifcate_public_key(x509_cert, cs_ec_key_handle->priv_key, cs_ec_key_handle->priv_key_size); 00532 SA_PV_ERR_RECOVERABLE_GOTO_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status = kcm_status, exit, "cs_check_certifcate_public_key failed"); 00533 00534 exit: 00535 00536 kcm_free_status = cs_close_handle_x509_cert(&x509_cert); 00537 SA_PV_ERR_RECOVERABLE_RETURN_IF((KCM_STATUS_SUCCESS != kcm_free_status), kcm_free_status, "cs_close_handle_x509_cert failed"); 00538 00539 return kcm_status; 00540 } 00541 00542 kcm_status_e cs_generate_keys_and_create_csr_from_certificate(const uint8_t *certificate, 00543 size_t certificate_size, 00544 cs_key_handle_t csr_key_h, 00545 uint8_t *csr_buff_out, 00546 const size_t csr_buff_max_size, 00547 size_t *csr_buff_act_size_out) 00548 { 00549 kcm_status_e kcm_status = KCM_STATUS_SUCCESS; 00550 palStatus_t pal_status = PAL_SUCCESS; 00551 00552 palECKeyHandle_t pal_ec_key_handle = NULLPTR; 00553 palx509CSRHandle_t pal_csr_handle = NULLPTR; 00554 palX509Handle_t pal_crt_handle = NULLPTR; 00555 cs_ec_key_context_s *ec_key_ctx = NULL; 00556 00557 // Get the key context from the handle 00558 ec_key_ctx = (cs_ec_key_context_s *)(csr_key_h); 00559 00560 // Create new key handle 00561 pal_status = pal_ECKeyNew(&pal_ec_key_handle); 00562 SA_PV_ERR_RECOVERABLE_GOTO_IF((PAL_SUCCESS != pal_status), kcm_status = cs_error_handler(pal_status), exit, "pal_ECKeyNew failed"); 00563 00564 // Call to internal key_pair_generate 00565 kcm_status = cs_key_pair_generate_int(pal_ec_key_handle, KCM_SCHEME_EC_SECP256R1, 00566 ec_key_ctx->priv_key, sizeof(ec_key_ctx->priv_key), &ec_key_ctx->priv_key_size, 00567 ec_key_ctx->pub_key, sizeof(ec_key_ctx->pub_key), &ec_key_ctx->pub_key_size); 00568 SA_PV_ERR_RECOVERABLE_GOTO_IF((KCM_STATUS_SUCCESS != kcm_status), (kcm_status = kcm_status), exit, "Failed to generate keys"); 00569 00570 // Create CRT handle 00571 kcm_status = cs_create_handle_from_der_x509_cert(certificate, certificate_size, &pal_crt_handle); 00572 SA_PV_ERR_RECOVERABLE_GOTO_IF((KCM_STATUS_SUCCESS != kcm_status), (kcm_status = kcm_status), exit, "Failed getting handle from certificate"); 00573 00574 // Create CSR handle 00575 pal_status = pal_x509CSRInit(&pal_csr_handle); 00576 SA_PV_ERR_RECOVERABLE_GOTO_IF((PAL_SUCCESS != pal_status), kcm_status = cs_error_handler(pal_status), exit, "Failed intializing X509 CSR object"); 00577 00578 // Set keys into CSR 00579 pal_status = pal_x509CSRSetKey(pal_csr_handle, pal_ec_key_handle, NULLPTR); 00580 SA_PV_ERR_RECOVERABLE_GOTO_IF((PAL_SUCCESS != pal_status), kcm_status = cs_error_handler(pal_status), exit, "Failed to Set keys into CSR"); 00581 00582 // Create CSR from the given CRT 00583 pal_status = pal_x509CSRFromCertWriteDER(pal_crt_handle, pal_csr_handle, csr_buff_out, csr_buff_max_size, csr_buff_act_size_out); 00584 SA_PV_ERR_RECOVERABLE_GOTO_IF((PAL_SUCCESS != pal_status), kcm_status = cs_error_handler(pal_status), exit, "Failed generating CSR from Certificate"); 00585 00586 exit: 00587 //Free key handle 00588 if (pal_ec_key_handle != NULLPTR) { 00589 pal_status = pal_ECKeyFree(&pal_ec_key_handle); 00590 SA_PV_ERR_RECOVERABLE_RETURN_IF((PAL_SUCCESS != pal_status) && (kcm_status == KCM_STATUS_SUCCESS), KCM_STATUS_ERROR, "Free key handle failed"); 00591 } 00592 //Free x509 CSR handle 00593 if (pal_csr_handle != NULLPTR) { 00594 pal_status = pal_x509CSRFree(&pal_csr_handle); 00595 SA_PV_ERR_RECOVERABLE_RETURN_IF((PAL_SUCCESS != pal_status) && (kcm_status == KCM_STATUS_SUCCESS), KCM_STATUS_ERROR, "Free x509 CSR handle failed"); 00596 } 00597 //Free x509 CRT handle 00598 if (pal_crt_handle != NULLPTR) { 00599 pal_status = pal_x509Free(&pal_crt_handle); 00600 SA_PV_ERR_RECOVERABLE_RETURN_IF((PAL_SUCCESS != pal_status) && (kcm_status == KCM_STATUS_SUCCESS), KCM_STATUS_ERROR, "Free x509 CRT handle failed"); 00601 } 00602 00603 return kcm_status; 00604 } 00605 00606 kcm_status_e cs_ec_key_new(cs_key_handle_t *key_h) 00607 { 00608 cs_ec_key_context_s *ec_key_ctx = NULL; 00609 00610 ec_key_ctx = (cs_ec_key_context_s*)fcc_malloc(sizeof(cs_ec_key_context_s)); 00611 SA_PV_ERR_RECOVERABLE_RETURN_IF((ec_key_ctx == NULL), KCM_STATUS_OUT_OF_MEMORY, "Failed to allocate EC key context"); 00612 00613 *key_h = (cs_key_handle_t)ec_key_ctx; 00614 00615 return KCM_STATUS_SUCCESS; 00616 } 00617 00618 kcm_status_e cs_ec_key_free(cs_key_handle_t *key_h) 00619 { 00620 cs_ec_key_context_s *ec_key_ctx = (cs_ec_key_context_s *)(*key_h); 00621 fcc_free(ec_key_ctx); 00622 *key_h = 0; 00623 00624 return KCM_STATUS_SUCCESS; 00625 } 00626 00627
Generated on Tue Jul 12 2022 20:20:58 by
