diff --git a/attestation-agent/attestation-agent/src/bin/grpc-aa/server.rs b/attestation-agent/attestation-agent/src/bin/grpc-aa/server.rs index 5e3147b36..a4b5053e9 100644 --- a/attestation-agent/attestation-agent/src/bin/grpc-aa/server.rs +++ b/attestation-agent/attestation-agent/src/bin/grpc-aa/server.rs @@ -8,7 +8,7 @@ use attestation::attestation_agent_service_server::{ AttestationAgentService, AttestationAgentServiceServer, }; use attestation::{ - CheckInitDataRequest, CheckInitDataResponse, ExtendRuntimeMeasurementRequest, + BindInitDataRequest, BindInitDataResponse, ExtendRuntimeMeasurementRequest, ExtendRuntimeMeasurementResponse, GetEvidenceRequest, GetEvidenceResponse, GetTeeTypeRequest, GetTeeTypeResponse, GetTokenRequest, GetTokenResponse, UpdateConfigurationRequest, UpdateConfigurationResponse, @@ -108,25 +108,25 @@ impl AttestationAgentService for AA { Result::Ok(Response::new(reply)) } - async fn check_init_data( + async fn bind_init_data( &self, - request: Request, - ) -> Result, Status> { + request: Request, + ) -> Result, Status> { let request = request.into_inner(); - debug!("AA (grpc): check init data ..."); + debug!("AA (grpc): bind init data ..."); self.inner - .check_init_data(&request.digest) + .bind_init_data(&request.digest) .await .map_err(|e| { - error!("AA (grpc): check init data failed:\n{e:?}"); - Status::internal(format!("[ERROR:{AGENT_NAME}] AA check init data failed")) + error!("AA (grpc): binding init data failed:\n{e:?}"); + Status::internal(format!("[ERROR:{AGENT_NAME}] AA binding init data failed")) })?; - debug!("AA (grpc): Check init data successfully!"); + debug!("AA (grpc): init data binding successfully!"); - let reply = CheckInitDataResponse {}; + let reply = BindInitDataResponse {}; Result::Ok(Response::new(reply)) } diff --git a/attestation-agent/attestation-agent/src/bin/ttrpc-aa/ttrpc_protocol/attestation_agent.rs b/attestation-agent/attestation-agent/src/bin/ttrpc-aa/ttrpc_protocol/attestation_agent.rs index 4b6cfcac1..5ce4693dc 100644 --- a/attestation-agent/attestation-agent/src/bin/ttrpc-aa/ttrpc_protocol/attestation_agent.rs +++ b/attestation-agent/attestation-agent/src/bin/ttrpc-aa/ttrpc_protocol/attestation_agent.rs @@ -931,25 +931,25 @@ impl ::protobuf::reflect::ProtobufValue for InitDataPlaintext { type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; } -// @@protoc_insertion_point(message:attestation_agent.CheckInitDataRequest) +// @@protoc_insertion_point(message:attestation_agent.BindInitDataRequest) #[derive(PartialEq,Clone,Default,Debug)] -pub struct CheckInitDataRequest { +pub struct BindInitDataRequest { // message fields - // @@protoc_insertion_point(field:attestation_agent.CheckInitDataRequest.Digest) + // @@protoc_insertion_point(field:attestation_agent.BindInitDataRequest.Digest) pub Digest: ::std::vec::Vec, // special fields - // @@protoc_insertion_point(special_field:attestation_agent.CheckInitDataRequest.special_fields) + // @@protoc_insertion_point(special_field:attestation_agent.BindInitDataRequest.special_fields) pub special_fields: ::protobuf::SpecialFields, } -impl<'a> ::std::default::Default for &'a CheckInitDataRequest { - fn default() -> &'a CheckInitDataRequest { - ::default_instance() +impl<'a> ::std::default::Default for &'a BindInitDataRequest { + fn default() -> &'a BindInitDataRequest { + ::default_instance() } } -impl CheckInitDataRequest { - pub fn new() -> CheckInitDataRequest { +impl BindInitDataRequest { + pub fn new() -> BindInitDataRequest { ::std::default::Default::default() } @@ -958,19 +958,19 @@ impl CheckInitDataRequest { let mut oneofs = ::std::vec::Vec::with_capacity(0); fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( "Digest", - |m: &CheckInitDataRequest| { &m.Digest }, - |m: &mut CheckInitDataRequest| { &mut m.Digest }, + |m: &BindInitDataRequest| { &m.Digest }, + |m: &mut BindInitDataRequest| { &mut m.Digest }, )); - ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( - "CheckInitDataRequest", + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "BindInitDataRequest", fields, oneofs, ) } } -impl ::protobuf::Message for CheckInitDataRequest { - const NAME: &'static str = "CheckInitDataRequest"; +impl ::protobuf::Message for BindInitDataRequest { + const NAME: &'static str = "BindInitDataRequest"; fn is_initialized(&self) -> bool { true @@ -1018,8 +1018,8 @@ impl ::protobuf::Message for CheckInitDataRequest { &mut self.special_fields } - fn new() -> CheckInitDataRequest { - CheckInitDataRequest::new() + fn new() -> BindInitDataRequest { + BindInitDataRequest::new() } fn clear(&mut self) { @@ -1027,8 +1027,8 @@ impl ::protobuf::Message for CheckInitDataRequest { self.special_fields.clear(); } - fn default_instance() -> &'static CheckInitDataRequest { - static instance: CheckInitDataRequest = CheckInitDataRequest { + fn default_instance() -> &'static BindInitDataRequest { + static instance: BindInitDataRequest = BindInitDataRequest { Digest: ::std::vec::Vec::new(), special_fields: ::protobuf::SpecialFields::new(), }; @@ -1036,55 +1036,55 @@ impl ::protobuf::Message for CheckInitDataRequest { } } -impl ::protobuf::MessageFull for CheckInitDataRequest { +impl ::protobuf::MessageFull for BindInitDataRequest { fn descriptor() -> ::protobuf::reflect::MessageDescriptor { static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); - descriptor.get(|| file_descriptor().message_by_package_relative_name("CheckInitDataRequest").unwrap()).clone() + descriptor.get(|| file_descriptor().message_by_package_relative_name("BindInitDataRequest").unwrap()).clone() } } -impl ::std::fmt::Display for CheckInitDataRequest { +impl ::std::fmt::Display for BindInitDataRequest { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for CheckInitDataRequest { +impl ::protobuf::reflect::ProtobufValue for BindInitDataRequest { type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; } -// @@protoc_insertion_point(message:attestation_agent.CheckInitDataResponse) +// @@protoc_insertion_point(message:attestation_agent.BindInitDataResponse) #[derive(PartialEq,Clone,Default,Debug)] -pub struct CheckInitDataResponse { +pub struct BindInitDataResponse { // special fields - // @@protoc_insertion_point(special_field:attestation_agent.CheckInitDataResponse.special_fields) + // @@protoc_insertion_point(special_field:attestation_agent.BindInitDataResponse.special_fields) pub special_fields: ::protobuf::SpecialFields, } -impl<'a> ::std::default::Default for &'a CheckInitDataResponse { - fn default() -> &'a CheckInitDataResponse { - ::default_instance() +impl<'a> ::std::default::Default for &'a BindInitDataResponse { + fn default() -> &'a BindInitDataResponse { + ::default_instance() } } -impl CheckInitDataResponse { - pub fn new() -> CheckInitDataResponse { +impl BindInitDataResponse { + pub fn new() -> BindInitDataResponse { ::std::default::Default::default() } fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { let mut fields = ::std::vec::Vec::with_capacity(0); let mut oneofs = ::std::vec::Vec::with_capacity(0); - ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( - "CheckInitDataResponse", + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "BindInitDataResponse", fields, oneofs, ) } } -impl ::protobuf::Message for CheckInitDataResponse { - const NAME: &'static str = "CheckInitDataResponse"; +impl ::protobuf::Message for BindInitDataResponse { + const NAME: &'static str = "BindInitDataResponse"; fn is_initialized(&self) -> bool { true @@ -1123,36 +1123,36 @@ impl ::protobuf::Message for CheckInitDataResponse { &mut self.special_fields } - fn new() -> CheckInitDataResponse { - CheckInitDataResponse::new() + fn new() -> BindInitDataResponse { + BindInitDataResponse::new() } fn clear(&mut self) { self.special_fields.clear(); } - fn default_instance() -> &'static CheckInitDataResponse { - static instance: CheckInitDataResponse = CheckInitDataResponse { + fn default_instance() -> &'static BindInitDataResponse { + static instance: BindInitDataResponse = BindInitDataResponse { special_fields: ::protobuf::SpecialFields::new(), }; &instance } } -impl ::protobuf::MessageFull for CheckInitDataResponse { +impl ::protobuf::MessageFull for BindInitDataResponse { fn descriptor() -> ::protobuf::reflect::MessageDescriptor { static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); - descriptor.get(|| file_descriptor().message_by_package_relative_name("CheckInitDataResponse").unwrap()).clone() + descriptor.get(|| file_descriptor().message_by_package_relative_name("BindInitDataResponse").unwrap()).clone() } } -impl ::std::fmt::Display for CheckInitDataResponse { +impl ::std::fmt::Display for BindInitDataResponse { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for CheckInitDataResponse { +impl ::protobuf::reflect::ProtobufValue for BindInitDataResponse { type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; } @@ -1618,23 +1618,23 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x07Content\x12)\n\rRegisterIndex\x18\x04\x20\x01(\x04H\0R\rRegisterInde\ x\x88\x01\x01B\x10\n\x0e_RegisterIndex\"\"\n\x20ExtendRuntimeMeasurement\ Response\"K\n\x11InitDataPlaintext\x12\x18\n\x07Content\x18\x01\x20\x01(\ - \x0cR\x07Content\x12\x1c\n\tAlgorithm\x18\x02\x20\x01(\tR\tAlgorithm\".\ - \n\x14CheckInitDataRequest\x12\x16\n\x06Digest\x18\x01\x20\x01(\x0cR\x06\ - Digest\"\x17\n\x15CheckInitDataResponse\"4\n\x1aUpdateConfigurationReque\ - st\x12\x16\n\x06config\x18\x01\x20\x01(\tR\x06config\"\x1d\n\x1bUpdateCo\ - nfigurationResponse\"\x13\n\x11GetTeeTypeRequest\"&\n\x12GetTeeTypeRespo\ - nse\x12\x10\n\x03tee\x18\x01\x20\x01(\tR\x03tee2\x87\x05\n\x17Attestatio\ - nAgentService\x12\\\n\x0bGetEvidence\x12%.attestation_agent.GetEvidenceR\ - equest\x1a&.attestation_agent.GetEvidenceResponse\x12S\n\x08GetToken\x12\ - \".attestation_agent.GetTokenRequest\x1a#.attestation_agent.GetTokenResp\ - onse\x12\x83\x01\n\x18ExtendRuntimeMeasurement\x122.attestation_agent.Ex\ - tendRuntimeMeasurementRequest\x1a3.attestation_agent.ExtendRuntimeMeasur\ - ementResponse\x12b\n\rCheckInitData\x12'.attestation_agent.CheckInitData\ - Request\x1a(.attestation_agent.CheckInitDataResponse\x12t\n\x13UpdateCon\ - figuration\x12-.attestation_agent.UpdateConfigurationRequest\x1a..attest\ - ation_agent.UpdateConfigurationResponse\x12Y\n\nGetTeeType\x12$.attestat\ - ion_agent.GetTeeTypeRequest\x1a%.attestation_agent.GetTeeTypeResponseb\ - \x06proto3\ + \x0cR\x07Content\x12\x1c\n\tAlgorithm\x18\x02\x20\x01(\tR\tAlgorithm\"-\ + \n\x13BindInitDataRequest\x12\x16\n\x06Digest\x18\x01\x20\x01(\x0cR\x06D\ + igest\"\x16\n\x14BindInitDataResponse\"4\n\x1aUpdateConfigurationRequest\ + \x12\x16\n\x06config\x18\x01\x20\x01(\tR\x06config\"\x1d\n\x1bUpdateConf\ + igurationResponse\"\x13\n\x11GetTeeTypeRequest\"&\n\x12GetTeeTypeRespons\ + e\x12\x10\n\x03tee\x18\x01\x20\x01(\tR\x03tee2\x84\x05\n\x17AttestationA\ + gentService\x12\\\n\x0bGetEvidence\x12%.attestation_agent.GetEvidenceReq\ + uest\x1a&.attestation_agent.GetEvidenceResponse\x12S\n\x08GetToken\x12\"\ + .attestation_agent.GetTokenRequest\x1a#.attestation_agent.GetTokenRespon\ + se\x12\x83\x01\n\x18ExtendRuntimeMeasurement\x122.attestation_agent.Exte\ + ndRuntimeMeasurementRequest\x1a3.attestation_agent.ExtendRuntimeMeasurem\ + entResponse\x12_\n\x0cBindInitData\x12&.attestation_agent.BindInitDataRe\ + quest\x1a'.attestation_agent.BindInitDataResponse\x12t\n\x13UpdateConfig\ + uration\x12-.attestation_agent.UpdateConfigurationRequest\x1a..attestati\ + on_agent.UpdateConfigurationResponse\x12Y\n\nGetTeeType\x12$.attestation\ + _agent.GetTeeTypeRequest\x1a%.attestation_agent.GetTeeTypeResponseb\x06p\ + roto3\ "; /// `FileDescriptorProto` object which was a source for this generated file @@ -1660,8 +1660,8 @@ pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor { messages.push(ExtendRuntimeMeasurementRequest::generated_message_descriptor_data()); messages.push(ExtendRuntimeMeasurementResponse::generated_message_descriptor_data()); messages.push(InitDataPlaintext::generated_message_descriptor_data()); - messages.push(CheckInitDataRequest::generated_message_descriptor_data()); - messages.push(CheckInitDataResponse::generated_message_descriptor_data()); + messages.push(BindInitDataRequest::generated_message_descriptor_data()); + messages.push(BindInitDataResponse::generated_message_descriptor_data()); messages.push(UpdateConfigurationRequest::generated_message_descriptor_data()); messages.push(UpdateConfigurationResponse::generated_message_descriptor_data()); messages.push(GetTeeTypeRequest::generated_message_descriptor_data()); diff --git a/attestation-agent/attestation-agent/src/bin/ttrpc-aa/ttrpc_protocol/attestation_agent_ttrpc.rs b/attestation-agent/attestation-agent/src/bin/ttrpc-aa/ttrpc_protocol/attestation_agent_ttrpc.rs index 50e1b0929..f07547ae4 100644 --- a/attestation-agent/attestation-agent/src/bin/ttrpc-aa/ttrpc_protocol/attestation_agent_ttrpc.rs +++ b/attestation-agent/attestation-agent/src/bin/ttrpc-aa/ttrpc_protocol/attestation_agent_ttrpc.rs @@ -46,9 +46,9 @@ impl AttestationAgentServiceClient { ::ttrpc::async_client_request!(self, ctx, req, "attestation_agent.AttestationAgentService", "ExtendRuntimeMeasurement", cres); } - pub async fn check_init_data(&self, ctx: ttrpc::context::Context, req: &super::attestation_agent::CheckInitDataRequest) -> ::ttrpc::Result { - let mut cres = super::attestation_agent::CheckInitDataResponse::new(); - ::ttrpc::async_client_request!(self, ctx, req, "attestation_agent.AttestationAgentService", "CheckInitData", cres); + pub async fn bind_init_data(&self, ctx: ttrpc::context::Context, req: &super::attestation_agent::BindInitDataRequest) -> ::ttrpc::Result { + let mut cres = super::attestation_agent::BindInitDataResponse::new(); + ::ttrpc::async_client_request!(self, ctx, req, "attestation_agent.AttestationAgentService", "BindInitData", cres); } pub async fn update_configuration(&self, ctx: ttrpc::context::Context, req: &super::attestation_agent::UpdateConfigurationRequest) -> ::ttrpc::Result { @@ -95,14 +95,14 @@ impl ::ttrpc::r#async::MethodHandler for ExtendRuntimeMeasurementMethod { } } -struct CheckInitDataMethod { +struct BindInitDataMethod { service: Arc, } #[async_trait] -impl ::ttrpc::r#async::MethodHandler for CheckInitDataMethod { +impl ::ttrpc::r#async::MethodHandler for BindInitDataMethod { async fn handler(&self, ctx: ::ttrpc::r#async::TtrpcContext, req: ::ttrpc::Request) -> ::ttrpc::Result<::ttrpc::Response> { - ::ttrpc::async_request_handler!(self, ctx, req, attestation_agent, CheckInitDataRequest, check_init_data); + ::ttrpc::async_request_handler!(self, ctx, req, attestation_agent, BindInitDataRequest, bind_init_data); } } @@ -139,8 +139,8 @@ pub trait AttestationAgentService: Sync { async fn extend_runtime_measurement(&self, _ctx: &::ttrpc::r#async::TtrpcContext, _: super::attestation_agent::ExtendRuntimeMeasurementRequest) -> ::ttrpc::Result { Err(::ttrpc::Error::RpcStatus(::ttrpc::get_status(::ttrpc::Code::NOT_FOUND, "/attestation_agent.AttestationAgentService/ExtendRuntimeMeasurement is not supported".to_string()))) } - async fn check_init_data(&self, _ctx: &::ttrpc::r#async::TtrpcContext, _: super::attestation_agent::CheckInitDataRequest) -> ::ttrpc::Result { - Err(::ttrpc::Error::RpcStatus(::ttrpc::get_status(::ttrpc::Code::NOT_FOUND, "/attestation_agent.AttestationAgentService/CheckInitData is not supported".to_string()))) + async fn bind_init_data(&self, _ctx: &::ttrpc::r#async::TtrpcContext, _: super::attestation_agent::BindInitDataRequest) -> ::ttrpc::Result { + Err(::ttrpc::Error::RpcStatus(::ttrpc::get_status(::ttrpc::Code::NOT_FOUND, "/attestation_agent.AttestationAgentService/BindInitData is not supported".to_string()))) } async fn update_configuration(&self, _ctx: &::ttrpc::r#async::TtrpcContext, _: super::attestation_agent::UpdateConfigurationRequest) -> ::ttrpc::Result { Err(::ttrpc::Error::RpcStatus(::ttrpc::get_status(::ttrpc::Code::NOT_FOUND, "/attestation_agent.AttestationAgentService/UpdateConfiguration is not supported".to_string()))) @@ -164,8 +164,8 @@ pub fn create_attestation_agent_service(service: Arc); - methods.insert("CheckInitData".to_string(), - Box::new(CheckInitDataMethod{service: service.clone()}) as Box); + methods.insert("BindInitData".to_string(), + Box::new(BindInitDataMethod{service: service.clone()}) as Box); methods.insert("UpdateConfiguration".to_string(), Box::new(UpdateConfigurationMethod{service: service.clone()}) as Box); diff --git a/attestation-agent/attestation-agent/src/lib.rs b/attestation-agent/attestation-agent/src/lib.rs index fea8136a9..c41b7ca69 100644 --- a/attestation-agent/attestation-agent/src/lib.rs +++ b/attestation-agent/attestation-agent/src/lib.rs @@ -10,7 +10,7 @@ use kbs_types::Tee; use std::{io::Write, str::FromStr}; use tokio::sync::{Mutex, RwLock}; -pub use attester::InitdataResult; +pub use attester::InitDataResult; pub mod config; mod eventlog; @@ -32,8 +32,9 @@ use crate::config::Config; /// current hardware runtime measurement register (if any) or PCR for (v)TPM (under /// development) platforms /// with a runtime event. -/// - `check_init_data`: check if the given data slice matches the current confidential -/// computing environment's host data field, e.g. MRCONFIGID for TDX, HOSTDATA for SNP. +/// - `bind_init_data`: bind the given data slice to the current confidential +/// computing environment. This can be a verify operation or an extension of the TEE +/// evidence /// /// # Example /// @@ -69,8 +70,8 @@ pub trait AttestationAPIs { register_index: Option, ) -> Result<()>; - /// Check the initdata binding - async fn check_init_data(&self, init_data: &[u8]) -> Result; + /// Bind initdata + async fn bind_init_data(&self, init_data: &[u8]) -> Result; fn get_tee_type(&self) -> Tee; } @@ -233,10 +234,10 @@ impl AttestationAPIs for AttestationAgent { Ok(()) } - /// Check the initdata binding. If current platform does not support initdata - /// injection, return `InitdataResult::Unsupported`. - async fn check_init_data(&self, init_data: &[u8]) -> Result { - self.attester.check_init_data(init_data).await + /// Perform the initdata binding. If current platform does not support initdata + /// binding, return `InitdataResult::Unsupported`. + async fn bind_init_data(&self, init_data: &[u8]) -> Result { + self.attester.bind_init_data(init_data).await } /// Get the tee type of current platform. If no platform is detected, diff --git a/attestation-agent/attester/Cargo.toml b/attestation-agent/attester/Cargo.toml index a3603326b..c36b3b3b5 100644 --- a/attestation-agent/attester/Cargo.toml +++ b/attestation-agent/attester/Cargo.toml @@ -64,7 +64,7 @@ tsm-report = ["tempfile"] tdx-attester = ["scroll", "tsm-report", "tdx-attest-rs"] sgx-attester = ["occlum_dcap"] az-snp-vtpm-attester = ["az-snp-vtpm"] -az-tdx-vtpm-attester = ["az-tdx-vtpm"] +az-tdx-vtpm-attester = ["az-snp-vtpm-attester", "az-tdx-vtpm"] snp-attester = ["sev"] csv-attester = ["csv-rs", "codicon", "hyper", "hyper-tls", "tokio"] cca-attester = ["tsm-report"] diff --git a/attestation-agent/attester/src/az_snp_vtpm/mod.rs b/attestation-agent/attester/src/az_snp_vtpm/mod.rs index 709d3c7d4..c37d7f19c 100644 --- a/attestation-agent/attester/src/az_snp_vtpm/mod.rs +++ b/attestation-agent/attester/src/az_snp_vtpm/mod.rs @@ -3,7 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 // -use super::Attester; +use super::{Attester, InitDataResult}; use anyhow::{bail, Context, Result}; use az_snp_vtpm::{imds, is_snp_cvm, vtpm}; use log::{debug, info}; @@ -46,19 +46,31 @@ impl Attester for AzSnpVtpmAttester { Ok(serde_json::to_string(&evidence)?) } + async fn bind_init_data(&self, init_data_digest: &[u8]) -> anyhow::Result { + utils::extend_pcr(init_data_digest, utils::INIT_DATA_PCR)?; + Ok(InitDataResult::Ok) + } + async fn extend_runtime_measurement( &self, event_digest: Vec, register_index: u64, ) -> Result<()> { - let sha256_digest: [u8; 32] = event_digest - .as_slice() - .try_into() - .context("expected sha256 digest")?; - if register_index > 23 { - bail!("Invalid PCR index: {}", register_index); + utils::extend_pcr(&event_digest, register_index as u8)?; + Ok(()) + } +} + +pub(crate) mod utils { + use super::*; + + pub const INIT_DATA_PCR: u8 = 8; + + pub fn extend_pcr(digest: &[u8], pcr: u8) -> Result<()> { + let sha256_digest: [u8; 32] = digest.try_into().context("expected sha256 digest")?; + if pcr > 23 { + bail!("Invalid PCR index: {pcr}"); } - let pcr: u8 = register_index as u8; info!("Extending PCR {} with {}", pcr, hex::encode(sha256_digest)); vtpm::extend_pcr(pcr, &sha256_digest)?; diff --git a/attestation-agent/attester/src/az_tdx_vtpm/mod.rs b/attestation-agent/attester/src/az_tdx_vtpm/mod.rs index 5c281354f..173958a6d 100644 --- a/attestation-agent/attester/src/az_tdx_vtpm/mod.rs +++ b/attestation-agent/attester/src/az_tdx_vtpm/mod.rs @@ -3,11 +3,12 @@ // SPDX-License-Identifier: Apache-2.0 // -use super::Attester; +use super::{Attester, InitDataResult}; +use crate::az_snp_vtpm::utils; use anyhow::*; use az_tdx_vtpm::vtpm::Quote as TpmQuote; use az_tdx_vtpm::{hcl, imds, is_tdx_cvm, vtpm}; -use log::{debug, info}; +use log::debug; use serde::{Deserialize, Serialize}; use std::result::Result::Ok; @@ -49,22 +50,17 @@ impl Attester for AzTdxVtpmAttester { Ok(serde_json::to_string(&evidence)?) } + async fn bind_init_data(&self, init_data_digest: &[u8]) -> anyhow::Result { + utils::extend_pcr(init_data_digest, utils::INIT_DATA_PCR)?; + Ok(InitDataResult::Ok) + } + async fn extend_runtime_measurement( &self, event_digest: Vec, register_index: u64, ) -> Result<()> { - let sha256_digest: [u8; 32] = event_digest - .as_slice() - .try_into() - .context("expected sha256 digest")?; - if register_index > 23 { - bail!("Invalid PCR index: {}", register_index); - } - let pcr: u8 = register_index as u8; - info!("Extending PCR {} with {}", pcr, hex::encode(sha256_digest)); - vtpm::extend_pcr(pcr, &sha256_digest)?; - + utils::extend_pcr(&event_digest, register_index as u8)?; Ok(()) } } diff --git a/attestation-agent/attester/src/lib.rs b/attestation-agent/attester/src/lib.rs index 0c44e8bd1..090208998 100644 --- a/attestation-agent/attester/src/lib.rs +++ b/attestation-agent/attester/src/lib.rs @@ -67,7 +67,7 @@ impl TryFrom for BoxedAttester { } } -pub enum InitdataResult { +pub enum InitDataResult { Ok, Unsupported, } @@ -89,8 +89,8 @@ pub trait Attester { bail!("Unimplemented") } - async fn check_init_data(&self, _init_data: &[u8]) -> Result { - Ok(InitdataResult::Unsupported) + async fn bind_init_data(&self, _init_data_digest: &[u8]) -> Result { + Ok(InitDataResult::Unsupported) } } diff --git a/attestation-agent/attester/src/snp/mod.rs b/attestation-agent/attester/src/snp/mod.rs index 15f306433..d931d9d4b 100644 --- a/attestation-agent/attester/src/snp/mod.rs +++ b/attestation-agent/attester/src/snp/mod.rs @@ -4,7 +4,7 @@ // use crate::utils::pad; -use crate::InitdataResult; +use crate::InitDataResult; use super::Attester; use anyhow::*; @@ -53,13 +53,13 @@ impl Attester for SnpAttester { serde_json::to_string(&evidence).context("Serialize SNP evidence failed") } - async fn check_init_data(&self, init_data: &[u8]) -> Result { + async fn bind_init_data(&self, init_data_digest: &[u8]) -> Result { let hostdata = hostdata::get_snp_host_data().context("Get HOSTDATA failed")?; - let init_data: [u8; 32] = pad(init_data); + let init_data: [u8; 32] = pad(init_data_digest); if init_data != hostdata { bail!("HOSTDATA does not match."); } - Ok(InitdataResult::Ok) + Ok(InitDataResult::Ok) } } diff --git a/attestation-agent/attester/src/tdx/mod.rs b/attestation-agent/attester/src/tdx/mod.rs index 4269df765..7f99add51 100644 --- a/attestation-agent/attester/src/tdx/mod.rs +++ b/attestation-agent/attester/src/tdx/mod.rs @@ -8,7 +8,7 @@ use self::rtmr::TdxRtmrEvent; use super::tsm_report::*; use super::Attester; use crate::utils::pad; -use crate::InitdataResult; +use crate::InitDataResult; use anyhow::*; use base64::Engine; use scroll::Pread; @@ -157,7 +157,7 @@ impl Attester for TdxAttester { Ok(()) } - async fn check_init_data(&self, init_data: &[u8]) -> Result { + async fn bind_init_data(&self, init_data_digest: &[u8]) -> Result { let mut report = tdx_report_t { d: [0; 1024] }; match tdx_attest_rs::tdx_att_get_report(None, &mut report) { tdx_attest_rs::tdx_attest_error_t::TDX_ATTEST_SUCCESS => { @@ -176,12 +176,12 @@ impl Attester for TdxAttester { .pread::(0) .context("Parse TD report failed")?; - let init_data: [u8; 48] = pad(init_data); + let init_data: [u8; 48] = pad(init_data_digest); if init_data != td_report.tdinfo.mrconfigid { bail!("Init data does not match!"); } - Ok(InitdataResult::Ok) + Ok(InitDataResult::Ok) } } diff --git a/attestation-agent/kbs_protocol/src/token_provider/aa/attestation_agent.rs b/attestation-agent/kbs_protocol/src/token_provider/aa/attestation_agent.rs index 4b6cfcac1..5ce4693dc 100644 --- a/attestation-agent/kbs_protocol/src/token_provider/aa/attestation_agent.rs +++ b/attestation-agent/kbs_protocol/src/token_provider/aa/attestation_agent.rs @@ -931,25 +931,25 @@ impl ::protobuf::reflect::ProtobufValue for InitDataPlaintext { type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; } -// @@protoc_insertion_point(message:attestation_agent.CheckInitDataRequest) +// @@protoc_insertion_point(message:attestation_agent.BindInitDataRequest) #[derive(PartialEq,Clone,Default,Debug)] -pub struct CheckInitDataRequest { +pub struct BindInitDataRequest { // message fields - // @@protoc_insertion_point(field:attestation_agent.CheckInitDataRequest.Digest) + // @@protoc_insertion_point(field:attestation_agent.BindInitDataRequest.Digest) pub Digest: ::std::vec::Vec, // special fields - // @@protoc_insertion_point(special_field:attestation_agent.CheckInitDataRequest.special_fields) + // @@protoc_insertion_point(special_field:attestation_agent.BindInitDataRequest.special_fields) pub special_fields: ::protobuf::SpecialFields, } -impl<'a> ::std::default::Default for &'a CheckInitDataRequest { - fn default() -> &'a CheckInitDataRequest { - ::default_instance() +impl<'a> ::std::default::Default for &'a BindInitDataRequest { + fn default() -> &'a BindInitDataRequest { + ::default_instance() } } -impl CheckInitDataRequest { - pub fn new() -> CheckInitDataRequest { +impl BindInitDataRequest { + pub fn new() -> BindInitDataRequest { ::std::default::Default::default() } @@ -958,19 +958,19 @@ impl CheckInitDataRequest { let mut oneofs = ::std::vec::Vec::with_capacity(0); fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( "Digest", - |m: &CheckInitDataRequest| { &m.Digest }, - |m: &mut CheckInitDataRequest| { &mut m.Digest }, + |m: &BindInitDataRequest| { &m.Digest }, + |m: &mut BindInitDataRequest| { &mut m.Digest }, )); - ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( - "CheckInitDataRequest", + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "BindInitDataRequest", fields, oneofs, ) } } -impl ::protobuf::Message for CheckInitDataRequest { - const NAME: &'static str = "CheckInitDataRequest"; +impl ::protobuf::Message for BindInitDataRequest { + const NAME: &'static str = "BindInitDataRequest"; fn is_initialized(&self) -> bool { true @@ -1018,8 +1018,8 @@ impl ::protobuf::Message for CheckInitDataRequest { &mut self.special_fields } - fn new() -> CheckInitDataRequest { - CheckInitDataRequest::new() + fn new() -> BindInitDataRequest { + BindInitDataRequest::new() } fn clear(&mut self) { @@ -1027,8 +1027,8 @@ impl ::protobuf::Message for CheckInitDataRequest { self.special_fields.clear(); } - fn default_instance() -> &'static CheckInitDataRequest { - static instance: CheckInitDataRequest = CheckInitDataRequest { + fn default_instance() -> &'static BindInitDataRequest { + static instance: BindInitDataRequest = BindInitDataRequest { Digest: ::std::vec::Vec::new(), special_fields: ::protobuf::SpecialFields::new(), }; @@ -1036,55 +1036,55 @@ impl ::protobuf::Message for CheckInitDataRequest { } } -impl ::protobuf::MessageFull for CheckInitDataRequest { +impl ::protobuf::MessageFull for BindInitDataRequest { fn descriptor() -> ::protobuf::reflect::MessageDescriptor { static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); - descriptor.get(|| file_descriptor().message_by_package_relative_name("CheckInitDataRequest").unwrap()).clone() + descriptor.get(|| file_descriptor().message_by_package_relative_name("BindInitDataRequest").unwrap()).clone() } } -impl ::std::fmt::Display for CheckInitDataRequest { +impl ::std::fmt::Display for BindInitDataRequest { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for CheckInitDataRequest { +impl ::protobuf::reflect::ProtobufValue for BindInitDataRequest { type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; } -// @@protoc_insertion_point(message:attestation_agent.CheckInitDataResponse) +// @@protoc_insertion_point(message:attestation_agent.BindInitDataResponse) #[derive(PartialEq,Clone,Default,Debug)] -pub struct CheckInitDataResponse { +pub struct BindInitDataResponse { // special fields - // @@protoc_insertion_point(special_field:attestation_agent.CheckInitDataResponse.special_fields) + // @@protoc_insertion_point(special_field:attestation_agent.BindInitDataResponse.special_fields) pub special_fields: ::protobuf::SpecialFields, } -impl<'a> ::std::default::Default for &'a CheckInitDataResponse { - fn default() -> &'a CheckInitDataResponse { - ::default_instance() +impl<'a> ::std::default::Default for &'a BindInitDataResponse { + fn default() -> &'a BindInitDataResponse { + ::default_instance() } } -impl CheckInitDataResponse { - pub fn new() -> CheckInitDataResponse { +impl BindInitDataResponse { + pub fn new() -> BindInitDataResponse { ::std::default::Default::default() } fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { let mut fields = ::std::vec::Vec::with_capacity(0); let mut oneofs = ::std::vec::Vec::with_capacity(0); - ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( - "CheckInitDataResponse", + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "BindInitDataResponse", fields, oneofs, ) } } -impl ::protobuf::Message for CheckInitDataResponse { - const NAME: &'static str = "CheckInitDataResponse"; +impl ::protobuf::Message for BindInitDataResponse { + const NAME: &'static str = "BindInitDataResponse"; fn is_initialized(&self) -> bool { true @@ -1123,36 +1123,36 @@ impl ::protobuf::Message for CheckInitDataResponse { &mut self.special_fields } - fn new() -> CheckInitDataResponse { - CheckInitDataResponse::new() + fn new() -> BindInitDataResponse { + BindInitDataResponse::new() } fn clear(&mut self) { self.special_fields.clear(); } - fn default_instance() -> &'static CheckInitDataResponse { - static instance: CheckInitDataResponse = CheckInitDataResponse { + fn default_instance() -> &'static BindInitDataResponse { + static instance: BindInitDataResponse = BindInitDataResponse { special_fields: ::protobuf::SpecialFields::new(), }; &instance } } -impl ::protobuf::MessageFull for CheckInitDataResponse { +impl ::protobuf::MessageFull for BindInitDataResponse { fn descriptor() -> ::protobuf::reflect::MessageDescriptor { static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); - descriptor.get(|| file_descriptor().message_by_package_relative_name("CheckInitDataResponse").unwrap()).clone() + descriptor.get(|| file_descriptor().message_by_package_relative_name("BindInitDataResponse").unwrap()).clone() } } -impl ::std::fmt::Display for CheckInitDataResponse { +impl ::std::fmt::Display for BindInitDataResponse { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for CheckInitDataResponse { +impl ::protobuf::reflect::ProtobufValue for BindInitDataResponse { type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; } @@ -1618,23 +1618,23 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x07Content\x12)\n\rRegisterIndex\x18\x04\x20\x01(\x04H\0R\rRegisterInde\ x\x88\x01\x01B\x10\n\x0e_RegisterIndex\"\"\n\x20ExtendRuntimeMeasurement\ Response\"K\n\x11InitDataPlaintext\x12\x18\n\x07Content\x18\x01\x20\x01(\ - \x0cR\x07Content\x12\x1c\n\tAlgorithm\x18\x02\x20\x01(\tR\tAlgorithm\".\ - \n\x14CheckInitDataRequest\x12\x16\n\x06Digest\x18\x01\x20\x01(\x0cR\x06\ - Digest\"\x17\n\x15CheckInitDataResponse\"4\n\x1aUpdateConfigurationReque\ - st\x12\x16\n\x06config\x18\x01\x20\x01(\tR\x06config\"\x1d\n\x1bUpdateCo\ - nfigurationResponse\"\x13\n\x11GetTeeTypeRequest\"&\n\x12GetTeeTypeRespo\ - nse\x12\x10\n\x03tee\x18\x01\x20\x01(\tR\x03tee2\x87\x05\n\x17Attestatio\ - nAgentService\x12\\\n\x0bGetEvidence\x12%.attestation_agent.GetEvidenceR\ - equest\x1a&.attestation_agent.GetEvidenceResponse\x12S\n\x08GetToken\x12\ - \".attestation_agent.GetTokenRequest\x1a#.attestation_agent.GetTokenResp\ - onse\x12\x83\x01\n\x18ExtendRuntimeMeasurement\x122.attestation_agent.Ex\ - tendRuntimeMeasurementRequest\x1a3.attestation_agent.ExtendRuntimeMeasur\ - ementResponse\x12b\n\rCheckInitData\x12'.attestation_agent.CheckInitData\ - Request\x1a(.attestation_agent.CheckInitDataResponse\x12t\n\x13UpdateCon\ - figuration\x12-.attestation_agent.UpdateConfigurationRequest\x1a..attest\ - ation_agent.UpdateConfigurationResponse\x12Y\n\nGetTeeType\x12$.attestat\ - ion_agent.GetTeeTypeRequest\x1a%.attestation_agent.GetTeeTypeResponseb\ - \x06proto3\ + \x0cR\x07Content\x12\x1c\n\tAlgorithm\x18\x02\x20\x01(\tR\tAlgorithm\"-\ + \n\x13BindInitDataRequest\x12\x16\n\x06Digest\x18\x01\x20\x01(\x0cR\x06D\ + igest\"\x16\n\x14BindInitDataResponse\"4\n\x1aUpdateConfigurationRequest\ + \x12\x16\n\x06config\x18\x01\x20\x01(\tR\x06config\"\x1d\n\x1bUpdateConf\ + igurationResponse\"\x13\n\x11GetTeeTypeRequest\"&\n\x12GetTeeTypeRespons\ + e\x12\x10\n\x03tee\x18\x01\x20\x01(\tR\x03tee2\x84\x05\n\x17AttestationA\ + gentService\x12\\\n\x0bGetEvidence\x12%.attestation_agent.GetEvidenceReq\ + uest\x1a&.attestation_agent.GetEvidenceResponse\x12S\n\x08GetToken\x12\"\ + .attestation_agent.GetTokenRequest\x1a#.attestation_agent.GetTokenRespon\ + se\x12\x83\x01\n\x18ExtendRuntimeMeasurement\x122.attestation_agent.Exte\ + ndRuntimeMeasurementRequest\x1a3.attestation_agent.ExtendRuntimeMeasurem\ + entResponse\x12_\n\x0cBindInitData\x12&.attestation_agent.BindInitDataRe\ + quest\x1a'.attestation_agent.BindInitDataResponse\x12t\n\x13UpdateConfig\ + uration\x12-.attestation_agent.UpdateConfigurationRequest\x1a..attestati\ + on_agent.UpdateConfigurationResponse\x12Y\n\nGetTeeType\x12$.attestation\ + _agent.GetTeeTypeRequest\x1a%.attestation_agent.GetTeeTypeResponseb\x06p\ + roto3\ "; /// `FileDescriptorProto` object which was a source for this generated file @@ -1660,8 +1660,8 @@ pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor { messages.push(ExtendRuntimeMeasurementRequest::generated_message_descriptor_data()); messages.push(ExtendRuntimeMeasurementResponse::generated_message_descriptor_data()); messages.push(InitDataPlaintext::generated_message_descriptor_data()); - messages.push(CheckInitDataRequest::generated_message_descriptor_data()); - messages.push(CheckInitDataResponse::generated_message_descriptor_data()); + messages.push(BindInitDataRequest::generated_message_descriptor_data()); + messages.push(BindInitDataResponse::generated_message_descriptor_data()); messages.push(UpdateConfigurationRequest::generated_message_descriptor_data()); messages.push(UpdateConfigurationResponse::generated_message_descriptor_data()); messages.push(GetTeeTypeRequest::generated_message_descriptor_data()); diff --git a/attestation-agent/kbs_protocol/src/token_provider/aa/attestation_agent_ttrpc.rs b/attestation-agent/kbs_protocol/src/token_provider/aa/attestation_agent_ttrpc.rs index 85fe45a8f..735978670 100644 --- a/attestation-agent/kbs_protocol/src/token_provider/aa/attestation_agent_ttrpc.rs +++ b/attestation-agent/kbs_protocol/src/token_provider/aa/attestation_agent_ttrpc.rs @@ -46,9 +46,9 @@ impl AttestationAgentServiceClient { ::ttrpc::async_client_request!(self, ctx, req, "attestation_agent.AttestationAgentService", "ExtendRuntimeMeasurement", cres); } - pub async fn check_init_data(&self, ctx: ttrpc::context::Context, req: &super::attestation_agent::CheckInitDataRequest) -> ::ttrpc::Result { - let mut cres = super::attestation_agent::CheckInitDataResponse::new(); - ::ttrpc::async_client_request!(self, ctx, req, "attestation_agent.AttestationAgentService", "CheckInitData", cres); + pub async fn bind_init_data(&self, ctx: ttrpc::context::Context, req: &super::attestation_agent::BindInitDataRequest) -> ::ttrpc::Result { + let mut cres = super::attestation_agent::BindInitDataResponse::new(); + ::ttrpc::async_client_request!(self, ctx, req, "attestation_agent.AttestationAgentService", "BindInitData", cres); } pub async fn update_configuration(&self, ctx: ttrpc::context::Context, req: &super::attestation_agent::UpdateConfigurationRequest) -> ::ttrpc::Result { @@ -95,14 +95,14 @@ impl ::ttrpc::r#async::MethodHandler for ExtendRuntimeMeasurementMethod { } } -struct CheckInitDataMethod { +struct BindInitDataMethod { service: Arc, } #[async_trait] -impl ::ttrpc::r#async::MethodHandler for CheckInitDataMethod { +impl ::ttrpc::r#async::MethodHandler for BindInitDataMethod { async fn handler(&self, ctx: ::ttrpc::r#async::TtrpcContext, req: ::ttrpc::Request) -> ::ttrpc::Result<::ttrpc::Response> { - ::ttrpc::async_request_handler!(self, ctx, req, attestation_agent, CheckInitDataRequest, check_init_data); + ::ttrpc::async_request_handler!(self, ctx, req, attestation_agent, BindInitDataRequest, bind_init_data); } } @@ -139,8 +139,8 @@ pub trait AttestationAgentService: Sync { async fn extend_runtime_measurement(&self, _ctx: &::ttrpc::r#async::TtrpcContext, _: super::attestation_agent::ExtendRuntimeMeasurementRequest) -> ::ttrpc::Result { Err(::ttrpc::Error::RpcStatus(::ttrpc::get_status(::ttrpc::Code::NOT_FOUND, "/attestation_agent.AttestationAgentService/ExtendRuntimeMeasurement is not supported".to_string()))) } - async fn check_init_data(&self, _ctx: &::ttrpc::r#async::TtrpcContext, _: super::attestation_agent::CheckInitDataRequest) -> ::ttrpc::Result { - Err(::ttrpc::Error::RpcStatus(::ttrpc::get_status(::ttrpc::Code::NOT_FOUND, "/attestation_agent.AttestationAgentService/CheckInitData is not supported".to_string()))) + async fn bind_init_data(&self, _ctx: &::ttrpc::r#async::TtrpcContext, _: super::attestation_agent::BindInitDataRequest) -> ::ttrpc::Result { + Err(::ttrpc::Error::RpcStatus(::ttrpc::get_status(::ttrpc::Code::NOT_FOUND, "/attestation_agent.AttestationAgentService/BindInitData is not supported".to_string()))) } async fn update_configuration(&self, _ctx: &::ttrpc::r#async::TtrpcContext, _: super::attestation_agent::UpdateConfigurationRequest) -> ::ttrpc::Result { Err(::ttrpc::Error::RpcStatus(::ttrpc::get_status(::ttrpc::Code::NOT_FOUND, "/attestation_agent.AttestationAgentService/UpdateConfiguration is not supported".to_string()))) @@ -164,8 +164,8 @@ pub fn create_attestation_agent_service(service: Arc); - methods.insert("CheckInitData".to_string(), - Box::new(CheckInitDataMethod{service: service.clone()}) as Box); + methods.insert("BindInitData".to_string(), + Box::new(BindInitDataMethod{service: service.clone()}) as Box); methods.insert("UpdateConfiguration".to_string(), Box::new(UpdateConfigurationMethod{service: service.clone()}) as Box); diff --git a/attestation-agent/protos/attestation-agent.proto b/attestation-agent/protos/attestation-agent.proto index 665044cde..634b2681c 100644 --- a/attestation-agent/protos/attestation-agent.proto +++ b/attestation-agent/protos/attestation-agent.proto @@ -41,11 +41,11 @@ message InitDataPlaintext { string Algorithm = 2; } -message CheckInitDataRequest { +message BindInitDataRequest { bytes Digest = 1; } -message CheckInitDataResponse {} +message BindInitDataResponse {} message UpdateConfigurationRequest { string config = 1; @@ -63,7 +63,7 @@ service AttestationAgentService { rpc GetEvidence(GetEvidenceRequest) returns (GetEvidenceResponse) {}; rpc GetToken(GetTokenRequest) returns (GetTokenResponse) {}; rpc ExtendRuntimeMeasurement(ExtendRuntimeMeasurementRequest) returns (ExtendRuntimeMeasurementResponse) {}; - rpc CheckInitData(CheckInitDataRequest) returns (CheckInitDataResponse) {}; + rpc BindInitData(BindInitDataRequest) returns (BindInitDataResponse) {}; // This is a workaround API for initdata in CoCo. Once // a better design is implemented we can deprecate the API.