完整的工程间附件,替换\STM32Cube_FW_H5_V1.2.0\Projects\NUCLEO-H533RE\Applications\ThreadX\Tx_Thread_Creation
前一篇我们体验了HASH384算法,这一篇继续安全相关加速器的ECC384. PKA模块。测试硬件计算。
ECC384原理见https://www.rfc-editor.org/rfc/rfc5639
https://wiki.openssl.org/index.php/Elliptic_Curve_Cryptography
参考英飞凌的
micro-ecc项目
https://github.com/kmackay/micro-ecc
git clone https://github.com/kmackay/micro-ecc
添加驱动文件
stm32h5xx_hal_pka.c
stm32h5xx_hal_rng_ex.c
stm32h5xx_hal_rng.c
stm32h5xx_hal_conf.h中取消注释
#define HAL_PKA_MODULE_ENABLED
#define HAL_RNG_MODULE_ENABLED
MSP初始化 PKA和RNG
/**
* @brief PKA MSP Initialization
* This function configures the hardware resources used in this example
* @param hpka: PKA handle pointer
* @retval None
*/
void HAL_PKA_MspInit(PKA_HandleTypeDef* hpka)
{
if(hpka->Instance==PKA)
{
/* USER CODE BEGIN PKA_MspInit 0 */
/* USER CODE END PKA_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_PKA_CLK_ENABLE();
/* USER CODE BEGIN PKA_MspInit 1 */
/* USER CODE END PKA_MspInit 1 */
}
}
/**
* @brief PKA MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param hpka: PKA handle pointer
* @retval None
*/
void HAL_PKA_MspDeInit(PKA_HandleTypeDef* hpka)
{
if(hpka->Instance==PKA)
{
/* USER CODE BEGIN PKA_MspDeInit 0 */
/* Enable PKA reset state */
__HAL_RCC_PKA_FORCE_RESET();
/* Release PKA from reset state */
__HAL_RCC_PKA_RELEASE_RESET();
/* USER CODE END PKA_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_PKA_CLK_DISABLE();
/* USER CODE BEGIN PKA_MspDeInit 1 */
/* USER CODE END PKA_MspDeInit 1 */
}
}
/**
* @brief RNG MSP Initialization
* This function configures the hardware resources used in this example
* @param hrng: RNG handle pointer
* @retval None
*/
void HAL_RNG_MspInit(RNG_HandleTypeDef* hrng)
{
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
if(hrng->Instance==RNG)
{
/* USER CODE BEGIN RNG_MspInit 0 */
/* USER CODE END RNG_MspInit 0 */
/** Initializes the peripherals clock
*/
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RNG;
PeriphClkInitStruct.RngClockSelection = RCC_RNGCLKSOURCE_HSI48;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
/* Peripheral clock enable */
__HAL_RCC_RNG_CLK_ENABLE();
/* RNG interrupt Init */
HAL_NVIC_SetPriority(RNG_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(RNG_IRQn);
/* USER CODE BEGIN RNG_MspInit 1 */
/* USER CODE END RNG_MspInit 1 */
}
}
/**
* @brief RNG MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param hrng: RNG handle pointer
* @retval None
*/
void HAL_RNG_MspDeInit(RNG_HandleTypeDef* hrng)
{
if(hrng->Instance==RNG)
{
/* USER CODE BEGIN RNG_MspDeInit 0 */
/* USER CODE END RNG_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_RNG_CLK_DISABLE();
/* RNG interrupt DeInit */
HAL_NVIC_DisableIRQ(RNG_IRQn);
/* USER CODE BEGIN RNG_MspDeInit 1 */
/* USER CODE END RNG_MspDeInit 1 */
}
}
PKA_HandleTypeDef hpka;
RNG_HandleTypeDef hrng;
RNG初始化
hrng.Instance = RNG;
hrng.Init.ClockErrorDetection = RNG_CED_ENABLE;
if (HAL_RNG_Init(&hrng) != HAL_OK)
{
Error_Handler();
}
PKA初始化
hpka.Instance = PKA;
if (HAL_PKA_Init(&hpka) != HAL_OK)
{
Error_Handler();
}
计算
PKA_ECDSASignInTypeDef in = {0};
PKA_ECDSASignOutTypeDef out = {0};
/* Set input parameters */
in.primeOrderSize = prime256v1_Order_len;
in.modulusSize = prime256v1_Prime_len;
in.coefSign = prime256v1_A_sign;
in.coef = prime256v1_absA;
in.coefB = prime256v1_B;
in.modulus = prime256v1_Prime;
in.basePointX = prime256v1_GeneratorX;
in.basePointY = prime256v1_GeneratorY;
in.primeOrder = prime256v1_Order;
in.integer = SigGen_k;
in.hash = SigGen_Hash_Msg;
in.privateKey = SigGen_d;
/* Launch the verification */
if(HAL_PKA_ECDSASign(&hpka, &in, 5000) != HAL_OK)
{
Error_Handler();
}
/* Allocate required space */
out.RSign = malloc(prime256v1_Order_len);
out.SSign = malloc(prime256v1_Order_len);
if(out.RSign == NULL || out.SSign == NULL)
{
/* Not enough memory in heap */
Error_Handler();
}
/* Copy the result to allocated space */
HAL_PKA_ECDSASign_GetResult(&hpka , &out, NULL);
/* Compare to expected result */
if (memcmp(out.RSign, SigGen_R, SigGen_R_len) != 0)
{
Error_Handler();
}
if (memcmp(out.SSign, SigGen_S, SigGen_S_len) != 0)
{
Error_Handler();
}
/* Deinitialize the PKA */
if(HAL_PKA_DeInit(&hpka) != HAL_OK)
{
Error_Handler();
}
中断处理
extern RNG_HandleTypeDef hrng;
/**
* @brief This function handles RNG global interrupt.
*/
void RNG_IRQHandler(void)
{
/* USER CODE BEGIN RNG_IRQn 0 */
/* USER CODE END RNG_IRQn 0 */
HAL_RNG_IRQHandler(&hrng);
/* USER CODE BEGIN RNG_IRQn 1 */
/* USER CODE END RNG_IRQn 1 */
}
shell_func.c中
#include "prime256v1.c"
#include "SigGen.c"
申明实现函数
static void hw_pkatest_func(uint8_t* param);
新增命令用于计算
{ (uint8_t*)"hw_pkatest", hw_pkatest_func, (uint8_t*)"hw_pkatest testtimes"},
实现如下
PKA_HandleTypeDef hpka;
RNG_HandleTypeDef hrng;
PKA_ECDSASignInTypeDef in = {0};
PKA_ECDSASignOutTypeDef out = {0};
static void hw_pkatest_func(uint8_t* param)
{
uint8_t outRSign[32];
uint8_t outSSign[32];
hrng.Instance = RNG;
hrng.Init.ClockErrorDetection = RNG_CED_ENABLE;
if (HAL_RNG_Init(&hrng) != HAL_OK)
{
}
hpka.Instance = PKA;
if (HAL_PKA_Init(&hpka) != HAL_OK)
{
}
/* Set input parameters */
in.primeOrderSize = prime256v1_Order_len;
in.modulusSize = prime256v1_Prime_len;
in.coefSign = prime256v1_A_sign;
in.coef = prime256v1_absA;
in.coefB = prime256v1_B;
in.modulus = prime256v1_Prime;
in.basePointX = prime256v1_GeneratorX;
in.basePointY = prime256v1_GeneratorY;
in.primeOrder = prime256v1_Order;
in.integer = SigGen_k;
in.hash = SigGen_Hash_Msg;
in.privateKey = SigGen_d;
/* Launch the verification */
if(HAL_PKA_ECDSASign(&hpka, &in, 5000) != HAL_OK)
{
}
/* Allocate required space */
//out.RSign = malloc(prime256v1_Order_len);
//out.SSign = malloc(prime256v1_Order_len);
out.RSign = outRSign;
out.SSign = outSSign;
if(out.RSign == NULL || out.SSign == NULL)
{
/* Not enough memory in heap */
}
/* Copy the result to allocated space */
HAL_PKA_ECDSASign_GetResult(&hpka , &out, NULL);
/* Compare to expected result */
if (memcmp(out.RSign, SigGen_R, SigGen_R_len) != 0)
{
xprintf("test RSign err\r\n");
}
else
{
xprintf("test RSign ok\r\n");
}
if (memcmp(out.SSign, SigGen_S, SigGen_S_len) != 0)
{
xprintf("test SSign err\r\n");
}
else
{
xprintf("test SSign ok\r\n");
}
/* Deinitialize the PKA */
if(HAL_PKA_DeInit(&hpka) != HAL_OK)
{
}
if(HAL_RNG_DeInit(&hrng) != HAL_OK)
{
}
}
测试如下
hw_pkatest
以上测试了PKA加速计算,使用硬件加速计算运算很快,接口也很简单。
注意一定要使能HSI48时钟
SystemClock_Config中
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
驱动这里可以优化下,既然依赖于时钟HSI48那么使用对应的驱动时就应该自动使能。