Simple interface for Mbed Cloud Client

Dependents:  

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers cs_der_keys.c Source File

cs_der_keys.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.h"
00019 #include "pal.h"
00020 #include "cs_utils.h"
00021 #include "cs_hash.h"
00022 #include "pk.h"
00023 
00024 //For now only EC keys supported!!!
00025 static kcm_status_e  der_key_verify(const uint8_t *der_key, size_t der_key_length, palKeyToCheck_t key_type)
00026 {
00027     kcm_status_e  kcm_status = KCM_STATUS_SUCCESS;
00028     palStatus_t pal_status = PAL_SUCCESS;
00029     palECKeyHandle_t key_handle = NULLPTR;
00030     palCurveHandle_t grp = NULLPTR;
00031     palGroupIndex_t pal_grp_idx;
00032     bool verified = false;
00033 
00034 
00035     SA_PV_ERR_RECOVERABLE_RETURN_IF((der_key == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid der_key pointer");
00036     SA_PV_ERR_RECOVERABLE_RETURN_IF((der_key_length <= 0), KCM_STATUS_INVALID_PARAMETER, "Invalid der_key_length");
00037 
00038     //Create new key handler
00039     pal_status = pal_ECKeyNew(&key_handle);
00040     SA_PV_ERR_RECOVERABLE_RETURN_IF((PAL_SUCCESS != pal_status), cs_error_handler(pal_status), "pal_ECKeyNew failed ");
00041 
00042     //Parse the key from DER format
00043     if (key_type == PAL_CHECK_PRIVATE_KEY) {
00044         pal_status = pal_parseECPrivateKeyFromDER(der_key, der_key_length, key_handle);
00045         SA_PV_ERR_RECOVERABLE_GOTO_IF((PAL_SUCCESS != pal_status), kcm_status = cs_error_handler(pal_status), exit, "pal_parseECPrivateKeyFromDER failed ");
00046     } else {
00047         pal_status = pal_parseECPublicKeyFromDER(der_key, der_key_length, key_handle);
00048         SA_PV_ERR_RECOVERABLE_GOTO_IF((PAL_SUCCESS != pal_status), kcm_status = cs_error_handler(pal_status), exit, "pal_parseECPublicKeyFromDER failed ");
00049     }
00050 
00051     //retrieve key curve from key handle
00052     pal_status = pal_ECKeyGetCurve(key_handle, &pal_grp_idx);
00053     SA_PV_ERR_RECOVERABLE_GOTO_IF((PAL_SUCCESS != pal_status), kcm_status = cs_error_handler(pal_status), exit, "pal_ECKeyGetCurve failed ");
00054 
00055     //Allocate curve handler
00056     pal_status = pal_ECGroupInitAndLoad(&grp, pal_grp_idx);
00057     SA_PV_ERR_RECOVERABLE_GOTO_IF((PAL_SUCCESS != pal_status), kcm_status = cs_error_handler(pal_status), exit, "pal_parseECPrivateKeyFromDER failed ");
00058 
00059     //Perform key verification
00060     pal_status = pal_ECCheckKey(grp, key_handle, key_type, &verified);
00061     SA_PV_ERR_RECOVERABLE_GOTO_IF(((PAL_SUCCESS != pal_status) || (verified != true)), kcm_status = cs_error_handler(pal_status), exit, "pal_ECCheckKey failed ");
00062 
00063 
00064 exit:
00065     //Free curve handle
00066     (void)pal_ECGroupFree(&grp);
00067     //Free key handler
00068     (void)pal_ECKeyFree(&key_handle);
00069 
00070     if (kcm_status == KCM_STATUS_SUCCESS) {
00071         SA_PV_ERR_RECOVERABLE_RETURN_IF((grp != NULLPTR || key_handle != NULLPTR), KCM_STATUS_ERROR, "Free handle failed ");
00072     }
00073 
00074     return kcm_status;
00075 }
00076 //For now only EC SECP256R keys supported!!!
00077 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)
00078 {
00079     kcm_status_e  kcm_status = KCM_STATUS_SUCCESS;
00080     palStatus_t pal_status = PAL_SUCCESS;
00081     int mbdtls_result = 0;
00082     palECKeyHandle_t key_handle = NULLPTR;
00083     mbedtls_pk_context* localECKey;
00084     mbedtls_ecp_keypair *ecp_key_pair;
00085 
00086     SA_PV_ERR_RECOVERABLE_RETURN_IF((der_key == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid der_key pointer");
00087     SA_PV_ERR_RECOVERABLE_RETURN_IF((der_key_length != CS_EC_SECP256R1_PK_DER_SIZE), KCM_STATUS_INVALID_PARAMETER, "Invalid der_key_length");
00088     SA_PV_ERR_RECOVERABLE_RETURN_IF((raw_key_data_out == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid raw_key_data_out");
00089     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");
00090     SA_PV_ERR_RECOVERABLE_RETURN_IF((raw_key_data_max_size < CS_EC_SECP256R1_PK_RAW_SIZE), KCM_STATUS_INVALID_PARAMETER, "Invalid raw_key_size_out value");
00091 
00092     //Create new key handler
00093     pal_status = pal_ECKeyNew(&key_handle);
00094     SA_PV_ERR_RECOVERABLE_RETURN_IF((PAL_SUCCESS != pal_status), cs_error_handler(pal_status), "pal_ECKeyNew failed ");
00095 
00096     pal_status = pal_parseECPublicKeyFromDER(der_key, der_key_length, key_handle);
00097     SA_PV_ERR_RECOVERABLE_GOTO_IF((PAL_SUCCESS != pal_status), kcm_status = cs_error_handler(pal_status), exit, "pal_parseECPublicKeyFromDER failed ");
00098 
00099     localECKey = (mbedtls_pk_context*)key_handle;
00100     ecp_key_pair = (mbedtls_ecp_keypair*)localECKey->pk_ctx;
00101 
00102     //Get raw public key data
00103     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);
00104     SA_PV_ERR_RECOVERABLE_GOTO_IF((mbdtls_result != 0), kcm_status = KCM_CRYPTO_STATUS_INVALID_PK_PUBKEY, exit, "mbedtls_ecp_point_write_binary failed ");
00105     SA_PV_ERR_RECOVERABLE_GOTO_IF((raw_key_data_max_size != CS_EC_SECP256R1_PK_RAW_SIZE), kcm_status = KCM_CRYPTO_STATUS_INVALID_PK_PUBKEY, exit, "Wrong raw_key_data_max_size ");
00106 
00107 exit:
00108     //Free key handler
00109     (void)pal_ECKeyFree(&key_handle);
00110     return kcm_status;
00111 }
00112 
00113 
00114 kcm_status_e  cs_der_priv_key_verify(const uint8_t *key, size_t key_length)
00115 {
00116     kcm_status_e  kcm_status = KCM_STATUS_SUCCESS;
00117 
00118     kcm_status =  der_key_verify(key, key_length, PAL_CHECK_PRIVATE_KEY);
00119     SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Private key verification failed");
00120 
00121     return kcm_status;
00122 }
00123 
00124 kcm_status_e  cs_der_public_key_verify(const uint8_t *der_key, size_t der_key_length)
00125 {
00126     kcm_status_e  kcm_status = KCM_STATUS_SUCCESS;
00127 
00128     kcm_status = der_key_verify(der_key, der_key_length, PAL_CHECK_PUBLIC_KEY);
00129     SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Public key verification failed");
00130 
00131     return kcm_status;
00132 }
00133 
00134 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 size_of_hash_dgst, uint8_t *out_sign, size_t  signature_data_max_size,size_t * signature_data_act_size_out)
00135 {
00136     kcm_status_e  kcm_status = KCM_STATUS_SUCCESS;
00137     palStatus_t pal_status = PAL_SUCCESS;
00138     palECKeyHandle_t key_handle = NULLPTR;
00139     palCurveHandle_t grp = NULLPTR;
00140     palGroupIndex_t pal_grp_idx;
00141     palMDType_t md_type = PAL_SHA256;
00142 
00143     SA_PV_ERR_RECOVERABLE_RETURN_IF((der_priv_key == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid private key pointer");
00144     SA_PV_ERR_RECOVERABLE_RETURN_IF((der_priv_key_length <= 0), KCM_STATUS_INVALID_PARAMETER, "Invalid private key length");
00145     SA_PV_ERR_RECOVERABLE_RETURN_IF((hash_dgst == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid hash digest pointer");
00146     SA_PV_ERR_RECOVERABLE_RETURN_IF((size_of_hash_dgst != CS_SHA256_SIZE), KCM_STATUS_INVALID_PARAMETER, "Invalid hash digest size");
00147     SA_PV_ERR_RECOVERABLE_RETURN_IF((out_sign == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid out signature pointer");
00148     SA_PV_ERR_RECOVERABLE_RETURN_IF((signature_data_act_size_out == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid signature_data_act_size_out pointer");
00149     SA_PV_ERR_RECOVERABLE_RETURN_IF((signature_data_max_size < CS_ECDSA_SECP256R1_MAX_SIGNATURE_SIZE_IN_BYTES), KCM_STATUS_INVALID_PARAMETER, "Invalid size of signature buffer");
00150 
00151     
00152 
00153     //Create new key handler
00154     pal_status = pal_ECKeyNew(&key_handle);
00155     SA_PV_ERR_RECOVERABLE_RETURN_IF((PAL_SUCCESS != pal_status), cs_error_handler(pal_status), "pal_ECKeyNew failed ");
00156 
00157     //Parse der private key
00158     pal_status = pal_parseECPrivateKeyFromDER(der_priv_key, der_priv_key_length, key_handle);
00159     SA_PV_ERR_RECOVERABLE_GOTO_IF((PAL_SUCCESS != pal_status), kcm_status = cs_error_handler(pal_status), exit, "pal_parseECPrivateKeyFromDER failed ");
00160 
00161     //retrieve key curve from key handle
00162     pal_status = pal_ECKeyGetCurve(key_handle, &pal_grp_idx);
00163     SA_PV_ERR_RECOVERABLE_GOTO_IF((PAL_SUCCESS != pal_status), kcm_status = cs_error_handler(pal_status), exit, "pal_ECKeyGetCurve failed ");
00164 
00165     //Load the key curve
00166     pal_status = pal_ECGroupInitAndLoad(&grp, pal_grp_idx);
00167     SA_PV_ERR_RECOVERABLE_GOTO_IF((PAL_SUCCESS != pal_status), kcm_status = cs_error_handler(pal_status), exit, "pal_ECGroupInitAndLoad failed ");
00168 
00169     *signature_data_act_size_out = signature_data_max_size;
00170     //Sign on hash digest
00171     pal_status = pal_ECDSASign(grp, md_type, key_handle, (unsigned char*)hash_dgst, (uint32_t)size_of_hash_dgst, out_sign, signature_data_act_size_out);
00172     SA_PV_ERR_RECOVERABLE_GOTO_IF((PAL_SUCCESS != pal_status), kcm_status = cs_error_handler(pal_status), exit, "pal_ECDSASign failed ");
00173 
00174 exit:
00175 
00176     //Free curve handler
00177     (void)pal_ECGroupFree(&grp);
00178     //Free key handler
00179     (void)pal_ECKeyFree(&key_handle);
00180 
00181     if (kcm_status == KCM_STATUS_SUCCESS) {
00182         SA_PV_ERR_RECOVERABLE_RETURN_IF((grp != NULLPTR || key_handle != NULLPTR), KCM_STATUS_ERROR, "Free handle failed ");
00183     }
00184     return kcm_status;
00185 }