ta/pta: qcom: pas: authenticate PIL firmware signatures and device bindings - #20
Conversation
|
Depends on #19. The first 4 commits in this PR's diff belong to that PR and will disappear from this diff once it merges. |
b2d3d68 to
6c41610
Compare
ca740d4 to
eaf0b53
Compare
690842e to
a4d253d
Compare
|
Rebase to tip of qcom-next |
I will rebase this after testing is complete and will mark this PR as "Ready for review" post that. I have marked this as "Draft" for now since its WIP. (Testing is pending) |
da0584b to
e5b5bf9
Compare
|
Hi Sumit Garg (@b49020) / Jorge A. Ramirez-Ortiz (@ldts), The first 5 commits belong to #19. To get a view of changes part of this PR alone you can use below link: This change is now tested in Secure Boot. Please help to review this! |
There was a problem hiding this comment.
Pull request overview
This PR extends the Qualcomm PAS authentication path in OP-TEE to perform end-to-end trust of PIL firmware images on hoya-family platforms by authenticating the MBN hash-segment metadata (cert chain + signature) and binding it to device fuses/peripheral identity before trusting the per-segment digest table used for carveout verification.
Changes:
- Adds a fuse PTA (backed by QFPROM) and TA-side fuse wrappers to expose secure-boot anchors, device identity, MRC state, EKU/UIE policy bits, digest-size selection, and anti-rollback versioning to the qcom_pas TA.
- Implements X.509 chain validation + RSA-PSS/ECDSA signature verification and OEM/QTI metadata binding checks, wired into the TA’s INIT_IMAGE / AUTH_AND_RESET flow.
- Adds a core-side VERIFY_IMAGE command to re-hash loaded segments against an authenticated hash table immediately before reset de-assertion.
Reviewed changes
Copilot reviewed 38 out of 38 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| ta/qcom_pas/user_ta.mk | Adds CFG_QCOM_PAS_AUTH knob and increases heap when enabled. |
| ta/qcom_pas/src/user_ta_header_defines.h | Increases TA stack size when authentication is enabled. |
| ta/qcom_pas/src/sub.mk | Adds include dir and conditionally builds auth-related sources. |
| ta/qcom_pas/src/qcom_pas.c | Wires INIT_IMAGE/AUTH_AND_RESET through auth backend and manages fuse/PTA sessions. |
| ta/qcom_pas/src/pas_sig.c | Implements cert-chain policy enforcement, root binding, and signature verification helpers. |
| ta/qcom_pas/src/pas_sig_auth.c | Implements PAS TA signature-auth orchestration (bindings, anti-rollback, QTI countersign). |
| ta/qcom_pas/src/pas_policy.c | Adds pas_id→SW_ID mapping and signer-authority policy. |
| ta/qcom_pas/src/pas_meta.c | Parses OEM metadata fields and builds per-signer “signed region” copies. |
| ta/qcom_pas/src/pas_mbn_parser.c | Parses MBN v5/v6 hash segment and locates signing material/hash table. |
| ta/qcom_pas/src/pas_fuse.c | Adds TA-side wrapper calls into the fuse PTA. |
| ta/qcom_pas/src/pas_auth.c | Adds per-session metadata save, authentication, and VERIFY_IMAGE invocation packing. |
| ta/qcom_pas/include/qcom_pas_priv.h | Defines per-session metadata slots and parsed MBN storage. |
| ta/qcom_pas/include/pas_sig.h | Declares signature/cert-chain helper APIs. |
| ta/qcom_pas/include/pas_sig_auth.h | Declares signature-auth backend entry points (stubbed when disabled). |
| ta/qcom_pas/include/pas_policy.h | Declares policy APIs (expected SWID, required signer authority). |
| ta/qcom_pas/include/pas_meta.h | Declares metadata decoding and signed-region copy construction. |
| ta/qcom_pas/include/pas_mbn_parser.h | Declares MBN hash-segment parser and parsed structure. |
| ta/qcom_pas/include/pas_mbn_parser_priv.h | Shares MBN format constants/helpers between parser and metadata code. |
| ta/qcom_pas/include/pas_fuse.h | Declares fuse PTA wrapper API (stubbed when disabled). |
| ta/qcom_pas/include/pas_auth.h | Declares authentication backend API (stubbed when disabled). |
| lib/libutee/include/pta_qcom_pas.h | Adds PTA_QCOM_PAS_VERIFY_IMAGE command definition and param contract. |
| lib/libutee/include/pta_qcom_fuse.h | Defines fuse PTA UUID and command IDs/ABI. |
| lib/libmbedtls/include/mbedtls_config_uta.h | Enables mbedTLS features needed for RSASSA-PSS chain verification. |
| core/pta/qcom/sub.mk | Adds fuse PTA build knob and subdir wiring. |
| core/pta/qcom/pas/sub.mk | Links core-side auth verification code when CFG_QCOM_PAS_AUTH is enabled. |
| core/pta/qcom/pas/pta_qcom_pas.c | Adds VERIFY_IMAGE dispatch and fixes capability passthrough. |
| core/pta/qcom/pas/platform/platform_pas.h | Declares pas_platform_verify_image() with stubs when auth disabled. |
| core/pta/qcom/pas/platform/pas_subsys.h | Exposes pas_lookup() for shared subsystem resolution. |
| core/pta/qcom/pas/pas_core.c | Exposes pas_lookup() and clears cached carveout coordinates on shutdown. |
| core/pta/qcom/pas/pas_auth_core.h | Declares core-side per-segment verification context/API. |
| core/pta/qcom/pas/pas_auth_core.c | Implements carveout mapping + ELF/segment digest verification and pas_platform_verify_image(). |
| core/pta/qcom/fuse/sub.mk | Adds build rule for the new fuse PTA. |
| core/pta/qcom/fuse/pta_qcom_fuse.c | Implements fuse PTA commands and restricts access to qcom_pas TA only. |
| core/include/drivers/qcom/qfprom/qfprom.h | Declares secboot/QFPROM accessor APIs used by fuse PTA. |
| core/drivers/qcom/qfprom/qfprom_core.c | Implements secboot fuse accessors, ARB read/advance, device ID reads, MRC state, and SoC HW version read. |
| core/drivers/qcom/qfprom/lemans/qfprom_target.h | Adds lemans-specific fuse/register layout definitions for secboot features. |
| core/drivers/qcom/qfprom/kodiak/qfprom_target.h | Adds kodiak-specific fuse/register layout definitions for secboot features. |
| core/arch/arm/plat-qcom/hoya/lemans/target.mk | Enables PAS auth by default on lemans and forces fuse PTA/QFPROM dependencies. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
71e667a to
721ac7c
Compare
Sumit Garg (@b49020) — "Rebase to tip of qcom-next": Done. Rebased and the seven-commit "PR#20-only" delta view is still available |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 37 out of 37 changed files in this pull request and generated 2 comments.
Suppressed comments (2)
ta/qcom_pas/src/pas_sig_auth.c:380
- The authentication path returns success without enforcing or advancing
meta.anti_rollback. The field is only parsed inpas_meta.c:268; there is no fuse PTA command or QFPROM implementation for reading/updating an ARB version. Consequently, a correctly signed older image passes despite the PR's anti-rollback guarantee. Add the SW_ID-to-ARB-fuse policy plus fail-closed version comparison and update after signature/binding verification.
ta/qcom_pas/src/pas_policy.c:47 - This policy omits PAS ID 33, although Lemans registers
PAS_ID_CAMERAincore/pta/qcom/pas/platform/lemans/subsys.c:82. On secure-boot devices,reject_if_double_signed()calls this map first, receivesTEE_ERROR_NOT_SUPPORTED, and prevents camera firmware from reaching authentication or boot. Add the camera PAS ID with its correct signed SW_ID, or explicitly exclude that subsystem from the advertised auth flow.
1b568be to
713bbee
Compare
|
I have rebased this PR on #19 which is now merged to qcom-next. Tony J Hamilton (@TonyJH1) / Jorge A. Ramirez-Ortiz (@ldts) / Akhilesh Kumar Verma (@slategrey-vision-pwrf168), Please help to review & let me know if you have any other comments in this PR. |
713bbee to
8fc8952
Compare
8d235f5 to
60b16b6
Compare
The carveout base and size come from the REE, so the range must be proven non-secure memory before it is mapped for hashing, and the REE writes it outside this mapping's coherency domain, so hashing could otherwise see a stale cached copy. Also reject an ELF with inconsistent header geometry, so segment collection cannot run on a malformed image. Signed-off-by: Selvam Sathappan Periakaruppan <speriaka@qti.qualcomm.com> Assisted-by: Claude:sonnet-5
The secure-boot fuse accessors need per-target register offsets, masks and layout to operate. Keep the Lemans values as driver platform data so a future target only needs its own register layout, not a copy of the reader code. Signed-off-by: Selvam Sathappan Periakaruppan <speriaka@qti.qualcomm.com> Assisted-by: Claude:sonnet-5
Signature authentication has to bind an image to the device it runs on, which requires the OEM root-of-trust anchor and enable state, the device identity, and the EKU and image-encryption enforcement fuses. They are gated on CFG_QCOM_FUSE_PTA so a target without the fuse PTA carries none of this code. No caller reads them yet. Signed-off-by: Selvam Sathappan Periakaruppan <speriaka@qti.qualcomm.com> Assisted-by: Claude:sonnet-5
The secure-boot fuse readers live in the OP-TEE core, but the PAS TA that needs them runs in user space. Expose them through a pseudo-TA restricted to a REE_KERNEL-only login domain, so the TA can obtain fuse-backed values without a driver dependency of its own. Signed-off-by: Selvam Sathappan Periakaruppan <speriaka@qti.qualcomm.com> Assisted-by: Claude:sonnet-5
Signature authentication binds an image to its device and enforces anti-rollback using fields in the OEM metadata block. Decode them into typed values so the authentication backend never re-parses the raw block. Metadata version and root_cert_sel are readable on their own, because each selects the hash size the full parse needs as input. The OEM-signed region masks out the QTI-controlled fields, so the signature covers exactly what the OEM signed. Signed-off-by: Selvam Sathappan Periakaruppan <speriaka@qti.qualcomm.com> Assisted-by: Claude:sonnet-5
The signature-authentication path makes several fuse reads per image, so hold one fuse-PTA session per TA session rather than opening one per read, matching how the TA already holds its PAS PTA session. The helper applies no policy and fails closed: a read failure propagates instead of substituting a default, so an untrustworthy fuse value aborts authentication rather than silently weakening it. Signed-off-by: Selvam Sathappan Periakaruppan <speriaka@qti.qualcomm.com> Assisted-by: Claude:sonnet-5
Segment-hash verification proves an image matches its own digest table; it cannot prove who signed it or that it is permitted on this device, so establish provenance before the peripheral leaves reset. The fuse read selecting this path fails closed: an error means secure boot enabled, so a transient failure cannot downgrade a fused board to hash-only verification. UIE-encrypted and QTI-countersigned images are refused, as neither is implemented here, and the chain is limited to one ECDSA P-384 root. Signed-off-by: Selvam Sathappan Periakaruppan <speriaka@qti.qualcomm.com> Assisted-by: Claude:sonnet-5
…cation Signature authentication reads fuses at runtime, so CFG_QCOM_PAS_AUTH alone is not enough: the fuse PTA, the qfprom driver behind it, and the CMD_DB/RPMH client its write path needs must all come up with it. Fold the existing fuse-provisioning enable into the same block so it and the new fuse-PTA consumer share one QFPROM enable and cannot drift apart. Signed-off-by: Selvam Sathappan Periakaruppan <speriaka@qti.qualcomm.com> Assisted-by: Claude:sonnet-5
105b0d6 to
b6a5c63
Compare
|
This PR is being tracked upstream here for further review -> OP-TEE/optee_os#7937. Closing this PR in qcom-next which is based on qcom-next version of hash-verify (#19) since the upstream optee version of hash-verify (OP-TEE/optee_os#7885) has been refactored quite a bit post that & it'd make sense to track this PR further in upstream. |
Stacked on PR #19, which added segment-hash verification. Segment hashing
proves an image matches its own digest table, but not that the image was
signed by a trusted party or is permitted on this device. On a fused
secure-boot Lemans device this PR establishes the image's provenance at
INIT_IMAGE, before the REE loads any segment: OEM certificate chain,
signature, and SW/HW device bindings, all anchored to hardware
fuses. Enabled under the same
CFG_QCOM_PAS_AUTHknob as PR #19.Multi-root certificates and anti-rollback enforcement are not part of this
series; both are added in a stacked follow-up, PR #35.
Devices whose secure-boot fuse is unblown skip signature authentication and
rely on PR #19's segment-hash verification alone; segment re-hashing at
AUTH_AND_RESET runs on every device regardless.
Design
Authentication forks on a single fuse read of the secure-boot state and
root-of-trust anchor, and that read fails closed: a fuse-PTA error is
treated as secure-boot enabled, so a transient glitch can never downgrade a
secure-booted board to hash-only verification.
The crypto runs in the
qcom_pasuser-TA (mbedTLS-backed cert-chain andsignature verification); fuses are reached through a dedicated fuse PTA so the
TA needs no direct driver dependency. UIE-encrypted and QTI-countersigned
images are refused outright — neither decryption nor countersignature
verification is implemented here.
sequenceDiagram participant REE as REE (Linux) participant TA as qcom_pas TA participant FPTA as fuse PTA participant PTA as PAS PTA Note over REE,PTA: INIT_IMAGE - signature authentication (secure-boot devices) REE->>TA: INIT_IMAGE(pas_id, metadata_blob) TA->>PTA: PTA_QCOM_PAS_INIT_IMAGE PTA-->>TA: TEE_SUCCESS TA->>TA: pas_auth_save_metadata()<br/>TEE-private copy keyed by pas_id TA->>FPTA: read secure-boot state + root-of-trust anchor FPTA-->>TA: secboot_on, anchor<br/>(read error is treated as secboot_on) alt secure boot enabled TA->>TA: pas_mbn_parse() extracts hash_table TA->>FPTA: read device id fuses FPTA-->>TA: fuse values TA->>TA: verify cert chain vs fused anchor TA->>TA: verify signature over OEM-signed region TA->>TA: enforce SW/HW bindings else secure boot disabled TA->>TA: pas_mbn_parse() extracts hash_table<br/>(no signature auth) end TA-->>REE: TEE_SUCCESS (or TEE_ERROR_SECURITY on any failure) Note over REE,PTA: MEM_SETUP + REE segment load (unchanged from PR 19) Note over REE,PTA: AUTH_AND_RESET - segment hash verification + release REE->>TA: AUTH_AND_RESET(pas_id, fw_base, fw_size) TA->>PTA: PTA_QCOM_PAS_VERIFY_IMAGE with metadata and hash_table PTA->>PTA: re-hash each PT_LOAD segment vs hash_table entry PTA-->>TA: TEE_SUCCESS TA->>PTA: PTA_QCOM_PAS_AUTH_AND_RESET PTA-->>TA: TEE_SUCCESS peripheral released from reset TA-->>REE: TEE_SUCCESSTesting
PLATFORM=qcom-lemans CFG_QCOM_PAS_AUTH=y CFG_WERROR=y; checkpatchclean across the series.
cert-chain break, and SW/HW-binding mismatch are each rejected and the
peripheral stays in reset;
enforced.