Remote Attestation

About This Task

Remote attestation lets a system prove its boot and runtime state to a remote verifier. On eLxr, the TPM 2.0 records measurements in its Platform Configuration Registers (PCRs), and the Linux Integrity Measurement Architecture (IMA) records every executable, kernel module, and firmware file loaded at runtime into PCR 10. The TPM can then sign a quote over those PCRs with an attestation key, which a verifier checks against known-good values.

This procedure shows how to collect attestation evidence on an eLxr system and verify it.

Before You Begin

  • You must have a system with a TPM 2.0 device, whether physical, firmware, or a virtual TPM such as swtpm under QEMU/KVM. For a test environment, see Setting Up a Test Environment with QEMU/KVM.

  • You must have an eLxr bianca kernel. TPM and IMA support are enabled by default through CONFIG_TCG_TPM, CONFIG_IMA=y, and CONFIG_IMA_MEASURE_PCR_IDX=10.

  • You must have the tpm2-tools package installed.

    # apt install tpm2-tools
    
  • You must run the commands as root.

Confirm that the TPM is present and is version 2.0.

# ls /dev/tpm0 /dev/tpmrm0
# cat /sys/class/tpm/tpm0/tpm_version_major      # expected: 2

Mount securityfs

IMA exposes its policy and measurement log through securityfs. It is normally mounted at boot. Mount it manually if it is not.

# mountpoint -q /sys/kernel/security || mount -t securityfs securityfs /sys/kernel/security
# ls /sys/kernel/security/ima

If /sys/kernel/security/ima does not exist, the kernel was built without IMA.

Load the IMA Measurement Policy

eLxr ships a measurement policy designed for remote attestation at /etc/ima/ima-policy-remote-attestation. It measures:

  • every executed file, through FILE_CHECK and MAY_EXEC

  • every memory-mapped executable, through FILE_MMAP and MAY_EXEC

  • kernel modules, through MODULE_CHECK

  • firmware loaded by the kernel, through FIRMWARE_CHECK

  • kexec kernel images, through KEXEC_KERNEL_CHECK

  • IMA policy updates themselves, through POLICY_CHECK

The policy excludes transient filesystems, such as tmpfs-like runtime filesystems and the initramfs.

Check whether a policy is already active, and load the eLxr policy if not.

# cat /sys/kernel/security/ima/policy

If the output is empty, load the eLxr policy.

# cat /etc/ima/ima-policy-remote-attestation > /sys/kernel/security/ima/policy
# cat /sys/kernel/security/ima/policy

Note

A runtime IMA policy can be written only once per boot, unless the kernel is built with CONFIG_IMA_WRITE_POLICY. If the write fails with Device or resource busy or Permission denied, a policy has already been loaded. Reboot to load a different one.

Inspect the IMA Measurement Log

Each measured file is appended to the runtime measurement log and extended into PCR 10.

# wc -l /sys/kernel/security/ima/ascii_runtime_measurements
# head -20 /sys/kernel/security/ima/ascii_runtime_measurements

Each line contains the PCR index, the template hash, the template name, the file hash, and the file path. The first entry is boot_aggregate, which ties the IMA log to the boot PCRs 0-7.

The binary form of the same log, which is what a verifier consumes, is /sys/kernel/security/ima/binary_runtime_measurements.

Read the PCRs

Read the PCRs.

# tpm2_pcrread sha256:0,1,2,3,4,5,6,7,8,9,10

PCRs 0-7 hold firmware and boot-loader measurements, and PCR 10 holds IMA measurements. On a measured-boot system, none of PCRs 0-7 or PCR 10 should be all zeros.

If tpm2-tools is not installed, the same values are available from sysfs.

# for pcr in 0 1 2 3 4 5 6 7 8 9 10; do
      printf "PCR %2d: %s\n" "$pcr" "$(cat /sys/class/tpm/tpm0/pcr-sha256/$pcr)"
  done

Create an Attestation Key

A TPM quote must be signed with a restricted signing key. A default primary key created with tpm2_createprimary -C endorsement -G rsa is a decryption key and cannot sign quotes.

Create a restricted RSA signing key under the endorsement hierarchy and export its public part.

# mkdir -p ~/attest && cd ~/attest
# tpm2_createprimary -C endorsement -G rsa2048:rsassa-sha256:null \
  -g sha256 \
  -a 'fixedtpm|fixedparent|sensitivedataorigin|userwithauth|restricted|sign' \
  -c ak.ctx
# tpm2_readpublic -c ak.ctx -o ak.pub

This key exists only in this session, as it is transient. For a long-lived attestation key, see Production Deployment.

Generate a Quote

The verifier should supply a fresh random value, a nonce, for each attestation, so that an old quote cannot be replayed. For local testing, generate one yourself.

# NONCE=$(tpm2_getrandom --hex 16)

Ask the TPM to sign PCR 10. To cover the boot chain too, add more PCRs to the list, for example sha256:0,1,2,3,4,5,6,7,10.

# tpm2_quote -c ak.ctx -l sha256:10 -q "$NONCE" \
  -m quote.msg -s quote.sig -o pcr.bin -g sha256

This produces the following files:

File

Contents

quote.msg

The signed attestation structure, including the PCR selection, PCR digest, nonce, and TPM clock.

quote.sig

The TPM’s signature over quote.msg.

pcr.bin

The PCR values that were quoted.

Verify the Quote

Verify the signature, the PCR digest, and the nonce. Pass the public key file, ak.pub, not the context file.

# tpm2_checkquote -u ak.pub -m quote.msg -s quote.sig -f pcr.bin \
      -g sha256 -q "$NONCE"

A successful check prints the quoted PCR values and exits with status 0.

In a real deployment, this step runs on the verifier, not on the system being attested. Send the following to the verifier over a secure channel:

  • quote.msg, quote.sig, and pcr.bin

  • ak.pub, or the AK certificate, as described in Production Deployment

  • the IMA log, /sys/kernel/security/ima/binary_runtime_measurements

  • the firmware event log, /sys/kernel/security/tpm0/binary_bios_measurements

The verifier then:

  1. Checks that the AK belongs to a genuine TPM, as described in Production Deployment.

  2. Runs tpm2_checkquote with the nonce it issued.

  3. Replays the IMA log and firmware event log and confirms the results match the quoted PCR values.

  4. Compares each measured file hash and boot component against its list of approved values.

Production Deployment

The preceding steps use a transient key and verify locally, which is suitable for testing. For production:

  • Use a persistent, certified attestation key. Create the endorsement key and an attestation key from it with tpm2_createek and tpm2_createak, and have the verifier validate the EK certificate against the TPM vendor’s CA before trusting the AK.

  • Always use a verifier-supplied nonce, never a locally generated one.

  • Use an attestation framework such as Keylime rather than hand-written checks. It handles AK enrollment, nonce exchange, IMA log replay, and allow-lists of known-good file hashes.