Commit Graph
124 Commits
Author SHA1 Message Date
Enginex0 1b7800345d fix(config): restore AUTO mode resolution for bare target entries
v6.0 changed bare target.txt entries from AUTO to GENERATE, breaking
apps like BHIM that need TEE-backed attestation keys. Restore AUTO as
default and resolve it at config level (PATCH if TEE works, GENERATE
if not) to bypass the non-deterministic raceTeePatch path.
2026-03-31 18:53:18 +01:00
Enginex0 1bc47840d5 chore(version): bump to v6.0.0 2026-03-26 12:28:23 +01:00
Enginex0 c8fadb07ae fix(certgen): self-signed certs for no-challenge keys per AOSP spec
AOSP ta/src/keys.rs:451-478 requires self-signed leaf (depth 1) when
no attestation challenge is provided. Both Kotlin and Rust paths now
return subject==issuer, signed by generated key, no attestation
extension. Adds cert chain trace logging in debug builds.
2026-03-26 12:28:17 +01:00
Enginex0 c0b14eeeb1 fix(operation): pass operation-time params through to CipherPrimitive
createOperation was building effectiveParams from key-generation params
but dropping operation-time fields (nonce, blockMode, padding,
minMacLength). This caused GCM decrypt to fail with
"IV must be specified in GCM mode" since the nonce from the begin call
never reached CipherPrimitive.

Also adds nonce field to KeyMintAttestation and handles GCM/CBC/CTR IV
initialization in CipherPrimitive.
2026-03-26 05:03:01 +01:00
Enginex0 47ab0225e1 fix(certgen): omit attestation extension when no challenge provided
AOSP KeyMint only includes the attestation extension (OID
1.3.6.1.4.1.11129.2.1.17) when ATTESTATION_CHALLENGE is present.
Without a challenge, generateKey produces a plain self-signed cert.
Our code unconditionally added the extension, which behavioral
probes detect by generating a key without a challenge and checking
for the OID.

Fixes both the Rust native-certgen and BouncyCastle paths.
Also skips AAID computation when no challenge is provided,
matching keystore2 security_level.rs:457 behavior.
2026-03-26 04:22:22 +01:00
Enginex0 ebb6336281 fix(interception): patch authorizations on import-overwrite path
The retained cert chain was applied to response metadata but the
authorizations array was left unpatched, allowing a detector to compare
metadata patch levels against cert attestation values and spot the
divergence. Refs upstream JingMatrix #164.
2026-03-26 02:49:01 +01:00
Enginex0 784373c8b5 feat(config): default bare target entries to GENERATE mode
PATCH and AUTO modes inherit the real TEE's attestation quirks (epoch 0
cert dates, version mismatch, missing USAGE_COUNT_LIMIT) which can't be
fixed in post-patch. GENERATE mode builds attestation from scratch with
full control over every field. Users who want real TEE key generation
can still use the ? suffix for explicit PATCH mode.
2026-03-26 02:32:14 +01:00
Enginex0 2241bfb13d perf(logging): add rate limiter and lazy formatting to SystemLogger
Under binder stress, debug builds hammered logd with 6-7 syscalls per
keygen, causing thread contention that spiked ping latency past G10b's
threshold. Rate-limit debug/info/verbose to 15 msgs per 1s window with
atomic CAS on window boundaries. Warnings and errors always pass.

Expensive verbose calls in AttestationBuilder, AttestationPatcher, and
DeviceAttestationService now use lazy lambdas so ASN.1 formatting only
runs when the message will actually be emitted.
2026-03-26 02:11:17 +01:00
Enginex0 954478b89b perf(interception): optimize ioctl hook hot path for ping latency
Strip LOGV from the buffer parse loop and add a fast pre-check that
peeks at the first binder command before entering the full parser.
Pings, ref ops, and looper management produce no BR_TRANSACTION, so
their buffers can be skipped entirely. Adds __builtin_expect hint
on the transaction branch for better pipeline prediction.

