Mbed Cloud example program for workshop in W27 2018.

Dependencies:   MMA7660 LM75B

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 
00023 //For now only EC keys supported!!!
00024 static kcm_status_e der_key_verify(const uint8_t *der_key, size_t der_key_length, palKeyToCheck_t key_type)
00025 {
00026     kcm_status_e kcm_status = KCM_STATUS_SUCCESS;
00027     palStatus_t pal_status = PAL_SUCCESS;
00028     palECKeyHandle_t key_handle = NULLPTR;
00029     palCurveHandle_t grp = NULLPTR;
00030     palGroupIndex_t pal_grp_idx;
00031     bool verified = false;
00032 
00033 
00034     SA_PV_ERR_RECOVERABLE_RETURN_IF((der_key == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid der_key pointer");
00035     SA_PV_ERR_RECOVERABLE_RETURN_IF((der_key_length <= 0), KCM_STATUS_INVALID_PARAMETER, "Invalid der_key_length");
00036 
00037     //Create new key handler
00038     pal_status = pal_ECKeyNew(&key_handle);
00039     SA_PV_ERR_RECOVERABLE_RETURN_IF((PAL_SUCCESS != pal_status), cs_error_handler(pal_status), "pal_ECKeyNew failed ");
00040 
00041     //Parse the key from DER format
00042     if (key_type == PAL_CHECK_PRIVATE_KEY) {
00043         pal_status = pal_parseECPrivateKeyFromDER(der_key, der_key_length, key_handle);
00044         SA_PV_ERR_RECOVERABLE_GOTO_IF((PAL_SUCCESS != pal_status), kcm_status = cs_error_handler(pal_status), exit, "pal_parseECPrivateKeyFromDER failed ");
00045     } else {
00046         pal_status = pal_parseECPublicKeyFromDER(der_key, der_key_length, key_handle);
00047         SA_PV_ERR_RECOVERABLE_GOTO_IF((PAL_SUCCESS != pal_status), kcm_status = cs_error_handler(pal_status), exit, "pal_parseECPublicKeyFromDER failed ");
00048     }
00049 
00050     //retrieve key curve from key handle
00051     pal_status = pal_ECKeyGetCurve(key_handle, &pal_grp_idx);
00052     SA_PV_ERR_RECOVERABLE_GOTO_IF((PAL_SUCCESS != pal_status), kcm_status = cs_error_handler(pal_status), exit, "pal_ECKeyGetCurve failed ");
00053 
00054     //Allocate curve handler
00055     pal_status = pal_ECGroupInitAndLoad(&grp, pal_grp_idx);
00056     SA_PV_ERR_RECOVERABLE_GOTO_IF((PAL_SUCCESS != pal_status), kcm_status = cs_error_handler(pal_status), exit, "pal_parseECPrivateKeyFromDER failed ");
00057 
00058     //Perform key verification
00059     pal_status = pal_ECCheckKey(grp, key_handle, key_type, &verified);
00060     SA_PV_ERR_RECOVERABLE_GOTO_IF(((PAL_SUCCESS != pal_status) || (verified != true)), kcm_status = cs_error_handler(pal_status), exit, "pal_ECCheckKey failed ");
00061 
00062 
00063 exit:
00064     //Free curve handle
00065     (void)pal_ECGroupFree(&grp);
00066     //Free key handler
00067     (void)pal_ECKeyFree(&key_handle);
00068 
00069     if (kcm_status == KCM_STATUS_SUCCESS) {
00070         SA_PV_ERR_RECOVERABLE_RETURN_IF((grp != NULLPTR || key_handle != NULLPTR), KCM_STATUS_ERROR, "Free handle failed ");
00071     }
00072 
00073     return kcm_status;
00074 }
00075 
00076 kcm_status_e cs_der_priv_key_verify(const uint8_t *key, size_t key_length)
00077 {
00078     kcm_status_e kcm_status = KCM_STATUS_SUCCESS;
00079 
00080     kcm_status =  der_key_verify(key, key_length, PAL_CHECK_PRIVATE_KEY);
00081     SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Private key verification failed");
00082 
00083     return kcm_status;
00084 }
00085 
00086 kcm_status_e cs_der_public_key_verify(const uint8_t *der_key, size_t der_key_length)
00087 {
00088     kcm_status_e kcm_status = KCM_STATUS_SUCCESS;
00089 
00090     kcm_status = der_key_verify(der_key, der_key_length, PAL_CHECK_PUBLIC_KEY);
00091     SA_PV_ERR_RECOVERABLE_RETURN_IF((kcm_status != KCM_STATUS_SUCCESS), kcm_status, "Public key verification failed");
00092 
00093     return kcm_status;
00094 }
00095 
00096 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)
00097 {
00098     kcm_status_e kcm_status = KCM_STATUS_SUCCESS;
00099     palStatus_t pal_status = PAL_SUCCESS;
00100     palECKeyHandle_t key_handle = NULLPTR;
00101     palCurveHandle_t grp = NULLPTR;
00102     palGroupIndex_t pal_grp_idx;
00103     palMDType_t md_type = PAL_SHA256;
00104 
00105     SA_PV_ERR_RECOVERABLE_RETURN_IF((der_priv_key == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid private key pointer");
00106     SA_PV_ERR_RECOVERABLE_RETURN_IF((der_priv_key_length <= 0), KCM_STATUS_INVALID_PARAMETER, "Invalid private key length");
00107     SA_PV_ERR_RECOVERABLE_RETURN_IF((hash_dgst == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid hash digest pointer");
00108     SA_PV_ERR_RECOVERABLE_RETURN_IF((size_of_hash_dgst != CS_SHA256_SIZE), KCM_STATUS_INVALID_PARAMETER, "Invalid hash digest size");
00109     SA_PV_ERR_RECOVERABLE_RETURN_IF((out_sign == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid out signature pointer");
00110     SA_PV_ERR_RECOVERABLE_RETURN_IF((signature_data_act_size_out == NULL), KCM_STATUS_INVALID_PARAMETER, "Invalid signature_data_act_size_out pointer");
00111     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");
00112 
00113     
00114 
00115     //Create new key handler
00116     pal_status = pal_ECKeyNew(&key_handle);
00117     SA_PV_ERR_RECOVERABLE_RETURN_IF((PAL_SUCCESS != pal_status), cs_error_handler(pal_status), "pal_ECKeyNew failed ");
00118 
00119     //Parse der private key
00120     pal_status = pal_parseECPrivateKeyFromDER(der_priv_key, der_priv_key_length, key_handle);
00121     SA_PV_ERR_RECOVERABLE_GOTO_IF((PAL_SUCCESS != pal_status), kcm_status = cs_error_handler(pal_status), exit, "pal_parseECPrivateKeyFromDER failed ");
00122 
00123     //retrieve key curve from key handle
00124     pal_status = pal_ECKeyGetCurve(key_handle, &pal_grp_idx);
00125     SA_PV_ERR_RECOVERABLE_GOTO_IF((PAL_SUCCESS != pal_status), kcm_status = cs_error_handler(pal_status), exit, "pal_ECKeyGetCurve failed ");
00126 
00127     //Load the key curve
00128     pal_status = pal_ECGroupInitAndLoad(&grp, pal_grp_idx);
00129     SA_PV_ERR_RECOVERABLE_GOTO_IF((PAL_SUCCESS != pal_status), kcm_status = cs_error_handler(pal_status), exit, "pal_ECGroupInitAndLoad failed ");
00130 
00131     *signature_data_act_size_out = signature_data_max_size;
00132     //Sign on hash digest
00133     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);
00134     SA_PV_ERR_RECOVERABLE_GOTO_IF((PAL_SUCCESS != pal_status), kcm_status = cs_error_handler(pal_status), exit, "pal_ECDSASign failed ");
00135 
00136 exit:
00137 
00138     //Free curve handler
00139     (void)pal_ECGroupFree(&grp);
00140     //Free key handler
00141     (void)pal_ECKeyFree(&key_handle);
00142 
00143     if (kcm_status == KCM_STATUS_SUCCESS) {
00144         SA_PV_ERR_RECOVERABLE_RETURN_IF((grp != NULLPTR || key_handle != NULLPTR), KCM_STATUS_ERROR, "Free handle failed ");
00145     }
00146     return kcm_status;
00147 }