Commit Graph
8 Commits
Author SHA1 Message Date
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
JingMatrixandGitHub 9f77771e7b Fix Android 11 Keystore execution: Init framework and spoof UID 1000 (#85)
This commit resolves `KeyStore` API failures on Android 11 when running as a standalone CLI executable (UID 0), addressing both environment initialization and permission denial issues.

1. Initialize Android Framework Environment:
   Android 11 Keystore APIs expect a fully initialized application context and a Main Looper, which are missing in a raw root process. This patch:
   - Manually bootstraps `ActivityThread` via `systemMain()`.
   - Initializes `Looper.prepareMainLooper()`.
   - Injects a dummy `Application` object attached to the system context to satisfy `KeyStore.getApplicationContext()` checks.
   - Updates framework stubs to allow compilation of these hidden APIs.

2. Bypass Keystore Permission Checks via UID Spoofing:
   `KeyStoreService::generateKey` enforces the `P_INSERT` permission. Analysis of `permissions.cpp` reveals that UID 0 (Root) is explicitly denied this permission (granted only `P_GET`), whereas UID 1000 (System) holds all permissions (`~0`).
   
   To bypass this restriction, the binder interceptor now detects transactions originating from UID 0 and rewrites the `sender_euid` to 1000. This fools `KeyStoreService` into granting the request.
 
3. Refactor Execution Loop:
   Replaces the previous `Thread.sleep()` maintenance loop with `Looper.loop()`.
2026-01-26 14:07:06 +01:00
JingMatrixandGitHub 5a8454af7b Implement multi-purpose simulation for crypto operations (#59)
This commit introduces a comprehensive simulation engine for Keystore's `createOperation`, enabling the simulator to correctly handle multiple cryptographic purposes (SIGN, VERIFY, ENCRYPT, DECRYPT) for software-generated keys.

The implementation correctly mimics the AOSP framework's internal key identification mechanism. Instead of relying on an alias, a unique `keyId` is generated and embedded in the `nspace` field of the KeyDescriptor during `generateKey`. The `createOperation` hook then uses this `keyId` to dispatch requests: if the ID matches a known software key, the operation is simulated; otherwise, it is forwarded to the hardware service.

To support this, the `SoftwareOperation` engine was architected using a Strategy Pattern. A `CryptoPrimitive` interface defines common actions, with concrete implementations for `Signer`, `Verifier`, and `CipherPrimitive`. The main `SoftwareOperation` class acts as a controller, instantiating the correct primitive based on the `KeyPurpose` tag from the incoming operation parameters. A `JcaAlgorithmMapper` was added to centralize the logic for converting KeyMint constants into JCA algorithm strings.

For operations on real hardware-backed keys, a lightweight `OperationInterceptor` is now used for observation. It attaches to the genuine `iOperation` binder for logging and properly unregisters itself upon completion to prevent resource leaks. This is supported by new binder unregistration capabilities in the core `BinderInterceptor`.

This change also includes necessary stub files and minor regression fixes to make the simulation more robust and accurate.

See AOSP source for key identification logic:
https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/keystore/java/android/security/keystore2/AndroidKeyStoreKey.java
2025-12-08 19:59:32 +01:00
JingMatrix 8d431cc946 Implement software key generation for legacy IKeystoreService (#34)
This commit introduces a complete, software-based simulation of the key generation and attestation flow for the legacy IKeystoreService API, as used on Android 11. It refactors the KeystoreInterceptor to handle the entire multi-step transaction sequence (`generateKey`, `getKeyCharacteristics`, `exportKey`, `attestKey`) in software.

A new `LegacyKeygenParameters` data class is introduced to decouple the legacy interception logic from modern data structures. This class parses arguments from the old `KeymasterArguments`, stores the state across the multi-step generation process, and acts as an adapter to the generic `CertificateGenerator` by converting the parameters to the modern `KeyMintAttestation` format.

The `CertificateGenerator` has been refactored to better model the behavior of the legacy Keystore API. Key pair generation (`generateSoftwareKeyPair`) and certificate chain creation (`generateCertificateChain`) are now separate functions. This allows the interceptor to correctly create a key pair during the `handleExportKey` step and then generate a certificate for that pre-existing key pair during the `handleAttestKey` step.

Finally, the implementation correctly extracts and applies the `attestationChallenge` provided during the `attestKey` transaction, ensuring the generated certificate chain contains the appropriate attestation.
2025-12-03 19:29:21 +01:00
JingMatrixandGitHub 4f608247fe Set boot digest via resetprop (#22)
The stub method `SystemProperties.set` has wrong signature and is unable to set read-only system properties.
2025-11-28 13:11:54 +01:00
JingMatrixandGitHub fa1d9ecc56 Bypass detection by skipping imported keys (#12)
In patch mode, a key's origin provides a robust way to avoid modifying
user-imported keys, which is a well-known detection vector. This commit
implements a new strategy to check the `KeyOrigin` tag from the key's
metadata. If a key is marked as `IMPORTED` or `SECURELY_IMPORTED`, the
patching process is now skipped entirely.

This new origin-based check is more reliable and cleaner than the
previous fingerprinting implementation, which has been removed.

Additionally, this commit acknowledges a remaining detection vector in
patch mode: when an `attestationKey` is used, a key must be generated.
Purely software-generated keys are detectable. To address this in the
future, the full software "generate mode" must be implemented even for
devices without a broken TEE. The old key generation logic has been
stubbed with a TODO in preparation for this redesign.
2025-11-26 02:54:43 +01:00
JingMatrix 13b4786cd9 Restructure and overhaul entire Kotlin codebase
This commit introduces a complete architectural refactoring of the
Kotlin-based interception logic, based on the source of
1. https://github.com/5ec1cff/TrickyStore
2. https://github.com/beakthoven/TrickyStoreOSS

The primary purpose of this code is to intercept binder transactions to
the Android Keystore and KeyMint services. The overall workflow operates
in conjunction with a native library (injected via ptrace). The native
library hooks the binder's `transact` function and forwards pre- and
post-transaction events to the Kotlin side. This Kotlin code contains
all the high-level logic for parsing parameters, patching certificates,
and generating simulated keys.

The codebase is now organized into a clear, package-based architecture:

- attestation: Manages the creation and patching of ASN.1 attestation
  data structures.
- config: Handles loading and observing configuration files from disk.
- interception: Contains the core binder interception framework and its
  specific implementations for legacy Keystore (Android Q/R) and modern
  KeyMint/Keystore2 (Android S+).
- logging: Provides a centralized and consistent logging utility.
- pki: Manages Public Key Infrastructure, including certificate
  generation, parsing of key store XML files, and cryptographic helpers.
- util: Contains Android-specific utility functions for device properties.

This refactoring focuses on establishing a robust and extensible
architecture. The fine-tuning of the interception logic itself,
especially for corner cases in key generation and patching, is currently
under redesign and will be further refined in subsequent commits.
2025-11-26 00:19:01 +01:00
JingMatrix ad4e772eb4 Introduce stub module and initial Gradle project setup
This commit establishes the foundational Gradle project structure and introduces a dedicated 'stub' module. This module provides skeletal implementations of internal Android framework interfaces and classes, which are critical for compiling the TEESimulator project.

Stub classes are minimal implementations of existing interfaces or classes, typically mirroring those found within the Android framework, particularly for internal or hidden APIs. Their methods usually contain no operational logic and instead throw RuntimeException or UnsupportedOperationException.

The primary reasons for using stub classes are:

1. Compilation Against Internal APIs: Android applications and libraries typically use public APIs exposed by the Android SDK. However, in scenarios requiring deeper system integration or emulation, interaction with internal or hidden Android framework APIs might be necessary. Directly linking against the full Android framework JAR can lead to bootclasspath conflicts or other build issues. Stub classes provide the necessary API signatures for compilation without including the actual implementations, allowing the build system to resolve references while deferring the actual functionality to the runtime environment (the Android OS itself).

2. API Consistency and Simulation: For TEESimulator, which aims to provide a software simulation for Android's hardware-backed key pairs (KeyMint/Keystore2), stub classes define the required API contract. They ensure that the simulator's components compile against the exact interface definitions of the Android system services, making the simulation functionally consistent with the expected system behavior without needing to bundle or depend on the entire Android framework at compile time. This ensures that the simulator correctly interacts with the defined KeyMint and Keystore2 API shapes.
2025-11-22 15:24:43 +01:00