EDK2 UEFI应用中设置EPS失败,始终报Device Error错误
解决EDK2 UEFI应用中Tpm2ChangeEPS返回"Device Error"的问题
你遇到的"Device Error"主要源于代码中授权会话参数的错误构造,以及缺少合法的TPM会话建立流程,以下是具体分析和修复方案:
核心问题分析
无效的Nonce与HMAC值
你直接使用ASCII字符串作为Nonce和HMAC的二进制缓冲区是完全错误的:- TPM要求Nonce是20字节的随机二进制数据,而非可打印字符串;
- HMAC必须是基于会话密钥、命令参数(包括
Tpm2ChangeEPS的命令码、目标句柄等)计算出的SHA-256哈希值,硬编码的字符串会被TPM判定为无效授权。
跳过合法会话建立流程
TPMS_AUTH_COMMAND不能直接手动构造后传入,必须先通过Tpm2StartAuthSession与TPM建立合法的授权会话,获取有效的会话句柄和会话密钥,才能生成被TPM认可的HMAC。TPM硬件/固件限制
部分TPM设备会限制Tpm2ChangeEPS的执行场景:比如仅允许在BIOS初始化阶段调用,或者设备处于锁定状态禁止修改EPS,需要先确认TPM的硬件状态。
修复方案与示例代码
步骤1:建立合法授权会话
首先通过Tpm2StartAuthSession创建与TPM_RH_PLATFORM绑定的授权会话:
EFI_STATUS Status; TPM_HANDLE SessionHandle; TPM2B_NONCE NonceCaller; TPM2B_NONCE NonceTpm; // 生成符合要求的20字节随机Nonce NonceCaller.size = 20; GetRandomBytes(NonceCaller.buffer, NonceCaller.size); // 启动平台授权会话 Status = Tpm2StartAuthSession( TPM_RH_NULL, TPM_RH_PLATFORM, &NonceCaller, NULL, TPM_SE_POLICY, NULL, TPM_ALG_SHA256, &SessionHandle, &NonceTpm ); if (EFI_ERROR(Status)) { Print(L"Failed to start auth session: %r\n", Status); return Status; }
步骤2:计算合法HMAC
使用会话密钥(需从会话中推导)、Tpm2ChangeEPS的命令参数组合,计算SHA-256 HMAC:
TPMS_AUTH_COMMAND AuthSession; AuthSession.sessionHandle = SessionHandle; AuthSession.nonce = NonceTpm; // 使用TPM返回的Nonce AuthSession.sessionAttributes.continueSession = 1; // 此处需根据会话密钥、命令参数计算HMAC,示例省略具体计算逻辑 // 可参考EDK2 Tpm2Tools中changeeps工具的HMAC实现 // AuthSession.hmac = CalculateHmac(SessionKey, CommandParams);
步骤3:调用Tpm2ChangeEPS并清理会话
// 执行EPS修改操作 Status = Tpm2ChangeEPS(TPM_RH_PLATFORM, &AuthSession); Print(L"Tpm2ChangeEPS Status: %r\n", Status); // 关闭会话释放资源 Tpm2FlushContext(SessionHandle);
额外注意事项
- 确认平台BIOS中已开启TPM功能,并允许UEFI应用访问TPM命令;
- 使用
Tpm2GetCapability查询TPM状态,确认设备未处于锁定、禁止修改EPS的状态; - 参考EDK2源码中
Tpm2Tools项目的changeeps工具实现,获取完整的授权与HMAC计算逻辑。
内容的提问来源于stack exchange,提问作者Shmurkio
相关产品推荐
相关产品推荐

