diff --git a/microdroid_manager/src/dice.rs b/microdroid_manager/src/dice.rs
index 27905c9..a576416 100644
--- a/microdroid_manager/src/dice.rs
+++ b/microdroid_manager/src/dice.rs
@@ -1,10 +1,10 @@
-// Copyright 2022, The Android Open Source Project
+// Copyright 2023 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
+//      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,
@@ -12,142 +12,44 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-//! Logic for handling the DICE values and boot operations.
-
-use anyhow::{anyhow, bail, Context, Error, Result};
-use byteorder::{NativeEndian, ReadBytesExt};
+use crate::dice_driver::DiceDriver;
+use crate::{is_debuggable, MicrodroidData};
+use anyhow::{bail, Context, Result};
 use ciborium::{cbor, ser};
-use diced_open_dice::{
-    bcc_handover_parse, retry_bcc_main_flow, BccHandover, Config, DiceArtifacts, DiceMode, Hash,
-    Hidden, InputValues, OwnedDiceArtifacts,
-};
-use keystore2_crypto::ZVec;
-use libc::{c_void, mmap, munmap, MAP_FAILED, MAP_PRIVATE, PROT_READ};
+use diced_open_dice::OwnedDiceArtifacts;
 use microdroid_metadata::PayloadMetadata;
-use openssl::hkdf::hkdf;
-use openssl::md::Md;
-use std::fs;
-use std::os::unix::io::AsRawFd;
-use std::path::{Path, PathBuf};
-use std::ptr::null_mut;
-use std::slice;
+use openssl::sha::Sha512;
 
