蘇振宇,徐崢,劉雁鳴
(浪潮電子信息產業股份有限公司 安全技術部,山東 濟南 250101)
可編程片上系統(System on a Programmable Chip,SoPC)是一種特殊的嵌入式系統[1],由單個芯片完成整個系統的主要邏輯功能,通過軟硬件在系統可編程的功能使得設計方式具備可裁剪、可擴充、可升級等靈活特性。在SoPC 啟動過程中存在一定的安全風險,惡意軟件有可能會修改引導加載程序等固件,使SoPC 受到Rootkit 攻擊[2]。Rootkit 等惡意軟件通過修改系統的啟動過程,安裝到系統內以達到持久駐留系統的目的[3],SoPC 一旦受到Rootkit等惡意代碼感染,即使重新安裝系統也無法清除。因此有必要對SoPC 進行安全保護,防止在啟動過程中固件被惡意篡改。安全啟動對于保護設計的知識產權和防止惡意軟件在系統上運行至關重要。相關研究工作存在的問題主要有:(1)采用外接可信平臺模塊(Trusted Platform Module,TPM)[4]實現可信啟動[5],該方式增加了硬件成本且系統集成度低;(2)在構建信任鏈的過程中僅采用雜湊算法進行度量[6],缺少驗證的過程,因此安全性較低;(3)嵌入式系統上電時由最先啟動的引導加載程序Boot Loader 調用TPM 對后續加載的模塊進行度量[7-8],Boot Loader 默認是安全的,但Boot Loader 一旦被攻擊篡改,整個信任鏈就處于非可信的狀態。
基于現有技術的不足,提出一種SoPC 安全啟動模型,目的是確保SoPC 的引導加載程序等固件是可信的,安全啟動模型如圖1 所示。信任根是創建安全啟動最關鍵的部分,能夠確保安全級別配置正確并且安全密鑰受到保護。在該模型中信任根是SoPC 中受信任的第一階段的引導固件Boot ROM,作為引導SoPC 可信的、固有的安全起點。

圖1 SoPC 安全啟動模型
為了確保可信性,在安全啟動過程中通過建立信任鏈,使每個固件在加載運行前都經過數字簽名的驗證,只有當前階段對后續待啟動的模塊進行驗證通過后,才會加載和執行后續的模塊。具體為:依次對第二、三、四階段的Boot Loader、操作系統和應用程序的鏡像文件添加數字簽名后存儲,在SoPC 上電啟動建立信任鏈的過程中,首先由第一階段的Boot ROM 驗證第二階段Boot Loader的簽名,確保Boot Loader 是受信任的;之后由Boot Loader驗證操作系統的簽名,依次類推,從而確保各模塊是受信任的。為了進一步提高啟動過程的安全性,可以對固件鏡像加密后再進行數字簽名操作,并且將相關的密鑰存儲于SoPC 的安全區域中。
在安全啟動之前,對Xi的數字簽名SIGi 定義如下:

其中每階段待啟動的模塊為Xi,第一階段的引導程序X0為信任根。E 代表加密運算,D 代表解密運算,H 代表雜湊運算,K為對稱密碼算法的密鑰,PK、SK為非對稱密碼算法的公鑰、私鑰。SIGi為數字簽名值,H(Xi)表示對Xi進行雜湊運算后生成的摘要值。式(1)表示用私鑰SK 對H(Xi)進行數字簽名,即對H(Xi)做解密運算;為進一步提高安全性,式(2)在進行數字簽名之前,利用密鑰K 對H(Xi)進行了對稱加密運算。
在啟動過程中,由Xi-1對Xi進行校驗。驗證Xi的數字簽名SIGi的定義為:

