312 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			312 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | /****************************************************************************
 | ||
|  | 
 | ||
|  | Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED. | ||
|  | 
 | ||
|  | This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT | ||
|  | be copied by any method or incorporated into another program without | ||
|  | the express written consent of Aerospace C.Power. This Information or any portion | ||
|  | thereof remains the property of Aerospace C.Power. The Information contained herein | ||
|  | is believed to be accurate and Aerospace C.Power assumes no responsibility or | ||
|  | liability for its use in any way and conveys no license or title under | ||
|  | any patent or copyright and makes no representation or warranty that this | ||
|  | Information is free from patent or copyright infringement. | ||
|  | 
 | ||
|  | ****************************************************************************/ | ||
|  | 
 | ||
|  | #include "os_types.h"
 | ||
|  | #include "iot_config.h"
 | ||
|  | #include "iot_errno_api.h"
 | ||
|  | #include "iot_crypto_share.h"
 | ||
|  | #include "sec_cpu_utils.h"
 | ||
|  | #include "iot_crypto_internal.h"
 | ||
|  | #include "iot_crypto_async.h"
 | ||
|  | 
 | ||
|  | #define CRYPTO_CAL_BUF_LEN           256
 | ||
|  | 
 | ||
|  | /* plc_cpu & sec_cpu crypto share context,  */ | ||
|  | iot_crypto_share_t *g_crypto_share = NULL; | ||
|  | static uint8_t g_crypto_cal_buf[CRYPTO_CAL_BUF_LEN]; | ||
|  | 
 | ||
