Skip to content

R5 TPM: the CRB and TIS drivers, /dev/tpm0 and /dev/tpmrm0 #541

Open

Description

@tamnd

Part of #14.

rukernel has no TPM support. On x86_64 the kernel reads only the MADT of the ACPI tables (frame/rk-frame/src/arch/x86_64/acpi.rs). On arm64 it reads the device tree (frame/rk-frame/src/fdt.rs). There is no securityfs, no AF_ALG and no device mapper, and cargo xtask qemu does not start swtpm.

Scope

  • Start swtpm with cargo xtask qemu and boot-test when RK_TPM=1 is set: -tpmdev emulator with -device tpm-crb on x86_64 and -device tpm-tis-device on the arm64 virt machine. Test: all boot tests with RK_TPM=1. Exit: the results do not change. xtask: start swtpm for the QEMU machine with RK_TPM=1 #679: done, and the focused boot tests (x86_64 boot, mm, timer, syscall, init, bzImage and UEFI; arm64 boot) give the same results with RK_TPM=1. The run of all boot tests with RK_TPM=1 is not done yet.
  • Find the TPM and send commands. On x86_64, read the ACPI TPM2 table for the CRB address. On arm64, find the device tree node with compatible = "tcg,tpm-tis-mmio". Add the CRB driver (start, cancel and the command and response buffers) and the TIS FIFO driver (locality, status, burst count and data FIFO), with the time limits of the TCG specification. Test: a new tpm boot test that sends TPM2_Startup, TPM2_GetRandom and TPM2_PCR_Read from the kernel. Exit: the test passes on both architectures. drivers: a TPM 2.0 driver with the CRB and FIFO interfaces, and the tpm boot test #683: the tpm test passes on x86_64 (CRB) and arm64 (TIS).
  • /dev/tpm0 with one command at a time, and /sys/class/tpm/tpm0 with dev, uevent, tpm_version_major and pcr-sha256. Test: the tpm boot test runs tpm2_getrandom 8 and tpm2_pcrread sha256:0,7 of tpm2-tools on /dev/tpm0. Exit: both pass, and the PCR values are the same as in pcr-sha256. drivers: /dev/tpm0 and /sys/class/tpm/tpm0, and tpm2-tools in the tpm boot test #689: both pass on x86_64 and arm64, and PCRs 0 and 7 are the same as in pcr-sha256.
  • /dev/tpmrm0, the resource manager: a space for each open file, with the context save and load of transient objects and sessions and the change of handles, as drivers/char/tpm/tpm2-space.c. Test: add tpm2 to tools/kselftest/build.sh and run test_smoke.sh, test_space.sh and test_async.sh. Exit: the three pass on both architectures. drivers: /dev/tpmrm0, the resource manager of TPM 2.0, and the tpm2 kselftests in the tpm boot test #694: test_smoke.sh (9 tests), test_space.sh (4 tests) and test_async.sh (2 tests) pass on x86_64 and arm64.
  • The event log at /sys/kernel/security/tpm0/binary_bios_measurements, from the log area of the ACPI TPM2 table or the linux,sml-base property of the device tree. It needs securityfs from R5 AppArmor and SELinux: the LSM framework, permissive and then enforcing #540. Test: systemd-analyze pcrs in the systemd boot test with RK_TPM=1. Exit: the PCR values are the same as the values of tpm2_pcrread. drivers: the event log of the firmware at /sys/kernel/security/tpm0/binary_bios_measurements #696: the log of SeaBIOS is in securityfs on x86_64, and the replay with tpm2_eventlog gives the SHA-256 PCRs of tpm2_pcrread. The systemd test with RK_TPM=1 (systemd-analyze pcrs) did not run yet.
  • AF_ALG with skcipher for xts(aes) and cbc(aes) and hash for sha256, so that libcryptsetup can open a LUKS2 key slot without dm-crypt. Test: LTP runtest/crypto (af_alg01 to af_alg07). Exit: the af_alg tests reach the pass set of the reference.
  • systemd-cryptenroll: a new cryptenroll boot test makes a LUKS2 image in a file, runs systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=7, and opens the key slot with the TPM token by cryptsetup open --test-passphrase --token-only. Run the systemd TEST-70-TPM2 integration test and write the result. Exit: the boot test passes on both architectures, and TEST-70-TPM2 reaches the pass set of the reference, apart from the parts that need dm-crypt.

