Skip to content

jetson: fTPM and EK provisioning#1809

Merged
brianmcgillion merged 1 commit intotiiuae:mainfrom
vadika:pr/ftpm-ek-da-only
Mar 16, 2026
Merged

jetson: fTPM and EK provisioning#1809
brianmcgillion merged 1 commit intotiiuae:mainfrom
vadika:pr/ftpm-ek-da-only

Conversation

@vadika
Copy link
Copy Markdown
Contributor

@vadika vadika commented Mar 7, 2026

Summary

This PR enables the Jetson Orin fTPM (firmware TPM backed by OP-TEE) bring-up path.

Changes

jetson-orin.nix

Kernel structured config additions:

Option Value Reason
TCG_FTPM_TEE module Load fTPM driver as a module so it can be ordered after OP-TEE init
HW_RANDOM_TPM no Eliminate background entropy-poll pressure on the single-lane fTPM TA
EXPERT yes Required by TCG_FTPM_TEE

New boot-time systemd services (oneshot, idempotent):

  • ghaf-provision-ek-certs — Provisions self-signed EK endorsement certificates
    into NV indices 0x01C00002 (RSA-2048) and 0x01C0000A (ECC P-256) if not already
    present. Certificates are issued with a fixed validity window of 1970-01-01 → 2100-01-01 to remain valid regardless of RTC state at the time of provisioning.

  • ghaf-export-ek-endorsement-bundle — Reads the NV-resident DER certs and exports
    them as PEM files under /run/ghaf-spiffe/ for downstream services (SPIRE server,
    tpm-ek-verify) to consume at runtime. Runs After=ghaf-provision-ek-certs.service.

Firmware EKS image option:
Adds ghaf.hardware.nvidia.orin.ftpm.firmwareEksImage option (type: nullOr path, default
null). When set, the specified image is written to the EFI variable
EKS-8be4df61-93ca-11d2-aa0d-00e098032b8c at first boot so that the firmware-provisioned
EK certificates survive reflash.


Testing

# 1. Flash debug image and boot
# 2. On host:


systemctl status ghaf-provision-ek-certs.service
# → active (exited); NV indices 0x01C00002 and 0x01C0000A written on first boot,
#                     no-op on subsequent boots (idempotent guard)

systemctl status ghaf-export-ek-endorsement-bundle.service
# → active (exited)

ls -la /persist/common/spire/ca/
# → ek-rsa.pem  ek-ecc.pem  (both non-empty)

tpm2_nvreadpublic 0x01C00002 && tpm2_nvreadpublic 0x01C0000A
# → both return successfully

tpm2_getcap properties-variable | grep inLockout
# → inLockout: 0

# 3. Verify OP-TEE serial log is quiet (no plat_prng_add_jitter_entropy flood)
# 4. On second boot: confirm provision service exits immediately (idempotent)

Checklist

  • Tested on real NVIDIA Jetson Orin AGX hardware
  • CI/CD build — not applicable: Jetson NV indices and fTPM TA only accessible after QSPI reflash;

@vadika vadika force-pushed the pr/ftpm-ek-da-only branch from cbd826c to 57b4944 Compare March 7, 2026 12:02
@vadika vadika force-pushed the pr/ftpm-ek-da-only branch from 57b4944 to 20ad6c2 Compare March 7, 2026 12:25
@vadika vadika changed the title jetson: harden fTPM EK provisioning and reduce OP-TEE log verbosity jetson: fTPM and EK provisioning Mar 7, 2026
@vadika vadika added the Needs Testing CI Team to pre-verify label Mar 7, 2026
@leivos-unikie
Copy link
Copy Markdown
Contributor

leivos-unikie commented Mar 10, 2026

Tested on Orin AGX

Built flash script:
nix build .#packages.x86_64-linux.nvidia-jetson-orin-agx-debug-from-x86_64-flash-script

Flashed successfully with
sudo ./result/bin/flash-ghaf-host

[ghaf@ghaf-host:~]$ systemctl status ghaf-normalize-da-params.service
Unit ghaf-normalize-da-params.service could not be found.

[ghaf@ghaf-host:~]$ systemctl status ghaf-provision-ek-certs.service
Active: active (exited)

[ghaf@ghaf-host:~]$ systemctl status ghaf-export-ek-endorsement-bundle.service
Active: inactive (dead)

[ghaf@ghaf-host:~]$ ls -la /run/ghaf-spiffe/
ls: cannot access '/run/ghaf-spiffe/': No such file or directory

[ghaf@ghaf-host:~]$ tpm2_getcap properties-variable | grep inLockout
-bash: tpm2_getcap: command not found

Did I miss something?

@leivos-unikie
Copy link
Copy Markdown
Contributor

With the revised test instructions:

[ghaf@ghaf-host:~]$ systemctl status ghaf-normalize-tpm-da-params.service
Active: inactive (dead)

[ghaf@ghaf-host:~]$ systemctl status ghaf-provision-ek-certs.service
Active: active (exited)

[ghaf@ghaf-host:~]$ systemctl status ghaf-export-ek-endorsement-bundle.service
Active: inactive (dead)

