Merge "Route ECDH key import requests to Soft-KeyMint."
diff --git a/fsverity/fsverity_manifest_generator.py b/fsverity/fsverity_manifest_generator.py
index 79be591..181758a 100644
--- a/fsverity/fsverity_manifest_generator.py
+++ b/fsverity/fsverity_manifest_generator.py
@@ -50,7 +50,7 @@
       required=True)
   p.add_argument(
       'inputs',
-      nargs='+',
+      nargs='*',
       help='input file for the build manifest')
   args = p.parse_args(sys.argv[1:])
 
diff --git a/identity/Android.bp b/identity/Android.bp
index 4e4b79a..9117b7f 100644
--- a/identity/Android.bp
+++ b/identity/Android.bp
@@ -59,6 +59,7 @@
         "libutilscallstack",
     ],
     static_libs: [
+        "android.hardware.security.rkp-V3-cpp",
         "android.hardware.keymaster-V3-cpp",
         "libcppbor_external",
     ],
diff --git a/keystore2/Android.bp b/keystore2/Android.bp
index 0e5afd9..51ce9d1 100644
--- a/keystore2/Android.bp
+++ b/keystore2/Android.bp
@@ -31,6 +31,7 @@
     ],
 
     rustlibs: [
+        "android.hardware.security.rkp-V3-rust",
         "android.hardware.security.secureclock-V1-rust",
         "android.hardware.security.sharedsecret-V1-rust",
         "android.os.permissions_aidl-rust",
@@ -84,6 +85,7 @@
         "keystore2_use_latest_aidl_rust",
     ],
     rustlibs: [
+        "android.hardware.security.rkp-V3-rust",
         "libbinder_rs",
         "libkeystore2_selinux",
         "liblog_rust",
@@ -121,6 +123,7 @@
     auto_gen_config: true,
     compile_multilib: "first",
     rustlibs: [
+        "android.hardware.security.rkp-V3-rust",
         "libbinder_rs",
         "libkeystore2_selinux",
         "liblog_rust",
diff --git a/keystore2/aidl/Android.bp b/keystore2/aidl/Android.bp
index 8ea227b..1e6d4dc 100644
--- a/keystore2/aidl/Android.bp
+++ b/keystore2/aidl/Android.bp
@@ -107,6 +107,7 @@
     srcs: [ "android/security/remoteprovisioning/*.aidl" ],
     imports: [
         "android.hardware.security.keymint-V3",
+        "android.hardware.security.rkp-V3",
     ],
     unstable: true,
     backend: {
diff --git a/keystore2/src/globals.rs b/keystore2/src/globals.rs
index c617240..425812f 100644
--- a/keystore2/src/globals.rs
+++ b/keystore2/src/globals.rs
@@ -31,9 +31,10 @@
 use crate::km_compat::{KeyMintV1, BacklevelKeyMintWrapper};
 use crate::{enforcements::Enforcements, error::map_km_error};
 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
-    IKeyMintDevice::IKeyMintDevice, IRemotelyProvisionedComponent::IRemotelyProvisionedComponent,
-    KeyMintHardwareInfo::KeyMintHardwareInfo, SecurityLevel::SecurityLevel,
+    IKeyMintDevice::IKeyMintDevice, KeyMintHardwareInfo::KeyMintHardwareInfo,
+    SecurityLevel::SecurityLevel,
 };
+use android_hardware_security_rkp::aidl::android::hardware::security::keymint::IRemotelyProvisionedComponent::IRemotelyProvisionedComponent;
 use android_hardware_security_secureclock::aidl::android::hardware::security::secureclock::{
     ISecureClock::ISecureClock,
 };
diff --git a/keystore2/src/km_compat/km_compat_type_conversion.h b/keystore2/src/km_compat/km_compat_type_conversion.h
index 33248a4..5db7e3d 100644
--- a/keystore2/src/km_compat/km_compat_type_conversion.h
+++ b/keystore2/src/km_compat/km_compat_type_conversion.h
@@ -750,6 +750,7 @@
     case KMV1::Tag::CERTIFICATE_SUBJECT:
     case KMV1::Tag::CERTIFICATE_NOT_BEFORE:
     case KMV1::Tag::CERTIFICATE_NOT_AFTER:
+    case KMV1::Tag::ATTESTATION_ID_SECOND_IMEI:
         // These tags do not exist in KM < KeyMint 1.0.
         break;
     case KMV1::Tag::MAX_BOOT_LEVEL:
diff --git a/keystore2/src/remote_provisioning.rs b/keystore2/src/remote_provisioning.rs
index 00fb572..fec1b92 100644
--- a/keystore2/src/remote_provisioning.rs
+++ b/keystore2/src/remote_provisioning.rs
@@ -23,11 +23,13 @@
 
 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
     Algorithm::Algorithm, AttestationKey::AttestationKey, Certificate::Certificate,
-    DeviceInfo::DeviceInfo, IRemotelyProvisionedComponent::IRemotelyProvisionedComponent,
-    KeyParameter::KeyParameter, KeyParameterValue::KeyParameterValue,
-    MacedPublicKey::MacedPublicKey, ProtectedData::ProtectedData, SecurityLevel::SecurityLevel,
+    KeyParameter::KeyParameter, KeyParameterValue::KeyParameterValue, SecurityLevel::SecurityLevel,
     Tag::Tag,
 };
+use android_hardware_security_rkp::aidl::android::hardware::security::keymint::{
+    DeviceInfo::DeviceInfo, IRemotelyProvisionedComponent::IRemotelyProvisionedComponent,
+    MacedPublicKey::MacedPublicKey, ProtectedData::ProtectedData,
+};
 use android_security_remoteprovisioning::aidl::android::security::remoteprovisioning::{
     AttestationPoolStatus::AttestationPoolStatus, IRemoteProvisioning::BnRemoteProvisioning,
     IRemoteProvisioning::IRemoteProvisioning,
@@ -692,7 +694,7 @@
     use serde_cbor::Value;
     use std::collections::BTreeMap;
     use std::sync::{Arc, Mutex};
-    use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
+    use android_hardware_security_rkp::aidl::android::hardware::security::keymint::{
         RpcHardwareInfo::RpcHardwareInfo,
     };
 
diff --git a/keystore2/test_utils/key_generations.rs b/keystore2/test_utils/key_generations.rs
index 07cb3f9..175d8bb 100644
--- a/keystore2/test_utils/key_generations.rs
+++ b/keystore2/test_utils/key_generations.rs
@@ -18,11 +18,13 @@
 
 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
     Algorithm::Algorithm, BlockMode::BlockMode, Digest::Digest, EcCurve::EcCurve,
-    ErrorCode::ErrorCode, KeyPurpose::KeyPurpose, PaddingMode::PaddingMode,
+    ErrorCode::ErrorCode, KeyOrigin::KeyOrigin, KeyParameter::KeyParameter,
+    KeyParameterValue::KeyParameterValue, KeyPurpose::KeyPurpose, PaddingMode::PaddingMode,
+    Tag::Tag,
 };
 use android_system_keystore2::aidl::android::system::keystore2::{
-    Domain::Domain, IKeystoreSecurityLevel::IKeystoreSecurityLevel, KeyDescriptor::KeyDescriptor,
-    KeyMetadata::KeyMetadata, ResponseCode::ResponseCode,
+    Authorization::Authorization, Domain::Domain, IKeystoreSecurityLevel::IKeystoreSecurityLevel,
+    KeyDescriptor::KeyDescriptor, KeyMetadata::KeyMetadata, ResponseCode::ResponseCode,
 };
 
 use crate::authorizations::AuthSetBuilder;
@@ -59,6 +61,102 @@
     pub att_app_id: Option<Vec<u8>>,
 }
 
