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