1. 程式人生 > >痞子衡嵌入式:恩智浦MCU安全加密啟動一站式工具nxpSecBoot使用者指南

痞子衡嵌入式:恩智浦MCU安全加密啟動一站式工具nxpSecBoot使用者指南

nxpSecBoot

1 軟體概覽

1.1 介紹

  nxpSecBoot是一個專為NXP MCU安全加密啟動而設計的工具,其特性與NXP MCU裡BootROM功能相對應,目前主要支援i.MXRT系列MCU晶片,與NXP官方提供的標準安全加密配套工具集(OpenSSL, CST, sdphost, blhost, elftosb, BD, MfgTool2)相比,nxpSecBoot是一個真正的一站式工具,一個工具包含NXP官方所有加密配套工具的功能,並且是全圖形使用者介面操作。藉助於nxpSecBoot,你可以輕鬆上手NXP MCU安全加密啟動。
  nxpSecBoot主要功能如下:

  • 支援i.MXRT全系列MCU,包含i.MXRT105x、i.MXRT102x、i.MXRT106x
  • 支援UART和USB-HID兩種序列下載方式
  • 支援.elf和.srec格式的源image檔案輸入
  • 支援FlexSPI NOR和SEMC NAND介面的外部啟動裝置
  • 支援基於HAB實現的安全加密啟動(單簽名,簽名和加密)
  • 支援基於BEE實現的安全加密啟動(唯一SNVS key,使用者自定義key)
  • 支援基於HAB和BEE聯合實現的安全加密啟動(HAB簽名,BEE加密)
  • 支援eFuse memory的回讀和燒寫操作
  • 支援從外部啟動裝置回讀已下載的bootable image資料,並對資料組成部分進行標註

1.2 下載

  nxpSecBoot完全基於Python語言開發,並且原始碼全部開源,其具體開發環境為Python 2.7.14、wxPython 4.0.3、pySerial 3.4、bincopy 15.0.0、PyInstaller 3.3.1。

  nxpSecBoot在釋出時藉助PyInstaller將所有的Python依賴全部打包進一個可執行檔案(\nxp-sec-boot-ui\bin\nxpSecBoot.exe),因此如果不是對nxpSecBoot的二次開發,你不需要安裝任何Python軟體及相關庫。

Note: 原始碼包裡的nxpSecBoot.exe是在Windows 10 x64環境下打包的,也僅在該環境下測試過,如果因系統原因無法直接使用,你需要安裝相應的Python開發環境,並在\nxp-sec-boot-ui\bin\目錄下執行“pyinstaller .\nxpSecBoot.spec”命令重新生成nxpSecBoot.exe可執行檔案。

1.3 安裝

  nxpSecBoot是一個是純綠色免安裝的工具,下載了原始碼包之後,直接雙擊\nxp-sec-boot-ui\bin\nxpSecBoot.exe即可使用。使用nxpSecBoot沒有任何軟體依賴,不需要額外安裝任何軟體。

1.4 目錄

  nxpSecBoot軟體目錄組織如下:

\nxp-sec-boot-ui
                \apps                        --放置示例的源image檔案
                \bin                         --放置nxpSecBoot可執行檔案及PyInstaller打包描述檔案
                \doc                         --放置NXP官方安全啟動相關的參考文件
                \gen                         --放置nxpSecBoot使用過程中生成的臨時檔案
                      \bd_file                  --根據配置動態生成的BD檔案
                      \bee_crypto               --BEE加密過程中生成的檔案
                      \bootable_image           --生成的bootable image檔案
                      \hab_cert                 --HAB簽名過程中生成的檔案
                      \hab_crypto               --HAB加密過程中生成的檔案
                \gui                         --放置開發nxpSecBoot UI構建工程檔案
                \img                         --放置nxpSecBoot使用過程中需載入的圖片
                \src                         --放置開發nxpSecBoot的所有Python原始碼檔案
                \tools                       --放置nxpSecBoot使用過程中需呼叫的外部程式
                      \blhost                   --與Flashloader通訊的上位機命令列工具
                      \cst                      --HAB加密的配套命令列工具
                      \elftosb                  --生成bootable image的命令列工具
                      \image_enc                --BEE加密的配套命令列工具
                      \openssl                  --生成證書和祕鑰的標準工具
                      \sdphost                  --與ROM通訊的上位機命令列工具

