Merge "Revert "Add dependency on keymint cpp lib""
diff --git a/diced/Android.bp b/diced/Android.bp
index 525828e..e13d863 100644
--- a/diced/Android.bp
+++ b/diced/Android.bp
@@ -138,6 +138,24 @@
     init_rc: ["diced.rc"],
 }
 
+rust_binary {
+    name: "diced.microdroid",
+    srcs: ["src/diced_main.rs"],
+    prefer_rlib: true,
+    rustlibs: [
+        "android.hardware.security.dice-V1-rust",
+        "libandroid_logger",
+        "libbinder_rs",
+        "libdiced",
+        "libdiced_open_dice_cbor",
+        "libdiced_sample_inputs",
+        "libdiced_utils",
+        "liblog_rust",
+    ],
+    init_rc: ["diced.microdroid.rc"],
+    bootstrap: true,
+}
+
 rust_test {
     name: "diced_test",
     crate_name: "diced_test",
diff --git a/diced/diced.microdroid.rc b/diced/diced.microdroid.rc
new file mode 100644
index 0000000..2226f47
--- /dev/null
+++ b/diced/diced.microdroid.rc
@@ -0,0 +1,13 @@
+# Start the Diced service.
+#
+# See system/core/init/README.md for information on the init.rc language.
+
+service diced /system/bin/diced.microdroid
+    class main
+    user diced
+    group diced
+    # The diced service must not be allowed to restart.
+    # If it crashes for any reason security critical state is lost.
+    # The only remedy is to restart the device.
+    oneshot
+    writepid /dev/cpuset/foreground/tasks
diff --git a/fsverity/Android.bp b/fsverity/Android.bp
index 5c3d6a0..2fc3c01 100644
--- a/fsverity/Android.bp
+++ b/fsverity/Android.bp
@@ -53,3 +53,14 @@
         "com.android.compos",
     ],
 }
+
+cc_library_static {
+    name: "libfsverity_digests_proto_cc",
+    proto: {
+        type: "lite",
+        static: true,
+        canonical_path_from_root: false,
+        export_proto_headers: true,
+    },
+    srcs: ["fsverity_digests.proto"],
+}
diff --git a/keystore2/aidl/android/security/maintenance/IKeystoreMaintenance.aidl b/keystore2/aidl/android/security/maintenance/IKeystoreMaintenance.aidl
index 6a37c78..3df5936 100644
--- a/keystore2/aidl/android/security/maintenance/IKeystoreMaintenance.aidl
+++ b/keystore2/aidl/android/security/maintenance/IKeystoreMaintenance.aidl
@@ -23,10 +23,15 @@
  * user's password.
  * @hide
  */
- @SensitiveData
+@SensitiveData
 interface IKeystoreMaintenance {
 
     /**
+     * Special value indicating the callers uid.
+     */
+    const int UID_SELF = -1;
+
+    /**
      * Allows LockSettingsService to inform keystore about adding a new user.
      * Callers require 'AddUser' permission.
      *
@@ -115,6 +120,10 @@
      * The source may be specified by Domain::APP, Domain::SELINUX, or Domain::KEY_ID. The target
      * may be specified by Domain::APP or Domain::SELINUX.
      *
+     * If Domain::APP is selected in either source or destination, nspace must be set to UID_SELF,
+     * implying the caller's UID. If the caller has the MIGRATE_ANY_KEY permission, Domain::APP may
+     * be used with other nspace values which then indicates the UID of a different application.
+     *
      * ## Error conditions:
      * `ResponseCode::PERMISSION_DENIED` - If the caller lacks any of the required permissions.
      * `ResponseCode::KEY_NOT_FOUND` - If the source did not exist.
@@ -131,4 +140,22 @@
      * Tag::ROLLBACK_RESISTANCE may or may not be rendered unusable.
      */
     void deleteAllKeys();
+
+    /**
+     * List all entries accessible by the caller in the given `domain` and `nspace`.
+     *
+     * Callers either has to have the `GET_INFO` permission for the requested namespace or `LIST`
+     * permission to list all the entries.
+     *
+     * ## Error conditions
+     * `ResponseCode::INVALID_ARGUMENT` if `domain` is other than `Domain::APP` or `Domain::SELINUX`
+     * `ResponseCode::PERMISSION_DENIED` if the caller does not have the permission
+     *
+     * @param domain `Domain::APP` or `Domain::SELINUX`.
+     *
+     * @param nspace The SELinux keystore2_key namespace.
+     *
+     * @return List of KeyDescriptors.
+     */
+    KeyDescriptor[] listEntries(in Domain domain, in long nspace);
 }
