UEFI TGC2 的 sendCommand 总是 returns 错误 21
UEFI TGC2's sendCommand always returns error 21
我正在使用 TPM2 开发 UEFI 应用程序。 getCapabilities 有效,但其他一切都被推到这个 submitCommand() 函数上。我在那里尝试的一切 returns EFI_ABORTED 作为状态。
我尝试了几个命令,例如 read_PCR 和 get_random_number,但它似乎对所有命令都会发生(TPM2 规范第 3 部分)。我选择了随机数命令,因为它是一个简单的命令,没有授权或加密,正确执行时应该总是 return。
struct TPM2_ {
EFI_HANDLE image;
EFI_BOOT_SERVICES *BS;
EFI_TCG2_PROTOCOL *prot;
UINT32 activePCRbanks;
};
struct TPM2_Rand_Read_Command {
TPMI_ST_COMMAND_TAG tag;
UINT32 commandSize;
TPM_CC commandCode;
UINT16 bytesRequested;
};
struct TPM2_Rand_Read_Response {
TPM_ST tag;
UINT32 responseSize;
TPM_RC responseCode;
TPM2B_DIGEST randomBytes;
};
UINTN tpm_get_random(TPM2 * tpm) {
struct TPM2_Rand_Read_Command cmd;
struct TPM2_Rand_Read_Response resp;
cmd.tag = __builtin_bswap16(TPM_ST_NO_SESSIONS); //x86 is little endian, TPM2 is big-endian, use bswap to convert!)
cmd.commandCode = __builtin_bswap32(TPM_CC_GetRandom);
cmd.commandSize = __builtin_bswap32(sizeof(struct TPM2_Rand_Read_Command));
cmd.bytesRequested = __builtin_bswap16(4);
EFI_STATUS stat = tpm->prot->SubmitCommand(tpm->prot,sizeof(struct TPM2_Rand_Read_Command), (UINT8*)&cmd,sizeof(struct TPM2_Rand_Read_Response),(UINT8*)&resp); //responds 0x15 || 21
Print(L"statreadrand: %x \t %d \r\n", stat, *((UINT32*)resp.randomBytes.buffer));
CHECK_STATUS(stat, L"SubmitReadCommand");
return 0;
}
TPM2* tpm_create(EFI_BOOT_SERVICES *BS, EFI_HANDLE image) {
TPM2* tpm = calloc(1, sizeof(TPM2));
EFI_GUID prot_guid = (EFI_GUID)EFI_TCG2_PROTOCOL_GUID;
tpm->BS = BS;
tpm->image = image;
EFI_STATUS stat = tpm->BS->LocateProtocol(&prot_guid, NULL, (void **)&tpm->prot);
CHECK_STATUS(stat, L"LocateTPMProtocol");
return tpm;
}
我希望 SubmitCommand 函数 return EFI_SUCCESS (0) 并用 4 个随机字节填充响应结构。但是函数 returns EFI_ABORTED (21)
有人知道怎么解决吗?
编辑:尝试了不同的工具链(GNU-EFI/普通 GCC/EDK2)都给出了相同的行为。
特定的 PC 确实存在这个问题。可能是 TPM 被锁定了。
当使用另一台带有 TPM2 的 PC 时,问题没有发生,相反,我只是得到了一个随机数。
我正在使用 TPM2 开发 UEFI 应用程序。 getCapabilities 有效,但其他一切都被推到这个 submitCommand() 函数上。我在那里尝试的一切 returns EFI_ABORTED 作为状态。
我尝试了几个命令,例如 read_PCR 和 get_random_number,但它似乎对所有命令都会发生(TPM2 规范第 3 部分)。我选择了随机数命令,因为它是一个简单的命令,没有授权或加密,正确执行时应该总是 return。
struct TPM2_ {
EFI_HANDLE image;
EFI_BOOT_SERVICES *BS;
EFI_TCG2_PROTOCOL *prot;
UINT32 activePCRbanks;
};
struct TPM2_Rand_Read_Command {
TPMI_ST_COMMAND_TAG tag;
UINT32 commandSize;
TPM_CC commandCode;
UINT16 bytesRequested;
};
struct TPM2_Rand_Read_Response {
TPM_ST tag;
UINT32 responseSize;
TPM_RC responseCode;
TPM2B_DIGEST randomBytes;
};
UINTN tpm_get_random(TPM2 * tpm) {
struct TPM2_Rand_Read_Command cmd;
struct TPM2_Rand_Read_Response resp;
cmd.tag = __builtin_bswap16(TPM_ST_NO_SESSIONS); //x86 is little endian, TPM2 is big-endian, use bswap to convert!)
cmd.commandCode = __builtin_bswap32(TPM_CC_GetRandom);
cmd.commandSize = __builtin_bswap32(sizeof(struct TPM2_Rand_Read_Command));
cmd.bytesRequested = __builtin_bswap16(4);
EFI_STATUS stat = tpm->prot->SubmitCommand(tpm->prot,sizeof(struct TPM2_Rand_Read_Command), (UINT8*)&cmd,sizeof(struct TPM2_Rand_Read_Response),(UINT8*)&resp); //responds 0x15 || 21
Print(L"statreadrand: %x \t %d \r\n", stat, *((UINT32*)resp.randomBytes.buffer));
CHECK_STATUS(stat, L"SubmitReadCommand");
return 0;
}
TPM2* tpm_create(EFI_BOOT_SERVICES *BS, EFI_HANDLE image) {
TPM2* tpm = calloc(1, sizeof(TPM2));
EFI_GUID prot_guid = (EFI_GUID)EFI_TCG2_PROTOCOL_GUID;
tpm->BS = BS;
tpm->image = image;
EFI_STATUS stat = tpm->BS->LocateProtocol(&prot_guid, NULL, (void **)&tpm->prot);
CHECK_STATUS(stat, L"LocateTPMProtocol");
return tpm;
}
我希望 SubmitCommand 函数 return EFI_SUCCESS (0) 并用 4 个随机字节填充响应结构。但是函数 returns EFI_ABORTED (21)
有人知道怎么解决吗?
编辑:尝试了不同的工具链(GNU-EFI/普通 GCC/EDK2)都给出了相同的行为。
特定的 PC 确实存在这个问题。可能是 TPM 被锁定了。 当使用另一台带有 TPM2 的 PC 时,问题没有发生,相反,我只是得到了一个随机数。