Merge "Send Keystore2 logs to SYSTEM rather than MAIN"
diff --git a/keystore2/src/attestation_key_utils.rs b/keystore2/src/attestation_key_utils.rs
index a8c1ca9..8354ba5 100644
--- a/keystore2/src/attestation_key_utils.rs
+++ b/keystore2/src/attestation_key_utils.rs
@@ -35,6 +35,7 @@
 /// handled quite differently, thus the different representations.
 pub enum AttestationKeyInfo {
     RemoteProvisioned {
+        key_id_guard: KeyIdGuard,
         attestation_key: AttestationKey,
         attestation_certs: Certificate,
     },
@@ -66,8 +67,12 @@
                 "Trying to get remotely provisioned attestation key."
             ))
             .map(|result| {
-                result.map(|(attestation_key, attestation_certs)| {
-                    AttestationKeyInfo::RemoteProvisioned { attestation_key, attestation_certs }
+                result.map(|(key_id_guard, attestation_key, attestation_certs)| {
+                    AttestationKeyInfo::RemoteProvisioned {
+                        key_id_guard,
+                        attestation_key,
+                        attestation_certs,
+                    }
                 })
             }),
         None => Ok(None),
diff --git a/keystore2/src/database.rs b/keystore2/src/database.rs
index 65ee7ae..02ef408 100644
--- a/keystore2/src/database.rs
+++ b/keystore2/src/database.rs
@@ -323,6 +323,8 @@
     0x41, 0xe3, 0xb9, 0xce, 0x27, 0x58, 0x4e, 0x91, 0xbc, 0xfd, 0xa5, 0x5d, 0x91, 0x85, 0xab, 0x11,
 ]);
 
+static EXPIRATION_BUFFER_MS: i64 = 20000;
+
 /// Indicates how the sensitive part of this key blob is encrypted.
 #[derive(Debug, Eq, PartialEq, Ord, PartialOrd)]
 pub enum EncryptedBy {
@@ -1939,8 +1941,11 @@
                 )?
                 .collect::<rusqlite::Result<Vec<(i64, DateTime)>>>()
                 .context("Failed to get date metadata")?;
+            // Calculate curr_time with a discount factor to avoid a key that's milliseconds away
+            // from expiration dodging this delete call.
             let curr_time = DateTime::from_millis_epoch(
-                SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?.as_millis() as i64,
+                SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?.as_millis() as i64
+                    + EXPIRATION_BUFFER_MS,
             );
             let mut num_deleted = 0;
             for id in key_ids_to_check.iter().filter(|kt| kt.1 < curr_time).map(|kt| kt.0) {
@@ -2049,6 +2054,41 @@
         .context("In get_attestation_pool_status: ")
     }
 
+    fn query_kid_for_attestation_key_and_cert_chain(
+        &self,
+        tx: &Transaction,
+        domain: Domain,
+        namespace: i64,
+        km_uuid: &Uuid,
+    ) -> Result<Option<i64>> {
+        let mut stmt = tx.prepare(
+            "SELECT id
+             FROM persistent.keyentry
+             WHERE key_type = ?
+                   AND domain = ?
+                   AND namespace = ?
+                   AND state = ?
+                   AND km_uuid = ?;",
+        )?;
+        let rows = stmt
+            .query_map(
+                params![
+                    KeyType::Attestation,
+                    domain.0 as u32,
+                    namespace,
+                    KeyLifeCycle::Live,
+                    km_uuid
+                ],
+                |row| row.get(0),
+            )?
+            .collect::<rusqlite::Result<Vec<i64>>>()
+            .context("query failed.")?;
+        if rows.is_empty() {
+            return Ok(None);
+        }
+        Ok(Some(rows[0]))
+    }
+
     /// Fetches the private key and corresponding certificate chain assigned to a
     /// domain/namespace pair. Will either return nothing if the domain/namespace is
     /// not assigned, or one CertificateChain.
@@ -2057,7 +2097,7 @@
         domain: Domain,
         namespace: i64,
         km_uuid: &Uuid,
-    ) -> Result<Option<CertificateChain>> {
+    ) -> Result<Option<(KeyIdGuard, CertificateChain)>> {
         let _wp = wd::watch_millis("KeystoreDB::retrieve_attestation_key_and_cert_chain", 500);
 
         match domain {
@@ -2067,69 +2107,70 @@
                     .context(format!("Domain {:?} must be either App or SELinux.", domain));
             }
         }
