迄今为止最强的Wi-Fi

我已经不记得什么时候开始使用的WPA2 Enterprise了,大约是在2012年前后吧,到今天也是14年了。相比之下WPA3 Enterprise出来得比较难产,特别是Suite B,要求过于苛刻,2019年前后才开始有硬件支持,实际的生态成熟更是要等到2023年左右。对于懒癌晚期的我(嗯这不都两年多了我才写篇文章)对于怎么把这套方案打通实在是没有太多的动力,直到用上DeepSeek。

先简单介绍一下Wi-Fi安全性的历史。

802.11本身是Wi-Fi的载体,规定了怎么实现无线网络通讯,其中有一个单独的章节是如何保护这种在开放空域当中通讯的安全性,包括WEP(Wired Equivalent Privacy/104 bit密钥)和WPA(Wi-Fi Protected Access/128 bit密钥),其中WPA又分为123版本,其基本内容都是如何在认证完成后进行通讯加密。至于如何进行认证,则有单独的方案例如PSK/SAE、WPS以及802.1X。这两组东西其实是相对独立的。到今天,最强的通讯加密很显然是WPA3 Suite B(192 bit密钥),而这个加密模式要求认证方式只能是EAP-TLS,因此这个模式也一般叫做WPA3 Enterprise 192 bit mode。EAP-TLS (Extensible Authentication Protocol – Transport Layer Security)是802.1X规定的最早但是也是最强的身份认证模式,AP和STA进行基于公钥体系的双向认证,两边都需要可信X509证书。因此除了基础设施本身,如何进行设备初始化是这个问题的主要难点。

为了实现设备自动化证书签发,我先实现了SCEP (Simple Certificate Enrollment Protocol)服务器,但是在测试的时候发现macOS Big Sur的SCEP实现竟然存在安全问题,给苹果报了BUG之后对方表示哎Monterey发布了,你要不看看修了没,然而我的老MacBook不支持升级了,于是这个事情就搁置了。后来发现其实这个事情也没必要去纠结了,SCEP这个东西大抵是死了,ACME大行其道的时代到来了。苹果悄无声息地把各种企业方案都迁移到了ACME。

相比于SCEP,ACME是一个非常开放和灵活的框架,这句话的意思就是它什么都没规定,都得你自己来。于是苹果自己定了一个认证方案,基于Secure Enclave安全芯片的设备认证。哎我这两年不是玩了很多TPM的东西吗,这就是一个完整的attestation样板实现。因此在秉承自己动手的理念下,靠DeepSeek助力先搓了一个ACME服务器出来(这里鄙视一下step-ca),然后苹果全家桶一个mobileconfig文件往上一扔,它就自动实现了可信签发证书并且挂上Wi-Fi的全过程。这里面踩坑不少,被AI各种承诺骗来骗去,最后还是土法炼钢搞定了。看了一眼,嗯苹果设备都可以连接到迄今为止最强的Wi-Fi了。

事情就这么结束了。

那也就不用写这篇文章了。

作为coreboot玩家,对TPM2.0的一边厌恶一边离不开的矛盾心情在这一刻显然是无法平息的。苹果全家桶竟然什么都准备好了,那么我的主力笔记本,ChromeBook,怎么才能也实现同等级别的安全连接呢?很显然,要达到同样的可信等级,传说中的TPM Remote Attestation终于到了要报效国家的时候。

TPM1.2咱就放弃了,这东西确实是死了。TPM2.0,现代的事实标准,在ChromeBook里是由GSC(Google Security Chip),也叫做Cr50、Ti50、Titan,实现的。Google很干脆地告诉你,因为我们除了TPM还需要干别的,芯片能力不够,所以部分TPM功能咱就阉割了啊。其实在写coreboot payload的时候都没觉得有什么问题,因为我其实用到的功能很少,甚至我一度怀疑Google到底阉割啥了。结果一做Wi-Fi的项目,好么,一顿缺东西。

WPA3 Enterprise 192 bit mode,顾名思义,所有的密码学协议至少应该有192 bits强度,因此最低的非对称加密算法是RSA3072或者EC384。然而Google觉得128 bits够了啊,所以它的设备身份证(Endorsement Key Certificate)是EC256的。嗯嗯,那我无视这个问题,只要你的证书是有效的,我TPM生成EC384就行了吧。然后Google又华丽丽地把这个阉割了,只支持RSA2048/EC256。一顿挠头,所有的AI都告诉我不符合规范,不可能连接成功。我一跺脚,强行签发了一份EC256证书,然后试了一下,它就华丽丽地……连上了。

所以规范是txt不是exe。

那么整个流程应该怎么自动化呢?首先回到我刚才说的ACME是一个非常开放和灵活的框架,换句话说什么都没规定。苹果自定义了一个device-attest-01的认证模式,这个模式还提交了RFC,但是这个模式是一个鸡和蛋的问题,它依赖于第三方的认证机关来帮你确认身份,而这个第三方机关怎么认证你,比如通过Secure Enclave还是TPM2.0,走什么协议,统统都是私有的。这个RFC等于一个空壳。苹果固然是做好了它的私有协议,但是咱一个带TPM2.0的Linux笔记本完全没有任何生态,这个第三方就不存在。再搓一个认证机关?咱ACME本来就是负责签发证书的,你那个认证机关不跑ACME跑啥呢……既然咱都自己搓ACME了(毕竟咱鄙视step-ca),显然应该自己扩展一下这个非常开放和灵活的框架,反正也是自己用。

