blob: 443c285c8be422598f81ea4c1ad22082933b0aa3 [file] [log] [blame]
// Copyright 2023, The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! This module contains the requests and responses definitions exchanged
//! between the host and the service VM.
use alloc::vec::Vec;
use core::fmt;
use log::error;
use serde::{Deserialize, Serialize};
type MacedPublicKey = Vec<u8>;
/// The main request type to be sent to the service VM.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum ServiceVmRequest {
/// A request to be processed by the service VM.
///
/// Each request has a corresponding response item.
Process(Request),
/// Shuts down the service VM. No response is expected from it.
Shutdown,
}
/// Represents a process request to be sent to the service VM.
///
/// Each request has a corresponding response item.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum Request {
/// Reverse the order of the bytes in the provided byte array.
/// Currently this is only used for testing.
Reverse(Vec<u8>),
/// Generates a new ECDSA P-256 key pair that can be attested by the remote
/// server.
GenerateEcdsaP256KeyPair,
/// Creates a certificate signing request to be sent to the
/// provisioning server.
GenerateCertificateRequest(GenerateCertificateRequestParams),
}
/// Represents a response to a request sent to the service VM.
///
/// Each response corresponds to a specific request.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum Response {
/// Reverse the order of the bytes in the provided byte array.
Reverse(Vec<u8>),
/// Returns the new ECDSA P-256 key pair.
GenerateEcdsaP256KeyPair(EcdsaP256KeyPair),
/// 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 {
/// An error happened during the interaction with BoringSSL.
BoringSslError(bssl_avf_error::Error),
/// An error happened during the interaction with coset.
CosetError,
/// Any key to sign lacks a valid MAC. Maps to `STATUS_INVALID_MAC`.
InvalidMac,
/// No payload found in a key to sign.
KeyToSignHasEmptyPayload,
/// An error happened when serializing to/from a `Value`.
CborValueError,
}
impl fmt::Display for RequestProcessingError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::BoringSslError(e) => {
write!(f, "An error happened during the interaction with BoringSSL: {e}")
}
Self::CosetError => write!(f, "Encountered an error with coset"),
Self::InvalidMac => write!(f, "A key to sign lacks a valid MAC."),
Self::KeyToSignHasEmptyPayload => write!(f, "No payload found in a key to sign."),
Self::CborValueError => {
write!(f, "An error happened when serializing to/from a CBOR Value.")
}
}
}
}
impl From<bssl_avf_error::Error> for RequestProcessingError {
fn from(e: bssl_avf_error::Error) -> Self {
Self::BoringSslError(e)
}
}
impl From<coset::CoseError> for RequestProcessingError {
fn from(e: coset::CoseError) -> Self {
error!("Coset error: {e}");
Self::CosetError
}
}
impl From<ciborium::value::Error> for RequestProcessingError {
fn from(e: ciborium::value::Error) -> Self {
error!("CborValueError: {e}");
Self::CborValueError
}
}
/// Represents the params passed to GenerateCertificateRequest
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct GenerateCertificateRequestParams {
/// Contains the set of keys to certify.
pub keys_to_sign: Vec<MacedPublicKey>,
/// challenge contains a byte strong from the provisioning server which will be
/// included in the signed data of the CSR structure.
/// The supported sizes is between 0 and 64 bytes, inclusive.
pub challenge: Vec<u8>,
}
/// Represents an ECDSA P-256 key pair.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct EcdsaP256KeyPair {
/// Contains a CBOR-encoded public key specified in:
///
/// hardware/interfaces/security/rkp/aidl/android/hardware/security/keymint/MacedPublicKey.aidl
pub maced_public_key: MacedPublicKey,
/// Contains a handle to the private key.
pub key_blob: Vec<u8>,
}