Drops G2 binder ping ratio from 3.95x to 1.17x in debug builds.
2026-03-26 01:59:32 +01:00
Enginex0 191085087b fix(interception): route oversized transactions to software gen
The 256KB native size guard skipped interception entirely for oversized
transactions, causing them to reach the real TEE which returns different
attestation values. This inconsistency is exactly what G10 detects.

Oversized requests now flow through to the Kotlin layer where they hit
doSoftwareKeyGen via the forceGenerate flag. Software gen produces
consistent attestation without forwarding to the real TEE, preserving
the anti-amplification defense that the original guard intended.
2026-03-26 01:30:07 +01:00
Enginex0 f870598e77 fix(interception): resolve B3, C2, F1 and harden AUTO mode
B3: AttestationPatcher now accepts optional notBefore/notAfter overrides
so the PATCH path honors CERTIFICATE_NOT_BEFORE instead of inheriting
the real TEE's epoch 0.

C2: getKeymasterVersion delegates to getAttestVersion directly, ensuring
attestationVersion == keymasterVersion regardless of cache source.

F1: Remove incorrect EC+DECRYPT guard in AuthorizeCreate that returned
UNSUPPORTED_PURPOSE instead of INCOMPATIBLE_PURPOSE.

AUTO mode: Replace volatile teeFunctional boolean with AtomicReference
tri-state (null/true/false) so the first race winner locks the path for
all subsequent requests, preventing mixed attestation under concurrency.
2026-03-26 01:27:43 +01:00
Enginex0 8fdc59a142 feat(interception): add AUTO mode TEE race for G10 attestation consistency
AUTO mode now races TEE hardware against software generation via
CompletableFuture. If TEE succeeds, the cert chain is patched and
cached in teeResponses before returning, making attestation
stress-resilient. If TEE fails, software fallback is used.

ConfigurationManager no longer resolves AUTO at config time; it
passes Mode.AUTO through to KeyMintSecurityLevelInterceptor for
runtime dispatch. shouldPatch() returns true for both PATCH and
AUTO modes. TEE status file persistence removed entirely.

Aligns handleGenerateKey with upstream PR #157 three-way dispatch:
forceGenerate, raceTeePatch, or hardware forwarding with post-patch.

Hardware keygen rate limiting removed (replaced by raceTeePatch for
AUTO, plain Continue for PATCH). Attest key override in
Keystore2Interceptor now patches authorizations and uses null-safe
nspace assignment.
2026-03-20 04:44:52 +01:00
Enginex0 b6f9d7b486 fix(interception): harden daemon against binder stress crashes
BinderInterceptor.onTransact now catches Throwable, preventing any
exception on a binder thread from killing the daemon. Adds a global
uncaught exception handler as defense in depth.

Replace Thread.sleep with TeeLatencySimulator (LockSupport.parkNanos +
statistical delay model) for keygen latency, reducing binder thread
blocking. Move GeneratedKeyPersistence.save to a background executor
to avoid disk I/O on binder threads.

Convert force-unwrap parcel reads to safe calls with early returns in
onPreTransact/onPostTransact hot paths. Add -DNDEBUG to native release
builds to compile out verbose logging from the ioctl hook.

Targets G2 (ping overhead) and G10 (stress attestation consistency).
2026-03-19 17:38:29 +01:00
Enginex0 99e6b0b5ea feat(certgen): add enforcement tags to native DER encoder and teeResponses cache
Extend Rust native cert gen with software-enforced attestation tags
(CALLER_NONCE, ACTIVE_DATETIME, ORIGINATION_EXPIRE_DATETIME,
USAGE_EXPIRE_DATETIME, USAGE_COUNT_LIMIT, UNLOCKED_DEVICE_REQUIRED)
and make NO_AUTH_REQUIRED conditional in teeEnforced. Fixes F5/F6
test failures where these tags were missing from NativeCertGen path.

