張小領,謝 演,馮乃琪
(成都三零嘉微電子有限公司,四川 成都 610041)
2020 年1 月1 日起,《密碼法》的正式施行對我國密碼相關行業和技術的發展具有里程碑意義,將極大地推進我國密碼技術的發展和各行各業對密碼技術的應用,使得“密碼泛在化”理念深入人心。
《密碼法》在商用密碼部分中定義“商用密碼用于保護不屬于國家秘密的信息。公民、法人和其他組織可以依法使用商用密碼保護網絡與信息安全”。
目前,商用密碼已經應用于電力、能源、通信、金融、交通及政務等領域。在人們的日常生活中,移動支付、電子錢包等技術就包含對商用密碼技術的應用。通常,對稱密碼算法的應用模式分為單段式調用和三段式調用。單段式是指只調用一次密碼算法接口輸入所需指定參數便可以完成一次少量數據的密碼算法功能。三段式是指需要按照指定順序多次調用密碼算法接口完成一次大量數據的密碼算法功能。但是,在商密對稱算法實際應用中,當主機端多線程、多會話、多任務等都需要使用密碼算法時,三段式調用應當能夠支持被打斷或交叉調用,表現為當一個線程在三段式調用時另一個線程以任何一種方式調用算法接口,都不會使前序線程的密碼算法狀態丟失。
為滿足和支持主機端多線程、多會話、多任務等對密碼算法交叉調用的需求,需要對目前的商密算法實現方式進行修改、調整,使得在采用三段式密碼算法調用時能夠保持各自獨立的中間狀態,同時應用軟件需要配合商密算法的實現而設計交叉機制進行中間結果和狀態緩存,并管理和調度密碼算法的調用者——主機的線程、會話、任務等。
本文中采用的密碼設備端是以成都三零嘉微電子有限公司的密碼模塊(SSX1721 密碼卡)為主體實現的。此芯片通過國家商用密碼芯片二級認證,支持SM2[1]、SM3[2]、SM4[3]以及ZUC[4]等算法,具備可編程硬件密碼引擎。
為滿足密碼端設備可以被主機端多線程、多會話、多任務調用密碼功能,SSX1721 密碼模塊引擎通過編程邏輯可以使得密碼設備端中運行的固件可以訪問算法中間結果和狀態。密碼設備端中運行的固件需要能夠根據算法調用者編號以及其調用密碼算法的中間結果和狀態進行緩存,最后算法引擎能夠通過輸入算法的中間結果和緩存狀態恢復因交叉調用而打斷的算法,并能正確進行后續的運算。
密碼設備端的硬件密碼引擎包括算法所需要的各類寄存器、內存以及算數邏輯運算單元,能夠通過專用的命令組合實現密碼算法,接收數據輸入,輸出所需要的中間結果、狀態或最終結果。
密碼設備端固件中的業務功能層需要實現對調用者的管理以及其調用中算法的管理,記錄當前算法調用者的ID、密鑰信息、IV 以及算法模式等重要信息,實施引擎狀態管理,并能夠提供密碼設備端的狀態信息供主機端查詢。
在主機端協議調度層中實現對密碼設備端設備的設備占用鎖,當進行對密碼設備端的原子功能進行調用時采用。譬如,線程A 采用單段式調用一次計算,或采用三段式的某一步驟,調用者需要在進行算法功能調用時,先查詢密碼設備端的狀態。只有在密碼設備端空閑時設置占用鎖,才能進行密碼功能的調用。
如圖1 所示,整個框架有主機端和密碼設備端部分組成。

圖1 總體框架
其中,主機端包含應用程序以及與密碼設備交互的協議調度層、驅動層和硬件層。應用程序根據業務需要通過調用協議調度層形成與密碼設備交互的命令和數據,接著通過調用驅動層的硬件接口發送命令和數據到密碼設備端。密碼設備端接收、處理數據,并將處理后的數據反饋到主機端。
密碼設備端包括協議調度層、業務功能層、驅動層以及硬件層4 大部分,如圖2 所示。

圖2 密碼設備端架構
協議調度層主要完成和主機之間的數據協議處理。根據協議要求進行業務調度和執行,是整個軟件的主體控制。
業務功能層稱為抽象層,通過調用SDK 提供的各模塊接口形成指定的業務需求功能。此項目需求的功能集中于該層,是項目實施的聚焦點。
驅動層直接與硬件層進行交互,并提供操作硬件模塊的軟件接口,又稱之為SDK 層。
硬件層是密碼卡底層硬件物理模塊。
密碼算法功能主體為商密算法,包括非對稱算法的加解密、簽名、驗簽、公私密鑰對生成、密鑰協商、對稱算法[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 數據。
圖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 加密運算。
測試中采用的算法在經過上述流程的交叉調用后,將其輸出的數據與事先準備好的樣本數據進行對比,結果正確。文中提出的算法交叉調用機制的實現方式被證實是正確可行的,可在實際應用中用于滿足主機端多線程、多會話、多任務等對密碼算法交叉調用的需求。
本文介紹了一種算法交叉調用機制的實現方法,核心在于對算法執行的中間結果和狀態的保存,并對其實現結果進行測試。測試顯示,此實現方法能夠使得密碼設備所支持的算法被主機端多線程、多任務交叉調用,滿足當今愈發復雜的應用場景。此外,此實現方法采用的資源少,效率高,能夠低成本地移植在同類型的產品上。