diff --git a/keystore2/legacykeystore/lib.rs b/keystore2/legacykeystore/lib.rs
index da60297..13a9143 100644
--- a/keystore2/legacykeystore/lib.rs
+++ b/keystore2/legacykeystore/lib.rs
@@ -25,8 +25,8 @@
 };
 use anyhow::{Context, Result};
 use keystore2::{
-    async_task::AsyncTask, legacy_blob::LegacyBlobLoader, maintenance::DeleteListener,
-    maintenance::Domain, utils::watchdog as wd,
+    async_task::AsyncTask, error::anyhow_error_to_cstring, legacy_blob::LegacyBlobLoader,
+    maintenance::DeleteListener, maintenance::Domain, utils::watchdog as wd,
 };
 use rusqlite::{
     params, Connection, OptionalExtension, Transaction, TransactionBehavior, NO_PARAMS,
@@ -226,7 +226,10 @@
             if log_error {
                 log::error!("{:?}", e);
             }
-            Err(BinderStatus::new_service_specific_error(rc, None))
+            Err(BinderStatus::new_service_specific_error(
+                rc,
+                anyhow_error_to_cstring(&e).as_deref(),
+            ))
         },
         handle_ok,
     )
diff --git a/keystore2/src/apc.rs b/keystore2/src/apc.rs
index 0096686..7d56dc9 100644
--- a/keystore2/src/apc.rs
+++ b/keystore2/src/apc.rs
@@ -21,6 +21,7 @@
     sync::{mpsc::Sender, Arc, Mutex},
 };
 
+use crate::error::anyhow_error_to_cstring;
 use crate::utils::{compat_2_response_code, ui_opts_2_compat, watchdog as wd};
 use android_security_apc::aidl::android::security::apc::{
     IConfirmationCallback::IConfirmationCallback,
@@ -110,7 +111,10 @@
                     _ => ResponseCode::SYSTEM_ERROR.0,
                 },
             };
-            Err(BinderStatus::new_service_specific_error(rc, None))
+            Err(BinderStatus::new_service_specific_error(
+                rc,
+                anyhow_error_to_cstring(&e).as_deref(),
+            ))
         },
         handle_ok,
     )
diff --git a/keystore2/src/authorization.rs b/keystore2/src/authorization.rs
index 516a860..64b498f 100644
--- a/keystore2/src/authorization.rs
+++ b/keystore2/src/authorization.rs
@@ -15,6 +15,7 @@
 //! This module implements IKeystoreAuthorization AIDL interface.
 
 use crate::error::Error as KeystoreError;
+use crate::error::anyhow_error_to_cstring;
 use crate::globals::{ENFORCEMENTS, SUPER_KEY, DB, LEGACY_MIGRATOR};
 use crate::permission::KeystorePerm;
 use crate::super_key::UserState;
@@ -88,7 +89,10 @@
                     // as well.
                     _ => ResponseCode::SYSTEM_ERROR.0,
                 };
-                return Err(BinderStatus::new_service_specific_error(rc, None));
+                return Err(BinderStatus::new_service_specific_error(
+                    rc,
+                    anyhow_error_to_cstring(&e).as_deref(),
+                ));
             }
             let rc = match root_cause.downcast_ref::<Error>() {
                 Some(Error::Rc(rcode)) => rcode.0,
@@ -98,7 +102,10 @@
                     _ => ResponseCode::SYSTEM_ERROR.0,
                 },
             };
-            Err(BinderStatus::new_service_specific_error(rc, None))
+            Err(BinderStatus::new_service_specific_error(
+                rc,
+                anyhow_error_to_cstring(&e).as_deref(),
+            ))
         },
         handle_ok,
     )
diff --git a/keystore2/src/error.rs b/keystore2/src/error.rs
index 84d741f..f34c5da 100644
--- a/keystore2/src/error.rs
+++ b/keystore2/src/error.rs
@@ -37,6 +37,7 @@
 };
 use keystore2_selinux as selinux;
 use std::cmp::PartialEq;