-        self.with_transaction(TransactionBehavior::Deferred, |tx| {
-            let mut stmt = tx.prepare(
-                "SELECT subcomponent_type, blob
-             FROM persistent.blobentry
-             WHERE keyentryid IN
-                (SELECT id
-                 FROM persistent.keyentry
-                 WHERE key_type = ?
-                       AND domain = ?
-                       AND namespace = ?
-                       AND state = ?
-                       AND km_uuid = ?);",
-            )?;
-            let rows = stmt
-                .query_map(
-                    params![
-                        KeyType::Attestation,
-                        domain.0 as u32,
-                        namespace,
-                        KeyLifeCycle::Live,
-                        km_uuid
-                    ],
-                    |row| Ok((row.get(0)?, row.get(1)?)),
-                )?
-                .collect::<rusqlite::Result<Vec<(SubComponentType, Vec<u8>)>>>()
-                .context("query failed.")?;
-            if rows.is_empty() {
-                return Ok(None).no_gc();
-            } else if rows.len() != 3 {
-                return Err(KsError::sys()).context(format!(
-                    concat!(
-                        "Expected to get a single attestation",
-                        "key, cert, and cert chain for a total of 3 entries, but instead got {}."
-                    ),
-                    rows.len()
-                ));
-            }
-            let mut km_blob: Vec<u8> = Vec::new();
-            let mut cert_chain_blob: Vec<u8> = Vec::new();
-            let mut batch_cert_blob: Vec<u8> = Vec::new();
-            for row in rows {
-                let sub_type: SubComponentType = row.0;
-                match sub_type {
-                    SubComponentType::KEY_BLOB => {
-                        km_blob = row.1;
-                    }
-                    SubComponentType::CERT_CHAIN => {
-                        cert_chain_blob = row.1;
-                    }
-                    SubComponentType::CERT => {
-                        batch_cert_blob = row.1;
-                    }
-                    _ => Err(KsError::sys()).context("Unknown or incorrect subcomponent type.")?,
+
+        self.delete_expired_attestation_keys().context(
+            "In retrieve_attestation_key_and_cert_chain: failed to prune expired attestation keys",
+        )?;
+        let tx = self.conn.unchecked_transaction().context(
+            "In retrieve_attestation_key_and_cert_chain: Failed to initialize transaction.",
+        )?;
+        let key_id: i64;
+        match self.query_kid_for_attestation_key_and_cert_chain(&tx, domain, namespace, km_uuid)? {
+            None => return Ok(None),
+            Some(kid) => key_id = kid,
+        }
+        tx.commit()
+            .context("In retrieve_attestation_key_and_cert_chain: Failed to commit keyid query")?;
+        let key_id_guard = KEY_ID_LOCK.get(key_id);
+        let tx = self.conn.unchecked_transaction().context(
+            "In retrieve_attestation_key_and_cert_chain: Failed to initialize transaction.",
+        )?;
+        let mut stmt = tx.prepare(
+            "SELECT subcomponent_type, blob
+            FROM persistent.blobentry
+            WHERE keyentryid = ?;",
+        )?;
+        let rows = stmt
+            .query_map(params![key_id_guard.id()], |row| Ok((row.get(0)?, row.get(1)?)))?
+            .collect::<rusqlite::Result<Vec<(SubComponentType, Vec<u8>)>>>()
+            .context("query failed.")?;
+        if rows.is_empty() {
+            return Ok(None);
+        } else if rows.len() != 3 {
+            return Err(KsError::sys()).context(format!(
+                concat!(
+                    "Expected to get a single attestation",
+                    "key, cert, and cert chain for a total of 3 entries, but instead got {}."
+                ),
+                rows.len()
+            ));
+        }
+        let mut km_blob: Vec<u8> = Vec::new();
+        let mut cert_chain_blob: Vec<u8> = Vec::new();
+        let mut batch_cert_blob: Vec<u8> = Vec::new();
+        for row in rows {
+            let sub_type: SubComponentType = row.0;
+            match sub_type {
+                SubComponentType::KEY_BLOB => {
+                    km_blob = row.1;
                 }
+                SubComponentType::CERT_CHAIN => {
+                    cert_chain_blob = row.1;
+                }
+                SubComponentType::CERT => {
+                    batch_cert_blob = row.1;
+                }
+                _ => Err(KsError::sys()).context("Unknown or incorrect subcomponent type.")?,
             }
-            Ok(Some(CertificateChain {
+        }
+        Ok(Some((
+            key_id_guard,
+            CertificateChain {
                 private_key: ZVec::try_from(km_blob)?,
                 batch_cert: batch_cert_blob,
                 cert_chain: cert_chain_blob,
-            }))
-            .no_gc()
-        })
-        .context("In retrieve_attestation_key_and_cert_chain:")
+            },
+        )))
     }
 
     /// Updates the alias column of the given key id `newid` with the given alias,
@@ -3508,7 +3549,10 @@
     #[test]
     fn test_store_signed_attestation_certificate_chain() -> Result<()> {
         let mut db = new_test_db()?;
-        let expiration_date: i64 = 20;
+        let expiration_date: i64 =
+            SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?.as_millis() as i64
+                + EXPIRATION_BUFFER_MS
+                + 10000;
         let namespace: i64 = 30;
         let base_byte: u8 = 1;
         let loaded_values =
@@ -3516,7 +3560,7 @@
         let chain =
             db.retrieve_attestation_key_and_cert_chain(Domain::APP, namespace, &KEYSTORE_UUID)?;
         assert!(chain.is_some());
-        let cert_chain = chain.unwrap();
+        let (_, cert_chain) = chain.unwrap();
         assert_eq!(cert_chain.private_key.to_vec(), loaded_values.priv_key);
         assert_eq!(cert_chain.batch_cert, loaded_values.batch_cert);
         assert_eq!(cert_chain.cert_chain, loaded_values.cert_chain);
@@ -3585,7 +3629,9 @@
             TempDir::new("test_remove_expired_certs_").expect("Failed to create temp dir.");
         let mut db = new_test_db_with_gc(temp_dir.path(), |_, _| Ok(()))?;
         let expiration_date: i64 =
-            SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?.as_millis() as i64 + 10000;
+            SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?.as_millis() as i64
+                + EXPIRATION_BUFFER_MS
+                + 10000;
         let namespace: i64 = 30;
         let namespace_del1: i64 = 45;
         let namespace_del2: i64 = 60;
@@ -3596,7 +3642,7 @@
             0x01, /* base_byte */
         )?;
         load_attestation_key_pool(&mut db, 45, namespace_del1, 0x02)?;
-        load_attestation_key_pool(&mut db, 60, namespace_del2, 0x03)?;
+        load_attestation_key_pool(&mut db, expiration_date - 10001, namespace_del2, 0x03)?;
 
         let blob_entry_row_count: u32 = db
             .conn
@@ -3611,7 +3657,7 @@
         let mut cert_chain =
             db.retrieve_attestation_key_and_cert_chain(Domain::APP, namespace, &KEYSTORE_UUID)?;
         assert!(cert_chain.is_some());
-        let value = cert_chain.unwrap();
+        let (_, value) = cert_chain.unwrap();
         assert_eq!(entry_values.batch_cert, value.batch_cert);
         assert_eq!(entry_values.cert_chain, value.cert_chain);
         assert_eq!(entry_values.priv_key, value.private_key.to_vec());
@@ -3643,6 +3689,73 @@
         Ok(())
     }
 