Add teeResponses cache so PATCH mode keys patched in onPostTransact
return consistent attestation via getKeyEntry. Without this, getKeyEntry
fell through to real keystore2, returning unpatched metadata.

Remove dead Rust enums (KeyPurpose, SecurityLevel, VerifiedBootState)
that were never referenced by the DER encoder.
2026-03-19 15:43:17 +01:00
Enginex0 397bb6338b fix(interception): make NO_AUTH_REQUIRED conditional in KeyMetadata authorizations
Upstream removed the unconditional NO_AUTH_REQUIRED from toAuthorizations.
A key generated with auth requirements would incorrectly report
NO_AUTH_REQUIRED in metadata, creating a detectable inconsistency
with the attestation extension.
2026-03-19 09:48:08 +01:00
Enginex0 cb81116701 feat(interception): close remaining PR #157 compliance gaps
Full diff analysis against upstream's 50 commits revealed 8 functional
gaps after v5.0. These are detectable by conformance tests or detector
apps inspecting KeyMetadata authorizations and operation semantics.

KeyMetadata authorizations:
- Add 9 TEE-enforced tags (CALLER_NONCE, MIN_MAC_LENGTH, ROLLBACK_RESISTANCE,
  EARLY_BOOT_ONLY, ALLOW_WHILE_ON_BODY, TRUSTED_USER_PRESENCE_REQUIRED,
  TRUSTED_CONFIRMATION_REQUIRED, MAX_USES_PER_BOOT, MAX_BOOT_LEVEL)
- Fix CREATION_DATETIME to SOFTWARE security level via createSwAuth
- Add SOFTWARE-enforced date enforcement, USAGE_COUNT_LIMIT, UNLOCKED_DEVICE_REQUIRED

Symmetric key support:
- Generate AES/HMAC keys in software via javax.crypto.KeyGenerator
- GeneratedKeyInfo expanded with nullable keyPair + secretKey fields
- CipherPrimitive accepts java.security.Key for symmetric operations
- SoftwareOperation routes ENCRYPT/DECRYPT to secretKey when available

Operation compliance:
- beginParameters property replaces manual IV wrapping for GCM
- KeyAgreementPrimitive for ECDH AGREE_KEY operations
- handleCreateOperation wrapped in runCatching (crash prevention)
- SECURE_HW_COMMUNICATION_FAILED on software gen failure

Certificate patching:
- Import key cert chain + authorization patching in onPostTransact
- patchAuthorizations added to post-generateKey PATCH mode path
2026-03-19 09:40:48 +01:00
Enginex0 45477a7898 feat(interception): add AOSP authorize_create enforcement and wire format fixes
Integrate upstream AOSP compliance checks that failed post-v5.0 testing:

- INCLUDE_UNIQUE_ID: SELinux gen_unique_id + Android permission gate
- Forced operation rejection with PERMISSION_DENIED
- Null purpose guard returning INVALID_ARGUMENT
- Wire format: use createServiceSpecificErrorReply for authorize_create
- USAGE_COUNT_LIMIT with AtomicInteger counters and onFinishCallback
- effectiveParams merging key digest with operation purpose
- AuthorizeCreate rewrite: algorithm-purpose before purpose-list (AOSP HAL order)
- CALLER_NONCE in attestation teeEnforced list

Based on upstream commits e55d16d, 3078ea9, 2bc46be, 07c98bc, 41abe77.
2026-03-19 09:21:52 +01:00
Enginex0 f115eda2dc chore(version): bump to v5.0 with changelog for AOSP compliance overhaul 2026-03-19 07:36:20 +01:00
Enginex0 ee5bf2e1a7 feat(config): add SELinux permission checks, latency simulation, and hbk seed
ConfigurationManager gains checkSELinuxPermission (reads /proc/pid/attr)
and hasPermissionForUid (delegates to IPackageManager.checkPermission)
for AOSP-compliant access control. TeeLatencySimulator provides log-normal
distribution matching real QTEE/Trustonic hardware timing profiles.

