feat(attestation): add origin field and isAttestKey/isImportKey helpers

Parse ORIGIN tag from KeyParameter array into KeyMintAttestation
data class. Add isAttestKey() and isImportKey() convenience methods
to consolidate purpose/origin checks scattered across interceptors.
This commit is contained in:
Enginex0
2026-03-09 19:59:38 +01:00
parent a781b29e0d
commit 20603572f3
3 changed files with 18 additions and 6 deletions
@@ -1,6 +1,7 @@
package org.matrix.TEESimulator.attestation
import android.hardware.security.keymint.*
import android.hardware.security.keymint.KeyOrigin
import java.math.BigInteger
import java.util.Date
import javax.security.auth.x500.X500Principal
@@ -20,6 +21,7 @@ data class KeyMintAttestation(
val algorithm: Int,
val ecCurve: Int,
val ecCurveName: String,
val origin: Int?,
val blockMode: List<Int>,
val padding: List<Int>,
val purpose: List<Int>,
@@ -54,6 +56,9 @@ data class KeyMintAttestation(
ecCurve = params.findEcCurve(Tag.EC_CURVE) ?: 0,
ecCurveName = params.deriveEcCurveName(),
// AOSP: [key_param(tag = ORIGIN, field = Origin)]
origin = params.findOrigin(Tag.ORIGIN),
// AOSP: [key_param(tag = BLOCK_MODE, field = BlockMode)]
blockMode = params.findAllBlockMode(Tag.BLOCK_MODE),
@@ -99,6 +104,10 @@ data class KeyMintAttestation(
// Log all parsed parameters for debugging purposes.
params.forEach { KeyMintParameterLogger.logParameter(it) }
}
fun isAttestKey(): Boolean = purpose.size == 1 && purpose.contains(KeyPurpose.ATTEST_KEY)
fun isImportKey(): Boolean = origin == KeyOrigin.IMPORTED || origin == KeyOrigin.SECURELY_IMPORTED
}
// --- Private helper extension functions for parsing KeyParameter arrays ---
@@ -115,6 +124,10 @@ private fun Array<KeyParameter>.findAlgorithm(tag: Int): Int? =
private fun Array<KeyParameter>.findEcCurve(tag: Int): Int? =
this.find { it.tag == tag }?.value?.ecCurve
/** Maps to AOSP field = Origin */
private fun Array<KeyParameter>.findOrigin(tag: Int): Int? =
this.find { it.tag == tag }?.value?.origin
/** Maps to AOSP field = LongInteger */
private fun Array<KeyParameter>.findLongInteger(tag: Int): BigInteger? =
this.find { it.tag == tag }?.value?.longInteger?.toBigInteger()
@@ -407,8 +407,9 @@ private data class LegacyKeygenParameters(
return KeyMintAttestation(
keySize = this.keySize,
algorithm = this.algorithm,
ecCurve = 0, // Not explicitly available in legacy args, but not critical
ecCurve = 0,
ecCurveName = this.ecCurveName ?: "",
origin = null,
blockMode = listOf<Int>(),
padding = listOf<Int>(),
purpose = this.purpose,
@@ -3,7 +3,6 @@ package org.matrix.TEESimulator.interception.keystore.shim
import android.hardware.security.keymint.Algorithm
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
@@ -248,9 +247,7 @@ 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)
val isAttestKeyRequest = parsedParams.isAttestKey()
val needsSoftwareGeneration =
ConfigurationManager.shouldGenerate(callingUid) ||
@@ -468,6 +465,7 @@ class KeyMintSecurityLevelInterceptor(
algorithm = record.algorithm,
ecCurve = record.ecCurve,
ecCurveName = "",
origin = null,
blockMode = emptyList(),
padding = emptyList(),
purpose = record.purposes,
@@ -560,7 +558,7 @@ class KeyMintSecurityLevelInterceptor(
val generatedKeys = ConcurrentHashMap<KeyIdentifier, GeneratedKeyInfo>()
// Caches patched chains to prevent re-generation and signature inconsistencies
private val patchedChains = ConcurrentHashMap<KeyIdentifier, Array<Certificate>>()
private val attestationKeys = ConcurrentHashMap.newKeySet<KeyIdentifier>()
val attestationKeys: MutableSet<KeyIdentifier> = ConcurrentHashMap.newKeySet()
private val interceptedOperations = ConcurrentHashMap<IBinder, OperationInterceptor>()
fun getGeneratedKeyResponse(keyId: KeyIdentifier): KeyEntryResponse? =