Goodix Protocol - owaink/libfprint GitHub Wiki

This is everything we know about Goodix implementation of fingerprint scanning, mainly from reverse engineering the Windows driver. Some of it may be outdated, incomplete, inaccurate, missing, or straight up wrong. If you have any corrections to existing documentation or new information to contribute, feel free to do so. This wiki is an effort to make our documentation more accessible, as most has been left in conversations on discord.

Goodix Devices

Goodix devices are primarily found as embedded sensors in mobile devices like laptops and smartphones. We mostly focus on laptops here, but most of this should translate to smartphones or other devices if needed. The sensors we are working on primarily communicate over USB, though some do use SPI instead. Based on this page, future devices will most likely use SPI. Goodix devices are identified by their vendor ID of 27C6. If you have a different vendor ID, this project is likely of very little use to you. The specific device is then identified by it's device ID, such as 532D found on the Dell XPS 13 2-in-1 (7390), which is the device the writer of this documentation has. You can see a full list of the tracked devices in the #readme section of the community discord.

Encrypted Traffic

Some devices encrypt their traffic, making it much more difficult to reverse engineer. All devices with encryption discovered so far use TLS with a preshared key to encrypt the fingerprint image. Once that preshared key is known, you can see the fingerprint clearly. Commands to and from the device are generally not encrypted and can be seen in plain text. There are a few ways of getting around this:

Crack the preshared key that is already present

By determining the preshared key already on the scanner, we could listen into the traffic on every device. This has obvious security implications, so we won't go into detail here to prevent our efforts from undermining the security of Windows users. It has reportedly been cracked, but we don't recommend this option. If you are looking to dual boot Windows and Linux, this is the only option that allows the scanner to work on both without constant reflashing of firmware.

Overwrite the preshared key with a known one

Goodix devices use a Trust on First Use model, meaning the preshared key is provided by the driver when it is first initialized. By changing the preshared key after it has been generated, but before it has been transmitted to the device, we can provide a known preshared key for the device to use until the next time it is initialized (like when the driver is reinstalled). This is the preferred way of working around encryption.

Disable encryption all together

The Windows driver reads a few registry keys when it is loaded, with a few debug options that can be enabled. This option hasn't been thoroughly explored and likely won't be since a working method already exists. It may be discovered incidentally through further reverse engineering of the Windows driver

Protocol

Goodix devices use a client-server model for communicating with the driver. The driver can send a request to the device, the device will usually respond with an acknowledgement packet, then it will process the request. For example:

(> indicates driver to device, < indicates device to driver)

> GET_FIRMWARE_VERSION (A command to the device)

< ACK (Acknowledgement that the device received the command)

< GF5298_GM168SEC_APP_13016 (Some sort of reply)

This communication is wrapped in the USB protocol and sent in URBs. For fingerprint images, it is also wrapped in TLS encryption as discussed above.

The list of known commands are as follows:

Command Hex Description
GOODIX_CMD_NOP 0x00 This is a no-operation command, it does nothing, but is used in this context to test if the device is responding before sending more useful commands
GOODIX_CMD_MCU_GET_IMAGE 0x20 Asks the device for a scanner, the reply is sent to the driver TLS encrypted
GOODIX_CMD_MCU_SWITCH_TO_FDT_DOWN 0x32 Specifics unknown, current theory is to ask the device to start listening for a finger to be placed on the scanner
GOODIX_CMD_MCU_SWITCH_TO_FDT_UP 0x34 Specifics unknown, current theory is to ask the device to start listening for a finger to be lifted from the scanner
GOODIX_CMD_MCU_SWITCH_TO_FDT_MODE 0x36 Specifics unknown, current theory is to ask the device to start listening for a finger to be lifted or placed on the scanner
GOODIX_CMD_NAV_0 0x50 Specifics unknown, current theory is related to swipe navigation for mobile devices, unused on most devices
GOODIX_CMD_MCU_SWITCH_TO_SLEEP 0x60 Ask the scanner to go into sleep mode to conserve power, usually woken up with GOODIX_CMD_QUERY_MCU_STATE
GOODIX_CMD_MCU_SWITCH_TO_IDLE_MODE 0x70 Ask the scanner to idle to save power, not as deep as sleep mode
GOODIX_CMD_WRITE_SENSOR_REGISTER 0x80 Specifics are unknown, but this is called before and after getting an image from the sensor with GOODIX_CMD_MCU_GET_IMAGE
GOODIX_CMD_READ_SENSOR_REGISTER 0x82 Specifics unknown, this is performed only when the scanner is initialized
GOODIX_CMD_UPLOAD_CONFIG_MCU 0x90 Upload the config for the scanner, the config is just a binary blob, not sure what we are configuring here so its just copied from the windows driver
GOODIX_CMD_SET_POWERDOWN_SCAN_FREQUENCY 0x94 Unused and Unknown
GOODIX_CMD_ENABLE_CHIP 0x96 Unused and Unknown
GOODIX_CMD_RESET 0xa2 Reset the sensor, MCU, and/or the copy(?) depending on which flags are set
GOODIX_CMD_READ_OTP 0xa6 Read calibration information for the specific, individual sensor
GOODIX_CMD_FIRMWARE_VERSION 0xa8 Gives the string of the current firmware the scanner is running
GOODIX_CMD_QUERY_MCU_STATE 0xae Get the current state of the scanner?
GOODIX_CMD_ACK 0xb0 Acknowledge the previous command was received
GOODIX_CMD_REQUEST_TLS_CONNECTION 0xd0 Setup secure communication for transmitting fingerprint image
GOODIX_CMD_TLS_SUCCESSFULLY_ESTABLISHED 0xd4 Secure communication successful
GOODIX_CMD_PRESET_PSK_WRITE 0xe0 Write a new preshared key, this appears to only work on initial setup
GOODIX_CMD_PRESET_PSK_READ 0xe4 Checks that the preshared key defined when the firmware was uploaded to the scanner matches what the driver expects, returns a true or false, doesn't actually return the PSK
GOODIX_CMD_WRITE_FIRMWARE 0xf0 Write a chunk of firmware at the given offset
GOODIX_CMD_CHECK_FIRMWARE 0xf4 Sanity check that the firmware is as expected, returns the offset, length, and checksum