perform DISA/DIFF cmac fixing automatically upon unmounting

This commit is contained in:
aspargas2 2020-07-31 02:18:44 -04:00 committed by d0k3
parent e7fdf993a7
commit e744be504b
7 changed files with 28 additions and 24 deletions

View File

@ -65,9 +65,9 @@ bool InitImgFS(const char* path) {
} }
void DeinitExtFS() { void DeinitExtFS() {
InitImgFS(NULL);
SetupNandSdDrive(NULL, NULL, NULL, 0); SetupNandSdDrive(NULL, NULL, NULL, 0);
SetupNandSdDrive(NULL, NULL, NULL, 1); SetupNandSdDrive(NULL, NULL, NULL, 1);
InitImgFS(NULL);
for (u32 i = NORM_FS - 1; i > 0; i--) { for (u32 i = NORM_FS - 1; i > 0; i--) {
if (fs_mounted[i]) { if (fs_mounted[i]) {
char fsname[8]; char fsname[8];

View File

@ -1,11 +1,14 @@
#include "image.h" #include "image.h"
#include "vff.h" #include "vff.h"
#include "nandcmac.h"
static FIL mount_file; static FIL mount_file;
static u64 mount_state = 0; static u64 mount_state = 0;
static char mount_path[256] = { 0 }; static char mount_path[256] = { 0 };
static bool fix_cmac = false;
int ReadImageBytes(void* buffer, u64 offset, u64 count) { int ReadImageBytes(void* buffer, u64 offset, u64 count) {
UINT bytes_read; UINT bytes_read;
@ -28,6 +31,7 @@ int WriteImageBytes(const void* buffer, u64 offset, u64 count) {
if (fvx_tell(&mount_file) != offset) if (fvx_tell(&mount_file) != offset)
fvx_lseek(&mount_file, offset); fvx_lseek(&mount_file, offset);
ret = fvx_write(&mount_file, buffer, count, &bytes_written); ret = fvx_write(&mount_file, buffer, count, &bytes_written);
if (ret == 0) fix_cmac = true;
return (ret != 0) ? (int) ret : (bytes_written != count) ? -1 : 0; return (ret != 0) ? (int) ret : (bytes_written != count) ? -1 : 0;
} }
@ -59,6 +63,8 @@ u64 MountImage(const char* path) {
u64 type = (path) ? IdentifyFileType(path) : 0; u64 type = (path) ? IdentifyFileType(path) : 0;
if (mount_state) { if (mount_state) {
fvx_close(&mount_file); fvx_close(&mount_file);
if (fix_cmac) FixFileCmac(mount_path, false);
fix_cmac = false;
mount_state = 0; mount_state = 0;
*mount_path = 0; *mount_path = 0;
} }

View File

@ -892,7 +892,7 @@ u32 CmacCalculator(const char* path) {
pathstr, getbe64(cmac + 0), getbe64(cmac + 8), pathstr, getbe64(cmac + 0), getbe64(cmac + 8),
"CMAC verification: ", (identical) ? "passed!" : "failed!", "CMAC verification: ", (identical) ? "passed!" : "failed!",
(!identical) ? "\n \nFix CMAC in file?" : "") && (!identical) ? "\n \nFix CMAC in file?" : "") &&
!identical && (WriteFileCmac(path, cmac) != 0)) { !identical && (WriteFileCmac(path, cmac, true) != 0)) {
ShowPrompt(false, "Fixing CMAC: failed!"); ShowPrompt(false, "Fixing CMAC: failed!");
} }
} }
@ -901,7 +901,7 @@ u32 CmacCalculator(const char* path) {
if (ShowPrompt(!correct, "%s\nXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n%s%s%s", if (ShowPrompt(!correct, "%s\nXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n%s%s%s",
pathstr, "CMAC verification: ", (correct) ? "passed!" : "failed!", pathstr, "CMAC verification: ", (correct) ? "passed!" : "failed!",
(!correct) ? "\n \nFix CMAC in file?" : "") && (!correct) ? "\n \nFix CMAC in file?" : "") &&
!correct && (FixCmdCmac(path) != 0)) { !correct && (FixCmdCmac(path, true) != 0)) {
ShowPrompt(false, "Fixing CMAC: failed!"); ShowPrompt(false, "Fixing CMAC: failed!");
} }
} }
@ -1233,7 +1233,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan
continue; continue;
} }
if (CheckFileCmac(path) == 0) n_success++; if (CheckFileCmac(path) == 0) n_success++;
else if (fix && (FixFileCmac(path) == 0)) n_fixed++; else if (fix && (FixFileCmac(path, true) == 0)) n_fixed++;
else { // on failure: set cursor on failed file else { // on failure: set cursor on failed file
*cursor = i; *cursor = i;
continue; continue;

View File

@ -108,7 +108,7 @@ u32 TransferCtrNandImage(const char* path_img, const char* drv) {
snprintf(path_from, 32, "7:/dbs/%s", dbnames[i]); snprintf(path_from, 32, "7:/dbs/%s", dbnames[i]);
PathDelete(path_to); PathDelete(path_to);
PathCopy(path_dbs, path_from, &flags); PathCopy(path_dbs, path_from, &flags);
FixFileCmac(path_to); FixFileCmac(path_to, true);
} }
ShowString("Cleaning up titles, please wait..."); ShowString("Cleaning up titles, please wait...");
snprintf(path_to, 32, "%s/title", drv); snprintf(path_to, 32, "%s/title", drv);

