给2019年的MateBook13装指纹登录:一次走到底的失败

硬件是好的,社区驱动差一代固件,密钥拿不到,此路不通。一次从头查到尾的失败复盘。

给2019年的MateBook13装指纹登录:一次走到底的失败

一句话结论:硬件是好的,社区驱动差一代固件,密钥拿不到,此路不通。

写下来是因为中间有几处可复用的东西(无 root 构建、TLS-PSK 记录层、libgpiod v2 的坑),还有两处我踩错的坑,值得记。


一、起点:这颗传感器在 Linux 上根本不存在

机器是 HUAWEI WRT-WX9(MateBook 13 2019)。指纹模块是 Goodix GXFP51A7,挂在 SPI 上:

/sys/bus/spi/devices/spi-GXFP51A7:00     ACPI: GXFP51A7 @ \_SB.PCI0.SPI1.SPBA

fprintd-list 直接返回 No devices available。原因很清楚:libfprint 里的 Goodix 驱动(goodixmoc)只认 USB 款,SPI 这颗没有上游支持。PAM 那边其实已经铺好了(/etc/pam.d/gdm-fingerprint 存在),只是底下没有设备可接。

二、找到社区驱动:差一代固件的坑就在这里

社区项目 libfprint-goodixtls 是给 MateBook X Pro(MACH-WX9)的 GXFP5187 写的 TOD 驱动,协议全逆向,0xF2 命令从传感器 RAM 里读 48 字节 PSK,不需要 Windows 或 Intel ME/SGX。

PR #4 加了 GXFP51A7,参数写得和我的机器一模一样:MilanL 芯片 0x2205、复位 gpiochip0 line 264、PSK 地址 0x20007f14,作者还写了真机验证过 enroll/verify。

但作者那台的固件是 GF3288_ST411SEC_APP_14003,我这台报的是 GF_ST411SEC_APP_14115。 当时没在意这一行——后来它就是全部答案。

三、没有 root 也能把依赖装齐

构建要 libfprint-2-tod-dev、libssl-dev、libudev-dev、libgusb-dev 等等,但没有 sudo。办法是把 deb 下下来解包,拼一棵本地依赖树:

apt-get download libfprint-2-tod-dev libssl-dev libudev-dev libfprint-2-dev \
                 libgusb-dev libusb-1.0-0-dev libjson-glib-dev meson ninja-build
for f in *.deb; do dpkg-deb -x "$f" deps; done
# 再把 deps 里的 .pc 文件里的 /usr 改写成 deps 前缀,PKG_CONFIG_PATH 指过去

三个坑,都是同类问题(发行版打包差异):

  1. openssl/opensslconf.h 不在 /usr/include/openssl/,在 multiarch 子目录 x86_64-linux-gnu/openssl/,得手动补 -I;
  2. Ubuntu 的 libudev.pc 里没有 udev 这个名字,也没有 udevdir 变量(systemd 上游的 udev.pc 才有),meson 的 dependency('udev') 直接失败——补个别名的 .pc 和一行变量就行;
  3. OpenSSL 一度链成了静态 .a,把 jitterentropy 的符号拖进模块,dlopen 时报 undefined symbol: jent_entropy_init_ex。原因是我先前把 dev 包的 .so 符号链接指向了不存在的目标,链接器只好退到 .a。重建即可。

四、装上之后:第一道墙是密码套件

驱动装进 TOD 目录、spidev 绑上、fprintd 撑起来之后,GetDevices 能看到设备了。但一录入就断:

TLS handshake failed (-1/5) error:0A0000C1:SSL routines::no shared cipher

no shared cipher 只说明两边没交集,不告诉你对方提了什么。所以我给驱动加了 SSL_CTX_set_client_hello_cb,把传感器的 ClientHello 抄下来:

goodixtls: ClientHello legacy_version=0x0303, 4 bytes of suites: 00a8 00ff

0x00ff 是重协商 SCSV,不是套件。真正的套件是 0x00a8。

这里我错了一次:凭记忆把 0x00a8 当成 AES-256-GCM-SHA384,改完照样失败。一条命令就能查清:

