Merge "[fdt] Refactor read_serial_info_from in pvmfw with first_reg()" into main
diff --git a/libs/service_vm_comm/Android.bp b/libs/service_vm_comm/Android.bp
index cdb8fc3..9bce2f4 100644
--- a/libs/service_vm_comm/Android.bp
+++ b/libs/service_vm_comm/Android.bp
@@ -21,6 +21,8 @@
"libcore.rust_sysroot",
],
rustlibs: [
+ "libcoset_nostd",
+ "liblog_rust_nostd",
"libserde_nostd",
],
}
@@ -29,6 +31,8 @@
name: "libservice_vm_comm",
defaults: ["libservice_vm_comm_defaults"],
rustlibs: [
+ "libcoset",
+ "liblog_rust",
"libserde",
],
features: [
diff --git a/libs/service_vm_comm/src/lib.rs b/libs/service_vm_comm/src/lib.rs
index ca97ca1..d8f7bd7 100644
--- a/libs/service_vm_comm/src/lib.rs
+++ b/libs/service_vm_comm/src/lib.rs
@@ -23,6 +23,7 @@
mod vsock;
pub use message::{
- EcdsaP256KeyPair, GenerateCertificateRequestParams, Request, Response, ServiceVmRequest,
+ EcdsaP256KeyPair, GenerateCertificateRequestParams, Request, RequestProcessingError, Response,
+ ServiceVmRequest,
};
pub use vsock::VmType;
diff --git a/libs/service_vm_comm/src/message.rs b/libs/service_vm_comm/src/message.rs
index 80956cb..407c5e5 100644
--- a/libs/service_vm_comm/src/message.rs
+++ b/libs/service_vm_comm/src/message.rs
@@ -15,8 +15,10 @@
//! This module contains the requests and responses definitions exchanged
//! between the host and the service VM.
+use alloc::string::String;
use alloc::vec::Vec;
-
+use core::fmt;
+use log::error;
use serde::{Deserialize, Serialize};
type MacedPublicKey = Vec<u8>;
@@ -64,6 +66,41 @@
/// Returns a CBOR Certificate Signing Request (Csr) serialized into a byte array.
GenerateCertificateRequest(Vec<u8>),
+
+ /// Encountered an error during the request processing.
+ Err(RequestProcessingError),
+}
+
+/// Errors related to request processing.
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+pub enum RequestProcessingError {
+ /// Failed to invoke a BoringSSL API.
+ BoringSSLCallFailed(String),
+
+ /// An error happened during the interaction with coset.
+ CosetError,
+
+ /// Any key to sign lacks a valid MAC. Maps to `STATUS_INVALID_MAC`.
+ InvalidMac,
+}
+
+impl fmt::Display for RequestProcessingError {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ Self::BoringSSLCallFailed(api_name) => {
+ write!(f, "Failed to invoke a BoringSSL API: {api_name}")
+ }
+ Self::CosetError => write!(f, "Encountered an error with coset"),
+ Self::InvalidMac => write!(f, "A key to sign lacks a valid MAC."),
+ }
+ }
+}
+
+impl From<coset::CoseError> for RequestProcessingError {
+ fn from(e: coset::CoseError) -> Self {
+ error!("Coset error: {e}");
+ Self::CosetError
+ }
}
/// Represents the params passed to GenerateCertificateRequest
diff --git a/rialto/src/error.rs b/rialto/src/error.rs
index 911cb9b..d2bdbbe 100644
--- a/rialto/src/error.rs
+++ b/rialto/src/error.rs
@@ -20,6 +20,7 @@
use fdtpci::PciError;
use hyp::Error as HypervisorError;
use libfdt::FdtError;
+use service_vm_comm::RequestProcessingError;
use vmbase::{memory::MemoryTrackerError, virtio::pci};
pub type Result<T> = result::Result<T, Error>;
@@ -53,6 +54,8 @@
DeserializationFailed(CiboriumDeError),
/// Failed DICE operation.
DiceOperationFailed(DiceError),
+ /// Failed to process request.
+ RequestProcessingFailed(RequestProcessingError),
}
impl fmt::Display for Error {
@@ -76,6 +79,7 @@
Self::SerializationFailed(e) => write!(f, "Failed to serialize: {e}"),
Self::DeserializationFailed(e) => write!(f, "Failed to deserialize: {e}"),
Self::DiceOperationFailed(e) => write!(f, "Failed DICE operation: {e}"),
+ Self::RequestProcessingFailed(e) => write!(f, "Failed to process request: {e}"),
}
}
}
@@ -133,3 +137,9 @@
Self::DiceOperationFailed(e)
}
}
+
+impl From<RequestProcessingError> for Error {
+ fn from(e: RequestProcessingError) -> Self {
+ Self::RequestProcessingFailed(e)
+ }
+}
diff --git a/rialto/src/requests/api.rs b/rialto/src/requests/api.rs
index c4b2d8e..5ea0106 100644
--- a/rialto/src/requests/api.rs
+++ b/rialto/src/requests/api.rs
@@ -25,14 +25,10 @@
pub fn process_request(request: Request) -> Result<Response> {
let response = match request {
Request::Reverse(v) => Response::Reverse(reverse(v)),
- Request::GenerateEcdsaP256KeyPair => {
- let res = rkp::generate_ecdsa_p256_key_pair()?;
- Response::GenerateEcdsaP256KeyPair(res)
- }
- Request::GenerateCertificateRequest(p) => {
- let res = rkp::generate_certificate_request(p)?;
- Response::GenerateCertificateRequest(res)
- }
+ Request::GenerateEcdsaP256KeyPair => rkp::generate_ecdsa_p256_key_pair()
+ .map_or_else(Response::Err, Response::GenerateEcdsaP256KeyPair),
+ Request::GenerateCertificateRequest(p) => rkp::generate_certificate_request(p)
+ .map_or_else(Response::Err, Response::GenerateCertificateRequest),
};
Ok(response)
}
diff --git a/rialto/src/requests/rkp.rs b/rialto/src/requests/rkp.rs
index 5977bfb..d74bb43 100644
--- a/rialto/src/requests/rkp.rs
+++ b/rialto/src/requests/rkp.rs
@@ -15,9 +15,11 @@
//! This module contains functions related to the attestation of the
//! service VM via the RKP (Remote Key Provisionning) server.
-use crate::error::Result;
use alloc::vec::Vec;
-use service_vm_comm::{EcdsaP256KeyPair, GenerateCertificateRequestParams};
+use core::result;
+use service_vm_comm::{EcdsaP256KeyPair, GenerateCertificateRequestParams, RequestProcessingError};
+
+type Result<T> = result::Result<T, RequestProcessingError>;
pub(super) fn generate_ecdsa_p256_key_pair() -> Result<EcdsaP256KeyPair> {
// TODO(b/299055662): Generate the key pair.
diff --git a/virtualizationservice/src/remote_provisioning.rs b/virtualizationservice/src/remote_provisioning.rs
index 1c8d1e6..a9a07a5 100644
--- a/virtualizationservice/src/remote_provisioning.rs
+++ b/virtualizationservice/src/remote_provisioning.rs
@@ -19,7 +19,7 @@
DeviceInfo::DeviceInfo,
IRemotelyProvisionedComponent::{
BnRemotelyProvisionedComponent, IRemotelyProvisionedComponent, STATUS_FAILED,
- STATUS_REMOVED,
+ STATUS_INVALID_MAC, STATUS_REMOVED,
},
MacedPublicKey::MacedPublicKey,
ProtectedData::ProtectedData,
@@ -28,6 +28,7 @@
use anyhow::Context;
use avflog::LogResult;
use binder::{BinderFeatures, Interface, IntoBinderResult, Result as BinderResult, Status, Strong};
+use service_vm_comm::{RequestProcessingError, Response};
/// Constructs a binder object that implements `IRemotelyProvisionedComponent`.
pub(crate) fn new_binder() -> Strong<dyn IRemotelyProvisionedComponent> {
@@ -65,12 +66,18 @@
))
.with_log();
}
- let key_pair = rkpvm::generate_ecdsa_p256_key_pair()
+ let res = rkpvm::generate_ecdsa_p256_key_pair()
.context("Failed to generate ECDSA P-256 key pair")
.with_log()
.or_service_specific_exception(STATUS_FAILED)?;
- macedPublicKey.macedKey = key_pair.maced_public_key;
- Ok(key_pair.key_blob)
+ match res {
+ Response::GenerateEcdsaP256KeyPair(key_pair) => {
+ macedPublicKey.macedKey = key_pair.maced_public_key;
+ Ok(key_pair.key_blob)
+ }
+ _ => Err(to_service_specific_error(res)),
+ }
+ .with_log()
}
fn generateCertificateRequest(
@@ -104,10 +111,32 @@
return Err(Status::new_service_specific_error_str(STATUS_FAILED, Some(message)))
.with_log();
}
- // TODO(b/299259624): Validate the MAC of the keys to certify.
- rkpvm::generate_certificate_request(keysToSign, challenge)
+ let res = rkpvm::generate_certificate_request(keysToSign, challenge)
.context("Failed to generate certificate request")
.with_log()
- .or_service_specific_exception(STATUS_FAILED)
+ .or_service_specific_exception(STATUS_FAILED)?;
+ match res {
+ Response::GenerateCertificateRequest(res) => Ok(res),
+ _ => Err(to_service_specific_error(res)),
+ }
+ .with_log()
+ }
+}
+
+fn to_service_specific_error(response: Response) -> Status {
+ match response {
+ Response::Err(e) => match e {
+ RequestProcessingError::InvalidMac => {
+ Status::new_service_specific_error_str(STATUS_INVALID_MAC, Some(format!("{e}")))
+ }
+ _ => Status::new_service_specific_error_str(
+ STATUS_FAILED,
+ Some(format!("Failed to process request: {e}.")),
+ ),
+ },
+ other => Status::new_service_specific_error_str(
+ STATUS_FAILED,
+ Some(format!("Incorrect response type: {other:?}")),
+ ),
}
}
diff --git a/virtualizationservice/src/rkpvm.rs b/virtualizationservice/src/rkpvm.rs
index 80953b5..d6e87eb 100644
--- a/virtualizationservice/src/rkpvm.rs
+++ b/virtualizationservice/src/rkpvm.rs
@@ -18,7 +18,7 @@
use android_hardware_security_rkp::aidl::android::hardware::security::keymint::MacedPublicKey::MacedPublicKey;
use anyhow::{bail, Context, Result};
-use service_vm_comm::{EcdsaP256KeyPair, GenerateCertificateRequestParams, Request, Response};
+use service_vm_comm::{GenerateCertificateRequestParams, Request, Response};
use service_vm_manager::ServiceVm;
pub(crate) fn request_certificate(csr: &[u8]) -> Result<Vec<u8>> {
@@ -33,19 +33,16 @@
}
}
-pub(crate) fn generate_ecdsa_p256_key_pair() -> Result<EcdsaP256KeyPair> {
+pub(crate) fn generate_ecdsa_p256_key_pair() -> Result<Response> {
let mut vm = ServiceVm::start()?;
let request = Request::GenerateEcdsaP256KeyPair;
- match vm.process_request(request).context("Failed to process request")? {
- Response::GenerateEcdsaP256KeyPair(key_pair) => Ok(key_pair),
- _ => bail!("Incorrect response type"),
- }
+ vm.process_request(request).context("Failed to process request")
}
pub(crate) fn generate_certificate_request(
keys_to_sign: &[MacedPublicKey],
challenge: &[u8],
-) -> Result<Vec<u8>> {
+) -> Result<Response> {
let params = GenerateCertificateRequestParams {
keys_to_sign: keys_to_sign.iter().map(|v| v.macedKey.to_vec()).collect(),
challenge: challenge.to_vec(),
@@ -53,8 +50,5 @@
let request = Request::GenerateCertificateRequest(params);
let mut vm = ServiceVm::start()?;
- match vm.process_request(request).context("Failed to process request")? {
- Response::GenerateCertificateRequest(csr) => Ok(csr),
- _ => bail!("Incorrect response type"),
- }
+ vm.process_request(request).context("Failed to process request")
}