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