View File

@ -1489,9 +1489,7 @@ u32 InstallCiaSystemData(CiaStub* cia, const char* drv) {
InitImgFS(path_bak); InitImgFS(path_bak);
// fix CMACs where required // fix CMACs where required
if (!syscmd) FixFileCmac(path_cmd); if (!syscmd) FixFileCmac(path_cmd, true);
FixFileCmac(path_ticketdb);
FixFileCmac(path_titledb);
return 0; return 0;
} }

View File

@ -130,7 +130,7 @@ u32 CheckCmacPath(const char* path) {
return (CalculateFileCmac(path, NULL)) ? 0 : 1; return (CalculateFileCmac(path, NULL)) ? 0 : 1;
} }
u32 ReadWriteFileCmac(const char* path, u8* cmac, bool do_write) { u32 ReadWriteFileCmac(const char* path, u8* cmac, bool do_write, bool check_perms) {
u32 cmac_type = CalculateFileCmac(path, NULL); u32 cmac_type = CalculateFileCmac(path, NULL);
u32 offset = 0; u32 offset = 0;
@ -141,7 +141,7 @@ u32 ReadWriteFileCmac(const char* path, u8* cmac, bool do_write) {
else if ((cmac_type == CMAC_CMD_SD) || (cmac_type == CMAC_CMD_TWLN)) return 1; // can't do that here else if ((cmac_type == CMAC_CMD_SD) || (cmac_type == CMAC_CMD_TWLN)) return 1; // can't do that here
else offset = 0x000; else offset = 0x000;
if (do_write && !CheckWritePermissions(path)) return 1; if (do_write && check_perms && !CheckWritePermissions(path)) return 1;
if (!do_write) return (fvx_qread(path, cmac, offset, 0x10, NULL) != FR_OK) ? 1 : 0; if (!do_write) return (fvx_qread(path, cmac, offset, 0x10, NULL) != FR_OK) ? 1 : 0;
else return (fvx_qwrite(path, cmac, offset, 0x10, NULL) != FR_OK) ? 1 : 0; else return (fvx_qwrite(path, cmac, offset, 0x10, NULL) != FR_OK) ? 1 : 0;
} }
@ -298,13 +298,13 @@ u32 CheckFileCmac(const char* path) {
} else return 1; } else return 1;
} }
u32 FixFileCmac(const char* path) { u32 FixFileCmac(const char* path, bool check_perms) {
u32 cmac_type = CalculateFileCmac(path, NULL); u32 cmac_type = CalculateFileCmac(path, NULL);
if ((cmac_type == CMAC_CMD_SD) || (cmac_type == CMAC_CMD_TWLN)) { if ((cmac_type == CMAC_CMD_SD) || (cmac_type == CMAC_CMD_TWLN)) {
return FixCmdCmac(path); return FixCmdCmac(path, check_perms);
} else if (cmac_type) { } else if (cmac_type) {
u8 ccmac[16]; u8 ccmac[16];
return ((CalculateFileCmac(path, ccmac) == 0) && (WriteFileCmac(path, ccmac) == 0)) ? 0 : 1; return ((CalculateFileCmac(path, ccmac) == 0) && (WriteFileCmac(path, ccmac, check_perms) == 0)) ? 0 : 1;
} else return 1; } else return 1;
} }
@ -344,7 +344,7 @@ u32 FixAgbSaveCmac(void* data, u8* cmac, const char* sddrv) {
return 0; return 0;
} }
u32 CheckFixCmdCmac(const char* path, bool fix) { u32 CheckFixCmdCmac(const char* path, bool fix, bool check_perms) {
u8 cmac[16] __attribute__((aligned(4))); u8 cmac[16] __attribute__((aligned(4)));
u32 keyslot = ((*path == 'A') || (*path == 'B')) ? 0x30 : 0x0B; u32 keyslot = ((*path == 'A') || (*path == 'B')) ? 0x30 : 0x0B;
bool fixed = false; bool fixed = false;
@ -440,7 +440,7 @@ u32 CheckFixCmdCmac(const char* path, bool fix) {
} }
// if fixing is enabled, write back cmd file // if fixing is enabled, write back cmd file
if (fix && fixed && CheckWritePermissions(path) && if (fix && fixed && (!check_perms || CheckWritePermissions(path)) &&
(fvx_qwrite(path, cmd_data, 0, cmd_size, NULL) != FR_OK)) { (fvx_qwrite(path, cmd_data, 0, cmd_size, NULL) != FR_OK)) {
free(cmd_data); free(cmd_data);
return 1; return 1;
@ -472,14 +472,14 @@ u32 RecursiveFixFileCmacWorker(char* path) {
} else if (fno.fattrib & AM_DIR) { // directory, recurse through it } else if (fno.fattrib & AM_DIR) { // directory, recurse through it
if (RecursiveFixFileCmacWorker(path) != 0) err = 1; if (RecursiveFixFileCmacWorker(path) != 0) err = 1;
} else if (CheckCmacPath(path) == 0) { // file, try to fix the CMAC } else if (CheckCmacPath(path) == 0) { // file, try to fix the CMAC
if (FixFileCmac(path) != 0) err = 1; if (FixFileCmac(path, true) != 0) err = 1;
ShowString("%s\nFixing CMACs, please wait...", pathstr); ShowString("%s\nFixing CMACs, please wait...", pathstr);
} }
} }
f_closedir(&pdir); f_closedir(&pdir);
*(--fname) = '\0'; *(--fname) = '\0';
} else if (CheckCmacPath(path) == 0) // fix single file CMAC } else if (CheckCmacPath(path) == 0) // fix single file CMAC
return FixFileCmac(path); return FixFileCmac(path, true);
return err; return err;
} }