TPM2.0的设计思路是非常有讲究的,每块芯片有一个种子,这个种子在生产过程写入之后就成为了这块芯片的身份证,但是为了保护这个种子不被不必要地造成追踪,种子只能被用于产生一个固定不变但是却只能用于加密,不能用于签名的密钥称为EK(Endorsement Key),而这个key会得到一个厂商签发的证书EKC(Endorsement Key Certificate)从而可以被确认这块芯片的身份。众所周知,证明你的身份靠的是签名,不能签名的密钥怎么能证明身份呢?因此要先产生一个可变可丢弃的可以用于签名的AIK(Attestation Identity Key),并且证明这个key是在EK的保护下,而这个证明不需要EK进行签名(神奇)。然后这个AIK顾名思义是一个等效身份证,身份证很显然不适合拿来做高精尖的操作(比如撬门)所以AIK也被施加了限制,只能用于证明TPM产生的其他密钥确实是合法的。所以全过程就是EK证明AIK,AIK签名一个真正使用的密钥,真密钥获得ACME签发的证书。

扩展完ACME之后,使用这个私有协议,Linux就可以利用TPM2.0去请求证书了。但是得到了证书,下一步怎么才能让TPM保护的密钥去完成TLS握手呢?

Linux连接Wi-Fi靠的是wpa_supplicant,它的密码学实现是OpenSSL,而OpenSSL访问TPM历史上竟然有三种不同方案,但是每一种都需要调用者显式编程实现。鉴于通用性考虑,一般选择PKCS11接口。PKCS11是一种非常开放和灵活的框架,是的,它什么都没规定,因此实际实现TPM到PKCS11的软件也就有很多款。最终搞通的是NetworkManager -> wpa_supplicant -> openssl -> openssl-pkcs11 -> tpm2-pkcs11的路线(以上为Fedora的包名)。

tpm2-pkcs11需要通过tpm2-pkcs11-tools来初始化,因此咱又按教程+AI来把TPM密钥暴露成PKCS11接口,然后GSC又华丽丽地把这个功能阉割了,原因是PKCS11是一个通用证书接口,那么就包括了使用密钥进行签署(原始文件/原始文件的hash)的功能,而前者的标准实现是要求TPM对输入文件进行hash,但Google觉得没啥用就给去掉了。tpm2-pkcs11-tools要检查TPM是不是支持完整的功能,因此就会出错。但是实际上在EAP-TLS实现中,TLS仅仅用于握手,并不需要签署原始文件,所以这个错误是不影响用来连接Wi-Fi的。处理方法也非常暴力,因为tpm2-pkcs11-tools是Python的,所以直接改源代码跳过测试,这竟然没有任何影响,神奇。

PKCS11暴露之后,因为Gnome不支持Suite B这么高级的功能,只能nmcli手搓配置。有意思的是Gnome不认识Suite B,nmcli搓好之后的连接它直接认为是没有任何安全性,不过幸好不影响使用。然后咱一个up,它就没up起来。这个debug很是让我恶心,因为NetworkManager会自己拉起来wpa_supplicant,我之前手工测试的时候是可以的,换NM就起不来了,需要开wpa_supplicant的debug,发现哦找不到$HOME。合理,NM不存在HOME。在systemd里面给wpa_supplicant服务加上了一点配置使得它可以找到tpm2-pkcs11,然后再up,好嘛,很多年没见到过的selinux报警跳出来了。

很显然tpm2-pkcs11不是设计来给系统服务用的,它不但要求$HOME,更麻烦的是它选择了用sqlite来保存信息,而sqlite作为一个单进程数据库,使用lock文件来互斥是一个标准操作。于是你就看到NM尝试对配置文件进行——写入!这个selinux咱不怪你,换咱来咱也拒绝。而且这个问题的解决没有任何变通方案,因为这个行为实在是无法理解,所以必须要有一个特殊的selinux策略去放行,这也成为了我唯一的自定义selinux策略。

再up,终于在radiusd上看到了久违的TLS 1.3握手,它华丽丽地连上了。随机mac地址,EAP身份anonymous,客户端证书受到TLS 1.3加密保护因此无法被窃听(理论上还是可以探测出来客户端证书密钥长度不够……),整个握手过程完全无法知道客户端身份。握手完成之后GCMP-256加密启用,PMF因为WPA3的关系强制启用,因此数据流无法被窃听,控制流也无法被伪造。迄今为止最强的Wi-Fi就实现了。

接下来干嘛?继续等Linux和hostapd修复802.11r漫游的超时问题,以及802.11r和PMF冲突的问题。这些问题在企业AC/AP上差不多都已经解决了,但是开源方案还是得等。等这俩问题解决了,大概我(将要)用了15年的WPA2 Enterprise就可以最终谢幕了。