Gatekeeper 子系统在可信执行环境 (TEE) 中执行设备模式/密码验证。网守通过具有硬件支持的密钥的 HMAC 注册和验证密码。此外,Gatekeeper 会限制连续失败的验证尝试,并且必须根据给定的超时和给定的连续失败尝试次数拒绝服务请求。
当用户验证他们的密码时,Gatekeeper 使用 TEE 派生的共享密钥来签署身份验证证明,以发送到硬件支持的 Keystore 。也就是说,Gatekeeper 证明通知 Keystore 可以释放身份验证绑定密钥(例如,应用程序创建的密钥)以供应用程序使用。
建筑学
Gatekeeper 涉及三个主要组件:
-
gatekeeperd
(网守守护程序)。一个 C++ binder 服务,包含独立于平台的逻辑并对应于GateKeeperService
Java 接口。 - 网守硬件抽象层 (HAL) 。
hardware/libhardware/include/hardware/gatekeeper.h
中的 HAL 接口,以及实现模块。 - 看门人 (TEE) 。
gatekeeperd
的 TEE 对应项。基于 TEE 的 Gatekeeper 实现。
Gatekeeper 需要实现Gatekeeper HAL (特别是hardware/libhardware/include/hardware/gatekeeper.h
中的函数)和特定于 TEE 的 Gatekeeper 组件(部分基于system/gatekeeper/include/gatekeeper/gatekeeper.h
头文件包括用于创建/访问密钥和计算签名的纯虚拟功能)。
LockSettingsService
发出请求(通过 Binder)到达 Android 操作系统中的gatekeeperd
守护程序。然后, gatekeeperd
守护程序发出一个请求,到达 TEE 中的对应方(Gatekeeper):

gatekeeperd
守护程序为 Android 框架 API 提供对 HAL 的访问权限,并参与向 Keystore 报告设备身份验证。 gatekeeperd
守护程序在其自己的进程中运行,并且独立于系统服务器。
HAL 实施
gatekeeperd
守护程序使用 HAL 与gatekeeperd
守护程序的 TEE 对应项交互以进行密码身份验证。 HAL 实现必须能够签名(注册)和验证 blob。所有实现都应遵守每次成功密码验证时生成的身份验证令牌 (AuthToken) 的标准格式。有关 AuthToken 的内容和语义的详细信息,请参阅AuthToken 格式。
hardware/libhardware/include/hardware/gatekeeper.h
头文件的实现必须实现enroll
和verify
功能:
-
enroll
函数接受密码 blob,对其进行签名,然后将签名作为句柄返回。返回的 blob(来自对enroll
的调用)必须具有system/gatekeeper/include/gatekeeper/password_handle.h
中显示的结构。 -
verify
函数必须比较提供的密码产生的签名,并确保它与注册的密码句柄匹配。
用于注册和验证的密钥不得更改,并且应在每次设备启动时重新派生。
可信和其他实现
Trusty操作系统是 Google 用于 TEE 环境的开源可信操作系统,并包含经过批准的 GateKeeper 实施。但是,您可以使用任何 TEE 操作系统来实现 Gatekeeper,只要 TEE 可以访问硬件支持的密钥和一个在暂停状态下滴答作响的安全、单调时钟。
Trusty 使用内部 IPC 系统直接在 Keymaster 和 Gatekeeper 的 Trusty 实现( Trusty Gatekeeper )之间传递共享密钥。此共享密钥用于对发送到 Keystore 的 AuthToken 进行签名,以提供密码验证的证明。 Trusty Gatekeeper 每次使用都向 Keymaster 请求密钥,并且不会保留或缓存该值。实现可以以不损害安全性的任何方式自由共享此秘密。
用于注册和验证密码的 HMAC 密钥是派生的并仅保存在 GateKeeper 中。
Android 提供了 GateKeeper 的通用 C++ 实现,只需要添加特定于设备的例程即可完成。要为您的 TEE 使用特定于设备的代码实现 TEE Gatekeeper,请参阅system/gatekeeper/include/gatekeeper/gatekeeper.h
中的函数和注释。对于 TEE GateKeeper,合规实施的主要职责包括:
- 遵守关守 HAL。
- 返回的 AuthToken 必须根据 AuthToken 规范(在Authentication中描述)进行格式化。
- TEE 网关守卫必须能够与 Keymaster 共享 HMAC 密钥,方法是通过 TEE IPC 按需请求密钥或始终保持该值的有效缓存。
用户安全 ID (SID)
用户 SID 是用户的 TEE 表示(与 Android 用户 ID 没有强连接)。每当用户注册新密码而不提供以前的密码时,都会使用加密伪随机数生成器 (PRNG) 生成 SID。这称为不受信任的重新注册,通常情况下 Android 框架不允许这样做。当用户提供有效的先前密码时,会发生受信任的重新注册;在这种情况下,用户 SID 被迁移到新的密码句柄,保留绑定到它的密钥。
注册密码时,用户 SID 与密码句柄中的密码一起被 HMAC 化。
用户 SID 被写入verify
函数返回的 AuthToken 中,并与所有身份验证绑定的 Keystore 密钥相关联(有关 AuthToken 格式和 Keystore 的详细信息,请参阅Authentication )。由于对enroll
函数的不可信调用将更改用户 SID,因此该调用将使绑定到该密码的密钥无效。如果攻击者控制 Android 操作系统,他们可以更改设备的密码,但他们会在此过程中破坏受 root 保护的敏感密钥。
请求限制
GateKeeper 必须能够安全地限制对用户凭据的暴力破解尝试。如hardware/libhardware/include/hardware/gatekeeper.h
所示,HAL 提供以毫秒为单位返回超时。超时通知客户端在超时过去之前不要再次调用 GateKeeper;如果存在未决超时,GateKeeper 不应服务请求。
GateKeeper 必须在验证用户密码之前写入失败计数器。如果密码验证成功,则应清除失败计数器。这可以防止通过在发出verify
调用后禁用嵌入式 MMC (eMMC) 来防止限制的攻击。 enroll
功能还验证用户密码(如果提供)并且必须以相同的方式进行限制。
如果设备支持,强烈建议将故障计数器写入安全存储。如果设备不支持基于文件的加密,或者安全存储速度太慢,则实现可以直接使用重放保护内存块 (RPMB)。