Tuesday, August 31, 2010

Clearly you have no idea what an eFuse is.

Ever since the custom recovery images started showing up for the DroidX, people have been declaring the eFuse as officially broken.

Well, no, it isn't, and it's not really all that likely that it ever will be. Let me explain. (You might want to grab some coffee, this could take awhile)

Motorola uses a bootloader called mbm (no relation); it stands for Motorola Boot Manager.

A bootloader essentially has three tasks:

1) Initialize the hardware
2) Load the OS
3) Provide some mechanism to reload the OS

The Motorola logo you see on bootup is actually drawn by mbm, and persists on the screen long after the Linux kernel boots and is eventually replaced by the animated logo drawn by bootanim. Details aside, that's pretty much the only indication the end user has that there's even anything before the kernel; that is, until we get to number three on the list.

Pressing X on bootup gets you into "recovery mode", which displays a warning screen and then presents a menu when the camera and volume buttons are held. The menu contains various options to perform a factory reset by wiping data, or to perform an upgrade. The third party firmwares go a step further by offering backup and restore functionality, access to the command line and even usb mass storage emulation.

That's not actually the bootloader, much to the confusion (and complaints) of several sbf_flash users. Recovery mode is actually Linux. To enter the bootloader, you can either boot while holding the camera, volume keys and power, or the far less dexterous combination of up (towards the screen) and power. If done properly, the screen will actually say "Bootloader" at the top.

There really isn't much to do in the bootloader other than flash an sbf file.

What is an sbf file? Well, essentially it's a container format; within the sbf file are codegroups (often abbreviated as "cg"). I suppose the simplest way to explain it is that the flash is partitioned, and each partition can be thought of as a cg, hence the sbf file is a collection of raw data files to be written to the associated cg. (The sbf_flash utility will helpfully extract these for you, "sbf_flash -x file.sbf")

As for the codegroups themselves, the layout is determined by the cdt (which itself can be found in one of the codegroups). I've posted the decoded cdt from the DroidX at the end of the post. The start_addr and end_addr in this case refer to the absolute position from the start of the flash, the remaining addresses are written in terms of memory locations.

Note the signatures.

Yep, the individual code groups are signed.

If you were to inspect the individual code groups, the signature_start_addr minus the base address would be the offset into the cg that you could expect to find the signature. The sbf itself isn't signed.

So what prevents us from just patching the bootloader not to check the signatures? Well, the short answer that you can't; if it were that easy someone would have already done it.

The bootloader technically isn't the first thing to load. As it turns out, the very first thing to load is a piece of code burned onto the rom of the cpu itself. It's this rom that's actually responsible for validating the bootloader, and once the bootloader is run, the bootloader can then validate the remainder of the system.

So what's an eFuse? Didn't they crack all that stuff? No, I'm getting there, only a few more pages to go ...

The boot and recovery partitions both contain a kernel and ramdisk. The boot partition is used for normal bootup, and contains a ramdisk and init script which mount the partitions from flash and kickstart android. The recovery ramdisk on the other hand is a completely self contained environment. Signatures are checked by the bootloader before executing boot or recovery -- in other words you can't change either of them, except to another official version.

On the Milestone, (which also has a locked bootloader) the version of recovery initially shipped with the phone contained the same vunerability that was used to root the Droid, namely that with a carefully crafted update.zip file you could bypass the signature and execute whatever you wanted. For the Droid, this was used for nothing more than to gain root access (more info), the milestone users went one step further. Due to the inability to simply overwrite recovery, they created a update.zip file which loaded another copy of recovery into ram and executed it. The recovery vulnerability was patched in later versions, but it didn't matter -- all that had to be done was to download an older version of recovery and the update.zip exploit would work again.

The custom recovery for the DroidX is a bit more perverse. Unfortunately, the update.zip exploit was patched long before the DroidX was shipped to customers, but the same concept applies -- unfortunately it no longer involves booting into recovery. The new recovery method -- and I say this with some amount of disgust -- involves actually booting the system, shutting down the android interface and loading the recovery interface. The boot and recovery partitions remain completely unmodified, and technically the system needs to be bootable in order for the custom recovery to work -- if you somehow render the system unbootable prior to the point you can execute the custom recovery, you're facing reflashing the entire system back to stock and starting over again, hence my disgust.

Interestingly enough, while the bootloader checks both boot and recovery before executing them, it doesn't always check the signature of the system partitionm and instead only checks after a reflash; this makes some amount of sense when you consider that the system partition on a DroidX is 280M and is supposed to be mounted read-only.

Given root access, the system partition can be easily remounted as read-write, and since it wasn't modified using the bootloader, there are no signature checks. This is what forms the basis of "custom roms" -- it's nothing new, rooting the phone involves the creation of a /system/bin/su; all that's changed is the addition/replacement of all the other files in system with custom versions.

So that's it, nothing has been broken, the bootloader is still locked down. Feel free to educate anyone who says otherwise by forcing them to read this blog.

And the eFuse? Well, you can blame that on a rather clueless MyDroidWorld post which got overinflated by the media -- what ever happened to journalistic integrity? Yes there is an eFuse, but no the phone doesn't self destruct or anything. Think of it more as burning down bridges after you've moved your data across it; it's what prevents you from bypassing the bootloader validation. There's also another use I'll explain some other time as things progress.

DroidX CDT
(back to post)
CG_num: 64
CG_name: mbr
signature_type: 1
start_addr: 0x00000000
end_addr: 0x00020000
 + base address: 0x83000000
