Skip to content

Trust Domain at Runtime

On this page, we provide instructions on topics concerning a Trust Domain (TD) at runtime.

Perform Remote Attestation

As explained in the Intel TDX Remote Attestation section of the Infrastructure Setup page, remote attestation is one of the main features of Intel TDX.

In this section, we assume that your infrastructure provider has done the necessary setup steps. This includes the setup of a collateral caching service in the infrastructure and ensuring that a Quote Generation Service (QGS) is running on the same host as the TD.

Then, we show how TD Quotes can be generated, which always has to happen inside a TD.

We also describe how generated TD Quotes can be verified to close the loop. TD Quote Verification can be done by any party at any place. Examples:

  • Inside the TD by the TD owner.
  • In the host OS by the host OS owner.
  • On any remote platform by the owner of the remote platform.

Note that there are multiple TD Quote Verification alternatives.

TD Quote Generation

TD Quote Generation must always happen inside the TD. There are multiple ways to generate a TD Quote. In the following, we explore two alternative for TD Quote Generation using the Linux kernel's built-in configfs-tsm interface:

  1. Using manual shell commands
  2. Using the Intel TDX Quote Generation Sample

Manual Shell Commands

Execute the following shell commands to generate a TD Quote on your distro of choice:

REPORT_DIR="/sys/kernel/config/tsm/report"
REPORT="$REPORT_DIR/report0"
# Ensure configfs is mounted
if ! mountpoint -q /sys/kernel/config; then
    sudo mount -t configfs none /sys/kernel/config
fi
# Create report directory
sudo mkdir -p "$REPORT"
# Provide 64 bytes of REPORTDATA (nonce)
head -c 64 /dev/urandom | sudo tee "$REPORT/inblob" > /dev/null
# Retrieve the Quote
echo "[*] Retrieving TD Quote..."
sudo cat "$REPORT/outblob" > quote.dat
# Check if the output file is empty
if [ ! -s quote.dat ]; then
    echo "[!] Error: TD Quote is empty. Retrieval may have failed." >&2
    sudo rmdir "$REPORT"
else
    # Show formatted output
    echo "[*] Hexdump of the TD Quote:"
    sudo hexdump -C quote.dat
    # Cleanup
    sudo rmdir "$REPORT"
    echo "[*] Quote saved to quote.dat"
fi
REPORT_DIR="/sys/kernel/config/tsm/report"
REPORT="$REPORT_DIR/report0"
# Ensure configfs is mounted
if ! mountpoint -q /sys/kernel/config; then
    mount -t configfs none /sys/kernel/config
fi
# Create report directory
mkdir -p "$REPORT"
# Provide 64 bytes of REPORTDATA (nonce)
head -c 64 /dev/urandom | tee "$REPORT/inblob" > /dev/null
# Retrieve the Quote
echo "[*] Retrieving TD Quote..."
cat "$REPORT/outblob" > quote.dat
# Check if the output file is empty
if [ ! -s quote.dat ]; then
    echo "[!] Error: TD Quote is empty. Retrieval may have failed." >&2
    rmdir "$REPORT"
else
    # Show formatted output
    echo "[*] Hexdump of the TD Quote:"
    hexdump -C quote.dat
    # Cleanup
    rmdir "$REPORT"
    echo "[*] Quote saved to quote.dat"
fi
REPORT_DIR="/sys/kernel/config/tsm/report"
REPORT="$REPORT_DIR/report0"
# Ensure configfs is mounted
if ! mountpoint -q /sys/kernel/config; then
    sudo mount -t configfs none /sys/kernel/config
fi
# Create report directory
sudo mkdir -p "$REPORT"
# Provide 64 bytes of REPORTDATA (nonce)
head -c 64 /dev/urandom | sudo tee "$REPORT/inblob" > /dev/null
# Retrieve the Quote
echo "[*] Retrieving TD Quote..."
sudo cat "$REPORT/outblob" > quote.dat
# Check if the output file is empty
if [ ! -s quote.dat ]; then
    echo "[!] Error: TD Quote is empty. Retrieval may have failed." >&2
    sudo rmdir "$REPORT"
