Skip to content

Commit

Permalink
AA: fix eventlog idempotence
Browse files Browse the repository at this point in the history
This patch fixes the idempotence of eventlog. Before this, when AA
restarts and eventlog is activated, the originally recorded aael will be
truncated and the INIT event will be recorded repeatedly. This patch
will check whether there is an existing AAEL when AA is restarted. If
so, it will skip creating and recording the INIT event.

At the same time, a synchronization mechanism is used to ensure that
RTMR expansion will not occur repeatedly after AA abnormally interrupts
execution.

Signed-off-by: Xynnn007 <xynnn@linux.alibaba.com>
  • Loading branch information
Xynnn007 committed Nov 15, 2024
1 parent d7f8102 commit a879185
Show file tree
Hide file tree
Showing 9 changed files with 504 additions and 235 deletions.
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<Vec<u8>>,
}

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.as_bytes().to_vec())
.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);

Check warning on line 82 in attestation-agent/attestation-agent/src/eventlog/event.rs

View workflow job for this annotation

GitHub Actions / Check (stable, ubuntu-24.04)

the borrowed expression implements the required traits
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

0 comments on commit a879185

Please sign in to comment.