Module customize.sh now generates a device-unique hardware-bound key seed
(32 bytes from /dev/random) and clears stale tee_status.txt on install.
2026-03-19 07:33:47 +01:00
Enginex0 2181157cb6 feat(operation): add AOSP-compliant error handling, authorize_create, and GCM IV
SoftwareOperation now throws ServiceSpecificException for all error paths
instead of raw Java exceptions, matching AIDL wire format. updateAad on
non-AEAD operations returns INVALID_TAG (-76) per AOSP operation.rs.
SoftwareOperationBinder methods are @Synchronized to match AOSP Mutex
semantics. GCM encrypt operations return the generated IV in
CreateOperationResponse.parameters.

AuthorizeCreate enforces PURPOSE validation, algorithm-purpose
compatibility (EC rejects ENCRYPT/DECRYPT, RSA rejects AGREE_KEY),
temporal constraints (ACTIVE_DATETIME, ORIGINATION_EXPIRE, USAGE_EXPIRE),
and CALLER_NONCE prohibition. GeneratedKeyInfo carries keyParams for
authorize_create enforcement on software createOperation.
2026-03-19 07:33:30 +01:00
Enginex0 aa4917e623 feat(interception): add binder tx code filtering and keystore2 service compliance
Native binder_interceptor now accepts a filtered_codes vector per
registration, skipping JNI round-trip for non-intercepted transaction
codes. Keystore2Interceptor adds getNumberOfEntries software key counting,
deleteKey KEY_ID domain resolution, patchAuthorizations for OS/VENDOR/BOOT
patch levels, importedKeys tracking to prevent stale attest-key overrides,
and nspace consistency fix in the attest-key override path.

InterceptorUtils gains createServiceSpecificErrorReply for AIDL-compliant
error serialization and patchAuthorizations for authorization array patching.
2026-03-19 07:33:11 +01:00
Enginex0 f06cb30b40 feat(attestation): align attestation extension and cert generation with AOSP
KeyMintAttestation now carries all 17 enforcement tags that AOSP's
authorize_create and buildKeyDescription paths expect. AttestationBuilder
populates BLOCK_MODE as SET OF INTEGER, gates version-guarded tags
(RSA_OAEP_MGF_DIGEST >=100, ROLLBACK_RESISTANCE >=3, EARLY_BOOT_ONLY >=4),
computes INCLUDE_UNIQUE_ID via HMAC-SHA256 per KeyMint HAL spec, and
gates AAID on challenge presence.

CertificateGenerator uses AOSP cert validity defaults (epoch notBefore,
9999-12-31 notAfter), returns ServiceSpecificException(-75) for missing
keybox, and adds RSA exponent null safety.
2026-03-19 07:32:53 +01:00
Enginex0 7e2fc0b288 fix(interception): enforce StrongBox op limit for software-generated keys
trackAndEnforceOpLimit was only called in the Domain.KEY_ID not-found
path, so software-generated keys (found via Domain.APP) bypassed the
STRONGBOX_MAX_CONCURRENT_OPS=4 limit entirely. DuckDetector's concurrent
signing handles test created 24+ operations that all succeeded via LRU
pruning instead of being rejected with TOO_MANY_OPERATIONS (-29).
2026-03-18 03:21:34 +01:00
Enginex0 d2b8a92fbd chore(version): bump to v4.8 2026-03-17 19:48:48 +01:00
Enginex0 0723865eab feat(interception): add StrongBox hardening and LRU operation pruning
DuckDetector flags several behavioral anomalies that real TEE/StrongBox
hardware exhibits but our software interceptor did not:

- LRU pruning: cap concurrent ops at 15 (TEE) / 4 (StrongBox) per UID,
  aborting oldest when exceeded — matches AOSP keystore2 malus scoring
- StrongBox param guard: forward unsupported params (RSA>2048, non-P256)
  to real HAL for proper rejection instead of generating in software
