KVS/src/KVG/main.rs
kxtzownsu 8d8f390e98 bug fixes (kvs 2.0.0-rc)
- add debug printing if `--debug` or `-d` is passed to the KVS binary
- remove old RMASmoke references
- Add Darkn to credits for testing
- update arg_checks library
- add error checking in sysinfo
2025-01-28 17:50:03 +00:00

186 lines
4.9 KiB
Rust

use std::env;
use std::process;
use std::io::{self, Write};
const VB2_SHA256_DIGEST_SIZE: usize = 32;
const MAX_HEX_LENGTH: usize = 10;
#[repr(C, packed)]
struct Vb2SecdataKernelV0 {
struct_version: u8,
uid: u32,
kernver: u32,
reserved: [u8; 3],
crc8: u8,
}
#[repr(C, packed)]
struct Vb2SecdataKernelV1 {
struct_version: u8,
struct_size: u8,
crc8: u8,
flags: u8,
kernver: u32,
ec_hash: [u8; VB2_SHA256_DIGEST_SIZE],
}
struct Vb2Context<'a> {
secdata_kernel: &'a [u8],
}
fn vb2_crc8(data: &[u8]) -> u8 {
let mut crc: u16 = 0;
for byte in data {
crc ^= (*byte as u16) << 8;
for _ in 0..8 {
if crc & 0x8000 != 0 {
crc ^= 0x1070 << 3;
}
crc <<= 1;
}
}
(crc >> 8) as u8
}
fn is_v0(context: &Vb2Context) -> bool {
let major_version = (context.secdata_kernel[0] & 0xf0) >> 4;
major_version == 0
}
fn secdata_kernel_crc(context: &Vb2Context) -> u8 {
if is_v0(context) {
let size = std::mem::size_of::<Vb2SecdataKernelV0>() - 1;
vb2_crc8(&context.secdata_kernel[0..size])
} else {
let struct_size = context.secdata_kernel[1] as usize;
let offset = 3;
vb2_crc8(&context.secdata_kernel[offset..struct_size])
}
}
fn is_valid_hex(input: &str) -> bool {
if input.len() > MAX_HEX_LENGTH {
return false;
}
if let Some(stripped) = input.strip_prefix("0x") {
stripped.chars().all(|c| c.is_digit(16))
} else {
false
}
}
fn sanitize_input(input: &str) -> String {
input.replace('\n', "\0")
}
fn convert_to_u32(input: &str) -> u32 {
u32::from_str_radix(input.trim_start_matches("0x"), 16).unwrap_or_else(|_| {
eprintln!(
"The entered kernver, {}, was not valid hexadecimal. Please try again.",
input
);
process::exit(1);
})
}
fn print_hex(data: &[u8]) {
for byte in data {
print!("{:02x} ", byte);
}
println!();
}
fn main() {
let args: Vec<String> = env::args().collect();
if args.len() < 2 || args.contains(&"--help".to_string()) {
println!(
"USAGE: {} <kernver> <optional flags>\n\
e.g.: {} 0x00010001 --raw\n\
--raw - prints the output as raw hex bytes\n\
--ver=<0/1> - specifies the kernver struct version to use\n\
--help - shows this message\n\
KVG was created by kxtzownsu\n\
(now written in Rust)",
args[0], args[0]
);
process::exit(0);
}
let kernver = sanitize_input(&args[1]);
if !is_valid_hex(&kernver) {
eprintln!(
"The entered kernver: {}, wasn't detected as valid hexadecimal (max 10 characters). Please try again.",
kernver
);
process::exit(1);
}
let kvarg = convert_to_u32(&kernver);
let version = args.iter().find(|arg| arg.starts_with("--ver=")).map_or("", |v| &v[6..]);
if version != "0" && version != "1" {
eprintln!(
"The entered struct version: {}, wasn't valid (see --help). Please try again.",
version
);
process::exit(1);
}
let mut buffer = Vec::new();
if version == "0" {
let mut secdata0 = Vb2SecdataKernelV0 {
struct_version: 0x02,
uid: 0x4752574c,
kernver: kvarg,
reserved: [0x00; 3],
crc8: 0,
};
let ctx = Vb2Context {
secdata_kernel: unsafe {
std::slice::from_raw_parts(
&secdata0 as *const _ as *const u8,
std::mem::size_of::<Vb2SecdataKernelV0>(),
)
},
};
secdata0.crc8 = secdata_kernel_crc(&ctx);
buffer.extend_from_slice(unsafe {
std::slice::from_raw_parts(
&secdata0 as *const _ as *const u8,
std::mem::size_of::<Vb2SecdataKernelV0>(),
)
});
} else if version == "1" {
let mut secdata1 = Vb2SecdataKernelV1 {
struct_version: 0x10,
struct_size: std::mem::size_of::<Vb2SecdataKernelV1>() as u8,
crc8: 0,
flags: 0x0,
kernver: kvarg,
ec_hash: [0; VB2_SHA256_DIGEST_SIZE],
};
let ctx = Vb2Context {
secdata_kernel: unsafe {
std::slice::from_raw_parts(
&secdata1 as *const _ as *const u8,
std::mem::size_of::<Vb2SecdataKernelV1>(),
)
},
};
secdata1.crc8 = secdata_kernel_crc(&ctx);
buffer.extend_from_slice(unsafe {
std::slice::from_raw_parts(
&secdata1 as *const _ as *const u8,
std::mem::size_of::<Vb2SecdataKernelV1>(),
)
});
}
if args.contains(&"--raw".to_string()) {
io::stdout().write_all(&buffer).unwrap();
} else {
print_hex(&buffer);
}
}