fix(attestation): cache AOSP attestVersion on A16

The A16 test device's KeyMint HAL reports attestVersion 100 (KeyMint
1.0); the lazy cache stored that and it shadowed the map's BAKLAVA->400
in getAttestVersion. fetchAttestationData now caches
AndroidDeviceUtils.aospAttestVersion (attestVersionMap[SDK_INT]),
falling back to the parsed device value only when the SDK is unmapped,
so the forge presents the AOSP-correct 400. attestVersionMap unchanged.

Bucket a16-ec-attestkey-red, task T02.
This commit is contained in:
Enginex0
2026-06-17 20:28:27 +01:00
parent 0b67700763
commit a54e8a5315
2 changed files with 10 additions and 2 deletions
@@ -16,6 +16,7 @@ import org.bouncycastle.asn1.ASN1TaggedObject
import org.bouncycastle.asn1.x509.Extension import org.bouncycastle.asn1.x509.Extension
import org.bouncycastle.cert.X509CertificateHolder import org.bouncycastle.cert.X509CertificateHolder
import org.matrix.TEESimulator.logging.SystemLogger import org.matrix.TEESimulator.logging.SystemLogger
import org.matrix.TEESimulator.util.AndroidDeviceUtils
import org.matrix.TEESimulator.util.toHex import org.matrix.TEESimulator.util.toHex
/** /**
@@ -157,12 +158,15 @@ object DeviceAttestationService {
} }
val fields = keyDescriptionSeq.toArray() val fields = keyDescriptionSeq.toArray()
val attestVersion = val deviceAttestVersion =
ASN1Integer.getInstance( ASN1Integer.getInstance(
fields[AttestationConstants.KEY_DESCRIPTION_ATTESTATION_VERSION_INDEX] fields[AttestationConstants.KEY_DESCRIPTION_ATTESTATION_VERSION_INDEX]
) )
.positiveValue .positiveValue
.toInt() .toInt()
// The device KeyMint HAL can report a version below its OS's AOSP value (100 on an A16
// where BAKLAVA mandates 400); cache the AOSP value so the forge matches an updated device.
val attestVersion = AndroidDeviceUtils.aospAttestVersion ?: deviceAttestVersion
val keymasterVersion = val keymasterVersion =
ASN1Integer.getInstance( ASN1Integer.getInstance(
fields[AttestationConstants.KEY_DESCRIPTION_KEYMINT_VERSION_INDEX] fields[AttestationConstants.KEY_DESCRIPTION_KEYMINT_VERSION_INDEX]
@@ -256,7 +260,7 @@ object DeviceAttestationService {
} }
SystemLogger.info( SystemLogger.info(
"Successfully extracted attestation data: version=$attestVersion, osVersion=$osVersion, osPatch=$osPatchLevel, vendorPatch=$vendorPatchLevel, bootPatch=$bootPatchLevel, moduleHash=${moduleHash?.toHex()}, bootKey=${verifiedBootKey?.toHex()}, bootHash=${verifiedBootHash?.toHex()}" "Successfully extracted attestation data: version=$deviceAttestVersion, osVersion=$osVersion, osPatch=$osPatchLevel, vendorPatch=$vendorPatchLevel, bootPatch=$bootPatchLevel, moduleHash=${moduleHash?.toHex()}, bootKey=${verifiedBootKey?.toHex()}, bootHash=${verifiedBootHash?.toHex()}"
) )
return AttestationData( return AttestationData(
moduleHash, moduleHash,
@@ -428,6 +428,10 @@ object AndroidDeviceUtils {
Build.VERSION_CODES.BAKLAVA to 400, // KeyMint 4.0 Build.VERSION_CODES.BAKLAVA to 400, // KeyMint 4.0
) )
/** AOSP-mandated attestation version for the running OS, or null when the SDK is unmapped. */
internal val aospAttestVersion: Int?
get() = attestVersionMap[Build.VERSION.SDK_INT]
/** /**
* Retrieves the attestation version for the given security level. The value follows the device * Retrieves the attestation version for the given security level. The value follows the device
* OS: cached attestation data wins, then attestVersionMap[SDK_INT], then 400 as last resort. A * OS: cached attestation data wins, then attestVersionMap[SDK_INT], then 400 as last resort. A