$ openssl ciphers -V 'PSK-AES128-GCM-SHA256:PSK-AES256-GCM-SHA384:PSK-AES128-CBC-SHA256'
0x00,0xA8 - PSK-AES128-GCM-SHA256   TLSv1.2 Enc=AESGCM(128) Mac=AEAD
0x00,0xA9 - PSK-AES256-GCM-SHA384   TLSv1.2 Enc=AESGCM(256) Mac=AEAD
0x00,0xAE - PSK-AES128-CBC-SHA256   TLSv1   Enc=AES(128)     Mac=SHA256

驱动原本写死的是 0x00ae(CBC)。传感器要的是 0x00a8(AES-128-GCM)。

五、补 GCM:套件、密钥派生、记录层

这个驱动之所以要自己解记录层,是因为传感器把 22 kB 的图像塞进单个 TLS 记录,超过 16384 的规格上限,任何合规库都会拒收;它让 OpenSSL 只做握手和小写入,大记录自己解。换成 GCM 之后这套逻辑要跟着改三处:

  1. 套件列表加上 PSK-AES128-GCM-SHA256;
  2. 密钥派生:AES-128-GCM 用 PRF-SHA256,key block 是 client_key|server_key|client_IV|server_IV(AEAD 没有 MAC 密钥,IV 只有 4 字节固定前缀);
  3. 记录解密:explicit_nonce(8) || ciphertext || tag(16),nonce = 固定 IV + explicit,用 EVP_aes_128_gcm 校验 tag,无 padding、无序列号。

改完,握手走到了 Finished:

goodixtls: handshake err: error:0A000119:SSL routines::decryption failed or bad record mac

有交集了,但 MAC 不对——意味着握着的那把 PSK 是假的。

六、第二道墙:这代固件不按地址返回内存

驱动从 0x20007f14 读 48 字节当 PSK。读是“成功”的,长度正好 48:

14 7f 00 18 30 00 00 00 | d4 bf 63 ce 6e 74 79 5d ...

前 8 字节是地址和长度的回显,后面才是数据。于是试了几个地址,结果是这样:

请求 返回(前 16 字节)
0x20007f14 14 7f 00 18 30 00 00 00 d4 bf 63 ce 6e 74 79 5d
0x20000000 00 00 00 18 40 00 00 00 57 bf 63 ce 6e 74 79 5d
0x20008000 00 80 00 18 40 00 00 00 d7 bf 63 ce 6e 74 79 5d

64 字节里只有 2 个字节不同:地址回显,和一个像是状态/随机值的首字节。其余 63 字节完全一致。

也就是说,这代固件的 0xF2 不理会地址,返回的是一块固定内容。PSK 不在那条老路径上了——驱动能走到 Finished,全靠手里那把假钥匙。

七、结论

  • 硬件没坏(Windows 下一直能用),坏的是“协议还差一代”。
  • 我这台:GF_ST411SEC_APP_14115,社区驱动覆盖的是 14003,前缀都变了。
  • 要往下走只有两条:逆向新固件的密钥获取,或者从 Windows 侧抓一次真实握手。都不划算。

想要指纹登录的替代方案,是买个 libfprint 支持的外接 USB 读卡器——插上就能 fprintd-enroll,GDM 登录和 sudo 都覆盖。

八、两个我自己的错误

记下来,因为都是“该先验证却先动手”:

  1. 套件编号靠记忆猜,白白多跑一轮。openssl ciphers -V 就在手边。
  2. 日志埋点放在成功路径上,读失败时函数提前返回,日志根本没执行,我据此还以为“没读”。埋点要埋在失败分支。

另外两个操作层面的坑:gpioset 在 libgpiod v2 里没有 -m 选项,而且默认不会退出(它要维持电平)——要么用 timeout 杀掉进程,要么用 -p/--hold-period 配合 -t。用错的表现是脚本卡死。


工具链细节:Ubuntu 26.04、kernel 7.0.0-38、libfprint 1.95.1+tod1。

转发至

微信扫一扫分享

WeChat QR Code

有AI相关的想法,但不知道怎么落地?

我是国冰,独立AI开发者。十多年技术一线——半导体显示、智慧城市到自动驾驶;现在一个人+AI,接AI落地项目,从梳理需求到系统落地,陪你走通。

微信聊聊 微信二维码 看我能做什么