Merge "[authfs][refactoring] Use crate hex to decode hex string" into main
diff --git a/libs/bssl/src/evp.rs b/libs/bssl/src/evp.rs
index 30bfc21..5362925 100644
--- a/libs/bssl/src/evp.rs
+++ b/libs/bssl/src/evp.rs
@@ -26,14 +26,14 @@
 use core::ptr::NonNull;
 
 /// Wrapper of an `EVP_PKEY` object, representing a public or private key.
-pub struct EvpPKey {
+pub struct PKey {
     pkey: NonNull<EVP_PKEY>,
     /// Since this struct owns the inner key, the inner key remains valid as
     /// long as the pointer to `EVP_PKEY` is valid.
     _inner_key: EcKey,
 }
 
-impl Drop for EvpPKey {
+impl Drop for PKey {
     fn drop(&mut self) {
         // SAFETY: It is safe because `EVP_PKEY` has been allocated by BoringSSL and isn't
         // used after this.
@@ -48,7 +48,7 @@
     NonNull::new(key).ok_or(to_call_failed_error(ApiName::EVP_PKEY_new))
 }
 
-impl TryFrom<EcKey> for EvpPKey {
+impl TryFrom<EcKey> for PKey {
     type Error = bssl_avf_error::Error;
 
     fn try_from(key: EcKey) -> Result<Self> {
@@ -64,7 +64,7 @@
     }
 }
 
-impl EvpPKey {
+impl PKey {
     /// Returns a DER-encoded SubjectPublicKeyInfo structure as specified
     /// in RFC 5280 s4.1.2.7:
     ///
diff --git a/libs/bssl/src/lib.rs b/libs/bssl/src/lib.rs
index e378386..25b0163 100644
--- a/libs/bssl/src/lib.rs
+++ b/libs/bssl/src/lib.rs
@@ -38,7 +38,7 @@
 pub use cbs::Cbs;
 pub use digest::Digester;
 pub use ec_key::{EcKey, ZVec};
-pub use evp::EvpPKey;
+pub use evp::PKey;
 pub use hkdf::hkdf;
 pub use hmac::hmac_sha256;
 pub use rand::rand_bytes;
diff --git a/libs/bssl/tests/eckey_test.rs b/libs/bssl/tests/eckey_test.rs
index 2eb908a..4f0697c 100644
--- a/libs/bssl/tests/eckey_test.rs
+++ b/libs/bssl/tests/eckey_test.rs
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-use bssl_avf::{sha256, ApiName, EcKey, EcdsaError, Error, EvpPKey, Result};
+use bssl_avf::{sha256, ApiName, EcKey, EcdsaError, Error, PKey, Result};
 use coset::CborSerializable;
 use spki::{
     der::{AnyRef, Decode},
@@ -43,7 +43,7 @@
 fn subject_public_key_info_serialization() -> Result<()> {
     let mut ec_key = EcKey::new_p256()?;
     ec_key.generate_key()?;
-    let pkey: EvpPKey = ec_key.try_into()?;
+    let pkey: PKey = ec_key.try_into()?;
     let subject_public_key_info = pkey.subject_public_key_info()?;
 
     let subject_public_key_info = SubjectPublicKeyInfo::from_der(&subject_public_key_info).unwrap();
diff --git a/pvmfw/Android.bp b/pvmfw/Android.bp
index f49bbce..c6befb4 100644
--- a/pvmfw/Android.bp
+++ b/pvmfw/Android.bp
@@ -34,7 +34,6 @@
         "libvmbase",
         "libzerocopy_nostd",
         "libzeroize_nostd",
-        "libspin_nostd",
     ],
 }
 
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}");
diff --git a/rialto/tests/test.rs b/rialto/tests/test.rs
index 0260773..c1a8394 100644
--- a/rialto/tests/test.rs
+++ b/rialto/tests/test.rs
@@ -22,7 +22,7 @@
     binder::{ParcelFileDescriptor, ProcessState},
 };
 use anyhow::{bail, Context, Result};
-use bssl_avf::{sha256, EcKey, EvpPKey};
+use bssl_avf::{sha256, EcKey, PKey};
 use ciborium::value::Value;
 use client_vm_csr::generate_attestation_key_and_csr;
 use coset::{CborSerializable, CoseMac0, CoseSign};
@@ -246,7 +246,7 @@
         cose_sign.payload.as_ref().and_then(|v| CsrPayload::from_cbor_slice(v).ok()).unwrap();
     let subject_public_key = EcKey::from_cose_public_key(&csr_payload.public_key).unwrap();
     let expected_spki_data =
-        EvpPKey::try_from(subject_public_key).unwrap().subject_public_key_info().unwrap();
+        PKey::try_from(subject_public_key).unwrap().subject_public_key_info().unwrap();
     let (remaining, expected_spki) = SubjectPublicKeyInfo::from_der(&expected_spki_data)?;
     assert!(remaining.is_empty());
     assert_eq!(&expected_spki, cert.public_key());
diff --git a/service_vm/requests/src/client_vm.rs b/service_vm/requests/src/client_vm.rs
index bb92f4a..ddf230b 100644
--- a/service_vm/requests/src/client_vm.rs
+++ b/service_vm/requests/src/client_vm.rs
@@ -19,7 +19,7 @@
 use crate::dice::{validate_client_vm_dice_chain_prefix_match, ClientVmDiceChain};
 use crate::keyblob::decrypt_private_key;
 use alloc::vec::Vec;
-use bssl_avf::{rand_bytes, sha256, EcKey, EvpPKey};
+use bssl_avf::{rand_bytes, sha256, EcKey, PKey};
 use core::result;
 use coset::{CborSerializable, CoseSign};
 use der::{Decode, Encode};
@@ -66,7 +66,7 @@
     cose_sign.verify_signature(ATTESTATION_KEY_SIGNATURE_INDEX, aad, |signature, message| {
         ecdsa_verify(&ec_public_key, signature, message)
     })?;
-    let subject_public_key_info = EvpPKey::try_from(ec_public_key)?.subject_public_key_info()?;
+    let subject_public_key_info = PKey::try_from(ec_public_key)?.subject_public_key_info()?;
 
     // Builds the TBSCertificate.
     // The serial number can be up to 20 bytes according to RFC5280 s4.1.2.2.