From 59836e143c55c56a413630fe86846a22268e0f6a Mon Sep 17 00:00:00 2001 From: Enginex0 Date: Tue, 19 May 2026 13:05:36 +0100 Subject: [PATCH] feat(intercept): inject SSE on non-AEAD updateAad Real MediaTek mt6768 KeyMint silently returns OK on non-AEAD updateAad, contradicting AOSP's mandate at system/keymint/ta/src/operation.rs:430-446 to throw InvalidTag when aad_allowed is false. Duck-detector flags this divergence as "updateAad mismatch" in OperationErrorPathProbe. Wire UPDATE_AAD into OperationInterceptor and inject ServiceSpecificException(INVALID_TAG) when create params indicate non-AEAD. AEAD (BlockMode.GCM) passes through to real KeyMint untouched so AES-GCM round-trips remain valid. --- .../keystore/shim/KeyMintSecurityLevelInterceptor.kt | 3 ++- .../interception/keystore/shim/OperationInterceptor.kt | 8 +++++++- 2 files changed, 9 insertions(+), 2 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 8e57f01..6a9ea1c 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 @@ -194,7 +194,8 @@ class KeyMintSecurityLevelInterceptor( SystemLogger.info("Found new IKeystoreOperation. Registering interceptor...") val backdoor = getBackdoor(target) if (backdoor != null) { - val interceptor = OperationInterceptor(operation, backdoor) + val isAead = parsedParams.blockMode.firstOrNull() == BlockMode.GCM + val interceptor = OperationInterceptor(operation, backdoor, isAead) register(backdoor, operationBinder, interceptor, OperationInterceptor.INTERCEPTED_CODES) interceptedOperations[operationBinder] = interceptor } else { diff --git a/app/src/main/java/org/matrix/TEESimulator/interception/keystore/shim/OperationInterceptor.kt b/app/src/main/java/org/matrix/TEESimulator/interception/keystore/shim/OperationInterceptor.kt index c8236a3..b8051ac 100644 --- a/app/src/main/java/org/matrix/TEESimulator/interception/keystore/shim/OperationInterceptor.kt +++ b/app/src/main/java/org/matrix/TEESimulator/interception/keystore/shim/OperationInterceptor.kt @@ -13,6 +13,7 @@ import org.matrix.TEESimulator.interception.keystore.InterceptorUtils class OperationInterceptor( private val original: IKeystoreOperation, private val backdoor: IBinder, + private val isAead: Boolean, ) : BinderInterceptor() { override fun onPreTransact( @@ -27,6 +28,10 @@ class OperationInterceptor( val methodName = transactionNames[code] ?: "unknown code=$code" logTransaction(txId, methodName, callingUid, callingPid, true) + if (code == UPDATE_AAD_TRANSACTION && !isAead) { + return InterceptorUtils.createServiceSpecificErrorReply(KeystoreErrorCodes.invalidTag) + } + if (code == FINISH_TRANSACTION || code == ABORT_TRANSACTION) { KeyMintSecurityLevelInterceptor.removeOperationInterceptor(target, backdoor) } @@ -44,7 +49,8 @@ class OperationInterceptor( private val ABORT_TRANSACTION = InterceptorUtils.getTransactCode(IKeystoreOperation.Stub::class.java, "abort") - val INTERCEPTED_CODES = intArrayOf(FINISH_TRANSACTION, ABORT_TRANSACTION) + val INTERCEPTED_CODES = + intArrayOf(UPDATE_AAD_TRANSACTION, FINISH_TRANSACTION, ABORT_TRANSACTION) private val transactionNames: Map by lazy { IKeystoreOperation.Stub::class