mirror of
https://github.com/suchmememanyskill/TegraExplorer.git
synced 2024-11-22 11:56:42 +00:00
Add save signing
This commit is contained in:
parent
19fe7f15a9
commit
43617ef511
9 changed files with 152 additions and 8 deletions
|
@ -64,7 +64,7 @@ ini_sec_t *_ini_create_section(link_t *dst, ini_sec_t *csec, char *name, u8 type
|
|||
return csec;
|
||||
}
|
||||
|
||||
int ini_parse(link_t *dst, char *ini_path, bool is_dir)
|
||||
int ini_parse(link_t *dst, const char *ini_path, bool is_dir)
|
||||
{
|
||||
u32 lblen;
|
||||
u32 pathlen = strlen(ini_path);
|
||||
|
|
|
@ -43,7 +43,7 @@ typedef struct _ini_sec_t
|
|||
u32 color;
|
||||
} ini_sec_t;
|
||||
|
||||
int ini_parse(link_t *dst, char *ini_path, bool is_dir);
|
||||
int ini_parse(link_t *dst, const char *ini_path, bool is_dir);
|
||||
char *ini_check_payload_section(ini_sec_t *cfg);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -23,7 +23,8 @@ enum utils_err_codes_te_call {
|
|||
ERR_SD_EJECTED,
|
||||
ERR_PARSE_FAIL,
|
||||
ERR_CANNOT_COPY_FILE_TO_FS_PART,
|
||||
ERR_NO_DESTINATION
|
||||
ERR_NO_DESTINATION,
|
||||
ERR_INI_PARSE_FAIL
|
||||
};
|
||||
|
||||
extern const char *utils_err_codes_te[];
|
||||
|
@ -86,7 +87,8 @@ enum fs_menu_file_return {
|
|||
FILE_PAYLOAD,
|
||||
FILE_SCRIPT,
|
||||
FILE_HEXVIEW,
|
||||
FILE_DUMPBIS
|
||||
FILE_DUMPBIS,
|
||||
FILE_SIGN
|
||||
};
|
||||
|
||||
extern menu_entry fs_menu_file[];
|
||||
|
|
|
@ -52,7 +52,8 @@ const char *utils_err_codes_te[] = { // these start at 50
|
|||
"SD EJECTED",
|
||||
"PARSING FAILED",
|
||||
"CANNOT COPY FILE TO FS PART",
|
||||
"NO DESTINATION"
|
||||
"NO DESTINATION",
|
||||
"INI PARSE FAIL"
|
||||
};
|
||||
/*
|
||||
const char *pkg2names[] = {
|
||||
|
|
|
@ -53,7 +53,8 @@ menu_entry fs_menu_file[] = {
|
|||
{"Launch Payload", COLOR_ORANGE, {ISMENU}},
|
||||
{"Launch Script", COLOR_YELLOW, {ISMENU}},
|
||||
{"View Hex", COLOR_GREEN, {ISMENU}},
|
||||
{"\nExtract BIS", COLOR_YELLOW, {ISMENU}}
|
||||
{"\nExtract BIS", COLOR_YELLOW, {ISMENU}},
|
||||
{"Sign Save", COLOR_ORANGE, {ISMENU}}
|
||||
};
|
||||
|
||||
menu_entry fs_menu_folder[] = {
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "../emmc/emmcoperations.h"
|
||||
#include "../../hid/hid.h"
|
||||
#include "../utils/menuUtils.h"
|
||||
#include "savesign.h"
|
||||
|
||||
extern char *currentpath;
|
||||
extern char *clipboard;
|
||||
|
@ -150,6 +151,7 @@ int filemenu(menu_entry file){
|
|||
fs_menu_file[8].isHide = (!(strstr(file.name, ".bin") != NULL && file.size == 1) && strstr(file.name, ".rom") == NULL);
|
||||
fs_menu_file[9].isHide = (strstr(file.name, ".te") == NULL);
|
||||
fs_menu_file[11].isHide = (strstr(file.name, ".bis") == NULL);
|
||||
fs_menu_file[12].isHide = (!!strcmp(currentpath, "emmc:/save"));
|
||||
|
||||
/*
|
||||
SETBIT(fs_menu_file[6].property, ISHIDE, !hidConnected());
|
||||
|
@ -158,7 +160,7 @@ int filemenu(menu_entry file){
|
|||
SETBIT(fs_menu_file[11].property, ISHIDE, strstr(file.name, ".bis") == NULL);
|
||||
*/
|
||||
|
||||
temp = menu_make(fs_menu_file, 12, "-- File Menu --");
|
||||
temp = menu_make(fs_menu_file, 13, "-- File Menu --");
|
||||
switch (temp){
|
||||
case FILE_COPY:
|
||||
fsreader_writeclipboard(fsutil_getnextloc(currentpath, file.name), OPERATIONCOPY);
|
||||
|
@ -213,6 +215,17 @@ int filemenu(menu_entry file){
|
|||
extract_bis_file(fsutil_getnextloc(currentpath, file.name), currentpath);
|
||||
fsreader_readfolder(currentpath);
|
||||
hidWait();
|
||||
break;
|
||||
case FILE_SIGN:
|
||||
if (gfx_defaultWaitMenu("WARNING!\n\nThis should only be used if you know what signing and a save is\nDo not do this if you don't know what this does\n\nRequires you to have a prod.keys located in the switch folder\n", 5)){
|
||||
gfx_clearscreen();
|
||||
gfx_printf("Signing save...\n");
|
||||
if (save_sign("sd:/switch/prod.keys", fsutil_getnextloc(currentpath, file.name))){
|
||||
gfx_printf("Done!\nPress any key to exit");
|
||||
hidWait();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case -1:
|
||||
return -1;
|
||||
|
|
123
source/tegraexplorer/fs/savesign.c
Normal file
123
source/tegraexplorer/fs/savesign.c
Normal file
|
@ -0,0 +1,123 @@
|
|||
#include "savesign.h"
|
||||
#include "../../utils/types.h"
|
||||
#include "../../libs/fatfs/ff.h"
|
||||
#include "../../sec/se.h"
|
||||
#include "../../mem/heap.h"
|
||||
#include "../gfx/gfxutils.h"
|
||||
#include "../../config/ini.h"
|
||||
#include "../common/common.h"
|
||||
#include <string.h>
|
||||
|
||||
bool save_commit(const char *path, u8 *save_mac_key){
|
||||
FIL file;
|
||||
int res;
|
||||
u8 *buf, hash[0x20], *cmac_data, cmac[0x10];
|
||||
const u32 hashed_data_size = 0x3D00, cmac_data_size = 0x200;
|
||||
bool success = false;
|
||||
|
||||
buf = malloc(hashed_data_size);
|
||||
cmac_data = malloc(cmac_data_size);
|
||||
|
||||
if ((res = f_open(&file, path, FA_OPEN_EXISTING | FA_READ | FA_WRITE))){
|
||||
gfx_errDisplay("save_commit", res, 1);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
f_lseek(&file, 0x300);
|
||||
if ((res = f_read(&file, buf, hashed_data_size, NULL))){
|
||||
gfx_errDisplay("save_commit", res, 2);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
se_calc_sha256(hash, buf, hashed_data_size);
|
||||
|
||||
f_lseek(&file, 0x108);
|
||||
if ((res = f_write(&file, hash, sizeof(hash), NULL))){
|
||||
gfx_errDisplay("save_commit", res, 3);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
f_lseek(&file, 0x100);
|
||||
if ((res = f_read(&file, cmac_data, cmac_data_size, NULL))){
|
||||
gfx_errDisplay("save_commit", res, 4);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
se_aes_key_set(3, save_mac_key, 0x10);
|
||||
se_aes_cmac(3, cmac, 0x10, cmac_data, cmac_data_size);
|
||||
|
||||
f_lseek(&file, 0);
|
||||
|
||||
if ((res = f_write(&file, cmac, sizeof(cmac), NULL))){
|
||||
gfx_errDisplay("save_commit", res, 5);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
success = true;
|
||||
|
||||
out_free:;
|
||||
free(buf);
|
||||
free(cmac_data);
|
||||
f_close(&file);
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
char *getKey(const char *search, link_t *inilist){
|
||||
LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, inilist, link){
|
||||
if (ini_sec->type == INI_CHOICE){
|
||||
LIST_FOREACH_ENTRY(ini_kv_t, kv, &ini_sec->kvs, link)
|
||||
{
|
||||
if (!strcmp(search, kv->key))
|
||||
return kv->val;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
u8 getHexSingle(const char c) {
|
||||
if (c >= '0' && c <= '9')
|
||||
return c - '0';
|
||||
if (c >= 'a' && c <= 'f')
|
||||
return c - 'a' + 10;
|
||||
}
|
||||
|
||||
u8 *getHex(const char *in){
|
||||
u32 len = strlen(in), count = 0;
|
||||
u8 *out = calloc(len / 2, sizeof(u8));
|
||||
|
||||
for (u32 i = 0; i < len; i += 2){
|
||||
out[count++] = (u8)(getHexSingle(in[i]) << 4) | (getHexSingle(in[i + 1]));
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
bool save_sign(const char *keypath, const char *savepath){
|
||||
LIST_INIT(inilist);
|
||||
char *key;
|
||||
u8 *hex;
|
||||
bool success = false;
|
||||
|
||||
if (!ini_parse(&inilist, keypath, false)){
|
||||
gfx_errDisplay("save_sign", ERR_INI_PARSE_FAIL, 1);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
if ((key = getKey("save_mac_key", &inilist)) == NULL){
|
||||
gfx_errDisplay("save_sign", ERR_INI_PARSE_FAIL, 2);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
hex = getHex(key);
|
||||
|
||||
if (!save_commit(savepath, hex))
|
||||
goto out_free;
|
||||
|
||||
success = true;
|
||||
|
||||
out_free:;
|
||||
list_empty(&inilist);
|
||||
return success;
|
||||
}
|
4
source/tegraexplorer/fs/savesign.h
Normal file
4
source/tegraexplorer/fs/savesign.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
#pragma once
|
||||
#include "../../utils/types.h"
|
||||
|
||||
bool save_sign(const char *keypath, const char *savepath);
|
|
@ -52,7 +52,7 @@ u32 gfx_errDisplay(const char *src_func, int err, int loc){
|
|||
|
||||
if (err < 15)
|
||||
gfx_printf("Desc: %s\n", utils_err_codes[err]);
|
||||
else if (err >= ERR_SAME_LOC && err <= ERR_NO_DESTINATION)
|
||||
else if (err >= ERR_SAME_LOC && err <= ERR_INI_PARSE_FAIL)
|
||||
gfx_printf("Desc: %s\n", utils_err_codes_te[err - 50]);
|
||||
|
||||
if (loc)
|
||||
|
|
Loading…
Reference in a new issue