From ee943afbc9282d08b851846daf4a6a2dfac46af5 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Fri, 30 Jun 2023 15:50:52 -0700 Subject: [PATCH] Cleanup SHA hash implementation --- native/src/Cargo.toml | 16 ++++++++---- native/src/boot/bootimg.cpp | 7 +++--- native/src/boot/lib.rs | 18 +++++++------- native/src/boot/main.cpp | 8 ++++-- native/src/boot/sha.rs | 49 +++++++++++++++++++++++++------------ 5 files changed, 63 insertions(+), 35 deletions(-) diff --git a/native/src/Cargo.toml b/native/src/Cargo.toml index e87ab1de1..ce59eba12 100644 --- a/native/src/Cargo.toml +++ b/native/src/Cargo.toml @@ -14,11 +14,17 @@ thiserror = "1.0" byteorder = "1" size = "0.4" argh = "0.1.10" -pb-rs = { git = "https://github.com/tafia/quick-protobuf.git", rev = "2f37d5a65504de7d716b5b28fd82219501a901a9" } -quick-protobuf = { git = "https://github.com/tafia/quick-protobuf.git", rev = "2f37d5a65504de7d716b5b28fd82219501a901a9" } -sha1 = "0.10.5" -sha2 = "0.10.7" -digest = "0.10.7" +sha1 = "0.10" +sha2 = "0.10" +digest = "0.10" + +[workspace.dependencies.pb-rs] +git = "https://github.com/tafia/quick-protobuf.git" +rev = "2f37d5a65504de7d716b5b28fd82219501a901a9" + +[workspace.dependencies.quick-protobuf] +git = "https://github.com/tafia/quick-protobuf.git" +rev = "2f37d5a65504de7d716b5b28fd82219501a901a9" [profile.dev] opt-level = "z" diff --git a/native/src/boot/bootimg.cpp b/native/src/boot/bootimg.cpp index 4abcea2a6..d87b08581 100644 --- a/native/src/boot/bootimg.cpp +++ b/native/src/boot/bootimg.cpp @@ -777,8 +777,7 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) { ctx->update(byte_view(&size, sizeof(size))); } memset(id, 0, BOOT_ID_SIZE); - auto digest = ctx->finalize(); - memcpy(id, digest.data(), digest.size()); + ctx->finalize_into(byte_data(id, ctx->output_size())); } // Print new header info @@ -809,8 +808,8 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) { auto d_hdr = reinterpret_cast(out.buf()); memcpy(d_hdr, DHTB_MAGIC, 8); d_hdr->size = off.total - sizeof(dhtb_hdr); - auto checksum = sha_digest(byte_view(out.buf() + sizeof(dhtb_hdr), d_hdr->size), false); - memcpy(d_hdr->checksum, checksum.data(), checksum.size()); + sha256_hash(byte_view(out.buf() + sizeof(dhtb_hdr), d_hdr->size), + byte_data(d_hdr->checksum, 32)); } else if (boot.flags[BLOB_FLAG]) { // Blob header auto b_hdr = reinterpret_cast(out.buf()); diff --git a/native/src/boot/lib.rs b/native/src/boot/lib.rs index d791b51cd..d528fd572 100644 --- a/native/src/boot/lib.rs +++ b/native/src/boot/lib.rs @@ -5,7 +5,7 @@ pub use base; use cpio::cpio_commands; use patch::{hexpatch, patch_encryption, patch_verity}; use payload::extract_boot_from_payload; -use sha::{get_sha, sha_digest, SHA}; +use sha::{get_sha, sha1_hash, sha256_hash, SHA}; mod cpio; mod patch; @@ -24,6 +24,14 @@ pub mod ffi { } extern "Rust" { + type SHA; + fn get_sha(use_sha1: bool) -> Box; + fn update(self: &mut SHA, data: &[u8]); + fn finalize_into(self: &mut SHA, out: &mut [u8]); + fn output_size(self: &SHA) -> usize; + fn sha1_hash(data: &[u8], out: &mut [u8]); + fn sha256_hash(data: &[u8], out: &mut [u8]); + fn hexpatch(file: &[u8], from: &[u8], to: &[u8]) -> bool; fn patch_encryption(buf: &mut [u8]) -> usize; fn patch_verity(buf: &mut [u8]) -> usize; @@ -39,12 +47,4 @@ pub mod ffi { unsafe fn cpio_commands(argc: i32, argv: *const *const c_char) -> bool; } - - extern "Rust" { - type SHA; - fn get_sha(use_sha1: bool) -> Box; - fn finalize(&mut self) -> Vec; - fn update(&mut self, data: &[u8]); - fn sha_digest(data: &[u8], use_sha1: bool) -> Vec; - } } diff --git a/native/src/boot/main.cpp b/native/src/boot/main.cpp index 390a5076e..e43f0255e 100644 --- a/native/src/boot/main.cpp +++ b/native/src/boot/main.cpp @@ -133,8 +133,12 @@ int main(int argc, char *argv[]) { unlink(RECV_DTBO_FILE); unlink(DTB_FILE); } else if (argc > 2 && action == "sha1") { - mmap_data m(argv[2]); - for (auto i : sha_digest(byte_view(m.buf(), m.sz()), true)) + uint8_t sha1[20]; + { + mmap_data m(argv[2]); + sha1_hash(m, byte_data(sha1, sizeof(sha1))); + } + for (uint8_t i : sha1) printf("%02x", i); printf("\n"); } else if (argc > 2 && action == "split") { diff --git a/native/src/boot/sha.rs b/native/src/boot/sha.rs index ccb2e5ea0..d4b1e1a65 100644 --- a/native/src/boot/sha.rs +++ b/native/src/boot/sha.rs @@ -2,32 +2,51 @@ use digest::DynDigest; use sha1::Sha1; use sha2::Sha256; -pub struct SHA { - hasher: Box, +pub enum SHA { + SHA1(Sha1), + SHA256(Sha256), } impl SHA { pub fn update(&mut self, data: &[u8]) { - self.hasher.update(data); + match self { + SHA::SHA1(h) => h.update(data), + SHA::SHA256(h) => h.update(data), + } } - pub fn finalize(&mut self) -> Vec { - self.hasher.finalize_reset().to_vec() + pub fn output_size(&self) -> usize { + match self { + SHA::SHA1(h) => h.output_size(), + SHA::SHA256(h) => h.output_size(), + } + } + + pub fn finalize_into(&mut self, out: &mut [u8]) { + match self { + SHA::SHA1(h) => h.finalize_into_reset(out), + SHA::SHA256(h) => h.finalize_into_reset(out), + } + .ok(); } } pub fn get_sha(use_sha1: bool) -> Box { - Box::new(SHA { - hasher: if use_sha1 { - Box::new(Sha1::default()) - } else { - Box::new(Sha256::default()) - }, + Box::new(if use_sha1 { + SHA::SHA1(Sha1::default()) + } else { + SHA::SHA256(Sha256::default()) }) } -pub fn sha_digest(data: &[u8], use_sha1: bool) -> Vec { - let mut sha = get_sha(use_sha1); - sha.update(data); - sha.finalize() +pub fn sha1_hash(data: &[u8], out: &mut [u8]) { + let mut h = Sha1::default(); + h.update(data); + DynDigest::finalize_into(h, out).ok(); +} + +pub fn sha256_hash(data: &[u8], out: &mut [u8]) { + let mut h = Sha256::default(); + h.update(data); + DynDigest::finalize_into(h, out).ok(); }