From 5c29271cec26b40fb8a937af4be5bb3560bca27c Mon Sep 17 00:00:00 2001 From: OuyangHang33 Date: Thu, 29 Feb 2024 23:19:59 +0800 Subject: [PATCH] Split file operation from loader.rs and change parse() API Signed-off-by: OuyangHang33 --- .github/workflows/main.yml | 2 +- td-shim-tools/Cargo.toml | 5 +- td-shim-tools/src/bin/td-shim-checker/main.rs | 5 +- td-shim-tools/src/lib.rs | 3 + td-shim-tools/src/loader.rs | 82 ++++--------------- td-shim-tools/src/read_file.rs | 56 +++++++++++++ 6 files changed, 85 insertions(+), 68 deletions(-) create mode 100644 td-shim-tools/src/read_file.rs diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 12c45b5b..83a1be09 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -87,7 +87,7 @@ jobs: - name: Meta data check run: | - cargo run -p td-shim-tools --bin td-shim-checker --no-default-features --features=loader -- target/release/final.bin + cargo run -p td-shim-tools --bin td-shim-checker --no-default-features --features=loader,read_file -- target/release/final.bin - name: Build debug image without payload run: | diff --git a/td-shim-tools/Cargo.toml b/td-shim-tools/Cargo.toml index a4e7f572..f99ec9a8 100644 --- a/td-shim-tools/Cargo.toml +++ b/td-shim-tools/Cargo.toml @@ -21,7 +21,7 @@ required-features = ["signer"] [[bin]] name = "td-shim-checker" -required-features = ["loader"] +required-features = ["loader", "read_file"] [[bin]] name = "td-shim-strip-info" @@ -61,11 +61,12 @@ byteorder = { version = "1.4.3", optional = true } parse_int = { version = "0.6.0", optional = true } [features] -default = ["enroller", "linker", "signer", "loader", "tee", "calculator"] +default = ["enroller", "linker", "signer", "loader", "tee", "calculator", "read_file"] enroller = ["clap", "der", "env_logger", "log", "ring", "td-shim/secure-boot"] linker = ["clap", "env_logger", "log", "parse_int", "serde_json", "serde", "td-loader"] signer = ["clap", "der", "env_logger", "log", "ring", "td-shim/secure-boot"] loader = ["clap", "env_logger", "log"] +read_file = ["clap", "env_logger", "log", "anyhow"] tee = ["clap", "env_logger", "log", "serde_json", "serde", "hex", "sha2", "byteorder"] calculator = ["clap", "hex", "parse_int", "sha2", "anyhow", "block-padding"] exec-payload-section = [] diff --git a/td-shim-tools/src/bin/td-shim-checker/main.rs b/td-shim-tools/src/bin/td-shim-checker/main.rs index 8046171e..822bbf98 100644 --- a/td-shim-tools/src/bin/td-shim-checker/main.rs +++ b/td-shim-tools/src/bin/td-shim-checker/main.rs @@ -12,6 +12,7 @@ use std::vec::Vec; use std::{env, io}; use td_shim::metadata::{TdxMetadataDescriptor, TdxMetadataSection}; use td_shim_tools::loader::TdShimLoader; +use td_shim_tools::read_file::read_from_binary_file; struct Config { // Input file path to be read @@ -101,7 +102,9 @@ fn main() -> io::Result<()> { "Parse td-shim binary [{}] to get TdxMetadata ...", config.input ); - let tdx_metadata = TdShimLoader::parse(&config.input); + + let tdx_file_buff = read_from_binary_file(&config.input).unwrap(); + let tdx_metadata = TdShimLoader::parse(tdx_file_buff); if tdx_metadata.is_none() { println!( "Failed to parse td-shim binary [{}] to get TdxMetadata", diff --git a/td-shim-tools/src/lib.rs b/td-shim-tools/src/lib.rs index 9d42b0f4..bb0c5c64 100644 --- a/td-shim-tools/src/lib.rs +++ b/td-shim-tools/src/lib.rs @@ -27,6 +27,9 @@ pub mod signer; #[cfg(feature = "loader")] pub mod loader; +#[cfg(feature = "read_file")] +pub mod read_file; + #[cfg(feature = "tee")] pub mod tee_info_hash; diff --git a/td-shim-tools/src/loader.rs b/td-shim-tools/src/loader.rs index dca17dbb..88957dc8 100644 --- a/td-shim-tools/src/loader.rs +++ b/td-shim-tools/src/loader.rs @@ -2,13 +2,9 @@ // // SPDX-License-Identifier: BSD-2-Clause-Patent -use log::debug; +use core::convert::TryInto; use log::error; use scroll::Pread; -use std::fs; -use std::io; -use std::io::Read; -use std::io::Seek; use td_shim::metadata::{ self, TdxMetadataDescriptor, TdxMetadataGuid, TdxMetadataSection, TDX_METADATA_DESCRIPTOR_LEN, TDX_METADATA_GUID_LEN, TDX_METADATA_OFFSET, TDX_METADATA_SECTION_LEN, @@ -16,55 +12,22 @@ use td_shim::metadata::{ pub struct TdShimLoader; -fn read_from_file(file: &mut std::fs::File, pos: u64, buffer: &mut [u8]) -> io::Result<()> { - debug!("Read at pos={0:X}, len={1:X}", pos, buffer.len()); - let _pos = std::io::SeekFrom::Start(pos); - file.seek(_pos)?; - file.read_exact(buffer)?; - debug!("{:X?}", buffer); - Ok(()) -} - impl TdShimLoader { /// generate TdxMetadata elements tupple from input file /// /// # Arguments /// /// * `filename` - The td-shim binary which contains TdxMetadata - pub fn parse(filename: &String) -> Option<(TdxMetadataDescriptor, Vec)> { - // first we open the input file and get its size - let f = fs::File::open(filename); - if f.is_err() { - error!("Problem opening the file"); - return None; - } - - let mut file = f.unwrap(); - - let file_metadata = fs::metadata(filename); - if file_metadata.is_err() { - error!("Problem read file meatadata"); - return None; - } - - let file_metadata = file_metadata.unwrap(); - let file_size = file_metadata.len(); - + pub fn parse(binary_file: Vec) -> Option<(TdxMetadataDescriptor, Vec)> { + let file_size = binary_file.len(); // Then read 4 bytes at the pos of [file_len - 0x20] // This is the offset of TdxMetadata - let mut buffer: [u8; 4] = [0; 4]; - if read_from_file( - &mut file, - file_size - TDX_METADATA_OFFSET as u64, - &mut buffer, - ) - .is_err() - { - error!("Failed to read metadata offset"); - return None; - } - - let mut metadata_offset = u32::from_le_bytes(buffer); + let metadata_offset_addr = file_size - TDX_METADATA_OFFSET as usize; + let buffer = &binary_file[metadata_offset_addr..metadata_offset_addr + 4]; + let mut metadata_offset = ((buffer[3] as u32) << 24) + | ((buffer[2] as u32) << 16) + | ((buffer[1] as u32) << 8) + | (buffer[0] as u32); if metadata_offset > file_size as u32 - TDX_METADATA_OFFSET - TDX_METADATA_DESCRIPTOR_LEN { error!("The metadata offset is invalid. {}", metadata_offset); error!("{:X?}", buffer); @@ -73,12 +36,11 @@ impl TdShimLoader { // Then read the guid metadata_offset -= TDX_METADATA_GUID_LEN; - let mut buffer: [u8; TDX_METADATA_GUID_LEN as usize] = [0; TDX_METADATA_GUID_LEN as usize]; - if read_from_file(&mut file, metadata_offset as u64, &mut buffer).is_err() { - error!("Failed to read metadata guid from file"); - return None; - } - let metadata_guid = TdxMetadataGuid::from_bytes(&buffer); + let buffer = &binary_file + [metadata_offset as usize..(metadata_offset + TDX_METADATA_GUID_LEN) as usize] + .try_into() + .unwrap(); + let metadata_guid = TdxMetadataGuid::from_bytes(buffer); if metadata_guid.is_none() { error!("Invalid TdxMetadataGuid"); error!("{:X?}", &buffer); @@ -86,13 +48,9 @@ impl TdShimLoader { } // Then the descriptor - let mut buffer: [u8; TDX_METADATA_DESCRIPTOR_LEN as usize] = - [0; TDX_METADATA_DESCRIPTOR_LEN as usize]; metadata_offset += TDX_METADATA_GUID_LEN; - if read_from_file(&mut file, metadata_offset as u64, &mut buffer).is_err() { - error!("Failed to read metadata descriptor from file"); - return None; - } + let buffer = &binary_file + [metadata_offset as usize..(metadata_offset + TDX_METADATA_DESCRIPTOR_LEN) as usize]; let metadata_descriptor: TdxMetadataDescriptor = buffer.pread::(0).unwrap(); if !metadata_descriptor.is_valid() { @@ -117,12 +75,8 @@ impl TdShimLoader { metadata_offset += TDX_METADATA_DESCRIPTOR_LEN; loop { - let mut buffer: [u8; TDX_METADATA_SECTION_LEN as usize] = - [0; TDX_METADATA_SECTION_LEN as usize]; - if read_from_file(&mut file, metadata_offset as u64, &mut buffer).is_err() { - error!("Failed to read section[{}] from file", i); - return None; - } + let buffer = &binary_file + [metadata_offset as usize..(metadata_offset + TDX_METADATA_SECTION_LEN) as usize]; let section = buffer.pread::(0).unwrap(); metadata_sections.push(section); diff --git a/td-shim-tools/src/read_file.rs b/td-shim-tools/src/read_file.rs new file mode 100644 index 00000000..09779ca6 --- /dev/null +++ b/td-shim-tools/src/read_file.rs @@ -0,0 +1,56 @@ +// Copyright (c) 2022 Intel Corporation +// +// SPDX-License-Identifier: BSD-2-Clause-Patent + +use anyhow::*; +use log::debug; +use std::fs; +use std::io::Read; +use std::io::Seek; +use td_shim::metadata::TDX_METADATA_OFFSET; + +fn read_from_file(file: &mut std::fs::File, pos: u64, buffer: &mut [u8]) -> Result<()> { + debug!("Read at pos={0:X}, len={1:X}", pos, buffer.len()); + let _pos = std::io::SeekFrom::Start(pos); + file.seek(_pos)?; + file.read_exact(buffer)?; + debug!("{:X?}", buffer); + Ok(()) +} + +pub fn read_from_binary_file(filename: &String) -> Result> { + let f = fs::File::open(filename); + if f.is_err() { + bail!("Problem opening the file"); + } + + let mut file = f.unwrap(); + + let file_metadata = fs::metadata(filename); + if file_metadata.is_err() { + bail!("Problem read file meatadata"); + } + + let file_metadata = file_metadata.unwrap(); + let file_size = file_metadata.len(); + + // Then read 4 bytes at the pos of [file_len - 0x20] + // This is the offset of TdxMetadata + let mut metadata_buffer: Vec = vec![0; 4]; + if read_from_file( + &mut file, + file_size - TDX_METADATA_OFFSET as u64, + &mut metadata_buffer, + ) + .is_err() + { + bail!("Failed to read metadata offset"); + } + + // Read whole binary file and return binary string + let mut buffer: Vec = vec![0; file_size as usize]; + if read_from_file(&mut file, 0, &mut buffer).is_err() { + bail!("Failed to read tdshim binary file"); + } + Ok(buffer) +}