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 | Fix the idempotence of eventlog #807

Merged
merged 1 commit into from
Dec 4, 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
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions attestation-agent/attestation-agent/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ clap = { workspace = true, features = ["derive"], optional = true }
config.workspace = true
const_format.workspace = true
env_logger = { workspace = true, optional = true }
hex.workspace = true
kbs_protocol = { path = "../kbs_protocol", default-features = false, optional = true }
kbs-types.workspace = true
log.workspace = true
Expand Down
183 changes: 0 additions & 183 deletions attestation-agent/attestation-agent/src/eventlog.rs

This file was deleted.

104 changes: 104 additions & 0 deletions attestation-agent/attestation-agent/src/eventlog/event.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// Copyright (c) 2024 Alibaba Cloud
//
// SPDX-License-Identifier: Apache-2.0
//

use std::str::FromStr;

use anyhow::{anyhow, bail, Context, Result};
use crypto::HashAlgorithm;
use sha2::{digest::FixedOutput, Digest, Sha256, Sha384, Sha512};

#[derive(Clone)]
pub struct AAEventlog {
pub hash_algorithm: HashAlgorithm,
pub init_state: Vec<u8>,
pub events: Vec<String>,
}

impl FromStr for AAEventlog {
type Err = anyhow::Error;

fn from_str(input: &str) -> Result<Self> {
let all_lines = input.lines().collect::<Vec<&str>>();

let (initline, eventlines) = all_lines
.split_first()
.ok_or(anyhow!("at least one line should be included in AAEL"))?;

// Init line looks like
// INIT sha256/0000000000000000000000000000000000000000000000000000000000000000
let init_line_items = initline.split_ascii_whitespace().collect::<Vec<&str>>();
if init_line_items.len() != 2 {
bail!("Illegal INIT event record.");
}

if init_line_items[0] != "INIT" {
bail!("INIT event should start with `INIT` key word");
}

let (hash_algorithm, init_state) = init_line_items[1].split_once('/').ok_or(anyhow!(
"INIT event should have `<sha-algorithm>/<init-PCR-value>` as content after `INIT`"
))?;

let hash_algorithm = HashAlgorithm::from_str(hash_algorithm)
.context("parse Hash Algorithm in INIT entry")?;
let init_state = hex::decode(init_state).context("parse init state in INIT entry")?;

let events = eventlines
.iter()
.map(|line| line.trim_end().to_string())
.collect();

Ok(Self {
events,
hash_algorithm,
init_state,
})
}
}

impl AAEventlog {
fn accumulate_hash<D: Digest + FixedOutput>(&self) -> Vec<u8> {
let mut state = self.init_state.clone();

let mut init_event_hasher = D::new();
let init_event = format!(
"INIT {}/{}",
self.hash_algorithm.as_ref(),
hex::encode(&self.init_state)
);
Digest::update(&mut init_event_hasher, init_event.as_bytes());
let init_event_hash = init_event_hasher.finalize();

let mut hasher = D::new();
Digest::update(&mut hasher, &state);

Digest::update(&mut hasher, init_event_hash);
state = hasher.finalize().to_vec();

self.events.iter().for_each(|event| {
let mut event_hasher = D::new();
Digest::update(&mut event_hasher, event);
let event_hash = event_hasher.finalize();

let mut hasher = D::new();
Digest::update(&mut hasher, &state);
Digest::update(&mut hasher, event_hash);
state = hasher.finalize().to_vec();
});

state
}

/// Check the integrity of the AAEL, and gets a digest. Return whether the rtmr is the same as the digest.
pub fn integrity_check(&self, rtmr: &[u8]) -> bool {
let result = match self.hash_algorithm {
HashAlgorithm::Sha256 => self.accumulate_hash::<Sha256>(),
HashAlgorithm::Sha384 => self.accumulate_hash::<Sha384>(),
HashAlgorithm::Sha512 => self.accumulate_hash::<Sha512>(),
};

rtmr == result
}
}
Loading
Loading