国密算法交叉调用机制研究与实现*
2021-01-26张小领冯乃琪
张小领,谢 演,冯乃琪
(成都三零嘉微电子有限公司,四川 成都 610041)
0 引言
2020 年1 月1 日起,《密码法》的正式施行对我国密码相关行业和技术的发展具有里程碑意义,将极大地推进我国密码技术的发展和各行各业对密码技术的应用,使得“密码泛在化”理念深入人心。
《密码法》在商用密码部分中定义“商用密码用于保护不属于国家秘密的信息。公民、法人和其他组织可以依法使用商用密码保护网络与信息安全”。
目前,商用密码已经应用于电力、能源、通信、金融、交通及政务等领域。在人们的日常生活中,移动支付、电子钱包等技术就包含对商用密码技术的应用。通常,对称密码算法的应用模式分为单段式调用和三段式调用。单段式是指只调用一次密码算法接口输入所需指定参数便可以完成一次少量数据的密码算法功能。三段式是指需要按照指定顺序多次调用密码算法接口完成一次大量数据的密码算法功能。但是,在商密对称算法实际应用中,当主机端多线程、多会话、多任务等都需要使用密码算法时,三段式调用应当能够支持被打断或交叉调用,表现为当一个线程在三段式调用时另一个线程以任何一种方式调用算法接口,都不会使前序线程的密码算法状态丢失。
为满足和支持主机端多线程、多会话、多任务等对密码算法交叉调用的需求,需要对目前的商密算法实现方式进行修改、调整,使得在采用三段式密码算法调用时能够保持各自独立的中间状态,同时应用软件需要配合商密算法的实现而设计交叉机制进行中间结果和状态缓存,并管理和调度密码算法的调用者——主机的线程、会话、任务等。
1 实现原理及方式
本文中采用的密码设备端是以成都三零嘉微电子有限公司的密码模块(SSX1721 密码卡)为主体实现的。此芯片通过国家商用密码芯片二级认证,支持SM2[1]、SM3[2]、SM4[3]以及ZUC[4]等算法,具备可编程硬件密码引擎。
为满足密码端设备可以被主机端多线程、多会话、多任务调用密码功能,SSX1721 密码模块引擎通过编程逻辑可以使得密码设备端中运行的固件可以访问算法中间结果和状态。密码设备端中运行的固件需要能够根据算法调用者编号以及其调用密码算法的中间结果和状态进行缓存,最后算法引擎能够通过输入算法的中间结果和缓存状态恢复因交叉调用而打断的算法,并能正确进行后续的运算。
密码设备端的硬件密码引擎包括算法所需要的各类寄存器、内存以及算数逻辑运算单元,能够通过专用的命令组合实现密码算法,接收数据输入,输出所需要的中间结果、状态或最终结果。
密码设备端固件中的业务功能层需要实现对调用者的管理以及其调用中算法的管理,记录当前算法调用者的ID、密钥信息、IV 以及算法模式等重要信息,实施引擎状态管理,并能够提供密码设备端的状态信息供主机端查询。
在主机端协议调度层中实现对密码设备端设备的设备占用锁,当进行对密码设备端的原子功能进行调用时采用。譬如,线程A 采用单段式调用一次计算,或采用三段式的某一步骤,调用者需要在进行算法功能调用时,先查询密码设备端的状态。只有在密码设备端空闲时设置占用锁,才能进行密码功能的调用。
2 总体架构实现
2.1 总体架构
如图1 所示,整个框架有主机端和密码设备端部分组成。
图1 总体框架
其中,主机端包含应用程序以及与密码设备交互的协议调度层、驱动层和硬件层。应用程序根据业务需要通过调用协议调度层形成与密码设备交互的命令和数据,接着通过调用驱动层的硬件接口发送命令和数据到密码设备端。密码设备端接收、处理数据,并将处理后的数据反馈到主机端。
2.2 密码设备端架构
密码设备端包括协议调度层、业务功能层、驱动层以及硬件层4 大部分,如图2 所示。
图2 密码设备端架构
协议调度层主要完成和主机之间的数据协议处理。根据协议要求进行业务调度和执行,是整个软件的主体控制。
业务功能层称为抽象层,通过调用SDK 提供的各模块接口形成指定的业务需求功能。此项目需求的功能集中于该层,是项目实施的聚焦点。
驱动层直接与硬件层进行交互,并提供操作硬件模块的软件接口,又称之为SDK 层。
硬件层是密码卡底层硬件物理模块。
3 交叉算法功能设计
密码算法功能主体为商密算法,包括非对称算法的加解密、签名、验签、公私密钥对生成、密钥协商、对称算法[5]的分组以及序列算法的加解密和摘要算法。
算法调用模式为单段式和三段式调用。单段式调用是指只需要一次调用一个功能接口便可完成一个完整密码功能的调用方式,包含对称算法、摘要、随机数生成[5]、公私密钥对生成[1]、签名[1]、验证[1]、非对称加密和解密以及密码协商。三段式调用是指需要按指定顺序调用3 个功能接口才能完成一个完整的密码功能,并且允许多次调用中间功能接口的调用方式,含摘要和对称加解密。
如图3 所示,多调用交叉管理的核心机制为多调用会话管理和引擎状态管理。多调用会话管理会记录当前密码算法调用者ID、密钥信息、IV 以及算法模式等重要信息。引擎状态管理则直接与会话管理配套使用,随时记录或更新三段式调用过程中属于每一个密码算法调用者ID 的当前引擎状态或中间结果。在发生交叉调用后,引擎状态管理则可以恢复需要继续调用算法的密码算法调用者ID 上一次引擎状态和中间结果,使得该密码算法调用者ID 继续完成后续密码业务,以此完成对称算法、摘要(Hash)算法、非对称算法(签名、验签、加解密、密钥协商)的多调用者单段式和三段式的交叉调用、三段式与三段式的交叉调用。
图3 密码功能设计
设计cipher_sess_st 结构体实现多调用会话管理和引擎状态管理。
结构体原型如下:
该会话结构体可存储调用者的当前算法信息,并且缓存三段式调用时中间状态临时缓存,恢复每个调用者使用密码算法的打断交叉调用前状态。
三段式调用中,每一段(init、update、final)都需要传入算法调用者ID。cipher_sess_st 可以根据此ID 进行关系映射,算法引擎以此恢复此前运行的算法中间结果和状态,保证算法后续的正确运行。
多会话调用流程如图4 所示。
图4 多调用交叉管理流程
(1)第一段init 调用时,通过cipher_sess[0]数组记录cipher_id0 的密码信息,cipher_sess[1]数组记录cipher_id1 的密码信息,并将各自status 置位init 状态。
(2)第二段update 调用时,cipher_id0 将第一段中cipher_sess[0]中的密钥、模式、iv 等信息配置到密码引擎。
(3)检查cipher_sess[0]中的status,如果是init,则调用一次算法运算接口,完成后将cipher_sess[0]中的status 置位update 状态。
(4)读取此时引擎中间状态和数据,将中间状态和数据记录或更新在cipher_sess[0]的mid_tmp_data 和iv 中(根据具体算法)。
(5)随后cipher_id1 也调用了一次第二段update 操作,即为一次交叉调用,此时引擎内部状态已发生改变。
(6)cipher_id0 再次执行update 时,将cipher_sess[0]的密码信息配置到引擎。
(7)判断cipher_sess[0]的status,如果不是init,则表明需要恢复引擎数据。
(8)将cipher_sess[0]上次保存或更新的引擎中间状态和数据回写到引擎,再调用一次算法运算接口。
(9)每次算法运算后都读取此时引擎中间状态和数据,并更新在cipher_sess[0]的mid_tmp_data和iv 中(根据具体算法)。
(10)反复调用update 后,最后调用final 结束三段式调用,并清除cipher_sess 数据。
4 设计结果
图5 展示了对多调用交叉算法实现测试的代码片段。整个流程采用国密算法中的分组算法、摘要算法、SM2 算法签名、验签、加密、解密以及密钥协商的三段式和单段式交叉调用。由于图文限制,展示的流程只为测试的一小部分。
图5 多调用交叉展示
测试流程如下:
(1)分组算法SM4 的CBC 模式初始化;
(2)分组算法SM4 的CBC 模式做一次加密运算,并比较计算结果;
(3)分组算法SM4 的ECB 模式初始化;
(4)分组算法SM4 的ECB 模式做一次加密运算;
(5)SM3(摘要)初始化;
(6)分组算法的SM4 ECB 模式初始化;
(7)SM3(摘要)做一次运算;
(8)SM3(摘要)做final 运算;
(9)SM2 签名运算;
(10)SM4 ECB 做一次加密运算;
(11)SM2 加密运算。
测试中采用的算法在经过上述流程的交叉调用后,将其输出的数据与事先准备好的样本数据进行对比,结果正确。文中提出的算法交叉调用机制的实现方式被证实是正确可行的,可在实际应用中用于满足主机端多线程、多会话、多任务等对密码算法交叉调用的需求。
5 结语
本文介绍了一种算法交叉调用机制的实现方法,核心在于对算法执行的中间结果和状态的保存,并对其实现结果进行测试。测试显示,此实现方法能够使得密码设备所支持的算法被主机端多线程、多任务交叉调用,满足当今愈发复杂的应用场景。此外,此实现方法采用的资源少,效率高,能够低成本地移植在同类型的产品上。