Compare commits

...

2 Commits
master ... sha1

Author SHA1 Message Date
d0k3
9dec7c3124 Display SHA-1 over two lines (like SHA-256) 2021-10-09 11:57:32 +02:00
BuildTools
3a8e005430 add user-facing sha1 support 2021-09-30 13:12:54 -04:00
5 changed files with 79 additions and 53 deletions

View File

@ -161,7 +161,7 @@ size_t FileGetSize(const char* path) {
return fno.fsize;
}
bool FileGetSha256(const char* path, u8* sha256, u64 offset, u64 size) {
bool FileGetSha(const char* path, u8* hash, u64 offset, u64 size, bool sha1) {
bool ret = true;
FIL file;
u64 fsize;
@ -179,7 +179,7 @@ bool FileGetSha256(const char* path, u8* sha256, u64 offset, u64 size) {
if (!buffer) return false;
ShowProgress(0, 0, path);
sha_init(SHA256_MODE);
sha_init(sha1 ? SHA1_MODE : SHA256_MODE);
for (u64 pos = 0; (pos < size) && ret; pos += bufsiz) {
UINT read_bytes = min(bufsiz, size - pos);
UINT bytes_read = 0;
@ -190,7 +190,7 @@ bool FileGetSha256(const char* path, u8* sha256, u64 offset, u64 size) {
sha_update(buffer, bytes_read);
}
sha_get(sha256);
sha_get(hash);
fvx_close(&file);
free(buffer);
@ -448,6 +448,7 @@ bool PathMoveCopyRec(char* dest, char* orig, u32* flags, bool move, u8* buffer,
bool silent = (flags && (*flags & SILENT));
bool append = (flags && (*flags & APPEND_ALL));
bool calcsha = (flags && (*flags & CALC_SHA) && !append);
bool sha1 = (flags && (*flags & USE_SHA1));
bool ret = false;
// check destination write permission (special paths only)
@ -552,7 +553,7 @@ bool PathMoveCopyRec(char* dest, char* orig, u32* flags, bool move, u8* buffer,
fvx_lseek(&ofile, 0);
fvx_sync(&ofile);
if (calcsha) sha_init(SHA256_MODE);
if (calcsha) sha_init(sha1 ? SHA1_MODE : SHA256_MODE);
for (u64 pos = 0; (pos < osize) && ret; pos += bufsiz) {
UINT bytes_read = 0;
UINT bytes_written = 0;
@ -580,11 +581,11 @@ bool PathMoveCopyRec(char* dest, char* orig, u32* flags, bool move, u8* buffer,
if (!ret && ((dsize == 0) || (fvx_lseek(&dfile, dsize) != FR_OK) || (f_truncate(&dfile) != FR_OK))) {
fvx_unlink(dest);
} else if (!to_virtual && calcsha) {
u8 sha256[0x20];
u8 hash[0x20];
char* ext_sha = dest + strnlen(dest, 256);
strncpy(ext_sha, ".sha", 256 - (ext_sha - dest));
sha_get(sha256);
FileSetData(dest, sha256, 0x20, 0, true);
snprintf(ext_sha, 256 - (ext_sha - dest), ".sha%c", sha1 ? '1' : '\0');
sha_get(hash);
FileSetData(dest, hash, sha1 ? 20 : 32, 0, true);
}
}

View File

@ -7,12 +7,13 @@
#define NO_CANCEL (1UL<<1)
#define SILENT (1UL<<2)
#define CALC_SHA (1UL<<3)
#define BUILD_PATH (1UL<<4)
#define ALLOW_EXPAND (1UL<<5)
#define ASK_ALL (1UL<<6)
#define SKIP_ALL (1UL<<7)
#define OVERWRITE_ALL (1UL<<8)
#define APPEND_ALL (1UL<<9)
#define USE_SHA1 (1UL<<4)
#define BUILD_PATH (1UL<<5)
#define ALLOW_EXPAND (1UL<<6)
#define ASK_ALL (1UL<<7)
#define SKIP_ALL (1UL<<8)
#define OVERWRITE_ALL (1UL<<9)
#define APPEND_ALL (1UL<<10)
// file selector flags
#define NO_DIRS (1UL<<0)
@ -43,7 +44,7 @@ size_t FileGetData(const char* path, void* data, size_t size, size_t foffset);
size_t FileGetSize(const char* path);
/** Get SHA-256 of file **/
bool FileGetSha256(const char* path, u8* sha256, u64 offset, u64 size);
bool FileGetSha(const char* path, u8* hash, u64 offset, u64 size, bool sha1);
/** Find data in file **/
u32 FileFindData(const char* path, u8* data, u32 size_data, u32 offset_file);

View File

@ -842,37 +842,46 @@ u32 FileHexViewer(const char* path) {
return 0;
}
u32 Sha256Calculator(const char* path) {
u32 ShaCalculator(const char* path, bool sha1) {
const u8 hashlen = sha1 ? 20 : 32;
u32 drvtype = DriveType(path);
char pathstr[32 + 1];
u8 sha256[32];
u8 hash[32];
TruncateString(pathstr, path, 32, 8);
if (!FileGetSha256(path, sha256, 0, 0)) {
ShowPrompt(false, "Calculating SHA-256: failed!");
if (!FileGetSha(path, hash, 0, 0, sha1)) {
ShowPrompt(false, "Calculating SHA-%s: failed!", sha1 ? "1" : "256");
return 1;
} else {
static char pathstr_prev[32 + 1] = { 0 };
static u8 sha256_prev[32] = { 0 };
static u8 hash_prev[32] = { 0 };
char sha_path[256];
u8 sha256_file[32];
u8 sha_file[32];
snprintf(sha_path, 256, "%s.sha", path);
bool have_sha = (FileGetData(sha_path, sha256_file, 32, 0) == 32);
bool match_sha = have_sha && (memcmp(sha256, sha256_file, 32) == 0);
bool match_prev = (memcmp(sha256, sha256_prev, 32) == 0);
snprintf(sha_path, 256, "%s.sha%c", path, sha1 ? '1' : '\0');
bool have_sha = (FileGetData(sha_path, sha_file, hashlen, 0) == hashlen);
bool match_sha = have_sha && (memcmp(hash, sha_file, hashlen) == 0);
bool match_prev = (memcmp(hash, hash_prev, hashlen) == 0);
bool write_sha = (!have_sha || !match_sha) && (drvtype & DRV_SDCARD); // writing only on SD
if (ShowPrompt(write_sha, "%s\n%016llX%016llX\n%016llX%016llX%s%s%s%s%s",
pathstr, getbe64(sha256 + 0), getbe64(sha256 + 8), getbe64(sha256 + 16), getbe64(sha256 + 24),
char hash_str[32+1+32+1];
if (sha1)
snprintf(hash_str, 32+1+8+1, "%016llX%016llX\n%08lX", getbe64(hash + 0), getbe64(hash + 8),
getbe32(hash + 16));
else
snprintf(hash_str, 32+1+32+1, "%016llX%016llX\n%016llX%016llX", getbe64(hash + 0), getbe64(hash + 8),
getbe64(hash + 16), getbe64(hash + 24));
if (ShowPrompt(write_sha, "%s\n%s%s%s%s%s%c \nWrite .SHA%s file?",
pathstr, hash_str,
(have_sha) ? "\nSHA verification: " : "",
(have_sha) ? ((match_sha) ? "passed!" : "failed!") : "",
(match_prev) ? "\n \nIdentical with previous file:\n" : "",
(match_prev) ? pathstr_prev : "",
(write_sha) ? "\n \nWrite .SHA file?" : "") && write_sha) {
FileSetData(sha_path, sha256, 32, 0, true);
(write_sha) ? '\n' : '\0',
(sha1) ? "1" : "") && write_sha) {
FileSetData(sha_path, hash, hashlen, 0, true);
}
strncpy(pathstr_prev, pathstr, 32 + 1);
memcpy(sha256_prev, sha256, 32);
memcpy(hash_prev, hash, hashlen);
}
return 0;
@ -1158,7 +1167,8 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan
int special = (special_opt) ? ++n_opt : -1;
int hexviewer = ++n_opt;
int textviewer = (filetype & TXT_GENERIC) ? ++n_opt : -1;
int calcsha = ++n_opt;
int calcsha256 = ++n_opt;
int calcsha1 = ++n_opt;
int calccmac = (CheckCmacPath(file_path) == 0) ? ++n_opt : -1;
int fileinfo = ++n_opt;
int copystd = (!in_output_path) ? ++n_opt : -1;
@ -1170,7 +1180,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan
int titleman = -1;
if (DriveType(current_path) & DRV_TITLEMAN) {
// special case: title manager (disable almost everything)
hexviewer = textviewer = calcsha = calccmac = fileinfo = copystd = inject = searchdrv = -1;
hexviewer = textviewer = calcsha256 = calcsha1 = calccmac = fileinfo = copystd = inject = searchdrv = -1;
special = 1;
titleman = 2;
n_opt = 2;
@ -1210,7 +1220,8 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan
(filetype & HDR_NAND) ? "Rebuild NCSD header" :
(filetype & NOIMG_NAND) ? "Rebuild NCSD header" : "???";
optionstr[hexviewer-1] = "Show in Hexeditor";
optionstr[calcsha-1] = "Calculate SHA-256";
optionstr[calcsha256-1] = "Calculate SHA-256";
optionstr[calcsha1-1] = "Calculate SHA-1";
optionstr[fileinfo-1] = "Show file info";
if (textviewer > 0) optionstr[textviewer-1] = "Show in Textviewer";
if (calccmac > 0) optionstr[calccmac-1] = "Calculate CMAC";
@ -1230,8 +1241,13 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan
FileTextViewer(file_path, scriptable);
return 0;
}
else if (user_select == calcsha) { // -> calculate SHA-256
Sha256Calculator(file_path);
else if (user_select == calcsha256) { // -> calculate SHA-256
ShaCalculator(file_path, false);
GetDirContents(current_dir, current_path);
return 0;
}
else if (user_select == calcsha1) { // -> calculate SHA-1
ShaCalculator(file_path, true);
GetDirContents(current_dir, current_path);
return 0;
}

View File

@ -895,7 +895,7 @@ u32 VerifyTadFile(const char* path) {
u8 hash[32];
u32 len = align(hdr->content_size[i], 0x10);
if (!len) continue; // non-existant section
if (!FileGetSha256(path, hash, content_start, len) ||
if (!FileGetSha(path, hash, content_start, len, false) ||
(memcmp(hash, ftr->content_sha256[i], 32) != 0))
return 1;
content_start += len + sizeof(TadBlockMetaData);

View File

@ -59,7 +59,7 @@
// some useful macros
#define IS_WHITESPACE(c) ((c == ' ') || (c == '\t') || (c == '\r') || (c == '\n'))
#define MATCH_STR(s,l,c) ((l == strlen(c)) && (strncmp(s, c, l) == 0))
#define _FLG(c) ((c >= 'a') ? (1 << (c - 'a')) : 0)
#define _FLG(c) ((c >= 'a') ? (1 << (c - 'a')) : ((c >= '0') ? (1 << (26 + c - '0')) : 0))
#define IS_CTRLFLOW_CMD(id) ((id == CMD_ID_IF) || (id == CMD_ID_ELIF) || (id == CMD_ID_ELSE) || (id == CMD_ID_END) || \
(id == CMD_ID_GOTO) || (id == CMD_ID_LABELSEL) || \
@ -163,7 +163,7 @@ static const Gm9ScriptCmd cmd_list[] = {
{ CMD_ID_STRREP , "strrep" , 3, 0 },
{ CMD_ID_CHK , "chk" , 2, _FLG('u') },
{ CMD_ID_ALLOW , "allow" , 1, _FLG('a') },
{ CMD_ID_CP , "cp" , 2, _FLG('h') | _FLG('w') | _FLG('k') | _FLG('s') | _FLG('n') | _FLG('p')},
{ CMD_ID_CP , "cp" , 2, _FLG('h') | _FLG('1') | _FLG('w') | _FLG('k') | _FLG('s') | _FLG('n') | _FLG('p')},
{ CMD_ID_MV , "mv" , 2, _FLG('w') | _FLG('k') | _FLG('s') | _FLG('n') },
{ CMD_ID_INJECT , "inject" , 2, _FLG('n') },
{ CMD_ID_FILL , "fill" , 2, _FLG('n') },
@ -176,8 +176,8 @@ static const Gm9ScriptCmd cmd_list[] = {
{ CMD_ID_FINDNOT , "findnot" , 2, 0 },
{ CMD_ID_FGET , "fget" , 2, _FLG('e') },
{ CMD_ID_FSET , "fset" , 2, _FLG('e') },
{ CMD_ID_SHA , "sha" , 2, 0 },
{ CMD_ID_SHAGET , "shaget" , 2, 0 },
{ CMD_ID_SHA , "sha" , 2, _FLG('1') },
{ CMD_ID_SHAGET , "shaget" , 2, _FLG('1') },
{ CMD_ID_DUMPTXT , "dumptxt" , 2, _FLG('p') },
{ CMD_ID_FIXCMAC , "fixcmac" , 1, 0 },
{ CMD_ID_VERIFY , "verify" , 1, 0 },
@ -584,6 +584,7 @@ u32 get_flag(char* str, u32 len, char* err_str) {
if ((len < 2) || (*str != '-')) flag_char = '\0';
else if (len == 2) flag_char = str[1];
else if (strncmp(str, "--sha1", len) == 0) flag_char = '1';
else if (strncmp(str, "--all", len) == 0) flag_char = 'a';
else if (strncmp(str, "--before", len) == 0) flag_char = 'b';
else if (strncmp(str, "--include_dirs", len) == 0) flag_char = 'd';
@ -603,7 +604,7 @@ u32 get_flag(char* str, u32 len, char* err_str) {
else if (strncmp(str, "--overwrite", len) == 0) flag_char = 'w';
else if (strncmp(str, "--explorer", len) == 0) flag_char = 'x';
if ((flag_char < 'a') && (flag_char > 'z')) {
if (((flag_char < 'a') || (flag_char > 'z')) && ((flag_char < '0') || (flag_char > '5'))) {
if (err_str) snprintf(err_str, _ERR_STR_LEN, "illegal flag");
return 0;
}
@ -1150,6 +1151,7 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) {
else if (id == CMD_ID_CP) {
u32 flags_ext = BUILD_PATH;
if (flags & _FLG('h')) flags_ext |= CALC_SHA;
if (flags & _FLG('1')) flags_ext |= USE_SHA1;
if (flags & _FLG('n')) flags_ext |= NO_CANCEL;
if (flags & _FLG('s')) flags_ext |= SILENT;
if (flags & _FLG('w')) flags_ext |= OVERWRITE_ALL;
@ -1291,30 +1293,36 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) {
}
}
else if (id == CMD_ID_SHA) {
u8 sha256_fil[0x20];
u8 sha256_cmp[0x20];
if (!FileGetSha256(argv[0], sha256_fil, at_org, sz_org)) {
const u8 hashlen = (flags & _FLG('1')) ? 20 : 32;
u8 hash_fil[0x20];
u8 hash_cmp[0x20];
if (!FileGetSha(argv[0], hash_fil, at_org, sz_org, flags & _FLG('1'))) {
ret = false;
if (err_str) snprintf(err_str, _ERR_STR_LEN, "sha arg0 fail");
} else if ((FileGetData(argv[1], sha256_cmp, 0x20, 0) != 0x20) && !strntohex(argv[1], sha256_cmp, 0x20)) {
} else if ((FileGetData(argv[1], hash_cmp, hashlen, 0) != hashlen) && !strntohex(argv[1], hash_cmp, hashlen)) {
ret = false;
if (err_str) snprintf(err_str, _ERR_STR_LEN, "sha arg1 fail");
} else {
ret = (memcmp(sha256_fil, sha256_cmp, 0x20) == 0);
ret = (memcmp(hash_fil, hash_cmp, hashlen) == 0);
if (err_str) snprintf(err_str, _ERR_STR_LEN, "sha does not match");
}
}
else if (id == CMD_ID_SHAGET) {
u8 sha256_fil[0x20];
if (!(ret = FileGetSha256(argv[0], sha256_fil, at_org, sz_org))) {
const u8 hashlen = (flags & _FLG('1')) ? 20 : 32;
u8 hash_fil[0x20];
if (!(ret = FileGetSha(argv[0], hash_fil, at_org, sz_org, flags & _FLG('1')))) {
if (err_str) snprintf(err_str, _ERR_STR_LEN, "sha arg0 fail");
} else if (!strchr(argv[1], ':')) {
char sha256_str[64+1];
snprintf(sha256_str, 64+1, "%016llX%016llX%016llX%016llX", getbe64(sha256_fil + 0), getbe64(sha256_fil + 8),
getbe64(sha256_fil + 16), getbe64(sha256_fil + 24));
ret = set_var(argv[1], sha256_str);
char hash_str[64+1];
if (flags & _FLG('1'))
snprintf(hash_str, 64+1, "%016llX%016llX%08lX", getbe64(hash_fil + 0), getbe64(hash_fil + 8),
getbe32(hash_fil + 16));
else
snprintf(hash_str, 64+1, "%016llX%016llX%016llX%016llX", getbe64(hash_fil + 0), getbe64(hash_fil + 8),
getbe64(hash_fil + 16), getbe64(hash_fil + 24));
ret = set_var(argv[1], hash_str);
if (err_str) snprintf(err_str, _ERR_STR_LEN, "var fail");
} else if (!(ret = FileSetData(argv[1], sha256_fil, 0x20, 0, true))) {
} else if (!(ret = FileSetData(argv[1], hash_fil, hashlen, 0, true))) {
if (err_str) snprintf(err_str, _ERR_STR_LEN, "sha write fail");
}
}