發(fā)環(huán)境搭建實(shí)戰(zhàn):OP-TEE與BoostKit配置指南)
做安全開(kāi)發(fā)越久越覺(jué)得可信執(zhí)行環(huán)境是個(gè)繞不開(kāi)的坎。無(wú)論是密鑰管理、生物特征校驗(yàn)還是支付類業(yè)務(wù)普通操作系統(tǒng)里的“安全”再怎么做都躲不過(guò)一個(gè)終極問(wèn)題攻擊者一旦拿下了內(nèi)核權(quán)限你所有的防護(hù)都是紙糊的。ARM提出TrustZone的思路就是把CPU一刀切成兩個(gè)世界——正常世界和安全世界敏感邏輯直接搬進(jìn)安全世界運(yùn)行。華為的iTrustee就是基于這套硬件隔離機(jī)制打造的企業(yè)級(jí)TEE方案而B(niǎo)oostKit則是讓TEE場(chǎng)景在新的硬件平臺(tái)上跑得更快、性能更穩(wěn)的加速套件。這篇文章我不扯太多理論直接帶你把TrustZone開(kāi)發(fā)環(huán)境從零搭起來(lái)跑通第一個(gè)TATrusted Application可信應(yīng)用順便把BoostKit的配置技巧一起梳理清楚。不管你是剛接觸TEE的新人還是準(zhǔn)備把業(yè)務(wù)遷移到可信環(huán)境里的工程師都可以直接照著做。整個(gè)流程我盡量控制在最快路徑上5分鐘指的是“已經(jīng)準(zhǔn)備好依賴、按腳本一鍵拉起”的場(chǎng)景如果你要從零編譯整套系統(tǒng)那還得留出半小時(shí)到一小時(shí)這部分我也會(huì)把時(shí)間花在哪兒、為什么這么慢講明白。1. 內(nèi)容整體設(shè)計(jì)與思路拆解1.1 為什么要“自己動(dòng)手”搭 TrustZone 環(huán)境做TEE相關(guān)開(kāi)發(fā)最怕兩件事第一真機(jī)上的安全世界刷壞了很難恢復(fù)尤其涉及到efuse、OTP這類一次性燒寫(xiě)區(qū)域操作失誤可能就是整塊板子報(bào)廢第二業(yè)務(wù)側(cè)還沒(méi)定型需要頻繁改內(nèi)核、改設(shè)備樹(shù)、調(diào)共享內(nèi)存布局如果用真機(jī)做這些事效率會(huì)低到讓人抓狂。所以絕大多數(shù)團(tuán)隊(duì)都會(huì)先在模擬器或者開(kāi)發(fā)板/云實(shí)例上搭一套可復(fù)現(xiàn)的TrustZone開(kāi)發(fā)環(huán)境把TA開(kāi)發(fā)和CAClient Application客戶端應(yīng)用開(kāi)發(fā)流程跑通再遷移到最終硬件上。這套環(huán)境要解決的核心問(wèn)題有三個(gè)一是能編譯出安全世界的固件鏡像也就是TEE OS二是能啟動(dòng)包含普通世界Linux內(nèi)核的完整系統(tǒng)三是能在系統(tǒng)里安裝TA、運(yùn)行CA并驗(yàn)證兩者的安全通信。在這篇文章里我用的載體是ARM體系下最經(jīng)典、也最容易復(fù)現(xiàn)的TrustZone軟件棧組合QEMU虛擬平臺(tái) OP-TEE作為開(kāi)源TEE OS參考實(shí)現(xiàn)同時(shí)會(huì)在業(yè)務(wù)側(cè)介紹華為iTrustee和BoostKit的銜接方式。有人可能會(huì)問(wèn)iTrustee不是華為自研的嗎怎么用OP-TEE來(lái)講這里先解釋一下iTrustee遵循GlobalPlatform TEE標(biāo)準(zhǔn)體系TA/CA的開(kāi)發(fā)接口與OP-TEE高度一致而且OP-TEE本身就是業(yè)界最通用的TEE參考實(shí)現(xiàn)。用OP-TEE把開(kāi)發(fā)流程跑通再遷移到iTrustee平臺(tái)是實(shí)際項(xiàng)目里非常主流的路徑。1.2 iTrustee、TrustZone與OP-TEE的關(guān)系要理解這三個(gè)詞可以打一個(gè)比方TrustZone是ARM在CPU硬件層面畫(huà)出的一條“隔離紅線”它把處理器分成Normal World普通世界和Secure World安全世界普通世界跑Linux/Android安全世界跑專門(mén)的TEE OS兩邊通過(guò)SMC指令進(jìn)行切換。iTrustee是華為基于TrustZone機(jī)制實(shí)現(xiàn)的企業(yè)級(jí)TEE操作系統(tǒng)它負(fù)責(zé)在安全世界里管理可信應(yīng)用、密鑰存儲(chǔ)、安全啟動(dòng)等能力。因?yàn)樗巧虡I(yè)產(chǎn)品并不完全開(kāi)源普通開(kāi)發(fā)者拿不到完整的TEE OS源碼來(lái)自己編譯一個(gè)一模一樣的iTrustee鏡像但iTrustee提供標(biāo)準(zhǔn)化的TA運(yùn)行環(huán)境和Client API接口開(kāi)發(fā)出來(lái)的TA是可以直接部署上去的。OP-TEE則是開(kāi)源社區(qū)里最完整的TEE OS參考實(shí)現(xiàn)由Linaro維護(hù)支持QEMU、樹(shù)莓派、各種開(kāi)發(fā)板和部分服務(wù)器平臺(tái)。它的代碼風(fēng)格、接口設(shè)計(jì)、構(gòu)建方式都很規(guī)范而且同樣遵循GlobalPlatform標(biāo)準(zhǔn)。所以業(yè)界普遍的做法是用OP-TEE環(huán)境做開(kāi)發(fā)調(diào)試驗(yàn)證確認(rèn)邏輯沒(méi)問(wèn)題后再按iTrustee的TA簽名、加載規(guī)范打包部署到華為平臺(tái)上。這篇文章的實(shí)操部分會(huì)以O(shè)P-TEE為主線但所有開(kāi)發(fā)思路對(duì)iTrustee同樣適用。1.3 BoostKit在整體方案里的角色BoostKit是華為面向特定服務(wù)器平臺(tái)推出的應(yīng)用加速與性能調(diào)優(yōu)套件它的定位不是替代TEE而是讓跑在TEE場(chǎng)景下的業(yè)務(wù)更“省力”。舉個(gè)例子你在安全世界里做一次AES-GCM加解密如果沒(méi)有做任何優(yōu)化CPU可能要用軟實(shí)現(xiàn)方式一條條指令去算延遲和吞吐都很難看但如果你用的底層庫(kù)能自動(dòng)切入ARM的硬件加密擴(kuò)展指令比如ARMv8-A的Cryptography Extensions性能數(shù)據(jù)可能直接翻倍。所以在整體方案里TrustZone解決的是“安全隔離”問(wèn)題iTrustee解決的是“可信應(yīng)用怎么跑”的問(wèn)題BoostKit解決的是“在可信場(chǎng)景下怎么保持高性能”的問(wèn)題。三者配合起來(lái)才是真正能落地的企業(yè)級(jí)方案。后面第4章我會(huì)專門(mén)說(shuō)BoostKit的配置細(xì)節(jié)這里先建立整體認(rèn)知框架。2. 環(huán)境準(zhǔn)備與工具鏈選型2.1 硬件平臺(tái)怎么選模擬器、開(kāi)發(fā)板還是云實(shí)例搭建TrustZone環(huán)境硬件選型會(huì)直接影響開(kāi)發(fā)效率和后期部署路徑。我列個(gè)對(duì)比表方便你按自己情況選。平臺(tái)類型代表方案優(yōu)點(diǎn)缺點(diǎn)適合場(chǎng)景全系統(tǒng)模擬器QEMUqemu-virt/qemu_sbsa成本為零環(huán)境可腳本化重建支持?jǐn)帱c(diǎn)調(diào)試壞了隨時(shí)重來(lái)性能偏低部分硬件特性如RPMB靠軟件模擬學(xué)習(xí)驗(yàn)證、TA/CA邏輯開(kāi)發(fā)、CI集成ARM開(kāi)發(fā)板樹(shù)莓派3B/4B、Rockchip系列真實(shí)物理環(huán)境能驗(yàn)證真實(shí)硬件行為需要額外采購(gòu)硬件SD卡燒錄和串口調(diào)試稍麻煩接近真機(jī)驗(yàn)證、外設(shè)交互測(cè)試華為云鯤鵬實(shí)例鯤鵬云服務(wù)器可部署B(yǎng)oostKit原生ARMv8-A環(huán)境能直接安裝BoostKit性能參考價(jià)值高需要云資源費(fèi)用調(diào)試系統(tǒng)鏡像沒(méi)有QEMU方便業(yè)務(wù)預(yù)研、性能壓測(cè)、方案匯報(bào)我的建議比較直接如果你是第一次接觸TEE或者只想把TA開(kāi)發(fā)流程搞清楚直接用QEMU就夠了別一上來(lái)就買板子如果你已經(jīng)在華為生態(tài)里做方案交付那就開(kāi)一臺(tái)鯤鵬實(shí)例把OP-TEE先在QEMU上跑通邏輯再到鯤鵬實(shí)例上裝BoostKit做性能對(duì)比。兩條路徑并不沖突反而能覆蓋“開(kāi)發(fā)—驗(yàn)證—調(diào)優(yōu)”全流程。2.2 軟件依賴安裝我以Ubuntu 22.04 LTS為例先裝基礎(chǔ)依賴。命令如下sudo apt update sudo apt install -y \ build-essential \ git \ wget \ curl \ python3 \ python3-pip \ cmake \ make \ gcc \ g \ pkg-config \ libssl-dev \ uuid-dev \ device-tree-compiler \ bc \ cpio \ flex \ bison \ libncurses-dev \ acpica-tools這里有幾個(gè)包特別容易漏我單獨(dú)說(shuō)一下device-tree-compiler編譯設(shè)備樹(shù)二進(jìn)制.dtb必須用漏裝會(huì)在編譯內(nèi)核時(shí)突然報(bào)錯(cuò)“dtc: command not found”。uuid-devTA和CA代碼里會(huì)用到UUID生成和操作接口沒(méi)裝會(huì)在鏈接階段報(bào)uuid相關(guān)錯(cuò)誤。cpio制作initramfs時(shí)需要OP-TEE標(biāo)準(zhǔn)構(gòu)建流程會(huì)用到。裝完基礎(chǔ)依賴后還需要安裝交叉編譯工具鏈因?yàn)槲覀円趚86主機(jī)上編譯出ARM64架構(gòu)的鏡像sudo apt install -y gcc-aarch64-linux-gnu g-aarch64-linux-gnu這里強(qiáng)調(diào)一下交叉編譯工具鏈版本盡量和發(fā)行版自帶版本保持一致不要手動(dòng)下載過(guò)新或過(guò)舊的aarch64工具鏈否則編譯內(nèi)核時(shí)容易出現(xiàn)隱晦的鏈接錯(cuò)誤排查起來(lái)非常浪費(fèi)時(shí)間。2.3 源碼獲取TEE OS、客戶端、測(cè)試套件與內(nèi)核搭建TrustZone開(kāi)發(fā)環(huán)境本質(zhì)上需要四類源碼配合TEE OS本體optee_os安全世界運(yùn)行的內(nèi)核TEE客戶端庫(kù)optee_client普通世界的用戶態(tài)庫(kù)CA調(diào)用TA時(shí)通過(guò)它進(jìn)入安全世界TEE測(cè)試套件optee_test用于驗(yàn)證TEE功能是否正常Linux內(nèi)核與引導(dǎo)固件普通世界系統(tǒng)以及負(fù)責(zé)安全世界啟動(dòng)的ATFARM Trusted Firmware我建議直接用OP-TEE官方維護(hù)的manifest倉(cāng)庫(kù)來(lái)拉取一套版本匹配的源碼避免自己手動(dòng)組合版本導(dǎo)致接口對(duì)不上。通過(guò)repo工具拉取sudo apt install -y repo mkdir -p ~/optee cd ~/optee repo init -u https://github.com/OP-TEE/manifest.git -m qemu_v8.xml repo sync -j4如果你的網(wǎng)絡(luò)環(huán)境拉取GitHub比較慢也可以訪問(wèn)國(guó)內(nèi)鏡像源或者使用代理工具具體手段自己按實(shí)際網(wǎng)絡(luò)情況選擇我這里不展開(kāi)。repo sync的過(guò)程會(huì)花一些時(shí)間因?yàn)橐瑫r(shí)拉取optee_os、optee_client、optee_test、atf、u-boot、linux等多個(gè)倉(cāng)庫(kù)。首次同步后建議把整目錄打成壓縮包備份以后環(huán)境搞壞了直接解壓恢復(fù)能省很多時(shí)間。3. 5分鐘快速搭建 TrustZone 開(kāi)發(fā)環(huán)境的實(shí)操記錄3.1 快速路徑用構(gòu)建腳本一鍵拉起完整環(huán)境先說(shuō)一個(gè)反直覺(jué)的結(jié)論真正到實(shí)戰(zhàn)階段5分鐘是可以做到的但前提是你已經(jīng)走完了源碼同步和依賴安裝這兩步。OP-TEE倉(cāng)庫(kù)里面提供了一個(gè)build目錄里面封裝好了qemu_v8這個(gè)目標(biāo)平臺(tái)的全部編譯流程我們要做的事情其實(shí)很簡(jiǎn)潔cd ~/optee/build make -j$(nproc)這條命令會(huì)自動(dòng)編譯ATF、U-Boot、OP-TEE OS、Linux內(nèi)核、optee_client和optee_test最終生成一個(gè)可以直接啟動(dòng)的QEMU虛擬化固件包。第一次執(zhí)行時(shí)因?yàn)橐獜牧憔幾gLinux內(nèi)核和ATF根據(jù)機(jī)器配置不同通常需要30到60分鐘這是正?,F(xiàn)象不要中途打斷。但在“已經(jīng)緩存了編譯產(chǎn)物”的情況下后續(xù)每次增量編譯確實(shí)能控制在幾分鐘內(nèi)。我實(shí)測(cè)過(guò)如果只是改了一個(gè)TA文件或者改了optee_os里某個(gè)模塊make -j8重新編譯大約只需2到4分鐘。這就是“5分鐘搭建”的真實(shí)含義它指的是快速迭代能力而不是第一次從零編譯的速度。想更進(jìn)一步提速可以用ccachesudo apt install -y ccache export PATH/usr/lib/ccache:$PATH cd ~/optee/build make -j$(nproc)加了ccache之后相同配置的重復(fù)編譯能減少50%以上的時(shí)間第二次再編譯時(shí)明顯更快。熟悉這套流程后體驗(yàn)基本就是“喝完一杯水環(huán)境已經(jīng)重新拉好了”。3.2 從源碼編譯optee_os與ATF版本匹配是硬底線雖然一鍵腳本很方便但你還是需要知道底層到底在編譯什么否則遇到問(wèn)題只能干瞪眼。腳本的核心編譯步驟可以拆分來(lái)看ATF負(fù)責(zé)在啟動(dòng)階段完成EL3最高特權(quán)層的初始化然后跳轉(zhuǎn)到OP-TEE OSOP-TEE OS運(yùn)行在安全世界負(fù)責(zé)初始化安全中斷、共享內(nèi)存、TA加載等功能U-Boot負(fù)責(zé)引導(dǎo)Linux內(nèi)核進(jìn)入普通世界。如果手動(dòng)編譯ATF和OP-TEE OS需要保證兩個(gè)倉(cāng)庫(kù)的版本匹配尤其是涉及平臺(tái)端口定義時(shí)接口簽名不一致會(huì)導(dǎo)致安全世界啟動(dòng)后立刻崩潰。用官方manifest拉取的是一整套經(jīng)過(guò)測(cè)試的固定版本組合這就是為什么我強(qiáng)烈推薦用manifest而不是自己自由組合各倉(cāng)庫(kù)版本。# 如果手動(dòng)編譯ATF典型命令如下僅示意實(shí)際以build腳本為準(zhǔn) make -C atf \ PLATFORMqemu \ SPDopteed \ BL32/path/to/optee_os/build/arm-plat-qemu/core/tee.bin關(guān)鍵參數(shù)理解SPDopteed表示ATF啟動(dòng)后要引導(dǎo)OP-TEE作為安全世界負(fù)載BL32指向OP-TEE編譯出來(lái)的tee.bin這是安全世界鏡像PLATFORMqemu指定ATF適配的虛擬平臺(tái)。我自己第一次手動(dòng)編譯時(shí)就是漏了SPDopteed結(jié)果ATF啟動(dòng)后完全找不到安全世界鏡像系統(tǒng)一直停留在EL3不動(dòng)串口日志只打到一半就卡死。如果你也遇到類似問(wèn)題優(yōu)先檢查這幾個(gè)參數(shù)。3.3 Linux內(nèi)核配置、設(shè)備樹(shù)與安全內(nèi)存預(yù)留普通世界的Linux內(nèi)核不是隨便編一編就能和TEE配合的需要在內(nèi)核配置里打開(kāi)兩個(gè)關(guān)鍵選項(xiàng)CONFIG_ARM64_VA_BITS48 CONFIG_DMA_CMAy前者保證地址空間足夠容納安全世界預(yù)留內(nèi)存后者確保連續(xù)內(nèi)存分配器正常工作。更重要的是設(shè)備樹(shù)里需要給安全世界預(yù)留物理內(nèi)存區(qū)域讓TEE OS和Linux不會(huì)互相踩踏。參考QEMU平臺(tái)設(shè)備樹(shù)里的預(yù)留節(jié)點(diǎn)reserved-memory { #address-cells 2; #size-cells 2; ranges; optee_core0x40000000 { reg 0x0 0x40000000 0x0 0x02000000; no-map; }; };no-map屬性非常關(guān)鍵它告訴Linux內(nèi)核這塊內(nèi)存不要做頁(yè)表映射只能由安全世界直接管理。如果你改內(nèi)存大小時(shí)把這兩個(gè)十六進(jìn)制數(shù)字寫(xiě)錯(cuò)了啟動(dòng)時(shí)會(huì)出現(xiàn)“Unhandled memory reservation”之類的報(bào)錯(cuò)或者OP-TEE初始化時(shí)找不到自己的內(nèi)存區(qū)域。不過(guò)使用build腳本自動(dòng)編譯時(shí)這些配置都已經(jīng)由預(yù)設(shè)的defconfig和設(shè)備樹(shù)模板準(zhǔn)備好了你不需要手動(dòng)改。這里講出來(lái)只是為了讓你在換成自己的開(kāi)發(fā)板時(shí)知道要從哪些方向下手。3.4 啟動(dòng)QEMU并確認(rèn)安全世界正常加載編譯完成后啟動(dòng)系統(tǒng)的方式也很簡(jiǎn)單cd ~/optee/build make run這個(gè)命令會(huì)拉起QEMU窗口或者通過(guò)串口重定向輸出日志。啟動(dòng)日志里如果出現(xiàn)類似下面這些關(guān)鍵信息說(shuō)明TrustZone環(huán)境已經(jīng)正常I/TC: OP-TEE version: 3.x.x I/TC: Initialized I/TC: Secure world initialized successfully I/TC: Warning: RPMB not supportedRPMB not supported在QEMU下是正常提示因?yàn)樘摂M平臺(tái)沒(méi)有模擬eMMC的Replay Protected Memory Block不用慌張。接下來(lái)在Linux終端里運(yùn)行測(cè)試套件optee_test xtest正常時(shí)你會(huì)看到一長(zhǎng)串測(cè)試用例輸出并在最后出現(xiàn)類似[PASSED]或測(cè)試通過(guò)率的匯總信息。我第一次跑通時(shí)看到一屏一屏的PASS日志心里的石頭才真正落地。這個(gè)階段通過(guò)后就說(shuō)明普通世界和安全世界之間的通信通道已經(jīng)打通TA加載和運(yùn)行的基本鏈路都是好的。4. iTrustee TA/CA開(kāi)發(fā)快速上手與BoostKit配置技巧4.1 第一個(gè)TA的開(kāi)發(fā)流程從Hello World到真實(shí)業(yè)務(wù)環(huán)境跑通后真正的重頭戲是寫(xiě)TA。TA是運(yùn)行在安全世界里的應(yīng)用它的開(kāi)發(fā)模型和普通Linux應(yīng)用完全不同必須要遵循GlobalPlatform TEE標(biāo)準(zhǔn)。一個(gè)最小TA的目錄結(jié)構(gòu)大致如下hello_world_ta/ ├── Makefile ├── include/ │ └── hello_world_ta.h ├── src/ │ └── ta_entry.c └── user_ta_header_defines.h重點(diǎn)看ta_entry.c所有TA的入口核心都在這里#include tee_internal_api.h #include tee_internal_api_extensions.h #include hello_world_ta.h static TEE_Result invoke_command( uint32_t cmd_id, uint32_t param_types, TEE_Param params[4]) { switch (cmd_id) { case CMD_HELLO_WORLD: /* 業(yè)務(wù)邏輯寫(xiě)在這里比如對(duì)輸入?yún)?shù)做哈希返回摘要 */ return TEE_SUCCESS; default: return TEE_ERROR_BAD_PARAMETERS; } } TEE_Result TA_CreateEntryPoint(void) { return TEE_SUCCESS; } void TA_DestroyEntryPoint(void) { } TEE_Result TA_InvokeCommandEntryPoint( uint32_t cmd_id, uint32_t param_types, TEE_Param params[4]) { return invoke_command(cmd_id, param_types, params); }這里最關(guān)鍵的接口規(guī)則是TA的入口函數(shù)名是固定的TA_CreateEntryPoint、TA_DestroyEntryPoint、TA_InvokeCommandEntryPoint這三個(gè)符號(hào)必須導(dǎo)出TEE OS在加載TA時(shí)會(huì)通過(guò)這幾個(gè)符號(hào)完成生命周期管理。我見(jiàn)過(guò)很多新手在重構(gòu)代碼時(shí)把函數(shù)名改動(dòng)一下結(jié)果TA加載時(shí)直接報(bào)“Symbol not found”。在iTrustee平臺(tái)上開(kāi)發(fā)TA時(shí)接口思路完全一樣只是編譯和簽名工具鏈換成華為提供的iTrustee開(kāi)發(fā)者工具包。通常流程是先在OP-TEE環(huán)境里把TA邏輯寫(xiě)正確、測(cè)試通過(guò)再按iTrustee的簽名規(guī)范對(duì)TA文件進(jìn)行簽名然后通過(guò)平臺(tái)指定的部署方式安裝。這樣最大程度復(fù)用開(kāi)發(fā)經(jīng)驗(yàn)也降低了安全審核的返工成本。4.2 CA側(cè)如何調(diào)用TA建立上下文與參數(shù)傳遞只有TA沒(méi)有CA整個(gè)業(yè)務(wù)流程是跑不起來(lái)的。CA運(yùn)行在普通世界它通過(guò)libteec庫(kù)與TEE客戶端驅(qū)動(dòng)交互再經(jīng)過(guò)OP-TEE驅(qū)動(dòng)進(jìn)入安全世界。最小CA調(diào)用邏輯如下#include tee_client_api.h #include hello_world_ta.h int main(void) { TEEC_Context ctx; TEEC_Session session; TEEC_Operation op; uint32_t origin 0; TEEC_Result res; res TEEC_InitializeContext(NULL, ctx); if (res ! TEEC_SUCCESS) return -1; res TEEC_OpenSession(ctx, session, HELLO_WORLD_TA_UUID, TEEC_LOGIN_PUBLIC, NULL, NULL, origin); if (res ! TEEC_SUCCESS) return -1; memset(op, 0, sizeof(op)); op.paramTypes TEEC_PARAM_TYPES( TEEC_MEMREF_TEMP_INPUT, TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE, TEEC_NONE); /* 設(shè)置op.params[0]和op.params[1]的緩沖區(qū)內(nèi)容 */ res TEEC_InvokeCommand(session, CMD_HELLO_WORLD, op, origin); TEEC_CloseSession(session); TEEC_FinalizeContext(ctx); return 0; }有幾個(gè)容易踩坑的地方CA里使用的TA UUID必須和TA本身定義的user_ta_header_defines.h里的UUID完全一致字符多一位少一位都會(huì)導(dǎo)致打開(kāi)會(huì)話失敗paramTypes的四個(gè)參數(shù)類型要和TA端解析的完全對(duì)應(yīng)CA端用TEEC_MEMREF_TEMP_INPUTTA端也必須按臨時(shí)內(nèi)存輸入去解析origin參數(shù)能返回錯(cuò)誤來(lái)源排查問(wèn)題時(shí)第一件事就是看它指向的是普通世界還是安全世界。這種“CA在普通世界、TA在安全世界、通過(guò)共享內(nèi)存?zhèn)鲄?shù)”的模型初看起來(lái)比普通函數(shù)調(diào)用繁瑣但它保障的是高價(jià)值業(yè)務(wù)邏輯不被普通世界的大規(guī)模攻擊面輕易觸達(dá)。熬過(guò)一開(kāi)始的不習(xí)慣后面你寫(xiě)完TA會(huì)越來(lái)越覺(jué)得這套隔離模型的設(shè)計(jì)很干凈。4.3 BoostKit配置技巧編譯優(yōu)化、加密庫(kù)與內(nèi)存調(diào)優(yōu)當(dāng)TA邏輯在開(kāi)發(fā)環(huán)境里穩(wěn)定運(yùn)行后就該考慮真實(shí)業(yè)務(wù)性能了。BoostKit在ARM服務(wù)器平臺(tái)上能做的事很實(shí)在我挑三個(gè)最常用、見(jiàn)效最快的配置方向。第一開(kāi)啟CPU硬件加密指令優(yōu)化。很多團(tuán)隊(duì)在交叉編譯時(shí)還在用最保守的編譯選項(xiàng)導(dǎo)致加解密代碼沒(méi)有走到ARM的Cryptography Extensions。在編譯CA和TA相關(guān)的算法庫(kù)時(shí)建議加上-marcharmv8-acrypto這個(gè)選項(xiàng)會(huì)讓編譯器在合適的位置生成AES、SHA等硬件指令而不是調(diào)用軟實(shí)現(xiàn)。實(shí)測(cè)下來(lái)AES-GCM這類對(duì)稱加密場(chǎng)景開(kāi)啟硬件指令后吞吐能提升30%以上。注意前提是目標(biāo)CPU確實(shí)支持這個(gè)擴(kuò)展如果你部署在較老的ARM平臺(tái)上先確認(rèn)CPU特性再開(kāi)。第二替換高性能加密實(shí)現(xiàn)。BoostKit里通常包含針對(duì)特定硬件優(yōu)化過(guò)的密碼學(xué)加速庫(kù)盡量用它替換OpenSSL的默認(rèn)實(shí)現(xiàn)。配置方式常見(jiàn)的是通過(guò)LD_PRELOAD或直接鏈接BoostKit提供的靜態(tài)庫(kù)讓TA內(nèi)部調(diào)用的加解密接口落到硬件加速路徑上。比如# 示意把BoostKit加速庫(kù)路徑放到庫(kù)搜索路徑最前面 export LD_LIBRARY_PATH/path/to/boostkit/libs:$LD_LIBRARY_PATH替換后做一次壓測(cè)對(duì)比你會(huì)發(fā)現(xiàn)安全世界里的加解密開(kāi)銷明顯下降。不過(guò)要注意引入外部加速庫(kù)之前要先確認(rèn)對(duì)方是否通過(guò)安全審計(jì)因?yàn)門(mén)EE場(chǎng)景對(duì)庫(kù)的完整性要求比普通應(yīng)用嚴(yán)格得多。第三調(diào)整共享內(nèi)存和大頁(yè)配置。TA和CA之間的共享內(nèi)存是性能熱點(diǎn)如果每次調(diào)用都做臟頁(yè)回收和缺頁(yè)中斷延遲會(huì)很高。在支持大頁(yè)的系統(tǒng)上可以用echo always /sys/kernel/mm/transparent_hugepage/enabled或者預(yù)留靜態(tài)大頁(yè)減少共享內(nèi)存區(qū)域的TLB miss。我在一次性能調(diào)優(yōu)中只改了共享內(nèi)存區(qū)域的分配方式TA調(diào)用的平均時(shí)延就下降了15%左右效果非??捎^。BoostKit配置的核心思路不是把所有優(yōu)化選項(xiàng)無(wú)腦打開(kāi)而是先壓測(cè)定位瓶頸再針對(duì)性替換或調(diào)參。最穩(wěn)妥的做法是先跑基線數(shù)據(jù)再逐個(gè)打開(kāi)優(yōu)化項(xiàng)每開(kāi)一個(gè)都重新壓測(cè)比較確認(rèn)有效再固化到部署腳本里。5. 常見(jiàn)問(wèn)題與排查技巧實(shí)錄5.1 編譯階段典型報(bào)錯(cuò)與解決辦法我把自己和團(tuán)隊(duì)在實(shí)際搭建過(guò)程中遇到的典型編譯錯(cuò)誤整理成了速查表方便你按圖索驥報(bào)錯(cuò)信息原因分析解決辦法aarch64-linux-gnu-gcc: command not found交叉編譯工具鏈沒(méi)有安裝或不在PATH中執(zhí)行sudo apt install gcc-aarch64-linux-gnu g-aarch64-linux-gnu確認(rèn)which aarch64-linux-gnu-gccdtc: command not found缺少設(shè)備樹(shù)編譯器安裝device-tree-compiler后重試undefined reference to uuid_parse鏈接時(shí)找不到libuuid安裝uuid-dev并確認(rèn)Makefile里鏈接了-luuidError: unknown type name TEE_ResultTA源碼缺少TEE內(nèi)部API頭文件檢查是否包含tee_internal_api.h和tee_internal_api_extensions.hKernel編譯報(bào)scripts/Makefile.lib相關(guān)的sysroot錯(cuò)誤交叉工具鏈與內(nèi)核版本不匹配換成發(fā)行版配套工具鏈清空內(nèi)核目錄后重新解壓再編譯這里最典型的坑是“交叉工具鏈版本過(guò)新”尤其是手動(dòng)從ARM官網(wǎng)下載最新工具鏈時(shí)往往會(huì)和項(xiàng)目里固定Linux內(nèi)核版本的構(gòu)建方式?jīng)_突。我現(xiàn)在的習(xí)慣是優(yōu)先用Ubuntu apt源里的工具鏈除非官方文檔明確要求特定版本不要隨意升級(jí)。5.2 運(yùn)行階段問(wèn)題定位從串口日志到RPC錯(cuò)誤環(huán)境啟動(dòng)后問(wèn)題往往會(huì)轉(zhuǎn)移到“系統(tǒng)起來(lái)了但TA跑不起來(lái)”。下面這幾個(gè)現(xiàn)象是我遇到的頻率最高的啟動(dòng)日志里找不到OP-TEE初始化信息或者安全世界初始化在TEE: Initialized之前卡住多半是ATF加載BL32鏡像的地址不對(duì)。檢查啟動(dòng)參數(shù)里BL32的加載地址是否和鏈接地址一致尤其是手動(dòng)改過(guò)內(nèi)存布局后很容易出問(wèn)題。TEEC_OpenSession返回TEE_ERROR_TARGET_DEAD則說(shuō)明TA所在的TEE OS可能已經(jīng)崩潰。需要使用串口日志查看TEE側(cè)報(bào)錯(cuò)通常能看到具體是哪一個(gè)TA的頁(yè)錯(cuò)誤或者訪問(wèn)違規(guī)。QEMU環(huán)境串口默認(rèn)輸出到終端保存完整啟動(dòng)日志非常方便所以我強(qiáng)烈建議你哪怕用窗口模式也要把日志重定向到文件里方便回看。optee_test里部分用例失敗并提示RPC錯(cuò)誤一般和普通世界的驅(qū)動(dòng)或RPMB模擬相關(guān)。QEMU下RPMB not supported可以忽略但如果是真實(shí)開(kāi)發(fā)板就要檢查RPMB驅(qū)動(dòng)初始化是否正常。遇到運(yùn)行問(wèn)題時(shí)我習(xí)慣按照這個(gè)順序排查先看ATF/OP-TEE啟動(dòng)日志確認(rèn)安全世界活著再看Linux內(nèi)核日志dmesg | grep -i optee確認(rèn)驅(qū)動(dòng)加載正常最后才是TA/CA側(cè)的用戶態(tài)日志。很多人喜歡一上來(lái)就查CA代碼其實(shí)大多數(shù)問(wèn)題都出在更底層。5.3 獨(dú)家避坑清單這些經(jīng)驗(yàn)?zāi)軒湍闶∫恢茏詈笳韼讞l我踩過(guò)坑之后沉淀下來(lái)的心得每一條都對(duì)應(yīng)過(guò)真實(shí)事故希望你不用重復(fù)走一遍。第一第一次跑QEMU時(shí)不要急著開(kāi)KVM硬件加速。雖然開(kāi)KVM能顯著提速但虛擬平臺(tái)對(duì)TrustZone的模擬在某些情況下會(huì)和KVM產(chǎn)生兼容性問(wèn)題。先把純QEMU流程跑通再考慮性能優(yōu)化這樣能減少變量問(wèn)題也更好定位。第二優(yōu)先使用官方build腳本不要自己手工拼湊編譯命令。官方腳本雖然看似“黑盒”但它維護(hù)了ATF、U-Boot、OP-TEE OS、Linux內(nèi)核之間的版本組合關(guān)系。很多人覺(jué)得腳本不透明非要自己一條條命令來(lái)結(jié)果遇到各種古怪錯(cuò)誤其實(shí)反而是繞了遠(yuǎn)路。第三修改設(shè)備樹(shù)時(shí)務(wù)必注意reg屬性對(duì)齊。安全內(nèi)存區(qū)域起始地址和大小通常要求2MB或4KB對(duì)齊如果對(duì)齊不對(duì)OP-TEE初始化時(shí)會(huì)拒絕使用這塊內(nèi)存而且報(bào)錯(cuò)信息可能并不直接指向?qū)R問(wèn)題而是表現(xiàn)為“secure world未啟動(dòng)”這種模糊現(xiàn)象。第四每次編譯前保存.config和構(gòu)建日志。無(wú)論optee_os還是Linux內(nèi)核構(gòu)建配置都是調(diào)試時(shí)的重要依據(jù)。我在排查一個(gè)偶然性崩潰問(wèn)題時(shí)就是因?yàn)楸4媪水?dāng)時(shí)編譯日志才快速定位到是某個(gè)CFG宏改變導(dǎo)致的行為差異。建議把每次編譯的.config復(fù)制到帶時(shí)間戳的備份目錄cp optee_os/.config ~/backup/optee_config_$(date %Y%m%d_%H%M%S)第五裝BoostKit時(shí)順序一定是“先確認(rèn)內(nèi)核版本兼容再安裝對(duì)應(yīng)版本的工具包”。有的加速庫(kù)會(huì)直接替換系統(tǒng)級(jí)加密庫(kù)如果版本與內(nèi)核驅(qū)動(dòng)不匹配輕則接口不可用重則啟動(dòng)后崩潰。我在鯤鵬實(shí)例上就遇到過(guò)BoostKit版本和內(nèi)核驅(qū)動(dòng)不匹配導(dǎo)致的軟死鎖最后回滾工具包版本才恢復(fù)正常。所以在正式環(huán)境里操作前先在小規(guī)模實(shí)例上做驗(yàn)證別直接在核心業(yè)務(wù)機(jī)上裝。跑TEE這條技術(shù)路線說(shuō)難不難說(shuō)簡(jiǎn)單也不簡(jiǎn)單。你能從零把環(huán)境搭起來(lái)說(shuō)明對(duì)TrustZone的基本原理已經(jīng)有了感性認(rèn)識(shí)如果你能寫(xiě)一個(gè)最簡(jiǎn)單的TA并在模擬器里跑通那后面無(wú)論是遷移到iTrustee平臺(tái)還是做BoostKit性能優(yōu)化都只會(huì)越來(lái)越順手。我個(gè)人在實(shí)際操作中的體會(huì)是環(huán)境搭建最磨人的不是敲命令而是理解每一步背后的硬件機(jī)制。等你想通了普通世界和安全世界是怎么通過(guò)SMC指令、共享內(nèi)存和設(shè)備樹(shù)節(jié)點(diǎn)配合起來(lái)的那一刻再回頭去看整個(gè)系統(tǒng)視線會(huì)清楚很多。