Skip to content

verifier/tdx: add a TDX quote verification backend with no external DCAP shared library#191

Merged
jialez0 merged 6 commits into
openanolis:mainfrom
jialez0:tdx-verifier-dual-backend
Jul 13, 2026
Merged

verifier/tdx: add a TDX quote verification backend with no external DCAP shared library#191
jialez0 merged 6 commits into
openanolis:mainfrom
jialez0:tdx-verifier-dual-backend

Conversation

@jialez0

@jialez0 jialez0 commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

What

TDX quote verification depends on the Intel DCAP shared library
(libsgx_dcap_quoteverify), reached through the intel-tee-quote-verification-rs
FFI bindings plus its dynamically loaded quote provider for PCCS collateral.

This PR makes the TDX quote-verification backend selectable at compile time
and adds a second backend that needs no external DCAP shared library. The
default build is unchanged
and still links libsgx_dcap_quoteverify exactly as
before.

Backends

feature backend external shared lib toolchain
tdx-dcap-ffi (default) Intel DCAP QVL via FFI (existing code, moved verbatim) libsgx_dcap_quoteverify + quote provider Rust 1.76
tdx-dcap-rust (opt-in) dcap-qvl (ring crypto backend) none Rust 1.76

tdx-verifier is now an umbrella that no longer implies a backend; a backend
feature must be selected, and enabling it without one is a clear
compile_error!. all-verifier, az-tdx-vtpm-verifier and the
attestation-service passthroughs all resolve to tdx-dcap-ffi, so every
existing build path (dist/, Dockerfiles, RPM) keeps using the DCAP shared
library. A new all-verifier-rust / make VERIFIER=all-verifier-rust builds
the shared-library-free variant.

The tdx-dcap-rust backend

  • Uses only dcap-qvl's offline verify (the report feature, which would pull
    in reqwest 0.13 / aws-lc-sys, is left off); collateral is fetched over
    HTTPS with the verifier's existing reqwest.
  • Returns the same TcbVerificationResult as the FFI backend, including
    tcb_level_date_tag, recovered by reproducing Intel QVL's TCB-level matching
    (SGX TCB components + PCE SVN from the PCK certificate, TDX TEE TCB SVN from
    the TD report).
  • Matches the FFI backend's "defer to policy" behaviour: debug / service TDs and
    expired collateral are non-fatal (expiry is still reported via
    collateral_expired). Expiry tolerance uses a small allow_expired option
    added in the dcap-qvl fork — this matters because the Alibaba Cloud PCCS
    mirror serves stale TCB info for some FMSPCs.
  • Resolves the PCCS URL from PCCS_URL, then /etc/sgx_default_qcnl.conf
    (the same file the DCAP quote provider reads, so both backends share one
    configuration), then a built-in default.
  • Currently supports quotes that embed the PCK chain (PCK cert type 5), i.e.
    cloud TDX quotes.

Same toolchain as the default build (Rust 1.76)

dcap-qvl's dependency tree otherwise pulls edition-2024 / high-MSRV crates. The
backend is brought down to Rust 1.76 (matching the default build and CI) by
using ring (MSRV 1.66, still no external shared library) instead of the
RustCrypto stack, plus a few MSRV fixes in the dcap-qvl fork (drop an unused
wasm-bindgen-futures dep, cap parity-scale-codec/derive_more, enable
anyhow/std, avoid a 1.80-only slice API) and keeping the transitive
crypto/x509 crates pinned in Cargo.lock.

The dcap-qvl fork (based on Phala-Network/dcap-qvl v0.4.1) is patched in via
[patch.crates-io], consistent with the repo's other git dependencies:
https://github.com/jialez0/dcap-qvl/tree/v0.4.1-allow-expired

Validation

  • cargo +1.76 check --features tdx-dcap-ffi --locked — default build compiles,
    behaviour unchanged, dcap-qvl subtree pruned.
  • cargo +1.76 test --features tdx-dcap-rust and
    restful-as/grpc-as --features all-verifier-rust — the shared-library-free
    path builds and its unit tests pass on Rust 1.76.
  • Against real TDX quotes + PCCS, the tdx-dcap-rust backend reproduces the
    expected TCB status, advisory IDs and tcb_level_date_tag, and tolerates a
    stale-collateral FMSPC.
  • End to end on real Intel TDX hardware: swapping the pure-Rust grpc-as
    into a live Trustee stack and running
    attestation-agent-client get-token --token-type coco_as yields an EAR token
    whose verdict (status + trustworthiness vector) is identical to the DCAP FFI
    backend's.

