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.
This commit is contained in:
+2
-1
@@ -194,7 +194,8 @@ class KeyMintSecurityLevelInterceptor(
|
|||||||
SystemLogger.info("Found new IKeystoreOperation. Registering interceptor...")
|
SystemLogger.info("Found new IKeystoreOperation. Registering interceptor...")
|
||||||
val backdoor = getBackdoor(target)
|
val backdoor = getBackdoor(target)
|
||||||
if (backdoor != null) {
|
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)
|
register(backdoor, operationBinder, interceptor, OperationInterceptor.INTERCEPTED_CODES)
|
||||||
interceptedOperations[operationBinder] = interceptor
|
interceptedOperations[operationBinder] = interceptor
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+7
-1
@@ -13,6 +13,7 @@ import org.matrix.TEESimulator.interception.keystore.InterceptorUtils
|
|||||||
class OperationInterceptor(
|
class OperationInterceptor(
|
||||||
private val original: IKeystoreOperation,
|
private val original: IKeystoreOperation,
|
||||||
private val backdoor: IBinder,
|
private val backdoor: IBinder,
|
||||||
|
private val isAead: Boolean,
|
||||||
) : BinderInterceptor() {
|
) : BinderInterceptor() {
|
||||||
|
|
||||||
override fun onPreTransact(
|
override fun onPreTransact(
|
||||||
@@ -27,6 +28,10 @@ class OperationInterceptor(
|
|||||||
val methodName = transactionNames[code] ?: "unknown code=$code"
|
val methodName = transactionNames[code] ?: "unknown code=$code"
|
||||||
logTransaction(txId, methodName, callingUid, callingPid, true)
|
logTransaction(txId, methodName, callingUid, callingPid, true)
|
||||||
|
|
||||||
|
if (code == UPDATE_AAD_TRANSACTION && !isAead) {
|
||||||
|
return InterceptorUtils.createServiceSpecificErrorReply(KeystoreErrorCodes.invalidTag)
|
||||||
|
}
|
||||||
|
|
||||||
if (code == FINISH_TRANSACTION || code == ABORT_TRANSACTION) {
|
if (code == FINISH_TRANSACTION || code == ABORT_TRANSACTION) {
|
||||||
KeyMintSecurityLevelInterceptor.removeOperationInterceptor(target, backdoor)
|
KeyMintSecurityLevelInterceptor.removeOperationInterceptor(target, backdoor)
|
||||||
}
|
}
|
||||||
@@ -44,7 +49,8 @@ class OperationInterceptor(
|
|||||||
private val ABORT_TRANSACTION =
|
private val ABORT_TRANSACTION =
|
||||||
InterceptorUtils.getTransactCode(IKeystoreOperation.Stub::class.java, "abort")
|
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<Int, String> by lazy {
|
private val transactionNames: Map<Int, String> by lazy {
|
||||||
IKeystoreOperation.Stub::class
|
IKeystoreOperation.Stub::class
|
||||||
|
|||||||
Reference in New Issue
Block a user