Root Cause
Platform TCB matching uses Rust's .zip() iterator to compare cpu_svn bytes (16 bytes extracted from the PCK certificate) against sgx_components (deserialized from Intel's TCB Info JSON). The .zip() adapter stops at the shorter of the two iterators, silently skipping any remaining elements:
// src/verify.rs:509-516
let sgx_components: Vec<u8> = tcb_level.tcb.sgx_components.iter().map(|c| c.svn).collect();
if sgx_components.is_empty() {
bail!("No SGX components in the TCB info");
}
// Component-wise comparison: every cpu_svn[i] must be >= sgx_components[i]
if cpu_svn.iter().zip(&sgx_components).any(|(a, b)| a < b) {
continue;
}
The sgx_components field is deserialized as Vec<TcbComponents> (in tcb_info.rs:44-45) with no length validation — any number of components is accepted. The only guard is an is_empty() check, but there is no assertion that sgx_components.len() == cpu_svn.len() (i.e., 16).
The same pattern exists for TDX components at lines 530-534:
if td_report
.tee_tcb_svn
.iter()
.zip(&tdx_components)
.any(|(a, b)| a < b)
{
continue;
}
Notably, the JavaScript port of this library (verify.js:445-448) correctly validates array length equality before comparison:
function compareSvnArrays(actual, required) {
if (actual.length !== required.length) {
return false; // <-- explicit length check, absent in Rust
}
// ...
}
This confirms the issue was recognized as a concern in the JS implementation but missed in the Rust version.
Attack Path
- Attacker cannot directly modify Intel-signed TCB Info JSON. However, the library's correctness should not depend solely on Intel never making a mistake in collateral formatting.
- If Intel publishes TCB Info with fewer than 16
sgxtcbcomponents (e.g., during a format transition or version mismatch), SVN values at positions beyond the component count are never checked.
- A platform with outdated SVNs in those unchecked positions would incorrectly pass TCB matching and receive a better status than warranted.
Impact
If TCB Info contains fewer than 16 SGX components (or fewer TDX components than expected), CPU SVN / TEE TCB SVN values at positions beyond the component count are not validated. The library would accept a platform that should be classified at a lower TCB level. The TCB Info signature provides protection, but defense-in-depth requires the library to validate the invariant it depends on.
Suggested Fix
Add explicit length checks before the .zip() comparison:
if sgx_components.len() != cpu_svn.len() {
bail!(
"SGX component count mismatch: expected {}, got {}",
cpu_svn.len(),
sgx_components.len()
);
}
And for TDX:
if tdx_components.len() != td_report.tee_tcb_svn.len() {
bail!(
"TDX component count mismatch: expected {}, got {}",
td_report.tee_tcb_svn.len(),
tdx_components.len()
);
}
Note: This finding was reported automatically as part of an AI/Claude-driven internal audit by the NEAR One MPC team. It has not been manually verified by a human to confirm whether it constitutes an actual security issue.
Root Cause
Platform TCB matching uses Rust's
.zip()iterator to comparecpu_svnbytes (16 bytes extracted from the PCK certificate) againstsgx_components(deserialized from Intel's TCB Info JSON). The.zip()adapter stops at the shorter of the two iterators, silently skipping any remaining elements:The
sgx_componentsfield is deserialized asVec<TcbComponents>(intcb_info.rs:44-45) with no length validation — any number of components is accepted. The only guard is anis_empty()check, but there is no assertion thatsgx_components.len() == cpu_svn.len()(i.e., 16).The same pattern exists for TDX components at lines 530-534:
Notably, the JavaScript port of this library (
verify.js:445-448) correctly validates array length equality before comparison:This confirms the issue was recognized as a concern in the JS implementation but missed in the Rust version.
Attack Path
sgxtcbcomponents(e.g., during a format transition or version mismatch), SVN values at positions beyond the component count are never checked.Impact
If TCB Info contains fewer than 16 SGX components (or fewer TDX components than expected), CPU SVN / TEE TCB SVN values at positions beyond the component count are not validated. The library would accept a platform that should be classified at a lower TCB level. The TCB Info signature provides protection, but defense-in-depth requires the library to validate the invariant it depends on.
Suggested Fix
Add explicit length checks before the
.zip()comparison:And for TDX: