From 9e00e5394e6965e01624df1aa92c5c2855d68928 Mon Sep 17 00:00:00 2001 From: urmum-69 Date: Sat, 20 Mar 2021 18:54:21 +0000 Subject: [PATCH] Implement calculating SHA1 hash of files (#86) * implement calculating SHA1 hash of a file * fix bug where incorrect SHA1 hash would be calculated --- arm9/source/fileOperations.cpp | 34 ++++++++++++++++++++++++++++++++++ arm9/source/fileOperations.h | 1 + arm9/source/file_browse.cpp | 31 +++++++++++++++++++++++++++++-- arm9/source/file_browse.h | 1 + 4 files changed, 65 insertions(+), 2 deletions(-) diff --git a/arm9/source/fileOperations.cpp b/arm9/source/fileOperations.cpp index 14e1d81..5c1b33e 100644 --- a/arm9/source/fileOperations.cpp +++ b/arm9/source/fileOperations.cpp @@ -9,6 +9,7 @@ #include "file_browse.h" #define copyBufSize 0x8000 +#define shaChunkSize 0x10000 u32 copyBuf[copyBufSize]; @@ -68,6 +69,39 @@ off_t getFileSize(const char *fileName) return fsize; } +bool calculateSHA1(const char *fileName, u8 *sha1) +{ + off_t fsize = getFileSize(fileName); + u8 *buf = (u8*) malloc(shaChunkSize); + if (!buf) { + iprintf("Could not allocate buffer\n"); + return false; + } + FILE* fp = fopen(fileName, "rb"); + if (!fp) { + iprintf("Could not open file for reading\n"); + free(buf); + return false; + } + memset(sha1, 0, 20); + swiSHA1context_t ctx; + ctx.sha_block=0; //this is weird but it has to be done + swiSHA1Init(&ctx); + while (true) { + size_t ret = fread(buf, 1, shaChunkSize, fp); + if (!ret) break; + swiSHA1Update(&ctx, buf, ret); + scanKeys(); + int keys = keysHeld(); + if (keys & KEY_START) return false; + iprintf("\x1b[1;A"); + iprintf("%ld/%lld bytes\n", ftell(fp), fsize); + } + swiSHA1Final(sha1, &ctx); + free(buf); + return true; +} + void dirCopy(DirEntry* entry, int i, const char *destinationPath, const char *sourcePath) { std::vector dirContents; dirContents.clear(); diff --git a/arm9/source/fileOperations.h b/arm9/source/fileOperations.h index 795ebed..a7e0931 100644 --- a/arm9/source/fileOperations.h +++ b/arm9/source/fileOperations.h @@ -23,6 +23,7 @@ extern void printBytes(int bytes); extern void printBytesAlign(int bytes); extern off_t getFileSize(const char *fileName); +extern bool calculateSHA1(const char *fileName, u8 *sha1); extern int fcopy(const char *sourcePath, const char *destinationPath); void changeFileAttribs(DirEntry* entry); diff --git a/arm9/source/file_browse.cpp b/arm9/source/file_browse.cpp index 052fa6a..fc73e01 100644 --- a/arm9/source/file_browse.cpp +++ b/arm9/source/file_browse.cpp @@ -242,8 +242,12 @@ FileOperation fileBrowse_A(DirEntry* entry, char path[PATH_MAX]) { assignedOp[++maxCursors] = FileOperation::copyFatOut; printf(" Copy to fat:/gm9i/out\n"); } - printf("\n"); - printf("( select, cancel)"); + // The bios SHA1 functions are only availible on the DSi + // https://problemkaputt.de/gbatek.htm#biossha1functionsdsionly + if (isDSiMode()) { + assignedOp[++maxCursors] = FileOperation::calculateSHA1; + printf(" Calculate SHA1 hash\n"); + } consoleSelect(&bottomConsole); printf ("\x1B[47m"); // Print foreground white color while (true) { @@ -375,6 +379,29 @@ FileOperation fileBrowse_A(DirEntry* entry, char path[PATH_MAX]) { currentDrive = 6; } break; + } case FileOperation::calculateSHA1: { + iprintf("\x1b[2J"); + iprintf("Calculating SHA1 hash of:\n%s\n", entry->name.c_str()); + iprintf("Press to cancel\n\n"); + u8 sha1[20] = {0}; + bool ret = calculateSHA1(strcat(getcwd(path, PATH_MAX), entry->name.c_str()), sha1); + if (!ret) break; + iprintf("SHA1 hash is: "); + for (int i = 0; i < 19; ++i) iprintf("%02X", sha1[i]); + consoleSelect(&topConsole); + iprintf ("\x1B[30m"); // Print black color + // Power saving loop. Only poll the keys once per frame and sleep the CPU if there is nothing else to do + int pressed; + do { + // Move to right side of screen + iprintf ("\x1b[0;26H"); + // Print time + iprintf (" %s" ,RetTime().c_str()); + scanKeys(); + pressed = keysDownRepeat(); + swiWaitForVBlank(); + } while (!(pressed & (KEY_A | KEY_Y | KEY_B | KEY_X))); + break; } case FileOperation::none: { break; } diff --git a/arm9/source/file_browse.h b/arm9/source/file_browse.h index 0255590..367543e 100644 --- a/arm9/source/file_browse.h +++ b/arm9/source/file_browse.h @@ -43,6 +43,7 @@ enum class FileOperation { showInfo, copySdOut, copyFatOut, + calculateSHA1, }; bool extension(const std::string &filename, const std::vector &extensions);