OP-TEE / optee_os

Trusted side of the TEE
Other
1.57k stars 1.06k forks source link

Optee version mismatch in kernel #2994

Closed jonsmirl closed 4 years ago

jonsmirl commented 5 years ago

I would like to use optee encryption support from user space so I enabled optee support in the rk3288 kernel. The released rockchip 4.4 kernel needs optee API >2.0

drivers/tee/optee/optee_msg.h
#define OPTEE_MSG_REVISION_MAJOR    2
#define OPTEE_MSG_REVISION_MINOR    0

https://github.com/rockchip-linux

[    0.452166] TEE Core Framework initialization (ver 1:0.1)
[    0.452888] TEE armv7 Driver initialization
[    0.453884] tz_tee_probe: name="armv7sec", id=0, pdev_name="armv7sec.0"
[    0.454532] TEE core: Alloc the misc device "opteearmtz00" (id=0)
[    0.455474] TEE Core: Register the misc device "opteearmtz00" (id=0,minor=62)

I added a printk to show to revision of the loaded core:

[ 2.271440] optee: probing for conduit method from DT.
[ 2.276756] JDS: major 1 minor 0
[ 2.281685] optee: api revision mismatch

Where is the version 1.0 coming from? bl31? Do I need to rebuild it with a later version of optee?

I can run mmc testsecurestorage from uboot and it succeeds.

