Quantcast
Channel: CodeSection,代码区,Linux操作系统:Ubuntu_Centos_Debian - CodeSec
Viewing all articles
Browse latest Browse all 11063

Amlogic S905 SoC: bypassing the (not so) Secure Boot to dump the BootROM

$
0
0

The Amlogic S905 System-On-Chip is an ARM processor designed for video applications. It's widely used in Android/Kodi media boxes. The SoC implements the TrustZone security extensions to run a Trusted Execution Environment (TEE) that enables DRM & other security features :


Amlogic S905 SoC: bypassing the (not so) Secure Boot to dump the BootROM
Amlogic S905 System Block Diagram

The SoC contains a Secure Boot mechanism to authenticate the TEE image before loading it in TrustZone. And the first link of this Secure Boot chain is the BootROM code, stored directly in the chip.


This articles describes how to extract the BootROM code from this SoC in the Android-based Inphic Spot i7 device . Technical documentation

Amlogic released a public version of the S905 datasheet thanks to Hardkernel . However, it's heavily redacted, and most parts regarding the Secure Boot or the TrustZone have been removed. But we can still find a lot of technical information in GPL source code packages released by Amlogic & OEMs .

For example, we can find a potential address for the BootROM code:

#define ROMBOOT_START 0xD9040000

#define ROM_SIZE (64*1024)

#define ROMBOOT_END (ROMBOOT_START+ROM_SIZE)

Root access over the UART

We start by connecting the serial port (or UART) because this interface could provide a quick & easy access to debug messages & serial console on bootloaders and linux kernel.

Identifying the serial port on this board is quite simple since there is a port header with labels for the pinout:


Amlogic S905 SoC: bypassing the (not so) Secure Boot to dump the BootROM
UART on Inphic Spot i7 board

We connect an USB to UART adapter to this port. Once the Linux kernel boot process is finished, we have directly access to a root shell.

We can start to explore the (Non-Secure side of the) system.For example, we can dump the partitions :

root@p200:/ # ls -l /dev/block/platform/d0074000.emmc/

lrwxrwxrwx root root 2015-01-01 00:00 boot -> /dev/block/boot

lrwxrwxrwx root root 2015-01-01 00:00 bootloader -> /dev/block/bootloader

drwxr-xr-x root root 2015-01-01 00:00 by-num

lrwxrwxrwx root root 2015-01-01 00:00 cache -> /dev/block/cache

lrwxrwxrwx root root 2015-01-01 00:00 crypt -> /dev/block/crypt

lrwxrwxrwx root root 2015-01-01 00:00 data -> /dev/block/data

lrwxrwxrwx root root 2015-01-01 00:00 env -> /dev/block/env

lrwxrwxrwx root root 2015-01-01 00:00 instaboot -> /dev/block/instaboot

lrwxrwxrwx root root 2015-01-01 00:00 logo -> /dev/block/logo

lrwxrwxrwx root root 2015-01-01 00:00 misc -> /dev/block/misc

lrwxrwxrwx root root 2015-01-01 00:00 mmcblk0 -> /dev/block/mmcblk0

lrwxrwxrwx root root 2015-01-01 00:00 mmcblk0boot0 -> /dev/block/mmcblk0boot0

lrwxrwxrwx root root 2015-01-01 00:00 mmcblk0boot1 -> /dev/block/mmcblk0boot1

lrwxrwxrwx root root 2015-01-01 00:00 mmcblk0rpmb -> /dev/block/mmcblk0rpmb

lrwxrwxrwx root root 2015-01-01 00:00 recovery -> /dev/block/recovery

lrwxrwxrwx root root 2015-01-01 00:00 reserved -> /dev/block/reserved

lrwxrwxrwx root root 2015-01-01 00:00 rsv -> /dev/block/rsv

lrwxrwxrwx root root 2015-01-01 00:00 system -> /dev/block/system

lrwxrwxrwx root root 2015-01-01 00:00 tee -> /dev/block/tee

While the tee partition (Trusted Execution Environment) turns out to be empty, the bootloader partition contains several bootloaders. But not the BootROMbecause it's stored in the SoC, not the flash.

(Fail at) Reading the BootROM

Since we have root permissions and a potential memory address for the BootROM, we can try to read it directly. The provided Android ROM contains a handy debugfs interface to peek & poke physical memory from user-land:

root@p200:/ # echo "d0070000" >/sys/kernel/debug/aml_reg/paddr

root@p200:/ # cat /sys/kernel/debug/aml_reg/paddr

[0xd0070000] = 0x1000254

This aml_reg driver uses the ioremap kernel function to set up an appropriate kernel page-table mapping for the requested address.

However, if we try to read the hypotheticalBootROMarea:

root@p200:/ # echo "d9040000" >/sys/kernel/debug/aml_reg/paddr

root@p200:/ # cat /sys/kernel/debug/aml_reg/paddr

[ 376.546491@0] Unhandled fault: synchronous external abort (0x96000010) at 0xffffff80001aa000 [ 376.549396@0] Internal error: : 96000010 [#1] PREEMPT SMP [ 376.554712@0] Modules linked in: dwc_otg dhd(O) aml_thermal(O) mali(O) aml_nftl_dev(PO)

The kernel crashes. So either theBootROMaddress is wrong or this memory area is set as secure .

Since we don't have other candidates for theBootROMaddress, let's say theBootROMarea is not accessible fromtheNon-Secure World.

Enter the Secure World

In theory, the Secure Boot chain prevents loading unauthorized code in the Secure World.

A quick inspection of debug logs from the UART during the early phases of boot indicates that the bootloaders are based on the ARM Trusted Firmware (ATF) reference implementation.


Amlogic S905 SoC: bypassing the (not so) Secure Boot to dump the BootROM
ARM Trusted Firmware Design

We will now explore some ways to get access to Secure World.

U-Boot bootloader

Using the console over UART, we can interrupt the U-Boot boot sequence to access to the prompt. From here we can run arbitrary U-boot commands:

Hit any key to stop autoboot: 0

gxb_p200_v1#help

? - alias for 'help'

aml_sysrecovery- Burning with amlogic format package from partition sysrecovery

amlmmc - AMLMMC sub system

amlnf - aml nand sub-system

amlnf_test- AMLPHYNAND sub-system

autoping- do auto ping test

autoscr - run script from memory

However the U-Boot bootloader (named BL33 in the ATF design) runs in Non-Secure mode as we can see in boot logs from the UART console:

INFO: BL3-1: Preparing for EL3 exit to normal world

INFO: BL3-1: Next image address = 0x1000000

INFO:

Viewing all articles
Browse latest Browse all 11063