+/// DER-encoded PKCS#8 format RSA key. Generated using:
+/// openssl genrsa 2048 | openssl pkcs8 -topk8 -nocrypt -outform der | hexdump -e '30/1  "%02X" "\n"'
+pub static RSA_2048_KEY: &[u8] = &[
+    0x30, 0x82, 0x04, 0xBD, 0x02, 0x01, 0x00, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7,
+    0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x04, 0xA7, 0x30, 0x82, 0x04, 0xA3, 0x02, 0x01,
+    0x00, 0x02, 0x82, 0x01, 0x01, 0x00, 0xE5, 0x14, 0xE3, 0xC2, 0x43, 0xF3, 0x0F, 0xCC, 0x22, 0x73,
+    0x9C, 0x84, 0xCC, 0x1B, 0x6C, 0x97, 0x4B, 0xC9, 0xDF, 0x1F, 0xE2, 0xB8, 0x80, 0x85, 0xF9, 0x27,
+    0xAB, 0x97, 0x94, 0x58, 0x4B, 0xC9, 0x40, 0x94, 0x5A, 0xB4, 0xD4, 0xF8, 0xD0, 0x36, 0xC4, 0x86,
+    0x17, 0x7D, 0xA2, 0x48, 0x6D, 0x40, 0xF0, 0xB9, 0x61, 0x4F, 0xCE, 0x65, 0x80, 0x88, 0x81, 0x59,
+    0x95, 0x11, 0x24, 0xF4, 0x36, 0xB7, 0xB7, 0x37, 0x44, 0xF4, 0x6C, 0x1C, 0xEB, 0x04, 0x19, 0x78,
+    0xB2, 0x29, 0x4D, 0x21, 0x44, 0x16, 0x57, 0x58, 0x6D, 0x7D, 0x56, 0xB5, 0x99, 0xDD, 0xD2, 0xAD,
+    0x02, 0x9A, 0x72, 0x16, 0x67, 0xD6, 0x00, 0x9F, 0x69, 0xE0, 0x25, 0xEE, 0x7C, 0x86, 0x54, 0x27,
+    0x4B, 0x50, 0xEF, 0x60, 0x52, 0x60, 0x82, 0xAA, 0x09, 0x15, 0x72, 0xD2, 0xEB, 0x01, 0x52, 0x04,
+    0x39, 0x60, 0xBC, 0x5E, 0x95, 0x07, 0xC8, 0xC2, 0x3A, 0x3A, 0xE2, 0xA4, 0x99, 0x6B, 0x27, 0xE3,
+    0xA3, 0x55, 0x69, 0xC4, 0xB3, 0x2D, 0x19, 0xC4, 0x34, 0x76, 0xFC, 0x27, 0xDA, 0x22, 0xB2, 0x62,
+    0x69, 0x25, 0xDE, 0x0D, 0xE7, 0x54, 0x3C, 0xBB, 0x61, 0xD2, 0x20, 0xDA, 0x7B, 0x6E, 0x63, 0xBD,
+    0x9A, 0x4B, 0xCD, 0x75, 0xC6, 0xA1, 0x5E, 0x1C, 0x3E, 0xD5, 0x63, 0x59, 0x22, 0x7E, 0xE0, 0x6C,
+    0x98, 0x25, 0x63, 0x97, 0x56, 0xDF, 0x71, 0xF5, 0x4C, 0x78, 0xE9, 0xE1, 0xD5, 0xFC, 0xF8, 0x5A,
+    0x5B, 0xF6, 0x1D, 0xFA, 0x5A, 0x99, 0x4C, 0x99, 0x19, 0x21, 0x1D, 0xF5, 0x24, 0x07, 0xEF, 0x8A,
+    0xC9, 0x9F, 0xE7, 0x3F, 0xBB, 0x46, 0x1A, 0x16, 0x96, 0xC6, 0xD6, 0x12, 0x7E, 0xDA, 0xCB, 0xEB,
+    0x2F, 0x1D, 0x3B, 0x31, 0xCC, 0x55, 0x63, 0xA2, 0x6F, 0x8A, 0xDE, 0x35, 0x52, 0x40, 0x04, 0xBF,
+    0xE0, 0x82, 0x32, 0xE1, 0x6D, 0x8B, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, 0x00, 0x2D,
+    0x1F, 0x71, 0x41, 0x79, 0xBA, 0xED, 0xD8, 0xAA, 0xCC, 0x94, 0xFE, 0xFF, 0x69, 0x43, 0x79, 0x85,
+    0xBF, 0x2C, 0xC9, 0x0E, 0x12, 0x83, 0x96, 0x60, 0x1E, 0x75, 0x49, 0x35, 0x3A, 0x33, 0x2B, 0x60,
+    0x22, 0x18, 0xBF, 0xD7, 0xD7, 0x6E, 0xC3, 0xEA, 0xEF, 0xF2, 0xBE, 0x97, 0x71, 0xA6, 0xBB, 0x8C,
+    0xEF, 0x27, 0x00, 0xDE, 0x49, 0xD6, 0x08, 0x8D, 0x5A, 0x04, 0xE7, 0xCC, 0x9C, 0xA2, 0x0E, 0x8B,
+    0xF3, 0x42, 0x0C, 0xD7, 0x22, 0xD7, 0x14, 0x06, 0xA4, 0x64, 0x8B, 0x88, 0x1A, 0xCE, 0x5B, 0x8C,
+    0x36, 0xE9, 0xD2, 0x2F, 0x7B, 0x33, 0xE4, 0xA2, 0xB3, 0xDB, 0x78, 0x6A, 0x92, 0x89, 0x3F, 0x78,
+    0xFD, 0xED, 0x8F, 0xEE, 0x48, 0xCC, 0x94, 0x75, 0x0D, 0x0C, 0x63, 0xD3, 0xD2, 0xE8, 0x47, 0x04,
+    0x55, 0xD3, 0xD6, 0x3A, 0xB8, 0xDA, 0xFB, 0x76, 0x99, 0x48, 0x68, 0x0A, 0x92, 0xA2, 0xCD, 0xF7,
+    0x45, 0x8B, 0x50, 0xFE, 0xF9, 0x1A, 0x33, 0x24, 0x3C, 0x2E, 0xDE, 0x88, 0xAD, 0xB2, 0x5B, 0x9F,
+    0x44, 0xEA, 0xD1, 0x9F, 0xC7, 0x9F, 0x02, 0x5E, 0x31, 0x61, 0xB3, 0xD6, 0xE2, 0xE1, 0xBC, 0xFB,
+    0x1C, 0xDB, 0xBD, 0xB2, 0x9A, 0xE5, 0xEF, 0xDA, 0xCD, 0x29, 0xA5, 0x45, 0xCC, 0x67, 0x01, 0x8B,
+    0x1C, 0x1D, 0x0E, 0x8F, 0x73, 0x69, 0x4D, 0x4D, 0xF6, 0x9D, 0xA6, 0x6C, 0x9A, 0x1C, 0xF4, 0x5C,
+    0xE4, 0x83, 0x9A, 0x77, 0x12, 0x01, 0xBD, 0xCE, 0x66, 0x3A, 0x4B, 0x3D, 0x6E, 0xE0, 0x6E, 0x82,
+    0x98, 0xDE, 0x74, 0x11, 0x47, 0xEC, 0x7A, 0x3A, 0xA9, 0xD8, 0x48, 0x00, 0x26, 0x64, 0x47, 0x7B,
+    0xAE, 0x55, 0x9D, 0x29, 0x22, 0xB4, 0xB3, 0xB9, 0xB1, 0x64, 0xEA, 0x3B, 0x5A, 0xD3, 0x3F, 0x8D,
+    0x0F, 0x14, 0x7E, 0x4E, 0xB8, 0x1B, 0x06, 0xFC, 0xB1, 0x7E, 0xCD, 0xB9, 0x1A, 0x4E, 0xA1, 0x02,
+    0x81, 0x81, 0x00, 0xF9, 0xDE, 0xEE, 0xED, 0x13, 0x2F, 0xBB, 0xE7, 0xE2, 0xB3, 0x2D, 0x98, 0xD2,
+    0xE8, 0x25, 0x07, 0x5A, 0x1E, 0x51, 0x0A, 0xC8, 0xAD, 0x50, 0x4B, 0x80, 0xC6, 0x22, 0xF5, 0x9B,
+    0x08, 0xE6, 0x3D, 0x01, 0xC6, 0x3E, 0xC8, 0xD2, 0x54, 0x9F, 0x91, 0x77, 0x95, 0xCD, 0xCA, 0xC7,
+    0xE7, 0x47, 0x94, 0xA9, 0x5F, 0x4E, 0xBE, 0x31, 0x3D, 0xB4, 0xAF, 0x43, 0x0F, 0xDC, 0x8D, 0x9C,
+    0x1E, 0x52, 0x7B, 0x72, 0x21, 0x34, 0xB3, 0x96, 0x7C, 0x9C, 0xB8, 0x51, 0x65, 0x60, 0xAC, 0x3D,
+    0x11, 0x32, 0xB8, 0xD6, 0x34, 0x35, 0x66, 0xD0, 0x30, 0xB9, 0xE9, 0x67, 0x2C, 0x87, 0x73, 0x43,
+    0x9C, 0x12, 0x16, 0x7D, 0x4A, 0xD9, 0xA3, 0x4C, 0x24, 0x64, 0x6A, 0x32, 0x8E, 0xC3, 0xD8, 0x00,
+    0x90, 0x5C, 0x4D, 0x65, 0x01, 0x53, 0x8A, 0xD0, 0x87, 0xCE, 0x96, 0xEF, 0xFA, 0x73, 0x03, 0xF1,
+    0xDC, 0x1B, 0x9B, 0x02, 0x81, 0x81, 0x00, 0xEA, 0xB3, 0x69, 0x00, 0x11, 0x0E, 0x50, 0xAA, 0xD3,
+    0x22, 0x51, 0x78, 0x9D, 0xFF, 0x05, 0x62, 0xBC, 0x9A, 0x67, 0x86, 0xE1, 0xC5, 0x02, 0x2D, 0x14,
+    0x11, 0x29, 0x30, 0xE7, 0x90, 0x5D, 0x72, 0x6F, 0xC5, 0x62, 0xEB, 0xD4, 0xB0, 0x3F, 0x3D, 0xDC,
+    0xB9, 0xFC, 0x2B, 0x5C, 0xBD, 0x9E, 0x71, 0x81, 0x5C, 0xC5, 0xFE, 0xDF, 0x69, 0x73, 0x12, 0x66,
+    0x92, 0x06, 0xD4, 0xD5, 0x8F, 0xDF, 0x14, 0x2E, 0x9C, 0xD0, 0x4C, 0xC2, 0x4D, 0x31, 0x2E, 0x47,
+    0xA5, 0xDC, 0x8A, 0x83, 0x7B, 0xE8, 0xA5, 0xC3, 0x03, 0x98, 0xD8, 0xBF, 0xF4, 0x7D, 0x6E, 0x87,
+    0x55, 0xE4, 0x0F, 0x15, 0x10, 0xC8, 0x76, 0x4F, 0xAD, 0x1D, 0x1C, 0x95, 0x41, 0x9D, 0x88, 0xEC,
+    0x8C, 0xDA, 0xBA, 0x90, 0x7F, 0x8D, 0xD9, 0x8B, 0x47, 0x6C, 0x0C, 0xFF, 0xBA, 0x73, 0x00, 0x20,
+    0x1F, 0xF7, 0x7E, 0x5F, 0xF4, 0xEC, 0xD1, 0x02, 0x81, 0x80, 0x16, 0xB7, 0x43, 0xB5, 0x5D, 0xD7,
+    0x2B, 0x18, 0x0B, 0xAE, 0x0A, 0x69, 0x28, 0x53, 0x5E, 0x7A, 0x6A, 0xA0, 0xF2, 0xF1, 0x2E, 0x09,
+    0x43, 0x91, 0x79, 0xA5, 0x89, 0xAC, 0x16, 0x6A, 0x1A, 0xB4, 0x55, 0x22, 0xF6, 0xB6, 0x3F, 0x18,
+    0xDE, 0x60, 0xD5, 0x24, 0x53, 0x4F, 0x2A, 0x19, 0x46, 0x92, 0xA7, 0x4B, 0x38, 0xD7, 0x65, 0x96,
+    0x9C, 0x84, 0x8A, 0x6E, 0x38, 0xB8, 0xCF, 0x06, 0x9A, 0xAD, 0x0A, 0x55, 0x26, 0x7B, 0x65, 0x24,
+    0xF3, 0x02, 0x76, 0xB3, 0xE6, 0xB4, 0x01, 0xE1, 0x3C, 0x61, 0x3D, 0x68, 0x05, 0xAA, 0xD1, 0x26,
+    0x7C, 0xE0, 0x51, 0x36, 0xE5, 0x21, 0x7F, 0x76, 0x02, 0xD6, 0xF4, 0x91, 0x07, 0x74, 0x27, 0x09,
+    0xEF, 0xEF, 0x0F, 0xA5, 0x96, 0xFC, 0x5E, 0x20, 0xC1, 0xA3, 0x6F, 0x99, 0x4D, 0x45, 0x03, 0x6C,
+    0x35, 0x45, 0xD7, 0x8F, 0x47, 0x41, 0x86, 0x8D, 0x62, 0x1D, 0x02, 0x81, 0x81, 0x00, 0xC3, 0x93,
+    0x85, 0xA7, 0xFC, 0x8E, 0x85, 0x42, 0x14, 0x76, 0xC0, 0x95, 0x56, 0x73, 0xB0, 0xB5, 0x3A, 0x9D,
+    0x20, 0x30, 0x11, 0xEA, 0xED, 0x89, 0x4A, 0xF3, 0x91, 0xF3, 0xA2, 0xC3, 0x76, 0x5B, 0x6A, 0x30,
+    0x7D, 0xE2, 0x2F, 0x76, 0x3E, 0xFC, 0xF9, 0xF6, 0x31, 0xE0, 0xA0, 0x83, 0x92, 0x88, 0xDB, 0x57,
+    0xC7, 0xD6, 0x3F, 0xAD, 0xCB, 0xAA, 0x45, 0xB6, 0xE1, 0xE2, 0x71, 0xA4, 0x56, 0x2C, 0xA7, 0x3B,
+    0x1D, 0x89, 0x19, 0x50, 0xE1, 0xEE, 0xC2, 0xDD, 0xC0, 0x0D, 0xDC, 0xCB, 0x60, 0x6E, 0xE1, 0x37,
+    0x1A, 0x23, 0x64, 0xB2, 0x03, 0xE4, 0x1A, 0xFA, 0xC3, 0xF4, 0x9D, 0x85, 0x42, 0xC6, 0xF4, 0x56,
+    0x39, 0xB0, 0x1B, 0xE0, 0x75, 0xBA, 0x28, 0x04, 0xA8, 0x30, 0x57, 0x41, 0x33, 0x9F, 0x58, 0xA4,
+    0xC7, 0xB1, 0x7D, 0x58, 0x8D, 0x84, 0x49, 0x40, 0xDA, 0x28, 0x81, 0x25, 0xC4, 0x41, 0x02, 0x81,
+    0x80, 0x13, 0x20, 0x65, 0xD5, 0x96, 0x98, 0x8D, 0x16, 0x73, 0xA1, 0x31, 0x73, 0x79, 0xBA, 0xEC,
+    0xB0, 0xD9, 0x0C, 0xF6, 0xEF, 0x2F, 0xC2, 0xE7, 0x96, 0x9B, 0xA1, 0x2D, 0xE9, 0xFB, 0x45, 0xB9,
+    0xD0, 0x30, 0xE2, 0xBD, 0x30, 0x4F, 0xB6, 0xFE, 0x24, 0x02, 0xCF, 0x8D, 0x51, 0x48, 0x45, 0xD9,
+    0xF7, 0x20, 0x53, 0x1C, 0x0B, 0xA9, 0x7E, 0xC2, 0xA2, 0x65, 0xCC, 0x3E, 0x0E, 0x0D, 0xF1, 0x62,
+    0xDD, 0x5F, 0xBC, 0x55, 0x9B, 0x58, 0x26, 0x40, 0x6A, 0xEE, 0x02, 0x55, 0x36, 0xE9, 0xBA, 0x82,
+    0x5A, 0xFD, 0x3C, 0xDF, 0xA6, 0x26, 0x32, 0x81, 0xA9, 0x5E, 0x46, 0xBE, 0xBA, 0xDC, 0xD3, 0x2A,
+    0x3A, 0x3B, 0xC1, 0x4E, 0xF7, 0x1A, 0xDC, 0x4B, 0xAF, 0x67, 0x1B, 0x3A, 0x83, 0x0D, 0x04, 0xDE,
+    0x27, 0x47, 0xFC, 0xE6, 0x39, 0x89, 0x7B, 0x66, 0xF9, 0x50, 0x4D, 0xF1, 0xAC, 0x20, 0x43, 0x7E,
+    0xEE,
+];
+
+/// DER-encoded PKCS#8 format EC key. Generated using:
+/// openssl ecparam -name prime256v1 -genkey | openssl pkcs8 -topk8 -nocrypt -outform der | hexdump -e '30/1  "%02X" "\n"'
+pub static EC_P_256_KEY: &[u8] = &[
+    0x30, 0x81, 0x87, 0x02, 0x01, 0x00, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02,
+    0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x04, 0x6D, 0x30, 0x6B, 0x02,
+    0x01, 0x01, 0x04, 0x20, 0xB9, 0x1D, 0xAF, 0x50, 0xFD, 0xD8, 0x6A, 0x40, 0xAB, 0x2C, 0xCB, 0x54,
+    0x4E, 0xED, 0xF1, 0x64, 0xBC, 0x30, 0x25, 0xFB, 0xC4, 0x69, 0x00, 0x34, 0x1A, 0x82, 0xA3, 0x72,
+    0x5D, 0xC7, 0xA9, 0x85, 0xA1, 0x44, 0x03, 0x42, 0x00, 0x04, 0xE8, 0x53, 0x0A, 0xF2, 0xD3, 0x68,
+    0x40, 0x48, 0x8C, 0xB4, 0x2F, 0x11, 0x34, 0xD7, 0xF4, 0x4A, 0x5C, 0x33, 0xFF, 0xF6, 0x2B, 0xF7,
+    0x98, 0x0F, 0x02, 0xA5, 0xD7, 0x4F, 0xF9, 0xDE, 0x60, 0x9C, 0x6E, 0xB0, 0x45, 0xDA, 0x3F, 0xF4,
+    0x34, 0x23, 0x9B, 0x4C, 0x3A, 0x09, 0x9C, 0x5E, 0x5D, 0x37, 0x96, 0xAC, 0x4A, 0xE7, 0x65, 0x2B,
+    0xD6, 0x84, 0x98, 0xEA, 0x96, 0x91, 0xFB, 0x78, 0xED, 0x86,
+];
+
 /// To map Keystore errors.
 #[derive(thiserror::Error, Debug, Eq, PartialEq)]
 pub enum Error {
@@ -465,3 +563,276 @@
 
     Ok(ec_key_metadata)
 }
