pvattest: Verify hybrid keys

Allow pvattest verify to verify hybrid keys. The hybrid key is
represented by a sha512 hash truncated to 32 bytes.

Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Marc Hartmayer <marc@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
This commit is contained in:
Steffen Eiden
2026-07-22 17:24:38 +02:00
parent 1078e6d45f
commit 73c227fa9a
4 changed files with 51 additions and 25 deletions
+4 -5
View File
@@ -6,8 +6,8 @@ use std::path::PathBuf;
use clap::{Args, Parser, Subcommand, ValueEnum, ValueHint};
use utils::{
AutoOrExplicit, AutoOrExplicitParser, CertificateOptions, DeprecatedVerbosityOptions,
HkdVersion, ValueEnumDisplay, ValueEnumFromStr,
AutoOrExplicit, CertificateOptions, DeprecatedVerbosityOptions, HkdVersion, ValueEnumDisplay,
ValueEnumFromStr,
};
/// create, perform, and verify attestation measurements
@@ -82,7 +82,6 @@ pub enum AttVersion {
}
pub type AttVersionSelection = AutoOrExplicit<AttVersion>;
pub type AttVersionSelectionParser = AutoOrExplicitParser<AttVersion>;
impl From<AttVersion> for HkdVersion {
fn from(val: AttVersion) -> Self {
@@ -122,8 +121,8 @@ pub struct CreateAttOpt {
pub add_data: Vec<AttAddFlags>,
/// Specify the Attestation Request version to use.
#[arg(long = "att-version", value_name = "VERSION", default_value_t = AttVersionSelection::Explicit(AttVersion::V1), value_parser = AttVersionSelectionParser::default())]
pub att_version: AttVersionSelection,
#[arg(long = "att-version", value_name = "VERSION", default_value_t = AttVersion::V1)]
pub att_version: AttVersion,
}
#[derive(Debug, ValueEnum, Clone, Copy)]
+27 -8
View File
@@ -6,10 +6,9 @@ use std::fmt::Display;
use std::path::Path;
use anyhow::Result;
use log::{debug, info};
use log::{debug, info, warn};
use pv::misc::{read_certs, read_file};
use pv::request::openssl::DigestBytes;
use pv::request::EcPubKeyCoord;
use pv::request::{EcPubKeyCoord, HybridPKey, KeyslotV2};
use serde::Serialize;
use utils::HexSlice;
@@ -36,7 +35,7 @@ impl Display for HkCheck {
}
}
fn load_host_keys<A: AsRef<Path>>(hkds: &[A]) -> Result<Vec<(&Path, DigestBytes)>> {
fn load_host_keys<A: AsRef<Path>>(hkds: &[A]) -> Result<Vec<(&Path, Vec<u8>)>> {
let mut hkd_hash = Vec::with_capacity(hkds.len());
for hkd in hkds {
let hkd = hkd.as_ref();
@@ -45,21 +44,41 @@ fn load_host_keys<A: AsRef<Path>>(hkds: &[A]) -> Result<Vec<(&Path, DigestBytes)
hkd: hkd.display().to_string(),
source,
})?;
let ec_coord: EcPubKeyCoord = certs.first().unwrap().public_key()?.as_ref().try_into()?;
hkd_hash.push((hkd, ec_coord.sha256()?));
let ec_key = certs.first().unwrap().public_key()?;
match certs.len() {
1 => {
let ec_coord: EcPubKeyCoord = ec_key.as_ref().try_into()?;
hkd_hash.push((hkd, ec_coord.sha256()?.as_ref().to_vec()));
}
2 => {
let mlkem_key = certs[1].public_key()?;
let ks = KeyslotV2::new(HybridPKey::new(ec_key, mlkem_key)?);
let hash = ks.sha512()?;
hkd_hash.push((hkd, hash[..32].to_vec()));
}
_ => {
warn!(
"The host-key document in '{}' contains more than two certificates!",
hkd.display()
);
Err(pv::Error::WrongNumberOfKeys(hkd.display().to_string()))?;
}
}
}
Ok(hkd_hash)
}
fn contains_phkh<'a>(
hkd_hashes: &[(&'a Path, DigestBytes)],
hkd_hashes: &[(&'a Path, Vec<u8>)],
phkh: &HexSlice<'_>,
mode: HkCheck,
check_enforced: bool,
) -> CheckState<HostKeyCheck<'a>> {
let hk: Vec<_> = hkd_hashes
.iter()
.filter_map(|(path, hash)| match hash.as_ref() == phkh.as_ref() {
.filter_map(|(path, hash)| match hash == phkh.as_ref() {
true => Some(*path),
false => None,
})
+5 -4
View File
@@ -62,11 +62,12 @@ fn determine_version(
}
pub fn create(opt: &CreateAttOpt) -> Result<ExitCode> {
let hkds = opt
.certificate_args
.get_verified_hkds_new("attestation request", opt.att_version.map(|v| v.into()))?;
let hkds = opt.certificate_args.get_verified_hkds_new(
"attestation request",
AttVersionSelection::Explicit(opt.att_version).map(|v| v.into()),
)?;
let att_version = determine_version(opt.att_version, &hkds);
let att_version = determine_version(AttVersionSelection::Explicit(opt.att_version), &hkds);
let meas_alg = AttestationMeasAlg::HmacSha512;
let mut arcb = AttestationRequest::new(att_version, meas_alg, flags(&opt.add_data))?;