jialez0 added 3 commits July 9, 2026 17:34
Extract the ECDSA quote-verification step out of tdx::quote into a new
tdx::verify module so that the backend can be selected at compile time.
Today there is exactly one backend, tdx-dcap-ffi, which contains the
existing Intel DCAP QVL (libsgx_dcap_quoteverify) FFI implementation
moved verbatim; behaviour is unchanged.

The tdx-verifier feature no longer implies a backend: a backend feature
(currently only tdx-dcap-ffi) must be enabled, and enabling tdx-verifier
without one is a clear compile_error. all-verifier, az-tdx-vtpm-verifier
and the attestation-service passthroughs are wired to tdx-dcap-ffi, so
every default build keeps using the DCAP shared library exactly as before.

This is groundwork for a second, pure-Rust backend (tdx-dcap-rust).

Signed-off-by: Jiale Zhang <zhangjiale@linux.alibaba.com>
Add tdx-dcap-rust, a second TDX quote-verification backend built on the
pure-Rust dcap-qvl crate. It removes the dependency on the Intel DCAP
shared library (libsgx_dcap_quoteverify) and its dynamically loaded quote
provider: the ECDSA signature, PCK certificate chain, TCB info and QE
identity are all verified in Rust, and verification collateral is fetched
over HTTPS from a PCCS using the verifier's existing reqwest stack (the
dcap-qvl 'report' feature, which would pull in reqwest 0.13 / aws-lc-sys,
is deliberately left off).

The returned TcbVerificationResult is populated to match the FFI backend,
including tcb_level_date_tag, which is recovered by reproducing Intel QVL's
TCB-level matching over the platform TCB (SGX TCB components + PCE SVN from
the PCK certificate, TDX TEE TCB SVN from the TD report). Debug / service
TDs are accepted and left to the policy engine, matching the FFI backend;
expired collateral remains a hard error (dcap-qvl is stricter than the FFI
QVL here) but is still surfaced via collateral_expired.

Notes:
- Opt-in only. The default build keeps using tdx-dcap-ffi; with this
  feature disabled, Cargo prunes the whole dcap-qvl subtree, so the
  default build's toolchain requirement (Rust 1.76) is unchanged. Building
  this backend itself requires a newer toolchain (Rust >= 1.86) because
  dcap-qvl's dependency tree uses edition 2024.
- Collateral fetch currently supports quotes that embed the PCK chain
  (PCK cert type 5), i.e. cloud TDX quotes.
- Verified end to end against a real TDX quote and PCCS: the backend
  reproduces the expected TCB status, advisory IDs and tcb_level_date_tag.

Signed-off-by: Jiale Zhang <zhangjiale@linux.alibaba.com>
Add attestation-service feature passthroughs for the pure-Rust TDX quote
verification backend:

  * tdx-dcap-rust      -> verifier/tdx-dcap-rust
  * all-verifier-rust  -> verifier/all-verifier-rust (all verifiers, TDX on
                          the pure-Rust backend, SGX dropped)

and document how to build it via the Makefile:

    make VERIFIER=all-verifier-rust

The default (VERIFIER=all-verifier) is unchanged and still selects the DCAP
shared-library backend, so the dist/, Docker and RPM builds keep linking
libsgx_dcap_quoteverify exactly as before.

Signed-off-by: Jiale Zhang <zhangjiale@linux.alibaba.com>
@shankailun-aliyun

Copy link
Copy Markdown
Collaborator

@jialez0 ,您好,您的请求已接收,请耐心等待结果。

@shankailun-aliyun

Copy link
Copy Markdown
Collaborator

@jialez0 ,您好,未检测到有镜像需要构建,如需重新检测请评论 /start

