ta: qcom_pas: anti-rollback enforcement and multi-root certificate selection - #35
Draft
Selvam Sathappan (zelvam95) wants to merge 17 commits into
Draft
ta: qcom_pas: anti-rollback enforcement and multi-root certificate selection#35Selvam Sathappan (zelvam95) wants to merge 17 commits into
Selvam Sathappan (zelvam95) wants to merge 17 commits into
Conversation
Selvam Sathappan (zelvam95)
force-pushed
the
feature/pil-arb-mrc
branch
3 times, most recently
from
August 11, 2026 11:02
e2cbc40 to
224faa9
Compare
A stale carveout could be reused across peripheral loads: shutdown did not clear the cached MEM_SETUP coordinates, so a subsystem that was stopped and reloaded without a fresh MEM_SETUP call would pass the resulting VERIFY_IMAGE cross-check against physical memory it no longer owns. qcom_pas_capabilities() also passed the wrong parameter to pas_platform_capabilities(), reading the output flags field instead of the caller-supplied pas_id. Fix both ahead of the authentication work that builds on this code, along with unrelated include and logging cleanup, so the feature commits that follow stay focused on the feature. pas_lookup() is exported for the same reason: later commits need it directly. Signed-off-by: Selvam Sathappan Periakaruppan <speriaka@qti.qualcomm.com> Assisted-by: Claude:sonnet-5
PIL firmware images carry a Qualcomm MBN hash segment holding the per-segment digest table, signature and certificate material the PAS TA needs to authenticate an image before releasing the peripheral from reset. The segment is located by scanning the program-header table for the Qualcomm hash-segment flag rather than assuming a fixed offset, so a malformed image is rejected up front instead of being parsed at the wrong bytes. Parse it once into a single typed view so the hash- and signature-verification work that follows shares one source of truth for where each region starts, rather than each phase re-walking the raw metadata buffer and risking disagreement. Signed-off-by: Selvam Sathappan Periakaruppan <speriaka@qti.qualcomm.com> Assisted-by: Claude:sonnet-5
Segment-hash verification is the half of PIL firmware authentication that stands on its own and can be enabled and stress-tested before any signature work exists, so it lives in a self-contained module that does not pull in the wider PAS command dispatch. Add a VERIFY_IMAGE command that re-hashes each loaded segment against the image's own digest table, so a compromised REE cannot substitute firmware after the metadata has already been accepted. MEM_SETUP is a hard precondition, so the check runs against platform-validated memory rather than an attacker-chosen physical address. A segment's zero-init tail is bounds-checked and zeroed before hashing so stale REE bytes there cannot slip through the digest or run uninitialised after reset, and an image with no hashed loadable segment is rejected rather than launched on an entry-0-only check. Signed-off-by: Selvam Sathappan Periakaruppan <speriaka@qti.qualcomm.com> Assisted-by: Claude:sonnet-5
Segment-hash verification exists in the PTA but nothing invokes it yet. Wire the PAS TA to drive it around the existing PTA calls, keeping qcom_pas.c a thin dispatch layer by moving the logic into a new backend module: the TA saves a TEE-private copy of the REE-supplied metadata at INIT_IMAGE and hands [metadata | hash table] to the PTA's VERIFY_IMAGE at reset time, so the REE cannot alter the metadata it already committed to between the two calls. INIT_IMAGE invokes the PTA before stashing metadata so a failed PTA call cannot leak a per-pas_id session slot; per-session state is keyed by pas_id so concurrent DSP loads on one session do not clobber each other. Signature authentication is left as a placeholder here so segment-hash verification can be reviewed and enabled without waiting on it. Signed-off-by: Selvam Sathappan Periakaruppan <speriaka@qti.qualcomm.com> Assisted-by: Claude:sonnet-5
Enable CFG_QCOM_PAS_AUTH on Lemans so PIL images are authenticated before the peripheral leaves reset. Segment-hash verification takes effect immediately; signature authentication is a runtime step that only engages once secure-boot fuses are blown, and is filled in later in this series. 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 means reading the OEM root-of-trust anchor and enable state, device identity, and EKU/image-encryption enforcement fuses. Add those readers to the qfprom driver as straight reads over the SECURITY_CONTROL window the driver already owns. They are placed in a separate qfprom_secboot.c compiled only under CFG_QCOM_FUSE_PTA, so a target that does not build the fuse PTA carries none of this code and the platform-independent core driver keeps no dependency on it. Nothing reads these until the fuse PTA is turned on in a later commit, so existing paths are unaffected. 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. Add a pseudo-TA that exposes each reader as a command, 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 carried in the OEM metadata block of the MBN hash segment. Add a decoder that lifts those fields into typed values so the authentication backend does not re-parse the raw block itself. It also exposes the early peeks the backend needs before full parsing (metadata version, to reject rollback; root_cert_sel, to pick the segment hash size) and materialises the OEM-signed region with the QTI-controlled fields masked out, so the signature covers exactly what the OEM signed. Nothing calls it until the signature- authentication commit that follows. 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. Wrap the fuse PTA in a helper that opens one session per TA session, matching how the TA already holds its PAS PTA session, rather than opening one per call, and that maps each read one-to-one onto a fuse PTA command. The helper applies no policy and fails closed: every read returns a TEE_Result and propagates a fuse access failure to the caller instead of substituting a default, so a fuse value that cannot be trusted aborts authentication rather than silently weakening it. Nothing calls the helpers yet. Signed-off-by: Selvam Sathappan Periakaruppan <speriaka@qti.qualcomm.com> Assisted-by: Claude:sonnet-5
Segment-hash verification alone proves an image matches its own digest table; it cannot prove the image was signed by a trusted party or is permitted on this device. Replace the signature-authentication placeholder with the real implementation, so that on a fused secure-boot device the PAS TA establishes an image's provenance before the peripheral is released from reset. The decision 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 failure can never downgrade a secure-booted board to hash-only verification. When secure boot is on, the TA verifies the OEM certificate chain against the fused anchor, verifies the signature over the OEM-signed region, and enforces the SW and HW bindings against the fused device identity. UIE-encrypted images and QTI-countersigned images are refused outright, since neither decryption nor countersignature verification is implemented here. Devices whose secure-boot fuse is unblown skip this path entirely and rely on segment-hash verification alone. The chain is verified against a single provisioned root (ECDSA P-384 leaves, SHA-384). The crypto, orchestration and per-peripheral SW_ID policy are split into three file pairs. Signed-off-by: Selvam Sathappan Periakaruppan <speriaka@qti.qualcomm.com> Assisted-by: Claude:sonnet-5
The secure-boot fuse accessors added in the previous commit need per-target register offsets, masks and layout to operate: the SECURE_BOOT and device-identity sense registers, the root-of-trust digest size, and the OEM_CONFIG2/OEM_CONFIG0 fields the EKU, segment- hash-select and image-encryption checks read. Add the Lemans values as driver platform data, kept separate from the accessor logic 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
…cation Signature authentication reads device fuses at runtime, so enabling CFG_QCOM_PAS_AUTH is not enough on its own - the fuse PTA and the qfprom driver behind it (and the CMD_DB/RPMH client its fuse-write path needs) have to come up with it. Force that whole chain from CFG_QCOM_PAS_AUTH so a stock Lemans build brings up the complete PAS authentication stack end to end. Fold the existing fuse-provisioning enable into the same block so provisioning 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
Add the read and blow-write accessors for the PIL subsystem anti-
rollback (ARB) fuse so a later PAS-TA change can reject firmware older
than the device floor and advance that floor when a newer image is
authenticated.
The device version is the popcount of a unary ("thermometer") encoding
spread across two corrected-space fuse banks (LSB 32 bits, MSB 28
bits); the read sums both popcounts and the blow-write ORs in the extra
bits, keeping the fuse monotonic. Both accessors fail closed: they
report version 0 (enforcement off) unless secure boot and the PIL ARB
enable fuse are both blown, and the blow-write is additionally gated on
CFG_QFPROM_PROGRAMMING.
Signed-off-by: Selvam Sathappan Periakaruppan <speriaka@qti.qualcomm.com>
Assisted-by: Claude:sonnet-5
Add qcom_secboot_get_mrc_info() so a later PAS-TA change can enforce which provisioned root certificate a signed image is allowed to chain to. It reports how many roots are provisioned (OEM_CONFIG0 ROOT_CERT_TOTAL_NUM, encoded as count-1) and the per-index activation/revocation bitmaps. Root selection only exists when the anchor is fuse-resident (PK_HASH_IN_FUSE) and more than one root is provisioned; otherwise the accessor reports the single-root default (num_roots 1, empty lists) so a single-root device needs no MRC handling. Signed-off-by: Selvam Sathappan Periakaruppan <speriaka@qti.qualcomm.com> Assisted-by: Claude:sonnet-5
Wire the three new secboot accessors into the fuse PTA so the qcom_pas TA can reach them: read and blow-write the PIL anti-rollback version, and read the multi-root-certificate provisioning state. The command IDs are appended (9, 10, 11) after the existing secure-boot fuse commands. The blow-write is the PTA's only mutating command; the open-session restriction (qcom_pas TA only) already covers it. Signed-off-by: Selvam Sathappan Periakaruppan <speriaka@qti.qualcomm.com> Assisted-by: Claude:sonnet-5
Add the qcom_pas TA-side wrappers over the new fuse-PTA commands: read and blow-write the PIL anti-rollback version, and read the multi-root- certificate provisioning state into struct pas_fuse_mrc_info. The MRC reader keeps the single-root default (num_roots=1, empty lists) when the PTA reports selection disabled, so a single-root caller sees no behavioural change; a fuse-PTA access failure is propagated as an error so callers fail closed. Signed-off-by: Selvam Sathappan Periakaruppan <speriaka@qti.qualcomm.com> Assisted-by: Claude:sonnet-5
Turn on the two authentication policies the preceding fuse plumbing
enables:
- Anti-rollback: after the image is authenticated, reject firmware
whose metadata anti_rollback version is below the device floor, then
advance the fuse when the image is newer. MBN v5 images (no OEM
metadata) and devices with ARB enforcement off skip the check.
- Multi-root selection: read the MRC provisioning state and verify the
OEM cert chain against the root the image's root_cert_sel nominates,
validating that index against the device activation/revocation lists
(pas_sig_check_root_cert_index()). A single-root device keeps the
previous behaviour: num_roots is 1, selection is skipped, and the
chain verifies against root 0.
Both fuse reads fail closed: a fuse-PTA error aborts authentication
rather than falling back to a permissive default.
Signed-off-by: Selvam Sathappan Periakaruppan <speriaka@qti.qualcomm.com>
Assisted-by: Claude:sonnet-5
Selvam Sathappan (zelvam95)
force-pushed
the
feature/pil-arb-mrc
branch
from
August 12, 2026 03:26
224faa9 to
87845ab
Compare
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
Builds on the PAS firmware-authentication work to add two hardware-backed
security enforcements to the image authentication path:
Anti-rollback (ARB): rejects firmware whose rollback version is older
than the value fused on the device, and advances the on-device fuse version
when a newer, successfully-authenticated image is loaded. This prevents an
attacker from downgrading a peripheral to a known-vulnerable signed image.
Multi-root certificate (MRC) selection: allows the signed image's
certificate chain to be validated against one of several provisioned root
certificates, honoring the fuse-programmed activation/revocation state so a
revoked root can no longer authorize firmware.
Both features extend the existing chain: QFPROM driver accessors expose the
relevant fuses, the fuse PTA surfaces them to the TA, and the PAS TA consumes
them during authentication. When the relevant fuses are unprovisioned the
behavior is unchanged from the base authentication flow (single root, no
rollback enforcement), so this is additive and backward compatible.
Dependencies / stacking
This PR is stacked and must be reviewed/merged in order:
Please set/keep the base branch of this PR to
feature/qcom-pas-sig-authso the diff shows only the ARB/MRC changes. It should be merged only after
#19 and #20. New fuse-PTA command IDs added here are appended contiguously
after PR2's set (no renumbering of existing commands).
Testing
PLATFORM=qcom PLATFORM_FLAVOR=lemanswithCFG_QCOM_PAS_AUTH=yand=n,CFG_WERROR=y, zero warnings.