本地环境

新建一个项目根目录,我的项目根目录为/opt/build_vtcm/vtcm。

先把cube-1.3、cube-tcm和gm_sm2_master克隆到项目根目录

1
2
3
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

根据《tcm工程初步》中所说,cube-tcm 的环境变量设置方法必须在cube-1.3的环境变量设置完成后进行, 设置方法类似,脚本执行后,会修改CUBEAPPPATH和CUBE_APP_PLUGIN 到vtcm-1.12工作目录。编译前需完成国密算法库文件的复制和环境变量的设置。

国密算法包编译

进入gm_sm2目录后,执行命令。

1
2
cd gm_sm2
make

观察gm_sm2/bin目录,应可看到编译完成的动态库libsm2So.so。此时国密算法包即编译完成。

image-20241205142843996

下面将该库复制到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
2
cd ../cube-1.3
vi set_env.sh

image-20241205103400314

将此处修改为你cube-1.3所在路径,比如我的是/opt/build_vtcm/vtcm/cube-1.3注意需要去掉`号!!!!

1
2
3
4
#编译环境设置
source set_env.sh
#cube架构的编译
sh env_build.sh

编译爆警告是正常现象,没有报错就行。

完成编译后,如果以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
2
cd ../cube-tcm
vi set_env.sh

image-20241205111312409

同样的

1
2
3
4
#编译环境设置
source set_env.sh
#cube架构的编译
sh env_build.sh

image-20241205111507541

如果sh env_build.sh没有报错,那么模拟器编译成功,否则需要检查一下环境变量设置和算法库位置。

设置.bashrc文件

由于每次启动都得输入source /opt/vtcm/cube-1.3/set_env.shsource /opt/vtcm/cube-tcm/set_env.sh,非常繁琐。所以我们把上面的命令写入.bashrc文件中,方便每次都自动完成设置。

1
vi /root/.bashrc

进入.bashrc在最后一行添加

1
2
source /opt/vtcm/cube-1.3/set_env.sh
source /opt/vtcm/cube-tcm/set_env.sh

image-20241205112905991

cube-tcm编译

安装tcm驱动并部署设备

我们在系统中启动两个终端term1和term2,确认两个终端均已完成环境变量配置。接下来在term1中打开驱动所在目录并执行make。

1
2
3
cd ./vtcm/cube-tcm/vtcm_dev
make
sudo ./load_vtcmd_dev.sh

执行完毕后可以查看一下/dev中是否已经成功安装tcm设备和vtcm设备。

1
ls /dev/*tcm*

image-20241206172025753

完成后打开模拟器

1
2
cd ../vtcm_netlink_emulator
./main_proc

image-20241206172054961

现在我们再转到term2。在term2的项目根目录中进入vtcm_utils目录。

1
cd ./vtcm/cube-tcm/vtcm_utils

该目录下是可信根应用实例的运行环境vtcm_utils。一个可信根需要通过与应用层的一个实例间的交互过程,来执行可信根的功能。

此时在vtcm_utils目录下执行(此处先不要运行)

1
./main_proc

即可与vtcm_emulator 互联。

TCM服务功能与操作实例

初始化

vtcm_utils缺省设为脚本操作,目录下有多个自动化脚本。我们这里使用交互模式来操作。

1
2
3
grep vtcm_auto *
sed -i "s|vtcm_auto|vtcm_input|" plugin_config.cfg
sed -i "s|vtcm_auto|vtcm_input|" router_policy.cfg

将查找到的所有地方替换为vtcm_input,即可转入互动操作模式,如需换回脚本操作模式,则只要再用vtcm_auto替换掉vtcm_input即可。

image-20241205160235129

此时直接执行

1
./main_proc

程序将进入等待命令状态。

image-20241205160343093

生成背书密钥

cube-TCM里设置了一条背书密钥命令createek, 命令格式为:

1
createek –wf ekpub.key

这里可信根命令的每个参数都由一个-打头的前缀来确定其类型。createek命令创建密钥后,会将密钥导出到ekpub.key文件中,在term2则可看到芯片输入输 出的二进制信息:

  • 输入信息是vtcm_utils根据芯片接口要求生成的数据包,如下所示:

    image-20241206172300574

    image-20241206161832580

  • 输出信息则为vtcm_emulator收到数据包后,按照tcm标准运行后,返回的数据,如下所示:

    image-20241206161913238

    image-20241206161926197

下面执行readpubek指令,该指令无输入参数

1
readpubek

该命令从vtcm_emulater中获取可信根公钥,并在vtcm_utils内存中存放。

image-20241206172844362

下一条指令是apcreate,这条指令用来创建应用和模拟器中对象的会话。初始化过程中,模拟器内部并没有合适的对象,因此apcreate命令将创建一个叫做 ET_NONE类型(编号为0x12)的会话,这一会话专用于初始化过程。 此时apcreate命令格式为

1
apcreate –it 12

image-20241206210850769

输出命令格式为

image-20241206210910901

此时vtcm_utils 和 vtcm_emulator 之间已经建立了一个会话。

下面是初始化过程中最关键的一个命令takeownership,该命令完成可信根属主口令的生成、可信根存储密钥以及根存储密钥口令的生成。属主口令用来获取可信根中属主的权限,可以进行用户鉴别密钥生成等操作。

命令的输入参数应包括属主口令、根存储密钥口令,也就是要自己设两个口令。

输入格式为:takeownership -pwdo 用户口令 – pwds smk口令

1
takeownership -pwdo 123456 –pwds 123

image-20241207152810390

在term1中可看到成功拿到句柄

image-20241207152852669

takeownership 命令执行成功后,将在TCM中创建存储根密钥smk,其实 体类型值为04。我们可以通过用apcreate命令创建vtcm_utils和smk的会话 来验证takeownership 是否成功。测试命令为apcreate -it 04 -pwd smk口令

1
apcreate -it 04 -pwd 123

下面为测试命令的输出内容,我们可以看到两个返回值,第一个是命令返回码,其取值为0,表示执行正确,第二个则是apcreate命令与smk之间建立可信会话连接的会话句柄。这表示takeownership命令执行正确。

image-20241207153121633

而如果我们输入错误的smk口令或者省略了-pwd选项,则我们应该在命令最 后得到下面的结果:

image-20241207153215303

初始化自动化脚本

下面附上我自己写的脚本(注意,我是在Windows上写的,Linux识别Windows的换行符会识别成字符,请先测试一下再实际使用

在项目根目录下创建四个shell文件:

  1. 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
  2. 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
  3. run_vtcm_netlink_emulator.sh

    1
    2
    3
    4
    5
    #!/bin/bash

    sudo ./load_vtcmd_dev.sh
    cd ../vtcm_netlink_emulator
    ./main_proc
  4. test_pcrread.sh

    1
    2
    3
    4
    #!/bin/bash

    cd ./vtcm/cube-tcm/vtcm_utils
    ./main_proc ./pcr/pcrread.cmd

在term1中执行

1
2
source build_vctm.sh
sh run_vtcm_netlink_emulator.sh

在term2中执行

1
2
source set_env.sh
sh test_pcrread.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
2
3
4
5
in: apcreate -it 04 -pwd sss
out: 1:$smkHandle
in: createwrapkey -ikh 40000000 -ish $smkHandle -is sm2 -kf sm2.key -pwdk sm2
in: createwrapkey -ikh 40000000 -ish $smkHandle -is sm4 -kf sm4.key -pwdk sm4
in: apterminate -ih $smkHandle

当然也可以手动输入,由于前文我已经获取到了句柄,为b90e432,所以我直接使用该句柄就行。

1
2
createwrapkey -ikh 40000000 -ish b90e432 -is sm2 -kf sm2.key -pwdk sm2
createwrapkey -ikh 40000000 -ish b90e432 -is sm4 -kf sm4.key -pwdk sm4

创建成功后可以看到文件夹下多了sm2和sm4的密钥文件

image-20241207161731111

加密解密

非对称密钥加密解密:

1
2
3
4
5
6
7
8
9
10
11
in: sm2encrypt -kf sm2.key -rf sm2test.dat -wf sm2crypt.dat
in: apcreate -it 04 -pwd sss
out: 1:$smkHandle
in: loadkey -ih $smkHandle -kf sm2.key
out: 1:$keyHandle
in: apterminate -ih $smkHandle
in: apcreate -it 01 -iv $keyHandle -pwd sm2
out: 1:$keyAuthHandle
in: sm2decrypt -ik $keyHandle -is $keyAuthHandle -rf sm2crypt.dat -wf
sm2decrypt.dat
in: apterminate -ih $keyAuthHandle

创建一个数据文件sm2test.dat,此处我写入数据vTCM_is_good:

image-20241207162537053

输入命令

1
sm2encrypt -kf sm2.key -rf sm2test.dat -wf sm2crypt.dat

image-20241207162709694

使用smk句柄(b90e432)输入命令

1
loadkey -ih b90e432 -kf sm2.key 

此时会返回sm2密钥的句柄80bd5ebe,之后请自行替换有关80bd5ebe的地方。

image-20241207163509456

使用密钥句柄,获取密钥授权句柄

1
apcreate -it 01 -iv 80bd5ebe -pwd sm2

image-20241207163856377

此处我的句柄为79d4a365,之后请自行替换有关79d4a365的地方。

1
sm2decrypt -ik 80bd5ebe -is 79d4a365 -rf sm2crypt.dat  -wf sm2decrypt.dat

打开sm2decrypt.dat文件,发现解密成功:

image-20241207165332904

对称密钥加解密脚本:

1
2
3
4
5
6
7
8
9
10
in: apcreate -it 04 -pwd sss
out: 1:$smkHandle
in: loadkey -ih $smkHandle -kf sm4.key
out: 1:$keyHandle
in: apterminate -ih $smkHandle
in: apcreate -it 01 -iv $keyHandle -pwd sm4
out: 1:$keyAuthHandle
in: sm4encrypt -ikh $keyHandle -idh $keyAuthHandle -rf sm4test.dat -wf sm4crypt.dat
in: sm4decrypt -ikh $keyHandle -idh $keyAuthHandle -rf sm4crypt.dat -wf sm4decrypt.dat
in: apterminate -ih $keyAuthHandle

接下来一步步来看对应的结果,首先smk句柄我们已经获取到了,那么直接获取密钥句柄

1
loadkey -ih b90e432 -kf sm4.key

image-20241207170828244

我的密钥句柄为7fee8800,请读者自行在对应的地方替换成自己的句柄。

1
2
apterminate -ih b90e432
apcreate -it 01 -iv 7fee8800 -pwd sm4

此时返回密钥授权句柄,为4f5e17bf。

image-20241207171131431

到这一步我们先在./vtcm_utils文件夹下建立sm4test.dat文件,并写入数据。

image-20241207171505646

使用sm4进行加密

1
sm4encrypt -ikh 7fee8800 -idh 4f5e17bf -rf sm4test.dat -wf sm4crypt.dat

image-20241207171559386

image-20241207171543801

接下来进行解密:

1
sm4decrypt -ikh 7fee8800 -idh 4f5e17bf -rf sm4crypt.dat -wf sm4decrypt.dat

解密成功:

image-20241207171910659

image-20241207171926293

PIK申请过程