qca / open-ath9k-htc-firmware

The firmware for QCA AR7010/AR9271 802.11n USB NICs
Other
428 stars 182 forks source link

Can we trust the boot ROM code ? #127

Open felipesanches opened 7 years ago

felipesanches commented 7 years ago

While looking up the AR9271 datasheet I noticed this:

The AR9271 has two internal memories, the
ROM (24 KB) and the RAM (160 KB). The ROM
provides the boot up sequence and various
control mechanisms. The RAM is used to store
part of the program code and all data packets
for transmission and receiving.

Does anybody know (in detail) which specific tasks are performed by this 24KB boot up sequence hardcoded into ROM ? Can we trust its security?

erikarn commented 7 years ago

TL;DR - yes. I've seen the code. There could be some reasonably hilarious bugs lurking there, but there's nothing overtly malicious. It's just library routines like printf(), some bootstrap code, memory/uart/etc initialisation, initial USB bootloader code, etc.

-adrian

On 10 March 2017 at 07:47, Felipe Corrêa da Silva Sanches < notifications@github.com> wrote:

While looking up the AR9271 datasheet I noticed this:

The AR9271 has two internal memories, the ROM (24 KB) and the RAM (160 KB). The ROM provides the boot up sequence and various control mechanisms. The RAM is used to store part of the program code and all data packets for transmission and receiving.

Does anybody know (in detail) which specific tasks are performed by this 24KB boot up sequence hardcoded into ROM ? Can we trust its security?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/qca/open-ath9k-htc-firmware/issues/127, or mute the thread https://github.com/notifications/unsubscribe-auth/ABGl7cw_Rpe53rbu3RiQp6Ct7fqiIUgkks5rkXCKgaJpZM4MZiUR .

olerem commented 7 years ago

the source code is available in sboot folder. You are welcome to review it. In perfekt world, it should be made compilable and compare it with binary. I personally don't have time to do this. It is open, any one welcome to do this.

felipesanches commented 7 years ago

I agree that comparing the boot rom binary with a build of it from the provided sources would be a necessary step in a security audit. For that we would have to dump an image of the internal ROM.

The datasheet mentions that:

The Memory Controller module provides the
channel for bus masters to access the memories
within the AR9271. The internal ROM can be
accessed by the CPU only, and the RAM can be
accessed by the CPU, MAC DMA and the USB
DMA.

So it means that the loaded firmware (running in the device CPU) would have to perform the dump of the internal ROM and then submit the block of 24Kbytes to the driver so that the user can inspect the binary.

felipesanches commented 7 years ago

Once (and if) someone can show that a build from sources perfectly matches the dumped ROM image, then its checksum could be added to a list of good bootrom signatures (initially with a single entry, but conceivably could have hashes for several good releases of the bootrom).

And it would be good to patch the firmware to always perform a checksum of the bootrom upon firmware init, verifying that the checksum is a good one from the list. If the detected internal ROM does not match any of the good ones, then I would suggest that the firmware should eigther refuse to work or, at least, it should send a message to the driver so that a security warning can be displayed to the user, meaning that further audits are needed for a new variant of the boot ROM.

olerem commented 7 years ago

firmware is already providing reg read/write interface. The linux side driver can be extended to use this interface for doing any kind of 0xaddr_dumps. At same time we already provided package which can be build reproducibly by debian build system offline. Suddenly it is still pending in a https://ftp-master.debian.org/new.html queue.

olerem commented 7 years ago

@felipesanches patches are welcome :)

felipesanches commented 7 years ago

At same time we already provided package which can be build reproducibly by debian build system offline.

The reproducible build you refer to is for the firmware payload (that gets loaded into RAM) ? Or for the boot routines that come from factory in the ROM ? (For the sake of clarity, I'm refering to a security audit of the boot ROM)

olerem commented 7 years ago

the RAM part - just to point that we did some work and it seems not to be important enough to be reviewed in three months. So why should any of us spend more time on it?

felipesanches commented 7 years ago

So why should any of us spend more time on it?

I'm not saying that you should. I am just stating that it seems like the next logical step to guarantee the device always does exactly what we expect it to do. Maybe someone will do it at some point (maybe even myself perhaps!). I'm not demanding any specific work from you.

erikarn commented 7 years ago

Hiya,

(Authentication chain and all that...)

-adrian

felipesanches commented 7 years ago

of course, this doesn't stop a patched ROM from patching the firmware to bypass it. :-)

Yup! That sounds scary indeed!

erikarn commented 7 years ago

Heh. :-)