else
    # Show formatted output
    echo "[*] Hexdump of the TD Quote:"
    sudo hexdump -C quote.dat
    # Cleanup
    sudo rmdir "$REPORT"
    echo "[*] Quote saved to quote.dat"
fi
REPORT_DIR="/sys/kernel/config/tsm/report"
REPORT="$REPORT_DIR/report0"
# Ensure configfs is mounted
if ! mountpoint -q /sys/kernel/config; then
    mount -t configfs none /sys/kernel/config
fi
# Create report directory
mkdir -p "$REPORT"
# Provide 64 bytes of REPORTDATA (nonce)
head -c 64 /dev/urandom | tee "$REPORT/inblob" > /dev/null
# Retrieve the Quote
echo "[*] Retrieving TD Quote..."
cat "$REPORT/outblob" > quote.dat
# Check if the output file is empty
if [ ! -s quote.dat ]; then
    echo "[!] Error: TD Quote is empty. Retrieval may have failed." >&2
    rmdir "$REPORT"
else
    # Show formatted output
    echo "[*] Hexdump of the TD Quote:"
    hexdump -C quote.dat
    # Cleanup
    rmdir "$REPORT"
    echo "[*] Quote saved to quote.dat"
fi
REPORT_DIR="/sys/kernel/config/tsm/report"
REPORT="$REPORT_DIR/report0"
# Ensure configfs is mounted
if ! mountpoint -q /sys/kernel/config; then
    sudo mount -t configfs none /sys/kernel/config
fi
# Create report directory
sudo mkdir -p "$REPORT"
# Provide 64 bytes of REPORTDATA (nonce)
head -c 64 /dev/urandom | sudo tee "$REPORT/inblob" > /dev/null
# Retrieve the Quote
echo "[*] Retrieving TD Quote..."
sudo cat "$REPORT/outblob" > quote.dat
# Check if the output file is empty
if [ ! -s quote.dat ]; then
    echo "[!] Error: TD Quote is empty. Retrieval may have failed." >&2
    sudo rmdir "$REPORT"
else
    # Show formatted output
    echo "[*] Hexdump of the TD Quote:"
    sudo hexdump -C quote.dat
    # Cleanup
    sudo rmdir "$REPORT"
    echo "[*] Quote saved to quote.dat"
fi

If successful, a TD Quote will be written to disk in a quote.dat file. This quote.dat file can now be verified as described in the next TD Quote Verification section.

Intel TDX Quote Generation Sample

