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();
 | |
| }
 |