一文看懂码灵半导体CFW32C7UL系列产品应用(二): 国密算法●下篇
发布时间:2020-07-27
分享到:
CFW32C7UL系列另外两个非常重要的加解密算法:分组加密算法SM4和非对称加密算法SM2。

欢迎再次来到“码灵半导体CFW32C7UL系列产品应用介绍”连载专题。通过上期对CFW32C7UL系列国密算法SM3和真随机数发生器TRNG的介绍,相信您对CFW32C7UL系列国密硬件模块有了更进一步的了解。今天我们继续介绍CFW32C7UL系列另外两个非常重要的加解密算法:分组加密算法SM4和非对称加密算法SM2。那么SM2和SM4国密模块又是如何使用的?它们加解密的速度如何呢?带着这些问题,今天我们详细介绍下CFW32C7UL系列的SM2和SM4模块及其具体使用方法。

 

一、SM4分组算法模块

SM4属于对称加密算法,由国家密码管理局于2012年3月21日发布的无线局域网标准的分组数据算法。顾名思义,对称加密(也叫私钥加密)指加密和解密使用相同密钥的加密算法。对这两个操作使用单个KEY使其成为一个简单的过程,因此称为“对称”。对称加密算法的特点是算法公开、计算量小、加密速度快、加密效率高。与非对称加密算法相比,对称加密的速度要快得多,需要的计算能力更少,在互联网中不需降低互联网速度。意味着,当加密的数据量很大时,对称加密是一个不错的选择。另外同类的对称加密方法还有AES,RC4,DES,3DES,RC5,RC6等。

SM4算法是一个分组算法,该算法的分组长度为128比特,密钥长度为128比特。加密算法与密钥扩展算法都采用32轮非线性迭代结构。解密算法与加密算法的结构相同,只是轮密钥的使用顺序相反,解密轮密钥是加密轮密钥的逆序。在码灵半导体CFW32C7UL系列中SM4算法是通过硬件方式实现的。

下面我们具体介绍下CFW32C7UL 系列SM4算法的使用方法。

开发模式一:裸机SDK

SM4 算法流程图

① 设置SM4密钥接口

void SM4_SetKey(uint32_t *keyin, uint32_t *ivin, uint32_t mode, uint8_t swap_en,uint8_t mask_en)

函数参数

 keyin:128bit密钥指针

 Ivin :CBC工作模式时的初始向量(使用CBC模式需要配置)

 mode :SM4模式选择

  swap_en :SWAP模式使能, 即大小端配置

 mask_en :随机掩码使能

使用范例

SM4_SetKey(key1,iv1_null,SM4_ECB_MODE,SM4_SWAP_DISABLE,SM4_MASK_DISABLE);

使用ECB模式,不使能SWAP模式,不使能随机掩码,key1为密钥,iv1_null 为空

② 加解密接口

void SM4_DRV_CPU(uint32_t *datain, uint32_t *dataout, uint32_t length, uint8_t enc, uint8_t vsm4_en)

函数参数:

 Datain: 数据输入指针

Dataout:数据输出指针

 Length :数据长度(length  =  bit长度 \128)

 Enc: 加密/解密模式

  vsm4_en: 伪SM4运算使能

使用范例

加密过程:

SM4_DRV_CPU (plain, result, 1, SM4_ENCRYPTION, SM4_VSM4_DISABLE);

明文为plain,输出的密文为result, 数据长度为128bit     ,加密模式,不使能伪sm4运算

解密过程:

SM4_DRV_CPU (result, decryp, 1, SM4_DECRYPTION,SM4_VSM4_DISABLE);

输入密文为result,输出的明文为decryp, 数据长度为128bit,解密模式,不使能伪sm4运算

开发模式二:Linux SDK

通过操作linux系统中/dev/wokoo_sm4 ,就可以进行SM4分组加解密算法的运算。

① SM4算法底层接口

open:打开设备节点

read:读取加解密后的数据

write:写入key数据和需要加解密的数据

ioctl:启动加解密操作

② 接口描述

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,其它失败

ioctl:

函数原型:static long uac_ioctl(struct file *file, unsigned int cmd, unsigned long arg)

参数:file:文件名,cmd:控制参数,arg:其它参数

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

③ 使用示例

fd = open("/dev/wokoo_sm4", O_RDWR);                                       打开sm4节点

write(fd, &sm4_data, sizeof(struct sm4_data_t));                    写入明文/密文

ioctl(fd, SM4_DIR_ENCRYPT/ SM4_DIR_DECRYPT, NULL);              选择加密/解密

read(fd, sm4_data.dataout, sizeof(sm4_data.dataout));              读出加密/解密的结果

CFW32C7UL系列 SM4算法的效率

我们通过输入128KB明文数据,执行加解密运算后输出加解密运算结果,并记录下含接口数据传输的芯片工作时长,得到CFW32C7UL系列 SM4算法的效率。

SM4接口加密运算(ECB模式)


SM4
接口解密运算(ECB模式)


可以看到,码灵半导体CFW32C7UL系列的SM4算法效率可以达到64Mbps。

