高通HLOS与TrustZone通信的框架演进(2): Android Gatekeeper密码验证完整通信链路
我们已在第一篇中学习了 QSEECOM 的通用架构和 API。本篇以 Android 系统中实际的 Gatekeeper 服务为例,展示 QSEECOM 在真实场景中的完整调用链路。
1. Gatekeeper 在系统中的位置
Android Gatekeeper 服务负责锁屏密码(PIN/密码/图案)的 enrollment(注册) 和 verification(验证)。当用户在锁屏界面输入密码时,Android Framework 通过 Binder 调用到 gatekeeperd 守护进程,最终进入 TrustZone 中的 Gatekeeper TA。验证成功后,Gatekeeper TA 生成一个 AuthToken(HMAC 签名的认证令牌),该令牌随后被 Keymaster TA 用来授权密钥的使用(如磁盘加密、指纹认证等)。
graph LR
subgraph "Android Framework"
LockSettings["LockSettingsService"]
end
subgraph "HLOS Userspace"
GKD["gatekeeperd<br/>(Binder 服务)"]
HAL["Gatekeeper HAL<br/>(vendor .so)"]
QSEEAPI["libQSEEComAPI.so"]
end
subgraph "HLOS Kernel"
QSEEDrv["QSEECom Driver<br/>(/dev/qseecom)"]
end
subgraph "Secure World"
GKTA["Gatekeeper TA"]
KMTA["Keymaster TA"]
end
LockSettings -- "Binder" --> GKD
GKD -- "HAL 接口" --> HAL
HAL -- "dlsym" --> QSEEAPI
QSEEAPI -- "ioctl" --> QSEEDrv
QSEEDrv -- "SMC" --> GKTA
GKTA -- "Auth Token<br/>(HMAC Key 共享)" --> KMTA
系统模块关系:
- Android Framework:
LockSettingsService - HLOS Userspace:
gatekeeperd(Binder 服务)、Gatekeeper HAL(vendor.so)、libQSEEComAPI.so - HLOS Kernel:
QSEECom Driver(/dev/qseecom) - Secure World:
Gatekeeper TA、Keymaster TA
Gatekeeper 端到端架构,参考 [6] AOSP gatekeeperd、[7] AOSP keymaster QSEECom 用法、[8] QSEECom 驱动源码
2. HLOS 侧完整调用链
2.1 gatekeeperd 守护进程
源码位置:system/core/gatekeeperd/
该进程注册 Binder 服务 android.service.gatekeeper.IGatekeeperService。Framework 发起 enroll 或 verify 请求时,gatekeeperd 通过 HIDL 调用到 HAL 层。
2.2 Gatekeeper HAL(厂商实现)
高通提供的 Gatekeeper HAL 是一个 vendor 共享库(如 gatekeeper.msm8996.so)实现了 gatekeeper_device_t 结构体中的 enroll() 和 verify() 函数指针。其内部动态加载 libQSEEComAPI.so:
struct qcom_gatekeeper_handle {
struct QSEECom_handle *qseecom;
void *libhandle;
int (*QSEECom_start_app)(struct QSEECom_handle **handle,
char *path, char *appname, uint32_t size);
int (*QSEECom_send_cmd)(struct QSEECom_handle *handle,
void *cbuf, uint32_t clen,
void *rbuf, uint32_t rlen);
int (*QSEECom_shutdown_app)(struct QSEECom_handle **handle);
};
// 动态加载
handle->libhandle = dlopen("libQSEEComAPI.so", RTLD_NOW);
*(void**)(&handle->QSEECom_start_app) = dlsym(handle->libhandle, "QSEECom_start_app");
*(void**)(&handle->QSEECom_send_cmd) = dlsym(handle->libhandle, "QSEECom_send_cmd");
*(void**)(&handle->QSEECom_shutdown_app) = dlsym(handle->libhandle, "QSEECom_shutdown_app");
2.3 libQSEEComAPI.so 与 ioctl
libQSEEComAPI.so 将 API 调用转换为对 /dev/qseecom 的 ioctl 操作。例如 QSEECom_send_cmd 最终调用 ioctl(fd, QSEECOM_IOCTL_SEND_CMD_REQ, &req)。
3. 完整密码验证流程时序图
sequenceDiagram
participant FW as Android Framework<br/>(LockSettingsService)
participant GK as gatekeeperd
participant HAL as Gatekeeper HAL<br/>(vendor .so)
participant LIB as libQSEEComAPI
participant DRV as QSEECom Driver<br/>(kernel)
participant TZ as Gatekeeper TA
FW->>GK: verify(userId, enrolledPasswordHandle, enteredPassword)
GK->>HAL: device->verify(...)
Note over HAL,TZ: Step 1: 启动 Gatekeeper TA
HAL->>LIB: QSEECom_start_app(&handle, "/vendor/firmware/gatekeeper", "gatekeeper64", sb_size)
LIB->>DRV: ioctl(QSEECOM_IOCTL_LOAD_APP_REQ)<br/>img_name="gatekeeper64"
DRV->>DRV: 检查 TA 是否已加载
DRV->>TZ: SMC (TZ_OS_START_APP_SMC_ID)
TZ-->>TZ: 验证签名、加载 TA 到 pIMEM
TZ-->>DRV: 返回 app_id
DRV-->>LIB: 返回 handle
LIB-->>HAL: 返回 QSEECom_handle
Note over HAL,TZ: Step 2: 构造并发送验证请求
HAL->>HAL: 序列化 VerifyRequest<br/>cmd_id=VERIFY<br/>+ enrolled_password_handle<br/>+ entered_password
HAL->>LIB: QSEECom_send_cmd(handle, send_buf, sbuf_len, rcv_buf, rbuf_len)
LIB->>DRV: ioctl(QSEECOM_IOCTL_SEND_CMD_REQ)<br/>{cmd_req_buf, cmd_req_len, resp_buf, resp_len}
DRV->>DRV: 将用户态虚拟地址转换为物理地址<br/>cache clean (DMA 同步)
DRV->>TZ: SMC (TZ_OS_SEND_CMD_SMC_ID)<br/>args: app_id, req_phys, req_len, rsp_phys, rsp_len
TZ-->>TZ: QTEE 将共享内存映射到 TA 地址空间
TZ-->>TZ: Gatekeeper TA: tz_app_cmd_handler(req, reqlen, rsp, rsplen)
TZ->>TZ: 反序列化请求 → scrypt 验证 → 生成 AuthToken
TZ->>TZ: 序列化 VerifyResponse 写入响应缓冲区
TZ-->>DRV: SMC return
DRV->>DRV: cache invalidate (DMA 同步)
DRV-->>LIB: ioctl 返回
LIB-->>HAL: QSEECom_send_cmd 返回
HAL->>HAL: 反序列化 VerifyResponse<br/>提取 AuthToken
Note over HAL,TZ: Step 3: 关闭 TA(如果不再需要)
HAL->>LIB: QSEECom_shutdown_app(&handle)
LIB->>DRV: ioctl(QSEECOM_IOCTL_UNLOAD_APP_REQ)
DRV->>TZ: SMC (TZ_OS_SHUTDOWN_APP_SMC_ID)
TZ-->>TZ: Unload Gatekeeper TA
TZ-->>DRV: return
DRV-->>LIB: return
HAL-->>GK: 返回验证结果 + AuthToken
GK-->>FW: 验证成功,Auth Token 可用于 Keymaster
阶段一:启动 Gatekeeper TA
- HAL 调用
QSEECom_start_app(handle, "/vendor/firmware/gatekeeper", "gatekeeper64", sb_size) - libQSEEComAPI 执行
ioctl(QSEECOM_IOCTL_LOAD_APP_REQ) - QSEECom Driver 检查 TA 是否已加载,构建 SMC 命令
- Driver 发送 SMC(
TZ_OS_START_APP_SMC_ID) - QTEE 验证 TA 签名,将 TA 加载到 pIMEM(安全内存)
- QTEE 返回
app_id给 Driver - Driver 返回
handle给 HAL
阶段二:发送验证请求
- HAL 序列化
VerifyRequest,包含cmd_id=VERIFY、enrolled_password_handle、entered_password - 调用
QSEECom_send_cmd(handle, send_buf, sbuf_len, rcv_buf, rbuf_len) - libQSEEComAPI 执行
ioctl(QSEECOM_IOCTL_SEND_CMD_REQ) - Driver 将用户态虚拟地址转换为物理地址,执行 cache clean(DMA 同步)
- Driver 发送 SMC(
TZ_OS_SEND_CMD_SMC_ID),参数含app_id、req_phys、req_len、rsp_phys、rsp_len - QTEE 将共享内存映射到 TA 地址空间
- Gatekeeper TA 调用
tz_app_cmd_handler(req, reqlen, rsp, rsplen) - TA 反序列化请求,执行 scrypt 验证,生成 AuthToken
- TA 序列化
VerifyResponse写入响应缓冲区 - SMC 返回,Driver 执行 cache invalidate
ioctl返回,HAL 反序列化响应,提取 AuthToken
阶段三:关闭 TA(可选)
- HAL 调用
QSEECom_shutdown_app(&handle) - Driver 发送 SMC(
TZ_OS_SHUTDOWN_APP_SMC_ID) - QTEE 卸载 Gatekeeper TA
Gatekeeper 密码验证全链路,参考 [8] qseecom.c ioctl 流程、[4] 80-NH537-4 §8.5-8.9
4. 请求/响应的线格式(TLV 示例)
Gatekeeper 协议定义(gatekeeper_messages.h):
struct serial_header_t {
uint32_t error; // 错误码
uint32_t user_id; // Android 用户 ID
};
// 后续为 SizedBuffer 字段: [uint32_t length][uint8_t data[length]]
const uint32_t ENROLL = 0;
const uint32_t VERIFY = 1;
const uint32_t DELETE_USER = 2;
特点:线格式由 Client 和 TA 各自手动序列化/反序列化。没有 IDL 约束,完全依赖双方一致性。这是 QSEECOM “自定义协议” 的典型体现,也是接口不一致的隐患来源。
5. QSEECOM 模式下的特征总结
通过 Gatekeeper 实例可以清晰归纳 QSEECOM 的几个特征:
- TA 名称硬编码:
"gatekeeper64"字符串定位 TA,无标准化服务发现 - 共享内存协议自定义:序列化格式由 HAL 和 TA 各自实现,容易出错
- TA 身份不可知:TA 的入口
tz_app_cmd_handler只接收原始字节,无法获知调用者进程身份 - 引用关系简单:
QSEECom_handle是扁平句柄,不能传递引用计数,无法共享给其他 Client
这些特征在高安全要求场景(如 Keymaster、DRM)中逐渐成为瓶颈,推动高通设计新一代框架 SMCInvoke。
Gatekeeper 案例让我们看到了 QSEECOM 在实际使用中的诸多不便和安全隐患。**下一篇**我们将系统性地总结 QSEECOM 的设计局限,并分析高通文档中提及的真实安全攻击案例,解释为何高通必须设计新一代通信框架。
更多推荐


所有评论(0)