fix(dispatch): forge AUTO attestation requests

Plain attestation (Use-attest-key OFF, challenge present) on an AUTO-mode target was routed to PATCH, deferring to the real TEE. The AUTO probe (checkTeeFunctionality) only proves the device can mint one EC key, so devices that cannot attest RSA or device-ID, or whose patched chain fails RSA verify, surfaced as KeyAttestation reds (ATTESTATION_KEYS_NOT_PROVISIONED/-49, BLOCK_TYPE_IS_NOT_01).

Forge these from the keybox instead, gated on isAutoMode + attestationChallenge, matching the attest-key-ON path that already yields a green Google-rooted chain. Non-attestation keys still pass through to real hardware, so KeyDetector hardware-backed checks are unaffected.

Verified offline against real FORGE captures with scripts/keyatt_conformance.py: uid10389/uid10154 chains are GREEN and the root SPKI byte-matches GOOGLE_ROOT_PUBLIC_KEY.
This commit is contained in:
Enginex0
2026-06-19 14:22:56 +01:00
parent af3c27451d
commit b2d84b4661
@@ -713,12 +713,16 @@ class KeyMintSecurityLevelInterceptor(
// Device-ID attestation must be forged, not patched: the real TEE returns
// CANNOT_ATTEST_IDS, so there is no real chain to patch — only a synthetic one
// carrying the requested IDs and rooted under the keybox will satisfy the caller.
// AUTO attestation forges from the keybox instead of trusting the EC-only TEE
// probe, which cannot tell whether the device can attest RSA / device-ID / StrongBox.
val forceGenerate =
oversized ||
ConfigurationManager.shouldGenerate(callingUid) ||
isAttestKeyRequest ||
attestationKey != null ||
hasDeviceIdAttestation
hasDeviceIdAttestation ||
(ConfigurationManager.isAutoMode(callingUid) &&
parsedParams.attestationChallenge != null)
SystemLogger.trace {
"[TRACE-$txId] dispatch: forceGen=$forceGenerate hasChallenge=${challenge != null} isSymmetric=$isSymmetric isAttestKey=$isAttestKeyRequest"