一、实验目的
(1)注释seal文件
二、实验环境
(1)Linux操作系统(内核2.6.12版本及以上);
(2)TPM模拟器——Tpm_emulator;
(3)TSS软件栈——trousers软件包。
三、实验原理
seal文件数据密封操作过程如下
(1)调用Tspi_Context_CreateObject分别创建一个加密数据句柄 hEncData和Pcr句柄hPcrs。
(2)调用Tspi_TPM_GetCapability获取TPM版本信息,当capArea=TSS_TPMCAP_PROPERTY 而rgbSubCap=TSS_TPMCAP_PROP_PCR时,prgbRespData,也就是此函数最后一个参数,返回的就是TPM支持的最大PCR寄存器个数。
(3)调用Tspi_TPM_PcrRead 读出TPM中各个per的值并写到上面得到的hPcrs句柄中。
(4)调用Tspi_Data_Seal加密数据,用的密钥是SRK,加密后的数据在hEncData 指向的位置。
(5)调用Tspi_GetAtribData导出DataBlob,并将其写入文件“sealedData”。
(6)释放内存关闭上下文。
四、实验内容
/**
#include “common.h” //常用头文件,文件夹中没有,我自己写了一个附上一起交上去
#include “hex-out.h” //将指定的缓冲区以十六进制格式转储到设备(stdout或stderr)
int main(int argc, char **argv)
{
char version; //定义版本名称
version = parseArgs(argc, argv); //获取版本名
if (version) { //判断版本名是否为0
main_v1_1(); //如果不为0,则运行main_v1_1函数
} else {
print_wrongVersion(); //否则输出版本错误
}
}
int main_v1_1(void)
{
//设置TSS相关参数
TSS_RESULT result;
TSS_HKEY hSRK; //hSRK SRK对象的句柄
TSS_HCONTEXT hContext; //context对象的句柄
TSS_HTPM hTPM; //hTPM TPM对象的句柄
TSS_HENCDATA hEncData; //hEncData为数据对象的句柄,其中包含成功完成命令时密封的数据
TSS_HPOLICY hEncPolicy;
TSS_HPCRS hPcrs; //hPcrs Pcr对象的句柄
UINT32 subCap, subCapLength, ulPcrValueLength, ulEncDataLength; //设置各参数的长度(以字节为单位)
UINT32 pulRespDataLength, dataLength = 32;
UINT32 numPcrs;
BYTE *pNumPcrs, *rgbDataToSeal; //rgbDataToSeal 指向包含要加密的数据的内存的指针
BYTE *rgbPcrValue, *rgbEncData;
int i, exitCode; //设置计数器
FILE *fEncData = NULL; //定义文件内容为空
char *file_name = “sealedData”; //定义文件名
rgbDataToSeal = "0123456789ABCDEF0123456789ABCDEF";
#define DEBUG //设置define宏
#ifdef DEBUG
#define SET_ANCHOR(x) printf(x “\n”)
#else
#define SET_ANCHOR(x) do { }while(0)
#endif // #ifdef DEBUG
SET_ANCHOR("1");
// load Context, SRK, and TPM
if ((result = connect_load_all(&hContext, &hSRK, &hTPM))) { //加载Context,SRK和TPM
return result; //返回结果
}
SET_ANCHOR("2");
// Create Encrypted Data Object
result = Tspi_Context_CreateObject(hContext,
TSS_OBJECT_TYPE_ENCDATA,
TSS_ENCDATA_SEAL,
&hEncData); //创建TSP中被加密数据对象
if (TSS_SUCCESS != result) { //如果值不相等
print_error("Tspi_Context_CreateObject", result); //输出错误
Tspi_Context_FreeMemory(hContext, NULL); //释放hContext占用的内存
Tspi_Context_Close(hContext);
exit(result); //进程停止
}
SET_ANCHOR("3");
if ((result = set_secret(hContext, hEncData, &hEncPolicy))) { //set_secret设置口令
printf("set_secret failed\n"); //输出设置口令失败
Tspi_Context_FreeMemory(hContext, NULL); //释放hContext占用的内存
Tspi_Context_Close(hContext);
exit(result); //进程停止
}
SET_ANCHOR("4");
// Create PCRs Object
result = Tspi_Context_CreateObject(hContext,
TSS_OBJECT_TYPE_PCRS,
0,
&hPcrs); //Tspi_Context_CreateObject 创建PCR对象
if (TSS_SUCCESS != result) { //判断值是否相等
print_error("Tspi_Context_CreateObject", result); //若不相等,输出错误
Tspi_Context_FreeMemory(hContext, NULL); //释放hContext占用的内存
Tspi_Context_Close(hContext);
exit(result); //进程停止
}
SET_ANCHOR("5");
subCap = TSS_TPMCAP_PROP_PCR;
subCapLength = sizeof(UINT32); //获取UNIT32长度
result = Tspi_TPM_GetCapability(hTPM,
TSS_TPMCAP_PROPERTY,
subCapLength, (BYTE *)&subCap,
&pulRespDataLength,
&pNumPcrs); //获取TPM版本信息,返回TPM支持的最大PCR寄存器个数
if (TSS_SUCCESS != result) { //如果结果不相等
print_error("Tspi_TPM_GetCapability", result); //输出错误
Tspi_Context_FreeMemory(hContext, NULL); //释放hContext占用的内存
Tspi_Context_Close(hContext);
exit(result); //进程停止
}
SET_ANCHOR("6");
numPcrs = *(UINT32 *)pNumPcrs; //指针转换
for (i = 0; i < numPcrs; i++) {
// In Physical TPM not all pcrs are available, so we choose pcr 15
if (i != 15) { // 如果i不等于15
continue; //跳过下面代码,继续i++
}
result = Tspi_TPM_PcrRead(hTPM, i, &ulPcrValueLength, &rgbPcrValue); //Tspi_TPM_PcrRead()函数输出PCR值,即读取PCR的i中的数据
if (TSS_SUCCESS != result) { //判断PCR值是否相等
print_error("Tspi_TPM_PcrRead", result); //如果不相等,则输出错误
Tspi_Context_FreeMemory(hContext, NULL); //释放hContext占用的内存
Tspi_Context_Close(hContext);
exit(result); //进程停止
}
result = Tspi_PcrComposite_SetPcrValue(hPcrs, i, ulPcrValueLength,
rgbPcrValue); //Tspi_PcrComposite_SetPcrValue将读取到的PCRi中的值写入PCR对象中
if (TSS_SUCCESS != result) {
print_error("Tspi_PcrComposite_SetPcrValue", result); //输出错误
Tspi_Context_FreeMemory(hContext, NULL); //释放hContext占用的内存
Tspi_Context_Close(hContext);
exit(result); //进程停止
}
}
SET_ANCHOR("7");
// Seal Data
result = Tspi_Data_Seal(hEncData,
hSRK,
dataLength,
rgbDataToSeal,
hPcrs); //数据密封
if (TSS_SUCCESS != result) { //如果值不相等
print_error("Tspi_Data_Seal", result); //输出错误
Tspi_Context_FreeMemory(hContext, NULL); //释放hContext占用的内存
Tspi_Context_Close(hContext);
exit(result); //进程停止
}
result = Tspi_GetAttribData(hEncData,
TSS_TSPATTRIB_ENCDATA_BLOB,
TSS_TSPATTRIB_ENCDATABLOB_BLOB,
&ulEncDataLength,
&rgbEncData); //执行这步后要比较&ulEncDataLength和&rgbEncData大小,以防被加密的blob过大
if (TSS_SUCCESS != result) { //如果值不相等
print_error("Tspi_GetAttribData", result); //输出错误
Tspi_Context_FreeMemory(hContext, NULL); //释放hContext占用的内存
Tspi_Context_Close(hContext);
exit(result); //进程停止
}
printf("EncDataBlob:\n"); //输出EncDataBlob
print_hex(rgbEncData, ulEncDataLength); //输出加密数据和长度的16进制
fEncData = fopen(file_name, "w+b"); //打开可读写二进制文件
if (NULL == fEncData) { //如果文件内容为空
printf("fopen %s failed\n", file_name); //则输出打开文件失败
Tspi_Context_FreeMemory(hContext, NULL); //释放hContext占用的内存
Tspi_Context_Close(hContext);
exit(-1); //进程停止
}
if (fwrite(rgbEncData, 1, ulEncDataLength, fEncData) != ulEncDataLength) { //fwrite将加密数据、密文长度等依次写入文件,并判断是否相等
printf("fwrite failed\n"); //输出写入失败
fclose(fEncData); //关闭文件
Tspi_Context_FreeMemory(hContext, NULL); //释放hContext占用的内存
Tspi_Context_Close(hContext);
exit(-1); //进程停止
}
fclose(fEncData); //关闭文件
printf("\nSuccess\n"); //输出“成功”
Tspi_Context_FreeMemory(hContext, NULL); //释放hContext占用的内存
Tspi_Context_Close(hContext);
//exit(exitCode);
return 0; //返回
}