Weaver 硬件抽象层 (HAL)
(IWeaver.aidl) 在 Android 8.1 中推出,为使用锁定屏幕知识因素 (LSKF)(例如 PIN 码、图案和密码)进行用户身份验证提供了一个安全接口。
Weaver 取代了 Gatekeeper 的 LSKF 验证功能。 不过,Gatekeeper 仍用于生成 硬件身份验证令牌。
在 Android 9 及更高版本中, CDD 9.11.2 要求支持 StrongBox 的设备提供专用安全硬件,以 支持安全用户身份验证。使用此安全硬件实现 Weaver HAL 可满足“安全用户身份验证”要求。
在没有专用 安全元件 (SE)的设备上, Weaver 仍可在可信执行环境 (TEE)(例如 Trusty)中实现。
在 Android 17 及更高版本中,即使在没有专用安全元件的设备上,也强烈建议实现 Weaver。
组件
Weaver 由三个组件组成:
- Weaver AIDL 接口 (
IWeaver): HAL 的正式规范。Android 13 及更低版本使用 HIDL 而不是 AIDL。 - Weaver 硬件抽象层 (HAL) 服务:
实现
IWeaver接口的供应商专用 Android 进程。 - Weaver 可信应用 (TA): 在安全环境中运行的核心逻辑。它执行 LSKF 验证 并强制执行速率限制。HAL 服务使用特定于实现的的安全信道与 TA 通信。
接口
Weaver 的接口提供了一个固定大小的永久性槽数组,每个槽都包含一个固定大小的密钥和一个固定大小的值。每个槽都由其 ID(区间 [0, numSlots - 1] 中的整数)标识。只有在提供与存储的密钥匹配的密钥时,才能访问槽的值。
Weaver 的接口主要包含以下内容:
getConfig():检索实现支持的槽数、密钥大小和 值大小。write():使用新的键值对覆盖指定的槽。此操作是原子操作,会使之前的数据永久 无法恢复(安全删除)。read():尝试检索指定槽的值。 只有在速率限制超时(由 TA 强制执行) 未处于活动状态且提供的密钥与存储的密钥完全匹配时,此操作才会成功。warmUp():在 Android 17 及更高版本中, 传达提示,表明可能很快会发生读取或写入操作。
如需查看完整的接口规范,请参阅
IWeaver.aidl。
Android 的使用
如果有 Weaver 实现,Android 系统服务器中的 LockSettingsService 会使用它来保护用户数据。对于设备上的每个用户,LockSettingsService 都会管理一个 Weaver 槽:
- 槽密钥 (
weaverKey):用户 LSKF 的哈希值。如果用户没有屏幕锁定,则使用默认字符串 。 - 槽值 (
weaverSecret):高熵、 随机生成的加密密钥。
weaverSecret 旨在仅通过以下方式检索:
- 在其
速率限制政策内向 Weaver TA 提供正确的
weaverKey。 - 破坏 Weaver TA 运行的安全环境。这应该 非常困难。
LockSettingsService 同时使用 weaverKey 和 weaverSecret 来加密用户的合成密码。由于
合成密码保护用户的
基于文件的加密 (FBE)
的凭据加密 (CE) 存储空间以及用户的
Android Keystore 中与用户身份验证绑定的密钥,
因此在 Weaver 发布密钥之前,数据仍无法访问。
在 Android 17 及更高版本中,当 LSKF 开始输入时,LockSettingsService 会调用 Weaver 的 warmUp() 方法。Weaver 实现可以使用此信号将安全硬件从低功耗状态转换为正常状态,以减少即将到来的 read() 请求的延迟。
Weaver 与 Gatekeeper
从历史上看,
Gatekeeper HAL
在单个 verify() 调用中执行两个不同的角色:
- 验证:检查 LSKF,并施加 TEE 强制 速率限制。
- 证明:发布
HardwareAuthToken以 通知 KeyMint (以前称为 Keymaster)LSKF 身份验证成功。
为何要改用 Weaver?
随着 Android 8.1 中引入 安全
密码重置令牌,“合成密码”成为
主要加密密钥。上述两个角色现在由
单独的 Gatekeeper 注册处理,一个用于 userId + 100000
下的 LSKF,另一个用于 userId下的合成密码。
Weaver 的推出是为了接管第一个角色,它使用更简单的 HAL 接口,并支持基于安全元件 (SE) 的实现。
| 功能 | Weaver | Gatekeeper |
|---|---|---|
| 安全删除 | 需要安全删除,并且很容易实现,因为该 接口使用固定数量的固定大小的槽。 | 不需要安全删除,并且很难实现,因为该接口支持无限数量的注册。 |
| 硬件 | 针对 SE 进行了优化,但也可在 TEE 中使用。 | 实际上仅适用于 TEE。在 SE 中实现它在当前设计中不会提供安全 优势。 |
| 错误处理 | 更清晰的错误代码 | 模糊的错误代码。因此,锁定屏幕无法 区分不正确的 LSKF 和不相关的故障。 |
| 原子性 | 使用 Weaver 的 LockSettingsService 中的代码以原子方式执行
LSKF 更改。新数据会写入新的 Weaver 槽,只有在安全的情况下才会擦除旧槽。 |
使用 Gatekeeper 的 LockSettingsService 中的代码
不会以原子方式执行 LSKF 更改。如果在更改 LSKF 时出现问题,所有用户数据可能会丢失。 |
参考代码
AOSP 包含两个 Weaver 参考实现:
-
在 Android 17 及更高版本中,
system/weaver/包含适用于一般安全环境的 Weaver 实现。 -
在 Android 8.1 及更高版本中,
external/libese/包含适用于 ISO/IEC7816-4 兼容安全元件的 Weaver 实现。
测试
如需验证 Weaver 实现,请使用
VtsHalWeaverTargetTest:
atest VtsHalWeaverTargetTest
或者:
vts-tradefed run vts -m VtsHalWeaverTargetTest