[avb] Add library libpvmfw_avb_nostd and test it in presubmit
Bug: 237373557
Test: m pvmfw_img && atest libpvmfw_avb.test
Change-Id: I80c19d4081b97ae57d0b50c04d3368b417a6411a
diff --git a/TEST_MAPPING b/TEST_MAPPING
index dd81738..321dbf4 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -58,6 +58,9 @@
"path": "packages/modules/Virtualization/authfs"
},
{
+ "path": "packages/modules/Virtualization/pvmfw"
+ },
+ {
"path": "packages/modules/Virtualization/rialto"
},
{
diff --git a/libs/avb/Android.bp b/libs/avb/Android.bp
index 8bac942..436f672 100644
--- a/libs/avb/Android.bp
+++ b/libs/avb/Android.bp
@@ -37,18 +37,3 @@
clippy_lints: "none",
lints: "none",
}
-
-rust_library_rlib {
- name: "libavb_nostd",
- crate_name: "avb",
- srcs: ["src/lib.rs"],
- no_stdlibs: true,
- prefer_rlib: true,
- stdlibs: [
- "libcore.rust_sysroot",
- ],
- rustlibs: [
- "libavb_bindgen",
- "liblog_rust_nostd",
- ],
-}
diff --git a/pvmfw/Android.bp b/pvmfw/Android.bp
index 318c7fe..5ed7bd6 100644
--- a/pvmfw/Android.bp
+++ b/pvmfw/Android.bp
@@ -13,11 +13,11 @@
],
rustlibs: [
"libaarch64_paging",
- "libavb_nostd",
"libbuddy_system_allocator",
"libdice_nostd",
"liblibfdt",
"liblog_rust_nostd",
+ "libpvmfw_avb_nostd",
"libpvmfw_embedded_key",
"libtinyvec_nostd",
"libvirtio_drivers",
diff --git a/pvmfw/TEST_MAPPING b/pvmfw/TEST_MAPPING
new file mode 100644
index 0000000..8a2d352
--- /dev/null
+++ b/pvmfw/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+ "avf-presubmit" : [
+ {
+ "name" : "libpvmfw_avb.test"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/pvmfw/avb/Android.bp b/pvmfw/avb/Android.bp
new file mode 100644
index 0000000..65259a5
--- /dev/null
+++ b/pvmfw/avb/Android.bp
@@ -0,0 +1,28 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+rust_defaults {
+ name: "libpvmfw_avb_nostd_defaults",
+ crate_name: "pvmfw_avb",
+ srcs: ["src/lib.rs"],
+ prefer_rlib: true,
+ rustlibs: [
+ "libavb_bindgen",
+ ],
+}
+
+rust_library_rlib {
+ name: "libpvmfw_avb_nostd",
+ defaults: ["libpvmfw_avb_nostd_defaults"],
+ no_stdlibs: true,
+ stdlibs: [
+ "libcore.rust_sysroot",
+ ],
+}
+
+rust_test {
+ name: "libpvmfw_avb.test",
+ defaults: ["libpvmfw_avb_nostd_defaults"],
+ test_suites: ["general-tests"],
+}
diff --git a/libs/avb/src/lib.rs b/pvmfw/avb/src/lib.rs
similarity index 77%
rename from libs/avb/src/lib.rs
rename to pvmfw/avb/src/lib.rs
index 21b7d2a..eb1f918 100644
--- a/libs/avb/src/lib.rs
+++ b/pvmfw/avb/src/lib.rs
@@ -12,12 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-//! This module regroups the rust API for libavb.
+//! A library implementing the payload verification for pvmfw with libavb
-#![no_std]
+#![cfg_attr(not(test), no_std)]
-extern crate alloc;
+mod verify;
-mod ops;
-
-pub use ops::{verify_image, AvbImageVerifyError};
+pub use verify::{verify_payload, AvbImageVerifyError};
diff --git a/libs/avb/src/ops.rs b/pvmfw/avb/src/verify.rs
similarity index 60%
rename from libs/avb/src/ops.rs
rename to pvmfw/avb/src/verify.rs
index 8eb67f4..7f3ba3d 100644
--- a/libs/avb/src/ops.rs
+++ b/pvmfw/avb/src/verify.rs
@@ -12,20 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-//! This module regroups methods related to AvbOps.
+//! This module handles the pvmfw payload verification.
-#![warn(unsafe_op_in_unsafe_fn)]
-// TODO(b/256148034): Remove this when the feature is code complete.
-#![allow(dead_code)]
-#![allow(unused_imports)]
-
-use alloc::ffi::CString;
-use avb_bindgen::{avb_slot_verify, AvbHashtreeErrorMode, AvbSlotVerifyFlags, AvbSlotVerifyResult};
+use avb_bindgen::AvbSlotVerifyResult;
use core::fmt;
-use log::debug;
/// Error code from AVB image verification.
-#[derive(Clone, Copy, Debug)]
+#[derive(Clone, Debug)]
pub enum AvbImageVerifyError {
/// AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT
InvalidArgument,
@@ -45,6 +38,24 @@
Verification,
}
+impl fmt::Display for AvbImageVerifyError {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ Self::InvalidArgument => write!(f, "Invalid parameters."),
+ Self::InvalidMetadata => write!(f, "Invalid metadata."),
+ Self::Io => write!(f, "I/O error while trying to load data or get a rollback index."),
+ Self::Oom => write!(f, "Unable to allocate memory."),
+ Self::PublicKeyRejected => write!(f, "Public key rejected or data not signed."),
+ Self::RollbackIndex => write!(f, "Rollback index is less than its stored value."),
+ Self::UnsupportedVersion => write!(
+ f,
+ "Some of the metadata requires a newer version of libavb than what is in use."
+ ),
+ Self::Verification => write!(f, "Data does not verify."),
+ }
+ }
+}
+
fn to_avb_verify_result(result: AvbSlotVerifyResult) -> Result<(), AvbImageVerifyError> {
match result {
AvbSlotVerifyResult::AVB_SLOT_VERIFY_RESULT_OK => Ok(()),
@@ -71,63 +82,31 @@
}
}
-impl fmt::Display for AvbImageVerifyError {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- match self {
- Self::InvalidArgument => write!(f, "Invalid parameters."),
- Self::InvalidMetadata => write!(f, "Invalid metadata."),
- Self::Io => write!(f, "I/O error while trying to load data or get a rollback index."),
- Self::Oom => write!(f, "Unable to allocate memory."),
- Self::PublicKeyRejected => write!(
- f,
- "Everything is verified correctly out but the public key is not accepted. \
- This includes the case where integrity data is not signed."
- ),
- Self::RollbackIndex => write!(f, "Rollback index is less than its stored value."),
- Self::UnsupportedVersion => write!(
- f,
- "Some of the metadata requires a newer version of libavb than what is in use."
- ),
- Self::Verification => write!(f, "Data does not verify."),
- }
- }
+/// Verifies the payload (signed kernel + initrd) against the trusted public key.
+pub fn verify_payload(_public_key: &[u8]) -> Result<(), AvbImageVerifyError> {
+ // TODO(b/256148034): Verify the kernel image with avb_slot_verify()
+ // let result = unsafe {
+ // avb_slot_verify(
+ // &mut avb_ops,
+ // requested_partitions.as_ptr(),
+ // ab_suffix.as_ptr(),
+ // flags,
+ // hashtree_error_mode,
+ // null_mut(),
+ // )
+ // };
+ let result = AvbSlotVerifyResult::AVB_SLOT_VERIFY_RESULT_OK;
+ to_avb_verify_result(result)
}
-/// Verifies that for the given image:
-/// - The given public key is acceptable.
-/// - The VBMeta struct is valid.
-/// - The partitions of the image match the descriptors of the verified VBMeta struct.
-/// Returns Ok if everything is verified correctly and the public key is accepted.
-pub fn verify_image(_image: &[u8], _public_key: &[u8]) -> Result<(), AvbImageVerifyError> {
- // TODO(b/256148034): Call verify_slot() from pvmfw.
- AvbOps::new().verify_slot()
-}
+#[cfg(test)]
+mod tests {
+ use super::*;
-/// TODO(b/256148034): Make AvbOps a rust wrapper of avb_bindgen::AvbOps using foreign_types.
-struct AvbOps {}
-
-impl AvbOps {
- fn new() -> Self {
- AvbOps {}
- }
-
- fn verify_slot(&mut self) -> Result<(), AvbImageVerifyError> {
- let flags = AvbSlotVerifyFlags::AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION;
- let hashtree_error_mode = AvbHashtreeErrorMode::AVB_HASHTREE_ERROR_MODE_EIO;
- debug!("flags: {:?}", flags);
- debug!("hashtree_error_mode: {:?}", hashtree_error_mode);
- // TODO(b/256148034): Verify the kernel image with avb_slot_verify()
- // let result = unsafe {
- // avb_slot_verify(
- // self.as_ptr(),
- // requested_partitions.as_ptr(),
- // ab_suffix.as_ptr(),
- // flags,
- // hashtree_error_mode,
- // &image.as_ptr(),
- // )
- // };
- let result = AvbSlotVerifyResult::AVB_SLOT_VERIFY_RESULT_OK;
- to_avb_verify_result(result)
+ // TODO(b/256148034): Test verification succeeds with valid payload later.
+ #[test]
+ fn verification_succeeds_with_placeholder_input() {
+ let fake_public_key = [0u8; 2];
+ assert!(verify_payload(&fake_public_key).is_ok());
}
}
diff --git a/pvmfw/src/main.rs b/pvmfw/src/main.rs
index 79b6f57..039e674 100644
--- a/pvmfw/src/main.rs
+++ b/pvmfw/src/main.rs
@@ -38,10 +38,10 @@
memory::MemoryTracker,
pci::{allocate_all_virtio_bars, PciError, PciInfo, PciMemory32Allocator},
};
-use ::avb::verify_image;
use dice::bcc;
use libfdt::Fdt;
use log::{debug, error, info, trace};
+use pvmfw_avb::verify_payload;
fn main(
fdt: &Fdt,
@@ -71,7 +71,7 @@
let mut pci_root = unsafe { pci_info.make_pci_root() };
allocate_all_virtio_bars(&mut pci_root, &mut bar_allocator).map_err(handle_pci_error)?;
- verify_image(signed_kernel, PUBLIC_KEY).map_err(|e| {
+ verify_payload(PUBLIC_KEY).map_err(|e| {
error!("Failed to verify the payload: {e}");
RebootReason::PayloadVerificationError
})?;