-/// Artifacts that are mapped into the process address space from the driver.
-pub enum DiceDriver<'a> {
-    Real {
-        driver_path: PathBuf,
-        mmap_addr: *mut c_void,
-        mmap_size: usize,
-        bcc_handover: BccHandover<'a>,
-    },
-    Fake(OwnedDiceArtifacts),
-}
-
-impl DiceDriver<'_> {
-    fn dice_artifacts(&self) -> &dyn DiceArtifacts {
-        match self {
-            Self::Real { bcc_handover, .. } => bcc_handover,
-            Self::Fake(owned_dice_artifacts) => owned_dice_artifacts,
-        }
+/// Perform an open DICE derivation for the payload.
+pub fn dice_derivation(
+    dice: DiceDriver,
+    verified_data: &MicrodroidData,
+    payload_metadata: &PayloadMetadata,
+) -> Result<OwnedDiceArtifacts> {
+    // Calculate compound digests of code and authorities
+    let mut code_hash_ctx = Sha512::new();
+    let mut authority_hash_ctx = Sha512::new();
+    code_hash_ctx.update(verified_data.apk_data.root_hash.as_ref());
+    authority_hash_ctx.update(verified_data.apk_data.pubkey.as_ref());
+    for extra_apk in &verified_data.extra_apks_data {
+        code_hash_ctx.update(extra_apk.root_hash.as_ref());
+        authority_hash_ctx.update(extra_apk.pubkey.as_ref());
     }
-
-    pub fn new(driver_path: &Path) -> Result<Self> {
-        if driver_path.exists() {
-            log::info!("Using DICE values from driver");
-        } else if super::is_strict_boot() {
-            bail!("Strict boot requires DICE value from driver but none were found");
-        } else {
-            log::warn!("Using sample DICE values");
-            let dice_artifacts = diced_sample_inputs::make_sample_bcc_and_cdis()
-                .expect("Failed to create sample dice artifacts.");
-            return Ok(Self::Fake(dice_artifacts));
-        };
-
-        let mut file = fs::File::open(driver_path)
-            .map_err(|error| Error::new(error).context("Opening driver"))?;
-        let mmap_size =
-            file.read_u64::<NativeEndian>()
-                .map_err(|error| Error::new(error).context("Reading driver"))? as usize;
-        // SAFETY: It's safe to map the driver as the service will only create a single
-        // mapping per process.
-        let mmap_addr = unsafe {
-            let fd = file.as_raw_fd();
-            mmap(null_mut(), mmap_size, PROT_READ, MAP_PRIVATE, fd, 0)
-        };
-        if mmap_addr == MAP_FAILED {
-            bail!("Failed to mmap {:?}", driver_path);
-        }
-        let mmap_buf =
-        // SAFETY: The slice is created for the region of memory that was just
-        // successfully mapped into the process address space so it will be
-        // accessible and not referenced from anywhere else.
-            unsafe { slice::from_raw_parts((mmap_addr as *const u8).as_ref().unwrap(), mmap_size) };
-        let bcc_handover =
-            bcc_handover_parse(mmap_buf).map_err(|_| anyhow!("Failed to parse Bcc Handover"))?;
-        Ok(Self::Real {
-            driver_path: driver_path.to_path_buf(),
-            mmap_addr,
-            mmap_size,
-            bcc_handover,
-        })
+    for apex in &verified_data.apex_data {
+        code_hash_ctx.update(apex.root_digest.as_ref());
+        authority_hash_ctx.update(apex.public_key.as_ref());
     }
+    let code_hash = code_hash_ctx.finish();
+    let authority_hash = authority_hash_ctx.finish();
 
-    /// Derives a sealing key of `key_length` bytes from the DICE sealing CDI.
-    pub fn get_sealing_key(&self, identifier: &[u8], key_length: usize) -> Result<ZVec> {
-        // Deterministically derive a key to use for sealing data, rather than using the CDI
-        // directly, so we have the chance to rotate the key if needed. A salt isn't needed as the
-        // input key material is already cryptographically strong.
-        let mut key = ZVec::new(key_length)?;
-        let salt = &[];
-        hkdf(&mut key, Md::sha256(), self.dice_artifacts().cdi_seal(), salt, identifier)?;
-        Ok(key)
-    }
+    let config_descriptor = format_payload_config_descriptor(payload_metadata)?;
 
-    pub fn derive(
-        self,
-        code_hash: Hash,
-        config_desc: &[u8],
-        authority_hash: Hash,
-        debug: bool,
-        hidden: Hidden,
-    ) -> Result<OwnedDiceArtifacts> {
-        let input_values = InputValues::new(
-            code_hash,
-            Config::Descriptor(config_desc),
-            authority_hash,
-            if debug { DiceMode::kDiceModeDebug } else { DiceMode::kDiceModeNormal },
-            hidden,
-        );
-        let current_dice_artifacts = self.dice_artifacts();
-        let next_dice_artifacts = retry_bcc_main_flow(
-            current_dice_artifacts.cdi_attest(),
-            current_dice_artifacts.cdi_seal(),
-            current_dice_artifacts.bcc().ok_or_else(|| anyhow!("bcc is none"))?,
-            &input_values,
-        )
-        .context("DICE derive from driver")?;
-        if let Self::Real { driver_path, .. } = &self {
-            // Writing to the device wipes the artifacts. The string is ignored by the driver but
-            // included for documentation.
-            fs::write(driver_path, "wipe")
-                .map_err(|err| Error::new(err).context("Wiping driver"))?;
-        }
-        Ok(next_dice_artifacts)
-    }
-}
+    // Check debuggability, conservatively assuming it is debuggable
+    let debuggable = is_debuggable()?;
 
-impl Drop for DiceDriver<'_> {
-    fn drop(&mut self) {
-        if let &mut Self::Real { mmap_addr, mmap_size, .. } = self {
-            // SAFETY: All references to the mapped region have the same lifetime as self. Since
-            // self is being dropped, so are all the references to the mapped region meaning it's
-            // safe to unmap.
-            let ret = unsafe { munmap(mmap_addr, mmap_size) };
-            if ret != 0 {
-                log::warn!("Failed to munmap ({})", ret);
-            }
-        }
-    }
+    // Send the details to diced
+    let hidden = verified_data.salt.clone().try_into().unwrap();
+    dice.derive(code_hash, &config_descriptor, authority_hash, debuggable, hidden)
 }
 
 /// Returns a configuration descriptor of the given payload following the BCC's specification:
@@ -160,7 +62,7 @@
 /// PayloadConfig = {
 ///   1: tstr ; payload_binary_name
 /// }
-pub fn format_payload_config_descriptor(payload: &PayloadMetadata) -> Result<Vec<u8>> {
+fn format_payload_config_descriptor(payload: &PayloadMetadata) -> Result<Vec<u8>> {
     const MICRODROID_PAYLOAD_COMPONENT_NAME: &str = "Microdroid payload";
 
     let config_descriptor_cbor_value = match payload {
diff --git a/microdroid_manager/src/dice_driver.rs b/microdroid_manager/src/dice_driver.rs
new file mode 100644
index 0000000..229f3e0
--- /dev/null
+++ b/microdroid_manager/src/dice_driver.rs
@@ -0,0 +1,149 @@
+// 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.
+
+//! Logic for handling the DICE values and boot operations.
+
+use anyhow::{anyhow, bail, Context, Error, Result};
+use byteorder::{NativeEndian, ReadBytesExt};
+use diced_open_dice::{
+    bcc_handover_parse, retry_bcc_main_flow, BccHandover, Config, DiceArtifacts, DiceMode, Hash,
+    Hidden, InputValues, OwnedDiceArtifacts,
+};
+use keystore2_crypto::ZVec;
+use libc::{c_void, mmap, munmap, MAP_FAILED, MAP_PRIVATE, PROT_READ};
+use openssl::hkdf::hkdf;
+use openssl::md::Md;
+use std::fs;
+use std::os::unix::io::AsRawFd;
+use std::path::{Path, PathBuf};
+use std::ptr::null_mut;
+use std::slice;
+
+/// Artifacts that are mapped into the process address space from the driver.
+pub enum DiceDriver<'a> {
+    Real {
+        driver_path: PathBuf,
+        mmap_addr: *mut c_void,
+        mmap_size: usize,
+        bcc_handover: BccHandover<'a>,
+    },
+    Fake(OwnedDiceArtifacts),
+}
+
+impl DiceDriver<'_> {
+    fn dice_artifacts(&self) -> &dyn DiceArtifacts {
+        match self {
+            Self::Real { bcc_handover, .. } => bcc_handover,
+            Self::Fake(owned_dice_artifacts) => owned_dice_artifacts,
+        }
+    }
+
+    pub fn new(driver_path: &Path) -> Result<Self> {
+        if driver_path.exists() {
+            log::info!("Using DICE values from driver");
+        } else if super::is_strict_boot() {
+            bail!("Strict boot requires DICE value from driver but none were found");
+        } else {
+            log::warn!("Using sample DICE values");
+            let dice_artifacts = diced_sample_inputs::make_sample_bcc_and_cdis()
+                .expect("Failed to create sample dice artifacts.");
+            return Ok(Self::Fake(dice_artifacts));
+        };
+
+        let mut file = fs::File::open(driver_path)
+            .map_err(|error| Error::new(error).context("Opening driver"))?;
+        let mmap_size =
+            file.read_u64::<NativeEndian>()
+                .map_err(|error| Error::new(error).context("Reading driver"))? as usize;
+        // SAFETY: It's safe to map the driver as the service will only create a single
+        // mapping per process.
+        let mmap_addr = unsafe {
+            let fd = file.as_raw_fd();
+            mmap(null_mut(), mmap_size, PROT_READ, MAP_PRIVATE, fd, 0)
+        };
+        if mmap_addr == MAP_FAILED {
+            bail!("Failed to mmap {:?}", driver_path);
+        }
+        let mmap_buf =
+        // SAFETY: The slice is created for the region of memory that was just
+        // successfully mapped into the process address space so it will be
+        // accessible and not referenced from anywhere else.
+            unsafe { slice::from_raw_parts((mmap_addr as *const u8).as_ref().unwrap(), mmap_size) };
+        let bcc_handover =
+            bcc_handover_parse(mmap_buf).map_err(|_| anyhow!("Failed to parse Bcc Handover"))?;
+        Ok(Self::Real {
+            driver_path: driver_path.to_path_buf(),
+            mmap_addr,
+            mmap_size,
+            bcc_handover,
+        })
+    }
+
+    /// Derives a sealing key of `key_length` bytes from the DICE sealing CDI.
+    pub fn get_sealing_key(&self, identifier: &[u8], key_length: usize) -> Result<ZVec> {
+        // Deterministically derive a key to use for sealing data, rather than using the CDI
+        // directly, so we have the chance to rotate the key if needed. A salt isn't needed as the
+        // input key material is already cryptographically strong.
+        let mut key = ZVec::new(key_length)?;
+        let salt = &[];
+        hkdf(&mut key, Md::sha256(), self.dice_artifacts().cdi_seal(), salt, identifier)?;
+        Ok(key)
+    }
+
+    pub fn derive(
+        self,
+        code_hash: Hash,
+        config_desc: &[u8],
+        authority_hash: Hash,
+        debug: bool,
+        hidden: Hidden,
+    ) -> Result<OwnedDiceArtifacts> {
+        let input_values = InputValues::new(
+            code_hash,
+            Config::Descriptor(config_desc),
+            authority_hash,
+            if debug { DiceMode::kDiceModeDebug } else { DiceMode::kDiceModeNormal },
+            hidden,
+        );
+        let current_dice_artifacts = self.dice_artifacts();
+        let next_dice_artifacts = retry_bcc_main_flow(
+            current_dice_artifacts.cdi_attest(),
+            current_dice_artifacts.cdi_seal(),
+            current_dice_artifacts.bcc().ok_or_else(|| anyhow!("bcc is none"))?,
+            &input_values,
+        )
+        .context("DICE derive from driver")?;
+        if let Self::Real { driver_path, .. } = &self {
+            // Writing to the device wipes the artifacts. The string is ignored by the driver but
+            // included for documentation.
+            fs::write(driver_path, "wipe")
+                .map_err(|err| Error::new(err).context("Wiping driver"))?;
+        }
+        Ok(next_dice_artifacts)
+    }
+}
+
+impl Drop for DiceDriver<'_> {
+    fn drop(&mut self) {
+        if let &mut Self::Real { mmap_addr, mmap_size, .. } = self {
+            // SAFETY: All references to the mapped region have the same lifetime as self. Since
+            // self is being dropped, so are all the references to the mapped region meaning it's
+            // safe to unmap.
+            let ret = unsafe { munmap(mmap_addr, mmap_size) };
+            if ret != 0 {
+                log::warn!("Failed to munmap ({})", ret);
+            }
+        }
+    }
+}
diff --git a/microdroid_manager/src/instance.rs b/microdroid_manager/src/instance.rs
index b16a1e1..2ff04f1 100644
--- a/microdroid_manager/src/instance.rs
+++ b/microdroid_manager/src/instance.rs
@@ -33,7 +33,7 @@
 //! The payload of a partition is encrypted/signed by a key that is unique to the loader and to the
 //! VM as well. Failing to decrypt/authenticate a partition by a loader stops the boot process.
 
-use crate::dice::DiceDriver;
+use crate::dice_driver::DiceDriver;
 use crate::ioutil;
 
 use anyhow::{anyhow, bail, Context, Result};
diff --git a/microdroid_manager/src/main.rs b/microdroid_manager/src/main.rs
index 491d4de..8175753 100644
--- a/microdroid_manager/src/main.rs
+++ b/microdroid_manager/src/main.rs
@@ -15,16 +15,15 @@
 //! Microdroid Manager
 
 mod dice;
+mod dice_driver;
 mod instance;
 mod ioutil;
 mod payload;
 mod swap;
+mod verify;
 mod vm_payload_service;
 mod vm_secret;
 
-use crate::dice::{DiceDriver, format_payload_config_descriptor};
-use crate::instance::{ApexData, ApkData, InstanceDisk, MicrodroidData, RootHash};
-use crate::vm_payload_service::register_vm_payload_service;
 use android_system_virtualizationcommon::aidl::android::system::virtualizationcommon::ErrorCode::ErrorCode;
 use android_system_virtualmachineservice::aidl::android::system::virtualmachineservice::IVirtualMachineService::IVirtualMachineService;
 use android_system_virtualization_payload::aidl::android::system::virtualization::payload::IVmPayloadService::{
@@ -32,55 +31,46 @@
     VM_PAYLOAD_SERVICE_SOCKET_NAME,
     ENCRYPTEDSTORE_MOUNTPOINT,
 };
+
+use crate::dice::dice_derivation;
+use crate::dice_driver::DiceDriver;
+use crate::instance::{ApexData, InstanceDisk, MicrodroidData};
+use crate::verify::verify_payload;
+use crate::vm_payload_service::register_vm_payload_service;
 use anyhow::{anyhow, bail, ensure, Context, Error, Result};
-use apkverify::{get_public_key_der, verify, V4Signature};
-use apkmanifest::get_manifest_info;
 use binder::Strong;
-use diced_open_dice::OwnedDiceArtifacts;
-use glob::glob;
-use itertools::sorted;
-use libc::VMADDR_CID_HOST;
-use log::{error, info, warn};
 use keystore2_crypto::ZVec;
-use microdroid_metadata::{write_metadata, Metadata, PayloadMetadata};
+use libc::VMADDR_CID_HOST;
+use log::{error, info};
+use microdroid_metadata::{write_metadata, PayloadMetadata};
 use microdroid_payload_config::{OsConfig, Task, TaskType, VmPayloadConfig};
 use nix::sys::signal::Signal;
-use openssl::sha::Sha512;
-use payload::{get_apex_data_from_payload, load_metadata, to_metadata};
-use rand::Fill;
+use payload::{load_metadata, to_metadata};
 use rpcbinder::RpcSession;
 use rustutils::sockets::android_get_control_socket;
 use rustutils::system_properties;
 use rustutils::system_properties::PropertyWatcher;
 use std::borrow::Cow::{Borrowed, Owned};
-use std::convert::TryInto;
 use std::env;
 use std::ffi::CString;
-use std::fs::{self, create_dir, OpenOptions, File};
+use std::fs::{self, create_dir, File, OpenOptions};
 use std::io::{Read, Write};
+use std::os::unix::io::{FromRawFd, OwnedFd};
 use std::os::unix::process::CommandExt;
 use std::os::unix::process::ExitStatusExt;
-use std::os::unix::io::{FromRawFd, OwnedFd};
 use std::path::Path;
 use std::process::{Child, Command, Stdio};
 use std::str;
-use std::time::{Duration, SystemTime};
+use std::time::Duration;
 use vm_secret::VmSecret;
 
 const WAIT_TIMEOUT: Duration = Duration::from_secs(10);
-const MAIN_APK_PATH: &str = "/dev/block/by-name/microdroid-apk";
-const MAIN_APK_IDSIG_PATH: &str = "/dev/block/by-name/microdroid-apk-idsig";
-const MAIN_APK_DEVICE_NAME: &str = "microdroid-apk";
-const EXTRA_APK_PATH_PATTERN: &str = "/dev/block/by-name/extra-apk-*";
-const EXTRA_IDSIG_PATH_PATTERN: &str = "/dev/block/by-name/extra-idsig-*";
-const DM_MOUNTED_APK_PATH: &str = "/dev/block/mapper/microdroid-apk";
 const AVF_STRICT_BOOT: &str = "/sys/firmware/devicetree/base/chosen/avf,strict-boot";
 const AVF_NEW_INSTANCE: &str = "/sys/firmware/devicetree/base/chosen/avf,new-instance";
 const AVF_DEBUG_POLICY_RAMDUMP: &str = "/sys/firmware/devicetree/base/avf/guest/common/ramdump";
 const DEBUG_MICRODROID_NO_VERIFIED_BOOT: &str =
     "/sys/firmware/devicetree/base/virtualization/guest/debug-microdroid,no-verified-boot";
 
-const APKDMVERITY_BIN: &str = "/system/bin/apkdmverity";
 const ENCRYPTEDSTORE_BIN: &str = "/system/bin/encryptedstore";
 const ZIPFUSE_BIN: &str = "/system/bin/zipfuse";
 
@@ -164,7 +154,7 @@
 
 fn main() -> Result<()> {
     // If debuggable, print full backtrace to console log with stdio_to_kmsg
-    if system_properties::read_bool(DEBUGGABLE_PROP, true)? {
+    if is_debuggable()? {
         env::set_var("RUST_BACKTRACE", "full");
     }
 
@@ -279,36 +269,6 @@
     }
     Ok(())
 }
-fn dice_derivation(
-    dice: DiceDriver,
-    verified_data: &MicrodroidData,
-    payload_metadata: &PayloadMetadata,
-) -> Result<OwnedDiceArtifacts> {
-    // Calculate compound digests of code and authorities
-    let mut code_hash_ctx = Sha512::new();
-    let mut authority_hash_ctx = Sha512::new();
-    code_hash_ctx.update(verified_data.apk_data.root_hash.as_ref());
-    authority_hash_ctx.update(verified_data.apk_data.pubkey.as_ref());
-    for extra_apk in &verified_data.extra_apks_data {
-        code_hash_ctx.update(extra_apk.root_hash.as_ref());
-        authority_hash_ctx.update(extra_apk.pubkey.as_ref());
-    }
-    for apex in &verified_data.apex_data {
-        code_hash_ctx.update(apex.root_digest.as_ref());
-        authority_hash_ctx.update(apex.public_key.as_ref());
-    }
-    let code_hash = code_hash_ctx.finish();
-    let authority_hash = authority_hash_ctx.finish();
-
-    let config_descriptor = format_payload_config_descriptor(payload_metadata)?;
-
-    // Check debuggability, conservatively assuming it is debuggable
-    let debuggable = system_properties::read_bool(DEBUGGABLE_PROP, true)?;
-
-    // Send the details to diced
-    let hidden = verified_data.salt.clone().try_into().unwrap();
-    dice.derive(code_hash, &config_descriptor, authority_hash, debuggable, hidden)
-}
 
 fn is_strict_boot() -> bool {
     Path::new(AVF_STRICT_BOOT).exists()
@@ -322,10 +282,14 @@
     !Path::new(DEBUG_MICRODROID_NO_VERIFIED_BOOT).exists()
 }
 
+fn is_debuggable() -> Result<bool> {
+    Ok(system_properties::read_bool(DEBUGGABLE_PROP, true)?)
+}
+
 fn should_export_tombstones(config: &VmPayloadConfig) -> bool {
     match config.export_tombstones {
         Some(b) => b,
-        None => system_properties::read_bool(DEBUGGABLE_PROP, true).unwrap_or(false),
+        None => is_debuggable().unwrap_or(false),
     }
 }
 
@@ -425,7 +389,7 @@
     zipfuse.mount(
         MountForExec::Allowed,
         "fscontext=u:object_r:zipfusefs:s0,context=u:object_r:system_file:s0",
-        Path::new(DM_MOUNTED_APK_PATH),
+        Path::new(verify::DM_MOUNTED_APK_PATH),
         Path::new(VM_APK_CONTENTS_PATH),
         "microdroid_manager.apk.mounted".to_owned(),
     )?;
@@ -491,28 +455,6 @@
     exec_task(task, service).context("Failed to run payload")
 }
 
