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内核驱动算法概述

目前反对的内核态驱动算法如下表所示。

加速器算法算法名驱动名
对称引擎SM4ecb(sm4)
cbc(sm4)
ctr(sm4)
ofb(sm4)
ecb(sm4)-phytium
cbc(sm4)phytium
ctr(sm4)-phytium
ofb(sm4)-phytium
对称引擎AESecb(aes)
cbc(aes)
ctr(aes)
ofb(aes)
ecb(aes)-phytium
cbc(aes)phytium
ctr(aes)-phytium
ofb(aes)-phytium
对称引擎DESecb(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
哈希引擎DESecb(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
哈希引擎SHAsha1
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
哈希引擎SM3sm3
hmac(sm3)
sm3-phytium
hmac(sm3)-phytium
真随机数生成器TRNGTRNGtrng-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 术语和缩略语

术语全称解释
ACAAsymmetric Cryptography Accelerator非对称明码加速器
SCASymmetric Cryptography Accelerator对称明码加速器
TRNGTrue Random Number Generator真随机数发生器

6 常见问题


版权所有。飞腾信息技术有限公司 2023。保留所有权力。
未经本公司批准,任何单位、公司或集体不得擅自复制,翻译,摘抄本文档内容的局部或全副,不得以任何形式或路径进行流传和宣传。

商标申明
Phytium和其余飞腾商标均为飞腾信息技术有限公司的商标。
本文档提及的其余所有商标或注册商标,由各自的所有人领有。

留神
本文档的内容视为飞腾的窃密信息,您该当严格遵守窃密工作;未经飞腾当时书面批准,您不得向任何第三方披露本文档内容或提供给任何第三方应用。

因为产品版本升级或其余起因,本文档内容会不定期进行更新。除非另有约定,本文档仅作为应用领导,飞腾在现有技术的根底上尽最大致力提供相应的介绍及操作指引,但飞腾在此明确申明对本文档内容的准确性、完整性、适用性、可靠性的等不作任何明示或暗示的保障。

本文档中所有内容,包含但不限于图片、架构设计、页面布局、文字描述,均由飞腾和/或其关联公司依法领有其知识产权,包含但不限于商标权、专利权、著作权等。非经飞腾和/或其关联公司书面批准,任何人不得擅自应用、批改,复制上述内容。
如有技术问题,可分割support@phytium.com.cn获取反对。