Execute the following commands to generate a TD Quote using the Intel TDX Quote Generation Sample on your distro of choice:

  1. If not done during another component installation, set up the appropriate Intel SGX package repository for your distribution of choice:

    sudo dnf install -y yum-utils wget tar
    sudo mkdir -p /opt/intel
    wget https://download.01.org/intel-sgx/latest/dcap-latest/linux/distro/centos-stream10/sgx_rpm_local_repo.tgz
    sudo tar -xvzf sgx_rpm_local_repo.tgz -C /opt/intel
    sudo yum-config-manager --add-repo file:///opt/intel/sgx_rpm_local_repo
    sudo wget https://download.01.org/intel-sgx/sgx_repo/ubuntu/intel-sgx-deb.key -O /opt/intel/intel-sgx.key
    sudo yum-config-manager --save --setopt=*sgx_rpm_local_repo.gpgkey=file:///opt/intel/intel-sgx.key
    # Set the priority of the local repo to 1 (highest) to avoid conflicts with other repos
    sudo yum-config-manager --save --setopt=*sgx_rpm_local_repo.priority=1
    
    zypper install -y wget tar
    mkdir -p /opt/intel
    rpm --import https://download.01.org/intel-sgx/sgx_repo/ubuntu/intel-sgx-deb.key
    wget https://download.01.org/intel-sgx/sgx-dcap/1.27.1/linux/distro/suse16-server/sgx_rpm_local_repo.tgz
    tar -xvzf sgx_rpm_local_repo.tgz -C /opt/intel
    zypper addrepo /opt/intel/sgx_rpm_local_repo sgx_rpm_local_repo
    
    sudo dnf install -y yum-utils wget tar
    sudo mkdir -p /opt/intel
    wget https://download.01.org/intel-sgx/latest/dcap-latest/linux/distro/rhel10.2-server/sgx_rpm_local_repo.tgz
    sudo tar -xvzf sgx_rpm_local_repo.tgz -C /opt/intel
    sudo yum-config-manager --add-repo file:///opt/intel/sgx_rpm_local_repo
    sudo wget https://download.01.org/intel-sgx/sgx_repo/ubuntu/intel-sgx-deb.key -O /opt/intel/intel-sgx.key
    sudo yum-config-manager --save --setopt=*sgx_rpm_local_repo.gpgkey=file:///opt/intel/intel-sgx.key
    # Set the priority of the local repo to 1 (highest) to avoid conflicts with other repos
    sudo yum-config-manager --save --setopt=*sgx_rpm_local_repo.priority=1
    
    zypper install -y wget tar
    mkdir -p /opt/intel
    rpm --import https://download.01.org/intel-sgx/sgx_repo/ubuntu/intel-sgx-deb.key
    wget https://download.01.org/intel-sgx/sgx-dcap/1.27.1/linux/distro/suse16-server/sgx_rpm_local_repo.tgz
    tar -xvzf sgx_rpm_local_repo.tgz -C /opt/intel
    zypper addrepo /opt/intel/sgx_rpm_local_repo sgx_rpm_local_repo
    
    echo 'deb [signed-by=/etc/apt/keyrings/intel-sgx-keyring.asc arch=amd64]' \
      'https://download.01.org/intel-sgx/sgx_repo/ubuntu resolute main' \
      | sudo tee /etc/apt/sources.list.d/intel-sgx.list
    curl -fsSLO https://download.01.org/intel-sgx/sgx_repo/ubuntu/intel-sgx-deb.key
    sudo mkdir -p /etc/apt/keyrings
    sudo mv intel-sgx-deb.key /etc/apt/keyrings/intel-sgx-keyring.asc
    sudo apt-get update
    
    echo 'deb [signed-by=/etc/apt/keyrings/intel-sgx-keyring.asc arch=amd64]' \
      'file:///opt/intel/sgx_debian_local_repo resolute main' \
      | sudo tee /etc/apt/sources.list.d/intel-sgx-local.list
    curl -fsSLO https://download.01.org/intel-sgx/sgx_repo/ubuntu/intel-sgx-deb.key
    sudo mkdir -p /etc/apt/keyrings /opt/intel
    sudo mv intel-sgx-deb.key /etc/apt/keyrings/intel-sgx-keyring.asc
    curl -fsSLO https://download.01.org/intel-sgx/latest/dcap-latest/linux/distro/ubuntu26.04-server/sgx_debian_local_repo.tgz
    sudo tar -xvzf sgx_debian_local_repo.tgz -C /opt/intel
    sudo apt-get update
    
  2. Install, build, and run the Intel TDX Quote Generation Sample application (test_tdx_attest)

    sudo dnf install -y libtdx-attest-devel make gcc
    cd /opt/intel/tdx-quote-generation-sample
    make
    ./test_tdx_attest
    mv ./quote.dat ~/quote.dat
    
    zypper install -y make gcc libtdx-attest-devel
    cd /opt/intel/tdx-quote-generation-sample
    make
    ./test_tdx_attest
    mv ./quote.dat ~/quote.dat
    
    sudo dnf install -y libtdx-attest-devel make gcc
    cd /opt/intel/tdx-quote-generation-sample
    make
    ./test_tdx_attest
    mv ./quote.dat ~/quote.dat
    
    zypper install -y make gcc libtdx-attest-devel
    cd /opt/intel/tdx-quote-generation-sample
    make
    ./test_tdx_attest
    mv ./quote.dat ~/quote.dat
    
    sudo apt install -y libtdx-attest-dev make gcc
    cd /opt/intel/tdx-quote-generation-sample
    make
    ./test_tdx_attest
    mv ./quote.dat ~/quote.dat
    

    If successful, a TD Quote will be written to disk in a quote.dat file. This quote.dat file can now be verified as described in the TD Quote Verification section.

