远程证明

TEE套件完成了rats-tls的适配,本章节主要介绍如何实现基于rats-tls的远程证明。

获取基线度量值

环境准备安装virtCCA_sdk时,会主动安装gen_rim_ref二进制工具。

  1. 生成dtb设备树二进制文件。

    1. 编辑cVM的xml配置,增加如下透传QEMU参数。
      <qemu:arg value='-machine'/>
      <qemu:arg value='dumpdtb=/path/to/dump.dtb'/>

      其中dumpdtb为指定的dtb生成路径。

    2. 启动cVM虚拟机,将在指定路径下生成dtb文件。
      virsh define <cvm.xml>
      virsh start <cvm>

    3. 编辑cVM虚拟机xml配置,删除增加的QEMU透传参数。

  2. 基于gen_rim_ref获取cVM基线度量值。根据启动方式的不同执行对应的命令行。

    • Kernel直接启动:在虚拟机中通过配置Kernel镜像和initramfs启动的方式。
      gen_rim_ref -k <kernel_path> -d <dtb_path> [-i <initramfs_path>] -v <vcpu_num> 
    • grub启动:通过配置UEFI路径和qcow2镜像启动的方式。
      gen_rim_ref -f <firmware_path> -d <dtb_path> -v <vcpu_num>

    其中:

    • kernel_path:为cVM虚拟机使用的guest的Kernel文件路径。
    • dtb_path:为cVM的设备树二进制文件。
    • 可选:initramfs_path:为初始ram文件系统路径。需在使用initramfs时添加。
    • vcpu_nums:为cVM虚拟机配置虚拟CPU个数。
    • firmware_path:为cVM配置的UEFI固件路径。

    默认使用的hash算法为sha256,若需要使用sha512,可修改gen_rim_ref源码中的hash_algo为1。gen_rim_ref源码位于“virtCCA_sdk/attestation/rim_ref/”下。

Demo演示

  1. 请参见编译远程证明Demo完成演示Demo的编译。
  2. 请参见启动虚机完成机密虚拟机的启动,并将server部署到虚拟机任意目录下。
  3. 在虚拟机内启动server。

    ./server -i <ip> -p <port> 

    其中:

    • 可选:ip:服务端配置的IP地址。默认为本地回环。
    • 可选:port:服务端配置的端口。默认为7220。

  4. client发起远程证明请求。

    ./client -i <ip> -p <port> -m <measurement>

    其中:

    • 可选:ip:要连接的服务端IP地址。默认为本地回环。
    • 可选:port:要连接的服务端端口。默认为7220。
    • measurement:cVM虚拟机的基线度量值。请参见获取基线度量值

rats-tls演示

TEE套件完成了rats-tls的适配,请参见如下步骤实现基于rats-tls的远程证明。

  1. 请参见编译rats-tls样例完成rats-tls库和样例demo编译。
  2. 远程证明服务端部署。将编译好的rats-tls.tar.gz拷贝到cVM内,解压后拷贝到系统目录。

    tar xvf rats-tls.tar.gz
    cp -rf lib/rats-tls /usr/lib/
    cp -rfL lib/rats-tls/librats_tls.so.0 /lib64/

  3. 启动rats-tls的服务端Demo。

    ./virtcca-server

    可选参数同rats-tls原始提供的样例,可执行以下命令查看。

    ./virtcca-server -h

  4. 请参见2在证明客户端完成rats-tls库的部署,并启动rats-tls的客户端Demo。

    ./virtcca-client -i <ip> -r <measurement> -d <ima_hash_path>

    其中:

    • 可选:ip:服务端的IP地址,默认为本地回环。
    • measurement:cVM的基线度量,请参见获取基线度量值
    • 可选:ima_hash_path:需要使能IMA度量时指定。

    • 若需要将IMA度量纳入验证,需在客户端通过-d参数指定hash文件路径,该文件包括所有纳入IMA度量的文件的hash值,每行对应一个文件的hash值,此外还需增加虚拟机的基线度量值。若不指定-d参数,则默认不校验IMA度量。

      文件的hash值计算方法应与虚拟机内IMA度量的算法保持一致,如sha256可使用如下方法计算。

      sha256sum path/to/file

      IMA策略配置可参考可信计算

    • 可选参数同rats-tls原始提供的样例,可执行以下命令查看。
      ./virtcca-server -h

    • 若使用双向认证时(添加-m时),由于机密虚拟机里的服务器使用的verify实例默认为virtCCA,只能验证virtCCA格式的度量报告。此时客户端需要运行在机密虚拟机内,或通过-v指定server使用的verify实例,例如,若客户端无度量,可指定-v nullverifier。

启动时度量

TEE套件基于initramfs提供启动时度量的能力,请参见如下步骤实现启动时度量。

  1. 请参见编译initramfs完成initramfs的构建。
  2. 在cVM虚拟机xml配置中增加initrd属性。(需要使用gen_rim_ref重新计算RIM度量值)

    <initrd>/path/to/rootfs.cpio.gz</initrd>

    “/path/to/rootfs.cpio.gz”替换为实际绝对路径。

  3. 启动机密虚拟机。

    virsh start <cvm>

    虚拟机启动将卡在virtcca-server,等待client发起远程证明请求。initramfs会主动获取可用IP。

  4. 启动客户端,发起远程证明和校验。

    ./virtcca-client -i <ip> -r <measurement> -d <ima_hash_path>

    • 客户端获取度量报告后,并验证通过后,虚拟机将切换到rootfs,并完成虚拟机启动。如果验证不通过,虚拟机将一直卡死直到客户端校验成功。
    • 使用gen_rim_ref生成基线度量值时,需要传入initramfs的路径,否则将导致度量报告验证不通过。

cVM启动

  1. 修改XML文件,通过QEMU加载构建的initramfs和加密的rootfs,需使用重新编译后的Guest_kernel

    <os>
    <type arch='aarch64' machine='virt'>hvm</type>
    <kernel>path/guest_kernel</kernel>
    <initrd>/path/rootfs_with_encryptluks.cpio.gz</initrd>
    <cmdline>swiotlb=262144,force console=tty0 console=ttyAMA0 kaslr.disabled=1 root=/dev/vda rw  rodata=off cma=64M cvm_guest=1</cmdline>
    </os>
    <disk type='file' device='disk' model='virtio-non-transitional'>
    <driver name='qemu' type='raw' queues='4' cache='none' iommu='on'/>
    <source file='/path/encrypt.img'/>
    <target dev='vda' bus='virtio'/>
    </disk>

  2. 远程证明client客户端验证完成解密磁盘。

    1. 加入-k输入解密磁盘密钥文件路径。
      ./virtcca-client -i [ip] -r [rim] -k [rootfs_key]

    2. 在client端验证通过。

      在完成cVM远程证明、建立安全信道之后,用户输入解密密钥,server端进行后续的解密和挂载rootfs启动流程。

      编译Guest_kernel时需打开以下.config文件中选项启用磁盘加密,否则会报未知类型等异常,具体请参见2.2.1编译Guest Kernel和rootfs

      CONFIG_CRYPTO_SM3=y
      CONFIG_CRYPTO_SM3_GENERIC=y
      CONFIG_CRYPTO_SM4=y
      CONFIG_CRYPTO_SM4_GENERIC=y
      CONFIG_CRYPTO_XTS=y
      CONFIG_BLK_DEV_DM=y
      CONFIG_DM_CRYPT=y

      在提示 DM "dm-mod.create=" parameter support (DM_INIT) [N/y/?] (NEW) 时输入“y”后可继续执行。

额外数据盘的加密

  1. 在机密虚机XML文件中额外定义一块vdb磁盘。(使用DD命令创建的空磁盘)

    <disk type='file' device='disk' model='virtio-non-transitional'>
    <driver name='qemu' type='raw' queues='4' cache='none' iommu='on'/>
    <source file='/path/encrypt_empty.img'/>
    <target dev='vdb' bus='virtio'/>
    </disk>

  2. 进入虚机后使用cryptsetup工具加密vdb,方法请参见#ZH-CN_TOPIC_0000002187807873/section558211131209模块中的“落盘加密”流程。

    cryptsetup luksFormat /dev/vdb -c sm4-xts-plain64 --key-size 256 --hash sm3

  3. 使用cryptsetup luksOPen打开(解密)LUKS设备。

    cryptsetup luksOpen /dev/vdb encryptfs_sm4

  4. 格式化加密磁盘。

    mkfs.ext4 /dev/mapper/encryptfs_sm4

  5. 创建挂载点并挂载到指定目录。

    mkdir -p /encryptmnt
    mount /dev/mapper/encryptfs_sm4 /encryptmnt/

    虚机重启后需要再次使用cryptsetup luksOPen打开(解密)LUKS设备后,挂载到指定目录。