Skip to content

Commit

Permalink
attester: rename check_init_data => bind_init_data
Browse files Browse the repository at this point in the history
This change generalizes the concept of binding init_data to the TEE
evidence. In SNP and TDX attesters this currently happens via equality
checks on the HW report's HOSTDATA/MRCONFIGID fields.

On vTPM attester modules or other attesters which do not allow
setting similar fields, the binding can be performed by extending the
HW evidence.

Signed-off-by: Magnus Kulke <[email protected]>
  • Loading branch information
mkulke committed Oct 29, 2024
1 parent 962d4c2 commit 89da8e5
Show file tree
Hide file tree
Showing 13 changed files with 208 additions and 199 deletions.
20 changes: 10 additions & 10 deletions attestation-agent/attestation-agent/src/bin/grpc-aa/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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<CheckInitDataRequest>,
) -> Result<Response<CheckInitDataResponse>, Status> {
request: Request<BindInitDataRequest>,
) -> Result<Response<BindInitDataResponse>, 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))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -931,25 +931,25 @@ impl ::protobuf::reflect::ProtobufValue for InitDataPlaintext {
type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>;
}

// @@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<u8>,
// 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 {
<CheckInitDataRequest as ::protobuf::Message>::default_instance()
impl<'a> ::std::default::Default for &'a BindInitDataRequest {
fn default() -> &'a BindInitDataRequest {
<BindInitDataRequest as ::protobuf::Message>::default_instance()
}
}

impl CheckInitDataRequest {
pub fn new() -> CheckInitDataRequest {
impl BindInitDataRequest {
pub fn new() -> BindInitDataRequest {
::std::default::Default::default()
}

Expand All @@ -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>(
"CheckInitDataRequest",
::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<BindInitDataRequest>(
"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
Expand Down Expand Up @@ -1018,73 +1018,73 @@ impl ::protobuf::Message for CheckInitDataRequest {
&mut self.special_fields
}

fn new() -> CheckInitDataRequest {
CheckInitDataRequest::new()
fn new() -> BindInitDataRequest {
BindInitDataRequest::new()
}

fn clear(&mut self) {
self.Digest.clear();
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(),
};
&instance
}
}

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<Self>;
}

// @@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 {
<CheckInitDataResponse as ::protobuf::Message>::default_instance()
impl<'a> ::std::default::Default for &'a BindInitDataResponse {
fn default() -> &'a BindInitDataResponse {
<BindInitDataResponse as ::protobuf::Message>::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>(
"CheckInitDataResponse",
::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<BindInitDataResponse>(
"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
Expand Down Expand Up @@ -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<Self>;
}

Expand Down Expand Up @@ -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
Expand All @@ -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());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<super::attestation_agent::CheckInitDataResponse> {
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<super::attestation_agent::BindInitDataResponse> {
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<super::attestation_agent::UpdateConfigurationResponse> {
Expand Down Expand Up @@ -95,14 +95,14 @@ impl ::ttrpc::r#async::MethodHandler for ExtendRuntimeMeasurementMethod {
}
}

struct CheckInitDataMethod {
struct BindInitDataMethod {
service: Arc<dyn AttestationAgentService + Send + Sync>,
}

#[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);
}
}

Expand Down Expand Up @@ -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<super::attestation_agent::ExtendRuntimeMeasurementResponse> {
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<super::attestation_agent::CheckInitDataResponse> {
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<super::attestation_agent::BindInitDataResponse> {
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<super::attestation_agent::UpdateConfigurationResponse> {
Err(::ttrpc::Error::RpcStatus(::ttrpc::get_status(::ttrpc::Code::NOT_FOUND, "/attestation_agent.AttestationAgentService/UpdateConfiguration is not supported".to_string())))
Expand All @@ -164,8 +164,8 @@ pub fn create_attestation_agent_service(service: Arc<dyn AttestationAgentService
methods.insert("ExtendRuntimeMeasurement".to_string(),
Box::new(ExtendRuntimeMeasurementMethod{service: service.clone()}) as Box<dyn ::ttrpc::r#async::MethodHandler + Send + Sync>);

methods.insert("CheckInitData".to_string(),
Box::new(CheckInitDataMethod{service: service.clone()}) as Box<dyn ::ttrpc::r#async::MethodHandler + Send + Sync>);
methods.insert("BindInitData".to_string(),
Box::new(BindInitDataMethod{service: service.clone()}) as Box<dyn ::ttrpc::r#async::MethodHandler + Send + Sync>);

methods.insert("UpdateConfiguration".to_string(),
Box::new(UpdateConfigurationMethod{service: service.clone()}) as Box<dyn ::ttrpc::r#async::MethodHandler + Send + Sync>);
Expand Down
19 changes: 10 additions & 9 deletions attestation-agent/attestation-agent/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
///
Expand Down Expand Up @@ -69,8 +70,8 @@ pub trait AttestationAPIs {
register_index: Option<u64>,
) -> Result<()>;

/// Check the initdata binding
async fn check_init_data(&self, init_data: &[u8]) -> Result<InitdataResult>;
/// Bind initdata
async fn bind_init_data(&self, init_data: &[u8]) -> Result<InitDataResult>;

fn get_tee_type(&self) -> Tee;
}
Expand Down Expand Up @@ -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<InitdataResult> {
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<InitDataResult> {
self.attester.bind_init_data(init_data).await
}

/// Get the tee type of current platform. If no platform is detected,
Expand Down
Loading

0 comments on commit 89da8e5

Please sign in to comment.