-adrian

felipesanches commented 7 years ago

Out of curiosity... does the payload link to the boot ROM to re-use some of the functions provided in it? Or is the boot ROM code only executed during boot and then the payload does all of its job on its own afterwards ?

erikarn commented 7 years ago

There are some support routines in the ROM that get called. I think stuff like printf(), memcpy(), etc.

-adrian

felipesanches commented 7 years ago

Just a quick thought: maybe our own implementations of these functions could be added to the payload (if it fits the available RAM area) in order to minimize how much it relies on the ROM code.

erikarn commented 7 years ago

I mean, again, patches gratefully accepted. :-P

But the ROM code is really there to save on needing RAM for it; you can sacrifice RAM for reimplementing stuff but then we'd have to cut down on features/stations/throughput.

-adrian

felipesanches commented 7 years ago

I see.

psyborg55 commented 7 years ago

hi

any idea what is limiting firmware to allow more virtual interfaces and connected stations?

with ralink card i got about 40-50 connected clients

olerem commented 7 years ago
  1. limit set by software
  2. limit decision was made from available RAM on adapter.
  3. move some functionality from firmware to host will increase the latency and reduce the speed.
felipesanches commented 7 years ago

I would be happy to inspect the boot ROM code if anyone here could provide me a dump of it. I owned one of these usb-wifi dongles in the past, but lost it and did not order a new one yet, so I can't perform the dump myself right now.

ranma commented 7 years ago

The dump is actually in the repository as sboot/magpie_1_1/image/output/asic/rom.asic.bin. I've dumped the AR7010 rom on my Xbox360 adapter over the serial console ("memdmp 4e0000 4f0000") and it matches this bin exactly (the remainder being filled with 0x00): $ cmp sboot/magpie_1_1/image/output/asic/rom.asic.bin /tmp/romdump.bin cmp: EOF on sboot/magpie_1_1/image/output/asic/rom.asic.bin

I think not all of it is in the sboot sources, for example strings shows "3.1 SNST: eep init failed!" in the rom.asic.bin, but I don't see that in the sboot sources.

Side-note: Apparently the rom is execute-only mapped at 0x8e0000 and data-readable at 0x4e0000. This is similar to how the fw gets uploaded into ram at 0x501000, but then the entry point the Linux driver uses is 0x903000 (AR9271) or 0x906000 (AR7010).

As an interesting side-note, ath10k appears to use a similar Xtensa arch, but in little endian instead of big endian.

ranma commented 7 years ago

Also: The cpu core config includes the VECBASE option, so except for static reset and memory error vectors you can relocate the interrupt vector table into ram and bypass the rom completely if you want to:

$ grep VECBASE sboot/include/xtensa/config/core-isa.h

define XCHAL_HAVE_VECBASE 1 / relocatable vectors /

define XCHAL_VECBASE_RESET_VADDR 0x008E0800 / VECBASE reset value /

define XCHAL_VECBASE_RESET_PADDR 0x008E0800

define XCHAL_RESET_VECBASE_OVERLAP 0

$ grep RESET_VECTOR sboot/include/xtensa/config/core-isa.h

define XCHAL_RESET_VECTOR0_VADDR 0x008E0000

define XCHAL_RESET_VECTOR0_PADDR 0x008E0000

define XCHAL_RESET_VECTOR1_VADDR 0x0F000000

define XCHAL_RESET_VECTOR1_PADDR 0x0F000000

define XCHAL_RESET_VECTOR_VADDR 0x008E0000

define XCHAL_RESET_VECTOR_PADDR 0x008E0000

XCHAL_RESET_VECTOR1_PADDR is the external SPI flash. Event though the cpu config says VECBASE defaults to 0x008E0800, setting VECBASE is also one of the first things the reset startup code does, see sboot/magpie_1_1/sboot/athos/src/xtos/reset-vector.S