[ghaf@ghaf-host:~]$ ls -la /persist/common/spire/ca/
total 20
drwxr-xr-x 2 root root 4096 Jan  1  1970 .
drwxr-xr-x 3 root root 4096 Jan  1  1970 ..
-rw-r--r-- 1 root root  810 Mar 10 12:46 ek-ecc.pem
-rw-r--r-- 1 root root 1082 Mar 10 12:46 ek-rsa.pem
-rw-r--r-- 1 root root 1892 Mar 10 12:46 endorsement-bundle.pem

[ghaf@ghaf-host:~]$ tpm2_nvreadpublic 0x01C00002 && tpm2_nvreadpublic 0x01C0000A
-bash: tpm2_nvreadpublic: command not found

[ghaf@ghaf-host:~]$ tpm2_getcap properties-variable | grep inLockout
-bash: tpm2_getcap: command not found

@leivos-unikie
Copy link
Copy Markdown
Contributor

Tested on Orin NX

nix build .#packages.x86_64-linux.nvidia-jetson-orin-nx-debug-from-x86_64-flash-qspi
Flashed qspi succesfully.
nix build .#packages.x86_64-linux.nvidia-jetson-orin-nx-debug-from-x86_64
Flashed the image on USB SSD
Booted

Same test results as with Orin AGX above, except with Orin NX
tpm2_nvreadpublic 0x01C00002 && tpm2_nvreadpublic 0x01C0000A
returned succesfully.

On second boot:

[ghaf@ghaf-host:~]$ systemctl status ghaf-provision-ek-certs.service
● ghaf-provision-ek-certs.service - Provision fTPM EK certificates into standard NV indices
     Loaded: loaded (/etc/systemd/system/ghaf-provision-ek-certs.service; enabled; preset: ignored)
     Active: active (exited) since Thu 1970-01-01 00:04:49 UTC; 2min 15s ago
 Invocation: ad2f303570904c04bf1721147bf5d2e3
    Process: 941 ExecStart=/nix/store/njc5ywcd1hldsz3mg243zkdy1h2i8xgm-ghaf-provision-ek-certs/bin/ghaf-provision-ek-certs (code=exited, status=0/SUCCESS)
    Process: 1458 ExecStartPost=/nix/store/5as96w6vsmgpsnf2sdhag5s4rgqlqbrb-systemd-aarch64-unknown-linux-gnu-258.3/bin/systemctl --no-block start ghaf-export-ek-endorsement-bundle.service (code=exited, status=0/SUCCESS)
   Main PID: 941 (code=exited, status=0/SUCCESS)
         IP: 0B in, 0B out
         IO: 6.7M read, 0B written
   Mem peak: 19M
        CPU: 2.170s

Jan 01 00:04:48 ghaf-host ghaf-provision-ek-certs[1055]: ........+.+++++++++++++++++++++++++++++++++++++++*...+........+...+....+......+.....+.......+...+..............+++++++++++++++++++++++++++++++++++++++*.+.........+....+...+......>
Jan 01 00:04:48 ghaf-host ghaf-provision-ek-certs[1055]: -----
Jan 01 00:04:48 ghaf-host ghaf-provision-ek-certs[1259]: nv-index: 0x1c00002
Jan 01 00:04:48 ghaf-host ghaf-provision-ek-certs[941]: Provisioned EK cert at NV index 0x01C00002 (rsa, 759 bytes)
Jan 01 00:04:49 ghaf-host ghaf-provision-ek-certs[1323]: .+..+...+...+............+...+....+.....+.+..................+++++++++++++++++++++++++++++++++++++++*......+.....+++++++++++++++++++++++++++++++++++++++*.+....+.....+....+..+.+..>
Jan 01 00:04:49 ghaf-host ghaf-provision-ek-certs[1323]: .......+......+.+...+++++++++++++++++++++++++++++++++++++++*.......+.....+...+.+.....+.........+.+...+........+.......+...+..+.......+++++++++++++++++++++++++++++++++++++++*....+>
Jan 01 00:04:49 ghaf-host ghaf-provision-ek-certs[1323]: -----
Jan 01 00:04:49 ghaf-host ghaf-provision-ek-certs[1454]: nv-index: 0x1c0000a
Jan 01 00:04:49 ghaf-host ghaf-provision-ek-certs[941]: Provisioned EK cert at NV index 0x01C0000A (ecc, 556 bytes)
Jan 01 00:04:49 ghaf-host systemd[1]: Finished Provision fTPM EK certificates into standard NV indices.

@leivos-unikie leivos-unikie added question Further information is requested and removed Needs Testing CI Team to pre-verify labels Mar 10, 2026
@leivos-unikie
Copy link
Copy Markdown
Contributor

Should these checks pass also?

tpm2_nvreadpublic 0x01C00002 && tpm2_nvreadpublic 0x01C0000A
# → both return successfully

tpm2_getcap properties-variable | grep inLockout
# → inLockout: 0

@vadika
Copy link
Copy Markdown
Contributor Author

vadika commented Mar 10, 2026

