Align the attested version to the device's Keymaster HAL on legacy devices - #257
Conversation
…vices #247 clamps the attested attestationVersion to the KeyMint HAL version the device declares in VINTF, but Vintf only ever reads the AIDL KeyMint HAL (android.hardware.security.keymint.IKeyMintDevice). A device that ships the legacy Keymaster HIDL HAL instead -- android.hardware.keymaster/IKeymasterDevice/default@4.1 -- declares no KeyMint HAL, so keyMintHalVersion returns null, the clamp is a no-op, and the presented pair stays at whatever was captured or fabricated. On such a device that came out keymasterVersion=4/attestationVersion=3 (Keymaster 4.0), one minor version below the declared 4.1, and a checker that maps IKeymasterDevice@N to the attestation version a real device of that HAL reports (AOSP system/keymaster version_to_attestation_version / version_to_keymaster_version: 4.1 -> attestation 4, keymaster 41) flags the mismatch. Vintf now also parses the Keymaster HIDL HAL and returns its attestation-version equivalent (2.0 -> 1, 3.0 -> 2, 4.0 -> 3, 4.1 -> 4). When no KeyMint HAL is declared, the harvest aligns the presented attestationVersion/keymasterVersion -- and the StrongBox instance's version -- to the declared Keymaster HAL. Unlike the KeyMint ceiling, which only clamps down, this aligns in both directions: a captured or fabricated value may sit either side of the legacy HAL, and the checker wants an exact match rather than an upper bound. keymasterVersionFor already yields the matching keymasterVersion (attestation 4 -> keymaster 41), so the pair stays self-consistent, and the resulting sub-400 version keeps MODULE_HASH off, as a Keymaster device expects.
…styles
The first cut returned "declared Keymaster HAL attestationVersion = unknown" on the
reported Android 16 device, so no alignment happened and the VINTF mismatch stood. Two
gaps: Vintf only scanned the device manifests (/vendor, /odm), and the Keymaster parser
only read the <version> + <interface> form. On that device the Keymaster HAL is declared
framework-side and/or via <fqname>, so the scan found nothing -- while the integrity
checker, reading the assembled VINTF, sees android.hardware.keymaster/IKeymasterDevice/
default@4.1 and flags keymasterVersion=4/attestationVersion=3 against the expected 41/4.
Vintf now scans the framework manifests too (/system, /system_ext, /product) alongside
/vendor and /odm, and the Keymaster parser handles both the <fqname> form
(@4.1::IKeymasterDevice/default, version bound to its instance) and HIDL version ranges
("4.0-1"), matching how the checker's own manifest reader (Duck-Detector's
VintfKeyMintVersionProbe) reads them.
The KeyMint ceiling and the Keymaster exact-match now share one accessor,
Vintf.attestationVersionConstraint(instance) -> (version, exact), so
clampAttestationToVintf reconciles both levels through a single path: clamp down to an
AIDL ceiling, move exactly to a legacy HIDL target. The declaration-parsing and
constraint model follow the approach in #259 (Ahmad Addas).
|
Hi @kukIux — the Keymaster VINTF fix is ready. Could you retest on the Android 16 device whose Duck Detector showed "KeyMint VINTF: MISMATCH" ( Debug build Please install it, reopen Duck Detector, and check whether the KeyMint VINTF row is now green — then attach the log and a screenshot. Thanks! |
Anyway detected! |





#247 clamps the attested
attestationVersionto the KeyMint HAL version the device declares in VINTF, butVintfonly ever reads the AIDL KeyMint HAL (android.hardware.security.keymint.IKeyMintDevice). A device that ships the legacy Keymaster HIDL HAL instead —android.hardware.keymaster/IKeymasterDevice/default@4.1— declares no KeyMint HAL, sokeyMintHalVersionreturns null, the clamp is a no-op, and the presented pair stays at whatever was captured or fabricated. On such a device that came outkeymasterVersion=4/attestationVersion=3(Keymaster 4.0), one minor version below the declared 4.1, and a checker that mapsIKeymasterDevice@Nto the attestation version a real device of that HAL reports (AOSP system/keymasterversion_to_attestation_version/version_to_keymaster_version: 4.1 → attestation 4, keymaster 41) flags the mismatch.Vintfnow also parses the Keymaster HIDL HAL and returns its attestation-version equivalent (2.0 → 1, 3.0 → 2, 4.0 → 3, 4.1 → 4). When no KeyMint HAL is declared, the harvest aligns the presentedattestationVersion/keymasterVersion— and the StrongBox instance's version — to the declared Keymaster HAL. Unlike the KeyMint ceiling, which only clamps down, this aligns in both directions: a captured or fabricated value may sit either side of the legacy HAL, and the checker wants an exact match rather than an upper bound.keymasterVersionForalready yields the matchingkeymasterVersion(attestation 4 → keymaster 41), so the pair stays self-consistent, and the resulting sub-400 version keeps MODULE_HASH off, as a Keymaster device expects.