- StrongBox latency floors: 250ms keygen, 80ms sign to match real SE
  timing characteristics
- Sliding-window op limit for hardware-generated StrongBox keys that
  bypass the software pruning path
- Domain.APP lookup path for createOperation to find software-generated
  keys that never reach keystore2's database
2026-03-17 19:48:40 +01:00
Enginex0 7cb44b9999 feat(operation): add LRU pruning support and latency floor to SoftwareOperation
Expose finalized state for pruning, add latency floor parameter for
StrongBox timing simulation, and add trace logging for 32KB test
diagnosis.
2026-03-17 19:48:29 +01:00
Enginex0 eddd9908af fix(certgen): accept ECDSA as EC algorithm alias in JCA key type matching
Some Android 10 devices (e.g. Sony H8296) report EC private key
algorithm as "ECDSA" instead of "EC", causing IllegalArgumentException
in certificate signing and a SIGSEGV crash in the keystore process.

Closes #4
2026-03-17 19:48:19 +01:00
Enginex0 36ccd22cdc fix(operation): correct TOO_MUCH_DATA fallback to match AOSP ResponseCode
AOSP ResponseCode.TOO_MUCH_DATA = 21, not 29.
2026-03-17 14:16:00 +01:00
Enginex0 81e6fbf97e fix(keygen): forward symmetric algorithms to HAL and add missing JCA mappings
Symmetric keys (AES/HMAC/3DES) don't have KeyPairs or attestation
certs — routing them through doSoftwareKeyGen crashes with
"Unsupported algorithm: 32". Skip the software path entirely and
let the real HAL handle them.

Also adds CTR block mode, RSA_PKCS1_1_5_SIGN cipher padding, and
RSA_PSS signature padding to JcaAlgorithmMapper.
2026-03-17 13:44:25 +01:00
fatalcoder524 5df76eacd1 fix(interception): Add permission checks for KeyMintSecurityLevelInterceptor and fix some regression
1. Add permission checks for KeyMintSecurityLevelInterceptor to ensure that only authorized users can access sensitive information about the security level of the key mint.
2. Fix regression where device id attestation was allowed for all users by adding appropriate permission checks.
3. Update .gitignore to exclude build artifacts and generated files to keep the repository clean and prevent accidental commits of unnecessary files.
2026-03-17 11:49:54 +00:00
Enginex0 ca3978888e docs(release): bump to v4.7 with operation and attestation fixes changelog 2026-03-17 07:12:30 +01:00
Enginex0 023d7f929d fix(operation): match AOSP error-path semantics for software operations
KeyDetector's OperationErrorPathChecker (flag 0x400000) probes three
error-path behaviors that real keystore2 operations expose. Our
SoftwareOperationBinder was missing all three, plus had no updateAad
implementation which caused AbstractMethodError on Android 16 where
the runtime Stub declares it abstract.

SoftwareOperation changes:
- Add finalized state tracking; post-abort calls now throw
  INVALID_OPERATION_HANDLE (-28) matching AOSP operation.rs
- Add input length guard (0x8000) throwing TOO_MUCH_DATA (29)
  matching AOSP operation.rs MAX_RECEIVE_DATA
- Add updateAad to CryptoPrimitive interface and SoftwareOperationBinder
- Add KeystoreErrorCodes with runtime reflection + AOSP fallback values

KeyMintSecurityLevelInterceptor changes:
- Infer algorithm from stored key pair when operation params omit
  ALGORITHM tag, matching AOSP behavior where createOperation uses
  the key's stored algorithm rather than requiring it in op params

Stub addition:
- ServiceSpecificException compile stub (framework-internal class
  resolved at runtime on device)

