1 // Copyright 2023, The Android Open Source Project 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 //! This module contains the requests and responses definitions exchanged 16 //! between the host and the service VM. 17 18 use alloc::vec::Vec; 19 use core::fmt; 20 use log::error; 21 use serde::{Deserialize, Serialize}; 22 23 type MacedPublicKey = Vec<u8>; 24 25 /// The main request type to be sent to the service VM. 26 #[derive(Clone, Debug, Serialize, Deserialize)] 27 pub enum ServiceVmRequest { 28 /// A request to be processed by the service VM. 29 /// 30 /// Each request has a corresponding response item. 31 Process(Request), 32 33 /// Shuts down the service VM. No response is expected from it. 34 Shutdown, 35 } 36 37 /// Represents a process request to be sent to the service VM. 38 /// 39 /// Each request has a corresponding response item. 40 #[derive(Clone, Debug, Serialize, Deserialize)] 41 pub enum Request { 42 /// Reverse the order of the bytes in the provided byte array. 43 /// Currently this is only used for testing. 44 Reverse(Vec<u8>), 45 46 /// Generates a new ECDSA P-256 key pair that can be attested by the remote 47 /// server. 48 GenerateEcdsaP256KeyPair, 49 50 /// Creates a certificate signing request to be sent to the 51 /// provisioning server. 52 GenerateCertificateRequest(GenerateCertificateRequestParams), 53 54 /// Requests the service VM to attest the client VM and issue a certificate 55 /// if the attestation succeeds. 56 RequestClientVmAttestation(ClientVmAttestationParams), 57 } 58 59 impl Request { 60 /// Returns the name of the request. name(&self) -> &'static str61 pub fn name(&self) -> &'static str { 62 match self { 63 Self::Reverse(_) => "Reverse", 64 Self::GenerateEcdsaP256KeyPair => "GenerateEcdsaP256KeyPair", 65 Self::GenerateCertificateRequest(_) => "GenerateCertificateRequest", 66 Self::RequestClientVmAttestation(_) => "RequestClientVmAttestation", 67 } 68 } 69 } 70 71 /// Represents the params passed to `Request::RequestClientVmAttestation`. 72 #[derive(Clone, Debug, Serialize, Deserialize)] 73 pub struct ClientVmAttestationParams { 74 /// The CBOR-encoded CSR signed by the CDI_Leaf_Priv of the client VM's DICE chain 75 /// and the private key to be attested. 76 /// See client_vm_csr.cddl for the definition of the CSR. 77 pub csr: Vec<u8>, 78 79 /// The key blob retrieved from RKPD by virtualizationservice. 80 pub remotely_provisioned_key_blob: Vec<u8>, 81 82 /// The leaf certificate of the certificate chain retrieved from RKPD by 83 /// virtualizationservice. 84 /// 85 /// This certificate is a DER-encoded X.509 certificate that includes the remotely 86 /// provisioned public key. 87 pub remotely_provisioned_cert: Vec<u8>, 88 } 89 90 /// Represents a response to a request sent to the service VM. 91 /// 92 /// Each response corresponds to a specific request. 93 #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] 94 pub enum Response { 95 /// Reverse the order of the bytes in the provided byte array. 96 Reverse(Vec<u8>), 97 98 /// Returns the new ECDSA P-256 key pair. 99 GenerateEcdsaP256KeyPair(EcdsaP256KeyPair), 100 101 /// Returns a CBOR Certificate Signing Request (Csr) serialized into a byte array. 102 GenerateCertificateRequest(Vec<u8>), 103 104 /// Returns a certificate covering the public key to be attested in the provided CSR. 105 /// The certificate is signed by the remotely provisioned private key and also 106 /// includes an extension that describes the attested client VM. 107 RequestClientVmAttestation(Vec<u8>), 108 109 /// Encountered an error during the request processing. 110 Err(RequestProcessingError), 111 } 112 113 impl Response { 114 /// Returns the name of the response. name(&self) -> &'static str115 pub fn name(&self) -> &'static str { 116 match self { 117 Self::Reverse(_) => "Reverse", 118 Self::GenerateEcdsaP256KeyPair(_) => "GenerateEcdsaP256KeyPair", 119 Self::GenerateCertificateRequest(_) => "GenerateCertificateRequest", 120 Self::RequestClientVmAttestation(_) => "RequestClientVmAttestation", 121 Self::Err(_) => "Err", 122 } 123 } 124 } 125 126 /// Errors related to request processing. 127 #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] 128 pub enum RequestProcessingError { 129 /// An error happened during the interaction with BoringSSL. 130 BoringSslError(bssl_avf_error::Error), 131 132 /// An error happened during the interaction with coset. 133 CosetError, 134 135 /// An unexpected internal error occurred. 136 InternalError, 137 138 /// Any key to sign lacks a valid MAC. Maps to `STATUS_INVALID_MAC`. 139 InvalidMac, 140 141 /// No payload found in a key to sign. 142 KeyToSignHasEmptyPayload, 143 144 /// An error happened when serializing to/from a `Value`. 145 CborValueError, 146 147 /// The DICE chain of the service VM is missing. 148 MissingDiceChain, 149 150 /// Failed to decrypt the remotely provisioned key blob. 151 FailedToDecryptKeyBlob, 152 153 /// The requested operation has not been implemented. 154 OperationUnimplemented, 155 156 /// An error happened during the DER encoding/decoding. 157 DerError, 158 159 /// The DICE chain from the client VM is invalid. 160 InvalidDiceChain, 161 162 /// Cannot find the vendor hash tree root digest in the device tree. 163 NoVendorHashTreeRootDigestInDT, 164 165 /// The vendor partition loaded by the client VM is invalid. 166 InvalidVendorPartition, 167 } 168 169 impl fmt::Display for RequestProcessingError { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result170 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 171 match self { 172 Self::BoringSslError(e) => { 173 write!(f, "An error happened during the interaction with BoringSSL: {e}") 174 } 175 Self::CosetError => write!(f, "Encountered an error with coset"), 176 Self::InternalError => write!(f, "An unexpected internal error occurred"), 177 Self::InvalidMac => write!(f, "A key to sign lacks a valid MAC."), 178 Self::KeyToSignHasEmptyPayload => write!(f, "No payload found in a key to sign."), 179 Self::CborValueError => { 180 write!(f, "An error happened when serializing to/from a CBOR Value.") 181 } 182 Self::MissingDiceChain => write!(f, "The DICE chain of the service VM is missing"), 183 Self::FailedToDecryptKeyBlob => { 184 write!(f, "Failed to decrypt the remotely provisioned key blob") 185 } 186 Self::OperationUnimplemented => { 187 write!(f, "The requested operation has not been implemented") 188 } 189 Self::DerError => { 190 write!(f, "An error happened during the DER encoding/decoding") 191 } 192 Self::InvalidDiceChain => { 193 write!(f, "The DICE chain from the client VM is invalid") 194 } 195 Self::NoVendorHashTreeRootDigestInDT => { 196 write!(f, "Cannot find the vendor hash tree root digest in the device tree") 197 } 198 Self::InvalidVendorPartition => { 199 write!(f, "The vendor partition loaded by the client VM is invalid") 200 } 201 } 202 } 203 } 204 205 impl From<bssl_avf_error::Error> for RequestProcessingError { from(e: bssl_avf_error::Error) -> Self206 fn from(e: bssl_avf_error::Error) -> Self { 207 Self::BoringSslError(e) 208 } 209 } 210 211 impl From<coset::CoseError> for RequestProcessingError { from(e: coset::CoseError) -> Self212 fn from(e: coset::CoseError) -> Self { 213 error!("Coset error: {e}"); 214 Self::CosetError 215 } 216 } 217 218 impl From<ciborium::value::Error> for RequestProcessingError { from(e: ciborium::value::Error) -> Self219 fn from(e: ciborium::value::Error) -> Self { 220 error!("CborValueError: {e}"); 221 Self::CborValueError 222 } 223 } 224 225 #[cfg(not(feature = "std"))] 226 impl From<der::Error> for RequestProcessingError { from(e: der::Error) -> Self227 fn from(e: der::Error) -> Self { 228 error!("DER encoding/decoding error: {e}"); 229 Self::DerError 230 } 231 } 232 233 /// Represents the params passed to GenerateCertificateRequest 234 #[derive(Clone, Debug, Serialize, Deserialize)] 235 pub struct GenerateCertificateRequestParams { 236 /// Contains the set of keys to certify. 237 pub keys_to_sign: Vec<MacedPublicKey>, 238 239 /// challenge contains a byte strong from the provisioning server which will be 240 /// included in the signed data of the CSR structure. 241 /// The supported sizes is between 0 and 64 bytes, inclusive. 242 pub challenge: Vec<u8>, 243 } 244 245 /// Represents an ECDSA P-256 key pair. 246 #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] 247 pub struct EcdsaP256KeyPair { 248 /// Contains a CBOR-encoded public key specified in: 249 /// 250 /// hardware/interfaces/security/rkp/aidl/android/hardware/security/keymint/MacedPublicKey.aidl 251 pub maced_public_key: MacedPublicKey, 252 253 /// Contains a handle to the private key. 254 pub key_blob: Vec<u8>, 255 } 256