這里先來看看安全驅(qū)動怎么設(shè)計。支持TruztZone技術(shù)的芯片可將某個特定外部設(shè)備配置成安全設(shè)備,使其只能被處于安全世界狀態(tài)(SWS)的ARM核訪問。如果要在OP-TEE中使用安全設(shè)備, 需要在OP-TEE OS中集成該安全設(shè)備的驅(qū)動程序 ,TA或OP-TEE OS可使用該安全驅(qū)動提供的接口來使用該安全設(shè)備。
要完成一個驅(qū)動的設(shè)計:向外暴露被調(diào)用的接口,將驅(qū)動集成。
在設(shè)計安全驅(qū)動的時候,先回顧一下,為什么可將某個特定外部設(shè)備配置成安全設(shè)備?
1、安全設(shè)備的硬件安全隔離
系統(tǒng)的外部設(shè)備一般是通過APB總線掛接到AXI總線上的,APB總線不支持ARM核對設(shè)備訪問時進行安全檢查的功能,故如果要將某個外部設(shè)備配置成安全設(shè)備,則需在SOC中添加TZPC組件和AXI-to-APB橋。
TZPC組件負責(zé)將某個特定外部設(shè)備配置成安全設(shè)備,并為該安全設(shè)備提供額外的安全信號, AXI-to-APB橋使用TZPC配置給該外部設(shè)備的安全信號來校驗ARM核發(fā)送的訪問請求中的安全狀態(tài)位(NS bit)是否與之匹配, 如果TZPC給外部設(shè)備提供的信號為安全信號而ARM核的訪問請求是在正常世界狀態(tài)(NWS)發(fā)起的,則AXI-to-APB總線會判定訪問失敗,從而實現(xiàn)系統(tǒng)對該外部設(shè)備的安全隔離。
TZPC組件主要有兩個作用,一是為TZMA提供安全區(qū)域大小配置信號,用于TZMA來配置片上SRAM、ROM安全區(qū)域的大小,另外一個作用是接入到AXI-to-APB總線上,為外部設(shè)備提供安全信號,將某個外部設(shè)備配置成安全設(shè)備。TZPC組件的信號連接圖如圖22-1所示。
TZPCR0SIZE信號線將被連接到TZMA組件上,用于TZMA配置片上SRAM、ROM安全區(qū)域的大小,
TZPCDECPROTx信號線將連接到AXI-to-APB橋上,用于配置某個外設(shè)是否為安全設(shè)備。
TZPC最多支持將24個外部設(shè)備設(shè)定為安全設(shè)備,且需將TZPC組件的寄存器地址設(shè)定在安全地址范圍內(nèi)。
TZPC提供了18個寄存器,這些寄存器用于配置安全信號。這些寄存器的相關(guān)信息如表22-1所示。
通過配置TZPC組件寄存器的值可設(shè)定特定的安全信號的輸出組合,用于將外部設(shè)備設(shè)定成安全設(shè)備。
TZPC的基地址并不固定,但需確保TZPC的基地址是在安全地址區(qū)域中的。
知道這個安全驅(qū)動硬件是實現(xiàn)安全驅(qū)動的基礎(chǔ),那么下一步就來看看怎么軟件實現(xiàn)安全驅(qū)動。
2、OP-TEE中安全驅(qū)動的框架
OP-TEE中的安全驅(qū)動是OP-TEE操作安全設(shè)備的載體。
TA通過調(diào)用某個安全驅(qū)動的接口就可實現(xiàn)對特定安全設(shè)備的操作。安全驅(qū)動在OP-TEE中的軟件框架如圖22-2所示。
(其實這里,你要搞清楚linux kernel與驅(qū)動的關(guān)系,那真的還是蠻簡單好理解的。但是我不知道~嚶嚶嚶) 系統(tǒng)服務(wù)層并非必需的,主要是為方便管理和上層使用。例如OP-TEE提供了各種各樣的密碼學(xué)算法,每一種算法的實現(xiàn)可通過不同的硬件引擎來完成。
為統(tǒng)一管理,可將這些硬件引擎驅(qū)動提供的操作接口統(tǒng)一集成到一個系統(tǒng)服務(wù)中,而上層用戶只需調(diào)用系統(tǒng)服務(wù)暴露的接口就可實現(xiàn)對硬件引擎的調(diào)用。(可能是通過輸入的參數(shù)進行分發(fā))
下面展開講講這個框架的細節(jié)。
2.1 系統(tǒng)服務(wù)層
系統(tǒng)服務(wù)層在OP-TEE啟動過程中由initcall段的代碼進行初始化和啟動,一個系統(tǒng)服務(wù)的初始化函數(shù)則是通過使用service_init宏來進行定義并在編譯時鏈接到OP-TEE的鏡像文件中。
在編譯OP-TEE時,該初始化函數(shù)將被保存到OP-TEE鏡像文件的initcall段中。
至于系統(tǒng)服務(wù)的初始化函數(shù)所要執(zhí)行的內(nèi)容則由開發(fā)者自行決定,一般是在系統(tǒng)服務(wù)的初始化函數(shù)中進行該 服務(wù)的配置 、狀態(tài)量的初始化以及系統(tǒng)服務(wù)提供給上層調(diào)用的 操作接口變量的初始化 ,系統(tǒng)服務(wù)提供的結(jié)構(gòu)體變量會包含 用于實現(xiàn)具體功能的函數(shù)指針變量 ,這些函數(shù)指針變量指向的函數(shù)就是安全驅(qū)動提供給TA調(diào)用的操作接口。
2.2 驅(qū)動層
OP-TEE啟動過程中會執(zhí)行各安全驅(qū)動的初始化 ,驅(qū)動的初始化函數(shù)是在OP-TEE執(zhí)行initcall段中的內(nèi)容時被調(diào)用的,在OP-TEE中通過使用driver_init宏來告訴編譯器,在編譯時將driver_init宏傳入的函數(shù)作為某個驅(qū)動的入口函數(shù)保存在鏡像文件的initcall段中。
安全驅(qū)動的初始化主要用來完成安全設(shè)備的寄存器的配置以及私有數(shù)據(jù)的初始化。
如果某個安全驅(qū)動需要系統(tǒng)服務(wù)的配合,則還需要將驅(qū)動提供的操作接口連接到系統(tǒng)服務(wù)中的操作接口變量中。
若該驅(qū)動不需以系統(tǒng)服務(wù)的方式向上層提供操作接口,則不用將對應(yīng)接口暴露給系統(tǒng)服務(wù),而是由TA通過系統(tǒng)調(diào)用的方式直接調(diào)用安全驅(qū)動的接口來操作安全設(shè)備。
driver_init service_init
2.3 驅(qū)動文件在源代碼中的位置
安全驅(qū)動需要被編譯到OP-TEE鏡像文件中,OP-TEE中有專門的目錄來存放驅(qū)動和系統(tǒng)服務(wù)的源代碼。
將驅(qū)動編譯到OP-TEE鏡像文件之前還需修改對應(yīng)的sub.mk文件,OP-TEE中保存驅(qū)動和系統(tǒng)服務(wù)源代碼的目錄對應(yīng)關(guān)系如表22-2所示。
下面開始創(chuàng)建一個實例吧!
來看看基于上文的概念,創(chuàng)建一個安全驅(qū)動的流程是什么?
3、來整個栗子--安全驅(qū)動的開發(fā)過程和示例
在OP-TEE中,若需要使用系統(tǒng)服務(wù)的方式為上層TA提供操作接口,則一個完整的安全驅(qū)動需要實現(xiàn)TA接口部分、系統(tǒng)調(diào)用部分、系統(tǒng)服務(wù)部分、驅(qū)動實現(xiàn)部分。本節(jié)將結(jié)合實際的示例介紹這四部分的開發(fā)流程。
- TA接口部分
- 系統(tǒng)調(diào)用部分
- 系統(tǒng)服務(wù)部分
- 驅(qū)動實現(xiàn)部分
如果不使用系統(tǒng)服務(wù),就少了一個步驟。
3.1 示例代碼獲取和集成
本示例中的驅(qū)動只實現(xiàn)了對內(nèi)存的讀寫操作,并提供了測試使用的TA和CA。
讀者可使用如下指令從GitHub上獲取到示例源代碼:
git clone https://GitHub.com/shuaifengyun/opentee_driver.git
下載完代碼后就需要將該TA和CA集成到OP-TEE中,需修改OP-TEE源代碼build目錄下的qemu.mk(開發(fā)者板級對應(yīng)的mk文件)和common.mk文件,同時也需要將安全驅(qū)動集成到OP-TEE的內(nèi)核中。
然后編譯整體OP-TEE后就能夠使用該份示例代碼來驗證本書提供的安全驅(qū)動示例是否運行正常。
獲取到示例代碼后將opentee_driver/my_test目錄全部復(fù)制到op-tee的根目錄下,再切換到根目錄的build目錄中,然后使用git apply命令合入補丁文件后就可完成測試使用的TA和CA集成到OP-TEE,合入全部補丁的操作步驟如下:
1)將示例代碼中的my_test_common_3.0.0.patch文件和my_test_qemu_3.0.0.patch文件復(fù)制到build目錄中,將0001-Integrate-secure-driver-test-into-op-tee.patch文件復(fù)制到optee_os目錄中。
2)切換到build目錄,使用如下命令合入補丁:
git apply my_test_common_3.0.0.patch
3)切換到optee_os目錄,使用如下命令合入安全驅(qū)動在內(nèi)核中的補丁:
git am 0001-Integrate-secure-driver-test-into-op-tee.patch
將補丁合入完成后就可使用make -f qemu.mk all編譯整個工程,然后使用make -f qemu.mk run-only來啟動OP-TEE,在啟動的正常世界狀態(tài)的終端執(zhí)行secStorTest命令就能實現(xiàn)該示例的CA對TA的調(diào)用。示例代碼的運行效果如圖22-3所示。
3.2 驅(qū)動實現(xiàn)
開發(fā)一個安全驅(qū)動時,需要在optee_os/core/drivers目錄中建立該安全驅(qū)動的源文件,在源文件中實現(xiàn)驅(qū)動的初始化函數(shù)、操作設(shè)備的接口函數(shù)(read、write、ioctl),具體的接口函數(shù)由開發(fā)者自行定義。
若該驅(qū)動需要在系統(tǒng)啟動過程中執(zhí)行一些初始化操作則可使用driver_init宏進行定義, 編譯完成后需要被執(zhí)行的內(nèi)容將會被保存到鏡像文件的initcall段中, 這些使用driver_init宏定義的內(nèi)容將在OP-TEE啟動時被調(diào)用。 (相當(dāng)于提前為驅(qū)動的調(diào)用準備了環(huán)境與初始條件)
示例源代碼中的driver_test.c文件需要放在optee_os/core/drivers目錄中,然后修改optee_os/core/drivers目錄下的sub.mk文件,將driver_test.c文件添加編譯系統(tǒng)中。在sub. mk文件中添加如下內(nèi)容:
osrcs-y += driver_test.c
若需要使用宏的方式來控制該驅(qū)動的編譯,可將添加到sub.mk的內(nèi)容修改成“srcs-$(CFG_XXX) += driver_test.c”,然后在optee_os/mk/config.mk文件中定義CFG_XXX變量,通過將CFG_XXX變量賦值成y或n來控制該驅(qū)動是否需要被編譯進系統(tǒng)。 (這個還是蠻有用的)
該驅(qū)動對應(yīng)的頭文件driver_test.h文件需保存到optee_os/core/inlcude/drivers目錄中,該文件中聲明了該驅(qū)動暴露給外界調(diào)用的接口和相關(guān)結(jié)構(gòu)體。
實現(xiàn)完驅(qū)動接口實現(xiàn),現(xiàn)在來實現(xiàn)添加系統(tǒng)服務(wù)
3.3 添加系統(tǒng)服務(wù)
系統(tǒng)服務(wù)的添加不是必需的,為方便對底層驅(qū)動的管理和對外部設(shè)備的擴展,可將安全驅(qū)動的接口接入到某個系統(tǒng)服務(wù)中,通過系統(tǒng)服務(wù)向外界暴露調(diào)用接口,以便上層TA可以使用該安全驅(qū)動。
在本示例中建立的系統(tǒng)服務(wù)的源代碼為tee_test.c文件,需將該文件保存到optee_os/core/tee目錄中,同時將tee_test.h文件保存到optee_os/core/include/tee目錄中,然后修改optee_os/core/tee目錄中的sub.mk文件,添加“srcs-y += tee_test.c”,將tee_test.c集成到編譯系統(tǒng)中。
也可使用宏來控制該系統(tǒng)服務(wù)的編譯,其實現(xiàn)方法與上一節(jié)相同。
在tee_test.c文件中使用service_init宏來定義該系統(tǒng)服務(wù)的初始化函數(shù)(tee_test_init),該初始化函數(shù)將會被編譯到OP-TEE的初始化段中,OP-TEE啟動時將會執(zhí)行服務(wù)段中包含的函數(shù),調(diào)用tee_test_init函數(shù)初始化該系統(tǒng)服務(wù)。
到這里明白了driver_init和service_init的差異。一個是直接注冊驅(qū)動的系統(tǒng)調(diào)用,一個注冊到系統(tǒng)服務(wù)。
3.4 添加系統(tǒng)調(diào)用
上層的TA運行于OP-TEE的用戶空間,如果上層的TA需要調(diào)用安全驅(qū)動,則需通過調(diào)用系統(tǒng)調(diào)用接口的方式來調(diào)用安全驅(qū)動提供的操作接口。
若要在TA中使用本示例中的安全驅(qū)動,則還需在OP-TEE中增加該驅(qū)動對應(yīng)的系統(tǒng)調(diào)用。包括用戶空間接口的定義和內(nèi)核空間接口的定義,關(guān)于OP-TEE中系統(tǒng)調(diào)用的實現(xiàn)原理可參閱第16章。(小的馬上后面補上)
1.用戶空間代碼的修改
修改optee_os/lib/libutee/arch/arm/utee_syscalls_asm.S文件,添加如下內(nèi)容:
UTEE_SYSCALL utee_testDriver_write, TEE_SCN_TESTDRIVER_WRITE, 3
utee_testDriver_xxx是在TA中調(diào)用該驅(qū)動時使用的函數(shù),
TEE_SCN_TESTDRIVER_XXX是該系統(tǒng)調(diào)用對應(yīng)的索引值。
上層TA調(diào)用utee_testDriver_xxx函數(shù)后會進入OP-TEE的內(nèi)核空間,系統(tǒng)通過查找TEE_SCN_TESTDRIVER_XXX對應(yīng)的接口來找到該功能在OP-TEE內(nèi)核中的實現(xiàn)。
最后的數(shù)字表示調(diào)用該接口時需要代入的參數(shù)的個數(shù)。
修改optee_os/lib/libutee/include/utee_syscalls.h文件,添加如下內(nèi)容,申明上述三個函數(shù)接口。在TA的源代碼中包含該頭文件后就可調(diào)用這三個接口來對該安全驅(qū)動進行調(diào)用。
TEE_Result utee_testDriver_write(void *buf, size_t blen, size_t offset);
修改optee_os/lib/libutee/include/tee_syscall_numbers.h文件,添加上述三個系統(tǒng)調(diào)用接口的索引值,并修改TEE_SCN_MAX的值,需要修改和添加的內(nèi)容如下:
#define TEE_SCN_TESTDRIVER_WRITE 71
2.內(nèi)核空間代碼的修改
修改optee_os/core/arch/arm/tee/arch_svc.c文件中系統(tǒng)調(diào)用數(shù)組變量tee_svc_syscall_table的內(nèi)容,將上述系統(tǒng)調(diào)用對應(yīng)的內(nèi)核層接口添加到該數(shù)組中,并包含申明這三個接口的頭文件,在該文件中添加的內(nèi)容如下:
SYSCALL_ENTRY(syscall_testDriver_write),
上述三個函數(shù)的具體實現(xiàn)在tee_test.c文件中,讀者可自行查閱這三個接口函數(shù)的實現(xiàn)。
3.5 測試使用的TA和CA
將該示例的測試TA和CA添加到OP-TEE中需要修改讀者開發(fā)環(huán)境對應(yīng)的mk文件中。以使用QEMU方式運行OP-TEE為例,則需要修改qemu.mk文件添加該示例代碼的編譯目標,修改步驟如下:
1)添加my_test的編譯目標:
############################################################################
# secure driver test TA--my_test
############################################################################
my_test: my_test-common
my_test-clean: my_test-clean-common
2)將my_test和my_test-clean添加到全局的all和clean目標依賴關(guān)系中:
all: bios-qemu qemu soc-term optee-examples my_test
clean: bios-qemu-clean busybox-clean linux-clean optee-os-clean
optee-client-clean qemu-clean soc-term-clean check-clean
optee-examples-clean my_test-clean
添加部分的主要作用是定義my_test目標并建立該編譯目標與all的依賴關(guān)系,在編譯整個OP-TEE工程時會被使用到。修改完板級編譯的mk文件后,還需修改build/common.mk文件。修改的內(nèi)容主要是將my_test的編譯目標集成到系統(tǒng)編譯中,需要修改的內(nèi)容如下:
1)定義my_test路徑變量:
MY_TEST_PATH ? = $(ROOT)/my_test
2)添加my_test的目標依賴,修改filelist-tee-common目標的依賴關(guān)系如下:
filelist-tee-common: optee-client xtest optee-examples my_test
3)增加TA和CA的common目標:
############################################################################
# my_test
###########################################################################
MY_TEST_COMMON_FLAGS ? = HOST_CROSS_COMPILE=$(CROSS_COMPILE_NS_USER)
TA_CROSS_COMPILE=$(CROSS_COMPILE_S_USER)
TA_DEV_KIT_DIR=$(OPTEE_OS_TA_DEV_KIT_DIR)
TEEC_EXPORT=$(OPTEE_CLIENT_EXPORT)
.PHONY: my_test-common
my_test-common: optee-os optee-client
$(MAKE) -C $(MY_TEST_PATH) $(MY_TEST_COMMON_FLAGS)
MY_TEST_CLEAN_COMMON_FLAGS ? = TA_DEV_KIT_DIR=$(OPTEE_OS_TA_DEV_KIT_DIR)
.PHONY: my_test-clean-common
my_test-clean-common:
$(MAKE) -C $(MY_TEST_PATH) $(MY_TEST_CLEAN_COMMON_FLAGS) clean
4)添加clean操作的依賴關(guān)系:
optee-os-clean-common: xtest-clean optee-examples-clean my_test-clean
5)在filelist-tee-common中添加TA和CA鏡像需要被打包到文件系統(tǒng)中的操作:
@echo“#secure driver test TA“ > > $(fl)
@if [ -e $(MY_TEST_PATH)/host/my_test ]; then
echo "file /bin/my_test"
"$(MY_TEST_PATH)/host/my_test 755 0 0" > > $(fl);
echo "file /lib/optee_armtz/9269fadd-99d5-4afb-a1dc-ee3e9c61b04c.ta"
"$(MY_TEST_PATH)/ta/9269fadd-99d5-4afb-a1dc-ee3e9c61b04c.ta 444 0 0"
> > $(fl);
fi
2.4 安全驅(qū)動示例的測試
完成所有修改之后,編譯整個OP-TEE工程然后運行。在OP-TEE的啟動日志中能看見示例中的系統(tǒng)服務(wù)和驅(qū)動啟動的日志,啟動的日志如圖22-4所示。
系統(tǒng)啟動后,在REE側(cè)的終端中輸入對應(yīng)的指令就可通過TA調(diào)用到該示例的安全驅(qū)動,指令說明如下。
1.向驅(qū)動中寫入數(shù)據(jù)
my_test writeDev [offset] [len]
offset:表示需將數(shù)據(jù)寫入驅(qū)動提供的buffer中的偏移位置。
len:表示需要寫入驅(qū)動中數(shù)據(jù)的長度。寫入驅(qū)動中的數(shù)據(jù)在CA源代碼中被設(shè)定,讀者可通過修改CA源代碼中g(shù)_WriteData變量中的值將不同的內(nèi)容寫入該安全驅(qū)動中。
2.讀取驅(qū)動中的數(shù)據(jù)
my_test readDev [offset] [len]
offset:表示從驅(qū)動中buffer的哪個位置開始讀取。
len:表示需要從驅(qū)動中讀取的內(nèi)容長度。
3.打印出驅(qū)動中的數(shù)據(jù)
my_test dumpDev [len]
len:表示需要打印的數(shù)據(jù)的長度。
用于測試添加的模擬安全驅(qū)動的TA和CA運行的效果如圖22-5所示。
小結(jié)一下啦
前輩的《手機安全和可信應(yīng)用開發(fā)指南》確實寫的很好啊,但是這里估計有l(wèi)inux的驅(qū)動開發(fā)經(jīng)歷,會更加深映像一些。這個part的學(xué)習(xí)解決了我的一些問題。
一起學(xué)習(xí)了OP-TEE中安全設(shè)備驅(qū)動的開發(fā)以及實現(xiàn)安全設(shè)備的安全隔離的原理。
當(dāng)需要在系統(tǒng)中增加安全設(shè)備時,除了需在OP-TEE中開發(fā)該設(shè)備對應(yīng)的安全驅(qū)動之外,還需修改TZPC的配置為該設(shè)備提供安全信號。
TA通過調(diào)用系統(tǒng)調(diào)用接口的方式陷入OP-TEE的內(nèi)核空間來使用驅(qū)動,如需對多個安全設(shè)備進行統(tǒng)一管理,則可添加一個系統(tǒng)服務(wù),將各安全驅(qū)動提供的接口集成到該系統(tǒng)服務(wù)中,使該系統(tǒng)服務(wù)封裝接口暴露給上層使用。
-
驅(qū)動器
+關(guān)注
關(guān)注
54文章
8480瀏覽量
148525 -
寄存器
+關(guān)注
關(guān)注
31文章
5400瀏覽量
122731 -
狀態(tài)機
+關(guān)注
關(guān)注
2文章
493瀏覽量
27964 -
SRAM控制器
+關(guān)注
關(guān)注
0文章
11瀏覽量
5948
發(fā)布評論請先 登錄
相關(guān)推薦
請問搭建智能硬件安全實驗室需要什么設(shè)備或者是技術(shù)?求大神指教
硬件安全是什么?
介紹一種基于硬件的安全模塊
白皮書:PSA Certified 的10個安全目標和 Microsoft 的高安全設(shè)備的7個屬性
面向安全設(shè)備的網(wǎng)絡(luò)安全管理平臺
Fortinet發(fā)布新款企業(yè)安全設(shè)備FortiGate-62
清華大學(xué)首次提出用獨立的芯片“動態(tài)”監(jiān)測硬件安全
Cocoon的家居安全設(shè)備,可智能檢測侵入者
工業(yè)安全設(shè)備的用處是什么
常見的安全設(shè)備盤點
如何將硬件安全模塊功能直接集成到車輛的安全概念中?
聊聊硬件安全設(shè)計以及硬件安全機制相關(guān)的內(nèi)容
安全設(shè)備的硬件安全隔離

評論