式(3)與式(1)對應,驗證簽名時利用公鑰PK 對數字簽名值SIGi進行加密運算后恢復出Xi的標準摘要值H(Xi),之后計算待加載模塊Xi鏡像的摘要值H(),并與H(Xi)進行比對,當H()=H(Xi)時說明Xi未篡改(即=Xi),數字簽名驗證通過;如果Xi的鏡像被篡改為,由于Xi′≠Xi,故H()≠H(Xi),校驗不通過。式(4)與式(2)對應,先利用公鑰PK 對SIGi進行加密運算,再利用K 進行解密運算后恢復出標準摘要值H(Xi)。
以信任根X0為信任起點逐級進行驗證,如果每個模塊Xi的數字簽名都驗證通過,則啟動過程是安全可信的,最終構建一個安全可信的信任鏈:X0→X1→X2…→Xi,如果在啟動過程中任意Xi的數字簽名驗證不通過,則信任鏈的建立終止,系統不會啟動。
安全啟動模型采用了Intel Arria10 現場可編程門陣列(Field Programmable Gate Array,FPGA)開發平臺[9]進行設計和驗證,EDA 工具采用的是Quartus II 19.1[10]、嵌入式開發套件為EDS[11]、操作系統為Linux Ubuntu 14.0。SoPC 安全啟動硬件架構設計如圖2 所示,包括硬件處理器系統(Hard Processor System,HPS)和FPGA 可編程邏輯區域,其中HPS 包括微控制器MPU、安全管理器(Security Manager,SM)、Boot ROM、On-chip RAM 等;FPGA區域包括配置邏輯(Configuration Logic,CL)、安全熔絲Fuse、Flash/SD 卡等。

圖2 SoPC 安全啟動硬件架構
主要功能模塊的作用如下:
(1)SM:用于系統初始化和引導,在SoPC 上電復位后根據熔絲寄存器(Fuse_REG)對系統進行配置。
(2)Boot ROM:管理安全引導過程的第一階段,并對第二階段的引導程序Boot Loader 進行驗證。
(3)CL:發送配置信息給SM,另外包括256 位橢圓曲線數字簽名算法(Elliptic Curve Digital Signature Algorithm,ECDSA-256)[12]、256 位安全散列算法(Secure Hash Algorithm,SHA-256)[13]和高級加密標準(Advanced Encryption Standard,AES)[14],作為對鏡像加密和簽名的密碼算法模塊。
(4)Fuse:一次性可編程區域,作為安全存儲區存儲公鑰PK、對稱密鑰K 以及系統安全配置信息。
(5)Flash/SD 卡:為片外非易失存儲器,存儲經過加密和簽名的Boot Loader、OS 等鏡像文件,啟動過程中鏡像驗證通過后才能加載到SoPC 片內RAM 運行。
SoPC 上電復位后,CL 初始化并將Fuse 安全配置信息發送到HPS 中的SM,配置信息保存在SM 中的Fuse_REG寄存器中。SM 根據Fuse_REG 中的配置信息執行安全檢查并發送系統初始化信號,控制Fuse 信息自動發送到時鐘管理器,內存控制Fuse 信息自動發送到復位管理器,認證、加密、公鑰等配置信息存儲在相應的存儲器映射位置,由Boot ROM 代碼讀取。
之后HPS 在安全狀態下退出復位狀態,Boot ROM 開始執行。此時,HPS 處于受信任狀態,并且保證Boot ROM代碼按預期執行。Boot ROM 讀取安全報頭,如圖3 所示,確定根密鑰的存儲位置并驗證第二階段Boot Loader 鏡像安全報頭中的數字簽名值。如果校驗通過,Boot ROM允許Boot Loader 鏡像加載和執行。

圖3 Boot Loader 鏡像的驗證報頭和安全報頭
ECDSA-256 算法的私鑰用于對鏡像進行簽名,公鑰用于對鏡像進行驗證。公鑰可通過Fuse_REG 寄存器選擇配置為3 種類型,如表1 所示。

