Authenticate file w/ fs-verity digest in hex
An input directory is configured by a build manifest file. With this
change, authfs starts to use the fs-verity digest in the manifest to
authenticate the corresponding file.
Although we're not using it, this change also makes it possible to
specify a known fs-verity digest to a remote file from the command line
(and deprecate the fake support of signature verification by the given
certificate).
Since we no longer derive fs-verity digest from the first chunk of a
Merkle tree, some relevant functions are deleted.
Bug: 206869687
Test: atest AuthFsHostTest ComposHostTestCases
Test: atest authfs_device_test_src_lib
Change-Id: Ibb5c246fb0d29aeafde187555f8d72c0282a65c7
diff --git a/authfs/src/auth.rs b/authfs/src/auth.rs
deleted file mode 100644
index 729b4d2..0000000
--- a/authfs/src/auth.rs
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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 std::io;
-
-// TODO(b/170494765): Implement an authenticator to verify a PKCS#7 signature. We only need to
-// verify the signature, not the full certificate chain.
-
-pub trait Authenticator {
- fn verify(&self, signature: Option<&[u8]>, signed_data: &[u8]) -> io::Result<bool>;
-}
-
-pub struct FakeAuthenticator {
- should_allow: bool,
-}
-
-#[allow(dead_code)]
-impl FakeAuthenticator {
- pub fn always_succeed() -> Self {
- FakeAuthenticator { should_allow: true }
- }
-
- pub fn always_fail() -> Self {
- FakeAuthenticator { should_allow: false }
- }
-}
-
-impl Authenticator for FakeAuthenticator {
- fn verify(&self, _signature_pem: Option<&[u8]>, _signed_data: &[u8]) -> io::Result<bool> {
- Ok(self.should_allow)
- }
-}
diff --git a/authfs/src/fsverity/common.rs b/authfs/src/fsverity/common.rs
index 83e8ae4..eba379d 100644
--- a/authfs/src/fsverity/common.rs
+++ b/authfs/src/fsverity/common.rs
@@ -24,8 +24,8 @@
#[derive(Error, Debug)]
pub enum FsverityError {
- #[error("Cannot verify a signature")]
- BadSignature,
+ #[error("Invalid digest")]
+ InvalidDigest,
#[error("Insufficient data, only got {0}")]
InsufficientData(usize),
#[error("Cannot verify a block")]
diff --git a/authfs/src/fsverity/metadata/Android.bp b/authfs/src/fsverity/metadata/Android.bp
index b155224..af3729f 100644
--- a/authfs/src/fsverity/metadata/Android.bp
+++ b/authfs/src/fsverity/metadata/Android.bp
@@ -18,6 +18,7 @@
],
rustlibs: [
"libauthfs_fsverity_metadata_bindgen",
+ "libring",
],
edition: "2018",
apex_available: ["com.android.virt"],
diff --git a/authfs/src/fsverity/metadata/metadata.hpp b/authfs/src/fsverity/metadata/metadata.hpp
index 7bbd3da..f05740e 100644
--- a/authfs/src/fsverity/metadata/metadata.hpp
+++ b/authfs/src/fsverity/metadata/metadata.hpp
@@ -47,6 +47,9 @@
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,
diff --git a/authfs/src/fsverity/metadata/metadata.rs b/authfs/src/fsverity/metadata/metadata.rs
index 073e044..8bc0617 100644
--- a/authfs/src/fsverity/metadata/metadata.rs
+++ b/authfs/src/fsverity/metadata/metadata.rs
@@ -16,18 +16,31 @@
//! Rust bindgen interface for FSVerity Metadata file (.fsv_meta)
use authfs_fsverity_metadata_bindgen::{
- fsverity_metadata_header, FSVERITY_SIGNATURE_TYPE_NONE, FSVERITY_SIGNATURE_TYPE_PKCS7,
- FSVERITY_SIGNATURE_TYPE_RAW,
+ fsverity_descriptor, fsverity_metadata_header, FSVERITY_HASH_ALG_SHA256,
+ FSVERITY_SIGNATURE_TYPE_NONE, FSVERITY_SIGNATURE_TYPE_PKCS7, FSVERITY_SIGNATURE_TYPE_RAW,
};
+use ring::digest::{Context, SHA256};
use std::cmp::min;
-use std::os::unix::fs::MetadataExt;
+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>>,
@@ -54,14 +67,6 @@
}
}
-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;
-use std::path::{Path, PathBuf};
-use std::slice::from_raw_parts_mut;
-
/// Common block and page size in Linux.
pub const CHUNK_SIZE: u64 = authfs_fsverity_metadata_bindgen::CHUNK_SIZE;
@@ -75,23 +80,42 @@
/// 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_size = size_of::<fsverity_metadata_header>();
+ let (header, digest) = {
+ // SAFETY: The header doesn't include any pointers.
+ let mut header: fsverity_metadata_header = unsafe { zeroed() };
- // SAFETY: the header doesn't include any pointers
- let header: fsverity_metadata_header = unsafe {
- let mut header: fsverity_metadata_header = zeroed();
- let buffer = from_raw_parts_mut(
- &mut header as *mut fsverity_metadata_header as *mut u8,
- header_size,
- );
- metadata_file.read_exact(buffer)?;
+ // 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 => {
+ let mut context = Context::new(&SHA256);
+ context.update(
+ &back_buffer
+ [DESCRIPTOR_OFFSET..DESCRIPTOR_OFFSET + size_of::<fsverity_descriptor>()],
+ );
+ Ok(context.finish().as_ref().to_owned())
+ }
+ 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
+ (header, digest)
};
if header.version != 1 {
@@ -113,5 +137,5 @@
let merkle_tree_offset =
(metadata_file.stream_position()? + CHUNK_SIZE - 1) / CHUNK_SIZE * CHUNK_SIZE;
- Ok(Box::new(FSVerityMetadata { header, signature, metadata_file, merkle_tree_offset }))
+ Ok(Box::new(FSVerityMetadata { header, digest, signature, metadata_file, merkle_tree_offset }))
}
diff --git a/authfs/src/fsverity/sys.rs b/authfs/src/fsverity/sys.rs
index b3222db..51e10a5 100644
--- a/authfs/src/fsverity/sys.rs
+++ b/authfs/src/fsverity/sys.rs
@@ -14,9 +14,6 @@
* limitations under the License.
*/
-/// Magic used in fs-verity digest
-pub const FS_VERITY_MAGIC: &[u8; 8] = b"FSVerity";
-
/// fs-verity version that we are using
pub const FS_VERITY_VERSION: u8 = 1;
diff --git a/authfs/src/fsverity/verifier.rs b/authfs/src/fsverity/verifier.rs
index 17a0a2a..61b8e13 100644
--- a/authfs/src/fsverity/verifier.rs
+++ b/authfs/src/fsverity/verifier.rs
@@ -18,17 +18,12 @@
use std::io;
use super::common::{build_fsverity_digest, merkle_tree_height, FsverityError};
-use super::sys::{FS_VERITY_HASH_ALG_SHA256, FS_VERITY_MAGIC};
-use crate::auth::Authenticator;
use crate::common::{divide_roundup, CHUNK_SIZE};
use crate::crypto::{CryptoError, Sha256Hasher};
use crate::file::{ChunkBuffer, ReadByChunk};
const ZEROS: [u8; CHUNK_SIZE as usize] = [0u8; CHUNK_SIZE as usize];
-// The size of `struct fsverity_formatted_digest` in Linux with SHA-256.
-const SIZE_OF_FSVERITY_FORMATTED_DIGEST_SHA256: usize = 12 + Sha256Hasher::HASH_SIZE;
-
type HashBuffer = [u8; Sha256Hasher::HASH_SIZE];
fn hash_with_padding(chunk: &[u8], pad_to: usize) -> Result<HashBuffer, CryptoError> {
@@ -116,21 +111,6 @@
}))
}
-fn build_fsverity_formatted_digest(
- root_hash: &HashBuffer,
- file_size: u64,
-) -> Result<[u8; SIZE_OF_FSVERITY_FORMATTED_DIGEST_SHA256], CryptoError> {
- let digest = build_fsverity_digest(root_hash, file_size)?;
- // Little-endian byte representation of fsverity_formatted_digest from linux/fsverity.h
- // Not FFI-ed as it seems easier to deal with the raw bytes manually.
- let mut formatted_digest = [0u8; SIZE_OF_FSVERITY_FORMATTED_DIGEST_SHA256];
- formatted_digest[0..8].copy_from_slice(FS_VERITY_MAGIC);
- formatted_digest[8..10].copy_from_slice(&(FS_VERITY_HASH_ALG_SHA256 as u16).to_le_bytes());
- formatted_digest[10..12].copy_from_slice(&(Sha256Hasher::HASH_SIZE as u16).to_le_bytes());
- formatted_digest[12..].copy_from_slice(&digest);
- Ok(formatted_digest)
-}
-
pub struct VerifiedFileReader<F: ReadByChunk, M: ReadByChunk> {
chunked_file: F,
file_size: u64,
@@ -139,11 +119,10 @@
}
impl<F: ReadByChunk, M: ReadByChunk> VerifiedFileReader<F, M> {
- pub fn new<A: Authenticator>(
- authenticator: &A,
+ pub fn new(
chunked_file: F,
file_size: u64,
- sig: Option<&[u8]>,
+ expected_digest: &[u8],
merkle_tree: M,
) -> Result<VerifiedFileReader<F, M>, FsverityError> {
let mut buf = [0u8; CHUNK_SIZE as usize];
@@ -157,12 +136,11 @@
}
}
let root_hash = Sha256Hasher::new()?.update(&buf[..])?.finalize()?;
- let formatted_digest = build_fsverity_formatted_digest(&root_hash, file_size)?;
- let valid = authenticator.verify(sig, &formatted_digest)?;
- if valid {
+ 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::BadSignature)
+ Err(FsverityError::InvalidDigest)
}
}
}
@@ -183,7 +161,6 @@
#[cfg(test)]
mod tests {
use super::*;
- use crate::auth::FakeAuthenticator;
use crate::file::ReadByChunk;
use anyhow::Result;
use authfs_fsverity_metadata::{parse_fsverity_metadata, FSVerityMetadata};
@@ -245,13 +222,11 @@
let file_reader = LocalFileReader::new(File::open(content_path)?)?;
let file_size = file_reader.len();
let metadata = parse_fsverity_metadata(File::open(metadata_path)?)?;
- let authenticator = FakeAuthenticator::always_succeed();
Ok((
VerifiedFileReader::new(
- &authenticator,
file_reader,
file_size,
- metadata.signature.clone().as_deref(),
+ &metadata.digest.clone(),
MerkleTreeReader { metadata },
)?,
file_size,
@@ -312,21 +287,4 @@
assert!(file_reader.read_chunk(last_index, &mut buf).is_ok());
Ok(())
}
-
- #[test]
- fn invalid_signature() -> Result<()> {
- let authenticator = FakeAuthenticator::always_fail();
- let file_reader = LocalFileReader::new(File::open("testdata/input.4m")?)?;
- let file_size = file_reader.len();
- let metadata = parse_fsverity_metadata(File::open("testdata/input.4m.fsv_meta")?)?;
- assert!(VerifiedFileReader::new(
- &authenticator,
- file_reader,
- file_size,
- metadata.signature.clone().as_deref(),
- MerkleTreeReader { metadata },
- )
- .is_err());
- Ok(())
- }
}
diff --git a/authfs/src/main.rs b/authfs/src/main.rs
index 3561b8f..f664ca2 100644
--- a/authfs/src/main.rs
+++ b/authfs/src/main.rs
@@ -17,15 +17,20 @@
//! 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
-//! public key from a trusted party, this filesystem can still verify a (read-only) file signed by
-//! the trusted party 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.
+//! 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. A file configuration may include the
-//! source (e.g. remote file server), verification method (e.g. certificate for fs-verity
-//! verification, or no verification if expected to mount over dm-verity), and file ID. Regardless
-//! of the actual file name, the exposed file names through AuthFS are currently integer, e.g.
-//! /mountpoint/42.
+//! 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 log::error;
@@ -35,7 +40,6 @@
use std::path::{Path, PathBuf};
use structopt::StructOpt;
-mod auth;
mod common;
mod crypto;
mod file;
@@ -43,7 +47,6 @@
mod fsverity;
mod fusefs;
-use auth::FakeAuthenticator;
use file::{
Attr, EagerChunkReader, InMemoryDir, RemoteDirEditor, RemoteFileEditor, RemoteFileReader,
RemoteMerkleTreeReader,
@@ -69,8 +72,9 @@
/// A read-only remote file with integrity check. Can be multiple.
///
- /// For example, `--remote-ro-file 5:/path/to/cert` tells the filesystem to associate the
- /// file $MOUNTPOINT/5 with a remote FD 5, and need to be verified against the /path/to/cert.
+ /// 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.
#[structopt(long, parse(try_from_str = parse_remote_ro_file_option))]
remote_ro_file: Vec<OptionRemoteRoFile>,
@@ -123,9 +127,8 @@
/// ID to refer to the remote file.
remote_fd: i32,
- /// Certificate to verify the authenticity of the file's fs-verity signature.
- /// TODO(170494765): Implement PKCS#7 signature verification.
- _certificate_path: PathBuf,
+ /// Expected fs-verity digest (with sha256) for the remote file.
+ digest: String,
}
struct OptionRemoteRoDir {
@@ -145,10 +148,11 @@
if strs.len() != 2 {
bail!("Invalid option: {}", option);
}
- Ok(OptionRemoteRoFile {
- remote_fd: strs[0].parse::<i32>()?,
- _certificate_path: PathBuf::from(strs[1]),
- })
+ 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> {
@@ -163,20 +167,32 @@
})
}
+fn from_hex_string(s: &str) -> Result<Vec<u8>> {
+ if s.len() % 2 == 1 {
+ bail!("Incomplete hex string: {}", s);
+ } else {
+ let results = (0..s.len())
+ .step_by(2)
+ .map(|i| {
+ u8::from_str_radix(&s[i..i + 2], 16)
+ .map_err(|e| anyhow!("Cannot parse hex {}: {}", &s[i..i + 2], e))
+ })
+ .collect::<Result<Vec<_>>>();
+ Ok(results?)
+ }
+}
+
fn new_remote_verified_file_entry(
service: file::VirtFdService,
remote_fd: i32,
+ expected_digest: &str,
file_size: u64,
) -> Result<AuthFsEntry> {
- let signature = service.readFsveritySignature(remote_fd).ok();
-
- let authenticator = FakeAuthenticator::always_succeed();
Ok(AuthFsEntry::VerifiedReadonly {
reader: VerifiedFileReader::new(
- &authenticator,
RemoteFileReader::new(service.clone(), remote_fd),
file_size,
- signature.as_deref(),
+ &from_hex_string(expected_digest)?,
EagerChunkReader::new(
RemoteMerkleTreeReader::new(service.clone(), remote_fd),
merkle_tree_size(file_size),
@@ -226,6 +242,7 @@
new_remote_verified_file_entry(
service.clone(),
config.remote_fd,
+ &config.digest,
service.getFileSize(config.remote_fd)?.try_into()?,
)?,
)?;
@@ -268,7 +285,11 @@
// 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 in proto.digests.keys() {
+ 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)
@@ -279,9 +300,20 @@
config.remote_dir_fd,
Path::new(remote_path_str),
)?;
- let file_size = service.getFileSize(remote_file.get_remote_fd())?.try_into()?;
- // TODO(206869687): Switch to VerifiedReadonly
- AuthFsEntry::UnverifiedReadonly { reader: remote_file, file_size }
+ let remote_fd = remote_file.get_remote_fd();
+ let file_size = service.getFileSize(remote_fd)?.try_into()?;
+ AuthFsEntry::VerifiedReadonly {
+ reader: VerifiedFileReader::new(
+ remote_file,
+ file_size,
+ &digest.digest,
+ EagerChunkReader::new(
+ RemoteMerkleTreeReader::new(service.clone(), remote_fd),
+ merkle_tree_size(file_size),
+ )?,
+ )?,
+ file_size,
+ }
};
authfs.add_entry_at_ro_dir_by_path(dir_root_inode, Path::new(path_str), file_entry)?;
}
@@ -316,3 +348,18 @@
std::process::exit(1);
}
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn parse_hex_string() {
+ assert_eq!(from_hex_string("deadbeef").unwrap(), vec![0xde, 0xad, 0xbe, 0xef]);
+ assert_eq!(from_hex_string("DEADBEEF").unwrap(), vec![0xde, 0xad, 0xbe, 0xef]);
+ assert_eq!(from_hex_string("").unwrap(), Vec::<u8>::new());
+
+ assert!(from_hex_string("deadbee").is_err());
+ assert!(from_hex_string("X").is_err());
+ }
+}
diff --git a/authfs/tests/java/src/com/android/fs/AuthFsHostTest.java b/authfs/tests/java/src/com/android/fs/AuthFsHostTest.java
index ef544b2..7df3b3e 100644
--- a/authfs/tests/java/src/com/android/fs/AuthFsHostTest.java
+++ b/authfs/tests/java/src/com/android/fs/AuthFsHostTest.java
@@ -70,12 +70,12 @@
/** Path to authfs on Microdroid */
private static final String AUTHFS_BIN = "/system/bin/authfs";
- /** Idsig paths to be created for each APK in the "extra_apks" of vm_config.json. */
+ /** Idsig paths to be created for each APK in the "extra_apks" of vm_config_extra_apk.json. */
private static final String[] EXTRA_IDSIG_PATHS = new String[] {
TEST_DIR + "BuildManifest.apk.idsig",
};
- /** Build manifest path in the VM. 0 is the index of extra_apks in vm_config.json. */
+ /** Build manifest path in the VM. 0 is the index of extra_apks in vm_config_extra_apk.json. */
private static final String BUILD_MANIFEST_PATH = "/mnt/extra-apk/0/assets/build_manifest.pb";
/** Plenty of time for authfs to get ready */
@@ -84,6 +84,14 @@
/** FUSE's magic from statfs(2) */
private static final String FUSE_SUPER_MAGIC_HEX = "65735546";
+ // fs-verity digest (sha256) of testdata/input.{4k, 4k1, 4m}
+ private static final String DIGEST_4K =
+ "sha256-9828cd65f4744d6adda216d3a63d8205375be485bfa261b3b8153d3358f5a576";
+ private static final String DIGEST_4K1 =
+ "sha256-3c70dcd4685ed256ebf1ef116c12e472f35b5017eaca422c0483dadd7d0b5a9f";
+ private static final String DIGEST_4M =
+ "sha256-f18a268d565348fb4bbf11f10480b198f98f2922eb711de149857b3cecf98a8d";
+
private static final int VMADDR_CID_HOST = 2;
private static CommandRunner sAndroid;
@@ -177,7 +185,7 @@
"--ro-fds 3:4 --ro-fds 6");
runAuthFsOnMicrodroid(
- "--remote-ro-file-unverified 6 --remote-ro-file 3:cert.der --cid "
+ "--remote-ro-file-unverified 6 --remote-ro-file 3:" + DIGEST_4M + " --cid "
+ VMADDR_CID_HOST);
// Action
@@ -201,7 +209,8 @@
+ " 6:input.4k1 --open-ro 7:input.4k1.fsv_meta",
"--ro-fds 3:4 --ro-fds 6:7");
runAuthFsOnMicrodroid(
- "--remote-ro-file 3:cert.der --remote-ro-file 6:cert.der --cid " + VMADDR_CID_HOST);
+ "--remote-ro-file 3:" + DIGEST_4K + " --remote-ro-file 6:" + DIGEST_4K1 + " --cid "
+ + VMADDR_CID_HOST);
// Action
String actualHash4k = computeFileHashOnMicrodroid(MOUNT_DIR + "/3");
@@ -221,7 +230,7 @@
runFdServerOnAndroid(
"--open-ro 3:input.4m --open-ro 4:input.4m.fsv_meta.bad_merkle",
"--ro-fds 3:4");
- runAuthFsOnMicrodroid("--remote-ro-file 3:cert.der --cid " + VMADDR_CID_HOST);
+ runAuthFsOnMicrodroid("--remote-ro-file 3:" + DIGEST_4M + " --cid " + VMADDR_CID_HOST);
// Verify
assertFalse(copyFileOnMicrodroid(MOUNT_DIR + "/3", "/dev/null"));