정보
IMXBSPPG
Rev. LF5.15.5_1.0.0, 31 March 2022를 기준으로 작성
Chapter 5 Configuring OP-TEE
5.1 Introduction
Trusted Execution Envirnoment(TEE : 신뢰할 수 있는 실행 환경)는 GlobalPlatform 협회(www.globalplatform.org)에서 발행된 사양의 집합이다. TEE의 목적은 보안 애플리케이션을 개발하고 실행하기 위해서 애플리케이션 프로세서 내부에 안전한 환경을 제공하는 것이다. Android나 Linux와 같은 Rich OS를 실행하는 시스템을 애플리케이션 프로세서로 부른다. Rich 환경은 엄청난 양의 코드를 나타낸다. Rich 환경은 타사 애플리케이션에 개방되어 있고 개방형 ecosystem이다. Rich 환경은 Rich OS를 감사하기 어렵게 만든다. Rich 환경은 버그/취약점에 취약하므로 전체 시스템의 보안과 무결성을 손상시킬 수 있다. TEE는 Rich OS의 공격에 대해 또 다른 보호 레벨을 제공한다. TEE는 신뢰할 수 있는 파트너에게만 열려있으므로 감사하기가 더 쉽다. TEE는 신뢰할 수 있고 승인된 소프트웨어만 실행한다. 모든 민감한 데이터는 나머지 애플리케이션 프로세서와 외부 세계로부터 보호된다.
TEE는 Arm TrustZone 기술에 의존한다. TrustZone은 대부분의 Arm Cortex A/M 프로세서에서 사용할 수 있는 system-on-chip 보안 기술이다. 이는 보안 환경(TEE)와 일반 환경(REE) 사이에 엄격한 하드웨어적인 격리를 제공한다. 이 기술을 통해 각 물리적인 프로세스 코어는 두 개의 가상 코어를 제공할 수 있다. 하나는 일반 환경을 위한 것이고 다른 하나는 보안 환경를 위한 것이다.
OP-TEE는 Trusted Execution Environment의 오픈 소스 스택이다. 이 프로젝트에는 다음이 포함된다 :
- OP-TEE OS : TEE의 신뢰할 수 있는 측면
- OP-TEE Client : TEE의 일반 환경 클라이언트 측면
- OP_TEE Test (or xtest) : OP-TEE 테스트 Suite
OP-TEE 프로젝트는 BSD 2-Clause(라이센스)에 따라 Linaro가 개발과 유지 관리한다. 소스 코드는 https://github.com/OP-TEE에서 사용할 수 있다. 이 스택은 Arm-v7과 Arm-v8 아키텍처를 지원한다.
TEE는 Client Application과 Trusted Application 사이에 직렬화를 통해 기능을 노출한다. Client Application은 Rich OS에서 실행되고 항상 Trusted OS에서 실행하는 Trusted Application과 통신을 시작한다. Client Application은 TEE 클라이언트 API 인터페이스를 통해 TEE와 상호 작용한다. Secure Application은 TEE 내부 API를 통해 TEE Core와 상호 작용한다.
TEE GlobalPlatform 사양은 https://globalplatform.org/specs-library/에서 찾을 수 있다.
5.2 Boards supported
모든 i.MX 6, 7, 8 보드는 OP-TEE를 지원한다. 일부는 i.MX 6ULL EVK와 i.MX 6ULZ EVK 같은 여러 보드에 대해 동일한 OP-TEE flavor를 지원한다.
5.3 OP-TEE booting flow
Booting flow on i.MX 6 and i.MX 7 (Arm V7) :
부트 파티션에 필요한 파일과 바이너리 :
- u-boot-imx*_sd_optee.imx : 부트 OP-TEE에 특정한 U-Boot 바이너리. TEE는 SD 카드에서 부팅만 지원한다.
- uTee-* : OP-TEE 바이너리가 포함된 self-extracting(자동 압축 풀기) 이미지.
- zImage : 커널 이미지.
- zImage-*.dtb : 디바이스 트리
i.MX 6, i.MX 7에서 부트로더는 U-Boot이다. OP-TEE를 부팅하려면, U-Boot의 특정 버전(u-boot-imx<soc>_sd-optee.imx)이 필요하다. U-Boot는 메모리에 OP-TEE OS, Linux OS, DTB를 로드한다. U-Boot는 OP-TEE OS로 점프한다. OP-TEE OS는 보안 환경을 초기화하고, Linux TEE 드라이버를 로드할 특정 노드를 추가하기 위해 즉시 DTB를 수정한다. 그런 다음, 일반 환경으로 점프하여 Linux OS를 부팅한다.
Booting flow on i.MX 8 (Arm V8)
부트 파티션에 필요한 파일과 바이너리 :
- flash.bin : U-Boot와 ATF가 포함된 fit(적당)한 이미지
- zImage : 커널 이미지
- zImage-*.dtb : 디바이스 트리
Arm V8에서는, Arm은 ATF(Arm Trusted Firmware)로 Secure Component를 부팅하는 특정 기본 설정 방법이 있다. ATF는 먼저 OP-TEE OS를 로드한다. OP-TEE OS는 보안 환경을 초기화한다. 그런 다음, Linux TEE 드라이버를 로드할 특정 노드를 추가하기 위해, 즉시 DTB를 수정한 U-Boot를 ATF가 로드한다. 그 후 Linux OS가 부팅된다.
5.4 OP-TEE Linux support
Linux Tee 드라이버는 TEE에 대한 일반 인터페이스를 정의한다. 자세한 내용은 Documentation/tee.txt를 참조한다.
아래 노드가 디바이스 트리에 있으면, Linux TEE 드라이버는 부팅된다.
firmware {
optee {
compatible = "linaro, optee-tz";
method = "smc";
};
};
이 노드는 i.MX 6, i.MX 7, i.MX 7ULP에서는 OP-TEE OS에서 추가되고, i.MX 8M Mini, i.MX 8M Nano, i.MX 8M Plus에서는 U-Boot에서 추가된다.
5.5 Memory protection
OCRAM protection
OCRAM은 On-Chip RAM의 약자이다. i.MX 6과 i.MX 7에서는 128KB이나 256KB 사이로 그 크기가 다양하다. OCRAM의 주요 목적은 전원 관리 기능(CPU idle, bus frequency, suspending와 같은)을 유지하고 실행하는 것이다. OCRAM이 활성화 되면, OP-TEE는 suspending이나 CPU idle 같은 전원 관리 기능을 처리한다. 따라서, OP-TEE는 자체 전원 관리 코드를 실행하기 위해 OCRAM에 보안 환경을 할당해야 한다. 이것은 IOMUXC_GPR 레지스터를 구성하여 수행할 수 있다. 하위 영역은 non-secure로 설정되어 있고, 상위 영역은 secure로 설정되어 있다.
secure OCRAM의 시작 주소와 크기는 디바이스 트리 ocram_optee 노드에서 정의된다 :
ocram: sram@00905000 {
compatible = "mmio-sram";
reg = <0x00905000 0x3B000>;
clocks = <&clks IMX6QDL_CLK_OCRAM>;
};
ocram_optee: sram@00938000 {
compatible = "fsl,optee-lpm-sram";
reg = <0x00938000 0x8000>;
overw_reg = <&ocram 0x00905000 0x33000>;
};
부팅 시, OP-TEE는 디바이스 트리의 ocram 노드를 즉시 수정한다. OCRAM 영역을 할당하고 확보하기 위해서, OP-TEE는 커널에 할당된 OCRAM 공간을 줄인다. 이것은 ocram_optee 노드의 overw_reg에 정의된 속성으로 ocram 노드를 수정하여 수행된다.
참고
i.MX 6SoloX와 i.MX 7Dual의 경우, OCRAM에 OCRAM과 OCRAM_S 두 가지 유형이 있다. OCRAM_S는 secure(보안)나 non-secure(일반)이다. 두 가지로 나눌 수 없다(둘 중 하나로만 사용가능). 이 경우에 OP-TEE는 항상 전원 관리 기능을 위해 OCRAM_S를 선택하고 OCRAM non-secure를 벗어난다. OCRAM의 크기 조정은 수행되지 않는다.
TZASC380 - RAM protection
TZC-380은 DRAM 메모리 영역에 구성가능한 보호 기능을 제공하도록 설계된 Arm에서 개발된 IP 이다. 주요 기능은 플랫폼에서 실행되는 잠재적으로 손상될 수 있는 소프트웨어로 부터 TEE(Trusted Execution Envirnoment)에서 보안에 민감한 소프트웨어와 데이터를 보호하는 것이다. TZASC의 주요 기능은 아래와 같다 :
- 16개의 독립적인 주소 영역을 지원한다.
- 액세스 컨트롤은 각 주소 영역에 대해 독립적으로 프로그래밍할 수 있다.
- 민감한 레지스터가 잠겨(locked) 있을 수 있다.
- 호스트 인터럽트는 시도된 액세스 컨트롤 위반을 알리도록 프로그래밍될 수 있다.
- 트랜잭션을 위한 AXI 마스터/슬레이브 인터페이스.
- 구성과 상태 보고를 위한 APB 슬레이브 인터페이스.
Setting TZASC regions
TZC-380은 최대 16개의 독립 영역을 지원한다. 이 영역은 DRAM 주소 공간에 대한 트랜잭션 액세스를 accept(허용) 또는 deny(거부)하도록 구성할 수 있다. 디바이스에서 제공하는 영역의 수는 구성 레지스터(offset 0x0)에서 확인할 수 있다. 영역 0을 제외하고, 영역에 아래의 파라미터를 프로그래밍할 수 있다 :
- 영역 활성화
- 기본 주소
- 크기 (영역의 최소 주소 크기는 32KB이다.)
- 하위 영역 권한
영역은 겹칠 수 있으며, 영역 우선 순위에 따라 최종 권한이 정의 된다. 우선 순위는 영역 번호로 정의된다. 영역 0은 가장 낮은 우선 순위이다.
RAM 공간의 32MB가 OP-TEE에 할당된다. 28MB는 TZASC에 의해 secure(OP-TEE RAM)으로 매핑되고, 나머지 4MB는 non-secure(shared memory)로 매핑된다. 이 보안 메모리의 시작 주소(CFG_TZDRAM_START)와 크기(CFG_TZDRAM_SIZE)는 하드코딩되어 있다. 이러한 값은 초기화 후 OP-TEE OS에 의해 디바이스 트리에 추가된다 :
/sys/firmware/devicetree/base/reserved-memory/optee_core@<some_address>optee@<some address>
optee-core 주소는 OP-TEE 펌웨어에 있다. 일반 환경에서 읽거나 쓰면 충돌이 발생할 수 있다. OP-TEE 주소는 Linux OS와 OP-TEE 사이의 공유 메모리이다. 읽기와 쓰기는 보안과 일반 환경에서 허용된다.
Example of TZASC configuration for i.MX 6UL :
static int board_imx_tzasc_configure(vaddr_t addr)
{
tzc_init(addr);
tzc_configure_region(0, 0x00000000,
TZC_ATTR_REGION_SIZE(TZC_REGION_SIZE_4G) |
TZC_ATTR_REGION_EN_MASK | TZC_ATTR_SP_S_RW);
tzc_configure_region(1, 0x80000000,
TZC_ATTR_REGION_SIZE(TZC_REGION_SIZE_512M) |
TZC_ATTR_REGION_EN_MASK | TZC_ATTR_SP_NS_RW);
tzc_configure_region(2, 0x84000000,
TZC_ATTR_REGION_SIZE(TZC_REGION_SIZE_32M) |
TZC_ATTR_REGION_EN_MASK | TZC_ATTR_SP_S_RW);
tzc_configure_region(3, 0x9fe00000,
TZC_ATTR_REGION_SIZE(TZC_REGION_SIZE_2M) |
TZC_ATTR_REGION_EN_MASK | TZC_ATTR_SP_ALL);
tzc_dump_state();
return 0;
}
참고
i.MX 8QuadMax와 i.MX 8QuadXPlus에서, SCFW는 리소스를 분할하는 파티션 개념을 제공한다. 28MB OP-TEE 메모리(0xFE000000 -- 0xFFC00000)는 ATF에 의해 secure 파티션에 할당된다. U-Boot와 커널과 같은 non-secure 파티션에서는 액세스할 수 없다. U-Boot는 현재 non-secure 파티션에서 메모리 영역을 가져오고, 커널에 대한 메모리 노드를 설정한다.
- i.MX 6, i.MX 7
TZASC 활성화는 IOMUXC_GPR9 레지스터에 TZASC_BYPASS비트를 설정하는 U-Boot에 의해 수행된다. 이 비트가 한번 프로그램되면, TZASC는 바이패스 모드에서 벗어나고 DRAM 메모리의 AXI 액세스에 대한 보안 검사를 수행하기 시작한다. TZASC_BYPASS 비트는 "one time write (일회성 쓰기)" 유형 비트이다. 한번 활성화되면, 다음에 전원이 공급될 때가지 변경할 수 없다. 이것은 무단으로 비활성화하는 작업을 방지 한다. - i.MX 8M Quad, i.MX 8M Mini, i.MX 8M Nano, i.MX 8M Plus
i.MX 6, i.MX 7 제품군과 유사하게, TZASC 활성화는 IOMUXC_GPR10에서 TZASC_EN 비트를 설정하여 수행된다. mscale 제품군에서, 이 비트는 "one time write (일회성 쓰기)" 유형이 아니고, 의도하지 않은 비활성화 작업을 방지하기 위해 TZASC_EN_LOCK은 프로그램되어야 한다. i.MX 8M Mini에서, GPU를 사용할 때 AXI 버스 오류를 방지하려면 IOMUXC_GPR10[1]에서 TZASC_ID_SWAP_BYPASS를 활성화해야 한다. TZASC ID Swap 기능은 특정 조건에서 GPU 충돌로 이어지는 AXI Users IDs를 올바르게 처리하지 않는다.
5.6 How to compile OP-TEE
OP-TEE는 기본으로 BSP에서 활성화되어 있다. 이미지를 빌드하는 방법에 대한 정보는 i.MX Yocto User’s Guide (IMXLXYOCTOUG)의 지침을 따른다. SD 카드에 flash(저장)하려면 아래를 참조한다.
Flash the SD card :
$ cd tmp/deploy/images/<platform>/
$ bzip2 -d tmp/deploy/images/<platform>/imx-image-multimedia*.wic.bz2
$ sudo dd if=imx-image-multimedia*.wic of=/dev/sd<partition> bs=1M && syncRun the test suite to check if optee is operational:
$ root@imx: xtest
OP-TEE를 컴파일하는 다른 방법은 imx-optee-os/scripts/imx-build.sh 스크립트를 사용하는 것이다. 크로스 컴파일을 위한 Linaro 툴 체인을 다운로드하고 설치한다 :
$ export CROSS_COMPILE=/<path>/arm-linux-gnueabihf-
$ export CROSS_COMPILE64=/<path>/aarch64-linux-gnu-
$ scripts/imx-build.sh <board>
5.7 Adding OP-TEE support for a new board
이 섹션에서는 OP-TEE OS를 새로운 보드에 추가하는 방법을 설명한다.
- U-Boot
U-Boot는 레지스터에서 TZASC bypass를 비활성화해야 한다. 그렇게 하려면, General-Purpose Register(IOMUXC_GPR9/10)에서 비트를 설정해야 한다. Reference Manual에 따라, TZASC bypass를 비활성화하는 설정 비트를 확인한다. 아래 U-Boot 소스 코드에서 작업을 수행한다 :
/uboot-imx/board/freescale/<platform>/<soc>.cfg에서 디바이스 구성 데이터(DCD)에 다음 코드를 추가한다 :
#ifdef CONFIG_IMX_OPTEE DATA 4 <register addr> <value> CHECK_BITS_SET 4 <register addr> <value> #endif
/uboot-imx/board/freescale/<platform>/< platform>.c에서 tee 환경 속성은 기본으로 "yes"로 설정되어야 한다 :
env_set("tee", "no"); #ifdef CONFIG_IMX_OPTEE env_set("tee", "yes"); #endif
참고
OP-TEE는 U-Boot 환경에서 env set tee no를 설정하여 언제든지 비활성화할 수 있다.
- OP-TEE OS
plat-imx/imx-common.c에 bool soc_imx*(void)와 같은 보드 식별 함수를 추가한다.
plat-imx/config/imx*.h에 DRAM0_BASE, DRAM0_SIZE, CFG_UART_BASE, CONSOL_UART_BASE와 같은 상수를 정의하는 보드별 헤더 파일을 추가한다. plat-imx/platform_config.h에 구성 파일을 추가한다.
plat-imx/registers/에 마지막으로 보드별 레지스터를 추가한다.
plat-imx/conf.mk에서 플랫폼 flavorlist(즐겨 찾는 목록)에 새로운 SoC를 추가하고 새로운 보드의 SoC와 코어 수를 정의한다 :
else ifneq ($(filter $(PLATFORM_FLAVOR),$(mx*-flavorlist))) $(call force,CFG_MX*,y) $(call force,CFG_MX*,y) $(call force,CFG_TEE_CORE_NB_CORE,*)
Linux 엔트리 주소, 디바이스 트리 주소, DDR 크기를 지정한다.
ifneq (,$(filter $(PLATFORM_FLAVOR),mx*)) CFG_DT ?= y CFG_NS_ENTRY_ADDR ?= CFG_DT_ADDR ?= CFG_DDR_SIZE ?= CFG_PSCI_ARM32 ?= y CFG_BOOT_SYNC_CPU = * CFG_BOOT_SECONDARY_REQUEST = * endif
plat-imx/sub.mk에서, SoC가 Arm V7인 경우 Arm 프로세서(Cortex A7이나 A9)를 정의한다.
plat-imx/tzasc.c에서, secure 메모리 매핑을 구성한다. 대부분의 경우 4개의 영역(기본 영역, Linux용 non-secure 영역, OP-TEE용 secure 영역, 공유 메모리 영역)을 매핑해야 한다.
scripts/imx_build.sh에서 새로운 플랫폼 flavor를 board_list에 추가한다. - Linux OS
None
'NXP i.MX SoC Family > i.MX BSP Porting Guide' 카테고리의 다른 글
i.MX BSP Porting Guide - Memory Assignment (0) | 2022.07.04 |
---|---|
i.MX BSP Porting Guide - Configuring Arm Trusted Firmware (0) | 2022.07.04 |
i.MX BSP Porting Guide - Porting System Controller Firmware (0) | 2022.07.01 |
i.MX BSP Porting Guide - Porting U-Boot (0) | 2022.06.29 |
i.MX BSP Porting Guide - Porting Kernel (0) | 2022.06.29 |