From 649136ab4e7e239b59e767ada48084f25f6f074d Mon Sep 17 00:00:00 2001 From: Enginex0 Date: Sat, 30 May 2026 03:10:36 +0100 Subject: [PATCH] fix(shim): match real gen-mode auth shape Real keystore2 (captured on-device, MediaTek SDK 35) emits 11 EC authorizations in the generateKey KeyMetadata: no VENDOR_PATCHLEVEL or BOOT_PATCHLEVEL, and USER_ID tagged at SecurityLevel.SOFTWARE. The shim emitted 13 with both patchlevels and USER_ID at KEYSTORE. Duck-Detector's generate-mode parcel fingerprint stride-walks the reply and keys on the 13-entry layout, so the two extra entries were the tell. Drop both patchlevels from the authorization list (they remain in the attestation extension via AttestationBuilder, so attestation content is unchanged) and move USER_ID to SOFTWARE to mirror the captured device. On-device 23106RN0DA: generate-mode fingerprint signal gone (0 local), TEE tamper score 18 -> 8. Refs Phase 7 .omc/plans/tee-fingerprint-phase-7-generate-mode-coherence.md --- .../shim/KeyMintSecurityLevelInterceptor.kt | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/org/matrix/TEESimulator/interception/keystore/shim/KeyMintSecurityLevelInterceptor.kt b/app/src/main/java/org/matrix/TEESimulator/interception/keystore/shim/KeyMintSecurityLevelInterceptor.kt index 081ae16..d2ace00 100644 --- a/app/src/main/java/org/matrix/TEESimulator/interception/keystore/shim/KeyMintSecurityLevelInterceptor.kt +++ b/app/src/main/java/org/matrix/TEESimulator/interception/keystore/shim/KeyMintSecurityLevelInterceptor.kt @@ -1359,14 +1359,13 @@ private fun KeyMintAttestation.toAuthorizations( if (osPatch != AndroidDeviceUtils.DO_NOT_REPORT) { authList.add(createAuth(Tag.OS_PATCHLEVEL, KeyParameterValue.integer(osPatch))) } - val vendorPatch = AndroidDeviceUtils.getVendorPatchLevelLong(callingUid) - if (vendorPatch != AndroidDeviceUtils.DO_NOT_REPORT) { - authList.add(createAuth(Tag.VENDOR_PATCHLEVEL, KeyParameterValue.integer(vendorPatch))) - } - val bootPatch = AndroidDeviceUtils.getBootPatchLevelLong(callingUid) - if (bootPatch != AndroidDeviceUtils.DO_NOT_REPORT) { - authList.add(createAuth(Tag.BOOT_PATCHLEVEL, KeyParameterValue.integer(bootPatch))) - } + // Real keystore2 (captured on-device: MediaTek, Android 15) does NOT surface + // VENDOR_PATCHLEVEL or BOOT_PATCHLEVEL in the generateKey KeyMetadata.authorizations + // — they exist only in the attestation extension. Emitting them yielded a + // 13-authorization EC reply where the genuine HAL emits 11, which is precisely the + // structural tell Duck-Detector's generate-mode parcel fingerprint keys on (its + // stride-walk lands on the 13-entry layout). Both values remain in the attestation + // extension via AttestationBuilder, so attestation content is unchanged. /** * Keystore-enforced authorizations (CREATION_DATETIME, ACTIVE_DATETIME, @@ -1408,7 +1407,17 @@ private fun KeyMintAttestation.toAuthorizations( authList.add(createKeystoreAuth(Tag.UNLOCKED_DEVICE_REQUIRED, KeyParameterValue.boolValue(true))) } - authList.add(createKeystoreAuth(Tag.USER_ID, KeyParameterValue.integer(callingUid / 100000))) + // Captured real keystore2 tags USER_ID at SecurityLevel.SOFTWARE (0), even though + // CREATION_DATETIME above is KEYSTORE (100). Mirror that split exactly. + authList.add( + Authorization().apply { + this.keyParameter = KeyParameter().apply { + this.tag = Tag.USER_ID + this.value = KeyParameterValue.integer(callingUid / 100000) + } + this.securityLevel = SecurityLevel.SOFTWARE + }, + ) return authList.toTypedArray() }