TD Quote Verification

TD Quote Verification can be done by any party at an arbitrary place. There are multiple TD Quote Verification alternatives. In the following, we explore how TD Quote Verification can be tested using the Quote Verification Sample application deployed in the host OS.

Steps:

  1. Copy the TD Quote file (e.g., quote.dat) to the host OS. Use a tool of your choice for this operation. Possible commands using scp or virt-copy-out:

    Note

    SSH access to your TD is necessary for this approach. If the VM is started with sudo privileges, ensure you execute the following command with sudo.

    Adjust the following command to your environment and use it to copy the file:

    scp -i ./guest_TD_root_id -p <TD SSH port> <TD user>@<TD IP>:<guest-path-to>/quote.dat <host_directory>/.
    

    Example command:

    scp -i ./guest_TD_root_id -P 10022 root@localhost:/root/quote.dat ~/quote.dat
    

    Note

    Host OS access is necessary for this approach. Also, you must shutdown the TD before accessing the guest image.

    Terminate TD. Then, adjust the following command to your environment and use it to copy the file:

    sudo virt-copy-out -a <image_path> <guest-path-to>/quote.dat <host_directory>
    

    Example command:

    sudo virt-copy-out -a ~/ubuntu-26.04-server-cloudimg-amd64.img /root/quote.dat ~
    

  2. If not done during another component installation, setup the appropriate Intel SGX package repository for your distribution of choice:

    sudo dnf install -y yum-utils wget tar
    sudo mkdir -p /opt/intel
    wget https://download.01.org/intel-sgx/latest/dcap-latest/linux/distro/centos-stream10/sgx_rpm_local_repo.tgz
    sudo tar -xvzf sgx_rpm_local_repo.tgz -C /opt/intel
    sudo yum-config-manager --add-repo file:///opt/intel/sgx_rpm_local_repo
    sudo wget https://download.01.org/intel-sgx/sgx_repo/ubuntu/intel-sgx-deb.key -O /opt/intel/intel-sgx.key
    sudo yum-config-manager --save --setopt=*sgx_rpm_local_repo.gpgkey=file:///opt/intel/intel-sgx.key
    # Set the priority of the local repo to 1 (highest) to avoid conflicts with other repos
    sudo yum-config-manager --save --setopt=*sgx_rpm_local_repo.priority=1
    
    sudo zypper install -y wget tar
    sudo mkdir -p /opt/intel
    sudo rpm --import https://download.01.org/intel-sgx/sgx_repo/ubuntu/intel-sgx-deb.key
    wget https://download.01.org/intel-sgx/sgx-dcap/1.27.1/linux/distro/suse16-server/sgx_rpm_local_repo.tgz
    sudo tar -xvzf sgx_rpm_local_repo.tgz -C /opt/intel
    sudo zypper addrepo /opt/intel/sgx_rpm_local_repo sgx_rpm_local_repo
    
    sudo dnf install -y yum-utils wget tar
    sudo mkdir -p /opt/intel
    wget https://download.01.org/intel-sgx/latest/dcap-latest/linux/distro/rhel10.2-server/sgx_rpm_local_repo.tgz
    sudo tar -xvzf sgx_rpm_local_repo.tgz -C /opt/intel
    sudo yum-config-manager --add-repo file:///opt/intel/sgx_rpm_local_repo
    sudo wget https://download.01.org/intel-sgx/sgx_repo/ubuntu/intel-sgx-deb.key -O /opt/intel/intel-sgx.key
    sudo yum-config-manager --save --setopt=*sgx_rpm_local_repo.gpgkey=file:///opt/intel/intel-sgx.key
    # Set the priority of the local repo to 1 (highest) to avoid conflicts with other repos
    sudo yum-config-manager --save --setopt=*sgx_rpm_local_repo.priority=1
    
    sudo zypper install -y wget tar
    sudo mkdir -p /opt/intel
    sudo rpm --import https://download.01.org/intel-sgx/sgx_repo/ubuntu/intel-sgx-deb.key
    wget https://download.01.org/intel-sgx/sgx-dcap/1.27.1/linux/distro/suse16-server/sgx_rpm_local_repo.tgz
    sudo tar -xvzf sgx_rpm_local_repo.tgz -C /opt/intel
    sudo zypper addrepo /opt/intel/sgx_rpm_local_repo sgx_rpm_local_repo
    
    echo 'deb [signed-by=/etc/apt/keyrings/intel-sgx-keyring.asc arch=amd64]' \
      'https://download.01.org/intel-sgx/sgx_repo/ubuntu resolute main' \
      | sudo tee /etc/apt/sources.list.d/intel-sgx.list
    curl -fsSLO https://download.01.org/intel-sgx/sgx_repo/ubuntu/intel-sgx-deb.key
    sudo mkdir -p /etc/apt/keyrings
    sudo mv intel-sgx-deb.key /etc/apt/keyrings/intel-sgx-keyring.asc
    sudo apt-get update
    
    echo 'deb [signed-by=/etc/apt/keyrings/intel-sgx-keyring.asc arch=amd64]' \
      'file:///opt/intel/sgx_debian_local_repo resolute main' \
      | sudo tee /etc/apt/sources.list.d/intel-sgx-local.list
    curl -fsSLO https://download.01.org/intel-sgx/sgx_repo/ubuntu/intel-sgx-deb.key
    sudo mkdir -p /etc/apt/keyrings /opt/intel
    sudo mv intel-sgx-deb.key /etc/apt/keyrings/intel-sgx-keyring.asc
    curl -fsSLO https://download.01.org/intel-sgx/latest/dcap-latest/linux/distro/ubuntu26.04-server/sgx_debian_local_repo.tgz
    sudo tar -xvzf sgx_debian_local_repo.tgz -C /opt/intel
    sudo apt-get update
    
  3. Execute the following command to install the dependencies for the Quote Verification Sample application, retrieve the application, build the application, and use the application to verify the TD Quote (i.e., quote.dat):

    sudo dnf install -y gcc make git g++
    sudo dnf install -y libsgx-enclave-common-devel \
        libsgx-dcap-quote-verify-devel libsgx-dcap-default-qpl-devel
    cd ~
    git clone https://github.com/intel/confidential-computing.tee.dcap.git
    cd confidential-computing.tee.dcap/SampleCode/QuoteVerificationSample
    make QVL_ONLY=1
    ./app -quote ~/quote.dat
    
    sudo zypper install -y make gcc-c++ git \
    libsgx-enclave-common-devel libsgx-dcap-quote-verify-devel libsgx-dcap-default-qpl-devel
    git clone https://github.com/intel/confidential-computing.tee.dcap.git
    cd confidential-computing.tee.dcap/SampleCode/QuoteVerificationSample
    make QVL_ONLY=1
    ./app -quote ~/quote.dat
    
    sudo dnf install -y gcc make git g++
    sudo dnf install -y libsgx-enclave-common-devel \
        libsgx-dcap-quote-verify-devel libsgx-dcap-default-qpl-devel
    cd ~
    git clone https://github.com/intel/confidential-computing.tee.dcap.git
    cd confidential-computing.tee.dcap/SampleCode/QuoteVerificationSample
    make QVL_ONLY=1
    ./app -quote ~/quote.dat
    
    sudo zypper install -y make gcc-c++ git \
    libsgx-enclave-common-devel libsgx-dcap-quote-verify-devel libsgx-dcap-default-qpl-devel
    git clone https://github.com/intel/confidential-computing.tee.dcap.git
    cd confidential-computing.tee.dcap/SampleCode/QuoteVerificationSample
    make QVL_ONLY=1
    ./app -quote ~/quote.dat
    
    sudo apt install -y make g++ libsgx-enclave-common-dev \
        libsgx-dcap-quote-verify-dev libsgx-dcap-default-qpl-dev
    git clone https://github.com/intel/confidential-computing.tee.dcap.git
    cd confidential-computing.tee.dcap/SampleCode/QuoteVerificationSample
    make QVL_ONLY=1
    ./app -quote ~/quote.dat
    

    If TD Quote Verification is successful, the output will contain Verification completed.