Simple interface for Mbed Cloud Client
Embed:
(wiki syntax)
Show/hide line numbers
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 }
Generated on Tue Jul 12 2022 19:01:34 by 1.7.2