1.5 介面

  下圖為nxpSecBoot工具的主介面,介面主要由六部分組成,各部分功能如下:

  • 【Menu Bar】:功能選單欄,提供軟體通用設定。
  • 【Target Setup】:目標裝置設定欄,提供MCU Device和Boot Device配置選項。
  • 【Port Setup】:序列介面設定欄,選擇用於連線MCU Device的介面。
  • 【Device Status】:目標裝置狀態資訊欄,當連線上目標裝置之後,用於顯示目標裝置的狀態。
  • 【Main Window】:安全加密啟動主介面,提供對目標裝置做安全加密啟動的所有操作。
  • 【Log Window】:操作日誌欄,記錄軟體操作日誌。

2 軟體使用

2.1 設定目標裝置

  在使用nxpSecBoot時首先需要配置目標裝置,目標裝置包括MCU Device和Boot Device。以NXP官方開發板EVK-MIMXRT1060為例,該開發板主晶片為i.MXRT1062DVL6A,所以【MCU Device】應設為i.MXRT106x。且以最常用的FlexSPI NOR啟動為例,【Boot Device】設為FLEXSPI NOR,開發板上對應的外部儲存晶片為IS25WP064AJBLE,其是一顆常用的四線QSPI NOR Flash,我們需要在軟體裡進一步配置該Boot Device,單擊【Boot Device Configuration】按鈕可彈出如下新的配置頁面:

  在彈出的名為FlexSPI NOR Device Configuration頁面裡可以看到很多描述Multi-IO SPI NOR Flash特性的選項,比如Device Type、Query Pads等,這些選項都需要被正確地設定,以與開發板上的外部儲存晶片相匹配。
  除此以外,頁面上還有一個名為【Use Typical Device Model】的選項,nxpSecBoot軟體預先定義了一些常用的Multi-IO SPI NOR Flash型號模型,如果開發板上的外部儲存晶片恰好在軟體預定義的型號列表裡,那麼你可以直接在【Use Typical Device Model】選擇對應型號,而不必在Nor Option裡逐一配置。
  EVK-MIMXRT1060開發板上的IS25WP064AJBLE晶片屬於ISSI - IS25LP064A大類,因此我們只需要在【Use Typical Device Model】選擇ISSI - IS25LP064A並點選【Ok】即完成了目標裝置的設定。

2.2 連線目標裝置

  設定好目標裝置之後,下一步便是連線目標裝置,以USB-HID介面連線為例,給EVK-MIMXRT1060板子供電,並用USB Cable將PC與J9口連線起來,如果一切正常,應該可以在裝置管理器找到vid,pid為0x1fc9,0x0135的HID-compliant vendor-defined device裝置被列舉。如果沒有發現該HID裝置,請仔細檢查板子SW7撥碼開關是否將Boot Mode設為2'b01即Serial Downloader模式。

  確認HID裝置存在之後,在【Port Setup】選中USB-HID,然後直接點選【Connect to ROM】按鈕,此時軟體便會自動完成目標裝置連線全過程(使用sdphost連線ROM,獲取一些MCU內部暫存器資訊,使用sdphost載入Flashloader並跳轉過去,使用blhost連線Flashloader,獲取一些eFuse資訊,使用blhost去配置boot device並獲取boot device meomry資訊),這個過程需要大概5s的時間,如果目標裝置連線正常,你可以看到指示燈變藍,並且【Connect to ROM】按鈕標籤變為【Reset Device】。如果目標裝置連線失敗,指示燈會變紅,並且【Connect to ROM】按鈕標籤變為【Reconnect】。

  目標裝置連線成功後可以在目標裝置狀態資訊欄看到一些有用的裝置狀態資訊,比如MCU晶片的UUID值、HAB狀態、與啟動相關的重要Fuse值,Boot Device的Page/Sector/Block大小等。

