mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
Allow the creation of SE images using headers with hybrid (=quantum safe) keys. This results in using the headers in version 2 (0x200). Co-developed-by: Marc Hartmayer <marc@linux.ibm.com> Signed-off-by: Marc Hartmayer <marc@linux.ibm.com> Signed-off-by: Timo Keller <tkeller@linux.ibm.com> Reviewed-by: Steffen Eiden <seiden@linux.ibm.com> Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
110 lines
3.1 KiB
Rust
110 lines
3.1 KiB
Rust
// SPDX-License-Identifier: MIT
|
|
//
|
|
// Copyright IBM Corp. 2024
|
|
|
|
use std::path::Path;
|
|
|
|
use anyhow::Result;
|
|
use log::{info, warn};
|
|
use pv::misc::{open_file, read_hkd};
|
|
use pv::{FileAccessErrorType, PvCoreError};
|
|
use pvimg::error::{Error, OwnExitCode};
|
|
use pvimg::uvdata::{KeyExchangeTrait, SeHdr, UvKeyHashesV1};
|
|
use utils::HexSlice;
|
|
|
|
use crate::cli::TestArgs;
|
|
use crate::log_println;
|
|
|
|
/// Returns `Ok(true)` if at least one of the hashes is included.
|
|
fn hdr_test_target_hashes(hdr: &SeHdr, key_hashes: &Path) -> Result<bool> {
|
|
let file = open_file(key_hashes).map_err(|err| match err {
|
|
PvCoreError::FileAccess {
|
|
ref ty,
|
|
ref path,
|
|
ref source,
|
|
} if matches!(ty, FileAccessErrorType::Open)
|
|
&& source.kind() == std::io::ErrorKind::NotFound
|
|
&& path == Path::new(UvKeyHashesV1::SYS_UV_KEYS_ALL) =>
|
|
{
|
|
Error::UnavailableQueryUvKeyHashesSupport { source: err }
|
|
}
|
|
err => Error::PvCore(err),
|
|
})?;
|
|
let hashes = UvKeyHashesV1::read_from_io(file)?;
|
|
let mut contains = hdr.contains_hash(&hashes.pchkh);
|
|
if contains {
|
|
log_println!(
|
|
" ✓ Host key hash {:#} is included",
|
|
HexSlice::from(&hashes.pchkh)
|
|
);
|
|
}
|
|
if hdr.contains_hash(&hashes.pbhkh) {
|
|
log_println!(
|
|
" ✓ Backup host key hash {:#} is included",
|
|
HexSlice::from(&hashes.pbhkh)
|
|
);
|
|
contains = true;
|
|
};
|
|
|
|
for hash in hashes.res {
|
|
if hdr.contains_hash(&hash) {
|
|
log_println!(" ✓ Key hash {:#} is included", HexSlice::from(&hash));
|
|
contains = true;
|
|
}
|
|
}
|
|
|
|
if !contains {
|
|
warn!(" ✘ None of the key hashes is included");
|
|
}
|
|
Ok(contains)
|
|
}
|
|
|
|
/// Returns `Ok(true)` if at least one of the given public key of the host key
|
|
/// documents was used for the image creation or if no host key document was
|
|
/// specified.
|
|
fn hdr_test_hkd<P>(hdr: &SeHdr, host_key_documents: &[P]) -> Result<bool>
|
|
where
|
|
P: AsRef<Path>,
|
|
{
|
|
if host_key_documents.is_empty() {
|
|
return Ok(true);
|
|
}
|
|
|
|
let mut result = false;
|
|
for path in host_key_documents {
|
|
let hkd = read_hkd(path)?;
|
|
if hdr.contains(hkd)? {
|
|
result = true;
|
|
log_println!(
|
|
" ✓ Host key document '{}' is included",
|
|
path.as_ref().display()
|
|
);
|
|
} else {
|
|
log_println!(
|
|
" ✘ Host key document '{}' is not included",
|
|
path.as_ref().display()
|
|
);
|
|
}
|
|
}
|
|
Ok(result)
|
|
}
|
|
|
|
pub fn test(opt: &TestArgs) -> Result<OwnExitCode> {
|
|
info!("Testing a Secure Execution image");
|
|
|
|
let mut input = open_file(&opt.input.path)?;
|
|
SeHdr::seek_sehdr(&mut input, None)?;
|
|
let hdr = SeHdr::try_from_io(input)?;
|
|
|
|
let mut success = hdr_test_hkd(&hdr, &opt.host_key_documents)?;
|
|
if let Some(path) = &opt.key_hashes {
|
|
success = hdr_test_target_hashes(&hdr, path)? && success;
|
|
}
|
|
|
|
Ok(if success {
|
|
OwnExitCode::Success
|
|
} else {
|
|
OwnExitCode::GenericError
|
|
})
|
|
}
|