458 lines
15 KiB
C
458 lines
15 KiB
C
/**
|
|
* @file sdrv_crypto_mailbox_eccp.c
|
|
* @brief SemiDrive CRYPTO mailbox eccp api source file.
|
|
*
|
|
* @copyright Copyright (c) 2021 Semidrive Semiconductor.
|
|
* All rights reserved.
|
|
*/
|
|
|
|
#include <sdrv_crypto_mailbox_eccp.h>
|
|
|
|
/**
|
|
* @brief eccp point doubling.
|
|
*
|
|
* This function get eccp point doubling.
|
|
*
|
|
* @param[in] curve_id curve_id.
|
|
* @param[in] G_x_y curve xy buff.
|
|
* @param[out] output_x_y out buff.
|
|
* @return CMD_RETURN_SUCCESS or error code.
|
|
*/
|
|
sdrv_crypto_error_status_e cmd_eccp_point_doubling(uint8_t curve_id,
|
|
uint8_t *G_x_y,
|
|
uint8_t *output_x_y)
|
|
{
|
|
uint32_t cmd_buf[8] = {0};
|
|
uint32_t ret = 0;
|
|
cmd_eccp_pointdoubling_t *cmd_eccp_dbl = NULL;
|
|
|
|
/*********** point dbl ***********/
|
|
cmd_eccp_dbl = (cmd_eccp_pointdoubling_t *)cmd_buf;
|
|
cmd_eccp_dbl->cmd_id = ECCP_POINT_DOUBLING;
|
|
|
|
cmd_eccp_dbl->curve_id = curve_id;
|
|
set_big_endian_4byte((uint8_t *)cmd_eccp_dbl->inputPoint_ptr,
|
|
(uint32_t)G_x_y);
|
|
set_big_endian_4byte((uint8_t *)cmd_eccp_dbl->outputPoint_ptr,
|
|
(uint32_t)output_x_y);
|
|
|
|
ret = send_cmd_and_wait_response((uint32_t *)cmd_buf);
|
|
|
|
if (SEIP_SUCCESS == ret) {
|
|
printf("ECCP_POINT_DOUBLING success \n");
|
|
} else {
|
|
printf("ECCP_POINT_DOUBLING error, ret = 0x%x \n", ret);
|
|
return CMD_RETURN_FAIL;
|
|
}
|
|
|
|
return CMD_RETURN_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* @brief eccp point addition.
|
|
*
|
|
* This function get eccp point addition.
|
|
*
|
|
* @param[in] curve_id curve_id.
|
|
* @param[in] kG_x_y kG_x_y buff.
|
|
* @param[in] dblG_x_y dblG_x_y buff.
|
|
* @param[out] output_x_y out buff.
|
|
* @return CMD_RETURN_SUCCESS or error code.
|
|
*/
|
|
sdrv_crypto_error_status_e cmd_eccp_point_addition(uint8_t curve_id,
|
|
uint8_t *kG_x_y,
|
|
uint8_t *dblG_x_y,
|
|
uint8_t *output_x_y)
|
|
{
|
|
uint32_t cmd_buf[8] = {0};
|
|
uint32_t ret = 0;
|
|
cmd_eccp_pointaddition_t *cmd_eccp_add = NULL;
|
|
|
|
/*********** point add ***********/
|
|
cmd_eccp_add = (cmd_eccp_pointaddition_t *)cmd_buf;
|
|
cmd_eccp_add->cmd_id = ECCP_POINT_ADDITION;
|
|
|
|
cmd_eccp_add->curve_id = curve_id;
|
|
set_big_endian_4byte((uint8_t *)cmd_eccp_add->inputPoint1_ptr,
|
|
(uint32_t)kG_x_y);
|
|
set_big_endian_4byte((uint8_t *)cmd_eccp_add->inputPoint2_ptr,
|
|
(uint32_t)dblG_x_y);
|
|
set_big_endian_4byte((uint8_t *)cmd_eccp_add->outputPoint_ptr,
|
|
(uint32_t)output_x_y);
|
|
|
|
ret = send_cmd_and_wait_response((uint32_t *)cmd_buf);
|
|
|
|
if (SEIP_SUCCESS == ret) {
|
|
printf("ECCP_POINT_ADDITION success \n");
|
|
} else {
|
|
printf("ECCP_POINT_ADDITION error, ret = 0x%x \n", ret);
|
|
return CMD_RETURN_FAIL;
|
|
}
|
|
|
|
return CMD_RETURN_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* @brief eccp point multplication.
|
|
*
|
|
* This function get eccp point multplication.
|
|
*
|
|
* @param[in] curve_id curved id.
|
|
* @param[in] G_x_y point value.
|
|
* @param[in] k scalar value.
|
|
* @param[out] output_x_y out buff.
|
|
* @return CMD_RETURN_SUCCESS or error code.
|
|
*/
|
|
sdrv_crypto_error_status_e cmd_eccp_point_multiplication(uint8_t curve_id,
|
|
uint8_t *G_x_y,
|
|
uint8_t *k,
|
|
uint8_t *output_x_y)
|
|
{
|
|
uint32_t cmd_buf[8] = {0};
|
|
uint32_t ret = 0;
|
|
cmd_eccp_pointmultiplication_t *cmd_eccp_mul = NULL;
|
|
|
|
/*********** point mul ***********/
|
|
|
|
cmd_eccp_mul = (cmd_eccp_pointmultiplication_t *)cmd_buf;
|
|
cmd_eccp_mul->cmd_id = ECCP_POINT_MULTIPLICATION;
|
|
|
|
cmd_eccp_mul->curve_id = curve_id;
|
|
set_big_endian_4byte((uint8_t *)cmd_eccp_mul->inputScalar_ptr, (uint32_t)k);
|
|
set_big_endian_4byte((uint8_t *)cmd_eccp_mul->inputPoint_ptr,
|
|
(uint32_t)G_x_y);
|
|
set_big_endian_4byte((uint8_t *)cmd_eccp_mul->outputPoint_ptr,
|
|
(uint32_t)output_x_y);
|
|
|
|
ret = send_cmd_and_wait_response((uint32_t *)cmd_buf);
|
|
|
|
if (SEIP_SUCCESS == ret) {
|
|
printf("ECCP_POINT_MULTIPLICATION success \n");
|
|
} else {
|
|
printf("ECCP_POINT_MULTIPLICATION error, ret = 0x%x \n", ret);
|
|
return CMD_RETURN_FAIL;
|
|
}
|
|
|
|
return CMD_RETURN_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* @brief eccp point verify.
|
|
*
|
|
* This function verify eccp point.
|
|
*
|
|
* @param[in] curve_id curved id.
|
|
* @param[in] G_x_y point value.
|
|
* @return CMD_RETURN_SUCCESS or error code.
|
|
*/
|
|
sdrv_crypto_error_status_e cmd_eccp_point_verify(uint8_t curve_id,
|
|
uint8_t *G_x_y)
|
|
{
|
|
uint32_t cmd_buf[8] = {0};
|
|
uint32_t ret = 0;
|
|
cmd_eccp_pointverifying_t *cmd_eccp_verify = NULL;
|
|
|
|
/*********** point verify ***********/
|
|
cmd_eccp_verify = (cmd_eccp_pointverifying_t *)cmd_buf;
|
|
cmd_eccp_verify->cmd_id = ECCP_POINT_VERIFY;
|
|
|
|
cmd_eccp_verify->curve_id = curve_id;
|
|
set_big_endian_4byte((uint8_t *)cmd_eccp_verify->inputPoint_ptr,
|
|
(uint32_t)G_x_y);
|
|
|
|
ret = send_cmd_and_wait_response((uint32_t *)cmd_buf);
|
|
|
|
if (SEIP_SUCCESS == ret) {
|
|
printf("ECCP_POINT_VERIFY success \n");
|
|
} else {
|
|
printf("ECCP_POINT_VERIFY error , ret = 0x%x \n", ret);
|
|
return CMD_RETURN_FAIL;
|
|
}
|
|
|
|
return CMD_RETURN_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* @brief eccp generate ecdh keypair.
|
|
*
|
|
* This function generate ecdh keypair.
|
|
*
|
|
* @param[in] curve_id curved id.
|
|
* @param[out] prikey prikey buff.
|
|
* @param[out] pubkey pubkey buff.
|
|
* @param[in] generate_key_type pri and pub key output type.
|
|
* @param[in] generate_key_id for enc key.
|
|
* @param[in] mac_buf key_id mac buf.
|
|
* @return CMD_RETURN_SUCCESS or error code.
|
|
*/
|
|
sdrv_crypto_error_status_e cmd_eccp_ecdh_generate_keypair(
|
|
uint8_t curve_id, uint8_t *prikey, uint8_t *pubkey,
|
|
cmd_key_type_e generate_key_type, uint16_t generate_key_id,
|
|
uint8_t *mac_buf)
|
|
{
|
|
sdrv_crypto_error_status_e RetVal = CMD_RETURN_FAIL;
|
|
uint16_t key_id_array[2];
|
|
uint32_t cmd_buf[8] = {0};
|
|
uint32_t ret = 0;
|
|
uint8_t count;
|
|
cmd_eccp_generatekey_t *cmd_eccp_get_key = NULL;
|
|
|
|
/*********** get key pair ***********/
|
|
cmd_eccp_get_key = (cmd_eccp_generatekey_t *)cmd_buf;
|
|
cmd_eccp_get_key->cmd_id = ECCP_GENERATE_KEY;
|
|
|
|
if (CMD_KEY_EXTERNAL_PLAINTEXT == generate_key_type) {
|
|
key_id_array[0] = 0;
|
|
} else if (CMD_KEY_EXTERNAL_CIPHERTEXT == generate_key_type) {
|
|
key_id_array[0] = generate_key_id;
|
|
} else {
|
|
key_id_array[0] = 0;
|
|
}
|
|
|
|
set_big_endian_2byte((uint8_t *)cmd_eccp_get_key->key_id, key_id_array[0]);
|
|
|
|
cmd_eccp_get_key->curve_id = curve_id;
|
|
set_big_endian_4byte((uint8_t *)cmd_eccp_get_key->pubKey_ptr,
|
|
(uint32_t)pubkey);
|
|
set_big_endian_4byte((uint8_t *)cmd_eccp_get_key->priKey_ptr,
|
|
(uint32_t)prikey);
|
|
set_big_endian_4byte((uint8_t *)cmd_eccp_get_key->aut_info_ptr,
|
|
(uint32_t)mac_buf);
|
|
|
|
get_otp_key_aut_mac(key_id_array, 1, (uint8_t *)cmd_buf, mac_buf);
|
|
|
|
count = RETRY_COUNT;
|
|
do {
|
|
ret = send_cmd_and_wait_response((uint32_t *)cmd_buf);
|
|
if (SEIP_SUCCESS == ret) {
|
|
RetVal = CMD_RETURN_SUCCESS;
|
|
break;
|
|
} else if (SEIP_ERROR_ECC_GET_KEY_FAIL == ret) {
|
|
RetVal = CMD_RETURN_FAIL;
|
|
/* retry */
|
|
} else {
|
|
RetVal = CMD_RETURN_FAIL;
|
|
break;
|
|
}
|
|
|
|
count--;
|
|
} while (count);
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
/**
|
|
* @brief ecdh exchange key.
|
|
*
|
|
* This function for ecdh exchange key.
|
|
*
|
|
* @param[in] curve_id curved id.
|
|
* @param[in] key_len key len.
|
|
* @param[out] KA key buff.
|
|
* @param[in] pubkey_B PeerPubKey buff.
|
|
* @param[in] prikey_A selfPrikey buff.
|
|
* @param[in] ecdh_key_type selfPrikey type.
|
|
* @param[in] ecdh_key_id for enc key.
|
|
* @param[in] output_key_type output key type.
|
|
* @param[in] output_key_id for enc key.
|
|
* @param[in] mac_buf key_id mac buf.
|
|
* @return CMD_RETURN_SUCCESS or error code.
|
|
*/
|
|
sdrv_crypto_error_status_e cmd_eccp_ecdh_exchange_key(
|
|
uint8_t curve_id, uint8_t key_len, uint8_t *KA, uint8_t *pubkey_B,
|
|
uint8_t *prikey_A, cmd_key_type_e ecdh_key_type, uint16_t ecdh_key_id,
|
|
cmd_key_type_e output_key_type, uint16_t output_key_id, uint8_t *mac_buf)
|
|
{
|
|
uint16_t key_id_array[3];
|
|
uint32_t cmd_buf[8] = {0};
|
|
uint32_t ret = 0;
|
|
cmd_ecdh_exchangekey_t *cmd_eccp_exc_key = NULL;
|
|
|
|
/*********** calc ***********/
|
|
cmd_eccp_exc_key = (cmd_ecdh_exchangekey_t *)cmd_buf;
|
|
cmd_eccp_exc_key->cmd_id = ECDH_EXCHANGE_KEY;
|
|
|
|
cmd_eccp_exc_key->curve_id = curve_id;
|
|
set_big_endian_4byte((uint8_t *)cmd_eccp_exc_key->PeerPubKey_ptr,
|
|
(uint32_t)pubkey_B);
|
|
set_big_endian_4byte((uint8_t *)cmd_eccp_exc_key->aut_info_ptr,
|
|
(uint32_t)mac_buf);
|
|
|
|
if (CMD_KEY_EXTERNAL_PLAINTEXT == ecdh_key_type) {
|
|
set_big_endian_4byte((uint8_t *)cmd_eccp_exc_key->selfPrikey_ptr,
|
|
(uint32_t)prikey_A);
|
|
key_id_array[0] = 0;
|
|
key_id_array[1] = 0;
|
|
} else if (CMD_KEY_EXTERNAL_CIPHERTEXT == ecdh_key_type) {
|
|
set_big_endian_4byte((uint8_t *)cmd_eccp_exc_key->selfPrikey_ptr,
|
|
(uint32_t)prikey_A);
|
|
key_id_array[0] = 0;
|
|
key_id_array[1] = ecdh_key_id;
|
|
} else if (CMD_KEY_INTERNAL == ecdh_key_type) {
|
|
set_big_endian_4byte((uint8_t *)cmd_eccp_exc_key->selfPrikey_ptr, 0);
|
|
key_id_array[0] = ecdh_key_id;
|
|
key_id_array[1] = 0;
|
|
} else {
|
|
return CMD_RETURN_FAIL;
|
|
}
|
|
|
|
set_big_endian_2byte((uint8_t *)cmd_eccp_exc_key->key_id0, key_id_array[0]);
|
|
set_big_endian_2byte((uint8_t *)cmd_eccp_exc_key->key_id1, key_id_array[1]);
|
|
|
|
cmd_eccp_exc_key->key_len = key_len;
|
|
set_big_endian_4byte((uint8_t *)cmd_eccp_exc_key->key_ptr, (uint32_t)KA);
|
|
|
|
if (CMD_KEY_EXTERNAL_PLAINTEXT == output_key_type) {
|
|
key_id_array[2] = 0;
|
|
} else if (CMD_KEY_EXTERNAL_CIPHERTEXT == output_key_type) {
|
|
key_id_array[2] = output_key_id;
|
|
} else {
|
|
key_id_array[2] = 0;
|
|
}
|
|
|
|
set_big_endian_2byte((uint8_t *)cmd_eccp_exc_key->key_id2, key_id_array[2]);
|
|
|
|
uint32_clear((uint32_t *)mac_buf, 4 * 2);
|
|
get_otp_key_aut_mac(key_id_array, 3, (uint8_t *)cmd_buf, mac_buf);
|
|
|
|
ret = send_cmd_and_wait_response((uint32_t *)cmd_buf);
|
|
|
|
if (SEIP_SUCCESS == ret) {
|
|
|
|
} else {
|
|
printf("calc error, ret = 0x%x \n", ret);
|
|
return CMD_RETURN_FAIL;
|
|
}
|
|
|
|
return CMD_RETURN_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* @brief eccp ecdsa gen signature.
|
|
*
|
|
* This function for ecdsa gen signature.
|
|
*
|
|
* @param[in] curve_id curved id.
|
|
* @param[in] e e value.
|
|
* @param[out] e_len e len.
|
|
* @param[in] sign_key_type sign key type.
|
|
* @param[in] sign_key_id sign key id.
|
|
* @param[in] prikey prikey value.
|
|
* @param[out] signature signature value.
|
|
* @param[in] mac_buf key_id mac buf.
|
|
* @return CMD_RETURN_SUCCESS or error code.
|
|
*/
|
|
sdrv_crypto_error_status_e cmd_eccp_ecdsa_gen_signature(
|
|
uint8_t curve_id, uint8_t *e, uint32_t e_len,
|
|
cmd_key_type_e sign_key_type, uint16_t sign_key_id,
|
|
uint8_t *prikey, uint8_t *signature, uint8_t *mac_buf)
|
|
{
|
|
sdrv_crypto_error_status_e RetVal = CMD_RETURN_FAIL;
|
|
uint8_t count;
|
|
uint16_t key_id_array[2];
|
|
uint32_t cmd_buf[8] = {0};
|
|
uint32_t ret = 0;
|
|
cmd_ecdsa_generatesignature_t *cmd_ecdsa_sign = NULL;
|
|
|
|
/*********** ecdsa sign ***********/
|
|
cmd_ecdsa_sign = (cmd_ecdsa_generatesignature_t *)cmd_buf;
|
|
cmd_ecdsa_sign->cmd_id = ECDSA_GENERATE_SIGNATURE;
|
|
|
|
cmd_ecdsa_sign->curve_id = curve_id;
|
|
cmd_ecdsa_sign->e_len = e_len;
|
|
set_big_endian_4byte((uint8_t *)cmd_ecdsa_sign->e_ptr, (uint32_t)e);
|
|
set_big_endian_4byte((uint8_t *)cmd_ecdsa_sign->aut_info_ptr,
|
|
(uint32_t)mac_buf);
|
|
|
|
if (CMD_KEY_EXTERNAL_PLAINTEXT == sign_key_type) {
|
|
key_id_array[0] = 0;
|
|
key_id_array[1] = 0;
|
|
set_big_endian_4byte((uint8_t *)cmd_ecdsa_sign->priKey_ptr,
|
|
(uint32_t)prikey);
|
|
} else if (CMD_KEY_EXTERNAL_CIPHERTEXT == sign_key_type) {
|
|
key_id_array[0] = 0;
|
|
key_id_array[1] = sign_key_id;
|
|
set_big_endian_4byte((uint8_t *)cmd_ecdsa_sign->priKey_ptr,
|
|
(uint32_t)prikey);
|
|
} else if (CMD_KEY_INTERNAL == sign_key_type) {
|
|
set_big_endian_4byte((uint8_t *)cmd_ecdsa_sign->priKey_ptr, 0);
|
|
key_id_array[0] = sign_key_id;
|
|
key_id_array[1] = 0;
|
|
} else {
|
|
return CMD_RETURN_FAIL;
|
|
}
|
|
|
|
set_big_endian_2byte((uint8_t *)cmd_ecdsa_sign->key_id0, key_id_array[0]);
|
|
set_big_endian_2byte((uint8_t *)cmd_ecdsa_sign->key_id1, key_id_array[1]);
|
|
set_big_endian_4byte((uint8_t *)cmd_ecdsa_sign->signature_ptr,
|
|
(uint32_t)signature);
|
|
|
|
get_otp_key_aut_mac(key_id_array, 2, (uint8_t *)cmd_buf, mac_buf);
|
|
|
|
count = RETRY_COUNT;
|
|
do {
|
|
ret = send_cmd_and_wait_response((uint32_t *)cmd_buf);
|
|
if (SEIP_SUCCESS == ret) {
|
|
RetVal = CMD_RETURN_SUCCESS;
|
|
break;
|
|
} else if (SEIP_ERROR_ECDSA_VERIFY_FAIL == ret) {
|
|
RetVal = CMD_RETURN_FAIL;
|
|
/* retry */
|
|
} else {
|
|
RetVal = CMD_RETURN_FAIL;
|
|
break;
|
|
}
|
|
|
|
count--;
|
|
} while (count);
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
/**
|
|
* @brief eccp point verify.
|
|
*
|
|
* This function verify eccp point.
|
|
*
|
|
* @param[in] curve_id curved id.
|
|
* @param[in] e e value.
|
|
* @param[out] e_len e len.
|
|
* @param[in] pubkey pubkey value.
|
|
* @param[in] signature signature value.
|
|
* @return CMD_RETURN_SUCCESS or error code.
|
|
*/
|
|
sdrv_crypto_error_status_e cmd_eccp_ecdsa_verify_signature(uint8_t curve_id,
|
|
uint8_t *e,
|
|
uint32_t e_len,
|
|
uint8_t *pubkey,
|
|
uint8_t *signature)
|
|
{
|
|
uint32_t cmd_buf[8] = {0};
|
|
uint32_t ret = 0;
|
|
cmd_ecdsa_verifysignature_t *cmd_ecdsa_verify = NULL;
|
|
|
|
/*********** ecdsa verify ***********/
|
|
cmd_ecdsa_verify = (cmd_ecdsa_verifysignature_t *)cmd_buf;
|
|
cmd_ecdsa_verify->cmd_id = ECDSA_VERIFY_SIGNATURE;
|
|
|
|
cmd_ecdsa_verify->curve_id = curve_id;
|
|
cmd_ecdsa_verify->e_len = e_len;
|
|
set_big_endian_4byte((uint8_t *)cmd_ecdsa_verify->e_ptr, (uint32_t)e);
|
|
|
|
set_big_endian_4byte((uint8_t *)cmd_ecdsa_verify->pubKey_ptr,
|
|
(uint32_t)pubkey);
|
|
|
|
set_big_endian_4byte((uint8_t *)cmd_ecdsa_verify->signature_ptr,
|
|
(uint32_t)signature);
|
|
|
|
ret = send_cmd_and_wait_response((uint32_t *)cmd_buf);
|
|
|
|
if (SEIP_SUCCESS == ret) {
|
|
printf("ecdsa verify pass \n");
|
|
} else {
|
|
printf("ecdsa verify error, ret = 0x%x \n", ret);
|
|
return CMD_RETURN_FAIL;
|
|
}
|
|
|
|
return CMD_RETURN_SUCCESS;
|
|
} |