2.3 安全加密啟動

  目標裝置連線成功後便可以開始最核心的安全加密啟動操作,在做安全加密啟動之前先來介紹安全加密啟動主介面分佈:

  • 【Image Generation Sequence】:image生成視窗,用於對源image進行加密安全處理,生成可放在Boot Device中的bootable image
  • 【Image Loading Sequence】:image下載視窗,用於將生成的bootable image下載進Boot Device中,並且在MCU中燒錄相應的Fuse值(各種Key,HAB設定等)
  • 【eFuse Operation Utility】:eFuse燒錄視窗,使用者可燒錄自定義值進Fuse Region。
  • 【Boot Device Memory】:image回讀與標註視窗,用於從Boot Device回讀已下載的Bootable image資料,並對資料組成各部分進行標註
  • 【Secure Boot Type】:安全模式選擇,選擇想要安全模式(不使能安全,HAB單簽名,HAB簽名加密,BEE加密)。
  • 【All-In-One Action】:一鍵操作,image生成視窗和image下載窗口裡啟用的操作自動按序執行
2.3.1 模式一:不啟用任何安全措施

  第一種模式是最簡單的模式,即不啟動任何安全措施,一般用於產品開發除錯階段。
  【Secure Boot Type】選擇“Unsigned (XIP) Image Boot”,然後點選【Browse】按鈕選擇一個原始image檔案(使用IDE生成的裸.elf/.srec檔案即可,不需要包含任何i.MXRT啟動所需的額外檔案頭),點選【All-In-One Action】按鈕即可完成bootable image生成與下載所有操作。

  上圖中Step4和Step5並不是必需操作,僅是用於確認【All-In-One Action】按鈕操作是否成功,尤其是Step5操作,可以對應image下載窗口裡顯示的Bootable image構成圖做一遍檢查。
  一切操作無誤,板子上SW7撥碼開關將Boot Mode設為2'b10即Internal Boot模式,其餘保持全0,重新上電便可以看到unsigned image正常執行了。

