Keystore 2.0: Implement storage key upgrade on demand.

Bug: 185811713
Test: N/A
Change-Id: Ie996f1b1ecf05f89e3ba11a53a5f8ed55083388a
diff --git a/keystore2/src/security_level.rs b/keystore2/src/security_level.rs
index c654c02..117b48c 100644
--- a/keystore2/src/security_level.rs
+++ b/keystore2/src/security_level.rs
@@ -24,8 +24,8 @@
 };
 use android_system_keystore2::aidl::android::system::keystore2::{
     AuthenticatorSpec::AuthenticatorSpec, CreateOperationResponse::CreateOperationResponse,
-    Domain::Domain, IKeystoreOperation::IKeystoreOperation,
-    IKeystoreSecurityLevel::BnKeystoreSecurityLevel,
+    Domain::Domain, EphemeralStorageKeyResponse::EphemeralStorageKeyResponse,
+    IKeystoreOperation::IKeystoreOperation, IKeystoreSecurityLevel::BnKeystoreSecurityLevel,
     IKeystoreSecurityLevel::IKeystoreSecurityLevel, KeyDescriptor::KeyDescriptor,
     KeyMetadata::KeyMetadata, KeyParameters::KeyParameters,
 };
@@ -783,7 +783,10 @@
         }
     }
 
-    fn convert_storage_key_to_ephemeral(&self, storage_key: &KeyDescriptor) -> Result<Vec<u8>> {
+    fn convert_storage_key_to_ephemeral(
+        &self,
+        storage_key: &KeyDescriptor,
+    ) -> Result<EphemeralStorageKeyResponse> {
         if storage_key.domain != Domain::BLOB {
             return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT)).context(concat!(
                 "In IKeystoreSecurityLevel convert_storage_key_to_ephemeral: ",
@@ -806,8 +809,26 @@
             "In IKeystoreSecurityLevel convert_storage_key_to_ephemeral: ",
             "Getting keymint device interface"
         ))?;
-        map_km_error(km_dev.convertStorageKeyToEphemeral(key_blob))
-            .context("In keymint device convertStorageKeyToEphemeral")
+        match map_km_error(km_dev.convertStorageKeyToEphemeral(key_blob)) {
+            Ok(result) => {
+                Ok(EphemeralStorageKeyResponse { ephemeralKey: result, upgradedBlob: None })
+            }
+            Err(error::Error::Km(ErrorCode::KEY_REQUIRES_UPGRADE)) => {
+                let upgraded_blob = map_km_error(km_dev.upgradeKey(key_blob, &[]))
+                    .context("In convert_storage_key_to_ephemeral: Failed to upgrade key blob.")?;
+                let ephemeral_key = map_km_error(km_dev.convertStorageKeyToEphemeral(key_blob))
+                    .context(concat!(
+                        "In convert_storage_key_to_ephemeral: ",
+                        "Failed to retrieve ephemeral key (after upgrade)."
+                    ))?;
+                Ok(EphemeralStorageKeyResponse {
+                    ephemeralKey: ephemeral_key,
+                    upgradedBlob: Some(upgraded_blob),
+                })
+            }
+            Err(e) => Err(e)
+                .context("In convert_storage_key_to_ephemeral: Failed to retrieve ephemeral key."),
+        }
     }
 
     fn delete_key(&self, key: &KeyDescriptor) -> Result<()> {
@@ -884,7 +905,7 @@
     fn convertStorageKeyToEphemeral(
         &self,
         storage_key: &KeyDescriptor,
-    ) -> binder::public_api::Result<Vec<u8>> {
+    ) -> binder::public_api::Result<EphemeralStorageKeyResponse> {
         map_or_log_err(self.convert_storage_key_to_ephemeral(storage_key), Ok)
     }
     fn deleteKey(&self, key: &KeyDescriptor) -> binder::public_api::Result<()> {