Flipper Zero CKS/U2F 功能研究
本文仅作为研究记录,我并不是专业的STM32WB开发者,因此,如有错误欢迎指出。
基础信息
Flipper Zero 采用了 STM32WB 芯片,在其 CM0 核心内有一个安全区(被Flipper Zero官方称为secure enclave)。在这个安全区内,Flipper Zero出场时会自带1+10个密钥,并且在首次启动时生成第十二个密钥,因此将固定占用0-11+1密钥槽位。这些密钥主要用于实现 U2F 功能以及 Keeloq 协议,但也不排除其会被别的功能所使用(根据官方 “making your device unable to decrypt subghz mfcodes for leeloq” 猜测)。
Flipper was never designed to be secure, nor it passed cryptography audit.Despite of the fact that keys are stored in secure enclave there are some types of attack that can be performed against AES engine to recover keys(theoretical). Also there is no way to securely deliver user keys to device and never will be. In addition device is fully open and there is no way to guarantee safety of your data, it can be easily dumped with debugger or modified code.
Secure enclave on WB series is implemented on core2 FUS side and can be used only if core2 alive. Enclave is responsible for storing, loading and unloading keys to and from enclave/AES in secure manner(AES engine key registers will be locked when key from enclave loaded)
There are 11 keys that we provision at factory:
0 - Master key for secure key delivery. Impossible to use for anything but key provisioning. We don't plan to use it too.
1 - 10 - Keys used by firmware. All devices got the same set of keys. You also can use them in your applications.
Also there is a slot 11 that we use for device unique key. This slot is intentionally left blank till the moment of first use, so you can ensure that we don't know your unique key. Also you can provision this key by your self with crypto cli or API.
Other slots can be used for your needs. But since enclave is sequential append only, we can not guarantee you that slots you want are free. NEVER USE THEM FOR PUBLIC APPLICATIONS.
Also you can directly load raw keys into AES engine and use it for your needs.
Flipper Zero U2F 的实现
初始化
applications/main/U2F/U2F.c
- 尝试加载certification
- 通过 U2F_data.c ,尝试使用 CKS 区的2号密钥加载 cert_key.U2F 内的证书密钥cert_key.U2F 中存储的 IV 就是用来解密其中 Data 的 IV,在默认状态下,使用2号出厂密钥与 IV 即可解密其中的 Data,Data解密后即为 cert.der 的私钥。
- 通过 device_key(由U2F初始化时生成,保存在U2F的数据空间中)解密U2F数据
- 加载U2F使用的次数计数器
- 设置所使用的算法(MBEDTLS_ECP_DP_SECP256R1)
验证
通过读取初始化时生成的 key.U2F(存储 U2F 密钥)与 cnt.U2F(存储计数器)来实现主要的 U2F 功能,其二者均符合 U2F 文件格式。二者通过 FURI_HAL_CRYPTO_ENCLAVE_UNIQUE_KEY_SLOT 密钥槽内的密钥加密,如为空则会自动生成。
Flipper Zero SubGHz功能对CKS的调用
lib/subghz/subghz_keystore.c
SubGHz 功能采用1号槽位的密钥来加密 Keeloq 协议读取与发送的内容,此协议常用于车钥匙。
FURI_HAL_CRYPTO_ENCLAVE_UNIQUE_KEY_SLOT
此密钥为 Flipper Zero 在初次启动或调用 targets/f7/furi_hal/furi_hal_crypto.c 中的 furi_hal_crypto_enclave_ensure_key 函数时自动生成。每台 Flipper Zero 均不同,目前发现的用途为加密 U2F 密钥。
一般情况下,如果在系统初次启动前没有函数先一步访问调用 STM32WB 芯片内的密钥区,则其应处于11号槽。
Factory Key 验证
targets/f7/furi_hal/furi_hal_crypto.c
在 furi_hal_crypto_enclave_verify 函数中,对出厂的1-10号密钥进行了一次验证,具体如下:
- 对于每个密钥槽位,读取位于文件头的不同的验证内容与IV
- 通过 AES-128-CBC,采用每个密钥槽位中的密钥与对应的IV对验证内容加密
- 验证加密后的内容是否与文件头的验证内容相同
- 如果十个密钥有不同的,则返回false,验证失败
如何在没有原厂 key 的情况下使得 Flipper Zero 全部功能运作正常?
以下内容均为笔者的推测,不保证正确,欢迎实践反馈!
- 生成一个 master key,用于加密其他 key。(理论上来说这一步可能是不需要的,因为STM32WB可能自己就有个自带的0号 master key,如果这样的话那剩下的 key 直接载入就好)
- 生成10个 key ,私钥采用 master key 加密后写入(通过CubeProgrammer?) CKS 的安全区。
- 1号、3-10号 key 无需额外关照,因为没有任何固件内容会需要这些 key 解密。
- 生成 U2F 证书,替换掉原厂的处于 applications/main/U2F/resources/U2F/assets 文件夹的 cert.der 证书。
- 采用2号 key 对用于生成 U2F 证书的密钥加上 IV 进行 AES-128-CBC 加密,密文内容与 IV 按照格式写入 cert_key.U2F 文件中。
- 参照 Factory Key 验证环节,对那10串验证内容加上 IV 进行加密,生成验证内容,替换 targets/f7/furi_hal/furi_hal_crypto.c 头部的内容。
U2F 文件格式
Filetype: Flipper U2F Certificate Key File Version: 1 Type: 0 IV: E1 56 CE 83 98 FA 59 0D 45 EC 1C EB 34 FC 08 C9 Data: E1 8C C9 9A 98 F7 B9 50 1E 85 71 8F A4 CE 76 95 87 4F AC 8B 5E D0 1F 13 BA 3B 2E E7 98 73 54 64 58 0A 00 20 55 B8 00 08 58 0A 00 20 50 4E 01 20
Filetype:
文件类型
对于 U2F 证书密钥文件:Flipper U2F Certificate Key File
对于 U2F 设备密钥文件:Flipper U2F Device Key File
对于 U2F 计数器文件:Flipper U2F Counter File
Version:
版本信息
对于 U2F 证书密钥文件:1
对于 U2F 设备密钥文件:1
对于 U2F 计数器文件:2(1为老版本计数器文件,也可以使用,但是调用的计数器函数不同)
Type:
证书类型,仅存在于 U2F 证书密钥文件
对于原厂证书:0
对于用户自定证书:1
对于用户自定的非加密证书:2
IV
用于加载 Flipper Zero 于 STM32WB 内置的出厂密钥
Data
对于 U2F 证书密钥文件:证书key,经过Flipper Zero内的2号出厂密钥加密
对于 U2F 设备密钥文件:U2F 实际使用的key
对于 U2F 计数器文件:计数器次数
Flipper Zero 对内置密钥槽位的使用情况
| 槽位编号 | 保存的内容/用途 |
| 0 | Master Key,用于加密剩余所有槽位的密钥 |
| 1 | Keeloq 协议实现所使用的,数据处理加密密钥 |
| 2 | U2F 功能所使用的,配合证书使用的密钥 |
| 3 | / |
| 4 | / |
| 5 | / |
| 6 | / |
| 7 | / |
| 8 | / |
| 9 | / |
| 10 | / |
| 11 | 常规情况下的 FURI_HAL_CRYPTO_ENCLAVE_UNIQUE_KEY_SLOT,由 Flipper Zero 自动生成 |