It’s been a while since my last blog post Hacking Brightway scooters: A case study. I’ve picked up their most recent scooter, the Xiaomi 4 Pro (2nd gen) to see what’s changed in Brightway’s security practices. And, spoiler alert, they really did step up their game! Brightway evolved an open system (3 Lite, 4, 4 Lite, …) into the most modding-unfriendly device one can imagine. Unfortunately, also at the cost of performing repair and maintenance.
BLE access: „Please enter password“
Brightway has secured the BLE chip, which is the heart of the dashboard, from external access that would normally be possible via SWD. Any access attempt from the DP (debug port) is denied. According to the manual, the SWD can be locked down with a password that is stored in an „eFuse“ (=EEPROM). In addition to that, an encryption key for encrypting the firmware can be stored in the eFuse. I don’t know if that’s the case here, but certainly the password mechanism is in place. The password has to be sent via HCI UART to the chip using a special programming tool (Windows). SWIO / SWCLK / TX / RX pins are exposed as pads at the bottom of the front side of the dashboard module.
Without knowing the password, the DP cannot be unlocked. This path will not be explored any further because of time constraints … and because I don’t like Windows.
MCU access: New security layers
Unlike before, the controller (MCU) is no longer easily programmable. Here’s a list of new measures undertaken by the manufacturer to secure the device against tampering:
Bottom lid glued directly to the battery with double-sided tape: Removing the lid risks tearing the blue plastic cover encasing the battery. Safety hazard no. 1.
Controller trapped inside a plastic box: The controller is hardly accessible due to a black plastic box enclosing it. While the box can be unscrewed, the controller is trapped inside. Only after removing the sealing at each side the cables are given more leeway, allowing the controller to be pulled out just so slightly. Since the main capacitor is charged with 50V or so, fiddling inside the box to remove all connectors gives us safety hazard no. 2.
Controller dipped in conformal coating: The amount of acrylic(?) material to seal the PCB used is mind boggling. It’s clear that this isn’t just water protection, but also tamper / maintenance protection. Repairing this controller likely involves these two steps: 1. dispose of the controller 2. install a new sample.
MCU SWD pins not exposed: At least the top part of the PCB does not have any traces leading to the SWD pins of the MCU. This underscores my theory that this controller was never meant to be maintained after production.
MCU underneath main cap: The MCU is stationed right below the biggest capacitor on the board, which carries significant charge. The cap has to be bent up to access the MCU. Caution: Don’t touch without discharging! Expect a big spark upon bridging the legs with a screwdriver (my method). Better use a resistor for discharging.
MCU Read-Protection (RDP): It’s not possible to read out the flash of the controller due to read-out protection. The SWD pins on the chip are enabled and debugging is possible, which means RDP Level 1 is in place.
Firmware checksum verification: Custom bootloader code that calculates the checksum over all firmware bytes and denies updating / booting if its checksum doesn’t match. Modification is not possible without internal knowledge of this function and the location of the checksum bytes.
Moddin-de-firmwhere
Even though RDP Level 1 is in place, the firmware can be extracted using a specially crafted attack. I’m not going to disclose how, but let me say it’s a known tactic.
The firmware in fact consists of two firmwares: DFU bootloader and main firmware (incl. bootloader). Depending on the flash configuration, either one or the other is mapped to memory location 0x0. Upon entering DFU mode, e.g. when updating the firmware, the DFU bootloader starting at flash address 0x8000000 is mapped to 0x0 and the controller is restarted to boot that code. After a successful program attempt, the firmware starting at address 0x8003000 is mapped to 0x0 and the controller is restarted to boot up the firmware.
There’s also the usual user data section, containing board serial number (SN) and scooter SN… but also a special 16 byte UID, which will be important in a short moment!
Flash dump of 4 Pro 2nd gen showing three sections: DFU bootloader, main firmware and user data
There are two possible ways to load firmware to the controller: SWD (relatively easy) or using the DFU process (hard). The first one is interesting, but we’ll dig deeper into the second approach.
DFU over UART
When I first tried to reverse engineer the UART protocol implemented by Brightway I failed miserably. This time I didn’t! A standard two-wire UART (TX+RX) implementation running at baudrate 19200 (8 bit, 1 stop bit, no parity) is used. With that said, sniffing the UART traffic is straight-forward to understand the messaging protocol.
I’ve recorded the messages exchanged during a firmware update to replicate the DFU process, which can be outlined as follows:
Mutual authenticatiion
DFU writes / Sending firmware packets
DFU verification
DFU completion (restart)
Step 1 is arguably the most difficult one to hack due to the custom key derivation and verification. You remember the special 16 byte UID mentioned before? Turns out, this UID is used to generate a shared key in a key-derivation process. A series of custom routines scramble this UID into a longer byte sequence (the shared key), which is then used to scramble a random 16 byte challenge sent by the other party and return the 16 byte scrambled response. Since both parties scramble in the same deterministic way, the expected response is calculated in advance and checked against. If this confuses you: the figure below explains it better.
Mutual authentication between BLE (Alice) and MCU (Bob) using the UID to derive the shared key
When sending firmware packets, the checksum of the packet and the checksum of each data chunk is included as part of the message. However, the chunks / packets themselves are transferred unencrypted, i.e. they’re not encrypted using the shared key. Either way, it wouldn’t increase security by much, since the same update file can be acquired from the mobile device as well and more easily.
Additional security measures
Security by obscurity: The MCU found in this scooter model is an unicorn, a Mew glitch, in the far-east outskirts of MCU manufacturing. With no data sheet or whatsoever available, as a researcher, one has to go trial and error mode and use every bit of information gathered from related components.
Firmware signing and verification in the BLE module: Like with all recent Xiaomi scooter models, it’s not possible to send a modified firmware to the BLE to due signature verification. Since all use the same certs, all firmware files are signed using the same private key by Xiaomi, regardless of the model.
Bad code / shitty compilers: The MCU firmware assembler code, especially motor control, is hard to read due to code redundancies and missing code encapsulation. There seems to be a „one function to rule them all“ mantra overshadowing the programmers ambition to deliver a functioning system.
Conclusion
Brightway has learned from their past and locked down both BLE and MCU as the essential components to the integrity of the scooter. A) Access to the BLE is secured by a password. B) Access to the MCU flash is secured by RDP Level 1.
In addition to the known firmware signing, specific measures have been implemented to prevent installation of (modified) firmware. A) The initiation of the DFU process is secured with a shared key and a custom key-derivation function. B) Modified firmware (with wrong checksum) is rejected by the MCU’s DFU bootloader. Obscure component choices and bad programming habits further enhance the security.
Yet, there’s one glaring problem that overshadows all aspects of added security: Brightway has created a scooter that is impossible to repair. The way the controller is installed into the chassis is extremely maintenance-unfriendly. Since spare parts are practically unavailable for most Brightway scooter models, including this one, buyers with an expired warranty and a malfunctioning controller have little option other than selling the entire scooter for parts.
Linko Semiconductor Co., LTD. is a privately held company specialized development of ICs for motion control, based in Nanjing (China). It produces cost-effective ICs with integrated MCU (motor control unit); the LKS32 comes with a 32bit MCU.
I’m interesting in running custom firmware on this chip because Xiaomi, more specifically Brightway, uses it in it’s latest electric scooters models. For experimentation, I ordered a few matching LKS32MC081 samples from a friendly seller on Alibaba.
Even though one should be able to manually program the chip using the flash controller registers, I found it more convenient to use the tools provided by Linkosemi.
I was able to compile and download a custom Blinky program (attached below) onto the chip.
Running Blinky on LKS32MC081
Attachment: Blinky program for LKS32MC08x
int main(void)
{
Hardware_init();
while (1)
{
GPIO_SetBits(GPIO0, GPIO_Pin_6);
SoftDelay(0xFFFFF);
GPIO_ResetBits(GPIO0, GPIO_Pin_6);
SoftDelay(0xFFFFF);
}
}
The Xiaomi Mi Motion Activated Night Light is a relatively cheap device that comes with a Xiaomi MHCB05P BLE module (the same module is used in the latest Xiaomi electric scooters).
I was able to dump the existing firmware, since the flash was not read-out protected. After this, I compiled and download my own code to the module.
The LED strip of the light is connected to P0_0 of the BLE module and I flashed some classic Blinky code that turns the GPIO pin on and off in a fixed interval.
Running Blinky custom firmware on Yeelight
Going further
The next step is publishing a BLE service that allows turning the lamp on and off. It would also be interesting to make use of the motion sensor and broadcast messages over BLE whenever motion is detected.
Xiaomi 3 Lite dashboard with attached SWD and UART wires
Choose your character!
Brightway (Brightway Innovation Intelligent Technology (Suzhou) Co., Ltd.) produces scooters for the NAVEE and Xiaomi brand. The latest additions to the Xiaomi portfolio are the Electric Scooter 3 Lite, 4, 4 Pro and 4 Ultra. With exception of the 4 Pro, all are produced by Brightway. If you’re hearing the name Brightway for the first time and want to learn more about every Xiaomi scooter released, check out my previous blog post.
The cheapest Xiaomi/Brightway model is the 3 Lite. It costs almost the same as the Xiaomi/Ninebot Mi 1S, but has somewhat weaker specs, such as a 5200mAh instead of a 7650mAh battery. So what’s the point of buying this seemingly inferior scooter? Well… it’s security research! By studying the inner workings of the 3 Lite, both from a hardware and a software standpoint, we can shed a light onto how serious Brightway takes security in their scooters.
In this blog post, I will be dismantling my newly bought 3 Lite scooter. After an initial introduction, I’m giving insights into the pairing and activation procedure, after which I describe the available registers, the command and message format and the structure of the serial numbers. It follows a detailed description of all the hardware and respective SOC memory layouts, after which I look at the UART and BLE protocols. Lastly, I will talk about the obvious security flaws discovered in the 3 Lite and how this relates to all other new Xiaomi scooter models.
Intro
In this section, I’ll be giving a short overview over the essential scooter components, for those of you who are not familiar with previous Xiaomi models or electric scooters in general.
Even though riding the scooter is possible without any app whatsoever, Xiaomi requires you to watch a training video and prove that your the legitimate owner of the vehicle. Only after this is done, restrictions imposed upon speed and such are lifted. Apart from that, an app is helpful for reading or controlling scooter parameters (more in section „Info registers“).
Diagram showing all components involved in the scooter communication, based on the latest Xiaomi specification
Several components are involved in the communication between your phone and the scooter. The communication process is the following:
Create secure channel between the app on your phone and the scooter BLE module, which for Xiaomi scooters is located within the dashboard.
Send commands from app to scooter over the secure BLE channel.
Pass commands designated to the electronic speed controller (ESC) or battery management system (BMS) via UART bus. Commands can have different targets: the dashboard (BLE) itself, ESC or BMS.
Pass responses, packed into commands, back to the user over the secure BLE channel.
To ensure device security, each one of these components and pathways needs to be secure.
Pairing process
Xiaomi started rolling out a stronger bonding mechanism with the 3 Lite and 4 Pro models. For connecting with the scooter, you have to download the Xiaomi Mi Home app. After scanning for scooters and selecting your 3 Lite scooter, the app asks for the camera permission. Now, you scan a QR code that’s printed on top of a sticker that covers the dashboard. After the QR code is verified by the app backend server, you’re connected. A button press is no longer required.
The QR code is stored in the app and can be viewed while being connected to the scooter. The app tells you to take a screenshot of the QR code in case you lose the original one.
Usage note: Every time you remove the scooter from the app and re-add it, you have to scan the QR code. However, the verification fails unless you do a BLE hard-reset first (throttle + 5x button press).
Activation
When you first turn on the 3 Lite it will constantly beep and be speed-limited to 10 km/h. Just like with previous (Xiaomi/Ninebot) models, you have to activate it. The activation button becomes available after watching the usual introduction video in the Mi Home app.
I’m greeted by a firmware update dialog immediately after connecting to the scooter. This update is not mandatory and the dialog can be dismissed.
Mi Home app offering firmware update for 3 Lite
Info registers
At this point, I will refer to the Mi Home scooter app as the „Brightway plugin“. The way Mi Home works is that it provides an API which vendors can use to integrate their hardware, as a plugin. Now, since the 3 Lite is produced by Brightway, their plugin looks and feels different from the Ninebot plugin some us of are used to. Nonetheless, the provided functionality and available information is equivalent. By looking into the Brightway plugin script source code, we can locate all register addresses with their respective functions (typos included [sic]).
The Brightway plugin script gives further insight into the command types and how a package is defined.
Type
Command
01
WRITE
02
COMMAND
03
READ
11
MCU_WRITE_RESPOND
12
MCU_COMMAND_RESPOND
13
MCU_READ_RESPOND
14
MCU_REPORT
Command types
A package consists of DATA plus the checksum of DATA. A custom function is used to calculate the checksum. DATA is defined as follows: DATA = TYPE + ADDRESS + REST + LEN + PAYLOAD
TYPE is a command type (see table)
ADDRESS is a register address (see table)
REST is the number of packages remaining, in the case where multiple packages have to be send
LEN is the length of the PAYLOAD
PAYLOAD is the actual hex values to transmit
Both the command sent to the scooter and the commands received follow this format specification.
Serial numbers
Brightway scooters have a 20-character SN format: 5-digit prefix + '/' + 14-character suffix.
The SN prefix is used to identify different regions. The following table shows all known prefixes for the 3 Lite (valid prefixes start with a ‚3‘) and their restrictions.
SN Prefix
Region
BacklightOn
CruiseControl
Speed
37707
DE
❌
❌
❌
37713
??
❌
❌
❌
37708
??
✅
❌
❌
37712
??
✅
❌
❌
37701
??
❌
✅
✅
37714
??
❌
✅
✅
Others
Global
✅
✅
✅
All 3 Lite SN regions with their restrictions ✅: No restriction ❌: Restricted
SNs are stored on MCU (ref. 0x93FC in EEC0130, 0x23f14 in image) but read and processed by BLE (ref. 0x1e63e in MCU0214).
The 3 Lite provides a BLE GATT service for authentication and another service for TX/RX and broadcasting the button press using the followings UUIDs:
Service: 00000101-0065-6C62-2E74-6F696D2E696D
TX/RX: 00000100-0065-6C62-2E74-6F696D2E696D
Button: 00000102-0065-6C62-2E74-6F696D2E696D
For BLE authentication the Brightway plugin uses MIOT BLESecurityLock:encryptMessage() and notencryptMessageWithToken(). What’s the difference, you ask?
encryptMessage() uses MIOTBluetooth.encryptMessageXiaoMiBLE() -> securityChipEncrypt() [Same as StandardAuthEncrypt()] -> ECDH with secp256r1 curve (we know this crypto)
We already know the type of encryption/decryption scheme used. What’s new is the call of the function securityChipEncrypt(). Wait, what… Security chip? Very interesting! A BLE packet sniff reveals an exchange of certificates, likely related to the QR code. Further, memory footprints contains records of a 7-step authentication process involving the secure chip. This is a noticeable divergence from previous authentication methods.
Unverified: Since the QR code is used for bonding, it likely contains data which can only be decoded by the Mi Home app. This data could be the certificate (public key) that is transmitted in the key-exchange.
Hardware breakdown
The following section identifies all ICs used by the manufacturer. This is a necessary step for the examining device security and the potential for modification.
Starting with the dashboard, it has the label „P2185_Display_V2.0 211126“ printed on it. The dashboard looks almost identical to the „P2223_Display_V1.0.1 20220111“ of the NAVEE S65. Luckily for us, both boards expose them SWD ports! The P2223 has all SWD pins labeled, the P2185 has not (but, it’s easy to find out). Check the image below for the correct SWD pin assignment.
P2185 („3 Lite“): SWD pins identified
P2223 (NAVEE S65): [Source] reveals a lot of internal information
We already observed the app code hinting at the existence of a secure chip. When first examining the hardware, I could not find any such chip. Only with the help of my microscope and zooming into one of the small ICs on the dashboard I could locate a component that turned out the be the legendary „MJA1“ secure chip!
Dashboard comes with a MJA1 secure chip – I’m probably the first person posting a photo of this special Xiaomi component!
Vendor
Part number
Function
Xiaomi/Realtek
MHCB05P-IB module with RTL8762C chip
BLE Mesh
Xiaomi
MJA1 HCIW
Secure chip
???
??? (hidden underneath display)
20-Pin Display driver IC
Dashboard components
As for the ESC, the part numbers are difficult to read, since the board is potted in a thick layer of transparent encapsulation resin (too thick to be conformal coating). Nevertheless, I could identify all but one component with my microscope, by using its integrated light source past the reflective layer.
Having identified all hardware components, it took me quite some time to gather the relevant documents and get a clear understanding of the SoC characteristics. This section lists the specs and the memory mapping table of each SoC.
Type
SOC
Family
Arch
RAM
ROM
Flash
BLE
RTL8762C (MHCB05P)
Cortex-M4
ARMv7-M
128KB
384KB
512KB
MCU
LKS32MC08x
Cortex-M0
ARMv6-M
8KB
1KB
64KB
SOC specs: MCU has limited resources – logic is handled by BLE!
Area
Start address
End address
Size
Function
ROM
0x0
0x5 FFFF
384KB
Bootloader, BT-Stack, Flash driver
RAM (Data)
0x20 0000
0x21 BFFF
112KB
RAM code
> ROM Data
0x20 0000
0x20 2FFF
12KB
Variables of ROM
> Main Stack
0x20 3000
0x20 37FF
2KB
MSP
> Patch RAM1
0x20 3800
0x20 7BFF
17KB
Variables/RAM code of Patch
> APP/Data RAM
0x20 7C00
0x21 7FFF
65KB
Variables/RAM code of APP + Data heap
> Patch RAM2
0x21 8000
0x21 BFFF
16KB
Optional, same as Patch RAM1
RAM (Cache)
0x21 C000
0x21 FFFF
12KB
Speed up SPI Flash R/W
SPI Flash (Cached)
0x80 0000
0x9F FFFF
512KB
With cache (faster)
> Reserved
0x80 0000
0x80 0FFF
Reserved
> OEM Header
0x80 1000
0x80 1FFF
Config: BT address, AES Key, flash layout
> OTA Bank 0
–
–
Data and code
> OTA Bank 1
–
–
Same as Bank 0
> FTL
–
–
Access flash with logic address
> OTA Temp
–
–
OTA backup
> APP Defined
–
–
User defined
Memory mapping: RTL8762C
Area
Start address
End address
FLASH (NVR)
0x0
0x3FF
FLASH (MAIN)
0x0
0xFFFF
RAM
0x2000 0000
0x2000 1FFF
SYS CTRL
0x4000 0000
0x4000 03FF
FLASH CTRL
0x4000 0400
0x4000 07FF
Memory mapping: LKS32MC08x
UART
The bus between dashboard and controller is no longer realized by a single-wire (1-wire) UART, like in previous Xiaomi scooter models. The 3 Lite downright uses the standard UART mode: one wire for TX, one wire for RX. The MCU-UART is configured as follows: baudrate = 19200, data length = 8 bit, stop bit len = 1 bit, LSB, even parity, check disabled, multi-drop disabled.
Curiously, my recordings do not contain messages, but pulses with three possible state values.
Value
Meaning
20
floating(F)
30
low(L)
65
high(H)
UART protocol: only three different values
A single pulse follows the pattern: F[H|L][H|L]
In reality, only two of the four possible combinations are used: FLL, FHL. We can conclude that FLL translates to „0“ and FHL translates to „1“. I visualized the sampled data using a tool called binocle, which helps identifying recurring patterns.
Commands send via UART-TX, visualized with binocle
Data received via UART-RX, visualized with binocle
At the time of conducting the experiments and recording the UART transmission, I didn’t know about the correct parameter stated in the first paragraph. For recording the data, I used a higher baudrate than specified by the MCU. Please leave a comment, if you can verify seeing similar values and patterns in your recording with the correct baudrate set.
If we assume these captures to be accurate, then it means that both the BLE and MCU have a buffer to store incoming packets and then translate them back to messages, as defined in the „Commands and message format“ section.
3 Lite: Security oversights
Both the dashboard and controller board expose debugging pins (SWD). These have been left active and allow connection via OpenOCD. I quickly discovered the first security oversight by Brightway: the manufacturer left the content of both SOCs unprotected! I was able to generate full dumps of both BLE and MCU firmware, without any special measures, following the memory mapping tables laid out above.
The second oversight is that the firmware update (OTA) files for both the BLE (called „EEC“) and MCU come unencrypted, meaning that they can be decompiled without further measures. Analysis of these files allowed me draw some of the conclusions in this blog post, e.g., about the UART configuration. I could further observe that the MCU firmware, being very limited in size, contains almost no logic and that its main purpose is motor control.
Last year, Xiaomi introduced firmware signing to secure the BLE firmware from tampering. The BLE/EEC firmware for 3 Lite is signed in accordance to this new Xiaomi standard. However, the MCU firmware is not! This could potentially allow altering the content of the update (OTA) file before passing it to the BLE. This has the hard requirement of having the authentication and update procedure fully reverse-engineered.
What’s strange about the MCU firmware OTA file is that it’s almost three times larger than the MCU flash size. Next to the MCU flash/app content, this file contains one large code section of what seems to be executable DFU loader code and another section of what seems to be executable post-installation / setup code. Should it prove to be correct that the MCU OTA file is packed with executable code that the BLE willingly executes, one could try injecting their own code. This has a potential to defeat every security measure mentioned so far, but also serious implications for the scooter safety. But again, proving this would require full knowledge of the authentication and update process.
While the authentication process (pairing with QR code, secure key exchange) doesn’t seem to have any obvious flaws, Brightway has left room for debugging and possible modification of the scooter. It is a misunderstanding that authentication with a secure chip provides absolute security. It’s main safety mechanism is to prevent tampering with the device of someone else, because we don’t have the QR code (certificate) to pair with that (secure chip). The secure chip doesn’t prevent you from hacking your own scooter. This is how it should be!
3 Lite: Custom firmware?
The Realtek BLE module uses SPI to communicate with the flash. The (unsurprising) fact is that this module doesn’t allow writing bytes to the memory-mapped flash directly. The RTL8762C SoC comes with a feature called block protect and the manual states the following regarding write protection: „The protected flash zone can’t be written and erased. If necessary, user can unlock flash first, and then write or erase, finally lock the flash to the previous level.“ Realtek provides both an API for reading and writing to flash and tools for programming. This means that flashing a custom firmware to the BLE module is just a matter of figuring out the correct programming procedure!
As for the MCU: If you’re familiar with the flash controller in STM32, the LKS32 MCU isn’t too different. It has a register for enabling the programming mode, a register for the address to program and a register for the data to be written to that address. In my tests, writing single bytes (words) using the LKS32 flash controller was unsuccessful (also, writing single bytes to the memory-mapped flash didn’t succeed). Based on hints in the manual, it’s very likely that a prior erasure of the flash region to be written to is necessary!
BLE custom firmware
Up to this point, everything I did so far was non-destructive. In order to not risk bricking my newly brought scooter and keeping the factory settings intact, I bought a much cheaper Xiaomi device that comes with the exact same BLE module for experimentation. Both devices contain the exact same ROM image and there’s no setting (so called „eFuse“) in EEPROM that might potentially disable flashing. Therefore, the process and outcome of flashing the scooter BLE module is expected to be exactly the same.
I was able to erase the existing firmware from the BLE module and flash a modified 3 Lite BLE firmware back to it. My modification, for demonstration, is simply changing the device name from „dreame.scooter.epro“ to „dreame.scooter.nono“ . This shows that a 3 Lite custom firmware could very much be possible, in theory!
Successfully flashed back modified firmware to Xiaomi BLE module with device name altered
MCU custom firmware
Custom firmware can be flashed to LKS32MC081 MCU without limitations using the SWD port. After flashing the original 3 Lite MCU firmware, I was able to erase and reprogram the chip with a modified original firmware.
What about other new Xiaomi models?
Thanks to internal FCC documents we can tell that the hardware of the Xiaomi/Brightway 3 Lite and the Xiaomi/Brightway 4 (non-Pro) model look similar. The MCU has the same amount of pins and we can make out exposed SWD pads. Overall, the board design, including caps and connectors, looks familiar. Chances are, that the 4 Ultra comes with the hardware described in this post.
The Xiaomi/Ninebot 4 Pro, like all other other new Xiaomi scooter models, uses the same BLE module as the 3 Lite, as disclosed by a Bluetooth certification. This means that the 4 Pro uses the same BLE stack and Xiaomi core libraries for authentication. As for the controller, the 4 Pro uses a STM32 based board in the tradition of previous Ninebot scooters; the STM32 MCU is well established in the scooter modding community.
Xiaomi/Brightway 3 Lite: MCU with 48 pins underneath blue cap
Xiaomi/Brightway 4: [Source] shows MCU, also with 48 pins, blue cap and SWD pads
In a nutshell, the new Xiaomi models could be pwned as follows:
For 3 Lite + 4 + 4 Ultra, the easy way would be to modify the existing MCU firmware and flash it via SWD. The hard way would be developing and flashing a custom BLE firmware for the (Realtek) BLE module that bypasses the secure chip, with a custom MCU OTA flashing procedure.
For the 4 Pro, there is no easy way at this time. A possible way is to develop and flash a custom ESC firmware for the STM32 board. This firmware could be based, for example, on the OpenSource SmartESC firmware. The hard way would involve a custom BLE firmware, just like for the other models (same BLE module).
Summary
In this research, I had an extensive look at the hardware, software and security implemented by Brightway, the new Xiaomi scooter supplier, by examining their 3 Lite scooter model. I could fully dump both the BLE and MCU flash content, get a glimpse at the OTA procedure and the command & communication protocol used by in the 3 Lite.
My conclusion is that Brightway scooters, at the example of the 3 Lite, are secure from hostile takeover by a third party, thanks to the use BLE authentication using the secure chip, but open for your own modifications!
I have shown that both chips can be (re-)programmed through the respective (enabled) SWD port: I was able to flash a modified 3 Lite BLE to an identical Xiaomi BLE module, which suggests that BLE custom firmware is possible on the actual device. I was also able to flash (and re-flash) the original 3 Lite MCU firmware to an identical LKS32 MCU, which suggestes that MCU custom firmware is possible.
At the time of writing, I could not discover any security exploits that would warrant a notification of the manufacturer. As for the security flaws, such as missing encryption and read-out protection of the firmware files, I assume that the manufacturer is well aware thereof. Please understand that I will not go into detail of the exact flashing procedures. Further, the question how regional restrictions such as speed limits can be removed are not the scope of my research.
Xiaomi recently added three new scooter models to their portfolio: Xiaomi Electric Scooter 3 Lite, Xiaomi Electric Scooter 4 (Canada) and Xiaomi Electric Scooter 4 Pro. This blog post seeks to explore the Xiaomi scooter product line and its interweb with different manufacturers.
Ultimately, this blog article seeks to answer the question, if any of the new models can be hacked or not.
History: Xiaomi, Mi, Mijia?
Xiaomi released its first scooter, the „Xiaomi Mi Electric Scooter“, also known as „Xiaomi Mijia M365“, in December 2016. „Mi“ and „Mijia“ are two brands used by Xiaomi for smart home devices. The „Mijia“ brand is more prominent in Asian regions, whereas the „Mi“ brand is used globally.
The „Mi“ label was dropped from the latest scooters model names. But, the „Mijia“ brand still exists in Asian regions.
Who produces Xiaomi scooters?
Xiaomi is primarily a design and marketing company, meaning that it does not manufacture all of its products in-house. Instead, Xiaomi partners with a network of suppliers and contract manufacturers to produce its products.
For example, Xiaomi works with Foxconn, a major contract manufacturer, to produce some of its smartphones. It also works with other manufacturers for different product categories, such as Huami for its wearables and Viomi for its home appliances.
Unsurprisingly, Xiaomi does not actually produce scooters. The producers are named in the following list, together with detailed information on each released scooter model and their internal device naming (Xiaomi Mi Home App):
Ninebot (Changzhou) Tech Co., Ltd. [founded in 2012, acquired the U.K. based Segway Inc. in 2015]
M365 [ninebot.scooter.v1]
M365 Pro [ninebot.scooter.v2]
Mi 1S [ninebot.scooter.v3]
Mi Pro 2 [ninebot.scooter.v4]
Mi Lite (Essential) [ninebot.scooter.v5]
Mijia 1S (China) [ninebot.scooter.v6]
Mi 3 [ninebot.scooter.v7]
4 Pro (old version?) [ninebot.scooter.v8]
Mi 3 (new version?) [ninebot.scooter.v10]
4 Go [ninebot.scooter.v13]
4 Pro [ninebot.scooter.15/v15]
5 Pro (China) [ninebot.scooter.v16]
Brightway Innovation Intelligent Technology (Suzhou) Co., Ltd. [founded in 2020]
NAVEE Electric Scooter S65 [dreame.scooter.p2223]
Mijia Electric Scooter 3 Youth Edition (China) [dreame.scooter.t2185]
Xiaomi Electric Scooter 3 Lite [dreame.scooter.epro]
Xiaomi Electric Scooter 4 [dreame.scooter.t2201]
Xiaomi Electric Scooter 4 Ultra [dreame.scooter.p2301]
Xiaomi Electric Scooter 4 Lite [navee1.scooter.t2210]
NAVEE Electric Scooter V40 [navee1.scooter.t2208]
NAVEE Electric Scooter V50 [navee1.scooter.t2211]
NAVEE Electric Scooter S65C [navee1.scooter.t2214]
Brightway scooters?
Up until recently, all „Xiaomi“ scooters were produced by Ninebot. This changed when Brightway came to light in 2020.
Brightway first released a scooter for the Chinese market, named 米家电动滑板车3青春版 (Mijia Electric Scooter 3 Youth Edition). This scooter is now available globally under the name „Xiaomi Electric Scooter 3 Lite“. Fun fact: The original name indicates it’s target audience (youngsters), which explains why the scooter has the weakest specs of all scooters in the Xiaomi portfolio.
Furthermore, Brightway has its own scooter brand: NAVEE TECH. Even if Brightway doesn’t use the NAVEE brand for all Xiaomi models, they left traces with „Navee“ tags all over the place, for example, in the Xiaomi 3 Lite FCC documents.
Brightway vs. Dreame
In the Xiaomi Mi Home app, all Brightway scooter model names start with „dreame.scooter“. This is strange, because „Dreame“ mainly produces vacuum cleaning robots… So the question is: How is Brightway related to Dreame?
My research concludes that Brightway and Dreame are both brands owned by the Chinese company Shenzhen Liwei Electronics Co., Ltd. (also known as Liwei Century or Liwei Chuangzhi).
Liwei Electronics is a leading manufacturer of home appliances, including vacuum cleaners, air purifiers, and other cleaning products. Dreame is Liwei’s premium brand of vacuum cleaners and other cleaning products, while Brightway is… well… a scooter brand.
With regards to the Mi Home app, I assume, that Liwei Electronics wanted to bundle both their Dreame and Brightway products within the Xiaomi Mi Ecosystem and found the easiest way to achieve this by using the already existing „dreame“ namespace/account.
Hackability
Ninebot scooters have had a long-standing reputation for being hacker-friendly. However, this changed last year with the introduction of new security features (cryptographic signatures) specifically aimed at preventing tampering with the device firmware. Now, with the „4 Pro“ model, Ninebot put a nail in the coffin of firmware manipulation: They added a secure chip, dubbed „MJA1“, to (possibly) store encryption keys and cryptographic functions. Secure chips usually come with a physical protection layer that, for example, causes the chip to erase itself when tampered with physically. (Side note: Xiaomi also uses the „MJA1“ in other devices, such as the „Vacuum-Mop 2“ robot vacuum cleaner and the „Smart Camera 2 PTZ“ security cam.) It can be said that, starting with the „4 Pro“, all upcoming Ninebot scooters will be difficult to hack.
However, public information about Brightway scooters (including the „3 Lite“, „4“ and NAVEE scooters) do not seem to indicate similar measures: FCC documents from the NAVEE Electric Scooter S65 show a dashboard equipped with a Realtek MCU (AMB1) and exposed serial wire pins (CLK/DIO/G), meaning: a potential for further exploration!
With a price of €150 the De’Longhi Dedica EC685 is by far the cheapest portafilter espresso machine one can get. It is the successor to the EC680 model with minor differences in frother and tray.
Out of the box the EC680/685, despite the overwhelmingly positive reviews, delivers horribly tasting espresso: Sour, bitter and lifeless. If you ask why there is such a discrepancy between reviews and results, I guess it’s because many reviewers simply don’t know what to expect.
With the right modifications you can get espresso shots tasting equally as good or better than in most cafe’s. The modifications come at a price: at first your espresso will taste far worse than before! But: You’ll receive the ability to tune the extraction process and hence the taste and flavor.
Necessary modifications
It’s actually very simple: Replace the basket, get a bottomless portafilter and strip the frother.
The biggest issue comes from the original pressurized baskets. Baskets found in gastronomical espresso machines have plenty of laser cut holes. The EC680/685 has exactly one hole. Because this machine uses a vibratory pump, pressure is build up by blockage of the pathway. To deliver somewhat constant pressure the basket is designed such that it forces the water through a tiny hole, this is why it’s called a pressurized basket.
So how do you achieve constant pressure without a pressurized basket? The answer is simple: By grinding your beans extremely fine, so fine, that the ground beans act as a natural counterpart for the vibratory pump. This of course comes with a plethora of new issues, but none which a true barista would mind learning to deal with.
A bottomless portafilter
DIY bottomless portafilter
This is a MUST have if you want to learn anything remotely about your coffee extraction. By opening up the portafilter you’ll get a clear glimpse at the shape and color of the extraction stream and also potential flaws in your coffee tamp.
For my project I ordered an original DeLonghi portafilter and cut down both the portafilter holder and the included basket with a Dremel tool:
Saw right below handle junctionDon’t forget to deburr edges!It’s best to cut round the outsideFinal result
Graef filter baskets
A standard recommendation for the EC680/685 are these Graef filter baskets, comparable to VST baskets on the German market. I have tested them and I do not recommend them for this machine!
One important metric for sieves is the nominal open area of the basket, i.e. the ratio between open and closed surface. If you have more or bigger holes you have more open area than with a few tiny holes. Now there are two problems with the Graef sieves: 1) The nominal open area is too large and 2) The 14g basket is missing the conic shape necessary for building up the required pressure!
So overall, you’ll not be able to reduce the extraction flow and hit the correct extraction times and yields using these baskets. The modified original basket on the other hand, both though its conic shape and smaller holes, is able to hit almost perfect extraction parameters.
Fundamentals of espresso
No matter what machine you have, without quality roasted beans you’re not going anywhere. Even though it’s temping to buy cheap beans for learning I wouldn’t recommend doing so: Uneven roasts, bean sizes and fragments all lead to an unpredictable extraction and varying results.
Now, given you have the right beans you’ll have to make sure that you understand the coffee extraction process. We have the following parameters to play with, ordered by importance:
Grind size, from coarse to very fine
Brew ratio
Water temperature
Grind size
We’ve already learned that the grind size controls the pressure in this machine. For espresso, the finer you grind, the more area is created for the water to extract. Generally, you’ll want to go as fine as possible. We’ll get into the physics another time, for now this rule of thumb are enough to find the perfect grind setting:
Grind so fine that you choke your machine (nothing comes out, machine aborts process)
Set the grinder one step coarser at a time until you see a very slow but constant flow
Many people like me bought the Graef CM800 grinder together with their DeLonghi machine. This grinder has one flaw: It’s not specifically designed for espresso-grade grinds. It can, however, be „fine-tuned“, by removing the outer shell, removing the screw on the inner grinder and rotating the inner piece three steps in FINE direction (inner piece clock-wise). The effect of this is that the outer scale (the one you normally look at) gets shifted to the left: What was before the grind setting „5“ now becomes „15“. This gives you more room to work with finer grind settings. Another thing is that pressing down on the hopper while grinding helps getting a more even grind.
CM800: Move screw three steps in FINE direction to get finer grinds
If your grind and tamp are not even enough you’ll get what’s called channeling: Water under pressure seeks the path with lowest resistance, creating channels. The presence of channels the bottomless portafilter is noticeable through coffee spurts in random directions. Because the contact time of this channeled water with the coffee is almost non-existent, this water will taste sour and body-less if it makes way into the cup.
Chances are that this is what you’ve been drinking before, because with the normal portafilter defects in the tamp are invisible. Once you get a constant, single stream your tamp is free of channeling and your coffee is guaranteed to taste well.
Brew ratio
The next thing you want to set up is the brew ratio, i.e. the weight of the ground coffee beans vs. the weight of extracted coffee (including water). Don’t rely on the specs of the basket, measure the weight of the portafilter with and without the ground coffee and you have your input weight. Stay constant with your input weight, learn to always dose in the same amount without gauge.
Then, measure the weight of the cup without coffee and with coffee to get the output weight (the yield). Now divide the output weight by the input weight and you have your brew ratio. If your output weight is around two times as much as the input weight (brew ratio 1:2), voila! If not: press and hold the start button on the machine for one or two cups to program the extraction time. If you need more coffee in the cup, you need more time, if it’s too much coffee in the cup, you need less time. Adjust the time by releasing the cup button sooner (less time) or later (more time). You’re done once you hit your brew ratio for consecutive trials.
See how extraction time is not really a parameter you set. You only set up the grind size and brew ratio, extraction time is just a result. If the time, given the correct grind setting and brew ratio, is around 20 seconds, good, if not, ignore.
Water temperature
Many guides recommend 92 degrees as the extraction temperature for espresso. With the EC680/685 we have no direct control over the temperature and the temperature itself is very instable: Depending on whether it’s the first, second or third coffee in a row the temperature changes, but also across the extraction the temperature drops quickly.
The EC680/685 has the option to change the temperature from low, middle to high. After testing all settings (and doing tricks like „temperature surfing“) I recommend leaving the temperature setting untouched! While not perfect, the machine is able to produce temperatures high enough to deliver good extraction. Only one thing is extremely important: Preheating the brewing group! This is easily done by removing the portafilter and then making one cup of coffee without coffee.
There have been some studies on the importance of temperature in coffee extraction. Up to a certain point, gradually more coffee practicals get dissolved as the temperature increases. But we’re talking about minor varieties, bean/roast quality and grind size are far, far more important!