-struct ApkDmverityArgument<'a> {
-    apk: &'a str,
-    idsig: &'a str,
-    name: &'a str,
-    saved_root_hash: Option<&'a RootHash>,
-}
-
-fn run_apkdmverity(args: &[ApkDmverityArgument]) -> Result<Child> {
-    let mut cmd = Command::new(APKDMVERITY_BIN);
-
-    for argument in args {
-        cmd.arg("--apk").arg(argument.apk).arg(argument.idsig).arg(argument.name);
-        if let Some(root_hash) = argument.saved_root_hash {
-            cmd.arg(&to_hex_string(root_hash));
-        } else {
-            cmd.arg("none");
-        }
-    }
-
-    cmd.spawn().context("Spawn apkdmverity")
-}
-
 enum MountForExec {
     Allowed,
     Disallowed,
@@ -583,147 +525,6 @@
     Ok(())
 }
 
-// Verify payload before executing it. For APK payload, Full verification (which is slow) is done
-// when the root_hash values from the idsig file and the instance disk are different. This function
-// returns the verified root hash (for APK payload) and pubkeys (for APEX payloads) that can be
-// saved to the instance disk.
-fn verify_payload(
-    metadata: &Metadata,
-    saved_data: Option<&MicrodroidData>,
-) -> Result<MicrodroidData> {
-    let start_time = SystemTime::now();
-
-    // Verify main APK
-    let root_hash_from_idsig = get_apk_root_hash_from_idsig(MAIN_APK_IDSIG_PATH)?;
-    let root_hash_trustful =
-        saved_data.map(|d| d.apk_data.root_hash_eq(root_hash_from_idsig.as_ref())).unwrap_or(false);
-
-    // If root_hash can be trusted, pass it to apkdmverity so that it uses the passed root_hash
-    // instead of the value read from the idsig file.
-    let main_apk_argument = {
-        ApkDmverityArgument {
-            apk: MAIN_APK_PATH,
-            idsig: MAIN_APK_IDSIG_PATH,
-            name: MAIN_APK_DEVICE_NAME,
-            saved_root_hash: if root_hash_trustful {
-                Some(root_hash_from_idsig.as_ref())
-            } else {
-                None
-            },
-        }
-    };
-    let mut apkdmverity_arguments = vec![main_apk_argument];
-
-    // Verify extra APKs
-    // For now, we can't read the payload config, so glob APKs and idsigs.
-    // Later, we'll see if it matches with the payload config.
-
-    // sort globbed paths to match apks (extra-apk-{idx}) and idsigs (extra-idsig-{idx})
-    // e.g. "extra-apk-0" corresponds to "extra-idsig-0"
-    let extra_apks =
-        sorted(glob(EXTRA_APK_PATH_PATTERN)?.collect::<Result<Vec<_>, _>>()?).collect::<Vec<_>>();
-    let extra_idsigs =
-        sorted(glob(EXTRA_IDSIG_PATH_PATTERN)?.collect::<Result<Vec<_>, _>>()?).collect::<Vec<_>>();
-    ensure!(
-        extra_apks.len() == extra_idsigs.len(),
-        "Extra apks/idsigs mismatch: {} apks but {} idsigs",
-        extra_apks.len(),
-        extra_idsigs.len()
-    );
-
-    let extra_root_hashes_from_idsig: Vec<_> = extra_idsigs
-        .iter()
-        .map(|idsig| {
-            get_apk_root_hash_from_idsig(idsig).expect("Can't find root hash from extra idsig")
-        })
-        .collect();
-
-    let extra_root_hashes_trustful: Vec<_> = if let Some(data) = saved_data {
-        extra_root_hashes_from_idsig
-            .iter()
-            .enumerate()
-            .map(|(i, root_hash)| data.extra_apk_root_hash_eq(i, root_hash))
-            .collect()
-    } else {
-        vec![false; extra_root_hashes_from_idsig.len()]
-    };
-    let extra_apk_names: Vec<_> =
-        (0..extra_apks.len()).map(|i| format!("extra-apk-{}", i)).collect();
-
-    for (i, extra_apk) in extra_apks.iter().enumerate() {
-        apkdmverity_arguments.push({
-            ApkDmverityArgument {
-                apk: extra_apk.to_str().unwrap(),
-                idsig: extra_idsigs[i].to_str().unwrap(),
-                name: &extra_apk_names[i],
-                saved_root_hash: if extra_root_hashes_trustful[i] {
-                    Some(&extra_root_hashes_from_idsig[i])
-                } else {
-                    None
-                },
-            }
-        });
-    }
-
-    // Start apkdmverity and wait for the dm-verify block
-    let mut apkdmverity_child = run_apkdmverity(&apkdmverity_arguments)?;
-
-    // While waiting for apkdmverity to mount APK, gathers public keys and root digests from
-    // APEX payload.
-    let apex_data_from_payload = get_apex_data_from_payload(metadata)?;
-
-    // Writing /apex/vm-payload-metadata is to verify that the payload isn't changed.
-    // Skip writing it if the debug policy ignoring identity is on
-    if is_verified_boot() {
-        write_apex_payload_data(saved_data, &apex_data_from_payload)?;
-    }
-
-    // Start apexd to activate APEXes
-    system_properties::write("ctl.start", "apexd-vm")?;
-
-    // TODO(inseob): add timeout
-    apkdmverity_child.wait()?;
-
-    // Do the full verification if the root_hash is un-trustful. This requires the full scanning of
-    // the APK file and therefore can be very slow if the APK is large. Note that this step is
-    // taken only when the root_hash is un-trustful which can be either when this is the first boot
-    // of the VM or APK was updated in the host.
-    // TODO(jooyung): consider multithreading to make this faster
-    let main_apk_pubkey = get_public_key_from_apk(DM_MOUNTED_APK_PATH, root_hash_trustful)?;
-    let extra_apks_data = extra_root_hashes_from_idsig
-        .into_iter()
-        .enumerate()
-        .map(|(i, extra_root_hash)| {
-            let mount_path = format!("/dev/block/mapper/{}", &extra_apk_names[i]);
-            let apk_pubkey = get_public_key_from_apk(&mount_path, extra_root_hashes_trustful[i])?;
-            Ok(ApkData { root_hash: extra_root_hash, pubkey: apk_pubkey })
-        })
-        .collect::<Result<Vec<_>>>()?;
-
-    info!("payload verification successful. took {:#?}", start_time.elapsed().unwrap());
-
-    // Use the salt from a verified instance, or generate a salt for a new instance.
-    let salt = if let Some(saved_data) = saved_data {
-        saved_data.salt.clone()
-    } else if is_strict_boot() {
-        // No need to add more entropy as a previous stage must have used a new, random salt.
-        vec![0u8; 64]
-    } else {
-        let mut salt = vec![0u8; 64];
-        salt.as_mut_slice().try_fill(&mut rand::thread_rng())?;
-        salt
-    };
-
-    // At this point, we can ensure that the root_hash from the idsig file is trusted, either by
-    // fully verifying the APK or by comparing it with the saved root_hash.
-    Ok(MicrodroidData {
-        salt,
-        apk_data: ApkData { root_hash: root_hash_from_idsig, pubkey: main_apk_pubkey },
-        extra_apks_data,
-        apex_data: apex_data_from_payload,
-    })
-}
-
 fn mount_extra_apks(config: &VmPayloadConfig, zipfuse: &mut Zipfuse) -> Result<()> {
     // For now, only the number of apks is important, as the mount point and dm-verity name is fixed
     for i in 0..config.extra_apks.len() {
@@ -771,39 +572,6 @@
     Ok(())
 }
 
-fn get_apk_root_hash_from_idsig<P: AsRef<Path>>(idsig_path: P) -> Result<Box<RootHash>> {
-    Ok(V4Signature::from_idsig_path(idsig_path)?.hashing_info.raw_root_hash)
-}
-
-fn get_public_key_from_apk(apk: &str, root_hash_trustful: bool) -> Result<Box<[u8]>> {
-    let current_sdk = get_current_sdk()?;
-
-    let public_key_der = if !root_hash_trustful {
-        verify(apk, current_sdk).context(MicrodroidError::PayloadVerificationFailed(format!(
-            "failed to verify {}",
-            apk
-        )))?
-    } else {
-        get_public_key_der(apk, current_sdk)?
-    };
-
-    match get_manifest_info(apk) {
-        Ok(manifest_info) => {
-            // TODO (b/299591171): Do something with this info
-            info!("Manifest info is {manifest_info:?}")
-        }
-        Err(e) => warn!("Failed to read manifest info from APK: {e:?}"),
-    };
-
-    Ok(public_key_der)
-}
-
-fn get_current_sdk() -> Result<u32> {
-    let current_sdk = system_properties::read("ro.build.version.sdk")?;
-    let current_sdk = current_sdk.ok_or_else(|| anyhow!("SDK version missing"))?;
-    current_sdk.parse().context("Malformed SDK version")
-}
-
 fn load_config(payload_metadata: PayloadMetadata) -> Result<VmPayloadConfig> {
     match payload_metadata {
         PayloadMetadata::ConfigPath(path) => {
@@ -843,7 +611,7 @@
         return Ok(());
     }
 
-    let debuggable = system_properties::read_bool(DEBUGGABLE_PROP, true)?;
+    let debuggable = is_debuggable()?;
     let ramdump = get_debug_policy_bool(AVF_DEBUG_POLICY_RAMDUMP)?.unwrap_or_default();
     let requested = debuggable | ramdump;
 
@@ -920,10 +688,6 @@
     Ok(path)
 }
 
-fn to_hex_string(buf: &[u8]) -> String {
-    buf.iter().map(|b| format!("{:02X}", b)).collect()
-}
-
 fn prepare_encryptedstore(vm_secret: &VmSecret) -> Result<Child> {
     let mut key = ZVec::new(ENCRYPTEDSTORE_KEYSIZE)?;
     vm_secret.derive_encryptedstore_key(&mut key)?;
diff --git a/microdroid_manager/src/verify.rs b/microdroid_manager/src/verify.rs
new file mode 100644
index 0000000..06b15f7
--- /dev/null
+++ b/microdroid_manager/src/verify.rs
@@ -0,0 +1,236 @@
+// Copyright 2023 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 crate::instance::{ApkData, MicrodroidData, RootHash};
+use crate::payload::get_apex_data_from_payload;
+use crate::{is_strict_boot, is_verified_boot, write_apex_payload_data, MicrodroidError};
+use anyhow::{anyhow, ensure, Context, Result};
+use apkmanifest::get_manifest_info;
+use apkverify::{get_public_key_der, verify, V4Signature};
+use glob::glob;
+use itertools::sorted;
+use log::{info, warn};
+use microdroid_metadata::Metadata;
+use rand::Fill;
+use rustutils::system_properties;
+use std::path::Path;
+use std::process::{Child, Command};
+use std::str;
+use std::time::SystemTime;
+
+pub const DM_MOUNTED_APK_PATH: &str = "/dev/block/mapper/microdroid-apk";
+
+const MAIN_APK_PATH: &str = "/dev/block/by-name/microdroid-apk";
+const MAIN_APK_IDSIG_PATH: &str = "/dev/block/by-name/microdroid-apk-idsig";
+const MAIN_APK_DEVICE_NAME: &str = "microdroid-apk";
+const EXTRA_APK_PATH_PATTERN: &str = "/dev/block/by-name/extra-apk-*";
+const EXTRA_IDSIG_PATH_PATTERN: &str = "/dev/block/by-name/extra-idsig-*";
+
+const APKDMVERITY_BIN: &str = "/system/bin/apkdmverity";
+
+/// Verify payload before executing it. For APK payload, Full verification (which is slow) is done
+/// when the root_hash values from the idsig file and the instance disk are different. This function
+/// returns the verified root hash (for APK payload) and pubkeys (for APEX payloads) that can be
+/// saved to the instance disk.
+pub fn verify_payload(
+    metadata: &Metadata,
+    saved_data: Option<&MicrodroidData>,
+) -> Result<MicrodroidData> {
+    let start_time = SystemTime::now();
+
+    // Verify main APK
+    let root_hash_from_idsig = get_apk_root_hash_from_idsig(MAIN_APK_IDSIG_PATH)?;
+    let root_hash_trustful =
+        saved_data.map(|d| d.apk_data.root_hash_eq(root_hash_from_idsig.as_ref())).unwrap_or(false);
+
+    // If root_hash can be trusted, pass it to apkdmverity so that it uses the passed root_hash
+    // instead of the value read from the idsig file.
+    let main_apk_argument = {
+        ApkDmverityArgument {
+            apk: MAIN_APK_PATH,
+            idsig: MAIN_APK_IDSIG_PATH,
+            name: MAIN_APK_DEVICE_NAME,
+            saved_root_hash: if root_hash_trustful {
+                Some(root_hash_from_idsig.as_ref())
+            } else {
+                None
+            },
+        }
+    };
+    let mut apkdmverity_arguments = vec![main_apk_argument];
+
+    // Verify extra APKs
+    // For now, we can't read the payload config, so glob APKs and idsigs.
+    // Later, we'll see if it matches with the payload config.
+
+    // sort globbed paths to match apks (extra-apk-{idx}) and idsigs (extra-idsig-{idx})
+    // e.g. "extra-apk-0" corresponds to "extra-idsig-0"
+    let extra_apks =
+        sorted(glob(EXTRA_APK_PATH_PATTERN)?.collect::<Result<Vec<_>, _>>()?).collect::<Vec<_>>();
+    let extra_idsigs =
+        sorted(glob(EXTRA_IDSIG_PATH_PATTERN)?.collect::<Result<Vec<_>, _>>()?).collect::<Vec<_>>();
+    ensure!(
+        extra_apks.len() == extra_idsigs.len(),
+        "Extra apks/idsigs mismatch: {} apks but {} idsigs",
+        extra_apks.len(),
+        extra_idsigs.len()
+    );
+
+    let extra_root_hashes_from_idsig: Vec<_> = extra_idsigs
+        .iter()
+        .map(|idsig| {
+            get_apk_root_hash_from_idsig(idsig).expect("Can't find root hash from extra idsig")
+        })
+        .collect();
+
+    let extra_root_hashes_trustful: Vec<_> = if let Some(data) = saved_data {
+        extra_root_hashes_from_idsig
+            .iter()
+            .enumerate()
+            .map(|(i, root_hash)| data.extra_apk_root_hash_eq(i, root_hash))
+            .collect()
+    } else {
+        vec![false; extra_root_hashes_from_idsig.len()]
+    };
+    let extra_apk_names: Vec<_> =
+        (0..extra_apks.len()).map(|i| format!("extra-apk-{}", i)).collect();
+
+    for (i, extra_apk) in extra_apks.iter().enumerate() {
+        apkdmverity_arguments.push({
+            ApkDmverityArgument {
+                apk: extra_apk.to_str().unwrap(),
+                idsig: extra_idsigs[i].to_str().unwrap(),
+                name: &extra_apk_names[i],
+                saved_root_hash: if extra_root_hashes_trustful[i] {
+                    Some(&extra_root_hashes_from_idsig[i])
+                } else {
+                    None
+                },
+            }
+        });
+    }
+
+    // Start apkdmverity and wait for the dm-verify block
+    let mut apkdmverity_child = run_apkdmverity(&apkdmverity_arguments)?;
+
+    // While waiting for apkdmverity to mount APK, gathers public keys and root digests from
+    // APEX payload.
+    let apex_data_from_payload = get_apex_data_from_payload(metadata)?;
+
+    // Writing /apex/vm-payload-metadata is to verify that the payload isn't changed.
+    // Skip writing it if the debug policy ignoring identity is on
+    if is_verified_boot() {
+        write_apex_payload_data(saved_data, &apex_data_from_payload)?;
+    }
+
+    // Start apexd to activate APEXes
+    system_properties::write("ctl.start", "apexd-vm")?;
+
+    // TODO(inseob): add timeout
+    apkdmverity_child.wait()?;
+
+    // Do the full verification if the root_hash is un-trustful. This requires the full scanning of
+    // the APK file and therefore can be very slow if the APK is large. Note that this step is
+    // taken only when the root_hash is un-trustful which can be either when this is the first boot
+    // of the VM or APK was updated in the host.
+    // TODO(jooyung): consider multithreading to make this faster
+    let main_apk_pubkey = get_public_key_from_apk(DM_MOUNTED_APK_PATH, root_hash_trustful)?;
+    let extra_apks_data = extra_root_hashes_from_idsig
+        .into_iter()
+        .enumerate()
+        .map(|(i, extra_root_hash)| {
+            let mount_path = format!("/dev/block/mapper/{}", &extra_apk_names[i]);
+            let apk_pubkey = get_public_key_from_apk(&mount_path, extra_root_hashes_trustful[i])?;
+            Ok(ApkData { root_hash: extra_root_hash, pubkey: apk_pubkey })
+        })
+        .collect::<Result<Vec<_>>>()?;
+
+    info!("payload verification successful. took {:#?}", start_time.elapsed().unwrap());
+
+    // Use the salt from a verified instance, or generate a salt for a new instance.
+    let salt = if let Some(saved_data) = saved_data {
+        saved_data.salt.clone()
+    } else if is_strict_boot() {
+        // No need to add more entropy as a previous stage must have used a new, random salt.
+        vec![0u8; 64]
+    } else {
+        let mut salt = vec![0u8; 64];
+        salt.as_mut_slice().try_fill(&mut rand::thread_rng())?;
+        salt
+    };
+
+    // At this point, we can ensure that the root_hash from the idsig file is trusted, either by
+    // fully verifying the APK or by comparing it with the saved root_hash.
+    Ok(MicrodroidData {
+        salt,
+        apk_data: ApkData { root_hash: root_hash_from_idsig, pubkey: main_apk_pubkey },
+        extra_apks_data,
+        apex_data: apex_data_from_payload,
+    })
+}
+
+fn get_apk_root_hash_from_idsig<P: AsRef<Path>>(idsig_path: P) -> Result<Box<RootHash>> {
+    Ok(V4Signature::from_idsig_path(idsig_path)?.hashing_info.raw_root_hash)
+}
+
+fn get_public_key_from_apk(apk: &str, root_hash_trustful: bool) -> Result<Box<[u8]>> {
+    let current_sdk = get_current_sdk()?;
+
+    let public_key_der = if !root_hash_trustful {
+        verify(apk, current_sdk).context(MicrodroidError::PayloadVerificationFailed(format!(
+            "failed to verify {}",
+            apk
+        )))?
+    } else {
+        get_public_key_der(apk, current_sdk)?
+    };
+
+    match get_manifest_info(apk) {
+        Ok(manifest_info) => {
+            // TODO (b/299591171): Do something with this info
+            info!("Manifest info is {manifest_info:?}")
+        }
+        Err(e) => warn!("Failed to read manifest info from APK: {e:?}"),
+    };
+
+    Ok(public_key_der)
+}
+
+fn get_current_sdk() -> Result<u32> {
+    let current_sdk = system_properties::read("ro.build.version.sdk")?;
+    let current_sdk = current_sdk.ok_or_else(|| anyhow!("SDK version missing"))?;
+    current_sdk.parse().context("Malformed SDK version")
+}
+
+struct ApkDmverityArgument<'a> {
+    apk: &'a str,
+    idsig: &'a str,
+    name: &'a str,
+    saved_root_hash: Option<&'a RootHash>,
+}
+
+fn run_apkdmverity(args: &[ApkDmverityArgument]) -> Result<Child> {
+    let mut cmd = Command::new(APKDMVERITY_BIN);
+
+    for argument in args {
+        cmd.arg("--apk").arg(argument.apk).arg(argument.idsig).arg(argument.name);
+        if let Some(root_hash) = argument.saved_root_hash {
+            cmd.arg(&hex::encode(root_hash));
+        } else {
+            cmd.arg("none");
+        }
+    }
+
+    cmd.spawn().context("Spawn apkdmverity")
+}
