1.介绍
SCE部件作为飞腾平台的平安组件,提供了对称算法加速器(SCA)、哈希算法加速器(HASH)、非对称算法加速器(ACA)和真随机数生成器(TRNG)。
用户通过Linux Kernel Crypto API框架实现内核对各种算法驱动的反对,目前内核态已实现SCA、HASH、TRNG反对的算法驱动。通过装置SCE内核层驱动可查看已反对的算法驱动,利用开发者可通过相应的内核态接口实现对算法模块的调用。
2.装置与测试
2.1硬件及零碎要求
硬件要求如下表所示。
我的项目 | 阐明 |
---|---|
CPU | 飞腾平台CPU |
已支持系统 | 1、Ubuntu 22.04(kernel 4.19.0) |
存储 | 无要求 |
内存 | 无要求 |
2.2软件目录架构
软件目录架构如图所示:
1.src文件夹:驱动模块源码。
2.include文件夹:驱动模块头文件。
3.test文件夹:内核层驱动测试代码。
2.3内核驱动算法概述
目前反对的内核态驱动算法如下表所示。
加速器 | 算法 | 算法名 | 驱动名 |
---|---|---|---|
对称引擎 | SM4 | ecb(sm4) cbc(sm4) ctr(sm4) ofb(sm4) | ecb(sm4)-phytium cbc(sm4)phytium ctr(sm4)-phytium ofb(sm4)-phytium |
对称引擎 | AES | ecb(aes) cbc(aes) ctr(aes) ofb(aes) | ecb(aes)-phytium cbc(aes)phytium ctr(aes)-phytium ofb(aes)-phytium |
对称引擎 | DES | ecb(des) cbc(des) ctr(des) ofb(des) ecb(des3_ede) cbc(des3_ede) ctr(des3_ede) ofb(des3_ede) | ecb(aes)-phytium cbc(aes)phytium ctr(aes)-phytium ofb(aes)-phytium ecb(des3_ede)-phytium cbc(des3_ede)-phytium ctr(des3_ede)-phytium ofb(des3_ede)-phytium |
哈希引擎 | DES | ecb(des) cbc(des) ctr(des) ofb(des) ecb(des3_ede) cbc(des3_ede) ctr(des3_ede) ofb(des3_ede) | ecb(des)-phytium cbc(des)-phytium ctr(des)-phytium ofb(des)-phytium ecb(des3_ede)-phytium cbc(des3_ede)-phytium ctr(des3_ede)-phytium ofb(des3_ede)-phytium |
哈希引擎 | SHA | sha1 sha224 sha256 sha384 sha512 md5 hmac(sha1) hmac(sha224) hmac(sha256) hmac(sha384) hmac(sha512) hmac(md5) | sha1-phytium sha224-phytium sha256-phytium sha384-phytium sha512-phytium md5-phytium hmac(sha1)-phytium hmac(sha224)-phytium hmac(sha256)-phytium hmac(sha384)-phytium hmac(sha512)-phytium hmac(md5)-phytium |
哈希引擎 | SM3 | sm3 hmac(sm3) | sm3-phytium hmac(sm3)-phytium |
真随机数生成器 | TRNG | TRNG | trng-phytium |
2.4内核层编译、装置与测试
1.SCE内核层内核驱动编译装置步骤
进入驱动代码目录cd driver# 编译驱动模块make# 加载驱动模块sudo insmod phytium_sce.ko# 抉择应用内核层驱动模块# 驱动模块反对用户态和内核态切换# 通过操作/proc/sce_dir/sce_work_state管制# 输出1启用内核态模块,输出2启用用户态模块,输出0敞开所有模块sudo echo 1 > /proc/sce_dir/sce_work_state# 查看驱动模块以后模式cat /proc/sce_dir/sce_work_state# 查看内核反对的SCE算法驱动cat /proc/crypto | grep phytium
2.SCE内核态接口编译装置
#进入内核态测试代码目录cd driver/test# 编译测试模块make# 在执行mtest.ko前必须先加载好内核驱动模块# 执行mtest.ko时通过传入参数可反对对不同算法进行功能性测试# 倡议关上两个终端窗口A和B,其中可在A终端输出测试命令,B终端执行命令“sudo dmesg -w”sudo insmod mtest.ko #当在终端A执行该命令之后,可在终端B查到到内核打印信息,其中表明须要传入的参数信息#示例命令,对hash进行功能测试sudo insmod mtest.ko alg=sm3 mode=hash
3 SCE内核态API阐明
该章节介绍SCE内核态API接口,接口的应用示例可浏览参考kernel/test目录下的测试用例。
3.1哈希算法
3.1.1调配哈希算法对象
函数原型 | struct crypto_ahash *crypto_alloc_ahash(const char *alg_name, u32 type, u32 mask) |
函数性能 | 调配一个新创建的异步哈希算法实例 |
输出阐明 | alg_name - 算法名 type - 算法类型 mask - 算法类型屏蔽字 |
输入阐明 | 无 |
返回值阐明 | 新创建的异步哈希算法对象 |
应用阐明 | |
注意事项 | hash算法能够是同步形式实现或异步形式实现,但算法利用不关注hash算法的实现形式,而是关注hash算法提供的算法接口。为实现对立治理,加密框架默认hash算法的实现形式为异步形式,将哈希算法的内部接口对立定义为异步哈希算法接口 |
3.1.2调配哈希算法数据申请对象
函数原型 | struct ahash_request *ahash_request_alloc(struct crypto_ahash *tfm, gfp_t gfp) |
函数性能 | 调配申请数据结构 |
输出阐明 | tfm - 算法实例 gfp - API调用传递给kmalloc的内存调配标记 |
输入阐明 | 无 |
返回值阐明 | 胜利时返回调配的申请句柄,如果内存不足则返回NULL |
应用阐明 | |
注意事项 | 若为同步调用的形式,则不须要调配创立req对象 |
3.1.3设置异步回调
函数原型 | void ahash_request_set_callback(struct ahash_request *req, u32 flags,crypto_completion_t compl, void *data) |
函数性能 | 用于设置加解密实现后须要调用的回调函数 |
输出阐明 | req - 申请句柄 flags -标记位,指定为0或ORing compl -注册到申请句柄的回调函数指针 data - 指向内核加密API不应用的内存 |
输入阐明 | 无 |
返回值阐明 | 无 |
应用阐明 | |
注意事项 |
3.1.4设置密钥
函数原型 | int crypto_ahash_setkey(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen) |
函数性能 | 设置密钥 |
输出阐明 | tfm - 算法实例 key - 密钥数据 keylen - 密钥数据长度 |
输入阐明 | 无 |
返回值阐明 | 胜利时返回调配的申请句柄,如果内存不足则返回NULL |
应用阐明 | |
注意事项 |
3.1.5设置数据
函数原型 | void ahash_request_set_crypt(struct ahash_request *req, struct scatterlist *src, u8 *result, unsigned int nbytes) |
函数性能 | 设置数据内存 |
输出阐明 | req - 申请句柄 src - 源扩散/收集列表 result - 由音讯摘要填充的缓冲区 nbytes - 从@src解决的字节数 |
输入阐明 | 无 |
返回值阐明 | 无 |
应用阐明 | |
注意事项 |
3.1.6性能接口
函数原型 | int crypto_ahash_init(struct ahash_request *req) int crypto_ahash_digest(struct ahash_request *req) int crypto_ahash_update(struct ahash_request *req) int crypto_ahash_finup(struct ahash_request *req) int crypto_ahash_final(struct ahash_request *req) |
函数性能 | init:初始化音讯摘要 digest:计算缓冲区的音讯摘要 update:向音讯摘要中增加数据以进行解决 finup:更新和实现音讯摘要 final:计算音讯摘要 |
输出阐明 | req - ahash_request句柄 |
输入阐明 | 无 |
返回值阐明 | 胜利计算音讯摘要返回0,非0为 失败 |
应用阐明 | hash算法最终摘要值生成接口能够有多种调用形式,如crypto_ahash_digest示意在该接口中会实现生成摘要相干的所有流程。当然该操作也可拆分为init、update、final或init、update、finup类型的步骤,步骤拆分当前就能够反对在init之后执行屡次update,以间断为hash操作提供数据,并在数据更新实现后调用final操作获取所有数据的最终hash值 |
注意事项 |
3.1.7开释req资源
函数原型 | void ahash_request_free(struct ahash_request *req) |
函数性能 | 开释req资源 |
输出阐明 | req - ahash_request句柄 |
输入阐明 | 无 |
返回值阐明 | 无 |
应用阐明 | |
注意事项 |
3.1.8开释tfm资源
函数原型 | void crypto_free_ahash(struct crypto_ahash *tfm) |
函数性能 | 开释tfm资源 |
输出阐明 | tfm -算法实例 |
输入阐明 | 无 |
返回值阐明 | 无 |
应用阐明 | |
注意事项 |
3.2对称算法
3.2.1调配对称算法对象
函数原型 | struct crypto_skcipher *crypto_alloc_skcipher(const char *alg_name, u32 type, u32 mask) |
函数性能 | 调配一个新创建的对称算法实例 |
输出阐明 | alg_name - 算法名 type - 算法类型 mask - 算法类型屏蔽字 |
输入阐明 | 无 |
返回值阐明 | 新创建的算法实例 |
应用阐明 | |
注意事项 |
3.2.2调配对称算法数据申请对象
函数原型 | struct skcipher_request *skcipher_request_alloc(struct crypto_skcipher *tfm, gfp_t gfp) |
函数性能 | 调配req |
输出阐明 | tfm - 算法实例 gfp - API调用传递给kmalloc的内存调配标记 |
输入阐明 | 无 |
返回值阐明 | 胜利时返回调配的申请句柄,如果内存不足则返回NULL |
应用阐明 | |
注意事项 |
3.2.3设置异步回调
函数原型 | void skcipher_request_set_callback(struct skcipher_request *req, u32 flags, crypto_completion_t compl, void *data) |
函数性能 | 用于设置加解密实现后须要调用的回调函数 |
输出阐明 | req - 申请句柄 flags -标记位,指定为0或ORing compl -注册到申请句柄的回调函数指针 data - 指向内核加密API不应用的内存 |
输入阐明 | 无 |
返回值阐明 | 无 |
应用阐明 | |
注意事项 |
3.2.4设置密钥
函数原型 | int crypto_skcipher_setkey(struct crypto_skcipher *tfm, const u8 *key, unsigned int keylen) |
函数性能 | 设置密钥 |
输出阐明 | tfm - 算法实例 key - 密钥数据 keylen - 密钥数据长度 |
输入阐明 | 无 |
返回值阐明 | 胜利时返回调配的申请句柄,如果内存不足则返回NULL |
应用阐明 | |
注意事项 |
3.2.5设置数据
函数原型 | void skcipher_request_set_crypt(struct skcipher_request *req, struct scatterlist *src, struct scatterlist *dst, unsigned int cryptlen, void *iv) |
函数性能 | 设置数据内存 |
输出阐明 | req - 申请句柄 src - 源扩散/收集列表 dst - 指标扩散/收集列表 cryptlen - 从@src解决的字节数 iv - IV数据,必须合乎crypto_skcipher_ivsize定义的IV大小 |
输入阐明 | 无 |
返回值阐明 | 无 |
应用阐明 | |
注意事项 |
3.2.6加密
函数原型 | int crypto_skcipher_encrypt(struct skcipher_request *req) |
函数性能 | 加密流程 |
输出阐明 | req - 申请句柄 |
输入阐明 | 无 |
返回值阐明 | 胜利加密返回0,非0为失败 |
应用阐明 | |
注意事项 |
3.2.7解密
函数原型 | int crypto_skcipher_decrypt(struct skcipher_request *req) |
函数性能 | 解密流程 |
输出阐明 | req - 申请句柄 |
输入阐明 | 无 |
返回值阐明 | 胜利解密返回0,非0为失败 |
应用阐明 | |
注意事项 |
3.2.8开释req资源
函数原型 | void skcipher_request_free(struct skcipher_request *req) |
函数性能 | 开释req资源 |
输出阐明 | req - 申请句柄 |
输入阐明 | 无 |
返回值阐明 | 无 |
应用阐明 | |
注意事项 |
3.2.9开释tfm资源
函数原型 | void crypto_free_skcipher(struct crypto_skcipher *tfm) |
函数性能 | 开释tfm资源 |
输出阐明 | tfm -算法实例 |
输入阐明 | 无 |
返回值阐明 | 无 |
应用阐明 | |
注意事项 |
3.3真随机数生成器
3.3.1调配真随机数生成器对象
函数原型 | struct crypto_rng *crypto_alloc_rng(const char *alg_name, u32 type, u32 mask) |
函数性能 | 调配一个新创建的TRNG实例 |
输出阐明 | alg_name - 算法名 type - 算法类型 mask - 算法类型屏蔽字 |
输入阐明 | 无 |
返回值阐明 | 新创建的算法实例 |
应用阐明 | |
注意事项 |
3.3.2获取随机数
函数原型 | int crypto_rng_get_bytes(struct crypto_rng *tfm, u8 *rdata, unsigned int dlen) |
函数性能 | 获取随机数 |
输出阐明 | tfm - 算法实例 rdata - 保留随机数的输入缓冲区 dlen - 输入缓冲区的长度 |
输入阐明 | 无 |
返回值阐明 | 0为胜利,非0为失败 |
应用阐明 | |
注意事项 |
3.3.3开释tfm资源
函数原型 | void crypto_free_rng(struct crypto_rng *tfm) |
函数性能 | 开释tfm资源 |
输出阐明 | tfm -算法实例 |
输入阐明 | 无 |
返回值阐明 | 无 |
应用阐明 | |
注意事项 |
4 算法应用示例
4.1哈希算法应用示例
4.1.1定义构造
定义多个构造体变量,其中:
struct crypto_wait:异步操作期待对象
struct ahash_request:异步操作申请对象
struct crypto_ahash:哈希算法对象(上下文)
struct scatterlist:用来保留加/解密缓冲区的构造
struct crypto_wait wait; struct ahash_request *req; struct crypto_ahash *tfm; struct scatterlist *sg = NULL;
4.1.2申请内存
申请明文(src)和哈希值(dst)的数据内存空间。
src = kmalloc(1024 + 512, GFP_KERNEL); if (src == NULL) { printk(KERN_ERR"%s:kmalloc failed!\n", __func__); return; } dst = src+1024;
4.1.3调配算法对象
通过传入的算法名alg和内核接口crypto_alloc_ahash调配算法名对应的算法对象,反对的算法对象能够通过在/proc/crypto文件中查看。
tfm = crypto_alloc_ahash(alg, 0, 0); if (IS_ERR(tfm)) { printk(KERN_ERR"failed to load transform for %s: %ld\n", alg, PTR_ERR(tfm)); return; }
4.1.4调配算法数据申请对象
调配request异步操作期待对象。
req = ahash_request_alloc(tfm, GFP_KERNEL); if (!req) { printk(KERN_INFO"ahash: Failed to allocate request for %s\n", alg); goto fail; }
4.1.5设置上下文
设置上下文,通过ahash_request_set_callback接口给异步申请对象设置回调函数,负责唤醒实现量相干的的回调传给加解密函数,以使其能在实现后唤醒对应线程。通过crypto_ahash_setkey接口为hash算法设置密钥。通过ahash_request_set_crypt接口设置生成哈希值操作相干参数,如源数据sg指针、填充音讯哈希值的缓冲区以及数据长度信息。
crypto_init_wait(&wait); ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, crypto_req_done, &wait); if (key && klen) crypto_ahash_setkey(tfm, key, klen); if (len) { sg = kmalloc(sizeof(struct scatterlist) * len, GFP_KERNEL); if (sg == NULL) { printk(KERN_ERR"%s:kmalloc sg failed!\n", __func__); goto fail1; } sg_init_table(sg, len); for (i = 0; i < len; i ++) { sg_set_buf(sg + i, data + i, 1); } } ahash_request_set_crypt(req, sg, out, len);
4.1.6进行digest摘要操作
ret = crypto_wait_req(crypto_ahash_digest(req), &wait); if (ret) { printk(KERN_ERR"hashing failed ret=%d\n", ret); }
4.1.7开释对象
ahash_request_free(req); crypto_free_ahash(tfm);
4.2对称算法应用示例
定义多个构造体变量,其中:
struct crypto_wait:异步操作期待对象
struct skcipher_request:对称密钥异步操作申请对象
struct crypto_skcipher:加密算法对象(上下文)
struct scatterlist:用来保留加/解密缓冲区的构造
struct crypto_wait wait;struct skcipher_request *req;struct crypto_skcipher *tfm;struct scatterlist *ssg = NULL, *dsg = NULL;
4.2.2申请内存
申请明文(src)、密文(dst)、密钥(key)和IV(iv)等数据内存空间。
src = kmalloc(1024 * 3, GFP_KERNEL); if (src == NULL) { printk(KERN_ERR"%s:kmalloc failed!\n", __func__); return; } memset(src, 0, 1024*3); dst = src + 1024; key = dst + 1024; iv = key + 512;
4.2.3调配算法对象
通过传入的算法名alg和内核接口crypto_alloc_skcipher调配算法名对应的算法对象,反对的算法对象能够通过在/proc/crypto文件中查看。
tfm = crypto_alloc_skcipher(alg, 0, 0); if (IS_ERR(tfm)) { printk(KERN_ERR"failed to load transform for %s: %ld\n", alg, PTR_ERR(tfm)); return; }
4.2.4调配算法数据申请对象
调配request异步操作期待对象。
req = skcipher_request_alloc(tfm, GFP_KERNEL); if (!req) { printk(KERN_INFO"skcipher: Failed to allocate request for %s\n", alg); goto fail; }
4.2.5设置上下文
设置上下文,通过 skcipher_request_set_callback接口给异步申请对象设置回调函数,负责唤醒实现量相干的的回调传给加解密函数,以使其能在实现后唤醒对应线程。通过crypto_skcipher_setkey接口为skcipher算法设置密钥。通过skcipher_request_set_crypt接口设置加解密操作相干参数,如源数据、目标数据sg指针、iv指针以及数据长度信息。
crypto_init_wait(&wait); skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, crypto_req_done, &wait); crypto_skcipher_clear_flags(tfm, ~0); crypto_skcipher_setkey(tfm, key, klen); ssg = kmalloc(sizeof(struct scatterlist) * len, GFP_KERNEL); if (ssg == NULL) { printk(KERN_ERR"%s:kmalloc ssg failed!\n", __func__); goto fail1; } sg_init_table(ssg, len); for (i = 0; i < len; i ++) { sg_set_buf(ssg + i, data + i, 1); } dsg = kmalloc(sizeof(struct scatterlist) * len, GFP_KERNEL); if (dsg == NULL) { printk(KERN_ERR"%s:kmalloc dsg failed!\n", __func__); goto fail2; } sg_init_table(dsg, len); for (i = 0; i < len; i ++) { sg_set_buf(dsg + i, out + i, 1); } skcipher_request_set_crypt(req, ssg, dsg, len, iv);
4.2.6实现加/解密
通过crypto_skcipher_encrypt接口执行理论的加密流程。
通过crypto_skcipher_decrypt接口执行理论的解密流程。
if (enc) ret = crypto_wait_req(crypto_skcipher_encrypt(req), &wait); else ret = crypto_wait_req(crypto_skcipher_decrypt(req), &wait); if (ret) { printk(KERN_ERR"failed ret=%d\n", ret); }
4.2.7开释对象
skcipher_request_free(req); crypto_free_skcipher(tfm);
4.3真随机数生成器应用示例
4.3.1定义构造
定义多个构造体变量,其中:
struct crypto_rng:随机数算法对象(上下文)
struct crypto_rng *tfm;
4.3.2调配算法对象
通过传入的算法名alg和内核接口crypto_alloc_rng调配算法名对应的算法对象,反对的算法对象能够通过在/proc/crypto文件中查看。
tfm = crypto_alloc_rng("trng", 0, 0); if (IS_ERR(tfm)) { printk(KERN_ERR "alg: cprng: Failed to load transform for %s: ""%ld\n", "trng", PTR_ERR(tfm)); return; }
4.3.3获取随机数
err = crypto_rng_get_bytes(tfm, buf, len); if(err) { printk(KERN_ERR"generate len %d error", len); break; }
4.3.4开释对象
crypto_free_rng(tfm);
5 术语和缩略语
术语 | 全称 | 解释 |
---|---|---|
ACA | Asymmetric Cryptography Accelerator | 非对称明码加速器 |
SCA | Symmetric Cryptography Accelerator | 对称明码加速器 |
TRNG | True Random Number Generator | 真随机数发生器 |
6 常见问题
无
版权所有。飞腾信息技术有限公司 2023。保留所有权力。
未经本公司批准,任何单位、公司或集体不得擅自复制,翻译,摘抄本文档内容的局部或全副,不得以任何形式或路径进行流传和宣传。
商标申明
Phytium和其余飞腾商标均为飞腾信息技术有限公司的商标。
本文档提及的其余所有商标或注册商标,由各自的所有人领有。
留神
本文档的内容视为飞腾的窃密信息,您该当严格遵守窃密工作;未经飞腾当时书面批准,您不得向任何第三方披露本文档内容或提供给任何第三方应用。
因为产品版本升级或其余起因,本文档内容会不定期进行更新。除非另有约定,本文档仅作为应用领导,飞腾在现有技术的根底上尽最大致力提供相应的介绍及操作指引,但飞腾在此明确申明对本文档内容的准确性、完整性、适用性、可靠性的等不作任何明示或暗示的保障。
本文档中所有内容,包含但不限于图片、架构设计、页面布局、文字描述,均由飞腾和/或其关联公司依法领有其知识产权,包含但不限于商标权、专利权、著作权等。非经飞腾和/或其关联公司书面批准,任何人不得擅自应用、批改,复制上述内容。
如有技术问题,可分割support@phytium.com.cn获取反对。