二、SM2公钥算法模块

SM2属于非对称加密算法,是国家密码管理局于2010年12月17日发布的椭圆曲线公钥密码算法。与对称加密方法相反,非对称加密涉及多个密钥,用于数据的加密和解密,是在数学上彼此相关的两个不同的加密密钥,即:公开密钥(简称公钥)和私有密钥(简称私钥)。公钥与私钥是一对,如果用公钥对数据进行加密,只有用对应的私钥才能解密。非对称加密与与对称加密相比,在加密和解密花费的时间更长、速度相对较慢,比较适合对少量数据处理的应用场景。

         SM2算法是基于ECC椭圆曲线算法,CFW32C7UL系列支持硬件PKI,ECC,DIV大数运算,同时SM2算法是通过软件与硬件相结合的方式实现,是一种安全性极高和效率极高的公钥算法。同类算法如:RSA、Elgamal、背包算法、Rabin、D-H、ECC等。

下面我们具体介绍下CFW32C7UL系列 SM2算法的具体使用方法。

开发模式一:裸机SDK

① 产生密钥对函数

GM_GenSM2keypair(uint32_t prikey[],uint32_t *Q_X,uint32_t *Q_Y)

函数参数:

prikey: SM2私钥数据

Q_X  :公钥 X坐标

Q_Y  :公钥 Y坐标

使用范例

GM_GenSM2keypair(prikey,public_keyX,public_keyY);

生成并获取私钥prikey,公钥(public_keyX,public_keyY)

② SM2加密函数

GM_SM2Encrypt(uint32_t *encrydata,  uint32_t *endatalen,uint32_t *plain, uint32_t plainlen, uint32_t *pub_X,uint32_t *pub_Y)

函数参数

 encrydata:密文数据

endatalen:密文长度

plain:明文数据

plainlen:明文长度

pub_X:公钥坐标X

pub_Y:公钥坐标Y

使用范例

GM_SM2Encrypt(&endata[0],&endataLen,plain,plainlen,public_keyX,public_keyY)

使用公钥public_key 加密明文plain,输出密文endata。

 

③ SM2解密函数

GM_SM2Decrypt(uint32_t *DecDate, uint32_t DecDatelen,uint32_t *input , uint32_t inlen,uint32_t *pri_key )

函数参数

 DecDate: 解密出来的明文数据

DecDatelen: 解密出来的明文长度

input: 输入的密文

inlen: 输入的密文长度

pri_key        : 私钥数据

使用范例

 GM_SM2Decrypt(&dedata[0], plainlen, endata, endataLen, prikey);

使用私钥 pricey 解密密文endata 输出明文 dedata。

 

开发模式二:Linux SDK

         通过操作linux系统中/dev/wokoo_sm2 ,可以进行SM2加解密算法的运算。

① SM2算法底层接口

open:打开设备节点

read:读取加解密后的数据或私钥和公钥对

write:写入明文数据

ioctl:设置是加密还是解密操作

② 接口描述

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,其它失败

ioctl:

函数原型:static long uac_ioctl(struct file *file, unsigned int cmd, unsigned long arg)

参数:file:文件名,cmd:控制参数,arg:其它参数

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

③ 使用示例

sm2_fd = open("/dev/wokoo_sm2", O_RDWR);          打开sm2节点

ioctl(sm2_fd, SM2_DIR_KEY, NULL);                                  设置读取私钥和公钥对

read(sm2_fd, &sm2_data.prikey, sizeof(sm2_data.prikey) + sizeof(sm2_data.public_keyX) + sizeof(sm2_data.public_keyY));读取私钥和公钥

write(sm2_fd, &sm2_data.plain, sizeof(sm2_data.plain)); 写入明文/密文

ioctl(sm2_fd, SM2_DIR_ENCRYPT/ SM2_DIR_DECRYPT, NULL);       选择加密/解密

read(sm2_fd, &sm2_data.en_data, 256);                  读取解密/解密结果

         CFW32C7UL 系列SM2算法的效率

 

三、加密算法的选择

由于非对称加密算法的运行速度比对称加密算法的速度慢很多,当需要对大量的数据进行加密时,建议采用对称加密算法,以提高加解密速度。对称加密算法的密钥管理是一个复杂的过程,密钥的管理直接决定着他的安全性,因此当数据量很小时,我们可以考虑采用非对称加密算法。

因对称加密算法不能实现签名,因此签名时使用非对称算法。在实际的操作过程中,我们通常采用的方式是:采用非对称加密算法管理对称算法的密钥,然后用对称加密算法加密数据,这样我们就集成了两类加密算法的优点,既实现了加密速度快的优点,又实现了安全方便管理密钥的优点。

通过以上对CFW32C7UL系列 SM2和SM4算法模块的介绍,相信您对国密模块的使用有更深入的了解。码灵半导体CFW32C7UL系列除了支持国密算法外,同样也支持国际常见的通用加解密算法,如AES和SHA算法,这部分算法也是通过硬件实现。那么它们在CFW32C7UL系列中是如何具体使用呢?让我们带着这些问题,在下期中去探寻吧。