Skip to content

ta/pta: qcom: pas: authenticate PIL firmware signatures and device bindings - #20

Closed
Selvam Sathappan (zelvam95) wants to merge 8 commits into
qualcomm-linux:qcom-nextfrom
zelvam95:feature/qcom-pas-sig-auth
Closed

ta/pta: qcom: pas: authenticate PIL firmware signatures and device bindings#20
Selvam Sathappan (zelvam95) wants to merge 8 commits into
qualcomm-linux:qcom-nextfrom
zelvam95:feature/qcom-pas-sig-auth

Conversation

@zelvam95

@zelvam95 Selvam Sathappan (zelvam95) commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

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_AUTH knob 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_pas user-TA (mbedTLS-backed cert-chain and
signature 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_SUCCESS
Loading

Any failure — cert-chain break, signature mismatch, or an SW/HW-binding
mismatch — fails INIT_IMAGE with TEE_ERROR_SECURITY;
the image is never loaded and the peripheral is never released from reset.

Testing

  • Built PLATFORM=qcom-lemans CFG_QCOM_PAS_AUTH=y CFG_WERROR=y; checkpatch
    clean across the series.
  • On a Lemans board, both fuse configurations:
    • secure-boot on: positive path authenticates and boots; signature mismatch,
      cert-chain break, and SW/HW-binding mismatch are each rejected and the
      peripheral stays in reset;
    • secure-boot off: signature path skipped, segment-hash verification still
      enforced.

@zelvam95

Copy link
Copy Markdown
Contributor Author

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.
A clean 6-commit-only view is available at: zelvam95/optee_os-qcom_next@feature/qcom-pas-hash-verify...zelvam95:optee_os-qcom_next:feature/qcom-pas-sig-auth

@b49020

Copy link
Copy Markdown
Member

Rebase to tip of qcom-next

@zelvam95

Copy link
Copy Markdown
Contributor Author

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)

@zelvam95
Selvam Sathappan (zelvam95) force-pushed the feature/qcom-pas-sig-auth branch 2 times, most recently from da0584b to e5b5bf9 Compare July 30, 2026 11:00
@zelvam95
Selvam Sathappan (zelvam95) marked this pull request as ready for review July 30, 2026 12:25
@zelvam95

Copy link
Copy Markdown
Contributor Author

Hi Sumit Garg (@b49020) / Jorge A. Ramirez-Ortiz (@ldts),
Can you please help to review this PR & share your thoughts/comments?

The first 5 commits belong to #19. To get a view of changes part of this PR alone you can use below link:
zelvam95/optee_os-qcom_next@feature/qcom-pas-hash-verify...zelvam95:optee_os-qcom_next:feature/qcom-pas-sig-auth

This change is now tested in Secure Boot. Please help to review this!

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread ta/qcom_pas/src/pas_auth.c Outdated
Comment thread ta/qcom_pas/src/pas_sig.c Outdated
Comment thread ta/qcom_pas/src/pas_sig.c Outdated
Comment thread ta/qcom_pas/include/pas_sig_auth.h Outdated
Comment thread ta/qcom_pas/src/pas_sig_auth.c Outdated
Comment thread core/pta/qcom/pas/pas_auth_core.c Outdated
Comment thread ta/qcom_pas/src/pas_fuse.c Outdated
@zelvam95
Selvam Sathappan (zelvam95) force-pushed the feature/qcom-pas-sig-auth branch 9 times, most recently from 71e667a to 721ac7c Compare August 7, 2026 15:38
@zelvam95 Selvam Sathappan (zelvam95) changed the title qcom_pas: authenticate PIL firmware images and bind them to the device ta/pta: qcom: pas: authenticate PIL firmware signatures and device bindings Aug 7, 2026
@zelvam95

Copy link
Copy Markdown
Contributor Author

Rebase to tip of qcom-next

Sumit Garg (@b49020) — "Rebase to tip of qcom-next":

Done. Rebased and the seven-commit "PR#20-only" delta view is still available
at
zelvam95/optee_os-qcom_next@feature/qcom-pas-hash-verify...zelvam95:optee_os-qcom_next:feature/qcom-pas-sig-auth
for anyone reviewing PR#20 without checking out PR#19 first. Testing on
Lemans in both secure-boot and non-secure-boot fuse configurations is
complete (positive path + signature-mismatch + hash-segment-corruption all
rejected cleanly), as summarized in the PR description's Testing section.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 in pas_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_CAMERA in core/pta/qcom/pas/platform/lemans/subsys.c:82. On secure-boot devices, reject_if_double_signed() calls this map first, receives TEE_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.

Comment thread ta/qcom_pas/src/pas_sig_auth.c Outdated
Comment thread core/pta/qcom/pas/pas_auth_core.c
Comment thread ta/qcom_pas/src/pas_meta.c
Comment thread ta/qcom_pas/src/pas_auth.c Outdated
@zelvam95

Selvam Sathappan (zelvam95) commented Aug 13, 2026

Copy link
Copy Markdown
Contributor Author

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.

Comment thread core/drivers/qcom/qfprom/qfprom_secboot.c Outdated
Comment thread core/drivers/qcom/qfprom/qfprom_secboot.c
@zelvam95
Selvam Sathappan (zelvam95) force-pushed the feature/qcom-pas-sig-auth branch 2 times, most recently from 8d235f5 to 60b16b6 Compare August 14, 2026 07:30
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
@zelvam95
Selvam Sathappan (zelvam95) force-pushed the feature/qcom-pas-sig-auth branch 4 times, most recently from 105b0d6 to b6a5c63 Compare August 16, 2026 04:08
@zelvam95

Selvam Sathappan (zelvam95) commented Aug 19, 2026

Copy link
Copy Markdown
Contributor Author

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.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants