wolfTPM on the NVIDIA Jetson Orin firmware TPM

Most TPMs wolfTPM talks to are things you can hold, such as an SLB9672 or ST33KTPM2X soldered next to the SoC and reached over SPI or I2C. The NVIDIA Jetson Orin has no such chip. Its TPM 2.0 is a firmware TPM: software running as a trusted application inside OP-TEE on the same Cortex-A78AE cores as Linux, separated by ARM TrustZone rather than by a package boundary. Linux reaches it through the tpm_ftpm_tee driver, which registers an ordinary TPM chip, so you get /dev/tpm0 and /dev/tpmrm0 and every tool that already speaks to a Linux TPM works unchanged. There is no extra BOM component and no bus to route. wolfTPM now supports it and identifies it as Mfg MSFT (7), Vendor SSE fTPM, Fw 8216.1808, FIPS 140-2.

Two things stand out in the numbers below. Everything is supported: not one operation reported Skipped (not supported), where discrete parts routinely skip whole categories (the SLB9670 cannot do TPM-side AES at all). And it is fast for a TPM, with RSA-2048 key generation in 736 ms against roughly 6.8 seconds on a discrete part, and RSA public operations two orders of magnitude quicker. That gap is about where the TPM runs, not TPM quality. A discrete TPM is a small microcontroller behind a 33 MHz serial bus, while the fTPM is code on a 1728 MHz application core with a function call where the bus would be. Use these figures for capacity planning rather than as a security ranking. The real trade is that a discrete TPM is separate silicon whose keys survive a compromised host OS, while a firmware TPM shares the SoC with the software it attests. For measured boot, device identity, and key storage on a device that already trusts its SoC, the fTPM is compelling. For a threat model that includes physical possession, a discrete part remains a different proposition.

Benchmarks

Measured on Jetson Linux R36.4.4, kernel 5.15.148-tegra, MAXN_SUPER power mode with six A78AE cores at 1728 MHz, via /dev/tpmrm0:

Operation Result Operation Result
RSA-2048 key generation 736 ms (1.36 ops/sec) ECDHE P-256 agree 11.2 ops/sec
RSA-2048 public 1144 ops/sec (0.87 ms) AES-256-CBC 2.9 MB/s
RSA-2048 private 84 ops/sec (11.9 ms) SHA-256 1.57 MB/s
ECDSA P-256 sign 22.2 ops/sec (45.1 ms) RNG 562 KB/s
ECDSA P-256 verify 31.5 ops/sec (31.7 ms) Skipped as unsupported none

Reproducing this on your own Jetson

  1. Confirm the kernel sees the fTPM
    lsmod | grep tpm_ftpm_tee
    ls -l /dev/tpm*
    cat /sys/class/tpm/tpm0/tpm_version_major     # expect 2
    

    If the module is missing, try sudo modprobe tpm_ftpm_tee and check that the kernel was built with CONFIG_TCG_FTPM_TEE. On Jetson Linux, the driver is present and an fTPM Device Provisioning Service unit runs at boot. Note that an OP-TEE boot message about silicon-identity fTPM provisioning not being enabled refers to a separate NVIDIA feature and does not mean the TPM is unavailable.

  2. Grant access to the device
    The TPM character devices are mode 0660 owned by group tss, and on many images that group exists with no members:

    sudo usermod -aG tss $USER      # then start a new login session
    

    On Jetson Linux, /dev/tpm0 is tss:root while /dev/tpmrm0 is tss:tss, so joining tss grants the resource manager specifically. That is the node you want. See the permissions section of docs/DEVTPM.md for a udev rule if you prefer your own group.

  3. Build wolfSSL
    git clone https://github.com/wolfSSL/wolfssl.git
    cd wolfssl
    ./autogen.sh
    ./configure --enable-wolftpm
    make && sudo make install && sudo ldconfig
    

    Keep the examples enabled if you intend to run the TLS tests in step 7, since those need the wolfSSL server binary.

  4. Build wolfTPM
    git clone https://github.com/wolfSSL/wolftpm.git
    cd wolftpm
    ./autogen.sh
    ./configure --enable-autodetect
    make
    

    A bare ./configure will not work here. On Linux x86_64 and aarch64, wolfTPM auto-enables its software TPMs so make check runs without hardware, and that suppresses the kernel-device autodetect path, leaving you talking to a simulator on TCP port 2321. Use –enable-autodetect (kernel device first, SPI fallback) or –enable-devtpm (kernel device only). Configure prints a notice when it takes the software default, so check the tail of its output if a build unexpectedly cannot find your TPM. The full option list is in the wolfTPM README build section.

  5. Confirm the identity
    ./examples/wrap/caps
    Mfg MSFT (7), Vendor SSE fTPM, Fw 8216.1808 (0x105300), FIPS 140-2, CC-EAL4 0

    MSFT is what the TPM itself reports in TPM_PT_MANUFACTURER, because NVIDIA’s fTPM is built from Microsoft’s TPM 2.0 reference implementation. It identifies the implementation lineage rather than the silicon vendor, so the vendor string SSE fTPM is what distinguishes this platform. Fw 8216.1808 is 0x20180710, a build date rather than a version number. There is no Caps/Did/Vid/Rid line because those values come from TIS bus registers that a firmware TPM does not have. Compare against the other parts in the Device Identification table.

  6. Run the native and wrapper tests
    ./examples/native/native_test
    ./examples/wrap/wrap_test
    

    Per-example usage is documented in examples/README.md.

  7. Benchmark and run the full example suite
    ./examples/bench/bench
    ./examples/run_examples.sh
    

    bench defaults to one second per algorithm and fifteen seconds for key generation. Run it twice and keep the second result, since the first pays for the initial OP-TEE trusted-application load and CPU frequency ramp, and record your nvpmodel power mode alongside the numbers. Sample output for every supported part is in the TPM2 Benchmarks section.
    run_examples.sh covers the native and wrapper tests, NV, policies, parameter encryption, PKCS7, the full TLS matrix with the TPM acting as both client and server, attestation, PCR quote and policy, Secure Boot ROT, Seal/Unseal, and the EK certificate. One block will not pass on the resource manager: the provisioning section creates IAK and IDevID primaries with -keep in one process and then references them from another, and /dev/tpmrm0 virtualizes transient handles and flushes them when the file descriptor closes. That is correct resource-manager behavior, not a wolfTPM fault. Any workflow of the form “create a key here, use it in the next command” needs a single process or a persistent handle created with TPM2_EvictControl. The behavior, and how the kernel surfaces the resulting failure, is described in docs/DEVTPM.md.

Further reading

  • docs/DEVTPM.md covers the Linux kernel TPM transport in full: resource manager versus raw device, permissions, shared-state caveats, and the Jetson Orin specifics.
  • docs/SWTPM.md covers the software simulator transport, useful for development without hardware.
  • examples/README.md documents every example and its options.
  • The wolfTPM manual has the full API reference.

Check out PR#576!

If you have any questions, please email facts@wolfssl.com or call us at +1 425 245 8247.

Download wolfSSL Now