+
+fn check_key_param(authorizations: &[Authorization], key_param: KeyParameter) -> bool {
+    for authrization in authorizations {
+        if authrization.keyParameter == key_param {
+            return true;
+        }
+    }
+
+    false
+}
+
+/// Imports above defined RSA key - `RSA_2048_KEY` and validates imported key parameters.
+pub fn import_rsa_2048_key(
+    sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>,
+    domain: Domain,
+    nspace: i64,
+    alias: Option<String>,
+    import_params: AuthSetBuilder,
+) -> binder::Result<KeyMetadata> {
+    let key_metadata = sec_level
+        .importKey(
+            &KeyDescriptor { domain, nspace, alias, blob: None },
+            None,
+            &import_params,
+            0,
+            RSA_2048_KEY,
+        )
+        .unwrap();
+
+    assert!(key_metadata.certificate.is_some());
+    assert!(key_metadata.certificateChain.is_none());
+
+    assert!(check_key_param(
+        &key_metadata.authorizations,
+        KeyParameter { tag: Tag::ALGORITHM, value: KeyParameterValue::Algorithm(Algorithm::RSA) }
+    ));
+
+    assert!(check_key_param(
+        &key_metadata.authorizations,
+        KeyParameter { tag: Tag::KEY_SIZE, value: KeyParameterValue::Integer(2048) }
+    ));
+
+    assert!(check_key_param(
+        &key_metadata.authorizations,
+        KeyParameter { tag: Tag::DIGEST, value: KeyParameterValue::Digest(Digest::SHA_2_256) }
+    ));
+
+    assert!(check_key_param(
+        &key_metadata.authorizations,
+        KeyParameter {
+            tag: Tag::RSA_PUBLIC_EXPONENT,
+            value: KeyParameterValue::LongInteger(65537)
+        }
+    ));
+
+    assert!(check_key_param(
+        &key_metadata.authorizations,
+        KeyParameter {
+            tag: Tag::PADDING,
+            value: KeyParameterValue::PaddingMode(PaddingMode::RSA_PSS)
+        }
+    ));
+
+    assert!(check_key_param(
+        &key_metadata.authorizations,
+        KeyParameter { tag: Tag::ORIGIN, value: KeyParameterValue::Origin(KeyOrigin::IMPORTED) }
+    ));
+
+    Ok(key_metadata)
+}
+
+/// Imports above defined EC key - `EC_P_256_KEY` and validates imported key parameters.
+pub fn import_ec_p_256_key(
+    sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>,
+    domain: Domain,
+    nspace: i64,
+    alias: Option<String>,
+    import_params: AuthSetBuilder,
+) -> binder::Result<KeyMetadata> {
+    let key_metadata = sec_level
+        .importKey(
+            &KeyDescriptor { domain, nspace, alias, blob: None },
+            None,
+            &import_params,
+            0,
+            EC_P_256_KEY,
+        )
+        .unwrap();
+
+    assert!(key_metadata.certificate.is_some());
+    assert!(key_metadata.certificateChain.is_none());
+
+    assert!(check_key_param(
+        &key_metadata.authorizations,
+        KeyParameter { tag: Tag::ALGORITHM, value: KeyParameterValue::Algorithm(Algorithm::EC) }
+    ));
+
+    assert!(check_key_param(
+        &key_metadata.authorizations,
+        KeyParameter { tag: Tag::EC_CURVE, value: KeyParameterValue::EcCurve(EcCurve::P_256) }
+    ));
+
+    assert!(check_key_param(
+        &key_metadata.authorizations,
+        KeyParameter { tag: Tag::DIGEST, value: KeyParameterValue::Digest(Digest::SHA_2_256) }
+    ));
+    assert!(check_key_param(
+        &key_metadata.authorizations,
+        KeyParameter { tag: Tag::ORIGIN, value: KeyParameterValue::Origin(KeyOrigin::IMPORTED) }
+    ));
+
+    Ok(key_metadata)
+}
+
+/// Import sample AES key and validate its key parameters.
+pub fn import_aes_key(
+    sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>,
+    domain: Domain,
+    nspace: i64,
+    alias: Option<String>,
+) -> binder::Result<KeyMetadata> {
+    static AES_KEY: &[u8] = &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+    let key_size = AES_KEY.len() * 8;
+
+    let import_params = AuthSetBuilder::new()
+        .no_auth_required()
+        .algorithm(Algorithm::AES)
+        .block_mode(BlockMode::ECB)
+        .key_size(key_size.try_into().unwrap())
+        .purpose(KeyPurpose::ENCRYPT)
+        .purpose(KeyPurpose::DECRYPT)
+        .padding_mode(PaddingMode::PKCS7);
+
+    let key_metadata = sec_level.importKey(
+        &KeyDescriptor { domain, nspace, alias, blob: None },
+        None,
+        &import_params,
+        0,
+        AES_KEY,
+    )?;
+
+    assert!(check_key_param(
+        &key_metadata.authorizations,
+        KeyParameter { tag: Tag::ALGORITHM, value: KeyParameterValue::Algorithm(Algorithm::AES) }
+    ));
+    assert!(check_key_param(
+        &key_metadata.authorizations,
+        KeyParameter { tag: Tag::KEY_SIZE, value: KeyParameterValue::Integer(128) }
+    ));
+    assert!(check_key_param(
+        &key_metadata.authorizations,
+        KeyParameter {
+            tag: Tag::PADDING,
+            value: KeyParameterValue::PaddingMode(PaddingMode::PKCS7)
+        }
+    ));
+    assert!(check_key_param(
+        &key_metadata.authorizations,
+        KeyParameter { tag: Tag::BLOCK_MODE, value: KeyParameterValue::BlockMode(BlockMode::ECB) }
+    ));
+    assert!(check_key_param(
+        &key_metadata.authorizations,
+        KeyParameter { tag: Tag::ORIGIN, value: KeyParameterValue::Origin(KeyOrigin::IMPORTED) }
+    ));
+
+    Ok(key_metadata)
+}
+
+/// Import sample 3DES key and validate its key parameters.
+pub fn import_3des_key(
+    sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>,
+    domain: Domain,
+    nspace: i64,
+    alias: Option<String>,
+) -> binder::Result<KeyMetadata> {
+    static TRIPLE_DES_KEY: &[u8] = &[
+        0xa4, 0x9d, 0x75, 0x64, 0x19, 0x9e, 0x97, 0xcb, 0x52, 0x9d, 0x2c, 0x9d, 0x97, 0xbf, 0x2f,
+        0x98, 0xd3, 0x5e, 0xdf, 0x57, 0xba, 0x1f, 0x73, 0x58,
+    ];
+
+    let import_params = AuthSetBuilder::new()
+        .no_auth_required()
+        .algorithm(Algorithm::TRIPLE_DES)
+        .block_mode(BlockMode::ECB)
+        .key_size(168)
+        .purpose(KeyPurpose::ENCRYPT)
+        .purpose(KeyPurpose::DECRYPT)
+        .padding_mode(PaddingMode::PKCS7);
+
+    let key_metadata = sec_level.importKey(
+        &KeyDescriptor { domain, nspace, alias, blob: None },
+        None,
+        &import_params,
+        0,
+        TRIPLE_DES_KEY,
+    )?;
+
+    assert!(check_key_param(
+        &key_metadata.authorizations,
+        KeyParameter {
+            tag: Tag::ALGORITHM,
+            value: KeyParameterValue::Algorithm(Algorithm::TRIPLE_DES)
+        }
+    ));
+    assert!(check_key_param(
+        &key_metadata.authorizations,
+        KeyParameter { tag: Tag::KEY_SIZE, value: KeyParameterValue::Integer(168) }
+    ));
+    assert!(check_key_param(
+        &key_metadata.authorizations,
+        KeyParameter {
+            tag: Tag::PADDING,
+            value: KeyParameterValue::PaddingMode(PaddingMode::PKCS7)
+        }
+    ));
+    assert!(check_key_param(
+        &key_metadata.authorizations,
+        KeyParameter { tag: Tag::BLOCK_MODE, value: KeyParameterValue::BlockMode(BlockMode::ECB) }
+    ));
+    assert!(check_key_param(
+        &key_metadata.authorizations,
+        KeyParameter { tag: Tag::ORIGIN, value: KeyParameterValue::Origin(KeyOrigin::IMPORTED) }
+    ));
+
+    Ok(key_metadata)
+}
+
+/// Import sample HMAC key and validate its key parameters.
+pub fn import_hmac_key(
+    sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>,
+    domain: Domain,
+    nspace: i64,
+    alias: Option<String>,
+) -> binder::Result<KeyMetadata> {
+    static HMAC_KEY: &[u8] = &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+    let key_size = HMAC_KEY.len() * 8;
+
+    let import_params = AuthSetBuilder::new()
+        .no_auth_required()
+        .algorithm(Algorithm::HMAC)
+        .key_size(key_size.try_into().unwrap())
+        .purpose(KeyPurpose::SIGN)
+        .purpose(KeyPurpose::VERIFY)
+        .digest(Digest::SHA_2_256)
+        .min_mac_length(256);
+
+    let key_metadata = sec_level.importKey(
+        &KeyDescriptor { domain, nspace, alias, blob: None },
+        None,
+        &import_params,
+        0,
+        HMAC_KEY,
+    )?;
+
+    assert!(check_key_param(
+        &key_metadata.authorizations,
+        KeyParameter { tag: Tag::ALGORITHM, value: KeyParameterValue::Algorithm(Algorithm::HMAC) }
+    ));
+    assert!(check_key_param(
+        &key_metadata.authorizations,
+        KeyParameter { tag: Tag::KEY_SIZE, value: KeyParameterValue::Integer(128) }
+    ));
+    assert!(check_key_param(
+        &key_metadata.authorizations,
+        KeyParameter { tag: Tag::DIGEST, value: KeyParameterValue::Digest(Digest::SHA_2_256) }
+    ));
+    assert!(check_key_param(
+        &key_metadata.authorizations,
+        KeyParameter { tag: Tag::ORIGIN, value: KeyParameterValue::Origin(KeyOrigin::IMPORTED) }
+    ));
+
+    Ok(key_metadata)
+}
diff --git a/keystore2/tests/Android.bp b/keystore2/tests/Android.bp
index 8194100..dd5d782 100644
--- a/keystore2/tests/Android.bp
+++ b/keystore2/tests/Android.bp
@@ -45,6 +45,7 @@
         "libserde",
         "libthiserror",
 	"libcxx",
