Alice Wang | 748b032 | 2023-07-24 12:51:18 +0000 | [diff] [blame] | 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; |
Alice Wang | d80e99e | 2023-09-15 13:26:01 +0000 | [diff] [blame] | 19 | use core::fmt; |
| 20 | use log::error; |
Alice Wang | 748b032 | 2023-07-24 12:51:18 +0000 | [diff] [blame] | 21 | use serde::{Deserialize, Serialize}; |
| 22 | |
Alice Wang | 464e473 | 2023-09-06 12:25:22 +0000 | [diff] [blame] | 23 | type MacedPublicKey = Vec<u8>; |
| 24 | |
Alice Wang | fbdc85b | 2023-09-07 12:56:46 +0000 | [diff] [blame] | 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. |
Alice Wang | 748b032 | 2023-07-24 12:51:18 +0000 | [diff] [blame] | 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>), |
Alice Wang | 33f4cae | 2023-09-05 09:27:39 +0000 | [diff] [blame] | 45 | |
| 46 | /// Generates a new ECDSA P-256 key pair that can be attested by the remote |
| 47 | /// server. |
| 48 | GenerateEcdsaP256KeyPair, |
Alice Wang | 464e473 | 2023-09-06 12:25:22 +0000 | [diff] [blame] | 49 | |
| 50 | /// Creates a certificate signing request to be sent to the |
| 51 | /// provisioning server. |
| 52 | GenerateCertificateRequest(GenerateCertificateRequestParams), |
Alice Wang | 9aeb406 | 2023-10-30 14:19:38 +0000 | [diff] [blame] | 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 | |
Alice Wang | 2e6cdc1 | 2024-02-19 11:36:36 +0000 | [diff] [blame] | 59 | impl Request { |
| 60 | /// Returns the name of the request. |
| 61 | 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 | |
Alice Wang | 9aeb406 | 2023-10-30 14:19:38 +0000 | [diff] [blame] | 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>, |
Alice Wang | 20b8ebc | 2023-11-17 09:54:47 +0000 | [diff] [blame] | 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>, |
Alice Wang | 748b032 | 2023-07-24 12:51:18 +0000 | [diff] [blame] | 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>), |
Alice Wang | 33f4cae | 2023-09-05 09:27:39 +0000 | [diff] [blame] | 97 | |
| 98 | /// Returns the new ECDSA P-256 key pair. |
| 99 | GenerateEcdsaP256KeyPair(EcdsaP256KeyPair), |
Alice Wang | 464e473 | 2023-09-06 12:25:22 +0000 | [diff] [blame] | 100 | |
| 101 | /// Returns a CBOR Certificate Signing Request (Csr) serialized into a byte array. |
| 102 | GenerateCertificateRequest(Vec<u8>), |
Alice Wang | d80e99e | 2023-09-15 13:26:01 +0000 | [diff] [blame] | 103 | |
Alice Wang | 9aeb406 | 2023-10-30 14:19:38 +0000 | [diff] [blame] | 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 | |
Alice Wang | d80e99e | 2023-09-15 13:26:01 +0000 | [diff] [blame] | 109 | /// Encountered an error during the request processing. |
| 110 | Err(RequestProcessingError), |
| 111 | } |
| 112 | |
Alice Wang | 2e6cdc1 | 2024-02-19 11:36:36 +0000 | [diff] [blame] | 113 | impl Response { |
| 114 | /// Returns the name of the response. |
| 115 | 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 | |
Alice Wang | d80e99e | 2023-09-15 13:26:01 +0000 | [diff] [blame] | 126 | /// Errors related to request processing. |
| 127 | #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] |
| 128 | pub enum RequestProcessingError { |
Alice Wang | c8f88f5 | 2023-09-25 14:02:17 +0000 | [diff] [blame] | 129 | /// An error happened during the interaction with BoringSSL. |
| 130 | BoringSslError(bssl_avf_error::Error), |
Alice Wang | d80e99e | 2023-09-15 13:26:01 +0000 | [diff] [blame] | 131 | |
| 132 | /// An error happened during the interaction with coset. |
| 133 | CosetError, |
| 134 | |
Alice Wang | 6bc2a70 | 2023-09-22 12:42:13 +0000 | [diff] [blame] | 135 | /// An unexpected internal error occurred. |
| 136 | InternalError, |
| 137 | |
Alice Wang | d80e99e | 2023-09-15 13:26:01 +0000 | [diff] [blame] | 138 | /// Any key to sign lacks a valid MAC. Maps to `STATUS_INVALID_MAC`. |
| 139 | InvalidMac, |
Alice Wang | f7c0f94 | 2023-09-14 09:33:04 +0000 | [diff] [blame] | 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, |
Alice Wang | a2738b7 | 2023-09-22 15:31:28 +0000 | [diff] [blame] | 146 | |
| 147 | /// The DICE chain of the service VM is missing. |
| 148 | MissingDiceChain, |
Alice Wang | 9aeb406 | 2023-10-30 14:19:38 +0000 | [diff] [blame] | 149 | |
| 150 | /// Failed to decrypt the remotely provisioned key blob. |
| 151 | FailedToDecryptKeyBlob, |
| 152 | |
| 153 | /// The requested operation has not been implemented. |
| 154 | OperationUnimplemented, |
Alice Wang | 20b8ebc | 2023-11-17 09:54:47 +0000 | [diff] [blame] | 155 | |
| 156 | /// An error happened during the DER encoding/decoding. |
| 157 | DerError, |
Alice Wang | d3a9640 | 2023-11-24 15:37:39 +0000 | [diff] [blame] | 158 | |
| 159 | /// The DICE chain from the client VM is invalid. |
| 160 | InvalidDiceChain, |
Alice Wang | d80e99e | 2023-09-15 13:26:01 +0000 | [diff] [blame] | 161 | } |
| 162 | |
| 163 | impl fmt::Display for RequestProcessingError { |
| 164 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
| 165 | match self { |
Alice Wang | c8f88f5 | 2023-09-25 14:02:17 +0000 | [diff] [blame] | 166 | Self::BoringSslError(e) => { |
| 167 | write!(f, "An error happened during the interaction with BoringSSL: {e}") |
Alice Wang | d80e99e | 2023-09-15 13:26:01 +0000 | [diff] [blame] | 168 | } |
| 169 | Self::CosetError => write!(f, "Encountered an error with coset"), |
Alice Wang | 6bc2a70 | 2023-09-22 12:42:13 +0000 | [diff] [blame] | 170 | Self::InternalError => write!(f, "An unexpected internal error occurred"), |
Alice Wang | d80e99e | 2023-09-15 13:26:01 +0000 | [diff] [blame] | 171 | Self::InvalidMac => write!(f, "A key to sign lacks a valid MAC."), |
Alice Wang | f7c0f94 | 2023-09-14 09:33:04 +0000 | [diff] [blame] | 172 | Self::KeyToSignHasEmptyPayload => write!(f, "No payload found in a key to sign."), |
| 173 | Self::CborValueError => { |
| 174 | write!(f, "An error happened when serializing to/from a CBOR Value.") |
| 175 | } |
Alice Wang | a2738b7 | 2023-09-22 15:31:28 +0000 | [diff] [blame] | 176 | Self::MissingDiceChain => write!(f, "The DICE chain of the service VM is missing"), |
Alice Wang | 9aeb406 | 2023-10-30 14:19:38 +0000 | [diff] [blame] | 177 | Self::FailedToDecryptKeyBlob => { |
| 178 | write!(f, "Failed to decrypt the remotely provisioned key blob") |
| 179 | } |
| 180 | Self::OperationUnimplemented => { |
| 181 | write!(f, "The requested operation has not been implemented") |
| 182 | } |
Alice Wang | 20b8ebc | 2023-11-17 09:54:47 +0000 | [diff] [blame] | 183 | Self::DerError => { |
| 184 | write!(f, "An error happened during the DER encoding/decoding") |
| 185 | } |
Alice Wang | d3a9640 | 2023-11-24 15:37:39 +0000 | [diff] [blame] | 186 | Self::InvalidDiceChain => { |
| 187 | write!(f, "The DICE chain from the client VM is invalid") |
| 188 | } |
Alice Wang | d80e99e | 2023-09-15 13:26:01 +0000 | [diff] [blame] | 189 | } |
| 190 | } |
| 191 | } |
| 192 | |
Alice Wang | c8f88f5 | 2023-09-25 14:02:17 +0000 | [diff] [blame] | 193 | impl From<bssl_avf_error::Error> for RequestProcessingError { |
| 194 | fn from(e: bssl_avf_error::Error) -> Self { |
| 195 | Self::BoringSslError(e) |
| 196 | } |
| 197 | } |
| 198 | |
Alice Wang | d80e99e | 2023-09-15 13:26:01 +0000 | [diff] [blame] | 199 | impl From<coset::CoseError> for RequestProcessingError { |
| 200 | fn from(e: coset::CoseError) -> Self { |
| 201 | error!("Coset error: {e}"); |
| 202 | Self::CosetError |
| 203 | } |
Alice Wang | 464e473 | 2023-09-06 12:25:22 +0000 | [diff] [blame] | 204 | } |
| 205 | |
Alice Wang | f7c0f94 | 2023-09-14 09:33:04 +0000 | [diff] [blame] | 206 | impl From<ciborium::value::Error> for RequestProcessingError { |
| 207 | fn from(e: ciborium::value::Error) -> Self { |
| 208 | error!("CborValueError: {e}"); |
| 209 | Self::CborValueError |
| 210 | } |
| 211 | } |
| 212 | |
Alice Wang | 20b8ebc | 2023-11-17 09:54:47 +0000 | [diff] [blame] | 213 | #[cfg(not(feature = "std"))] |
| 214 | impl From<der::Error> for RequestProcessingError { |
| 215 | fn from(e: der::Error) -> Self { |
| 216 | error!("DER encoding/decoding error: {e}"); |
| 217 | Self::DerError |
| 218 | } |
| 219 | } |
| 220 | |
Alice Wang | 464e473 | 2023-09-06 12:25:22 +0000 | [diff] [blame] | 221 | /// Represents the params passed to GenerateCertificateRequest |
| 222 | #[derive(Clone, Debug, Serialize, Deserialize)] |
| 223 | pub struct GenerateCertificateRequestParams { |
| 224 | /// Contains the set of keys to certify. |
| 225 | pub keys_to_sign: Vec<MacedPublicKey>, |
| 226 | |
| 227 | /// challenge contains a byte strong from the provisioning server which will be |
| 228 | /// included in the signed data of the CSR structure. |
| 229 | /// The supported sizes is between 0 and 64 bytes, inclusive. |
| 230 | pub challenge: Vec<u8>, |
Alice Wang | 33f4cae | 2023-09-05 09:27:39 +0000 | [diff] [blame] | 231 | } |
| 232 | |
| 233 | /// Represents an ECDSA P-256 key pair. |
| 234 | #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] |
| 235 | pub struct EcdsaP256KeyPair { |
| 236 | /// Contains a CBOR-encoded public key specified in: |
| 237 | /// |
| 238 | /// hardware/interfaces/security/rkp/aidl/android/hardware/security/keymint/MacedPublicKey.aidl |
Alice Wang | 464e473 | 2023-09-06 12:25:22 +0000 | [diff] [blame] | 239 | pub maced_public_key: MacedPublicKey, |
Alice Wang | 33f4cae | 2023-09-05 09:27:39 +0000 | [diff] [blame] | 240 | |
| 241 | /// Contains a handle to the private key. |
| 242 | pub key_blob: Vec<u8>, |
Alice Wang | 748b032 | 2023-07-24 12:51:18 +0000 | [diff] [blame] | 243 | } |