Skip to content
Vince Cali edited this page May 5, 2015 · 34 revisions

The USB Armory is intended to be a fully open platform. In order for this to be true, everything must be available for audit: apps, kernel, bootloader, and firmware.

There is a boot rom dumper which will allow us to inspect the ROM inside the i.MX53. Eventually inspect the firmware of the SD cards should also be analyzed.

# imx53_bootrom-dump 0 16 > bootrom-0-16k.bin
# imx53_bootrom-dump 0x404000 48 > bootrom-1-48k.bin
# cat bootrom-0-16k.bin > image.bin
# truncate --size 4m image.bin
# cat bootrom-1-48k.bin >> image.bin

Consult §7.4.1 of IMX53RM (i.MX53 Multimedia Applications Processor Reference Manual); figure 7-2 illustrates the memory mapping.

Additionally, §7.10 describes some functions of the HAB library:

The RVT table contains the pointers to the HAB API functions and is located at 0x00000094

The HAB ... includes a software implementation of SHA-256 for cases where a hardware accelerator cannot be used. The core RSA signature verification operations are performed by a software implementation contained in the HAB library. The main features supported by HAB are X.509 Public key certificate ... [and] CMS signature format support

Also of interest is §7.4.5 which says:

The exception vectors located at the start of iROM are used to map all the ARM exceptions (except the reset exception) to a duplicate exception vector table in internal RAM. During the boot phase, the iRAM vectors point to the serial downloader in iROM.

Hopper is awesome for this.

Things to consider:

  • X.509 certificate parser will be found
  • RSA signature verification will be found
  • i.MX53 has a USB downloader: find instructions relating to USB
  • SAHARAv4 may be used: find instructions that call it
  • When secure boot is active, the processor will probably reset if signature checks fail. Look for resets...
  • get friendly with the datasheet and register maps. there's a really good chance that every time you see 53fd4000 something nearby is messing with the clock control module. take a few passes through the assembly listing and annotate potential register accesses
  • as you reverse things, name your subroutines descriptively until you understand their true names eg. sub_218_wait_for_pll_ready
  • sometimes the call graph makes more sense, other times the pseudocode is easier. switch back and forth, name memory locations, annotate function names until it all makes sense
  • watch out for disassembly that doesn't make sense. the example below is probably interpreting a lot of zeroes as code.
...
0040abd4         movs       r0, r0
0040abd6         movs       r0, r0
0040abd8         movs       r0, r0
0040abda         movs       r0, r0
0040abdc         movs       r0, r0
0040abde         movs       r0, r0
...

Observations

  • the boot rom operates mostly in Thumb mode
  • there are a few places where the processor will apparently deadlock itself (probably either entering deep sleep or halting for debugger attach)

###Functions

  • 0x000574 enable clock gates for peripheral
    • case 1: eSDHC1
    • case 2: eSDHC2
    • case 3: eSDHC3
    • case 4: eSDHC4
    • case 5: I2C1
    • case 6: I2C2
    • case 7: I2C3
    • case 8: ECSPI1
    • case 9: ECSPI2
    • case 10: CSPI
    • case 15: UART1
    • case 16: UART2
    • case 17: UART3
    • case 18: UART4
    • case 19: UART5
  • 0x001be0 main()
  • 0x001d86 setup exception vectors, copy rodata, do secure init, jump to main()
  • 0x404000 read GPIO pad status
  • 0x404010 write GPIO data
  • 0x40407e write IOMUXC control register
  • 0x404090 refresh watchdog timeout counter
  • 0x40409e setup watchdog
  • 0x4040f2 disable watchdog power down counter
  • 0x404924 enter USB/UART polling loop, if activity is detected, run serial downloader
  • 0x405b9c __aeabi_memcpy()
  • 0x405c44 wait for n general purpose timer ticks
  • 0x405c72 set general purpose timer OF1 trigger value
  • 0x405c92 get general purpose timer OF1 value
  • 0x405ca0 disable general purpose timer
  • 0x407a9a appears to extract 1/2/4-byte integers from a buffer (ASN.1 parser?)
  • 0x407a86 memcpy()
  • 0x407ab6 copies 1/2/4 byte from one pointer to another
  • 0x40a00a start of SHA256-related functions
  • 0x40bff8 appears to extract integers and change their endianness (ASN.1 parser?)
  • 0x40e2bc decode SIGFPE reason to string
  • 0x40e364 possibly a puts() implementation
  • 0x40e508 return from exception
  • 0x40e510 disable interrupts for entering deep sleep mode
  • 0x40e55c exception vector(s) target
  • 0x40e568 reset vector target; init registers, disable interrupts, setup stack
  • 0x40e5b0 write L1 TTEs
  • 0x40e624 zero target memory region in 32 bit chunks
  • 0x405b9c copy 32bit aligned words (part of __aeabi_memcpy family)
  • 0x40e6c8 disable data and instruction caches
  • 0x40e76c invalidate data cache
  • 0x40e884 shutdown MMU
  • 0x40e8f4 wait for interrupt
  • 0x40e8fc disable VFP (CP11 and CP10 access)

###rodata contents

  • SHA256 initial registers are at 0x40f094
  • SHA256 round constants are at 0x40f0b4
  • USB descriptor structs are in rodata at 0x40fa36 - 0x40fb9a
  • USB identification strings are at 0x40fad4

Reading List

Clone this wiki locally