[rkp] Introduce a new request type for attestation request
The attestation keys will be transmitted to the RKP VM along with
the client VM CSR for attestation, using the newly added request
type later.
The retrieval of remotely provisioned keys has been separated in
a subsequent change to unblock the work of handling the new
request.
Bug: 241428146
Test: m com.android.virt
Test: atest libservice_vm_requests.test rialto_test
Change-Id: I900924996a3f06c13e1d2ca11f7edfc2a518ffc2
diff --git a/service_vm/comm/src/client_vm_csr.cddl b/service_vm/comm/src/client_vm_csr.cddl
new file mode 100644
index 0000000..bbc709a
--- /dev/null
+++ b/service_vm/comm/src/client_vm_csr.cddl
@@ -0,0 +1,62 @@
+; CDDL for the CSR sent from the client VM to the RKP VM for pVM remote attestation.
+
+Csr = [
+ DiceCertChain, ; The DICE chain containing measurement of the client VM. See
+ ; keymint/generateCertificateRequestV2.cddl for the DiceCertChain
+ ; definition.
+ SignedData,
+]
+
+; COSE_Sign [RFC9052 s4.1]
+SignedData = [
+ protected: {}, ; The signing algorithms are specified in each signature
+ ; separately.
+ unprotected: {},
+ payload: bstr .cbor CsrPayload,
+ Signatures,
+]
+
+CsrPayload = [ ; CBOR Array defining the payload for CSR
+ challenge: bstr .size (0..64), ; The challenge is provided by the client server.
+ ; It will be included in the certificate chain in the
+ ; attestation result, serving as proof of the freshness
+ ; of the result.
+ PublicKey, ; COSE_Key encoded EC P-256 public key [ RFC9053 s7.1.1 ]
+ ; to be attested. See keymint/PublicKey.cddl for the
+ ; definition, the test flag `-70000` is never used.
+]
+
+Signatures = [
+ dice_cdi_leaf_signature: COSE_Signature_Dice_Cdi_Leaf,
+ attestation_key_signature: COSE_Signature_Attestation_Key,
+]
+
+; COSE_Signature [RFC9052 s4.1]
+COSE_Signature_Dice_Cdi_Leaf = [
+ protected: bstr .cbor { 1: AlgorithmEdDSA },
+ unprotected: {},
+ signature: bstr, ; Ed25519(CDI_Leaf_Priv, SigStruct)
+]
+
+; COSE_Signature [RFC9052 s4.1]
+COSE_Signature_Attestation_Key = [
+ protected: bstr .cbor { 1: AlgorithmES256 },
+ unprotected: {},
+ signature: bstr, ; ECDSA(PrivateKey, SigStruct)
+]
+
+; Sig_structure for SignedData [ RFC9052 s4.4 ]
+SigStruct = {
+ context: "Signature",
+ external_aad: bstr .size 0,
+ payload: bstr .cbor CsrPayload,
+}
+
+; ASN.1 DER-encoded EC P-256 ECPrivateKey [ RFC 5915 s3 ]:
+; ECPrivateKey ::= SEQUENCE {
+; version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
+; privateKey OCTET STRING,
+; parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
+; publicKey [1] BIT STRING OPTIONAL
+;}
+PrivateKey = bstr
diff --git a/service_vm/comm/src/csr.rs b/service_vm/comm/src/csr.rs
index 5e1cbad..e913bb5 100644
--- a/service_vm/comm/src/csr.rs
+++ b/service_vm/comm/src/csr.rs
@@ -21,6 +21,8 @@
use coset::{self, CborSerializable, CoseError};
/// Represents a CSR sent from the client VM to the service VM for attestation.
+///
+/// See client_vm_csr.cddl for the definition of the CSR.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Csr {
/// The DICE certificate chain of the client VM.
diff --git a/service_vm/comm/src/lib.rs b/service_vm/comm/src/lib.rs
index 0818f24..bb85a26 100644
--- a/service_vm/comm/src/lib.rs
+++ b/service_vm/comm/src/lib.rs
@@ -25,7 +25,7 @@
pub use csr::{Csr, CsrPayload};
pub use message::{
- EcdsaP256KeyPair, GenerateCertificateRequestParams, Request, RequestProcessingError, Response,
- ServiceVmRequest,
+ ClientVmAttestationParams, EcdsaP256KeyPair, GenerateCertificateRequestParams, Request,
+ RequestProcessingError, Response, ServiceVmRequest,
};
pub use vsock::VmType;
diff --git a/service_vm/comm/src/message.rs b/service_vm/comm/src/message.rs
index f8d7420..6dd0ccd 100644
--- a/service_vm/comm/src/message.rs
+++ b/service_vm/comm/src/message.rs
@@ -50,6 +50,22 @@
/// Creates a certificate signing request to be sent to the
/// provisioning server.
GenerateCertificateRequest(GenerateCertificateRequestParams),
+
+ /// Requests the service VM to attest the client VM and issue a certificate
+ /// if the attestation succeeds.
+ RequestClientVmAttestation(ClientVmAttestationParams),
+}
+
+/// Represents the params passed to `Request::RequestClientVmAttestation`.
+#[derive(Clone, Debug, Serialize, Deserialize)]
+pub struct ClientVmAttestationParams {
+ /// The CBOR-encoded CSR signed by the CDI_Leaf_Priv of the client VM's DICE chain
+ /// and the private key to be attested.
+ /// See client_vm_csr.cddl for the definition of the CSR.
+ pub csr: Vec<u8>,
+
+ /// The key blob retrieved from RKPD by virtualizationservice.
+ pub remotely_provisioned_key_blob: Vec<u8>,
}
/// Represents a response to a request sent to the service VM.
@@ -66,6 +82,11 @@
/// Returns a CBOR Certificate Signing Request (Csr) serialized into a byte array.
GenerateCertificateRequest(Vec<u8>),
+ /// Returns a certificate covering the public key to be attested in the provided CSR.
+ /// The certificate is signed by the remotely provisioned private key and also
+ /// includes an extension that describes the attested client VM.
+ RequestClientVmAttestation(Vec<u8>),
+
/// Encountered an error during the request processing.
Err(RequestProcessingError),
}
@@ -93,6 +114,12 @@
/// The DICE chain of the service VM is missing.
MissingDiceChain,
+
+ /// Failed to decrypt the remotely provisioned key blob.
+ FailedToDecryptKeyBlob,
+
+ /// The requested operation has not been implemented.
+ OperationUnimplemented,
}
impl fmt::Display for RequestProcessingError {
@@ -109,6 +136,12 @@
write!(f, "An error happened when serializing to/from a CBOR Value.")
}
Self::MissingDiceChain => write!(f, "The DICE chain of the service VM is missing"),
+ Self::FailedToDecryptKeyBlob => {
+ write!(f, "Failed to decrypt the remotely provisioned key blob")
+ }
+ Self::OperationUnimplemented => {
+ write!(f, "The requested operation has not been implemented")
+ }
}
}
}