Cleanup SHA hash implementation

This commit is contained in:
topjohnwu 2023-06-30 15:50:52 -07:00
parent 1f7c3e9f14
commit ee943afbc9
5 changed files with 63 additions and 35 deletions

View File

@ -14,11 +14,17 @@ thiserror = "1.0"
byteorder = "1" byteorder = "1"
size = "0.4" size = "0.4"
argh = "0.1.10" argh = "0.1.10"
pb-rs = { git = "https://github.com/tafia/quick-protobuf.git", rev = "2f37d5a65504de7d716b5b28fd82219501a901a9" } sha1 = "0.10"
quick-protobuf = { git = "https://github.com/tafia/quick-protobuf.git", rev = "2f37d5a65504de7d716b5b28fd82219501a901a9" } sha2 = "0.10"
sha1 = "0.10.5" digest = "0.10"
sha2 = "0.10.7"
digest = "0.10.7" [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] [profile.dev]
opt-level = "z" opt-level = "z"

View File

@ -777,8 +777,7 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) {
ctx->update(byte_view(&size, sizeof(size))); ctx->update(byte_view(&size, sizeof(size)));
} }
memset(id, 0, BOOT_ID_SIZE); memset(id, 0, BOOT_ID_SIZE);
auto digest = ctx->finalize(); ctx->finalize_into(byte_data(id, ctx->output_size()));
memcpy(id, digest.data(), digest.size());
} }
// Print new header info // 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<dhtb_hdr *>(out.buf()); auto d_hdr = reinterpret_cast<dhtb_hdr *>(out.buf());
memcpy(d_hdr, DHTB_MAGIC, 8); memcpy(d_hdr, DHTB_MAGIC, 8);
d_hdr->size = off.total - sizeof(dhtb_hdr); d_hdr->size = off.total - sizeof(dhtb_hdr);
auto checksum = sha_digest(byte_view(out.buf() + sizeof(dhtb_hdr), d_hdr->size), false); sha256_hash(byte_view(out.buf() + sizeof(dhtb_hdr), d_hdr->size),
memcpy(d_hdr->checksum, checksum.data(), checksum.size()); byte_data(d_hdr->checksum, 32));
} else if (boot.flags[BLOB_FLAG]) { } else if (boot.flags[BLOB_FLAG]) {
// Blob header // Blob header
auto b_hdr = reinterpret_cast<blob_hdr *>(out.buf()); auto b_hdr = reinterpret_cast<blob_hdr *>(out.buf());

View File

@ -5,7 +5,7 @@ pub use base;
use cpio::cpio_commands; use cpio::cpio_commands;
use patch::{hexpatch, patch_encryption, patch_verity}; use patch::{hexpatch, patch_encryption, patch_verity};
use payload::extract_boot_from_payload; 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 cpio;
mod patch; mod patch;
@ -24,6 +24,14 @@ pub mod ffi {
} }
extern "Rust" { extern "Rust" {
type SHA;
fn get_sha(use_sha1: bool) -> Box<SHA>;
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 hexpatch(file: &[u8], from: &[u8], to: &[u8]) -> bool;
fn patch_encryption(buf: &mut [u8]) -> usize; fn patch_encryption(buf: &mut [u8]) -> usize;
fn patch_verity(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; unsafe fn cpio_commands(argc: i32, argv: *const *const c_char) -> bool;
} }
extern "Rust" {
type SHA;
fn get_sha(use_sha1: bool) -> Box<SHA>;
fn finalize(&mut self) -> Vec<u8>;
fn update(&mut self, data: &[u8]);
fn sha_digest(data: &[u8], use_sha1: bool) -> Vec<u8>;
}
} }

View File

@ -133,8 +133,12 @@ int main(int argc, char *argv[]) {
unlink(RECV_DTBO_FILE); unlink(RECV_DTBO_FILE);
unlink(DTB_FILE); unlink(DTB_FILE);
} else if (argc > 2 && action == "sha1") { } else if (argc > 2 && action == "sha1") {
mmap_data m(argv[2]); uint8_t sha1[20];
for (auto i : sha_digest(byte_view(m.buf(), m.sz()), true)) {
mmap_data m(argv[2]);
sha1_hash(m, byte_data(sha1, sizeof(sha1)));
}
for (uint8_t i : sha1)
printf("%02x", i); printf("%02x", i);
printf("\n"); printf("\n");
} else if (argc > 2 && action == "split") { } else if (argc > 2 && action == "split") {

View File

@ -2,32 +2,51 @@ use digest::DynDigest;
use sha1::Sha1; use sha1::Sha1;
use sha2::Sha256; use sha2::Sha256;
pub struct SHA { pub enum SHA {
hasher: Box<dyn DynDigest>, SHA1(Sha1),
SHA256(Sha256),
} }
impl SHA { impl SHA {
pub fn update(&mut self, data: &[u8]) { 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<u8> { pub fn output_size(&self) -> usize {
self.hasher.finalize_reset().to_vec() 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<SHA> { pub fn get_sha(use_sha1: bool) -> Box<SHA> {
Box::new(SHA { Box::new(if use_sha1 {
hasher: if use_sha1 { SHA::SHA1(Sha1::default())
Box::new(Sha1::default()) } else {
} else { SHA::SHA256(Sha256::default())
Box::new(Sha256::default())
},
}) })
} }
pub fn sha_digest(data: &[u8], use_sha1: bool) -> Vec<u8> { pub fn sha1_hash(data: &[u8], out: &mut [u8]) {
let mut sha = get_sha(use_sha1); let mut h = Sha1::default();
sha.update(data); h.update(data);
sha.finalize() 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();
} }