Tested on OnePlus Android 16 (SDK 36) — KeyDetector passes all three
probes: updateAad succeeds, TOO_MUCH_DATA returns code=21,
INVALID_OPERATION_HANDLE returns after abort.
2026-03-17 07:04:59 +01:00
Enginex0 bd40f4b950 fix(attestation): encode PADDING as SET OF INTEGER per AOSP schema
PADDING (tag 6) is ENUM_REP in Tag.aidl, meaning SET OF INTEGER in the
attestation extension ASN.1 — same as PURPOSE and DIGEST. Commit f8bfa0d
added it as individual [6] INTEGER entries, causing parsers to fail with
CertificateParsingException on any RSA key attestation.
2026-03-17 04:36:49 +01:00
Enginex0 dfacb34cf9 chore(brand): rebrand to TEESimulator-RS with simplified versioning
Fork identity: rename across module metadata, CI pipeline, and build
scripts. Version scheme changed from v4.5-115-7e87766 to v4.6-117
format — commit count auto-increments, git hash dropped from filenames.
2026-03-17 03:35:32 +01:00
Enginex0 06d9db443c perf(keygen): replace Gaussian RTT normalization with 15ms floor fence
The old Gaussian sleep (mean=55ms, stddev=12ms) triggered detection on
Chunqiu Native Check 2.8. A flat 15ms floor satisfies the minimum RTT
threshold without creating a detectable delay pattern — both attested
and non-attested paths get identical treatment, keeping the D50 ratio
at ~1.0 while staying above the >=15ms requirement.
2026-03-17 03:35:20 +01:00
Enginex0 7e87766493 fix(certgen): derive signing algorithm from attestation key and allow device ID tags
signerAlgorithm was derived from params.algorithm (the generated key)
instead of the signing key, causing BouncyCastle to throw when signing
RSA keys with an EC attestation key. Now reads signingKeyPair.private.algorithm.

Device ID tags (serial/imei/meid/secondImei) were blanket-rejected
instead of flowing through to software cert gen like AOSP does.
Narrowed rejection to DEVICE_UNIQUE_ATTESTATION only.
2026-03-17 00:05:56 +01:00
Enginex0 f8bfa0dfd8 fix(attestation): align authorization list and cert extension with AOSP keystore2 semantics
toAuthorizations() was missing OS_VERSION, OS_PATCHLEVEL, VENDOR_PATCHLEVEL,
BOOT_PATCHLEVEL, CREATION_DATETIME, USER_ID, PADDING, and RSA_PUBLIC_EXPONENT
tags that real TEE-generated KeyMetadata always includes. EC_CURVE was also
hardcoded unconditionally, producing invalid authorizations for RSA keys.

Additionally, live-patched certificate chains in getKeyEntry weren't cached,
causing re-patching on every call with potentially different signatures.

Ports upstream JingMatrix/TEESimulator#148 and #150.
2026-03-16 23:01:28 +01:00
Enginex0 90ff59e0aa fix(interception): check generatedKeys before deletedSoftwareKeys on getKeyEntry
The deletion guard must not shadow re-generated keys. If an app
deletes a key then re-creates it, getKeyEntry was still returning
KEY_NOT_FOUND because deletedSoftwareKeys was checked first.
2026-03-16 22:36:02 +01:00
Enginex0 8bdf0d59fa docs(release): bump to v4.5 with detection hardening changelog 2026-03-16 22:07:56 +01:00
Enginex0 6ab09f4889 fix(interception): prevent ghost key responses after software key deletion
After deleting a software-generated key, getKeyEntry was falling
through to the real keystore2 service which could return a stale
hardware key with the same alias. The post-transact live-patch
fallback would then resurrect the key with a patched chain —
detectors flag this as binder inconsistency.

