[原创] 【NUCLEO H533RE】ECC384 PKA模块测试

qinyunti   2024-7-13 08:49 楼主

完整的工程间附件,替换\STM32Cube_FW_H5_V1.2.0\Projects\NUCLEO-H533RE\Applications\ThreadX\Tx_Thread_Creation

Tx_Thread_Creation.zip (576.87 KB)
(下载次数: 2, 2024-7-13 08:49 上传)

 

  • 前言

前一篇我们体验了HASH384算法,这一篇继续安全相关加速器的ECC384. PKA模块。测试硬件计算。

  • ECC-384

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

 

 

  • STM32硬件驱动

添加驱动文件

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 

image-20240713084921-1.png  

    

  • 总结

以上测试了PKA加速计算,使用硬件加速计算运算很快,接口也很简单。

 

注意一定要使能HSI48时钟

SystemClock_Config中

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_HSE;

  RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;

 

驱动这里可以优化下,既然依赖于时钟HSI48那么使用对应的驱动时就应该自动使能。

回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复