signature_start_addr: 0x83003800
signature_end_addr:  0x83003fff

CG_num: 63
CG_name: mbmloader
signature_type: 0
start_addr: 0x00020000
end_addr: 0x00040000
 + base address: 0x87000780
signature_start_addr: 0x8701ff80
signature_end_addr:  0x8702077f

CG_num: 30
CG_name: mbm
signature_type: 0
start_addr: 0x00080000
end_addr: 0x00100000
 + base address: 0x89310000
signature_start_addr: 0x8934f800
signature_end_addr:  0x8934ffff

CG_num: 55
CG_name: mbmbackup
signature_type: 0
start_addr: 0x00100000
end_addr: 0x00180000
 + base address: 0xffffffff
signature_start_addr: 0xffffffff
signature_end_addr:  0xffffffff

CG_num: 65
CG_name: ebr
signature_type: 1
start_addr: 0x00180000
end_addr: 0x00200000
 + base address: 0x83010000
signature_start_addr: 0x83013800
signature_end_addr:  0x83013fff

CG_num: 56
CG_name: bploader
signature_type: 0
start_addr: 0x00200000
end_addr: 0x00280000
 + base address: 0xffffffff
signature_start_addr: 0xffffffff
signature_end_addr:  0xffffffff

CG_num: 31
CG_name: cdt.bin
signature_type: 1
start_addr: 0x00280000
end_addr: 0x00300000
 + base address: 0x89070000
signature_start_addr: 0x89073800
signature_end_addr:  0x89073fff

CG_num: 38
CG_name: pds
signature_type: 0
start_addr: 0x00300000
end_addr: 0x00700000
 + base address: 0xffffffff
signature_start_addr: 0xffffffff
signature_end_addr:  0xffffffff

CG_num: 34
CG_name: lbl
signature_type: 1
start_addr: 0x00700000
end_addr: 0x00780000
 + base address: 0x80d00000
signature_start_addr: 0x80d03800
signature_end_addr:  0x80d03fff

CG_num: 57
CG_name: lbl_backup
signature_type: 1
start_addr: 0x00780000
end_addr: 0x00800000
 + base address: 0x80d00000
signature_start_addr: 0x80d03800
signature_end_addr:  0x80d03fff

CG_num: 42
CG_name: logo.bin
signature_type: 0
start_addr: 0x00800000
end_addr: 0x00900000
 + base address: 0x86e70000
signature_start_addr: 0x86f6f800
signature_end_addr:  0x86f6ffff

CG_num: 41
CG_name: sp
signature_type: 0
start_addr: 0x00900000
end_addr: 0x00b00000
 + base address: 0x890b0000
signature_start_addr: 0x892af800
signature_end_addr:  0x892affff

CG_num: 61
CG_name: devtree
signature_type: 1
start_addr: 0x00b00000
end_addr: 0x00b80000
 + base address: 0x89090000
signature_start_addr: 0x8910f800
signature_end_addr:  0x8910ffff

CG_num: 62
CG_name: devtree_backup
signature_type: 1
start_addr: 0x00b80000
end_addr: 0x00c00000
 + base address: 0x89090000
signature_start_addr: 0x8910f800
signature_end_addr:  0x8910ffff

CG_num: 45
CG_name: bpsw
signature_type: 2
start_addr: 0x00c00000
end_addr: 0x01000000
 + base address: 0x64100000
signature_start_addr: 0x644ff800
signature_end_addr:  0x644fffff

CG_num: 35
CG_name: boot
signature_type: 1
start_addr: 0x01000000
end_addr: 0x01400000
 + base address: 0x81100000
signature_start_addr: 0x814ff800
signature_end_addr:  0x814fffff

CG_num: 47
CG_name: recovery
signature_type: 1
start_addr: 0x01400000
end_addr: 0x01900000
 + base address: 0x81100000
signature_start_addr: 0x815ff800
signature_end_addr:  0x815fffff

CG_num: 33
CG_name: cdrom
signature_type: 5
start_addr: 0x01900000
end_addr: 0x02500000
 + base address: 0x8b000000
signature_start_addr: 0x8bbbf800
signature_end_addr:  0x8bbbffff

CG_num: 44
CG_name: misc
signature_type: 0
start_addr: 0x02500000
end_addr: 0x02580000
 + base address: 0xffffffff
signature_start_addr: 0xffffffff
signature_end_addr:  0xffffffff

CG_num: 43
CG_name: cid
signature_type: 0
start_addr: 0x02580000
end_addr: 0x02600000
 + base address: 0xffffffff
signature_start_addr: 0xffffffff
signature_end_addr:  0xffffffff

CG_num: 53
CG_name: kpanic
signature_type: 0
start_addr: 0x02600000
end_addr: 0x02a00000
 + base address: 0xffffffff
signature_start_addr: 0xffffffff
signature_end_addr:  0xffffffff

CG_num: 39
CG_name: system
signature_type: 5
start_addr: 0x02a00000
end_addr: 0x14200000
 + base address: 0x8b000000
signature_start_addr: 0x9c7bf800
signature_end_addr:  0x9c7bffff

CG_num: 40
CG_name: cache
signature_type: 0
start_addr: 0x14200000
end_addr: 0x20000000
 + base address: 0xffffffff
signature_start_addr: 0xffffffff
signature_end_addr:  0xffffffff

CG_num: 37
CG_name: userdata
signature_type: 0
start_addr: 0x20000000
end_addr: 0x40000000
 + base address: 0xffffffff
signature_start_addr: 0xffffffff
signature_end_addr:  0xffffffff