View File

@ -2,16 +2,16 @@
#include "common.h" #include "common.h"
#define ReadFileCmac(path, cmac) ReadWriteFileCmac(path, cmac, false) #define ReadFileCmac(path, cmac) ReadWriteFileCmac(path, cmac, false, true)
#define WriteFileCmac(path, cmac) ReadWriteFileCmac(path, cmac, true) #define WriteFileCmac(path, cmac, check_perms) ReadWriteFileCmac(path, cmac, true, check_perms)
#define CheckCmdCmac(path) CheckFixCmdCmac(path, false) #define CheckCmdCmac(path) CheckFixCmdCmac(path, false, true)
#define FixCmdCmac(path) CheckFixCmdCmac(path, true) #define FixCmdCmac(path, check_perms) CheckFixCmdCmac(path, true, check_perms)
u32 CheckCmacPath(const char* path); u32 CheckCmacPath(const char* path);
u32 ReadWriteFileCmac(const char* path, u8* cmac, bool do_write); u32 ReadWriteFileCmac(const char* path, u8* cmac, bool do_write, bool check_perms);
u32 CalculateFileCmac(const char* path, u8* cmac); u32 CalculateFileCmac(const char* path, u8* cmac);
u32 CheckFileCmac(const char* path); u32 CheckFileCmac(const char* path);
u32 FixFileCmac(const char* path); u32 FixFileCmac(const char* path, bool check_perms);
u32 FixAgbSaveCmac(void* data, u8* cmac, const char* sddrv); u32 FixAgbSaveCmac(void* data, u8* cmac, const char* sddrv);
u32 CheckFixCmdCmac(const char* path, bool fix); u32 CheckFixCmdCmac(const char* path, bool fix, bool check_perms);
u32 RecursiveFixFileCmac(const char* path); u32 RecursiveFixFileCmac(const char* path);