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 函数

声明参数

  • 得知函数使用的参数,简单列出:

    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] 标志的 hTPMulPcrIndex 都为 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] 标志的 hContextNULL ,需要赋予它内容。

    • hContext 是上下文对象的句柄,需通过其他函数返回。

获得 上下文对象 句柄

要获得 TPM 句柄,需要使用 Tspi_Context_Create()Tspi_Context_Connect()函数。

Tspi_Context_Create() 返回 新上下文对象的句柄。

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
posted @ 2020-04-29 16:00  Yogile  阅读(1013)  评论(0编辑  收藏  举报