4 Commits

Author SHA1 Message Date
1881583eea Bump version to v1.8.4 2020-06-17 10:39:02 -06:00
47f749c6fe Support sept from Atmosphere 0.13.0 2020-06-17 10:37:48 -06:00
7649eb1362 Improve code readability 2020-06-17 10:31:29 -06:00
d8586b4763 fatfs: Merge some hekate changes 2020-06-17 10:30:58 -06:00
10 changed files with 180 additions and 91 deletions

View File

@ -11,7 +11,7 @@ include $(DEVKITARM)/base_rules
IPL_LOAD_ADDR := 0x40003000 IPL_LOAD_ADDR := 0x40003000
LPVERSION_MAJOR := 1 LPVERSION_MAJOR := 1
LPVERSION_MINOR := 8 LPVERSION_MINOR := 8
LPVERSION_BUGFX := 3 LPVERSION_BUGFX := 4
################################################################################ ################################################################################

View File

@ -22,10 +22,61 @@
#include "pkg1.h" #include "pkg1.h"
#include "../sec/se.h" #include "../sec/se.h"
#define HASH_ORDER_100_100 {2, 3, 4, 0, 5, 6, 1} #define HASH_ORDER_100_100 { \
#define HASH_ORDER_200_510 {2, 3, 4, 0, 5, 7, 10, 12, 11, 6, 8, 1} FS_KEY_AREA_KEY_APPLI_SOURCE, \
#define HASH_ORDER_600_620 {6, 5, 10, 7, 8, 2, 3, 4, 0, 12, 11, 1} FS_KEY_AREA_KEY_OCEAN_SOURCE, \
#define HASH_ORDER_700_10x {6, 5, 10, 7, 8, 2, 3, 4, 0, 12, 11, 9, 1} FS_KEY_AREA_KEY_SYSTE_SOURCE, \
FS_HEADER_KEK_SOURCE, \
FS_SAVE_MAC_KEK_SOURCE, \
FS_SAVE_MAC_KEY_SOURCE, \
FS_HEADER_KEY_SOURCE \
}
#define HASH_ORDER_200_510 { \
FS_KEY_AREA_KEY_APPLI_SOURCE, \
FS_KEY_AREA_KEY_OCEAN_SOURCE, \
FS_KEY_AREA_KEY_SYSTE_SOURCE, \
FS_HEADER_KEK_SOURCE, \
FS_SAVE_MAC_KEK_SOURCE, \
FS_SAVE_MAC_SD_KEK_SOURCE, \
FS_SD_KEK_SOURCE, \
FS_SD_SAVE_KEY_SOURCE, \
FS_SD_NCA_KEY_SOURCE, \
FS_SAVE_MAC_KEY_SOURCE, \
FS_SAVE_MAC_SD_KEY_SOURCE, \
FS_HEADER_KEY_SOURCE \
}
#define HASH_ORDER_600_620 { \
FS_SAVE_MAC_KEY_SOURCE, \
FS_SAVE_MAC_KEK_SOURCE, \
FS_SD_KEK_SOURCE, \
FS_SAVE_MAC_SD_KEK_SOURCE, \
FS_SAVE_MAC_SD_KEY_SOURCE, \
FS_KEY_AREA_KEY_APPLI_SOURCE, \
FS_KEY_AREA_KEY_OCEAN_SOURCE, \
FS_KEY_AREA_KEY_SYSTE_SOURCE, \
FS_HEADER_KEK_SOURCE, \
FS_SD_SAVE_KEY_SOURCE, \
FS_SD_NCA_KEY_SOURCE, \
FS_HEADER_KEY_SOURCE \
}
#define HASH_ORDER_700_10x { \
FS_SAVE_MAC_KEY_SOURCE, \
FS_SAVE_MAC_KEK_SOURCE, \
FS_SD_KEK_SOURCE, \
FS_SAVE_MAC_SD_KEK_SOURCE, \
FS_SAVE_MAC_SD_KEY_SOURCE, \
FS_KEY_AREA_KEY_APPLI_SOURCE, \
FS_KEY_AREA_KEY_OCEAN_SOURCE, \
FS_KEY_AREA_KEY_SYSTE_SOURCE, \
FS_HEADER_KEK_SOURCE, \
FS_SD_SAVE_KEY_SOURCE, \
FS_SD_NCA_KEY_SOURCE, \
FS_SD_CUSTOM_KEY_SOURCE, \
FS_HEADER_KEY_SOURCE \
}
static const pkg1_id_t _pkg1_ids[] = { static const pkg1_id_t _pkg1_ids[] = {
{ "20161121183008", 0, {0x1b517, 0x125bc2, 1, 16, 6, HASH_ORDER_100_100, 0, 0x449dc} }, //1.0.0 { "20161121183008", 0, {0x1b517, 0x125bc2, 1, 16, 6, HASH_ORDER_100_100, 0, 0x449dc} }, //1.0.0
@ -42,7 +93,7 @@ static const pkg1_id_t _pkg1_ids[] = {
{ "20190531152432", 8, {0x29c50, 0x6a73, 0, 8, 12, HASH_ORDER_700_10x, 0x5563, 0x1d437} }, //8.1.0 { "20190531152432", 8, {0x29c50, 0x6a73, 0, 8, 12, HASH_ORDER_700_10x, 0x5563, 0x1d437} }, //8.1.0
{ "20190809135709", 9, {0x2ec10, 0x5573, 0, 1, 12, HASH_ORDER_700_10x, 0x6495, 0x1d807} }, //9.0.0 - 9.0.1 { "20190809135709", 9, {0x2ec10, 0x5573, 0, 1, 12, HASH_ORDER_700_10x, 0x6495, 0x1d807} }, //9.0.0 - 9.0.1
{ "20191021113848", 10,{0x2ec10, 0x5573, 0, 1, 12, HASH_ORDER_700_10x, 0x6495, 0x1d807} }, //9.1.0 { "20191021113848", 10,{0x2ec10, 0x5573, 0, 1, 12, HASH_ORDER_700_10x, 0x6495, 0x1d807} }, //9.1.0
{ "20200303104606", 10,{0x30ea0, 0x5e4b, 0, 1, 12, HASH_ORDER_700_10x, 0x663c, 0x1d9a4} }, //10.0.0 { "20200303104606", 10,{0x30ea0, 0x5e4b, 0, 1, 12, HASH_ORDER_700_10x, 0x663c, 0x1d9a4} }, //10.0.0+
{ NULL } //End. { NULL } //End.
}; };

View File

@ -19,6 +19,20 @@
#include "../utils/types.h" #include "../utils/types.h"
#define FS_HEADER_KEK_SOURCE 0
#define FS_HEADER_KEY_SOURCE 1
#define FS_KEY_AREA_KEY_APPLI_SOURCE 2
#define FS_KEY_AREA_KEY_OCEAN_SOURCE 3
#define FS_KEY_AREA_KEY_SYSTE_SOURCE 4
#define FS_SAVE_MAC_KEK_SOURCE 5
#define FS_SAVE_MAC_KEY_SOURCE 6
#define FS_SAVE_MAC_SD_KEK_SOURCE 7
#define FS_SAVE_MAC_SD_KEY_SOURCE 8
#define FS_SD_CUSTOM_KEY_SOURCE 9
#define FS_SD_KEK_SOURCE 10
#define FS_SD_NCA_KEY_SOURCE 11
#define FS_SD_SAVE_KEY_SOURCE 12
typedef struct _key_info_t typedef struct _key_info_t
{ {
u32 start_offset; u32 start_offset;

View File

@ -234,7 +234,7 @@ void dump_keys() {
if (!reboot_to_sept((u8 *)tsec_ctxt.fw, tsec_ctxt.size, pkg1_id->kb)) if (!reboot_to_sept((u8 *)tsec_ctxt.fw, tsec_ctxt.size, pkg1_id->kb))
goto out_wait; goto out_wait;
} else { } else {
se_aes_key_read(12, master_key[KB_FIRMWARE_VERSION_MAX], 0x10); se_aes_key_read(se_key_acc_ctrl_get(12) == 0x6A ? 13 : 12, master_key[KB_FIRMWARE_VERSION_MAX], 0x10);
} }
} }
@ -472,7 +472,7 @@ get_tsec: ;
if (!pkg1_not_100) { if (!pkg1_not_100) {
// 1.0.0 doesn't have SD keys at all and the first key isn't aligned with the rest // 1.0.0 doesn't have SD keys at all and the first key isn't aligned with the rest
memcpy(fs_keys[2], ki->kip1->data + ki->kip1->sections[0].size_comp + 0x1ae0e, 0x10); memcpy(fs_keys[FS_KEY_AREA_KEY_APPLI_SOURCE], ki->kip1->data + ki->kip1->sections[0].size_comp + 0x1ae0e, 0x10);
hash_index = 1; hash_index = 1;
} }
@ -506,15 +506,15 @@ pkg2_done:
TPRINTFARGS("%kFS keys... ", colors[(color_idx++) % 6]); TPRINTFARGS("%kFS keys... ", colors[(color_idx++) % 6]);
if (_key_exists(fs_keys[0]) && _key_exists(fs_keys[1]) && _key_exists(master_key[0])) { if (_key_exists(fs_keys[FS_HEADER_KEK_SOURCE]) && _key_exists(fs_keys[FS_HEADER_KEY_SOURCE]) && _key_exists(master_key[0])) {
_generate_kek(8, fs_keys[0], master_key[0], aes_kek_generation_source, aes_key_generation_source); _generate_kek(8, fs_keys[FS_HEADER_KEK_SOURCE], master_key[0], aes_kek_generation_source, aes_key_generation_source);
se_aes_crypt_block_ecb(8, 0, header_key + 0x00, fs_keys[1] + 0x00); se_aes_crypt_block_ecb(8, 0, header_key + 0x00, fs_keys[FS_HEADER_KEY_SOURCE] + 0x00);
se_aes_crypt_block_ecb(8, 0, header_key + 0x10, fs_keys[1] + 0x10); se_aes_crypt_block_ecb(8, 0, header_key + 0x10, fs_keys[FS_HEADER_KEY_SOURCE] + 0x10);
} }
if (_key_exists(fs_keys[5]) && _key_exists(fs_keys[6]) && _key_exists(device_key)) { if (_key_exists(fs_keys[FS_SAVE_MAC_KEK_SOURCE]) && _key_exists(fs_keys[FS_SAVE_MAC_KEY_SOURCE]) && _key_exists(device_key)) {
_generate_kek(8, fs_keys[5], device_key, aes_kek_generation_source, NULL); _generate_kek(8, fs_keys[FS_SAVE_MAC_KEK_SOURCE], device_key, aes_kek_generation_source, NULL);
se_aes_crypt_block_ecb(8, 0, save_mac_key, fs_keys[6]); se_aes_crypt_block_ecb(8, 0, save_mac_key, fs_keys[FS_SAVE_MAC_KEY_SOURCE]);
} }
if (_key_exists(master_key[MAX_KEY])) { if (_key_exists(master_key[MAX_KEY])) {
@ -523,9 +523,9 @@ pkg2_done:
for (u32 i = 0; i < MAX_KEY; i++) { for (u32 i = 0; i < MAX_KEY; i++) {
if (!_key_exists(master_key[i])) if (!_key_exists(master_key[i]))
continue; continue;
if (_key_exists(fs_keys[2]) && _key_exists(fs_keys[3]) && _key_exists(fs_keys[4])) { if (_key_exists(fs_keys[FS_KEY_AREA_KEY_APPLI_SOURCE]) && _key_exists(fs_keys[FS_KEY_AREA_KEY_OCEAN_SOURCE]) && _key_exists(fs_keys[FS_KEY_AREA_KEY_SYSTE_SOURCE])) {
for (u32 j = 0; j < 3; j++) { for (u32 j = 0; j < 3; j++) {
_generate_kek(8, fs_keys[2 + j], master_key[i], aes_kek_generation_source, NULL); _generate_kek(8, fs_keys[FS_KEY_AREA_KEY_APPLI_SOURCE + j], master_key[i], aes_kek_generation_source, NULL);
se_aes_crypt_block_ecb(8, 0, key_area_key[j][i], aes_key_generation_source); se_aes_crypt_block_ecb(8, 0, key_area_key[j][i], aes_key_generation_source);
} }
} }
@ -981,15 +981,15 @@ key_output: ;
SAVE_KEY("eticket_rsa_kek_personalized", eticket_rsa_kek_personalized, 0x10); SAVE_KEY("eticket_rsa_kek_personalized", eticket_rsa_kek_personalized, 0x10);
SAVE_KEY("eticket_rsa_kek_source", es_keys[0], 0x10); SAVE_KEY("eticket_rsa_kek_source", es_keys[0], 0x10);
SAVE_KEY("eticket_rsa_kekek_source", es_keys[1], 0x10); SAVE_KEY("eticket_rsa_kekek_source", es_keys[1], 0x10);
SAVE_KEY("header_kek_source", fs_keys[0], 0x10); SAVE_KEY("header_kek_source", fs_keys[FS_HEADER_KEK_SOURCE], 0x10);
SAVE_KEY("header_key", header_key, 0x20); SAVE_KEY("header_key", header_key, 0x20);
SAVE_KEY("header_key_source", fs_keys[1], 0x20); SAVE_KEY("header_key_source", fs_keys[FS_HEADER_KEY_SOURCE], 0x20);
SAVE_KEY_FAMILY("key_area_key_application", key_area_key[0], 0, MAX_KEY, 0x10); SAVE_KEY_FAMILY("key_area_key_application", key_area_key[0], 0, MAX_KEY, 0x10);
SAVE_KEY("key_area_key_application_source", fs_keys[2], 0x10); SAVE_KEY("key_area_key_application_source", fs_keys[FS_KEY_AREA_KEY_APPLI_SOURCE], 0x10);
SAVE_KEY_FAMILY("key_area_key_ocean", key_area_key[1], 0, MAX_KEY, 0x10); SAVE_KEY_FAMILY("key_area_key_ocean", key_area_key[1], 0, MAX_KEY, 0x10);
SAVE_KEY("key_area_key_ocean_source", fs_keys[3], 0x10); SAVE_KEY("key_area_key_ocean_source", fs_keys[FS_KEY_AREA_KEY_OCEAN_SOURCE], 0x10);
SAVE_KEY_FAMILY("key_area_key_system", key_area_key[2], 0, MAX_KEY, 0x10); SAVE_KEY_FAMILY("key_area_key_system", key_area_key[2], 0, MAX_KEY, 0x10);
SAVE_KEY("key_area_key_system_source", fs_keys[4], 0x10); SAVE_KEY("key_area_key_system_source", fs_keys[FS_KEY_AREA_KEY_SYSTE_SOURCE], 0x10);
SAVE_KEY_FAMILY("keyblob", keyblob, 0, 6, 0x90); SAVE_KEY_FAMILY("keyblob", keyblob, 0, 6, 0x90);
SAVE_KEY_FAMILY("keyblob_key", keyblob_key, 0, 6, 0x10); SAVE_KEY_FAMILY("keyblob_key", keyblob_key, 0, 6, 0x10);
SAVE_KEY_FAMILY("keyblob_key_source", keyblob_key_source, 0, 6, 0x10); SAVE_KEY_FAMILY("keyblob_key_source", keyblob_key_source, 0, 6, 0x10);
@ -1010,15 +1010,15 @@ key_output: ;
for (u32 i = 0; i < 0x10; i++) for (u32 i = 0; i < 0x10; i++)
temp_key[i] = aes_kek_generation_source[i] ^ aes_kek_seed_01[i]; temp_key[i] = aes_kek_generation_source[i] ^ aes_kek_seed_01[i];
SAVE_KEY("rsa_private_kek_generation_source", temp_key, 0x10); SAVE_KEY("rsa_private_kek_generation_source", temp_key, 0x10);
SAVE_KEY("save_mac_kek_source", fs_keys[5], 0x10); SAVE_KEY("save_mac_kek_source", fs_keys[FS_SAVE_MAC_KEK_SOURCE], 0x10);
SAVE_KEY("save_mac_key", save_mac_key, 0x10); SAVE_KEY("save_mac_key", save_mac_key, 0x10);
SAVE_KEY("save_mac_key_source", fs_keys[6], 0x10); SAVE_KEY("save_mac_key_source", fs_keys[FS_SAVE_MAC_KEY_SOURCE], 0x10);
SAVE_KEY("save_mac_sd_card_kek_source", fs_keys[7], 0x10); SAVE_KEY("save_mac_sd_card_kek_source", fs_keys[FS_SAVE_MAC_SD_KEK_SOURCE], 0x10);
SAVE_KEY("save_mac_sd_card_key_source", fs_keys[8], 0x10); SAVE_KEY("save_mac_sd_card_key_source", fs_keys[FS_SAVE_MAC_SD_KEY_SOURCE], 0x10);
SAVE_KEY("sd_card_custom_storage_key_source", fs_keys[9], 0x20); SAVE_KEY("sd_card_custom_storage_key_source", fs_keys[FS_SD_CUSTOM_KEY_SOURCE], 0x20);
SAVE_KEY("sd_card_kek_source", fs_keys[10], 0x10); SAVE_KEY("sd_card_kek_source", fs_keys[FS_SD_KEK_SOURCE], 0x10);
SAVE_KEY("sd_card_nca_key_source", fs_keys[11], 0x20); SAVE_KEY("sd_card_nca_key_source", fs_keys[FS_SD_NCA_KEY_SOURCE], 0x20);
SAVE_KEY("sd_card_save_key_source", fs_keys[12], 0x20); SAVE_KEY("sd_card_save_key_source", fs_keys[FS_SD_SAVE_KEY_SOURCE], 0x20);
SAVE_KEY("sd_seed", sd_seed, 0x10); SAVE_KEY("sd_seed", sd_seed, 0x10);
SAVE_KEY("secure_boot_key", sbk, 0x10); SAVE_KEY("secure_boot_key", sbk, 0x10);
SAVE_KEY("ssl_rsa_kek", ssl_rsa_kek, 0x10); SAVE_KEY("ssl_rsa_kek", ssl_rsa_kek, 0x10);

View File

@ -193,7 +193,7 @@ typedef struct {
} remap_storage_ctx_t; } remap_storage_ctx_t;
typedef struct { typedef struct {
uint64_t title_id; uint64_t program_id;
uint8_t user_id[0x10]; uint8_t user_id[0x10];
uint64_t save_id; uint64_t save_id;
uint8_t save_data_type; uint8_t save_data_type;

View File

@ -38,10 +38,8 @@
#include "ff.h" /* Declarations of FatFs API */ #include "ff.h" /* Declarations of FatFs API */
#include "diskio.h" /* Declarations of device I/O functions */ #include "diskio.h" /* Declarations of device I/O functions */
#include "../../gfx/gfx.h"
#define EFSPRINTF(text, ...) print_error(); gfx_printf("%k"text"%k\n", 0xFFFFFF00, 0xFFFFFFFF); #define EFSPRINTF(text, ...)
//#define EFSPRINTF(...)
/*-------------------------------------------------------------------------- /*--------------------------------------------------------------------------
@ -532,7 +530,7 @@ static WCHAR LfnBuf[FF_MAX_LFN + 1]; /* LFN working buffer */
#define FREE_NAMBUF() ff_memfree(lfn) #define FREE_NAMBUF() ff_memfree(lfn)
#endif #endif
#define LEAVE_MKFS(res) { if (!work) ff_memfree(buf); return res; } #define LEAVE_MKFS(res) { if (!work) ff_memfree(buf); return res; }
#define MAX_MALLOC 0x8000 /* Must be >=FF_MAX_SS */ #define MAX_MALLOC 0x4000 /* Must be >=FF_MAX_SS */
#else #else
#error Wrong setting of FF_USE_LFN #error Wrong setting of FF_USE_LFN
@ -592,16 +590,6 @@ static const BYTE DbcTbl[] = MKCVTBL(TBL_DC, FF_CODE_PAGE);
---------------------------------------------------------------------------*/ ---------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------*/
/* Print error header */
/*-----------------------------------------------------------------------*/
void print_error()
{
gfx_printf("\n\n\n%k[FatFS] Error: %k", 0xFFFFFF00, 0xFFFFFFFF);
}
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* Load/Store multi-byte word in the FAT structure */ /* Load/Store multi-byte word in the FAT structure */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
@ -3921,13 +3909,12 @@ FRESULT f_read_fast (
FATFS *fs; FATFS *fs;
UINT csize_bytes; UINT csize_bytes;
DWORD clst; DWORD clst;
UINT count = 0; DWORD wbytes;
UINT count;
FSIZE_t work_sector = 0; FSIZE_t work_sector = 0;
FSIZE_t sector_base = 0; FSIZE_t sector_base = 0;
BYTE *wbuff = (BYTE*)buff; BYTE *wbuff = (BYTE*)buff;
// TODO support sector reading inside a cluster
res = validate(&fp->obj, &fs); /* Check validity of the file object */ res = validate(&fp->obj, &fs); /* Check validity of the file object */
if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) { if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) {
EFSPRINTF("FOV"); EFSPRINTF("FOV");
@ -3939,6 +3926,17 @@ FRESULT f_read_fast (
if (btr > remain) btr = (UINT)remain; /* Truncate btr by remaining bytes */ if (btr > remain) btr = (UINT)remain; /* Truncate btr by remaining bytes */
csize_bytes = fs->csize * SS(fs); csize_bytes = fs->csize * SS(fs);
DWORD csect = (UINT)((fp->fptr / SS(fs)) & (fs->csize - 1)); /* Sector offset in the cluster */
/* If inside a cluster, read the sectors and align to cluster. */
if (csect) {
wbytes = MIN(btr, (fs->csize - csect) * SS(fs));
f_read(fp, wbuff, wbytes, (void *)0);
wbuff += wbytes;
btr -= wbytes;
if (!btr)
goto out;
}
if (!fp->fptr) { /* On the top of the file? */ if (!fp->fptr) { /* On the top of the file? */
clst = fp->obj.sclust; /* Follow from the origin */ clst = fp->obj.sclust; /* Follow from the origin */
@ -3946,15 +3944,22 @@ FRESULT f_read_fast (
if (fp->cltbl) clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */ if (fp->cltbl) clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */
else { EFSPRINTF("CLTBL"); ABORT(fs, FR_CLTBL_NO_INIT); } else { EFSPRINTF("CLTBL"); ABORT(fs, FR_CLTBL_NO_INIT); }
} }
if (clst < 2) { EFSPRINTF("CCHK"); ABORT(fs, FR_INT_ERR); } if (clst < 2) { EFSPRINTF("CCHK"); ABORT(fs, FR_INT_ERR); }
else if (clst == 0xFFFFFFFF) { EFSPRINTF("DSKC"); ABORT(fs, FR_DISK_ERR); } else if (clst == 0xFFFFFFFF) { EFSPRINTF("DSKC"); ABORT(fs, FR_DISK_ERR); }
fp->clust = clst; /* Set working cluster */ fp->clust = clst; /* Set working cluster */
wbytes = MIN(btr, csize_bytes);
sector_base = clst2sect(fs, fp->clust); sector_base = clst2sect(fs, fp->clust);
count += fs->csize; count = wbytes / SS(fs);
btr -= csize_bytes; fp->fptr += wbytes;
fp->fptr += csize_bytes; btr -= wbytes;
if (!btr) { /* Final cluster/sectors read. */
if (disk_read(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR);
goto out;
}
while (btr) { while (btr) {
clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */ clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */
@ -3965,26 +3970,25 @@ FRESULT f_read_fast (
fp->clust = clst; fp->clust = clst;
work_sector = clst2sect(fs, fp->clust); work_sector = clst2sect(fs, fp->clust);
if ((work_sector - sector_base) == count) count += fs->csize; wbytes = MIN(btr, csize_bytes);
if ((work_sector - sector_base) == count) count += wbytes / SS(fs);
else { else {
if (disk_read(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR); if (disk_read(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR);
wbuff += count * SS(fs); wbuff += count * SS(fs);
sector_base = work_sector; sector_base = work_sector;
count = fs->csize; count = wbytes / SS(fs);
} }
fp->fptr += MIN(btr, csize_bytes); fp->fptr += wbytes;
btr -= MIN(btr, csize_bytes); btr -= wbytes;
// TODO: what about if data is smaller than cluster?
// Must read-write back that cluster.
if (!btr) { /* Final cluster/sectors read. */ if (!btr) { /* Final cluster/sectors read. */
if (disk_read(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR); if (disk_read(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR);
} }
} }
out:
LEAVE_FF(fs, FR_OK); LEAVE_FF(fs, FR_OK);
} }
#endif #endif
@ -4147,12 +4151,11 @@ FRESULT f_write_fast (
FATFS *fs; FATFS *fs;
UINT csize_bytes; UINT csize_bytes;
DWORD clst; DWORD clst;
UINT count = 0; DWORD wbytes;
UINT count;
FSIZE_t work_sector = 0; FSIZE_t work_sector = 0;
FSIZE_t sector_base = 0; FSIZE_t sector_base = 0;
const BYTE *wbuff = (const BYTE*)buff; BYTE *wbuff = (BYTE*)buff;
// TODO support sector writing inside a cluster
res = validate(&fp->obj, &fs); /* Check validity of the file object */ res = validate(&fp->obj, &fs); /* Check validity of the file object */
if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) { if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) {
@ -4167,6 +4170,19 @@ FRESULT f_write_fast (
} }
csize_bytes = fs->csize * SS(fs); csize_bytes = fs->csize * SS(fs);
DWORD csect = (UINT)((fp->fptr / SS(fs)) & (fs->csize - 1)); /* Sector offset in the cluster */
/* If inside a cluster, write the sectors and align to cluster. */
if (csect) {
wbytes = MIN(btw, (fs->csize - csect) * SS(fs));
f_write(fp, wbuff, wbytes, (void *)0);
/* Ensure flushing of it. FatFS is not notified for next write if raw. */
f_sync(fp);
wbuff += wbytes;
btw -= wbytes;
if (!btw)
goto out;
}
if (!fp->fptr) { /* On the top of the file? */ if (!fp->fptr) { /* On the top of the file? */
clst = fp->obj.sclust; /* Follow from the origin */ clst = fp->obj.sclust; /* Follow from the origin */
@ -4176,44 +4192,51 @@ FRESULT f_write_fast (
} }
if (clst < 2) { EFSPRINTF("CCHK"); ABORT(fs, FR_INT_ERR); } if (clst < 2) { EFSPRINTF("CCHK"); ABORT(fs, FR_INT_ERR); }
else if (clst == 0xFFFFFFFF) { EFSPRINTF("DERR"); ABORT(fs, FR_DISK_ERR); } else if (clst == 0xFFFFFFFF) { EFSPRINTF("DSKC"); ABORT(fs, FR_DISK_ERR); }
fp->clust = clst; /* Set working cluster */ fp->clust = clst; /* Set working cluster */
wbytes = MIN(btw, csize_bytes);
sector_base = clst2sect(fs, fp->clust); sector_base = clst2sect(fs, fp->clust);
count += fs->csize; count = wbytes / SS(fs);
btw -= csize_bytes; fp->fptr += wbytes;
fp->fptr += csize_bytes; btw -= wbytes;
if (!btw) { /* Final cluster/sectors write. */
if (disk_write(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR);
fp->flag &= (BYTE)~FA_DIRTY;
goto out;
}
while (btw) { while (btw) {
clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */ clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */
if (clst < 2) { EFSPRINTF("CCHK2"); ABORT(fs, FR_INT_ERR); } if (clst < 2) { EFSPRINTF("CCHK2"); ABORT(fs, FR_INT_ERR); }
else if (clst == 0xFFFFFFFF) { EFSPRINTF("DERR"); ABORT(fs, FR_DISK_ERR); } else if (clst == 0xFFFFFFFF) { EFSPRINTF("DSKC"); ABORT(fs, FR_DISK_ERR); }
fp->clust = clst; fp->clust = clst;
work_sector = clst2sect(fs, fp->clust); work_sector = clst2sect(fs, fp->clust);
if ((work_sector - sector_base) == count) count += fs->csize; wbytes = MIN(btw, csize_bytes);
if ((work_sector - sector_base) == count) count += wbytes / SS(fs);
else { else {
if (disk_write(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR); if (disk_write(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR);
wbuff += count * SS(fs); wbuff += count * SS(fs);
sector_base = work_sector; sector_base = work_sector;
count = fs->csize; count = wbytes / SS(fs);
} }
fp->fptr += MIN(btw, csize_bytes); fp->fptr += wbytes;
btw -= MIN(btw, csize_bytes); btw -= wbytes;
// what about if data is smaller than cluster?
// Probably must read-write back that cluster.
if (!btw) { /* Final cluster/sectors write. */ if (!btw) { /* Final cluster/sectors write. */
if (disk_write(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR); if (disk_write(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR);
fp->flag &= (BYTE)~FA_DIRTY; fp->flag &= (BYTE)~FA_DIRTY;
} }
} }
out:
fp->flag |= FA_MODIFIED; /* Set file change flag */ fp->flag |= FA_MODIFIED; /* Set file change flag */
LEAVE_FF(fs, FR_OK); LEAVE_FF(fs, FR_OK);
@ -4689,19 +4712,17 @@ FRESULT f_lseek (
DWORD *f_expand_cltbl ( DWORD *f_expand_cltbl (
FIL* fp, /* Pointer to the file object */ FIL* fp, /* Pointer to the file object */
UINT tblsz, /* Size of table */ UINT tblsz, /* Size of table */
DWORD *tbl, /* Table pointer */
FSIZE_t ofs /* File pointer from top of file */ FSIZE_t ofs /* File pointer from top of file */
) )
{ {
if (fp->flag & FA_WRITE) f_lseek(fp, ofs); /* Expand file if write is enabled */ if (fp->flag & FA_WRITE) f_lseek(fp, ofs); /* Expand file if write is enabled */
if (!fp->cltbl) { /* Allocate memory for cluster link table */ fp->cltbl = (DWORD *)tbl;
fp->cltbl = (DWORD *)ff_memalloc(tblsz); fp->cltbl[0] = tblsz;
fp->cltbl[0] = tblsz;
}
if (f_lseek(fp, CREATE_LINKMAP)) { /* Create cluster link table */ if (f_lseek(fp, CREATE_LINKMAP)) { /* Create cluster link table */
ff_memfree(fp->cltbl); fp->cltbl = (void *)0;
fp->cltbl = NULL;
EFSPRINTF("CLTBLSZ"); EFSPRINTF("CLTBLSZ");
return NULL; return (void *)0;
} }
f_lseek(fp, 0); f_lseek(fp, 0);
@ -5842,7 +5863,7 @@ FRESULT f_mkfs (
UINT len /* Size of working buffer [byte] */ UINT len /* Size of working buffer [byte] */
) )
{ {
const UINT n_fats = 2; /* Number of FATs for FAT/FAT32 volume (1 or 2) */ const UINT n_fats = 1; /* Number of FATs for FAT/FAT32 volume (1 or 2) */
const UINT n_rootdir = 512; /* Number of root directory entries for FAT volume */ const UINT n_rootdir = 512; /* Number of root directory entries for FAT volume */
static const WORD cst[] = {1, 4, 16, 64, 256, 512, 0}; /* Cluster size boundary for FAT volume (4Ks unit) */ static const WORD cst[] = {1, 4, 16, 64, 256, 512, 0}; /* Cluster size boundary for FAT volume (4Ks unit) */
static const WORD cst32[] = {1, 2, 4, 8, 16, 32, 0}; /* Cluster size boundary for FAT32 volume (128Ks unit) */ static const WORD cst32[] = {1, 2, 4, 8, 16, 32, 0}; /* Cluster size boundary for FAT32 volume (128Ks unit) */
@ -5906,7 +5927,7 @@ FRESULT f_mkfs (
} else { } else {
/* Create a single-partition in this function */ /* Create a single-partition in this function */
if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_vol) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_vol) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);
b_vol = (opt & FM_SFD) ? 0 : 32768; /* Volume start sector. Align to 16MB */ b_vol = (opt & FM_SFD) ? 0 : 63; /* Volume start sector */
if (sz_vol < b_vol) LEAVE_MKFS(FR_MKFS_ABORTED); if (sz_vol < b_vol) LEAVE_MKFS(FR_MKFS_ABORTED);
sz_vol -= b_vol; /* Volume size */ sz_vol -= b_vol; /* Volume size */
} }
@ -6130,9 +6151,6 @@ FRESULT f_mkfs (
if (fmt == FS_FAT32) { /* FAT32: Move FAT base */ if (fmt == FS_FAT32) { /* FAT32: Move FAT base */
sz_rsv += n; b_fat += n; sz_rsv += n; b_fat += n;
} else { /* FAT: Expand FAT size */ } else { /* FAT: Expand FAT size */
if (n % n_fats) { /* Adjust fractional error if needed */
n--; sz_rsv++; b_fat++;
}
sz_fat += n / n_fats; sz_fat += n / n_fats;
} }
@ -6196,13 +6214,13 @@ FRESULT f_mkfs (
st_word(buf + BPB_BkBootSec32, 6); /* Offset of backup VBR (VBR + 6) */ st_word(buf + BPB_BkBootSec32, 6); /* Offset of backup VBR (VBR + 6) */
buf[BS_DrvNum32] = 0x80; /* Drive number (for int13) */ buf[BS_DrvNum32] = 0x80; /* Drive number (for int13) */
buf[BS_BootSig32] = 0x29; /* Extended boot signature */ buf[BS_BootSig32] = 0x29; /* Extended boot signature */
mem_cpy(buf + BS_VolLab32, "SWITCH SD " "FAT32 ", 19); /* Volume label, FAT signature */ mem_cpy(buf + BS_VolLab32, "NO NAME " "FAT32 ", 19); /* Volume label, FAT signature */
} else { } else {
st_dword(buf + BS_VolID, GET_FATTIME()); /* VSN */ st_dword(buf + BS_VolID, GET_FATTIME()); /* VSN */
st_word(buf + BPB_FATSz16, (WORD)sz_fat); /* FAT size [sector] */ st_word(buf + BPB_FATSz16, (WORD)sz_fat); /* FAT size [sector] */
buf[BS_DrvNum] = 0x80; /* Drive number (for int13) */ buf[BS_DrvNum] = 0x80; /* Drive number (for int13) */
buf[BS_BootSig] = 0x29; /* Extended boot signature */ buf[BS_BootSig] = 0x29; /* Extended boot signature */
mem_cpy(buf + BS_VolLab, "SWITCH SD " "FAT ", 19); /* Volume label, FAT signature */ mem_cpy(buf + BS_VolLab, "NO NAME " "FAT ", 19); /* Volume label, FAT signature */
} }
st_word(buf + BS_55AA, 0xAA55); /* Signature (offset is fixed here regardless of sector size) */ st_word(buf + BS_55AA, 0xAA55); /* Signature (offset is fixed here regardless of sector size) */
if (disk_write(pdrv, buf, b_vol, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Write it to the VBR sector */ if (disk_write(pdrv, buf, b_vol, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Write it to the VBR sector */

View File

@ -289,7 +289,7 @@ FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume
FRESULT f_setlabel (const TCHAR* label); /* Set volume label */ FRESULT f_setlabel (const TCHAR* label); /* Set volume label */
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */ FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
#ifdef FF_FASTFS #ifdef FF_FASTFS
DWORD *f_expand_cltbl (FIL* fp, UINT tblsz, FSIZE_t ofs); /* Expand file and populate cluster table */ DWORD *f_expand_cltbl (FIL* fp, UINT tblsz, DWORD *tbl, FSIZE_t ofs); /* Expand file and populate cluster table */
#endif #endif
FRESULT f_expand (FIL* fp, FSIZE_t fsz, BYTE opt); /* Allocate a contiguous block to the file */ FRESULT f_expand (FIL* fp, FSIZE_t fsz, BYTE opt); /* Allocate a contiguous block to the file */
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */ FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */

View File

@ -41,7 +41,7 @@
#define FF_USE_MKFS 0 #define FF_USE_MKFS 0
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */ /* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
#define FF_FASTFS 0 #define FF_FASTFS 0
#if FF_FASTFS #if FF_FASTFS
#define FF_USE_FASTSEEK 1 #define FF_USE_FASTSEEK 1

View File

@ -230,6 +230,11 @@ void se_key_acc_ctrl(u32 ks, u32 flags)
SE(SE_KEY_TABLE_ACCESS_LOCK_OFFSET) &= ~(1 << ks); SE(SE_KEY_TABLE_ACCESS_LOCK_OFFSET) &= ~(1 << ks);
} }
u32 se_key_acc_ctrl_get(u32 ks)
{
return SE(SE_KEY_TABLE_ACCESS_REG_OFFSET + 4 * ks);
}
void se_aes_key_set(u32 ks, const void *key, u32 size) void se_aes_key_set(u32 ks, const void *key, u32 size)
{ {
u32 *data = (u32 *)key; u32 *data = (u32 *)key;
@ -418,8 +423,8 @@ int se_aes_xts_crypt_sec(u32 ks1, u32 ks2, u32 enc, u64 sec, void *dst, const vo
u8 *tweak = (u8 *)malloc(0x10); u8 *tweak = (u8 *)malloc(0x10);
u8 *temptweak = (u8 *)malloc(0x10); u8 *temptweak = (u8 *)malloc(0x10);
u32 *pdst = (u32 *)dst; u32 *pdst = (u32 *)dst;
u32 *psrc = (u32 *)src; u32 *psrc = (u32 *)src;
u32 *ptweak = (u32 *)tweak; u32 *ptweak = (u32 *)tweak;
//Generate tweak. //Generate tweak.
for (int i = 0xF; i >= 0; i--) for (int i = 0xF; i >= 0; i--)

View File

@ -24,6 +24,7 @@ void se_rsa_key_set(u32 ks, const void *mod, u32 mod_size, const void *exp, u32
void se_rsa_key_clear(u32 ks); void se_rsa_key_clear(u32 ks);
int se_rsa_exp_mod(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size); int se_rsa_exp_mod(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size);
void se_key_acc_ctrl(u32 ks, u32 flags); void se_key_acc_ctrl(u32 ks, u32 flags);
u32 se_key_acc_ctrl_get(u32 ks);
void se_aes_key_set(u32 ks, const void *key, u32 size); void se_aes_key_set(u32 ks, const void *key, u32 size);
void se_aes_iv_set(u32 ks, const void *iv, u32 size); void se_aes_iv_set(u32 ks, const void *iv, u32 size);
void se_aes_key_read(u32 ks, void *key, u32 size); void se_aes_key_read(u32 ks, void *key, u32 size);