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