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
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
package android.hardware.security.keymint;
|
||||
|
||||
public @interface BlockMode {
|
||||
public static final int ECB = 1;
|
||||
public static final int CBC = 2;
|
||||
public static final int CTR = 3;
|
||||
public static final int GCM = 32;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package android.hardware.security.keymint;
|
||||
|
||||
public @interface PaddingMode {
|
||||
public static final int NONE = 1;
|
||||
public static final int RSA_OAEP = 2;
|
||||
public static final int RSA_PSS = 3;
|
||||
public static final int RSA_PKCS1_1_5_ENCRYPT = 4;
|
||||
public static final int RSA_PKCS1_1_5_SIGN = 5;
|
||||
public static final int PKCS7 = 64;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package android.system.keystore2;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public class CreateOperationResponse implements Parcelable {
|
||||
public IKeystoreOperation iOperation;
|
||||
|
||||
public OperationChallenge operationChallenge;
|
||||
|
||||
public KeyParameters parameters;
|
||||
|
||||
public byte[] upgradedBlob;
|
||||
|
||||
public static final Creator<CreateOperationResponse> CREATOR = new Creator<CreateOperationResponse>() {
|
||||
@Override
|
||||
public CreateOperationResponse createFromParcel(Parcel in) {
|
||||
throw new UnsupportedOperationException("STUB!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CreateOperationResponse[] newArray(int size) {
|
||||
throw new UnsupportedOperationException("STUB!");
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
throw new UnsupportedOperationException("STUB!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel parcel, int i) {
|
||||
throw new UnsupportedOperationException("STUB!");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package android.system.keystore2;
|
||||
|
||||
public @interface Domain {
|
||||
public static final int APP = 0;
|
||||
public static final int GRANT = 1;
|
||||
public static final int SELINUX = 2;
|
||||
public static final int BLOB = 3;
|
||||
public static final int KEY_ID = 4;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package android.system.keystore2;
|
||||
|
||||
import android.os.IBinder;
|
||||
import android.os.Binder;
|
||||
import android.os.IInterface;
|
||||
|
||||
public interface IKeystoreOperation extends IInterface {
|
||||
public static final java.lang.String DESCRIPTOR = "android.system.keystore2.IKeystoreOperation";
|
||||
|
||||
public void updateAad(byte[] aadInput);
|
||||
|
||||
public byte[] update(byte[] input);
|
||||
|
||||
public byte[] finish(byte[] input, byte[] signature);
|
||||
|
||||
public void abort() throws android.os.RemoteException;
|
||||
|
||||
abstract class Stub extends Binder implements IKeystoreOperation {
|
||||
public static IKeystoreOperation asInterface(IBinder b) {
|
||||
throw new UnsupportedOperationException("STUB!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder asBinder() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAad(byte[] aadInput) {
|
||||
throw new UnsupportedOperationException("STUB!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package android.system.keystore2;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.hardware.security.keymint.KeyParameter;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public class KeyParameters implements Parcelable {
|
||||
public KeyParameter[] keyParameter;
|
||||
|
||||
public static final Creator<KeyParameters> CREATOR = new Creator<KeyParameters>() {
|
||||
@Override
|
||||
public KeyParameters createFromParcel(Parcel in) {
|
||||
throw new UnsupportedOperationException("STUB!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyParameters[] newArray(int size) {
|
||||
throw new UnsupportedOperationException("STUB!");
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
throw new UnsupportedOperationException("STUB!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel parcel, int i) {
|
||||
throw new UnsupportedOperationException("STUB!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package android.system.keystore2;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public class OperationChallenge implements Parcelable {
|
||||
public long challenge = 0L;
|
||||
|
||||
public static final Creator<OperationChallenge> CREATOR = new Creator<OperationChallenge>() {
|
||||
@Override
|
||||
public OperationChallenge createFromParcel(Parcel in) {
|
||||
throw new UnsupportedOperationException("STUB!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public OperationChallenge[] newArray(int size) {
|
||||
throw new UnsupportedOperationException("STUB!");
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
throw new UnsupportedOperationException("STUB!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel parcel, int i) {
|
||||
throw new UnsupportedOperationException("STUB!");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user