Merge "Migrate pkvm_perf_test.py test_compilation_in_android function to AOSP"
diff --git a/libs/apexutil/src/lib.rs b/libs/apexutil/src/lib.rs
index 63b09de..1183aea 100644
--- a/libs/apexutil/src/lib.rs
+++ b/libs/apexutil/src/lib.rs
@@ -93,6 +93,19 @@
Err(ApexParseError::DescriptorNotHashtree)
}
+/// Gets the hash of the payload's verified VBMeta image data.
+pub fn get_payload_vbmeta_image_hash(path: &str) -> Result<Vec<u8>, ApexVerificationError> {
+ let apex_file = File::open(path).map_err(ApexParseError::Io)?;
+ let (_, offset, size) = get_public_key_and_image_info(&apex_file)?;
+ let vbmeta = VbMetaImage::verify_reader_region(apex_file, offset, size)?;
+ Ok(vbmeta.hash().ok_or(ApexVerificationError::ApexPubkeyMistmatch)?.to_vec())
+}
+
+/// Converts the buffer to a Hex String
+pub fn to_hex_string(buf: &[u8]) -> String {
+ buf.iter().map(|b| format!("{:02x}", b)).collect()
+}
+
fn get_public_key_and_image_info(apex_file: &File) -> Result<(Vec<u8>, u64, u64), ApexParseError> {
let mut z = ZipArchive::new(apex_file).map_err(|err| match err {
ZipError::Io(err) => ApexParseError::Io(err),
@@ -130,9 +143,7 @@
#[cfg(test)]
mod tests {
use super::*;
- fn to_hex_string(buf: &[u8]) -> String {
- buf.iter().map(|b| format!("{:02x}", b)).collect()
- }
+
#[test]
fn test_open_apex() {
let res = verify("tests/data/test.apex").unwrap();
@@ -141,4 +152,13 @@
"fe11ab17da0a3a738b54bdc3a13f6139cbdf91ec32f001f8d4bbbf8938e04e39"
);
}
+
+ #[test]
+ fn test_payload_vbmeta_image_hash() {
+ let result = get_payload_vbmeta_image_hash("tests/data/test.apex").unwrap();
+ assert_eq!(
+ to_hex_string(&result),
+ "296e32a76544de9da01713e471403ab4667705ad527bb4f1fac0cf61e7ce122d"
+ );
+ }
}
diff --git a/libs/apkverify/Android.bp b/libs/apkverify/Android.bp
index d45a77f..2d58bb0 100644
--- a/libs/apkverify/Android.bp
+++ b/libs/apkverify/Android.bp
@@ -14,7 +14,6 @@
"libbytes",
"liblog_rust",
"libopenssl",
- "libx509_parser",
"libzip",
],
}
diff --git a/libs/apkverify/src/v3.rs b/libs/apkverify/src/v3.rs
index 96ca7bc..0c20a2e 100644
--- a/libs/apkverify/src/v3.rs
+++ b/libs/apkverify/src/v3.rs
@@ -25,11 +25,11 @@
use openssl::pkey::{self, PKey};
use openssl::rsa::Padding;
use openssl::sign::Verifier;
+use openssl::x509::X509;
use std::fs::File;
use std::io::{Read, Seek};
use std::ops::Range;
use std::path::Path;
-use x509_parser::{parse_x509_certificate, prelude::FromDer, x509::SubjectPublicKeyInfo};
use crate::bytes_ext::{BytesExt, LengthPrefixed, ReadFromBytes};
use crate::sigutil::*;
@@ -168,8 +168,8 @@
// 2. Verify the corresponding signature from signatures against signed data using public key.
// (It is now safe to parse signed data.)
- let (_, key_info) = SubjectPublicKeyInfo::from_der(self.public_key.as_ref())?;
- verify_signed_data(&self.signed_data, strongest, &key_info)?;
+ let public_key = PKey::public_key_from_der(self.public_key.as_ref())?;
+ verify_signed_data(&self.signed_data, strongest, &public_key)?;
// It is now safe to parse signed data.
let signed_data: SignedData = self.signed_data.slice(..).read()?;
@@ -209,11 +209,11 @@
);
}
- // 7. Verify that SubjectPublicKeyInfo of the first certificate of certificates is identical
+ // 7. Verify that public key of the first certificate of certificates is identical
// to public key.
let cert = signed_data.certificates.first().context("No certificates listed")?;
- let (_, cert) = parse_x509_certificate(cert.as_ref())?;
- if cert.tbs_certificate.subject_pki != key_info {
+ let cert = X509::from_der(cert.as_ref())?;
+ if !cert.public_key()?.public_eq(&public_key) {
bail!("Public key mismatch between certificate and signature record");
}
@@ -222,11 +222,7 @@
}
}
-fn verify_signed_data(
- data: &Bytes,
- signature: &Signature,
- key_info: &SubjectPublicKeyInfo,
-) -> Result<()> {
+fn verify_signed_data(data: &Bytes, signature: &Signature, key: &PKey<pkey::Public>) -> Result<()> {
let (pkey_id, padding, digest) = match signature.signature_algorithm_id {
SIGNATURE_RSA_PSS_WITH_SHA256 => {
(pkey::Id::RSA, Padding::PKCS1_PSS, MessageDigest::sha256())
@@ -254,9 +250,8 @@
}
_ => bail!("Unsupported signature algorithm: {:#x}", signature.signature_algorithm_id),
};
- let key = PKey::public_key_from_der(key_info.raw)?;
ensure!(key.id() == pkey_id, "Public key has the wrong ID");
- let mut verifier = Verifier::new(digest, &key)?;
+ let mut verifier = Verifier::new(digest, key)?;
if pkey_id == pkey::Id::RSA {
verifier.set_rsa_padding(padding)?;
}
diff --git a/libs/vbmeta/src/lib.rs b/libs/vbmeta/src/lib.rs
index 2d3463c..887844c 100644
--- a/libs/vbmeta/src/lib.rs
+++ b/libs/vbmeta/src/lib.rs
@@ -138,6 +138,18 @@
Some(&self.data[begin..end])
}
+ /// Get the hash of the verified data in the VBMeta image from the authentication block. If the
+ /// image was not signed, there might not be a hash and, if there is, it's not known to be
+ /// correct.
+ pub fn hash(&self) -> Option<&[u8]> {
+ if self.header.algorithm_type == AvbAlgorithmType_AVB_ALGORITHM_TYPE_NONE {
+ return None;
+ }
+ let begin = size_of::<AvbVBMetaImageHeader>() + self.header.hash_offset as usize;
+ let end = begin + self.header.hash_size as usize;
+ Some(&self.data[begin..end])
+ }
+
/// Get the descriptors of the VBMeta image.
pub fn descriptors(&self) -> Result<Descriptors<'_>, VbMetaImageParseError> {
Descriptors::from_image(&self.data)
diff --git a/microdroid/kdump/kexec.c b/microdroid/kdump/kexec.c
index 65ea0ea..8d88951 100644
--- a/microdroid/kdump/kexec.c
+++ b/microdroid/kdump/kexec.c
@@ -27,6 +27,17 @@
#include <sys/types.h>
#include <unistd.h>
+#if defined(__aarch64__)
+#define EARLYCON "earlycon=uart8250,mmio,0x3f8"
+#elif defined(__x86_64__)
+#define EARLYCON "earlycon=uart8250,io,0x3f8"
+#endif
+
+static const char *KERNEL = "/system/etc/microdroid_crashdump_kernel";
+static const char *INITRD = "/system/etc/microdroid_crashdump_initrd.img";
+static const char *CMDLINE = "1 panic=-1 rdinit=/bin/crashdump nr_cpus=1 reset_devices "
+ "console=hvc0 " EARLYCON;
+
static int open_checked(const char* path) {
int fd = open(path, O_RDONLY);
if (fd == -1) {
@@ -36,20 +47,11 @@
return fd;
}
-int main(int argc, const char* argv[]) {
- if (argc != 4) {
- fprintf(stderr, "Usage: %s <kernel> <initrd> <commandline>\n", argv[0]);
- return 1;
- }
+int main() {
+ unsigned long cmdline_len = strlen(CMDLINE) + 1; // include null terminator, otherwise EINVAL
- // TODO(b/238272206): consider harding these
- const char* kernel = argv[1];
- const char* initrd = argv[2];
- const char* cmdline = argv[3];
- unsigned long cmdline_len = strlen(cmdline) + 1; // include null terminator, otherwise EINVAL
-
- if (syscall(SYS_kexec_file_load, open_checked(kernel), open_checked(initrd), cmdline_len,
- cmdline, KEXEC_FILE_ON_CRASH) == -1) {
+ if (syscall(SYS_kexec_file_load, open_checked(KERNEL), open_checked(INITRD), cmdline_len,
+ CMDLINE, KEXEC_FILE_ON_CRASH) == -1) {
fprintf(stderr, "Failed to load panic kernel: %s\n", strerror(errno));
return 1;
}