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"
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"

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)));
}
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<dhtb_hdr *>(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<blob_hdr *>(out.buf());

View File

@ -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<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 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<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(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") {

View File

@ -2,32 +2,51 @@ use digest::DynDigest;
use sha1::Sha1;
use sha2::Sha256;
pub struct SHA {
hasher: Box<dyn DynDigest>,
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<u8> {
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<SHA> {
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<u8> {
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();
}