mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
rust/pv: Add conversion implementations
Add AsRef<[u8]> and TryFrom<Vec<u8>> implementations so that the tag data can be converted into base64. See: https://docs.rs/serde_with/latest/serde_with/base64/struct.Base64.html While at it, fix some typos and simplify the tag extraction. Suggested-by: Qi Feng Huo <huoqif@cn.ibm.com> Acked-by: Qi Feng Huo <huoqif@cn.ibm.com> Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com> Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
// Copyright IBM Corp. 2023
|
||||
// Copyright IBM Corp. 2023, 2024
|
||||
|
||||
use std::{
|
||||
io::{Read, Seek, SeekFrom::Current},
|
||||
@@ -20,15 +20,32 @@ use zerocopy::{AsBytes, BigEndian, FromBytes, FromZeroes, U32, U64};
|
||||
/// Tweak List Digest (tld)
|
||||
/// SE Header Tag (tag)
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Copy, AsBytes, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Copy, AsBytes, PartialEq, Eq, FromBytes, FromZeroes)]
|
||||
pub struct BootHdrTags {
|
||||
pld: [u8; BootHdrHead::DIGEST_SIZE],
|
||||
ald: [u8; BootHdrHead::DIGEST_SIZE],
|
||||
tld: [u8; BootHdrHead::DIGEST_SIZE],
|
||||
tag: [u8; BootHdrHead::TAG_SIZE],
|
||||
}
|
||||
assert_size!(BootHdrTags, 0xd0);
|
||||
|
||||
/// Magiv value for a SE-(boot)header
|
||||
impl AsRef<[u8]> for BootHdrTags {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
self.as_bytes()
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<Vec<u8>> for BootHdrTags {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
|
||||
Self::ref_from(&value)
|
||||
.ok_or_else(|| Error::InvBootHdrSize(value.len()))
|
||||
.copied()
|
||||
}
|
||||
}
|
||||
|
||||
/// Magic value for a SE-(boot)header
|
||||
pub struct BootHdrMagic;
|
||||
impl MagicValue<8> for BootHdrMagic {
|
||||
const MAGIC: [u8; 8] = [0x49, 0x42, 0x4d, 0x53, 0x65, 0x63, 0x45, 0x78];
|
||||
@@ -46,9 +63,9 @@ impl BootHdrTags {
|
||||
Self { ald, tld, pld, tag }
|
||||
}
|
||||
|
||||
/// returns false if no hdr found, true otherwise
|
||||
/// in the very unlikel case an IO error can appear
|
||||
/// when seeking to the beginning of the header
|
||||
/// Returns `false` if no hdr found, `true` otherwise.
|
||||
/// In the very unlikely case an IO error can appear
|
||||
/// when seeking to the beginning of the header.
|
||||
fn seek_se_hdr_start<R>(img: &mut R) -> Result<bool>
|
||||
where
|
||||
R: Read + Seek,
|
||||
@@ -100,21 +117,27 @@ impl BootHdrTags {
|
||||
let mut hdr = vec![0u8; size_of::<BootHdrHead>()];
|
||||
img.read_exact(&mut hdr)?;
|
||||
|
||||
// Very unlikely - seek_se_hdr_start should point to a header or error-out
|
||||
if !BootHdrMagic::starts_with_magic(&hdr) {
|
||||
debug!("Inv magic");
|
||||
return Err(Error::InvBootHdr);
|
||||
}
|
||||
|
||||
let hdr_head = match BootHdrHead::read_from_prefix(hdr.as_mut_slice()) {
|
||||
Some(hdr) => hdr,
|
||||
None => {
|
||||
debug!("Boot hdr is to small");
|
||||
debug!("Boot hdr is too small");
|
||||
return Err(Error::InvBootHdr);
|
||||
}
|
||||
};
|
||||
|
||||
//Some sanity checks
|
||||
if !BootHdrMagic::starts_with_magic(&hdr) || hdr_head.version.get() != 0x100 {
|
||||
debug!("Inv magic or size");
|
||||
// Some sanity checks
|
||||
if hdr_head.version.get() != 0x100 {
|
||||
debug!("Unsupported hdr-version: {:0>4x}", hdr_head.version.get());
|
||||
return Err(Error::InvBootHdr);
|
||||
}
|
||||
|
||||
//go to the Bot header tag
|
||||
// go to the Boot header tag
|
||||
img.seek(Current(
|
||||
hdr_head.size.get() as i64
|
||||
- size_of::<BootHdrHead>() as i64
|
||||
@@ -218,7 +241,7 @@ mod tests {
|
||||
Err(Error::InvBootHdr)
|
||||
));
|
||||
|
||||
//header is at a non expected position
|
||||
// header is at a non expected position
|
||||
let mut img = vec![0u8; PAGESIZE];
|
||||
img[0x008..0x288].copy_from_slice(bin_hdr);
|
||||
assert!(matches!(
|
||||
@@ -235,4 +258,24 @@ mod tests {
|
||||
let hdr_tags = BootHdrTags::from_se_image(&mut Cursor::new(img)).unwrap();
|
||||
assert_eq!(hdr_tags, EXP_HDR);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tags_convert_u8() {
|
||||
let bin_hdr = get_test_asset!("exp/secure_guest.hdr");
|
||||
let hdr_tags = BootHdrTags::from_se_image(&mut Cursor::new(*bin_hdr)).unwrap();
|
||||
let ser: &[u8] = hdr_tags.as_ref();
|
||||
let mut ser = ser.to_vec();
|
||||
|
||||
let der: BootHdrTags = ser.clone().try_into().unwrap();
|
||||
assert_eq!(hdr_tags, der);
|
||||
|
||||
ser.pop();
|
||||
let der: Result<BootHdrTags> = ser.clone().try_into();
|
||||
assert!(matches!(der, Err(Error::InvBootHdrSize(_))));
|
||||
|
||||
ser.push(17);
|
||||
ser.push(17);
|
||||
let der: Result<BootHdrTags> = ser.clone().try_into();
|
||||
assert!(matches!(der, Err(Error::InvBootHdrSize(_))));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,6 +79,9 @@ pub enum Error {
|
||||
#[error("The provided host key document in {0} contains no certificate!")]
|
||||
NoHkdInFile(String),
|
||||
|
||||
#[error("Invalid input size ({0}) for boot hdr")]
|
||||
InvBootHdrSize(usize),
|
||||
|
||||
// errors from other crates
|
||||
#[error(transparent)]
|
||||
PvCore(#[from] pv_core::Error),
|
||||
|
||||
Reference in New Issue
Block a user