Friday, June 14, 2013

Do we really need S-OFF?

Lately there has been a lot of confusion about if we - HTC users - really need S-OFF on our devices. I think it's time to make this case as clear as possible, and clear up any remaining doubts.

First of all, S-OFF stands for "Security OFF" and S-ON for "Security ON". It's a term specific to HTC devices (and refers to digital signature checking on the bootloader "hboot"). Retail devices always come with SHIP S-ON locked bootloaders. Hboot can also be found in an engineering version (ENG as opposed to SHIP), but it's not easy to get such a device.

You should also know the "fastboot" term: it is a diagnostic protocol used primarily to modify the flash filesystem via a USB connection from host computer. After enabling the protocol on the device itself (entering "fastboot" mode from inside the bootloader), it will accept a specific set of commands sent to it via USB using a command line, for example "fastboot flash boot boot.img" or "fastboot erase cache".

What's the main difference between S-ON and S-OFF from the end-user point of view?

With S-OFF you can:

  • Flash in fastboot original parts of the firmware like: Trust Zone (tz.img), Resource Power Manager (rpm.img), Advanced Digital Signal Processor (adsp.img), bootloader (hboot.img), Radio Config Data (rcdata.img), Splash Screen and others, very often device specific firmware like Consumer IR (cir.img) for the television remote controller in HTC One.
  • Flash in fastboot custom parts of the firmware above, however I've never seen in my life anyone compiling custom rpm.img or tz.img. I've seen custom bootloaders and Splash Screens only. You can also flash modified radio.img but there is rarely anyone out there who does this.
  • Use more advanced fastboot commands, for example you can change the CID (Carrier ID) of your device or even MID (Model ID). And this one is the most important one in the context of this article.
  • Reset the Tampered flag, so your device does not show up as "Relocked" if you relock your bootloader.

For about 2 years you have been able to unlock bootloaders of selected HTC devices on the webpage. Unlocking your bootloader results in an "UNLOCKED" message in the bootloader screen, and allows you to use some of the fastboot commands. For example system, boot and recovery partitions are no longer locked and you can flash a custom boot or recovery onto your device. This doesn't mean S-OFF, but it does give you some more control over your device.

Sometimes there are differences specific to the SoC ("System on a Chip") of each device. Both HTC One X and One X+ (nVidia Tegra 3) have locked out the capability to flash the boot partition from inside recovery, even if your bootloader is unlocked. It is possible to flash the boot partition only via the "fastboot flash boot <boot image name>" command. On the newest HTC smartphone - HTC One (Qualcomm Snapdragon S600) you can use either fastboot or adb shell (dd if=/... of=/...) to write the boot partition.

Do we really need S-OFF?

No, we don't. So what do we need? Because we surely need something. But to understand what we need, it's important to realize where the problem is first.

First of all, comparing HTC devices with Nexus devices is a pointless activity. Never do that. Why? Because they are all S-ON (they call it Secure Boot), and updates for Nexus devices contain the following (based on my experience with Samsung Galaxy Nexus):
  1. bootloader.img
  2. recovery.img
  3. GSM radio
  4. CDMA radio (in case of CDMA device)
That's all. On Nexus device you can flash the original bootloader or radio using the "package_extract_file" command in the updater-script. When HTC releases a major update, however, you will get:
  1. adsp.img
  2. cir.img
  3. dzdata_16g.hdr
  4. dzdata_16g.img
  5. dzdata_32g.hdr
  6. dzdata_32g.img
  7. dzdata_64g.hdr
  8. dzdata_64g.img
  9. bootloader.img
  10. radio.img
  11. recovery.img
  12. rpm.img
  13. sbl1-1.img
  14. sbl1-2.img
  15. sbl1-3.img
  16. sbl2.img
  17. sbl3.img
  18. tp.img
  19. tz.img
  20. more...
See the difference? This firmware images (if updated) are stored inside inside the OTA update. And without S-OFF you can manually update (using fastboot commands or command shell) only recovery, boot, system and sometimes radio. Other partitions are locked and you can't update firmware images other way then only with signed

Content of HTC OTA update

However, very often, flashing only the content of the system and boot partitions is not enough to have the device fully working. For example, in the HTC One X it was necessary to use the new bootloader together with the official HTC Jelly Bean update, otherwise your device wouldn't boot with an older bootloader. This is why flashing a custom ROM for an HTC device is nowhere the same as flashing a custom ROM on a Nexus device. Apart from having the latest system files, you need to have the latest package flashed as well.

Because HTC sells their devices to different carriers around the world, they need to accept some requirements. For example carrier branding. Because of carrier branding, HTC has more than one version of the RUU (ROM Update Utility) for each device. To indicate the difference between the branded and un-branded versions of the same device, HTC used so called "CID" numbers. 