|  | static void sec_cpu_crypto_share_query_handle(uint8_t *data) | ||
|  | { | ||
|  |     iot_crypto_async_hdr_t *hdr; | ||
|  |     uint32_t ret = ERR_OK; | ||
|  | 
 | ||
|  |     hdr = (iot_crypto_async_hdr_t *)(data + | ||
|  |         sizeof(iot_crypto_async_src_info_t)); | ||
|  |     switch (hdr->type) { | ||
|  |     case IOT_CRYPTO_CALC_TYPE_SM2_SIGN: | ||
|  |     { | ||
|  |         uint32_t rlen, slen; | ||
|  |         iot_crypto_ret_sm2_sign_t *sign; | ||
|  |         iot_crypto_async_sm2_sign_info_t *info = | ||
|  |             (iot_crypto_async_sm2_sign_info_t *)data; | ||
|  | 
 | ||
|  |         sign = (iot_crypto_ret_sm2_sign_t *)((uint8_t *)hdr + sizeof(*hdr)); | ||
|  |         ret = iot_crypto_sm2_sign_internal(info->msg.data, info->msg.len, | ||
|  |             info->id, IOT_CRYPTO_ASYNC_SM2_USER_ID_LEN, info->pub_key, | ||
|  |             IOT_CRYPTO_ASYNC_SM2_PUB_LEN, sign->r, &rlen, sign->s, | ||
|  |             &slen, info->pri_key, IOT_CRYPTO_ASYNC_SM2_PRI_LEN); | ||
|  |         info->hdr.err_code = ret; | ||
|  |         break; | ||
|  |     } | ||
|  | 
 | ||
|  |     case IOT_CRYPTO_CALC_TYPE_SM2_VERIFY: | ||
|  |     { | ||
|  |         iot_crypto_async_sm2_verify_info_t *info = | ||
|  |             (iot_crypto_async_sm2_verify_info_t *)data; | ||
|  |         ret = iot_crypto_sm2_verify_internal(info->msg.data, info->msg.len, | ||
|  |             info->id, IOT_CRYPTO_ASYNC_SM2_USER_ID_LEN, info->pub_key, | ||
|  |             IOT_CRYPTO_ASYNC_SM2_PUB_LEN, info->r, IOT_CRYPTO_ASYNC_R_S_LEN, | ||
|  |             info->s, IOT_CRYPTO_ASYNC_R_S_LEN); | ||
|  |         info->hdr.err_code = ret; | ||
|  |         break; | ||
|  |     } | ||
|  | 
 | ||
|  |     case IOT_CRYPTO_CALC_TYPE_ECDSA_SHA256_SIGN: | ||
|  |     { | ||
|  |         uint32_t rlen, slen; | ||
|  |         iot_crypto_ret_ecdsa_sha256_sign_t *sign = | ||
|  |             (iot_crypto_ret_ecdsa_sha256_sign_t *)((uint8_t *)hdr + | ||
|  |             sizeof(*hdr)); | ||
|  |         iot_crypto_async_ecdsa_sign_info_t *info = | ||
|  |             (iot_crypto_async_ecdsa_sign_info_t *)data; | ||
|  | 
 | ||
|  |         ret = iot_crypto_ecdsa_with_sha256_sign_internal(info->ecp, | ||
|  |             info->msg.data, info->msg.len, info->pri_key, | ||
|  |             IOT_CRYPTO_ASYNC_ECDSA_PRI_LEN, sign->r, &rlen, sign->s, &slen); | ||
|  |         info->hdr.err_code = ret; | ||
|  |         break; | ||
|  |     } | ||
|  | 
 | ||
|  |     case IOT_CRYPTO_CALC_TYPE_ECDSA_SHA256_VERIFY: | ||
|  |     { | ||
|  |         iot_crypto_async_ecdsa_verify_info_t *info = | ||
|  |             (iot_crypto_async_ecdsa_verify_info_t *)data; | ||
|  | 
 | ||
|  |         ret = iot_crypto_ecdsa_with_sha256_sign_verify_internal(info->ecp, | ||
|  |             info->msg.data, info->msg.len, info->pub_key, | ||
|  |             IOT_CRYPTO_ASYNC_ECDSA_PUB_LEN, info->r, | ||
|  |             IOT_CRYPTO_ASYNC_ECDSA_R_S_LEN, info->s, | ||
|  |             IOT_CRYPTO_ASYNC_ECDSA_R_S_LEN); | ||
|  |         info->hdr.err_code = ret; | ||
|  |         break; | ||
|  |     } | ||
|  | 
 | ||
|  |     case IOT_CRYPTO_CALC_TYPE_SM2_KDF_GEN: | ||
|  |     { | ||
|  |         uint32_t genkey_len_tmp; | ||
|  |         iot_crypto_async_sm2_gen_key_info_t *info = | ||
|  |             (iot_crypto_async_sm2_gen_key_info_t *)data; | ||
|  |         iot_crypto_ret_sm2_kdf_gen_t *genkey = | ||
|  |             (iot_crypto_ret_sm2_kdf_gen_t *)((uint8_t *)hdr + sizeof(*hdr)); | ||
|  | 
 | ||
|  |         genkey_len_tmp = info->gen_key.len; | ||
|  |         ret = iot_crypto_sm2_gen_share_key_internal(info->pub_key, | ||
|  |             info->pri_key, genkey->key, genkey_len_tmp); | ||
|  |         info->hdr.err_code = ret; | ||
|  |         genkey->len = genkey_len_tmp; | ||
|  |         break; | ||
|  |     } | ||
|  | 
 | ||
|  |     case IOT_CRYPTO_CALC_TYPE_SM2_KEYPAIR_GEN: | ||
|  |     { | ||
|  |         iot_crypto_async_sm2_gen_keypair_info_t *info = | ||
|  |             (iot_crypto_async_sm2_gen_keypair_info_t *)data; | ||
|  | 
 | ||
|  |         ret = iot_crypto_sm2_gen_keypair_internal(info->ret_info.pub_key, | ||
|  |             &info->ret_info.pub_key_len, info->ret_info.pri_key, | ||
|  |             &info->ret_info.pri_key_len); | ||
|  |         if ((info->ret_info.pub_key_len > IOT_CRYPTO_ASYNC_ECDSA_PUB_LEN) || | ||
|  |             (info->ret_info.pri_key_len > IOT_CRYPTO_ASYNC_ECDSA_PRI_LEN)) { | ||
|  |             IOT_ASSERT(0); | ||
|  |         } | ||
|  | 
 | ||
|  |         info->hdr.err_code = ret; | ||
|  |         break; | ||
|  |     } | ||
|  | 
 | ||
|  |     case IOT_CRYPTO_CALC_TYPE_ECDSA_KEYPAIR_GEN: | ||
|  |     { | ||
|  |         iot_crypto_async_ecdsa_gen_keypair_info_t *info = | ||
|  |             (iot_crypto_async_ecdsa_gen_keypair_info_t *)data; | ||
|  | 
 | ||
|  |         ret = iot_crypto_ecdsa_gen_keypair_internal(info->ret_info.ecp, | ||
|  |             info->ret_info.pub_key, &info->ret_info.pub_key_len, | ||
|  |             info->ret_info.pri_key, &info->ret_info.pri_key_len); | ||
|  |         if ((info->ret_info.pub_key_len > IOT_CRYPTO_ASYNC_ECDSA_PUB_LEN) || | ||
|  |             (info->ret_info.pri_key_len > IOT_CRYPTO_ASYNC_ECDSA_PRI_LEN)) { | ||
|  |             IOT_ASSERT(0); | ||
|  |         } | ||
|  | 
 | ||
|  |         info->hdr.err_code = ret; | ||
|  |         break; | ||
|  |     } | ||
|  | 
 | ||
|  |     case IOT_CRYPTO_CALC_TYPE_SG_AUTH_SIGN: | ||
|  |     { | ||
|  |         uint32_t rlen, slen; | ||
|  |         iot_crypto_ret_sg_sign_async_t *tmp_buf = | ||
|  |             (iot_crypto_ret_sg_sign_async_t *)g_crypto_cal_buf; | ||
|  | 
 | ||
|  |         iot_crypto_async_sg_auth_sign_info_t *info = | ||
|  |             (iot_crypto_async_sg_auth_sign_info_t *)data; | ||
|  |         iot_crypto_ret_sg_sign_async_t *out_info = | ||
|  |             (iot_crypto_ret_sg_sign_async_t *)hdr; | ||
|  | 
 | ||
|  |         if (sizeof(*out_info) + info->gen_key_len > CRYPTO_CAL_BUF_LEN) { | ||
|  |             IOT_ASSERT(0); | ||
|  |         } | ||
|  | 
 | ||
|  |         info->hdr.err_code = CRYPTO_RET_OK; | ||
|  |         tmp_buf->sg_gen_key.key_len = info->gen_key_len; | ||
|  | 
 | ||
|  |         do { | ||
|  |             /* step1: verify the id_info based on SM2 */ | ||
|  |             ret = iot_crypto_sm2_verify_internal((uint8_t *)&info->chip_id, | ||
|  |                 info->chip_id_len + IOT_CRYPTO_ASYNC_ECP_LEN + | ||
|  |                 IOT_CRYPTO_ASYNC_SM2_PUB_LEN, | ||
|  |                 info->user_id, IOT_CRYPTO_ASYNC_SM2_USER_ID_LEN, info->root_pub, | ||
|  |                 IOT_CRYPTO_ASYNC_SM2_PUB_LEN, | ||
|  |                 info->sign_r, IOT_CRYPTO_ASYNC_R_S_LEN, | ||
|  |                 info->sign_s, IOT_CRYPTO_ASYNC_R_S_LEN); | ||
|  |             if (ERR_OK != ret) { | ||
|  |                 out_info->async_hdr.err_code = CRYPTO_RET_CALC_ERR; | ||
|  |                 break; | ||
|  |             } | ||
|  | 
 | ||
|  |             /* step2: random number signature */ | ||
|  |             ret = iot_crypto_sm2_sign_internal(info->random, info->random_len, | ||
|  |                 info->user_id, IOT_CRYPTO_ASYNC_SM2_USER_ID_LEN, | ||
|  |                 info->local_pub, IOT_CRYPTO_ASYNC_SM2_PUB_LEN, | ||
|  |                 tmp_buf->sm2_sign.r, &rlen, tmp_buf->sm2_sign.s, &slen, | ||
|  |                 info->local_pri, IOT_CRYPTO_ASYNC_SM2_PUB_LEN); | ||
|  |             if (ERR_OK != ret) { | ||
|  |                 out_info->async_hdr.err_code = CRYPTO_RET_CALC_ERR; | ||
|  |                 break; | ||
|  |             } | ||
|  | 
 | ||
|  |             /**
 | ||
|  |              * step3: generate share key, | ||
|  |              * the step3 function iot_crypto_sm2_gen_share_key is only used by | ||
|  |              * sm2, | ||
|  |              * so this sg function can only be used by sm2 | ||
|  |              */ | ||
|  |             ret = iot_crypto_sm2_gen_share_key_internal(info->auth_pub, | ||
|  |                 info->local_pri, tmp_buf->sg_gen_key.key, | ||
|  |                 tmp_buf->sg_gen_key.key_len); | ||
|  |             if (CRYPTO_RET_OK != ret) { | ||
|  |                 out_info->async_hdr.err_code = CRYPTO_RET_CALC_ERR; | ||
|  |                 break; | ||
|  |             } | ||
|  | 
 | ||
|  |             os_mem_cpy((uint8_t *)&out_info->sm2_sign, | ||
|  |                 (uint8_t *)&tmp_buf->sm2_sign, sizeof(tmp_buf->sm2_sign)); | ||
|  | 
 | ||
|  |             os_mem_cpy(out_info->sg_gen_key.key, tmp_buf->sg_gen_key.key, | ||
|  |                 tmp_buf->sg_gen_key.key_len); | ||
|  |             out_info->sg_gen_key.key_len = tmp_buf->sg_gen_key.key_len; | ||
|  |         } while(0); | ||
|  |         break; | ||
|  |     } | ||
|  | 
 | ||
|  |     case IOT_CRYPTO_CALC_TYPE_SG_AUTH_VERIRY: | ||
|  |     { | ||
|  |         iot_crypto_ret_sg_verify_async_t *tmp_buf = | ||
|  |             (iot_crypto_ret_sg_verify_async_t *)g_crypto_cal_buf; | ||
|  |         iot_crypto_ret_sg_verify_async_t *out_info = | ||
|  |             (iot_crypto_ret_sg_verify_async_t *)hdr; | ||
|  |         iot_crypto_async_sg_auth_verify_info_t *info = | ||
|  |             (iot_crypto_async_sg_auth_verify_info_t *)data; | ||
|  | 
 | ||
|  |         if (sizeof(*out_info) + info->gen_key_len > CRYPTO_CAL_BUF_LEN) { | ||
|  |             IOT_ASSERT(0); | ||
|  |         } | ||
|  | 
 | ||
|  |         info->hdr.err_code = CRYPTO_RET_OK; | ||
|  |         tmp_buf->sg_gen_key.key_len = info->gen_key_len; | ||
|  | 
 | ||
|  |         do { | ||
|  |             /* step1: verify the id_info based on SM2 */ | ||
|  |             ret = iot_crypto_sm2_verify_internal((uint8_t *)&info->chip_id, | ||
|  |                 info->chip_id_len + IOT_CRYPTO_ASYNC_ECP_LEN + | ||
|  |                 IOT_CRYPTO_ASYNC_SM2_PUB_LEN, | ||
|  |                 info->user_id, IOT_CRYPTO_ASYNC_SM2_USER_ID_LEN, info->root_pub, | ||
|  |                 IOT_CRYPTO_ASYNC_SM2_PUB_LEN, | ||
|  |                 info->sign_r, IOT_CRYPTO_ASYNC_R_S_LEN, | ||
|  |                 info->sign_s, IOT_CRYPTO_ASYNC_R_S_LEN); | ||
|  |             if (CRYPTO_RET_OK != ret) { | ||
|  |                 out_info->async_hdr.err_code = CRYPTO_RET_CALC_ERR; | ||
|  |                 break; | ||
|  |             } | ||
|  | 
 | ||
|  |             /* step2: random number verify */ | ||
|  |             ret = iot_crypto_sm2_verify_internal(info->random, info->random_len, | ||
|  |                 info->user_id, IOT_CRYPTO_ASYNC_SM2_USER_ID_LEN, info->auth_pub, | ||
|  |                 IOT_CRYPTO_ASYNC_SM2_PUB_LEN, | ||
|  |                 info->random_r, IOT_CRYPTO_ASYNC_R_S_LEN, info->random_s, | ||
|  |                 IOT_CRYPTO_ASYNC_R_S_LEN); | ||
|  |             if (CRYPTO_RET_OK != ret) { | ||
|  |                out_info->async_hdr.err_code = CRYPTO_RET_CALC_ERR; | ||
|  |                break; | ||
|  |             } | ||
|  | 
 | ||
|  |             /* step3: generate share key */ | ||
|  |             ret = iot_crypto_sm2_gen_share_key_internal(info->auth_pub, | ||
|  |                 info->local_pri, tmp_buf->sg_gen_key.key, | ||
|  |                 tmp_buf->sg_gen_key.key_len); | ||
|  |             if (CRYPTO_RET_OK != ret) { | ||
|  |                 out_info->async_hdr.err_code = CRYPTO_RET_CALC_ERR; | ||
|  |                 break; | ||
|  |             } | ||
|  | 
 | ||
|  |             os_mem_cpy(out_info->sg_gen_key.key, tmp_buf->sg_gen_key.key, | ||
|  |                 tmp_buf->sg_gen_key.key_len); | ||
|  |             out_info->sg_gen_key.key_len = tmp_buf->sg_gen_key.key_len; | ||
|  |         } while(0); | ||
|  |         break; | ||
|  |     } | ||
|  | 
 | ||
|  |     default: | ||
|  |         sec_cpu_printf("sec cpu type error = %d\n", hdr->type); | ||
|  |         IOT_ASSERT(0); | ||
|  |         break; | ||
|  |     } | ||
|  | 
 | ||
|  | } | ||
|  | 
 | ||
