Let protected VM be able to run with microdroid vendor partition.

Warning: This patch leads temporary solution. For the long-term
solution, we should bring vendor public key from pvmfw configuration
ata, not from fdt given by the host.

This change will enable dm-verity process of microdroid vendor partition
for protected VM as well. However, we should keep mind that vendor
public key itself won't be trustable before bringing vendor public key
from ABL.

Bug: 285855885
Test: adb shell /apex/com.android.virt/bin/vm run-microdroid --vendor /vendor/etc/avf/microdroid/microdroid_vendor.img --protected

Change-Id: I620f4e39c599514c472aae889b57b3579d937f72
diff --git a/pvmfw/src/fdt.rs b/pvmfw/src/fdt.rs
index 4fe2c34..5fbc767 100644
--- a/pvmfw/src/fdt.rs
+++ b/pvmfw/src/fdt.rs
@@ -201,6 +201,22 @@
     Ok(())
 }
 
+fn read_vendor_public_key_from(fdt: &Fdt) -> libfdt::Result<Option<Vec<u8>>> {
+    if let Some(avf_node) = fdt.node(cstr!("/avf"))? {
+        if let Some(vendor_public_key) = avf_node.getprop(cstr!("vendor_public_key"))? {
+            return Ok(Some(vendor_public_key.to_vec()));
+        }
+    }
+    Ok(None)
+}
+
+fn patch_vendor_public_key(fdt: &mut Fdt, vendor_public_key: &[u8]) -> libfdt::Result<()> {
+    let mut root_node = fdt.root_mut()?;
+    let mut avf_node = root_node.add_subnode(cstr!("/avf"))?;
+    avf_node.setprop(cstr!("vendor_public_key"), vendor_public_key)?;
+    Ok(())
+}
+
 #[derive(Debug)]
 struct PciInfo {
     ranges: [PciAddrRange; 2],
@@ -593,6 +609,7 @@
     serial_info: SerialInfo,
     pub swiotlb_info: SwiotlbInfo,
     device_assignment: Option<DeviceAssignmentInfo>,
+    vendor_public_key: Option<Vec<u8>>,
 }
 
 impl DeviceTreeInfo {
@@ -701,6 +718,18 @@
         None => None,
     };
 
+    // TODO(b/285854379) : A temporary solution lives. This is for enabling
+    // microdroid vendor partition for non-protected VM as well. When passing
+    // DT path containing vendor_public_key via fstab, init stage will check
+    // if vendor_public_key exists in the init stage, regardless the protection.
+    // Adding this temporary solution will prevent fatal in init stage for
+    // protected VM. However, this data is not trustable without validating
+    // with vendor public key value comes from ABL.
+    let vendor_public_key = read_vendor_public_key_from(fdt).map_err(|e| {
+        error!("Failed to read vendor_public_key from DT: {e}");
+        RebootReason::InvalidFdt
+    })?;
+
     Ok(DeviceTreeInfo {
         kernel_range,
         initrd_range,
@@ -711,6 +740,7 @@
         serial_info,
         swiotlb_info,
         device_assignment,
+        vendor_public_key,
     })
 }
 
@@ -768,6 +798,12 @@
             RebootReason::InvalidFdt
         })?;
     }
+    if let Some(vendor_public_key) = &info.vendor_public_key {
+        patch_vendor_public_key(fdt, vendor_public_key).map_err(|e| {
+            error!("Failed to patch vendor_public_key to DT: {e}");
+            RebootReason::InvalidFdt
+        })?;
+    }
 
     fdt.pack().map_err(|e| {
         error!("Failed to pack DT after patching: {e}");