SoC : : Architecture/: : i.MX

i.MX 9 BSP Porting Guide - Configuring OP-TEE

Jay.P Morgan 2024. 4. 30. 23:36

  5.1  Intro

 

  Trusted Execution Environment (TEE, 신뢰할 수 있는 실행환경)은 GlobalPlatform 협회(http://www.globalplatform.org)에서 발표한 사양 Set 입니다. TEE의 목적은 보안 애플리케이션을 개발하고 실행하기 위해, 애플리케이션 프로세서 내에 안전한 환경을 제공하는 것입니다. 우리는 애플리케이션 프로세서를 Android나 Linux와 같은 Rich OS를 실행하는 시스템이라고 부릅니다. 리치 환경은 엄청난 양의 코드를 나타냅니다. 이는 타사 애플리케이션에 개방되어 있으며 개방형 생태계입니다. 이로 인해 Rich OS를 검증하기 어렵습니다. 전체 시스템의 보안과 무결성을 손상시킬 수 있는 버그/취약성이 발생하기 쉽습니다. TEE는 풍부한 OS의 공격에 대해 또 다른 수준의 보호를 제공합니다. TEE는 신뢰할 수 있는 파트너에게만 공개되므로 감사가 더 쉽습니다. 신뢰할 수 있고 승인된 소프트웨어만 실행합니다. 모든 민감한 데이터는 애플리케이션 프로세서의 나머지 부분과 외부 세계로부터 보호됩니다.

  TEE는 Arm TrustZone 기술을 사용합니다. TrustZone은 대부분의 Arm Cortex A/M 프로세서에서 사용할 수 있는 시스템 온 칩 보안 기능입니다. 이는 보안 세계(TEE)와 일반 세계(REE) 사이에 엄격한 하드웨어 격리를 제공합니다. 이 기술을 사용하면 각 물리적 프로세서 코어가 두 개의 가상 코어(일반 세계용 하나와 보안 세계용 하나)를 제공할 수 있습니다.

OP-TEE는 Trusted Execution Environment의 오픈 소스 스택입니다. 이 프로젝트에는 다음이 포함됩니다.
     • OP-TEE OS: TEE의 신뢰할 수 있는 부분
     • OP-TEE 클라이언트: TEE의 일반 클라이언트 부분
     • OP-TEE 테스트(또는 xtest): OP-TEE Test Suite

OP-TEE 프로젝트는 BSD 2-Clause에 따라 Linaro에 의해 개발 및 유지 관리됩니다. 소스 코드는 https://github.com/OP-TEE에서 확인할 수 있습니다. 이 스택은 Arm-v7 및 Arm-v8 아키텍처를 지원합니다.

TEE는 클라이언트 애플리케이션과 신뢰할 수 있는 애플리케이션 간의 직렬 작업을 통해 기능을 노출합니다.

애플리케이션. 클라이언트 애플리케이션은 Rich OS에서 실행되며 항상 Trusted OS에서 실행되는 Trusted Application과의 통신을 시작합니다. 클라이언트 애플리케이션은 TEE 클라이언트 API 인터페이스를 통해 TEE와 상호 작용합니다. 보안 애플리케이션은 TEE 내부 API를 통해 TEE 코어와 상호 작용합니다.

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 버전을 지원합니다.

 

 

  5.3  OP-TEE booting flow

 

i.MX 6 및 i.MX 7(Arm V7)의 Booting flow:

부팅 파티션에 필요한 파일 및 바이너리:
     • u-boot-imx*_sd_optee.imx: OP-TEE 부팅 전용 U-Boot 바이너리입니다. OP-TEE는 SD카드 부팅만 지원됩니다.
     • uTee-*: OP-TEE 바이너리가 포함된 자동 추출 이미지입니다.
     • zImage: 커널 이미지.
     • zImage-*.dtb: 장치 트리.

i.MX 6 및 i.MX 7에서 부트로더는 U-Boot입니다. OP-TEE를 부팅하려면, 특정 버전의 U-Boot가 필요합니다(uboot-imx<soc>_sd-optee.imx).

U-Boot는 OP-TEE OS, Linux OS, DTB를 메모리에 로드합니다.

U-Boot가 OP-TEE OS로 점프합니다.

OP-TEE OS는 보안 세계를 초기화하고 DTB를 즉시 수정하여 Linux TEE 드라이버를 로드할 특정 노드를 추가합니다.

그런 다음 Linux OS를 부팅하기 위해 일반 세계로 점프합니다.

 

 

i.MX 8(Arm V8)의 Booting flow:

 

부팅 파티션에 필요한 파일 및 바이너리:
     • flash.bin: U-Boot 및 ATF가 포함된 Fit 이미지
     • zImage: 커널 이미지
     • zImage-*.dtb: 디바이스 트리

  Arm V8에서 Arm에는 Arm Trusted Firmware(ATF)를 사용하여 보안 구성 요소를 부팅하는 특정 기본 방법이 있습니다.

  ATF는 먼저 OP-TEE OS를 로드합니다. OP-TEE OS는 보안 세계를 초기화합니다. 그런 다음 ATF는 Linux TEE 드라이버를 로드하기 위한 특정 노드를 추가하기 위해 즉시 DTB를 수정하는 U-Boot를 로드합니다. 그런 다음 Linux OS가 부팅됩니다.

 

 

 

 

 

  5.4  OP-TEE Linux support

 

 

  Linux TEE 드라이버는 TEE에 대한 일반 인터페이스를 정의합니다. 자세한 내용은 Documentation/tee.txt를 참조하세요.
다음 node가 장치 트리에 있으면 Linux TEE 드라이버가 부팅됩니다 :

firmware {     optee {
        compatible = "linaro, optee-tz";
        method = "smc";
        };
    };

 

  이 node는 i.MX 6, i.MX 7 및 i.MX 7ULP용 OP-TEE OS에 의해 추가되고, i.MX 8M Mini, i.MX 8M Nano 및 i.MX 8M의 U-Boot에 의해 추가됩니다. 

 

 

  5.5  Memory protection

 

  5.5.1  OCRAM protection

 

  OCRAM은 On-Chip RAM을 의미합니다. i.MX 6 및 i.MX 7에서 크기는 128KB에서 256KB까지 다양합니다. OCRAM의 주요목적은 CPU idle, 버스 주파수 또는 suspending와 같은 전원 관리 기능을 유지하고 실행하는 것입니다. 활성화되면 OP-TEE는 suspending 또는 CPU idle과 같은 전원 관리 기능을 처리합니다. 따라서 OP-TEE는 자체 전원 관리 코드를 실행하기 위해 OCRAM에 보안 영역을 할당해야 합니다. 이는 IOMUXC_GPR 레지스터를 구성하여 수행할 수 있습니다. 하단은 비보안으로, 상단은 보안으로 설정되어 있습니다.

 

  보안 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 노드를 수정하여 수행됩니다.

Note:
  i.MX 6SoloX 및 i.MX 7Dual의 경우 OCRAM에는 OCRAM과 OCRAM_S의 두 가지 유형이 있습니다. OCRAM_S는 보안 또는 비보안입니다. 두 개로 분할할 수 없습니다. 이 경우 OP-TEE는 전원 관리 기능을 위해 항상 OCRAM_S를 인수하고 OCRAM을 비보안 상태로 유지하며 OCRAM 크기 조정이 수행되지 않습니다.

 

 

  5.5.2 TZASC380 – RAM 보호

 

  TZC-380은 DRAM 메모리 공간에 대해 구성 가능한 보호를 제공하도록 설계된 Arm에서 개발한 IP입니다. 주요 기능은 플랫폼에서 실행되는 잠재적으로 손상된 소프트웨어로부터 TEE(신뢰할 수 있는 실행 환경)의 보안에 민감한 소프트웨어와 데이터를 보호하는 것입니다. TZASC의 주요 기능은 다음과 같습니다.

     • 16개의 독립적인 주소 영역을 지원합니다.
     • 액세스 제어는 각 주소 영역에 대해 독립적으로 프로그래밍 가능합니다.
     • 민감한 레지스터가 잠겨 있을 수 있습니다.
     • 액세스 제어 위반 시도를 알리도록 호스트 인터럽트를 프로그래밍할 수 있습니다.
     • 트랜잭션을 위한 AXI 마스터/슬레이브 인터페이스.
     • 구성 및 상태 보고를 위한 APB 슬레이브 인터페이스.

 

 

  5.5.3 TZASC 영역 설정


  TZC-380은 특정 DRAM 주소공간에 대한 트랜잭션 액세스를 허용하거나 거부하도록 구성할 수 있는, 최대 16개의 독립 영역을 지원합니다. 해당 장치가 제공하는 영역 개수는 구성 레지스터(Offset 0x0)에서 확인할 수 있습니다. 지역 0을 제외하고 다음 지역 매개변수를 프로그래밍할 수 있습니다.

     • 지역 활성화
     • 기본 주소
     • 크기(영역의 최소 주소 크기는 32KB)
     • 소지역 권한

  지역은 중복될 수 있으며, 지역 우선순위에 따라 최종 권한이 정의됩니다. 우선순위는 지역 번호로 정의됩니다. 지역 0은 우선순위가 가장 낮습니다.

  32MB의 RAM 공간이 OP-TEE에 할당됩니다. 28MB는 TZASC에 의해 보안(OP-TEE RAM)으로 매핑되고 마지막 4MB는 비보안(공유 메모리)으로 매핑됩니다. 이 보안 메모리의 시작 주소와 크기는 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 간의 공유 메모리입니다. 보안 및 일반 환경에서 읽기 및 쓰기가 허용됩니다.

  i.MX 6UL에서의 TZASC 구성 예:

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; }

 