To find out your current CID number (together with some other useful info) you can use the "fastboot getvar all" command. Also, keep in mind that every OTA update checks CID/MID numbers before it will start to patch your system:

                         ifelse( is_ship_bootloader(getprop("ro.bootloader")) == "t" ,
                         assert(check_cid(getprop("ro.cid"), "00000000" , "11111111" ,
                         "22222222" , "33333333" , "44444444" , "55555555" , "66666666" ,
                         "77777777" , "88888888" , "99999999" , "HTC__001" , "HTC__E11" ,
                         "HTC__102" , "HTC__203" , "HTC__405" , "HTC__Y13" , "HTC__304" ,
                         "HTC__032" , "HTC__A07" , "HTC__J15" , "HTC__016") == "t"););
                         ifelse( is_ship_bootloader(getprop("ro.bootloader")) == "t" ,
                         assert(check_mid("full", "PN0710000") == "t");,
                         assert(check_mid("simple", "PN0710000") == "t"););

Obviously "check_cid" includes also SuperCIDs (00000000, 11111111, ...).
Content of android-info.txt
It's all in updater-script, so it can be easily edited anyway. But the real problem is different. As mentioned already, every OTA update contains - package with bootloader, radio, touch panel drivers, trust zone and other parts of important firmware. It also contains the "android-info.txt" file, where CIDs/MIDs are listed, so your S-ON bootloader won't let you flash an original if your CID number is not listed there. Yes, I'm not talking here about custom radio, bootloader or anything custom at all. Original, untouched from an OTA update can't be flashed onto the device if the CID number doesn't match. Is it a problem? Yes, this is the real problem we're dealing here with. Not S-ON/S-OFF, but CID restrictions and an inability to change the CID number.

How this can be resolved? "android-info.txt" is a plain text file, so it can be edited easily. If your CID number is not on the list, just add one more line with your CID. However, as long as your device is S-ON, you won't be able to flash it, because every is signed with a special key. Once is modified, the signature is broken and the bootloader will reject the request to update it. But there is a different method: you can change the CID number on your device with a fastboot command "fastboot oem writecid <cid number>". The best CID number to use is one of the WWE CIDs (for instance HTC__001). But wait - you can't use this particular fastboot command without S-OFF.

Is this problem a real one, or just some sort of users ill-informed craving? It's very real, because without the ability to flash from a WWE OTA update, every user from any carrier or different world region is forced to wait months to receive OTA updates customized to his CID. Everyone can de-brand his device easily by flashing a stock system image, but it won't be enough: because with corresponding parts of the firmware is needed at the same time. This isn't about the OTA itself, it's about the inside that OTA update.


So what are the dangers of obtaining S-OFF on your device? Some of the partitions in the device are extremely sensitive and can result in your device being bricked if they are even slightly corrupted. With S-OFF you can access all of these partitions and the slightest corruption during transfer (whether that be a power spike or you jiggled the cable slightly) can result in a bricked device as it does not check for signatures.

Here’s an example which has almost happened to me once on an S-OFF device: I was flashing a boot.img via fastboot, the command is: "fastboot flash boot boot.img". However I had made a small but significant typo: "fastboot flash hboot boot.img", simply by mis-hitting the B key; this command would be rejected by a device with S-ON as it is a protected partition, but would be accepted on a device with S-OFF. If I had pressed enter without checking the command, my device would have turned into a paperweight in seconds.
One of the most popular protected partitions the hacking community enjoy flashing is the radio partition. This is also a partition where the slightest corruption will cause your phone to brick. The FCC guidelines state the the radio must be booted with a separate processor (I guess to decrease the risk of it being tampered with), so what happens in a phone when it turns on is: radio is booted via a dedicated processor by the first stage loader, initialising the radio hardware (Wifi, Data, Bluetooth, etc.). Radio successfully boots and initiates the first stage loader to use the main CPU to load the second stage loader into RAM (also known as the SPL). Depending on the boot operation, it will either initiate the system or recovery. So without a functioning radio, the main CPU will not kick on and boot the phone.

Some other facts:
  1. You don't need S-OFF to root your device.
  2. You don't need S-OFF to be able to run Titanium Backup or other applications that requires root access. You just need root privileges for that.
  3. You don't need S-OFF to flash custom recovery image onto your device.
To summarize:

We don't need S-OFF, but we do need the ability to edit the CID number on the device (let's say at least on officially UNLOCKED devices), or the packages inside an OTA update should not be signed, so that "android-info.txt" can be easily edited, or the CID restrictions from android-info.txt should be removed (MID is enough to ensure that the right firmware gets to the right devices).

Something to re-think?

Even if we don't need S-OFF I'm quite worried about the policies of mobile companies and carriers. Their philosophy is "the more you are locked down, the more you are protected". That means Police should not fight with criminals, but everyone should just lock down their doors, windows and stay at home instead. It's far easier and cheaper to lock down mobile devices and not allow root access rather then improving the security in other areas.

Can you imagine that you just bought a brand new notebook for $3000 and:
  • you can login only as a Guest (no Administrator account available by default),
  • you can't change your operating system,
  • you can't use applications that requires Administrator privileges,
  • you can't browse freely the content of your hard drive.
You would say "Where the hell is my freedom?!" Here comes the answer from your notebook manufacturer - "For your own security, you don't have any freedom". Sounds like a George Orwell story to me.

I want the same freedom on my phone that I have on my PC.

This article was written in a cooperation with Shen Ye

Have any questions or comments? Feel free to share! Also, if you like this article, please use media sharing buttons (Twitter, G+, Facebook) down this post!

PS. I want thank to Tom Kelsall, my HTC Elevate companion for his help in a proper grammar redaction of the review! Thanks Tom!