安全之安全(security2)博客目錄導讀
目錄
一、組件構成
二、Arm FVP平臺PoC構建
三、在Armv8-A Foundation FVP上運行PoC
四、微調fTPM TA
可信啟動(Measured Boot)是通過密碼學方式度量啟動階段代碼及關鍵數據(例如使用TPM芯片)的過程,以便后續對系統安全狀態進行驗證。
當前TF-A集成的驅動支持多種后端存儲方式,每種方式采用不同的測量值存儲機制。本節重點討論TCG事件日志后端,該后端將測量值存儲在安全內存中。
詳見可信啟動設計文檔。
該驅動還提供將事件日志傳遞至普通世界的機制。
本手冊提供的概念驗證(PoC)構建指南,旨在演示如何將可信啟動與基于OP-TEE實現的fTPM(fTPM)服務結合使用。
【注意】本文檔的構建指南僅用于展示TF-A可信啟動如何與第三方(f)TPM服務交互,內容盡可能保持通用性。不同平臺可能存在不同需求和配置(例如采用不同SHA算法),也可能使用不同類型的TPM服務(甚至其他類型的證明服務),因此部分指南可能不適用于特定場景。
一、組件構成
該PoC基于OP-TEE工具鏈構建(自提交cf56848起支持在Foundation模型上運行帶可信啟動功能的TF-A)。該工具鏈生成的鏡像集包含驗證事件日志正確性所需的所有組件,其中一個鏡像將集成第三方fTPM服務用于處理事件日志。
選擇OP-TEE工具鏈構建PoC主要出于便利性考慮。由于fTPM服務是OP-TEE可信應用(TA),可輕松將其編譯支持添加到工具鏈中。
與可信啟動/fTPM功能密切相關的核心組件包括:
-
OP-TEE:本PoC使用的fTPM服務作為OP-TEE TA運行,因此需包含OP-TEE OS鏡像。OP-TEE 3.9.0版本通過實現PTA_SYSTEM_GET_TPM_EVENT_LOG系統調用,支持從TF-A獲取事件日志副本。OP-TEE通過解析TF-A傳遞的DTB綁定信息定位事件日志(詳見事件日志DTB綁定屬性說明)。
-
fTPM服務:采用微軟ms-tpm-20-ref參考實現中的Aarch32架構示例,該服務已擴展支持在啟動時處理可信啟動事件日志,并通過上述系統調用獲取日志副本。
【注意】Arm不提供fTPM實現。本PoC使用的第三方fTPM服務經修改支持TF-A可信啟動,其輸出正確性驗證超出本手冊范圍。
-
TPM內核模塊:用于將用戶空間請求轉發至安全世界。
-
tpm2-tools工具集:用于讀取fTPM服務中的PCR測量值。
二、Arm FVP平臺PoC構建
如前所述,此PoC基于OP-TEE工具包,具有一些擴展以啟用Measured Boot和fTPM服務。因此,我們可以依靠這些指令來構建原始的OP-TEE工具包。一般來說,以下步驟就足夠了:
-
首先,按照獲取和構建解決方案的指導來構建OP-TEE工具包。在步驟3中,您需要從主分支獲取FVP平臺的manifest:
$ repo init -u https://github.com/OP-TEE/manifest.git -m fvp.xml
-
接下來,您應該獲得Armv8-A Foundation Platform (For Linux Hosts Only)。二進制文件應該解壓縮到repo樹的根目錄,即像這樣:<fvp-project>/Foundation_Platformpkg。最后,在克隆所有源代碼,獲得工具鏈并“安裝”Foundation_Platformpkg之后,你應該有一個看起來像這樣的文件夾結構:
$ ls -la
total 80
drwxrwxr-x 20 tf-a_user tf-a_user 4096 Jul 1 12:16 .
drwxr-xr-x 23 tf-a_user tf-a_user 4096 Jul 1 10:40 ..
drwxrwxr-x 12 tf-a_user tf-a_user 4096 Jul 1 10:45 build
drwxrwxr-x 16 tf-a_user tf-a_user 4096 Jul 1 12:16 buildroot
drwxrwxr-x 51 tf-a_user tf-a_user 4096 Jul 1 10:45 edk2
drwxrwxr-x 6 tf-a_user tf-a_user 4096 Jul 1 12:14 edk2-platforms
drwxr-xr-x 7 tf-a_user tf-a_user 4096 Jul 1 10:52 Foundation_Platformpkg
drwxrwxr-x 17 tf-a_user tf-a_user 4096 Jul 2 10:40 grub
drwxrwxr-x 25 tf-a_user tf-a_user 4096 Jul 2 10:39 linux
drwxrwxr-x 15 tf-a_user tf-a_user 4096 Jul 1 10:45 mbedtls
drwxrwxr-x 6 tf-a_user tf-a_user 4096 Jul 1 10:45 ms-tpm-20-ref
drwxrwxr-x 8 tf-a_user tf-a_user 4096 Jul 1 10:45 optee_client
drwxrwxr-x 10 tf-a_user tf-a_user 4096 Jul 1 10:45 optee_examples
drwxrwxr-x 12 tf-a_user tf-a_user 4096 Jul 1 12:13 optee_os
drwxrwxr-x 8 tf-a_user tf-a_user 4096 Jul 1 10:45 optee_test
drwxrwxr-x 7 tf-a_user tf-a_user 4096 Jul 1 10:45 .repo
drwxrwxr-x 4 tf-a_user tf-a_user 4096 Jul 1 12:12 toolchains
drwxrwxr-x 21 tf-a_user tf-a_user 4096 Jul 1 12:15 trusted-firmware-a
??????3. 現在進入ms-tpm-20-ref并獲取其依賴項:
$ cd ms-tpm-20-ref
$ git submodule init
$ git submodule update
Submodule path 'external/wolfssl': checked out '9c87f979a7f1d3a6d786b260653d566c1d31a1c4'
??????4.現在,您應該能夠繼續執行“獲取并構建解決方案(Get and build the solution)”說明中的第5步。為了啟用對Measured Boot的支持,您需要設置以下構建選項:
$ MEASURED_BOOT=y MEASURED_BOOT_FTPM=y make -j `nproc`
【注意】:構建過程可能需要很長時間。強烈建議傳遞-j選項以使進程運行得更快。
在這一步之后,您應該已經準備好運行鏡像了。
三、在Armv8-A Foundation FVP上運行PoC
構建好所有內容后,現在可以運行鏡像:
$ make run-only
【注意】:使用make run將構建并運行鏡像,可以使用它來代替簡單的make。但是,一旦構建了鏡像,建議使用make run-only來避免重新運行所有構建規則,這將花費時間。
當啟動FVP(固定虛擬平臺)時,會出現兩個終端窗口。FVP terminal_0是用戶空間終端,而FVP terminal_1是安全世界(Secure World)的對應終端(例如可信應用TAs的日志將在此處輸出)。
使用root用戶登錄系統鏡像shell(無需密碼),隨后可執行ftpm命令。該命令是一個組合別名,其功能包括:
-
加載ftpm內核模塊
-
調用tpm2_pcrread訪問fTPM服務以讀取PCR值
當加載ftpm內核模塊時,fTPM可信應用(TA)會被載入安全世界。該TA隨后會請求獲取引導過程中生成的事件日志(Event Log)副本,從而首先檢索并記錄日志中的所有條目。
【注意】對于這個PoC,在BL33和NT_FW_CONFIG之后加載的任何內容都不會記錄在事件日志中。
安全世界終端應該顯示fTPM服務的調試日志,包括正在處理的事件日志中可用的所有測量:
M/TA: Preparing to extend the following TPM Event Log:
M/TA: TCG_EfiSpecIDEvent:
M/TA: PCRIndex : 0
M/TA: EventType : 3
M/TA: Digest : 00
M/TA: : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
M/TA: : 00 00 00
M/TA: EventSize : 33
M/TA: Signature : Spec ID Event03
M/TA: PlatformClass : 0
M/TA: SpecVersion : 2.0.2
M/TA: UintnSize : 1
M/TA: NumberOfAlgorithms : 1
M/TA: DigestSizes :
M/TA: #0 AlgorithmId : SHA256
M/TA: DigestSize : 32
M/TA: VendorInfoSize : 0
M/TA: PCR_Event2:
M/TA: PCRIndex : 0
M/TA: EventType : 3
M/TA: Digests Count : 1
M/TA: #0 AlgorithmId : SHA256
M/TA: Digest : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
M/TA: : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
M/TA: EventSize : 17
M/TA: Signature : StartupLocality
M/TA: StartupLocality : 0
M/TA: PCR_Event2:
M/TA: PCRIndex : 0
M/TA: EventType : 1
M/TA: Digests Count : 1
M/TA: #0 AlgorithmId : SHA256
M/TA: Digest : 58 26 32 6e 64 45 64 da 45 de 35 db 96 fd ed 63
M/TA: : 2a 6a d4 0d aa 94 b0 b1 55 e4 72 e7 1f 0a e0 d5
M/TA: EventSize : 5
M/TA: Event : BL_2
M/TA: PCR_Event2:
M/TA: PCRIndex : 0
M/TA: EventType : 1
M/TA: Digests Count : 1
M/TA: #0 AlgorithmId : SHA256
M/TA: Digest : cf f9 7d a3 5c 73 ac cb 7b a0 25 80 6a 6e 50 a5
M/TA: : 6b 2e d2 8c c9 36 92 7d 46 c5 b9 c3 a4 6c 51 7c
M/TA: EventSize : 6
M/TA: Event : BL_31
M/TA: PCR_Event2:
M/TA: PCRIndex : 0
M/TA: EventType : 1
M/TA: Digests Count : 1
M/TA: #0 AlgorithmId : SHA256
M/TA: Digest : 23 b0 a3 5d 54 d9 43 1a 5c b9 89 63 1c da 06 c2
M/TA: : e5 de e7 7e 99 17 52 12 7d f7 45 ca 4f 4a 39 c0
M/TA: EventSize : 10
M/TA: Event : HW_CONFIG
M/TA: PCR_Event2:
M/TA: PCRIndex : 0
M/TA: EventType : 1
M/TA: Digests Count : 1
M/TA: #0 AlgorithmId : SHA256
M/TA: Digest : 4e e4 8e 5a e6 50 ed e0 b5 a3 54 8a 1f d6 0e 8a
M/TA: : ea 0e 71 75 0e a4 3f 82 76 ce af cd 7c b0 91 e0
M/TA: EventSize : 14
M/TA: Event : SOC_FW_CONFIG
M/TA: PCR_Event2:
M/TA: PCRIndex : 0
M/TA: EventType : 1
M/TA: Digests Count : 1
M/TA: #0 AlgorithmId : SHA256
M/TA: Digest : 01 b0 80 47 a1 ce 86 cd df 89 d2 1f 2e fc 6c 22
M/TA: : f8 19 ec 6e 1e ec 73 ba 5a be d0 96 e3 5f 6d 75
M/TA: EventSize : 6
M/TA: Event : BL_32
M/TA: PCR_Event2:
M/TA: PCRIndex : 0
M/TA: EventType : 1
M/TA: Digests Count : 1
M/TA: #0 AlgorithmId : SHA256
M/TA: Digest : 5d c6 ef 35 5a 90 81 b4 37 e6 3b 52 da 92 ab 8e
M/TA: : d9 6e 93 98 2d 40 87 96 1b 5a a7 ee f1 f4 40 63
M/TA: EventSize : 18
M/TA: Event : BL32_EXTRA1_IMAGE
M/TA: PCR_Event2:
M/TA: PCRIndex : 0
M/TA: EventType : 1
M/TA: Digests Count : 1
M/TA: #0 AlgorithmId : SHA256
M/TA: Digest : 39 b7 13 b9 93 db 32 2f 1b 48 30 eb 2c f2 5c 25
M/TA: : 00 0f 38 dc 8e c8 02 cd 79 f2 48 d2 2c 25 ab e2
M/TA: EventSize : 6
M/TA: Event : BL_33
M/TA: PCR_Event2:
M/TA: PCRIndex : 0
M/TA: EventType : 1
M/TA: Digests Count : 1
M/TA: #0 AlgorithmId : SHA256
M/TA: Digest : 25 10 60 5d d4 bc 9d 82 7a 16 9f 8a cc 47 95 a6
M/TA: : fd ca a0 c1 2b c9 99 8f 51 20 ff c6 ed 74 68 5a
M/TA: EventSize : 13
M/TA: Event : NT_FW_CONFIG
這些日志對應于TF-A在測量的引導過程中存儲的測量值,因此,它們應該與TF-A在啟動過程中轉儲的日志相匹配。這些可以在terminal_0上看到:
NOTICE: Booting Trusted Firmware
NOTICE: BL1: v2.5(release):v2.5
NOTICE: BL1: Built : 10:41:20, Jul 2 2021
NOTICE: BL1: Booting BL2
NOTICE: BL2: v2.5(release):v2.5
NOTICE: BL2: Built : 10:41:20, Jul 2 2021
NOTICE: TCG_EfiSpecIDEvent:
NOTICE: PCRIndex : 0
NOTICE: EventType : 3
NOTICE: Digest : 00
NOTICE: : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
NOTICE: : 00 00 00
NOTICE: EventSize : 33
NOTICE: Signature : Spec ID Event03
NOTICE: PlatformClass : 0
NOTICE: SpecVersion : 2.0.2
NOTICE: UintnSize : 1
NOTICE: NumberOfAlgorithms : 1
NOTICE: DigestSizes :
NOTICE: #0 AlgorithmId : SHA256
NOTICE: DigestSize : 32
NOTICE: VendorInfoSize : 0
NOTICE: PCR_Event2:
NOTICE: PCRIndex : 0
NOTICE: EventType : 3
NOTICE: Digests Count : 1
NOTICE: #0 AlgorithmId : SHA256
NOTICE: Digest : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
NOTICE: : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
NOTICE: EventSize : 17
NOTICE: Signature : StartupLocality
NOTICE: StartupLocality : 0
NOTICE: PCR_Event2:
NOTICE: PCRIndex : 0
NOTICE: EventType : 1
NOTICE: Digests Count : 1
NOTICE: #0 AlgorithmId : SHA256
NOTICE: Digest : 58 26 32 6e 64 45 64 da 45 de 35 db 96 fd ed 63
NOTICE: : 2a 6a d4 0d aa 94 b0 b1 55 e4 72 e7 1f 0a e0 d5
NOTICE: EventSize : 5
NOTICE: Event : BL_2
NOTICE: PCR_Event2:
NOTICE: PCRIndex : 0
NOTICE: EventType : 1
NOTICE: Digests Count : 1
NOTICE: #0 AlgorithmId : SHA256
NOTICE: Digest : cf f9 7d a3 5c 73 ac cb 7b a0 25 80 6a 6e 50 a5
NOTICE: : 6b 2e d2 8c c9 36 92 7d 46 c5 b9 c3 a4 6c 51 7c
NOTICE: EventSize : 6
NOTICE: Event : BL_31
NOTICE: PCR_Event2:
NOTICE: PCRIndex : 0
NOTICE: EventType : 1
NOTICE: Digests Count : 1
NOTICE: #0 AlgorithmId : SHA256
NOTICE: Digest : 23 b0 a3 5d 54 d9 43 1a 5c b9 89 63 1c da 06 c2
NOTICE: : e5 de e7 7e 99 17 52 12 7d f7 45 ca 4f 4a 39 c0
NOTICE: EventSize : 10
NOTICE: Event : HW_CONFIG
NOTICE: PCR_Event2:
NOTICE: PCRIndex : 0
NOTICE: EventType : 1
NOTICE: Digests Count : 1
NOTICE: #0 AlgorithmId : SHA256
NOTICE: Digest : 4e e4 8e 5a e6 50 ed e0 b5 a3 54 8a 1f d6 0e 8a
NOTICE: : ea 0e 71 75 0e a4 3f 82 76 ce af cd 7c b0 91 e0
NOTICE: EventSize : 14
NOTICE: Event : SOC_FW_CONFIG
NOTICE: PCR_Event2:
NOTICE: PCRIndex : 0
NOTICE: EventType : 1
NOTICE: Digests Count : 1
NOTICE: #0 AlgorithmId : SHA256
NOTICE: Digest : 01 b0 80 47 a1 ce 86 cd df 89 d2 1f 2e fc 6c 22
NOTICE: : f8 19 ec 6e 1e ec 73 ba 5a be d0 96 e3 5f 6d 75
NOTICE: EventSize : 6
NOTICE: Event : BL_32
NOTICE: PCR_Event2:
NOTICE: PCRIndex : 0
NOTICE: EventType : 1
NOTICE: Digests Count : 1
NOTICE: #0 AlgorithmId : SHA256
NOTICE: Digest : 5d c6 ef 35 5a 90 81 b4 37 e6 3b 52 da 92 ab 8e
NOTICE: : d9 6e 93 98 2d 40 87 96 1b 5a a7 ee f1 f4 40 63
NOTICE: EventSize : 18
NOTICE: Event : BL32_EXTRA1_IMAGE
NOTICE: PCR_Event2:
NOTICE: PCRIndex : 0
NOTICE: EventType : 1
NOTICE: Digests Count : 1
NOTICE: #0 AlgorithmId : SHA256
NOTICE: Digest : 39 b7 13 b9 93 db 32 2f 1b 48 30 eb 2c f2 5c 25
NOTICE: : 00 0f 38 dc 8e c8 02 cd 79 f2 48 d2 2c 25 ab e2
NOTICE: EventSize : 6
NOTICE: Event : BL_33
NOTICE: PCR_Event2:
NOTICE: PCRIndex : 0
NOTICE: EventType : 1
NOTICE: Digests Count : 1
NOTICE: #0 AlgorithmId : SHA256
NOTICE: Digest : 25 10 60 5d d4 bc 9d 82 7a 16 9f 8a cc 47 95 a6
NOTICE: : fd ca a0 c1 2b c9 99 8f 51 20 ff c6 ed 74 68 5a
NOTICE: EventSize : 13
NOTICE: Event : NT_FW_CONFIG
NOTICE: BL1: Booting BL31
NOTICE: BL31: v2.5(release):v2.5
NOTICE: BL31: Built : 10:41:20, Jul 2 2021
跟蹤fTPM啟動過程,我們可以看到事件日志中的所有測量都被擴展并記錄在適當的PCR中:
M/TA: TPM2_PCR_EXTEND_COMMAND returned value:
M/TA: ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000
M/TA: TPM2_PCR_EXTEND_COMMAND returned value:
M/TA: ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000
M/TA: TPM2_PCR_EXTEND_COMMAND returned value:
M/TA: ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000
M/TA: TPM2_PCR_EXTEND_COMMAND returned value:
M/TA: ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000
M/TA: TPM2_PCR_EXTEND_COMMAND returned value:
M/TA: ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000
M/TA: TPM2_PCR_EXTEND_COMMAND returned value:
M/TA: ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000
M/TA: TPM2_PCR_EXTEND_COMMAND returned value:
M/TA: ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000
M/TA: TPM2_PCR_EXTEND_COMMAND returned value:
M/TA: ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000
M/TA: TPM2_PCR_EXTEND_COMMAND returned value:
M/TA: ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000
M/TA: 9 Event logs processed
在加載fTPM TA之后,由fTPM別名發出的對insmod的調用返回,以加載fTPM內核模塊,然后通過tpm_pcrread命令讀取TPM PCRs。請注意,我們在這里只對SHA256日志感興趣,因為這是我們在TF-A上用于測量的算法(參見上面日志中的AlgorithmId字段):
sha256:
0 : 0xA6EB3A7417B8CFA9EBA2E7C22AD5A4C03CDB8F3FBDD7667F9C3EF2EA285A8C9F
1 : 0x0000000000000000000000000000000000000000000000000000000000000000
2 : 0x0000000000000000000000000000000000000000000000000000000000000000
3 : 0x0000000000000000000000000000000000000000000000000000000000000000
4 : 0x0000000000000000000000000000000000000000000000000000000000000000
5 : 0x0000000000000000000000000000000000000000000000000000000000000000
6 : 0x0000000000000000000000000000000000000000000000000000000000000000
7 : 0x0000000000000000000000000000000000000000000000000000000000000000
8 : 0x0000000000000000000000000000000000000000000000000000000000000000
9 : 0x0000000000000000000000000000000000000000000000000000000000000000
10: 0x0000000000000000000000000000000000000000000000000000000000000000
11: 0x0000000000000000000000000000000000000000000000000000000000000000
12: 0x0000000000000000000000000000000000000000000000000000000000000000
13: 0x0000000000000000000000000000000000000000000000000000000000000000
14: 0x0000000000000000000000000000000000000000000000000000000000000000
15: 0x0000000000000000000000000000000000000000000000000000000000000000
16: 0x0000000000000000000000000000000000000000000000000000000000000000
17: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
18: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
19: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
20: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
21: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
22: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
23: 0x0000000000000000000000000000000000000000000000000000000000000000
在這個PoC中,我們只對PCR0感興趣,它必須是非空的。這是因為引導進程記錄了這個PCR中的所有映像(參見上面事件日志中的PCRIndex字段)。此時其余的記錄必須為0。
【注意】:使用的fTPM服務只支持16個pcr,因此超過15個pcr的內容可以忽略。
【注意】:如前所述,Arm不提供fTPM實現,因此我們在這里不驗證PCR0的內容是否正確。對于這個PoC,我們只關注事件日志可以傳遞給第三方fTPM,并且它的記錄得到了適當的擴展。
四、微調fTPM TA
如前所述,OP-TEE工具包包括對構建第三方fTPM服務的支持。此服務的構建選項是為PoC量身定制的,并在構建環境變量FTPM_FLAGS中定義(請參閱<toolkit_home>/build/common.mk),但如果需要,可以修改它們以更好地適應特定場景。
測量引導支持最相關的選項是:
?CFG_TA_DEBUG:啟用Terminal_1控制臺的調試日志。
?CFG_TEE_TA_LOG_LEVEL:定義用于調試消息的日志級別。
?CFG_TA_MEASURED_BOOT:啟用對fTPM上測量引導的支持。
?CFG_TA_EVENT_LOG_SIZE:定義fTPM能夠存儲的大事件日志的大小(以字節為單位),因為這個緩沖區是在構建時分配的。這必須至少與TF-A生成的事件日志的大小相同。如果沒有定義這個構建選項,那么fTPM就會退回到1024字節的默認值,這對于這個PoC來說已經足夠了,所以這個變量沒有在FTPM_FLAGS中定義。