+use std::ffi::CString;
 
 /// This is the main Keystore error type. It wraps the Keystore `ResponseCode` generated
 /// from AIDL in the `Rc` variant and Keymint `ErrorCode` in the Km variant.
@@ -189,6 +190,20 @@
     )
 }
 
+/// This function turns an anyhow error into an optional CString.
+/// This is especially useful to add a message string to a service specific error.
+/// If the formatted string was not convertible because it contained a nul byte,
+/// None is returned and a warning is logged.
+pub fn anyhow_error_to_cstring(e: &anyhow::Error) -> Option<CString> {
+    match CString::new(format!("{:?}", e)) {
+        Ok(msg) => Some(msg),
+        Err(_) => {
+            log::warn!("Cannot convert error message to CStr. It contained a nul byte.");
+            None
+        }
+    }
+}
+
 /// This function behaves similar to map_or_log_error, but it does not log the errors, instead
 /// it calls map_err on the error before mapping it to a binder result allowing callers to
 /// log or transform the error before mapping it.
@@ -205,7 +220,10 @@
         |e| {
             let e = map_err(e);
             let rc = get_error_code(&e);
-            Err(BinderStatus::new_service_specific_error(rc, None))
+            Err(BinderStatus::new_service_specific_error(
+                rc,
+                anyhow_error_to_cstring(&e).as_deref(),
+            ))
         },
         handle_ok,
     )
diff --git a/keystore2/src/maintenance.rs b/keystore2/src/maintenance.rs
index ca73820..d5feee1 100644
--- a/keystore2/src/maintenance.rs
+++ b/keystore2/src/maintenance.rs
@@ -22,12 +22,14 @@
 use crate::globals::{DB, LEGACY_MIGRATOR, SUPER_KEY};
 use crate::permission::{KeyPerm, KeystorePerm};
 use crate::super_key::UserState;