+	"libopenssl",
     ],
     static_libs: [
         "libkeystore2_ffi_test_utils",
diff --git a/keystore2/tests/keystore2_client_import_keys_tests.rs b/keystore2/tests/keystore2_client_import_keys_tests.rs
new file mode 100644
index 0000000..abf35b5
--- /dev/null
+++ b/keystore2/tests/keystore2_client_import_keys_tests.rs
@@ -0,0 +1,374 @@
+// Copyright 2022, The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use nix::unistd::getuid;
+
+use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
+    Algorithm::Algorithm, BlockMode::BlockMode, Digest::Digest, EcCurve::EcCurve,
+    ErrorCode::ErrorCode, KeyPurpose::KeyPurpose, PaddingMode::PaddingMode,
+    SecurityLevel::SecurityLevel,
+};
+use android_system_keystore2::aidl::android::system::keystore2::{
+    Domain::Domain, IKeystoreSecurityLevel::IKeystoreSecurityLevel, KeyDescriptor::KeyDescriptor,
+};
+
+use keystore2_test_utils::{
+    authorizations, get_keystore_service, key_generations, key_generations::Error,
+};
+
+use crate::keystore2_client_test_utils::{
+    has_trusty_keymint, perform_sample_asym_sign_verify_op, perform_sample_hmac_sign_verify_op,
+    perform_sample_sym_key_decrypt_op, perform_sample_sym_key_encrypt_op, SAMPLE_PLAIN_TEXT,
+};
+
+pub fn import_rsa_sign_key_and_perform_sample_operation(
+    sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>,
+    domain: Domain,
+    nspace: i64,
+    alias: Option<String>,
+    import_params: authorizations::AuthSetBuilder,
+) {
+    let key_metadata =
+        key_generations::import_rsa_2048_key(sec_level, domain, nspace, alias, import_params)
+            .unwrap();
+
+    perform_sample_asym_sign_verify_op(
+        sec_level,
+        &key_metadata,
+        Some(PaddingMode::RSA_PSS),
+        Some(Digest::SHA_2_256),
+    );
+}
+
+/// Import RSA key and verify imported key parameters. Try to create an operation using the
+/// imported key. Test should be able to create an operation successfully.
+#[test]
+fn keystore2_rsa_import_key_success() {
+    let keystore2 = get_keystore_service();
+    let sec_level = keystore2.getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT).unwrap();
+
+    let alias = format!("ks_rsa_key_test_import_1_{}{}", getuid(), 2048);
+
+    let import_params = authorizations::AuthSetBuilder::new()
+        .no_auth_required()
+        .algorithm(Algorithm::RSA)
+        .digest(Digest::SHA_2_256)
+        .purpose(KeyPurpose::SIGN)
+        .purpose(KeyPurpose::VERIFY)
+        .padding_mode(PaddingMode::RSA_PSS)
+        .key_size(2048)
+        .rsa_public_exponent(65537)
+        .cert_not_before(0)
+        .cert_not_after(253402300799000);
+
+    import_rsa_sign_key_and_perform_sample_operation(
+        &sec_level,
+        Domain::APP,
+        -1,
+        Some(alias),
+        import_params,
+    );
+}
+
+/// Import RSA key without providing key-size and public exponent in import key parameters list.
+/// Let Key-size and public-exponent to be determined from the imported key material. Verify
+/// imported key parameters. Try to create an operation using the imported key. Test should be
+/// able to create an operation successfully.
+#[test]
+fn keystore2_rsa_import_key_determine_key_size_and_pub_exponent() {
+    let keystore2 = get_keystore_service();
+    let sec_level = keystore2.getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT).unwrap();
+
+    let alias = format!("ks_rsa_key_test_import_2_{}{}", getuid(), 2048);
+
+    // key-size and public-exponent shouldn't be specified in import key parameters list.
+    let import_params = authorizations::AuthSetBuilder::new()
+        .no_auth_required()
+        .algorithm(Algorithm::RSA)
+        .digest(Digest::SHA_2_256)
+        .purpose(KeyPurpose::SIGN)
+        .purpose(KeyPurpose::VERIFY)
+        .padding_mode(PaddingMode::RSA_PSS)
+        .cert_not_before(0)
+        .cert_not_after(253402300799000);
+
+    import_rsa_sign_key_and_perform_sample_operation(
+        &sec_level,
+        Domain::APP,
+        -1,
+        Some(alias),
+        import_params,
+    );
+}
+
+/// Try to import RSA key with wrong key size as import-key-parameter. Test should fail to import
+/// a key with `IMPORT_PARAMETER_MISMATCH` error code.
+#[test]
+fn keystore2_rsa_import_key_fails_with_keysize_param_mismatch_error() {
+    let keystore2 = get_keystore_service();
+    let sec_level = keystore2.getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT).unwrap();
+
+    let alias = format!("ks_rsa_key_test_import_3_{}{}", getuid(), 2048);
+
+    let import_params = authorizations::AuthSetBuilder::new()
+        .no_auth_required()
+        .algorithm(Algorithm::RSA)
+        .digest(Digest::SHA_2_256)
+        .purpose(KeyPurpose::SIGN)
+        .purpose(KeyPurpose::VERIFY)
+        .padding_mode(PaddingMode::RSA_PSS)
+        .key_size(1024) // Wrong key size is specified, (actual key-size is 2048).
+        .rsa_public_exponent(65537)
+        .cert_not_before(0)
+        .cert_not_after(253402300799000);
+
+    let result = key_generations::map_ks_error(sec_level.importKey(
+        &KeyDescriptor { domain: Domain::APP, nspace: -1, alias: Some(alias), blob: None },
+        None,
+        &import_params,
+        0,
+        key_generations::RSA_2048_KEY,
+    ));
+
+    assert!(result.is_err());
+    assert_eq!(Error::Km(ErrorCode::IMPORT_PARAMETER_MISMATCH), result.unwrap_err());
+}
+
+/// Try to import RSA key with wrong public-exponent as import-key-parameter.
+/// Test should fail to import a key with `IMPORT_PARAMETER_MISMATCH` error code.
+#[test]
+fn keystore2_rsa_import_key_fails_with_public_exponent_param_mismatch_error() {
+    let keystore2 = get_keystore_service();
+    let sec_level = keystore2.getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT).unwrap();
+
+    let alias = format!("ks_rsa_key_test_import_4_{}{}", getuid(), 2048);
+
+    let import_params = authorizations::AuthSetBuilder::new()
+        .no_auth_required()
+        .algorithm(Algorithm::RSA)
+        .digest(Digest::SHA_2_256)
+        .purpose(KeyPurpose::SIGN)
+        .purpose(KeyPurpose::VERIFY)
+        .padding_mode(PaddingMode::RSA_PSS)
+        .key_size(2048)
+        .rsa_public_exponent(3) // This doesn't match the key.
+        .cert_not_before(0)
+        .cert_not_after(253402300799000);
+
+    let result = key_generations::map_ks_error(sec_level.importKey(
+        &KeyDescriptor { domain: Domain::APP, nspace: -1, alias: Some(alias), blob: None },
+        None,
+        &import_params,
+        0,
+        key_generations::RSA_2048_KEY,
+    ));
+
+    assert!(result.is_err());
+    assert_eq!(Error::Km(ErrorCode::IMPORT_PARAMETER_MISMATCH), result.unwrap_err());
+}
+
+/// Try to import a key with multiple purposes. Test should fail to import a key with
+/// `INCOMPATIBLE_PURPOSE` error code. If the backend is `keymaster` then `importKey` shall be
+/// successful.
+#[test]
+fn keystore2_rsa_import_key_with_multipurpose_fails_incompt_purpose_error() {
+    let keystore2 = get_keystore_service();
+    let sec_level = keystore2.getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT).unwrap();
+
+    let alias = format!("ks_rsa_key_test_import_5_{}{}", getuid(), 2048);
+
+    let import_params = authorizations::AuthSetBuilder::new()
+        .no_auth_required()
+        .algorithm(Algorithm::RSA)
+        .digest(Digest::SHA_2_256)
+        .purpose(KeyPurpose::SIGN)
+        .purpose(KeyPurpose::ATTEST_KEY)
+        .padding_mode(PaddingMode::RSA_PSS)
+        .key_size(2048)
+        .rsa_public_exponent(65537)
+        .cert_not_before(0)
+        .cert_not_after(253402300799000);
+
+    let result = key_generations::map_ks_error(sec_level.importKey(
+        &KeyDescriptor { domain: Domain::APP, nspace: -1, alias: Some(alias), blob: None },
+        None,
+        &import_params,
+        0,
+        key_generations::RSA_2048_KEY,
+    ));
+
+    if has_trusty_keymint() {
+        assert!(result.is_err());
+        assert_eq!(Error::Km(ErrorCode::INCOMPATIBLE_PURPOSE), result.unwrap_err());
+    } else {
+        assert!(result.is_ok());
+    }
+}
+
+/// Import EC key and verify imported key parameters. Let ec-curve to be determined from the
+/// imported key material. Try to create an operation using the imported key. Test should be
+/// able to create an operation successfully.
+#[test]
+fn keystore2_import_ec_key_success() {
+    let keystore2 = get_keystore_service();
+    let sec_level = keystore2.getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT).unwrap();
+
+    let alias = format!("ks_ec_key_test_import_1_{}{}", getuid(), 256);
+
+    // Don't specify ec-curve.
+    let import_params = authorizations::AuthSetBuilder::new()
+        .no_auth_required()
+        .algorithm(Algorithm::EC)
+        .digest(Digest::SHA_2_256)
+        .purpose(KeyPurpose::SIGN)
+        .purpose(KeyPurpose::VERIFY)
+        .cert_not_before(0)
+        .cert_not_after(253402300799000);
+
+    let key_metadata = key_generations::import_ec_p_256_key(
+        &sec_level,
+        Domain::APP,
+        -1,
+        Some(alias),
+        import_params,
+    )
+    .expect("Failed to import EC key.");
+
+    perform_sample_asym_sign_verify_op(&sec_level, &key_metadata, None, Some(Digest::SHA_2_256));
+}
+
+/// Try to import EC key with wrong ec-curve as import-key-parameter. Test should fail to import a
+/// key with `IMPORT_PARAMETER_MISMATCH` error code.
+#[test]
+fn keystore2_ec_import_key_fails_with_mismatch_curve_error() {
+    let keystore2 = get_keystore_service();
+    let sec_level = keystore2.getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT).unwrap();
+
+    let alias = format!("ks_ec_key_test_import_1_{}{}", getuid(), 256);
+
+    let import_params = authorizations::AuthSetBuilder::new()
+        .no_auth_required()
+        .algorithm(Algorithm::EC)
+        .digest(Digest::SHA_2_256)
+        .ec_curve(EcCurve::P_224) // It doesn't match with key material.
+        .purpose(KeyPurpose::SIGN)
+        .purpose(KeyPurpose::VERIFY)
+        .cert_not_before(0)
+        .cert_not_after(253402300799000);
+
+    let result = key_generations::map_ks_error(sec_level.importKey(
+        &KeyDescriptor { domain: Domain::APP, nspace: -1, alias: Some(alias), blob: None },
+        None,
+        &import_params,
+        0,
+        key_generations::EC_P_256_KEY,
+    ));
+    assert!(result.is_err());
+    assert_eq!(Error::Km(ErrorCode::IMPORT_PARAMETER_MISMATCH), result.unwrap_err());
+}
+
+/// Import AES key and verify key parameters. Try to create an operation using the imported key.
+/// Test should be able to create an operation successfully.
+#[test]
+fn keystore2_import_aes_key_success() {
+    let keystore2 = get_keystore_service();
+    let sec_level = keystore2.getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT).unwrap();
+
+    let alias = format!("ks_aes_key_test_import_1_{}{}", getuid(), 256);
+    let key_metadata = key_generations::import_aes_key(&sec_level, Domain::APP, -1, Some(alias))
+        .expect("Failed to import AES key.");
+
+    let cipher_text = perform_sample_sym_key_encrypt_op(
+        &sec_level,
+        PaddingMode::PKCS7,
+        BlockMode::ECB,
+        &mut None,
+        None,
+        &key_metadata.key,
+    )
+    .unwrap();
+
+    assert!(cipher_text.is_some());
+
+    let plain_text = perform_sample_sym_key_decrypt_op(
+        &sec_level,
+        &cipher_text.unwrap(),
+        PaddingMode::PKCS7,
+        BlockMode::ECB,
+        &mut None,
+        None,
+        &key_metadata.key,
+    )
+    .unwrap();
+
+    assert!(plain_text.is_some());
+    assert_eq!(plain_text.unwrap(), SAMPLE_PLAIN_TEXT.to_vec());
+}
+
+/// Import 3DES key and verify key parameters. Try to create an operation using the imported key.
+/// Test should be able to create an operation successfully.
+#[test]
+fn keystore2_import_3des_key_success() {
+    let keystore2 = get_keystore_service();
+    let sec_level = key_generations::map_ks_error(
+        keystore2.getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT),
+    )
+    .unwrap();
+
+    let alias = format!("ks_3des_key_test_import_1_{}{}", getuid(), 168);
+
+    let key_metadata = key_generations::import_3des_key(&sec_level, Domain::APP, -1, Some(alias))
+        .expect("Failed to import 3DES key.");
+
+    let cipher_text = perform_sample_sym_key_encrypt_op(
+        &sec_level,
+        PaddingMode::PKCS7,
+        BlockMode::ECB,
+        &mut None,
+        None,
+        &key_metadata.key,
+    )
+    .unwrap();
+
+    assert!(cipher_text.is_some());
+
+    let plain_text = perform_sample_sym_key_decrypt_op(
+        &sec_level,
+        &cipher_text.unwrap(),
+        PaddingMode::PKCS7,
+        BlockMode::ECB,
+        &mut None,
+        None,
+        &key_metadata.key,
+    )
+    .unwrap();
+
+    assert!(plain_text.is_some());
+    assert_eq!(plain_text.unwrap(), SAMPLE_PLAIN_TEXT.to_vec());
+}
+
+/// Import HMAC key and verify key parameters. Try to create an operation using the imported key.
+/// Test should be able to create an operation successfully.
+#[test]
+fn keystore2_import_hmac_key_success() {
+    let keystore2 = get_keystore_service();
+    let sec_level = keystore2.getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT).unwrap();
+
+    let alias = format!("ks_hmac_key_test_import_1_{}", getuid());
+
+    let key_metadata = key_generations::import_hmac_key(&sec_level, Domain::APP, -1, Some(alias))
+        .expect("Failed to import HMAC key.");
+
+    perform_sample_hmac_sign_verify_op(&sec_level, &key_metadata.key);
+}
diff --git a/keystore2/tests/keystore2_client_test_utils.rs b/keystore2/tests/keystore2_client_test_utils.rs
index f385d90..758e88b 100644
--- a/keystore2/tests/keystore2_client_test_utils.rs
+++ b/keystore2/tests/keystore2_client_test_utils.rs
@@ -15,6 +15,11 @@
 use nix::unistd::{Gid, Uid};
 use serde::{Deserialize, Serialize};
 
