mirror of
https://github.com/libretro/FBNeo.git
synced 2024-11-26 18:40:26 +00:00
add BurnComputeSHA1(buffer, buffer_size, hash_string)
This commit is contained in:
parent
315f811ed0
commit
8a85cf2eb0
@ -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 \
|
||||
|
@ -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
166
src/burn/burn_sha1.cpp
Normal 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;
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user