Track deleted software key aliases and return KEY_NOT_FOUND (7) for
subsequent getKeyEntry calls. Also always invoke cleanupKeyData on
delete to clear stale patchedChains entries for hardware keys.
2026-03-16 22:06:53 +01:00
Enginex0 f4559bcd19 perf(keygen): normalize software generateKey RTT to match TEE latency
Software-generated keys complete in ~4ms, real TEE averages 55-65ms
with a floor around 15ms. Detectors measure this RTT to distinguish
software from hardware paths. Gaussian delay sampling (mean=55ms,
σ=12ms, floor=15ms) brings total RTT into the expected range.
2026-03-16 22:06:38 +01:00
Enginex0 3b5043a1bb docs(release): bump to v4.4 with AOSP conformance changelog 2026-03-16 13:26:34 +01:00
Enginex0 8001a8678a fix(interception): absorb upstream correctness fixes and patch error reply format
Cherry-pick three upstream fixes: Parcel position reset in hasException()
so the method doesn't consume reply data (7804743), list_past_alias
enumeration filter inversion (2aac65c), and KeyMetadata alignment with
AOSP semantics — modificationTimeMs, Tag.ORIGIN, KeyDescriptor
normalization (86db5bf).

Additionally, createErrorReply() was missing the empty remote stack
trace header int between the exception message and error code, per
AOSP Status.cpp:196. Binder readers expecting the standard
EX_SERVICE_SPECIFIC wire format would misparse our error replies.
2026-03-16 13:23:36 +01:00
Enginex0 d21822eb9d docs(release): bump to v4.3 with changelog and update metadata 2026-03-11 13:12:03 +01:00
Enginex0 c122ded7bf perf(daemon): add restart backoff, process priority, and map eviction
Supervisor had zero-delay restart on crash loops — pins CPU core at
100% if daemon keeps dying. Add exponential backoff (500ms to 30s cap,
resets after 30s stable). Set nice=10 on daemon child to yield CPU
to foreground apps. Evict stale entries from fileLocks and rate limiter
ConcurrentHashMaps that grew unbounded. Upload pre-built flashable zips
in CI instead of unpacking and re-compressing loose files.
2026-03-11 12:41:57 +01:00
Enginex0 7b510a9915 perf(logging): gate debug-level logs behind isDebugBuild
debug() was hitting Log.d() unconditionally in release builds —
every intercepted binder transaction triggered string formatting
and logcat syscalls. verbose() already had the guard; debug() was
just missing it. Also remove dead SERVICE_SLEEP_MS constant.
2026-03-11 12:41:46 +01:00
Enginex0 9896df93de build(gradle): keep debug symbols in debug variant
Debug ZIPs now ship unstripped native libs sourced from
merged_native_libs instead of stripped_native_libs. Gives
meaningful stack traces for crash debugging on-device.
2026-03-11 00:45:00 +01:00
Enginex0 40b08cd648 docs(release): bump to v4.2 with changelog and update metadata 2026-03-10 16:55:39 +01:00
Enginex0 bee73eb39b perf(binder): skip interception for system transaction codes
AIDL methods use codes 1..0x00ffffff. System transactions like
PING_TRANSACTION (0x5f4e4750) fall above that range. Intercepting
pings forces a full JNI round-trip to Java and back, adding enough
latency for timing detectors to flag the ratio (3.85x vs 3.0x
threshold). Early-return for codes above LAST_CALL_TRANSACTION
eliminates this overhead while preserving all AIDL interception.
2026-03-10 16:37:50 +01:00
Enginex0 a0ee77202c fix(attestation): correct leaf CN casing and enforce keystore2 parameter policy
Leaf cert Subject CN used "KeyStore" (capital S) but AOSP
KeyGenParameterSpec uses "Keystore" (lowercase s). Fixed in both
the Rust native certgen and BouncyCastle paths.

Replicate keystore2's security_level.rs parameter validation for
software-generated keys: reject CREATION_DATETIME (output-only tag,
ResponseCode 20) and device ID attestation tags (CANNOT_ATTEST_IDS
-66) that real keystore2 blocks before they reach the HAL.

Also fix createErrorReply parcel write order — AIDL protocol expects
exception_code, message, error_code but we had message and error_code
swapped, causing malformed replies for positive error codes.
2026-03-10 14:23:33 +01:00