From 3cc953c8d0ace2f20cbcf3920b0771d25301960a Mon Sep 17 00:00:00 2001 From: Laura Abbott Date: Mon, 5 Aug 2024 12:39:09 -0400 Subject: [PATCH] TQ operations This lets the upper layers perform signing operations --- Cargo.lock | 11 +++++++++-- Cargo.toml | 1 + attest-data/Cargo.toml | 3 ++- attest-data/src/messages.rs | 29 +++++++++++++++++++++++------ verifier/Cargo.toml | 2 +- verifier/src/lib.rs | 20 ++++++++++++++++++++ 6 files changed, 56 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ed2419c..b7faaca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -114,7 +114,7 @@ checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" [[package]] name = "attest-data" -version = "0.2.0" +version = "0.3.0" dependencies = [ "getrandom", "hubpack", @@ -122,6 +122,7 @@ dependencies = [ "serde", "serde_with", "sha3", + "static_assertions", "thiserror", ] @@ -518,7 +519,7 @@ dependencies = [ [[package]] name = "dice-verifier" -version = "0.1.0" +version = "0.2.0" dependencies = [ "anyhow", "attest-data", @@ -1298,6 +1299,12 @@ dependencies = [ "der", ] +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "string-error" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index cac28e5..a95db74 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,6 +37,7 @@ serde_with = { version = "3.6", default-features = false } serialport = { git = "https://github.com/jgallagher/serialport-rs", branch = "illumos-support" } sha2 = "0.10" sha3 = { version = "0.10", default-features = false } +static_assertions = { version = "1", default-features = false } string-error = "0.1" tempfile = { version = "3", default-features = false } thiserror = "1.0.57" diff --git a/attest-data/Cargo.toml b/attest-data/Cargo.toml index c1fe700..be26ab4 100644 --- a/attest-data/Cargo.toml +++ b/attest-data/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "attest-data" -version = "0.2.0" +version = "0.3.0" edition = "2021" [dependencies] @@ -11,6 +11,7 @@ salty.workspace = true serde = { workspace = true, features = ["derive"] } serde_with = { workspace = true, features = ["macros"] } sha3.workspace = true +static_assertions.workspace = true [features] std = ["getrandom", "thiserror"] diff --git a/attest-data/src/messages.rs b/attest-data/src/messages.rs index fcdec01..96e833c 100644 --- a/attest-data/src/messages.rs +++ b/attest-data/src/messages.rs @@ -2,17 +2,22 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -use crate::NONCE_SIZE; +use crate::{NONCE_SIZE, SHA3_256_DIGEST_SIZE}; +use hubpack::error::Error as HubpackError; use hubpack::SerializedSize; use serde::{de::DeserializeOwned, Deserialize, Serialize}; -use hubpack::error::Error as HubpackError; - /// Magic value for [`Header::magic`] pub const ATTEST_MAGIC: u32 = 0xA77E5700; -/// Right now `Attest` is the only command that takes data (nonce) -pub const MAX_DATA_LEN: usize = NONCE_SIZE; +/// Right now `Attest` and `TqSign` are the only commands that take data +/// argumenets. They happen to be the same length right now but this also +/// catches anything silly + +const fn const_max(a: usize, b: usize) -> usize { + [a, b][(a < b) as usize] +} +pub const MAX_DATA_LEN: usize = const_max(NONCE_SIZE, SHA3_256_DIGEST_SIZE); pub const MAX_REQUEST_SIZE: usize = HostRotHeader::MAX_SIZE + HostToRotCommand::MAX_SIZE + MAX_DATA_LEN; @@ -56,6 +61,10 @@ pub enum HostToRotCommand { /// Calculates sign(sha3_256(hubpack(measurement_log) | nonce)) /// and returns the result. Attest, + /// Returns the certificate chain associated with TQ + GetTqCertificates, + /// Signs a 32 byte message with the TQ key + TqSign, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)] @@ -151,6 +160,8 @@ pub enum RotToHost { RotCertificates, RotMeasurementLog, RotAttestation, + RotTqCertificates, + RotTqSign, } impl From for RotToHost { @@ -185,7 +196,8 @@ pub fn parse_message( match command { // These commands don't take data HostToRotCommand::GetCertificates - | HostToRotCommand::GetMeasurementLog => { + | HostToRotCommand::GetMeasurementLog + | HostToRotCommand::GetTqCertificates => { if !leftover.is_empty() { return Err(HostToRotError::IncorrectDataLen); } @@ -195,6 +207,11 @@ pub fn parse_message( return Err(HostToRotError::IncorrectDataLen); } } + HostToRotCommand::TqSign => { + if leftover.len() != SHA3_256_DIGEST_SIZE { + return Err(HostToRotError::IncorrectDataLen); + } + } } Ok((command, leftover)) diff --git a/verifier/Cargo.toml b/verifier/Cargo.toml index 6dedad1..e5794b5 100644 --- a/verifier/Cargo.toml +++ b/verifier/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "dice-verifier" -version = "0.1.0" +version = "0.2.0" edition = "2021" description = "a library crate implementing the attestation verifier" license = "MPL-2.0" diff --git a/verifier/src/lib.rs b/verifier/src/lib.rs index 04f5f0d..b397185 100644 --- a/verifier/src/lib.rs +++ b/verifier/src/lib.rs @@ -229,6 +229,26 @@ impl PkiPathSignatureVerifier { } } +pub fn verify_signature( + cert: &Certificate, + hash: &[u8], + signature: &[u8], +) -> Result<()> { + use ed25519_dalek::{Signature, Verifier, VerifyingKey}; + + let signature = Signature::from_slice(signature)?; + + let cert = cert + .tbs_certificate + .subject_public_key_info + .subject_public_key + .as_bytes() + .ok_or_else(|| anyhow!("Invalid / unaligned public key"))?; + + let verifying_key = VerifyingKey::from_bytes(cert.try_into()?)?; + Ok(verifying_key.verify(hash, &signature)?) +} + pub fn verify_attestation( alias: &Certificate, attestation: &Attestation,