+    fn compare_rem_prov_values(
+        expected: &RemoteProvValues,
+        actual: Option<(KeyIdGuard, CertificateChain)>,
+    ) {
+        assert!(actual.is_some());
+        let (_, value) = actual.unwrap();
+        assert_eq!(expected.batch_cert, value.batch_cert);
+        assert_eq!(expected.cert_chain, value.cert_chain);
+        assert_eq!(expected.priv_key, value.private_key.to_vec());
+    }
+
+    #[test]
+    fn test_dont_remove_valid_certs() -> Result<()> {
+        let temp_dir =
+            TempDir::new("test_remove_expired_certs_").expect("Failed to create temp dir.");
+        let mut db = new_test_db_with_gc(temp_dir.path(), |_, _| Ok(()))?;
+        let expiration_date: i64 =
+            SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?.as_millis() as i64
+                + EXPIRATION_BUFFER_MS
+                + 10000;
+        let namespace1: i64 = 30;
+        let namespace2: i64 = 45;
+        let namespace3: i64 = 60;
+        let entry_values1 = load_attestation_key_pool(
+            &mut db,
+            expiration_date,
+            namespace1,
+            0x01, /* base_byte */
+        )?;
+        let entry_values2 =
+            load_attestation_key_pool(&mut db, expiration_date + 40000, namespace2, 0x02)?;
+        let entry_values3 =
+            load_attestation_key_pool(&mut db, expiration_date - 9000, namespace3, 0x03)?;
+
+        let blob_entry_row_count: u32 = db
+            .conn
+            .query_row("SELECT COUNT(id) FROM persistent.blobentry;", NO_PARAMS, |row| row.get(0))
+            .expect("Failed to get blob entry row count.");
+        // We expect 9 rows here because there are three blobs per attestation key, i.e.,
+        // one key, one certificate chain, and one certificate.
+        assert_eq!(blob_entry_row_count, 9);
+
+        let mut cert_chain =
+            db.retrieve_attestation_key_and_cert_chain(Domain::APP, namespace1, &KEYSTORE_UUID)?;
+        compare_rem_prov_values(&entry_values1, cert_chain);
+
+        cert_chain =
+            db.retrieve_attestation_key_and_cert_chain(Domain::APP, namespace2, &KEYSTORE_UUID)?;
+        compare_rem_prov_values(&entry_values2, cert_chain);
+
+        cert_chain =
+            db.retrieve_attestation_key_and_cert_chain(Domain::APP, namespace3, &KEYSTORE_UUID)?;
+        compare_rem_prov_values(&entry_values3, cert_chain);
+
+        // Give the garbage collector half a second to catch up.
+        std::thread::sleep(Duration::from_millis(500));
+
+        let blob_entry_row_count: u32 = db
+            .conn
+            .query_row("SELECT COUNT(id) FROM persistent.blobentry;", NO_PARAMS, |row| row.get(0))
+            .expect("Failed to get blob entry row count.");
+        // There shound be 9 blob entries left, because all three keys are valid with
+        // three blobs each.
+        assert_eq!(blob_entry_row_count, 9);
+
+        Ok(())
+    }
     #[test]
     fn test_delete_all_attestation_keys() -> Result<()> {
         let mut db = new_test_db()?;
diff --git a/keystore2/src/keystore2_main.rs b/keystore2/src/keystore2_main.rs
index 5b53ae1..55f5d15 100644
--- a/keystore2/src/keystore2_main.rs
+++ b/keystore2/src/keystore2_main.rs
@@ -155,17 +155,20 @@
     // Even if the IRemotelyProvisionedComponent HAL is implemented, it doesn't mean that the keys
     // may be fetched via the key pool. The HAL must be a new version that exports a unique id. If
     // none of the HALs support this, then the key pool service is not published.
-    if let Ok(key_pool_service) = RemotelyProvisionedKeyPoolService::new_native_binder() {
-        binder::add_service(
-            REMOTELY_PROVISIONED_KEY_POOL_SERVICE_NAME,
-            key_pool_service.as_binder(),
-        )
-        .unwrap_or_else(|e| {
-            panic!(
-                "Failed to register service {} because of {:?}.",
-                REMOTELY_PROVISIONED_KEY_POOL_SERVICE_NAME, e
-            );
-        });
+    match RemotelyProvisionedKeyPoolService::new_native_binder() {
+        Ok(key_pool_service) => {
+            binder::add_service(
+                REMOTELY_PROVISIONED_KEY_POOL_SERVICE_NAME,
+                key_pool_service.as_binder(),
+            )
+            .unwrap_or_else(|e| {
+                panic!(
+                    "Failed to register service {} because of {:?}.",
+                    REMOTELY_PROVISIONED_KEY_POOL_SERVICE_NAME, e
+                );
+            });
+        }
+        Err(e) => log::info!("Not publishing IRemotelyProvisionedKeyPool service: {:?}", e),
     }
 
     binder::add_service(LEGACY_KEYSTORE_SERVICE_NAME, legacykeystore.as_binder()).unwrap_or_else(
diff --git a/keystore2/src/km_compat.rs b/keystore2/src/km_compat.rs
index 84855df..788beef 100644
--- a/keystore2/src/km_compat.rs
+++ b/keystore2/src/km_compat.rs
@@ -299,6 +299,15 @@
             KeyBlob::Wrapped(keyblob) => self.soft.getKeyCharacteristics(keyblob, app_id, app_data),
         }
     }
+    fn getRootOfTrustChallenge(&self) -> binder::Result<[u8; 16]> {
+        self.real.getRootOfTrustChallenge()
+    }
+    fn getRootOfTrust(&self, challenge: &[u8; 16]) -> binder::Result<Vec<u8>> {
+        self.real.getRootOfTrust(challenge)
+    }
+    fn sendRootOfTrust(&self, root_of_trust: &[u8]) -> binder::Result<()> {
+        self.real.sendRootOfTrust(root_of_trust)
+    }
     fn convertStorageKeyToEphemeral(&self, storage_keyblob: &[u8]) -> binder::Result<Vec<u8>> {
         // Storage keys should never be associated with a software emulated device.
         self.real.convertStorageKeyToEphemeral(storage_keyblob)
diff --git a/keystore2/src/km_compat/km_compat.cpp b/keystore2/src/km_compat/km_compat.cpp
index 3ade2cf..0775f2f 100644
--- a/keystore2/src/km_compat/km_compat.cpp
+++ b/keystore2/src/km_compat/km_compat.cpp
@@ -506,16 +506,15 @@
     auto legacyKeyGENParams = convertKeyParametersToLegacy(extractGenerationParams(inKeyParams));
     auto legacyKeyFormat = convertKeyFormatToLegacy(in_inKeyFormat);
     KMV1::ErrorCode errorCode;
-    auto result = mDevice->importKey(legacyKeyGENParams, legacyKeyFormat, in_inKeyData,
-                                     [&](V4_0_ErrorCode error, const hidl_vec<uint8_t>& keyBlob,
-                                         const V4_0_KeyCharacteristics& keyCharacteristics) {
-                                         errorCode = convert(error);
-                                         out_creationResult->keyBlob =
-                                             keyBlobPrefix(keyBlob, false);
-                                         out_creationResult->keyCharacteristics =
-                                             processLegacyCharacteristics(
-                                                 securityLevel_, inKeyParams, keyCharacteristics);
-                                     });
+    auto result = mDevice->importKey(
+        legacyKeyGENParams, legacyKeyFormat, in_inKeyData,
+        [&](V4_0_ErrorCode error, const hidl_vec<uint8_t>& keyBlob,
+            const V4_0_KeyCharacteristics& keyCharacteristics) {
+            errorCode = convert(error);
+            out_creationResult->keyBlob = keyBlobPrefix(keyBlob, false);
+            out_creationResult->keyCharacteristics =
+                processLegacyCharacteristics(securityLevel_, inKeyParams, keyCharacteristics);
+        });
     if (!result.isOk()) {
         LOG(ERROR) << __func__ << " transaction failed. " << result.description();
         return convertErrorCode(KMV1::ErrorCode::UNKNOWN_ERROR);
@@ -771,6 +770,19 @@
     }
 }
 
+ScopedAStatus KeyMintDevice::getRootOfTrustChallenge(std::array<uint8_t, 16>* /* challenge */) {
+    return convertErrorCode(KMV1::ErrorCode::UNIMPLEMENTED);
+}
+
+ScopedAStatus KeyMintDevice::getRootOfTrust(const std::array<uint8_t, 16>& /* challenge */,
+                                            std::vector<uint8_t>* /* rootOfTrust */) {
+    return convertErrorCode(KMV1::ErrorCode::UNIMPLEMENTED);
+}
+
+ScopedAStatus KeyMintDevice::sendRootOfTrust(const std::vector<uint8_t>& /* rootOfTrust */) {
+    return convertErrorCode(KMV1::ErrorCode::UNIMPLEMENTED);
+}
+
 ScopedAStatus KeyMintOperation::updateAad(const std::vector<uint8_t>& input,
                                           const std::optional<HardwareAuthToken>& optAuthToken,
                                           const std::optional<TimeStampToken>& optTimeStampToken) {
diff --git a/keystore2/src/km_compat/km_compat.h b/keystore2/src/km_compat/km_compat.h
index f6f5eb4..6654c4a 100644
--- a/keystore2/src/km_compat/km_compat.h
+++ b/keystore2/src/km_compat/km_compat.h
@@ -142,6 +142,11 @@
                           const std::vector<uint8_t>& appId, const std::vector<uint8_t>& appData,
                           std::vector<KeyCharacteristics>* keyCharacteristics) override;
 
+    ScopedAStatus getRootOfTrustChallenge(std::array<uint8_t, 16>* challenge);
+    ScopedAStatus getRootOfTrust(const std::array<uint8_t, 16>& challenge,
+                                 std::vector<uint8_t>* rootOfTrust);
+    ScopedAStatus sendRootOfTrust(const std::vector<uint8_t>& rootOfTrust);
+
     // These are public to allow testing code to use them directly.
     // This class should not be used publicly anyway.
     std::variant<std::vector<Certificate>, KMV1_ErrorCode>
diff --git a/keystore2/src/remote_provisioning.rs b/keystore2/src/remote_provisioning.rs
index 639fe1e..be23ae5 100644
--- a/keystore2/src/remote_provisioning.rs
+++ b/keystore2/src/remote_provisioning.rs
@@ -45,7 +45,7 @@
 use std::collections::BTreeMap;
 use std::sync::atomic::{AtomicBool, Ordering};
 
-use crate::database::{CertificateChain, KeystoreDB, Uuid};
+use crate::database::{CertificateChain, KeyIdGuard, KeystoreDB, Uuid};
 use crate::error::{self, map_or_log_err, map_rem_prov_error, Error};
 use crate::globals::{get_keymint_device, get_remotely_provisioned_component, DB};
 use crate::metrics_store::log_rkp_error_stats;
@@ -73,6 +73,11 @@
         Self { security_level, km_uuid, is_hal_present: AtomicBool::new(true) }
     }
 