+use openssl::hash::MessageDigest;
+use openssl::rsa::Padding;
+use openssl::sign::Verifier;
+use openssl::x509::X509;
+
 use binder::wait_for_interface;
 
 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
@@ -25,8 +30,8 @@
 use android_system_keystore2::aidl::android::system::keystore2::{
     CreateOperationResponse::CreateOperationResponse, Domain::Domain,
     IKeystoreOperation::IKeystoreOperation, IKeystoreSecurityLevel::IKeystoreSecurityLevel,
-    IKeystoreService::IKeystoreService, KeyDescriptor::KeyDescriptor, KeyParameters::KeyParameters,
-    ResponseCode::ResponseCode,
+    IKeystoreService::IKeystoreService, KeyDescriptor::KeyDescriptor, KeyMetadata::KeyMetadata,
+    KeyParameters::KeyParameters, ResponseCode::ResponseCode,
 };
 
 use packagemanager_aidl::aidl::android::content::pm::IPackageManagerNative::IPackageManagerNative;
@@ -115,6 +120,104 @@
     Ok(())
 }
 
+/// Perform sample HMAC sign and verify operations.
+pub fn perform_sample_hmac_sign_verify_op(
+    sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>,
+    key: &KeyDescriptor,
+) {
+    let sign_op = sec_level
+        .createOperation(
+            key,
+            &authorizations::AuthSetBuilder::new()
+                .purpose(KeyPurpose::SIGN)
+                .digest(Digest::SHA_2_256)
+                .mac_length(256),
+            false,
+        )
+        .unwrap();
+    assert!(sign_op.iOperation.is_some());
+
+    let op = sign_op.iOperation.unwrap();
+    op.update(b"my message").unwrap();
+    let sig = op.finish(None, None).unwrap();
+    assert!(sig.is_some());
+
+    let sig = sig.unwrap();
+    let verify_op = sec_level
+        .createOperation(
+            key,
+            &authorizations::AuthSetBuilder::new()
+                .purpose(KeyPurpose::VERIFY)
+                .digest(Digest::SHA_2_256),
+            false,
+        )
+        .unwrap();
+    assert!(verify_op.iOperation.is_some());
+
+    let op = verify_op.iOperation.unwrap();
+    let result = op.finish(Some(b"my message"), Some(&sig)).unwrap();
+    assert!(result.is_none());
+}
+
+/// Map KeyMint Digest values to OpenSSL MessageDigest.
+pub fn get_openssl_digest_mode(digest: Option<Digest>) -> MessageDigest {
+    match digest {
+        Some(Digest::MD5) => MessageDigest::md5(),
+        Some(Digest::SHA1) => MessageDigest::sha1(),
+        Some(Digest::SHA_2_224) => MessageDigest::sha224(),
+        Some(Digest::SHA_2_256) => MessageDigest::sha256(),
+        Some(Digest::SHA_2_384) => MessageDigest::sha384(),
+        Some(Digest::SHA_2_512) => MessageDigest::sha512(),
+        _ => MessageDigest::sha256(),
+    }
+}
+
+/// Map KeyMint PaddingMode values to OpenSSL Padding.
+pub fn get_openssl_padding_mode(padding: PaddingMode) -> Padding {
+    match padding {
+        PaddingMode::RSA_OAEP => Padding::PKCS1_OAEP,
+        PaddingMode::RSA_PSS => Padding::PKCS1_PSS,
+        PaddingMode::RSA_PKCS1_1_5_SIGN => Padding::PKCS1,
+        PaddingMode::RSA_PKCS1_1_5_ENCRYPT => Padding::PKCS1,
+        _ => Padding::NONE,
+    }
+}
+
+/// Perform sample sign and verify operations using RSA or EC key.
+pub fn perform_sample_asym_sign_verify_op(
+    sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>,
+    key_metadata: &KeyMetadata,
+    padding: Option<PaddingMode>,
+    digest: Option<Digest>,
+) {
+    let mut authorizations = authorizations::AuthSetBuilder::new().purpose(KeyPurpose::SIGN);
+    if let Some(value) = padding {
+        authorizations = authorizations.padding_mode(value);
+    }
+    if let Some(value) = digest {
+        authorizations = authorizations.digest(value);
+    }
+
+    let sign_op = sec_level.createOperation(&key_metadata.key, &authorizations, false).unwrap();
+    assert!(sign_op.iOperation.is_some());
+
+    let op = sign_op.iOperation.unwrap();
+    op.update(b"my message").unwrap();
+    let sig = op.finish(None, None).unwrap();
+    assert!(sig.is_some());
+
+    let sig = sig.unwrap();
+    let cert_bytes = key_metadata.certificate.as_ref().unwrap();
+    let cert = X509::from_der(cert_bytes.as_ref()).unwrap();
+    let pub_key = cert.public_key().unwrap();
+    let mut verifier = Verifier::new(get_openssl_digest_mode(digest), pub_key.as_ref()).unwrap();
+    if let Some(value) = padding {
+        verifier.set_rsa_padding(get_openssl_padding_mode(value)).unwrap();
+    }
+    verifier.update(b"my message").unwrap();
+    assert!(verifier.verify(&sig).unwrap());
+}
+
 /// Create new operation on child proc and perform simple operation after parent notification.
 pub fn execute_op_run_as_child(
     target_ctx: &'static str,
diff --git a/keystore2/tests/keystore2_client_tests.rs b/keystore2/tests/keystore2_client_tests.rs
index 71768a6..41e3e36 100644
--- a/keystore2/tests/keystore2_client_tests.rs
+++ b/keystore2/tests/keystore2_client_tests.rs
@@ -18,6 +18,7 @@
 pub mod keystore2_client_ec_key_tests;
 pub mod keystore2_client_grant_key_tests;
 pub mod keystore2_client_hmac_key_tests;
+pub mod keystore2_client_import_keys_tests;
 pub mod keystore2_client_key_id_domain_tests;
 pub mod keystore2_client_list_entries_tests;
 pub mod keystore2_client_operation_tests;
diff --git a/ondevice-signing/Android.bp b/ondevice-signing/Android.bp
index d73f8fe..f56cfab 100644
--- a/ondevice-signing/Android.bp
+++ b/ondevice-signing/Android.bp
@@ -101,6 +101,15 @@
   recovery_available: true,
 }
 
