Yocto layer 使用 TI AM62 安全啟動功能
簡介
Arm 處理器的 Secure Boot 安全啟動功能能夠有效防止在設備上運行非授權的或者惡意竄改的固件。Secure Boot 系統在啟動時會使用燒錄的處理器上的密鑰驗證 Bootloader,Bootloader 會驗證 kernel FIT 鏡像,而 kernel 繼續驗證 rootfs 的有效性。這一逐個驗證的流程成為 Chain of Trust。用戶如果使用傳統方法使用啟動功能需用需要依次實現上述的每個環節。借助meta-toradex-securitylayer,只要幾行簡單的配置即可實現。
生成密鑰
安全啟動依賴于匹配的密鑰對來驗證軟件。要啟用安全啟動,您需要將公鑰燒錄到設備的 OTP 存儲器中。該密鑰必須與用于簽名已驗證固件的私鑰相匹配。
TI 設備使用三組密鑰對實現安全啟動:
MEK(Manufacture Encryption Key):由 TI 提供并永久燒錄至 SoC 中,用于驗證 TI 簽名軟件且不可更改。
SMPK(Secondary Manufacture Public Key):由用戶創建并燒錄到設備中,用于驗證用戶生成的引導加載程序的簽名。
BMPK(Backup Manufacture Public Key):可選的用戶生成備份密鑰。若 SMPK 丟失或遭泄露,系統可重新配置為使用 BMPK 來驗證引導加載程序的簽名。
SMPK 和 BMPK 用于簽名引導加載程序,因此該密鑰的生成和管理必須謹慎處理,并做和完善的備份。
在寫該文章時生成密鑰需要使用 OpenSSL 1.1.1 版本,除非 TI 在后續新版本軟件中注明,否則請使用openssl version命令查看當前系統的 OpenSSL 版本。如果本版不匹配,可以使用下面命令在 Linux 系統安裝。
$ wget https://ftp.debian.org/debian/pool/main/o/openssl/ openssl_1.1.1w-0+deb11u1_amd64.deb $ wget http://ftp.debian.org/debian/pool/main/o/openssl/ libssl1.1_1.1.1w-0+deb11u1_amd64.deb $ sudo apt install ./libssl1.1_1.1.1w-0+deb11u1_amd64.deb ./openssl_1.1.1w-0+deb11u1_amd64.deb
設置環境變量。由于后續的 TI MCU SDK 和 OPT Keywriter 的編譯也需要使用到這些密鑰,請勿更新這些變量的參數。
$ export KEYS_DIR=~/keys/ti $ export SMPK_NAME=custMpk $ export BMPK_NAME=backMpk
創建密鑰生成的路徑。
$ mkdir -p "${KEYS_DIR}" && cd "${KEYS_DIR}"
生成 RSA-4096 的 SMPK 密鑰對 SSL 證書。
$ openssl genrsa -F4 -out ${SMPK_NAME}.key 4096 $ cp ${SMPK_NAME}.key ${SMPK_NAME}.pem $ openssl req -batch -new -x509 -key ${SMPK_NAME}.key -out ${SMPK_NAME}.crt
生成 RSA-4096 的 BMPK 密鑰對 SSL 證書。
$ openssl genrsa -F4 -out ${BMPK_NAME}.key 4096 $ cp ${BMPK_NAME}.key ${BMPK_NAME}.pem $ openssl req -batch -new -x509 -key ${BMPK_NAME}.key -out ${BMPK_NAME}.crt
生成 ti-degenerate-key。
$ openssl genrsa -F4 -out ti-degenerate-key.pem 4096
生成 AES-256 加密密鑰。
$ openssl rand -out aes256.key 32 $ openssl rand -out bmek.key 32 $ openssl rand -out smek.key 32
刪除密鑰和證書的可寫權限。
$ chmod a-w *
Yocot Project 配置
和之前的文章一樣,首先需要搭建Yocto Project 編譯環境。這里我們將以基于 TI AM62 SoC 的 Verdin AM62 模塊為例進行介紹。在 local.conf 的結尾添加下面兩行配置即可。
INHERIT += "tdx-signed" TDX_K3_SECBOOT_TARGET_HSSE_DEVICE = "1"
在編譯鏡像時,用于簽名啟動引導程序的密鑰默認從 Ycoto 編譯目錄的 ${TOPDIR}/keys/ti 位置尋找。可以在 Yocto 的 build 目錄下創建 keys/ti 目錄,將上面在 ~/keys/ti 中生成的所有文件都復制過來。在 build 目錄下會有以下文件夾。
tree -L 1 . |-- buildhistory |-- cache |-- conf |-- deploy |-- keys |-- tmp `-- tmp-k3r5
INHERIT可以使用tdx-signed和tdxref-signed兩個參數。
tdxref-signed:生成的鏡像將啟用 Bootloader 簽名驗證、U-Boot 安全加固、FIT 鏡像簽名驗證、Rootfs 簽名驗證所有功能。
tdx-signed:除"Rootfs 簽名校驗"外,其余功能全部啟用。若無需通過 dm-verity 保護根文件系統,此類模式可能比 tdxref-signed 更適用。
用于 FIT 鏡像簽名的密鑰位于 ${TOPDIR}/keys/ti/fit 目錄下。同樣建議妥善管理這些密鑰。
tree keys -L 1 keys |-- fit `-- ti
TDX_K3_SECBOOT_TARGET_HSSE_DEVICE設置為 0 時,編譯的鏡像能夠在沒有 fuse 的 AM62 模塊上運行。這通常用于前期開發測試階段。當設置為 1 時,生成的鏡像只能運行在 fused AM62 模塊上。生產環節批量燒錄系統時,則使用該鏡像。為了后續演示整個流程,這里編譯鏡像時設置為 1。
然后使用 bitbake 命令編譯鏡像即可。整個過程就這么簡單,
bitbake tdx-reference-minimal-image
編譯 OTP Keywriter
AM62 SoC 借助 OTP Keywriter 固件將用于安全啟動期間使用的密鑰燒錄到處理器的寄存器。這些寄存器是一次性燒錄,且不可撤銷,請謹慎操作。
編譯 OTP keywriter 需要安裝下面軟件,其中 OTP Keywriter 需要向 TI 申請,通常數個工作日可以通過。具體下載地址參考該網頁。主要注意的是,在寫該文章時編譯 OTP keywriter 需要使用 MCU Plus SDK v9 版本,v10 版本編譯的 OTP keywriter 還無法在 AM62 上運行。安裝時請使用默認安裝路徑,否則可能導致編譯失敗。
MCU Plus SDK
Code Composer Studio
SysConfig
OTP Keywriter
進入 OTP keywriter 編譯目錄
$ cd ~/ti/mcu_plus_sdk_am62x_09_01_00_43/source/security/ sbl_keywriter/am62x-sk/r5fss0-0_nortos
下載并打上下面補丁。
$ wget https://docs.toradex.cn/private/116128-verdin-am62v1.2-vpp.patch $ git apply 116128-verdin-am62v1.2-vpp.patch
進入 ti-arm-clang 目錄即可編譯。成功后可以看到 tiboot3.bin 文件。
$ cd ~/ti/mcu_plus_sdk_am62x_09_01_00_43/source/security/ sbl_keywriter/am62x-sk/r5fss0-0_nortos/ti-arm-clang
$ make -sj clean PROFILE=debug $ make -sj PROFILE=debug
運行 OTP Keywriter
Verdin AM62 模塊上可以通過恢復模式或者從 eMMC 上加載 bootloader 并運行 OTP Keywriter 燒錄密鑰寄存器。恢復模式需要將 Verdin AM62 通過 USB OTG 接口連接到電腦,并在電腦上運行相關指令。Bootloader 也可以通過 Toradex Easy Installer 寫入到 eMMC 上啟動分區,模塊上電啟動后從 eMMC 加載 bootloader。前者適合開發期間使用,后者由于無需 PC,更適合于批量燒寫流程。
從恢復模式加載 bootloader
在 PC 上安裝 dfu-util。
$ sudo apt install dfu-util
然后運行:
$ sudo dfu-util -c 1 -i 0 -a bootloader -D tiboot3.bin
運行成功后 Verdin AM62 將從 HS-FS 變為 HS-SE 模式,即啟用安全啟動功能。在下一次啟動時將會加載前面生成的簽名鏡像。
從 eMMC 加載 bootloader
Verdin AM62 的 eMMC 具有兩個啟動分區,mmcblk0boot0 和 mmcblk0boot1。包含 OTP Keywriter 的 tiboot3.bin bootloader 首先會被燒錄在 mmcblk0boot0。常規啟動的 bootloader tiboot3-am62x-hs-verdin.bin 會被燒錄到 mmcblk0boot1 分區,其包含在 Yocto Project 生成的鏡像中。首次啟動時加載 mmcblk0boot0 上的 bootloader 運行 OTP Keywriter 完成密鑰寄存器燒錄。同時配置 eMMC EXTCSD register[179],將 設置 mmcblk0boot1 為默認啟動分區。這樣在下一次啟動時,即可加載 mmcblk0boot1 上常規 bootloader,隨后加載 U-boot。
MCU SDK 中已經有 MMC 的驅動,因此,只需要在 OTP Keywritter 代碼中調用MMCSD_enableBootPartition()即可。在之前的 OTP Keywritter 中打上下面補丁并重新編譯。
$ wget https://docs.toradex.cn/117166-verdin-am62-fuse-switch-bootpart2.patch $ git apply 117166-verdin-am62-fuse-switch-bootpart2.patch
修改 Yocto Project 生成的簽名鏡像中的 image.json 文件,將原來的 "name": "mmcblk0boot0"改為 "name": "mmcblk0boot1",。
{ "name": "mmcblk0boot1", "erase": true, "content": { "filesystem_type": "raw", "rawfiles": [ { "filename": "tiboot3-am62x-gp-verdin.bin", "dd_options": "seek=0", "product_ids": "0069"
在新加一個 "name": "mmcblk0boot0"分區配置,"product_ids": "0074"時需要燒錄的 PID4,"filename": "tiboot3.bin"為重新編譯生成的 bootloader。
{ "name": "mmcblk0boot0", "erase": true, "content": { "filesystem_type": "raw", "rawfiles": [ { "filename": "tiboot3.bin", "dd_options": "seek=0", "product_ids": "0074" } ] } },
燒錄完成后,Verdin AM62 第一次啟動時將從 HS-FS 變為 HS-SE 模式,即啟用安全啟動功能。在下一次啟動時將會從 mmcblk0boot1 加載前面生成的簽名鏡像。在 Linux 系統啟動后,可以刪除 mmcblk0boot0 上的 bootloader 文件。
總結
借助 meta-toradex-security,用戶能夠輕松地使用模塊的安全啟動功能。更多來自 meta-toradex-security 實用功能,我們將在后續文章介紹,敬請關注。

提交
定制 Linux Kernel Driver 編譯示例
在 NXP i.MX 95 上運行 Zephyr 實現非對稱多核處理
HDMI 顯示器熱插拔對應顯示應用啟停測試
Yocto meta-toradex-security layer 創建加密數據分區應用說明
NXP iMX8MP ARM 平臺多屏幕克隆顯示測試