一文看懂码灵半导体CFW32C7UL系列产品应用(二): 国密算法●中篇

发布时间:2020-07-15
分享到:
上期对CFW32C7UL系列支持的国密算法种类支持的介绍,相信您对CFW327UL系列的国密硬件模块有了些初步了解,那么这些国密模块如何使用?应用是否便捷?加解密的速度如何?带着这些疑问,我们今天从真随机数发生器TRNG和SM3算法模块调用开始谈起。

欢迎再次来到“码灵半导体CFW32C7UL系列产品应用介绍”连载专题。通过上期对CFW32C7UL系列支持的国密算法种类的介绍,相信您对CFW327UL系列的国密硬件模块有了初步了解,那么这些国密模块如何使用?应用是否便捷?加解密的速度如何?带着这些疑问,我们今天从真随机数发生器TRNG和SM3算法模块的调用开始谈起。

一、真随机数发生器TRNG模块

说到随机,有两个必须要搞清楚的概念即“真随机数生成器”(TRNG)和伪随机数生成器(PRNG)。大部分计算机程序和语言中的随机函数,都是伪随机数生成器,它们都是由确定的算法,通过一个“种子”(如“时间”)来产生“看起来随机”的结果值。毫无疑问,只要知道算法和种子,或者是之前已经产生了的随机数,那么就有可能获得接下来随机数序列的信息,因此它们带有可预测性。这种可预测性在密码学上并不安全,所以我们称其为“伪随机”。

与“伪随机”相对应的是“真随机”,真正的随机数仅存在于量子力学中,而我们需要的是一种不可预测的、统计意义上的、高安全性的随机数。在码灵半导体CFW32C7UL系列产品中我们提供了四组这种真随机数源,用以产生真随机数,同时该功能模块是采用硬件方式实现的,并且通过了NIST统计检测程序的随机性测试。

下面我们具体介绍下CFW32C7UL系列产品的真随机数发生器TRNG模块是如何通过码灵半导体官方提供的SDK函数来进行调用的。目前码灵半导体官方提供了两种SDK,即裸机SDK和Linux SDK。

开发模式一:裸机SDK

裸机SDK与提供的freeRTOS和uCOS SDK中相同。

① 产生一个真随机数

调用HAL_TRNG_GetValue()

uint32_t HAL_TRNG_GetValue() 函数返回值为一个真随机数

② 使用范例

uint32_t random = HAL_TRNG_GetValue();

单个函数看不出硬件实现和软件实现有什么不同,那下面展现一下函数源码:

uint32_t HAL_HRNG_GetValue()

{

  uint32_t ret;

  HRNG->CMPRES = 0x02;

  HRNG->CTRL |= (HRNG_CTRL_RNG_EN0 | HRNG_CTRL_RNG_EN1 | HRNG_CTRL_RNG_EN2 | HRNG_CTRL_RNG_EN3 | HRNG_CTRL_SCLK_SEL);

  while((HRNG->STATUS& HRNG_STATUS_FIFO_NOT_EMPTY) ==0);

  ret= HRNG->LFSR;

  return ret;

}

上面所述的就是对寄存器HRNG->CMPRE、HRNG->CTRL进行一个配置后,等待HRNG->STATUS,之后HRNG->LFSR寄存器中取出随机数。

开发模式二:Linux SDK

通过操作linux系统中/dev/wokoo_trng,就可以进行产生真随机数。

① TRNG算法底层接口

• open:打开设备节点

• read:读取随机数的数据

② 接口描述

• open

函数原型:static int uac_open(struct inode *inode, struct file * file)

参数:file:文件名

返回值:成功0,其它失败

• read

函数原型:static ssize_t uac_read(struct file * file, char __user *buffer, size_t size , loff_t *p)

参数:file:文件名,buffer:读出数据缓存,size:读出数据长度

返回值:成功0,其它失败

③ 使用示例

trng_fd = open("/dev/wokoo_trng", O_RDWR);             //打开trng的节点

read(trng_fd, (unsigned char *)&trng_data, 1);               //读取真随机数

CFW32C7UL系列的TRNG效率

    目前码灵半导体CFW32C7UL系列产品产生随机数的速率是75kb/s,每秒可以产生75kb的真随机数。

二、SM3杂凑硬件算法模块

SM3算法为国密杂凑算法,数据分组长度为512bit,杂凑值长度为256bit。基本运算流程为:对输入数据流做填充,构成整数个512bit长度的数据流;再对数据做分组;然后对每个分组做扩展和替换压缩操作,得到中间的临时杂凑值,反复进行直到所有分组处理完毕,最后一个计算得到的杂凑值作为整个数据流的最终杂凑值输出。

开发模式一:裸机SDK

调用SM3_Hash产生SM3 最终hash 值。

void SM3_Hash(uint32_t *pDataIn,uint32_t DataLen,uint32_t *pDigest)

① 函数参数说明

  pDataIn: 输入的数据指针( big endian)

  DataLen :数据的bit 长度

  pDigest: 输出的最终hash值

② 使用范例

SM3_Hash (message,32,tempbuf);

//message 是原始数据,数据长度为32,tempbuf是产生的256位hash值

开发模式二:Linux SDK

      通过操作linux系统中/dev/wokoo_sm3 ,就可以进行SM3杂凑算法的运算。

① SM3算法底层接口

• open:打开设备节点

• read:读取加密后的数据

• write:写入加密的数据

② 接口描述

• Open

函数原型: static int uac_open(struct inode *inode, struct file * file)

参数:file:文件名

返回值:成功0,其它失败

• Read

函数原型:static ssize_t uac_read(struct file * file, char __user *buffer, size_t size , loff_t *p)

参数:file:文件名,buffer:读出数据缓存,size:读出数据长度

返回值:成功0,其它失败

• Write

函数原型: static ssize_t uac_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)

参数:file:文件名,buf:写入数据缓存,count:写入数据长度

返回值:成功0,其它失败

使用示例

  sm3_fd = open("/dev/wokoo_sm3", O_RDWR);                     //打开sm3节点

  write(sm3_fd, &sm3_data.datain, sm3_data.datalen);  //写入需杂凑的数据

  read(sm3_fd, &sm3_data.dataout, NULL);                               //读出杂凑完的结果

CFW32C7UL系列SM3算法的效率

通过输入128KB数据,完成杂凑运算后输出运算结果,统计时间如下图



目前码灵半导体CFW32C7UL系列产品可以实现45Mbps的杂凑速率。

通过以上对CFW32C7UL系列产品的真随机数发生器TRNG和SM3算法模块的介绍,相信大家对国密模块的如何使用有了初步了解,那么SM2和SM4算法在CFW32C7UL系列产品中如何具体使用呢?让我们带着这些问题,在下期中继续探寻吧。

今天的专题就到这儿,更多关于码灵半导体CFW32C7UL系列产品的介绍,我们下期见!