+    /// Returns the uuid for the KM instance attached to this RemProvState struct.
+    pub fn get_uuid(&self) -> Uuid {
+        self.km_uuid
+    }
+
     /// Checks if remote provisioning is enabled and partially caches the result. On a hybrid system
     /// remote provisioning can flip from being disabled to enabled depending on responses from the
     /// server, so unfortunately caching the presence or absence of the HAL is not enough to fully
@@ -121,7 +126,7 @@
         caller_uid: u32,
         params: &[KeyParameter],
         db: &mut KeystoreDB,
-    ) -> Result<Option<(AttestationKey, Certificate)>> {
+    ) -> Result<Option<(KeyIdGuard, AttestationKey, Certificate)>> {
         if !self.is_asymmetric_key(params) || !self.check_rem_prov_enabled(db)? {
             // There is no remote provisioning component for this security level on the
             // device. Return None so the underlying KM instance knows to use its
@@ -142,7 +147,8 @@
                     Ok(None)
                 }
                 Ok(v) => match v {
-                    Some(cert_chain) => Ok(Some((
+                    Some((guard, cert_chain)) => Ok(Some((
+                        guard,
                         AttestationKey {
                             keyBlob: cert_chain.private_key.to_vec(),
                             attestKeyParams: vec![],
@@ -433,7 +439,7 @@
     caller_uid: u32,
     db: &mut KeystoreDB,
     km_uuid: &Uuid,
-) -> Result<Option<CertificateChain>> {
+) -> Result<Option<(KeyIdGuard, CertificateChain)>> {
     match domain {
         Domain::APP => {
             // Attempt to get an Attestation Key once. If it fails, then the app doesn't
@@ -458,7 +464,7 @@
                             "key and failed silently. Something is very wrong."
                         ))
                     },
-                    |cert_chain| Ok(Some(cert_chain)),
+                    |(guard, cert_chain)| Ok(Some((guard, cert_chain))),
                 )
         }
         _ => Ok(None),
@@ -471,12 +477,12 @@
     caller_uid: u32,
     db: &mut KeystoreDB,
     km_uuid: &Uuid,
-) -> Result<Option<CertificateChain>> {
-    let cert_chain = db
+) -> Result<Option<(KeyIdGuard, CertificateChain)>> {
+    let guard_and_chain = db
         .retrieve_attestation_key_and_cert_chain(domain, caller_uid as i64, km_uuid)
         .context("In get_rem_prov_attest_key_helper: Failed to retrieve a key + cert chain")?;
-    match cert_chain {
-        Some(cert_chain) => Ok(Some(cert_chain)),
+    match guard_and_chain {
+        Some((guard, cert_chain)) => Ok(Some((guard, cert_chain))),
         // Either this app needs to be assigned a key, or the pool is empty. An error will
         // be thrown if there is no key available to assign. This will indicate that the app
         // should be nudged to provision more keys so keystore can retry.
@@ -598,10 +604,11 @@
             .context(format!("In get_attestation_key: unknown irpc id '{}'", irpc_id))?;
         let (_, _, km_uuid) = get_keymint_device(sec_level)?;
 
-        let cert_chain = get_rem_prov_attest_key(Domain::APP, caller_uid as u32, db, &km_uuid)
-            .context("In get_attestation_key")?;
-        match cert_chain {
-            Some(chain) => Ok(RemotelyProvisionedKey {
+        let guard_and_cert_chain =
+            get_rem_prov_attest_key(Domain::APP, caller_uid as u32, db, &km_uuid)
+                .context("In get_attestation_key")?;
+        match guard_and_cert_chain {
+            Some((_, chain)) => Ok(RemotelyProvisionedKey {
                 keyBlob: chain.private_key.to_vec(),
                 encodedCertChain: chain.cert_chain,
             }),
diff --git a/keystore2/src/security_level.rs b/keystore2/src/security_level.rs
index 4cf41c5..8574244 100644
--- a/keystore2/src/security_level.rs
+++ b/keystore2/src/security_level.rs
@@ -319,7 +319,7 @@
                 &*self.keymint,
                 key_id_guard,
                 &km_blob,
-                &blob_metadata,
+                blob_metadata.km_uuid().copied(),
                 operation_parameters,
                 |blob| loop {
                     match map_km_error({
@@ -557,7 +557,7 @@
                     &*self.keymint,
                     Some(key_id_guard),
                     &KeyBlob::Ref(&blob),
-                    &blob_metadata,
+                    blob_metadata.km_uuid().copied(),
                     &params,
                     |blob| {
                         let attest_key = Some(AttestationKey {
@@ -579,23 +579,40 @@
                 )
                 .context("In generate_key: Using user generated attestation key.")
                 .map(|(result, _)| result),
-            Some(AttestationKeyInfo::RemoteProvisioned { attestation_key, attestation_certs }) => {
-                map_km_error({
-                    let _wp = self.watch_millis(
-                        concat!(
-                            "In KeystoreSecurityLevel::generate_key (RemoteProvisioned): ",
-                            "calling generate_key.",
-                        ),
-                        5000, // Generate can take a little longer.
-                    );
-                    self.keymint.generateKey(&params, Some(&attestation_key))
-                })
+            Some(AttestationKeyInfo::RemoteProvisioned {
+                key_id_guard,
+                attestation_key,
+                attestation_certs,
+            }) => self
+                .upgrade_keyblob_if_required_with(
+                    &*self.keymint,
+                    Some(key_id_guard),
+                    &KeyBlob::Ref(&attestation_key.keyBlob),
+                    Some(self.rem_prov_state.get_uuid()),
+                    &[],
+                    |blob| {
+                        map_km_error({
+                            let _wp = self.watch_millis(
+                                concat!(
+                                    "In KeystoreSecurityLevel::generate_key (RemoteProvisioned): ",
+                                    "calling generate_key.",
+                                ),
+                                5000, // Generate can take a little longer.
+                            );
+                            let dynamic_attest_key = Some(AttestationKey {
+                                keyBlob: blob.to_vec(),
+                                attestKeyParams: vec![],
+                                issuerSubjectName: attestation_key.issuerSubjectName.clone(),
+                            });
+                            self.keymint.generateKey(&params, dynamic_attest_key.as_ref())
+                        })
+                    },
+                )
                 .context("While generating Key with remote provisioned attestation key.")
-                .map(|mut creation_result| {
-                    creation_result.certificateChain.push(attestation_certs);
-                    creation_result
-                })
-            }
+                .map(|(mut result, _)| {
+                    result.certificateChain.push(attestation_certs);
+                    result
+                }),
             None => map_km_error({
                 let _wp = self.watch_millis(
                     concat!(
@@ -781,7 +798,7 @@
                 &*self.keymint,
                 Some(wrapping_key_id_guard),
                 &wrapping_key_blob,
-                &wrapping_blob_metadata,
+                wrapping_blob_metadata.km_uuid().copied(),
                 &[],
                 |wrapping_blob| {
                     let _wp = self.watch_millis(
@@ -807,7 +824,7 @@
 
     fn store_upgraded_keyblob(
         key_id_guard: KeyIdGuard,
-        km_uuid: Option<&Uuid>,
+        km_uuid: Option<Uuid>,
         key_blob: &KeyBlob,
         upgraded_blob: &[u8],
     ) -> Result<()> {
@@ -817,7 +834,7 @@
 
         let mut new_blob_metadata = new_blob_metadata.unwrap_or_default();
         if let Some(uuid) = km_uuid {
-            new_blob_metadata.add(BlobMetaEntry::KmUuid(*uuid));
+            new_blob_metadata.add(BlobMetaEntry::KmUuid(uuid));
         }
 
         DB.with(|db| {
@@ -837,7 +854,7 @@
         km_dev: &dyn IKeyMintDevice,
         mut key_id_guard: Option<KeyIdGuard>,
         key_blob: &KeyBlob,
-        blob_metadata: &BlobMetaData,
+        km_uuid: Option<Uuid>,
         params: &[KeyParameter],
         f: F,
     ) -> Result<(T, Option<Vec<u8>>)>
@@ -853,13 +870,9 @@
                 if key_id_guard.is_some() {
                     // Unwrap cannot panic, because the is_some was true.
                     let kid = key_id_guard.take().unwrap();
-                    Self::store_upgraded_keyblob(
-                        kid,
-                        blob_metadata.km_uuid(),
-                        key_blob,
-                        upgraded_blob,
+                    Self::store_upgraded_keyblob(kid, km_uuid, key_blob, upgraded_blob).context(
+                        "In upgrade_keyblob_if_required_with: store_upgraded_keyblob failed",
                     )
-                    .context("In upgrade_keyblob_if_required_with: store_upgraded_keyblob failed")
                 } else {
                     Ok(())
                 }
@@ -872,11 +885,10 @@
         // upgrade was performed above and if one was given in the first place.
         if key_blob.force_reencrypt() {
             if let Some(kid) = key_id_guard {
-                Self::store_upgraded_keyblob(kid, blob_metadata.km_uuid(), key_blob, key_blob)
-                    .context(concat!(
-                        "In upgrade_keyblob_if_required_with: ",
-                        "store_upgraded_keyblob failed in forced reencrypt"
-                    ))?;
+                Self::store_upgraded_keyblob(kid, km_uuid, key_blob, key_blob).context(concat!(
+                    "In upgrade_keyblob_if_required_with: ",
+                    "store_upgraded_keyblob failed in forced reencrypt"
+                ))?;
             }
         }
         Ok((v, upgraded_blob))
diff --git a/ondevice-signing/KeystoreHmacKey.cpp b/ondevice-signing/KeystoreHmacKey.cpp
index 09677d7..916cbbc 100644
--- a/ondevice-signing/KeystoreHmacKey.cpp
+++ b/ondevice-signing/KeystoreHmacKey.cpp
@@ -49,17 +49,14 @@
 
 using android::base::unique_fd;
 
-// Keystore boot level that the odsign key uses
-static const int kOdsignBootLevel = 30;
-
-static KeyDescriptor getHmacKeyDescriptor() {
+static KeyDescriptor getHmacKeyDescriptor(const android::String16& keyAlias, int64_t keyNspace) {
     // AIDL parcelable objects don't have constructor
     static KeyDescriptor descriptor;
     static std::once_flag flag;
     std::call_once(flag, [&]() {
         descriptor.domain = Domain::SELINUX;
-        descriptor.alias = String16("ondevice-signing-hmac");
-        descriptor.nspace = 101;  // odsign_key
+        descriptor.alias = keyAlias + android::String16("-hmac");
+        descriptor.nspace = keyNspace;
     });
 
     return descriptor;
@@ -106,7 +103,7 @@
 
     KeyParameter boot_level;
     boot_level.tag = Tag::MAX_BOOT_LEVEL;
-    boot_level.value = KeyParameterValue::make<KeyParameterValue::integer>(kOdsignBootLevel);
+    boot_level.value = KeyParameterValue::make<KeyParameterValue::integer>(mKeyBootLevel);
     params.push_back(boot_level);
 
     KeyMetadata metadata;
@@ -133,7 +130,7 @@
         // Make sure this is an early boot key
         for (const auto& auth : keyEntryResponse.metadata.authorizations) {
             if (auth.keyParameter.tag == Tag::MAX_BOOT_LEVEL) {
-                if (auth.keyParameter.value.get<KeyParameterValue::integer>() == kOdsignBootLevel) {
+                if (auth.keyParameter.value.get<KeyParameterValue::integer>() == mKeyBootLevel) {
                     keyValid = true;
                     break;
                 }
@@ -152,9 +149,9 @@
     }
 }
 
-KeystoreHmacKey::KeystoreHmacKey() {
-    mDescriptor = getHmacKeyDescriptor();
-}
+KeystoreHmacKey::KeystoreHmacKey(const android::String16& keyAlias, int64_t keyNspace,
+                                 int keyBootLevel)
+    : mDescriptor(getHmacKeyDescriptor(keyAlias, keyNspace)), mKeyBootLevel(keyBootLevel) {}
 
 static std::vector<KeyParameter> getVerifyOpParameters() {
     std::vector<KeyParameter> opParameters;
diff --git a/ondevice-signing/KeystoreHmacKey.h b/ondevice-signing/KeystoreHmacKey.h
index 782969a..1a815a3 100644
--- a/ondevice-signing/KeystoreHmacKey.h
+++ b/ondevice-signing/KeystoreHmacKey.h
@@ -31,7 +31,7 @@
     using KeyDescriptor = ::android::system::keystore2::KeyDescriptor;
 
   public:
-    KeystoreHmacKey();
+    KeystoreHmacKey(const android::String16& keyAlias, int64_t keyNspace, int keyBootLevel);
     android::base::Result<void> initialize(android::sp<IKeystoreService> service,
                                            android::sp<IKeystoreSecurityLevel> securityLevel);
     android::base::Result<std::string> sign(const std::string& message) const;
@@ -44,4 +44,6 @@
     KeyDescriptor mDescriptor;
     android::sp<IKeystoreService> mService;
     android::sp<IKeystoreSecurityLevel> mSecurityLevel;
+
+    int mKeyBootLevel;
 };
diff --git a/ondevice-signing/KeystoreKey.cpp b/ondevice-signing/KeystoreKey.cpp
index 03bb6d5..6ce65d6 100644
--- a/ondevice-signing/KeystoreKey.cpp
+++ b/ondevice-signing/KeystoreKey.cpp
@@ -50,27 +50,24 @@
 using android::base::Error;
 using android::base::Result;
 
-// Keystore boot level that the odsign key uses
-static const int kOdsignBootLevel = 30;
-
-const std::string kPublicKeySignature = "/data/misc/odsign/publickey.signature";
-
-static KeyDescriptor getKeyDescriptor() {
+static KeyDescriptor getKeyDescriptor(const android::String16& keyAlias, int64_t keyNspace) {
     // AIDL parcelable objects don't have constructor
     static KeyDescriptor descriptor;
     static std::once_flag flag;
     std::call_once(flag, [&]() {
         descriptor.domain = Domain::SELINUX;
-        descriptor.alias = String16("ondevice-signing");
-        descriptor.nspace = 101;  // odsign_key
+        descriptor.alias = keyAlias;
+        descriptor.nspace = keyNspace;
     });
 
     return descriptor;
 }
 
-KeystoreKey::KeystoreKey() {
-    mDescriptor = getKeyDescriptor();
-}
+KeystoreKey::KeystoreKey(std::string signedPubKeyPath, const android::String16& keyAlias,
+                         int64_t keyNspace, int keyBootLevel)
+    : mDescriptor(getKeyDescriptor(keyAlias, keyNspace)),
+      mHmacKey(keyAlias, keyNspace, keyBootLevel), mSignedPubKeyPath(std::move(signedPubKeyPath)),
+      mKeyBootLevel(keyBootLevel) {}
 
 Result<std::vector<uint8_t>> KeystoreKey::createKey() {
     std::vector<KeyParameter> params;
@@ -113,7 +110,7 @@
 
     KeyParameter boot_level;
     boot_level.tag = Tag::MAX_BOOT_LEVEL;
-    boot_level.value = KeyParameterValue::make<KeyParameterValue::integer>(kOdsignBootLevel);
+    boot_level.value = KeyParameterValue::make<KeyParameterValue::integer>(mKeyBootLevel);
     params.push_back(boot_level);
 
     KeyMetadata metadata;
@@ -137,7 +134,7 @@
         return Error() << "Failed to sign public key.";
     }
 
-    if (!android::base::WriteStringToFile(*signature, kPublicKeySignature)) {
+    if (!android::base::WriteStringToFile(*signature, mSignedPubKeyPath)) {
         return Error() << "Can't write public key signature.";
     }
 
@@ -206,7 +203,7 @@
     bool foundBootLevel = false;
     for (const auto& auth : keyEntryResponse.metadata.authorizations) {
         if (auth.keyParameter.tag == Tag::MAX_BOOT_LEVEL) {
-            if (auth.keyParameter.value.get<KeyParameterValue::integer>() == kOdsignBootLevel) {
+            if (auth.keyParameter.value.get<KeyParameterValue::integer>() == mKeyBootLevel) {
                 foundBootLevel = true;
                 break;
             }
@@ -232,7 +229,7 @@
     std::string publicKeyString = {publicKey->begin(), publicKey->end()};
 
     std::string signature;
-    if (!android::base::ReadFileToString(kPublicKeySignature, &signature)) {
+    if (!android::base::ReadFileToString(mSignedPubKeyPath, &signature)) {
         return Error() << "Can't find signature for public key.";
     }
 
@@ -256,13 +253,15 @@
     return *existingKey;
 }
 
-Result<SigningKey*> KeystoreKey::getInstance() {
-    static KeystoreKey keystoreKey;
+Result<SigningKey*> KeystoreKey::getInstance(const std::string& signedPubKeyPath,
+                                             const android::String16& keyAlias, int64_t keyNspace,
+                                             int keyBootLevel) {
+    auto keystoreKey = new KeystoreKey(signedPubKeyPath, keyAlias, keyNspace, keyBootLevel);
 
-    if (!keystoreKey.initialize()) {
+    if (!keystoreKey->initialize()) {
         return Error() << "Failed to initialize keystore key.";
     } else {
-        return &keystoreKey;
+        return keystoreKey;
     }
 }
 
diff --git a/ondevice-signing/KeystoreKey.h b/ondevice-signing/KeystoreKey.h
index f2fbb70..3c9a0ab 100644
--- a/ondevice-signing/KeystoreKey.h
+++ b/ondevice-signing/KeystoreKey.h
@@ -36,13 +36,16 @@
 
   public:
     virtual ~KeystoreKey(){};
-    static android::base::Result<SigningKey*> getInstance();
+    static android::base::Result<SigningKey*> getInstance(const std::string& signedPubKeyPath,
+                                                          const android::String16& keyAlias,
+                                                          int64_t KeyNspace, int keyBootLevel);
 
     virtual android::base::Result<std::string> sign(const std::string& message) const;
     virtual android::base::Result<std::vector<uint8_t>> getPublicKey() const;
 
   private:
-    KeystoreKey();
+    KeystoreKey(std::string signedPubKeyPath, const android::String16& keyAlias, int64_t keyNspace,
+                int keyBootLevel);
     bool initialize();
     android::base::Result<std::vector<uint8_t>> verifyExistingKey();
     android::base::Result<std::vector<uint8_t>> createKey();
@@ -53,4 +56,7 @@
     android::sp<IKeystoreService> mService;
     android::sp<IKeystoreSecurityLevel> mSecurityLevel;
     std::vector<uint8_t> mPublicKey;
+
+    std::string mSignedPubKeyPath;
+    int mKeyBootLevel;
 };
diff --git a/ondevice-signing/VerityUtils.cpp b/ondevice-signing/VerityUtils.cpp
index 24a46b9..8ea0727 100644
--- a/ondevice-signing/VerityUtils.cpp
+++ b/ondevice-signing/VerityUtils.cpp
@@ -43,6 +43,11 @@
 using android::base::unique_fd;
 
 static const char* kFsVerityInitPath = "/system/bin/fsverity_init";
+static const char* kFsVerityProcPath = "/proc/sys/fs/verity";
+
+bool SupportsFsVerity() {
+    return access(kFsVerityProcPath, F_OK) == 0;
+}
 
 static std::string toHex(std::span<const uint8_t> data) {
     std::stringstream ss;
@@ -165,7 +170,7 @@
     return {};
 }
 
-static Result<std::string> enableFsVerity(int fd, const SigningKey& key) {
+Result<std::string> enableFsVerity(int fd, const SigningKey& key) {
     auto digest = createDigest(fd);
     if (!digest.ok()) {
         return Error() << digest.error();
diff --git a/ondevice-signing/include/VerityUtils.h b/ondevice-signing/include/VerityUtils.h
index 0559c35..0650563 100644
--- a/ondevice-signing/include/VerityUtils.h
+++ b/ondevice-signing/include/VerityUtils.h
@@ -26,6 +26,8 @@
 
 android::base::Result<void> addCertToFsVerityKeyring(const std::string& path, const char* keyName);
 android::base::Result<std::vector<uint8_t>> createDigest(const std::string& path);
+android::base::Result<std::string> enableFsVerity(int fd, const SigningKey& key);
+bool SupportsFsVerity();
 android::base::Result<std::map<std::string, std::string>>
 verifyAllFilesInVerity(const std::string& path);
 
diff --git a/ondevice-signing/odsign_main.cpp b/ondevice-signing/odsign_main.cpp
index 5c541ae..7be8b51 100644
--- a/ondevice-signing/odsign_main.cpp
+++ b/ondevice-signing/odsign_main.cpp
@@ -44,6 +44,12 @@
 
 using OdsignInfo = ::odsign::proto::OdsignInfo;
 
+// Keystore boot level that the odsign key uses
+const int kKeyBootLevel = 30;
+const std::string kPublicKeySignature = "/data/misc/odsign/publickey.signature";
+const android::String16 kKeyAlias{"ondevice-signing"};
+constexpr int kKeyNspace = 101;  // odsign_key
+
 const std::string kSigningKeyCert = "/data/misc/odsign/key.cert";
 const std::string kOdsignInfo = "/data/misc/odsign/odsign.info";
 const std::string kOdsignInfoSignature = "/data/misc/odsign/odsign.info.signature";
@@ -51,18 +57,11 @@
 const std::string kArtArtifactsDir = "/data/misc/apexdata/com.android.art/dalvik-cache";
 
 constexpr const char* kOdrefreshPath = "/apex/com.android.art/bin/odrefresh";
-constexpr const char* kCompOsVerifyPath = "/apex/com.android.compos/bin/compos_verify_key";
-constexpr const char* kFsVerityProcPath = "/proc/sys/fs/verity";
+constexpr const char* kCompOsVerifyPath = "/apex/com.android.compos/bin/compos_verify";
 
 constexpr bool kForceCompilation = false;
 constexpr bool kUseCompOs = true;
 
-const std::string kCompOsCert = "/data/misc/odsign/compos_key.cert";
-
-const std::string kCompOsCurrentPublicKey =
-    "/data/misc/apexdata/com.android.compos/current/key.pubkey";
-const std::string kCompOsPendingPublicKey =
-    "/data/misc/apexdata/com.android.compos/pending/key.pubkey";
 const std::string kCompOsPendingArtifactsDir = "/data/misc/apexdata/com.android.art/compos-pending";
 const std::string kCompOsInfo = kArtArtifactsDir + "/compos.info";
 const std::string kCompOsInfoSignature = kCompOsInfo + ".signature";
@@ -85,12 +84,6 @@
 
 namespace {
 
-std::vector<uint8_t> readBytesFromFile(const std::string& path) {
-    std::string str;
-    android::base::ReadFileToString(path, &str);
-    return std::vector<uint8_t>(str.begin(), str.end());
-}
-
 bool rename(const std::string& from, const std::string& to) {
     std::error_code ec;
     std::filesystem::rename(from, to, ec);
@@ -182,108 +175,6 @@
     return createSelfSignedCertificate(*publicKey, keySignFunction, outPath);
 }
 
-Result<std::vector<uint8_t>> extractRsaPublicKeyFromLeafCert(const SigningKey& key,
-                                                             const std::string& certPath,
-                                                             const std::string& expectedCn) {
-    if (access(certPath.c_str(), F_OK) < 0) {
-        return ErrnoError() << "Certificate not found: " << certPath;
-    }
-    auto trustedPublicKey = key.getPublicKey();
-    if (!trustedPublicKey.ok()) {
-        return Error() << "Failed to retrieve signing public key: " << trustedPublicKey.error();
-    }
-
-    auto existingCertInfo = verifyAndExtractCertInfoFromX509(certPath, trustedPublicKey.value());
-    if (!existingCertInfo.ok()) {
-        return Error() << "Failed to verify certificate at " << certPath << ": "
-                       << existingCertInfo.error();
-    }
-
-    auto& actualCn = existingCertInfo.value().subjectCn;
-    if (actualCn != expectedCn) {
-        return Error() << "CN of existing certificate at " << certPath << " is " << actualCn
-                       << ", should be " << expectedCn;
-    }
-
-    return existingCertInfo.value().subjectRsaPublicKey;
-}
-
-// Attempt to start a CompOS VM for the specified instance to get it to
-// verify ita public key & key blob.
-bool startCompOsAndVerifyKey(CompOsInstance instance) {
-    bool isCurrent = instance == CompOsInstance::kCurrent;
-    const std::string& keyPath = isCurrent ? kCompOsCurrentPublicKey : kCompOsPendingPublicKey;
-    if (access(keyPath.c_str(), R_OK) != 0) {
-        return false;
-    }
-
-    const char* const argv[] = {kCompOsVerifyPath, "--instance", isCurrent ? "current" : "pending"};
-    int result =
-        logwrap_fork_execvp(arraysize(argv), argv, nullptr, false, LOG_ALOG, false, nullptr);
-    if (result == 0) {
-        return true;
-    }
-
-    LOG(ERROR) << kCompOsVerifyPath << " returned " << result;
-    return false;
-}
-
-Result<std::vector<uint8_t>> verifyCompOsKey(const SigningKey& signingKey) {
-    bool verified = false;
-
-    // If a pending key has been generated we don't know if it is the correct
-    // one for the pending CompOS VM, so we need to start it and ask it.
-    if (startCompOsAndVerifyKey(CompOsInstance::kPending)) {
-        verified = true;
-    }
-
-    if (!verified) {
-        // Alternatively if we signed a cert for the key on a previous boot, then we
-        // can use that straight away.
-        auto existing_key =
-            extractRsaPublicKeyFromLeafCert(signingKey, kCompOsCert, kCompOsSubject.commonName);
-        if (existing_key.ok()) {
-            LOG(INFO) << "Found and verified existing CompOS public key certificate: "
-                      << kCompOsCert;
-            return existing_key.value();
-        }
-    }
-
-    // Otherwise, if there is an existing key that we haven't signed yet, then we can sign
-    // it now if CompOS confirms it's OK.
-    if (!verified && startCompOsAndVerifyKey(CompOsInstance::kCurrent)) {
-        verified = true;
-    }
-
-    if (!verified) {
-        return Error() << "No valid CompOS key present.";
-    }
-
-    // If the pending key was verified it will have been promoted to current, so
-    // at this stage if there is a key it will be the current one.
-    auto publicKey = readBytesFromFile(kCompOsCurrentPublicKey);
-    if (publicKey.empty()) {
-        // This shouldn`t really happen.
-        return Error() << "Failed to read CompOS key.";
-    }
-
-    // One way or another we now have a valid public key. Persist a certificate so
-    // we can simplify the checks on subsequent boots.
-
-    auto signFunction = [&](const std::string& to_be_signed) {
-        return signingKey.sign(to_be_signed);
-    };
-    auto certStatus = createLeafCertificate(kCompOsSubject, publicKey, signFunction,
-                                            kSigningKeyCert, kCompOsCert);
-    if (!certStatus.ok()) {
-        return Error() << "Failed to create CompOS cert: " << certStatus.error();
-    }
-
-    LOG(INFO) << "Verified key, wrote new CompOS cert";
-
-    return publicKey;
-}
-
 Result<std::map<std::string, std::string>> computeDigests(const std::string& path) {
     std::error_code ec;
     std::map<std::string, std::string> digests;
@@ -439,27 +330,12 @@
     return {};
 }
 
-Result<std::vector<uint8_t>> addCompOsCertToFsVerityKeyring(const SigningKey& signingKey) {
-    auto publicKey = verifyCompOsKey(signingKey);
-    if (!publicKey.ok()) {
-        return publicKey.error();
-    }
-
-    auto cert_add_result = addCertToFsVerityKeyring(kCompOsCert, "fsv_compos");
-    if (!cert_add_result.ok()) {
-        // Best efforts only - nothing we can do if deletion fails.
-        unlink(kCompOsCert.c_str());
-        return Error() << "Failed to add CompOS certificate to fs-verity keyring: "
-                       << cert_add_result.error();
-    }
-
-    return publicKey;
-}
-
-Result<OdsignInfo> getComposInfo(const std::vector<uint8_t>& compos_key) {
-    std::string compos_signature;
-    if (!android::base::ReadFileToString(kCompOsInfoSignature, &compos_signature)) {
-        return ErrnoError() << "Failed to read " << kCompOsInfoSignature;
+Result<OdsignInfo> getComposInfo() {
+    const char* const argv[] = {kCompOsVerifyPath, "--instance", "current"};
+    int result =
+        logwrap_fork_execvp(arraysize(argv), argv, nullptr, false, LOG_ALOG, false, nullptr);
+    if (result != 0) {
+        return Error() << kCompOsVerifyPath << " returned " << result;
     }
 
     std::string compos_info_str;
@@ -467,21 +343,12 @@
         return ErrnoError() << "Failed to read " << kCompOsInfo;
     }
 
-    // Delete the files - if they're valid we don't need them any more, and
-    // they'd confuse artifact verification; if they're not we never need to
-    // look at them again.
+    // Delete the files - we don't need them any more, and they'd confuse
+    // artifact verification
     if (unlink(kCompOsInfo.c_str()) != 0 || unlink(kCompOsInfoSignature.c_str()) != 0) {
         return ErrnoError() << "Unable to delete CompOS info/signature file";
     }
 
-    // Verify the signature
-    auto verified = verifyRsaPublicKeySignature(compos_info_str, compos_signature, compos_key);
-    if (!verified.ok()) {
-        return Error() << kCompOsInfoSignature << " does not match.";
-    } else {
-        LOG(INFO) << kCompOsInfoSignature << " matches.";
-    }
-
     OdsignInfo compos_info;
     if (!compos_info.ParseFromString(compos_info_str)) {
         return Error() << "Failed to parse " << kCompOsInfo;
@@ -491,8 +358,7 @@
     return compos_info;
 }
 
-art::odrefresh::ExitCode checkCompOsPendingArtifacts(const std::vector<uint8_t>& compos_key,
-                                                     const SigningKey& signing_key,
+art::odrefresh::ExitCode checkCompOsPendingArtifacts(const SigningKey& signing_key,
                                                      bool* digests_verified) {
     if (!directoryHasContent(kCompOsPendingArtifactsDir)) {
         return art::odrefresh::ExitCode::kCompilationRequired;
@@ -527,7 +393,7 @@
 
     // Make sure the artifacts we have are genuinely produced by the current
     // instance of CompOS.
-    auto compos_info = getComposInfo(compos_key);
+    auto compos_info = getComposInfo();
     if (!compos_info.ok()) {
         LOG(WARNING) << compos_info.error();
     } else {
@@ -591,15 +457,15 @@
         LOG(INFO) << "Device doesn't support updatable APEX, exiting.";
         return 0;
     }
-
-    auto keystoreResult = KeystoreKey::getInstance();
+    auto keystoreResult =
+        KeystoreKey::getInstance(kPublicKeySignature, kKeyAlias, kKeyNspace, kKeyBootLevel);
     if (!keystoreResult.ok()) {
         LOG(ERROR) << "Could not create keystore key: " << keystoreResult.error();
         return -1;
     }
     SigningKey* key = keystoreResult.value();
 
-    bool supportsFsVerity = access(kFsVerityProcPath, F_OK) == 0;
+    bool supportsFsVerity = SupportsFsVerity();
     if (!supportsFsVerity) {
         LOG(INFO) << "Device doesn't support fsverity. Falling back to full verification.";
     }
@@ -633,13 +499,7 @@
     bool digests_verified = false;
 
     if (useCompOs) {
-        auto compos_key = addCompOsCertToFsVerityKeyring(*key);
-        if (!compos_key.ok()) {
-            LOG(WARNING) << compos_key.error();
-        } else {
-            odrefresh_status =
-                checkCompOsPendingArtifacts(compos_key.value(), *key, &digests_verified);
-        }
+        odrefresh_status = checkCompOsPendingArtifacts(*key, &digests_verified);
     }
 
     if (odrefresh_status == art::odrefresh::ExitCode::kCompilationRequired) {