Merge "Use std::optional instead of std::unique_ptr"
diff --git a/keystore2/Android.bp b/keystore2/Android.bp
index 2c135f8..40d91c2 100644
--- a/keystore2/Android.bp
+++ b/keystore2/Android.bp
@@ -19,7 +19,7 @@
 
     rustlibs: [
         "android.system.keystore2-rust",
-        "libandroid_hardware_keymint_keystore2",
+        "android.hardware.keymint-rust",
         "libanyhow",
         "libbinder_rs",
         "libkeystore2_selinux",
@@ -40,8 +40,8 @@
     auto_gen_config: true,
     rustlibs: [
         "android.system.keystore2-rust",
+        "android.hardware.keymint-rust",
         "libandroid_logger",
-        "libandroid_hardware_keymint_keystore2",
         "libanyhow",
         "libbinder_rs",
         "libkeystore2_crypto_bindgen",
@@ -106,18 +106,3 @@
     ],
     name: "keystore2_crypto_test",
 }
-
-// This is a placeholder for the libraries that will be generated from the AIDL specs
-// eventually.
-rust_library {
-    name: "libandroid_hardware_keymint_keystore2",
-    crate_name: "android_hardware_keymint",
-
-    srcs: ["src/android_hardware_keymint.rs"],
-
-    rustlibs: [
-        "libbinder_rs",
-        "liblazy_static",
-    ],
-}
-
diff --git a/keystore2/src/android_hardware_keymint.rs b/keystore2/src/android_hardware_keymint.rs
deleted file mode 100644
index 103b9b9..0000000
--- a/keystore2/src/android_hardware_keymint.rs
+++ /dev/null
@@ -1,1656 +0,0 @@
-#![allow(non_snake_case)]
-#![allow(missing_docs)]
-#![allow(clippy::identity_op)]
-#![allow(clippy::excessive_precision)]
-#![allow(clippy::too_many_arguments)]
-pub use binder::public_api as binder;
-pub mod aidl {
-  pub mod android {
-    pub mod hardware {
-      pub mod keymint {
-        pub mod Algorithm {
-          #![allow(non_upper_case_globals)]
-          use binder::declare_binder_enum;
-          declare_binder_enum! { Algorithm : i32 {
-            RSA = 1,
-            EC = 3,
-            AES = 32,
-            TRIPLE_DES = 33,
-            HMAC = 128,
-          } }
-          pub(crate) mod mangled { pub use super::Algorithm as _7_android_8_hardware_7_keymint_9_Algorithm; }
-        }
-        pub mod BeginResult {
-          #[derive(Debug)]
-          pub struct BeginResult {
-            pub challenge: i64, 
-            pub params: Vec<crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter>, 
-            pub operation: Option<Box<dyn crate::mangled::_7_android_8_hardware_7_keymint_17_IKeyMintOperation>>, 
-          }
-          pub(crate) mod mangled { pub use super::BeginResult as _7_android_8_hardware_7_keymint_11_BeginResult; }
-          impl Default for BeginResult {
-            fn default() -> Self {
-              Self {
-                challenge: 0,
-                params: Default::default(),
-                operation: Default::default(),
-              }
-            }
-          }
-          impl binder::parcel::Serialize for BeginResult {
-            fn serialize(&self, parcel: &mut binder::parcel::Parcel) -> binder::Result<()> {
-              <Self as binder::parcel::SerializeOption>::serialize_option(Some(self), parcel)
-            }
-          }
-          impl binder::parcel::SerializeArray for BeginResult {}
-          impl binder::parcel::SerializeOption for BeginResult {
-            fn serialize_option(this: Option<&Self>, parcel: &mut binder::parcel::Parcel) -> binder::Result<()> {
-              let this = if let Some(this) = this {
-                parcel.write(&1i32)?;
-                this
-              } else {
-                return parcel.write(&0i32);
-              };
-              let start_pos = parcel.get_data_position();
-              parcel.write(&0i32)?;
-              parcel.write(&this.challenge)?;
-              parcel.write(&this.params)?;
-              let __field_ref = this.operation.as_ref().ok_or(binder::StatusCode::UNEXPECTED_NULL)?;
-              parcel.write(__field_ref)?;
-              let end_pos = parcel.get_data_position();
-              let parcelable_size = (end_pos - start_pos) as i32;
-              unsafe { parcel.set_data_position(start_pos)?; }
-              parcel.write(&parcelable_size)?;
-              unsafe { parcel.set_data_position(end_pos)?; }
-              Ok(())
-            }
-          }
-          impl binder::parcel::Deserialize for BeginResult {
-            fn deserialize(parcel: &binder::parcel::Parcel) -> binder::Result<Self> {
-              <Self as binder::parcel::DeserializeOption>::deserialize_option(parcel)
-                 .transpose()
-                 .unwrap_or(Err(binder::StatusCode::UNEXPECTED_NULL))
-            }
-          }
-          impl binder::parcel::DeserializeArray for BeginResult {}
-          impl binder::parcel::DeserializeOption for BeginResult {
-            fn deserialize_option(parcel: &binder::parcel::Parcel) -> binder::Result<Option<Self>> {
-              let status: i32 = parcel.read()?;
-              if status == 0 { return Ok(None); }
-              let start_pos = parcel.get_data_position();
-              let parcelable_size: i32 = parcel.read()?;
-              if parcelable_size < 0 { return Err(binder::StatusCode::BAD_VALUE); }
-              let mut result = Self::default();
-              result.challenge = parcel.read()?;
-              if (parcel.get_data_position() - start_pos) == parcelable_size {
-                return Ok(Some(result));
-              }
-              result.params = parcel.read()?;
-              if (parcel.get_data_position() - start_pos) == parcelable_size {
-                return Ok(Some(result));
-              }
-              result.operation = Some(parcel.read()?);
-              if (parcel.get_data_position() - start_pos) == parcelable_size {
-                return Ok(Some(result));
-              }
-              Ok(Some(result))
-            }
-          }
-        }
-        pub mod BlockMode {
-          #![allow(non_upper_case_globals)]
-          use binder::declare_binder_enum;
-          declare_binder_enum! { BlockMode : i32 {
-            ECB = 1,
-            CBC = 2,
-            CTR = 3,
-            GCM = 32,
-          } }
-          pub(crate) mod mangled { pub use super::BlockMode as _7_android_8_hardware_7_keymint_9_BlockMode; }
-        }
-        pub mod Certificate {
-          #[derive(Debug)]
-          pub struct Certificate {
-            pub encodedCertificate: Vec<u8>, 
-          }
-          pub(crate) mod mangled { pub use super::Certificate as _7_android_8_hardware_7_keymint_11_Certificate; }
-          impl Default for Certificate {
-            fn default() -> Self {
-              Self {
-                encodedCertificate: Default::default(),
-              }
-            }
-          }
-          impl binder::parcel::Serialize for Certificate {
-            fn serialize(&self, parcel: &mut binder::parcel::Parcel) -> binder::Result<()> {
-              <Self as binder::parcel::SerializeOption>::serialize_option(Some(self), parcel)
-            }
-          }
-          impl binder::parcel::SerializeArray for Certificate {}
-          impl binder::parcel::SerializeOption for Certificate {
-            fn serialize_option(this: Option<&Self>, parcel: &mut binder::parcel::Parcel) -> binder::Result<()> {
-              let this = if let Some(this) = this {
-                parcel.write(&1i32)?;
-                this
-              } else {
-                return parcel.write(&0i32);
-              };
-              let start_pos = parcel.get_data_position();
-              parcel.write(&0i32)?;
-              parcel.write(&this.encodedCertificate)?;
-              let end_pos = parcel.get_data_position();
-              let parcelable_size = (end_pos - start_pos) as i32;
-              unsafe { parcel.set_data_position(start_pos)?; }
-              parcel.write(&parcelable_size)?;
-              unsafe { parcel.set_data_position(end_pos)?; }
-              Ok(())
-            }
-          }
-          impl binder::parcel::Deserialize for Certificate {
-            fn deserialize(parcel: &binder::parcel::Parcel) -> binder::Result<Self> {
-              <Self as binder::parcel::DeserializeOption>::deserialize_option(parcel)
-                 .transpose()
-                 .unwrap_or(Err(binder::StatusCode::UNEXPECTED_NULL))
-            }
-          }
-          impl binder::parcel::DeserializeArray for Certificate {}
-          impl binder::parcel::DeserializeOption for Certificate {
-            fn deserialize_option(parcel: &binder::parcel::Parcel) -> binder::Result<Option<Self>> {
-              let status: i32 = parcel.read()?;
-              if status == 0 { return Ok(None); }
-              let start_pos = parcel.get_data_position();
-              let parcelable_size: i32 = parcel.read()?;
-              if parcelable_size < 0 { return Err(binder::StatusCode::BAD_VALUE); }
-              let mut result = Self::default();
-              result.encodedCertificate = parcel.read()?;
-              if (parcel.get_data_position() - start_pos) == parcelable_size {
-                return Ok(Some(result));
-              }
-              Ok(Some(result))
-            }
-          }
-        }
-        pub mod Constants {
-          #![allow(non_upper_case_globals)]
-          use binder::declare_binder_enum;
-          declare_binder_enum! { Constants : i32 {
-            AUTH_TOKEN_MAC_LENGTH = 32,
-          } }
-          pub(crate) mod mangled { pub use super::Constants as _7_android_8_hardware_7_keymint_9_Constants; }
-        }
-        pub mod Digest {
-          #![allow(non_upper_case_globals)]
-          use binder::declare_binder_enum;
-          declare_binder_enum! { Digest : i32 {
-            NONE = 0,
-            MD5 = 1,
-            SHA1 = 2,
-            SHA_2_224 = 3,
-            SHA_2_256 = 4,
-            SHA_2_384 = 5,
-            SHA_2_512 = 6,
-          } }
-          pub(crate) mod mangled { pub use super::Digest as _7_android_8_hardware_7_keymint_6_Digest; }
-        }
-        pub mod EcCurve {
-          #![allow(non_upper_case_globals)]
-          use binder::declare_binder_enum;
-          declare_binder_enum! { EcCurve : i32 {
-            P_224 = 0,
-            P_256 = 1,
-            P_384 = 2,
-            P_521 = 3,
-          } }
-          pub(crate) mod mangled { pub use super::EcCurve as _7_android_8_hardware_7_keymint_7_EcCurve; }
-        }
-        pub mod ErrorCode {
-          #![allow(non_upper_case_globals)]
-          use binder::declare_binder_enum;
-          declare_binder_enum! { ErrorCode : i32 {
-            OK = 0,
-            ROOT_OF_TRUST_ALREADY_SET = -1,
-            UNSUPPORTED_PURPOSE = -2,
-            INCOMPATIBLE_PURPOSE = -3,
-            UNSUPPORTED_ALGORITHM = -4,
-            INCOMPATIBLE_ALGORITHM = -5,
-            UNSUPPORTED_KEY_SIZE = -6,
-            UNSUPPORTED_BLOCK_MODE = -7,
-            INCOMPATIBLE_BLOCK_MODE = -8,
-            UNSUPPORTED_MAC_LENGTH = -9,
-            UNSUPPORTED_PADDING_MODE = -10,
-            INCOMPATIBLE_PADDING_MODE = -11,
-            UNSUPPORTED_DIGEST = -12,
-            INCOMPATIBLE_DIGEST = -13,
-            INVALID_EXPIRATION_TIME = -14,
-            INVALID_USER_ID = -15,
-            INVALID_AUTHORIZATION_TIMEOUT = -16,
-            UNSUPPORTED_KEY_FORMAT = -17,
-            INCOMPATIBLE_KEY_FORMAT = -18,
-            UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM = -19,
-            UNSUPPORTED_KEY_VERIFICATION_ALGORITHM = -20,
-            INVALID_INPUT_LENGTH = -21,
-            KEY_EXPORT_OPTIONS_INVALID = -22,
-            DELEGATION_NOT_ALLOWED = -23,
-            KEY_NOT_YET_VALID = -24,
-            KEY_EXPIRED = -25,
-            KEY_USER_NOT_AUTHENTICATED = -26,
-            OUTPUT_PARAMETER_NULL = -27,
-            INVALID_OPERATION_HANDLE = -28,
-            INSUFFICIENT_BUFFER_SPACE = -29,
-            VERIFICATION_FAILED = -30,
-            TOO_MANY_OPERATIONS = -31,
-            UNEXPECTED_NULL_POINTER = -32,
-            INVALID_KEY_BLOB = -33,
-            IMPORTED_KEY_NOT_ENCRYPTED = -34,
-            IMPORTED_KEY_DECRYPTION_FAILED = -35,
-            IMPORTED_KEY_NOT_SIGNED = -36,
-            IMPORTED_KEY_VERIFICATION_FAILED = -37,
-            INVALID_ARGUMENT = -38,
-            UNSUPPORTED_TAG = -39,
-            INVALID_TAG = -40,
-            MEMORY_ALLOCATION_FAILED = -41,
-            IMPORT_PARAMETER_MISMATCH = -44,
-            SECURE_HW_ACCESS_DENIED = -45,
-            OPERATION_CANCELLED = -46,
-            CONCURRENT_ACCESS_CONFLICT = -47,
-            SECURE_HW_BUSY = -48,
-            SECURE_HW_COMMUNICATION_FAILED = -49,
-            UNSUPPORTED_EC_FIELD = -50,
-            MISSING_NONCE = -51,
-            INVALID_NONCE = -52,
-            MISSING_MAC_LENGTH = -53,
-            KEY_RATE_LIMIT_EXCEEDED = -54,
-            CALLER_NONCE_PROHIBITED = -55,
-            KEY_MAX_OPS_EXCEEDED = -56,
-            INVALID_MAC_LENGTH = -57,
-            MISSING_MIN_MAC_LENGTH = -58,
-            UNSUPPORTED_MIN_MAC_LENGTH = -59,
-            UNSUPPORTED_KDF = -60,
-            UNSUPPORTED_EC_CURVE = -61,
-            KEY_REQUIRES_UPGRADE = -62,
-            ATTESTATION_CHALLENGE_MISSING = -63,
-            KEYMINT_NOT_CONFIGURED = -64,
-            ATTESTATION_APPLICATION_ID_MISSING = -65,
-            CANNOT_ATTEST_IDS = -66,
-            ROLLBACK_RESISTANCE_UNAVAILABLE = -67,
-            HARDWARE_TYPE_UNAVAILABLE = -68,
-            PROOF_OF_PRESENCE_REQUIRED = -69,
-            CONCURRENT_PROOF_OF_PRESENCE_REQUESTED = -70,
-            NO_USER_CONFIRMATION = -71,
-            DEVICE_LOCKED = -72,
-            EARLY_BOOT_ENDED = -73,
-            ATTESTATION_KEYS_NOT_PROVISIONED = -74,
-            ATTESTATION_IDS_NOT_PROVISIONED = -75,
-            INVALID_OPERATION = -76,
-            STORAGE_KEY_UNSUPPORTED = -77,
-            UNIMPLEMENTED = -100,
-            VERSION_MISMATCH = -101,
-            UNKNOWN_ERROR = -1000,
-          } }
-          pub(crate) mod mangled { pub use super::ErrorCode as _7_android_8_hardware_7_keymint_9_ErrorCode; }
-        }
-        pub mod HardwareAuthToken {
-          #[derive(Debug)]
-          pub struct HardwareAuthToken {
-            pub challenge: i64, 
-            pub userId: i64, 
-            pub authenticatorId: i64, 
-            pub authenticatorType: crate::mangled::_7_android_8_hardware_7_keymint_25_HardwareAuthenticatorType, 
-            pub timestamp: crate::mangled::_7_android_8_hardware_7_keymint_9_Timestamp, 
-            pub mac: Vec<u8>, 
-          }
-          pub(crate) mod mangled { pub use super::HardwareAuthToken as _7_android_8_hardware_7_keymint_17_HardwareAuthToken; }
-          impl Default for HardwareAuthToken {
-            fn default() -> Self {
-              Self {
-                challenge: 0,
-                userId: 0,
-                authenticatorId: 0,
-                authenticatorType: Default::default(),
-                timestamp: Default::default(),
-                mac: Default::default(),
-              }
-            }
-          }
-          impl binder::parcel::Serialize for HardwareAuthToken {
-            fn serialize(&self, parcel: &mut binder::parcel::Parcel) -> binder::Result<()> {
-              <Self as binder::parcel::SerializeOption>::serialize_option(Some(self), parcel)
-            }
-          }
-          impl binder::parcel::SerializeArray for HardwareAuthToken {}
-          impl binder::parcel::SerializeOption for HardwareAuthToken {
-            fn serialize_option(this: Option<&Self>, parcel: &mut binder::parcel::Parcel) -> binder::Result<()> {
-              let this = if let Some(this) = this {
-                parcel.write(&1i32)?;
-                this
-              } else {
-                return parcel.write(&0i32);
-              };
-              let start_pos = parcel.get_data_position();
-              parcel.write(&0i32)?;
-              parcel.write(&this.challenge)?;
-              parcel.write(&this.userId)?;
-              parcel.write(&this.authenticatorId)?;
-              parcel.write(&this.authenticatorType)?;
-              parcel.write(&this.timestamp)?;
-              parcel.write(&this.mac)?;
-              let end_pos = parcel.get_data_position();
-              let parcelable_size = (end_pos - start_pos) as i32;
-              unsafe { parcel.set_data_position(start_pos)?; }
-              parcel.write(&parcelable_size)?;
-              unsafe { parcel.set_data_position(end_pos)?; }
-              Ok(())
-            }
-          }
-          impl binder::parcel::Deserialize for HardwareAuthToken {
-            fn deserialize(parcel: &binder::parcel::Parcel) -> binder::Result<Self> {
-              <Self as binder::parcel::DeserializeOption>::deserialize_option(parcel)
-                 .transpose()
-                 .unwrap_or(Err(binder::StatusCode::UNEXPECTED_NULL))
-            }
-          }
-          impl binder::parcel::DeserializeArray for HardwareAuthToken {}
-          impl binder::parcel::DeserializeOption for HardwareAuthToken {
-            fn deserialize_option(parcel: &binder::parcel::Parcel) -> binder::Result<Option<Self>> {
-              let status: i32 = parcel.read()?;
-              if status == 0 { return Ok(None); }
-              let start_pos = parcel.get_data_position();
-              let parcelable_size: i32 = parcel.read()?;
-              if parcelable_size < 0 { return Err(binder::StatusCode::BAD_VALUE); }
-              let mut result = Self::default();
-              result.challenge = parcel.read()?;
-              if (parcel.get_data_position() - start_pos) == parcelable_size {
-                return Ok(Some(result));
-              }
-              result.userId = parcel.read()?;
-              if (parcel.get_data_position() - start_pos) == parcelable_size {
-                return Ok(Some(result));
-              }
-              result.authenticatorId = parcel.read()?;
-              if (parcel.get_data_position() - start_pos) == parcelable_size {
-                return Ok(Some(result));
-              }
-              result.authenticatorType = parcel.read()?;
-              if (parcel.get_data_position() - start_pos) == parcelable_size {
-                return Ok(Some(result));
-              }
-              result.timestamp = parcel.read()?;
-              if (parcel.get_data_position() - start_pos) == parcelable_size {
-                return Ok(Some(result));
-              }
-              result.mac = parcel.read()?;
-              if (parcel.get_data_position() - start_pos) == parcelable_size {
-                return Ok(Some(result));
-              }
-              Ok(Some(result))
-            }
-          }
-        }
-        pub mod HardwareAuthenticatorType {
-          #![allow(non_upper_case_globals)]
-          use binder::declare_binder_enum;
-          declare_binder_enum! { HardwareAuthenticatorType : i32 {
-            NONE = 0,
-            PASSWORD = 1,
-            FINGERPRINT = 2,
-            ANY = -1,
-          } }
-          pub(crate) mod mangled { pub use super::HardwareAuthenticatorType as _7_android_8_hardware_7_keymint_25_HardwareAuthenticatorType; }
-        }
-        pub mod HmacSharingParameters {
-          #[derive(Debug)]
-          pub struct HmacSharingParameters {
-            pub seed: Vec<u8>, 
-            pub nonce: Vec<u8>, 
-          }
-          pub(crate) mod mangled { pub use super::HmacSharingParameters as _7_android_8_hardware_7_keymint_21_HmacSharingParameters; }
-          impl Default for HmacSharingParameters {
-            fn default() -> Self {
-              Self {
-                seed: Default::default(),
-                nonce: Default::default(),
-              }
-            }
-          }
-          impl binder::parcel::Serialize for HmacSharingParameters {
-            fn serialize(&self, parcel: &mut binder::parcel::Parcel) -> binder::Result<()> {
-              <Self as binder::parcel::SerializeOption>::serialize_option(Some(self), parcel)
-            }
-          }
-          impl binder::parcel::SerializeArray for HmacSharingParameters {}
-          impl binder::parcel::SerializeOption for HmacSharingParameters {
-            fn serialize_option(this: Option<&Self>, parcel: &mut binder::parcel::Parcel) -> binder::Result<()> {
-              let this = if let Some(this) = this {
-                parcel.write(&1i32)?;
-                this
-              } else {
-                return parcel.write(&0i32);
-              };
-              let start_pos = parcel.get_data_position();
-              parcel.write(&0i32)?;
-              parcel.write(&this.seed)?;
-              parcel.write(&this.nonce)?;
-              let end_pos = parcel.get_data_position();
-              let parcelable_size = (end_pos - start_pos) as i32;
-              unsafe { parcel.set_data_position(start_pos)?; }
-              parcel.write(&parcelable_size)?;
-              unsafe { parcel.set_data_position(end_pos)?; }
-              Ok(())
-            }
-          }
-          impl binder::parcel::Deserialize for HmacSharingParameters {
-            fn deserialize(parcel: &binder::parcel::Parcel) -> binder::Result<Self> {
-              <Self as binder::parcel::DeserializeOption>::deserialize_option(parcel)
-                 .transpose()
-                 .unwrap_or(Err(binder::StatusCode::UNEXPECTED_NULL))
-            }
-          }
-          impl binder::parcel::DeserializeArray for HmacSharingParameters {}
-          impl binder::parcel::DeserializeOption for HmacSharingParameters {
-            fn deserialize_option(parcel: &binder::parcel::Parcel) -> binder::Result<Option<Self>> {
-              let status: i32 = parcel.read()?;
-              if status == 0 { return Ok(None); }
-              let start_pos = parcel.get_data_position();
-              let parcelable_size: i32 = parcel.read()?;
-              if parcelable_size < 0 { return Err(binder::StatusCode::BAD_VALUE); }
-              let mut result = Self::default();
-              result.seed = parcel.read()?;
-              if (parcel.get_data_position() - start_pos) == parcelable_size {
-                return Ok(Some(result));
-              }
-              result.nonce = parcel.read()?;
-              if (parcel.get_data_position() - start_pos) == parcelable_size {
-                return Ok(Some(result));
-              }
-              Ok(Some(result))
-            }
-          }
-        }
-        pub mod IKeyMintDevice {
-          #![allow(non_upper_case_globals)]
-          #![allow(non_snake_case)]
-          #[allow(unused_imports)] use binder::IBinder;
-          use binder::declare_binder_interface;
-          declare_binder_interface! {
-            IKeyMintDevice["android.hardware.keymint.IKeyMintDevice"] {
-              native: BnKeyMintDevice(on_transact),
-              proxy: BpKeyMintDevice {
-              },
-            }
-          }
-          pub trait IKeyMintDevice: binder::Interface + Send {
-            fn get_descriptor() -> &'static str where Self: Sized { "android.hardware.keymint.IKeyMintDevice" }
-            fn getHardwareInfo(&self) -> binder::public_api::Result<crate::mangled::_7_android_8_hardware_7_keymint_19_KeyMintHardwareInfo> {
-              Err(binder::StatusCode::UNKNOWN_TRANSACTION.into())
-            }
-            fn verifyAuthorization(&self, _arg_challenge: i64, _arg_parametersToVerify: &[crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter], _arg_token: &crate::mangled::_7_android_8_hardware_7_keymint_17_HardwareAuthToken) -> binder::public_api::Result<crate::mangled::_7_android_8_hardware_7_keymint_17_VerificationToken> {
-              Err(binder::StatusCode::UNKNOWN_TRANSACTION.into())
-            }
-            fn addRngEntropy(&self, _arg_data: &[u8]) -> binder::public_api::Result<()> {
-              Err(binder::StatusCode::UNKNOWN_TRANSACTION.into())
-            }
-            fn generateKey(&self, _arg_keyParams: &[crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter], _arg_generatedKeyBlob: &mut Vec<u8>, _arg_generatedKeyCharacteristics: &mut crate::mangled::_7_android_8_hardware_7_keymint_18_KeyCharacteristics, _arg_outCertChain: &mut Vec<crate::mangled::_7_android_8_hardware_7_keymint_11_Certificate>) -> binder::public_api::Result<()> {
-              Err(binder::StatusCode::UNKNOWN_TRANSACTION.into())
-            }
-            fn importKey(&self, _arg_inKeyParams: &[crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter], _arg_inKeyFormat: crate::mangled::_7_android_8_hardware_7_keymint_9_KeyFormat, _arg_inKeyData: &[u8], _arg_outImportedKeyBlob: &mut Vec<u8>, _arg_outImportedKeyCharacteristics: &mut crate::mangled::_7_android_8_hardware_7_keymint_18_KeyCharacteristics, _arg_outCertChain: &mut Vec<crate::mangled::_7_android_8_hardware_7_keymint_11_Certificate>) -> binder::public_api::Result<()> {
-              Err(binder::StatusCode::UNKNOWN_TRANSACTION.into())
-            }
-            fn importWrappedKey(&self, _arg_inWrappedKeyData: &[u8], _arg_inWrappingKeyBlob: &[u8], _arg_inMaskingKey: &[u8], _arg_inUnwrappingParams: &[crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter], _arg_inPasswordSid: i64, _arg_inBiometricSid: i64, _arg_outImportedKeyBlob: &mut Vec<u8>, _arg_outImportedKeyCharacteristics: &mut crate::mangled::_7_android_8_hardware_7_keymint_18_KeyCharacteristics) -> binder::public_api::Result<()> {
-              Err(binder::StatusCode::UNKNOWN_TRANSACTION.into())
-            }
-            fn upgradeKey(&self, _arg_inKeyBlobToUpgrade: &[u8], _arg_inUpgradeParams: &[crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter]) -> binder::public_api::Result<Vec<u8>> {
-              Err(binder::StatusCode::UNKNOWN_TRANSACTION.into())
-            }
-            fn deleteKey(&self, _arg_inKeyBlob: &[u8]) -> binder::public_api::Result<()> {
-              Err(binder::StatusCode::UNKNOWN_TRANSACTION.into())
-            }
-            fn deleteAllKeys(&self) -> binder::public_api::Result<()> {
-              Err(binder::StatusCode::UNKNOWN_TRANSACTION.into())
-            }
-            fn destroyAttestationIds(&self) -> binder::public_api::Result<()> {
-              Err(binder::StatusCode::UNKNOWN_TRANSACTION.into())
-            }
-            fn begin(&self, _arg_inPurpose: crate::mangled::_7_android_8_hardware_7_keymint_10_KeyPurpose, _arg_inKeyBlob: &[u8], _arg_inParams: &[crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter], _arg_inAuthToken: &crate::mangled::_7_android_8_hardware_7_keymint_17_HardwareAuthToken) -> binder::public_api::Result<crate::mangled::_7_android_8_hardware_7_keymint_11_BeginResult> {
-              Err(binder::StatusCode::UNKNOWN_TRANSACTION.into())
-            }
-            fn getDefaultImpl() -> IKeyMintDeviceDefault where Self: Sized {
-              DEFAULT_IMPL.lock().unwrap().clone()
-            }
-            fn setDefaultImpl(d: IKeyMintDeviceDefault) -> IKeyMintDeviceDefault where Self: Sized {
-              std::mem::replace(&mut *DEFAULT_IMPL.lock().unwrap(), d)
-            }
-          }
-          pub mod transactions {
-            #[allow(unused_imports)] use binder::IBinder;
-            pub const getHardwareInfo: binder::TransactionCode = binder::SpIBinder::FIRST_CALL_TRANSACTION + 0;
-            pub const verifyAuthorization: binder::TransactionCode = binder::SpIBinder::FIRST_CALL_TRANSACTION + 1;
-            pub const addRngEntropy: binder::TransactionCode = binder::SpIBinder::FIRST_CALL_TRANSACTION + 2;
-            pub const generateKey: binder::TransactionCode = binder::SpIBinder::FIRST_CALL_TRANSACTION + 3;
-            pub const importKey: binder::TransactionCode = binder::SpIBinder::FIRST_CALL_TRANSACTION + 4;
-            pub const importWrappedKey: binder::TransactionCode = binder::SpIBinder::FIRST_CALL_TRANSACTION + 5;
-            pub const upgradeKey: binder::TransactionCode = binder::SpIBinder::FIRST_CALL_TRANSACTION + 6;
-            pub const deleteKey: binder::TransactionCode = binder::SpIBinder::FIRST_CALL_TRANSACTION + 7;
-            pub const deleteAllKeys: binder::TransactionCode = binder::SpIBinder::FIRST_CALL_TRANSACTION + 8;
-            pub const destroyAttestationIds: binder::TransactionCode = binder::SpIBinder::FIRST_CALL_TRANSACTION + 9;
-            pub const begin: binder::TransactionCode = binder::SpIBinder::FIRST_CALL_TRANSACTION + 10;
-          }
-          pub type IKeyMintDeviceDefault = Option<std::sync::Arc<dyn IKeyMintDevice + Sync>>;
-          use lazy_static::lazy_static;
-          lazy_static! {
-            static ref DEFAULT_IMPL: std::sync::Mutex<IKeyMintDeviceDefault> = std::sync::Mutex::new(None);
-          }
-          pub(crate) mod mangled { pub use super::IKeyMintDevice as _7_android_8_hardware_7_keymint_14_IKeyMintDevice; }
-          impl IKeyMintDevice for BpKeyMintDevice {
-            fn getHardwareInfo(&self) -> binder::public_api::Result<crate::mangled::_7_android_8_hardware_7_keymint_19_KeyMintHardwareInfo> {
-              let _aidl_reply = self.binder.transact(transactions::getHardwareInfo, 0, |_aidl_data| {
-                Ok(())
-              });
-              if let Err(binder::StatusCode::UNKNOWN_TRANSACTION) = _aidl_reply {
-                if let Some(_aidl_default_impl) = <Self as IKeyMintDevice>::getDefaultImpl() {
-                  return _aidl_default_impl.getHardwareInfo();
-                }
-              }
-              let _aidl_reply = _aidl_reply?;
-              let _aidl_status: binder::Status = _aidl_reply.read()?;
-              if !_aidl_status.is_ok() { return Err(_aidl_status); }
-              let _aidl_return: crate::mangled::_7_android_8_hardware_7_keymint_19_KeyMintHardwareInfo = _aidl_reply.read()?;
-              Ok(_aidl_return)
-            }
-            fn verifyAuthorization(&self, _arg_challenge: i64, _arg_parametersToVerify: &[crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter], _arg_token: &crate::mangled::_7_android_8_hardware_7_keymint_17_HardwareAuthToken) -> binder::public_api::Result<crate::mangled::_7_android_8_hardware_7_keymint_17_VerificationToken> {
-              let _aidl_reply = self.binder.transact(transactions::verifyAuthorization, 0, |_aidl_data| {
-                _aidl_data.write(&_arg_challenge)?;
-                _aidl_data.write(_arg_parametersToVerify)?;
-                _aidl_data.write(_arg_token)?;
-                Ok(())
-              });
-              if let Err(binder::StatusCode::UNKNOWN_TRANSACTION) = _aidl_reply {
-                if let Some(_aidl_default_impl) = <Self as IKeyMintDevice>::getDefaultImpl() {
-                  return _aidl_default_impl.verifyAuthorization(_arg_challenge, _arg_parametersToVerify, _arg_token);
-                }
-              }
-              let _aidl_reply = _aidl_reply?;
-              let _aidl_status: binder::Status = _aidl_reply.read()?;
-              if !_aidl_status.is_ok() { return Err(_aidl_status); }
-              let _aidl_return: crate::mangled::_7_android_8_hardware_7_keymint_17_VerificationToken = _aidl_reply.read()?;
-              Ok(_aidl_return)
-            }
-            fn addRngEntropy(&self, _arg_data: &[u8]) -> binder::public_api::Result<()> {
-              let _aidl_reply = self.binder.transact(transactions::addRngEntropy, 0, |_aidl_data| {
-                _aidl_data.write(_arg_data)?;
-                Ok(())
-              });
-              if let Err(binder::StatusCode::UNKNOWN_TRANSACTION) = _aidl_reply {
-                if let Some(_aidl_default_impl) = <Self as IKeyMintDevice>::getDefaultImpl() {
-                  return _aidl_default_impl.addRngEntropy(_arg_data);
-                }
-              }
-              let _aidl_reply = _aidl_reply?;
-              let _aidl_status: binder::Status = _aidl_reply.read()?;
-              if !_aidl_status.is_ok() { return Err(_aidl_status); }
-              Ok(())
-            }
-            fn generateKey(&self, _arg_keyParams: &[crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter], _arg_generatedKeyBlob: &mut Vec<u8>, _arg_generatedKeyCharacteristics: &mut crate::mangled::_7_android_8_hardware_7_keymint_18_KeyCharacteristics, _arg_outCertChain: &mut Vec<crate::mangled::_7_android_8_hardware_7_keymint_11_Certificate>) -> binder::public_api::Result<()> {
-              let _aidl_reply = self.binder.transact(transactions::generateKey, 0, |_aidl_data| {
-                _aidl_data.write(_arg_keyParams)?;
-                _aidl_data.write_slice_size(Some(_arg_generatedKeyBlob))?;
-                _aidl_data.write_slice_size(Some(_arg_outCertChain))?;
-                Ok(())
-              });
-              if let Err(binder::StatusCode::UNKNOWN_TRANSACTION) = _aidl_reply {
-                if let Some(_aidl_default_impl) = <Self as IKeyMintDevice>::getDefaultImpl() {
-                  return _aidl_default_impl.generateKey(_arg_keyParams, _arg_generatedKeyBlob, _arg_generatedKeyCharacteristics, _arg_outCertChain);
-                }
-              }
-              let _aidl_reply = _aidl_reply?;
-              let _aidl_status: binder::Status = _aidl_reply.read()?;
-              if !_aidl_status.is_ok() { return Err(_aidl_status); }
-              *_arg_generatedKeyBlob = _aidl_reply.read()?;
-              *_arg_generatedKeyCharacteristics = _aidl_reply.read()?;
-              *_arg_outCertChain = _aidl_reply.read()?;
-              Ok(())
-            }
-            fn importKey(&self, _arg_inKeyParams: &[crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter], _arg_inKeyFormat: crate::mangled::_7_android_8_hardware_7_keymint_9_KeyFormat, _arg_inKeyData: &[u8], _arg_outImportedKeyBlob: &mut Vec<u8>, _arg_outImportedKeyCharacteristics: &mut crate::mangled::_7_android_8_hardware_7_keymint_18_KeyCharacteristics, _arg_outCertChain: &mut Vec<crate::mangled::_7_android_8_hardware_7_keymint_11_Certificate>) -> binder::public_api::Result<()> {
-              let _aidl_reply = self.binder.transact(transactions::importKey, 0, |_aidl_data| {
-                _aidl_data.write(_arg_inKeyParams)?;
-                _aidl_data.write(&_arg_inKeyFormat)?;
-                _aidl_data.write(_arg_inKeyData)?;
-                _aidl_data.write_slice_size(Some(_arg_outImportedKeyBlob))?;
-                _aidl_data.write_slice_size(Some(_arg_outCertChain))?;
-                Ok(())
-              });
-              if let Err(binder::StatusCode::UNKNOWN_TRANSACTION) = _aidl_reply {
-                if let Some(_aidl_default_impl) = <Self as IKeyMintDevice>::getDefaultImpl() {
-                  return _aidl_default_impl.importKey(_arg_inKeyParams, _arg_inKeyFormat, _arg_inKeyData, _arg_outImportedKeyBlob, _arg_outImportedKeyCharacteristics, _arg_outCertChain);
-                }
-              }
-              let _aidl_reply = _aidl_reply?;
-              let _aidl_status: binder::Status = _aidl_reply.read()?;
-              if !_aidl_status.is_ok() { return Err(_aidl_status); }
-              *_arg_outImportedKeyBlob = _aidl_reply.read()?;
-              *_arg_outImportedKeyCharacteristics = _aidl_reply.read()?;
-              *_arg_outCertChain = _aidl_reply.read()?;
-              Ok(())
-            }
-            fn importWrappedKey(&self, _arg_inWrappedKeyData: &[u8], _arg_inWrappingKeyBlob: &[u8], _arg_inMaskingKey: &[u8], _arg_inUnwrappingParams: &[crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter], _arg_inPasswordSid: i64, _arg_inBiometricSid: i64, _arg_outImportedKeyBlob: &mut Vec<u8>, _arg_outImportedKeyCharacteristics: &mut crate::mangled::_7_android_8_hardware_7_keymint_18_KeyCharacteristics) -> binder::public_api::Result<()> {
-              let _aidl_reply = self.binder.transact(transactions::importWrappedKey, 0, |_aidl_data| {
-                _aidl_data.write(_arg_inWrappedKeyData)?;
-                _aidl_data.write(_arg_inWrappingKeyBlob)?;
-                _aidl_data.write(_arg_inMaskingKey)?;
-                _aidl_data.write(_arg_inUnwrappingParams)?;
-                _aidl_data.write(&_arg_inPasswordSid)?;
-                _aidl_data.write(&_arg_inBiometricSid)?;
-                _aidl_data.write_slice_size(Some(_arg_outImportedKeyBlob))?;
-                Ok(())
-              });
-              if let Err(binder::StatusCode::UNKNOWN_TRANSACTION) = _aidl_reply {
-                if let Some(_aidl_default_impl) = <Self as IKeyMintDevice>::getDefaultImpl() {
-                  return _aidl_default_impl.importWrappedKey(_arg_inWrappedKeyData, _arg_inWrappingKeyBlob, _arg_inMaskingKey, _arg_inUnwrappingParams, _arg_inPasswordSid, _arg_inBiometricSid, _arg_outImportedKeyBlob, _arg_outImportedKeyCharacteristics);
-                }
-              }
-              let _aidl_reply = _aidl_reply?;
-              let _aidl_status: binder::Status = _aidl_reply.read()?;
-              if !_aidl_status.is_ok() { return Err(_aidl_status); }
-              *_arg_outImportedKeyBlob = _aidl_reply.read()?;
-              *_arg_outImportedKeyCharacteristics = _aidl_reply.read()?;
-              Ok(())
-            }
-            fn upgradeKey(&self, _arg_inKeyBlobToUpgrade: &[u8], _arg_inUpgradeParams: &[crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter]) -> binder::public_api::Result<Vec<u8>> {
-              let _aidl_reply = self.binder.transact(transactions::upgradeKey, 0, |_aidl_data| {
-                _aidl_data.write(_arg_inKeyBlobToUpgrade)?;
-                _aidl_data.write(_arg_inUpgradeParams)?;
-                Ok(())
-              });
-              if let Err(binder::StatusCode::UNKNOWN_TRANSACTION) = _aidl_reply {
-                if let Some(_aidl_default_impl) = <Self as IKeyMintDevice>::getDefaultImpl() {
-                  return _aidl_default_impl.upgradeKey(_arg_inKeyBlobToUpgrade, _arg_inUpgradeParams);
-                }
-              }
-              let _aidl_reply = _aidl_reply?;
-              let _aidl_status: binder::Status = _aidl_reply.read()?;
-              if !_aidl_status.is_ok() { return Err(_aidl_status); }
-              let _aidl_return: Vec<u8> = _aidl_reply.read()?;
-              Ok(_aidl_return)
-            }
-            fn deleteKey(&self, _arg_inKeyBlob: &[u8]) -> binder::public_api::Result<()> {
-              let _aidl_reply = self.binder.transact(transactions::deleteKey, 0, |_aidl_data| {
-                _aidl_data.write(_arg_inKeyBlob)?;
-                Ok(())
-              });
-              if let Err(binder::StatusCode::UNKNOWN_TRANSACTION) = _aidl_reply {
-                if let Some(_aidl_default_impl) = <Self as IKeyMintDevice>::getDefaultImpl() {
-                  return _aidl_default_impl.deleteKey(_arg_inKeyBlob);
-                }
-              }
-              let _aidl_reply = _aidl_reply?;
-              let _aidl_status: binder::Status = _aidl_reply.read()?;
-              if !_aidl_status.is_ok() { return Err(_aidl_status); }
-              Ok(())
-            }
-            fn deleteAllKeys(&self) -> binder::public_api::Result<()> {
-              let _aidl_reply = self.binder.transact(transactions::deleteAllKeys, 0, |_aidl_data| {
-                Ok(())
-              });
-              if let Err(binder::StatusCode::UNKNOWN_TRANSACTION) = _aidl_reply {
-                if let Some(_aidl_default_impl) = <Self as IKeyMintDevice>::getDefaultImpl() {
-                  return _aidl_default_impl.deleteAllKeys();
-                }
-              }
-              let _aidl_reply = _aidl_reply?;
-              let _aidl_status: binder::Status = _aidl_reply.read()?;
-              if !_aidl_status.is_ok() { return Err(_aidl_status); }
-              Ok(())
-            }
-            fn destroyAttestationIds(&self) -> binder::public_api::Result<()> {
-              let _aidl_reply = self.binder.transact(transactions::destroyAttestationIds, 0, |_aidl_data| {
-                Ok(())
-              });
-              if let Err(binder::StatusCode::UNKNOWN_TRANSACTION) = _aidl_reply {
-                if let Some(_aidl_default_impl) = <Self as IKeyMintDevice>::getDefaultImpl() {
-                  return _aidl_default_impl.destroyAttestationIds();
-                }
-              }
-              let _aidl_reply = _aidl_reply?;
-              let _aidl_status: binder::Status = _aidl_reply.read()?;
-              if !_aidl_status.is_ok() { return Err(_aidl_status); }
-              Ok(())
-            }
-            fn begin(&self, _arg_inPurpose: crate::mangled::_7_android_8_hardware_7_keymint_10_KeyPurpose, _arg_inKeyBlob: &[u8], _arg_inParams: &[crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter], _arg_inAuthToken: &crate::mangled::_7_android_8_hardware_7_keymint_17_HardwareAuthToken) -> binder::public_api::Result<crate::mangled::_7_android_8_hardware_7_keymint_11_BeginResult> {
-              let _aidl_reply = self.binder.transact(transactions::begin, 0, |_aidl_data| {
-                _aidl_data.write(&_arg_inPurpose)?;
-                _aidl_data.write(_arg_inKeyBlob)?;
-                _aidl_data.write(_arg_inParams)?;
-                _aidl_data.write(_arg_inAuthToken)?;
-                Ok(())
-              });
-              if let Err(binder::StatusCode::UNKNOWN_TRANSACTION) = _aidl_reply {
-                if let Some(_aidl_default_impl) = <Self as IKeyMintDevice>::getDefaultImpl() {
-                  return _aidl_default_impl.begin(_arg_inPurpose, _arg_inKeyBlob, _arg_inParams, _arg_inAuthToken);
-                }
-              }
-              let _aidl_reply = _aidl_reply?;
-              let _aidl_status: binder::Status = _aidl_reply.read()?;
-              if !_aidl_status.is_ok() { return Err(_aidl_status); }
-              let _aidl_return: crate::mangled::_7_android_8_hardware_7_keymint_11_BeginResult = _aidl_reply.read()?;
-              Ok(_aidl_return)
-            }
-          }
-          impl IKeyMintDevice for binder::Binder<BnKeyMintDevice> {
-            fn getHardwareInfo(&self) -> binder::public_api::Result<crate::mangled::_7_android_8_hardware_7_keymint_19_KeyMintHardwareInfo> { self.0.getHardwareInfo() }
-            fn verifyAuthorization(&self, _arg_challenge: i64, _arg_parametersToVerify: &[crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter], _arg_token: &crate::mangled::_7_android_8_hardware_7_keymint_17_HardwareAuthToken) -> binder::public_api::Result<crate::mangled::_7_android_8_hardware_7_keymint_17_VerificationToken> { self.0.verifyAuthorization(_arg_challenge, _arg_parametersToVerify, _arg_token) }
-            fn addRngEntropy(&self, _arg_data: &[u8]) -> binder::public_api::Result<()> { self.0.addRngEntropy(_arg_data) }
-            fn generateKey(&self, _arg_keyParams: &[crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter], _arg_generatedKeyBlob: &mut Vec<u8>, _arg_generatedKeyCharacteristics: &mut crate::mangled::_7_android_8_hardware_7_keymint_18_KeyCharacteristics, _arg_outCertChain: &mut Vec<crate::mangled::_7_android_8_hardware_7_keymint_11_Certificate>) -> binder::public_api::Result<()> { self.0.generateKey(_arg_keyParams, _arg_generatedKeyBlob, _arg_generatedKeyCharacteristics, _arg_outCertChain) }
-            fn importKey(&self, _arg_inKeyParams: &[crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter], _arg_inKeyFormat: crate::mangled::_7_android_8_hardware_7_keymint_9_KeyFormat, _arg_inKeyData: &[u8], _arg_outImportedKeyBlob: &mut Vec<u8>, _arg_outImportedKeyCharacteristics: &mut crate::mangled::_7_android_8_hardware_7_keymint_18_KeyCharacteristics, _arg_outCertChain: &mut Vec<crate::mangled::_7_android_8_hardware_7_keymint_11_Certificate>) -> binder::public_api::Result<()> { self.0.importKey(_arg_inKeyParams, _arg_inKeyFormat, _arg_inKeyData, _arg_outImportedKeyBlob, _arg_outImportedKeyCharacteristics, _arg_outCertChain) }
-            fn importWrappedKey(&self, _arg_inWrappedKeyData: &[u8], _arg_inWrappingKeyBlob: &[u8], _arg_inMaskingKey: &[u8], _arg_inUnwrappingParams: &[crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter], _arg_inPasswordSid: i64, _arg_inBiometricSid: i64, _arg_outImportedKeyBlob: &mut Vec<u8>, _arg_outImportedKeyCharacteristics: &mut crate::mangled::_7_android_8_hardware_7_keymint_18_KeyCharacteristics) -> binder::public_api::Result<()> { self.0.importWrappedKey(_arg_inWrappedKeyData, _arg_inWrappingKeyBlob, _arg_inMaskingKey, _arg_inUnwrappingParams, _arg_inPasswordSid, _arg_inBiometricSid, _arg_outImportedKeyBlob, _arg_outImportedKeyCharacteristics) }
-            fn upgradeKey(&self, _arg_inKeyBlobToUpgrade: &[u8], _arg_inUpgradeParams: &[crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter]) -> binder::public_api::Result<Vec<u8>> { self.0.upgradeKey(_arg_inKeyBlobToUpgrade, _arg_inUpgradeParams) }
-            fn deleteKey(&self, _arg_inKeyBlob: &[u8]) -> binder::public_api::Result<()> { self.0.deleteKey(_arg_inKeyBlob) }
-            fn deleteAllKeys(&self) -> binder::public_api::Result<()> { self.0.deleteAllKeys() }
-            fn destroyAttestationIds(&self) -> binder::public_api::Result<()> { self.0.destroyAttestationIds() }
-            fn begin(&self, _arg_inPurpose: crate::mangled::_7_android_8_hardware_7_keymint_10_KeyPurpose, _arg_inKeyBlob: &[u8], _arg_inParams: &[crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter], _arg_inAuthToken: &crate::mangled::_7_android_8_hardware_7_keymint_17_HardwareAuthToken) -> binder::public_api::Result<crate::mangled::_7_android_8_hardware_7_keymint_11_BeginResult> { self.0.begin(_arg_inPurpose, _arg_inKeyBlob, _arg_inParams, _arg_inAuthToken) }
-          }
-          fn on_transact(_aidl_service: &dyn IKeyMintDevice, _aidl_code: binder::TransactionCode, _aidl_data: &binder::parcel::Parcel, _aidl_reply: &mut binder::parcel::Parcel) -> binder::Result<()> {
-            match _aidl_code {
-              transactions::getHardwareInfo => {
-                let _aidl_return = _aidl_service.getHardwareInfo();
-                match &_aidl_return {
-                  Ok(_aidl_return) => {
-                    _aidl_reply.write(&binder::Status::from(binder::StatusCode::OK))?;
-                    _aidl_reply.write(_aidl_return)?;
-                  }
-                  Err(_aidl_status) => _aidl_reply.write(_aidl_status)?
-                }
-                Ok(())
-              }
-              transactions::verifyAuthorization => {
-                let _arg_challenge: i64 = _aidl_data.read()?;
-                let _arg_parametersToVerify: Vec<crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter> = _aidl_data.read()?;
-                let _arg_token: crate::mangled::_7_android_8_hardware_7_keymint_17_HardwareAuthToken = _aidl_data.read()?;
-                let _aidl_return = _aidl_service.verifyAuthorization(_arg_challenge, &_arg_parametersToVerify, &_arg_token);
-                match &_aidl_return {
-                  Ok(_aidl_return) => {
-                    _aidl_reply.write(&binder::Status::from(binder::StatusCode::OK))?;
-                    _aidl_reply.write(_aidl_return)?;
-                  }
-                  Err(_aidl_status) => _aidl_reply.write(_aidl_status)?
-                }
-                Ok(())
-              }
-              transactions::addRngEntropy => {
-                let _arg_data: Vec<u8> = _aidl_data.read()?;
-                let _aidl_return = _aidl_service.addRngEntropy(&_arg_data);
-                match &_aidl_return {
-                  Ok(_aidl_return) => {
-                    _aidl_reply.write(&binder::Status::from(binder::StatusCode::OK))?;
-                  }
-                  Err(_aidl_status) => _aidl_reply.write(_aidl_status)?
-                }
-                Ok(())
-              }
-              transactions::generateKey => {
-                let _arg_keyParams: Vec<crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter> = _aidl_data.read()?;
-                let mut _arg_generatedKeyBlob: Vec<u8> = Default::default();
-                _aidl_data.resize_out_vec(&mut _arg_generatedKeyBlob)?;
-                let mut _arg_generatedKeyCharacteristics: crate::mangled::_7_android_8_hardware_7_keymint_18_KeyCharacteristics = Default::default();
-                let mut _arg_outCertChain: Vec<crate::mangled::_7_android_8_hardware_7_keymint_11_Certificate> = Default::default();
-                _aidl_data.resize_out_vec(&mut _arg_outCertChain)?;
-                let _aidl_return = _aidl_service.generateKey(&_arg_keyParams, &mut _arg_generatedKeyBlob, &mut _arg_generatedKeyCharacteristics, &mut _arg_outCertChain);
-                match &_aidl_return {
-                  Ok(_aidl_return) => {
-                    _aidl_reply.write(&binder::Status::from(binder::StatusCode::OK))?;
-                    _aidl_reply.write(&_arg_generatedKeyBlob)?;
-                    _aidl_reply.write(&_arg_generatedKeyCharacteristics)?;
-                    _aidl_reply.write(&_arg_outCertChain)?;
-                  }
-                  Err(_aidl_status) => _aidl_reply.write(_aidl_status)?
-                }
-                Ok(())
-              }
-              transactions::importKey => {
-                let _arg_inKeyParams: Vec<crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter> = _aidl_data.read()?;
-                let _arg_inKeyFormat: crate::mangled::_7_android_8_hardware_7_keymint_9_KeyFormat = _aidl_data.read()?;
-                let _arg_inKeyData: Vec<u8> = _aidl_data.read()?;
-                let mut _arg_outImportedKeyBlob: Vec<u8> = Default::default();
-                _aidl_data.resize_out_vec(&mut _arg_outImportedKeyBlob)?;
-                let mut _arg_outImportedKeyCharacteristics: crate::mangled::_7_android_8_hardware_7_keymint_18_KeyCharacteristics = Default::default();
-                let mut _arg_outCertChain: Vec<crate::mangled::_7_android_8_hardware_7_keymint_11_Certificate> = Default::default();
-                _aidl_data.resize_out_vec(&mut _arg_outCertChain)?;
-                let _aidl_return = _aidl_service.importKey(&_arg_inKeyParams, _arg_inKeyFormat, &_arg_inKeyData, &mut _arg_outImportedKeyBlob, &mut _arg_outImportedKeyCharacteristics, &mut _arg_outCertChain);
-                match &_aidl_return {
-                  Ok(_aidl_return) => {
-                    _aidl_reply.write(&binder::Status::from(binder::StatusCode::OK))?;
-                    _aidl_reply.write(&_arg_outImportedKeyBlob)?;
-                    _aidl_reply.write(&_arg_outImportedKeyCharacteristics)?;
-                    _aidl_reply.write(&_arg_outCertChain)?;
-                  }
-                  Err(_aidl_status) => _aidl_reply.write(_aidl_status)?
-                }
-                Ok(())
-              }
-              transactions::importWrappedKey => {
-                let _arg_inWrappedKeyData: Vec<u8> = _aidl_data.read()?;
-                let _arg_inWrappingKeyBlob: Vec<u8> = _aidl_data.read()?;
-                let _arg_inMaskingKey: Vec<u8> = _aidl_data.read()?;
-                let _arg_inUnwrappingParams: Vec<crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter> = _aidl_data.read()?;
-                let _arg_inPasswordSid: i64 = _aidl_data.read()?;
-                let _arg_inBiometricSid: i64 = _aidl_data.read()?;
-                let mut _arg_outImportedKeyBlob: Vec<u8> = Default::default();
-                _aidl_data.resize_out_vec(&mut _arg_outImportedKeyBlob)?;
-                let mut _arg_outImportedKeyCharacteristics: crate::mangled::_7_android_8_hardware_7_keymint_18_KeyCharacteristics = Default::default();
-                let _aidl_return = _aidl_service.importWrappedKey(&_arg_inWrappedKeyData, &_arg_inWrappingKeyBlob, &_arg_inMaskingKey, &_arg_inUnwrappingParams, _arg_inPasswordSid, _arg_inBiometricSid, &mut _arg_outImportedKeyBlob, &mut _arg_outImportedKeyCharacteristics);
-                match &_aidl_return {
-                  Ok(_aidl_return) => {
-                    _aidl_reply.write(&binder::Status::from(binder::StatusCode::OK))?;
-                    _aidl_reply.write(&_arg_outImportedKeyBlob)?;
-                    _aidl_reply.write(&_arg_outImportedKeyCharacteristics)?;
-                  }
-                  Err(_aidl_status) => _aidl_reply.write(_aidl_status)?
-                }
-                Ok(())
-              }
-              transactions::upgradeKey => {
-                let _arg_inKeyBlobToUpgrade: Vec<u8> = _aidl_data.read()?;
-                let _arg_inUpgradeParams: Vec<crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter> = _aidl_data.read()?;
-                let _aidl_return = _aidl_service.upgradeKey(&_arg_inKeyBlobToUpgrade, &_arg_inUpgradeParams);
-                match &_aidl_return {
-                  Ok(_aidl_return) => {
-                    _aidl_reply.write(&binder::Status::from(binder::StatusCode::OK))?;
-                    _aidl_reply.write(_aidl_return)?;
-                  }
-                  Err(_aidl_status) => _aidl_reply.write(_aidl_status)?
-                }
-                Ok(())
-              }
-              transactions::deleteKey => {
-                let _arg_inKeyBlob: Vec<u8> = _aidl_data.read()?;
-                let _aidl_return = _aidl_service.deleteKey(&_arg_inKeyBlob);
-                match &_aidl_return {
-                  Ok(_aidl_return) => {
-                    _aidl_reply.write(&binder::Status::from(binder::StatusCode::OK))?;
-                  }
-                  Err(_aidl_status) => _aidl_reply.write(_aidl_status)?
-                }
-                Ok(())
-              }
-              transactions::deleteAllKeys => {
-                let _aidl_return = _aidl_service.deleteAllKeys();
-                match &_aidl_return {
-                  Ok(_aidl_return) => {
-                    _aidl_reply.write(&binder::Status::from(binder::StatusCode::OK))?;
-                  }
-                  Err(_aidl_status) => _aidl_reply.write(_aidl_status)?
-                }
-                Ok(())
-              }
-              transactions::destroyAttestationIds => {
-                let _aidl_return = _aidl_service.destroyAttestationIds();
-                match &_aidl_return {
-                  Ok(_aidl_return) => {
-                    _aidl_reply.write(&binder::Status::from(binder::StatusCode::OK))?;
-                  }
-                  Err(_aidl_status) => _aidl_reply.write(_aidl_status)?
-                }
-                Ok(())
-              }
-              transactions::begin => {
-                let _arg_inPurpose: crate::mangled::_7_android_8_hardware_7_keymint_10_KeyPurpose = _aidl_data.read()?;
-                let _arg_inKeyBlob: Vec<u8> = _aidl_data.read()?;
-                let _arg_inParams: Vec<crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter> = _aidl_data.read()?;
-                let _arg_inAuthToken: crate::mangled::_7_android_8_hardware_7_keymint_17_HardwareAuthToken = _aidl_data.read()?;
-                let _aidl_return = _aidl_service.begin(_arg_inPurpose, &_arg_inKeyBlob, &_arg_inParams, &_arg_inAuthToken);
-                match &_aidl_return {
-                  Ok(_aidl_return) => {
-                    _aidl_reply.write(&binder::Status::from(binder::StatusCode::OK))?;
-                    _aidl_reply.write(_aidl_return)?;
-                  }
-                  Err(_aidl_status) => _aidl_reply.write(_aidl_status)?
-                }
-                Ok(())
-              }
-              _ => Err(binder::StatusCode::UNKNOWN_TRANSACTION)
-            }
-          }
-        }
-        pub mod IKeyMintOperation {
-          #![allow(non_upper_case_globals)]
-          #![allow(non_snake_case)]
-          #[allow(unused_imports)] use binder::IBinder;
-          use binder::declare_binder_interface;
-          declare_binder_interface! {
-            IKeyMintOperation["android.hardware.keymint.IKeyMintOperation"] {
-              native: BnKeyMintOperation(on_transact),
-              proxy: BpKeyMintOperation {
-              },
-            }
-          }
-          pub trait IKeyMintOperation: binder::Interface + Send {
-            fn get_descriptor() -> &'static str where Self: Sized { "android.hardware.keymint.IKeyMintOperation" }
-            fn update(&self, _arg_inParams: &[crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter], _arg_input: &[u8], _arg_inVerificationToken: &crate::mangled::_7_android_8_hardware_7_keymint_17_VerificationToken, _arg_outParams: &mut Vec<crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter>, _arg_output: &mut Vec<u8>) -> binder::public_api::Result<i32> {
-              Err(binder::StatusCode::UNKNOWN_TRANSACTION.into())
-            }
-            fn finish(&self, _arg_inParams: &[crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter], _arg_input: &[u8], _arg_inSignature: &[u8], _arg_authToken: &crate::mangled::_7_android_8_hardware_7_keymint_17_HardwareAuthToken, _arg_inVerificationToken: &crate::mangled::_7_android_8_hardware_7_keymint_17_VerificationToken, _arg_outParams: &mut Vec<crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter>, _arg_output: &mut Vec<u8>) -> binder::public_api::Result<()> {
-              Err(binder::StatusCode::UNKNOWN_TRANSACTION.into())
-            }
-            fn abort(&self) -> binder::public_api::Result<()> {
-              Err(binder::StatusCode::UNKNOWN_TRANSACTION.into())
-            }
-            fn getDefaultImpl() -> IKeyMintOperationDefault where Self: Sized {
-              DEFAULT_IMPL.lock().unwrap().clone()
-            }
-            fn setDefaultImpl(d: IKeyMintOperationDefault) -> IKeyMintOperationDefault where Self: Sized {
-              std::mem::replace(&mut *DEFAULT_IMPL.lock().unwrap(), d)
-            }
-          }
-          pub mod transactions {
-            #[allow(unused_imports)] use binder::IBinder;
-            pub const update: binder::TransactionCode = binder::SpIBinder::FIRST_CALL_TRANSACTION + 0;
-            pub const finish: binder::TransactionCode = binder::SpIBinder::FIRST_CALL_TRANSACTION + 1;
-            pub const abort: binder::TransactionCode = binder::SpIBinder::FIRST_CALL_TRANSACTION + 2;
-          }
-          pub type IKeyMintOperationDefault = Option<std::sync::Arc<dyn IKeyMintOperation + Sync>>;
-          use lazy_static::lazy_static;
-          lazy_static! {
-            static ref DEFAULT_IMPL: std::sync::Mutex<IKeyMintOperationDefault> = std::sync::Mutex::new(None);
-          }
-          pub(crate) mod mangled { pub use super::IKeyMintOperation as _7_android_8_hardware_7_keymint_17_IKeyMintOperation; }
-          impl IKeyMintOperation for BpKeyMintOperation {
-            fn update(&self, _arg_inParams: &[crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter], _arg_input: &[u8], _arg_inVerificationToken: &crate::mangled::_7_android_8_hardware_7_keymint_17_VerificationToken, _arg_outParams: &mut Vec<crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter>, _arg_output: &mut Vec<u8>) -> binder::public_api::Result<i32> {
-              let _aidl_reply = self.binder.transact(transactions::update, 0, |_aidl_data| {
-                _aidl_data.write(_arg_inParams)?;
-                _aidl_data.write(_arg_input)?;
-                _aidl_data.write(_arg_inVerificationToken)?;
-                _aidl_data.write_slice_size(Some(_arg_outParams))?;
-                _aidl_data.write_slice_size(Some(_arg_output))?;
-                Ok(())
-              });
-              if let Err(binder::StatusCode::UNKNOWN_TRANSACTION) = _aidl_reply {
-                if let Some(_aidl_default_impl) = <Self as IKeyMintOperation>::getDefaultImpl() {
-                  return _aidl_default_impl.update(_arg_inParams, _arg_input, _arg_inVerificationToken, _arg_outParams, _arg_output);
-                }
-              }
-              let _aidl_reply = _aidl_reply?;
-              let _aidl_status: binder::Status = _aidl_reply.read()?;
-              if !_aidl_status.is_ok() { return Err(_aidl_status); }
-              let _aidl_return: i32 = _aidl_reply.read()?;
-              *_arg_outParams = _aidl_reply.read()?;
-              *_arg_output = _aidl_reply.read()?;
-              Ok(_aidl_return)
-            }
-            fn finish(&self, _arg_inParams: &[crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter], _arg_input: &[u8], _arg_inSignature: &[u8], _arg_authToken: &crate::mangled::_7_android_8_hardware_7_keymint_17_HardwareAuthToken, _arg_inVerificationToken: &crate::mangled::_7_android_8_hardware_7_keymint_17_VerificationToken, _arg_outParams: &mut Vec<crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter>, _arg_output: &mut Vec<u8>) -> binder::public_api::Result<()> {
-              let _aidl_reply = self.binder.transact(transactions::finish, 0, |_aidl_data| {
-                _aidl_data.write(_arg_inParams)?;
-                _aidl_data.write(_arg_input)?;
-                _aidl_data.write(_arg_inSignature)?;
-                _aidl_data.write(_arg_authToken)?;
-                _aidl_data.write(_arg_inVerificationToken)?;
-                _aidl_data.write_slice_size(Some(_arg_outParams))?;
-                _aidl_data.write_slice_size(Some(_arg_output))?;
-                Ok(())
-              });
-              if let Err(binder::StatusCode::UNKNOWN_TRANSACTION) = _aidl_reply {
-                if let Some(_aidl_default_impl) = <Self as IKeyMintOperation>::getDefaultImpl() {
-                  return _aidl_default_impl.finish(_arg_inParams, _arg_input, _arg_inSignature, _arg_authToken, _arg_inVerificationToken, _arg_outParams, _arg_output);
-                }
-              }
-              let _aidl_reply = _aidl_reply?;
-              let _aidl_status: binder::Status = _aidl_reply.read()?;
-              if !_aidl_status.is_ok() { return Err(_aidl_status); }
-              *_arg_outParams = _aidl_reply.read()?;
-              *_arg_output = _aidl_reply.read()?;
-              Ok(())
-            }
-            fn abort(&self) -> binder::public_api::Result<()> {
-              let _aidl_reply = self.binder.transact(transactions::abort, 0, |_aidl_data| {
-                Ok(())
-              });
-              if let Err(binder::StatusCode::UNKNOWN_TRANSACTION) = _aidl_reply {
-                if let Some(_aidl_default_impl) = <Self as IKeyMintOperation>::getDefaultImpl() {
-                  return _aidl_default_impl.abort();
-                }
-              }
-              let _aidl_reply = _aidl_reply?;
-              let _aidl_status: binder::Status = _aidl_reply.read()?;
-              if !_aidl_status.is_ok() { return Err(_aidl_status); }
-              Ok(())
-            }
-          }
-          impl IKeyMintOperation for binder::Binder<BnKeyMintOperation> {
-            fn update(&self, _arg_inParams: &[crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter], _arg_input: &[u8], _arg_inVerificationToken: &crate::mangled::_7_android_8_hardware_7_keymint_17_VerificationToken, _arg_outParams: &mut Vec<crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter>, _arg_output: &mut Vec<u8>) -> binder::public_api::Result<i32> { self.0.update(_arg_inParams, _arg_input, _arg_inVerificationToken, _arg_outParams, _arg_output) }
-            fn finish(&self, _arg_inParams: &[crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter], _arg_input: &[u8], _arg_inSignature: &[u8], _arg_authToken: &crate::mangled::_7_android_8_hardware_7_keymint_17_HardwareAuthToken, _arg_inVerificationToken: &crate::mangled::_7_android_8_hardware_7_keymint_17_VerificationToken, _arg_outParams: &mut Vec<crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter>, _arg_output: &mut Vec<u8>) -> binder::public_api::Result<()> { self.0.finish(_arg_inParams, _arg_input, _arg_inSignature, _arg_authToken, _arg_inVerificationToken, _arg_outParams, _arg_output) }
-            fn abort(&self) -> binder::public_api::Result<()> { self.0.abort() }
-          }
-          fn on_transact(_aidl_service: &dyn IKeyMintOperation, _aidl_code: binder::TransactionCode, _aidl_data: &binder::parcel::Parcel, _aidl_reply: &mut binder::parcel::Parcel) -> binder::Result<()> {
-            match _aidl_code {
-              transactions::update => {
-                let _arg_inParams: Vec<crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter> = _aidl_data.read()?;
-                let _arg_input: Vec<u8> = _aidl_data.read()?;
-                let _arg_inVerificationToken: crate::mangled::_7_android_8_hardware_7_keymint_17_VerificationToken = _aidl_data.read()?;
-                let mut _arg_outParams: Vec<crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter> = Default::default();
-                _aidl_data.resize_out_vec(&mut _arg_outParams)?;
-                let mut _arg_output: Vec<u8> = Default::default();
-                _aidl_data.resize_out_vec(&mut _arg_output)?;
-                let _aidl_return = _aidl_service.update(&_arg_inParams, &_arg_input, &_arg_inVerificationToken, &mut _arg_outParams, &mut _arg_output);
-                match &_aidl_return {
-                  Ok(_aidl_return) => {
-                    _aidl_reply.write(&binder::Status::from(binder::StatusCode::OK))?;
-                    _aidl_reply.write(_aidl_return)?;
-                    _aidl_reply.write(&_arg_outParams)?;
-                    _aidl_reply.write(&_arg_output)?;
-                  }
-                  Err(_aidl_status) => _aidl_reply.write(_aidl_status)?
-                }
-                Ok(())
-              }
-              transactions::finish => {
-                let _arg_inParams: Vec<crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter> = _aidl_data.read()?;
-                let _arg_input: Vec<u8> = _aidl_data.read()?;
-                let _arg_inSignature: Vec<u8> = _aidl_data.read()?;
-                let _arg_authToken: crate::mangled::_7_android_8_hardware_7_keymint_17_HardwareAuthToken = _aidl_data.read()?;
-                let _arg_inVerificationToken: crate::mangled::_7_android_8_hardware_7_keymint_17_VerificationToken = _aidl_data.read()?;
-                let mut _arg_outParams: Vec<crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter> = Default::default();
-                _aidl_data.resize_out_vec(&mut _arg_outParams)?;
-                let mut _arg_output: Vec<u8> = Default::default();
-                _aidl_data.resize_out_vec(&mut _arg_output)?;
-                let _aidl_return = _aidl_service.finish(&_arg_inParams, &_arg_input, &_arg_inSignature, &_arg_authToken, &_arg_inVerificationToken, &mut _arg_outParams, &mut _arg_output);
-                match &_aidl_return {
-                  Ok(_aidl_return) => {
-                    _aidl_reply.write(&binder::Status::from(binder::StatusCode::OK))?;
-                    _aidl_reply.write(&_arg_outParams)?;
-                    _aidl_reply.write(&_arg_output)?;
-                  }
-                  Err(_aidl_status) => _aidl_reply.write(_aidl_status)?
-                }
-                Ok(())
-              }
-              transactions::abort => {
-                let _aidl_return = _aidl_service.abort();
-                match &_aidl_return {
-                  Ok(_aidl_return) => {
-                    _aidl_reply.write(&binder::Status::from(binder::StatusCode::OK))?;
-                  }
-                  Err(_aidl_status) => _aidl_reply.write(_aidl_status)?
-                }
-                Ok(())
-              }
-              _ => Err(binder::StatusCode::UNKNOWN_TRANSACTION)
-            }
-          }
-        }
-        pub mod KeyCharacteristics {
-          #[derive(Debug)]
-          pub struct KeyCharacteristics {
-            pub softwareEnforced: Vec<crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter>, 
-            pub hardwareEnforced: Vec<crate::mangled::_7_android_8_hardware_7_keymint_12_KeyParameter>, 
-          }
-          pub(crate) mod mangled { pub use super::KeyCharacteristics as _7_android_8_hardware_7_keymint_18_KeyCharacteristics; }
-          impl Default for KeyCharacteristics {
-            fn default() -> Self {
-              Self {
-                softwareEnforced: Default::default(),
-                hardwareEnforced: Default::default(),
-              }
-            }
-          }
-          impl binder::parcel::Serialize for KeyCharacteristics {
-            fn serialize(&self, parcel: &mut binder::parcel::Parcel) -> binder::Result<()> {
-              <Self as binder::parcel::SerializeOption>::serialize_option(Some(self), parcel)
-            }
-          }
-          impl binder::parcel::SerializeArray for KeyCharacteristics {}
-          impl binder::parcel::SerializeOption for KeyCharacteristics {
-            fn serialize_option(this: Option<&Self>, parcel: &mut binder::parcel::Parcel) -> binder::Result<()> {
-              let this = if let Some(this) = this {
-                parcel.write(&1i32)?;
-                this
-              } else {
-                return parcel.write(&0i32);
-              };
-              let start_pos = parcel.get_data_position();
-              parcel.write(&0i32)?;
-              parcel.write(&this.softwareEnforced)?;
-              parcel.write(&this.hardwareEnforced)?;
-              let end_pos = parcel.get_data_position();
-              let parcelable_size = (end_pos - start_pos) as i32;
-              unsafe { parcel.set_data_position(start_pos)?; }
-              parcel.write(&parcelable_size)?;
-              unsafe { parcel.set_data_position(end_pos)?; }
-              Ok(())
-            }
-          }
-          impl binder::parcel::Deserialize for KeyCharacteristics {
-            fn deserialize(parcel: &binder::parcel::Parcel) -> binder::Result<Self> {
-              <Self as binder::parcel::DeserializeOption>::deserialize_option(parcel)
-                 .transpose()
-                 .unwrap_or(Err(binder::StatusCode::UNEXPECTED_NULL))
-            }
-          }
-          impl binder::parcel::DeserializeArray for KeyCharacteristics {}
-          impl binder::parcel::DeserializeOption for KeyCharacteristics {
-            fn deserialize_option(parcel: &binder::parcel::Parcel) -> binder::Result<Option<Self>> {
-              let status: i32 = parcel.read()?;
-              if status == 0 { return Ok(None); }
-              let start_pos = parcel.get_data_position();
-              let parcelable_size: i32 = parcel.read()?;
-              if parcelable_size < 0 { return Err(binder::StatusCode::BAD_VALUE); }
-              let mut result = Self::default();
-              result.softwareEnforced = parcel.read()?;
-              if (parcel.get_data_position() - start_pos) == parcelable_size {
-                return Ok(Some(result));
-              }
-              result.hardwareEnforced = parcel.read()?;
-              if (parcel.get_data_position() - start_pos) == parcelable_size {
-                return Ok(Some(result));
-              }
-              Ok(Some(result))
-            }
-          }
-        }
-        pub mod KeyDerivationFunction {
-          #![allow(non_upper_case_globals)]
-          use binder::declare_binder_enum;
-          declare_binder_enum! { KeyDerivationFunction : i32 {
-            NONE = 0,
-            RFC5869_SHA256 = 1,
-            ISO18033_2_KDF1_SHA1 = 2,
-            ISO18033_2_KDF1_SHA256 = 3,
-            ISO18033_2_KDF2_SHA1 = 4,
-            ISO18033_2_KDF2_SHA256 = 5,
-          } }
-          pub(crate) mod mangled { pub use super::KeyDerivationFunction as _7_android_8_hardware_7_keymint_21_KeyDerivationFunction; }
-        }
-        pub mod KeyFormat {
-          #![allow(non_upper_case_globals)]
-          use binder::declare_binder_enum;
-          declare_binder_enum! { KeyFormat : i32 {
-            X509 = 0,
-            PKCS8 = 1,
-            RAW = 3,
-          } }
-          pub(crate) mod mangled { pub use super::KeyFormat as _7_android_8_hardware_7_keymint_9_KeyFormat; }
-        }
-        pub mod KeyMintHardwareInfo {
-          #[derive(Debug)]
-          pub struct KeyMintHardwareInfo {
-            pub versionNumber: i32, 
-            pub securityLevel: crate::mangled::_7_android_8_hardware_7_keymint_13_SecurityLevel, 
-            pub keyMintName: String, 
-            pub keyMintAuthorName: String, 
-          }
-          pub(crate) mod mangled { pub use super::KeyMintHardwareInfo as _7_android_8_hardware_7_keymint_19_KeyMintHardwareInfo; }
-          impl Default for KeyMintHardwareInfo {
-            fn default() -> Self {
-              Self {
-                versionNumber: 0,
-                securityLevel: Default::default(),
-                keyMintName: Default::default(),
-                keyMintAuthorName: Default::default(),
-              }
-            }
-          }
-          impl binder::parcel::Serialize for KeyMintHardwareInfo {
-            fn serialize(&self, parcel: &mut binder::parcel::Parcel) -> binder::Result<()> {
-              <Self as binder::parcel::SerializeOption>::serialize_option(Some(self), parcel)
-            }
-          }
-          impl binder::parcel::SerializeArray for KeyMintHardwareInfo {}
-          impl binder::parcel::SerializeOption for KeyMintHardwareInfo {
-            fn serialize_option(this: Option<&Self>, parcel: &mut binder::parcel::Parcel) -> binder::Result<()> {
-              let this = if let Some(this) = this {
-                parcel.write(&1i32)?;
-                this
-              } else {
-                return parcel.write(&0i32);
-              };
-              let start_pos = parcel.get_data_position();
-              parcel.write(&0i32)?;
-              parcel.write(&this.versionNumber)?;
-              parcel.write(&this.securityLevel)?;
-              parcel.write(&this.keyMintName)?;
-              parcel.write(&this.keyMintAuthorName)?;
-              let end_pos = parcel.get_data_position();
-              let parcelable_size = (end_pos - start_pos) as i32;
-              unsafe { parcel.set_data_position(start_pos)?; }
-              parcel.write(&parcelable_size)?;
-              unsafe { parcel.set_data_position(end_pos)?; }
-              Ok(())
-            }
-          }
-          impl binder::parcel::Deserialize for KeyMintHardwareInfo {
-            fn deserialize(parcel: &binder::parcel::Parcel) -> binder::Result<Self> {
-              <Self as binder::parcel::DeserializeOption>::deserialize_option(parcel)
-                 .transpose()
-                 .unwrap_or(Err(binder::StatusCode::UNEXPECTED_NULL))
-            }
-          }
-          impl binder::parcel::DeserializeArray for KeyMintHardwareInfo {}
-          impl binder::parcel::DeserializeOption for KeyMintHardwareInfo {
-            fn deserialize_option(parcel: &binder::parcel::Parcel) -> binder::Result<Option<Self>> {
-              let status: i32 = parcel.read()?;
-              if status == 0 { return Ok(None); }
-              let start_pos = parcel.get_data_position();
-              let parcelable_size: i32 = parcel.read()?;
-              if parcelable_size < 0 { return Err(binder::StatusCode::BAD_VALUE); }
-              let mut result = Self::default();
-              result.versionNumber = parcel.read()?;
-              if (parcel.get_data_position() - start_pos) == parcelable_size {
-                return Ok(Some(result));
-              }
-              result.securityLevel = parcel.read()?;
-              if (parcel.get_data_position() - start_pos) == parcelable_size {
-                return Ok(Some(result));
-              }
-              result.keyMintName = parcel.read()?;
-              if (parcel.get_data_position() - start_pos) == parcelable_size {
-                return Ok(Some(result));
-              }
-              result.keyMintAuthorName = parcel.read()?;
-              if (parcel.get_data_position() - start_pos) == parcelable_size {
-                return Ok(Some(result));
-              }
-              Ok(Some(result))
-            }
-          }
-        }
-        pub mod KeyOrigin {
-          #![allow(non_upper_case_globals)]
-          use binder::declare_binder_enum;
-          declare_binder_enum! { KeyOrigin : i32 {
-            GENERATED = 0,
-            DERIVED = 1,
-            IMPORTED = 2,
-            RESERVED = 3,
-            SECURELY_IMPORTED = 4,
-          } }
-          pub(crate) mod mangled { pub use super::KeyOrigin as _7_android_8_hardware_7_keymint_9_KeyOrigin; }
-        }
-        pub mod KeyParameter {
-          #[derive(Debug)]
-          pub struct KeyParameter {
-            pub tag: crate::mangled::_7_android_8_hardware_7_keymint_3_Tag, 
-            pub boolValue: bool, 
-            pub integer: i32, 
-            pub longInteger: i64, 
-            pub dateTime: i64, 
-            pub blob: Vec<u8>, 
-          }
-          pub(crate) mod mangled { pub use super::KeyParameter as _7_android_8_hardware_7_keymint_12_KeyParameter; }
-          impl Default for KeyParameter {
-            fn default() -> Self {
-              Self {
-                tag: Default::default(),
-                boolValue: false,
-                integer: 0,
-                longInteger: 0,
-                dateTime: 0,
-                blob: Default::default(),
-              }
-            }
-          }
-          impl binder::parcel::Serialize for KeyParameter {
-            fn serialize(&self, parcel: &mut binder::parcel::Parcel) -> binder::Result<()> {
-              <Self as binder::parcel::SerializeOption>::serialize_option(Some(self), parcel)
-            }
-          }
-          impl binder::parcel::SerializeArray for KeyParameter {}
-          impl binder::parcel::SerializeOption for KeyParameter {
-            fn serialize_option(this: Option<&Self>, parcel: &mut binder::parcel::Parcel) -> binder::Result<()> {
-              let this = if let Some(this) = this {
-                parcel.write(&1i32)?;
-                this
-              } else {
-                return parcel.write(&0i32);
-              };
-              let start_pos = parcel.get_data_position();
-              parcel.write(&0i32)?;
-              parcel.write(&this.tag)?;
-              parcel.write(&this.boolValue)?;
-              parcel.write(&this.integer)?;
-              parcel.write(&this.longInteger)?;
-              parcel.write(&this.dateTime)?;
-              parcel.write(&this.blob)?;
-              let end_pos = parcel.get_data_position();
-              let parcelable_size = (end_pos - start_pos) as i32;
-              unsafe { parcel.set_data_position(start_pos)?; }
-              parcel.write(&parcelable_size)?;
-              unsafe { parcel.set_data_position(end_pos)?; }
-              Ok(())
-            }
-          }
-          impl binder::parcel::Deserialize for KeyParameter {
-            fn deserialize(parcel: &binder::parcel::Parcel) -> binder::Result<Self> {
-              <Self as binder::parcel::DeserializeOption>::deserialize_option(parcel)
-                 .transpose()
-                 .unwrap_or(Err(binder::StatusCode::UNEXPECTED_NULL))
-            }
-          }
-          impl binder::parcel::DeserializeArray for KeyParameter {}
-          impl binder::parcel::DeserializeOption for KeyParameter {
-            fn deserialize_option(parcel: &binder::parcel::Parcel) -> binder::Result<Option<Self>> {
-              let status: i32 = parcel.read()?;
-              if status == 0 { return Ok(None); }
-              let start_pos = parcel.get_data_position();
-              let parcelable_size: i32 = parcel.read()?;
-              if parcelable_size < 0 { return Err(binder::StatusCode::BAD_VALUE); }
-              let mut result = Self::default();
-              result.tag = parcel.read()?;
-              if (parcel.get_data_position() - start_pos) == parcelable_size {
-                return Ok(Some(result));
-              }
-              result.boolValue = parcel.read()?;
-              if (parcel.get_data_position() - start_pos) == parcelable_size {
-                return Ok(Some(result));
-              }
-              result.integer = parcel.read()?;
-              if (parcel.get_data_position() - start_pos) == parcelable_size {
-                return Ok(Some(result));
-              }
-              result.longInteger = parcel.read()?;
-              if (parcel.get_data_position() - start_pos) == parcelable_size {
-                return Ok(Some(result));
-              }
-              result.dateTime = parcel.read()?;
-              if (parcel.get_data_position() - start_pos) == parcelable_size {
-                return Ok(Some(result));
-              }
-              result.blob = parcel.read()?;
-              if (parcel.get_data_position() - start_pos) == parcelable_size {
-                return Ok(Some(result));
-              }
-              Ok(Some(result))
-            }
-          }
-        }
-        pub mod KeyPurpose {
-          #![allow(non_upper_case_globals)]
-          use binder::declare_binder_enum;
-          declare_binder_enum! { KeyPurpose : i32 {
-            ENCRYPT = 0,
-            DECRYPT = 1,
-            SIGN = 2,
-            VERIFY = 3,
-            WRAP_KEY = 5,
-          } }
-          pub(crate) mod mangled { pub use super::KeyPurpose as _7_android_8_hardware_7_keymint_10_KeyPurpose; }
-        }
-        pub mod PaddingMode {
-          #![allow(non_upper_case_globals)]
-          use binder::declare_binder_enum;
-          declare_binder_enum! { PaddingMode : i32 {
-            NONE = 1,
-            RSA_OAEP = 2,
-            RSA_PSS = 3,
-            RSA_PKCS1_1_5_ENCRYPT = 4,
-            RSA_PKCS1_1_5_SIGN = 5,
-            PKCS7 = 64,
-          } }
-          pub(crate) mod mangled { pub use super::PaddingMode as _7_android_8_hardware_7_keymint_11_PaddingMode; }
-        }
-        pub mod SecurityLevel {
-          #![allow(non_upper_case_globals)]
-          use binder::declare_binder_enum;
-          declare_binder_enum! { SecurityLevel : i32 {
-            SOFTWARE = 0,
-            TRUSTED_ENVIRONMENT = 1,
-            STRONGBOX = 2,
-          } }
-          pub(crate) mod mangled { pub use super::SecurityLevel as _7_android_8_hardware_7_keymint_13_SecurityLevel; }
-        }
-        pub mod Tag {
-          #![allow(non_upper_case_globals)]
-          use binder::declare_binder_enum;
-          declare_binder_enum! { Tag : i32 {
-            INVALID = 0,
-            PURPOSE = 536870913,
-            ALGORITHM = 268435458,
-            KEY_SIZE = 805306371,
-            BLOCK_MODE = 536870916,
-            DIGEST = 536870917,
-            PADDING = 536870918,
-            CALLER_NONCE = 1879048199,
-            MIN_MAC_LENGTH = 805306376,
-            EC_CURVE = 268435466,
-            RSA_PUBLIC_EXPONENT = 1342177480,
-            INCLUDE_UNIQUE_ID = 1879048394,
-            BLOB_USAGE_REQUIREMENTS = 268435757,
-            BOOTLOADER_ONLY = 1879048494,
-            ROLLBACK_RESISTANCE = 1879048495,
-            HARDWARE_TYPE = 268435760,
-            EARLY_BOOT_ONLY = 1879048497,
-            ACTIVE_DATETIME = 1610613136,
-            ORIGINATION_EXPIRE_DATETIME = 1610613137,
-            USAGE_EXPIRE_DATETIME = 1610613138,
-            MIN_SECONDS_BETWEEN_OPS = 805306771,
-            MAX_USES_PER_BOOT = 805306772,
-            USER_ID = 805306869,
-            USER_SECURE_ID = 1073742326,
-            NO_AUTH_REQUIRED = 1879048695,
-            USER_AUTH_TYPE = 268435960,
-            AUTH_TIMEOUT = 805306873,
-            ALLOW_WHILE_ON_BODY = 1879048698,
-            TRUSTED_USER_PRESENCE_REQUIRED = 1879048699,
-            TRUSTED_CONFIRMATION_REQUIRED = 1879048700,
-            UNLOCKED_DEVICE_REQUIRED = 1879048701,
-            APPLICATION_ID = -1879047591,
-            APPLICATION_DATA = -1879047492,
-            CREATION_DATETIME = 1610613437,
-            ORIGIN = 268436158,
-            ROOT_OF_TRUST = -1879047488,
-            OS_VERSION = 805307073,
-            OS_PATCHLEVEL = 805307074,
-            UNIQUE_ID = -1879047485,
-            ATTESTATION_CHALLENGE = -1879047484,
-            ATTESTATION_APPLICATION_ID = -1879047483,
-            ATTESTATION_ID_BRAND = -1879047482,
-            ATTESTATION_ID_DEVICE = -1879047481,
-            ATTESTATION_ID_PRODUCT = -1879047480,
-            ATTESTATION_ID_SERIAL = -1879047479,
-            ATTESTATION_ID_IMEI = -1879047478,
-            ATTESTATION_ID_MEID = -1879047477,
-            ATTESTATION_ID_MANUFACTURER = -1879047476,
-            ATTESTATION_ID_MODEL = -1879047475,
-            VENDOR_PATCHLEVEL = 805307086,
-            BOOT_PATCHLEVEL = 805307087,
-            DEVICE_UNIQUE_ATTESTATION = 1879048912,
-            IDENTITY_CREDENTIAL_KEY = 1879048913,
-            STORAGE_KEY = 1879048914,
-            ASSOCIATED_DATA = -1879047192,
-            NONCE = -1879047191,
-            MAC_LENGTH = 805307371,
-            RESET_SINCE_ID_ROTATION = 1879049196,
-            CONFIRMATION_TOKEN = -1879047187,
-          } }
-          pub(crate) mod mangled { pub use super::Tag as _7_android_8_hardware_7_keymint_3_Tag; }
-        }
-        pub mod TagType {
-          #![allow(non_upper_case_globals)]
-          use binder::declare_binder_enum;
-          declare_binder_enum! { TagType : i32 {
-            INVALID = 0,
-            ENUM = 268435456,
-            ENUM_REP = 536870912,
-            UINT = 805306368,
-            UINT_REP = 1073741824,
-            ULONG = 1342177280,
-            DATE = 1610612736,
-            BOOL = 1879048192,
-            BIGNUM = -2147483648,
-            BYTES = -1879048192,
-            ULONG_REP = -1610612736,
-          } }
-          pub(crate) mod mangled { pub use super::TagType as _7_android_8_hardware_7_keymint_7_TagType; }
-        }
-        pub mod Timestamp {
-          #[derive(Debug)]
-          pub struct Timestamp {
-            pub milliSeconds: i64, 
-          }
-          pub(crate) mod mangled { pub use super::Timestamp as _7_android_8_hardware_7_keymint_9_Timestamp; }
-          impl Default for Timestamp {
-            fn default() -> Self {
-              Self {
-                milliSeconds: 0,
-              }
-            }
-          }
-          impl binder::parcel::Serialize for Timestamp {
-            fn serialize(&self, parcel: &mut binder::parcel::Parcel) -> binder::Result<()> {
-              <Self as binder::parcel::SerializeOption>::serialize_option(Some(self), parcel)
-            }
-          }
-          impl binder::parcel::SerializeArray for Timestamp {}
-          impl binder::parcel::SerializeOption for Timestamp {
-            fn serialize_option(this: Option<&Self>, parcel: &mut binder::parcel::Parcel) -> binder::Result<()> {
-              let this = if let Some(this) = this {
-                parcel.write(&1i32)?;
-                this
-              } else {
-                return parcel.write(&0i32);
-              };
-              let start_pos = parcel.get_data_position();
-              parcel.write(&0i32)?;
-              parcel.write(&this.milliSeconds)?;
-              let end_pos = parcel.get_data_position();
-              let parcelable_size = (end_pos - start_pos) as i32;
-              unsafe { parcel.set_data_position(start_pos)?; }
-              parcel.write(&parcelable_size)?;
-              unsafe { parcel.set_data_position(end_pos)?; }
-              Ok(())
-            }
-          }
-          impl binder::parcel::Deserialize for Timestamp {
-            fn deserialize(parcel: &binder::parcel::Parcel) -> binder::Result<Self> {
-              <Self as binder::parcel::DeserializeOption>::deserialize_option(parcel)
-                 .transpose()
-                 .unwrap_or(Err(binder::StatusCode::UNEXPECTED_NULL))
-            }
-          }
-          impl binder::parcel::DeserializeArray for Timestamp {}
-          impl binder::parcel::DeserializeOption for Timestamp {
-            fn deserialize_option(parcel: &binder::parcel::Parcel) -> binder::Result<Option<Self>> {
-              let status: i32 = parcel.read()?;
-              if status == 0 { return Ok(None); }
-              let start_pos = parcel.get_data_position();
-              let parcelable_size: i32 = parcel.read()?;
-              if parcelable_size < 0 { return Err(binder::StatusCode::BAD_VALUE); }
-              let mut result = Self::default();
-              result.milliSeconds = parcel.read()?;
-              if (parcel.get_data_position() - start_pos) == parcelable_size {
-                return Ok(Some(result));
-              }
-              Ok(Some(result))
-            }
-          }
-        }
-        pub mod VerificationToken {
-          #[derive(Debug)]
-          pub struct VerificationToken {
-            pub challenge: i64, 
-            pub timestamp: crate::mangled::_7_android_8_hardware_7_keymint_9_Timestamp, 
-            pub securityLevel: crate::mangled::_7_android_8_hardware_7_keymint_13_SecurityLevel, 
-            pub mac: Vec<u8>, 
-          }
-          pub(crate) mod mangled { pub use super::VerificationToken as _7_android_8_hardware_7_keymint_17_VerificationToken; }
-          impl Default for VerificationToken {
-            fn default() -> Self {
-              Self {
-                challenge: 0,
-                timestamp: Default::default(),
-                securityLevel: Default::default(),
-                mac: Default::default(),
-              }
-            }
-          }
-          impl binder::parcel::Serialize for VerificationToken {
-            fn serialize(&self, parcel: &mut binder::parcel::Parcel) -> binder::Result<()> {
-              <Self as binder::parcel::SerializeOption>::serialize_option(Some(self), parcel)
-            }
-          }
-          impl binder::parcel::SerializeArray for VerificationToken {}
-          impl binder::parcel::SerializeOption for VerificationToken {
-            fn serialize_option(this: Option<&Self>, parcel: &mut binder::parcel::Parcel) -> binder::Result<()> {
-              let this = if let Some(this) = this {
-                parcel.write(&1i32)?;
-                this
-              } else {
-                return parcel.write(&0i32);
-              };
-              let start_pos = parcel.get_data_position();
-              parcel.write(&0i32)?;
-              parcel.write(&this.challenge)?;
-              parcel.write(&this.timestamp)?;
-              parcel.write(&this.securityLevel)?;
-              parcel.write(&this.mac)?;
-              let end_pos = parcel.get_data_position();
-              let parcelable_size = (end_pos - start_pos) as i32;
-              unsafe { parcel.set_data_position(start_pos)?; }
-              parcel.write(&parcelable_size)?;
-              unsafe { parcel.set_data_position(end_pos)?; }
-              Ok(())
-            }
-          }
-          impl binder::parcel::Deserialize for VerificationToken {
-            fn deserialize(parcel: &binder::parcel::Parcel) -> binder::Result<Self> {
-              <Self as binder::parcel::DeserializeOption>::deserialize_option(parcel)
-                 .transpose()
-                 .unwrap_or(Err(binder::StatusCode::UNEXPECTED_NULL))
-            }
-          }
-          impl binder::parcel::DeserializeArray for VerificationToken {}
-          impl binder::parcel::DeserializeOption for VerificationToken {
-            fn deserialize_option(parcel: &binder::parcel::Parcel) -> binder::Result<Option<Self>> {
-              let status: i32 = parcel.read()?;
-              if status == 0 { return Ok(None); }
-              let start_pos = parcel.get_data_position();
-              let parcelable_size: i32 = parcel.read()?;
-              if parcelable_size < 0 { return Err(binder::StatusCode::BAD_VALUE); }
-              let mut result = Self::default();
-              result.challenge = parcel.read()?;
-              if (parcel.get_data_position() - start_pos) == parcelable_size {
-                return Ok(Some(result));
-              }
-              result.timestamp = parcel.read()?;
-              if (parcel.get_data_position() - start_pos) == parcelable_size {
-                return Ok(Some(result));
-              }
-              result.securityLevel = parcel.read()?;
-              if (parcel.get_data_position() - start_pos) == parcelable_size {
-                return Ok(Some(result));
-              }
-              result.mac = parcel.read()?;
-              if (parcel.get_data_position() - start_pos) == parcelable_size {
-                return Ok(Some(result));
-              }
-              Ok(Some(result))
-            }
-          }
-        }
-      }
-    }
-  }
-}
-pub mod mangled {
-  pub use super::aidl::android::hardware::keymint::Algorithm::mangled::*;
-  pub use super::aidl::android::hardware::keymint::BeginResult::mangled::*;
-  pub use super::aidl::android::hardware::keymint::BlockMode::mangled::*;
-  pub use super::aidl::android::hardware::keymint::Certificate::mangled::*;
-  pub use super::aidl::android::hardware::keymint::Constants::mangled::*;
-  pub use super::aidl::android::hardware::keymint::Digest::mangled::*;
-  pub use super::aidl::android::hardware::keymint::EcCurve::mangled::*;
-  pub use super::aidl::android::hardware::keymint::ErrorCode::mangled::*;
-  pub use super::aidl::android::hardware::keymint::HardwareAuthToken::mangled::*;
-  pub use super::aidl::android::hardware::keymint::HardwareAuthenticatorType::mangled::*;
-  pub use super::aidl::android::hardware::keymint::HmacSharingParameters::mangled::*;
-  pub use super::aidl::android::hardware::keymint::IKeyMintDevice::mangled::*;
-  pub use super::aidl::android::hardware::keymint::IKeyMintOperation::mangled::*;
-  pub use super::aidl::android::hardware::keymint::KeyCharacteristics::mangled::*;
-  pub use super::aidl::android::hardware::keymint::KeyDerivationFunction::mangled::*;
-  pub use super::aidl::android::hardware::keymint::KeyFormat::mangled::*;
-  pub use super::aidl::android::hardware::keymint::KeyMintHardwareInfo::mangled::*;
-  pub use super::aidl::android::hardware::keymint::KeyOrigin::mangled::*;
-  pub use super::aidl::android::hardware::keymint::KeyParameter::mangled::*;
-  pub use super::aidl::android::hardware::keymint::KeyPurpose::mangled::*;
-  pub use super::aidl::android::hardware::keymint::PaddingMode::mangled::*;
-  pub use super::aidl::android::hardware::keymint::SecurityLevel::mangled::*;
-  pub use super::aidl::android::hardware::keymint::Tag::mangled::*;
-  pub use super::aidl::android::hardware::keymint::TagType::mangled::*;
-  pub use super::aidl::android::hardware::keymint::Timestamp::mangled::*;
-  pub use super::aidl::android::hardware::keymint::VerificationToken::mangled::*;
-}
diff --git a/keystore2/src/database.rs b/keystore2/src/database.rs
index df71d94..f612495 100644
--- a/keystore2/src/database.rs
+++ b/keystore2/src/database.rs
@@ -46,17 +46,22 @@
 use crate::permission::KeyPermSet;
 use anyhow::{anyhow, Context, Result};
 