-use crate::utils::{check_key_permission, check_keystore_permission, watchdog as wd};
+use crate::utils::{
+    check_key_permission, check_keystore_permission, list_key_entries, watchdog as wd,
+};
 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
     IKeyMintDevice::IKeyMintDevice, SecurityLevel::SecurityLevel,
 };
 use android_security_maintenance::aidl::android::security::maintenance::{
-    IKeystoreMaintenance::{BnKeystoreMaintenance, IKeystoreMaintenance},
+    IKeystoreMaintenance::{BnKeystoreMaintenance, IKeystoreMaintenance, UID_SELF},
     UserState::UserState as AidlUserState,
 };
 use android_security_maintenance::binder::{
@@ -37,6 +39,7 @@
 use android_system_keystore2::aidl::android::system::keystore2::ResponseCode::ResponseCode;
 use anyhow::{Context, Result};
 use keystore2_crypto::Password;
+use keystore2_selinux as selinux;
 
 /// Reexport Domain for the benefit of DeleteListener
 pub use android_system_keystore2::aidl::android::system::keystore2::Domain::Domain;
@@ -214,46 +217,64 @@
     }
 
     fn migrate_key_namespace(source: &KeyDescriptor, destination: &KeyDescriptor) -> Result<()> {
-        let caller_uid = ThreadState::get_calling_uid();
         let migrate_any_key_permission =
             check_keystore_permission(KeystorePerm::MigrateAnyKey).is_ok();
 
-        DB.with(|db| {
-            let key_id_guard = match source.domain {
-                Domain::APP | Domain::SELINUX | Domain::KEY_ID => {
-                    let (key_id_guard, _) = LEGACY_MIGRATOR
-                        .with_try_migrate(source, caller_uid, || {
-                            db.borrow_mut().load_key_entry(
-                                source,
-                                KeyType::Client,
-                                KeyEntryLoadBits::NONE,
-                                caller_uid,
-                                |k, av| {
-                                    if !migrate_any_key_permission {
-                                        check_key_permission(KeyPerm::Use, k, &av)?;
-                                        check_key_permission(KeyPerm::Delete, k, &av)?;
-                                        check_key_permission(KeyPerm::Grant, k, &av)?;
-                                    }
-                                    Ok(())
-                                },
-                            )
-                        })
-                        .context("In migrate_key_namespace: Failed to load key blob.")?;
-                    key_id_guard
-                }
-                _ => {
-                    return Err(Error::Rc(ResponseCode::INVALID_ARGUMENT)).context(concat!(
-                        "In migrate_key_namespace: ",
-                        "Source domain must be one of APP, SELINUX, or KEY_ID."
-                    ))
-                }
-            };
+        let src_uid = match source.domain {
+            Domain::SELINUX | Domain::KEY_ID => ThreadState::get_calling_uid(),
+            Domain::APP if source.nspace == UID_SELF.into() => ThreadState::get_calling_uid(),
+            Domain::APP if source.nspace != UID_SELF.into() && migrate_any_key_permission => {
+                source.nspace as u32
+            }
+            _ => {
+                return Err(Error::Rc(ResponseCode::INVALID_ARGUMENT)).context(
+                    "In migrate_key_namespace:
+                     Source domain must be one of APP, SELINUX, or KEY_ID.",
+                )
+            }
+        };
 
-            db.borrow_mut().migrate_key_namespace(key_id_guard, destination, caller_uid, |k| {
-                if !migrate_any_key_permission {
-                    check_key_permission(KeyPerm::Rebind, k, &None)?;
+        let dest_uid = match destination.domain {
+            Domain::SELINUX => ThreadState::get_calling_uid(),
+            Domain::APP if destination.nspace == UID_SELF.into() => ThreadState::get_calling_uid(),
+            Domain::APP if destination.nspace != UID_SELF.into() && migrate_any_key_permission => {
+                destination.nspace as u32
+            }
+            _ => {
+                return Err(Error::Rc(ResponseCode::INVALID_ARGUMENT)).context(
+                    "In migrate_key_namespace:
+                     Destination domain must be one of APP or SELINUX.",
+                )
+            }
+        };
+
+        DB.with(|db| {
+            let (key_id_guard, _) = LEGACY_MIGRATOR
+                .with_try_migrate(source, src_uid, || {
+                    db.borrow_mut().load_key_entry(
+                        source,
+                        KeyType::Client,
+                        KeyEntryLoadBits::NONE,
+                        src_uid,
+                        |k, av| {
+                            if migrate_any_key_permission {
+                                Ok(())
+                            } else {
+                                check_key_permission(KeyPerm::Use, k, &av)?;
+                                check_key_permission(KeyPerm::Delete, k, &av)?;
+                                check_key_permission(KeyPerm::Grant, k, &av)
+                            }
+                        },
+                    )
+                })
+                .context("In migrate_key_namespace: Failed to load key blob.")?;
+
+            db.borrow_mut().migrate_key_namespace(key_id_guard, destination, dest_uid, |k| {
+                if migrate_any_key_permission {
+                    Ok(())
+                } else {
+                    check_key_permission(KeyPerm::Rebind, k, &None)
                 }
-                Ok(())
             })
         })
     }
@@ -266,6 +287,30 @@
 
         Maintenance::call_on_all_security_levels("deleteAllKeys", |dev| dev.deleteAllKeys())
     }
+
+    fn list_entries(domain: Domain, nspace: i64) -> Result<Vec<KeyDescriptor>> {
+        let k = match domain {
+            Domain::APP | Domain::SELINUX => KeyDescriptor{domain, nspace, ..Default::default()},
+            _ => return Err(Error::perm()).context(
+                "In list_entries: List entries is only supported for Domain::APP and Domain::SELINUX."
+            ),
+        };
+
+        // The caller has to have either GetInfo for the namespace or List permission
+        check_key_permission(KeyPerm::GetInfo, &k, &None)
+            .or_else(|e| {
+                if Some(&selinux::Error::PermissionDenied)
+                    == e.root_cause().downcast_ref::<selinux::Error>()
+                {
+                    check_keystore_permission(KeystorePerm::List)
+                } else {
+                    Err(e)
+                }
+            })
+            .context("In list_entries: While checking key and keystore permission.")?;
+
+        DB.with(|db| list_key_entries(&mut db.borrow_mut(), domain, nspace))
+    }
 }
 
 impl Interface for Maintenance {}
@@ -315,6 +360,11 @@
         map_or_log_err(Self::migrate_key_namespace(source, destination), Ok)
     }
 
+    fn listEntries(&self, domain: Domain, namespace: i64) -> BinderResult<Vec<KeyDescriptor>> {
+        let _wp = wd::watch_millis("IKeystoreMaintenance::listEntries", 500);
+        map_or_log_err(Self::list_entries(domain, namespace), Ok)
+    }
+
     fn deleteAllKeys(&self) -> BinderResult<()> {
         let _wp = wd::watch_millis("IKeystoreMaintenance::deleteAllKeys", 500);
         map_or_log_err(Self::delete_all_keys(), Ok)
diff --git a/keystore2/src/service.rs b/keystore2/src/service.rs
index 4697481..2725dc2 100644
--- a/keystore2/src/service.rs
+++ b/keystore2/src/service.rs
@@ -22,7 +22,7 @@
 use crate::security_level::KeystoreSecurityLevel;
 use crate::utils::{
     check_grant_permission, check_key_permission, check_keystore_permission,
-    key_parameters_to_authorizations, watchdog as wd,
+    key_parameters_to_authorizations, list_key_entries, watchdog as wd,
 };
 use crate::{
     database::Uuid,
@@ -286,22 +286,7 @@
             Ok(()) => {}
         };
 
-        let mut result = LEGACY_MIGRATOR
-            .list_uid(k.domain, k.nspace)
-            .context("In list_entries: Trying to list legacy keys.")?;
-
-        result.append(
-            &mut DB
-                .with(|db| {
-                    let mut db = db.borrow_mut();
-                    db.list(k.domain, k.nspace, KeyType::Client)
-                })
-                .context("In list_entries: Trying to list keystore database.")?,
-        );
-
-        result.sort_unstable();
-        result.dedup();
-        Ok(result)
+        DB.with(|db| list_key_entries(&mut db.borrow_mut(), k.domain, k.nspace))
     }
 
     fn delete_key(&self, key: &KeyDescriptor) -> Result<()> {
diff --git a/keystore2/src/utils.rs b/keystore2/src/utils.rs
index f6d92ee..82e6700 100644
--- a/keystore2/src/utils.rs
+++ b/keystore2/src/utils.rs
@@ -18,6 +18,10 @@
 use crate::error::{map_binder_status, Error, ErrorCode};
 use crate::permission;
 use crate::permission::{KeyPerm, KeyPermSet, KeystorePerm};
+use crate::{
+    database::{KeyType, KeystoreDB},
+    globals::LEGACY_MIGRATOR,
+};
 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
     KeyCharacteristics::KeyCharacteristics, Tag::Tag,
 };
@@ -27,9 +31,9 @@
     ResponseCode::ResponseCode as ApcResponseCode,
 };
 use android_system_keystore2::aidl::android::system::keystore2::{
-    Authorization::Authorization, KeyDescriptor::KeyDescriptor,
+    Authorization::Authorization, Domain::Domain, KeyDescriptor::KeyDescriptor,
 };
-use anyhow::Context;
+use anyhow::{Context, Result};
 use binder::{Strong, ThreadState};
 use keystore2_apc_compat::{
     ApcCompatUiOptions, APC_COMPAT_ERROR_ABORTED, APC_COMPAT_ERROR_CANCELLED,
@@ -199,6 +203,28 @@
     rustutils::users::multiuser_get_user_id(uid)
 }
 
+/// List all key aliases for a given domain + namespace.
+pub fn list_key_entries(
+    db: &mut KeystoreDB,
+    domain: Domain,
+    namespace: i64,
+) -> Result<Vec<KeyDescriptor>> {
+    let mut result = Vec::new();
+    result.append(
+        &mut LEGACY_MIGRATOR
+            .list_uid(domain, namespace)
+            .context("In list_key_entries: Trying to list legacy keys.")?,
+    );
+    result.append(
+        &mut db
+            .list(domain, namespace, KeyType::Client)
+            .context("In list_key_entries: Trying to list keystore database.")?,
+    );
+    result.sort_unstable();
+    result.dedup();
+    Ok(result)
+}
+
 /// This module provides helpers for simplified use of the watchdog module.
 #[cfg(feature = "watchdog")]
 pub mod watchdog {