Skip to main content

compute_hash_digest/
compute-hash-digest.rs

1//! Computes the [`HeaderV0::hash_digest`] value with SHA-1.
2use std::{fs::File, process::ExitCode};
3
4use abootimg_oxide::HeaderV0;
5
6fn main() -> ExitCode {
7    let args: Vec<_> = std::env::args().skip(1).collect();
8    let Ok([hash_type, paths @ ..]) = TryInto::<[_; 6]>::try_into(args) else {
9        eprintln!("Usage: compute-hash-digest <--sha1|--sha256> <kernel> <ramdisk> <second bootloader> <recovery dtbo> <dtb>\n\nEmpty paths and errors are ignored.");
10        return ExitCode::FAILURE;
11    };
12
13    let files = paths.map(|path| {
14        if path.is_empty() {
15            None
16        } else {
17            File::open(path).ok()
18        }
19    });
20
21    let mut files = files.each_ref().map(|opt| opt.as_ref());
22    let files = files.each_mut().map(|opt| opt.as_mut());
23
24    let hash_digest = match hash_type.as_str() {
25        "--sha1" => hash_files::<sha1::Sha1>(files),
26        "--sha256" => hash_files::<sha2::Sha256>(files),
27        _ => {
28            eprintln!("Unknown hash type: {hash_type}.\n\nUsage: compute-hash-digest <--sha1|--sha256> <kernel> <ramdisk> <second bootloader> <recovery dtbo> <dtb>\n\nEmpty paths and errors are ignored.");
29            return ExitCode::FAILURE;
30        }
31    };
32
33    println!("The hash digest is {}", hex_fmt::HexFmt(hash_digest));
34    ExitCode::SUCCESS
35}
36
37fn hash_files<D: digest::Digest>(files: [Option<&mut &File>; 5]) -> [u8; 32] {
38    let [kernel_f, ramdisk_f, second_bootloader_f, recovery_dtbo_f, dtb_f] = files;
39
40    HeaderV0::compute_hash_digest::<_, D>(
41        kernel_f,
42        ramdisk_f,
43        second_bootloader_f,
44        recovery_dtbo_f,
45        dtb_f,
46    )
47    .unwrap()
48}