add BurnComputeSHA1(buffer, buffer_size, hash_string)

This commit is contained in:
dinkc64 2024-11-15 00:43:54 -05:00
parent 315f811ed0
commit 8a85cf2eb0
4 changed files with 181 additions and 4 deletions

View File

@ -102,7 +102,7 @@ drvsrc = d_akkaarrh.o d_arcadecl.o d_atarig1.o d_badlands.o d_batman.o d_blstro
d_spectrum.o
depobj = burn.o burn_bitmap.o burn_gun.o burn_led.o burn_shift.o burn_memory.o burn_pal.o burn_sound.o burn_sound_c.o cheat.o debug_track.o hiscore.o \
load.o tilemap_generic.o tiles_generic.o timer.o vector.o \
load.o burn_sha1.o tilemap_generic.o tiles_generic.o timer.o vector.o \
\
6821pia.o 6840ptm.o 8255ppi.o 8257dma.o c169.o atariic.o atarijsa.o atarimo.o atarirle.o atarivad.o avgdvg.o bsmt2000.o decobsmt.o ds2404.o dtimer.o earom.o eeprom.o epic12.o gaelco_crypt.o i4x00.o intelfsh.o \
joyprocess.o nb1414m4.o nb1414m4_8bit.o nmk004.o nmk112.o k1ge.o kaneko_hit.o kaneko_tmap.o mathbox.o mb87078.o mermaid.o midcsd.o midsat.o midsg.o midcvsd.o midssio.o midtcs.o \

View File

@ -464,6 +464,11 @@ extern bool bDoIpsPatch;
void IpsApplyPatches(UINT8* base, char* rom_name, UINT32 rom_crc, bool readonly = false);
// ---------------------------------------------------------------------------
// MISC Helper / utility functions, etc
int BurnComputeSHA1(const UINT8 *buffer, int buffer_size, char *hash_str);
//int BurnComputeSHA1(const char *filename, char *hash_str);
// ---------------------------------------------------------------------------
// Flags used with the Burndriver structure

166
src/burn/burn_sha1.cpp Normal file
View File

@ -0,0 +1,166 @@
#include "burnint.h"
#include <stdint.h>
#define SHA1_BLOCK_SIZE 64
#define SHA1_HASH_SIZE 20
struct sha1_state {
UINT32 state[5];
UINT64 bitcount;
UINT8 buffer[SHA1_BLOCK_SIZE];
};
#define ROTLEFT(a, b) (((a) << (b)) | ((a) >> (32 - (b))))
#define F0(b, c, d) ((b & c) | (~b & d))
#define F1(b, c, d) (b ^ c ^ d)
#define F2(b, c, d) ((b & c) | (b & d) | (c & d))
#define F3(b, c, d) (b ^ c ^ d)
void SHA1_Transform(sha1_state *ctx, const UINT8 *data) {
UINT32 a, b, c, d, e, i, t;
UINT32 m[80];
for (i = 0; i < 16; i++) {
m[i] = (data[i * 4] << 24) | (data[i * 4 + 1] << 16) |
(data[i * 4 + 2] << 8) | (data[i * 4 + 3]);
}
for (i = 16; i < 80; i++) {
m[i] = ROTLEFT(m[i - 3] ^ m[i - 8] ^ m[i - 14] ^ m[i - 16], 1);
}
a = ctx->state[0];
b = ctx->state[1];
c = ctx->state[2];
d = ctx->state[3];
e = ctx->state[4];
for (i = 0; i < 80; i++) {
if (i < 20) {
t = ROTLEFT(a, 5) + F0(b, c, d) + e + m[i] + 0x5A827999;
} else if (i < 40) {
t = ROTLEFT(a, 5) + F1(b, c, d) + e + m[i] + 0x6ED9EBA1;
} else if (i < 60) {
t = ROTLEFT(a, 5) + F2(b, c, d) + e + m[i] + 0x8F1BBCDC;
} else {
t = ROTLEFT(a, 5) + F3(b, c, d) + e + m[i] + 0xCA62C1D6;
}
e = d;
d = c;
c = ROTLEFT(b, 30);
b = a;
a = t;
}
ctx->state[0] += a;
ctx->state[1] += b;
ctx->state[2] += c;
ctx->state[3] += d;
ctx->state[4] += e;
}
void SHA1_Init(sha1_state *ctx) {
ctx->state[0] = 0x67452301;
ctx->state[1] = 0xEFCDAB89;
ctx->state[2] = 0x98BADCFE;
ctx->state[3] = 0x10325476;
ctx->state[4] = 0xC3D2E1F0;
ctx->bitcount = 0;
memset(ctx->buffer, 0, SHA1_BLOCK_SIZE);
}
void SHA1_Update(sha1_state *ctx, const UINT8 *data, INT32 len) {
INT32 i;
for (i = 0; i < len; i++) {
ctx->buffer[ctx->bitcount / 8 % SHA1_BLOCK_SIZE] = data[i];
ctx->bitcount += 8;
if ((ctx->bitcount / 8 % SHA1_BLOCK_SIZE) == 0) {
SHA1_Transform(ctx, ctx->buffer);
}
}
}
void SHA1_Final(UINT8 *hash, sha1_state *ctx) {
INT32 i = ctx->bitcount / 8 % SHA1_BLOCK_SIZE;
ctx->buffer[i++] = 0x80;
if (i > SHA1_BLOCK_SIZE - 8) {
while (i < SHA1_BLOCK_SIZE) {
ctx->buffer[i++] = 0;
}
SHA1_Transform(ctx, ctx->buffer);
i = 0;
}
while (i < SHA1_BLOCK_SIZE - 8) {
ctx->buffer[i++] = 0;
}
for (int j = 0; j < 8; j++) {
ctx->buffer[SHA1_BLOCK_SIZE - 1 - j] = ctx->bitcount >> (j * 8);
}
SHA1_Transform(ctx, ctx->buffer);
for (i = 0; i < 5; i++) {
hash[i * 4 + 0] = (ctx->state[i] >> 24) & 0xff;
hash[i * 4 + 1] = (ctx->state[i] >> 16) & 0xff;
hash[i * 4 + 2] = (ctx->state[i] >> 8) & 0xff;
hash[i * 4 + 3] = (ctx->state[i]) & 0xff;
}
}
int BurnComputeSHA1(const UINT8 *buffer, int buffer_size, char *hash_str) {
sha1_state ctx;
UINT8 hash[SHA1_HASH_SIZE];
SHA1_Init(&ctx);
SHA1_Update(&ctx, buffer, buffer_size);
SHA1_Final(hash, &ctx);
for (int i = 0; i < SHA1_HASH_SIZE; i++) {
char temp[128];
sprintf(temp, "%02x", hash[i]);
hash_str[i*2 + 0] = temp[0];
hash_str[i*2 + 1] = temp[1];
}
hash_str[SHA1_HASH_SIZE*2] = 0;
return 0;
}
int BurnComputeSHA1(const char *filename, char *hash_str) {
sha1_state ctx;
UINT8 hash[SHA1_HASH_SIZE];
const int filebuf_size = 1024 * 1024;
UINT8 *buffer;
FILE *file = fopen(filename, "rb");
if (!file) {
return 1;
}
buffer = (UINT8*)malloc(filebuf_size);
if (!buffer) return 2;
SHA1_Init(&ctx);
INT32 bytes_read;
while ((bytes_read = fread(buffer, 1, filebuf_size, file)) > 0) {
SHA1_Update(&ctx, buffer, bytes_read);
}
fclose(file);
free(buffer);
SHA1_Final(hash, &ctx);
for (int i = 0; i < SHA1_HASH_SIZE; i++) {
char temp[128];
sprintf(temp, "%02x", hash[i]);
hash_str[i*2 + 0] = temp[0];
hash_str[i*2 + 1] = temp[1];
}
hash_str[SHA1_HASH_SIZE*2] = 0;
return 0;
}

View File

@ -10975,7 +10975,7 @@ static INT32 gg_decode(char *gg_code, UINT16 &address, UINT8 &value, INT32 &comp
return 0;
}
const INT32 cheat_MAX = 0x100;
static const INT32 cheat_MAX = 0x100;
static INT32 cheats_active = 0;
struct cheat_struct {
@ -10987,7 +10987,7 @@ struct cheat_struct {
static cheat_struct cheats[cheat_MAX];
void nes_add_cheat(char *code) // 6/8 character game genie codes allowed
static void nes_add_cheat(char *code) // 6/8 character game genie codes allowed
{
UINT16 address;
UINT8 value;
@ -11009,7 +11009,7 @@ void nes_add_cheat(char *code) // 6/8 character game genie codes allowed
}
}
void nes_remove_cheat(char *code)
static void nes_remove_cheat(char *code)
{
cheat_struct cheat_temp[cheat_MAX];
INT32 temp_num = 0;
@ -11192,6 +11192,12 @@ static INT32 NESInit()
if (fds_load(rom, ri.nLen, ri.nCrc)) return 1;
} else {
if (BurnLoadRom(rom, 0, 1)) return 1;
// sha1 hash
char hash_potato[128] = { 0, };
BurnComputeSHA1(rom + 0x10, ri.nLen - 0x10, hash_potato);
bprintf(0, _T("sha1 hash: [%S]\n"), hash_potato);
if (cartridge_load(rom, ri.nLen, ri.nCrc)) return 1;
}