Mayank Gupta / Mbed OS pelion-example-frdm

Dependencies:   FXAS21002 FXOS8700Q

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers cs_der_keys_and_csrs.c Source File

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