Note:  i.MX 8QuadMax 및 i.MX 8QuadXPlus에서 SCFW는 리소스를 분할하는 파티션 개념을 제공합니다. 28MB OP-TEE 메모리(0xFE000000 - 0xFFC00000)는 ATF에 의해 보안 파티션에 할당됩니다. U-Boot 및 커널과 같은 비보안 파티션에서는 액세스할 수 없습니다. U-Boot는 현재 비보안 파티션에서 메모리 영역을 가져오고 커널용 메모리 노드를 설정합니다.

 

• i.MX 6 및 i.MX 7
  TZASC 활성화는 IOMUXC_GPR9 레지스터의 TZASC_BYPASS bit(s)를 설정하는 U-Boot에 의해 수행됩니다. 이 비트가 프로그래밍되면 TZASC는 바이패스 모드에서 벗어나 DRAM 메모리에 대한 AXI 액세스에 대한 보안 검사를 수행하기 시작합니다. TZASC_BYPASS 비트는 "일회성 쓰기" 유형 비트입니다. 일단 활성화되면 다음 전원 공급 주기까지 변경할 수 없습니다. 이는 무단 비활성화 작업을 방지합니다.

• 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 제품군에서 이 비트는 "일회성 쓰기" 유형이 아니며 의도하지 않은 비활성화 작업을 방지하기 위해 TZASC_EN_LOCK을 프로그래밍해야 합니다. i.MX 8M Mini에서는 GPU를 사용할 때 AXI 버스 오류를 방지하려면 IOMUXC_GPR10[1]에서 TZASC_ID_SWAP_BYPASS를 활성화해야 합니다. TZASC ID 교환 기능은 특정 조건에서 GPU 충돌을 일으키는 AXI 사용자 ID를 올바르게 처리하지 못합니다.

 

 

  5.6  How to compile OP-TEE

 

  OP-TEE는 BSP에서 기본적으로 활성화됩니다. 이미지 빌드 방법에 대한 정보는 i.MX Yocto User's Guide (IMXLXYOCTOUG)의 지침을 따르세요.