+genrule {
+  name: "statslog_odsign.h",
+  tools: ["stats-log-api-gen"],
+  cmd: "$(location stats-log-api-gen) --header $(genDir)/statslog_odsign.h --module art --namespace art,metrics,statsd",
+  out: [
+    "statslog_odsign.h",
+  ],
+}
+
 cc_binary {
   name: "odsign",
   defaults: [
@@ -114,6 +123,7 @@
     "odsign_main.cpp",
     "StatsReporter.cpp",
   ],
+  generated_headers: ["statslog_odsign.h"],
 
   header_libs: ["odrefresh_headers"],
 
diff --git a/ondevice-signing/StatsReporter.cpp b/ondevice-signing/StatsReporter.cpp
index 65e645a..e4e4a03 100644
--- a/ondevice-signing/StatsReporter.cpp
+++ b/ondevice-signing/StatsReporter.cpp
@@ -20,12 +20,13 @@
 #include <string>
 #include <sys/stat.h>
 
-// Keep these constant in sync with COMPOS_METRIC_NAME & METRICS_FILE in OdsignStatsLogger.java.
+// Keep these constants in sync with those in OdsignStatsLogger.java.
 constexpr const char* kOdsignMetricsFile = "/data/misc/odsign/metrics/odsign-metrics.txt";
 constexpr const char* kComposMetricName = "comp_os_artifacts_check_record";
+constexpr const char* kOdsignMetricName = "odsign_record";
 
 StatsReporter::~StatsReporter() {
-    if (comp_os_artifacts_check_record_ == nullptr) {
+    if (comp_os_artifacts_check_record_ == nullptr && !odsign_record_enabled_) {
         LOG(INFO) << "Metrics report is empty";
 
         // Remove the metrics file if any old version of the file already exists
@@ -42,24 +43,31 @@
         PLOG(ERROR) << "Could not open file: " << kOdsignMetricsFile;
         return;
     }
-
-    odsign_metrics_file_ << kComposMetricName << ' ';
-    odsign_metrics_file_ << comp_os_artifacts_check_record_->current_artifacts_ok << ' ';
-    odsign_metrics_file_ << comp_os_artifacts_check_record_->comp_os_pending_artifacts_exists
-                         << ' ';
-    odsign_metrics_file_ << comp_os_artifacts_check_record_->use_comp_os_generated_artifacts
-                         << '\n';
     if (chmod(kOdsignMetricsFile, 0644) != 0) {
         PLOG(ERROR) << "Could not set correct file permissions for " << kOdsignMetricsFile;
         return;
     }
+
+    if (comp_os_artifacts_check_record_ != nullptr) {
+        odsign_metrics_file_ << kComposMetricName << ' '
+                             << comp_os_artifacts_check_record_->current_artifacts_ok << ' '
+                             << comp_os_artifacts_check_record_->comp_os_pending_artifacts_exists
+                             << ' '
+                             << comp_os_artifacts_check_record_->use_comp_os_generated_artifacts
+                             << '\n';
+    }
+
+    if (odsign_record_enabled_) {
+        odsign_metrics_file_ << kOdsignMetricName << ' ' << odsign_record_.status << '\n';
+    }
+
     odsign_metrics_file_.close();
     if (!odsign_metrics_file_) {
         PLOG(ERROR) << "Failed to close the file";
     }
 }
 
-StatsReporter::CompOsArtifactsCheckRecord* StatsReporter::GetComposArtifactsCheckRecord() {
+StatsReporter::CompOsArtifactsCheckRecord* StatsReporter::GetOrCreateComposArtifactsCheckRecord() {
     if (comp_os_artifacts_check_record_ == nullptr) {
         comp_os_artifacts_check_record_ = std::make_unique<CompOsArtifactsCheckRecord>();
     }
diff --git a/ondevice-signing/StatsReporter.h b/ondevice-signing/StatsReporter.h
index 2682b96..add7a11 100644
--- a/ondevice-signing/StatsReporter.h
+++ b/ondevice-signing/StatsReporter.h
@@ -18,27 +18,44 @@
 
 #include <fstream>
 
+#include "statslog_odsign.h"
+
 // Class to store CompOsArtifactsCheck related metrics.
 // These are flushed to a file kOdsignMetricsFile and consumed by
 // System Server (in class OdsignStatsLogger) & sent to statsd.
 class StatsReporter {
   public:
-    // Keep sync with EarlyBootCompOsArtifactsCheckReported
-    // definition in proto_logging/stats/atoms.proto.
+    // Keep in sync with the EarlyBootCompOsArtifactsCheckReported definition in
+    // proto_logging/stats/atoms.proto.
     struct CompOsArtifactsCheckRecord {
         bool current_artifacts_ok = false;
         bool comp_os_pending_artifacts_exists = false;
         bool use_comp_os_generated_artifacts = false;
     };
 
+    // Keep in sync with the OdsignReported definition in proto_logging/stats/atoms.proto.
+    struct OdsignRecord {
+        int32_t status = art::metrics::statsd::ODSIGN_REPORTED__STATUS__STATUS_UNSPECIFIED;
+    };
+
     // The report is flushed (from buffer) into a file by the destructor.
     ~StatsReporter();
 
-    // Get pointer to comp_os_artifacts_check_record, caller can then modify it.
-    // Note: pointer remains valid for the lifetime of this StatsReporter.
-    CompOsArtifactsCheckRecord* GetComposArtifactsCheckRecord();
+    // Returns a mutable CompOS record. The pointer remains valid for the lifetime of this
+    // StatsReporter. If this function is not called, no CompOS record will be logged.
+    CompOsArtifactsCheckRecord* GetOrCreateComposArtifactsCheckRecord();
+
+    // Returns a mutable odsign record. The pointer remains valid for the lifetime of this
+    // StatsReporter.
+    OdsignRecord* GetOdsignRecord() { return &odsign_record_; }
+
+    // Enables/disables odsign metrics.
+    void SetOdsignRecordEnabled(bool value) { odsign_record_enabled_ = value; }
 
   private:
     // Temporary buffer which stores the metrics.
     std::unique_ptr<CompOsArtifactsCheckRecord> comp_os_artifacts_check_record_;
+
+    OdsignRecord odsign_record_;
+    bool odsign_record_enabled_ = true;
 };
diff --git a/ondevice-signing/odsign_main.cpp b/ondevice-signing/odsign_main.cpp
index c45e308..93ec3e4 100644
--- a/ondevice-signing/odsign_main.cpp
+++ b/ondevice-signing/odsign_main.cpp
@@ -35,6 +35,7 @@
 #include "KeystoreKey.h"
 #include "StatsReporter.h"
 #include "VerityUtils.h"
+#include "statslog_odsign.h"
 
 #include "odsign_info.pb.h"
 
@@ -370,7 +371,7 @@
                                                      bool* digests_verified,
                                                      StatsReporter* stats_reporter) {
     StatsReporter::CompOsArtifactsCheckRecord* compos_check_record =
-        stats_reporter->GetComposArtifactsCheckRecord();
+        stats_reporter->GetOrCreateComposArtifactsCheckRecord();
 
     if (!directoryHasContent(kCompOsPendingArtifactsDir)) {
         // No pending CompOS artifacts, all that matters is the current ones.
@@ -468,12 +469,9 @@
 }  // namespace
 
 int main(int /* argc */, char** argv) {
-    // stats_reporter is a pointer so that we can explicitly delete it
-    // instead of waiting for the program to die & its destrcutor be called
-    auto stats_reporter = std::make_unique<StatsReporter>();
     android::base::InitLogging(argv, android::base::LogdLogger(android::base::SYSTEM));
 
-    auto errorScopeGuard = []() {
+    auto scope_guard = android::base::make_scope_guard([]() {
         // In case we hit any error, remove the artifacts and tell Zygote not to use
         // anything
         removeDirectory(kArtArtifactsDir);
@@ -485,17 +483,24 @@
         SetProperty(kOdsignVerificationDoneProp, "1");
         // Tell init it shouldn't try to restart us - see odsign.rc
         SetProperty(kStopServiceProp, "odsign");
-    };
-    auto scope_guard = android::base::make_scope_guard(errorScopeGuard);
+    });
+
+    // `stats_reporter` must come after `scope_guard` so that its destructor is called before
+    // `scope_guard`.
+    auto stats_reporter = std::make_unique<StatsReporter>();
+    StatsReporter::OdsignRecord* odsign_record = stats_reporter->GetOdsignRecord();
 
     if (!android::base::GetBoolProperty("ro.apex.updatable", false)) {
         LOG(INFO) << "Device doesn't support updatable APEX, exiting.";
+        stats_reporter->SetOdsignRecordEnabled(false);
         return 0;
     }
     auto keystoreResult =
         KeystoreKey::getInstance(kPublicKeySignature, kKeyAlias, kKeyNspace, kKeyBootLevel);
     if (!keystoreResult.ok()) {
         LOG(ERROR) << "Could not create keystore key: " << keystoreResult.error();
+        odsign_record->status =
+            art::metrics::statsd::ODSIGN_REPORTED__STATUS__STATUS_KEYSTORE_FAILED;
         return -1;
     }
     SigningKey* key = keystoreResult.value();
@@ -517,6 +522,8 @@
             if (!new_cert.ok()) {
                 LOG(ERROR) << "Failed to create X509 certificate: " << new_cert.error();
                 // TODO apparently the key become invalid - delete the blob / cert
+                odsign_record->status =
+                    art::metrics::statsd::ODSIGN_REPORTED__STATUS__STATUS_CERT_FAILED;
                 return -1;
             }
         } else {
@@ -526,6 +533,8 @@
         if (!cert_add_result.ok()) {
             LOG(ERROR) << "Failed to add certificate to fs-verity keyring: "
                        << cert_add_result.error();
+            odsign_record->status =
+                art::metrics::statsd::ODSIGN_REPORTED__STATUS__STATUS_CERT_FAILED;
             return -1;
         }
     }
@@ -535,12 +544,6 @@
         useCompOs ? CheckCompOsPendingArtifacts(*key, &digests_verified, stats_reporter.get())
                   : checkArtifacts();
 
-    // Explicitly reset the pointer - We rely on stats_reporter's
-    // destructor for actually writing the buffered metrics. This will otherwise not be called
-    // if the program doesn't exit normally (for ex, killed by init, which actually happens
-    // because odsign (after it finishes) sets kStopServiceProp instructing init to kill it).
-    stats_reporter.reset();
-
     // The artifacts dir doesn't necessarily need to exist; if the existing
     // artifacts on the system partition are valid, those can be used.
     int err = access(kArtArtifactsDir.c_str(), F_OK);
@@ -578,6 +581,8 @@
                 // instead prevent Zygote from using them (which is taken care of
                 // in the exit handler).
                 LOG(ERROR) << "Failed to remove unknown artifacts.";
+                odsign_record->status =
+                    art::metrics::statsd::ODSIGN_REPORTED__STATUS__STATUS_CLEANUP_FAILED;
                 return -1;
             }
         }
@@ -591,11 +596,16 @@
     if (odrefresh_status == art::odrefresh::ExitCode::kOkay) {
         // No new artifacts generated, and we verified existing ones above, nothing left to do.
         LOG(INFO) << "odrefresh said artifacts are VALID";
+        stats_reporter->SetOdsignRecordEnabled(false);
     } else if (odrefresh_status == art::odrefresh::ExitCode::kCompilationSuccess ||
                odrefresh_status == art::odrefresh::ExitCode::kCompilationFailed) {
         const bool compiled_all = odrefresh_status == art::odrefresh::ExitCode::kCompilationSuccess;
         LOG(INFO) << "odrefresh compiled " << (compiled_all ? "all" : "partial")
                   << " artifacts, returned " << odrefresh_status;
+        // This value may be overwritten later.
+        odsign_record->status =
+            compiled_all ? art::metrics::statsd::ODSIGN_REPORTED__STATUS__STATUS_ALL_OK
+                         : art::metrics::statsd::ODSIGN_REPORTED__STATUS__STATUS_PARTIAL_OK;
         Result<std::map<std::string, std::string>> digests;
         if (supportsFsVerity) {
             digests = addFilesToVerityRecursive(kArtArtifactsDir, *key);
@@ -606,24 +616,39 @@
         }
         if (!digests.ok()) {
             LOG(ERROR) << digests.error();
+            odsign_record->status =
+                art::metrics::statsd::ODSIGN_REPORTED__STATUS__STATUS_SIGNING_FAILED;
             return -1;
         }
         auto persistStatus = persistDigests(*digests, *key);
         if (!persistStatus.ok()) {
             LOG(ERROR) << persistStatus.error();
+            odsign_record->status =
+                art::metrics::statsd::ODSIGN_REPORTED__STATUS__STATUS_SIGNING_FAILED;
             return -1;
         }
     } else if (odrefresh_status == art::odrefresh::ExitCode::kCleanupFailed) {
         LOG(ERROR) << "odrefresh failed cleaning up existing artifacts";
+        odsign_record->status =
+            art::metrics::statsd::ODSIGN_REPORTED__STATUS__STATUS_ODREFRESH_FAILED;
         return -1;
     } else {
         LOG(ERROR) << "odrefresh exited unexpectedly, returned " << odrefresh_status;
+        odsign_record->status =
+            art::metrics::statsd::ODSIGN_REPORTED__STATUS__STATUS_ODREFRESH_FAILED;
         return -1;
     }
 
     LOG(INFO) << "On-device signing done.";
 
     scope_guard.Disable();
+
+    // Explicitly reset the pointer - We rely on stats_reporter's
+    // destructor for actually writing the buffered metrics. This will otherwise not be called
+    // if the program doesn't exit normally (for ex, killed by init, which actually happens
+    // because odsign (after it finishes) sets kStopServiceProp instructing init to kill it).
+    stats_reporter.reset();
+
     // At this point, we're done with the key for sure
     SetProperty(kOdsignKeyDoneProp, "1");
     // And we did a successful verification
diff --git a/provisioner/Android.bp b/provisioner/Android.bp
index 87f39d0..b548973 100644
--- a/provisioner/Android.bp
+++ b/provisioner/Android.bp
@@ -55,6 +55,7 @@
         "liblog",
     ],
     static_libs: [
+        "android.hardware.security.rkp-V3-ndk",
         "libbase",
         "libcppbor_external",
         "libcppcose_rkp",