RunBL31 0x10000
NOTICE: BL31: v1.3(debug):0eba775
NOTICE: BL31: Built : 12:11:32, Nov 23 2018
NOTICE: BL31:Rockchip release version: v1.3
INFO: ARM GICv2 driver initialized
INFO: Using opteed sec cpu_context!
INFO: boot cpu mask: 1
INFO: plat_rockchip_pmu_init: pd status 0xe
INFO: BL31: Initializing runtime services
INFO: BL31: Initializing BL32
INF [0x0] TEE-CORE:init_primary_helper:337: Initializing (1.1.0-194-g646eecc5 #61 Wed Dec 5 06:31:51 UTC 2018 aarch64)
INF [0x0] TEE-CORE:init_primary_helper:338: Release version: 1.4
INF [0x0] TEE-CORE:init_teecore:83: teecore inits done
INFO: BL31: Preparing for EL3 exit to normal world
INFO: Entry point address = 0x200000
INFO: SPSR = 0x3c9
jbech-linaro commented 5 years ago

@JosephChen2017, would you mind having a look at this?

jenswi-linaro commented 5 years ago

It looks like you're using the (now very) old out of tree driver. I'd recommend switching to the upstream driver instead.

ElonZhang0328 commented 5 years ago

@jonsmirl Some rockchip platforms are still using old version OP-TEE software component(optee_os/optee_linuxdriver/optee_client/optee_test). So I think the optee function is OK on your rockchip platform. The upstream optee version maybe is not suitable for your platform.

JosephChen2017 commented 5 years ago

Hi, @jonsmirl: @zhangzj1990 is my colleague and responsible for rockchip optee development, you can take his advice. If you need, you can get latest optee binary from: https://github.com/rockchip-linux/rkbin.

jonsmirl commented 5 years ago

I am using the lastest binary from https://github.com/rockchip-linux/rkbin. I have also been trying to rebuild it. I would like to get a demo equivalent to the optee rasp pi demo working on the RK3328

Right now when I build the arm trusted firmware for RK3328 from the optee repo, the fip binary is ending up 4GB in size. I get the same result from the repo on rockchip-linux

-rwxr-xr-x 1 jonsmirl jonsmirl 4278715344 May  8 18:59 bl31.bin
-rw-r--r-- 1 jonsmirl jonsmirl 4278715508 May  8 18:59 fip.bin

CROSS_COMPILE=aarch64-linux-gnu- make NEED_BL32=yes BL32=/home/jonsmirl/aosp/optee/build/../optee_os/out/arm/core/tee-header_v2.bin BL32_EXTRA1=/home/jonsmirl/aosp/optee/build/../optee_os/out/arm/core/tee-pager_v2.bin BL32_EXTRA2=/home/jonsmirl/aosp/optee/build/../optee_os/out/arm/core/tee-pageable_v2.bin BL33=/home/jonsmirl/aosp/optee/build/../u-boot/u-boot.bin DEBUG=1 V=0 CRASH_REPORTING=1 LOG_LEVEL=40 PLAT=rk3328 RK3328_PRELOADED_DTB_BASE=0x00010000 SPD=opteed all fip
JosephChen2017 commented 5 years ago

./plat/rockchip/rk3328/include/plat.ld.S defines the sram data/text sections which makes bl31.bin always be 4GB size, and pre-loader is responsible for loading the bl31 sram section binary.

Usually for rockchip platform, we only use bl31.elf to pack but not bl31.bin by tool "trust_merger", it can parse bl31.elf and get real binary to pack it as trust.img [0], including bl31, bl32(optional). And we pack u-boot.bin as uboot.img by tool "loaderimage".

If your build command can not support bl31.elf, maybe you have to use objcopy to get real binary from elf ?

[0] Build trust.img or unpack trust.img Commands in rkbin project: ./tools/trust_merger --replace tools/rk_tools/ ./ RKTRUST/RK3328TRUST.ini ./tools/trust_merger --unpack trust.img

Source code for trust_merger: https://github.com/rockchip-linux/u-boot/blob/next-dev/tools/rockchip/boot_merger.c

jonsmirl commented 5 years ago

Our current product has an ATECC608A security chip on it. That chip can perform eliptic curve calculations and also securely store the keys. ECC is used to log into Amazon AWS IOT (same process works for MS Azure, Google, Baidu). We are evaluating the RK1808, but since RK1808 boards are not easily available I am using a RK3328 board to get started.

My goal is to run a TA that does the ECC and securely stores the keys which would let us eliminate the ATECC608A chip.

I am aware of this project, it is PCKS#11 driver for optee underdevelopment. https://github.com/etienne-lms/optee_os/tree/sks/ta/secure_key_services

So is it feasible to use a TA for ECC and keystore on the RK3328? My optimal solution would be an OpenSSL plugin that calls out to the TA for the ECC portion and then uses the RK3328 hardware for DES. I have this model working via the ATECC608A since it comes with a PKCS#11 plugin. That plugin works with the Rockchip supplied OpenSSL.

How do I go about building this, https://github.com/etienne-lms/optee_os/tree/sks/ta/secure_key_services, so that I can access it on the RK3328? This and the released Linux kernel both need optee 2.0

jonsmirl commented 5 years ago

Where are the scripts used to make binaries in rkbin/bin? I can't figure out how to reproduce: PATH=tools/rk_tools/bin/rk33/rk322xh_bl31_v1.40.elf PATH=tools/rk_tools/bin/rk33/rk322xh_bl32_v1.48.bin

I can compile new versions, but my versions don't match the ones in rkbin/bin. I need to know what command lines were used to make the binaries.

JosephChen2017 commented 5 years ago

rk322xh_bl31_v1.40.elf is from your ATF project bl31.elf; rk322xh_bl32_v1.48.bin is from your optee_os project tee-pager_v2.bin

“tools/rk_tools/“ is prefix path from rockchip legacy u-boot project[0], we still leave it in rkbin project to make compatible with legacy u-boot. In rkbin project, trust_merger will drop it when pack binary as a trust.img.

So, replace the file below in rkbin project with your own bl31 elf and optee bin: ./bin/rk33/rk322xh_bl31_v1.40.elf ./bin/rk33/rk322xh_bl32_v1.48.bin

Then execute command in rkbin/ and you get the trust.img: ./tools/trust_merger --replace tools/rk_tools/ ./ RKTRUST/RK3328TRUST.ini

[0] "tools/rk_tools/" in leagcy u-boot. https://github.com/rockchip-linux/u-boot/tree/rkproduct/tools/rk_tools/bin/rk33/rk322xh_xxx...

ElonZhang0328 commented 5 years ago

Hi @jonsmirl V1.1.0 OP-TEE component are used on the RK3328 board but V3.3.0 on RK1808 board. So if you want to run OP-TEE V2.0 on RK3328(as https://github.com/etienne-lms/optee_os/tree/sks/ta/secure_key_services is unavailabe on V1.1.0 OP-TEE), some porting work should be done as below: 1.Rebuid bl32.bin using upstream optee_os and pack the binary to trust.img as @JosephChen2017 described. And i think there is no need to rebuild bl31.elf. 2.Enable CONFIG_TEE and CONFIG_OPTEE in linux kernel to enable the new version optee linux driver. 3.Build the upstream optee_client to get tee-supplicant daemon and libteec.so. And build optee_test to get the test CA/TA and build you own CA/TA.

jonsmirl commented 5 years ago

objdump of rk322xh_bl31_v1.40.elf says it is 64b rk322xh_bl31_v1.40.elf: file format elf64-little

And the build for optee_os only works 32b.

CROSS_COMPILE=arm-linux-gnueabihf- make PLATFORM=rockchip CFG_TEE_CORE_LOG_LEVEL=3 DEBUG=1 CFG_TEE_BENCHMARK=n

this fails:

CROSS_COMPILE=aarch64-linux-gnu- make  CFG_ARM64_core=y PLATFORM=rockchip CFG_TEE_CORE_LOG_LEVEL=3 DEBUG=1 CFG_TEE_BENCHMARK=n
core/arch/arm/cpu/cortex-a7.mk:2: *** CFG_ARM64_core is set to 'y' (from command line) but its value must be 'n'.  Stop.

So how do I build a 64b rk3328 optee_os?

I tried booting with the 32b tee-pager_v2.bin and it hung when it tried to load.

LoadTrust Addr:0x4000
No find bl30.bin
Load uboot, ReadLba = 2000
Load OK, addr=0x200000, size=0xbe8bc
RunBL31 0x10000
NOTICE:  BL31: v1.3(debug):0eba775
NOTICE:  BL31: Built : 12:11:32, Nov 23 2018
NOTICE:  BL31:Rockchip release version: v1.3
INFO:    ARM GICv2 driver initialized
INFO:    Using opteed sec cpu_context!
INFO:    boot cpu mask: 1
INFO:    plat_rockchip_pmu_init: pd status 0xe
INFO:    BL31: Initializing runtime services
INFO:    BL31: Initializing BL32
hung here...

I tried compiling ATF using the rockchip-linux repo

CROSS_COMPILE=aarch64-linux-gnu- make DEBUG=1 SPD=opteed PLAT=rk3328

I am not building ATF correctly since it triggers a reboot loop.

ElonZhang0328 commented 5 years ago

Upstream optee_os only support rk322x, which is 32bit SoC. If you want to build a 64b rk3328 optee_os, maybe you should do the porting work by yourself.

jonsmirl commented 5 years ago

I built 32b optee using this:

CROSS_COMPILE=arm-linux-gnueabihf- make PLATFORM=rockchip CFG_TEE_CORE_LOG_LEVEL=3 DEBUG=1 CFG_TEE_BENCHMARK=n

I renamed tee-pager_v2.bin to rk322xh_bl32_v1.48.bin used the normal build process.

Then built trust.img and loaded it.

LoadTrust Addr:0x4000
No find bl30.bin
Load uboot, ReadLba = 2000
Load OK, addr=0x200000, size=0xbe8bc
RunBL31 0x10000
NOTICE: BL31: v1.3(debug):0eba775
NOTICE: BL31: Built : 12:11:32, Nov 23 2018
NOTICE: BL31:Rockchip release version: v1.3
INFO: ARM GICv2 driver initialized
INFO: Using opteed sec cpu_context!
INFO: boot cpu mask: 1
INFO: plat_rockchip_pmu_init: pd status 0xe
INFO: BL31: Initializing runtime services
INFO: BL31: Initializing BL32
hung here...

Is that the correct way to build rk3328 32b optee?

I have no preference for 32b vs 64b optee, I an just trying to build something that will boot with the optee 2.0 API.

ElonZhang0328 commented 5 years ago

That is not correct. The binary build from current upstream optee_os is for rk322x, not rk3328, which can not run on rk3328. If you want to build rk3328 optee 2.0, you can try to add an platform define called like rk3328 and implement the platform related code referring to rk3328 TRM.

jonsmirl commented 5 years ago

What is optee version on rk3399? I can easily get rk3399 boards in USA.

I am trying to talk to Beiqi about their TB-96AIoT with RK1808, but they don't speak English so it is difficult. It is not clear if they are shipping yet. And I need a MIPI camera for the board.

ElonZhang0328 commented 5 years ago

It's also v1.1.0 on rk3399.

jonsmirl commented 5 years ago

Is TEE_GenerateRandom() hooked up to the hardware random number generator on the RK1808? This is very important for crypto functions running inside the TA. The default implementation is a software pseudo RNG. For good security it is critical that TEE_GenerateRandom() uses the hardware RNG on the SOC.

jenswi-linaro commented 5 years ago

TEE_GenerateRandom() ends up in the syscall function syscall_cryp_random_number_generate(). On current OP-TEE this functions calls crypto_rng_read().

jonsmirl commented 5 years ago

crypto_rng_read() calls hw_get_random_byte() which has to be implemented on each HW platform. Otherwise it is a pseudo RNG. Since Rockchip has not published the source for RK1808 optee I can't tell what it is doing.

/ PRNG configuration
/ If CFG_WITH_SOFTWARE_PRNG is enabled, crypto provider provided
/ software PRNG implementation is used.
/ Otherwise, you need to implement hw_get_random_byte() for your platform
CFG_WITH_SOFTWARE_PRNG ?= y

jonsmirl@ares:/home/aosp/digipi/optee/optee_os$ grep -r hw_get_random_byte *
core/include/rng_support.h:uint8_t hw_get_random_byte(void);
core/crypto/rng_hw.c:       b[n] = hw_get_random_byte();
core/drivers/dra7_rng.c:uint8_t hw_get_random_byte(void)
core/drivers/hi16xx_rng.c:uint8_t hw_get_random_byte(void)
core/arch/arm/plat-stm/rng_support.c:uint8_t hw_get_random_byte(void)
mk/config.mk:# Otherwise, you need to implement hw_get_random_byte() for your platform
jonsmirl@ares:~/aosp/digipi/optee/optee_os$
github-actions[bot] commented 4 years ago

This issue has been marked as a stale issue because it has been open (more than) 30 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this issue will automatically be closed in 5 days. Note, that you can always re-open a closed issue at any time.

Dvergatal commented 4 years ago

Hello. I was looking for some instructions on how to build op-tee for the rk3328 SoC and found this issue. I have turned on OP-TEE driver in rockchip kernel but what i need is some kind of an instruction how to build now an OP-TEE os. Cause i admit i am a newbe in that matter and i also want just like jonsmirl to build an SKS TA to have a storage for my keys certificates and etc.