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(
- ¶ms,
- &[],
- // TODO HardwareAuthtoken missing
- &Default::default(),
+ Some(¶ms),
+ 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(
- ¶ms.iter().map(|p| keyparam_ks_to_km(p)).collect::<Vec<KmParam>>(),
+ ¶ms,
&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(
- ¶ms.iter().map(|p| keyparam_ks_to_km(p)).collect::<Vec<KmParam>>(),
+ ¶ms,
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,
- ¶ms.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,
+ ¶ms,
+ 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()
+}