|  | void sec_cpu_crypto_share_query(void) | ||
|  | { | ||
|  |     if (!iot_crypto_share_is_enable(g_crypto_share)) { | ||
|  |         return; | ||
|  |     } | ||
|  | 
 | ||
|  |     if (g_crypto_share->cur_buf) { | ||
|  |         if (ERR_OK != iot_crypto_share_fifo_put(&g_crypto_share->rsp, | ||
|  |             g_crypto_share->cur_buf)) { | ||
|  |             //TODO: maybe assert?
 | ||
|  |             sec_cpu_printf("sec cpu crypto put rsp error\n"); | ||
|  |             return; | ||
|  |         } else { | ||
|  |             g_crypto_share->cur_buf = NULL; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     while (iot_crypto_share_fifo_elements(&g_crypto_share->req)) { | ||
|  |         g_crypto_share->cur_buf = iot_crypto_share_fifo_get( | ||
|  |             &g_crypto_share->req); | ||
|  |         sec_cpu_crypto_share_query_handle(g_crypto_share->cur_buf); | ||
|  |         if (ERR_OK != iot_crypto_share_fifo_put(&g_crypto_share->rsp, | ||
|  |             g_crypto_share->cur_buf)) { | ||
|  |             break; | ||
|  |         } else { | ||
|  |             g_crypto_share->cur_buf = NULL; | ||
|  |         } | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | void sec_cpu_crypto_share_init(void) | ||
|  | { | ||
|  |     iot_crypto_dsa_init(); | ||
|  | } |