表1 公鑰類型
(1)安全密鑰:安全性最高,公鑰PK 經過SHA-256雜湊運算后的摘要值H(PK)存儲于Fuse 中,使用前先驗證公鑰完整性,校驗通過才允許加載;若公鑰被篡改為PK′,則H(PK′)≠H(PK),禁止公鑰加載。
(2)FPGA 密鑰:安全性較高,公鑰直接存儲于FPGA區域的RAM 中,未經過雜湊運算。
(3)測試密鑰:安全性最差,公鑰直接存儲于鏡像文件的報頭中,僅在測試階段使用。
鏡像文件有兩種創建方式,對應兩種安全級別,可通過Fuse_REG 寄存器進行選擇配置。
(1)簽名驗證方式
該方式首先需要利用OpenSSL[15]生成簽名密鑰對,OpenSSL 是一個支持安全套接字協議SSL 的開源工具包,集成于EDS 嵌入式命令shell 中。生成密鑰對的具體方式是在Linux 中啟動Boot Loader 生成器后調用OpenSSL,運行如下命令使OpenSSL 生成密鑰對:# openssl ecparam-genkey -name prime256v1 -out root_key.pem。
創建的簽名密鑰對存儲于root_key.pem 文件中,使用安全引導鏡像工具alt-secure-boot 對鏡像進行簽名的命令為:# alt-secure-boot sign-i Image.bin-o Image_sign.bin-t user。
其中user 代表的公鑰類型是測試密鑰,在測試階段的安全啟動過程中,直接讀取鏡像文件中的公鑰,不對公鑰進行SHA-256 雜湊校驗比對。Image.bin和Image_sign.bin 分別為簽名之前和添加數字簽名之后鏡像文件,將Image_sign.bin 文件存儲于片外SD 卡中。
(2)加密+簽名驗證方式
為了在引導期間提供最高級別的安全性,可以對鏡像文件加密后再添加數字簽名,以便在校驗階段提供雙重保護。在Boot Loader 生成器中通過文件encrypt.key生成加密密鑰key,用于對鏡像加密。具體為EDS 工具調用Boot Loader 生成器讀取encrypt.key 文件中的二進制位流生成加密密鑰key。對鏡像進行加密的命令為:# alt-secure-boot encrypt-i Image.bin-o Image_enc.bin-k key。
其中key為AES 對稱算法的密鑰,Image.bin和Image_enc.bin 分別為加密之前和加密之后鏡像文件。
驗證過程如圖4 所示,具體說明如下。啟動過程的每個階段利用公鑰PK和雜湊算法校驗下一階段鏡像的數字簽名,首先恢復出鏡像文件的標準摘要值H(Xi),如果鏡像被加密了,根據式(3)需要利用PK和對稱密鑰K 恢復出標準摘要值H(Xi)。在鏡像加載之前計算其摘要值H(Xi′),并與H(Xi)進行比對,如果H(Xi)=H(Xi′),說明鏡像未篡改,即Xi=,允許鏡像加載執行;如果H(Xi)≠H(),說明鏡像Xi已被篡改為,信任鏈為非可信狀態,啟動過程失敗。例如在引導過程中,Boot ROM 首先驗證Boot Loader 鏡像的數字簽名,驗證通過后才能加載運行,之后由Boot Loader 對后續階段的Linux 系統鏡像進行驗證和加載。如果驗證數字簽名失敗,啟動過程終止。

圖4 安全啟動驗證流程圖
表2為Boot Loader和Linux 的鏡像文件經過雜湊運算后的摘要值。為了驗證安全啟動的功能,對原始值的前2 個字節分別篡改為了“0x12,0x34”。

表2 鏡像文件摘要值篡改
表3為兩種安全啟動方式的測試結果,如果鏡像未篡改,SoPC 正常啟動;如果對Boot Loader 或Linux 系統鏡像文件進行了篡改,信任鏈建立終止,啟動失敗。

表3 安全啟動測試結果
圖5 所示為啟動方式的啟動時間對比,正常啟動時因未對鏡像進行簽名和驗證,所以啟動時間最短,但安全性最差;若采用簽名驗證方式啟動,從SoPC 上電到應用程序加載的時間總共為15 s;采用簽名+加密驗證方式的整個啟動時間最長,為25 s,但安全性最高。

圖5 安全啟動模式的啟動時間對比
SoPC 在啟動過程中通過校驗啟動階段各固件鏡像的數字簽名方式提升了安全性,保證了啟動過程中引導加載程序、操作系統及應用程序的安全可信,從而構建起完整的信任鏈。此外,測試階段為了避免把密鑰永久寫入一次性可編程區域而造成Fuse 資源浪費,靈活采用了把密鑰寫入文件和FPGA RAM 區域的方式進行功能的驗證。后續工作可以將該安全啟動模型應用于實際SoPC 的設計開發過程,實現對SoPC 啟動過程的安全保護,并且將密鑰固化在安全區域以防止被非法篡改,提高安全性。