Files
base/drivers/source/crypto/mailbox/sdrv_crypto_mailbox_rsa.c
2025-11-07 09:57:14 +08:00

570 lines
19 KiB
C

/**
* @file sdrv_crypto_mailbox_rsa.c
* @brief SemiDrive CRYPTO rsa interface source file.
*
* @copyright Copyright (c) 2021 Semidrive Semiconductor.
* All rights reserved.
*/
#include <sdrv_crypto_mailbox_rsa.h>
/**
* @brief get prime
*
* This function get prime
*
* @param[in] primebitlen prime len
* @param[out] prime out buff
* @return CMD_RETURN_SUCCESS or error code.
*/
sdrv_crypto_error_status_e cmd_rsa_get_prime(uint16_t primebitlen,
uint8_t *prime)
{
uint32_t cmd_buf[8] = {0};
uint32_t ret = 0;
cmd_rsa_getprime_t *cmd_get_prime = NULL;
/*********** generate random prime ***********/
cmd_get_prime = (cmd_rsa_getprime_t *)cmd_buf;
cmd_get_prime->cmd_id = RSA_GENERATE_PRIME;
set_big_endian_2byte((uint8_t *)cmd_get_prime->prime_len,
(uint32_t)primebitlen);
set_big_endian_4byte((uint8_t *)cmd_get_prime->prime_ptr, (uint32_t)prime);
ret = send_cmd_and_wait_response((uint32_t *)cmd_buf);
if (SEIP_SUCCESS == ret) {
printf("RSA_GENERATE_PRIME success(%d bits) \n", primebitlen);
} else {
printf("RSA_GENERATE_PRIME error, ret = 0x%x \n", ret);
return CMD_RETURN_FAIL;
}
return CMD_RETURN_SUCCESS;
}
/**
* @brief generate rsa key
*
* This function generate ras key.
*
* @param[in] ebitlen e bit len
* @param[in] nbitlen n bit len
* @param[in] generate_key_type out put key type
* @param[in] generate_key_id enc key id
* @param[out] n n buff
* @param[out] e e buff
* @param[out] d d buff
* @param[in] mac_buf mac buff
* @return CMD_RETURN_SUCCESS or error code.
*/
sdrv_crypto_error_status_e cmd_rsa_generate_key(
uint16_t ebitlen, uint16_t nbitlen,
cmd_key_type_e generate_key_type,
uint16_t generate_key_id, uint8_t *n,
uint8_t *e, uint8_t *d, 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_rsa_generatekey_t *cmd_rsa_get_key = NULL;
/*********** generate key pair ***********/
cmd_rsa_get_key = (cmd_rsa_generatekey_t *)cmd_buf;
cmd_rsa_get_key->cmd_id = RSA_GENERATE_KEY;
set_big_endian_2byte((uint8_t *)cmd_rsa_get_key->e_len, (uint32_t)ebitlen);
set_big_endian_2byte((uint8_t *)cmd_rsa_get_key->n_len, (uint32_t)nbitlen);
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;
}
set_big_endian_2byte((uint8_t *)cmd_rsa_get_key->key_id, key_id_array[0]);
set_big_endian_4byte((uint8_t *)cmd_rsa_get_key->e_ptr, (uint32_t)e);
set_big_endian_4byte((uint8_t *)cmd_rsa_get_key->n_ptr, (uint32_t)n);
set_big_endian_4byte((uint8_t *)cmd_rsa_get_key->d_ptr, (uint32_t)d);
set_big_endian_4byte((uint8_t *)cmd_rsa_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_RSA_GET_KEY_FAIL == ret) {
RetVal = CMD_RETURN_FAIL;
/* retry */
} else {
RetVal = CMD_RETURN_FAIL;
break;
}
count--;
} while (count);
return RetVal;
}
/**
* @brief rsa encrypt
*
* This function encrypt , msg_len is same with n bitlen
*
* @param[in] msg msg buff
* @param[in] e e buff
* @param[in] n n buff
* @param[in] nbitlen n bit len
* @param[out] out out buff
* @return CMD_RETURN_SUCCESS or error code.
*/
sdrv_crypto_error_status_e cmd_rsa_encrypt(uint8_t *msg, uint8_t *e, uint8_t *n,
uint32_t nbitlen, uint8_t *out)
{
uint32_t cmd_buf[8] = {0};
uint32_t ret = 0;
cmd_rsa_encrypt_t *cmd_rsa_enc = NULL;
/*********** encrypt ***********/
cmd_rsa_enc = (cmd_rsa_encrypt_t *)cmd_buf;
cmd_rsa_enc->cmd_id = RSA_ENCRYPT;
set_big_endian_4byte((uint8_t *)cmd_rsa_enc->data_ptr, (uint32_t)msg);
set_big_endian_4byte((uint8_t *)cmd_rsa_enc->e_ptr, (uint32_t)e);
set_big_endian_4byte((uint8_t *)cmd_rsa_enc->cipher_ptr, (uint32_t)out);
set_big_endian_4byte((uint8_t *)cmd_rsa_enc->n_ptr, (uint32_t)n);
set_big_endian_2byte((uint8_t *)cmd_rsa_enc->n_len, (uint32_t)nbitlen);
ret = send_cmd_and_wait_response((uint32_t *)cmd_buf);
if (SEIP_SUCCESS == ret) {
printf("enc %d pass \n", nbitlen);
} else {
printf("enc %d error, ret = 0x%x \n", nbitlen, ret);
return CMD_RETURN_FAIL;
}
return CMD_RETURN_SUCCESS;
}
/**
* @brief rsa decrypt
*
* This function decrypt.
*
* @param[out] plain plain buff
* @param[in] d d buff
* @param[in] e e buff
* @param[in] n n buff
* @param[in] nbitlen n bit len
* @param[in] cipher cipher buff
* @param[in] decrypt_key_type dec key type
* @param[in] decrypt_key_id dec key id
* @param[in] mac_buf out buff
* @return CMD_RETURN_SUCCESS or error code.
*/
sdrv_crypto_error_status_e cmd_rsa_decrypt(uint8_t *plain, uint8_t *d,
uint8_t *e, uint8_t *n,
uint32_t nbitlen, uint8_t *cipher,
cmd_key_type_e decrypt_key_type,
uint16_t decrypt_key_id,
uint8_t *mac_buf)
{
uint16_t key_id_array[2];
uint32_t cmd_buf[8] = {0};
uint32_t ret = 0;
cmd_rsa_decrypt_t *cmd_rsa_dec = NULL;
/*********** decrypt ***********/
cmd_rsa_dec = (cmd_rsa_decrypt_t *)cmd_buf;
cmd_rsa_dec->cmd_id = RSA_DECRYPT;
cmd_rsa_dec->need_high_sec_ver = 0;
set_big_endian_4byte((uint8_t *)cmd_rsa_dec->data_ptr, (uint32_t)plain);
set_big_endian_4byte((uint8_t *)cmd_rsa_dec->e_ptr, (uint32_t)e);
set_big_endian_4byte((uint8_t *)cmd_rsa_dec->cipher_ptr, (uint32_t)cipher);
set_big_endian_4byte((uint8_t *)cmd_rsa_dec->d_ptr, (uint32_t)d);
if (CMD_KEY_EXTERNAL_PLAINTEXT == decrypt_key_type) {
key_id_array[0] = 0;
} else if (CMD_KEY_EXTERNAL_CIPHERTEXT == decrypt_key_type) {
key_id_array[0] = decrypt_key_id;
} else {
return CMD_RETURN_FAIL;
}
set_big_endian_2byte((uint8_t *)cmd_rsa_dec->key_id, key_id_array[0]);
set_big_endian_4byte((uint8_t *)cmd_rsa_dec->n_ptr, (uint32_t)n);
set_big_endian_2byte((uint8_t *)cmd_rsa_dec->n_len, (uint32_t)nbitlen);
set_big_endian_4byte((uint8_t *)cmd_rsa_dec->aut_info_ptr,
(uint32_t)mac_buf);
get_otp_key_aut_mac(key_id_array, 1, (uint8_t *)cmd_buf, mac_buf);
ret = send_cmd_and_wait_response((uint32_t *)cmd_buf);
if (SEIP_SUCCESS == ret) {
printf("dec pass \n");
} else {
printf("dec error, ret = 0x%x \n", ret);
return CMD_RETURN_FAIL;
}
return CMD_RETURN_SUCCESS;
}
/**
* @brief rsa generate sign
*
* This function generate signature.
*
* @param[in] msg msg buff
* @param[in] d d buff
* @param[in] e e buff
* @param[in] n n buff
* @param[in] nbitlen n bit len
* @param[out] out out buff
* @param[in] sign_key_type sign key type
* @param[in] sign_key_id sign key id
* @param[in] mac_buf out buff
* @return CMD_RETURN_SUCCESS or error code.
*/
sdrv_crypto_error_status_e cmd_rsa_generate_signature(
uint8_t *msg, uint8_t *d, uint8_t *e, uint8_t *n,
uint32_t nbitlen, uint8_t *out,
cmd_key_type_e sign_key_type,
uint16_t sign_key_id, uint8_t *mac_buf)
{
uint16_t key_id_array[2];
uint32_t cmd_buf[8] = {0};
uint32_t ret = 0;
cmd_rsa_generate_signature_t *cmd_rsa_sign = NULL;
/*********** sign ***********/
cmd_rsa_sign = (cmd_rsa_generate_signature_t *)cmd_buf;
cmd_rsa_sign->cmd_id = RSA_GENERATE_SIGNATURE;
cmd_rsa_sign->need_high_sec_ver = 0;
set_big_endian_4byte((uint8_t *)cmd_rsa_sign->data_ptr, (uint32_t)msg);
set_big_endian_4byte((uint8_t *)cmd_rsa_sign->e_ptr, (uint32_t)e);
set_big_endian_4byte((uint8_t *)cmd_rsa_sign->signature_ptr, (uint32_t)out);
if (CMD_KEY_EXTERNAL_PLAINTEXT == sign_key_type) {
key_id_array[0] = 0;
} else if (CMD_KEY_EXTERNAL_CIPHERTEXT == sign_key_type) {
key_id_array[0] = sign_key_id;
} else {
return CMD_RETURN_FAIL;
}
set_big_endian_4byte((uint8_t *)cmd_rsa_sign->d_ptr, (uint32_t)d);
set_big_endian_2byte((uint8_t *)cmd_rsa_sign->key_id, key_id_array[0]);
set_big_endian_4byte((uint8_t *)cmd_rsa_sign->n_ptr, (uint32_t)n);
set_big_endian_2byte((uint8_t *)cmd_rsa_sign->n_len, (uint32_t)nbitlen);
set_big_endian_4byte((uint8_t *)cmd_rsa_sign->aut_info_ptr,
(uint32_t)mac_buf);
get_otp_key_aut_mac(key_id_array, 1, (uint8_t *)cmd_buf, mac_buf);
ret = send_cmd_and_wait_response((uint32_t *)cmd_buf);
if (SEIP_SUCCESS == ret) {
printf("sign pass \n");
} else {
printf("sign error, ret = 0x%x \n", ret);
return CMD_RETURN_FAIL;
}
return CMD_RETURN_SUCCESS;
}
/**
* @brief rsa verify signature
*
* This function verify sign
*
* @param[in] msg msg buff
* @param[in] e e buff
* @param[in] n n buff
* @param[in] nbitlen n bit len
* @param[in] sign sign buff
* @return CMD_RETURN_SUCCESS or error code.
*/
sdrv_crypto_error_status_e cmd_rsa_verify_signature(uint8_t *msg,
uint8_t *e,
uint8_t *n,
uint32_t nbitlen,
uint8_t *sign)
{
uint32_t cmd_buf[8] = {0};
uint32_t ret = 0;
cmd_rsa_verify_t *cmd_rsa_verify = NULL;
/*********** verify ***********/
cmd_rsa_verify = (cmd_rsa_verify_t *)cmd_buf;
cmd_rsa_verify->cmd_id = RSA_VERIFY_SIGNATURE;
set_big_endian_4byte((uint8_t *)cmd_rsa_verify->data_ptr, (uint32_t)msg);
set_big_endian_4byte((uint8_t *)cmd_rsa_verify->e_ptr, (uint32_t)e);
set_big_endian_4byte((uint8_t *)cmd_rsa_verify->signature_ptr,
(uint32_t)sign);
set_big_endian_4byte((uint8_t *)cmd_rsa_verify->n_ptr, (uint32_t)n);
set_big_endian_2byte((uint8_t *)cmd_rsa_verify->n_len, (uint32_t)nbitlen);
ret = send_cmd_and_wait_response((uint32_t *)cmd_buf);
if (SEIP_SUCCESS == ret) {
printf("verify pass \n");
} else {
printf("verify error, ret = 0x%x \n", ret);
return CMD_RETURN_FAIL;
}
return CMD_RETURN_SUCCESS;
}
/**
* @brief set prikey ptr
*
* This function set crt prikey
*
* @param[in] p p buff
* @param[in] q q buff
* @param[in] dp dp buff
* @param[in] dq dq buff
* @param[in] u u buff
* @param[in] rsa_crt_pri_key rsa_crt_pri_key buff
* @return CMD_RETURN_SUCCESS or error code.
*/
sdrv_crypto_error_status_e cmd_rsa_set_crt_prikey_ptr(
uint8_t *p, uint8_t *q, uint8_t *dp, uint8_t *dq,
uint8_t *u, rsa_crt_pri_key_ptr_t *rsa_crt_pri_key)
{
set_big_endian_4byte((uint8_t *)rsa_crt_pri_key->p_ptr, (uint32_t)p);
set_big_endian_4byte((uint8_t *)rsa_crt_pri_key->q_ptr, (uint32_t)q);
set_big_endian_4byte((uint8_t *)rsa_crt_pri_key->dp_ptr, (uint32_t)dp);
set_big_endian_4byte((uint8_t *)rsa_crt_pri_key->dq_ptr, (uint32_t)dq);
set_big_endian_4byte((uint8_t *)rsa_crt_pri_key->u_ptr, (uint32_t)u);
return CMD_RETURN_SUCCESS;
}
/**
* @brief rsa generate crt key
*
* This function get crt key.
*
* @param[in] ebitlen e bit len
* @param[in] nbitlen n bit len
* @param[in] generate_key_type out put key type
* @param[in] generate_key_id enc key id
* @param[in] n n buff
* @param[in] e e buff
* @param[in] rsa_crt_pri_key rsa_crt_pri_key buff
* @param[in] mac_buf out buff
* @return CMD_RETURN_SUCCESS or error code.
*/
sdrv_crypto_error_status_e cmd_rsa_generate_crt_key(
uint16_t ebitlen, uint16_t nbitlen, cmd_key_type_e generate_key_type,
uint16_t generate_key_id, uint8_t *n, uint8_t *e,
rsa_crt_pri_key_ptr_t *rsa_crt_pri_key, 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_rsa_generateCRTkey_t *cmd_rsa_get_crt_key = NULL;
/*********** generate key pair ***********/
cmd_rsa_get_crt_key = (cmd_rsa_generateCRTkey_t *)cmd_buf;
cmd_rsa_get_crt_key->cmd_id = RSA_GENERATE_CRT_KEY;
set_big_endian_2byte((uint8_t *)cmd_rsa_get_crt_key->e_len,
(uint32_t)ebitlen);
set_big_endian_2byte((uint8_t *)cmd_rsa_get_crt_key->n_len,
(uint32_t)nbitlen);
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;
}
set_big_endian_2byte((uint8_t *)cmd_rsa_get_crt_key->key_id,
key_id_array[0]);
set_big_endian_4byte((uint8_t *)cmd_rsa_get_crt_key->e_ptr, (uint32_t)e);
set_big_endian_4byte((uint8_t *)cmd_rsa_get_crt_key->n_ptr, (uint32_t)n);
set_big_endian_4byte((uint8_t *)cmd_rsa_get_crt_key->priKey_ptr,
(uint32_t)rsa_crt_pri_key);
set_big_endian_4byte((uint8_t *)cmd_rsa_get_crt_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_RSA_FAIL == ret) {
RetVal = CMD_RETURN_FAIL;
/* retry */
} else {
RetVal = CMD_RETURN_FAIL;
break;
}
count--;
} while (count);
return RetVal;
}
/**
* @brief rsa crt decrypt
*
* This function rsa crt decrypt.
*
* @param[in] msg msg buff
* @param[in] e e buff
* @param[in] n n buff
* @param[in] nbitlen n bit len
* @param[out] out out buff
* @param[in] decrypt_key_type dec key type
* @param[in] decrypt_key_id dec key id
* @param[in] rsa_crt_pri_key rsa_crt_pri_key buff
* @param[in] mac_buf out buff
* @return CMD_RETURN_SUCCESS or error code.
*/
sdrv_crypto_error_status_e cmd_rsa_crt_decrypt(
uint8_t *msg, uint8_t *e, uint8_t *n, uint32_t nbitlen,
uint8_t *out, cmd_key_type_e decrypt_key_type,
uint16_t decrypt_key_id, rsa_crt_pri_key_ptr_t *rsa_crt_pri_key,
uint8_t *mac_buf)
{
uint16_t key_id_array[2];
uint32_t cmd_buf[8] = {0};
uint32_t ret = 0;
cmd_rsa_CRT_decrypt_t *cmd_rsa_crt_dec = NULL;
/*********** decrypt ***********/
cmd_rsa_crt_dec = (cmd_rsa_CRT_decrypt_t *)cmd_buf;
cmd_rsa_crt_dec->cmd_id = RSA_CRT_DECRYPT;
cmd_rsa_crt_dec->need_high_sec_ver = 0;
set_big_endian_4byte((uint8_t *)cmd_rsa_crt_dec->data_ptr, (uint32_t)msg);
set_big_endian_4byte((uint8_t *)cmd_rsa_crt_dec->e_ptr, (uint32_t)e);
set_big_endian_4byte((uint8_t *)cmd_rsa_crt_dec->cipher_ptr, (uint32_t)out);
set_big_endian_4byte((uint8_t *)cmd_rsa_crt_dec->priKey_ptr,
(uint32_t)rsa_crt_pri_key);
set_big_endian_2byte((uint8_t *)cmd_rsa_crt_dec->n_len, (uint32_t)nbitlen);
if (CMD_KEY_EXTERNAL_PLAINTEXT == decrypt_key_type) {
key_id_array[0] = 0;
} else if (CMD_KEY_EXTERNAL_CIPHERTEXT == decrypt_key_type) {
key_id_array[0] = decrypt_key_id;
} else {
return CMD_RETURN_FAIL;
}
set_big_endian_2byte((uint8_t *)cmd_rsa_crt_dec->key_id, key_id_array[0]);
set_big_endian_4byte((uint8_t *)cmd_rsa_crt_dec->aut_info_ptr,
(uint32_t)mac_buf);
get_otp_key_aut_mac(key_id_array, 1, (uint8_t *)cmd_buf, mac_buf);
ret = send_cmd_and_wait_response((uint32_t *)cmd_buf);
if (SEIP_SUCCESS == ret) {
printf("rsa crt dec pass \n");
} else {
printf("rsa crt dec error, ret = 0x%x \n", ret);
return CMD_RETURN_FAIL;
}
return CMD_RETURN_SUCCESS;
}
/**
* @brief rsa crt generate sign
*
* This function rsa crt generate sign
*
* @param[in] msg msg buff
* @param[in] e e buff
* @param[in] n n buff
* @param[in] nbitlen n bit len
* @param[out] out out buff
* @param[in] sign_key_type sign key type
* @param[in] sign_key_id sign key id
* @param[in] rsa_crt_pri_key rsa_crt_pri_key buff
* @param[in] mac_buf out buff
* @return CMD_RETURN_SUCCESS or error code.
*/
sdrv_crypto_error_status_e cmd_rsa_crt_generate_signature(
uint8_t *msg, uint8_t *e, uint8_t *n, uint32_t nbitlen,
uint8_t *out, cmd_key_type_e sign_key_type,
uint16_t sign_key_id, rsa_crt_pri_key_ptr_t *rsa_crt_pri_key,
uint8_t *mac_buf)
{
uint16_t key_id_array[2];
uint32_t cmd_buf[8] = {0};
uint32_t ret = 0;
cmd_rsa_CRT_generate_signature_t *cmd_rsa_crt_sign = NULL;
/*********** sign ***********/
cmd_rsa_crt_sign = (cmd_rsa_CRT_generate_signature_t *)cmd_buf;
cmd_rsa_crt_sign->cmd_id = RSA_CRT_GENERATE_SIGNATURE;
cmd_rsa_crt_sign->need_high_sec_ver = 0;
set_big_endian_4byte((uint8_t *)cmd_rsa_crt_sign->data_ptr, (uint32_t)msg);
set_big_endian_4byte((uint8_t *)cmd_rsa_crt_sign->e_ptr, (uint32_t)e);
set_big_endian_4byte((uint8_t *)cmd_rsa_crt_sign->signature_ptr,
(uint32_t)out);
set_big_endian_4byte((uint8_t *)cmd_rsa_crt_sign->priKey_ptr,
(uint32_t)rsa_crt_pri_key);
set_big_endian_2byte((uint8_t *)cmd_rsa_crt_sign->n_len, (uint32_t)nbitlen);
if (CMD_KEY_EXTERNAL_PLAINTEXT == sign_key_type) {
key_id_array[0] = 0;
} else if (CMD_KEY_EXTERNAL_CIPHERTEXT == sign_key_type) {
key_id_array[0] = sign_key_id;
} else {
return CMD_RETURN_FAIL;
}
set_big_endian_2byte((uint8_t *)cmd_rsa_crt_sign->key_id, key_id_array[0]);
set_big_endian_4byte((uint8_t *)cmd_rsa_crt_sign->aut_info_ptr,
(uint32_t)mac_buf);
get_otp_key_aut_mac(key_id_array, 1, (uint8_t *)cmd_buf, mac_buf);
ret = send_cmd_and_wait_response((uint32_t *)cmd_buf);
if (SEIP_SUCCESS == ret) {
printf("rsa crt sign pass \n");
} else {
printf("rsa crt sign error, ret = 0x%x \n", ret);
return CMD_RETURN_FAIL;
}
return CMD_RETURN_SUCCESS;
}