TPM 程序设计基础 2-1 :具体函数调用步骤及解析示例
前言
本文简述调用 Tspi 相关函数的前提、要求、过程、结果。
代码示例
-
请下载示例代码:pcr_read.c
-
代码实现功能:
- 声明 TPM 相关句柄和变量
- 调用 Tspi_TPM_PcrRead() 等相关函数
- 输出 PCR 读取结果
-
主要结构如下:
复制
// 导入头文件 #include ...... // 设置 define 宏 #define Debug(message, tResult) ... // 声明句柄,调用相关函数,输出结果 void pcr_read() {} // 调用 void pcr_read() 函数 int main() {}
void pcr_read() 函数读取 PCR 值
我们来分析如何实现最终目的:输出 PCR 读取结果。
选择 read 函数
-
由于要读取 PCR 寄存器内的值,锁定关键词为
pcr
和read
,所以可以找到函数:Tspi_TPM_PcrRead()
-
到原英文文档中找到该函数,或者参阅 TPM 程序设计基础 1-2-2 :旧的 PCR 命令 。
声明参数
-
得知函数使用的参数,简单列出:
复制
TSS_HTPM hTPM, // [in]TPM 句柄 UINT32 ulPcrIndex, // [in]PCR寄存器的序号 UINT32* pulPcrValueLength, // [out]选定PCR寄存器的数据长度 BYTE** prgbPcrValue // [out]选定PCR寄存器的数据内容
-
所以声明这些参数。
-
并且在这个函数的定义开始,有个
TSS_RESULT
:复制
TSS_RESULT Tspi_TPM_PcrRead ( ....... );
-
还需要声明
TSS_RESULT
类型的参数,作为Tspi_TPM_PcrRead()
返回的句柄。 -
到此时,得到
pcr_read()
程序内容:复制
void pcr_read() { TSS_HTPM hTPM; TSS_RESULT result; UINT32 ulPcrIndex; UINT32 pulPcrValueLength; BYTE* prgbPcrValue; result = Tspi_TPM_PcrRead(hTPM, ulPcrIndex, &pulPcrValueLength, &prgbPcrValue); }
-
但是标有
[in]
标志的hTPM
和ulPcrIndex
都为NULL
,需要赋予它们内容。ulPcrIndex
范围是 0-23 ,原因:TSS V1.2 有 24个 PCR 寄存器。hTPM
是 TPM 句柄,需通过其他函数返回。
获得 TPM 句柄
要获得 TPM 句柄,需要使用 Tspi_Context_GetTpmObject()
函数。
-
到原英文文档中找到该函数,或者参阅 TPM 程序设计基础 1-2-1 :Tspi_Context 类定义 。
-
该函数参数:
复制
TSS_HCONTEXT hContext, // [in]上下文对象的句柄 TSS_HTPM* phTPM // [out] TPM 句柄
-
声明上下文对象的句柄
hContext
。 -
到此时,得到
pcr_read()
程序内容:Server.java
复制
void pcr_read() { TSS_HTPM hTPM; TSS_RESULT result; TSS_HCONTEXT hContext; UINT32 ulPcrIndex; UINT32 pulPcrValueLength; BYTE* prgbPcrValue; //获得 TPM 句柄 result = Tspi_Context_GetTpmObject(hContext, &hTPM); //设置读取的 PCR 的 index ulPcrIndex = 0; //读取 index 的 PCR result = Tspi_TPM_PcrRead(hTPM, ulPcrIndex, &pulPcrValueLength, &prgbPcrValue); }
-
但是又有一个标有
[in]
标志的hContext
为NULL
,需要赋予它内容。hContext
是上下文对象的句柄,需通过其他函数返回。
获得 上下文对象 句柄
要获得 TPM 句柄,需要使用 Tspi_Context_Create()
和 Tspi_Context_Connect()
函数。
Tspi_Context_Create()
返回 新上下文对象的句柄。
-
到原英文文档中找到该函数,或者参阅 TPM 程序设计基础 1-2-1 :Tspi_Context 类定义 。
-
该函数参数:
复制
TSS_HCONTEXT hContext, // [out]上下文对象的句柄
-
获得上下文对象的句柄
hContext
。
Tspi_Context_Connect()
建立到本地或远程TSS系统的连接。
-
到原英文文档中找到该函数,或者参阅 TPM 程序设计基础 1-2-1 :Tspi_Context 类定义 。
-
该函数参数:
复制
TSS_HCONTEXT hContext, // [in]上下文对象的句柄 TSS_UNICODE* wszDestination // [in]指向空终止的TSS_UNICODE字符串的指针
wszDestination
:该字符串指定要连接的远程系统。如果为空,则上下文对象绑定到本地系统。 这里设定为NULL
。
-
到此时,得到
pcr_read()
程序内容:Server.java
复制
void pcr_read() { TSS_HTPM hTPM; TSS_RESULT result; TSS_HCONTEXT hContext; UINT32 ulPcrIndex; UINT32 pulPcrValueLength; BYTE* prgbPcrValue; //获取 上下文对象 句柄 result = Tspi_Context_Create(&hContext); //建立与本地 TPM 的连接 result = Tspi_Context_Connect(hContext, NULL); //获得 TPM 句柄 result = Tspi_Context_GetTpmObject(hContext, &hTPM); //设置读取的 PCR 的 index ulPcrIndex = 0; //读取 index 的 PCR result = Tspi_TPM_PcrRead(hTPM, ulPcrIndex, &pulPcrValueLength, &prgbPcrValue); }
释放 hContext 占用的内存
复制Tspi_Context_FreeMemory(hContext, NULL);
Tspi_Context_Close(hContext);
- 现在,整个
pcr_read()
程序已经实现了从 TPM 的第 0 个 PCR 寄存器中读取了其中的值,存储到prgbPcrValue
中。 - 当每个函数的每个句柄都能获得,说明程序的调用链是完整的。
void pcr_read() 函数输出 PCR 值
-
由于
prgbPcrValue
的数据类型为BYTE**
,是一个指针,指向长度为pulPcrValueLength
的存储了第 0 个 PCR 寄存器值的内存块。 -
这里
pulPcrValueLength
一般为 20 ,单独BYTE
类型长度为 8 个 0/1 。 -
要输出其中的值,必须要按照
0X
(十六进制)显示输出。 -
然后输出从 0 到 23 个的 PCR 寄存器中的值。
复制
void pcr_read() { TSS_HTPM hTPM; TSS_RESULT result; TSS_HCONTEXT hContext; UINT32 ulPcrIndex; UINT32 pulPcrValueLength; BYTE* prgbPcrValue; result = Tspi_Context_Create(&hContext); result = Tspi_Context_Connect(hContext, NULL); result = Tspi_Context_GetTpmObject(hContext, &hTPM); for (int j = 0; j < 24; j++) { result = Tspi_TPM_PcrRead(hTPM, j, &pulPcrValueLength, &prgbPcrValue); printf("PCR %02d ", j); for (int i = 0; i < 20; i++) { printf("%02x", *(prgbPcrValue + i)); } printf("\n"); } Tspi_Context_FreeMemory(hContext, NULL); Tspi_Context_Close(hContext); }
编译、运行结果
-
编译 pcr_read.c。
复制
gcc pcr_read.c -o pcr_read.out -ltspi
-
运行 pcr_read.out。
复制
./pcr_read.out
- 我这里的 PCR 01 和 08 是已经扩展过的值。
- 一般来说,没有扩展过的 PCR 值:
- 0-15 个为全
0
; - 16-23 个为全
f
。
- 0-15 个为全
作者:Yogile
出处:https://www.cnblogs.com/Yogile/p/12802738.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构