Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AA: Add API to extend measurement register at runtime #392

Merged
merged 1 commit into from
Dec 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions attestation-agent/app/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,17 @@ use ttrpc_codegen::{Codegen, Customize, ProtobufCustomize};
fn main() -> std::io::Result<()> {
#[cfg(feature = "grpc")]
{
tonic_build::compile_protos("../protos/keyprovider.proto")?;
tonic_build::compile_protos("../protos/getresource.proto")?;
tonic_build::compile_protos("../protos/attestation-agent.proto")?;
tonic_build::configure()
.build_server(true)
.protoc_arg("--experimental_allow_proto3_optional")
.compile(
&[
"../protos/keyprovider.proto",
"../protos/getresource.proto",
"../protos/attestation-agent.proto",
],
&["../protos"],
Xynnn007 marked this conversation as resolved.
Show resolved Hide resolved
)?;
}

#[cfg(feature = "ttrpc")]
Expand Down
62 changes: 61 additions & 1 deletion attestation-agent/app/src/rpc/attestation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ pub mod grpc {
use attestation::attestation_agent_service_server::{
AttestationAgentService, AttestationAgentServiceServer,
};
use attestation::{GetEvidenceRequest, GetEvidenceResponse, GetTokenRequest, GetTokenResponse};
use attestation::{
ExtendRuntimeMeasurementRequest, ExtendRuntimeMeasurementResponse, GetEvidenceRequest,
GetEvidenceResponse, GetTokenRequest, GetTokenResponse,
};
use std::net::SocketAddr;
use tonic::{transport::Server, Request, Response, Status};

Expand Down Expand Up @@ -84,6 +87,35 @@ pub mod grpc {

Result::Ok(Response::new(reply))
}

async fn extend_runtime_measurement(
&self,
request: Request<ExtendRuntimeMeasurementRequest>,
) -> Result<Response<ExtendRuntimeMeasurementResponse>, Status> {
let request = request.into_inner();

let attestation_agent_mutex_clone = Arc::clone(&ASYNC_ATTESTATION_AGENT);
let mut attestation_agent = attestation_agent_mutex_clone.lock().await;

debug!("Call AA to extend runtime measurement ...");

attestation_agent
.extend_runtime_measurement(request.events, request.register_index)
.await
.map_err(|e| {
error!("Call AA to extend runtime measurement failed: {}", e);
Status::internal(format!(
"[ERROR:{}] AA extend runtime measurement failed: {}",
AGENT_NAME, e
))
})?;

debug!("Extend runtime measurement successfully!");

let reply = ExtendRuntimeMeasurementResponse {};

Result::Ok(Response::new(reply))
}
}

pub async fn start_grpc_service(socket: SocketAddr) -> Result<()> {
Expand Down Expand Up @@ -176,6 +208,34 @@ pub mod ttrpc {

::ttrpc::Result::Ok(reply)
}

async fn extend_runtime_measurement(
&self,
_ctx: &::ttrpc::r#async::TtrpcContext,
req: attestation_agent::ExtendRuntimeMeasurementRequest,
) -> ::ttrpc::Result<attestation_agent::ExtendRuntimeMeasurementResponse> {
debug!("Call AA to extend runtime measurement ...");

let attestation_agent_mutex_clone = ASYNC_ATTESTATION_AGENT.clone();
let mut attestation_agent = attestation_agent_mutex_clone.lock().await;

attestation_agent
.extend_runtime_measurement(req.Events, req.RegisterIndex)
.await
.map_err(|e| {
error!("Call AA to extend runtime measurement failed: {}", e);
let mut error_status = ::ttrpc::proto::Status::new();
error_status.set_code(Code::INTERNAL);
error_status.set_message(format!(
"[ERROR:{}] AA extend runtime measurement failed: {}",
AGENT_NAME, e
));
::ttrpc::Error::RpcStatus(error_status)
})?;

let reply = attestation_agent::ExtendRuntimeMeasurementResponse::new();
::ttrpc::Result::Ok(reply)
}
}

pub fn start_ttrpc_service() -> Result<HashMap<String, Service>> {
Expand Down
10 changes: 10 additions & 0 deletions attestation-agent/attester/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,16 @@ pub trait Attester {
/// The parameter `report_data` will be used as the user input of the
/// evidence to avoid reply attack.
async fn get_evidence(&self, report_data: Vec<u8>) -> Result<String>;

/// Extend TEE specific dynamic measurement register
/// to enable dynamic measurement capabilities for input data at runtime.
async fn extend_runtime_measurement(
&self,
_events: Vec<Vec<u8>>,
_register_index: Option<u64>,
) -> Result<()> {
bail!("Unimplemented")
}
}

// Detect which TEE platform the KBC running environment is.
Expand Down
22 changes: 22 additions & 0 deletions attestation-agent/attester/src/tdx/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,28 @@ impl Attester for TdxAttester {
serde_json::to_string(&evidence)
.map_err(|e| anyhow!("Serialize TDX evidence failed: {:?}", e))
}

async fn extend_runtime_measurement(
&self,
events: Vec<Vec<u8>>,
_register_index: Option<u64>,
) -> Result<()> {
for event in events {
match tdx_attest_rs::tdx_att_extend(&event) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The underlying tdx_att_extend function is defined in https://github.com/intel/SGXDataCenterAttestationPrimitives/blob/dcap_1.16_reproducible/QuoteGeneration/quote_wrapper/tdx_attest/tdx_attest.c#L477-L479

Do we need to specify a structured input of this function. In other words, will a random byte string work as an input here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jialez0 I think the commit message should be updated to reflect that this api is implemented only for TDX.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Xynnn007 good point, yes this is the expected struct:
https://github.com/intel/SGXDataCenterAttestationPrimitives/blob/5b320f93e16d0bebf700f2ce4bb5c63c4195bf58/QuoteGeneration/quote_wrapper/tdx_attest/tdx_attest.h#L89-L96

Now the event data itself should also follow a format so that we can verify it.
ACON uses an RTMR event log. @binxing can say more on that.
I don't think we need that event format in place for this PR, but this is a good reminder that we should start specifying it.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think a structured input is definitely necessary, otherwise the caller wouldn't have any idea what tdx_att_extend expects.

Maybe a bit off the topic. Have we ever considered keeping measurement logs for RTMRs? With logs, we can support more usages such as measuring the order in which the containers are started, or upgrading containers at runtime.

tdx_attest_rs::tdx_attest_error_t::TDX_ATTEST_SUCCESS => {
log::debug!("TDX extend runtime measurement succeeded.")
}
error_code => {
bail!(
"TDX Attester: Failed to extend RTMR. Error code: {:?}",
error_code
);
}
}
}

Ok(())
}
}

#[cfg(test)]
Expand Down
Loading
Loading