From 95b8c27a9f5e84e51afe769180ebbb12ccfd9110 Mon Sep 17 00:00:00 2001 From: Enginex0 Date: Wed, 20 May 2026 03:47:16 +0100 Subject: [PATCH] fix: intercept BYO request under any caller UID Shizuku-routed key attestation calls reach keystore2 with callingUid set to shell (2000) or root (0) instead of the originating app's uid. target.txt has no entry for those uids so shouldSkipUid returned true in onPreTransact, and handleGenerateKey was never entered. The transaction reached the real KeyMint HAL, which on older Keymaster 4.x HALs rejects Tag::ATTEST_KEY with -49 UNSUPPORTED_TAG. Move the shouldSkipUid gate from onPreTransact into handleGenerateKey itself, evaluated after attestationKey and isAttestKeyRequest are parsed. Skip only when the request is neither BYO nor attest-key- purpose. CREATE_OPERATION keeps its outer-level gate (not part of the BYO flow). After this change, Shizuku-routed BYO requests enter dispatch, hit forceGenerate=true via the prior simplification, and route to doSoftwareKeyGen. Non-BYO non-attest calls from shell/root uids still fall through to HAL unchanged. D3 (option 2B) from /home/rootdev/.claude/plans/breezy-seeking-wozniak.md. --- .../shim/KeyMintSecurityLevelInterceptor.kt | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 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 f388a8c..1c0e973 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 @@ -70,18 +70,16 @@ class KeyMintSecurityLevelInterceptor( callingPid: Int, data: Parcel, ): TransactionResult { - val shouldSkip = ConfigurationManager.shouldSkipUid(callingUid) - when (code) { GENERATE_KEY_TRANSACTION -> { logTransaction(txId, transactionNames[code]!!, callingUid, callingPid) - if (!shouldSkip) return handleGenerateKey(txId, callingUid, callingPid, data) + return handleGenerateKey(txId, callingUid, callingPid, data) } CREATE_OPERATION_TRANSACTION -> { logTransaction(txId, transactionNames[code]!!, callingUid, callingPid) - if (!shouldSkip) return handleCreateOperation(txId, callingUid, data) + if (!ConfigurationManager.shouldSkipUid(callingUid)) return handleCreateOperation(txId, callingUid, data) } IMPORT_KEY_TRANSACTION -> { logTransaction(txId, transactionNames[code]!!, callingUid, callingPid) @@ -430,6 +428,12 @@ class KeyMintSecurityLevelInterceptor( ) val params = data.createTypedArray(KeyParameter.CREATOR)!! val parsedParams = KeyMintAttestation(params) + val isAttestKeyRequest = parsedParams.isAttestKey() + + if (ConfigurationManager.shouldSkipUid(callingUid) + && attestationKey == null && !isAttestKeyRequest) { + return TransactionResult.ContinueAndSkipPost + } SystemLogger.trace { "[TRACE-$txId] generateKey alias=${keyDescriptor.alias} algo=${parsedParams.algorithm} challenge=${parsedParams.attestationChallenge?.size ?: "null"} serial=${parsedParams.serial != null} imei=${parsedParams.imei != null} noAuth=${parsedParams.noAuthRequired} purposes=${parsedParams.purpose}" } if (SystemLogger.isDebugBuild) params.forEach { p -> @@ -490,7 +494,6 @@ class KeyMintSecurityLevelInterceptor( } val keyId = KeyIdentifier(callingUid, keyDescriptor.alias) - val isAttestKeyRequest = parsedParams.isAttestKey() val forceGenerate = oversized ||