diff --git a/Makefile b/Makefile index c6bfa895d..728ddde6c 100644 --- a/Makefile +++ b/Makefile @@ -79,6 +79,13 @@ $(AA_BINARY): @echo build $(AA) for $(TEE_PLATFORM) cd $(AA) && $(MAKE) ttrpc=true ARCH=$(ARCH) LIBC=$(LIBC) ATTESTER=$(ATTESTER) +aa-docker-protobuf: + docker run --rm -it -v "$$PWD":/app --workdir /app rust:1.87 sh \ + -c "cd $(AA) && \ + apt -y update && \ + apt install -y tss2 libtss2-dev libtss2-esys-3.0.2-0 && \ + cargo build -p kbs_protocol -p attestation-agent" + $(ASR_BINARY): @echo build $(ASR) for $(TEE_PLATFORM) cd $(ASR) && $(MAKE) ARCH=$(ARCH) LIBC=$(LIBC) diff --git a/api-server-rest/build.rs b/api-server-rest/build.rs index 7d9b6afee..206cc86b0 100644 --- a/api-server-rest/build.rs +++ b/api-server-rest/build.rs @@ -61,6 +61,20 @@ fn _evidence() {} )] fn _resource() {} +#[utoipa::path( + post, + path = "/aa/derived_key", + request_body = Vec, + responses( + (status = 200, description = "success response", + content_type = "application/octet-stream", + body = Vec), + (status = 400, description = "invalid user data"), + (status = 500, description = "internal server error") + ) +)] +fn _derived_key() {} + fn generate_openapi_document() -> std::io::Result<()> { #[derive(OpenApi)] #[openapi( @@ -72,7 +86,7 @@ fn generate_openapi_document() -> std::io::Result<()> { (url = "http://127.0.0.1:8006", description = "CoCo Restful API") ), - paths(_token, _evidence, _resource) + paths(_token, _evidence, _resource, _derived_key) )] struct ApiDoc; let mut file = File::create("openapi/api.json")?; diff --git a/api-server-rest/openapi/api.json b/api-server-rest/openapi/api.json index c004d1783..a270b3d94 100644 --- a/api-server-rest/openapi/api.json +++ b/api-server-rest/openapi/api.json @@ -19,6 +19,50 @@ } ], "paths": { + "/aa/derived_key": { + "post": { + "tags": [], + "operationId": "_derived_key", + "requestBody": { + "content": { + "application/octet-stream": { + "schema": { + "type": "array", + "items": { + "type": "integer", + "format": "int32", + "minimum": 0 + } + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "success response", + "content": { + "application/octet-stream": { + "schema": { + "type": "array", + "items": { + "type": "integer", + "format": "int32", + "minimum": 0 + } + } + } + } + }, + "400": { + "description": "invalid user data" + }, + "500": { + "description": "internal server error" + } + } + } + }, "/aa/evidence": { "get": { "tags": [], diff --git a/api-server-rest/protos/attestation_agent.proto b/api-server-rest/protos/attestation_agent.proto index ec233db14..24d0afa6a 100644 --- a/api-server-rest/protos/attestation_agent.proto +++ b/api-server-rest/protos/attestation_agent.proto @@ -18,7 +18,16 @@ message GetTokenResponse { bytes Token = 1; } +message GetDerivedKeyRequest { + bytes KeyId = 1; +} + +message GetDerivedKeyResponse { + bytes DerivedKey = 1; +} + service AttestationAgentService { - rpc GetEvidence(GetEvidenceRequest) returns (GetEvidenceResponse) {}; - rpc GetToken(GetTokenRequest) returns (GetTokenResponse) {}; + rpc GetDerivedKey(GetDerivedKeyRequest) returns (GetDerivedKeyResponse) {}; + rpc GetEvidence(GetEvidenceRequest) returns (GetEvidenceResponse) {}; + rpc GetToken(GetTokenRequest) returns (GetTokenResponse) {}; } diff --git a/api-server-rest/src/aa.rs b/api-server-rest/src/aa.rs index 3c95b5333..e617028fb 100644 --- a/api-server-rest/src/aa.rs +++ b/api-server-rest/src/aa.rs @@ -4,7 +4,9 @@ // use crate::router::ApiHandler; -use crate::ttrpc_proto::attestation_agent::{GetEvidenceRequest, GetTokenRequest}; +use crate::ttrpc_proto::attestation_agent::{ + GetDerivedKeyRequest, GetEvidenceRequest, GetTokenRequest, +}; use crate::ttrpc_proto::attestation_agent_ttrpc::AttestationAgentServiceClient; use anyhow::*; use async_trait::async_trait; @@ -20,6 +22,7 @@ pub const AA_ROOT: &str = "/aa"; /// URL for querying CDH get resource API const AA_TOKEN_URL: &str = "/token"; const AA_EVIDENCE_URL: &str = "/evidence"; +const AA_DERIVED_KEY_URL: &str = "/derived_key"; pub struct AAClient { client: AttestationAgentServiceClient, @@ -50,34 +53,52 @@ impl ApiHandler for AAClient { .map(|v| form_urlencoded::parse(v.as_bytes()).into_owned().collect()) .unwrap_or_default(); - if params.len() != 1 { - return self.not_allowed(); + if params.len() == 0 { + match url_path { + AA_DERIVED_KEY_URL => { + let res = self.get_derived_key(); + match res.await { + std::result::Result::Ok(results) => { + return self.octet_stream_response(results) + } + Err(e) => return self.internal_error(e.to_string()), + }; + } + _ => { + return self.not_found(); + } + } } - match url_path { - AA_TOKEN_URL => match params.get("token_type") { - Some(token_type) => match self.get_token(token_type).await { - std::result::Result::Ok(results) => return self.octet_stream_response(results), - Err(e) => return self.internal_error(e.to_string()), - }, - None => return self.bad_request(), - }, - AA_EVIDENCE_URL => match params.get("runtime_data") { - Some(runtime_data) => { - match self.get_evidence(&runtime_data.clone().into_bytes()).await { + if params.len() == 1 { + match url_path { + AA_TOKEN_URL => match params.get("token_type") { + Some(token_type) => match self.get_token(token_type).await { std::result::Result::Ok(results) => { return self.octet_stream_response(results) } Err(e) => return self.internal_error(e.to_string()), + }, + None => return self.bad_request(), + }, + AA_EVIDENCE_URL => match params.get("runtime_data") { + Some(runtime_data) => { + match self.get_evidence(&runtime_data.clone().into_bytes()).await { + std::result::Result::Ok(results) => { + return self.octet_stream_response(results) + } + Err(e) => return self.internal_error(e.to_string()), + } } + None => return self.bad_request(), + }, + _ => { + return self.not_found(); } - None => return self.bad_request(), - }, - - _ => { - return self.not_found(); } } + + return self.not_found(); } } @@ -116,4 +137,15 @@ impl AAClient { .await?; Ok(res.Evidence) } + + pub async fn get_derived_key(&self) -> Result> { + let req = GetDerivedKeyRequest { + ..Default::default() + }; + let res = self + .client + .get_derived_key(ttrpc::context::with_timeout(TTRPC_TIMEOUT), &req) + .await?; + Ok(res.DerivedKey) + } } diff --git a/api-server-rest/src/ttrpc_proto/attestation_agent.rs b/api-server-rest/src/ttrpc_proto/attestation_agent.rs index ff9e89578..954b41305 100644 --- a/api-server-rest/src/ttrpc_proto/attestation_agent.rs +++ b/api-server-rest/src/ttrpc_proto/attestation_agent.rs @@ -512,16 +512,264 @@ impl ::protobuf::reflect::ProtobufValue for GetTokenResponse { type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; } +// @@protoc_insertion_point(message:attestation_agent.GetDerivedKeyRequest) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct GetDerivedKeyRequest { + // message fields + // @@protoc_insertion_point(field:attestation_agent.GetDerivedKeyRequest.KeyId) + pub KeyId: ::std::vec::Vec, + // special fields + // @@protoc_insertion_point(special_field:attestation_agent.GetDerivedKeyRequest.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a GetDerivedKeyRequest { + fn default() -> &'a GetDerivedKeyRequest { + ::default_instance() + } +} + +impl GetDerivedKeyRequest { + pub fn new() -> GetDerivedKeyRequest { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(1); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "KeyId", + |m: &GetDerivedKeyRequest| { &m.KeyId }, + |m: &mut GetDerivedKeyRequest| { &mut m.KeyId }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "GetDerivedKeyRequest", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for GetDerivedKeyRequest { + const NAME: &'static str = "GetDerivedKeyRequest"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.KeyId = is.read_bytes()?; + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if !self.KeyId.is_empty() { + my_size += ::protobuf::rt::bytes_size(1, &self.KeyId); + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if !self.KeyId.is_empty() { + os.write_bytes(1, &self.KeyId)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> GetDerivedKeyRequest { + GetDerivedKeyRequest::new() + } + + fn clear(&mut self) { + self.KeyId.clear(); + self.special_fields.clear(); + } + + fn default_instance() -> &'static GetDerivedKeyRequest { + static instance: GetDerivedKeyRequest = GetDerivedKeyRequest { + KeyId: ::std::vec::Vec::new(), + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for GetDerivedKeyRequest { + 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("GetDerivedKeyRequest").unwrap()).clone() + } +} + +impl ::std::fmt::Display for GetDerivedKeyRequest { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for GetDerivedKeyRequest { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + +// @@protoc_insertion_point(message:attestation_agent.GetDerivedKeyResponse) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct GetDerivedKeyResponse { + // message fields + // @@protoc_insertion_point(field:attestation_agent.GetDerivedKeyResponse.DerivedKey) + pub DerivedKey: ::std::vec::Vec, + // special fields + // @@protoc_insertion_point(special_field:attestation_agent.GetDerivedKeyResponse.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a GetDerivedKeyResponse { + fn default() -> &'a GetDerivedKeyResponse { + ::default_instance() + } +} + +impl GetDerivedKeyResponse { + pub fn new() -> GetDerivedKeyResponse { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(1); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "DerivedKey", + |m: &GetDerivedKeyResponse| { &m.DerivedKey }, + |m: &mut GetDerivedKeyResponse| { &mut m.DerivedKey }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "GetDerivedKeyResponse", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for GetDerivedKeyResponse { + const NAME: &'static str = "GetDerivedKeyResponse"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.DerivedKey = is.read_bytes()?; + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if !self.DerivedKey.is_empty() { + my_size += ::protobuf::rt::bytes_size(1, &self.DerivedKey); + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if !self.DerivedKey.is_empty() { + os.write_bytes(1, &self.DerivedKey)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> GetDerivedKeyResponse { + GetDerivedKeyResponse::new() + } + + fn clear(&mut self) { + self.DerivedKey.clear(); + self.special_fields.clear(); + } + + fn default_instance() -> &'static GetDerivedKeyResponse { + static instance: GetDerivedKeyResponse = GetDerivedKeyResponse { + DerivedKey: ::std::vec::Vec::new(), + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for GetDerivedKeyResponse { + 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("GetDerivedKeyResponse").unwrap()).clone() + } +} + +impl ::std::fmt::Display for GetDerivedKeyResponse { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for GetDerivedKeyResponse { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + static file_descriptor_proto_data: &'static [u8] = b"\ \n\x17attestation_agent.proto\x12\x11attestation_agent\"6\n\x12GetEviden\ ceRequest\x12\x20\n\x0bRuntimeData\x18\x01\x20\x01(\x0cR\x0bRuntimeData\ \"1\n\x13GetEvidenceResponse\x12\x1a\n\x08Evidence\x18\x01\x20\x01(\x0cR\ \x08Evidence\"/\n\x0fGetTokenRequest\x12\x1c\n\tTokenType\x18\x01\x20\ \x01(\tR\tTokenType\"(\n\x10GetTokenResponse\x12\x14\n\x05Token\x18\x01\ - \x20\x01(\x0cR\x05Token2\xcc\x01\n\x17AttestationAgentService\x12\\\n\ - \x0bGetEvidence\x12%.attestation_agent.GetEvidenceRequest\x1a&.attestati\ - on_agent.GetEvidenceResponse\x12S\n\x08GetToken\x12\".attestation_agent.\ - GetTokenRequest\x1a#.attestation_agent.GetTokenResponseb\x06proto3\ + \x20\x01(\x0cR\x05Token\",\n\x14GetDerivedKeyRequest\x12\x14\n\x05KeyId\ + \x18\x01\x20\x01(\x0cR\x05KeyId\"7\n\x15GetDerivedKeyResponse\x12\x1e\n\ + \nDerivedKey\x18\x01\x20\x01(\x0cR\nDerivedKey2\xb0\x02\n\x17Attestation\ + AgentService\x12b\n\rGetDerivedKey\x12'.attestation_agent.GetDerivedKeyR\ + equest\x1a(.attestation_agent.GetDerivedKeyResponse\x12\\\n\x0bGetEviden\ + ce\x12%.attestation_agent.GetEvidenceRequest\x1a&.attestation_agent.GetE\ + videnceResponse\x12S\n\x08GetToken\x12\".attestation_agent.GetTokenReque\ + st\x1a#.attestation_agent.GetTokenResponseb\x06proto3\ "; /// `FileDescriptorProto` object which was a source for this generated file @@ -539,11 +787,13 @@ pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor { file_descriptor.get(|| { let generated_file_descriptor = generated_file_descriptor_lazy.get(|| { let mut deps = ::std::vec::Vec::with_capacity(0); - let mut messages = ::std::vec::Vec::with_capacity(4); + let mut messages = ::std::vec::Vec::with_capacity(6); messages.push(GetEvidenceRequest::generated_message_descriptor_data()); messages.push(GetEvidenceResponse::generated_message_descriptor_data()); messages.push(GetTokenRequest::generated_message_descriptor_data()); messages.push(GetTokenResponse::generated_message_descriptor_data()); + messages.push(GetDerivedKeyRequest::generated_message_descriptor_data()); + messages.push(GetDerivedKeyResponse::generated_message_descriptor_data()); let mut enums = ::std::vec::Vec::with_capacity(0); ::protobuf::reflect::GeneratedFileDescriptor::new_generated( file_descriptor_proto(), diff --git a/api-server-rest/src/ttrpc_proto/attestation_agent_ttrpc.rs b/api-server-rest/src/ttrpc_proto/attestation_agent_ttrpc.rs index 0985c65ff..1fef9b722 100644 --- a/api-server-rest/src/ttrpc_proto/attestation_agent_ttrpc.rs +++ b/api-server-rest/src/ttrpc_proto/attestation_agent_ttrpc.rs @@ -31,6 +31,11 @@ impl AttestationAgentServiceClient { } } + pub async fn get_derived_key(&self, ctx: ttrpc::context::Context, req: &super::attestation_agent::GetDerivedKeyRequest) -> ::ttrpc::Result { + let mut cres = super::attestation_agent::GetDerivedKeyResponse::new(); + ::ttrpc::async_client_request!(self, ctx, req, "attestation_agent.AttestationAgentService", "GetDerivedKey", cres); + } + pub async fn get_evidence(&self, ctx: ttrpc::context::Context, req: &super::attestation_agent::GetEvidenceRequest) -> ::ttrpc::Result { let mut cres = super::attestation_agent::GetEvidenceResponse::new(); ::ttrpc::async_client_request!(self, ctx, req, "attestation_agent.AttestationAgentService", "GetEvidence", cres); @@ -42,6 +47,17 @@ impl AttestationAgentServiceClient { } } +struct GetDerivedKeyMethod { + service: Arc, +} + +#[async_trait] +impl ::ttrpc::r#async::MethodHandler for GetDerivedKeyMethod { + 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, GetDerivedKeyRequest, get_derived_key); + } +} + struct GetEvidenceMethod { service: Arc, } @@ -66,6 +82,9 @@ impl ::ttrpc::r#async::MethodHandler for GetTokenMethod { #[async_trait] pub trait AttestationAgentService: Sync { + async fn get_derived_key(&self, _ctx: &::ttrpc::r#async::TtrpcContext, _: super::attestation_agent::GetDerivedKeyRequest) -> ::ttrpc::Result { + Err(::ttrpc::Error::RpcStatus(::ttrpc::get_status(::ttrpc::Code::NOT_FOUND, "/attestation_agent.AttestationAgentService/GetDerivedKey is not supported".to_string()))) + } async fn get_evidence(&self, _ctx: &::ttrpc::r#async::TtrpcContext, _: super::attestation_agent::GetEvidenceRequest) -> ::ttrpc::Result { Err(::ttrpc::Error::RpcStatus(::ttrpc::get_status(::ttrpc::Code::NOT_FOUND, "/attestation_agent.AttestationAgentService/GetEvidence is not supported".to_string()))) } @@ -79,6 +98,9 @@ pub fn create_attestation_agent_service(service: Arc); + methods.insert("GetEvidence".to_string(), Box::new(GetEvidenceMethod{service: service.clone()}) as Box); 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 28ddc9546..463bd0d73 100644 --- a/attestation-agent/attestation-agent/src/bin/grpc-aa/server.rs +++ b/attestation-agent/attestation-agent/src/bin/grpc-aa/server.rs @@ -9,8 +9,9 @@ use attestation::attestation_agent_service_server::{ }; use attestation::{ BindInitDataRequest, BindInitDataResponse, ExtendRuntimeMeasurementRequest, - ExtendRuntimeMeasurementResponse, GetEvidenceRequest, GetEvidenceResponse, GetTeeTypeRequest, - GetTeeTypeResponse, GetTokenRequest, GetTokenResponse, + ExtendRuntimeMeasurementResponse, GetDerivedKeyRequest, GetDerivedKeyResponse, + GetEvidenceRequest, GetEvidenceResponse, GetTeeTypeRequest, GetTeeTypeResponse, + GetTokenRequest, GetTokenResponse, }; use attestation_agent::{AttestationAPIs, AttestationAgent}; use log::{debug, error}; @@ -130,6 +131,21 @@ impl AttestationAgentService for AA { Result::Ok(Response::new(reply)) } + async fn get_derived_key(&self) -> Result, Status> { + debug!("AA (grpc): get derived key ..."); + + let derived_key = self.inner.get_derived_key().await.map_err(|e| { + error!("AA (grpc): get derived key failed:\n{e:?}"); + Status::internal(format!("[ERROR:{AGENT_NAME}] AA get derived key failed")) + })?; + + debug!("AA (grpc): Get derived key successfully!"); + + let reply = GetDerivedKeyResponse { derived_key }; + + Result::Ok(Response::new(reply)) + } + async fn get_tee_type( &self, _request: Request, diff --git a/attestation-agent/attestation-agent/src/bin/ttrpc-aa-client.rs b/attestation-agent/attestation-agent/src/bin/ttrpc-aa-client.rs index 260796755..5de81ddd6 100644 --- a/attestation-agent/attestation-agent/src/bin/ttrpc-aa-client.rs +++ b/attestation-agent/attestation-agent/src/bin/ttrpc-aa-client.rs @@ -6,6 +6,7 @@ use base64::Engine; use clap::{arg, command, Args, Parser, Subcommand}; use const_format::concatcp; +use kbs_protocol::ttrpc_protos::attestation_agent::GetDerivedKeyRequest; use ttrpc::context; use ttrpc_dep::ttrpc_protocol::{ attestation_agent::{ @@ -54,6 +55,9 @@ enum Operation { /// Get attestation token GetToken(GetTokenArgs), + /// Get derived key + GetDerivedKey(GetDerivedKeyArgs), + /// Extend runtime measurement ExtendRuntimeMeasurement(ExtendRuntimeMeasurementArgs), } @@ -74,6 +78,10 @@ struct GetTokenArgs { token_type: String, } +#[derive(Args)] +#[command(author, version, about, long_about = None)] +struct GetDerivedKeyArgs {} + #[derive(Args)] #[command(author, version, about, long_about = None)] struct ExtendRuntimeMeasurementArgs { @@ -138,6 +146,17 @@ pub async fn main() { let token = String::from_utf8(res.Token).unwrap(); println!("{token}"); } + Operation::GetDerivedKey(get_derived_key_args) => { + let req = GetDerivedKeyRequest { + ..Default::default() + }; + let res = client + .get_derived_key(context::with_timeout(TIMEOUT), &req) + .await + .expect("request to AA"); + let key = String::from_utf8(res.Key).unwrap(); + println!("{key}"); + } Operation::ExtendRuntimeMeasurement(extend_runtime_measurement_args) => { let req = ExtendRuntimeMeasurementRequest { Domain: extend_runtime_measurement_args.domain, diff --git a/attestation-agent/attestation-agent/src/bin/ttrpc_dep/server.rs b/attestation-agent/attestation-agent/src/bin/ttrpc_dep/server.rs index 77d592b8d..317966650 100644 --- a/attestation-agent/attestation-agent/src/bin/ttrpc_dep/server.rs +++ b/attestation-agent/attestation-agent/src/bin/ttrpc_dep/server.rs @@ -10,9 +10,9 @@ use log::{debug, error}; use crate::ttrpc_dep::ttrpc_protocol::{ attestation_agent::{ - ExtendRuntimeMeasurementRequest, ExtendRuntimeMeasurementResponse, GetEvidenceRequest, - GetEvidenceResponse, GetTeeTypeRequest, GetTeeTypeResponse, GetTokenRequest, - GetTokenResponse, + ExtendRuntimeMeasurementRequest, ExtendRuntimeMeasurementResponse, GetDerivedKeyRequest, + GetDerivedKeyResponse, GetEvidenceRequest, GetEvidenceResponse, GetTeeTypeRequest, + GetTeeTypeResponse, GetTokenRequest, GetTokenResponse, }, attestation_agent_ttrpc::AttestationAgentService, }; @@ -78,6 +78,35 @@ impl AttestationAgentService for AA { ::ttrpc::Result::Ok(reply) } + async fn get_derived_key( + &self, + _ctx: &::ttrpc::r#async::TtrpcContext, + req: GetDerivedKeyRequest, + ) -> ::ttrpc::Result { + debug!("AA (ttrpc): get derived key ..."); + + let empty_context = Vec::new(); + let derived_key = self + .inner + .get_derived_key(empty_context) + .await + .map_err(|e| { + error!("AA (ttrpc): get derived key failed:\n {e:?}"); + let mut error_status = ::ttrpc::proto::Status::new(); + error_status.set_code(Code::INTERNAL); + error_status + .set_message("[ERROR:{AGENT_NAME}] AA-KBC get derived key failed.".to_string()); + ::ttrpc::Error::RpcStatus(error_status) + })?; + + debug!("AA (ttrpc): Get derived key successfully!"); + + let mut reply = GetDerivedKeyResponse::new(); + reply.DerivedKey = derived_key; + + ::ttrpc::Result::Ok(reply) + } + async fn extend_runtime_measurement( &self, _ctx: &::ttrpc::r#async::TtrpcContext, diff --git a/attestation-agent/attestation-agent/src/bin/ttrpc_dep/ttrpc_protocol/attestation_agent_ttrpc.rs b/attestation-agent/attestation-agent/src/bin/ttrpc_dep/ttrpc_protocol/attestation_agent_ttrpc.rs index b087791b7..93d8b77ba 100644 --- a/attestation-agent/attestation-agent/src/bin/ttrpc_dep/ttrpc_protocol/attestation_agent_ttrpc.rs +++ b/attestation-agent/attestation-agent/src/bin/ttrpc_dep/ttrpc_protocol/attestation_agent_ttrpc.rs @@ -55,6 +55,11 @@ impl AttestationAgentServiceClient { let mut cres = super::attestation_agent::GetTeeTypeResponse::new(); ::ttrpc::async_client_request!(self, ctx, req, "attestation_agent.AttestationAgentService", "GetTeeType", cres); } + + pub async fn get_derived_key(&self, ctx: ttrpc::context::Context, req: &super::attestation_agent::GetDerivedKeyRequest) -> ::ttrpc::Result { + let mut cres = super::attestation_agent::GetDerivedKeyResponse::new(); + ::ttrpc::async_client_request!(self, ctx, req, "attestation_agent.AttestationAgentService", "GetDerivedKey", cres); + } } struct GetEvidenceMethod { diff --git a/attestation-agent/attestation-agent/src/lib.rs b/attestation-agent/attestation-agent/src/lib.rs index 392bc86db..d6c39ee33 100644 --- a/attestation-agent/attestation-agent/src/lib.rs +++ b/attestation-agent/attestation-agent/src/lib.rs @@ -60,6 +60,9 @@ pub trait AttestationAPIs { /// Get TEE hardware signed evidence that includes the runtime data. async fn get_evidence(&self, runtime_data: &[u8]) -> Result>; + /// Get a derived key + async fn get_derived_key(&self, context: Vec) -> Result>; + /// Extend runtime measurement register async fn extend_runtime_measurement( &self, @@ -175,6 +178,10 @@ impl AttestationAPIs for AttestationAgent { Ok(evidence.into_bytes()) } + async fn get_derived_key(&self, context: Vec) -> Result> { + self.attester.get_derived_key(context).await + } + /// Extend runtime measurement register. Parameters /// - `events`: a event slice. Any single event will be calculated into a hash digest to extend the current /// platform's RTMR. diff --git a/attestation-agent/attester/src/lib.rs b/attestation-agent/attester/src/lib.rs index 5ecb69daf..df3cf4ac6 100644 --- a/attestation-agent/attester/src/lib.rs +++ b/attestation-agent/attester/src/lib.rs @@ -99,6 +99,12 @@ pub trait Attester { async fn get_runtime_measurement(&self, _pcr_index: u64) -> Result> { bail!("Unimplemented") } + + /// Get a derived key using the hardware-specific key derivation function. + /// The parameter `root_key_hinit` `context` is data potentially used in the derivation process. + async fn get_derived_key(&self, _context: Vec) -> Result> { + bail!("Unimplemented") + } } // Detect which TEE platform the KBC running environment is. diff --git a/attestation-agent/attester/src/snp/mod.rs b/attestation-agent/attester/src/snp/mod.rs index 83fdd5c1a..c61df056f 100644 --- a/attestation-agent/attester/src/snp/mod.rs +++ b/attestation-agent/attester/src/snp/mod.rs @@ -10,7 +10,9 @@ use super::Attester; use anyhow::*; use serde::{Deserialize, Serialize}; use sev::firmware::guest::AttestationReport; +use sev::firmware::guest::DerivedKey; use sev::firmware::guest::Firmware; +use sev::firmware::guest::GuestFieldSelect; use sev::firmware::host::CertTableEntry; use std::path::Path; @@ -63,4 +65,39 @@ impl Attester for SnpAttester { Ok(InitDataResult::Ok) } + + async fn get_derived_key(&self, mut context: Vec) -> Result> { + if context.len() > 64 { + bail!("SNP Attester: Context must be no more than 64 bytes"); + } + + context.resize(64, 0); + + let mut firmware: Firmware = Firmware::open()?; + + // Create DerivedKey request with the documented parameters + // + // GuestFieldSelect values below can be: + // 0 > GUEST_POLICY > Indicates that the guest policy will be mixed into the key. + // 1 > IMAGE_ID > Indicates that the image ID of the guest will be mixed into the key. + // 2 > FAMILY_ID > Indicates the family ID of the guest will be mixed into the key. + // 3 > MEASUREMENT > Indicates the measurement of the guest during launch will be mixed into the key. + // 4 > GUEST_SVN > Indicates that the guest-provided SVN will be mixed into the key. + // 5 > TCB_VERSION > Indicates that the guest-provided TCB_VERSION will be mixed into the key. + // https://docs.rs/sev/4.0.0/sev/firmware/guest/struct.GuestFieldSelect.html + // + let request = DerivedKey::new( + false, // mixed_svn + GuestFieldSelect(3), // fields to include in the derived_key + 0, // tcb_version + 0, // platform_info + 0, // author_key_en + ); + + let derived_key = firmware + .get_derived_key(None, request) + .context("Failed to get derived key")?; + + Ok(derived_key.to_vec()) + } } diff --git a/attestation-agent/kbs_protocol/src/error.rs b/attestation-agent/kbs_protocol/src/error.rs index 15cbb4fac..a0b2d8493 100644 --- a/attestation-agent/kbs_protocol/src/error.rs +++ b/attestation-agent/kbs_protocol/src/error.rs @@ -24,6 +24,9 @@ pub enum Error { #[error("get evidence failed: {0}")] GetEvidence(String), + #[error("get derived key failed: {0}")] + GetDerivedKey(String), + #[error("get token failed: {0}")] GetTokenFailed(String), diff --git a/attestation-agent/kbs_protocol/src/evidence_provider/aa_ttrpc.rs b/attestation-agent/kbs_protocol/src/evidence_provider/aa_ttrpc.rs index 79d35cfc1..2f15ae35f 100644 --- a/attestation-agent/kbs_protocol/src/evidence_provider/aa_ttrpc.rs +++ b/attestation-agent/kbs_protocol/src/evidence_provider/aa_ttrpc.rs @@ -10,7 +10,7 @@ use ttrpc::context; use crate::{ ttrpc_protos::{ - attestation_agent::{GetEvidenceRequest, GetTeeTypeRequest}, + attestation_agent::{GetDerivedKeyRequest, GetEvidenceRequest, GetTeeTypeRequest}, attestation_agent_ttrpc::AttestationAgentServiceClient, }, Error, Result, @@ -39,6 +39,22 @@ impl AAEvidenceProvider { #[async_trait] impl EvidenceProvider for AAEvidenceProvider { + /// Get derived key using the provided key ID + async fn get_derived_key(&self, _context: Vec) -> Result> { + let req = GetDerivedKeyRequest { + ..Default::default() + }; + let res = self + .client + .get_derived_key( + context::with_timeout(AA_TTRPC_TIMEOUT_SECONDS * 1000 * 1000 * 1000), + &req, + ) + .await + .map_err(|e| Error::AAEvidenceProvider(format!("call ttrpc failed: {e}")))?; + Ok(res.DerivedKey) + } + /// Get evidence with as runtime data (report data, challege) async fn get_evidence(&self, runtime_data: Vec) -> Result { let req = GetEvidenceRequest { diff --git a/attestation-agent/kbs_protocol/src/evidence_provider/mock.rs b/attestation-agent/kbs_protocol/src/evidence_provider/mock.rs index 83003e987..082e0d277 100644 --- a/attestation-agent/kbs_protocol/src/evidence_provider/mock.rs +++ b/attestation-agent/kbs_protocol/src/evidence_provider/mock.rs @@ -19,6 +19,10 @@ impl EvidenceProvider for MockedEvidenceProvider { Ok("test evidence".into()) } + async fn get_derived_key(&self, _context: Vec) -> Result> { + Ok(vec![0u8; 32]) // Return a mock 32-byte key filled with zeros + } + async fn get_tee_type(&self) -> Result { Ok(Tee::Sample) } diff --git a/attestation-agent/kbs_protocol/src/evidence_provider/mod.rs b/attestation-agent/kbs_protocol/src/evidence_provider/mod.rs index 404f4c51d..b5832f400 100644 --- a/attestation-agent/kbs_protocol/src/evidence_provider/mod.rs +++ b/attestation-agent/kbs_protocol/src/evidence_provider/mod.rs @@ -25,4 +25,8 @@ pub trait EvidenceProvider: Send + Sync { /// Get the underlying Tee type async fn get_tee_type(&self) -> Result; + + /// Get a derived key using the hardware-specific key derivation function. + /// The parameter `context` is data potentially used in the derivation process. + async fn get_derived_key(&self, context: Vec) -> Result>; } diff --git a/attestation-agent/kbs_protocol/src/evidence_provider/native.rs b/attestation-agent/kbs_protocol/src/evidence_provider/native.rs index bff0a58c0..8760a2d4b 100644 --- a/attestation-agent/kbs_protocol/src/evidence_provider/native.rs +++ b/attestation-agent/kbs_protocol/src/evidence_provider/native.rs @@ -34,4 +34,11 @@ impl EvidenceProvider for NativeEvidenceProvider { async fn get_tee_type(&self) -> Result { Ok(detect_tee_type()) } + + async fn get_derived_key(&self, context: Vec) -> Result> { + self.0 + .get_derived_key(context) + .await + .map_err(|e| Error::GetDerivedKey(e.to_string())) + } } diff --git a/attestation-agent/kbs_protocol/src/ttrpc_protos/attestation_agent.rs b/attestation-agent/kbs_protocol/src/ttrpc_protos/attestation_agent.rs index 1d6719648..10ba5418c 100644 --- a/attestation-agent/kbs_protocol/src/ttrpc_protos/attestation_agent.rs +++ b/attestation-agent/kbs_protocol/src/ttrpc_protos/attestation_agent.rs @@ -512,6 +512,231 @@ impl ::protobuf::reflect::ProtobufValue for GetTokenResponse { type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; } +// @@protoc_insertion_point(message:attestation_agent.GetDerivedKeyRequest) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct GetDerivedKeyRequest { + // special fields + // @@protoc_insertion_point(special_field:attestation_agent.GetDerivedKeyRequest.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a GetDerivedKeyRequest { + fn default() -> &'a GetDerivedKeyRequest { + ::default_instance() + } +} + +impl GetDerivedKeyRequest { + pub fn new() -> GetDerivedKeyRequest { + ::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::( + "GetDerivedKeyRequest", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for GetDerivedKeyRequest { + const NAME: &'static str = "GetDerivedKeyRequest"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> GetDerivedKeyRequest { + GetDerivedKeyRequest::new() + } + + fn clear(&mut self) { + self.special_fields.clear(); + } + + fn default_instance() -> &'static GetDerivedKeyRequest { + static instance: GetDerivedKeyRequest = GetDerivedKeyRequest { + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for GetDerivedKeyRequest { + 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("GetDerivedKeyRequest").unwrap()).clone() + } +} + +impl ::std::fmt::Display for GetDerivedKeyRequest { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for GetDerivedKeyRequest { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + +// @@protoc_insertion_point(message:attestation_agent.GetDerivedKeyResponse) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct GetDerivedKeyResponse { + // message fields + // @@protoc_insertion_point(field:attestation_agent.GetDerivedKeyResponse.DerivedKey) + pub DerivedKey: ::std::vec::Vec, + // special fields + // @@protoc_insertion_point(special_field:attestation_agent.GetDerivedKeyResponse.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a GetDerivedKeyResponse { + fn default() -> &'a GetDerivedKeyResponse { + ::default_instance() + } +} + +impl GetDerivedKeyResponse { + pub fn new() -> GetDerivedKeyResponse { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(1); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "DerivedKey", + |m: &GetDerivedKeyResponse| { &m.DerivedKey }, + |m: &mut GetDerivedKeyResponse| { &mut m.DerivedKey }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "GetDerivedKeyResponse", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for GetDerivedKeyResponse { + const NAME: &'static str = "GetDerivedKeyResponse"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.DerivedKey = is.read_bytes()?; + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if !self.DerivedKey.is_empty() { + my_size += ::protobuf::rt::bytes_size(1, &self.DerivedKey); + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if !self.DerivedKey.is_empty() { + os.write_bytes(1, &self.DerivedKey)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> GetDerivedKeyResponse { + GetDerivedKeyResponse::new() + } + + fn clear(&mut self) { + self.DerivedKey.clear(); + self.special_fields.clear(); + } + + fn default_instance() -> &'static GetDerivedKeyResponse { + static instance: GetDerivedKeyResponse = GetDerivedKeyResponse { + DerivedKey: ::std::vec::Vec::new(), + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for GetDerivedKeyResponse { + 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("GetDerivedKeyResponse").unwrap()).clone() + } +} + +impl ::std::fmt::Display for GetDerivedKeyResponse { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for GetDerivedKeyResponse { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + // @@protoc_insertion_point(message:attestation_agent.ExtendRuntimeMeasurementRequest) #[derive(PartialEq,Clone,Default,Debug)] pub struct ExtendRuntimeMeasurementRequest { @@ -1387,25 +1612,28 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \"1\n\x13GetEvidenceResponse\x12\x1a\n\x08Evidence\x18\x01\x20\x01(\x0cR\ \x08Evidence\"/\n\x0fGetTokenRequest\x12\x1c\n\tTokenType\x18\x01\x20\ \x01(\tR\tTokenType\"(\n\x10GetTokenResponse\x12\x14\n\x05Token\x18\x01\ - \x20\x01(\x0cR\x05Token\"\xae\x01\n\x1fExtendRuntimeMeasurementRequest\ - \x12\x16\n\x06Domain\x18\x01\x20\x01(\tR\x06Domain\x12\x1c\n\tOperation\ - \x18\x02\x20\x01(\tR\tOperation\x12\x18\n\x07Content\x18\x03\x20\x01(\tR\ - \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\x13BindInitDataRequest\x12\x16\n\x06Digest\x18\x01\x20\x01(\x0cR\x06D\ - igest\"\x16\n\x14BindInitDataResponse\"\x13\n\x11GetTeeTypeRequest\"&\n\ - \x12GetTeeTypeResponse\x12\x10\n\x03tee\x18\x01\x20\x01(\tR\x03tee2\x8e\ - \x04\n\x17AttestationAgentService\x12\\\n\x0bGetEvidence\x12%.attestatio\ - n_agent.GetEvidenceRequest\x1a&.attestation_agent.GetEvidenceResponse\ - \x12S\n\x08GetToken\x12\".attestation_agent.GetTokenRequest\x1a#.attesta\ - tion_agent.GetTokenResponse\x12\x83\x01\n\x18ExtendRuntimeMeasurement\ - \x122.attestation_agent.ExtendRuntimeMeasurementRequest\x1a3.attestation\ - _agent.ExtendRuntimeMeasurementResponse\x12_\n\x0cBindInitData\x12&.atte\ - station_agent.BindInitDataRequest\x1a'.attestation_agent.BindInitDataRes\ - ponse\x12Y\n\nGetTeeType\x12$.attestation_agent.GetTeeTypeRequest\x1a%.a\ - ttestation_agent.GetTeeTypeResponseb\x06proto3\ + \x20\x01(\x0cR\x05Token\"\x16\n\x14GetDerivedKeyRequest\"7\n\x15GetDeriv\ + edKeyResponse\x12\x1e\n\nDerivedKey\x18\x01\x20\x01(\x0cR\nDerivedKey\"\ + \xae\x01\n\x1fExtendRuntimeMeasurementRequest\x12\x16\n\x06Domain\x18\ + \x01\x20\x01(\tR\x06Domain\x12\x1c\n\tOperation\x18\x02\x20\x01(\tR\tOpe\ + ration\x12\x18\n\x07Content\x18\x03\x20\x01(\tR\x07Content\x12)\n\rRegis\ + terIndex\x18\x04\x20\x01(\x04H\0R\rRegisterIndex\x88\x01\x01B\x10\n\x0e_\ + RegisterIndex\"\"\n\x20ExtendRuntimeMeasurementResponse\"K\n\x11InitData\ + Plaintext\x12\x18\n\x07Content\x18\x01\x20\x01(\x0cR\x07Content\x12\x1c\ + \n\tAlgorithm\x18\x02\x20\x01(\tR\tAlgorithm\"-\n\x13BindInitDataRequest\ + \x12\x16\n\x06Digest\x18\x01\x20\x01(\x0cR\x06Digest\"\x16\n\x14BindInit\ + DataResponse\"\x13\n\x11GetTeeTypeRequest\"&\n\x12GetTeeTypeResponse\x12\ + \x10\n\x03tee\x18\x01\x20\x01(\tR\x03tee2\xf2\x04\n\x17AttestationAgentS\ + ervice\x12b\n\rGetDerivedKey\x12'.attestation_agent.GetDerivedKeyRequest\ + \x1a(.attestation_agent.GetDerivedKeyResponse\x12\\\n\x0bGetEvidence\x12\ + %.attestation_agent.GetEvidenceRequest\x1a&.attestation_agent.GetEvidenc\ + eResponse\x12S\n\x08GetToken\x12\".attestation_agent.GetTokenRequest\x1a\ + #.attestation_agent.GetTokenResponse\x12\x83\x01\n\x18ExtendRuntimeMeasu\ + rement\x122.attestation_agent.ExtendRuntimeMeasurementRequest\x1a3.attes\ + tation_agent.ExtendRuntimeMeasurementResponse\x12_\n\x0cBindInitData\x12\ + &.attestation_agent.BindInitDataRequest\x1a'.attestation_agent.BindInitD\ + ataResponse\x12Y\n\nGetTeeType\x12$.attestation_agent.GetTeeTypeRequest\ + \x1a%.attestation_agent.GetTeeTypeResponseb\x06proto3\ "; /// `FileDescriptorProto` object which was a source for this generated file @@ -1423,11 +1651,13 @@ pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor { file_descriptor.get(|| { let generated_file_descriptor = generated_file_descriptor_lazy.get(|| { let mut deps = ::std::vec::Vec::with_capacity(0); - let mut messages = ::std::vec::Vec::with_capacity(11); + let mut messages = ::std::vec::Vec::with_capacity(13); messages.push(GetEvidenceRequest::generated_message_descriptor_data()); messages.push(GetEvidenceResponse::generated_message_descriptor_data()); messages.push(GetTokenRequest::generated_message_descriptor_data()); messages.push(GetTokenResponse::generated_message_descriptor_data()); + messages.push(GetDerivedKeyRequest::generated_message_descriptor_data()); + messages.push(GetDerivedKeyResponse::generated_message_descriptor_data()); messages.push(ExtendRuntimeMeasurementRequest::generated_message_descriptor_data()); messages.push(ExtendRuntimeMeasurementResponse::generated_message_descriptor_data()); messages.push(InitDataPlaintext::generated_message_descriptor_data()); diff --git a/attestation-agent/kbs_protocol/src/ttrpc_protos/attestation_agent_ttrpc.rs b/attestation-agent/kbs_protocol/src/ttrpc_protos/attestation_agent_ttrpc.rs index b087791b7..75d16aaef 100644 --- a/attestation-agent/kbs_protocol/src/ttrpc_protos/attestation_agent_ttrpc.rs +++ b/attestation-agent/kbs_protocol/src/ttrpc_protos/attestation_agent_ttrpc.rs @@ -31,6 +31,11 @@ impl AttestationAgentServiceClient { } } + pub async fn get_derived_key(&self, ctx: ttrpc::context::Context, req: &super::attestation_agent::GetDerivedKeyRequest) -> ::ttrpc::Result { + let mut cres = super::attestation_agent::GetDerivedKeyResponse::new(); + ::ttrpc::async_client_request!(self, ctx, req, "attestation_agent.AttestationAgentService", "GetDerivedKey", cres); + } + pub async fn get_evidence(&self, ctx: ttrpc::context::Context, req: &super::attestation_agent::GetEvidenceRequest) -> ::ttrpc::Result { let mut cres = super::attestation_agent::GetEvidenceResponse::new(); ::ttrpc::async_client_request!(self, ctx, req, "attestation_agent.AttestationAgentService", "GetEvidence", cres); @@ -57,6 +62,17 @@ impl AttestationAgentServiceClient { } } +struct GetDerivedKeyMethod { + service: Arc, +} + +#[async_trait] +impl ::ttrpc::r#async::MethodHandler for GetDerivedKeyMethod { + 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, GetDerivedKeyRequest, get_derived_key); + } +} + struct GetEvidenceMethod { service: Arc, } @@ -114,6 +130,9 @@ impl ::ttrpc::r#async::MethodHandler for GetTeeTypeMethod { #[async_trait] pub trait AttestationAgentService: Sync { + async fn get_derived_key(&self, _ctx: &::ttrpc::r#async::TtrpcContext, _: super::attestation_agent::GetDerivedKeyRequest) -> ::ttrpc::Result { + Err(::ttrpc::Error::RpcStatus(::ttrpc::get_status(::ttrpc::Code::NOT_FOUND, "/attestation_agent.AttestationAgentService/GetDerivedKey is not supported".to_string()))) + } async fn get_evidence(&self, _ctx: &::ttrpc::r#async::TtrpcContext, _: super::attestation_agent::GetEvidenceRequest) -> ::ttrpc::Result { Err(::ttrpc::Error::RpcStatus(::ttrpc::get_status(::ttrpc::Code::NOT_FOUND, "/attestation_agent.AttestationAgentService/GetEvidence is not supported".to_string()))) } @@ -136,6 +155,9 @@ pub fn create_attestation_agent_service(service: Arc); + methods.insert("GetEvidence".to_string(), Box::new(GetEvidenceMethod{service: service.clone()}) as Box); diff --git a/attestation-agent/protos/attestation-agent.proto b/attestation-agent/protos/attestation-agent.proto index cbd6c6c9b..c18bd90a7 100644 --- a/attestation-agent/protos/attestation-agent.proto +++ b/attestation-agent/protos/attestation-agent.proto @@ -18,6 +18,12 @@ message GetTokenResponse { bytes Token = 1; } +message GetDerivedKeyRequest {} + +message GetDerivedKeyResponse { + bytes DerivedKey = 1; +} + // Extend the dynamic/runtime measurement with given materials. This would change the state // of current TEE's status, e.g. TDX's RTMR, (v)TPM's PCR, by adding a record in eventlog. message ExtendRuntimeMeasurementRequest { @@ -54,6 +60,7 @@ message GetTeeTypeResponse { } service AttestationAgentService { + rpc GetDerivedKey(GetDerivedKeyRequest) returns (GetDerivedKeyResponse) {}; rpc GetEvidence(GetEvidenceRequest) returns (GetEvidenceResponse) {}; rpc GetToken(GetTokenRequest) returns (GetTokenResponse) {}; rpc ExtendRuntimeMeasurement(ExtendRuntimeMeasurementRequest) returns (ExtendRuntimeMeasurementResponse) {};