+use android_hardware_keymint::aidl::android::hardware::keymint::SecurityLevel::SecurityLevel;
 use android_system_keystore2::aidl::android::system::keystore2::{
-    Domain::Domain, KeyDescriptor::KeyDescriptor, SecurityLevel::SecurityLevel,
+    Domain::Domain, KeyDescriptor::KeyDescriptor,
 };
 
+use lazy_static::lazy_static;
 #[cfg(not(test))]
 use rand::prelude::random;
 use rusqlite::{
     params, types::FromSql, types::FromSqlResult, types::ToSqlOutput, types::ValueRef, Connection,
     OptionalExtension, Row, Rows, ToSql, Transaction, TransactionBehavior, NO_PARAMS,
 };
-use std::sync::Once;
+use std::{
+    collections::HashSet,
+    sync::{Condvar, Mutex, Once},
+};
 #[cfg(test)]
 use tests::random;
 
@@ -88,11 +93,72 @@
     }
 }
 
+lazy_static! {
+    static ref KEY_ID_LOCK: KeyIdLockDb = KeyIdLockDb::new();
+}
+
+struct KeyIdLockDb {
+    locked_keys: Mutex<HashSet<i64>>,
+    cond_var: Condvar,
+}
+
+/// A locked key. While a guard exists for a given key id, the same key cannot be loaded
+/// from the database a second time. Most functions manipulating the key blob database
+/// require a KeyIdGuard.
+#[derive(Debug)]
+pub struct KeyIdGuard(i64);
+
+impl KeyIdLockDb {
+    fn new() -> Self {
+        Self { locked_keys: Mutex::new(HashSet::new()), cond_var: Condvar::new() }
+    }
+
+    /// This function blocks until an exclusive lock for the given key entry id can
+    /// be acquired. It returns a guard object, that represents the lifecycle of the
+    /// acquired lock.
+    pub fn get(&self, key_id: i64) -> KeyIdGuard {
+        let mut locked_keys = self.locked_keys.lock().unwrap();
+        while locked_keys.contains(&key_id) {
+            locked_keys = self.cond_var.wait(locked_keys).unwrap();
+        }
+        locked_keys.insert(key_id);
+        KeyIdGuard(key_id)
+    }
+
+    /// This function attempts to acquire an exclusive lock on a given key id. If the
+    /// given key id is already taken the function returns None immediately. If a lock
+    /// can be acquired this function returns a guard object, that represents the
+    /// lifecycle of the acquired lock.
+    pub fn try_get(&self, key_id: i64) -> Option<KeyIdGuard> {
+        let mut locked_keys = self.locked_keys.lock().unwrap();
+        if locked_keys.insert(key_id) {
+            Some(KeyIdGuard(key_id))
+        } else {
+            None
+        }
+    }
+}
+
+impl KeyIdGuard {
+    /// Get the numeric key id of the locked key.
+    pub fn id(&self) -> i64 {
+        self.0
+    }
+}
+
+impl Drop for KeyIdGuard {
+    fn drop(&mut self) {
+        let mut locked_keys = KEY_ID_LOCK.locked_keys.lock().unwrap();
+        locked_keys.remove(&self.0);
+        KEY_ID_LOCK.cond_var.notify_all();
+    }
+}
+
 /// This type represents a Keystore 2.0 key entry.
 /// An entry has a unique `id` by which it can be found in the database.
 /// It has a security level field, key parameters, and three optional fields
 /// for the KeyMint blob, public certificate and a public certificate chain.
