Use rust to calculate sha

This commit is contained in:
LoveSy
2023-06-25 03:50:21 +08:00
committed by John Wu
parent 46770db18b
commit 1f7c3e9f14
11 changed files with 155 additions and 29 deletions

View File

@@ -18,3 +18,6 @@ byteorder = { workspace = true }
size = { workspace = true }
quick-protobuf = { workspace = true }
argh = { workspace = true }
sha1 = { workspace = true }
sha2 = { workspace = true }
digest = { workspace = true }

View File

@@ -2,10 +2,9 @@
#include <memory>
#include <libfdt.h>
#include <mincrypt/sha.h>
#include <mincrypt/sha256.h>
#include <base.hpp>
#include "boot-rs.hpp"
#include "bootimg.hpp"
#include "magiskboot.hpp"
#include "compress.hpp"
@@ -13,6 +12,8 @@
using namespace std;
#define PADDING 15
#define SHA256_DIGEST_SIZE 32
#define SHA_DIGEST_SIZE 20
static void decompress(format_t type, int fd, const void *in, size_t size) {
auto ptr = get_decoder(type, make_unique<fd_channel>(fd));
@@ -749,35 +750,35 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) {
// Update checksum
if (char *id = hdr->id()) {
HASH_CTX ctx;
boot.flags[SHA256_FLAG] ? SHA256_init(&ctx) : SHA_init(&ctx);
auto ctx = get_sha(!boot.flags[SHA256_FLAG]);
uint32_t size = hdr->kernel_size();
HASH_update(&ctx, out.buf() + off.kernel, size);
HASH_update(&ctx, &size, sizeof(size));
ctx->update(byte_view(out.buf() + off.kernel, size));
ctx->update(byte_view(&size, sizeof(size)));
size = hdr->ramdisk_size();
HASH_update(&ctx, out.buf() + off.ramdisk, size);
HASH_update(&ctx, &size, sizeof(size));
ctx->update(byte_view(out.buf() + off.ramdisk, size));
ctx->update(byte_view(&size, sizeof(size)));
size = hdr->second_size();
HASH_update(&ctx, out.buf() + off.second, size);
HASH_update(&ctx, &size, sizeof(size));
ctx->update(byte_view(out.buf() + off.second, size));
ctx->update(byte_view(&size, sizeof(size)));
size = hdr->extra_size();
if (size) {
HASH_update(&ctx, out.buf() + off.extra, size);
HASH_update(&ctx, &size, sizeof(size));
ctx->update(byte_view(out.buf() + off.extra, size));
ctx->update(byte_view(&size, sizeof(size)));
}
uint32_t ver = hdr->header_version();
if (ver == 1 || ver == 2) {
size = hdr->recovery_dtbo_size();
HASH_update(&ctx, out.buf() + hdr->recovery_dtbo_offset(), size);
HASH_update(&ctx, &size, sizeof(size));
ctx->update(byte_view(out.buf() + hdr->recovery_dtbo_offset(), size));
ctx->update(byte_view(&size, sizeof(size)));
}
if (ver == 2) {
size = hdr->dtb_size();
HASH_update(&ctx, out.buf() + off.dtb, size);
HASH_update(&ctx, &size, sizeof(size));
ctx->update(byte_view(out.buf() + off.dtb, size));
ctx->update(byte_view(&size, sizeof(size)));
}
memset(id, 0, BOOT_ID_SIZE);
memcpy(id, HASH_final(&ctx), boot.flags[SHA256_FLAG] ? SHA256_DIGEST_SIZE : SHA_DIGEST_SIZE);
auto digest = ctx->finalize();
memcpy(id, digest.data(), digest.size());
}
// Print new header info
@@ -808,7 +809,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);
SHA256_hash(out.buf() + sizeof(dhtb_hdr), d_hdr->size, d_hdr->checksum);
auto checksum = sha_digest(byte_view(out.buf() + sizeof(dhtb_hdr), d_hdr->size), false);
memcpy(d_hdr->checksum, checksum.data(), checksum.size());
} else if (boot.flags[BLOB_FLAG]) {
// Blob header
auto b_hdr = reinterpret_cast<blob_hdr *>(out.buf());

View File

@@ -5,6 +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};
mod cpio;
mod patch;
@@ -13,6 +14,7 @@ mod payload;
#[allow(warnings)]
mod proto;
mod ramdisk;
mod sha;
#[cxx::bridge]
pub mod ffi {
@@ -37,4 +39,12 @@ 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

@@ -1,4 +1,3 @@
#include <mincrypt/sha.h>
#include <base.hpp>
#include "boot-rs.hpp"
@@ -134,10 +133,8 @@ int main(int argc, char *argv[]) {
unlink(RECV_DTBO_FILE);
unlink(DTB_FILE);
} else if (argc > 2 && action == "sha1") {
uint8_t sha1[SHA_DIGEST_SIZE];
mmap_data m(argv[2]);
SHA_hash(m.buf(), m.sz(), sha1);
for (uint8_t i : sha1)
for (auto i : sha_digest(byte_view(m.buf(), m.sz()), true))
printf("%02x", i);
printf("\n");
} else if (argc > 2 && action == "split") {

33
native/src/boot/sha.rs Normal file
View File

@@ -0,0 +1,33 @@
use digest::DynDigest;
use sha1::Sha1;
use sha2::Sha256;
pub struct SHA {
hasher: Box<dyn DynDigest>,
}
impl SHA {
pub fn update(&mut self, data: &[u8]) {
self.hasher.update(data);
}
pub fn finalize(&mut self) -> Vec<u8> {
self.hasher.finalize_reset().to_vec()
}
}
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())
},
})
}
pub fn sha_digest(data: &[u8], use_sha1: bool) -> Vec<u8> {
let mut sha = get_sha(use_sha1);
sha.update(data);
sha.finalize()
}