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 Eventlog Recording for Attestation Agent #548

Merged
merged 5 commits into from
Jul 10, 2024
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
288 changes: 139 additions & 149 deletions Cargo.lock

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions attestation-agent/attestation-agent/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ attester = { path = "../attester", default-features = false }
base64.workspace = true
clap = { workspace = true, features = ["derive"], optional = true }
config.workspace = true
const_format = { workspace = true, optional = true }
const_format.workspace = true
env_logger = { workspace = true, optional = true }
kbs_protocol = { path = "../kbs_protocol", default-features = false, optional = true }
log.workspace = true
Expand All @@ -33,7 +33,7 @@ sha2.workspace = true
strum.workspace = true
tempfile.workspace = true
thiserror.workspace = true
tokio = { workspace = true, features = ["fs"] }
tokio = { workspace = true, features = ["fs", "sync"] }
toml.workspace = true
tonic = { workspace = true, optional = true }
ttrpc = { workspace = true, features = ["async"], optional = true }
Expand Down Expand Up @@ -73,4 +73,4 @@ openssl = ["kbs_protocol?/openssl"]
# Binary RPC type
bin = ["clap", "env_logger", "tokio/rt-multi-thread"]
grpc = ["prost", "tonic", "tonic-build", "tokio/signal"]
ttrpc = ["const_format", "dep:ttrpc", "ttrpc-codegen", "protobuf", "tokio/signal"]
ttrpc = ["dep:ttrpc", "ttrpc-codegen", "protobuf", "tokio/signal"]
4 changes: 4 additions & 0 deletions attestation-agent/attestation-agent/config.example.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,9 @@
"url": "https://127.0.0.1:8080",
"cert": "-----BEGIN CERTIFICATE-----\nMIIDljCCAn6gAwIBAgIUR/UNh13GFam4emgludtype/S9BIwDQYJKoZIhvcNAQEL\nBQAwdTELMAkGA1UEBhMCQ04xETAPBgNVBAgMCFpoZWppYW5nMREwDwYDVQQHDAhI\nYW5nemhvdTERMA8GA1UECgwIQUFTLVRFU1QxFDASBgNVBAsMC0RldmVsb3BtZW50\nMRcwFQYDVQQDDA5BQVMtVEVTVC1IVFRQUzAeFw0yNDAzMTgwNzAzNTNaFw0yNTAz\nMTgwNzAzNTNaMHUxCzAJBgNVBAYTAkNOMREwDwYDVQQIDAhaaGVqaWFuZzERMA8G\nA1UEBwwISGFuZ3pob3UxETAPBgNVBAoMCEFBUy1URVNUMRQwEgYDVQQLDAtEZXZl\nbG9wbWVudDEXMBUGA1UEAwwOQUFTLVRFU1QtSFRUUFMwggEiMA0GCSqGSIb3DQEB\nAQUAA4IBDwAwggEKAoIBAQDfp1aBr6LiNRBlJUcDGcAbcUCPG6UzywtVIc8+comS\nay//gwz2AkDmFVvqwI4bdp/NUCwSC6ShHzxsrCEiagRKtA3af/ckM7hOkb4S6u/5\newHHFcL6YOUp+NOH5/dSLrFHLjet0dt4LkyNBPe7mKAyCJXfiX3wb25wIBB0Tfa0\np5VoKzwWeDQBx7aX8TKbG6/FZIiOXGZdl24DGARiqE3XifX7DH9iVZ2V2RL9+3WY\n05GETNFPKtcrNwTy8St8/HsWVxjAzGFzf75Lbys9Ff3JMDsg9zQzgcJJzYWisxlY\ng3CmnbENP0eoHS4WjQlTUyY0mtnOwodo4Vdf8ZOkU4wJAgMBAAGjHjAcMBoGA1Ud\nEQQTMBGCCWxvY2FsaG9zdIcEfwAAATANBgkqhkiG9w0BAQsFAAOCAQEAKW32spii\nt2JB7C1IvYpJw5mQ5bhIlldE0iB5rwWvNbuDgPrgfTI4xiX5sumdHw+P2+GU9KXF\nnWkFRZ9W/26xFrVgGIS/a07aI7xrlp0Oj+1uO91UhCL3HhME/0tPC6z1iaFeZp8Y\nT1tLnafqiGiThFUgvg6PKt86enX60vGaTY7sslRlgbDr9sAi/NDSS7U1PviuC6yo\nyJi7BDiRSx7KrMGLscQ+AKKo2RF1MLzlJMa1kIZfvKDBXFzRd61K5IjDRQ4HQhwX\nDYEbQvoZIkUTc1gBUWDcAUS5ztbJg9LCb9WVtvUTqTP2lGuNymOvdsuXq+sAZh9b\nM9QaC1mzQ/OStg==\n-----END CERTIFICATE-----\n"
}
},
"eventlog_config": {
"eventlog_algorithm": "sha384",
"init_pcr": 17
}
}
5 changes: 5 additions & 0 deletions attestation-agent/attestation-agent/config.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,8 @@ DYEbQvoZIkUTc1gBUWDcAUS5ztbJg9LCb9WVtvUTqTP2lGuNymOvdsuXq+sAZh9b
M9QaC1mzQ/OStg==
-----END CERTIFICATE-----
'''

[eventlog_config]

eventlog_algorithm = "sha384"
init_pcr = 17
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ pub async fn main() -> Result<()> {

let attestation_socket = cli.attestation_sock.parse::<SocketAddr>()?;

let aa = AttestationAgent::new(cli.config_file.as_deref()).context("start AA")?;
let mut aa = AttestationAgent::new(cli.config_file.as_deref()).context("start AA")?;
aa.init().await.context("init AA")?;
debug!(
"Attestation gRPC service listening on: {:?}",
cli.attestation_sock
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,12 @@ impl AttestationAgentService for AA {
debug!("AA (grpc): extend runtime measurement ...");

attestation_agent
.extend_runtime_measurement(request.events, request.register_index)
.extend_runtime_measurement(
&request.domain,
&request.operation,
&request.content,
request.register_index,
)
.await
.map_err(|e| {
error!("AA (grpc): extend runtime measurement failed:\n{e:?}");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ pub async fn main() -> Result<()> {
clean_previous_sock_file(&cli.attestation_sock)
.context("clean previous attestation socket file")?;

let aa = AttestationAgent::new(cli.config_file.as_deref()).context("start AA")?;
let mut aa = AttestationAgent::new(cli.config_file.as_deref()).context("start AA")?;
aa.init().await.context("init AA")?;
let att = server::start_ttrpc_service(aa)?;

let mut atts = Server::new()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,12 @@ impl AttestationAgentService for AA {
let mut attestation_agent = self.inner.lock().await;

attestation_agent
.extend_runtime_measurement(req.Events, req.RegisterIndex)
.extend_runtime_measurement(
&req.Domain,
&req.Operation,
&req.Content,
req.RegisterIndex,
)
.await
.map_err(|e| {
error!("AA (ttrpc): extend runtime measurement failed:\n {e:?}");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -517,8 +517,12 @@ impl ::protobuf::reflect::ProtobufValue for GetTokenResponse {
#[derive(PartialEq,Clone,Default,Debug)]
pub struct ExtendRuntimeMeasurementRequest {
// message fields
// @@protoc_insertion_point(field:attestation_agent.ExtendRuntimeMeasurementRequest.Events)
pub Events: ::std::vec::Vec<::std::vec::Vec<u8>>,
// @@protoc_insertion_point(field:attestation_agent.ExtendRuntimeMeasurementRequest.Domain)
pub Domain: ::std::string::String,
// @@protoc_insertion_point(field:attestation_agent.ExtendRuntimeMeasurementRequest.Operation)
pub Operation: ::std::string::String,
// @@protoc_insertion_point(field:attestation_agent.ExtendRuntimeMeasurementRequest.Content)
pub Content: ::std::string::String,
// @@protoc_insertion_point(field:attestation_agent.ExtendRuntimeMeasurementRequest.RegisterIndex)
pub RegisterIndex: ::std::option::Option<u64>,
// special fields
Expand All @@ -538,12 +542,22 @@ impl ExtendRuntimeMeasurementRequest {
}

fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
let mut fields = ::std::vec::Vec::with_capacity(2);
let mut fields = ::std::vec::Vec::with_capacity(4);
let mut oneofs = ::std::vec::Vec::with_capacity(0);
fields.push(::protobuf::reflect::rt::v2::make_vec_simpler_accessor::<_, _>(
"Events",
|m: &ExtendRuntimeMeasurementRequest| { &m.Events },
|m: &mut ExtendRuntimeMeasurementRequest| { &mut m.Events },
fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>(
"Domain",
|m: &ExtendRuntimeMeasurementRequest| { &m.Domain },
|m: &mut ExtendRuntimeMeasurementRequest| { &mut m.Domain },
));
fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>(
"Operation",
|m: &ExtendRuntimeMeasurementRequest| { &m.Operation },
|m: &mut ExtendRuntimeMeasurementRequest| { &mut m.Operation },
));
fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>(
"Content",
|m: &ExtendRuntimeMeasurementRequest| { &m.Content },
|m: &mut ExtendRuntimeMeasurementRequest| { &mut m.Content },
));
fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
"RegisterIndex",
Expand All @@ -569,9 +583,15 @@ impl ::protobuf::Message for ExtendRuntimeMeasurementRequest {
while let Some(tag) = is.read_raw_tag_or_eof()? {
match tag {
10 => {
self.Events.push(is.read_bytes()?);
self.Domain = is.read_string()?;
},
18 => {
self.Operation = is.read_string()?;
},
16 => {
26 => {
self.Content = is.read_string()?;
},
32 => {
self.RegisterIndex = ::std::option::Option::Some(is.read_uint64()?);
},
tag => {
Expand All @@ -586,23 +606,35 @@ impl ::protobuf::Message for ExtendRuntimeMeasurementRequest {
#[allow(unused_variables)]
fn compute_size(&self) -> u64 {
let mut my_size = 0;
for value in &self.Events {
my_size += ::protobuf::rt::bytes_size(1, &value);
};
if !self.Domain.is_empty() {
my_size += ::protobuf::rt::string_size(1, &self.Domain);
}
if !self.Operation.is_empty() {
my_size += ::protobuf::rt::string_size(2, &self.Operation);
}
if !self.Content.is_empty() {
my_size += ::protobuf::rt::string_size(3, &self.Content);
}
if let Some(v) = self.RegisterIndex {
my_size += ::protobuf::rt::uint64_size(2, v);
my_size += ::protobuf::rt::uint64_size(4, v);
}
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<()> {
for v in &self.Events {
os.write_bytes(1, &v)?;
};
if !self.Domain.is_empty() {
os.write_string(1, &self.Domain)?;
}
if !self.Operation.is_empty() {
os.write_string(2, &self.Operation)?;
}
if !self.Content.is_empty() {
os.write_string(3, &self.Content)?;
}
if let Some(v) = self.RegisterIndex {
os.write_uint64(2, v)?;
os.write_uint64(4, v)?;
}
os.write_unknown_fields(self.special_fields.unknown_fields())?;
::std::result::Result::Ok(())
Expand All @@ -621,14 +653,18 @@ impl ::protobuf::Message for ExtendRuntimeMeasurementRequest {
}

fn clear(&mut self) {
self.Events.clear();
self.Domain.clear();
self.Operation.clear();
self.Content.clear();
self.RegisterIndex = ::std::option::Option::None;
self.special_fields.clear();
}

fn default_instance() -> &'static ExtendRuntimeMeasurementRequest {
static instance: ExtendRuntimeMeasurementRequest = ExtendRuntimeMeasurementRequest {
Events: ::std::vec::Vec::new(),
Domain: ::std::string::String::new(),
Operation: ::std::string::String::new(),
Content: ::std::string::String::new(),
RegisterIndex: ::std::option::Option::None,
special_fields: ::protobuf::SpecialFields::new(),
};
Expand Down Expand Up @@ -1352,24 +1388,26 @@ 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\"v\n\x1fExtendRuntimeMeasurementRequest\x12\x16\
\n\x06Events\x18\x01\x20\x03(\x0cR\x06Events\x12)\n\rRegisterIndex\x18\
\x02\x20\x01(\x04H\0R\rRegisterIndex\x88\x01\x01B\x10\n\x0e_RegisterInde\
x\"\"\n\x20ExtendRuntimeMeasurementResponse\"K\n\x11InitDataPlaintext\
\x12\x18\n\x07Content\x18\x01\x20\x01(\x0cR\x07Content\x12\x1c\n\tAlgori\
thm\x18\x02\x20\x01(\tR\tAlgorithm\".\n\x14CheckInitDataRequest\x12\x16\
\n\x06Digest\x18\x01\x20\x01(\x0cR\x06Digest\"\x17\n\x15CheckInitDataRes\
ponse\"4\n\x1aUpdateConfigurationRequest\x12\x16\n\x06config\x18\x01\x20\
\x01(\tR\x06config\"\x1d\n\x1bUpdateConfigurationResponse2\xac\x04\n\x17\
AttestationAgentService\x12\\\n\x0bGetEvidence\x12%.attestation_agent.Ge\
tEvidenceRequest\x1a&.attestation_agent.GetEvidenceResponse\x12S\n\x08Ge\
tToken\x12\".attestation_agent.GetTokenRequest\x1a#.attestation_agent.Ge\
tTokenResponse\x12\x83\x01\n\x18ExtendRuntimeMeasurement\x122.attestatio\
n_agent.ExtendRuntimeMeasurementRequest\x1a3.attestation_agent.ExtendRun\
timeMeasurementResponse\x12b\n\rCheckInitData\x12'.attestation_agent.Che\
ckInitDataRequest\x1a(.attestation_agent.CheckInitDataResponse\x12t\n\
\x13UpdateConfiguration\x12-.attestation_agent.UpdateConfigurationReques\
t\x1a..attestation_agent.UpdateConfigurationResponseb\x06proto3\
\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\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\
nfigurationResponse2\xac\x04\n\x17AttestationAgentService\x12\\\n\x0bGet\
Evidence\x12%.attestation_agent.GetEvidenceRequest\x1a&.attestation_agen\
t.GetEvidenceResponse\x12S\n\x08GetToken\x12\".attestation_agent.GetToke\
nRequest\x1a#.attestation_agent.GetTokenResponse\x12\x83\x01\n\x18Extend\
RuntimeMeasurement\x122.attestation_agent.ExtendRuntimeMeasurementReques\
t\x1a3.attestation_agent.ExtendRuntimeMeasurementResponse\x12b\n\rCheckI\
nitData\x12'.attestation_agent.CheckInitDataRequest\x1a(.attestation_age\
nt.CheckInitDataResponse\x12t\n\x13UpdateConfiguration\x12-.attestation_\
agent.UpdateConfigurationRequest\x1a..attestation_agent.UpdateConfigurat\
ionResponseb\x06proto3\
";

/// `FileDescriptorProto` object which was a source for this generated file
Expand Down
60 changes: 58 additions & 2 deletions attestation-agent/attestation-agent/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

use anyhow::Result;
use serde::Deserialize;
use sha2::{Digest, Sha256, Sha384, Sha512};

use crate::DEFAULT_PCR_INDEX;

pub mod aa_kbc_params;

Expand All @@ -16,17 +19,69 @@ pub mod kbs;

pub const DEFAULT_AA_CONFIG_PATH: &str = "/etc/attestation-agent.conf";

pub const DEFAULT_EVENTLOG_HASH: &str = "sha384";

/// Hash algorithms used to calculate runtime/init data binding
#[derive(Deserialize, Clone, Debug, Copy)]
#[serde(rename_all = "lowercase")]
pub enum HashAlgorithm {
Sha256,
Sha384,
Sha512,
}

impl Default for HashAlgorithm {
fn default() -> Self {
Self::Sha384
}
}

fn hash_reportdata<D: Digest>(material: &[u8]) -> Vec<u8> {
D::new().chain_update(material).finalize().to_vec()
}

impl HashAlgorithm {
pub fn digest(&self, material: &[u8]) -> Vec<u8> {
match self {
HashAlgorithm::Sha256 => hash_reportdata::<Sha256>(material),
HashAlgorithm::Sha384 => hash_reportdata::<Sha384>(material),
HashAlgorithm::Sha512 => hash_reportdata::<Sha512>(material),
}
}
}

#[derive(Clone, Debug, Deserialize)]
pub struct Config {
/// configs about token
pub token_configs: TokenConfigs,
// TODO: Add more fields that accessing AS needs.

/// configs about eventlog
pub eventlog_config: EventlogConfig,
}

#[derive(Clone, Debug, Deserialize)]
pub struct EventlogConfig {
/// Hash algorithm used to extend runtime measurement for eventlog.
pub eventlog_algorithm: HashAlgorithm,

/// PCR Register to extend INIT entry
pub init_pcr: u64,
}

impl Default for EventlogConfig {
fn default() -> Self {
Self {
eventlog_algorithm: HashAlgorithm::Sha384,
init_pcr: DEFAULT_PCR_INDEX,
}
}
}

impl Config {
pub fn new() -> Result<Self> {
Ok(Self {
token_configs: TokenConfigs::new()?,
eventlog_config: EventlogConfig::default(),
})
}
}
Expand Down Expand Up @@ -59,6 +114,8 @@ impl TryFrom<&str> for Config {
fn try_from(config_path: &str) -> Result<Self, Self::Error> {
let c = config::Config::builder()
.add_source(config::File::with_name(config_path))
.set_default("eventlog_config.eventlog_algorithm", DEFAULT_EVENTLOG_HASH)?
.set_default("eventlog_config.init_pcr", DEFAULT_PCR_INDEX)?
.build()?;

let cfg = c.try_deserialize()?;
Expand All @@ -68,7 +125,6 @@ impl TryFrom<&str> for Config {

#[cfg(test)]
mod tests {
#[cfg(all(feature = "kbs", feature = "coco_as"))]
#[rstest::rstest]
#[case("config.example.toml")]
#[case("config.example.json")]
Expand Down
Loading
Loading