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