Open hansemro opened 1 year ago
Holtek HT32 Flash Commander is a command-line tool alternative to HT32 Flash Programmer described in the initial post. Unfortunately, it has bugs programming HT32F1654 where certain regions are left unprogrammed. The only difference I was able identify between Flash Commander and Flash Programmer is the frequency of status reports on the control endpoint.
As previously tested (https://gist.github.com/hansemro/acdb861d4bb9c5b52bac57d4dbf39601), IAP/ISP instructions (up-to 64) return codes are stored in a 64-byte buffer which are read over the control endpoint after sending the GET_REPORT control message (bmRequestType=0xa1, bRequest=0x01, wValue=0x0100, wLength=64). Once the status buffer is full, no entries will be saved until cleared by 4 new entries after filled or buffer read. Another thing to note is that a return code is saved after the operation is completed so the buffer may have fewer elements if read from too early.
HT32 Flash Programmer likely utilizes the buffer as a method to synchronize transactions (where 30 write requests yields 30 status entries over the span of one or more status requests). In contrast, HT32 Flash Commander does not wait for an equal number of write requests and may end up writing at a rate faster than can be consumed. More prototyping work is required to prove this theory...
If status report requests are necessary, then we may need to update rawhid to transmit/receive control messages in a way that is supported on all platforms.
Update: When buffer is full and gets 4 new instructions, the device reboots (which clears the buffer). So clearing the buffer before it gets full seems necessary for ISP flash programming.
Updated cooler master gist python script for Holtek ISP with basic status report tests: https://gist.github.com/hansemro/76493b59cbade75309dde1fdbe1b103b
This is very interesting! I never thought about the ROM bootloader in the HT32, because the user manuals just didn't say anything specific about it.
The HT32 ISP User Manual doesn't say anything at all about USB functionality. But that document is pretty old, so I guess they just never published the updated document after they added USB to the HT32 ISP?
The format and commands of the protocol you've figured out look very similar to the HID-based protocol the original non-RGB POK3R used for firmware updates. So, I suspect this protocol was based on the USB version of the IAP protocol.
Flash Commander user manual can be found in its install location and does describe connecting to ISP via USB. The command line tool features an engineering mode to do specific operations (mass erase, read/set flash security, program, crc, reset). It is just unfortunate that it cannot write properly to HT32F1654 (but works fine on HT32F52352).
Kinda funny how I did recognize the ISP USB VID/PID (https://github.com/mateuszradomski/re-masterkeys/issues/1#issuecomment-1146783414) months ago, but was a bit too panicked to check how it was even possible for my bricked keyboard to be recognized over USB.
Proof of concept branch with working writeFirmware operation: https://github.com/hansemro/pok3rtool/tree/holtek-isp-libusb-linux-poc
This targets Linux with new libusb-1.0 backend for now. My plan is to eventually replace rawhid backend drivers with a common libusb-1.0 driver to make development easier across platforms.
Branch with Linux+Windows support: https://github.com/hansemro/pok3rtool/tree/holtek-isp-libusb-linux-windows-poc
Reboot delays may need to be extended if libusb fails to find/reopen devices as done with ISP protocol.
Cherry-pick this commit to build and install from msys2: https://github.com/hansemro/pok3rtool/commit/095864f9900c048db5a9876f872d7628e35cfb40
Branch with Linux+Windows+macOS support: https://github.com/hansemro/pok3rtool/tree/holtek-isp-libusb-linux-windows-macos-poc
Not sure if the vulnerability can be assigned CVE since the vendor is not based in the US and not in the database, but I will still try to reach out the vendor so that they can fix it in future hardware revisions, notify their customers, etc.
Wow, that's very cool! Is the flash just not protected via the ISP read command? Or did you find a bug in it? IIRC, the flash security protection just disables flash reading altogether if a debug probe is detected, or if it is not booted from flash.
I think I have the firmware and bootloaders for all the Holtek-based keyboards I have. But good to know!
Is the flash just not protected via the ISP read command?
Read command obeys flash security at least by reading out 0s to the endpoint buffers.
Or did you find a bug in it?
Didn't find find a bug in the read command. If I had to define it, there is a security design flaw that was overlooked for an ISP feature. The flaw is pretty inconspicuous at first glance.
IIRC, the flash security protection just disables flash reading altogether if a debug probe is detected...
Close. Flash access is only partially disabled with debugger attached: the processor will continue to fetch/decode/execute instructions but with the caveat that the processor loads 0s when loading from flash memory (this ultimately breaks firmware in flash). This is to prevent the debugger from overwriting an argument of a load instruction to read out an address from flash (https://blog.includesecurity.com/2015/11/firmware-dumping-technique-for-an-arm-cortex-m0-soc/). Also, the user manual specifies that only DCODE read access is blocked (and not ICODE).
IIRC, the flash security protection just disables flash reading altogether ... if it is not booted from flash.
I guess ROM bootloader counts as flash since it is able to access flash memory somehow.
Found a new workaround that does not require WinUSB driver filter step or libusb.
Relevant change: https://github.com/hansemro/pok3rtool/commit/1259eb514b5dee9b679a6ed0d590cce45654295c Branch: https://github.com/hansemro/pok3rtool/tree/holtek-isp-dev
Decided to write a standalone tool for flashing ISP devices: https://github.com/hansemro/ht32-dfu-tool
ISP bootrom features programming via USB and UART using external software like HT32 Flash Programmer. Two important distinctions between ISP and IAP are that ISP bootrom is on all HT32 devices and ISP features a command to trigger mass erase (to clear flash security; to run QMK without lockups) without the need of an external SWD/JTAG debugger.
More information will be provided after analyzing USB packet captures on HT32F1654 and HT32F52352.
HT32 Flash Programmer Usage Notes
Tasks:
[ CMD, SUBCMD, CRC16, START_ADDR, END_ADDR, DATA ]
[0x00,0x0a,CRC16,0x00000000,0x00000000]
[0x00,0x08,CRC16,START_ADDR,END_ADDR]
[0x01,0x01,CRC16,START_ADDR,END_ADDR,DATA]
[0x01,0x00,CRC16,START_ADDR,END_ADDR,DATA]
[0x01,0x02,CRC16,START_ADDR,END_ADDR]
[0x02,0x00,CRC16,START_ADDR,LENGTH]
[CRC16,0x4f]
to status buffer[0x03,0x00,CRC16]
[0x04,0x01,CRC16]
[0x04,0x00,CRC16]
info
commandversion
commandreboot
commanddump
commandflash
commandwipe
command