通過TSS軟件棧使用TPM——獲取並改變TPM寄存器

實驗使用TPM_Emulator代替TPM硬件,原理是一樣的。

1.登錄系統後通過命令啓動TPM模擬器:

sudo modprobe tpmd_dev

sudo tpmd -f -d clear

2.啓動TrouSerS軟件棧

sudo tcsd -e -f

注:如有問題參考另一篇文章

3.代碼如下

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <tss/tss_error.h>
#include <tss/platform.h>
#include <tss/tss_defines.h>
#include <tss/tss_typedef.h>
#include <tss/tss_structs.h>
#include <tss/tspi.h>
#include <trousers/trousers.h>

#define Debug(message, tResult) printf("%s : %s\n", message, (char *)Trspi_Error_String(result))
void printMenu();

int main(int argc, char **argv)
{
	TSS_HCONTEXT 	hContext;
	TSS_HTPM		hTPM;
	TSS_HPCRS		hPcrs;
	TSS_HENCDATA	hEncData;
	TSS_HENCDATA	hRetrieveData;
	TSS_RESULT 		result;
	TSS_HKEY 		hSRK = 0;
	TSS_HPOLICY		hSRKPolicy = 0;
	TSS_UUID		SRK_UUID = TSS_UUID_SRK;

	BYTE 			wks[20];
	BYTE 			*pubKey;
	UINT32			pubKeySize;
	BYTE			*rgbPcrValue;
	UINT32			ulPcrLen;
	BYTE			*encData;
	UINT32			encDataSize;
	BYTE			*outstring;
	UINT32			outlength;
	FILE			*fout, *fin;
	int 			i;
	UINT32			j;
	BYTE			valueToExtend[250];
	int 			count = 0;
	int 			pcrToExtend = 0;
	

	memset(wks, 0, 20);
	memset(valueToExtend, 0, 250);

	//Pick the TPM you are talking to. 
	//In this case, it is the system TPM(indicated with NULL)
	result = Tspi_Context_Create(&hContext);
	Debug("Create Context", result);

	result = Tspi_Context_Connect(hContext, NULL);
	Debug("Context Connect", result);

	//Get the TPM handle
	result = Tspi_Context_GetTpmObject(hContext, &hTPM);
	Debug("Get TPM Handle", result);

	//Get the SRK handle
	result = Tspi_Context_LoadKeyByUUID(hContext, TSS_PS_TYPE_SYSTEM, SRK_UUID, &hSRK);
	Debug("Get the SRK handle", result);

	//Get the SRK policy
	result = Tspi_GetPolicyObject(hSRK, TSS_POLICY_USAGE, &hSRKPolicy);
	Debug("Get the SRK policy", result);

	//Then set the SRK policy to be the well known secret
	result = Tspi_Policy_SetSecret(hSRKPolicy, TSS_SECRET_MODE_SHA1, 20, wks);


	//輸出所有PCR寄存器內的值
	/*********************/
	for (j = 0; j < 24; j++)
	{
		result = Tspi_TPM_PcrRead(hTPM, j, &ulPcrLen, &rgbPcrValue);
		printf("PCR %02d ", j);
		for (i = 0; i < 19; i++)
			printf("%02x", *(rgbPcrValue + i));
		printf("\n");
	}
	/*********************/
	
	//Display each command line argument.
	printf("\n Command line arguments:\n");
	for (count = 0; count <argc; count++)
		printf("argv[%d] : %s\n", count, argv[count]);
	
	//Examine command line arguments.
	if (argc >= 3)
	{
		if (strcmp(argv[1],"-p") == 0)
		{
			pcrToExtend = atoi(argv[2]);
			if (pcrToExtend < 0 || pcrToExtend > 23)
			{
				printMenu();
				return 0;
			}
		}

		if (argc == 5)
		{
			if (strcmp(argv[3], "-v") == 0)
				memcpy(valueToExtend, argv[4], strlen(argv[4]));
		}
		else	//Use default value.
		{
			memcpy(valueToExtend, "abcdefghijklmnopqrst", 20);
		}
	}
	else
	{
		printMenu();
		return 0;
	}

	//Extend the value
	result = Tspi_TPM_PcrExtend(hTPM, pcrToExtend, 20, (BYTE *)valueToExtend, NULL, &ulPcrLen, &rgbPcrValue);
	Debug("Extended the PCR", result);

	//輸出所有PCR寄存器內的值
	/*********************/
	for (j = 0; j < 24; j++)
	{
		result = Tspi_TPM_PcrRead(hTPM, j, &ulPcrLen, &rgbPcrValue);
		printf("PCR %02d ", j);
		for (i = 0; i < 19; i++)
			printf("%02x", *(rgbPcrValue + i));
		printf("\n");
	}
	/*********************/
	

	//Clean up
	Tspi_Context_FreeMemory(hContext, NULL);
	Tspi_Context_Close(hContext);
	
	return 0;
}

void printMenu()
{
	printf("\nChangePCRn Help Menu:\n");
	printf("\t -p PCR regiter to extend(0-23)\n");
	printf("\t -v Value to be extended into PCR(abc...)\n");
	printf("\t Note: -v argument is optional and a default value will be used if no value is provided\n");
	printf("\t Example: ChangePCRn -p 10 -v abcdef\n");
}
4.編譯


5.運行效果

注:通過-p選項指定要修改的PCR寄存器的序號(此處爲PCR0,只是爲了演示,PCR0用來存放可信啓動過程中的度量值)

下圖爲程序輸出的沒有修改前PCR寄存器內值的情況:


下圖爲程序輸出的通過PCR_Extend操作後所有PCR寄存器內值的情況:


可見PCR0中160bit值被修改了。

注:結果也可通過Tpmmanager來驗證,可見結果與我們的輸出是一致的。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章