Match the FFI (DCAP QVL) backend, which reports expired collateral via a
flag and defers the decision to the policy engine, instead of hard-failing.
Upstream dcap-qvl always rejects TCB info / QE identity whose nextUpdate is
in the past, which diverges from the FFI backend and, in practice, breaks
verification whenever the configured PCCS serves stale collateral for a
platform's FMSPC (observed on the Alibaba Cloud PCCS mirror).

Point the tdx-dcap-rust backend at a small dcap-qvl fork that adds a
QuoteVerifier::allow_expired option (signatures and certificate chains are
still fully verified; only the freshness check is relaxed) via
[patch.crates-io], and enable it. The true expiry is still reported to the
policy through the collateral_expired claim.

The fork branch is based on Phala-Network/dcap-qvl v0.4.1:
  https://github.com/jialez0/dcap-qvl/tree/v0.4.1-allow-expired

The patch is inert for the default build, which does not enable
tdx-dcap-rust and never compiles dcap-qvl.

Signed-off-by: Jiale Zhang <zhangjiale@linux.alibaba.com>
@shankailun-aliyun

Copy link
Copy Markdown
Collaborator

@jialez0 ,您好,您的请求已接收,请耐心等待结果。

@shankailun-aliyun

Copy link
Copy Markdown
Collaborator

@jialez0 ,您好,未检测到有镜像需要构建,如需重新检测请评论 /start

jialez0 added 2 commits July 10, 2026 11:47
The pure-Rust backend previously required a newer toolchain (>= 1.86) than
the default (FFI) build's Rust 1.76, because dcap-qvl's dependency tree pulls
edition-2024 / high-MSRV crates. Bring it down to 1.76 so both backends and
CI share one toolchain:

* Use dcap-qvl's `ring` crypto backend instead of `rustcrypto`. `ring` (MSRV
  1.66) still links no external shared library, and avoids the RustCrypto
  stack (ed25519-dalek etc.) whose recent releases need Rust >= 1.81.
* The dcap-qvl fork (patched in for allow_expired) additionally: drops an
  unused wasm-bindgen-futures dep, caps parity-scale-codec to <3.7 and
  derive_more to <2.1, enables anyhow/std, and avoids a 1.80-only slice API.
* The shared Cargo.lock keeps the transitive crypto/x509 crates at their
  1.76-compatible versions (base64ct 1.6, zeroize 1.8, indexmap 2.7,
  parity-scale-codec 3.6, ...).

The default (FFI) build is unchanged: with tdx-dcap-rust disabled the whole
dcap-qvl subtree is pruned. Also fixes rustfmt import ordering in tdx/mod.rs.

Signed-off-by: Jiale Zhang <zhangjiale@linux.alibaba.com>
The pure-Rust backend read the PCCS endpoint only from the PCCS_URL
environment variable, defaulting otherwise to a built-in URL. That diverges
from the FFI backend, whose quote provider reads /etc/sgx_default_qcnl.conf,
so on a host configured for FFI the two backends would talk to different
PCCS servers unless PCCS_URL was also set.

Fall back to the qcnl.conf 'pccs_url' when PCCS_URL is unset, so both
backends share one configuration. Both the JSON ({"pccs_url": "..."}) and
legacy INI (PCCS_URL=...) forms are supported; unit-tested.

Signed-off-by: Jiale Zhang <zhangjiale@linux.alibaba.com>
@shankailun-aliyun

Copy link
Copy Markdown
Collaborator

@jialez0 ,您好,您的请求已接收,请耐心等待结果。

@shankailun-aliyun

Copy link
Copy Markdown
Collaborator

@jialez0 ,您好,未检测到有镜像需要构建,如需重新检测请评论 /start

@jialez0 jialez0 changed the title verifier/tdx: add a pure-Rust (dcap-qvl) quote verification backend alongside the DCAP FFI one verifier/tdx: add a TDX quote verification backend with no external DCAP shared library Jul 10, 2026
@shankailun-aliyun

Copy link
Copy Markdown
Collaborator

@jialez0 ,您好,您的请求已接收,请耐心等待结果。

@shankailun-aliyun

Copy link
Copy Markdown
Collaborator

@jialez0 ,您好,未检测到有镜像需要构建,如需重新检测请评论 /start

@jialez0
jialez0 merged commit b4c7e82 into openanolis:main Jul 13, 2026
5 checks passed
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.

2 participants