News from TmbInc:
After bushing had shown the first homebrew exploit, a lot of stuff has happened in the Wii-world. The exploit was based on a hole in the disc hashing&verification, but the original finder (segher) decided that he doesn’t want the bug to be published. While this caused some controversy, the reason behind this was that the hole could be patched very easily in a future firmware version, as no original function relies on it. The next goal was to find a bug which could not be patched so easily, for example a savegame exploit. Patching such game exploits is considerable harder. Of course you could patch the game code when it is loaded (like some gamecube games are fixed in compatibility mode by the “gamecube compatibility IPL”), but we could just move on to another game. We wouldn’t lose that much power if a game bug is fixed, vs. a critical system bug. I can totally understand that people are annoyed by us not doing full disclosure. Nevertheless we try our best to balance our different interests. It’s not always easy, even inside a team. Still, the rule is: If you find a bug, it’s your choice what you do with it. If you don’t like that, find your own bug.
I’ve concentrated less on the high-level things, I’m generally more interested in the system design and security architecture. So I’ve digged into the bootloader.
What we knew before was that there is a fixed block of code called “boot1″, which is supposed to be the first code executed from flash. It’s ARM (”Starlet”) code, btw, the powerpc (Broadway) is booted much later. We didn’t knew how boot1 is encrypted (rumours ranged from an LFSR-based streamcipher to AES), nor if and how it was hashed. But what we had was a program called “BC” (title id: 1-100), extracted out of a system update. We are absolutely not sure why BC does even exist (it might be used to return from GC mode to Wii mode, but why would you want to do so?), but what BC is doing matches what boot1 could be doing: Reading a bunch of sectors from flash, decrypting them, and checking a signature against a previously decoded cert chain, then jumping there. Once we re-coded the algorithm, it was clear that this in fact decrypts boot2. Encrypting a new boot2 requires signing the new hash. Now it turned out that “BC” also contains “the bug” (well, a similar one), so chances were big that boot1 also does. But flashing a new boot2 is dangerous if you have no return - there is a backup mechanism to boot another copy of boot2, but we cannot count on that for several reasons (for example, if our new boot2 code hangs, the backup would not be tried, as boot1 thinks that everything is right).
It also became clear that once we are able to execute starlet code, it will be a lot of trial&error. So what I did was to revive my old FPGA-based NAND flash emulator, which I once built for the Xbox 360. I wired the Wii’s flash pins to the FPGA. Now the Wii flash has different properties (large block, larger size, different ECC algorithm used), but I could adapt it in a matter of hours. I had to fix the RESET handling (the Wii is waiting for R/#B to go low for a short moment of time), and some minor things, but then it worked! I could boot from my FPGA instead of the original Flashrom. So I could do code changes in a matter of seconds, instead of always reprogramming the flashrom (potentially external). Because my FPGA board has “only” 512MB of RAM, I couldn’t fit the whole flash contents into the RAM. As part of the NAND emulation happens on the embedded PowerPC core in the FPGA (a Virtex 2 Pro), I just added an ethernet MAC, and used lwip to fetch the flash pages from a TCP server. That made the development cycle even easier, as I could now just modify the virtual NAND content on my PC!
bushing prepared a fixed boot2 for me (he just changed a dummy byte), and hey, it worked! I could now run code on the Starlet! First thing would obviously a “hello world”, but where to output? I’ve wanted a software UART, like I had done in GC mode before using the EXI_CS line, but I wasn’t be able to find any useful GPIO. Finally I was able to blink the sensorbar!Unfortunately, all those IOs aren’t TTL, and I didn’t wanted any level shifting.
An hour later I finally got the idea which I should have got in the first minute: Using the already existing NAND interface. I would just issue a non-standard command (the Starlet NAND controller is simple enough to be able to issue any command), and use the address bytes as payload. I’ve added the proper code on the FPGA side (luckily I hadn’t even to change my VHDL code…) to output the address bytes of the private command to the FPGA’s UART.
Some hours later I’ve dumped boot1 (it still was in memory), and some hour later I’ve dumped a new piece of code, which turned out to be decrypting something from the beginning of the NAND flash into memory, then calculating a SHA-1 hash over it, and compares that to a hash read from some “internal memory” (which we believe is an OTP area). It
...
Catherine: Full Body’s English translation for the Vita