-#[derive(Debug, Default, Clone, Eq, PartialEq, Ord, PartialOrd)]
+#[derive(Debug, Default, Eq, PartialEq, Ord, PartialOrd)]
 pub struct KeyEntry {
     id: i64,
     km_blob: Option<Vec<u8>>,
@@ -135,6 +201,14 @@
     pub fn sec_level(&self) -> SecurityLevel {
         self.sec_level
     }
+    /// Exposes the key parameters of this key entry.
+    pub fn key_parameters(&self) -> &Vec<KeyParameter> {
+        &self.parameters
+    }
+    /// Consumes this key entry and extracts the keyparameters from it.
+    pub fn into_key_parameters(self) -> Vec<KeyParameter> {
+        self.parameters
+    }
 }
 
 /// Indicates the sub component of a key entry for persistent storage.
@@ -260,7 +334,7 @@
     /// key artifacts, i.e., blobs and parameters have been associated with the new
     /// key id. Finalizing with `rebind_alias` makes the creation of a new key entry
     /// atomic even if key generation is not.
-    pub fn create_key_entry(&self, domain: Domain, namespace: i64) -> Result<i64> {
+    pub fn create_key_entry(&self, domain: Domain, namespace: i64) -> Result<KeyIdGuard> {
         match domain {
             Domain::APP | Domain::SELINUX => {}
             _ => {
@@ -268,14 +342,16 @@
                     .context(format!("Domain {:?} must be either App or SELinux.", domain));
             }
         }
-        Self::insert_with_retry(|id| {
-            self.conn.execute(
-                "INSERT into persistent.keyentry (id, creation_date, domain, namespace, alias)
+        Ok(KEY_ID_LOCK.get(
+            Self::insert_with_retry(|id| {
+                self.conn.execute(
+                    "INSERT into persistent.keyentry (id, creation_date, domain, namespace, alias)
                      VALUES(?, datetime('now'), ?, ?, NULL);",
-                params![id, domain.0 as u32, namespace],
-            )
-        })
-        .context("In create_key_entry")
+                    params![id, domain.0 as u32, namespace],
+                )
+            })
+            .context("In create_key_entry")?,
+        ))
     }
 
     /// Inserts a new blob and associates it with the given key id. Each blob
@@ -286,7 +362,7 @@
     /// other than `SubComponentType::KM_BLOB` are ignored.
     pub fn insert_blob(
         &mut self,
-        key_id: i64,
+        key_id: &KeyIdGuard,
         sc_type: SubComponentType,
         blob: &[u8],
         sec_level: SecurityLevel,
@@ -295,7 +371,7 @@
             .execute(
                 "INSERT into persistent.blobentry (subcomponent_type, keyentryid, blob, sec_level)
                     VALUES (?, ?, ?, ?);",
-                params![sc_type, key_id, blob, sec_level.0],
+                params![sc_type, key_id.0, blob, sec_level.0],
             )
             .context("Failed to insert blob.")?;
         Ok(())
@@ -305,7 +381,7 @@
     /// and associates them with the given `key_id`.
     pub fn insert_keyparameter<'a>(
         &mut self,
-        key_id: i64,
+        key_id: &KeyIdGuard,
         params: impl IntoIterator<Item = &'a KeyParameter>,
     ) -> Result<()> {
         let mut stmt = self
@@ -319,7 +395,7 @@
         let iter = params.into_iter();
         for p in iter {
             stmt.insert(params![
-                key_id,
+                key_id.0,
                 p.get_tag().0,
                 p.key_parameter_value(),
                 p.security_level().0
@@ -334,7 +410,7 @@
     /// with the same alias-domain-namespace tuple if such row exits.
     pub fn rebind_alias(
         &mut self,
-        newid: i64,
+        newid: &KeyIdGuard,
         alias: &str,
         domain: Domain,
         namespace: i64,
@@ -364,7 +440,7 @@
                 "UPDATE persistent.keyentry
                     SET alias = ?
                     WHERE id = ? AND domain = ? AND namespace = ?;",
-                params![alias, newid, domain.0 as u32, namespace],
+                params![alias, newid.0, domain.0 as u32, namespace],
             )
             .context("In rebind_alias: Failed to set alias.")?;
         if result != 1 {
@@ -588,10 +664,18 @@
         load_bits: KeyEntryLoadBits,
         caller_uid: u32,
         check_permission: impl FnOnce(&KeyDescriptor, Option<KeyPermSet>) -> Result<()>,
-    ) -> Result<KeyEntry> {
+    ) -> Result<(KeyIdGuard, KeyEntry)> {
+        // KEY ID LOCK 1/2
+        // If we got a key descriptor with a key id we can get the lock right away.
+        // Otherwise we have to defer it until we know the key id.
+        let key_id_guard = match key.domain {
+            Domain::KEY_ID => Some(KEY_ID_LOCK.get(key.nspace)),
+            _ => None,
+        };
+
         let tx = self
             .conn
-            .transaction_with_behavior(TransactionBehavior::Deferred)
+            .unchecked_transaction()
             .context("In load_key_entry: Failed to initialize transaction.")?;
 
         // Load the key_id and complete the access control tuple.
@@ -602,21 +686,71 @@
         // So do not touch that '?' at the end.
         check_permission(&access_key_descriptor, access_vector).context("In load_key_entry.")?;
 
-        let (sec_level, km_blob, cert_blob, cert_chain_blob) =
-            Self::load_blob_components(key_id, load_bits, &tx).context("In load_key_entry.")?;
+        // KEY ID LOCK 2/2
+        // If we did not get a key id lock by now, it was because we got a key descriptor
+        // without a key id. At this point we got the key id, so we can try and get a lock.
+        // However, we cannot block here, because we are in the middle of the transaction.
+        // So first we try to get the lock non blocking. If that fails, we roll back the
+        // transaction and block until we get the lock. After we successfully got the lock,
+        // we start a new transaction and load the access tuple again.
+        //
+        // We don't need to perform access control again, because we already established
+        // that the caller had access to the given key. But we need to make sure that the
+        // key id still exists. So we have to load the key entry by key id this time.
+        let (key_id_guard, tx) = match key_id_guard {
+            None => match KEY_ID_LOCK.try_get(key_id) {
+                None => {
+                    // Roll back the transaction.
+                    tx.rollback().context("In load_key_entry: Failed to roll back transaction.")?;
 
-        let parameters = Self::load_key_parameters(key_id, &tx).context("In load_key_entry.")?;
+                    // Block until we have a key id lock.
+                    let key_id_guard = KEY_ID_LOCK.get(key_id);
+
+                    // Create a new transaction.
+                    let tx = self.conn.unchecked_transaction().context(
+                        "In load_key_entry: Failed to initialize transaction. (deferred key lock)",
+                    )?;
+
+                    Self::load_access_tuple(
+                        &tx,
+                        // This time we have to load the key by the retrieved key id, because the
+                        // alias may have been rebound after we rolled back the transaction.
+                        KeyDescriptor {
+                            domain: Domain::KEY_ID,
+                            nspace: key_id,
+                            ..Default::default()
+                        },
+                        caller_uid,
+                    )
+                    .context("In load_key_entry. (deferred key lock)")?;
+                    (key_id_guard, tx)
+                }
+                Some(l) => (l, tx),
+            },
+            Some(key_id_guard) => (key_id_guard, tx),
+        };
+
+        let (sec_level, km_blob, cert_blob, cert_chain_blob) =
+            Self::load_blob_components(key_id_guard.id(), load_bits, &tx)
+                .context("In load_key_entry.")?;
+
+        let parameters =
+            Self::load_key_parameters(key_id_guard.id(), &tx).context("In load_key_entry.")?;
 
         tx.commit().context("In load_key_entry: Failed to commit transaction.")?;
 
-        Ok(KeyEntry {
-            id: key_id,
-            km_blob,
-            cert: cert_blob,
-            cert_chain: cert_chain_blob,
-            sec_level,
-            parameters,
-        })
+        let key_id = key_id_guard.id();
+        Ok((
+            key_id_guard,
+            KeyEntry {
+                id: key_id,
+                km_blob,
+                cert: cert_blob,
+                cert_chain: cert_chain_blob,
+                sec_level,
+                parameters,
+            },
+        ))
     }
 
     /// Adds a grant to the grant table.
@@ -797,6 +931,9 @@
     use crate::permission::{KeyPerm, KeyPermSet};
     use rusqlite::NO_PARAMS;
     use std::cell::RefCell;
+    use std::sync::atomic::{AtomicU8, Ordering};
+    use std::sync::Arc;
+    use std::thread;
 
     static PERSISTENT_TEST_SQL: &str = "/data/local/tmp/persistent.sqlite";
     static PERBOOT_TEST_SQL: &str = "/data/local/tmp/perboot.sqlite";
@@ -930,42 +1067,42 @@
         assert_eq!(extractor(&entries[1]), (Some(Domain::APP), Some(42), None));
 
         // Test that the first call to rebind_alias sets the alias.
-        db.rebind_alias(entries[0].id, "foo", Domain::APP, 42)?;
+        db.rebind_alias(&KEY_ID_LOCK.get(entries[0].id), "foo", Domain::APP, 42)?;
         let entries = get_keyentry(&db)?;
         assert_eq!(entries.len(), 2);
         assert_eq!(extractor(&entries[0]), (Some(Domain::APP), Some(42), Some("foo")));
         assert_eq!(extractor(&entries[1]), (Some(Domain::APP), Some(42), None));
 
         // Test that the second call to rebind_alias also empties the old one.
-        db.rebind_alias(entries[1].id, "foo", Domain::APP, 42)?;
+        db.rebind_alias(&KEY_ID_LOCK.get(entries[1].id), "foo", Domain::APP, 42)?;
         let entries = get_keyentry(&db)?;
         assert_eq!(entries.len(), 2);
-        assert_eq!(extractor(&entries[0]), (None, None, None));
+        assert_eq!(extractor(&entries[0]), (Some(Domain::APP), Some(42), None));
         assert_eq!(extractor(&entries[1]), (Some(Domain::APP), Some(42), Some("foo")));
 
         // Test that we must pass in a valid Domain.
         check_result_is_error_containing_string(
-            db.rebind_alias(0, "foo", Domain::GRANT, 42),
+            db.rebind_alias(&KEY_ID_LOCK.get(0), "foo", Domain::GRANT, 42),
             "Domain Domain(1) must be either App or SELinux.",
         );
         check_result_is_error_containing_string(
-            db.rebind_alias(0, "foo", Domain::BLOB, 42),
+            db.rebind_alias(&KEY_ID_LOCK.get(0), "foo", Domain::BLOB, 42),
             "Domain Domain(3) must be either App or SELinux.",
         );
         check_result_is_error_containing_string(
-            db.rebind_alias(0, "foo", Domain::KEY_ID, 42),
+            db.rebind_alias(&KEY_ID_LOCK.get(0), "foo", Domain::KEY_ID, 42),
             "Domain Domain(4) must be either App or SELinux.",
         );
 
         // Test that we correctly handle setting an alias for something that does not exist.
         check_result_is_error_containing_string(
-            db.rebind_alias(0, "foo", Domain::SELINUX, 42),
+            db.rebind_alias(&KEY_ID_LOCK.get(0), "foo", Domain::SELINUX, 42),
             "Expected to update a single entry but instead updated 0",
         );
         // Test that we correctly abort the transaction in this case.
         let entries = get_keyentry(&db)?;
         assert_eq!(entries.len(), 2);
-        assert_eq!(extractor(&entries[0]), (None, None, None));
+        assert_eq!(extractor(&entries[0]), (Some(Domain::APP), Some(42), None));
         assert_eq!(extractor(&entries[1]), (Some(Domain::APP), Some(42), Some("foo")));
 
         Ok(())
@@ -1127,15 +1264,20 @@
     #[test]
     fn test_insert_blob() -> Result<()> {
         let mut db = new_test_db()?;
-        db.insert_blob(1, SubComponentType::KM_BLOB, TEST_KM_BLOB, SecurityLevel::SOFTWARE)?;
         db.insert_blob(
-            1,
+            &KEY_ID_LOCK.get(1),
+            SubComponentType::KM_BLOB,
+            TEST_KM_BLOB,
+            SecurityLevel::SOFTWARE,
+        )?;
+        db.insert_blob(
+            &KEY_ID_LOCK.get(1),
             SubComponentType::CERT,
             TEST_CERT_BLOB,
             SecurityLevel::TRUSTED_ENVIRONMENT,
         )?;
         db.insert_blob(
-            1,
+            &KEY_ID_LOCK.get(1),
             SubComponentType::CERT_CHAIN,
             TEST_CERT_CHAIN_BLOB,
             SecurityLevel::STRONGBOX,
@@ -1165,8 +1307,9 @@
     fn test_insert_and_load_full_keyentry_domain_app() -> Result<()> {
         let mut db = new_test_db()?;
         let key_id = make_test_key_entry(&mut db, Domain::APP, 1, TEST_ALIAS)
-            .context("test_insert_and_load_full_keyentry_domain_app")?;
-        let key_entry = db.load_key_entry(
+            .context("test_insert_and_load_full_keyentry_domain_app")?
+            .0;
+        let (_key_guard, key_entry) = db.load_key_entry(
             KeyDescriptor {
                 domain: Domain::APP,
                 nspace: 0,
@@ -1185,7 +1328,7 @@
                 cert: Some(TEST_CERT_BLOB.to_vec()),
                 cert_chain: Some(TEST_CERT_CHAIN_BLOB.to_vec()),
                 sec_level: SecurityLevel::TRUSTED_ENVIRONMENT,
-                parameters: make_test_params()
+                parameters: make_test_params(),
             }
         );
         Ok(())
@@ -1195,8 +1338,9 @@
     fn test_insert_and_load_full_keyentry_domain_selinux() -> Result<()> {
         let mut db = new_test_db()?;
         let key_id = make_test_key_entry(&mut db, Domain::SELINUX, 1, TEST_ALIAS)
-            .context("test_insert_and_load_full_keyentry_domain_selinux")?;
-        let key_entry = db.load_key_entry(
+            .context("test_insert_and_load_full_keyentry_domain_selinux")?
+            .0;
+        let (_key_guard, key_entry) = db.load_key_entry(
             KeyDescriptor {
                 domain: Domain::SELINUX,
                 nspace: 1,
@@ -1215,7 +1359,7 @@
                 cert: Some(TEST_CERT_BLOB.to_vec()),
                 cert_chain: Some(TEST_CERT_CHAIN_BLOB.to_vec()),
                 sec_level: SecurityLevel::TRUSTED_ENVIRONMENT,
-                parameters: make_test_params()
+                parameters: make_test_params(),
             }
         );
         Ok(())
@@ -1225,8 +1369,9 @@
     fn test_insert_and_load_full_keyentry_domain_key_id() -> Result<()> {
         let mut db = new_test_db()?;
         let key_id = make_test_key_entry(&mut db, Domain::SELINUX, 1, TEST_ALIAS)
-            .context("test_insert_and_load_full_keyentry_domain_key_id")?;
-        let key_entry = db.load_key_entry(
+            .context("test_insert_and_load_full_keyentry_domain_key_id")?
+            .0;
+        let (_key_guard, key_entry) = db.load_key_entry(
             KeyDescriptor { domain: Domain::KEY_ID, nspace: key_id, alias: None, blob: None },
             KeyEntryLoadBits::BOTH,
             1,
@@ -1240,7 +1385,7 @@
                 cert: Some(TEST_CERT_BLOB.to_vec()),
                 cert_chain: Some(TEST_CERT_CHAIN_BLOB.to_vec()),
                 sec_level: SecurityLevel::TRUSTED_ENVIRONMENT,
-                parameters: make_test_params()
+                parameters: make_test_params(),
             }
         );
 
@@ -1251,7 +1396,8 @@
     fn test_insert_and_load_full_keyentry_from_grant() -> Result<()> {
         let mut db = new_test_db()?;
         let key_id = make_test_key_entry(&mut db, Domain::APP, 1, TEST_ALIAS)
-            .context("test_insert_and_load_full_keyentry_from_grant")?;
+            .context("test_insert_and_load_full_keyentry_from_grant")?
+            .0;
 
         let granted_key = db.grant(
             KeyDescriptor {
@@ -1268,11 +1414,12 @@
 
         debug_dump_grant_table(&mut db)?;
 
-        let key_entry = db.load_key_entry(granted_key, KeyEntryLoadBits::BOTH, 2, |k, av| {
-            assert_eq!(Domain::GRANT, k.domain);
-            assert!(av.unwrap().includes(KeyPerm::use_()));
-            Ok(())
-        })?;
+        let (_key_guard, key_entry) =
+            db.load_key_entry(granted_key, KeyEntryLoadBits::BOTH, 2, |k, av| {
+                assert_eq!(Domain::GRANT, k.domain);
+                assert!(av.unwrap().includes(KeyPerm::use_()));
+                Ok(())
+            })?;
 
         assert_eq!(
             key_entry,
@@ -1282,12 +1429,105 @@
                 cert: Some(TEST_CERT_BLOB.to_vec()),
                 cert_chain: Some(TEST_CERT_CHAIN_BLOB.to_vec()),
                 sec_level: SecurityLevel::TRUSTED_ENVIRONMENT,
-                parameters: make_test_params()
+                parameters: make_test_params(),
             }
         );
         Ok(())
     }
 
+    static KEY_LOCK_TEST_ALIAS: &str = "my super duper locked key";
+
+    static KEY_LOCK_TEST_SQL: &str = "/data/local/tmp/persistent_key_lock.sqlite";
+    static KEY_LOCK_PERBOOT_TEST_SQL: &str = "/data/local/tmp/perboot_key_lock.sqlite";
+
+    fn new_test_db_with_persistent_file_key_lock() -> Result<KeystoreDB> {
+        let conn = KeystoreDB::make_connection(KEY_LOCK_TEST_SQL, KEY_LOCK_PERBOOT_TEST_SQL)?;
+
+        KeystoreDB::init_tables(&conn).context("Failed to initialize tables.")?;
+        Ok(KeystoreDB { conn })
+    }
+
+    #[test]
+    fn test_insert_and_load_full_keyentry_domain_app_concurrently() -> Result<()> {
+        let handle = {
+            let _file_guard_persistent = Arc::new(TempFile { filename: KEY_LOCK_TEST_SQL });
+            let _file_guard_perboot = Arc::new(TempFile { filename: KEY_LOCK_PERBOOT_TEST_SQL });
+            let mut db = new_test_db_with_persistent_file_key_lock()?;
+            let key_id = make_test_key_entry(&mut db, Domain::APP, 33, KEY_LOCK_TEST_ALIAS)
+                .context("test_insert_and_load_full_keyentry_domain_app")?
+                .0;
+            let (_key_guard, key_entry) = db.load_key_entry(
+                KeyDescriptor {
+                    domain: Domain::APP,
+                    nspace: 0,
+                    alias: Some(KEY_LOCK_TEST_ALIAS.to_string()),
+                    blob: None,
+                },
+                KeyEntryLoadBits::BOTH,
+                33,
+                |_k, _av| Ok(()),
+            )?;
+            assert_eq!(
+                key_entry,
+                KeyEntry {
+                    id: key_id,
+                    km_blob: Some(TEST_KM_BLOB.to_vec()),
+                    cert: Some(TEST_CERT_BLOB.to_vec()),
+                    cert_chain: Some(TEST_CERT_CHAIN_BLOB.to_vec()),
+                    sec_level: SecurityLevel::TRUSTED_ENVIRONMENT,
+                    parameters: make_test_params(),
+                }
+            );
+            let state = Arc::new(AtomicU8::new(1));
+            let state2 = state.clone();
+
+            // Spawning a second thread that attempts to acquire the key id lock
+            // for the same key as the primary thread. The primary thread then
+            // waits, thereby forcing the secondary thread into the second stage
+            // of acquiring the lock (see KEY ID LOCK 2/2 above).
+            // The test succeeds if the secondary thread observes the transition
+            // of `state` from 1 to 2, despite having a whole second to overtake
+            // the primary thread.
+            let handle = thread::spawn(move || {
+                let _file_a = _file_guard_persistent;
+                let _file_b = _file_guard_perboot;
+                let mut db = new_test_db_with_persistent_file_key_lock().unwrap();
+                assert!(db
+                    .load_key_entry(
+                        KeyDescriptor {
+                            domain: Domain::APP,
+                            nspace: 0,
+                            alias: Some(KEY_LOCK_TEST_ALIAS.to_string()),
+                            blob: None,
+                        },
+                        KeyEntryLoadBits::BOTH,
+                        33,
+                        |_k, _av| Ok(()),
+                    )
+                    .is_ok());
+                // We should only see a 2 here because we can only return
+                // from load_key_entry when the `_key_guard` expires,
+                // which happens at the end of the scope.
+                assert_eq!(2, state2.load(Ordering::Relaxed));
+            });
+
+            thread::sleep(std::time::Duration::from_millis(1000));
+
+            assert_eq!(Ok(1), state.compare_exchange(1, 2, Ordering::Relaxed, Ordering::Relaxed));
+
+            // Return the handle from this scope so we can join with the
+            // secondary thread after the key id lock has expired.
+            handle
+            // This is where the `_key_guard` goes out of scope,
+            // which is the reason for concurrent load_key_entry on the same key
+            // to unblock.
+        };
+        // Join with the secondary thread and unwrap, to propagate failing asserts to the
+        // main test thread. We will not see failing asserts in secondary threads otherwise.
+        handle.join().unwrap();
+        Ok(())
+    }
+
     // Helpers
 
     // Checks that the given result is an error containing the given string.
@@ -1560,28 +1800,28 @@
         domain: Domain,
         namespace: i64,
         alias: &str,
-    ) -> Result<i64> {
+    ) -> Result<KeyIdGuard> {
         let key_id = db.create_key_entry(domain, namespace)?;
         db.insert_blob(
-            key_id,
+            &key_id,
             SubComponentType::KM_BLOB,
             TEST_KM_BLOB,
             SecurityLevel::TRUSTED_ENVIRONMENT,
         )?;
         db.insert_blob(
-            key_id,
+            &key_id,
             SubComponentType::CERT,
             TEST_CERT_BLOB,
             SecurityLevel::TRUSTED_ENVIRONMENT,
         )?;
         db.insert_blob(
-            key_id,
+            &key_id,
             SubComponentType::CERT_CHAIN,
             TEST_CERT_CHAIN_BLOB,
             SecurityLevel::TRUSTED_ENVIRONMENT,
         )?;
-        db.insert_keyparameter(key_id, &make_test_params())?;
-        db.rebind_alias(key_id, alias, domain, namespace)?;
+        db.insert_keyparameter(&key_id, &make_test_params())?;
+        db.rebind_alias(&key_id, alias, domain, namespace)?;
         Ok(key_id)
     }
 
diff --git a/keystore2/src/key_parameter.rs b/keystore2/src/key_parameter.rs
index 8825fc9..5698c96 100644
--- a/keystore2/src/key_parameter.rs
+++ b/keystore2/src/key_parameter.rs
@@ -23,9 +23,9 @@
     Algorithm::Algorithm, BlockMode::BlockMode, Digest::Digest, EcCurve::EcCurve,
     HardwareAuthenticatorType::HardwareAuthenticatorType, KeyOrigin::KeyOrigin,
     KeyParameter::KeyParameter as KmKeyParameter, KeyPurpose::KeyPurpose, PaddingMode::PaddingMode,
-    Tag::Tag,
+    SecurityLevel::SecurityLevel, Tag::Tag,
 };
-pub use android_system_keystore2::aidl::android::system::keystore2::SecurityLevel::SecurityLevel;
+use android_system_keystore2::aidl::android::system::keystore2::Authorization::Authorization;
 use anyhow::{Context, Result};
 use rusqlite::types::{FromSql, Null, ToSql, ToSqlOutput};
 use rusqlite::{Result as SqlResult, Row};
@@ -233,6 +233,16 @@
     pub fn security_level(&self) -> &SecurityLevel {
         &self.security_level
     }
+
+    /// An authorization is a KeyParameter with an associated security level that is used
+    /// to convey the key characteristics to keystore clients. This function consumes
+    /// an internal KeyParameter representation to produce the Authorization wire type.
+    pub fn into_authorization(self) -> Authorization {
+        Authorization {
+            securityLevel: self.security_level,
+            keyParameter: self.key_parameter_value.convert_to_wire(),
+        }
+    }
 }
 
 /// This struct is defined to postpone converting rusqlite column value to the
@@ -606,7 +616,6 @@
 ///         CallerNonce, CALLER_NONCE, boolValue;
 ///         UserSecureID, USER_SECURE_ID, longInteger;
 ///         ApplicationID, APPLICATION_ID, blob;
-///         ActiveDateTime, ACTIVE_DATETIME, dateTime;
 /// }
 /// ```
 /// expands to:
@@ -637,11 +646,6 @@
 ///                         blob: v,
 ///                         ..Default::default()
 ///                 },
-///                 KeyParameterValue::ActiveDateTime(v) => KmKeyParameter {
-///                         tag: Tag::ACTIVE_DATETIME,
-///                         dateTime: v,
-///                         ..Default::default()
-///                 },
 ///         }
 /// }
 /// ```
@@ -673,11 +677,6 @@
 ///                          blob: v,
 ///                          ..
 ///                 } => KeyParameterValue::ApplicationID(v),
-///                 KmKeyParameter {
-///                          tag: Tag::ACTIVE_DATETIME,
-///                          dateTime: v,
-///                          ..
-///                 } => KeyParameterValue::ActiveDateTime(v),
 ///                 _ => KeyParameterValue::Invalid,
 ///         }
 /// }
@@ -771,7 +770,7 @@
        }
     };
     // This rule handles all variants that are neither invalid nor bool values nor enums
-    // (i.e. all variants which correspond to integer, longInteger, dateTime and blob fields in
+    // (i.e. all variants which correspond to integer, longInteger, and blob fields in
     // KmKeyParameter).
     // On an input like: 'ConfirmationToken, CONFIRMATION_TOKEN, blob;' it generates a match arm
     // like: KeyParameterValue::ConfirmationToken(v) => KmKeyParameter {
@@ -855,7 +854,7 @@
         }
     };
     // This rule handles all variants that are neither invalid nor bool values nor enums
-    // (i.e. all variants which correspond to integer, longInteger, dateTime and blob fields in
+    // (i.e. all variants which correspond to integer, longInteger, and blob fields in
     // KmKeyParameter).
     // On an input like: 'ConfirmationToken, CONFIRMATION_TOKEN, blob;' it generates a match arm
     // like:
@@ -892,7 +891,7 @@
     // Invoke the macro that generates the code for key parameter conversion to/from wire type
     // with all possible variants of KeyParameterValue. Each line corresponding to a variant
     // contains: variant identifier, tag value, and the related field name (i.e.
-    // boolValue/integer/longInteger/dateTime/blob) in the KmKeyParameter.
+    // boolValue/integer/longInteger/blob) in the KmKeyParameter.
     implement_key_parameter_conversion_to_from_wire! {
         Invalid, INVALID, na;
         KeyPurpose, PURPOSE, integer, KeyPurpose;
@@ -908,9 +907,9 @@
         IncludeUniqueID, INCLUDE_UNIQUE_ID, boolValue;
         BootLoaderOnly, BOOTLOADER_ONLY, boolValue;
         RollbackResistance, ROLLBACK_RESISTANCE, boolValue;
-        ActiveDateTime, ACTIVE_DATETIME, dateTime;
-        OriginationExpireDateTime, ORIGINATION_EXPIRE_DATETIME, dateTime;
-        UsageExpireDateTime, USAGE_EXPIRE_DATETIME, dateTime;
+        ActiveDateTime, ACTIVE_DATETIME, longInteger;
+        OriginationExpireDateTime, ORIGINATION_EXPIRE_DATETIME, longInteger;
+        UsageExpireDateTime, USAGE_EXPIRE_DATETIME, longInteger;
         MinSecondsBetweenOps, MIN_SECONDS_BETWEEN_OPS, integer;
         MaxUsesPerBoot, MAX_USES_PER_BOOT, integer;
         UserID, USER_ID, integer;
@@ -924,7 +923,7 @@
         UnlockedDeviceRequired, UNLOCKED_DEVICE_REQUIRED, boolValue;
         ApplicationID, APPLICATION_ID, blob;
         ApplicationData, APPLICATION_DATA, blob;
-        CreationDateTime, CREATION_DATETIME, dateTime;
+        CreationDateTime, CREATION_DATETIME, longInteger;
         KeyOrigin, ORIGIN, integer, KeyOrigin;
         RootOfTrust, ROOT_OF_TRUST, blob;
         OSVersion, OS_VERSION, integer;
@@ -1243,13 +1242,12 @@
 }
 
 /// The wire_tests module tests the 'convert_to_wire' and 'convert_from_wire' methods for
-/// KeyParameter, for the five different types used in KmKeyParameter, in addition to Invalid
+/// KeyParameter, for the four different types used in KmKeyParameter, in addition to Invalid
 /// key parameter.
 /// i) bool
 /// ii) integer
 /// iii) longInteger
-/// iv) dateTime
-/// v) blob
+/// iv) blob
 #[cfg(test)]
 mod wire_tests {
     use crate::key_parameter::*;
@@ -1286,16 +1284,6 @@
         assert_eq!(i64::MAX, actual.longInteger);
     }
     #[test]
-    fn test_convert_to_wire_date_time() {
-        let kp = KeyParameter::new(
-            KeyParameterValue::ActiveDateTime(i64::MAX),
-            SecurityLevel::STRONGBOX,
-        );
-        let actual = KeyParameterValue::convert_to_wire(kp.key_parameter_value);
-        assert_eq!(Tag::ACTIVE_DATETIME, actual.tag);
-        assert_eq!(i64::MAX, actual.dateTime);
-    }
-    #[test]
     fn test_convert_to_wire_blob() {
         let kp = KeyParameter::new(
             KeyParameterValue::ConfirmationToken(String::from("ConfirmationToken").into_bytes()),
@@ -1341,13 +1329,6 @@
         assert_eq!(KeyParameterValue::UserSecureID(i64::MAX), actual);
     }
     #[test]
-    fn test_convert_from_wire_date_time() {
-        let aidl_kp =
-            KmKeyParameter { tag: Tag::ACTIVE_DATETIME, dateTime: i64::MAX, ..Default::default() };
-        let actual = KeyParameterValue::convert_from_wire(aidl_kp);
-        assert_eq!(KeyParameterValue::ActiveDateTime(i64::MAX), actual);
-    }
-    #[test]
     fn test_convert_from_wire_blob() {
         let aidl_kp = KmKeyParameter {
             tag: Tag::CONFIRMATION_TOKEN,
diff --git a/keystore2/src/operation.rs b/keystore2/src/operation.rs
index f987188..14edc6c 100644
--- a/keystore2/src/operation.rs
+++ b/keystore2/src/operation.rs
@@ -135,7 +135,8 @@
 use crate::error::{map_km_error, map_or_log_err, Error, ErrorCode, ResponseCode};
 use crate::utils::Asp;
 use android_hardware_keymint::aidl::android::hardware::keymint::{
-    IKeyMintOperation::IKeyMintOperation, KeyParameter::KeyParameter as KmParam, Tag::Tag,
+    ByteArray::ByteArray, IKeyMintOperation::IKeyMintOperation,
+    KeyParameter::KeyParameter as KmParam, KeyParameterArray::KeyParameterArray, Tag::Tag,
 };
 use android_system_keystore2::aidl::android::system::keystore2::{
     IKeystoreOperation::BnKeystoreOperation, IKeystoreOperation::IKeystoreOperation,
@@ -174,7 +175,6 @@
     index: usize,
 }
 
-static EMPTY_BLOB: &[u8] = &[];
 // We don't except more than 32KiB of data in `update`, `updateAad`, and `finish`.
 const MAX_RECEIVE_DATA: usize = 0x8000;
 
@@ -190,15 +190,29 @@
         }
     }
 
-    fn get_pruning_info(&self) -> PruningInfo {
-        // Expect safety:
-        // `last_usage` is locked only for primitive single line statements.
-        // There is no chance to panic and poison the mutex.
-        PruningInfo {
+    fn get_pruning_info(&self) -> Option<PruningInfo> {
+        // An operation may be finalized.
+        if let Ok(guard) = self.outcome.try_lock() {
+            match *guard {
+                Outcome::Unknown => {}
+                // If the outcome is any other than unknown, it has been finalized,
+                // and we can no longer consider it for pruning.
+                _ => return None,
+            }
+        }
+        // Else: If we could not grab the lock, this means that the operation is currently
+        //       being used and it may be transitioning to finalized or it was simply updated.
+        //       In any case it is fair game to consider it for pruning. If the operation
+        //       transitioned to a final state, we will notice when we attempt to prune, and
+        //       a subsequent attempt to create a new operation will succeed.
+        Some(PruningInfo {
+            // Expect safety:
+            // `last_usage` is locked only for primitive single line statements.
+            // There is no chance to panic and poison the mutex.
             last_usage: *self.last_usage.lock().expect("In get_pruning_info."),
             owner: self.owner,
             index: self.index,
-        }
+        })
     }
 
     fn prune(&self, last_usage: Instant) -> Result<(), Error> {
@@ -302,11 +316,16 @@
         Self::check_input_length(aad_input).context("In update_aad")?;
         self.touch();
 
-        let params =
-            [KmParam { tag: Tag::ASSOCIATED_DATA, blob: aad_input.into(), ..Default::default() }];
+        let params = KeyParameterArray {
+            params: vec![KmParam {
+                tag: Tag::ASSOCIATED_DATA,
+                blob: aad_input.into(),
+                ..Default::default()
+            }],
+        };
 
-        let mut out_params: Vec<KmParam> = Vec::new();
-        let mut output: Vec<u8> = Vec::new();
+        let mut out_params: Option<KeyParameterArray> = None;
+        let mut output: Option<ByteArray> = None;
 
         let km_op: Box<dyn IKeyMintOperation> =
             self.km_op.get_interface().context("In update: Failed to get KeyMintOperation.")?;
@@ -314,10 +333,12 @@
         self.update_outcome(
             &mut *outcome,
             map_km_error(km_op.update(
-                &params,
-                &[],
-                // TODO HardwareAuthtoken missing
-                &Default::default(),
+                Some(&params),
+                None,
+                // TODO Get auth token from enforcement module if required.
+                None,
+                // TODO Get verification token from enforcement module if required.
+                None,
                 &mut out_params,
                 &mut output,
             )),
@@ -334,8 +355,8 @@
         Self::check_input_length(input).context("In update")?;
         self.touch();
 
-        let mut out_params: Vec<KmParam> = Vec::new();
-        let mut output: Vec<u8> = Vec::new();
+        let mut out_params: Option<KeyParameterArray> = None;
+        let mut output: Option<ByteArray> = None;
 
         let km_op: Box<dyn IKeyMintOperation> =
             self.km_op.get_interface().context("In update: Failed to get KeyMintOperation.")?;
@@ -343,20 +364,21 @@
         self.update_outcome(
             &mut *outcome,
             map_km_error(km_op.update(
-                &[],
-                input,
-                // TODO HardwareAuthtoken missing
-                &Default::default(),
+                None,
+                Some(input),
+                // TODO Get auth token from enforcement module if required.
+                None,
+                // TODO Get verification token from enforcement module if required.
+                None,
                 &mut out_params,
                 &mut output,
             )),
         )
         .context("In update: KeyMint::update failed.")?;
 
-        if output.is_empty() {
-            Ok(None)
-        } else {
-            Ok(Some(output))
+        match output {
+            Some(blob) => Ok(Some(blob.data)),
+            None => Ok(None),
         }
     }
 
@@ -368,28 +390,27 @@
             Self::check_input_length(input).context("In finish")?;
         }
         self.touch();
-        let input = input.unwrap_or(EMPTY_BLOB);
-        let signature = signature.unwrap_or(EMPTY_BLOB);
 
-        let mut out_params: Vec<KmParam> = Vec::new();
-        let mut output: Vec<u8> = Vec::new();
+        let mut out_params: Option<KeyParameterArray> = None;
 
         let km_op: Box<dyn IKeyMintOperation> =
             self.km_op.get_interface().context("In finish: Failed to get KeyMintOperation.")?;
 
-        self.update_outcome(
-            &mut *outcome,
-            map_km_error(km_op.finish(
-                &[],
-                &input,
-                &signature,
-                &Default::default(),
-                &Default::default(),
-                &mut out_params,
-                &mut output,
-            )),
-        )
-        .context("In finish: KeyMint::finish failed.")?;
+        let output = self
+            .update_outcome(
+                &mut *outcome,
+                map_km_error(km_op.finish(
+                    None,
+                    input,
+                    signature,
+                    // TODO Get auth token from enforcement module if required.
+                    None,
+                    // TODO Get verification token from enforcement module if required.
+                    None,
+                    &mut out_params,
+                )),
+            )
+            .context("In finish: KeyMint::finish failed.")?;
 
         // At this point the operation concluded successfully.
         *outcome = Outcome::Success;
@@ -490,14 +511,17 @@
     /// To find a suitable candidate we compute the malus for the caller and each existing
     /// operation. The malus is the inverse of the pruning power (caller) or pruning
     /// resistance (existing operation).
+    ///
     /// The malus is based on the number of sibling operations and age. Sibling
     /// operations are operations that have the same owner (UID).
+    ///
     /// Every operation, existing or new, starts with a malus of 1. Every sibling
     /// increases the malus by one. The age is the time since an operation was last touched.
     /// It increases the malus by log6(<age in seconds> + 1) rounded down to the next
     /// integer. So the malus increases stepwise after 5s, 35s, 215s, ...
     /// Of two operations with the same malus the least recently used one is considered
     /// weaker.
+    ///
     /// For the caller to be able to prune an operation it must find an operation
     /// with a malus higher than its own.
     ///
@@ -534,12 +558,17 @@
     /// guaranteed that new operations can always be started. With the increased usage
     /// of Keystore we saw increased pruning activity which can lead to a livelock
     /// situation in the worst case.
+    ///
     /// With the new pruning strategy we want to provide well behaved clients with
     /// progress assurances while punishing DoS attempts. As a result of this
     /// strategy we can be in the situation where no operation can be pruned and the
     /// creation of a new operation fails. This allows single child operations which
     /// are frequently updated to complete, thereby breaking up livelock situations
     /// and facilitating system wide progress.
+    ///
+    /// ## Update
+    /// We also allow callers to cannibalize their own sibling operations if no other
+    /// slot can be found. In this case the least recently used sibling is pruned.
     pub fn prune(&self, caller: u32) -> Result<(), Error> {
         loop {
             // Maps the uid of the owner to the number of operations that owner has
@@ -556,11 +585,12 @@
                 .iter()
                 .for_each(|op| {
                     if let Some(op) = op.upgrade() {
-                        let p_info = op.get_pruning_info();
-                        let owner = p_info.owner;
-                        pruning_info.push(p_info);
-                        // Count operations per owner.
-                        *owners.entry(owner).or_insert(0) += 1;
+                        if let Some(p_info) = op.get_pruning_info() {
+                            let owner = p_info.owner;
+                            pruning_info.push(p_info);
+                            // Count operations per owner.
+                            *owners.entry(owner).or_insert(0) += 1;
+                        }
                     }
                 });
 
@@ -575,6 +605,7 @@
                 last_usage: Instant,
                 age: Duration,
             }
+            let mut oldest_caller_op: Option<CandidateInfo> = None;
             let candidate = pruning_info.iter().fold(
                 None,
                 |acc: Option<CandidateInfo>, &PruningInfo { last_usage, owner, index }| {
@@ -583,6 +614,19 @@
                         .checked_duration_since(last_usage)
                         .unwrap_or_else(|| Duration::new(0, 0));
 
+                    // Find the least recently used sibling as an alternative pruning candidate.
+                    if owner == caller {
+                        if let Some(CandidateInfo { age: a, .. }) = oldest_caller_op {
+                            if age > a {
+                                oldest_caller_op =
+                                    Some(CandidateInfo { index, malus: 0, last_usage, age });
+                            }
+                        } else {
+                            oldest_caller_op =
+                                Some(CandidateInfo { index, malus: 0, last_usage, age });
+                        }
+                    }
+
                     // Compute the malus of the current operation.
                     // Expect safety: Every owner in pruning_info was counted in
                     // the owners map. So this unwrap cannot panic.
@@ -615,6 +659,9 @@
                 },
             );
 
+            // If we did not find a suitable candidate we may cannibalize our oldest sibling.
+            let candidate = candidate.or(oldest_caller_op);
+
             match candidate {
                 Some(CandidateInfo { index, malus: _, last_usage, age: _ }) => {
                     match self.get(index) {
diff --git a/keystore2/src/security_level.rs b/keystore2/src/security_level.rs
index 30c9a86..24a2e99 100644
--- a/keystore2/src/security_level.rs
+++ b/keystore2/src/security_level.rs
@@ -17,28 +17,31 @@
 //! This crate implements the IKeystoreSecurityLevel interface.
 
 use android_hardware_keymint::aidl::android::hardware::keymint::{
-    Algorithm::Algorithm, Certificate::Certificate as KmCertificate,
-    IKeyMintDevice::IKeyMintDevice, KeyCharacteristics::KeyCharacteristics, KeyFormat::KeyFormat,
-    KeyParameter::KeyParameter as KmParam, KeyPurpose::KeyPurpose, Tag::Tag,
+    Algorithm::Algorithm, ByteArray::ByteArray, Certificate::Certificate as KmCertificate,
+    HardwareAuthenticatorType::HardwareAuthenticatorType, IKeyMintDevice::IKeyMintDevice,
+    KeyCharacteristics::KeyCharacteristics, KeyFormat::KeyFormat, KeyParameter::KeyParameter,
+    KeyPurpose::KeyPurpose, SecurityLevel::SecurityLevel, Tag::Tag,
 };
 use android_system_keystore2::aidl::android::system::keystore2::{
-    AuthenticatorSpec::AuthenticatorSpec, AuthenticatorType::AuthenticatorType,
-    CreateOperationResponse::CreateOperationResponse, Domain::Domain,
-    IKeystoreOperation::IKeystoreOperation, IKeystoreSecurityLevel::BnKeystoreSecurityLevel,
+    AuthenticatorSpec::AuthenticatorSpec, CreateOperationResponse::CreateOperationResponse,
+    Domain::Domain, IKeystoreOperation::IKeystoreOperation,
+    IKeystoreSecurityLevel::BnKeystoreSecurityLevel,
     IKeystoreSecurityLevel::IKeystoreSecurityLevel, KeyDescriptor::KeyDescriptor,
-    KeyMetadata::KeyMetadata, KeyParameter::KeyParameter, KeyParameters::KeyParameters,
-    SecurityLevel::SecurityLevel,
+    KeyMetadata::KeyMetadata, KeyParameters::KeyParameters,
 };
 
-use crate::error::{self, map_km_error, map_or_log_err, Error, ErrorCode};
-use crate::globals::DB;
 use crate::permission::KeyPerm;
-use crate::utils::{check_key_permission, keyparam_km_to_ks, keyparam_ks_to_km, Asp};
+use crate::utils::{check_key_permission, Asp};
+use crate::{database::KeyIdGuard, globals::DB};
 use crate::{
     database::{KeyEntry, KeyEntryLoadBits, SubComponentType},
     operation::KeystoreOperation,
     operation::OperationDb,
 };
+use crate::{
+    error::{self, map_km_error, map_or_log_err, Error, ErrorCode},
+    utils::key_characteristics_to_internal,
+};
 use anyhow::{anyhow, Context, Result};
 use binder::{IBinder, Interface, ThreadState};
 
@@ -83,8 +86,9 @@
     fn store_new_key(
         &self,
         key: KeyDescriptor,
+        key_characteristics: KeyCharacteristics,
         km_cert_chain: Option<Vec<KmCertificate>>,
-        blob: Vec<u8>,
+        blob: ByteArray,
     ) -> Result<KeyMetadata> {
         let (cert, cert_chain): (Option<Vec<u8>>, Option<Vec<u8>>) = match km_cert_chain {
             Some(mut chain) => (
@@ -107,9 +111,12 @@
             None => (None, None),
         };
 
+        let key_parameters =
+            key_characteristics_to_internal(key_characteristics, self.security_level);
+
         let key = match key.domain {
             Domain::BLOB => {
-                KeyDescriptor { domain: Domain::BLOB, blob: Some(blob), ..Default::default() }
+                KeyDescriptor { domain: Domain::BLOB, blob: Some(blob.data), ..Default::default() }
             }
             _ => DB
                 .with(|db| {
@@ -117,24 +124,31 @@
                     let key_id = db
                         .create_key_entry(key.domain, key.nspace)
                         .context("Trying to create a key entry.")?;
-                    db.insert_blob(key_id, SubComponentType::KM_BLOB, &blob, self.security_level)
-                        .context("Trying to insert km blob.")?;
+                    db.insert_blob(
+                        &key_id,
+                        SubComponentType::KM_BLOB,
+                        &blob.data,
+                        self.security_level,
+                    )
+                    .context("Trying to insert km blob.")?;
                     if let Some(c) = &cert {
-                        db.insert_blob(key_id, SubComponentType::CERT, c, self.security_level)
+                        db.insert_blob(&key_id, SubComponentType::CERT, c, self.security_level)
                             .context("Trying to insert cert blob.")?;
                     }
                     if let Some(c) = &cert_chain {
                         db.insert_blob(
-                            key_id,
+                            &key_id,
                             SubComponentType::CERT_CHAIN,
                             c,
                             self.security_level,
                         )
                         .context("Trying to insert cert chain blob.")?;
                     }
+                    db.insert_keyparameter(&key_id, &key_parameters)
+                        .context("Trying to insert key parameters.")?;
                     match &key.alias {
                         Some(alias) => db
-                            .rebind_alias(key_id, alias, key.domain, key.nspace)
+                            .rebind_alias(&key_id, alias, key.domain, key.nspace)
                             .context("Failed to rebind alias.")?,
                         None => {
                             return Err(error::Error::sys()).context(
@@ -144,7 +158,7 @@
                     }
                     Ok(KeyDescriptor {
                         domain: Domain::KEY_ID,
-                        nspace: key_id,
+                        nspace: key_id.id(),
                         ..Default::default()
                     })
                 })
@@ -156,7 +170,7 @@
             keySecurityLevel: self.security_level,
             certificate: cert,
             certificateChain: cert_chain,
-            // TODO initialize the authorizations.
+            authorizations: crate::utils::key_parameters_to_authorizations(key_parameters),
             ..Default::default()
         })
     }
@@ -172,7 +186,7 @@
         // so that we can use it by reference like the blob provided by the key descriptor.
         // Otherwise, we would have to clone the blob from the key descriptor.
         let scoping_blob: Vec<u8>;
-        let (km_blob, key_id) = match key.domain {
+        let (km_blob, key_id_guard) = match key.domain {
             Domain::BLOB => {
                 check_key_permission(KeyPerm::use_(), key, &None)
                     .context("In create_operation: checking use permission for Domain::BLOB.")?;
@@ -190,8 +204,8 @@
                 )
             }
             _ => {
-                let mut key_entry = DB
-                    .with::<_, Result<KeyEntry>>(|db| {
+                let (key_id_guard, mut key_entry) = DB
+                    .with::<_, Result<(KeyIdGuard, KeyEntry)>>(|db| {
                         db.borrow_mut().load_key_entry(
                             key.clone(),
                             KeyEntryLoadBits::KM,
@@ -209,7 +223,7 @@
                         ))
                     }
                 };
-                (&scoping_blob, Some(key_entry.id()))
+                (&scoping_blob, Some(key_id_guard))
             }
         };
 
@@ -217,76 +231,39 @@
         // Check if we need an authorization token.
         // Lookup authorization token and request VerificationToken if required.
 
-        let purpose = operation_parameters.iter().find(|p| p.tag == Tag::PURPOSE.0).map_or(
+        let purpose = operation_parameters.iter().find(|p| p.tag == Tag::PURPOSE).map_or(
             Err(Error::Km(ErrorCode::INVALID_ARGUMENT))
                 .context("In create_operation: No operation purpose specified."),
             |kp| Ok(KeyPurpose(kp.integer)),
         )?;
 
-        let km_params =
-            operation_parameters.iter().map(|p| keyparam_ks_to_km(p)).collect::<Vec<KmParam>>();
-
         let km_dev: Box<dyn IKeyMintDevice> = self
             .keymint
             .get_interface()
             .context("In create_operation: Failed to get KeyMint device")?;
 
-        let (begin_result, upgraded_blob) = loop {
-            match map_km_error(km_dev.begin(purpose, &km_blob, &km_params, &Default::default())) {
-                Ok(result) => break (result, None),
-                Err(Error::Km(ErrorCode::TOO_MANY_OPERATIONS)) => {
-                    self.operation_db
-                        .prune(caller_uid)
-                        .context("In create_operation: Outer loop.")?;
-                    continue;
-                }
-                Err(Error::Km(ErrorCode::KEY_REQUIRES_UPGRADE)) => {
-                    let upgraded_blob = map_km_error(km_dev.upgradeKey(&km_blob, &km_params))
-                        .context("In create_operation: Upgrade failed.")?;
-                    break loop {
-                        match map_km_error(km_dev.begin(
-                            purpose,
-                            &upgraded_blob,
-                            &km_params,
-                            &Default::default(),
-                        )) {
-                            Ok(result) => break (result, Some(upgraded_blob)),
-                            // If Keystore 2.0 is multi threaded another request may have
-                            // snatched up our previously pruned operation slot. So we might
-                            // need to prune again.
-                            Err(Error::Km(ErrorCode::TOO_MANY_OPERATIONS)) => {
-                                self.operation_db
-                                    .prune(caller_uid)
-                                    .context("In create_operation: Inner loop.")?;
-                                continue;
-                            }
-                            Err(e) => {
-                                return Err(e).context(
-                                    "In create_operation: Begin operation failed after upgrade.",
-                                )
-                            }
+        let (begin_result, upgraded_blob) = self
+            .upgrade_keyblob_if_required_with(
+                &*km_dev,
+                key_id_guard,
+                &km_blob,
+                &operation_parameters,
+                |blob| loop {
+                    match map_km_error(km_dev.begin(
+                        purpose,
+                        blob,
+                        &operation_parameters,
+                        &Default::default(),
+                    )) {
+                        Err(Error::Km(ErrorCode::TOO_MANY_OPERATIONS)) => {
+                            self.operation_db.prune(caller_uid)?;
+                            continue;
                         }
-                    };
-                }
-                Err(e) => return Err(e).context("In create_operation: Begin operation failed."),
-            };
-        };
-
-        if let Some(upgraded_blob) = upgraded_blob {
-            if let Some(key_id) = key_id {
-                DB.with(|db| {
-                    db.borrow_mut().insert_blob(
-                        key_id,
-                        SubComponentType::KM_BLOB,
-                        &upgraded_blob,
-                        self.security_level,
-                    )
-                })
-                .context(
-                    "In create_operation: Failed to insert upgraded blob into the database.",
-                )?;
-            }
-        }
+                        v => return v,
+                    }
+                },
+            )
+            .context("In create_operation: Failed to begin operation.")?;
 
         let operation = match begin_result.operation {
             Some(km_op) => self.operation_db.create_operation(km_op, caller_uid),
@@ -306,13 +283,7 @@
             operationChallenge: None,
             parameters: match begin_result.params.len() {
                 0 => None,
-                _ => Some(KeyParameters {
-                    keyParameter: begin_result
-                        .params
-                        .iter()
-                        .map(|p| keyparam_km_to_ks(p))
-                        .collect(),
-                }),
+                _ => Some(KeyParameters { keyParameter: begin_result.params }),
             },
         })
     }
@@ -345,17 +316,18 @@
 
         let km_dev: Box<dyn IKeyMintDevice> = self.keymint.get_interface()?;
         map_km_error(km_dev.addRngEntropy(entropy))?;
-        let mut blob: Vec<u8> = Default::default();
+        let mut blob: ByteArray = Default::default();
         let mut key_characteristics: KeyCharacteristics = Default::default();
         let mut certificate_chain: Vec<KmCertificate> = Default::default();
         map_km_error(km_dev.generateKey(
-            &params.iter().map(|p| keyparam_ks_to_km(p)).collect::<Vec<KmParam>>(),
+            &params,
             &mut blob,
             &mut key_characteristics,
             &mut certificate_chain,
         ))?;
 
-        self.store_new_key(key, Some(certificate_chain), blob).context("In generate_key.")
+        self.store_new_key(key, key_characteristics, Some(certificate_chain), blob)
+            .context("In generate_key.")
     }
 
     fn import_key(
@@ -384,13 +356,13 @@
         // import_key requires the rebind permission.
         check_key_permission(KeyPerm::rebind(), &key, &None).context("In import_key.")?;
 
-        let mut blob: Vec<u8> = Default::default();
+        let mut blob: ByteArray = Default::default();
         let mut key_characteristics: KeyCharacteristics = Default::default();
         let mut certificate_chain: Vec<KmCertificate> = Default::default();
 
         let format = params
             .iter()
-            .find(|p| p.tag == Tag::ALGORITHM.0)
+            .find(|p| p.tag == Tag::ALGORITHM)
             .ok_or(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
             .context("No KeyParameter 'Algorithm'.")
             .and_then(|p| match Algorithm(p.integer) {
@@ -403,7 +375,7 @@
 
         let km_dev: Box<dyn IKeyMintDevice> = self.keymint.get_interface()?;
         map_km_error(km_dev.importKey(
-            &params.iter().map(|p| keyparam_ks_to_km(p)).collect::<Vec<KmParam>>(),
+            &params,
             format,
             key_data,
             &mut blob,
@@ -411,7 +383,8 @@
             &mut certificate_chain,
         ))?;
 
-        self.store_new_key(key, Some(certificate_chain), blob).context("In import_key.")
+        self.store_new_key(key, key_characteristics, Some(certificate_chain), blob)
+            .context("In import_key.")
     }
 
     fn import_wrapped_key(
@@ -427,6 +400,12 @@
                 .context("In import_wrapped_key: Alias must be specified.");
         }
 
+        if wrapping_key.domain == Domain::BLOB {
+            return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT)).context(
+                "In import_wrapped_key: Import wrapped key not supported for self managed blobs.",
+            );
+        }
+
         let wrapped_data = match &key.blob {
             Some(d) => d,
             None => {
@@ -449,7 +428,7 @@
         // import_wrapped_key requires the rebind permission for the new key.
         check_key_permission(KeyPerm::rebind(), &key, &None).context("In import_wrapped_key.")?;
 
-        let wrapping_key_entry = DB
+        let (wrapping_key_id_guard, wrapping_key_entry) = DB
             .with(|db| {
                 db.borrow_mut().load_key_entry(
                     wrapping_key.clone(),
@@ -469,8 +448,6 @@
             }
         };
 
-        let mut blob: Vec<u8> = Default::default();
-        let mut key_characteristics: KeyCharacteristics = Default::default();
         // km_dev.importWrappedKey does not return a certificate chain.
         // TODO Do we assume that all wrapped keys are symmetric?
         // let certificate_chain: Vec<KmCertificate> = Default::default();
@@ -478,7 +455,7 @@
         let pw_sid = authenticators
             .iter()
             .find_map(|a| match a.authenticatorType {
-                AuthenticatorType::PASSWORD => Some(a.authenticatorId),
+                HardwareAuthenticatorType::PASSWORD => Some(a.authenticatorId),
                 _ => None,
             })
             .ok_or(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
@@ -487,7 +464,7 @@
         let fp_sid = authenticators
             .iter()
             .find_map(|a| match a.authenticatorType {
-                AuthenticatorType::FINGERPRINT => Some(a.authenticatorId),
+                HardwareAuthenticatorType::FINGERPRINT => Some(a.authenticatorId),
                 _ => None,
             })
             .ok_or(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
@@ -496,18 +473,73 @@
         let masking_key = masking_key.unwrap_or(ZERO_BLOB_32);
 
         let km_dev: Box<dyn IKeyMintDevice> = self.keymint.get_interface()?;
-        map_km_error(km_dev.importWrappedKey(
-            wrapped_data,
+        let ((blob, key_characteristics), _) = self.upgrade_keyblob_if_required_with(
+            &*km_dev,
+            Some(wrapping_key_id_guard),
             wrapping_key_blob,
-            masking_key,
-            &params.iter().map(|p| keyparam_ks_to_km(p)).collect::<Vec<KmParam>>(),
-            pw_sid,
-            fp_sid,
-            &mut blob,
-            &mut key_characteristics,
-        ))?;
+            &[],
+            |wrapping_blob| {
+                let mut blob: ByteArray = Default::default();
+                let mut key_characteristics: KeyCharacteristics = Default::default();
+                map_km_error(km_dev.importWrappedKey(
+                    wrapped_data,
+                    wrapping_key_blob,
+                    masking_key,
+                    &params,
+                    pw_sid,
+                    fp_sid,
+                    &mut blob,
+                    &mut key_characteristics,
+                ))?;
+                Ok((blob, key_characteristics))
+            },
+        )?;
 
-        self.store_new_key(key, None, blob).context("In import_wrapped_key.")
+        self.store_new_key(key, key_characteristics, None, blob).context("In import_wrapped_key.")
+    }
+
+    fn upgrade_keyblob_if_required_with<T, F>(
+        &self,
+        km_dev: &dyn IKeyMintDevice,
+        key_id_guard: Option<KeyIdGuard>,
+        blob: &[u8],
+        params: &[KeyParameter],
+        f: F,
+    ) -> Result<(T, Option<Vec<u8>>)>
+    where
+        F: Fn(&[u8]) -> Result<T, Error>,
+    {
+        match f(blob) {
+            Err(Error::Km(ErrorCode::KEY_REQUIRES_UPGRADE)) => {
+                let upgraded_blob = map_km_error(km_dev.upgradeKey(blob, params))
+                    .context("In upgrade_keyblob_if_required_with: Upgrade failed.")?;
+                key_id_guard.map_or(Ok(()), |key_id_guard| {
+                    DB.with(|db| {
+                        db.borrow_mut().insert_blob(
+                            &key_id_guard,
+                            SubComponentType::KM_BLOB,
+                            &upgraded_blob,
+                            self.security_level,
+                        )
+                    })
+                    .context(concat!(
+                        "In upgrade_keyblob_if_required_with: ",
+                        "Failed to insert upgraded blob into the database.",
+                    ))
+                })?;
+                match f(&upgraded_blob) {
+                    Ok(v) => Ok((v, Some(upgraded_blob))),
+                    Err(e) => Err(e).context(concat!(
+                        "In upgrade_keyblob_if_required_with: ",
+                        "Failed to perform operation on second try."
+                    )),
+                }
+            }
+            Err(e) => {
+                Err(e).context("In upgrade_keyblob_if_required_with: Failed perform operation.")
+            }
+            Ok(v) => Ok((v, None)),
+        }
     }
 }
 
diff --git a/keystore2/src/service.rs b/keystore2/src/service.rs
index 82954ca..71aecbd 100644
--- a/keystore2/src/service.rs
+++ b/keystore2/src/service.rs
@@ -18,18 +18,20 @@
 //! This crate implement the core Keystore 2.0 service API as defined by the Keystore 2.0
 //! AIDL spec.
 
-use crate::database::{KeyEntry, KeyEntryLoadBits, SubComponentType};
+use crate::database::{KeyEntryLoadBits, SubComponentType};
 use crate::error::{self, map_or_log_err, ErrorCode};
 use crate::globals::DB;
 use crate::permission;
 use crate::permission::KeyPerm;
 use crate::security_level::KeystoreSecurityLevel;
-use crate::utils::{check_grant_permission, check_key_permission, Asp};
+use crate::utils::{
+    check_grant_permission, check_key_permission, key_parameters_to_authorizations, Asp,
+};
+use android_hardware_keymint::aidl::android::hardware::keymint::SecurityLevel::SecurityLevel;
 use android_system_keystore2::aidl::android::system::keystore2::{
     Domain::Domain, IKeystoreSecurityLevel::IKeystoreSecurityLevel,
     IKeystoreService::BnKeystoreService, IKeystoreService::IKeystoreService,
     KeyDescriptor::KeyDescriptor, KeyEntryResponse::KeyEntryResponse, KeyMetadata::KeyMetadata,
-    SecurityLevel::SecurityLevel,
 };
 use anyhow::{anyhow, Context, Result};
 use binder::{IBinder, Interface, ThreadState};
@@ -68,7 +70,7 @@
     }
 
     fn get_key_entry(&self, key: &KeyDescriptor) -> Result<KeyEntryResponse> {
-        let mut key_entry: KeyEntry = DB
+        let (key_id_guard, mut key_entry) = DB
             .with(|db| {
                 db.borrow_mut().load_key_entry(
                     key.clone(),
@@ -92,13 +94,13 @@
             metadata: KeyMetadata {
                 key: KeyDescriptor {
                     domain: Domain::KEY_ID,
-                    nspace: key_entry.id(),
+                    nspace: key_id_guard.id(),
                     ..Default::default()
                 },
                 keySecurityLevel: key_entry.sec_level(),
                 certificate: key_entry.take_cert(),
                 certificateChain: key_entry.take_cert_chain(),
-                // TODO add key characteristics here.
+                authorizations: key_parameters_to_authorizations(key_entry.into_key_parameters()),
                 ..Default::default()
             },
         })
@@ -112,7 +114,7 @@
     ) -> Result<()> {
         DB.with::<_, Result<()>>(|db| {
             let mut db = db.borrow_mut();
-            let key_entry = db
+            let (key_id_guard, key_entry) = db
                 .load_key_entry(
                     key.clone(),
                     KeyEntryLoadBits::NONE,
@@ -125,13 +127,13 @@
                 .context("Failed to load key_entry.")?;
 
             if let Some(cert) = public_cert {
-                db.insert_blob(key_entry.id(), SubComponentType::CERT, cert, key_entry.sec_level())
+                db.insert_blob(&key_id_guard, SubComponentType::CERT, cert, key_entry.sec_level())
                     .context("Failed to update cert subcomponent.")?;
             }
 
             if let Some(cert_chain) = certificate_chain {
                 db.insert_blob(
-                    key_entry.id(),
+                    &key_id_guard,
                     SubComponentType::CERT_CHAIN,
                     cert_chain,
                     key_entry.sec_level(),
@@ -193,7 +195,7 @@
         &self,
         security_level: SecurityLevel,
     ) -> binder::public_api::Result<Box<dyn IKeystoreSecurityLevel>> {
-        map_or_log_err(self.get_security_level(security_level), Ok)
+        map_or_log_err(self.get_security_level(SecurityLevel(security_level.0)), Ok)
     }
     fn getKeyEntry(&self, key: &KeyDescriptor) -> binder::public_api::Result<KeyEntryResponse> {
         map_or_log_err(self.get_key_entry(key), Ok)
diff --git a/keystore2/src/utils.rs b/keystore2/src/utils.rs
index 27044dd..1c678c3 100644
--- a/keystore2/src/utils.rs
+++ b/keystore2/src/utils.rs
@@ -15,14 +15,14 @@
 //! This module implements utility functions used by the Keystore 2.0 service
 //! implementation.
 
-use crate::error::Error;
 use crate::permission;
 use crate::permission::{KeyPerm, KeyPermSet, KeystorePerm};
+use crate::{error::Error, key_parameter::KeyParameterValue};
 use android_hardware_keymint::aidl::android::hardware::keymint::{
-    KeyParameter::KeyParameter as KmParam, Tag::Tag,
+    KeyCharacteristics::KeyCharacteristics, SecurityLevel::SecurityLevel,
 };
 use android_system_keystore2::aidl::android::system::keystore2::{
-    KeyDescriptor::KeyDescriptor, KeyParameter::KeyParameter,
+    Authorization::Authorization, KeyDescriptor::KeyDescriptor,
 };
 use anyhow::{anyhow, Context};
 use binder::{FromIBinder, SpIBinder, ThreadState};
@@ -77,42 +77,6 @@
     })
 }
 
-/// This function converts a `KeyParameter` from the keystore2 AIDL
-/// bindings into a `KeyParameter` from the keymint AIDL bindings.
-/// TODO This is a temporary workaround until the keymint AIDL spec
-/// lands.
-pub fn keyparam_ks_to_km(p: &KeyParameter) -> KmParam {
-    KmParam {
-        tag: Tag(p.tag),
-        boolValue: p.boolValue,
-        integer: p.integer,
-        longInteger: p.longInteger,
-        dateTime: p.dateTime,
-        blob: match &p.blob {
-            Some(b) => b.clone(),
-            None => vec![],
-        },
-    }
-}
-
-/// This function converts a `KeyParameter` from the keymint AIDL
-/// bindings into a `KeyParameter` from the keystore2 AIDL bindings.
-/// TODO This is a temporary workaround until the keymint AIDL spec
-/// lands.
-pub fn keyparam_km_to_ks(p: &KmParam) -> KeyParameter {
-    KeyParameter {
-        tag: p.tag.0,
-        boolValue: p.boolValue,
-        integer: p.integer,
-        longInteger: p.longInteger,
-        dateTime: p.dateTime,
-        blob: match p.blob.len() {
-            0 => None,
-            _ => Some(p.blob.clone()),
-        },
-    }
-}
-
 /// Thread safe wrapper around SpIBinder. It is safe to have SpIBinder smart pointers to the
 /// same object in multiple threads, but cloning a SpIBinder is not thread safe.
 /// Keystore frequently hands out binder tokens to the security level interface. If this
@@ -138,3 +102,37 @@
             .map_err(|e| anyhow!(format!("get_interface failed with error code {:?}", e)))
     }
 }
+
+/// Converts a set of key characteristics as returned from KeyMint into the internal
+/// representation of the keystore service.
+/// The parameter `hw_security_level` indicates which security level shall be used for
+/// parameters found in the hardware enforced parameter list.
+pub fn key_characteristics_to_internal(
+    key_characteristics: KeyCharacteristics,
+    hw_security_level: SecurityLevel,
+) -> Vec<crate::key_parameter::KeyParameter> {
+    key_characteristics
+        .hardwareEnforced
+        .into_iter()
+        .map(|aidl_kp| {
+            crate::key_parameter::KeyParameter::new(
+                KeyParameterValue::convert_from_wire(aidl_kp),
+                hw_security_level,
+            )
+        })
+        .chain(key_characteristics.softwareEnforced.into_iter().map(|aidl_kp| {
+            crate::key_parameter::KeyParameter::new(
+                KeyParameterValue::convert_from_wire(aidl_kp),
+                SecurityLevel::SOFTWARE,
+            )
+        }))
+        .collect()
+}
+
+/// Converts a set of key characteristics from the internal representation into a set of
+/// Authorizations as they are used to convey key characteristics to the clients of keystore.
+pub fn key_parameters_to_authorizations(
+    parameters: Vec<crate::key_parameter::KeyParameter>,
+) -> Vec<Authorization> {
+    parameters.into_iter().map(|p| p.into_authorization()).collect()
+}