SD 카드를 플래시하려면 아래를 참조하세요.

$ 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 && sync Run the test suite to check if optee is operational:
$ root@imx: xtest

 

  OP-TEE를 컴파일하는 또 다른 방법은 make 명령을 사용하는 것입니다. 크로스 컴파일을 위한 Linaro 툴체인을 다운로드하고 설치합니다.

$ export CROSS_COMPILE=/<path>/arm-linux-gnueabihf-
$ export CROSS_COMPILE64=/<path>/aarch64-linux-gnu-
$ make PLATFORM=imx-<platform_flavor> <flags>

 

  OPTEE-OS에 대한 추가정보를 찾으신다면,  https://optee.readthedocs.io/en/latest/building/gits/ optee_os.html#build-instructions 을 확인하세요.

 

 

  5.7  Adding OP-TEE support for a new board

 

이 섹션에서는 새 보드에 OP-TEE OS를 추가하는 방법을 설명합니다.


  5.7.1 U-Boot


  U-Boot는 레지스터에서 TZASC 우회를 비활성화해야 합니다. 이를 위해서는 범용 레지스터(IOMUXC_GPR9/10)에 비트를 설정해야 합니다. 참조 매뉴얼에 따라 TZASC 바이패스를 비활성화하도록 설정할 비트를 확인하십시오. 다음 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

Note:  OP-TEE는 U-Boot 환경에서 env set tee no를 설정하여 언제든지 비활성화할 수 있습니다.

 

 

  5.7.2 OP-TEE OS

 

  plat-imx/imx-common.c에서, bool soc_imx*(void)와 같은 보드 함수 식별자(board function identifier)를 추가합니다.

  plat-imx/config/imx*.h에서 보드별 헤더 파일을 추가하여 DRAM0_BASE, DRAM0_SIZE, CFG_UART_BASE 및 CONSOLE_UART_BASE와 같은 상수를 정의합니다. plat-imx/platform_config.h에 구성 파일을 추가합니다.

  plat-imx/registers/에서, 마지막으로 보드별 레지스터를 추가합니다.
  plat-imx/conf.mk에서, 새 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 항목 주소(entry address), 장치 트리 주소(device tree address) 및 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에서 보안 메모리 매핑을 구성합니다. 대부분의 경우 기본 영역, Linux의 비보안 영역, OP-TEE의 보안 공간, 공유 메모리 공간의 네 가지 영역을 매핑해야 합니다.

 

 

  5.7.3 Linux OS


  없음.