mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
pvimg: Use indexed array for UV key hashes
Replace individual UV key hash fields with an indexed array and introduce dedicated types for hash indices and key hash kinds. This simplifies hash handling. Co-developed-by: Steffen Eiden <seiden@linux.ibm.com> Signed-off-by: Marc Hartmayer <marc@linux.ibm.com> Reviewed-by: Steffen Eiden <seiden@linux.ibm.com> Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
This commit is contained in:
committed by
Steffen Eiden
parent
ed74e84862
commit
08d21b24b4
@@ -33,32 +33,25 @@ fn hdr_test_target_hashes(hdr: &SeHdr, key_hashes: &Path) -> Result<bool> {
|
||||
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 {
|
||||
let matches = hashes.matching_hashes(hdr);
|
||||
if matches.is_empty() {
|
||||
warn!(" ✘ None of the key hashes is included");
|
||||
Ok(false)
|
||||
} else {
|
||||
for m in matches {
|
||||
match m.idx.kind() {
|
||||
Some(kind) => {
|
||||
log_println!(" ✓ {kind} {:#} is included", HexSlice::from(&m.hash))
|
||||
}
|
||||
None => log_println!(
|
||||
" ✓ Key hash {:#} is included (zero-based index {})",
|
||||
HexSlice::from(&m.hash),
|
||||
m.idx.index()
|
||||
),
|
||||
}
|
||||
}
|
||||
Ok(true)
|
||||
}
|
||||
Ok(contains)
|
||||
}
|
||||
|
||||
/// Returns `Ok(true)` if at least one of the given public key of the host key
|
||||
|
||||
@@ -7,7 +7,7 @@ use std::io::{BufRead, BufReader, Read};
|
||||
use enum_dispatch::enum_dispatch;
|
||||
use pv::misc::decode_hex;
|
||||
|
||||
use super::try_copy_slice_to_array;
|
||||
use super::{try_copy_slice_to_array, KeyExchangeTrait, SeHdr};
|
||||
use crate::error::{Error, Result};
|
||||
|
||||
/// The `enum_dispatch` macros needs at least one local trait to be implemented.
|
||||
@@ -41,11 +41,111 @@ impl UvKeyHashV1 {
|
||||
}
|
||||
}
|
||||
|
||||
use std::fmt::{self, Display};
|
||||
use std::ops::{Index, IndexMut};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum UvKeyHashV1Kind {
|
||||
PCHKH,
|
||||
PBHKH,
|
||||
PCHHKH,
|
||||
PBHHKH,
|
||||
}
|
||||
|
||||
impl Display for UvKeyHashV1Kind {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::PCHKH => write!(f, "Classical Host key hash"),
|
||||
Self::PBHKH => write!(f, "Backup classical host key hash"),
|
||||
Self::PCHHKH => write!(f, "Hybrid host key hash"),
|
||||
Self::PBHHKH => write!(f, "Backup hybrid host key hash"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Index into the UV key hash array.
|
||||
///
|
||||
/// The indices follow the UV specification layout:
|
||||
/// - 0: PCHKH (Classical host key hash)
|
||||
/// - 1: PBHKH (Backup classical host key hash)
|
||||
/// - 2-3: Reserved for future use
|
||||
/// - 4: PCHHKH (Hybrid host key hash)
|
||||
/// - 5: PBHHKH (Backup hybrid host key hash)
|
||||
/// - 6-14: Reserved for future use
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct UvKeyHashIdx(u8);
|
||||
|
||||
impl UvKeyHashIdx {
|
||||
pub const PCHKH: Self = Self(0);
|
||||
pub const PBHKH: Self = Self(1);
|
||||
pub const PCHHKH: Self = Self(4);
|
||||
pub const PBHHKH: Self = Self(5);
|
||||
|
||||
pub fn index(self) -> usize {
|
||||
self.0 as usize
|
||||
}
|
||||
|
||||
pub fn kind(self) -> Option<UvKeyHashV1Kind> {
|
||||
match self.0 {
|
||||
0 => Some(UvKeyHashV1Kind::PCHKH),
|
||||
1 => Some(UvKeyHashV1Kind::PBHKH),
|
||||
4 => Some(UvKeyHashV1Kind::PCHHKH),
|
||||
5 => Some(UvKeyHashV1Kind::PBHHKH),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<usize> for UvKeyHashIdx {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: usize) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
0..=14 => Ok(Self(value as u8)),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct UvKeyHashesV1 {
|
||||
pub pchkh: UvKeyHashV1,
|
||||
pub pbhkh: UvKeyHashV1,
|
||||
pub res: [UvKeyHashV1; 13],
|
||||
pub hashes: [UvKeyHashV1; 15],
|
||||
}
|
||||
|
||||
impl Index<UvKeyHashIdx> for UvKeyHashesV1 {
|
||||
type Output = UvKeyHashV1;
|
||||
|
||||
fn index(&self, pos: UvKeyHashIdx) -> &Self::Output {
|
||||
&self.hashes[pos.index()]
|
||||
}
|
||||
}
|
||||
|
||||
impl IndexMut<UvKeyHashIdx> for UvKeyHashesV1 {
|
||||
fn index_mut(&mut self, pos: UvKeyHashIdx) -> &mut Self::Output {
|
||||
&mut self.hashes[pos.index()]
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct MatchingUvKeyHash<'a> {
|
||||
pub idx: UvKeyHashIdx,
|
||||
pub hash: &'a UvKeyHashV1,
|
||||
}
|
||||
|
||||
impl UvKeyHashesV1 {
|
||||
pub fn matching_hashes(&self, hdr: &SeHdr) -> Vec<MatchingUvKeyHash<'_>> {
|
||||
self.hashes
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(_, hash)| hdr.contains_hash(hash))
|
||||
.filter_map(|(idx, hash)| {
|
||||
Some(MatchingUvKeyHash {
|
||||
idx: idx.try_into().ok()?,
|
||||
hash,
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl UvKeyHashV1 {
|
||||
@@ -108,9 +208,8 @@ impl UvKeyHashesV1 {
|
||||
return Err(Error::InvalidUvKeyHashes);
|
||||
}
|
||||
|
||||
let [pchkh, pbhkh, res @ ..]: [UvKeyHashV1; 15] =
|
||||
hashes.try_into().map_err(|_| Error::InvalidUvKeyHashes)?;
|
||||
Ok(Self { pchkh, pbhkh, res })
|
||||
let hashes: [UvKeyHashV1; 15] = hashes.try_into().map_err(|_| Error::InvalidUvKeyHashes)?;
|
||||
Ok(Self { hashes })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,21 +241,18 @@ mod tests {
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
";
|
||||
let result = UvKeyHashesV1::read_from_io(Cursor::new(data)).expect("should not fail");
|
||||
assert_eq!(
|
||||
result,
|
||||
UvKeyHashesV1 {
|
||||
pchkh: UvKeyHashV1::new(
|
||||
decode_hex("0b729fd62241b339840d61b964a06bb6a1fd4976d9ebea2b4fb48d44de3a2461")
|
||||
.unwrap()
|
||||
)
|
||||
.unwrap(),
|
||||
pbhkh: UvKeyHashV1::new(
|
||||
decode_hex("8ec6bc2f77d5d6474b1417cf0a8c914f576245a5b9bb0eefacc7b821483ece7d")
|
||||
.unwrap()
|
||||
)
|
||||
.unwrap(),
|
||||
res: [UvKeyHashV1::UV_KEY_HASH_NULL; 13],
|
||||
}
|
||||
);
|
||||
let mut exp_hashes = [UvKeyHashV1::UV_KEY_HASH_NULL; 15];
|
||||
exp_hashes[0] = UvKeyHashV1::new(
|
||||
decode_hex("0b729fd62241b339840d61b964a06bb6a1fd4976d9ebea2b4fb48d44de3a2461").unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
exp_hashes[1] = UvKeyHashV1::new(
|
||||
decode_hex("8ec6bc2f77d5d6474b1417cf0a8c914f576245a5b9bb0eefacc7b821483ece7d").unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let uv_hashes = UvKeyHashesV1 { hashes: exp_hashes };
|
||||
assert_eq!(result, uv_hashes);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user