Keymaster TA 实现原理:密钥生成、加解密、签名验签内部全逻辑
一、整体定位与核心设计原则
1. 运行层级与隔离边界
- 运行在OP-TEE 用户态(EL0_S),和普通业务 TA 一样处于沙箱隔离中,拥有独立地址空间;
- 仅通过系统调用访问安全内核能力(密码引擎、eFuse、安全存储),不直接操作硬件;
- 对外仅暴露标准化命令接口,所有输入参数都经过强校验。
2. 七大核心设计原则(TA内部逻辑的约束根基)
- 密钥不可导出原则:原始密钥明文永远不会流出安全世界,对外只返回加密后的 Key Blob;
- 设备强绑定原则:密钥 Blob 只能在生成它的设备上解密,拷贝到其他设备无效;
- 无状态设计原则:TA 本身不持久化存储密钥,所有密钥都以 Blob 形式交由非安全侧保存,使用时再传入 TA 解密,天然支持海量密钥;
- 授权强制原则:密钥生成时绑定所有使用约束(认证、有效期、用途),使用时强制校验,不满足条件绝不执行运算;
- 内存零残留原则:敏感密钥、明文数据使用后强制清零,运算上下文销毁彻底,防止内存残留泄露;
- 完整性保护原则:所有密钥元数据、密钥材料都带认证标签,篡改后直接拒绝使用;
- 算法标准化原则:严格遵循 Google Keymaster HAL 规范,支持 AES、RSA、EC、HMAC、HKDF 等标准算法与模式。
二、核心数据结构:加密密钥 Blob(Key Blob)
1. Blob 整体结构
┌─────────────────────────────────────────────────────┐ │ 明文头部(Plaintext Header) │ │ - 魔数、Blob版本、算法类型、密钥长度 │ │ - 授权集合(Authorization Set):所有使用约束 │ ├─────────────────────────────────────────────────────┤ │ 加密密钥区(Encrypted Key Material) │ │ - 用设备绑定 KEK 加密后的原始密钥明文 │ ├─────────────────────────────────────────────────────┤ │ 认证标签(GCM Tag,16字节) │ │ - 覆盖头部+授权集+加密区,保证完整性与真实性 │ └─────────────────────────────────────────────────────┘2. 各字段详细说明
① 明文头部与授权集合
- 基础属性:算法类型(AES/RSA/EC/HMAC)、密钥位数、Blob 格式版本、生成时间;
- 用途约束:标记密钥可用于加密/解密/签名/验签/密钥派生,防止密钥被滥用;
- 访问控制:用户认证要求(是否需要锁屏密码/生物认证)、认证有效期、调用者安全级别;
- 回滚保护:密钥版本号,与系统滚回版本比对,旧版本密钥直接失效。
② 加密密钥区
- 对称密钥:AES/HMAC 密钥原始字节;
- 非对称密钥:RSA 私钥参数(d/p/q)、EC 私钥参数(私钥标量);
- 由设备专属密钥加密密钥(KEK)通过 AES-GCM 加密,没有 KEK 无法解密出原始密钥。
③ 密钥加密密钥(KEK)的派生逻辑
eFuse 硬件根密钥 HUK ↓ 调用 System PTA 派生 设备级主密钥 SSK ↓ 加入 "AndroidKeymaster" 派生因子 Keymaster TA 专属 KEK- 每台设备的 KEK 唯一,由硬件根密钥派生,不可导出、不可篡改;
- 这就是为什么 Key Blob 拷贝到其他设备无法解密——KEK 不同,解密直接失败。
三、核心功能1:密钥生成(GenerateKey)内部全流程
步骤1:入参合法性强校验
- 算法与参数校验:检查算法是否支持、密钥长度是否合规(如 AES 仅支持 128/256 位、RSA 支持 2048/4096 位);
- 用途合法性校验:加密密钥不能用于签名、签名密钥不能用于解密,防止跨用途滥用;
- 授权参数校验:用户认证类型、有效期、回滚版本等参数是否符合规范;
- 边界校验:所有参数长度、指针范围检查,防止整数溢出和越界。
步骤2:生成原始密钥材料
- 对称密钥(AES/HMAC):调用 TEE_GenerateRandom 从硬件 TRNG 获取真随机数,直接作为密钥材料;
- 非对称密钥对(RSA/EC):
- 调用 TEE_AllocateTransientObject 创建临时密钥对象;
- 调用 TEE_GenerateKey,基于硬件随机数生成公私钥对;
- 私钥材料全程保存在安全内存中,公钥可后续明文导出。
步骤3:组装授权与元数据
- 写入算法类型、密钥大小、用途掩码;
- 写入用户认证要求、认证超时时间、有效起止时间;
- 写入当前系统回滚版本号,用于后续回滚防护。
步骤4:封装加密 Key Blob
- 从系统 PTA 获取 Keymaster 专属 KEK;
- 生成随机 IV(12字节,GCM 标准长度);
- 使用 AES-GCM 加密原始密钥材料,明文头部+授权集合全部作为 AAD(附加认证数据)参与标签计算;
- 把头部、IV、加密密钥、认证标签拼接成完整的 Key Blob。
步骤5:返回结果与内存清理
- 将完整的 Key Blob 写入输出共享内存,返回给非安全侧;
- 非对称密钥同时导出公钥明文(公钥本身不敏感,可公开);
- 强制清零安全内存中的临时密钥材料、KEK、运算上下文,销毁所有敏感中间态。
四、核心功能2:对称加解密(Encrypt/Decrypt)内部全流程
步骤1:Blob 解析与前置校验
- 收到非安全侧传入的 Key Blob、运算模式、输入数据、IV/AAD 等参数;
- 校验 Blob 魔数、版本,格式非法直接返回错误;
- 校验密钥用途:加密操作必须包含 encrypt 权限,解密必须包含 decrypt 权限,用途不匹配直接拒绝。
步骤2:解密 Blob 取出密钥
- 使用设备 KEK + Blob 中的 IV,执行 AES-GCM 解密;
- 同时校验认证标签,标签不匹配说明 Blob 被篡改,直接返回安全错误;
- 解密成功后,原始密钥材料仅存在于 TA 内部的临时安全内存中。
步骤3:授权强制校验
1.用户认证校验:如果密钥要求用户认证,必须传入有效的硬件认证令牌(Auth Token);
- TA 校验 Token 的签名(由 Gatekeeper/生物识别 TA 用共享密钥签发),确认是可信认证结果;
- 校验认证时间是否在有效期内,超时则要求重新认证;
2.有效期校验:当前时间是否在密钥有效起止时间内;
3.回滚版本校验:Blob 版本号不得低于系统最低允许版本,防止降级攻击。
步骤4:运算上下文初始化
- 调用 TEE_AllocateOperation 创建密码运算句柄,指定算法模式(AES-GCM)、运算方向(加密/解密);
- 调用 TEE_SetOperationKey,把解密出的密钥材料加载到运算上下文中;
- 初始化 IV、AAD(加密使用传入的 IV,解密使用 Blob 中附带的 IV);
- TA 内部为该运算分配唯一会话 ID,返回给非安全侧,后续分段运算通过会话 ID 复用上下文。
步骤5:分段运算与最终运算
- 短数据一次性运算:直接调用 TEE_AEEncryptFinal / TEE_AEDecryptFinal 完成全部运算;
- 长数据分段运算:
- 非安全侧多次调用 Update 命令,传入分片数据;
- TA 根据会话 ID 找到运算上下文,调用 TEE_AEUpdate 持续更新运算状态;
- 最后一次调用 Final 命令,输出最终结果和认证标签。
步骤6:结果输出与资源销毁
- 将密文/明文结果写入共享内存,更新输出长度;
- 调用 TEE_FreeOperation 销毁运算上下文;
- 强制清零临时密钥材料、明文缓冲区、所有中间敏感内存;
- 释放会话资源,运算句柄失效,防止后续复用。
五、核心功能3:非对称签名验签(Sign/Verify)内部全流程
1. 私钥签名流程
1.Blob 解密与校验:同加密流程,解密出 RSA/EC 私钥材料,校验用途必须包含 sign 权限;
2.授权校验:签名属于高危操作,通常强制要求用户认证,校验 Auth Token 有效性;
3.摘要预处理:
- 若上层传入的是原始数据,TA 内部先做哈希计算(SHA256/SHA384等);
- 若上层传入的是摘要,校验摘要长度与算法匹配,防止长度篡改;
4.执行签名运算:
- RSA:执行私钥指数运算,生成签名值;
- ECDSA:基于私钥标量和随机数 k,生成 (r,s) 签名对;
- 全程私钥材料只在安全内存中参与运算,不会以任何形式输出;
4.结果返回与清理:输出签名结果,清零私钥、运算上下文、临时缓冲区。
2. 公钥验签流程
- 从 Key Blob 中提取公钥参数(公钥属于明文信息,无需加密);
- 校验摘要、签名长度合法性;
- 调用 TEE_AsymmetricVerify 执行验签运算;
- 返回验签成功/失败结果,不泄露任何敏感信息。
六、关键安全机制的 TA 内部实现
1. 密钥不可导出的强制防护
- 生成密钥时,exportable 属性默认关闭,一旦标记为不可导出,TA 所有出口都不会输出密钥明文;
- 即使 TA 代码出现漏洞,内核层也会限制用户态内存访问范围,无法通过越界读取直接获取密钥材料;
- 公钥导出单独走分支,仅允许导出非敏感的公钥参数,私钥部分永远不会进入导出分支。
2. 用户认证绑定:Auth Token 校验
- Auth Token 由 Gatekeeper TA(密码校验)或生物识别 TA 在认证成功后签发,用 TEE 内共享的密钥做 HMAC 签名;
- Keymaster TA 持有相同的校验密钥,收到 Token 后先校验 HMAC 签名,确认是可信 TA 签发;
- 再校验认证类型、时间戳、安全等级,全部匹配才允许使用受保护的密钥;
- 非安全世界无法伪造 Token,也就无法绕过用户认证直接调用密钥。
3. 运算上下文隔离与会话管理
- 每个运算会话对应独立的运算句柄和内存空间,会话之间完全隔离,防止数据串扰;
- 会话有超时机制,长时间未使用自动销毁,防止会话被复用攻击;
- 会话 ID 随机生成,不可预测,防止暴力猜解会话 ID 越权使用运算上下文。
4. 敏感内存零残留策略
- 所有存放密钥、明文、中间运算状态的内存,使用完毕后调用 memzero_explicit 强制清零;
- 该函数不会被编译器优化掉,保证内存数据被真实覆盖;
- 运算句柄销毁时,内部所有状态内存同步清零,不留任何密钥痕迹;
- TA 退出会话时,整个用户地址空间回收,物理页清零后再放回内存池,防止泄露给下一个加载的 TA。
七、与 OP-TEE 系统能力的对应关系
- 密码运算:调用 libutee 标准 TEE 密码 API,底层走 OP-TEE 内核 Crypto 框架,可对接硬件加密引擎(CE);
- 密钥派生:调用 System PTA 的 DERIVE_TA_UNIQUE_KEY 接口,基于 HUK 派生专属 KEK,和你app_secrets 的实现完全同源;
- 真随机数:调用 TEE_GenerateRandom,底层对接硬件 TRNG,保证密钥熵源安全;
- 安全存储:可选模式下,密钥可存入 OP-TEE 安全存储,不返回 Blob 给非安全侧,仅返回密钥句柄,安全性更高(StrongBox 模式)。
和普通业务 TA 的异同
- 相同点:都遵循 GP TA 规范,都运行在用户态沙箱,都用「密封-解密-运算」的思路保护敏感数据;
- 不同点:Keymaster TA 是标准化系统 TA,有严格的 HAL 接口规范、更完善的授权体系、更全面的算法支持、更严苛的安全校验,是 Google 强制要求的 TEE 能力落地载体。