diff --git a/guest/authfs/Android.bp b/guest/authfs/Android.bp
new file mode 100644
index 0000000..b11da3d
--- /dev/null
+++ b/guest/authfs/Android.bp
@@ -0,0 +1,52 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+rust_defaults {
+    name: "authfs_defaults",
+    crate_name: "authfs",
+    edition: "2021",
+    srcs: [":authfs_src"],
+    rustlibs: [
+        "authfs_aidl_interface-rust",
+        "libandroid_logger",
+        "libanyhow",
+        "libauthfs_fsverity_metadata",
+        "libbinder_rs",
+        "libcfg_if",
+        "libclap",
+        "libfsverity_digests_proto_rust",
+        "libfuse_rust",
+        "libhex",
+        "liblibc",
+        "liblog_rust",
+        "libnix",
+        "libopenssl",
+        "libprotobuf",
+        "librpcbinder_rs",
+        "libthiserror",
+    ],
+    prefer_rlib: true,
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
+    defaults: [
+        "crosvm_defaults",
+        "avf_build_flags_rust",
+    ],
+}
+
+filegroup {
+    name: "authfs_src",
+    srcs: [
+        "src/main.rs",
+    ],
+}
+
+rust_binary {
+    name: "authfs",
+    defaults: ["authfs_defaults"],
+    apex_available: ["com.android.virt"],
+}
diff --git a/guest/authfs/TEST_MAPPING b/guest/authfs/TEST_MAPPING
new file mode 100644
index 0000000..62bc18f
--- /dev/null
+++ b/guest/authfs/TEST_MAPPING
@@ -0,0 +1,23 @@
+// When adding or removing tests here, don't forget to amend _all_modules list in
+// wireless/android/busytown/ath_config/configs/prod/avf/tests.gcl
+{
+  "avf-presubmit": [
+    {
+      "name": "authfs_device_test_src_lib"
+    },
+    {
+      "name": "fd_server.test"
+    },
+    {
+      "name": "open_then_run.test"
+    },
+    {
+      "name": "AuthFsHostTest"
+    }
+  ],
+  "avf-postsubmit": [
+    {
+      "name": "AuthFsBenchmarks"
+    }
+  ]
+}
diff --git a/guest/authfs/src/common.rs b/guest/authfs/src/common.rs
new file mode 100644
index 0000000..6556fde
--- /dev/null
+++ b/guest/authfs/src/common.rs
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+/// Common block and page size in Linux.
+pub const CHUNK_SIZE: u64 = 4096;
+
+pub fn divide_roundup(dividend: u64, divisor: u64) -> u64 {
+    (dividend + divisor - 1) / divisor
+}
+
+/// Given `offset` and `length`, generates (offset, size) tuples that together form the same length,
+/// and aligned to `alignment`.
+pub struct ChunkedSizeIter {
+    remaining: usize,
+    offset: u64,
+    alignment: usize,
+}
+
+impl ChunkedSizeIter {
+    pub fn new(remaining: usize, offset: u64, alignment: usize) -> Self {
+        ChunkedSizeIter { remaining, offset, alignment }
+    }
+}
+
+impl Iterator for ChunkedSizeIter {
+    type Item = (u64, usize);
+
+    fn next(&mut self) -> Option<Self::Item> {
+        if self.remaining == 0 {
+            return None;
+        }
+        let chunk_data_size = std::cmp::min(
+            self.remaining,
+            self.alignment - (self.offset % self.alignment as u64) as usize,
+        );
+        let retval = (self.offset, chunk_data_size);
+        self.offset += chunk_data_size as u64;
+        self.remaining = self.remaining.saturating_sub(chunk_data_size);
+        Some(retval)
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    fn collect_chunk_read_iter(remaining: usize, offset: u64) -> Vec<(u64, usize)> {
+        ChunkedSizeIter::new(remaining, offset, 4096).collect::<Vec<_>>()
+    }
+
+    #[test]
+    fn test_chunk_read_iter() {
+        assert_eq!(collect_chunk_read_iter(4096, 0), [(0, 4096)]);
+        assert_eq!(collect_chunk_read_iter(8192, 0), [(0, 4096), (4096, 4096)]);
+        assert_eq!(collect_chunk_read_iter(8192, 4096), [(4096, 4096), (8192, 4096)]);
+
+        assert_eq!(
+            collect_chunk_read_iter(16384, 1),
+            [(1, 4095), (4096, 4096), (8192, 4096), (12288, 4096), (16384, 1)]
+        );
+
+        assert_eq!(collect_chunk_read_iter(0, 0), []);
+        assert_eq!(collect_chunk_read_iter(0, 100), []);
+    }
+}
diff --git a/guest/authfs/src/file.rs b/guest/authfs/src/file.rs
new file mode 100644
index 0000000..55c783b
--- /dev/null
+++ b/guest/authfs/src/file.rs
@@ -0,0 +1,114 @@
+mod attr;
+mod dir;
+mod remote_file;
+
+pub use attr::Attr;
+pub use dir::{InMemoryDir, RemoteDirEditor};
+pub use remote_file::{RemoteFileEditor, RemoteFileReader, RemoteMerkleTreeReader};
+
+use crate::common::{divide_roundup, CHUNK_SIZE};
+use authfs_aidl_interface::aidl::com::android::virt::fs::IVirtFdService::IVirtFdService;
+use binder::{Status, StatusCode, Strong};
+use rpcbinder::RpcSession;
+use std::convert::TryFrom;
+use std::io;
+use std::path::{Path, MAIN_SEPARATOR};
+
+pub type VirtFdService = Strong<dyn IVirtFdService>;
+pub type VirtFdServiceStatus = Status;
+
+pub type ChunkBuffer = [u8; CHUNK_SIZE as usize];
+
+pub const RPC_SERVICE_PORT: u32 = 3264;
+
+pub fn get_rpc_binder_service(cid: u32) -> io::Result<VirtFdService> {
+    RpcSession::new().setup_vsock_client(cid, RPC_SERVICE_PORT).map_err(|e| match e {
+        StatusCode::BAD_VALUE => {
+            io::Error::new(io::ErrorKind::InvalidInput, "Invalid raw AIBinder")
+        }
+        _ => io::Error::new(
+            io::ErrorKind::AddrNotAvailable,
+            format!("Cannot connect to RPC service: {}", e),
+        ),
+    })
+}
+
+/// A trait for reading data by chunks. Chunks can be read by specifying the chunk index. Only the
+/// last chunk may have incomplete chunk size.
+pub trait ReadByChunk {
+    /// Reads the `chunk_index`-th chunk to a `ChunkBuffer`. Returns the size read, which has to be
+    /// `CHUNK_SIZE` except for the last incomplete chunk. Reading beyond the file size (including
+    /// empty file) should return 0.
+    fn read_chunk(&self, chunk_index: u64, buf: &mut ChunkBuffer) -> io::Result<usize>;
+}
+
+/// A trait to write a buffer to the destination at a given offset. The implementation does not
+/// necessarily own or maintain the destination state.
+///
+/// NB: The trait is required in a member of `fusefs::AuthFs`, which is required to be Sync and
+/// immutable (this the member).
+pub trait RandomWrite {
+    /// Writes `buf` to the destination at `offset`. Returns the written size, which may not be the
+    /// full buffer.
+    fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize>;
+
+    /// Writes the full `buf` to the destination at `offset`.
+    fn write_all_at(&self, buf: &[u8], offset: u64) -> io::Result<()> {
+        let mut input_offset = 0;
+        let mut output_offset = offset;
+        while input_offset < buf.len() {
+            let size = self.write_at(&buf[input_offset..], output_offset)?;
+            input_offset += size;
+            output_offset += size as u64;
+        }
+        Ok(())
+    }
+
+    /// Resizes the file to the new size.
+    fn resize(&self, size: u64) -> io::Result<()>;
+}
+
+/// Checks whether the path is a simple file name without any directory separator.
+pub fn validate_basename(path: &Path) -> io::Result<()> {
+    if matches!(path.to_str(), Some(path_str) if !path_str.contains(MAIN_SEPARATOR)) {
+        Ok(())
+    } else {
+        Err(io::Error::from_raw_os_error(libc::EINVAL))
+    }
+}
+
+pub struct EagerChunkReader {
+    buffer: Vec<u8>,
+}
+
+impl EagerChunkReader {
+    pub fn new<F: ReadByChunk>(chunked_file: F, file_size: u64) -> io::Result<EagerChunkReader> {
+        let last_index = divide_roundup(file_size, CHUNK_SIZE);
+        let file_size = usize::try_from(file_size).unwrap();
+        let mut buffer = Vec::with_capacity(file_size);
+        let mut chunk_buffer = [0; CHUNK_SIZE as usize];
+        for index in 0..last_index {
+            let size = chunked_file.read_chunk(index, &mut chunk_buffer)?;
+            buffer.extend_from_slice(&chunk_buffer[..size]);
+        }
+        if buffer.len() < file_size {
+            Err(io::Error::new(
+                io::ErrorKind::InvalidData,
+                format!("Insufficient data size ({} < {})", buffer.len(), file_size),
+            ))
+        } else {
+            Ok(EagerChunkReader { buffer })
+        }
+    }
+}
+
+impl ReadByChunk for EagerChunkReader {
+    fn read_chunk(&self, chunk_index: u64, buf: &mut ChunkBuffer) -> io::Result<usize> {
+        if let Some(chunk) = &self.buffer.chunks(CHUNK_SIZE as usize).nth(chunk_index as usize) {
+            buf[..chunk.len()].copy_from_slice(chunk);
+            Ok(chunk.len())
+        } else {
+            Ok(0) // Read beyond EOF is normal
+        }
+    }
+}
diff --git a/guest/authfs/src/file/attr.rs b/guest/authfs/src/file/attr.rs
new file mode 100644
index 0000000..48084aa
--- /dev/null
+++ b/guest/authfs/src/file/attr.rs
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2021 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 log::error;
+use nix::sys::stat::{mode_t, Mode, SFlag};
+use std::io;
+
+use super::VirtFdService;
+
+/// Default/assumed mode of files not created by authfs.
+///
+/// For files that are given to authfs as FDs (i.e. not created through authfs), their mode is
+/// unknown (or untrusted) until it is ever set. The default mode is just to make it
+/// readable/writable to VFS. When the mode is set, the value on fd_server is supposed to become
+/// consistent.
+const DEFAULT_FILE_MODE: Mode =
+    Mode::from_bits_truncate(Mode::S_IRUSR.bits() | Mode::S_IWUSR.bits());
+
+/// Default/assumed mode of directories not created by authfs.
+///
+/// See above.
+const DEFAULT_DIR_MODE: Mode = Mode::S_IRWXU;
+
+/// `Attr` maintains the local truth for attributes (e.g. mode and type) while allowing setting the
+/// remote attribute for the file description.
+pub struct Attr {
+    service: VirtFdService,
+    mode: Mode,
+    remote_fd: i32,
+    is_dir: bool,
+}
+
+impl Attr {
+    pub fn new_file(service: VirtFdService, remote_fd: i32) -> Attr {
+        Attr { service, mode: DEFAULT_FILE_MODE, remote_fd, is_dir: false }
+    }
+
+    pub fn new_dir(service: VirtFdService, remote_fd: i32) -> Attr {
+        Attr { service, mode: DEFAULT_DIR_MODE, remote_fd, is_dir: true }
+    }
+
+    pub fn new_file_with_mode(service: VirtFdService, remote_fd: i32, mode: mode_t) -> Attr {
+        Attr { service, mode: Mode::from_bits_truncate(mode), remote_fd, is_dir: false }
+    }
+
+    pub fn new_dir_with_mode(service: VirtFdService, remote_fd: i32, mode: mode_t) -> Attr {
+        Attr { service, mode: Mode::from_bits_truncate(mode), remote_fd, is_dir: true }
+    }
+
+    pub fn mode(&self) -> u32 {
+        self.mode.bits()
+    }
+
+    /// Sets the file mode.
+    ///
+    /// In addition to the actual file mode, `encoded_mode` also contains information of the file
+    /// type.
+    pub fn set_mode(&mut self, encoded_mode: u32) -> io::Result<()> {
+        let new_sflag = SFlag::from_bits_truncate(encoded_mode);
+        let new_mode = Mode::from_bits_truncate(encoded_mode);
+
+        let type_flag = if self.is_dir { SFlag::S_IFDIR } else { SFlag::S_IFREG };
+        if !type_flag.contains(new_sflag) {
+            return Err(io::Error::from_raw_os_error(libc::EINVAL));
+        }
+
+        // Request for update only if changing.
+        if new_mode != self.mode {
+            self.service.chmod(self.remote_fd, new_mode.bits() as i32).map_err(|e| {
+                error!(
+                    "Failed to chmod (fd: {}, mode: {:o}) on fd_server: {:?}",
+                    self.remote_fd, new_mode, e
+                );
+                io::Error::from_raw_os_error(libc::EIO)
+            })?;
+            self.mode = new_mode;
+        }
+        Ok(())
+    }
+}
diff --git a/guest/authfs/src/file/dir.rs b/guest/authfs/src/file/dir.rs
new file mode 100644
index 0000000..5d2ec9f
--- /dev/null
+++ b/guest/authfs/src/file/dir.rs
@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 2021 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 log::warn;
+use nix::sys::stat::Mode;
+use std::collections::{hash_map, HashMap};
+use std::ffi::{CString, OsString};
+use std::io;
+use std::os::unix::ffi::OsStringExt;
+use std::path::{Path, PathBuf};
+
+use super::attr::Attr;
+use super::remote_file::RemoteFileEditor;
+use super::{validate_basename, VirtFdService, VirtFdServiceStatus};
+use crate::fsverity::VerifiedFileEditor;
+use crate::fusefs::{AuthFsDirEntry, Inode};
+
+const MAX_ENTRIES: u16 = 1000; // Arbitrary limit
+
+struct InodeInfo {
+    inode: Inode,
+
+    // This information is duplicated since it is also available in `AuthFs::inode_table` via the
+    // type system. But it makes it simple to deal with deletion, where otherwise we need to get a
+    // mutable parent directory in the table, and query the table for directory/file type checking
+    // at the same time.
+    is_dir: bool,
+}
+
+/// A remote directory backed by a remote directory FD, where the provider/fd_server is not
+/// trusted.
+///
+/// The directory is assumed empty initially without the trust to the storage. Functionally, when
+/// the backing storage is not clean, the fd_server can fail to create a file or directory when
+/// there is name collision. From RemoteDirEditor's perspective of security, the creation failure
+/// is just one of possible errors that can happen, and what matters is RemoteDirEditor maintains
+/// the integrity itself.
+///
+/// When new files are created through RemoteDirEditor, the file integrity are maintained within the
+/// VM. Similarly, integrity (namely the list of entries) of the directory, or new directories
+/// created within such a directory, are also maintained within the VM. A compromised fd_server or
+/// malicious client can't affect the view to the files and directories within such a directory in
+/// the VM.
+pub struct RemoteDirEditor {
+    service: VirtFdService,
+    remote_dir_fd: i32,
+
+    /// Mapping of entry names to the corresponding inode. The actual file/directory is stored in
+    /// the global pool in fusefs.
+    entries: HashMap<PathBuf, InodeInfo>,
+}
+
+impl RemoteDirEditor {
+    pub fn new(service: VirtFdService, remote_dir_fd: i32) -> Self {
+        RemoteDirEditor { service, remote_dir_fd, entries: HashMap::new() }
+    }
+
+    /// Returns the number of entries created.
+    pub fn number_of_entries(&self) -> u16 {
+        self.entries.len() as u16 // limited to MAX_ENTRIES
+    }
+
+    /// Creates a remote file named `basename` with corresponding `inode` at the current directory.
+    pub fn create_file(
+        &mut self,
+        basename: &Path,
+        inode: Inode,
+        mode: libc::mode_t,
+    ) -> io::Result<(VerifiedFileEditor<RemoteFileEditor>, Attr)> {
+        let mode = self.validate_arguments(basename, mode)?;
+        let basename_str =
+            basename.to_str().ok_or_else(|| io::Error::from_raw_os_error(libc::EINVAL))?;
+        let new_fd = self
+            .service
+            .createFileInDirectory(self.remote_dir_fd, basename_str, mode as i32)
+            .map_err(into_io_error)?;
+
+        let new_remote_file =
+            VerifiedFileEditor::new(RemoteFileEditor::new(self.service.clone(), new_fd));
+        self.entries.insert(basename.to_path_buf(), InodeInfo { inode, is_dir: false });
+        let new_attr = Attr::new_file_with_mode(self.service.clone(), new_fd, mode);
+        Ok((new_remote_file, new_attr))
+    }
+
+    /// Creates a remote directory named `basename` with corresponding `inode` at the current
+    /// directory.
+    pub fn mkdir(
+        &mut self,
+        basename: &Path,
+        inode: Inode,
+        mode: libc::mode_t,
+    ) -> io::Result<(RemoteDirEditor, Attr)> {
+        let mode = self.validate_arguments(basename, mode)?;
+        let basename_str =
+            basename.to_str().ok_or_else(|| io::Error::from_raw_os_error(libc::EINVAL))?;
+        let new_fd = self
+            .service
+            .createDirectoryInDirectory(self.remote_dir_fd, basename_str, mode as i32)
+            .map_err(into_io_error)?;
+
+        let new_remote_dir = RemoteDirEditor::new(self.service.clone(), new_fd);
+        self.entries.insert(basename.to_path_buf(), InodeInfo { inode, is_dir: true });
+        let new_attr = Attr::new_dir_with_mode(self.service.clone(), new_fd, mode);
+        Ok((new_remote_dir, new_attr))
+    }
+
+    /// Deletes a file
+    pub fn delete_file(&mut self, basename: &Path) -> io::Result<Inode> {
+        let inode = self.force_delete_entry(basename, /* expect_dir */ false)?;
+
+        let basename_str =
+            basename.to_str().ok_or_else(|| io::Error::from_raw_os_error(libc::EINVAL))?;
+        if let Err(e) = self.service.deleteFile(self.remote_dir_fd, basename_str) {
+            // Ignore the error to honor the local state.
+            warn!("Deletion on the host is reportedly failed: {:?}", e);
+        }
+        Ok(inode)
+    }
+
+    /// Forces to delete a directory. The caller must only call if `basename` is a directory and
+    /// empty.
+    pub fn force_delete_directory(&mut self, basename: &Path) -> io::Result<Inode> {
+        let inode = self.force_delete_entry(basename, /* expect_dir */ true)?;
+
+        let basename_str =
+            basename.to_str().ok_or_else(|| io::Error::from_raw_os_error(libc::EINVAL))?;
+        if let Err(e) = self.service.deleteDirectory(self.remote_dir_fd, basename_str) {
+            // Ignore the error to honor the local state.
+            warn!("Deletion on the host is reportedly failed: {:?}", e);
+        }
+        Ok(inode)
+    }
+
+    /// Returns the inode number of a file or directory named `name` previously created through
+    /// `RemoteDirEditor`.
+    pub fn find_inode(&self, name: &Path) -> io::Result<Inode> {
+        self.entries
+            .get(name)
+            .map(|entry| entry.inode)
+            .ok_or_else(|| io::Error::from_raw_os_error(libc::ENOENT))
+    }
+
+    /// Returns whether the directory has an entry of the given name.
+    pub fn has_entry(&self, name: &Path) -> bool {
+        self.entries.contains_key(name)
+    }
+
+    pub fn retrieve_entries(&self) -> io::Result<Vec<AuthFsDirEntry>> {
+        self.entries
+            .iter()
+            .map(|(name, InodeInfo { inode, is_dir })| {
+                Ok(AuthFsDirEntry { inode: *inode, name: path_to_cstring(name)?, is_dir: *is_dir })
+            })
+            .collect::<io::Result<Vec<_>>>()
+    }
+
+    fn force_delete_entry(&mut self, basename: &Path, expect_dir: bool) -> io::Result<Inode> {
+        // Kernel should only give us a basename.
+        debug_assert!(validate_basename(basename).is_ok());
+
+        if let Some(entry) = self.entries.get(basename) {
+            match (expect_dir, entry.is_dir) {
+                (true, false) => Err(io::Error::from_raw_os_error(libc::ENOTDIR)),
+                (false, true) => Err(io::Error::from_raw_os_error(libc::EISDIR)),
+                _ => {
+                    let inode = entry.inode;
+                    let _ = self.entries.remove(basename);
+                    Ok(inode)
+                }
+            }
+        } else {
+            Err(io::Error::from_raw_os_error(libc::ENOENT))
+        }
+    }
+
+    fn validate_arguments(&self, basename: &Path, mode: u32) -> io::Result<u32> {
+        // Kernel should only give us a basename.
+        debug_assert!(validate_basename(basename).is_ok());
+
+        if self.entries.contains_key(basename) {
+            return Err(io::Error::from_raw_os_error(libc::EEXIST));
+        }
+
+        if self.entries.len() >= MAX_ENTRIES.into() {
+            return Err(io::Error::from_raw_os_error(libc::EMLINK));
+        }
+
+        Ok(Mode::from_bits_truncate(mode).bits())
+    }
+}
+
+/// An in-memory directory representation of a directory structure.
+pub struct InMemoryDir(HashMap<PathBuf, InodeInfo>);
+
+impl InMemoryDir {
+    /// Creates an empty instance of `InMemoryDir`.
+    pub fn new() -> Self {
+        // Hash map is empty since "." and ".." are excluded in entries.
+        InMemoryDir(HashMap::new())
+    }
+
+    /// Returns the number of entries in the directory (not including "." and "..").
+    pub fn number_of_entries(&self) -> u16 {
+        self.0.len() as u16 // limited to MAX_ENTRIES
+    }
+
+    /// Adds a directory name and its inode number to the directory. Fails if already exists. The
+    /// caller is responsible for ensure the inode uniqueness.
+    pub fn add_dir(&mut self, basename: &Path, inode: Inode) -> io::Result<()> {
+        self.add_entry(basename, InodeInfo { inode, is_dir: true })
+    }
+
+    /// Adds a file name and its inode number to the directory. Fails if already exists. The
+    /// caller is responsible for ensure the inode uniqueness.
+    pub fn add_file(&mut self, basename: &Path, inode: Inode) -> io::Result<()> {
+        self.add_entry(basename, InodeInfo { inode, is_dir: false })
+    }
+
+    fn add_entry(&mut self, basename: &Path, dir_entry: InodeInfo) -> io::Result<()> {
+        validate_basename(basename)?;
+        if self.0.len() >= MAX_ENTRIES.into() {
+            return Err(io::Error::from_raw_os_error(libc::EMLINK));
+        }
+
+        if let hash_map::Entry::Vacant(entry) = self.0.entry(basename.to_path_buf()) {
+            entry.insert(dir_entry);
+            Ok(())
+        } else {
+            Err(io::Error::from_raw_os_error(libc::EEXIST))
+        }
+    }
+
+    /// Looks up an entry inode by name. `None` if not found.
+    pub fn lookup_inode(&self, basename: &Path) -> Option<Inode> {
+        self.0.get(basename).map(|entry| entry.inode)
+    }
+
+    pub fn retrieve_entries(&self) -> io::Result<Vec<AuthFsDirEntry>> {
+        self.0
+            .iter()
+            .map(|(name, InodeInfo { inode, is_dir })| {
+                Ok(AuthFsDirEntry { inode: *inode, name: path_to_cstring(name)?, is_dir: *is_dir })
+            })
+            .collect::<io::Result<Vec<_>>>()
+    }
+}
+
+fn path_to_cstring(path: &Path) -> io::Result<CString> {
+    let bytes = OsString::from(path).into_vec();
+    CString::new(bytes).map_err(|_| io::Error::from_raw_os_error(libc::EILSEQ))
+}
+
+fn into_io_error(e: VirtFdServiceStatus) -> io::Error {
+    let maybe_errno = e.service_specific_error();
+    if maybe_errno > 0 {
+        io::Error::from_raw_os_error(maybe_errno)
+    } else {
+        io::Error::new(io::ErrorKind::Other, e.get_description())
+    }
+}
diff --git a/guest/authfs/src/file/remote_file.rs b/guest/authfs/src/file/remote_file.rs
new file mode 100644
index 0000000..4c112bd
--- /dev/null
+++ b/guest/authfs/src/file/remote_file.rs
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2021 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 std::cmp::min;
+use std::convert::TryFrom;
+use std::io;
+use std::path::Path;
+
+use super::{ChunkBuffer, RandomWrite, ReadByChunk, VirtFdService};
+use crate::common::CHUNK_SIZE;
+
+fn remote_read_chunk(
+    service: &VirtFdService,
+    remote_fd: i32,
+    chunk_index: u64,
+    buf: &mut ChunkBuffer,
+) -> io::Result<usize> {
+    let offset = i64::try_from(chunk_index * CHUNK_SIZE)
+        .map_err(|_| io::Error::from_raw_os_error(libc::EOVERFLOW))?;
+
+    let chunk = service
+        .readFile(remote_fd, offset, buf.len() as i32)
+        .map_err(|e| io::Error::new(io::ErrorKind::Other, e.get_description()))?;
+    let size = min(buf.len(), chunk.len());
+    buf[..size].copy_from_slice(&chunk[..size]);
+    Ok(size)
+}
+
+pub struct RemoteFileReader {
+    service: VirtFdService,
+    file_fd: i32,
+}
+
+impl RemoteFileReader {
+    pub fn new(service: VirtFdService, file_fd: i32) -> Self {
+        RemoteFileReader { service, file_fd }
+    }
+
+    pub fn new_by_path(
+        service: VirtFdService,
+        dir_fd: i32,
+        related_path: &Path,
+    ) -> io::Result<Self> {
+        let file_fd =
+            service.openFileInDirectory(dir_fd, related_path.to_str().unwrap()).map_err(|e| {
+                io::Error::new(
+                    io::ErrorKind::Other,
+                    format!(
+                        "Failed to create a remote file reader by path {}: {}",
+                        related_path.display(),
+                        e.get_description()
+                    ),
+                )
+            })?;
+        Ok(RemoteFileReader { service, file_fd })
+    }
+
+    pub fn get_remote_fd(&self) -> i32 {
+        self.file_fd
+    }
+}
+
+impl ReadByChunk for RemoteFileReader {
+    fn read_chunk(&self, chunk_index: u64, buf: &mut ChunkBuffer) -> io::Result<usize> {
+        remote_read_chunk(&self.service, self.file_fd, chunk_index, buf)
+    }
+}
+
+pub struct RemoteMerkleTreeReader {
+    service: VirtFdService,
+    file_fd: i32,
+}
+
+impl RemoteMerkleTreeReader {
+    pub fn new(service: VirtFdService, file_fd: i32) -> Self {
+        RemoteMerkleTreeReader { service, file_fd }
+    }
+}
+
+impl ReadByChunk for RemoteMerkleTreeReader {
+    fn read_chunk(&self, chunk_index: u64, buf: &mut ChunkBuffer) -> io::Result<usize> {
+        let offset = i64::try_from(chunk_index * CHUNK_SIZE)
+            .map_err(|_| io::Error::from_raw_os_error(libc::EOVERFLOW))?;
+
+        let chunk = self
+            .service
+            .readFsverityMerkleTree(self.file_fd, offset, buf.len() as i32)
+            .map_err(|e| io::Error::new(io::ErrorKind::Other, e.get_description()))?;
+        let size = min(buf.len(), chunk.len());
+        buf[..size].copy_from_slice(&chunk[..size]);
+        Ok(size)
+    }
+}
+
+pub struct RemoteFileEditor {
+    service: VirtFdService,
+    file_fd: i32,
+}
+
+impl RemoteFileEditor {
+    pub fn new(service: VirtFdService, file_fd: i32) -> Self {
+        RemoteFileEditor { service, file_fd }
+    }
+}
+
+impl RandomWrite for RemoteFileEditor {
+    fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
+        let offset =
+            i64::try_from(offset).map_err(|_| io::Error::from_raw_os_error(libc::EOVERFLOW))?;
+        let size = self
+            .service
+            .writeFile(self.file_fd, buf, offset)
+            .map_err(|e| io::Error::new(io::ErrorKind::Other, e.get_description()))?;
+        Ok(size as usize) // within range because size is supposed to <= buf.len(), which is a usize
+    }
+
+    fn resize(&self, size: u64) -> io::Result<()> {
+        let size =
+            i64::try_from(size).map_err(|_| io::Error::from_raw_os_error(libc::EOVERFLOW))?;
+        self.service
+            .resize(self.file_fd, size)
+            .map_err(|e| io::Error::new(io::ErrorKind::Other, e.get_description()))?;
+        Ok(())
+    }
+}
+
+impl ReadByChunk for RemoteFileEditor {
+    fn read_chunk(&self, chunk_index: u64, buf: &mut ChunkBuffer) -> io::Result<usize> {
+        remote_read_chunk(&self.service, self.file_fd, chunk_index, buf)
+    }
+}
diff --git a/guest/authfs/src/fsstat.rs b/guest/authfs/src/fsstat.rs
new file mode 100644
index 0000000..81eaca1
--- /dev/null
+++ b/guest/authfs/src/fsstat.rs
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2021 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 log::error;
+use std::convert::TryInto;
+use std::io;
+
+use crate::file::VirtFdService;
+use authfs_aidl_interface::aidl::com::android::virt::fs::IVirtFdService::FsStat::FsStat;
+
+/// Relevant/interesting stats of a remote filesystem.
+pub struct RemoteFsStats {
+    /// Block size of the filesystem
+    pub block_size: u64,
+    /// Fragment size of the filesystem
+    pub fragment_size: u64,
+    /// Number of blocks in the filesystem
+    pub block_numbers: u64,
+    /// Number of free blocks
+    pub block_available: u64,
+    /// Number of free inodes
+    pub inodes_available: u64,
+    /// Maximum filename length
+    pub max_filename: u64,
+}
+
+pub struct RemoteFsStatsReader {
+    service: VirtFdService,
+}
+
+impl RemoteFsStatsReader {
+    pub fn new(service: VirtFdService) -> Self {
+        Self { service }
+    }
+
+    pub fn statfs(&self) -> io::Result<RemoteFsStats> {
+        let st = self.service.statfs().map_err(|e| {
+            error!("Failed to call statfs on fd_server: {:?}", e);
+            io::Error::from_raw_os_error(libc::EIO)
+        })?;
+        try_into_remote_fs_stats(st).map_err(|_| {
+            error!("Received invalid stats from fd_server");
+            io::Error::from_raw_os_error(libc::EIO)
+        })
+    }
+}
+
+fn try_into_remote_fs_stats(st: FsStat) -> Result<RemoteFsStats, std::num::TryFromIntError> {
+    Ok(RemoteFsStats {
+        block_size: st.blockSize.try_into()?,
+        fragment_size: st.fragmentSize.try_into()?,
+        block_numbers: st.blockNumbers.try_into()?,
+        block_available: st.blockAvailable.try_into()?,
+        inodes_available: st.inodesAvailable.try_into()?,
+        max_filename: st.maxFilename.try_into()?,
+    })
+}
diff --git a/guest/authfs/src/fsverity.rs b/guest/authfs/src/fsverity.rs
new file mode 100644
index 0000000..61ae928
--- /dev/null
+++ b/guest/authfs/src/fsverity.rs
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+mod builder;
+mod common;
+mod editor;
+mod sys;
+mod verifier;
+
+pub use common::merkle_tree_size;
+pub use editor::VerifiedFileEditor;
+pub use verifier::VerifiedFileReader;
diff --git a/guest/authfs/src/fsverity/builder.rs b/guest/authfs/src/fsverity/builder.rs
new file mode 100644
index 0000000..6d724ca
--- /dev/null
+++ b/guest/authfs/src/fsverity/builder.rs
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 2021 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 super::common::{
+    build_fsverity_digest, merkle_tree_height, FsverityError, Sha256Hash, SHA256_HASH_SIZE,
+};
+use crate::common::{divide_roundup, CHUNK_SIZE};
+use openssl::sha::Sha256;
+
+const HASH_SIZE: usize = SHA256_HASH_SIZE;
+const HASH_PER_PAGE: usize = CHUNK_SIZE as usize / HASH_SIZE;
+
+const HASH_OF_4096_ZEROS: Sha256Hash = [
+    0xad, 0x7f, 0xac, 0xb2, 0x58, 0x6f, 0xc6, 0xe9, 0x66, 0xc0, 0x04, 0xd7, 0xd1, 0xd1, 0x6b, 0x02,
+    0x4f, 0x58, 0x05, 0xff, 0x7c, 0xb4, 0x7c, 0x7a, 0x85, 0xda, 0xbd, 0x8b, 0x48, 0x89, 0x2c, 0xa7,
+];
+
+/// MerkleLeaves can be used by the class' customer for bookkeeping integrity data for their bytes.
+/// It can also be used to generate the standard fs-verity digest for the source data.
+///
+/// It's in-memory because for the initial use cases, we don't need to read back an existing file,
+/// and only need to deal with new files. Also, considering that the output file won't be large at
+/// the moment, it is sufficient to simply keep the Merkle tree in memory in the trusted world. To
+/// further simplify the initial implementation, we only need to keep the leaf nodes in memory, and
+/// generate the tree / root hash when requested.
+pub struct MerkleLeaves {
+    leaves: Vec<Sha256Hash>,
+    file_size: u64,
+}
+
+fn hash_all_pages(source: &[Sha256Hash]) -> Vec<Sha256Hash> {
+    source
+        .chunks(HASH_PER_PAGE)
+        .map(|chunk| {
+            let padding_bytes = (HASH_PER_PAGE - chunk.len()) * HASH_SIZE;
+            let mut ctx = Sha256::new();
+            for data in chunk {
+                ctx.update(data.as_ref());
+            }
+            ctx.update(&vec![0u8; padding_bytes]);
+            ctx.finish()
+        })
+        .collect()
+}
+
+impl MerkleLeaves {
+    /// Creates a `MerkleLeaves` instance with empty data.
+    pub fn new() -> Self {
+        Self { leaves: Vec::new(), file_size: 0 }
+    }
+
+    /// Gets size of the file represented by `MerkleLeaves`.
+    pub fn file_size(&self) -> u64 {
+        self.file_size
+    }
+
+    /// Grows the `MerkleLeaves` to the new file size. To keep the consistency, if any new leaves
+    /// are added, the leaves/hashes are as if the extended content is all zero.
+    ///
+    /// However, when the change shrinks the leaf number, `MerkleLeaves` does not know if the hash
+    /// of the last chunk has changed, or what the new value should be. As the result, it is up to
+    /// the caller to fix the last leaf if needed.
+    pub fn resize(&mut self, new_file_size: usize) {
+        let new_file_size = new_file_size as u64;
+        let leaves_size = divide_roundup(new_file_size, CHUNK_SIZE);
+        self.leaves.resize(leaves_size as usize, HASH_OF_4096_ZEROS);
+        self.file_size = new_file_size;
+    }
+
+    /// Updates the hash of the `index`-th leaf, and increase the size to `size_at_least` if the
+    /// current size is smaller.
+    pub fn update_hash(&mut self, index: usize, hash: &Sha256Hash, size_at_least: u64) {
+        // +1 since index is zero-based.
+        if self.leaves.len() < index + 1 {
+            // When resizing, fill in hash of zeros by default. This makes it easy to handle holes
+            // in a file.
+            self.leaves.resize(index + 1, HASH_OF_4096_ZEROS);
+        }
+        self.leaves[index].clone_from_slice(hash);
+
+        if size_at_least > self.file_size {
+            self.file_size = size_at_least;
+        }
+    }
+
+    /// Returns whether `index` is within the bound of leaves.
+    pub fn is_index_valid(&self, index: usize) -> bool {
+        index < self.leaves.len()
+    }
+
+    /// Returns whether the `index`-th hash is consistent to `hash`.
+    pub fn is_consistent(&self, index: usize, hash: &Sha256Hash) -> bool {
+        if let Some(element) = self.leaves.get(index) {
+            element == hash
+        } else {
+            false
+        }
+    }
+
+    fn calculate_root_hash(&self) -> Result<Sha256Hash, FsverityError> {
+        match self.leaves.len() {
+            // Special cases per fs-verity digest definition.
+            0 => {
+                debug_assert_eq!(self.file_size, 0);
+                Ok([0u8; HASH_SIZE])
+            }
+            1 => {
+                debug_assert!(self.file_size <= CHUNK_SIZE && self.file_size > 0);
+                Ok(self.leaves[0])
+            }
+            n => {
+                debug_assert_eq!((self.file_size - 1) / CHUNK_SIZE, n as u64);
+                let size_for_equivalent = n as u64 * CHUNK_SIZE;
+                let level = merkle_tree_height(size_for_equivalent).unwrap(); // safe since n > 0
+
+                // `leaves` is owned and can't be the initial state below. Here we manually hash it
+                // first to avoid a copy and to get the type right.
+                let second_level = hash_all_pages(&self.leaves);
+                let hashes = (1..=level).fold(second_level, |source, _| hash_all_pages(&source));
+                if hashes.len() != 1 {
+                    Err(FsverityError::InvalidState)
+                } else {
+                    Ok(hashes.into_iter().next().unwrap())
+                }
+            }
+        }
+    }
+
+    /// Returns the fs-verity digest based on the current tree and file size.
+    pub fn calculate_fsverity_digest(&self) -> Result<Sha256Hash, FsverityError> {
+        let root_hash = self.calculate_root_hash()?;
+        Ok(build_fsverity_digest(&root_hash, self.file_size))
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    // Test data below can be generated by:
+    //  $ perl -e 'print "\x{00}" x 6000' > foo
+    //  $ perl -e 'print "\x{01}" x 5000' >> foo
+    //  $ fsverity digest foo
+    use super::*;
+    use anyhow::Result;
+    use openssl::sha::sha256;
+
+    #[test]
+    fn merkle_tree_empty_file() -> Result<()> {
+        assert_eq!(
+            hex::decode("3d248ca542a24fc62d1c43b916eae5016878e2533c88238480b26128a1f1af95")?,
+            generate_fsverity_digest_sequentially(&Vec::new())?
+        );
+        Ok(())
+    }
+
+    #[test]
+    fn merkle_tree_file_size_less_than_or_equal_to_4k() -> Result<()> {
+        // Test a file that contains 4096 '\01's.
+        assert_eq!(
+            hex::decode("cd0875ca59c7d37e962c5e8f5acd3770750ac80225e2df652ce5672fd34500af")?,
+            generate_fsverity_digest_sequentially(&vec![1; 4096])?
+        );
+        Ok(())
+    }
+
+    #[test]
+    fn merkle_tree_more_sizes() -> Result<()> {
+        // Test files that contains >4096 '\01's.
+
+        assert_eq!(
+            hex::decode("2901b849fda2d91e3929524561c4a47e77bb64734319759507b2029f18b9cc52")?,
+            generate_fsverity_digest_sequentially(&vec![1; 4097])?
+        );
+
+        assert_eq!(
+            hex::decode("2a476d58eb80394052a3a783111e1458ac3ecf68a7878183fed86ca0ff47ec0d")?,
+            generate_fsverity_digest_sequentially(&vec![1; 8192])?
+        );
+
+        // Test with max size that still fits in 2 levels.
+        assert_eq!(
+            hex::decode("26b7c190a34e19f420808ee7ec233b09fa6c34543b5a9d2950530114c205d14f")?,
+            generate_fsverity_digest_sequentially(&vec![1; 524288])?
+        );
+
+        // Test with data that requires 3 levels.
+        assert_eq!(
+            hex::decode("316835d9be1c95b5cd55d07ae7965d651689efad186e26cbf680e40b683a3262")?,
+            generate_fsverity_digest_sequentially(&vec![1; 524289])?
+        );
+        Ok(())
+    }
+
+    #[test]
+    fn merkle_tree_non_sequential() -> Result<()> {
+        let mut tree = MerkleLeaves::new();
+        let hash = sha256(&vec![1u8; CHUNK_SIZE as usize]);
+
+        // Update hashes of 4 1-blocks.
+        tree.update_hash(1, &hash, CHUNK_SIZE * 2);
+        tree.update_hash(3, &hash, CHUNK_SIZE * 4);
+        tree.update_hash(0, &hash, CHUNK_SIZE);
+        tree.update_hash(2, &hash, CHUNK_SIZE * 3);
+
+        assert_eq!(
+            hex::decode("7d3c0d2e1dc54230b20ed875f5f3a4bd3f9873df601936b3ca8127d4db3548f3")?,
+            tree.calculate_fsverity_digest()?
+        );
+        Ok(())
+    }
+
+    #[test]
+    fn merkle_tree_grow_leaves() -> Result<()> {
+        let mut tree = MerkleLeaves::new();
+        tree.update_hash(0, &[42; HASH_SIZE], CHUNK_SIZE); // fake hash of a CHUNK_SIZE block
+
+        // Grows the leaves
+        tree.resize(4096 * 3 - 100);
+
+        assert!(tree.is_index_valid(0));
+        assert!(tree.is_index_valid(1));
+        assert!(tree.is_index_valid(2));
+        assert!(!tree.is_index_valid(3));
+        assert!(tree.is_consistent(1, &HASH_OF_4096_ZEROS));
+        assert!(tree.is_consistent(2, &HASH_OF_4096_ZEROS));
+        Ok(())
+    }
+
+    #[test]
+    fn merkle_tree_shrink_leaves() -> Result<()> {
+        let mut tree = MerkleLeaves::new();
+        tree.update_hash(0, &[42; HASH_SIZE], CHUNK_SIZE);
+        tree.update_hash(0, &[42; HASH_SIZE], CHUNK_SIZE * 3);
+
+        // Shrink the leaves
+        tree.resize(CHUNK_SIZE as usize * 2 - 100);
+
+        assert!(tree.is_index_valid(0));
+        assert!(tree.is_index_valid(1));
+        assert!(!tree.is_index_valid(2));
+        // The second chunk is a hole and full of zero. When shrunk, with zero padding, the hash
+        // happens to be consistent to a full-zero chunk.
+        assert!(tree.is_consistent(1, &HASH_OF_4096_ZEROS));
+        Ok(())
+    }
+
+    fn generate_fsverity_digest_sequentially(test_data: &[u8]) -> Result<Sha256Hash> {
+        let mut tree = MerkleLeaves::new();
+        for (index, chunk) in test_data.chunks(CHUNK_SIZE as usize).enumerate() {
+            let mut ctx = Sha256::new();
+            ctx.update(chunk);
+            ctx.update(&vec![0u8; CHUNK_SIZE as usize - chunk.len()]);
+            let hash = ctx.finish();
+
+            tree.update_hash(index, &hash, CHUNK_SIZE * index as u64 + chunk.len() as u64);
+        }
+        Ok(tree.calculate_fsverity_digest()?)
+    }
+}
diff --git a/guest/authfs/src/fsverity/common.rs b/guest/authfs/src/fsverity/common.rs
new file mode 100644
index 0000000..cb268ef
--- /dev/null
+++ b/guest/authfs/src/fsverity/common.rs
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2021 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 std::io;
+
+use thiserror::Error;
+
+use super::sys::{FS_VERITY_HASH_ALG_SHA256, FS_VERITY_LOG_BLOCKSIZE, FS_VERITY_VERSION};
+use crate::common::{divide_roundup, CHUNK_SIZE};
+use openssl::sha::Sha256;
+
+/// Output size of SHA-256 in bytes.
+pub const SHA256_HASH_SIZE: usize = 32;
+
+/// A SHA-256 hash.
+pub type Sha256Hash = [u8; SHA256_HASH_SIZE];
+
+#[derive(Error, Debug)]
+pub enum FsverityError {
+    #[error("Invalid digest")]
+    InvalidDigest,
+    #[error("Insufficient data, only got {0}")]
+    InsufficientData(usize),
+    #[error("Cannot verify a block")]
+    CannotVerify,
+    #[error("I/O error")]
+    Io(#[from] io::Error),
+    #[error("Invalid state")]
+    InvalidState,
+}
+
+fn log128_ceil(num: u64) -> Option<u64> {
+    match num {
+        0 => None,
+        n => Some(divide_roundup(64 - (n - 1).leading_zeros() as u64, 7)),
+    }
+}
+
+/// Return the Merkle tree height for our tree configuration, or None if the size is 0.
+pub fn merkle_tree_height(data_size: u64) -> Option<u64> {
+    let hashes_per_node = CHUNK_SIZE / SHA256_HASH_SIZE as u64;
+    let hash_pages = divide_roundup(data_size, hashes_per_node * CHUNK_SIZE);
+    log128_ceil(hash_pages)
+}
+
+/// Returns the size of Merkle tree for `data_size` bytes amount of data.
+pub fn merkle_tree_size(mut data_size: u64) -> u64 {
+    let mut total = 0;
+    while data_size > CHUNK_SIZE {
+        let hash_size = divide_roundup(data_size, CHUNK_SIZE) * SHA256_HASH_SIZE as u64;
+        let hash_storage_size = divide_roundup(hash_size, CHUNK_SIZE) * CHUNK_SIZE;
+        total += hash_storage_size;
+        data_size = hash_storage_size;
+    }
+    total
+}
+
+pub fn build_fsverity_digest(root_hash: &Sha256Hash, file_size: u64) -> Sha256Hash {
+    // Little-endian byte representation of fsverity_descriptor from linux/fsverity.h
+    // Not FFI-ed as it seems easier to deal with the raw bytes manually.
+    let mut hash = Sha256::new();
+    hash.update(&FS_VERITY_VERSION.to_le_bytes()); // version
+    hash.update(&FS_VERITY_HASH_ALG_SHA256.to_le_bytes()); // hash_algorithm
+    hash.update(&FS_VERITY_LOG_BLOCKSIZE.to_le_bytes()); // log_blocksize
+    hash.update(&0u8.to_le_bytes()); // salt_size
+    hash.update(&0u32.to_le_bytes()); // sig_size
+    hash.update(&file_size.to_le_bytes()); // data_size
+    hash.update(root_hash); // root_hash, first 32 bytes
+    hash.update(&[0u8; 32]); // root_hash, last 32 bytes, always 0 because we are using sha256.
+    hash.update(&[0u8; 32]); // salt
+    hash.update(&[0u8; 32]); // reserved
+    hash.update(&[0u8; 32]); // reserved
+    hash.update(&[0u8; 32]); // reserved
+    hash.update(&[0u8; 32]); // reserved
+    hash.update(&[0u8; 16]); // reserved
+    hash.finish()
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_merkle_tree_size() {
+        // To produce groundtruth:
+        //   dd if=/dev/zero of=zeros bs=1 count=524289 && \
+        //   fsverity digest --out-merkle-tree=tree zeros && \
+        //   du -b tree
+        assert_eq!(merkle_tree_size(0), 0);
+        assert_eq!(merkle_tree_size(1), 0);
+        assert_eq!(merkle_tree_size(4096), 0);
+        assert_eq!(merkle_tree_size(4097), 4096);
+        assert_eq!(merkle_tree_size(524288), 4096);
+        assert_eq!(merkle_tree_size(524289), 12288);
+    }
+}
diff --git a/guest/authfs/src/fsverity/editor.rs b/guest/authfs/src/fsverity/editor.rs
new file mode 100644
index 0000000..c84500b
--- /dev/null
+++ b/guest/authfs/src/fsverity/editor.rs
@@ -0,0 +1,629 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+//! A module for writing to a file from a trusted world to an untrusted storage.
+//!
+//! Architectural Model:
+//!  * Trusted world: the writer, a signing secret, has some memory, but NO persistent storage.
+//!  * Untrusted world: persistent storage, assuming untrusted.
+//!  * IPC mechanism between trusted and untrusted world
+//!
+//! Use cases:
+//!  * In the trusted world, we want to generate a large file, sign it, and share the signature for
+//!    a third party to verify the file.
+//!  * In the trusted world, we want to read a previously signed file back with signature check
+//!    without having to touch the whole file.
+//!
+//! Requirements:
+//!  * Communication between trusted and untrusted world is not cheap, and files can be large.
+//!  * A file write pattern may not be sequential, neither does read.
+//!
+//! Considering the above, a technique similar to fs-verity is used. fs-verity uses an alternative
+//! hash function, a Merkle tree, to calculate the hash of file content. A file update at any
+//! location will propagate the hash update from the leaf to the root node. Unlike fs-verity, which
+//! assumes static files, to support write operation, we need to allow the file (thus tree) to
+//! update.
+//!
+//! For the trusted world to generate a large file with random write and hash it, the writer needs
+//! to hold some private information and update the Merkle tree during a file write (or even when
+//! the Merkle tree needs to be stashed to the untrusted storage).
+//!
+//! A write to a file must update the root hash. In order for the root hash to update, a tree
+//! walk to update from the write location to the root node is necessary. Importantly, in case when
+//! (part of) the Merkle tree needs to be read from the untrusted storage (e.g. not yet verified in
+//! cache), the original path must be verified by the trusted signature before the update to happen.
+//!
+//! Denial-of-service is a known weakness if the untrusted storage decides to simply remove the
+//! file. But there is nothing we can do in this architecture.
+//!
+//! Rollback attack is another possible attack, but can be addressed with a rollback counter when
+//! possible.
+
+use std::io;
+use std::sync::{Arc, RwLock};
+
+use super::builder::MerkleLeaves;
+use super::common::{Sha256Hash, SHA256_HASH_SIZE};
+use crate::common::{ChunkedSizeIter, CHUNK_SIZE};
+use crate::file::{ChunkBuffer, RandomWrite, ReadByChunk};
+use openssl::sha::{sha256, Sha256};
+
+fn debug_assert_usize_is_u64() {
+    // Since we don't need to support 32-bit CPU, make an assert to make conversion between
+    // u64 and usize easy below. Otherwise, we need to check `divide_roundup(offset + buf.len()
+    // <= usize::MAX` or handle `TryInto` errors.
+    debug_assert!(usize::MAX as u64 == u64::MAX, "Only 64-bit arch is supported");
+}
+
+/// VerifiedFileEditor provides an integrity layer to an underlying read-writable file, which may
+/// not be stored in a trusted environment. Only new, empty files are currently supported.
+pub struct VerifiedFileEditor<F: ReadByChunk + RandomWrite> {
+    file: F,
+    merkle_tree: Arc<RwLock<MerkleLeaves>>,
+}
+
+impl<F: ReadByChunk + RandomWrite> VerifiedFileEditor<F> {
+    /// Wraps a supposedly new file for integrity protection.
+    pub fn new(file: F) -> Self {
+        Self { file, merkle_tree: Arc::new(RwLock::new(MerkleLeaves::new())) }
+    }
+
+    /// Returns the fs-verity digest size in bytes.
+    pub fn get_fsverity_digest_size(&self) -> usize {
+        SHA256_HASH_SIZE
+    }
+
+    /// Calculates the fs-verity digest of the current file.
+    pub fn calculate_fsverity_digest(&self) -> io::Result<Sha256Hash> {
+        let merkle_tree = self.merkle_tree.read().unwrap();
+        merkle_tree.calculate_fsverity_digest().map_err(|e| io::Error::new(io::ErrorKind::Other, e))
+    }
+
+    fn read_backing_chunk_unverified(
+        &self,
+        chunk_index: u64,
+        buf: &mut ChunkBuffer,
+    ) -> io::Result<usize> {
+        self.file.read_chunk(chunk_index, buf)
+    }
+
+    fn read_backing_chunk_verified(
+        &self,
+        chunk_index: u64,
+        buf: &mut ChunkBuffer,
+        merkle_tree_locked: &MerkleLeaves,
+    ) -> io::Result<usize> {
+        debug_assert_usize_is_u64();
+
+        if merkle_tree_locked.is_index_valid(chunk_index as usize) {
+            let size = self.read_backing_chunk_unverified(chunk_index, buf)?;
+
+            // Ensure the returned buffer matches the known hash.
+            let hash = sha256(buf);
+            if !merkle_tree_locked.is_consistent(chunk_index as usize, &hash) {
+                return Err(io::Error::new(io::ErrorKind::InvalidData, "Inconsistent hash"));
+            }
+            Ok(size)
+        } else {
+            Ok(0)
+        }
+    }
+
+    fn new_hash_for_incomplete_write(
+        &self,
+        source: &[u8],
+        offset_from_alignment: usize,
+        output_chunk_index: usize,
+        merkle_tree: &mut MerkleLeaves,
+    ) -> io::Result<Sha256Hash> {
+        // The buffer is initialized to 0 purposely. To calculate the block hash, the data is
+        // 0-padded to the block size. When a chunk read is less than a chunk, the initial value
+        // conveniently serves the padding purpose.
+        let mut orig_data = [0u8; CHUNK_SIZE as usize];
+
+        // If previous data exists, read back and verify against the known hash (since the
+        // storage / remote server is not trusted).
+        if merkle_tree.is_index_valid(output_chunk_index) {
+            self.read_backing_chunk_unverified(output_chunk_index as u64, &mut orig_data)?;
+
+            // Verify original content
+            let hash = sha256(&orig_data);
+            if !merkle_tree.is_consistent(output_chunk_index, &hash) {
+                return Err(io::Error::new(io::ErrorKind::InvalidData, "Inconsistent hash"));
+            }
+        }
+
+        let mut ctx = Sha256::new();
+        ctx.update(&orig_data[..offset_from_alignment]);
+        ctx.update(source);
+        ctx.update(&orig_data[offset_from_alignment + source.len()..]);
+        Ok(ctx.finish())
+    }
+
+    fn new_chunk_hash(
+        &self,
+        source: &[u8],
+        offset_from_alignment: usize,
+        current_size: usize,
+        output_chunk_index: usize,
+        merkle_tree: &mut MerkleLeaves,
+    ) -> io::Result<Sha256Hash> {
+        if current_size as u64 == CHUNK_SIZE {
+            // Case 1: If the chunk is a complete one, just calculate the hash, regardless of
+            // write location.
+            Ok(sha256(source))
+        } else {
+            // Case 2: For an incomplete write, calculate the hash based on previous data (if
+            // any).
+            self.new_hash_for_incomplete_write(
+                source,
+                offset_from_alignment,
+                output_chunk_index,
+                merkle_tree,
+            )
+        }
+    }
+
+    pub fn size(&self) -> u64 {
+        self.merkle_tree.read().unwrap().file_size()
+    }
+}
+
+impl<F: ReadByChunk + RandomWrite> RandomWrite for VerifiedFileEditor<F> {
+    fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
+        debug_assert_usize_is_u64();
+
+        // The write range may not be well-aligned with the chunk boundary. There are various cases
+        // to deal with:
+        //  1. A write of a full 4K chunk.
+        //  2. A write of an incomplete chunk, possibly beyond the original EOF.
+        //
+        // Note that a write beyond EOF can create a hole. But we don't need to handle it here
+        // because holes are zeros, and leaves in MerkleLeaves are hashes of 4096-zeros by
+        // default.
+
+        // Now iterate on the input data, considering the alignment at the destination.
+        for (output_offset, current_size) in
+            ChunkedSizeIter::new(buf.len(), offset, CHUNK_SIZE as usize)
+        {
+            // Lock the tree for the whole write for now. There may be room to improve to increase
+            // throughput.
+            let mut merkle_tree = self.merkle_tree.write().unwrap();
+
+            let offset_in_buf = (output_offset - offset) as usize;
+            let source = &buf[offset_in_buf..offset_in_buf + current_size];
+            let output_chunk_index = (output_offset / CHUNK_SIZE) as usize;
+            let offset_from_alignment = (output_offset % CHUNK_SIZE) as usize;
+
+            let new_hash = match self.new_chunk_hash(
+                source,
+                offset_from_alignment,
+                current_size,
+                output_chunk_index,
+                &mut merkle_tree,
+            ) {
+                Ok(hash) => hash,
+                Err(e) => {
+                    // Return early when any error happens before the right. Even if the hash is not
+                    // consistent for the current chunk, we can still consider the earlier writes
+                    // successful. Note that nothing persistent has been done in this iteration.
+                    let written = output_offset - offset;
+                    if written > 0 {
+                        return Ok(written as usize);
+                    }
+                    return Err(e);
+                }
+            };
+
+            // A failed, partial write here will make the backing file inconsistent to the (old)
+            // hash. Nothing can be done within this writer, but at least it still maintains the
+            // (original) integrity for the file. To matches what write(2) describes for an error
+            // case (though it's about direct I/O), "Partial data may be written ... should be
+            // considered inconsistent", an error below is propagated.
+            self.file.write_all_at(source, output_offset)?;
+
+            // Update the hash only after the write succeeds. Note that this only attempts to keep
+            // the tree consistent to what has been written regardless the actual state beyond the
+            // writer.
+            let size_at_least = offset.saturating_add(buf.len() as u64);
+            merkle_tree.update_hash(output_chunk_index, &new_hash, size_at_least);
+        }
+        Ok(buf.len())
+    }
+
+    fn resize(&self, size: u64) -> io::Result<()> {
+        debug_assert_usize_is_u64();
+
+        let mut merkle_tree = self.merkle_tree.write().unwrap();
+        // In case when we are truncating the file, we may need to recalculate the hash of the (new)
+        // last chunk. Since the content is provided by the untrusted backend, we need to read the
+        // data back first, verify it, then override the truncated portion with 0-padding for
+        // hashing. As an optimization, we only need to read the data back if the new size isn't a
+        // multiple of CHUNK_SIZE (since the hash is already correct).
+        //
+        // The same thing does not need to happen when the size is growing. Since the new extended
+        // data is always 0, we can just resize the `MerkleLeaves`, where a new hash is always
+        // calculated from 4096 zeros.
+        if size < merkle_tree.file_size() && size % CHUNK_SIZE > 0 {
+            let new_tail_size = (size % CHUNK_SIZE) as usize;
+            let chunk_index = size / CHUNK_SIZE;
+            if new_tail_size > 0 {
+                let mut buf: ChunkBuffer = [0; CHUNK_SIZE as usize];
+                let s = self.read_backing_chunk_verified(chunk_index, &mut buf, &merkle_tree)?;
+                debug_assert!(new_tail_size <= s);
+
+                let zeros = vec![0; CHUNK_SIZE as usize - new_tail_size];
+                let mut ctx = Sha256::new();
+                ctx.update(&buf[..new_tail_size]);
+                ctx.update(&zeros);
+                let new_hash = ctx.finish();
+                merkle_tree.update_hash(chunk_index as usize, &new_hash, size);
+            }
+        }
+
+        self.file.resize(size)?;
+        merkle_tree.resize(size as usize);
+
+        Ok(())
+    }
+}
+
+impl<F: ReadByChunk + RandomWrite> ReadByChunk for VerifiedFileEditor<F> {
+    fn read_chunk(&self, chunk_index: u64, buf: &mut ChunkBuffer) -> io::Result<usize> {
+        let merkle_tree = self.merkle_tree.read().unwrap();
+        self.read_backing_chunk_verified(chunk_index, buf, &merkle_tree)
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    // Test data below can be generated by:
+    //  $ perl -e 'print "\x{00}" x 6000' > foo
+    //  $ perl -e 'print "\x{01}" x 5000' >> foo
+    //  $ fsverity digest foo
+    use super::*;
+    use anyhow::Result;
+    use std::cell::RefCell;
+    use std::convert::TryInto;
+
+    struct InMemoryEditor {
+        data: RefCell<Vec<u8>>,
+        fail_read: bool,
+    }
+
+    impl InMemoryEditor {
+        pub fn new() -> InMemoryEditor {
+            InMemoryEditor { data: RefCell::new(Vec::new()), fail_read: false }
+        }
+    }
+
+    impl RandomWrite for InMemoryEditor {
+        fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
+            let begin: usize =
+                offset.try_into().map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
+            let end = begin + buf.len();
+            if end > self.data.borrow().len() {
+                self.data.borrow_mut().resize(end, 0);
+            }
+            self.data.borrow_mut().as_mut_slice()[begin..end].copy_from_slice(buf);
+            Ok(buf.len())
+        }
+
+        fn resize(&self, size: u64) -> io::Result<()> {
+            let size: usize =
+                size.try_into().map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
+            self.data.borrow_mut().resize(size, 0);
+            Ok(())
+        }
+    }
+
+    impl ReadByChunk for InMemoryEditor {
+        fn read_chunk(&self, chunk_index: u64, buf: &mut ChunkBuffer) -> io::Result<usize> {
+            if self.fail_read {
+                return Err(io::Error::new(io::ErrorKind::Other, "test!"));
+            }
+
+            let borrowed = self.data.borrow();
+            let chunk = &borrowed
+                .chunks(CHUNK_SIZE as usize)
+                .nth(chunk_index as usize)
+                .ok_or_else(|| {
+                    io::Error::new(
+                        io::ErrorKind::InvalidInput,
+                        format!("read_chunk out of bound: index {}", chunk_index),
+                    )
+                })?;
+            buf[..chunk.len()].copy_from_slice(chunk);
+            Ok(chunk.len())
+        }
+    }
+
+    #[test]
+    fn test_writer() -> Result<()> {
+        let writer = InMemoryEditor::new();
+        let buf = [1; 4096];
+        assert_eq!(writer.data.borrow().len(), 0);
+
+        assert_eq!(writer.write_at(&buf, 16384)?, 4096);
+        assert_eq!(writer.data.borrow()[16384..16384 + 4096], buf);
+
+        assert_eq!(writer.write_at(&buf, 2048)?, 4096);
+        assert_eq!(writer.data.borrow()[2048..2048 + 4096], buf);
+
+        assert_eq!(writer.data.borrow().len(), 16384 + 4096);
+        Ok(())
+    }
+
+    #[test]
+    fn test_verified_writer_no_write() -> Result<()> {
+        // Verify fs-verity hash without any write.
+        let file = VerifiedFileEditor::new(InMemoryEditor::new());
+        assert_eq!(
+            file.calculate_fsverity_digest()?,
+            hex::decode("3d248ca542a24fc62d1c43b916eae5016878e2533c88238480b26128a1f1af95")?
+                .as_slice()
+        );
+        Ok(())
+    }
+
+    #[test]
+    fn test_verified_writer_from_zero() -> Result<()> {
+        // Verify a write of a full chunk.
+        let file = VerifiedFileEditor::new(InMemoryEditor::new());
+        assert_eq!(file.write_at(&[1; 4096], 0)?, 4096);
+        assert_eq!(
+            file.calculate_fsverity_digest()?,
+            hex::decode("cd0875ca59c7d37e962c5e8f5acd3770750ac80225e2df652ce5672fd34500af")?
+                .as_slice()
+        );
+
+        // Verify a write of across multiple chunks.
+        let file = VerifiedFileEditor::new(InMemoryEditor::new());
+        assert_eq!(file.write_at(&[1; 4097], 0)?, 4097);
+        assert_eq!(
+            file.calculate_fsverity_digest()?,
+            hex::decode("2901b849fda2d91e3929524561c4a47e77bb64734319759507b2029f18b9cc52")?
+                .as_slice()
+        );
+
+        // Verify another write of across multiple chunks.
+        let file = VerifiedFileEditor::new(InMemoryEditor::new());
+        assert_eq!(file.write_at(&[1; 10000], 0)?, 10000);
+        assert_eq!(
+            file.calculate_fsverity_digest()?,
+            hex::decode("7545409b556071554d18973a29b96409588c7cda4edd00d5586b27a11e1a523b")?
+                .as_slice()
+        );
+        Ok(())
+    }
+
+    #[test]
+    fn test_verified_writer_unaligned() -> Result<()> {
+        // Verify small, unaligned write beyond EOF.
+        let file = VerifiedFileEditor::new(InMemoryEditor::new());
+        assert_eq!(file.write_at(&[1; 5], 3)?, 5);
+        assert_eq!(
+            file.calculate_fsverity_digest()?,
+            hex::decode("a23fc5130d3d7b3323fc4b4a5e79d5d3e9ddf3a3f5872639e867713512c6702f")?
+                .as_slice()
+        );
+
+        // Verify bigger, unaligned write beyond EOF.
+        let file = VerifiedFileEditor::new(InMemoryEditor::new());
+        assert_eq!(file.write_at(&[1; 6000], 4000)?, 6000);
+        assert_eq!(
+            file.calculate_fsverity_digest()?,
+            hex::decode("d16d4c1c186d757e646f76208b21254f50d7f07ea07b1505ff48b2a6f603f989")?
+                .as_slice()
+        );
+        Ok(())
+    }
+
+    #[test]
+    fn test_verified_writer_with_hole() -> Result<()> {
+        // Verify an aligned write beyond EOF with holes.
+        let file = VerifiedFileEditor::new(InMemoryEditor::new());
+        assert_eq!(file.write_at(&[1; 4096], 4096)?, 4096);
+        assert_eq!(
+            file.calculate_fsverity_digest()?,
+            hex::decode("4df2aefd8c2a9101d1d8770dca3ede418232eabce766bb8e020395eae2e97103")?
+                .as_slice()
+        );
+
+        // Verify an unaligned write beyond EOF with holes.
+        let file = VerifiedFileEditor::new(InMemoryEditor::new());
+        assert_eq!(file.write_at(&[1; 5000], 6000)?, 5000);
+        assert_eq!(
+            file.calculate_fsverity_digest()?,
+            hex::decode("47d5da26f6934484e260630a69eb2eebb21b48f69bc8fbf8486d1694b7dba94f")?
+                .as_slice()
+        );
+
+        // Just another example with a small write.
+        let file = VerifiedFileEditor::new(InMemoryEditor::new());
+        assert_eq!(file.write_at(&[1; 5], 16381)?, 5);
+        assert_eq!(
+            file.calculate_fsverity_digest()?,
+            hex::decode("8bd118821fb4aff26bb4b51d485cc481a093c68131b7f4f112e9546198449752")?
+                .as_slice()
+        );
+        Ok(())
+    }
+
+    #[test]
+    fn test_verified_writer_various_writes() -> Result<()> {
+        let file = VerifiedFileEditor::new(InMemoryEditor::new());
+        assert_eq!(file.write_at(&[1; 2048], 0)?, 2048);
+        assert_eq!(file.write_at(&[1; 2048], 4096 + 2048)?, 2048);
+        assert_eq!(
+            file.calculate_fsverity_digest()?,
+            hex::decode("4c433d8640c888b629dc673d318cbb8d93b1eebcc784d9353e07f09f0dcfe707")?
+                .as_slice()
+        );
+        assert_eq!(file.write_at(&[1; 2048], 2048)?, 2048);
+        assert_eq!(file.write_at(&[1; 2048], 4096)?, 2048);
+        assert_eq!(
+            file.calculate_fsverity_digest()?,
+            hex::decode("2a476d58eb80394052a3a783111e1458ac3ecf68a7878183fed86ca0ff47ec0d")?
+                .as_slice()
+        );
+        assert_eq!(file.write_at(&[0; 2048], 2048)?, 2048);
+        assert_eq!(file.write_at(&[0; 2048], 4096)?, 2048);
+        assert_eq!(
+            file.calculate_fsverity_digest()?,
+            hex::decode("4c433d8640c888b629dc673d318cbb8d93b1eebcc784d9353e07f09f0dcfe707")?
+                .as_slice()
+        );
+        assert_eq!(file.write_at(&[1; 4096], 2048)?, 4096);
+        assert_eq!(
+            file.calculate_fsverity_digest()?,
+            hex::decode("2a476d58eb80394052a3a783111e1458ac3ecf68a7878183fed86ca0ff47ec0d")?
+                .as_slice()
+        );
+        assert_eq!(file.write_at(&[1; 2048], 8192)?, 2048);
+        assert_eq!(file.write_at(&[1; 2048], 8192 + 2048)?, 2048);
+        assert_eq!(
+            file.calculate_fsverity_digest()?,
+            hex::decode("23cbac08371e6ee838ebcc7ae6512b939d2226e802337be7b383c3e046047d24")?
+                .as_slice()
+        );
+        Ok(())
+    }
+
+    #[test]
+    fn test_verified_writer_inconsistent_read() -> Result<()> {
+        let file = VerifiedFileEditor::new(InMemoryEditor::new());
+        assert_eq!(file.write_at(&[1; 8192], 0)?, 8192);
+
+        // Replace the expected hash of the first/0-th chunk. An incomplete write will fail when it
+        // detects the inconsistent read.
+        {
+            let mut merkle_tree = file.merkle_tree.write().unwrap();
+            let overriding_hash = [42; SHA256_HASH_SIZE];
+            merkle_tree.update_hash(0, &overriding_hash, 8192);
+        }
+        assert!(file.write_at(&[1; 1], 2048).is_err());
+
+        // A write of full chunk can still succeed. Also fixed the inconsistency.
+        assert_eq!(file.write_at(&[1; 4096], 4096)?, 4096);
+
+        // Replace the expected hash of the second/1-th chunk. A write range from previous chunk can
+        // still succeed, but returns early due to an inconsistent read but still successfully. A
+        // resumed write will fail since no bytes can be written due to the same inconsistency.
+        {
+            let mut merkle_tree = file.merkle_tree.write().unwrap();
+            let overriding_hash = [42; SHA256_HASH_SIZE];
+            merkle_tree.update_hash(1, &overriding_hash, 8192);
+        }
+        assert_eq!(file.write_at(&[10; 8000], 0)?, 4096);
+        assert!(file.write_at(&[10; 8000 - 4096], 4096).is_err());
+        Ok(())
+    }
+
+    #[test]
+    fn test_verified_writer_failed_read_back() -> Result<()> {
+        let mut writer = InMemoryEditor::new();
+        writer.fail_read = true;
+        let file = VerifiedFileEditor::new(writer);
+        assert_eq!(file.write_at(&[1; 8192], 0)?, 8192);
+
+        // When a read back is needed, a read failure will fail to write.
+        assert!(file.write_at(&[1; 1], 2048).is_err());
+        Ok(())
+    }
+
+    #[test]
+    fn test_resize_to_same_size() -> Result<()> {
+        let file = VerifiedFileEditor::new(InMemoryEditor::new());
+        assert_eq!(file.write_at(&[1; 2048], 0)?, 2048);
+
+        assert!(file.resize(2048).is_ok());
+        assert_eq!(file.size(), 2048);
+
+        assert_eq!(
+            file.calculate_fsverity_digest()?,
+            hex::decode("fef1b4f19bb7a2cd944d7cdee44d1accb12726389ca5b0f61ac0f548ae40876f")?
+                .as_slice()
+        );
+        Ok(())
+    }
+
+    #[test]
+    fn test_resize_to_grow() -> Result<()> {
+        let file = VerifiedFileEditor::new(InMemoryEditor::new());
+        assert_eq!(file.write_at(&[1; 2048], 0)?, 2048);
+
+        // Resize should grow with 0s.
+        assert!(file.resize(4096).is_ok());
+        assert_eq!(file.size(), 4096);
+
+        assert_eq!(
+            file.calculate_fsverity_digest()?,
+            hex::decode("9e0e2745c21e4e74065240936d2047340d96a466680c3c9d177b82433e7a0bb1")?
+                .as_slice()
+        );
+        Ok(())
+    }
+
+    #[test]
+    fn test_resize_to_shrink() -> Result<()> {
+        let file = VerifiedFileEditor::new(InMemoryEditor::new());
+        assert_eq!(file.write_at(&[1; 4096], 0)?, 4096);
+
+        // Truncate.
+        file.resize(2048)?;
+        assert_eq!(file.size(), 2048);
+
+        assert_eq!(
+            file.calculate_fsverity_digest()?,
+            hex::decode("fef1b4f19bb7a2cd944d7cdee44d1accb12726389ca5b0f61ac0f548ae40876f")?
+                .as_slice()
+        );
+        Ok(())
+    }
+
+    #[test]
+    fn test_resize_to_shrink_with_read_failure() -> Result<()> {
+        let mut writer = InMemoryEditor::new();
+        writer.fail_read = true;
+        let file = VerifiedFileEditor::new(writer);
+        assert_eq!(file.write_at(&[1; 4096], 0)?, 4096);
+
+        // A truncate needs a read back. If the read fail, the resize should fail.
+        assert!(file.resize(2048).is_err());
+        Ok(())
+    }
+
+    #[test]
+    fn test_resize_to_shirink_to_chunk_boundary() -> Result<()> {
+        let mut writer = InMemoryEditor::new();
+        writer.fail_read = true;
+        let file = VerifiedFileEditor::new(writer);
+        assert_eq!(file.write_at(&[1; 8192], 0)?, 8192);
+
+        // Truncate to a chunk boundary. A read error doesn't matter since we won't need to
+        // recalcuate the leaf hash.
+        file.resize(4096)?;
+        assert_eq!(file.size(), 4096);
+
+        assert_eq!(
+            file.calculate_fsverity_digest()?,
+            hex::decode("cd0875ca59c7d37e962c5e8f5acd3770750ac80225e2df652ce5672fd34500af")?
+                .as_slice()
+        );
+        Ok(())
+    }
+}
diff --git a/guest/authfs/src/fsverity/metadata/Android.bp b/guest/authfs/src/fsverity/metadata/Android.bp
new file mode 100644
index 0000000..c874c2b
--- /dev/null
+++ b/guest/authfs/src/fsverity/metadata/Android.bp
@@ -0,0 +1,27 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+rust_bindgen {
+    name: "libauthfs_fsverity_metadata_bindgen",
+    wrapper_src: "metadata.hpp",
+    defaults: ["avf_build_flags_rust"],
+    crate_name: "authfs_fsverity_metadata_bindgen",
+    source_stem: "metadata_bindings",
+    apex_available: ["com.android.virt"],
+}
+
+rust_library {
+    name: "libauthfs_fsverity_metadata",
+    crate_name: "authfs_fsverity_metadata",
+    defaults: ["avf_build_flags_rust"],
+    srcs: [
+        "metadata.rs",
+    ],
+    rustlibs: [
+        "libauthfs_fsverity_metadata_bindgen",
+        "libopenssl",
+    ],
+    edition: "2021",
+    apex_available: ["com.android.virt"],
+}
diff --git a/guest/authfs/src/fsverity/metadata/metadata.hpp b/guest/authfs/src/fsverity/metadata/metadata.hpp
new file mode 100644
index 0000000..f05740e
--- /dev/null
+++ b/guest/authfs/src/fsverity/metadata/metadata.hpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#ifndef AUTHFS_FSVERITY_METADATA_H
+#define AUTHFS_FSVERITY_METADATA_H
+
+// This file contains the format of fs-verity metadata (.fsv_meta).
+//
+// The header format of .fsv_meta is:
+//
+// +-----------+---------------------------------------------+------------+
+// |  Address  |  Description                                |    Size    |
+// +-----------+---------------------------------------------+------------+
+// |  0x0000   |  32-bit LE, version of the format           |     4      |
+// |           |                                             |            |
+// |  0x0004   |  fsverity_descriptor (see linux/fsverity.h) |    256     |
+// |           |                                             |            |
+// |  0x0104   |  32-bit LE, type of signature               |     4      |
+// |           |  (0: NONE, 1: PKCS7, 2: RAW)                |            |
+// |           |                                             |            |
+// |  0x0108   |  32-bit LE, size of signature               |     4      |
+// |           |                                             |            |
+// |  0x010C   |  signature                                  | See 0x0108 |
+// +-----------+---------------------------------------------+------------+
+//
+// After the header, merkle tree dump exists at the first 4K boundary. Usually it's 0x1000, but it
+// could be, for example, 0x2000 or 0x3000, depending on the size of header.
+//
+// TODO(b/193113326): sync with build/make/tools/releasetools/fsverity_metadata_generator.py
+
+#include <stddef.h>
+#include <stdint.h>
+#include <linux/fsverity.h>
+
+const uint64_t CHUNK_SIZE = 4096;
+
+// Give the macro value a name to export.
+const uint8_t FSVERITY_HASH_ALG_SHA256 = FS_VERITY_HASH_ALG_SHA256;
+
+enum class FSVERITY_SIGNATURE_TYPE : __le32 {
+    NONE = 0,
+    PKCS7 = 1,
+    RAW = 2,
+};
+
+struct fsverity_metadata_header {
+    __le32 version;
+    fsverity_descriptor descriptor;
+    FSVERITY_SIGNATURE_TYPE signature_type;
+    __le32 signature_size;
+} __attribute__((packed));
+
+#endif   // AUTHFS_FSVERITY_METADATA_H
diff --git a/guest/authfs/src/fsverity/metadata/metadata.rs b/guest/authfs/src/fsverity/metadata/metadata.rs
new file mode 100644
index 0000000..54d0145
--- /dev/null
+++ b/guest/authfs/src/fsverity/metadata/metadata.rs
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+//! Rust bindgen interface for FSVerity Metadata file (.fsv_meta)
+use authfs_fsverity_metadata_bindgen::{
+    fsverity_descriptor, fsverity_metadata_header, FSVERITY_HASH_ALG_SHA256,
+    FSVERITY_SIGNATURE_TYPE_NONE, FSVERITY_SIGNATURE_TYPE_PKCS7, FSVERITY_SIGNATURE_TYPE_RAW,
+};
+
+use openssl::sha::sha256;
+use std::cmp::min;
+use std::ffi::OsString;
+use std::fs::File;
+use std::io::{self, Read, Seek};
+use std::mem::{size_of, zeroed};
+use std::os::unix::fs::{FileExt, MetadataExt};
+use std::path::{Path, PathBuf};
+use std::slice::from_raw_parts_mut;
+
+/// Offset of `descriptor` in `struct fsverity_metadatata_header`.
+const DESCRIPTOR_OFFSET: usize = 4;
+
+/// Structure for parsed metadata.
+pub struct FSVerityMetadata {
+    /// Header for the metadata.
+    pub header: fsverity_metadata_header,
+
+    /// fs-verity digest of the file, with hash algorithm defined in the fs-verity descriptor.
+    pub digest: Vec<u8>,
+
+    /// Optional signature for the metadata.
+    pub signature: Option<Vec<u8>>,
+
+    metadata_file: File,
+
+    merkle_tree_offset: u64,
+}
+
+impl FSVerityMetadata {
+    /// Read the raw Merkle tree from the metadata, if it exists. The API semantics is similar to a
+    /// regular pread(2), and may not return full requested buffer.
+    pub fn read_merkle_tree(&self, offset: u64, buf: &mut [u8]) -> io::Result<usize> {
+        let file_size = self.metadata_file.metadata()?.size();
+        let start = self.merkle_tree_offset + offset;
+        let end = min(file_size, start + buf.len() as u64);
+        let read_size = (end - start) as usize;
+        debug_assert!(read_size <= buf.len());
+        if read_size == 0 {
+            Ok(0)
+        } else {
+            self.metadata_file.read_exact_at(&mut buf[..read_size], start)?;
+            Ok(read_size)
+        }
+    }
+}
+
+/// Common block and page size in Linux.
+pub const CHUNK_SIZE: u64 = authfs_fsverity_metadata_bindgen::CHUNK_SIZE;
+
+/// Derive a path of metadata for a given path.
+/// e.g. "system/framework/foo.jar" -> "system/framework/foo.jar.fsv_meta"
+pub fn get_fsverity_metadata_path(path: &Path) -> PathBuf {
+    let mut os_string: OsString = path.into();
+    os_string.push(".fsv_meta");
+    os_string.into()
+}
+
+/// Parse metadata from given file, and returns a structure for the metadata.
+pub fn parse_fsverity_metadata(mut metadata_file: File) -> io::Result<Box<FSVerityMetadata>> {
+    let (header, digest) = {
+        // SAFETY: The header doesn't include any pointers.
+        let mut header: fsverity_metadata_header = unsafe { zeroed() };
+
+        // SAFETY: fsverity_metadata_header is packed, so reading/write from/to the back_buffer
+        // won't overflow.
+        let back_buffer = unsafe {
+            from_raw_parts_mut(
+                &mut header as *mut fsverity_metadata_header as *mut u8,
+                size_of::<fsverity_metadata_header>(),
+            )
+        };
+        metadata_file.read_exact(back_buffer)?;
+
+        // Digest needs to be calculated with the raw value (without changing the endianness).
+        let digest = match header.descriptor.hash_algorithm {
+            FSVERITY_HASH_ALG_SHA256 => Ok(sha256(
+                &back_buffer
+                    [DESCRIPTOR_OFFSET..DESCRIPTOR_OFFSET + size_of::<fsverity_descriptor>()],
+            )
+            .to_vec()),
+            alg => Err(io::Error::new(
+                io::ErrorKind::Other,
+                format!("Unsupported hash algorithm {}, continue (likely failing soon)", alg),
+            )),
+        }?;
+
+        // TODO(inseob): This doesn't seem ideal. Maybe we can consider nom?
+        header.version = u32::from_le(header.version);
+        header.descriptor.data_size = u64::from_le(header.descriptor.data_size);
+        header.signature_type = u32::from_le(header.signature_type);
+        header.signature_size = u32::from_le(header.signature_size);
+        (header, digest)
+    };
+
+    if header.version != 1 {
+        return Err(io::Error::new(io::ErrorKind::Other, "unsupported metadata version"));
+    }
+
+    let signature = match header.signature_type {
+        FSVERITY_SIGNATURE_TYPE_NONE => None,
+        FSVERITY_SIGNATURE_TYPE_PKCS7 | FSVERITY_SIGNATURE_TYPE_RAW => {
+            // TODO: unpad pkcs7?
+            let mut buf = vec![0u8; header.signature_size as usize];
+            metadata_file.read_exact(&mut buf)?;
+            Some(buf)
+        }
+        _ => return Err(io::Error::new(io::ErrorKind::Other, "unknown signature type")),
+    };
+
+    // merkle tree is at the next 4K boundary
+    let merkle_tree_offset =
+        (metadata_file.stream_position()? + CHUNK_SIZE - 1) / CHUNK_SIZE * CHUNK_SIZE;
+
+    Ok(Box::new(FSVerityMetadata { header, digest, signature, metadata_file, merkle_tree_offset }))
+}
diff --git a/guest/authfs/src/fsverity/sys.rs b/guest/authfs/src/fsverity/sys.rs
new file mode 100644
index 0000000..51e10a5
--- /dev/null
+++ b/guest/authfs/src/fsverity/sys.rs
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+/// fs-verity version that we are using
+pub const FS_VERITY_VERSION: u8 = 1;
+
+/// Hash algorithm to use from linux/fsverity.h
+pub const FS_VERITY_HASH_ALG_SHA256: u8 = 1;
+
+/// Log 2 of the block size (only 4096 is supported now)
+pub const FS_VERITY_LOG_BLOCKSIZE: u8 = 12;
diff --git a/guest/authfs/src/fsverity/verifier.rs b/guest/authfs/src/fsverity/verifier.rs
new file mode 100644
index 0000000..1434b7e
--- /dev/null
+++ b/guest/authfs/src/fsverity/verifier.rs
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2020 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 libc::EIO;
+use std::io;
+
+use super::common::{build_fsverity_digest, merkle_tree_height, FsverityError, SHA256_HASH_SIZE};
+use crate::common::{divide_roundup, CHUNK_SIZE};
+use crate::file::{ChunkBuffer, ReadByChunk};
+use openssl::sha::{sha256, Sha256};
+
+const ZEROS: [u8; CHUNK_SIZE as usize] = [0u8; CHUNK_SIZE as usize];
+
+type HashBuffer = [u8; SHA256_HASH_SIZE];
+
+fn hash_with_padding(chunk: &[u8], pad_to: usize) -> HashBuffer {
+    let padding_size = pad_to - chunk.len();
+    let mut ctx = Sha256::new();
+    ctx.update(chunk);
+    ctx.update(&ZEROS[..padding_size]);
+    ctx.finish()
+}
+
+fn verity_check<T: ReadByChunk>(
+    chunk: &[u8],
+    chunk_index: u64,
+    file_size: u64,
+    merkle_tree: &T,
+) -> Result<HashBuffer, FsverityError> {
+    // The caller should not be able to produce a chunk at the first place if `file_size` is 0. The
+    // current implementation expects to crash when a `ReadByChunk` implementation reads
+    // beyond the file size, including empty file.
+    assert_ne!(file_size, 0);
+
+    let chunk_hash = hash_with_padding(chunk, CHUNK_SIZE as usize);
+
+    // When the file is smaller or equal to CHUNK_SIZE, the root of Merkle tree is defined as the
+    // hash of the file content, plus padding.
+    if file_size <= CHUNK_SIZE {
+        return Ok(chunk_hash);
+    }
+
+    fsverity_walk(chunk_index, file_size, merkle_tree)?.try_fold(
+        chunk_hash,
+        |actual_hash, result| {
+            let (merkle_chunk, hash_offset_in_chunk) = result?;
+            let expected_hash =
+                &merkle_chunk[hash_offset_in_chunk..hash_offset_in_chunk + SHA256_HASH_SIZE];
+            if actual_hash != expected_hash {
+                return Err(FsverityError::CannotVerify);
+            }
+            Ok(hash_with_padding(&merkle_chunk, CHUNK_SIZE as usize))
+        },
+    )
+}
+
+/// Given a chunk index and the size of the file, returns an iterator that walks the Merkle tree
+/// from the leaf to the root. The iterator carries the slice of the chunk/node as well as the
+/// offset of the child node's hash. It is up to the iterator user to use the node and hash,
+/// e.g. for the actual verification.
+#[allow(clippy::needless_collect)]
+fn fsverity_walk<T: ReadByChunk>(
+    chunk_index: u64,
+    file_size: u64,
+    merkle_tree: &T,
+) -> Result<impl Iterator<Item = Result<([u8; 4096], usize), FsverityError>> + '_, FsverityError> {
+    let hashes_per_node = CHUNK_SIZE / SHA256_HASH_SIZE as u64;
+    debug_assert_eq!(hashes_per_node, 128u64);
+    let max_level = merkle_tree_height(file_size).expect("file should not be empty") as u32;
+    let root_to_leaf_steps = (0..=max_level)
+        .rev()
+        .map(|x| {
+            let leaves_per_hash = hashes_per_node.pow(x);
+            let leaves_size_per_hash = CHUNK_SIZE * leaves_per_hash;
+            let leaves_size_per_node = leaves_size_per_hash * hashes_per_node;
+            let nodes_at_level = divide_roundup(file_size, leaves_size_per_node);
+            let level_size = nodes_at_level * CHUNK_SIZE;
+            let offset_in_level = (chunk_index / leaves_per_hash) * SHA256_HASH_SIZE as u64;
+            (level_size, offset_in_level)
+        })
+        .scan(0, |level_offset, (level_size, offset_in_level)| {
+            let this_level_offset = *level_offset;
+            *level_offset += level_size;
+            let global_hash_offset = this_level_offset + offset_in_level;
+            Some(global_hash_offset)
+        })
+        .map(|global_hash_offset| {
+            let chunk_index = global_hash_offset / CHUNK_SIZE;
+            let hash_offset_in_chunk = (global_hash_offset % CHUNK_SIZE) as usize;
+            (chunk_index, hash_offset_in_chunk)
+        })
+        .collect::<Vec<_>>(); // Needs to collect first to be able to reverse below.
+
+    Ok(root_to_leaf_steps.into_iter().rev().map(move |(chunk_index, hash_offset_in_chunk)| {
+        let mut merkle_chunk = [0u8; 4096];
+        // read_chunk is supposed to return a full chunk, or an incomplete one at the end of the
+        // file. In the incomplete case, the hash is calculated with 0-padding to the chunk size.
+        // Therefore, we don't need to check the returned size here.
+        let _ = merkle_tree.read_chunk(chunk_index, &mut merkle_chunk)?;
+        Ok((merkle_chunk, hash_offset_in_chunk))
+    }))
+}
+
+pub struct VerifiedFileReader<F: ReadByChunk, M: ReadByChunk> {
+    pub file_size: u64,
+    chunked_file: F,
+    merkle_tree: M,
+    root_hash: HashBuffer,
+}
+
+impl<F: ReadByChunk, M: ReadByChunk> VerifiedFileReader<F, M> {
+    pub fn new(
+        chunked_file: F,
+        file_size: u64,
+        expected_digest: &[u8],
+        merkle_tree: M,
+    ) -> Result<VerifiedFileReader<F, M>, FsverityError> {
+        let mut buf = [0u8; CHUNK_SIZE as usize];
+        if file_size <= CHUNK_SIZE {
+            let _size = chunked_file.read_chunk(0, &mut buf)?;
+            // The rest of buffer is 0-padded.
+        } else {
+            let size = merkle_tree.read_chunk(0, &mut buf)?;
+            if buf.len() != size {
+                return Err(FsverityError::InsufficientData(size));
+            }
+        }
+        let root_hash = sha256(&buf[..]);
+        if expected_digest == build_fsverity_digest(&root_hash, file_size) {
+            // Once verified, use the root_hash for verification going forward.
+            Ok(VerifiedFileReader { chunked_file, file_size, merkle_tree, root_hash })
+        } else {
+            Err(FsverityError::InvalidDigest)
+        }
+    }
+}
+
+impl<F: ReadByChunk, M: ReadByChunk> ReadByChunk for VerifiedFileReader<F, M> {
+    fn read_chunk(&self, chunk_index: u64, buf: &mut ChunkBuffer) -> io::Result<usize> {
+        let size = self.chunked_file.read_chunk(chunk_index, buf)?;
+        let root_hash = verity_check(&buf[..size], chunk_index, self.file_size, &self.merkle_tree)
+            .map_err(|_| io::Error::from_raw_os_error(EIO))?;
+        if root_hash != self.root_hash {
+            Err(io::Error::from_raw_os_error(EIO))
+        } else {
+            Ok(size)
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::file::ReadByChunk;
+    use anyhow::Result;
+    use authfs_fsverity_metadata::{parse_fsverity_metadata, FSVerityMetadata};
+    use std::cmp::min;
+    use std::fs::File;
+    use std::os::unix::fs::FileExt;
+
+    struct LocalFileReader {
+        file: File,
+        size: u64,
+    }
+
+    impl LocalFileReader {
+        fn new(file: File) -> io::Result<LocalFileReader> {
+            let size = file.metadata()?.len();
+            Ok(LocalFileReader { file, size })
+        }
+
+        fn len(&self) -> u64 {
+            self.size
+        }
+    }
+
+    impl ReadByChunk for LocalFileReader {
+        fn read_chunk(&self, chunk_index: u64, buf: &mut ChunkBuffer) -> io::Result<usize> {
+            let start = chunk_index * CHUNK_SIZE;
+            if start >= self.size {
+                return Ok(0);
+            }
+            let end = min(self.size, start + CHUNK_SIZE);
+            let read_size = (end - start) as usize;
+            debug_assert!(read_size <= buf.len());
+            self.file.read_exact_at(&mut buf[..read_size], start)?;
+            Ok(read_size)
+        }
+    }
+
+    type LocalVerifiedFileReader = VerifiedFileReader<LocalFileReader, MerkleTreeReader>;
+
+    pub struct MerkleTreeReader {
+        metadata: Box<FSVerityMetadata>,
+    }
+
+    impl ReadByChunk for MerkleTreeReader {
+        fn read_chunk(&self, chunk_index: u64, buf: &mut ChunkBuffer) -> io::Result<usize> {
+            self.metadata.read_merkle_tree(chunk_index * CHUNK_SIZE, buf)
+        }
+    }
+
+    fn total_chunk_number(file_size: u64) -> u64 {
+        (file_size + 4095) / 4096
+    }
+
+    // Returns a reader with fs-verity verification and the file size.
+    fn new_reader_with_fsverity(
+        content_path: &str,
+        metadata_path: &str,
+    ) -> Result<(LocalVerifiedFileReader, u64)> {
+        let file_reader = LocalFileReader::new(File::open(content_path)?)?;
+        let file_size = file_reader.len();
+        let metadata = parse_fsverity_metadata(File::open(metadata_path)?)?;
+        Ok((
+            VerifiedFileReader::new(
+                file_reader,
+                file_size,
+                &metadata.digest.clone(),
+                MerkleTreeReader { metadata },
+            )?,
+            file_size,
+        ))
+    }
+
+    #[test]
+    fn fsverity_verify_full_read_4k() -> Result<()> {
+        let (file_reader, file_size) =
+            new_reader_with_fsverity("testdata/input.4k", "testdata/input.4k.fsv_meta")?;
+
+        for i in 0..total_chunk_number(file_size) {
+            let mut buf = [0u8; 4096];
+            assert!(file_reader.read_chunk(i, &mut buf).is_ok());
+        }
+        Ok(())
+    }
+
+    #[test]
+    fn fsverity_verify_full_read_4k1() -> Result<()> {
+        let (file_reader, file_size) =
+            new_reader_with_fsverity("testdata/input.4k1", "testdata/input.4k1.fsv_meta")?;
+
+        for i in 0..total_chunk_number(file_size) {
+            let mut buf = [0u8; 4096];
+            assert!(file_reader.read_chunk(i, &mut buf).is_ok());
+        }
+        Ok(())
+    }
+
+    #[test]
+    fn fsverity_verify_full_read_4m() -> Result<()> {
+        let (file_reader, file_size) =
+            new_reader_with_fsverity("testdata/input.4m", "testdata/input.4m.fsv_meta")?;
+
+        for i in 0..total_chunk_number(file_size) {
+            let mut buf = [0u8; 4096];
+            assert!(file_reader.read_chunk(i, &mut buf).is_ok());
+        }
+        Ok(())
+    }
+
+    #[test]
+    fn fsverity_verify_bad_merkle_tree() -> Result<()> {
+        let (file_reader, _) = new_reader_with_fsverity(
+            "testdata/input.4m",
+            "testdata/input.4m.fsv_meta.bad_merkle", // First leaf node is corrupted.
+        )?;
+
+        // A lowest broken node (a 4K chunk that contains 128 sha256 hashes) will fail the read
+        // failure of the underlying chunks, but not before or after.
+        let mut buf = [0u8; 4096];
+        let num_hashes = 4096 / 32;
+        let last_index = num_hashes;
+        for i in 0..last_index {
+            assert!(file_reader.read_chunk(i, &mut buf).is_err());
+        }
+        assert!(file_reader.read_chunk(last_index, &mut buf).is_ok());
+        Ok(())
+    }
+}
diff --git a/guest/authfs/src/fusefs.rs b/guest/authfs/src/fusefs.rs
new file mode 100644
index 0000000..618b8ac
--- /dev/null
+++ b/guest/authfs/src/fusefs.rs
@@ -0,0 +1,1075 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+mod file;
+mod mount;
+
+use anyhow::{anyhow, bail, Result};
+use fuse::filesystem::{
+    Context, DirEntry, DirectoryIterator, Entry, FileSystem, FsOptions, GetxattrReply,
+    SetattrValid, ZeroCopyReader, ZeroCopyWriter,
+};
+use fuse::sys::OpenOptions as FuseOpenOptions;
+use log::{error, trace, warn};
+use std::collections::{btree_map, BTreeMap};
+use std::convert::{TryFrom, TryInto};
+use std::ffi::{CStr, CString, OsStr};
+use std::io;
+use std::mem::{zeroed, MaybeUninit};
+use std::option::Option;
+use std::os::unix::ffi::OsStrExt;
+use std::path::{Component, Path, PathBuf};
+use std::sync::atomic::{AtomicU64, Ordering};
+use std::sync::{Arc, RwLock};
+use std::time::Duration;
+
+use crate::common::{divide_roundup, ChunkedSizeIter, CHUNK_SIZE};
+use crate::file::{
+    validate_basename, Attr, InMemoryDir, RandomWrite, ReadByChunk, RemoteDirEditor,
+    RemoteFileEditor, RemoteFileReader,
+};
+use crate::fsstat::RemoteFsStatsReader;
+use crate::fsverity::VerifiedFileEditor;
+
+pub use self::file::LazyVerifiedReadonlyFile;
+pub use self::mount::mount_and_enter_message_loop;
+use self::mount::MAX_WRITE_BYTES;
+
+pub type Inode = u64;
+type Handle = u64;
+
+/// Maximum time for a file's metadata to be cached by the kernel. Since any file and directory
+/// changes (if not read-only) has to go through AuthFS to be trusted, the timeout can be maximum.
+const DEFAULT_METADATA_TIMEOUT: Duration = Duration::MAX;
+
+const ROOT_INODE: Inode = 1;
+
+/// `AuthFsEntry` defines the filesystem entry type supported by AuthFS.
+pub enum AuthFsEntry {
+    /// A read-only directory (writable during initialization). Root directory is an example.
+    ReadonlyDirectory { dir: InMemoryDir },
+    /// A file type that is verified against fs-verity signature (thus read-only). The file is
+    /// served from a remote server.
+    VerifiedReadonly { reader: LazyVerifiedReadonlyFile },
+    /// A file type that is a read-only passthrough from a file on a remote server.
+    UnverifiedReadonly { reader: RemoteFileReader, file_size: u64 },
+    /// A file type that is initially empty, and the content is stored on a remote server. File
+    /// integrity is guaranteed with private Merkle tree.
+    VerifiedNew { editor: VerifiedFileEditor<RemoteFileEditor>, attr: Attr },
+    /// A directory type that is initially empty. One can create new file (`VerifiedNew`) and new
+    /// directory (`VerifiedNewDirectory` itself) with integrity guaranteed within the VM.
+    VerifiedNewDirectory { dir: RemoteDirEditor, attr: Attr },
+}
+
+impl AuthFsEntry {
+    fn expect_empty_deletable_directory(&self) -> io::Result<()> {
+        match self {
+            AuthFsEntry::VerifiedNewDirectory { dir, .. } => {
+                if dir.number_of_entries() == 0 {
+                    Ok(())
+                } else {
+                    Err(io::Error::from_raw_os_error(libc::ENOTEMPTY))
+                }
+            }
+            AuthFsEntry::ReadonlyDirectory { .. } => {
+                Err(io::Error::from_raw_os_error(libc::EACCES))
+            }
+            _ => Err(io::Error::from_raw_os_error(libc::ENOTDIR)),
+        }
+    }
+}
+
+struct InodeState {
+    /// Actual inode entry.
+    entry: AuthFsEntry,
+
+    /// Number of `Handle`s (i.e. file descriptors) that are currently referring to the this inode.
+    ///
+    /// Technically, this does not matter to readonly entries, since they live forever. The
+    /// reference count is only needed for manageing lifetime of writable entries like
+    /// `VerifiedNew` and `VerifiedNewDirectory`. That is, when an entry is deleted, the actual
+    /// entry needs to stay alive until the reference count reaches zero.
+    ///
+    /// Note: This is not to be confused with hardlinks, which AuthFS doesn't currently implement.
+    handle_ref_count: AtomicU64,
+
+    /// Whether the inode is already unlinked, i.e. should be removed, once `handle_ref_count` is
+    /// down to zero.
+    unlinked: bool,
+}
+
+impl InodeState {
+    fn new(entry: AuthFsEntry) -> Self {
+        InodeState { entry, handle_ref_count: AtomicU64::new(0), unlinked: false }
+    }
+
+    fn new_with_ref_count(entry: AuthFsEntry, handle_ref_count: u64) -> Self {
+        InodeState { entry, handle_ref_count: AtomicU64::new(handle_ref_count), unlinked: false }
+    }
+}
+
+/// Data type that a directory implementation should be able to present its entry to `AuthFs`.
+#[derive(Clone)]
+pub struct AuthFsDirEntry {
+    pub inode: Inode,
+    pub name: CString,
+    pub is_dir: bool,
+}
+
+/// A snapshot of a directory entries for supporting `readdir` operation.
+///
+/// The `readdir` implementation is required by FUSE to not return any entries that have been
+/// returned previously (while it's fine to not return new entries). Snapshot is the easiest way to
+/// be compliant. See `fuse::filesystem::readdir` for more details.
+///
+/// A `DirEntriesSnapshot` is created on `opendir`, and is associated with the returned
+/// `Handle`/FD. The snapshot is deleted when the handle is released in `releasedir`.
+type DirEntriesSnapshot = Vec<AuthFsDirEntry>;
+
+/// An iterator for reading from `DirEntriesSnapshot`.
+pub struct DirEntriesSnapshotIterator {
+    /// A reference to the `DirEntriesSnapshot` in `AuthFs`.
+    snapshot: Arc<DirEntriesSnapshot>,
+
+    /// A value determined by `Self` to identify the last entry. 0 is a reserved value by FUSE to
+    /// mean reading from the beginning.
+    prev_offset: usize,
+}
+
+impl DirectoryIterator for DirEntriesSnapshotIterator {
+    fn next(&mut self) -> Option<DirEntry> {
+        // This iterator should not be the only reference to the snapshot. The snapshot should
+        // still be hold in `dir_handle_table`, i.e. when the FD is not yet closed.
+        //
+        // This code is unreachable when `readdir` is called with a closed FD. Only when the FD is
+        // not yet closed, `DirEntriesSnapshotIterator` can be created (but still short-lived
+        // during `readdir`).
+        debug_assert!(Arc::strong_count(&self.snapshot) >= 2);
+
+        // Since 0 is reserved, let's use 1-based index for the offset. This allows us to
+        // resume from the previous read in the snapshot easily.
+        let current_offset = if self.prev_offset == 0 {
+            1 // first element in the vector
+        } else {
+            self.prev_offset + 1 // next element in the vector
+        };
+        if current_offset > self.snapshot.len() {
+            None
+        } else {
+            let AuthFsDirEntry { inode, name, is_dir } = &self.snapshot[current_offset - 1];
+            let entry = DirEntry {
+                offset: current_offset as u64,
+                ino: *inode,
+                name,
+                type_: if *is_dir { libc::DT_DIR.into() } else { libc::DT_REG.into() },
+            };
+            self.prev_offset = current_offset;
+            Some(entry)
+        }
+    }
+}
+
+type DirHandleTable = BTreeMap<Handle, Arc<DirEntriesSnapshot>>;
+
+// AuthFS needs to be `Sync` to be used with the `fuse` crate.
+pub struct AuthFs {
+    /// Table for `Inode` to `InodeState` lookup.
+    inode_table: RwLock<BTreeMap<Inode, InodeState>>,
+
+    /// The next available inode number.
+    next_inode: AtomicU64,
+
+    /// Table for `Handle` to `Arc<DirEntriesSnapshot>` lookup. On `opendir`, a new directory
+    /// handle is created and the snapshot of the current directory is created. This is not
+    /// super efficient, but is the simplest way to be compliant to the FUSE contract (see
+    /// `fuse::filesystem::readdir`).
+    ///
+    /// Currently, no code locks `dir_handle_table` and `inode_table` at the same time to avoid
+    /// deadlock.
+    dir_handle_table: RwLock<DirHandleTable>,
+
+    /// The next available handle number.
+    next_handle: AtomicU64,
+
+    /// A reader to access the remote filesystem stats, which is supposed to be of "the" output
+    /// directory. We assume all output are stored in the same partition.
+    remote_fs_stats_reader: RemoteFsStatsReader,
+}
+
+// Implementation for preparing an `AuthFs` instance, before starting to serve.
+// TODO(victorhsieh): Consider implement a builder to separate the mutable initialization from the
+// immutable / interiorly mutable serving phase.
+impl AuthFs {
+    pub fn new(remote_fs_stats_reader: RemoteFsStatsReader) -> AuthFs {
+        let mut inode_table = BTreeMap::new();
+        inode_table.insert(
+            ROOT_INODE,
+            InodeState::new(AuthFsEntry::ReadonlyDirectory { dir: InMemoryDir::new() }),
+        );
+
+        AuthFs {
+            inode_table: RwLock::new(inode_table),
+            next_inode: AtomicU64::new(ROOT_INODE + 1),
+            dir_handle_table: RwLock::new(BTreeMap::new()),
+            next_handle: AtomicU64::new(1),
+            remote_fs_stats_reader,
+        }
+    }
+
+    /// Add an `AuthFsEntry` as `basename` to the filesystem root.
+    pub fn add_entry_at_root_dir(
+        &mut self,
+        basename: PathBuf,
+        entry: AuthFsEntry,
+    ) -> Result<Inode> {
+        validate_basename(&basename)?;
+        self.add_entry_at_ro_dir_by_path(ROOT_INODE, &basename, entry)
+    }
+
+    /// Add an `AuthFsEntry` by path from the `ReadonlyDirectory` represented by `dir_inode`. The
+    /// path must be a related path. If some ancestor directories do not exist, they will be
+    /// created (also as `ReadonlyDirectory`) automatically.
+    pub fn add_entry_at_ro_dir_by_path(
+        &mut self,
+        dir_inode: Inode,
+        path: &Path,
+        entry: AuthFsEntry,
+    ) -> Result<Inode> {
+        // 1. Make sure the parent directories all exist. Derive the entry's parent inode.
+        let parent_path =
+            path.parent().ok_or_else(|| anyhow!("No parent directory: {:?}", path))?;
+        let parent_inode =
+            parent_path.components().try_fold(dir_inode, |current_dir_inode, path_component| {
+                match path_component {
+                    Component::RootDir => bail!("Absolute path is not supported"),
+                    Component::Normal(name) => {
+                        let inode_table = self.inode_table.get_mut().unwrap();
+                        // Locate the internal directory structure.
+                        let current_dir_entry = &mut inode_table
+                            .get_mut(&current_dir_inode)
+                            .ok_or_else(|| {
+                                anyhow!("Unknown directory inode {}", current_dir_inode)
+                            })?
+                            .entry;
+                        let dir = match current_dir_entry {
+                            AuthFsEntry::ReadonlyDirectory { dir } => dir,
+                            _ => unreachable!("Not a ReadonlyDirectory"),
+                        };
+                        // Return directory inode. Create first if not exists.
+                        if let Some(existing_inode) = dir.lookup_inode(name.as_ref()) {
+                            Ok(existing_inode)
+                        } else {
+                            let new_inode = self.next_inode.fetch_add(1, Ordering::Relaxed);
+                            let new_dir_entry =
+                                AuthFsEntry::ReadonlyDirectory { dir: InMemoryDir::new() };
+
+                            // Actually update the tables.
+                            dir.add_dir(name.as_ref(), new_inode)?;
+                            if inode_table
+                                .insert(new_inode, InodeState::new(new_dir_entry))
+                                .is_some()
+                            {
+                                bail!("Unexpected to find a duplicated inode");
+                            }
+                            Ok(new_inode)
+                        }
+                    }
+                    _ => Err(anyhow!("Path is not canonical: {:?}", path)),
+                }
+            })?;
+
+        // 2. Insert the entry to the parent directory, as well as the inode table.
+        let inode_table = self.inode_table.get_mut().unwrap();
+        let inode_state = inode_table.get_mut(&parent_inode).expect("previously returned inode");
+        match &mut inode_state.entry {
+            AuthFsEntry::ReadonlyDirectory { dir } => {
+                let basename =
+                    path.file_name().ok_or_else(|| anyhow!("Bad file name: {:?}", path))?;
+                let new_inode = self.next_inode.fetch_add(1, Ordering::Relaxed);
+
+                // Actually update the tables.
+                dir.add_file(basename.as_ref(), new_inode)?;
+                if inode_table.insert(new_inode, InodeState::new(entry)).is_some() {
+                    bail!("Unexpected to find a duplicated inode");
+                }
+                Ok(new_inode)
+            }
+            _ => unreachable!("Not a ReadonlyDirectory"),
+        }
+    }
+}
+
+// Implementation for serving requests.
+impl AuthFs {
+    /// Handles the file associated with `inode` if found. This function returns whatever
+    /// `handle_fn` returns.
+    fn handle_inode<F, R>(&self, inode: &Inode, handle_fn: F) -> io::Result<R>
+    where
+        F: FnOnce(&AuthFsEntry) -> io::Result<R>,
+    {
+        let inode_table = self.inode_table.read().unwrap();
+        handle_inode_locked(&inode_table, inode, |inode_state| handle_fn(&inode_state.entry))
+    }
+
+    /// Adds a new entry `name` created by `create_fn` at `parent_inode`, with an initial ref count
+    /// of one.
+    ///
+    /// The operation involves two updates: adding the name with a new allocated inode to the
+    /// parent directory, and insert the new inode and the actual `AuthFsEntry` to the global inode
+    /// table.
+    ///
+    /// `create_fn` receives the parent directory, through which it can create the new entry at and
+    /// register the new inode to. Its returned entry is then added to the inode table.
+    fn create_new_entry_with_ref_count<F>(
+        &self,
+        parent_inode: Inode,
+        name: &CStr,
+        create_fn: F,
+    ) -> io::Result<Inode>
+    where
+        F: FnOnce(&mut AuthFsEntry, &Path, Inode) -> io::Result<AuthFsEntry>,
+    {
+        let mut inode_table = self.inode_table.write().unwrap();
+        let (new_inode, new_file_entry) = handle_inode_mut_locked(
+            &mut inode_table,
+            &parent_inode,
+            |InodeState { entry, .. }| {
+                let new_inode = self.next_inode.fetch_add(1, Ordering::Relaxed);
+                let basename: &Path = cstr_to_path(name);
+                let new_file_entry = create_fn(entry, basename, new_inode)?;
+                Ok((new_inode, new_file_entry))
+            },
+        )?;
+
+        if let btree_map::Entry::Vacant(entry) = inode_table.entry(new_inode) {
+            entry.insert(InodeState::new_with_ref_count(new_file_entry, 1));
+            Ok(new_inode)
+        } else {
+            unreachable!("Unexpected duplication of inode {}", new_inode);
+        }
+    }
+
+    fn open_dir_store_snapshot(
+        &self,
+        dir_entries: Vec<AuthFsDirEntry>,
+    ) -> io::Result<(Option<Handle>, FuseOpenOptions)> {
+        let handle = self.next_handle.fetch_add(1, Ordering::Relaxed);
+        let mut dir_handle_table = self.dir_handle_table.write().unwrap();
+        if let btree_map::Entry::Vacant(value) = dir_handle_table.entry(handle) {
+            value.insert(Arc::new(dir_entries));
+            Ok((Some(handle), FuseOpenOptions::empty()))
+        } else {
+            unreachable!("Unexpected to see new handle {} to existing in the table", handle);
+        }
+    }
+}
+
+fn check_access_mode(flags: u32, mode: libc::c_int) -> io::Result<()> {
+    if (flags & libc::O_ACCMODE as u32) == mode as u32 {
+        Ok(())
+    } else {
+        Err(io::Error::from_raw_os_error(libc::EACCES))
+    }
+}
+
+cfg_if::cfg_if! {
+    if #[cfg(all(any(target_arch = "aarch64", target_arch = "riscv64"),
+                 target_pointer_width = "64"))] {
+        fn blk_size() -> libc::c_int { CHUNK_SIZE as libc::c_int }
+    } else {
+        fn blk_size() -> libc::c_long { CHUNK_SIZE as libc::c_long }
+    }
+}
+
+#[allow(clippy::enum_variant_names)]
+enum AccessMode {
+    ReadOnly,
+    Variable(u32),
+}
+
+fn create_stat(
+    ino: libc::ino_t,
+    file_size: u64,
+    access_mode: AccessMode,
+) -> io::Result<libc::stat64> {
+    // SAFETY: stat64 is a plan C struct without pointer.
+    let mut st = unsafe { MaybeUninit::<libc::stat64>::zeroed().assume_init() };
+
+    st.st_ino = ino;
+    st.st_mode = match access_mode {
+        AccessMode::ReadOnly => {
+            // Until needed, let's just grant the owner access.
+            libc::S_IFREG | libc::S_IRUSR
+        }
+        AccessMode::Variable(mode) => libc::S_IFREG | mode,
+    };
+    st.st_nlink = 1;
+    st.st_uid = 0;
+    st.st_gid = 0;
+    st.st_size = libc::off64_t::try_from(file_size)
+        .map_err(|_| io::Error::from_raw_os_error(libc::EFBIG))?;
+    st.st_blksize = blk_size();
+    // Per man stat(2), st_blocks is "Number of 512B blocks allocated".
+    st.st_blocks = libc::c_longlong::try_from(divide_roundup(file_size, 512))
+        .map_err(|_| io::Error::from_raw_os_error(libc::EFBIG))?;
+    Ok(st)
+}
+
+fn create_dir_stat(
+    ino: libc::ino_t,
+    file_number: u16,
+    access_mode: AccessMode,
+) -> io::Result<libc::stat64> {
+    // SAFETY: stat64 is a plan C struct without pointer.
+    let mut st = unsafe { MaybeUninit::<libc::stat64>::zeroed().assume_init() };
+
+    st.st_ino = ino;
+    st.st_mode = match access_mode {
+        AccessMode::ReadOnly => {
+            // Until needed, let's just grant the owner access and search to group and others.
+            libc::S_IFDIR | libc::S_IXUSR | libc::S_IRUSR | libc::S_IXGRP | libc::S_IXOTH
+        }
+        AccessMode::Variable(mode) => libc::S_IFDIR | mode,
+    };
+
+    // 2 extra for . and ..
+    st.st_nlink = file_number
+        .checked_add(2)
+        .ok_or_else(|| io::Error::from_raw_os_error(libc::EOVERFLOW))?
+        .into();
+
+    st.st_uid = 0;
+    st.st_gid = 0;
+    Ok(st)
+}
+
+fn offset_to_chunk_index(offset: u64) -> u64 {
+    offset / CHUNK_SIZE
+}
+
+fn read_chunks<W: io::Write, T: ReadByChunk>(
+    mut w: W,
+    file: &T,
+    file_size: u64,
+    offset: u64,
+    size: u32,
+) -> io::Result<usize> {
+    let remaining = file_size.saturating_sub(offset);
+    let size_to_read = std::cmp::min(size as usize, remaining as usize);
+    let total = ChunkedSizeIter::new(size_to_read, offset, CHUNK_SIZE as usize).try_fold(
+        0,
+        |total, (current_offset, planned_data_size)| {
+            // TODO(victorhsieh): There might be a non-trivial way to avoid this copy. For example,
+            // instead of accepting a buffer, the writer could expose the final destination buffer
+            // for the reader to write to. It might not be generally applicable though, e.g. with
+            // virtio transport, the buffer may not be continuous.
+            let mut buf = [0u8; CHUNK_SIZE as usize];
+            let read_size = file.read_chunk(offset_to_chunk_index(current_offset), &mut buf)?;
+            if read_size < planned_data_size {
+                return Err(io::Error::from_raw_os_error(libc::ENODATA));
+            }
+
+            let begin = (current_offset % CHUNK_SIZE) as usize;
+            let end = begin + planned_data_size;
+            let s = w.write(&buf[begin..end])?;
+            if s != planned_data_size {
+                return Err(io::Error::from_raw_os_error(libc::EIO));
+            }
+            Ok(total + s)
+        },
+    )?;
+
+    Ok(total)
+}
+
+impl FileSystem for AuthFs {
+    type Inode = Inode;
+    type Handle = Handle;
+    type DirIter = DirEntriesSnapshotIterator;
+
+    fn max_buffer_size(&self) -> u32 {
+        MAX_WRITE_BYTES
+    }
+
+    fn init(&self, _capable: FsOptions) -> io::Result<FsOptions> {
+        // Enable writeback cache for better performance especially since our bandwidth to the
+        // backend service is limited.
+        Ok(FsOptions::WRITEBACK_CACHE)
+    }
+
+    fn lookup(&self, _ctx: Context, parent: Inode, name: &CStr) -> io::Result<Entry> {
+        let inode_table = self.inode_table.read().unwrap();
+
+        // Look up the entry's inode number in parent directory.
+        let inode =
+            handle_inode_locked(&inode_table, &parent, |inode_state| match &inode_state.entry {
+                AuthFsEntry::ReadonlyDirectory { dir } => {
+                    let path = cstr_to_path(name);
+                    dir.lookup_inode(path).ok_or_else(|| io::Error::from_raw_os_error(libc::ENOENT))
+                }
+                AuthFsEntry::VerifiedNewDirectory { dir, .. } => {
+                    let path = cstr_to_path(name);
+                    dir.find_inode(path)
+                }
+                _ => Err(io::Error::from_raw_os_error(libc::ENOTDIR)),
+            })?;
+
+        // Create the entry's stat if found.
+        let st = handle_inode_locked(
+            &inode_table,
+            &inode,
+            |InodeState { entry, handle_ref_count, .. }| {
+                let st = match entry {
+                    AuthFsEntry::ReadonlyDirectory { dir } => {
+                        create_dir_stat(inode, dir.number_of_entries(), AccessMode::ReadOnly)
+                    }
+                    AuthFsEntry::UnverifiedReadonly { file_size, .. } => {
+                        create_stat(inode, *file_size, AccessMode::ReadOnly)
+                    }
+                    AuthFsEntry::VerifiedReadonly { reader } => {
+                        create_stat(inode, reader.file_size()?, AccessMode::ReadOnly)
+                    }
+                    AuthFsEntry::VerifiedNew { editor, attr, .. } => {
+                        create_stat(inode, editor.size(), AccessMode::Variable(attr.mode()))
+                    }
+                    AuthFsEntry::VerifiedNewDirectory { dir, attr } => create_dir_stat(
+                        inode,
+                        dir.number_of_entries(),
+                        AccessMode::Variable(attr.mode()),
+                    ),
+                }?;
+                if handle_ref_count.fetch_add(1, Ordering::Relaxed) == u64::MAX {
+                    panic!("Handle reference count overflow");
+                }
+                Ok(st)
+            },
+        )?;
+
+        Ok(Entry {
+            inode,
+            generation: 0,
+            attr: st,
+            entry_timeout: DEFAULT_METADATA_TIMEOUT,
+            attr_timeout: DEFAULT_METADATA_TIMEOUT,
+        })
+    }
+
+    fn forget(&self, _ctx: Context, inode: Self::Inode, count: u64) {
+        let mut inode_table = self.inode_table.write().unwrap();
+        let delete_now = handle_inode_mut_locked(
+            &mut inode_table,
+            &inode,
+            |InodeState { handle_ref_count, unlinked, .. }| {
+                let current = handle_ref_count.get_mut();
+                if count > *current {
+                    error!(
+                        "Trying to decrease refcount of inode {} by {} (> current {})",
+                        inode, count, *current
+                    );
+                    panic!(); // log to logcat with error!
+                }
+                *current -= count;
+                Ok(*unlinked && *current == 0)
+            },
+        );
+
+        match delete_now {
+            Ok(true) => {
+                let _ignored = inode_table.remove(&inode).expect("Removed an existing entry");
+            }
+            Ok(false) => { /* Let the inode stay */ }
+            Err(e) => {
+                warn!(
+                    "Unexpected failure when tries to forget an inode {} by refcount {}: {:?}",
+                    inode, count, e
+                );
+            }
+        }
+    }
+
+    fn getattr(
+        &self,
+        _ctx: Context,
+        inode: Inode,
+        _handle: Option<Handle>,
+    ) -> io::Result<(libc::stat64, Duration)> {
+        self.handle_inode(&inode, |config| {
+            Ok((
+                match config {
+                    AuthFsEntry::ReadonlyDirectory { dir } => {
+                        create_dir_stat(inode, dir.number_of_entries(), AccessMode::ReadOnly)
+                    }
+                    AuthFsEntry::UnverifiedReadonly { file_size, .. } => {
+                        create_stat(inode, *file_size, AccessMode::ReadOnly)
+                    }
+                    AuthFsEntry::VerifiedReadonly { reader } => {
+                        create_stat(inode, reader.file_size()?, AccessMode::ReadOnly)
+                    }
+                    AuthFsEntry::VerifiedNew { editor, attr, .. } => {
+                        create_stat(inode, editor.size(), AccessMode::Variable(attr.mode()))
+                    }
+                    AuthFsEntry::VerifiedNewDirectory { dir, attr } => create_dir_stat(
+                        inode,
+                        dir.number_of_entries(),
+                        AccessMode::Variable(attr.mode()),
+                    ),
+                }?,
+                DEFAULT_METADATA_TIMEOUT,
+            ))
+        })
+    }
+
+    fn open(
+        &self,
+        _ctx: Context,
+        inode: Self::Inode,
+        flags: u32,
+    ) -> io::Result<(Option<Self::Handle>, FuseOpenOptions)> {
+        // Since file handle is not really used in later operations (which use Inode directly),
+        // return None as the handle.
+        self.handle_inode(&inode, |config| {
+            match config {
+                AuthFsEntry::VerifiedReadonly { .. } | AuthFsEntry::UnverifiedReadonly { .. } => {
+                    check_access_mode(flags, libc::O_RDONLY)?;
+                }
+                AuthFsEntry::VerifiedNew { .. } => {
+                    // TODO(victorhsieh): Imeplement ACL check using the attr and ctx. Always allow
+                    // for now.
+                }
+                AuthFsEntry::ReadonlyDirectory { .. }
+                | AuthFsEntry::VerifiedNewDirectory { .. } => {
+                    // TODO(victorhsieh): implement when needed.
+                    return Err(io::Error::from_raw_os_error(libc::ENOSYS));
+                }
+            }
+            // Always cache the file content. There is currently no need to support direct I/O or
+            // avoid the cache buffer. Memory mapping is only possible with cache enabled.
+            Ok((None, FuseOpenOptions::KEEP_CACHE))
+        })
+    }
+
+    fn create(
+        &self,
+        _ctx: Context,
+        parent: Self::Inode,
+        name: &CStr,
+        mode: u32,
+        _flags: u32,
+        umask: u32,
+        _security_ctx: Option<&CStr>,
+    ) -> io::Result<(Entry, Option<Self::Handle>, FuseOpenOptions)> {
+        let new_inode = self.create_new_entry_with_ref_count(
+            parent,
+            name,
+            |parent_entry, basename, new_inode| match parent_entry {
+                AuthFsEntry::VerifiedNewDirectory { dir, .. } => {
+                    if dir.has_entry(basename) {
+                        return Err(io::Error::from_raw_os_error(libc::EEXIST));
+                    }
+                    let mode = mode & !umask;
+                    let (new_file, new_attr) = dir.create_file(basename, new_inode, mode)?;
+                    Ok(AuthFsEntry::VerifiedNew { editor: new_file, attr: new_attr })
+                }
+                _ => Err(io::Error::from_raw_os_error(libc::EBADF)),
+            },
+        )?;
+
+        Ok((
+            Entry {
+                inode: new_inode,
+                generation: 0,
+                attr: create_stat(new_inode, /* file_size */ 0, AccessMode::Variable(mode))?,
+                entry_timeout: DEFAULT_METADATA_TIMEOUT,
+                attr_timeout: DEFAULT_METADATA_TIMEOUT,
+            },
+            // See also `open`.
+            /* handle */ None,
+            FuseOpenOptions::KEEP_CACHE,
+        ))
+    }
+
+    fn read<W: io::Write + ZeroCopyWriter>(
+        &self,
+        _ctx: Context,
+        inode: Inode,
+        _handle: Handle,
+        w: W,
+        size: u32,
+        offset: u64,
+        _lock_owner: Option<u64>,
+        _flags: u32,
+    ) -> io::Result<usize> {
+        self.handle_inode(&inode, |config| {
+            match config {
+                AuthFsEntry::VerifiedReadonly { reader } => {
+                    read_chunks(w, reader, reader.file_size()?, offset, size)
+                }
+                AuthFsEntry::UnverifiedReadonly { reader, file_size } => {
+                    read_chunks(w, reader, *file_size, offset, size)
+                }
+                AuthFsEntry::VerifiedNew { editor, .. } => {
+                    // Note that with FsOptions::WRITEBACK_CACHE, it's possible for the kernel to
+                    // request a read even if the file is open with O_WRONLY.
+                    read_chunks(w, editor, editor.size(), offset, size)
+                }
+                AuthFsEntry::ReadonlyDirectory { .. }
+                | AuthFsEntry::VerifiedNewDirectory { .. } => {
+                    Err(io::Error::from_raw_os_error(libc::EISDIR))
+                }
+            }
+        })
+    }
+
+    fn write<R: io::Read + ZeroCopyReader>(
+        &self,
+        _ctx: Context,
+        inode: Self::Inode,
+        _handle: Self::Handle,
+        mut r: R,
+        size: u32,
+        offset: u64,
+        _lock_owner: Option<u64>,
+        _delayed_write: bool,
+        _flags: u32,
+    ) -> io::Result<usize> {
+        self.handle_inode(&inode, |config| match config {
+            AuthFsEntry::VerifiedNew { editor, .. } => {
+                let mut buf = vec![0; size as usize];
+                r.read_exact(&mut buf)?;
+                editor.write_at(&buf, offset)
+            }
+            AuthFsEntry::VerifiedReadonly { .. } | AuthFsEntry::UnverifiedReadonly { .. } => {
+                Err(io::Error::from_raw_os_error(libc::EPERM))
+            }
+            AuthFsEntry::ReadonlyDirectory { .. } | AuthFsEntry::VerifiedNewDirectory { .. } => {
+                Err(io::Error::from_raw_os_error(libc::EISDIR))
+            }
+        })
+    }
+
+    fn setattr(
+        &self,
+        _ctx: Context,
+        inode: Inode,
+        in_attr: libc::stat64,
+        _handle: Option<Handle>,
+        valid: SetattrValid,
+    ) -> io::Result<(libc::stat64, Duration)> {
+        let mut inode_table = self.inode_table.write().unwrap();
+        handle_inode_mut_locked(&mut inode_table, &inode, |InodeState { entry, .. }| match entry {
+            AuthFsEntry::VerifiedNew { editor, attr } => {
+                check_unsupported_setattr_request(valid)?;
+
+                // Initialize the default stat.
+                let mut new_attr =
+                    create_stat(inode, editor.size(), AccessMode::Variable(attr.mode()))?;
+                // `valid` indicates what fields in `attr` are valid. Update to return correctly.
+                if valid.contains(SetattrValid::SIZE) {
+                    // st_size is i64, but the cast should be safe since kernel should not give a
+                    // negative size.
+                    debug_assert!(in_attr.st_size >= 0);
+                    new_attr.st_size = in_attr.st_size;
+                    editor.resize(in_attr.st_size as u64)?;
+                }
+                if valid.contains(SetattrValid::MODE) {
+                    attr.set_mode(in_attr.st_mode)?;
+                    new_attr.st_mode = in_attr.st_mode;
+                }
+                Ok((new_attr, DEFAULT_METADATA_TIMEOUT))
+            }
+            AuthFsEntry::VerifiedNewDirectory { dir, attr } => {
+                check_unsupported_setattr_request(valid)?;
+                if valid.contains(SetattrValid::SIZE) {
+                    return Err(io::Error::from_raw_os_error(libc::EISDIR));
+                }
+
+                // Initialize the default stat.
+                let mut new_attr = create_dir_stat(
+                    inode,
+                    dir.number_of_entries(),
+                    AccessMode::Variable(attr.mode()),
+                )?;
+                if valid.contains(SetattrValid::MODE) {
+                    attr.set_mode(in_attr.st_mode)?;
+                    new_attr.st_mode = in_attr.st_mode;
+                }
+                Ok((new_attr, DEFAULT_METADATA_TIMEOUT))
+            }
+            _ => Err(io::Error::from_raw_os_error(libc::EPERM)),
+        })
+    }
+
+    fn getxattr(
+        &self,
+        _ctx: Context,
+        inode: Self::Inode,
+        name: &CStr,
+        size: u32,
+    ) -> io::Result<GetxattrReply> {
+        self.handle_inode(&inode, |config| {
+            match config {
+                AuthFsEntry::VerifiedNew { editor, .. } => {
+                    // FUSE ioctl is limited, thus we can't implement fs-verity ioctls without a
+                    // kernel change (see b/196635431). Until it's possible, use
+                    // xattr to expose what we need as an authfs specific API.
+                    if name != CStr::from_bytes_with_nul(b"authfs.fsverity.digest\0").unwrap() {
+                        return Err(io::Error::from_raw_os_error(libc::ENODATA));
+                    }
+
+                    if size == 0 {
+                        // Per protocol, when size is 0, return the value size.
+                        Ok(GetxattrReply::Count(editor.get_fsverity_digest_size() as u32))
+                    } else {
+                        let digest = editor.calculate_fsverity_digest()?;
+                        if digest.len() > size as usize {
+                            Err(io::Error::from_raw_os_error(libc::ERANGE))
+                        } else {
+                            Ok(GetxattrReply::Value(digest.to_vec()))
+                        }
+                    }
+                }
+                _ => Err(io::Error::from_raw_os_error(libc::ENODATA)),
+            }
+        })
+    }
+
+    fn mkdir(
+        &self,
+        _ctx: Context,
+        parent: Self::Inode,
+        name: &CStr,
+        mode: u32,
+        umask: u32,
+        _security_ctx: Option<&CStr>,
+    ) -> io::Result<Entry> {
+        let new_inode = self.create_new_entry_with_ref_count(
+            parent,
+            name,
+            |parent_entry, basename, new_inode| match parent_entry {
+                AuthFsEntry::VerifiedNewDirectory { dir, .. } => {
+                    if dir.has_entry(basename) {
+                        return Err(io::Error::from_raw_os_error(libc::EEXIST));
+                    }
+                    let mode = mode & !umask;
+                    let (new_dir, new_attr) = dir.mkdir(basename, new_inode, mode)?;
+                    Ok(AuthFsEntry::VerifiedNewDirectory { dir: new_dir, attr: new_attr })
+                }
+                AuthFsEntry::ReadonlyDirectory { .. } => {
+                    Err(io::Error::from_raw_os_error(libc::EACCES))
+                }
+                _ => Err(io::Error::from_raw_os_error(libc::EBADF)),
+            },
+        )?;
+
+        Ok(Entry {
+            inode: new_inode,
+            generation: 0,
+            attr: create_dir_stat(new_inode, /* file_number */ 0, AccessMode::Variable(mode))?,
+            entry_timeout: DEFAULT_METADATA_TIMEOUT,
+            attr_timeout: DEFAULT_METADATA_TIMEOUT,
+        })
+    }
+
+    fn unlink(&self, _ctx: Context, parent: Self::Inode, name: &CStr) -> io::Result<()> {
+        let mut inode_table = self.inode_table.write().unwrap();
+        handle_inode_mut_locked(
+            &mut inode_table,
+            &parent,
+            |InodeState { entry, unlinked, .. }| match entry {
+                AuthFsEntry::VerifiedNewDirectory { dir, .. } => {
+                    let basename: &Path = cstr_to_path(name);
+                    // Delete the file from in both the local and remote directories.
+                    let _inode = dir.delete_file(basename)?;
+                    *unlinked = true;
+                    Ok(())
+                }
+                AuthFsEntry::ReadonlyDirectory { .. } => {
+                    Err(io::Error::from_raw_os_error(libc::EACCES))
+                }
+                AuthFsEntry::VerifiedNew { .. } => {
+                    // Deleting a entry in filesystem root is not currently supported.
+                    Err(io::Error::from_raw_os_error(libc::ENOSYS))
+                }
+                AuthFsEntry::UnverifiedReadonly { .. } | AuthFsEntry::VerifiedReadonly { .. } => {
+                    Err(io::Error::from_raw_os_error(libc::ENOTDIR))
+                }
+            },
+        )
+    }
+
+    fn rmdir(&self, _ctx: Context, parent: Self::Inode, name: &CStr) -> io::Result<()> {
+        let mut inode_table = self.inode_table.write().unwrap();
+
+        // Check before actual removal, with readonly borrow.
+        handle_inode_locked(&inode_table, &parent, |inode_state| match &inode_state.entry {
+            AuthFsEntry::VerifiedNewDirectory { dir, .. } => {
+                let basename: &Path = cstr_to_path(name);
+                let existing_inode = dir.find_inode(basename)?;
+                handle_inode_locked(&inode_table, &existing_inode, |inode_state| {
+                    inode_state.entry.expect_empty_deletable_directory()
+                })
+            }
+            AuthFsEntry::ReadonlyDirectory { .. } => {
+                Err(io::Error::from_raw_os_error(libc::EACCES))
+            }
+            _ => Err(io::Error::from_raw_os_error(libc::ENOTDIR)),
+        })?;
+
+        // Look up again, this time with mutable borrow. This needs to be done separately because
+        // the previous lookup needs to borrow multiple entry references in the table.
+        handle_inode_mut_locked(
+            &mut inode_table,
+            &parent,
+            |InodeState { entry, unlinked, .. }| match entry {
+                AuthFsEntry::VerifiedNewDirectory { dir, .. } => {
+                    let basename: &Path = cstr_to_path(name);
+                    let _inode = dir.force_delete_directory(basename)?;
+                    *unlinked = true;
+                    Ok(())
+                }
+                _ => unreachable!("Mismatched entry type that is just checked"),
+            },
+        )
+    }
+
+    fn opendir(
+        &self,
+        _ctx: Context,
+        inode: Self::Inode,
+        _flags: u32,
+    ) -> io::Result<(Option<Self::Handle>, FuseOpenOptions)> {
+        let entries = self.handle_inode(&inode, |config| match config {
+            AuthFsEntry::VerifiedNewDirectory { dir, .. } => dir.retrieve_entries(),
+            AuthFsEntry::ReadonlyDirectory { dir } => dir.retrieve_entries(),
+            _ => Err(io::Error::from_raw_os_error(libc::ENOTDIR)),
+        })?;
+        self.open_dir_store_snapshot(entries)
+    }
+
+    fn readdir(
+        &self,
+        _ctx: Context,
+        _inode: Self::Inode,
+        handle: Self::Handle,
+        _size: u32,
+        offset: u64,
+    ) -> io::Result<Self::DirIter> {
+        let dir_handle_table = self.dir_handle_table.read().unwrap();
+        if let Some(entry) = dir_handle_table.get(&handle) {
+            Ok(DirEntriesSnapshotIterator {
+                snapshot: entry.clone(),
+                prev_offset: offset.try_into().unwrap(),
+            })
+        } else {
+            Err(io::Error::from_raw_os_error(libc::EBADF))
+        }
+    }
+
+    fn releasedir(
+        &self,
+        _ctx: Context,
+        inode: Self::Inode,
+        _flags: u32,
+        handle: Self::Handle,
+    ) -> io::Result<()> {
+        let mut dir_handle_table = self.dir_handle_table.write().unwrap();
+        if dir_handle_table.remove(&handle).is_none() {
+            unreachable!("Unknown directory handle {}, inode {}", handle, inode);
+        }
+        Ok(())
+    }
+
+    fn statfs(&self, _ctx: Context, _inode: Self::Inode) -> io::Result<libc::statvfs64> {
+        let remote_stat = self.remote_fs_stats_reader.statfs()?;
+
+        // SAFETY: We are zero-initializing a struct with only POD fields. Not all fields matter to
+        // FUSE. See also:
+        // https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/fs/fuse/inode.c?h=v5.15#n460
+        let mut st: libc::statvfs64 = unsafe { zeroed() };
+
+        // Use the remote stat as a template, since it'd matter the most to consider the writable
+        // files/directories that are written to the remote.
+        st.f_bsize = remote_stat.block_size;
+        st.f_frsize = remote_stat.fragment_size;
+        st.f_blocks = remote_stat.block_numbers;
+        st.f_bavail = remote_stat.block_available;
+        st.f_favail = remote_stat.inodes_available;
+        st.f_namemax = remote_stat.max_filename;
+        // Assuming we are not privileged to use all free spaces on the remote server, set the free
+        // blocks/fragment to the same available amount.
+        st.f_bfree = st.f_bavail;
+        st.f_ffree = st.f_favail;
+        // Number of inodes on the filesystem
+        st.f_files = self.inode_table.read().unwrap().len() as u64;
+
+        Ok(st)
+    }
+}
+
+fn handle_inode_locked<F, R>(
+    inode_table: &BTreeMap<Inode, InodeState>,
+    inode: &Inode,
+    handle_fn: F,
+) -> io::Result<R>
+where
+    F: FnOnce(&InodeState) -> io::Result<R>,
+{
+    if let Some(inode_state) = inode_table.get(inode) {
+        handle_fn(inode_state)
+    } else {
+        Err(io::Error::from_raw_os_error(libc::ENOENT))
+    }
+}
+
+fn handle_inode_mut_locked<F, R>(
+    inode_table: &mut BTreeMap<Inode, InodeState>,
+    inode: &Inode,
+    handle_fn: F,
+) -> io::Result<R>
+where
+    F: FnOnce(&mut InodeState) -> io::Result<R>,
+{
+    if let Some(inode_state) = inode_table.get_mut(inode) {
+        handle_fn(inode_state)
+    } else {
+        Err(io::Error::from_raw_os_error(libc::ENOENT))
+    }
+}
+
+fn check_unsupported_setattr_request(valid: SetattrValid) -> io::Result<()> {
+    if valid.contains(SetattrValid::UID) {
+        warn!("Changing st_uid is not currently supported");
+        return Err(io::Error::from_raw_os_error(libc::ENOSYS));
+    }
+    if valid.contains(SetattrValid::GID) {
+        warn!("Changing st_gid is not currently supported");
+        return Err(io::Error::from_raw_os_error(libc::ENOSYS));
+    }
+    if valid.intersects(
+        SetattrValid::CTIME
+            | SetattrValid::ATIME
+            | SetattrValid::ATIME_NOW
+            | SetattrValid::MTIME
+            | SetattrValid::MTIME_NOW,
+    ) {
+        trace!("Ignoring ctime/atime/mtime change as authfs does not maintain timestamp currently");
+    }
+    Ok(())
+}
+
+fn cstr_to_path(cstr: &CStr) -> &Path {
+    OsStr::from_bytes(cstr.to_bytes()).as_ref()
+}
diff --git a/guest/authfs/src/fusefs/file.rs b/guest/authfs/src/fusefs/file.rs
new file mode 100644
index 0000000..8c02281
--- /dev/null
+++ b/guest/authfs/src/fusefs/file.rs
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+use log::error;
+use std::convert::TryInto;
+use std::io;
+use std::path::PathBuf;
+use std::sync::Mutex;
+
+use crate::file::{
+    ChunkBuffer, EagerChunkReader, ReadByChunk, RemoteFileReader, RemoteMerkleTreeReader,
+    VirtFdService,
+};
+use crate::fsverity::{merkle_tree_size, VerifiedFileReader};
+
+enum FileInfo {
+    ByPathUnderDirFd(i32, PathBuf),
+    ByFd(i32),
+}
+
+type Reader = VerifiedFileReader<RemoteFileReader, EagerChunkReader>;
+
+/// A lazily created read-only file that is verified against the given fs-verity digest.
+///
+/// The main purpose of this struct is to wrap and construct `VerifiedFileReader` lazily.
+pub struct LazyVerifiedReadonlyFile {
+    expected_digest: Vec<u8>,
+
+    service: VirtFdService,
+    file_info: FileInfo,
+
+    /// A lazily instantiated reader.
+    reader: Mutex<Option<Reader>>,
+}
+
+impl LazyVerifiedReadonlyFile {
+    /// Prepare the file by a remote path, related to a remote directory FD.
+    pub fn prepare_by_path(
+        service: VirtFdService,
+        remote_dir_fd: i32,
+        remote_path: PathBuf,
+        expected_digest: Vec<u8>,
+    ) -> Self {
+        LazyVerifiedReadonlyFile {
+            service,
+            file_info: FileInfo::ByPathUnderDirFd(remote_dir_fd, remote_path),
+            expected_digest,
+            reader: Mutex::new(None),
+        }
+    }
+
+    /// Prepare the file by a remote file FD.
+    pub fn prepare_by_fd(service: VirtFdService, remote_fd: i32, expected_digest: Vec<u8>) -> Self {
+        LazyVerifiedReadonlyFile {
+            service,
+            file_info: FileInfo::ByFd(remote_fd),
+            expected_digest,
+            reader: Mutex::new(None),
+        }
+    }
+
+    fn ensure_init_then<F, T>(&self, callback: F) -> io::Result<T>
+    where
+        F: FnOnce(&Reader) -> io::Result<T>,
+    {
+        let mut reader = self.reader.lock().unwrap();
+        if reader.is_none() {
+            let remote_file = match &self.file_info {
+                FileInfo::ByPathUnderDirFd(dir_fd, related_path) => {
+                    RemoteFileReader::new_by_path(self.service.clone(), *dir_fd, related_path)?
+                }
+                FileInfo::ByFd(file_fd) => RemoteFileReader::new(self.service.clone(), *file_fd),
+            };
+            let remote_fd = remote_file.get_remote_fd();
+            let file_size = self
+                .service
+                .getFileSize(remote_fd)
+                .map_err(|e| {
+                    error!("Failed to get file size of remote fd {}: {}", remote_fd, e);
+                    io::Error::from_raw_os_error(libc::EIO)
+                })?
+                .try_into()
+                .map_err(|e| {
+                    error!("Failed convert file size: {}", e);
+                    io::Error::from_raw_os_error(libc::EIO)
+                })?;
+            let instance = VerifiedFileReader::new(
+                remote_file,
+                file_size,
+                &self.expected_digest,
+                EagerChunkReader::new(
+                    RemoteMerkleTreeReader::new(self.service.clone(), remote_fd),
+                    merkle_tree_size(file_size),
+                )?,
+            )
+            .map_err(|e| {
+                error!("Failed instantiate a verified file reader: {}", e);
+                io::Error::from_raw_os_error(libc::EIO)
+            })?;
+            *reader = Some(instance);
+        }
+        callback(reader.as_ref().unwrap())
+    }
+
+    pub fn file_size(&self) -> io::Result<u64> {
+        self.ensure_init_then(|reader| Ok(reader.file_size))
+    }
+}
+
+impl ReadByChunk for LazyVerifiedReadonlyFile {
+    fn read_chunk(&self, chunk_index: u64, buf: &mut ChunkBuffer) -> io::Result<usize> {
+        self.ensure_init_then(|reader| reader.read_chunk(chunk_index, buf))
+    }
+}
diff --git a/guest/authfs/src/fusefs/mount.rs b/guest/authfs/src/fusefs/mount.rs
new file mode 100644
index 0000000..7f8bac1
--- /dev/null
+++ b/guest/authfs/src/fusefs/mount.rs
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2021 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 fuse::mount::MountOption;
+use std::fs::OpenOptions;
+use std::num::NonZeroU8;
+use std::os::unix::io::AsRawFd;
+use std::path::Path;
+
+use super::AuthFs;
+
+/// Maximum bytes (excluding the FUSE header) `AuthFs` will receive from the kernel for write
+/// operations by another process.
+pub const MAX_WRITE_BYTES: u32 = 65536;
+
+/// Maximum bytes (excluding the FUSE header) `AuthFs` will receive from the kernel for read
+/// operations by another process.
+/// TODO(victorhsieh): This option is deprecated by FUSE. Figure out if we can remove this.
+const MAX_READ_BYTES: u32 = 65536;
+
+/// Mount and start the FUSE instance to handle messages. This requires CAP_SYS_ADMIN.
+pub fn mount_and_enter_message_loop(
+    authfs: AuthFs,
+    mountpoint: &Path,
+    extra_options: &Option<String>,
+    threads: Option<NonZeroU8>,
+) -> Result<(), fuse::Error> {
+    let dev_fuse = OpenOptions::new()
+        .read(true)
+        .write(true)
+        .open("/dev/fuse")
+        .expect("Failed to open /dev/fuse");
+
+    let mut mount_options = vec![
+        MountOption::FD(dev_fuse.as_raw_fd()),
+        MountOption::RootMode(libc::S_IFDIR | libc::S_IXUSR | libc::S_IXGRP | libc::S_IXOTH),
+        MountOption::AllowOther,
+        MountOption::UserId(0),
+        MountOption::GroupId(0),
+        MountOption::MaxRead(MAX_READ_BYTES),
+    ];
+    if let Some(value) = extra_options {
+        mount_options.push(MountOption::Extra(value));
+    }
+
+    fuse::mount(
+        mountpoint,
+        "authfs",
+        libc::MS_NOSUID | libc::MS_NODEV | libc::MS_NOEXEC,
+        &mount_options,
+    )
+    .expect("Failed to mount fuse");
+
+    let mut config = fuse::FuseConfig::new();
+    config.dev_fuse(dev_fuse).max_write(MAX_WRITE_BYTES).max_read(MAX_READ_BYTES);
+    if let Some(num) = threads {
+        config.num_threads(u8::from(num).into());
+    }
+    config.enter_message_loop(authfs)
+}
diff --git a/guest/authfs/src/main.rs b/guest/authfs/src/main.rs
new file mode 100644
index 0000000..e46b197
--- /dev/null
+++ b/guest/authfs/src/main.rs
@@ -0,0 +1,319 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+//! This crate implements AuthFS, a FUSE-based, non-generic filesystem where file access is
+//! authenticated. This filesystem assumes the underlying layer is not trusted, e.g. file may be
+//! provided by an untrusted host/VM, so that the content can't be simply trusted. However, with a
+//! known file hash from trusted party, this filesystem can still verify a (read-only) file even if
+//! the host/VM as the blob provider is malicious. With the Merkle tree, each read of file block can
+//! be verified individually only when needed.
+//!
+//! AuthFS only serve files that are specifically configured. Each remote file can be configured to
+//! appear as a local file at the mount point. A file configuration may include its remote file
+//! identifier and its verification method (e.g. by known digest).
+//!
+//! AuthFS also support remote directories. A remote directory may be defined by a manifest file,
+//! which contains file paths and their corresponding digests.
+//!
+//! AuthFS can also be configured for write, in which case the remote file server is treated as a
+//! (untrusted) storage. The file/directory integrity is maintained in memory in the VM. Currently,
+//! the state is not persistent, thus only new file/directory are supported.
+
+use anyhow::{anyhow, bail, Result};
+use clap::Parser;
+use log::error;
+use protobuf::Message;
+use std::convert::TryInto;
+use std::fs::File;
+use std::num::NonZeroU8;
+use std::path::{Path, PathBuf};
+
+mod common;
+mod file;
+mod fsstat;
+mod fsverity;
+mod fusefs;
+
+use file::{Attr, InMemoryDir, RemoteDirEditor, RemoteFileEditor, RemoteFileReader};
+use fsstat::RemoteFsStatsReader;
+use fsverity::VerifiedFileEditor;
+use fsverity_digests_proto::fsverity_digests::FSVerityDigests;
+use fusefs::{AuthFs, AuthFsEntry, LazyVerifiedReadonlyFile};
+
+#[derive(Parser)]
+struct Args {
+    /// Mount point of AuthFS.
+    mount_point: PathBuf,
+
+    /// CID of the VM where the service runs.
+    #[clap(long)]
+    cid: u32,
+
+    /// Extra options to FUSE
+    #[clap(short = 'o')]
+    extra_options: Option<String>,
+
+    /// Number of threads to serve FUSE requests.
+    #[clap(short = 'j')]
+    thread_number: Option<NonZeroU8>,
+
+    /// A read-only remote file with integrity check. Can be multiple.
+    ///
+    /// For example, `--remote-ro-file 5:sha256-1234abcd` tells the filesystem to associate the
+    /// file $MOUNTPOINT/5 with a remote FD 5, and has a fs-verity digest with sha256 of the hex
+    /// value 1234abcd.
+    #[clap(long, value_parser = parse_remote_ro_file_option)]
+    remote_ro_file: Vec<OptionRemoteRoFile>,
+
+    /// A read-only remote file without integrity check. Can be multiple.
+    ///
+    /// For example, `--remote-ro-file-unverified 5` tells the filesystem to associate the file
+    /// $MOUNTPOINT/5 with a remote FD 5.
+    #[clap(long)]
+    remote_ro_file_unverified: Vec<i32>,
+
+    /// A new read-writable remote file with integrity check. Can be multiple.
+    ///
+    /// For example, `--remote-new-rw-file 5` tells the filesystem to associate the file
+    /// $MOUNTPOINT/5 with a remote FD 5.
+    #[clap(long)]
+    remote_new_rw_file: Vec<i32>,
+
+    /// A read-only directory that represents a remote directory. The directory view is constructed
+    /// and finalized during the filesystem initialization based on the provided mapping file
+    /// (which is a serialized protobuf of android.security.fsverity.FSVerityDigests, which
+    /// essentially provides <file path, fs-verity digest> mappings of exported files). The mapping
+    /// file is supposed to come from a trusted location in order to provide a trusted view as well
+    /// as verified access of included files with their fs-verity digest. Not all files on the
+    /// remote host may be included in the mapping file, so the directory view may be partial. The
+    /// directory structure won't change throughout the filesystem lifetime.
+    ///
+    /// For example, `--remote-ro-dir 5:/path/to/mapping:prefix/` tells the filesystem to
+    /// construct a directory structure defined in the mapping file at $MOUNTPOINT/5, which may
+    /// include a file like /5/system/framework/framework.jar. "prefix/" tells the filesystem to
+    /// strip the path (e.g. "system/") from the mount point to match the expected location of the
+    /// remote FD (e.g. a directory FD of "/system" in the remote).
+    #[clap(long, value_parser = parse_remote_new_ro_dir_option)]
+    remote_ro_dir: Vec<OptionRemoteRoDir>,
+
+    /// A new directory that is assumed empty in the backing filesystem. New files created in this
+    /// directory are integrity-protected in the same way as --remote-new-verified-file. Can be
+    /// multiple.
+    ///
+    /// For example, `--remote-new-rw-dir 5` tells the filesystem to associate $MOUNTPOINT/5
+    /// with a remote dir FD 5.
+    #[clap(long)]
+    remote_new_rw_dir: Vec<i32>,
+
+    /// Enable debugging features.
+    #[clap(long)]
+    debug: bool,
+}
+
+#[derive(Clone)]
+struct OptionRemoteRoFile {
+    /// ID to refer to the remote file.
+    remote_fd: i32,
+
+    /// Expected fs-verity digest (with sha256) for the remote file.
+    digest: String,
+}
+
+#[derive(Clone)]
+struct OptionRemoteRoDir {
+    /// ID to refer to the remote dir.
+    remote_dir_fd: i32,
+
+    /// A mapping file that describes the expecting file/directory structure and integrity metadata
+    /// in the remote directory. The file contains serialized protobuf of
+    /// android.security.fsverity.FSVerityDigests.
+    mapping_file_path: PathBuf,
+
+    prefix: String,
+}
+
+fn parse_remote_ro_file_option(option: &str) -> Result<OptionRemoteRoFile> {
+    let strs: Vec<&str> = option.split(':').collect();
+    if strs.len() != 2 {
+        bail!("Invalid option: {}", option);
+    }
+    if let Some(digest) = strs[1].strip_prefix("sha256-") {
+        Ok(OptionRemoteRoFile { remote_fd: strs[0].parse::<i32>()?, digest: String::from(digest) })
+    } else {
+        bail!("Unsupported hash algorithm or invalid format: {}", strs[1]);
+    }
+}
+
+fn parse_remote_new_ro_dir_option(option: &str) -> Result<OptionRemoteRoDir> {
+    let strs: Vec<&str> = option.split(':').collect();
+    if strs.len() != 3 {
+        bail!("Invalid option: {}", option);
+    }
+    Ok(OptionRemoteRoDir {
+        remote_dir_fd: strs[0].parse::<i32>().unwrap(),
+        mapping_file_path: PathBuf::from(strs[1]),
+        prefix: String::from(strs[2]),
+    })
+}
+
+fn new_remote_verified_file_entry(
+    service: file::VirtFdService,
+    remote_fd: i32,
+    expected_digest: &str,
+) -> Result<AuthFsEntry> {
+    Ok(AuthFsEntry::VerifiedReadonly {
+        reader: LazyVerifiedReadonlyFile::prepare_by_fd(
+            service,
+            remote_fd,
+            hex::decode(expected_digest)?,
+        ),
+    })
+}
+
+fn new_remote_unverified_file_entry(
+    service: file::VirtFdService,
+    remote_fd: i32,
+    file_size: u64,
+) -> Result<AuthFsEntry> {
+    let reader = RemoteFileReader::new(service, remote_fd);
+    Ok(AuthFsEntry::UnverifiedReadonly { reader, file_size })
+}
+
+fn new_remote_new_verified_file_entry(
+    service: file::VirtFdService,
+    remote_fd: i32,
+) -> Result<AuthFsEntry> {
+    let remote_file = RemoteFileEditor::new(service.clone(), remote_fd);
+    Ok(AuthFsEntry::VerifiedNew {
+        editor: VerifiedFileEditor::new(remote_file),
+        attr: Attr::new_file(service, remote_fd),
+    })
+}
+
+fn new_remote_new_verified_dir_entry(
+    service: file::VirtFdService,
+    remote_fd: i32,
+) -> Result<AuthFsEntry> {
+    let dir = RemoteDirEditor::new(service.clone(), remote_fd);
+    let attr = Attr::new_dir(service, remote_fd);
+    Ok(AuthFsEntry::VerifiedNewDirectory { dir, attr })
+}
+
+fn prepare_root_dir_entries(
+    service: file::VirtFdService,
+    authfs: &mut AuthFs,
+    args: &Args,
+) -> Result<()> {
+    for config in &args.remote_ro_file {
+        authfs.add_entry_at_root_dir(
+            remote_fd_to_path_buf(config.remote_fd),
+            new_remote_verified_file_entry(service.clone(), config.remote_fd, &config.digest)?,
+        )?;
+    }
+
+    for remote_fd in &args.remote_ro_file_unverified {
+        let remote_fd = *remote_fd;
+        authfs.add_entry_at_root_dir(
+            remote_fd_to_path_buf(remote_fd),
+            new_remote_unverified_file_entry(
+                service.clone(),
+                remote_fd,
+                service.getFileSize(remote_fd)?.try_into()?,
+            )?,
+        )?;
+    }
+
+    for remote_fd in &args.remote_new_rw_file {
+        let remote_fd = *remote_fd;
+        authfs.add_entry_at_root_dir(
+            remote_fd_to_path_buf(remote_fd),
+            new_remote_new_verified_file_entry(service.clone(), remote_fd)?,
+        )?;
+    }
+
+    for remote_fd in &args.remote_new_rw_dir {
+        let remote_fd = *remote_fd;
+        authfs.add_entry_at_root_dir(
+            remote_fd_to_path_buf(remote_fd),
+            new_remote_new_verified_dir_entry(service.clone(), remote_fd)?,
+        )?;
+    }
+
+    for config in &args.remote_ro_dir {
+        let dir_root_inode = authfs.add_entry_at_root_dir(
+            remote_fd_to_path_buf(config.remote_dir_fd),
+            AuthFsEntry::ReadonlyDirectory { dir: InMemoryDir::new() },
+        )?;
+
+        // Build the directory tree based on the mapping file.
+        let mut reader = File::open(&config.mapping_file_path)?;
+        let proto = FSVerityDigests::parse_from_reader(&mut reader)?;
+        for (path_str, digest) in &proto.digests {
+            if digest.hash_alg != "sha256" {
+                bail!("Unsupported hash algorithm: {}", digest.hash_alg);
+            }
+
+            let file_entry = {
+                let remote_path_str = path_str.strip_prefix(&config.prefix).ok_or_else(|| {
+                    anyhow!("Expect path {} to match prefix {}", path_str, config.prefix)
+                })?;
+                AuthFsEntry::VerifiedReadonly {
+                    reader: LazyVerifiedReadonlyFile::prepare_by_path(
+                        service.clone(),
+                        config.remote_dir_fd,
+                        PathBuf::from(remote_path_str),
+                        digest.digest.clone(),
+                    ),
+                }
+            };
+            authfs.add_entry_at_ro_dir_by_path(dir_root_inode, Path::new(path_str), file_entry)?;
+        }
+    }
+
+    Ok(())
+}
+
+fn remote_fd_to_path_buf(fd: i32) -> PathBuf {
+    PathBuf::from(fd.to_string())
+}
+
+fn try_main() -> Result<()> {
+    let args = Args::parse();
+
+    let log_level = if args.debug { log::LevelFilter::Debug } else { log::LevelFilter::Info };
+    android_logger::init_once(
+        android_logger::Config::default().with_tag("authfs").with_max_level(log_level),
+    );
+
+    let service = file::get_rpc_binder_service(args.cid)?;
+    let mut authfs = AuthFs::new(RemoteFsStatsReader::new(service.clone()));
+    prepare_root_dir_entries(service, &mut authfs, &args)?;
+
+    fusefs::mount_and_enter_message_loop(
+        authfs,
+        &args.mount_point,
+        &args.extra_options,
+        args.thread_number,
+    )?;
+    bail!("Unexpected exit after the handler loop")
+}
+
+fn main() {
+    if let Err(e) = try_main() {
+        error!("failed with {:?}", e);
+        std::process::exit(1);
+    }
+}