For the tpm2_* checks, please use the same TCTI as the services:

export PATH="$PATH:/run/current-system/sw/bin"
export TPM2TOOLS_TCTI="device:/dev/tpmrm0"

tpm2_nvreadpublic 0x01C00002
tpm2_nvreadpublic 0x01C0000A
tpm2_getcap properties-variable | grep inLockout

(tpm2_*: command not found indicates PATH, not TPM behavior.)

@leivos-unikie leivos-unikie removed the question Further information is requested label Mar 11, 2026
@leivos-unikie
Copy link
Copy Markdown
Contributor

leivos-unikie commented Mar 11, 2026

Orin AGX:

Didn't succeed in including tpm2-tools in PATH but ran the commands from /nix/store.

[ghaf@ghaf-host:~]$ sudo /nix/store/yv1m9wzniifv8pbcgq9w9ff7vk1z0raa-tpm2-tools-aarch64-unknown-linux-gnu-5.7/bin/tpm2_nvreadpublic 0x01C00002
0x1c00002:
  name: 000b2678676e89a953ebd1fd133aef5f89c26f158b2645f7158b23283aaacf4cbcea
  hash algorithm:
    friendly: sha256
    value: 0xB
  attributes:
    friendly: ppwrite|writedefine|ppread|ownerread|authread|no_da|written|platformcreate
    value: 0x62072001
  size: 953

[ghaf@ghaf-host:~]$ sudo /nix/store/yv1m9wzniifv8pbcgq9w9ff7vk1z0raa-tpm2-tools-aarch64-unknown-linux-gnu-5.7/bin/tpm2_nvreadpublic 0x01C0000A
0x1c0000a:
  name: 000bf2fb81593e2ee8b810ad74bb5db023938c2fcee271420e2473fa0ac0a2dd6fa5
  hash algorithm:
    friendly: sha256
    value: 0xB
  attributes:
    friendly: ppwrite|writedefine|ppread|ownerread|authread|no_da|written|platformcreate
    value: 0x62072001
  size: 750

[ghaf@ghaf-host:~]$ sudo /nix/store/yv1m9wzniifv8pbcgq9w9ff7vk1z0raa-tpm2-tools-aarch64-unknown-linux-gnu-5.7/bin/tpm2_getcap properties-variable | grep inLockout
  inLockout:                 0

@leivos-unikie
Copy link
Copy Markdown
Contributor

leivos-unikie commented Mar 11, 2026

Orin AGX:

When I try running those check commands right after flash-script (without reboot) they fail. Also I saw one failed boot (got stuck) but was not able to reproduce it.

PR1809_checks.txt

After further reboot the checks are ok.

@leivos-unikie
Copy link
Copy Markdown
Contributor

Tested also with booting Orin AGX from USB SSD that the checks pass.

@leivos-unikie leivos-unikie added the Tested on Orin AGX Cross This PR has been tested on NVIDIA Jetson AGX Orin cross-compiled label Mar 11, 2026
@vadika vadika force-pushed the pr/ftpm-ek-da-only branch from 2bae14d to 2b370f1 Compare March 11, 2026 16:56
@leivos-unikie
Copy link
Copy Markdown
Contributor

Checked on Orin NX that steps defined under 'Testing' return as expected.

@leivos-unikie leivos-unikie added the Tested on Orin NX Cross This PR has been tested on NVIDIA Jetson NX Orin cross-compiled label Mar 12, 2026
@vadika vadika force-pushed the pr/ftpm-ek-da-only branch from 2b370f1 to fc31aaf Compare March 13, 2026 10:16
@vadika vadika requested a review from TanelDettenborn March 13, 2026 10:17
@vadika vadika force-pushed the pr/ftpm-ek-da-only branch from fc31aaf to ad65e99 Compare March 13, 2026 11:56
@TanelDettenborn
Copy link
Copy Markdown
Contributor

Codewise, this PR looks good. Approved for development, but we'll need an additional patch/work before going to production.

Switch Orin runtime EK provisioning to NVIDIA SIM tooling and enforce stage-2 fTPM module loading after tee-supplicant. Remove DA normalization service, simplify the fTPM module loader, and pin jetpack-nixos to feb-rebase for this branch.

Signed-off-by: vadik likholetov <vadikas@gmail.com>
@brianmcgillion
Copy link
Copy Markdown
Collaborator

is there a CI-test automation patch that has to go in with this?

@vadika
Copy link
Copy Markdown
Contributor Author

vadika commented Mar 13, 2026

is there a CI-test automation patch that has to go in with this?

not sure about the patch, but the test devices should all be reflashed.

@leivos-unikie
Copy link
Copy Markdown
Contributor

Rel and prod test devices are now flashed (qspi) aligning with this PR.

@brianmcgillion brianmcgillion merged commit cbddea9 into tiiuae:main Mar 16, 2026
31 of 32 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Tested on Orin AGX Cross This PR has been tested on NVIDIA Jetson AGX Orin cross-compiled Tested on Orin NX Cross This PR has been tested on NVIDIA Jetson NX Orin cross-compiled

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants