diff --git a/app/src/main/java/org/matrix/TEESimulator/config/ConfigurationManager.kt b/app/src/main/java/org/matrix/TEESimulator/config/ConfigurationManager.kt index fea017d..3b5f84a 100644 --- a/app/src/main/java/org/matrix/TEESimulator/config/ConfigurationManager.kt +++ b/app/src/main/java/org/matrix/TEESimulator/config/ConfigurationManager.kt @@ -81,6 +81,9 @@ object ConfigurationManager { /** Determines if a new certificate needs to be generated for a given UID. */ fun shouldGenerate(uid: Int): Boolean = getPackageModeForUid(uid) == Mode.GENERATE + /** Determines if no operation is needed for a given UID. */ + fun shouldSkipUid(uid: Int): Boolean = getPackageModeForUid(uid) == null + /** Resolves the operating mode for a given UID based on its packages and the TEE status. */ private fun getPackageModeForUid(uid: Int): Mode? { val packages = getPackagesForUid(uid) diff --git a/app/src/main/java/org/matrix/TEESimulator/interception/keystore/Keystore2Interceptor.kt b/app/src/main/java/org/matrix/TEESimulator/interception/keystore/Keystore2Interceptor.kt index 6bbe680..86a87a0 100644 --- a/app/src/main/java/org/matrix/TEESimulator/interception/keystore/Keystore2Interceptor.kt +++ b/app/src/main/java/org/matrix/TEESimulator/interception/keystore/Keystore2Interceptor.kt @@ -12,6 +12,7 @@ import android.system.keystore2.KeyEntryResponse import org.matrix.TEESimulator.attestation.AttestationPatcher import org.matrix.TEESimulator.config.ConfigurationManager import org.matrix.TEESimulator.interception.keystore.shim.KeyMintSecurityLevelInterceptor +import org.matrix.TEESimulator.logging.KeyMintParameterLogger import org.matrix.TEESimulator.logging.SystemLogger import org.matrix.TEESimulator.pki.CertificateHelper @@ -98,13 +99,33 @@ object Keystore2Interceptor : AbstractKeystoreInterceptor() { callingUid, callingPid, ) + + if (ConfigurationManager.shouldSkipUid(callingUid)) { + SystemLogger.debug( + "[TX_ID: $txId] Skip post-transaction hook for UID=${callingUid}" + ) + return TransactionResult.ContinueAndSkipPost + } + val keyId = KeyIdentifier(callingUid, descriptor.alias) - if (ConfigurationManager.shouldGenerate(callingUid)) { - // TODO: Redesign the interaction with KeyMintSecurityLevelInterceptor - } else if (ConfigurationManager.shouldPatch(callingUid)) { - return TransactionResult.Continue + if (code == DELETE_KEY_TRANSACTION) { + KeyMintSecurityLevelInterceptor.cleanupKeyData(keyId) + return TransactionResult.ContinueAndSkipPost } + + val response = + KeyMintSecurityLevelInterceptor.getGeneratedKeyResponse(keyId) + ?: return TransactionResult.Continue + + if (KeyMintSecurityLevelInterceptor.isAttestationKey(keyId)) + SystemLogger.debug("${descriptor.alias} was an attestation key") + + SystemLogger.info("[TX_ID: $txId] Found generated response for ${descriptor.alias}:") + response.metadata?.authorizations?.forEach { + KeyMintParameterLogger.logParameter(it.keyParameter) + } + return InterceptorUtils.createTypedObjectReply(response) } else { logTransaction( txId, @@ -134,6 +155,7 @@ object Keystore2Interceptor : AbstractKeystoreInterceptor() { return TransactionResult.SkipTransaction if (code == GET_KEY_ENTRY_TRANSACTION) { + data.enforceInterface(IKeystoreService.DESCRIPTOR) val keyDescriptor = data.readTypedObject(KeyDescriptor.CREATOR) 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 45e3ae9..6255031 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 @@ -2,13 +2,14 @@ package org.matrix.TEESimulator.interception.keystore.shim import android.hardware.security.keymint.KeyParameter import android.hardware.security.keymint.KeyParameterValue +import android.hardware.security.keymint.KeyPurpose +import android.hardware.security.keymint.Tag import android.os.IBinder import android.os.Parcel import android.system.keystore2.* import java.security.KeyPair import java.security.cert.Certificate import java.util.concurrent.ConcurrentHashMap -import org.matrix.TEESimulator.attestation.AttestationConstants import org.matrix.TEESimulator.attestation.KeyMintAttestation import org.matrix.TEESimulator.config.ConfigurationManager import org.matrix.TEESimulator.interception.core.BinderInterceptor @@ -70,12 +71,17 @@ class KeyMintSecurityLevelInterceptor( val params = data.createTypedArray(KeyParameter.CREATOR)!! val parsedParams = KeyMintAttestation(params) val keyId = KeyIdentifier(callingUid, keyDescriptor.alias) + val isAttestKeyRequest = + parsedParams.purpose.size == 1 && + parsedParams.purpose.contains(KeyPurpose.ATTEST_KEY) // Determine if we need to generate a key based on config or // if it's an attestation request in patch mode. val needsSoftwareGeneration = ConfigurationManager.shouldGenerate(callingUid) || - (attestationKey != null && ConfigurationManager.shouldPatch(callingUid)) + (ConfigurationManager.shouldPatch(callingUid) && isAttestKeyRequest) || + (attestationKey != null && + isAttestationKey(KeyIdentifier(callingUid, attestationKey.alias))) if (needsSoftwareGeneration) { SystemLogger.info( @@ -95,10 +101,9 @@ class KeyMintSecurityLevelInterceptor( // Store the generated key data. val response = buildKeyEntryResponse(keyData.second, parsedParams, keyDescriptor) + generatedKeys[keyId] = GeneratedKeyInfo(keyData.first, response) - if (parsedParams.attestationChallenge != null) { - attestationKeys.add(keyId) - } + if (isAttestKeyRequest) attestationKeys.add(keyId) // Return the metadata of our generated key, skipping the real hardware call. val resultParcel = @@ -204,25 +209,13 @@ private fun KeyMintAttestation.toAuthorizations(securityLevel: Int): Array "" } ?: "Unknown Value" - SystemLogger.debug("Key Parameter -> %-25s | Value: %s".format(tagName, formattedValue)) + SystemLogger.debug("KeyParam: %-25s | Value: %s".format(tagName, formattedValue)) } private fun ByteArray.toReadableString(): String {