搭建cube-TCM
本地环境
新建一个项目根目录,我的项目根目录为/opt/build_vtcm/vtcm。
先把cube-1.3、cube-tcm和gm_sm2_master克隆到项目根目录
1 | git clone https://gitee.com/biparadox/cube-1.3.git |
根据《tcm工程初步》中所说,cube-tcm 的环境变量设置方法必须在cube-1.3的环境变量设置完成后进行, 设置方法类似,脚本执行后,会修改CUBEAPPPATH和CUBE_APP_PLUGIN 到vtcm-1.12工作目录。编译前需完成国密算法库文件的复制和环境变量的设置。
国密算法包编译
进入gm_sm2目录后,执行命令。
1 | cd gm_sm2 |
观察gm_sm2/bin目录,应可看到编译完成的动态库libsm2So.so。此时国密算法包即编译完成。
下面将该库复制到cube-tcm的本地库目录cube-tcm/locallib/目录下。 cube-tcm 内部模块将会调用该库执行国密算法计算。
1 | cp ./bin/libsm2So.so ../cube-tcm/locallib/ |
cube-1.3环境变量设置
进入cube-1.3目录,并且完成编译环境配置
修改set_env.sh
1 | cd ../cube-1.3 |
将此处修改为你cube-1.3所在路径,比如我的是/opt/build_vtcm/vtcm/cube-1.3
,注意需要去掉`号!!!!
1 | 编译环境设置 |
编译爆警告是正常现象,没有报错就行。
完成编译后,如果以root权限登录,则可以直接运行cube实例;如果是以非root权限登录,应预先执行sudo dmidecode | grep UUID命令,获得uuid值,或自行为机器设置一个32字节的uuid值(可用随机数生成),而后在cube-1.3的proc/plugin目录下编辑一个名为uuid的文件,将UUID值填充到文件中,此时非root用户即可执行cube架构。
cube-tcm环境变量设置
进入cube-tcm目录下,修改set_env.sh。
1 | cd ../cube-tcm |
同样的
1 | 编译环境设置 |
如果sh env_build.sh
没有报错,那么模拟器编译成功,否则需要检查一下环境变量设置和算法库位置。
设置.bashrc文件
由于每次启动都得输入source /opt/vtcm/cube-1.3/set_env.sh
和source /opt/vtcm/cube-tcm/set_env.sh
,非常繁琐。所以我们把上面的命令写入.bashrc文件中,方便每次都自动完成设置。
1 | vi /root/.bashrc |
进入.bashrc在最后一行添加
1 | source /opt/vtcm/cube-1.3/set_env.sh |
cube-tcm编译
安装tcm驱动并部署设备
我们在系统中启动两个终端term1和term2,确认两个终端均已完成环境变量配置。接下来在term1中打开驱动所在目录并执行make。
1 | cd ./vtcm/cube-tcm/vtcm_dev |
执行完毕后可以查看一下/dev中是否已经成功安装tcm设备和vtcm设备。
1 | ls /dev/*tcm* |
完成后打开模拟器
1 | cd ../vtcm_netlink_emulator |
现在我们再转到term2。在term2的项目根目录中进入vtcm_utils目录。
1 | cd ./vtcm/cube-tcm/vtcm_utils |
该目录下是可信根应用实例的运行环境vtcm_utils。一个可信根需要通过与应用层的一个实例间的交互过程,来执行可信根的功能。
此时在vtcm_utils目录下执行(此处先不要运行)
1 | ./main_proc |
即可与vtcm_emulator 互联。
TCM服务功能与操作实例
初始化
vtcm_utils缺省设为脚本操作,目录下有多个自动化脚本。我们这里使用交互模式来操作。
1 | grep vtcm_auto * |
将查找到的所有地方替换为vtcm_input,即可转入互动操作模式,如需换回脚本操作模式,则只要再用vtcm_auto替换掉vtcm_input即可。
此时直接执行
1 | ./main_proc |
程序将进入等待命令状态。
生成背书密钥
cube-TCM里设置了一条背书密钥命令createek, 命令格式为:
1 | createek –wf ekpub.key |
这里可信根命令的每个参数都由一个-
打头的前缀来确定其类型。createek命令创建密钥后,会将密钥导出到ekpub.key文件中,在term2则可看到芯片输入输 出的二进制信息:
-
输入信息是vtcm_utils根据芯片接口要求生成的数据包,如下所示:
-
输出信息则为vtcm_emulator收到数据包后,按照tcm标准运行后,返回的数据,如下所示:
下面执行readpubek指令,该指令无输入参数
1 | readpubek |
该命令从vtcm_emulater中获取可信根公钥,并在vtcm_utils内存中存放。
下一条指令是apcreate,这条指令用来创建应用和模拟器中对象的会话。初始化过程中,模拟器内部并没有合适的对象,因此apcreate命令将创建一个叫做 ET_NONE类型(编号为0x12)的会话,这一会话专用于初始化过程。 此时apcreate命令格式为
1 | apcreate –it 12 |
输出命令格式为
此时vtcm_utils 和 vtcm_emulator 之间已经建立了一个会话。
下面是初始化过程中最关键的一个命令takeownership,该命令完成可信根属主口令的生成、可信根存储密钥以及根存储密钥口令的生成。属主口令用来获取可信根中属主的权限,可以进行用户鉴别密钥生成等操作。
命令的输入参数应包括属主口令、根存储密钥口令,也就是要自己设两个口令。
输入格式为:takeownership -pwdo 用户口令 – pwds smk口令
1 | takeownership -pwdo 123456 –pwds 123 |
在term1中可看到成功拿到句柄
takeownership 命令执行成功后,将在TCM中创建存储根密钥smk,其实 体类型值为04。我们可以通过用apcreate命令创建vtcm_utils和smk的会话 来验证takeownership 是否成功。测试命令为apcreate -it 04 -pwd smk口令
1 | apcreate -it 04 -pwd 123 |
下面为测试命令的输出内容,我们可以看到两个返回值,第一个是命令返回码,其取值为0,表示执行正确,第二个则是apcreate命令与smk之间建立可信会话连接的会话句柄。这表示takeownership命令执行正确。
而如果我们输入错误的smk口令或者省略了-pwd选项,则我们应该在命令最 后得到下面的结果:
初始化自动化脚本
下面附上我自己写的脚本(注意,我是在Windows上写的,Linux识别Windows的换行符会识别成字符,请先测试一下再实际使用)
在项目根目录下创建四个shell文件:
-
build_vctm.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24!/bin/bash
mkdir vtcm
cd vtcm
git clone https://gitee.com/biparadox/cube-1.3.git
git clone https://gitee.com/biparadox/cube-tcm.git
git clone https://github.com/TCLab-BJUT/gm_sm2.git
cd gm_sm2
make
cp ./bin/libsm2So.so ../cube-tcm/locallib
cd ../cube-1.3
sed -i "s|export CUBEAPPPATH=\`pwd\`|export CUBEAPPPATH=/opt/cube-1.3|" set_env.sh#把这里的/opt/cube-1.3改成自己cube-1.3的地址
source set_env.sh
sh env_build.sh
cd ../cube-tcm
sed -i "s|export CUBEAPPPATH=\`pwd\`|export CUBEAPPPATH=/opt/build_vtcm/vtcm/cube-tcm|" set_env.sh#把这里的/opt/cube-1.3改成自己cube-tcm的地址
source set_env.sh
sh env_build.sh
cd vtcm_dev
make -
set_env.sh
1
2
3
4
5
6
7
8!/bin/bash
current_path=/opt/build_vtcm#这里改成自己的根目录所在地址
cd ./vtcm/cube-1.3
source set_env.sh
cd ../cube-tcm
source set_env.sh
cd $current_path -
run_vtcm_netlink_emulator.sh
1
2
3
4
5!/bin/bash
sudo ./load_vtcmd_dev.sh
cd ../vtcm_netlink_emulator
./main_proc -
test_pcrread.sh
1
2
3
4!/bin/bash
cd ./vtcm/cube-tcm/vtcm_utils
./main_proc ./pcr/pcrread.cmd
在term1中执行
1 | source build_vctm.sh |
在term2中执行
1 | source set_env.sh |
加密、解密、签名、验证
密钥创建
下面首先执行创建密钥操作。TCM中,密钥创建可以选择基于SM2算法的非对称钥和基于SM4算法的对称钥。密钥创建命令为createwrapkey。tcm_utils 接受的密钥创建命令其格式如下:
createwrapkey -ikh 封装密钥句柄 –ish 封装密钥会话句柄 -is (sm2|sm4) -kf 密钥文件名称 -pwdk 密钥授权口令 [–pwdm 密钥移植口令]
下面我们写一个密钥创建脚本程序createkey.cmd,该程序以SMK为封装密钥创建一个非对称密钥和一个对称密钥,密钥口令分别为sm2和sm4,并分别存储在文件sm2.key和文件sm4.key中,脚本如下:
我们可以输入以下命令,来创建对称密钥和非对称密钥。
1 | in: apcreate -it 04 -pwd sss |
当然也可以手动输入,由于前文我已经获取到了句柄,为b90e432,所以我直接使用该句柄就行。
1 | createwrapkey -ikh 40000000 -ish b90e432 -is sm2 -kf sm2.key -pwdk sm2 |
创建成功后可以看到文件夹下多了sm2和sm4的密钥文件
加密解密
非对称密钥加密解密:
1 | in: sm2encrypt -kf sm2.key -rf sm2test.dat -wf sm2crypt.dat |
创建一个数据文件sm2test.dat,此处我写入数据vTCM_is_good:
输入命令
1 | sm2encrypt -kf sm2.key -rf sm2test.dat -wf sm2crypt.dat |
使用smk句柄(b90e432)输入命令
1 | loadkey -ih b90e432 -kf sm2.key |
此时会返回sm2密钥的句柄80bd5ebe,之后请自行替换有关80bd5ebe的地方。
使用密钥句柄,获取密钥授权句柄
1 | apcreate -it 01 -iv 80bd5ebe -pwd sm2 |
此处我的句柄为79d4a365,之后请自行替换有关79d4a365的地方。
1 | sm2decrypt -ik 80bd5ebe -is 79d4a365 -rf sm2crypt.dat -wf sm2decrypt.dat |
打开sm2decrypt.dat文件,发现解密成功:
对称密钥加解密脚本:
1 | in: apcreate -it 04 -pwd sss |
接下来一步步来看对应的结果,首先smk句柄我们已经获取到了,那么直接获取密钥句柄
1 | loadkey -ih b90e432 -kf sm4.key |
我的密钥句柄为7fee8800,请读者自行在对应的地方替换成自己的句柄。
1 | apterminate -ih b90e432 |
此时返回密钥授权句柄,为4f5e17bf。
到这一步我们先在./vtcm_utils文件夹下建立sm4test.dat文件,并写入数据。
使用sm4进行加密
1 | sm4encrypt -ikh 7fee8800 -idh 4f5e17bf -rf sm4test.dat -wf sm4crypt.dat |
接下来进行解密:
1 | sm4decrypt -ikh 7fee8800 -idh 4f5e17bf -rf sm4crypt.dat -wf sm4decrypt.dat |
解密成功: