-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This change adds tests for vtpm functionalities. The tests require XCP-ng 8.3 and a Debian UEFI VM. The first test creates and destroys a vtpm device. A second test does basic TPM tests (like message signing) using tpm2-tools. The second test uses a locally defined fixture called unix_vm_with_vtpm requiring an halted UEFI Unix VM. The fixture creates a vtpm device associated to the vm. The vtpm device is destroyed once the tests are done. The fixture also does a snapshot of the VM and revert it afterward. This is because the script needs the package tpm2-tools to be installed. Signed-off-by: Thierry Escande <[email protected]>
- Loading branch information
Showing
3 changed files
with
135 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import pytest | ||
|
||
@pytest.fixture(scope='module') | ||
def uefi_unix_halted_vm(uefi_vm, unix_vm, halted_vm): | ||
yield uefi_vm | ||
|
||
@pytest.fixture(scope='module') | ||
def unix_vm_with_vtpm(uefi_unix_halted_vm): | ||
vm = uefi_unix_halted_vm | ||
vtpm_uuid = None | ||
|
||
if vm.get_vtpm() is None: | ||
vtpm_uuid = vm.create_vtpm() | ||
|
||
snapshot = vm.snapshot() | ||
|
||
vm.start() | ||
|
||
yield vm | ||
|
||
# Tear down | ||
if not vm.is_halted(): | ||
vm.shutdown(verify=True) | ||
|
||
snapshot.destroy() | ||
|
||
if vtpm_uuid is not None: | ||
vm.destroy_vtpm() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
import logging | ||
import pytest | ||
import lib.commands as commands | ||
|
||
# These test are basic tests for vTPM devices. | ||
# - Create / Destroy a vTPM device against a VM | ||
# - Do some basic encryption tests using tpm2-tools package | ||
# | ||
# Requirements: | ||
# - an XCP-ng host >= 8.3 | ||
# - a Debian based VM | ||
|
||
from lib.common import PackageManagerEnum | ||
|
||
vtpm_signing_test_script = """#!/bin/env bash | ||
set -ex | ||
apt-get install -y tpm2-tools > /dev/null | ||
tpm2_selftest --fulltest | ||
tpm2_getrandom 32 > /dev/null | ||
TMPDIR=`mktemp -d` | ||
# Create an Endorsement primary key | ||
tpm2_createprimary --hierarchy e --key-context ${TMPDIR}/primary.ctx > /dev/null | ||
# Create key objects | ||
tpm2_create --key-algorithm rsa --public ${TMPDIR}/rsa.pub --private ${TMPDIR}/rsa.priv --parent-context \ | ||
${TMPDIR}/primary.ctx > /dev/null | ||
# Load keys into the TPM | ||
tpm2_load --parent-context ${TMPDIR}/primary.ctx --public ${TMPDIR}/rsa.pub --private ${TMPDIR}/rsa.priv \ | ||
--key-context ${TMPDIR}/rsa.ctx > /dev/null | ||
# Delete loaded key files | ||
rm -f ${TMPDIR}/rsa.pub ${TMPDIR}/rsa.priv | ||
# Message to sign | ||
echo 'XCP-ng Rulez' > ${TMPDIR}/message.dat | ||
# Sign the message | ||
tpm2_sign --key-context ${TMPDIR}/rsa.ctx --hash-algorithm sha256 --signature ${TMPDIR}/sig.rssa \ | ||
${TMPDIR}/message.dat > /dev/null | ||
# Verify signature | ||
tpm2_verifysignature --key-context ${TMPDIR}/rsa.ctx --hash-algorithm sha256 --message ${TMPDIR}/message.dat \ | ||
--signature ${TMPDIR}/sig.rssa > /dev/null | ||
# Verify with another message | ||
echo "XCP-ng Still Rulez" > ${TMPDIR}/message.dat | ||
# Verify signature !!!!! THIS MUST FAIL !!!!! | ||
if tpm2_verifysignature --key-context ${TMPDIR}/rsa.ctx --hash-algorithm sha256 --message ${TMPDIR}/message.dat \ | ||
--signature ${TMPDIR}/sig.rssa > /dev/null 2>&1; then | ||
echo "Should not succeed" | ||
exit 1 | ||
fi | ||
rm -rf ${TMPDIR} | ||
""" | ||
|
||
@pytest.mark.small_vm | ||
@pytest.mark.usefixtures("host_at_least_8_3") | ||
def test_create_and_destroy_vtpm(host, uefi_unix_halted_vm): | ||
vm = uefi_unix_halted_vm | ||
|
||
vtpm_uuid = vm.get_vtpm() | ||
if vtpm_uuid is not None: | ||
logging.warning("This vm is already associated with a vtpm. Destroying it first") | ||
vm.destroy_vtpm() | ||
|
||
vtpm_uuid = vm.create_vtpm() | ||
|
||
assert(vtpm_uuid is not None) | ||
|
||
logging.info("vtpm created with uuid: %s" % vtpm_uuid) | ||
|
||
vm.destroy_vtpm() | ||
|
||
@pytest.mark.small_vm | ||
@pytest.mark.usefixtures("host_at_least_8_3") | ||
def test_vtpm(host, unix_vm_with_vtpm): | ||
global vtpm_signing_test_script | ||
vm = unix_vm_with_vtpm | ||
|
||
# unix_vm_with_vtpm fixture starts the VM and stops it at teardown | ||
# No need to call vm.start() here | ||
|
||
# Also used to retreive the VM IP address | ||
vm.wait_for_os_booted() | ||
|
||
pkg_mgr = vm.detect_package_manager() | ||
if pkg_mgr != PackageManagerEnum.APT_GET: | ||
logging.error("This test requires a Debian based VM") | ||
assert False | ||
|
||
# Basic TPM2 tests with tpm2-tools | ||
try: | ||
logging.info("Running TPM2 test script on the VM") | ||
out = vm.execute_script(vtpm_signing_test_script) | ||
logging.info("*****\n%s\n*****" % out) | ||
except commands.SSHCommandFailed as e: | ||
logging.error("%s" % str(e)) | ||
assert False |