Files
kunlun/sec_cpu/driver/sec_cpu_crypto_share.c
2024-09-28 14:24:04 +08:00

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