2.3.2 模式二:啟用HAB簽名認證

  第二種模式是初級的安全模式,即僅對image進行簽名認證,一般用於對產品安全性要求較高的場合。簽名認證主要是對image合法性進行校驗,檢測image是否被異常破壞或篡改,如果檢測發現image不合法,那麼MCU便不會啟動執行該image。
  【Secure Boot Type】選擇“HAB Signed (XIP) Image Boot”,然後輸入serial(必須是8位數字)以及key_pass(任意長度字元)後點擊【Advanced Cert Settings】按鈕配置所有簽名認證的引數(熟悉 NXP官方HAB Code Signing Tool工具 使用的朋友應該對這些設定很熟悉),再點選【Browse】按鈕選擇一個原始image檔案,最後點選【All-In-One Action】按鈕即可完成bootable image生成與下載所有操作。

  上圖中Step5主要確認兩點:一、HAB狀態是否是Closed的(Fuse 0x460[31:0]的bit1為1'b1);二、SRKH是否被正確燒錄(Fuse 0x580 - 0x5f0,一共256bit,即sha-256演算法),SRKH是最終bootable image裡CSF資料裡的Public RSA Key的Hash值,用於校驗Public RSA Key是否合法。
  一切操作無誤,板子上SW7撥碼開關將Boot Mode設為2'b10即Internal Boot模式,其餘保持全0,重新上電便可以看到HAB signed image正常執行了。
  因為此時MCU晶片HAB狀態已經是Closed,並且SRKH已經被燒錄無法更改,所以未經簽名認證的image無法正常執行,在軟體目錄\nxp-sec-boot\tools\cst\3.0.1\crts資料夾下存放著Private RSA Key檔案,請妥善儲存好,一旦遺失,那麼新的image將無法被正確簽名從而導致HAB認證失敗無法被啟動執行。

2.3.3 模式三:啟用HAB簽名認證與HAB加密

  第三種模式是中級的安全模式,即對image進行簽名認證以及HAB級加密,一般用於對產品安全性要求很高的場合。簽名認證主要是對image合法性進行校驗,而加密則可以保護image在外部Boot Device中不被非法盜用,因為在外部Boot Device中存放的是image的密文資料,即使被非法獲取也無法輕易破解,並且加密是和MCU晶片繫結的,因為HAB加密過程中使用了MCU內部SNVS模組裡的唯一Master Secret Key。
  【Secure Boot Type】選擇“HAB Signed Encrypted Image Boot”,然後配置所有簽名認證的引數(如果本地已有證書,可以不用配置,軟體會嘗試複用),再點選【Browse】按鈕選擇一個原始image檔案,最後點選【All-In-One Action】按鈕即可完成bootable image生成與下載所有操作。

  上圖中Step6操作之後可以看到下載進Boot Deivce裡的image部分確實是密文,實際上HAB加密僅支援加密image區域,其他區域(比如FDCB、IVT、Boot Data等)均沒有加密。
  一切操作無誤,板子上SW7撥碼開關將Boot Mode設為2'b10即Internal Boot模式,其餘保持全0,重新上電便可以看到HAB signed encrypted image正常執行了。
  你可能會好奇,既然image是經過HAB加密的,那麼密碼在哪裡?怎麼設定的?其實image加密操作完全被HAB配套工具封裝好了,HAB加密使用的AES-128演算法,其對應的128bits的AES-128 Key不是由使用者自定義的,而是HAB加密工具自動隨機生成的,並且每一次加密操作生成的AES-128 Key都是不一樣的,即使你沒有更換輸入的原始image。AES-128 Key儲存在\nxp-sec-boot\gen\hab_crypto\hab_dek.bin檔案裡。
  從上圖中image下載窗口裡顯示的Bootable image構成圖裡可以看出,相比HAB單簽名的方式,HAB簽名加密方式最終使用的Bootable image的最後多了一個DEK KeyBlob組成部分,這個DEK KeyBlob是通過MCU晶片內部SNVS模組裡的Master Secret Key對hab_dek.bin裡的key資料進行動態加密生成的,因為Master Secret Key是晶片唯一的,因此DEK KeyBlob也是晶片唯一的,這是保護image不被非法盜用的關鍵。
  關於HAB加密為何不支援XIP Image,其實簡單分析一下啟動原理便清楚,Image在Boot Device裡儲存的是密文,這部分密文必須要經過HAB解密成明文才可以被CPU執行,因此必須要指定不同的儲存空間去存放Image明文,Non-XIP image天然指定了明文應存放在晶片內部SRAM或者外掛SDRAM中,而XIP Image是在Boot Device中直接執行的,一般明文地址與密文地址是相同的,因此HAB加密不支援XIP Image。

2.3.4 模式四:啟用單引擎BEE加密(唯一SNVS Key)

  第四種模式是高階的安全模式,即用唯一SNVS Key對image進行單引擎BEE級加密,一般用於對產品安全性要求極高的場合。BEE加密與HAB加密的主要區別是執行解密操作的主體不同,主要有如下三點區別:

  • HAB加密是由BootROM裡的HAB將加密後的image全部解密成明文另存後再執行(靜態解密),而BEE加密是由MCU晶片內部的BEE模組對加密後的image原地邊解密邊執行(動態解密)。
  • HAB加密僅支援Non-XIP Image(不限Boot Device),而BEE加密僅支援XIP在FlexSPI NOR中的Image。
  • HAB加密區域不可指定(預設全部使用者Image區域),而BEE加密的區域可由使用者指定。

  【Secure Boot Type】選擇“BEE (Signed) Encrypted XIP Image Boot”,點選【Browse】按鈕選擇一個原始image檔案(必須是XIP在FlexSPI NOR中的image),【Key Storage Region】選擇“Fixed SNVS Key”後點擊【Advanced Key Settings】按鈕配置所有BEE加密的引數,最後點選【All-In-One Action】按鈕即可完成bootable image生成與下載所有操作。

  上圖中Step5操作主要確認一點:BEE_KEY0_SEL是否設定的是From OTPMK[255:128](Fuse 0x460[31:0]的bit13,12為2'b10)。Step6操作之後可以看到下載進Boot Deivce裡的Bootable image從IVT開始全是密文,本示例僅啟用一塊加密區域,具體對哪些區域進行加密是在【Advanced Key Settings】裡指定的,最大支援指定3塊加密區域。
  一切操作無誤,板子上SW7撥碼開關將Boot Mode設為2'b10即Internal Boot模式,並且將BT_CFG[1]設為1'b1(使能Encrypted XIP),其餘保持全0,重新上電便可以看到BEE encrypted image正常執行了。
  BEE加密相比HAB加密是要更安全的,因為HAB加密畢竟是靜態解密,當HAB解密完成之後在SRAM/SDRAM中儲存的是全部的image明文,如果此刻黑客去非法訪問SRAM/SDRAM是有可能獲取全部image明文的;而BEE加密是動態解密,CPU執行到什麼地方才會去解密什麼地方,任何時候都不存在完整的image明文,黑客永遠無法獲取全部的image明文。

2.3.5 模式五:啟用雙引擎BEE加密(使用者自定義Key)

  第五種模式也是高階的安全模式,即用使用者自定義Key對image進行雙引擎BEE級加密,跟第四種模式(單引擎)原理類似,一般用於對產品安全性要求極高的場合。單引擎BEE加密與雙引擎BEE加密具體區別如下:

  • 唯一SNVS Key單引擎BEE加密預設使用SNVS Key,晶片出廠已預先燒錄,無法更改;使用者自定義Key雙引擎BEE加密使用的Key是由使用者自己設的,需要手動燒錄在Fuse SW_GP2和GP4區域。
  • 唯一SNVS Key單引擎BEE加密只啟用了BEE引擎0;使用者自定義Key雙引擎BEE加密可以同時啟用BEE引擎0和引擎1。但需要注意的是無論啟動幾個BEE引擎,最大加密區域總數均是3個。

  【Secure Boot Type】選擇“BEE (Signed) Encrypted XIP Image Boot”,點選【Browse】按鈕選擇一個原始image檔案(必須是XIP在FlexSPI NOR中的image),【Key Storage Region】選擇“Flexible User Keys”後點擊【Advanced Key Settings】按鈕配置所有BEE加密的引數,最後點選【All-In-One Action】按鈕即可完成bootable image生成與下載所有操作。
  有必要對如下使用Flexible User Keys加密的BEE引數設定頁面再做一下介紹,首先是選擇要啟用的BEE引擎,可以單獨啟用BEE引擎0,也可以單獨啟用BEE引擎1,當然更可以同時啟用BEE引擎0和1,本示例同時啟用BEE引擎0和1。指定了BEE引擎後需要進一步為該引擎配置加密所使用的Key的儲存空間以及需要使用者手動輸入Key(128bits)。最後還需要設定加密保護的區域,本示例共使能加密2個區域,分別為0x60001000 - 0x60001fff(由BEE引擎0保護),0x60002000 - 0x60002fff(由BEE引擎1保護)。

  上圖中Step5操作主要確認兩點:一、BEE_KEY0_SEL是否設定正確(Fuse 0x460[31:0]的bit13,12)和BEE_KEY1_SEL是否設定正確(Fuse 0x460[31:0]的bit15,14);二、使用者Key是否被正確燒錄(SW_GP2: Fuse 0x690 - 0x6c0,GP4: Fuse 0x8c0 - 0x8f0)。
  為了確認image是否按指定區域加密,你可以開啟\nxp-sec-boot\gen\bootable_image\資料夾下面生成的未加密bootable image檔案與image回讀窗口裡的內容進行比對。
  一切操作無誤,板子上SW7撥碼開關將Boot Mode設為2'b10即Internal Boot模式,並且將BT_CFG[1]設為1'b1(使能Encrypted XIP),其餘保持全0,重新上電便可以看到BEE encrypted image正常執行了。
  雙引擎BEE加密是將使用者自定義的Key燒錄進了Fuse SW_GP2/GP4區域裡,但該區域的Fuse內容是可以回讀的,如果黑客拿到Key,還是有可能破解存在外部Boot Device裡的image密文,有沒有對Fuse SW_GP2/GP4區域進行保護的方法?當然有,你可以對指定的Fuse區域進行加鎖,可設定Fuse區域訪問許可權(讀保護,防寫,覆蓋保護),具體後面有單獨章節詳細介紹。
  雙引擎BEE加密相比單引擎BEE加密,從破解角度來說難度加倍,畢竟可以啟用兩組不同的Key來共同保護image不被非法獲取。

2.3.6 模式六:啟用HAB簽名認證與BEE加密

  第六種模式是頂級的安全模式,即對image進行HAB簽名認證以及BEE級加密(單引擎/雙引擎均可),一般用於對產品安全性要求最高的場合。模式四以及模式五均只有加密功能,並沒有對image進行合法性檢測,引入HAB簽名認證可以解決image合法性問題。

  【Secure Boot Type】選擇“BEE (Signed) Encrypted XIP Image Boot”,【Enable Certificate For BEE Encryption】選擇“Yes”並點選【Advanced Cert Settings】按鈕配置所有簽名認證的引數,點選【Browse】按鈕選擇一個原始image檔案(必須是XIP在FlexSPI NOR中的image),【Key Storage Region】選擇“Fixed SNVS Key”或者“Flexible User Keys”均可並點選【Advanced Key Settings】按鈕配置所有BEE加密的引數,最後點選【All-In-One Action】按鈕即可完成bootable image生成與下載所有操作。

  一切操作無誤,板子上SW7撥碼開關將Boot Mode設為2'b10即Internal Boot模式,並且將BT_CFG[1]設為1'b1(使能Encrypted XIP),其餘保持全0,重新上電便可以看到BEE encrypted image正常執行了。
  需要特別注意的是,因為引入了HAB簽名認證,如果BEE加密Key選擇的是Fixed SNVS Key,需要在HAB Closed的狀態下執行上述操作,否則會啟動失敗,這是HAB與BEE聯合使用的限制。

3 軟體進階

  nxpSecBoot軟體開啟預設工作在Entry Mode下,可通過功能選單欄Tools->Option選擇進入Master Mode,在Master模式下開放了一些高階功能,適用於對NXP MCU晶片以及Boot ROM非常熟悉的使用者。

3.1 玩轉Fuse操作

  進入Master模式下,可以看到Fuse全部區域都開放了,你可以任意燒寫指定的Fuse區域。Fuse操作是按bit一次性的(類似熔絲燒斷),只能將0燒寫成1,燒錄成1之後便無法更改,所以Fuse的操作需要特別謹慎。

  在上一章節安全加密啟動過程中,我們會燒錄SRKH(0x580 - 0x5f0)、SW_GP2(0x690 - 0x6c0)、GP4(0x8c0 - 0x8f0),這些區域一經燒錄便不得更改,甚至我們希望這些區域不僅不能被更改,也要不能被回讀。

  從上圖可知Fuse 0x400即是各Fuse功能區域的Locker,我們可以通過燒錄Fuse 0x400來鎖住SRKH, SW_GP2, GP4區域。那麼如何燒錄呢?其實非常簡單,直接在各Fuse框內填寫想要燒錄的值,點選【Burn】按鈕即可。