attester: add PRoT software component reporting the OP-TEE OS version#3
Open
mmxsrup wants to merge 9 commits into
Open
attester: add PRoT software component reporting the OP-TEE OS version#3mmxsrup wants to merge 9 commits into
mmxsrup wants to merge 9 commits into
Conversation
- Measurement Type: "PRoT" → "ARoT" (TA is an ARoT component) - Implementation ID: move from TA to PTA, platform-specific values (imx8mp-optee-ra-... / qemu-optee-ra-...) - Client ID: derive from caller TA UUID instead of hardcoded value - Signer ID: read SRK hash from OCOTP fuses on i.MX8MP, test fallback on QEMU - Lifecycle: determine from fuse state on i.MX8MP, 0x3000 fallback on QEMU Platform-specific code gated by CFG_NXP_CAAM. Verified on QEMU with CBOR decode of all 5 claims.
Update comid-psa-refval-imx.json and comid-psa-ta.json with actual device values: - signer-id: SRK hash read from OCOTP fuses - measurement-value: TA memory hash from real hardware - impl-id: platform-specific implementation ID - instance-id and verification key: CAAM-generated keypair
- Fix instance-id and comid-psa-ta.json references across all READMEs - Separate English and Japanese into dedicated files (README.md / README-j.md, provisoning/README.md / provisoning/README-j.md)
Emit a second PSA software component (measurement-type "PRoT") for the OP-TEE OS itself, alongside the existing "ARoT" component for the TA.
hash.c: add get_hash_tee_memory(), a runtime SHA-256 over the core's immutable .text + .rodata (mirrors the upstream attestation PTA cmd_hash_tee_memory). The hashed range excludes relocated data (.data.rel.ro/.got live outside __rodata_start..__rodata_end), so it is reproducible across boots even with CFG_CORE_ASLR=y.
cbor.{c,h}: generalize encode_evidence_to_cbor() to take an array of psa_sw_component and emit the optional version field (#4).
remote_attestation.c: derive the OP-TEE OS version from core_v_str (e.g. "4.6.0") and build ARoT + PRoT components; signer-id stays the SRK hash and implementation-id is unchanged. A debug line logs the PRoT measurement in base64 for capturing the Veraison reference value.
Verification stays affirming with no provisioning change: the existing ARoT reference value still matches, and the new PRoT component is ignored until a "PRoT" reference value is provisioned.
The i.MX secure-boot output dir holds multi-hundred-MB WIC images and CST private keys owned by another user, which break and bloat the QEMU attester docker build context. It is not needed for that build.
Show the PRoT entry in the verification-result example (README.md / README-j.md) and explain that the OP-TEE OS is identified by the stable version field. Its measurement-value is a build-specific runtime hash (OP-TEE embeds the build timestamp in core_v_str, part of the hashed .rodata), so it is not provisioned as a reference value; the verifier ignores the PRoT component and ear.status stays affirming. OS integrity is rooted in HAB/SRK secure boot.
The client confirmed that the PRoT measurement-value changing on every build is acceptable, so the PRoT component is now verified by Veraison instead of being left unprovisioned: register the build's reference value and a matching build stays affirming while a different OP-TEE build (or modified code) is flagged as warning. Add provisoning/compute-prot-refval.py, the offline equivalent of the PTA's get_hash_tee_memory(): it computes the PRoT measurement-value from the tee.elf build artifact (same VA spans, same order), so the reference value can be obtained without booting the image or raising the core log level (i.MX production builds compile out all core trace). Verified on QEMU: the script output is identical to the runtime measurement reported by the PTA. Register the PRoT reference value of the current signed i.MX8MP build in comid-psa-refval-imx.json, and update the README note to describe the per-build provisioning flow. Note that Yocto optee-os builds are reproducible (SOURCE_DATE_EPOCH is set and the build counter resets on clean builds — confirmed: two cleansstate builds of identical source produce bit-identical tee.elf), so rebuilding the same source does not invalidate the registered value; QEMU container builds are not reproducible and need a fresh value per build.
The ARoT measurement (get_hash_ta_memory) hashes the TA's read-only regions as mapped by ldelf: the ELF-header page (ldelf maps file offset 0, one page, read-only — see init_elf()) plus every read-only PT_LOAD segment zero-padded to its page-rounded memsz, hashed smallest-first (ties by content, matching the runtime cmp_regions() ASLR-stable ordering). Since TA text/rodata contain no load-base-dependent bytes (all relocations target the writable segment), this can be reproduced from the build artifact alone. Add provisoning/compute-arot-refval.py implementing exactly that; verified on QEMU that its output is identical to the runtime measurement, both from the TA ELF and from the signed .ta (the signed header is skipped automatically). The script warns if a relocation targets a read-only segment, in which case the offline value may not match the runtime one. Update comid-psa-refval-imx.json with the ARoT value computed from the current signed i.MX8MP build (replacing the stale value from an older build), so both ARoT and PRoT reference values can now be provisioned from build artifacts without a first device run, and document the script in the READMEs.
Update the new-TA registration steps (section 6.2) to recommend computing the ARoT measurement-value offline from the build artifact with provisoning/compute-arot-refval.py instead of capturing the debug output of a first run; the run-capture method remains documented as an alternative for debug builds, with a note that it is unavailable on i.MX production builds (core log level 0). Add an offline-computation section to the provisioning READMEs covering both scripts (ARoT and PRoT), when each value changes, and the pyelftools requirement.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a second PSA software component (
measurement-type: "PRoT") reporting the OP-TEE OS version, alongside the existingARoT(TA) component.implementation-idandsigner-idare unchanged.hash.c:get_hash_tee_memory()— SHA-256 of the core.text+.rodata(mirrors the upstream attestation PTA).cbor.{c,h}: software components passed as an array; optionalversion(attester: add RA_PERF performance measurement logging #4) field emitted.remote_attestation.c: OS version taken fromcore_v_str(e.g."4.6.0"); builds ARoT + PRoT.Reference values: computed offline, registered per build
provisoning/compute-prot-refval.py tee.elf— PRoT. Build-specific (the build timestamp is part of the hashed.rodata), so recompute per release. Yocto builds are reproducible (bit-identicaltee.elffor the same source), so same-source rebuilds keep the value valid.provisoning/compute-arot-refval.py <uuid>.ta— ARoT (ELF-header page + read-only PT_LOAD segments, smallest-first). No first device run needed; required on i.MX production builds, which print no core trace.Both verified on QEMU: script output == runtime measurement.
Verification (QEMU E2E)
ear.status: affirming,executables: 2, components[ARoT, PRoT(version="4.6.0-dev")].affirming; wrong value (simulated build change) →warning.Scope
Based on
pr/psa-claims-rfc9783, so this PR also carries that branch's commits. New here: the PRoT component, the offline reference-value scripts and registered i.MX values, and docs.