Done when

systemd-cryptenroll binds a key to the virtual TPM. This is the exit of the sixth item of #14.

Test each task on x86_64 and on arm64. Give the result of both in the PR body.

Linux reference: drivers/char/tpm/tpm_crb.c, drivers/char/tpm/tpm_tis_core.c, drivers/char/tpm/tpm-dev-common.c, drivers/char/tpm/tpm2-space.c, drivers/char/tpm/eventlog/acpi.c, crypto/algif_skcipher.c.

Activity

  1. added
    kind/featureNew behavior or a new part.
    area/driversDevice drivers and virtio.
    area/securityLSMs, seccomp, Landlock, capabilities and mitigations.
    on Nov 2, 2026
  2. tamnd commented on Nov 9, 2026

    @tamnd
    OwnerAuthor

    #679 merged: item 1. With RK_TPM=1, cargo xtask qemu and boot-test start swtpm for each machine, with -device tpm-crb on x86_64 and -device tpm-tis-device on arm64.

    With a TPM, QEMU 8.2 puts the -initrd initramfs over a part of the ACPI tables of SeaBIOS (128 KiB of tables and a 64 KiB TPM log at the top of the memory, but x86_load_linux keeps only 160 KiB free). The kernel then found a bad RSDT and did not start. Now the x86_64 SeaBIOS machine with a TPM gets the initramfs from -device loader at 64 MiB, and the kernel finds it from initrdmem=ADDRESS,SIZE, as Linux does. The UEFI machine keeps -initrd.

    Test results:

    • server1 (load average 0.06 to 1.04), x86_64, with and without a TPM: boot, mm, timer, syscall and init pass.
    • server2 (load average 12.9 to 17.4), RK_TPM=1 cargo xtask boot-test boot: boot, boot with the bzImage and boot with UEFI pass. RK_TPM=1 RK_AARCH64_TESTS=boot cargo xtask boot-test aarch64: boot and boot with GICv2 pass.
    • Unit tests on server2: rk-frame boot:: 5 pass (with the new initrdmem= test), xtask 4 pass.
    • The gate of the PR script passed.

    Not done: a run of all boot tests with RK_TPM=1. I ran only the focused tests, so the item is not ticked.

  3. tamnd commented on Nov 10, 2026

    @tamnd
    OwnerAuthor

    #683 merged: item 2. rk-frame finds the TPM (the CRB address from the ACPI TPM2 table on x86_64, the tcg,tpm-tis-mmio node of the device tree on arm64). The new crate rk-drv-tpm has the CRB driver and the TIS FIFO driver, with the TCG time limits and the command durations of Linux, and starts the TPM as tpm2_auto_startup. The new tpm boot test sends TPM2_Startup, TPM2_GetRandom and TPM2_PCR_Read from the kernel.

    Test results:

    • x86_64 on server1 (load average 0.26 to 0.64): the tpm test passes. The kernel finds tpm_crb: TPM 2.0 at 0xfed40000, TPM2_GetRandom(8) gives two different sets of 8 bytes, and TPM2_PCR_Read gives the SHA-256 PCRs 0 and 7. boot and init with a TPM also pass.
    • arm64 on server2 (load average 4.9 to 22.7): RK_AARCH64_TESTS=tpm cargo xtask boot-test aarch64 passes.
    • Unit tests on server2: rk-drv-tpm 10 pass, rk-frame fdt:: 6 pass, xtask 4 pass.
    • The gate of the PR script passed.
  4. tamnd commented on Nov 11, 2026

    @tamnd
    OwnerAuthor

    Item 3 of #541 is done in #689: /dev/tpm0 (one command at a time) and /sys/class/tpm/tpm0 with dev, uevent, tpm_version_major and pcr-sha256. With the tpm2-tools tree of tools/tpm/build.sh, the tpm boot test runs tpm2_getrandom 8 and tpm2_pcrread sha256:0,7 on /dev/tpm0 and compares the PCRs with pcr-sha256.

    • x86_64 on server1 (load average 0.08 to 0.29): pass, and PCRs 0 and 7 of tpm2_pcrread are the same as in pcr-sha256.
    • arm64 on server2 (load average 12.8 to 16.0): pass.
    • Unit tests on server2: rk-drv-tpm 13, rk-fs-sys 27, rk-vfs 119 and xtask 4 pass.

    The full gate did not run.

  5. tamnd commented on Nov 11, 2026

    @tamnd
    OwnerAuthor

    Item 4 of #541 is done in #694: /dev/tpmrm0 (253:65536), the resource manager, as tpm2-space.c of Linux. Each open file has its own transient objects and sessions with virtual handles, and the driver saves and loads their contexts around each command. The tpm boot test runs the tpm2 kselftests of Linux v6.17.

    • x86_64 on server1 (load average 0.12 to 0.78): test_smoke.sh (9 tests), test_space.sh (4 tests) and test_async.sh (2 tests) pass.
    • arm64 on server2 (load average 9.5 to 18.5): the tpm test passes with the three kselftests.
    • Unit tests on server2: rk-drv-tpm 18 and xtask 4 pass.

    The full gate did not run.

  6. tamnd commented on Nov 11, 2026

    @tamnd
    OwnerAuthor

    Item 5 of #541 is partly done in #696: the event log of the firmware at /sys/kernel/security/tpm0/binary_bios_measurements, from the log area of the ACPI TPM2 table on x86-64 or linux,sml-base of the device tree on arm64, as drivers/char/tpm/eventlog of Linux.

    • x86_64 on server1 (load average 1.7 to 2.2): the log of SeaBIOS has 16 events. tpm2_eventlog replays PCRs 0 to 7, and they are the same as the SHA-256 PCRs of tpm2_pcrread.
    • arm64 on server2 (load average 11.4 to 18.2): the tpm test passes. QEMU virt with -kernel has no firmware, so there is no log.
    • Unit tests on server2: rk-drv-tpm 20, rk-frame fdt 6 and xtask 4 pass.

    Not done: systemd-analyze pcrs in the systemd boot test with RK_TPM=1 did not run.

    The full gate did not run.

  7. tamnd commented on Nov 12, 2026

    @tamnd
    OwnerAuthor

    #699 adds the crate rk-crypto, with SHA-1, SHA-224, SHA-256, SHA-384, SHA-512, hmac, AES and the modes ecb, cbc, ctr and xts, as crypto/ of Linux. The 13 unit tests use the vectors of crypto/testmgr.h, and they pass. The AF_ALG item is not done yet. The AF_ALG sockets with hash and with skcipher come in the next two PRs, with LTP af_alg01 to af_alg07.

  8. tamnd commented on Nov 12, 2026

    @tamnd
    OwnerAuthor

    #703 adds the AF_ALG sockets with the type hash, as crypto/af_alg.c and crypto/algif_hash.c, with the allow lists of crypto.af_alg_restrict. LTP af_alg01 passes on x86_64 and arm64. af_alg02 to af_alg06 and af_alg08 give TCONF, as on Linux with the allow list. af_alg07 fails, because fchownat on a socket after its release does not give ENOENT yet. The AF_ALG item is not done yet. The skcipher sockets and the fix for af_alg07 come next.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/driversDevice drivers and virtio.area/securityLSMs, seccomp, Landlock, capabilities and mitigations.kind/featureNew behavior or a new part.

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions