lrh2000 / Xiaomi-bootloader

Some research about the bootloader used in Xiaomi phones.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Xiaomi bootloader

Some research about the boot loader used in Xiaomi phones, mainly about how the boot loader's lock implements.

TL;DR: It is impossible to bypass Xiaomi's server to unlock the boot loader, unless the boot loader itself contains vulnerabilities.

Overview

As expected, Xiaomi's boot loader is modified from Qualcomm's boot loader. The boot loader is divided into three stages, named PBL (Primary Boot Loader), XBL (eXtensible Boot Loader) and ABL (Android Boot Loader). [1]

When powering up, the PBL is executed at first. This program seems to be stored in a non-writable storage in SoC. It is entirely built by Qualcomm and we even have no way to read it (in binary format, of course). Fortunately, it has nothing to do with the topic we're going to talk about. So we just need to know the PBL will load, verify and finally execute the XBL, that's enough.

The XBL is built by Qualcomm and Xiaomi. There is no available source code, but it is easy to get the XBL itself from the block device /dev/block/by-name/xbl. More conveniently, we can extract the XBL from the official MIUI ROM or the firmware update package. [2] This program implements the UEFI interface and some UEFI protocols for the ABL. We will discuss it later. Finally, the XBL will load, verify and execute the ABL.

The ABL is also built by Qualcomm and Xiaomi. Qualcomm's original ABL is open-source. [3] Although the source code is modified by Xiaomi in order to add some new features, such as the boot loader lock, having the original source code will make many things become much easier. Similarly to the XBL, the ABL itself can be gotten from the block device /dev/block/by-name/abl, the official MIUI ROM or the firmware update package. Note that the fastboot server is implemented in the ABL. In most cases, the ABL will load, verify and finally execute the Linux kernel.

Blobs

The files blobs/xbl.elf and blobs/abl.elf are the XBL and ABL binary files, respectively. We need use imgtool to unpack them into several files. [4] blobs/xbl/068AAE46-BDC6-4073-85D5-31C5EEF19A15 is the Mi-Token UEFI protocol (we'll see what it is later), which is extracted from blobs/xbl.elf. blobs/abl/LinuxLoader is the only file which is extracted from blobs/abl.elf.

Note that I'm using Redmi Note 8T (ginkgo), and the boot loaders are extracted from MIUI V11.0.4.0.PCOCNXM (2020-01-03). Things may be different for another phone or even for MIUI of another version.

Unlocking Process

Xiaomi provides us an official unlocking tool. How does the tool unlock our phones? Making use of fastboot/fake_fastboot.c, we are able to investigate the question easily. Here are the results.

  1. Get a token using the command fastboot getvar token.
  2. Ask server for a signature of the token. See the reference for details. [5]
  3. Let the device verify the signature, and the device will be unlocked if the verification is successful. See fastboot/unlock.py for how to send the command to the device.

There remain two questions: How is the token generated? How is the signature verified? We'll answer these questions below.

Mi-Token Protocol

As we mentioned above, the fastboot server is implemented in the ABL. So we can disassmble blobs/abl/LinuxLoader in order to find out how the fastboot server responses to fastboot getvar token and fastboot oem unlock.

That is not difficult. Actually, the fastboot server will locate the Mi-Token protocol through the UEFI interface. The Mi-Token protocol provides three functions. One is used to get the token. One is used to verify the signature. The other one is ignored by me. The fastboot server is just a wrapper that calls those functions.

Then we should turn to blobs/xbl/068AAE46-BDC6-4073-85D5-31C5EEF19A15 for details in Mi-Token protocol.

Token Generation

I guess that the function which generates the token is intentionally designed to be a little complex. But it is not very difficult to analyse if we are patient.

First, generate some binary data (36 bytes). In hex format, it is

55 01 01 20 01 10 XX XX XX XX XX XX XX XX XX XX
XX XX XX XX XX XX 03 06 67 69 6E 6B 67 6F 02 04
GH IJ KL MN

where

  1. the region filled by X is random generated by the RNG UEFI protocol,
  2. the 20 is the total length 0x24 minus four,
  3. the 67 69 6E 6B 67 6F is actually the ASCII representation of the codename ginkgo and
  4. 0xGHIJKLMN (instead of 0xMNKLIJGH) is the serial number gotten from Qualcomm's EfiChipinfo protocol.

(TODO: I wonder why the serial number here is different from the serial number in the Android's system setting. Are they totally different things?)

Then, the binary data will be encoded to the base64 format, and +, / will be respectively replaced by -, _. In the end, we'll get a string containing 48 characters. That is exactly the token.

Signature Verification

The core assembly code for signature verification is put into verify/verify.S, with some modifications to work correctly with verify/main.c. I rewrite the code in C language, which is put into verify/verify.c. So it means that we can compile verify/main.c and verify/verify.c together and we can also compile verify/main.c and verify/verify.S together. There should be no differences between them.

According to the code, the signature is implemented by the RSA algorithm, which is an asymmetric cryptography system. So it is impossible to fake the Xiaomi server's signature unless we can get the server's private key.

TODO: The multiply function seems to multiply two big numbers together. But the algorithm is very trick. I don't understand it at all. A detailed explanation is needed here.

References

[1] https://lineageos.org/engineering/Qualcomm-Firmware/ Qualcomm's Chain of Trust

[2] https://xiaomifirmwareupdater.com/ Xiaomi Fimware Updater

[3] https://source.codeaurora.org/quic/la/abl/tianocore/edk2/tree/QcomModulePkg Qualcomm's ABL source code

[4] http://newandroidbook.com/tools/imgtool.html imgtool

[5] https://github.com/penn5/miunlock Mi-Unlock Python Implementation

[6] https://hex-rays.com/products/ida/ IDA Disassembler

About

Some research about the bootloader used in Xiaomi phones.


Languages

Language:Assembly 58.8%Language:C 38.2%Language:Python 3.0%