tpm_emulator 搭建 TPM 仿真环境
参考《可信计算基础》实验指导书-20170326.PDF
目录
1. 平台环境
1.1. 系统平台
1.2. TPM 仿真环境结构
2. cmake
2.1. cmake 简介
2.2. 安装 cmake
3. m4
3.1. m4 简介
3.2. 安装 m4
4. GNU MP Library
4.1. GMP 简介
4.2. 安装 GMP
5. TPM_Emulator
5.1. 编译和安装 TPM_Emulator
5.2. 初始化 TPM_Emulator
5.3. 启动 TPM_Emulator
6. TSS 协议栈
6.1. 编译和安装 Trousers
6.2. 启动 TCSD
7. tpm-tools
7.1. tpm-tools 简介
7.2. 安装 tpm-tools
8. 测试 TPM 环境是否搭建成功
9. 运行测试程序
9.1. 在 tpm-emulator-0.7.5/tddl/ 目录下有测试程序
PS:解决后再更新???
9.2. 对TSS协议栈进行测试
9.2.1. 测试程序
9.2.2. 该程序实现的操作
9.2.3. 编译和执行
PS:解决后再更新???
1. 平台环境
1.1. 系统平台
宿主机系统:Windows 10 Pro
虚拟机工具:VMware® Workstation 15 Pro
虚拟机系统:CentOS Linux release 7.6.1810 (Core) 64位
本文在 centos 虚拟机上搭建 TPM 仿真环境。
1.2. TPM 仿真环境结构
下面是TPM仿真环境软件包依赖关系图,搭建环境应该是由下至上按部就班的安装。
2. cmake
2.1. cmake 简介
CMake 是一个跨平台的自动化建构系统,它使用一个名为 CMakeLists.txt 的文件来描述构建过程,可以产生标准的构建文件,如 Unix 的 Makefile 或Windows Visual C++ 的 projects/workspaces 。文件 CMakeLists.txt 需要手工编写,也可以通过编写脚本进行半自动的生成。CMake 提供了比 autoconfig 更简洁的语法。在 linux 平台下使用 CMake 生成 Makefile 并编译的流程如下:
(1)编写 CmakeLists.txt。
(2)执行命令“cmake PATH”或者“ccmake PATH”生成 Makefile ( PATH 是 CMakeLists.txt 所在的目录 )。
(3)使用 make 命令进行编译。
2.2. 安装 cmake
tar zxvf cmake-3.22.3.tar.gz
解压缩后 cd cmake-3.22.3
./bootstrap安装
sudo make install安装
完成后cmake --version
3. m4
3.1. m4 简介
m4 是一种宏处理器,它扫描用户输入的文本并将其输出,期间如果遇到宏就将其展开后输出。宏有两种,一种是内建的,另一种是用户自定义的,它们能接受任意数量的参数。除了做展开宏的工作之外,m4 内建的宏能够加载文件,执行 Shell 命令,做整数运算,操纵文本,形成递归等等。m4 可用作编译器的前端,或者单纯作为宏处理器来用。
3.2. 安装 m4
sudo apt-get install m4
4. GNU MP Library
4.1. GMP 简介
gmp是一个可以进行任意精度算术的自由库,可以操作有符号整数、有理数和浮点数。除了运行gmp的机器中可用内存所暗示的精度外,没有实际限制。gmp有一套丰富的功能,这些功能有一个常规的接口(本文不研究这个接口)。
gmp的主要目标应用是密码学应用与研究、互联网安全应用、代数系统、计算代数研究等。
gmp基于m4,所以在安装gmp之前要先安装m4。
4.2. 安装 GMP
下载地址:http://gmplib.org
我下载的版本:gmp-6.2.1.tar.zst
执行下列命令进行编译和安装:
tar -I zstd -xvf gmp-6.2.1.tar.zst (因为zstd没有安装,所以sudo apt-get install zstd后再解压缩)
解压后cd gmp-6.2.1
cd gmp-6.2.1
./configure
make
make check
make install
5. TPM_Emulator
下载地址:https://github.com/PeterHuewe/tpm-emulator
我下载的版本:tpm-emulator-master.zip
解压缩 unzip tpm-emulator-master.zip
该程序主要包含三个部分:
(1)tpmd:实现 TPM 仿真器的用户空间应用程序,可以通过 Unix 域套接字(Unix)或命名管道(Windows)进行访问。
(2)tpmd_dev:一个内核模块,它提供设备 /dev/tpm 以实现向后兼容,并将收到的命令转发给 tpmd(仅限Unix和Mac OS X)。
向后兼容(Backward Compatibility),又称作向下兼容(Downward Compatibility)。在计算机中指在一个程序或者类库更新到较新的版本后,用旧的版本程序创建的文档或系统仍能被正常操作或使用,或在旧版本的类库的基础上开发的程序仍能正常编译运行的情况。
(3)tddl:TPM 仿真器的 TSS 符合设备驱动程序库。
5.1. 编译和安装 TPM_Emulator
TPM 仿真器包的编译和安装基于 CMake 构建环境(2.6或更高版本),并要求在您的系统上正确安装 GNU MP 库(版本4.0或更高版本)。因为前面已经安装过了,所以这里直接执行下列命令进行编译和安装:
cd tpm-emulator-master
mkdir build
cd build
cmake ../
make
(make后出错,原因没有安装GMP库)sudo apt-get install libgmp-dev,再make即可
软连接问题:
su root
cd /lib/modules/5.11.0-40-generic 后ll,看是否有软连接存在 build-> /usr/lib/linux-headers-5.11.0-40-generic/是否存在,若为红色说明不存在,则需要下载;若存在,需要重新链接
sudo apt-get install linux-headers-5.11.0-40-generic
sudo apt-get install linux-kernel-headers kernel-package
查看内核开发文件路径下对应的文件名
ls /usr/src
cd /lib/modules/5.11.0-40-generic
链接文件
ln -s(或-sf表示强制链接) 、/usr/src/linux-headers-5.11.0-40-generic build
回到tpm-emulator-master文件夹 cd build重新make及make install
5.2. 初始化 TPM_Emulator
TPM的启动模式(参见TPM规范第1部分)由启动模式参数定义,可以设置为clear,save(默认)或deactivated,对应的中文意思分别是清除,保存和停用。 下面简单介绍tpmd的用法以及参数的含义:
如果模拟器以“save”模式启动并且无法加载先前存储的TPM状态,则它将进入“fail-stop”模式并且必须重新加载。 因此,第一次启动TPM仿真器时,参数必须设置为“clear”。 想要恢复处于“fail-stop”模式的TPM仿真器,首先将其停用,然后以“clear”模式重新加载,我们执行下列命令进行初始化:
5.3. 启动 TPM_Emulator
要想在 Unix 或 Mac OS X 上使用 TPM 仿真器,必须先启动 TPM 仿真器的守护程序(tpmd)并加载 TPM 设备转发模块(tpmd_dev)。 我们执行下列命令进行启动:
注释:
(1)若在执行第一条命令时遇到:Module tpmd_dev not found,则执行命令:depmod -a
(2)modprobe命令:
modprobe命令用于智能地向内核中加载模块或者从内核中移除模块。
modprobe可载入指定的个别模块,或是载入一组相依的模块。modprobe会根据depmod所产生的相依关系,决定要载入哪些模块。若在载入过程中发生错误,在modprobe会卸载整组的模块。
(3)depmod命令:
depmod命令可产生模块依赖的映射文件,在构建嵌入式系统时,需要由这个命令来生成相应的文件,由modprobe使用。
启动时遇到的错误:
解决方法:
启动tpm模拟器的时候出现了报错:/tpm/tpm_startup.c:83: Error: restoring permanent data failed
解决方法就是在“启动软TPM”这个地方把
#tpmd -f -d 换成 #tpmd -f -d clear
#modprobe tpmd_dev //将该模块加入内核
#tpmd -f -d
若出现tpmd.c:276:Error: bind(/var/run/tpm/tpmd_socket:0) failed: Address already in use,则:sudo rm/var/run/tpm/tpmd_socket:0
启动成功界面:
启动模拟器再同时启动TSTD,这个时候就相当于模拟器启动成功了,并可以查看这个模拟器的版本等等信息**
先打开2个窗口各运行tpmd和tcsd命令,Ctrl+alt+T打开新窗口
//setup tpm
#modprobe tpmd_dev //将该模块加入内核
#tpmd -f -d
若出现TCSD ERROR: Failed bind: Address already in use,则:
l ps –e | grep tcsd
l kill -9 。。。
成功启动后:
注:
#tpmd [-d] [-f][-h] [start mode]
其中[-d]: enable debug mode
[-f]:force the application to run in the forground 会显示你发送给tpmd的命令
[-h]:print this help message 打印帮助消息
Start mode:’clear’清除之前的状态, ’save’默认情况下打开之前的状态, ‘deactivate’无效
然后TPMManger其实就是相当于提供了可视化的界面来查看TPM芯片的信息
链接:https://github.com/Rohde-Schwarz/TPMManager
一些长识:
” apt-get“是一条linux命令,适用于deb包管理式的操作系统,主要用于自动从互联网的软件仓库中搜索、安装、升级、卸载软件或操作系统 ,可以为你获取和安装二进制软件包,而节省编译的时间
depmod可检测模块的相依性,供modprobe在安装模块时使用。
(原文链接:https://blog.csdn.net/qq_35297774/article/details/89188549)
再次启动 tpmd 就没有问题了。
查看TPM版本
tpm_version
若出现error while loading shared libraries: libtspi.so.1: cannot openshared object file: No such file or directory,则:
apt-get install libtspi-dev
tpm-tools-1.3.8/src/tpm_mgmt/目录下查看以下三个信息:
#./tpm_version #查看版本号
#./tpm_getpubek #查看ek公钥
#./tpm_takeownership #获取owner
注:如果都成功表明TPM模拟环境已经完全构建成功了。
如果 tpm_version出现tpm_version: error while loading shared libraries: libtspi.so.1: cannot open shared object file: No such file or directory,则使用命令apt-get install libtspi-dev
若出现Tspi_Context_Connect failed: 0x00003011 - layer=tsp, code=0011 (17), Communication failure
,则开启tpmd和tcsd即可。
原文链接:https://blog.csdn.net/lwyeluo/article/details/49963683
在tpm_emulator-0.7.4/tddl文件夹下有测试事例:
../tpm_emulator-0.7.4/tddl# gcc -o test_tddl test_tddl.c -ltddl// -ltddl 为链接tddl的动态链接库
../tpm_emulator-0.7.4/tddl# LD_LIBRARY_PATH=/usr/local/lib ./test_tddl//运行结果
因为$PATH中没有路径/usr/local/lib,因此,需要加上LD_LIBRARY_PATH=/usr/local/lib,不然会报错
6. TSS 协议栈
下载地址:https://sourceforge.net/projects/trousers/files/
我下载的版本:trousers-0.3.14.tar.gz
该程序是由 IBM 创建和发布的开源 TCG 软件栈。
6.1. 编译和安装 Trousers
Tips:
如果直接解压 trousers 的压缩包,它的各种文件会分散在父目录里面,所以要在解压时为其指定一个解压目录。当然,如果不小心直接解压了,也可以使用下列命令撤销解压操作:
我们先为 trousers 创建一个目录,再将其进行解压:
看一下 README 文件,并按要求安装如下的依赖包:
pkgconfig安装提示找不到包:
到pkg-config官网https://www.freedesktop.org/wiki/Software/pkg-config/,下载最新安装包
目前,最新版是2017年3月20日发布的0.29.2,下载地址https://pkg-config.freedesktop.org/releases/pkg-config-0.29.2.tar.gz。
命令wget https://pkg-config.freedesktop.org/releases/pkg-config-0.29.2.tar.gz,下载完成后解压
原文链接:https://blog.csdn.net/Charliewolf/article/details/101273248
tar -zxvf pkg-config-0.29.2.tar.gz
进入安装包
cd pkg-config-0.29.2
依次执行以下四个命令
./configure --with-internal-glib
make
make check
sudo make install
查看版本
pkg-config --version
0.29.0
libtool安装
wget http://ftpmirror.gnu.org/libtool/libtool-2.4.6.tar.gz
tar xvf libtool-2.4.6.tar.gz -C ~/
cd ~/libtool-2.4.6
配置
./configure --prefix=/home/jello/libtool
编译
make -j4
安装
make install
openssl-devel安装下载地址 https://www.openssl.org/source/
可以直接安装sudo apt-get install openssl
openssl version -a
#apt-get install build-essential#这将安装gcc/g++/gdb/make等基本编程工具
#apt-get install gnome-core-devel#这将安装 libgtk2.0-dev libglib2.0-dev等开发相关的库文件
#apt-get install pkg-config #用于在编译GTK程序时自动找出头文件及库文件位置
#apt-get install devhelp #这将安装 devhelp GTK文档查看程序
#apt-get install libglib2.0-doc libgtk2.0-doc #这将安装 gtk/glib的API参考手册及其它帮助文档
#apt-get install glade libglade2-dev#这将安装基于GTK的界面GTK是开发Gnome窗口的c/c++语言图形库
#apt-get install libgtk2.0* #gtk+2.0所需的所有文件统通下载安装完毕
原文链接:https://blog.csdn.net/qq_41426887/article/details/89742881
出现错误:libgtk2.0-0-dbg : Depends: libgtk2.0-0 (= 2.24.23-0ubuntu1.4) but 2.24.32-4ubuntu4 is to be installed
采用降级的方式,如下命令
apt-get aptitude
sudo aptitude install libgtk2.0-dev
安装完上述的依赖包后再执行下面的命令进行编译和安装:
Tips:
网上有说需要修改 Makefile.am 和 Makefile.in 文件,但那些都是 trousers-0.3.8 版本的教程,那个版本会遇到 Werror、ld 链接库等报错的问题。本文使用 trousers-0.3.14 版本,没有修改 Makefile.* 文件,直接编译安装成功无报错。
6.2. 启动 TCSD
Tips:
在执行下列命令之前需要先启动 TPM_Emulator,否则会提示找不到设备。
启动时遇到的错误:
解决方法:
带上 clear 参数重启 tpm-emulator:
再次启动 tcsd 就没有问题了。
7. tpm-tools
7.1. tpm-tools 简介
tpm-tools 是一组管理和利用可信计算组织的 TPM 硬件的工具。 TPM 硬件可以安全地创建,存储和使用 RSA密钥(不会暴露在内存中),使用加密哈希等来验证平台的软件状态。该程序包含的工具允许平台管理员管理和诊断平台的 TPM 硬件。 此外,该程序还包含命令,以利用 openCryptoki 项目中实现的 TPM PKCS#11 接口中提供的某些功能。
7.2. 安装 tpm-tools
8. 测试 TPM 环境是否搭建成功
(1)先启动 tpmd
(2)再启动 tcsd
(3)最后使用 tpm-tools 工具的命令加以验证:
要运行 tpm-tools 工具的命令,必须先启动 tpmd 和 tcsd,缺一不可。
安装TPMManager
其实tpmmanager可装可不装,主要是它提供QT界面可以直观查看和管理TPM而已,比较方便。tpmmanager-0.8安装需要QT支持,需要安装qt4-qmake。但是make过程会出现缺少uic-qt4 command not found,还需要安装libqt4-dev。编译安装过程
也就是说,首先:
sudo apt-get install qt4-qmake
sudo apt-get install libqt4-dev
#cd tpmmanager-0.8 //这个版本是博客里作者的,要看自己下载的是什么版本
#qmake–v #查看qt版本,如果没有,apt-get install qt4-qmake
#qmake
#make
(make的过程提示错误,src/TPMManager.cxx:412:47:error: can not call constructor ‘QUrl::Qurl’ directly[-fpermissive],如果出现了同样的错误,打开这个文件,修改TPMManager.cxx 412行,将
QUrl myURL = QUrl::QUrl(url, QUrl::strictMode)修改为QUrl myURL =QUrl(url, QUrl::strictMode) 源码就可以继续编译)
# install bin/tpmmanager /usr/local/bin
运行tpmmanager
#tpmmanager
提供几个安装的时候参考的网址:
1、http://www.uplook.cn/Linux/8/Linux_85695.html 超级详细很有用
2、http://blog.chinaunix.net/uid-23757972-id-3074677.html 也很详细,只是非ubuntu
3、 vTPM的安装,这个很本文无关,只是在这里记录一下
http://www.etcn.cn/Tech/Os/Linux/2012/1022/43906.html
4、http://blog.chinaunix.net/uid-23757972-id-3242694.html 这个和2是一个作者
5、http://blog.chinaunix.net/uid-20657527-id-1588199.html 这个解决了遇到的问题,就是tpm启动的是要clear一下。tpmd –d –f clear
6、http://blog.csdn.net/cicisensy/article/details/5291569 这个也是安装步骤,参考。不过就介绍了一点,只有TPM模拟器的安装。
9. 运行测试程序
9.1. 在 tpm-emulator-master/tddl/ 目录下有测试程序
gcc -o test_tddl test_tddl.c -ltddl //-ltddl为链接tddl的动态链接库
./test_tddl运行后出现错误
通过cmake ../
cd tddl
make
sudo ./test_tddl解决
9.2. 对TSS协议栈进行测试
9.2.1. 测试程序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <tss/platform.h>
#include <tss/tss_error.h>
#include <tss/tss_defines.h>
#include <tss/tss_structs.h>
#include <tss/tss_typedef.h>
#include <tss/tss_error_basics.h>
#include <tss/tspi.h>
#include <trousers/tss.h>
#include <tss/tpm.h>
const char *get_error(TSS_RESULT res)
{
switch(ERROR_CODE(res))
{
case 0x0001L:
return "Authentication failed";
case TSS_SUCCESS:
return "success";
case TSS_E_INVALID_HANDLE:
return "hContext or phObject is an invalid handle";
case TSS_E_BAD_PARAMETER:
return "persistentstoragetype is not valid/One or more parameters is incorrect";
case TSS_E_INTERNAL_ERROR:
return "an error occurred internal to the TSS";
case TSS_E_PS_KEY_NOTFOUND:
return "NOT FOUND SRK";
case TSS_E_INVALID_ATTRIB_FLAG:
return "attribflag is incorrect";
case TSS_E_INVALID_ATTRIB_SUBFLAG:
return "subflag is incorrect";
case TSS_E_INVALID_ATTRIB_DATA:
return "ulAttrib is incorrect";
case TSS_E_KEY_ALREADY_REGISTERED:
return "UUID used";
case TSS_E_KEY_NOT_LOADED:
return "the addressed key is currently not loaded";
default:
return "unknown error";
}
}
int main(int argc,char *argv)
{
TSS_RESULT result;
TSS_HTPM hTPM;
TSS_HCONTEXT hContext;
TSS_HPOLICY hownerpolicy,hSRKPolicy;
TSS_HKEY hSRK;
TSS_HKEY hkey,hkey2;
TSS_UUID SRK_UUID=TSS_UUID_SRK;
TSS_FLAG initFlags; //密钥标记
TSS_UUID bindkeyUUID=TSS_UUID_USK1; //用户的绑定密钥
printf("创建上下文对象......\n");
result=Tspi_Context_Create(&hContext);
if(result!=TSS_SUCCESS)
{
printf("Context_Create ERROR:%s(%04x)\n",get_error(result),result);
}
result=Tspi_Context_Connect(hContext,NULL);
if(result!=TSS_SUCCESS)
{
printf("Context_Connect ERROR:%s(%04x)\n",get_error(result),result);
}
printf("创建TPM对象......\n");
result=Tspi_Context_GetTpmObject(hContext,&hTPM);
if(result!=TSS_SUCCESS)
{
printf("Tspi_Context_GetTpmObject ERROR:%s(%04x)\n",get_error(result),result);
}
result=Tspi_GetPolicyObject(hTPM,TSS_POLICY_USAGE,&hownerpolicy);
if(result!=TSS_SUCCESS)
{
printf("Tspi_GetPolicyObject ERROR:%s(%04x)\n",get_error(result),result);
}
result=Tspi_Policy_SetSecret(hownerpolicy,TSS_SECRET_MODE_POPUP,0,NULL);
if(result!=TSS_SUCCESS)
{
printf("Tspi_Policy_SetSecret ERROR:%s(%04x)\n",get_error(result),result);
}
printf("载入SRK密钥......\n");
result=Tspi_Context_LoadKeyByUUID(hContext,TSS_PS_TYPE_SYSTEM,SRK_UUID,&hSRK);
if(result!=TSS_SUCCESS)
{
printf("Tspi_Context_LoadKeyByUUID ERROR:%s(%04x)\n",get_error(result),result);
}
printf("获取SRK的策略对象......");
result=Tspi_GetPolicyObject(hSRK,TSS_POLICY_USAGE,&hSRKPolicy);
if(result!=TSS_SUCCESS)
{
printf("Tspi_GetPolicyObject ERROR:%s(%04x)\n",get_error(result),result);
}
printf("设置SRK的策略授权......");
result=Tspi_Policy_SetSecret(hSRKPolicy,TSS_SECRET_MODE_POPUP,0,NULL);
if(result!=TSS_SUCCESS)
{
printf("Tspi_Policy_SetSecret ERROR:%s(%04x)\n",get_error(result),result);
}
printf("创建绑定密钥......\n");
initFlags=TSS_KEY_TYPE_BIND|TSS_KEY_SIZE_512|TSS_KEY_NO_AUTHORIZATION; //设置密钥标记
result=Tspi_Context_CreateObject(hContext,TSS_OBJECT_TYPE_RSAKEY,initFlags,&hkey); //创建绑定密钥
if(result!=TSS_SUCCESS)
{
printf("Tspi_Context_CreateObject ERROR:%s(%04x)\n",get_error(result),result);
}
printf("在TPM产生密钥前,设置填充类型......\n");
result=Tspi_SetAttribUint32(hkey,TSS_TSPATTRIB_KEY_INFO,TSS_TSPATTRIB_KEYINFO_ENCSCHEME,TSS_ES_RSAESPKCSV15);
if(result!=TSS_SUCCESS)
{
printf("Tspi_SetAttribUint32 ERROR:%s(%04x)\n",get_error(result),result);
}
printf("产生密钥,该密钥不合PCR绑定\n");
result=Tspi_Key_CreateKey(hkey,hSRK,0);
if(result!=TSS_SUCCESS)
{
printf("Tspi_Key_CreateKey ERROR:%s(%04x)\n",get_error(result),result);
}
printf("装载绑定密钥到UUID......\n");
result=Tspi_Context_RegisterKey(hContext,hkey,TSS_PS_TYPE_USER,bindkeyUUID,TSS_PS_TYPE_SYSTEM,SRK_UUID);
if(result!=TSS_SUCCESS)
{
if(ERROR_CODE(result)==TSS_E_KEY_ALREADY_REGISTERED)
{
printf("UUID已被使用,注销此密钥......\n");
result=Tspi_Context_UnregisterKey(hContext,TSS_PS_TYPE_USER,bindkeyUUID,&hkey);
if(result!=TSS_SUCCESS)
printf("UUID注销失败 Tspi_Context_UnregisterKey ERROR :%s(%04x)\n",get_error(result),result);
result=Tspi_Context_RegisterKey(hContext,hkey,TSS_PS_TYPE_USER,bindkeyUUID,TSS_PS_TYPE_SYSTEM,SRK_UUID);
if(result!=TSS_SUCCESS)
printf("Tspi_Context_RegisterKey ERROR:%s(%04x)\n",get_error(result),result);
}
}
printf("SUCCESS!\n");
Tspi_Context_Close(hContext);
return 0;
}
9.2.2. 该程序实现的操作
创建上下文对象…
创建TPM对象…
载入SRK密钥…
获取SRK的策略对象…
设置SRK的策略授权…
创建绑定密钥…
装载绑定密钥到UUID…
9.2.3. 编译和执行
Tips:
要先启动 tpmd 和 tcsd 进程,再运行测试程序的可执行文件。
遇到如下的错误:
Tspi_Key_CreateKey ERROR:persistentstoragetype is not valid/One or more parameters is incorrect(0003)
PS:解决后再更新???
————————————————
版权声明:本文为CSDN博主「l龙猫先生l」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/CSDN_FengXingwei/article/details/89342797