mirror of
https://github.com/Scandal-UK/Incognito_RCM.git
synced 2024-11-08 05:01:45 +00:00
Merged changes from Lockpick_RCM
This commit is contained in:
parent
d29010a84b
commit
dfb15ae203
10 changed files with 180 additions and 84 deletions
|
@ -414,6 +414,7 @@ void gfx_print_header()
|
|||
gfx_printf("%k _/ // / / / /__/ /_/ / /_/ / / / / / /_/ /_/ / / _, _/ /___/ / / / \n", COLOR_GREEN);
|
||||
gfx_printf("%k/___/_/ /_/\\___/\\____/\\__, /_/ /_/_/\\__/\\____/____/_/ |_|\\____/_/ /_/ \n", colors[4]);
|
||||
gfx_printf("%k /____/ /_____/ \n", colors[4]);
|
||||
gfx_printf("%k[UNOFFICIAL]\n", COLOR_BLUE);
|
||||
gfx_con.fntsz = 14;
|
||||
gfx_printf("%kv%d.%d.%d - by jimzrt%k\n\n\n\n",
|
||||
colors[4], LP_VER_MJ, LP_VER_MN, LP_VER_BF, 0xFFCCCCCC);
|
||||
|
|
|
@ -22,10 +22,61 @@
|
|||
#include "pkg1.h"
|
||||
#include "../sec/se.h"
|
||||
|
||||
#define HASH_ORDER_100_100 {2, 3, 4, 0, 5, 6, 1}
|
||||
#define HASH_ORDER_200_510 {2, 3, 4, 0, 5, 7, 10, 12, 11, 6, 8, 1}
|
||||
#define HASH_ORDER_600_620 {6, 5, 10, 7, 8, 2, 3, 4, 0, 12, 11, 1}
|
||||
#define HASH_ORDER_700_10x {6, 5, 10, 7, 8, 2, 3, 4, 0, 12, 11, 9, 1}
|
||||
#define HASH_ORDER_100_100 { \
|
||||
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_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[] = {
|
||||
{ "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
|
||||
{ "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
|
||||
{ "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.
|
||||
};
|
||||
|
||||
|
|
|
@ -19,6 +19,20 @@
|
|||
|
||||
#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
|
||||
{
|
||||
u32 start_offset;
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "../storage/emummc.h"
|
||||
#include "../storage/nx_emmc.h"
|
||||
#include "../storage/sdmmc.h"
|
||||
#include "../utils/btn.h"
|
||||
#include "../utils/list.h"
|
||||
#include "../utils/sprintf.h"
|
||||
#include "../utils/util.h"
|
||||
|
@ -81,7 +82,7 @@ emmc_part_t *prodinfo_part;
|
|||
static u8 temp_key[0x10],
|
||||
bis_key[4][0x20] = {0},
|
||||
device_key[0x10] = {0},
|
||||
new_device_key[0x10] = {0},
|
||||
device_key_4x[0x10] = {0},
|
||||
keyblob[KB_FIRMWARE_VERSION_600 + 1][0x90] = {0},
|
||||
keyblob_key[KB_FIRMWARE_VERSION_600 + 1][0x10] = {0},
|
||||
keyblob_mac_key[KB_FIRMWARE_VERSION_600 + 1][0x10] = {0},
|
||||
|
@ -93,8 +94,9 @@ static u8 temp_key[0x10],
|
|||
LIST_INIT(gpt);
|
||||
|
||||
// key functions
|
||||
static bool _key_exists(const void *data) { return memcmp(data, zeros, 0x10); };
|
||||
static int _key_exists(const void *data) { return memcmp(data, zeros, 0x10) != 0; };
|
||||
static void _generate_kek(u32 ks, const void *key_source, void *master_key, const void *kek_seed, const void *key_seed);
|
||||
static void _get_device_key(u32 ks, void *out_device_key, u32 revision, const void *device_key, const void *master_key);
|
||||
|
||||
unsigned int crc_16_table[16] = {
|
||||
0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401,
|
||||
|
@ -193,7 +195,7 @@ bool dump_keys()
|
|||
|
||||
// Read package1.
|
||||
u8 *pkg1 = (u8 *)malloc(0x40000);
|
||||
emummc_storage_set_mmc_partition(&storage, 1);
|
||||
emummc_storage_set_mmc_partition(&storage, EMMC_BOOT0);
|
||||
emummc_storage_read(&storage, 0x100000 / NX_EMMC_BLOCKSIZE, 0x40000 / NX_EMMC_BLOCKSIZE, pkg1);
|
||||
const pkg1_id_t *pkg1_id = pkg1_identify(pkg1);
|
||||
if (!pkg1_id)
|
||||
|
@ -232,7 +234,7 @@ bool dump_keys()
|
|||
|
||||
if (pkg1_id->kb >= KB_FIRMWARE_VERSION_700)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
//get_tsec: ;
|
||||
|
@ -293,14 +295,14 @@ bool dump_keys()
|
|||
if (i == 0)
|
||||
{
|
||||
se_aes_crypt_block_ecb(7, 0, device_key, per_console_key_source); // devkey = unwrap(pcks, kbk0)
|
||||
se_aes_crypt_block_ecb(7, 0, new_device_key, per_console_key_source_4x);
|
||||
se_aes_crypt_block_ecb(7, 0, device_key_4x, per_console_key_source_4x);
|
||||
}
|
||||
|
||||
// verify keyblob is not corrupt
|
||||
emummc_storage_read(&storage, 0x180000 / NX_EMMC_BLOCKSIZE + i, 1, keyblob_block);
|
||||
se_aes_key_set(3, keyblob_mac_key[i], 0x10);
|
||||
se_aes_cmac(3, keyblob_mac, 0x10, keyblob_block + 0x10, 0xa0);
|
||||
if (memcmp(keyblob_block, keyblob_mac, 0x10))
|
||||
if (memcmp(keyblob_block, keyblob_mac, 0x10) != 0)
|
||||
{
|
||||
EPRINTFARGS("Keyblob %x corrupt.", i);
|
||||
// gfx_hexdump(i, keyblob_block, 0x10);
|
||||
|
@ -325,17 +327,15 @@ bool dump_keys()
|
|||
if ((fuse_read_odm(4) & 0x800) && fuse_read_odm(0) == 0x8E61ECAE && fuse_read_odm(1) == 0xF2BA3BB2)
|
||||
{
|
||||
key_generation = fuse_read_odm(2) & 0x1F;
|
||||
if (key_generation)
|
||||
key_generation--;
|
||||
}
|
||||
}
|
||||
if (_key_exists(device_key))
|
||||
{
|
||||
if (key_generation)
|
||||
{
|
||||
se_aes_key_set(8, new_device_key, 0x10);
|
||||
se_aes_crypt_block_ecb(8, 0, temp_key, new_device_key_sources[pkg1_id->kb - KB_FIRMWARE_VERSION_400]);
|
||||
se_aes_key_set(8, master_key[0], 0x10);
|
||||
se_aes_unwrap_key(8, 8, new_device_keygen_sources[pkg1_id->kb - KB_FIRMWARE_VERSION_400]);
|
||||
se_aes_crypt_block_ecb(8, 0, temp_key, temp_key);
|
||||
_get_device_key(8, temp_key, key_generation, device_key_4x, master_key[0]);
|
||||
}
|
||||
else
|
||||
memcpy(temp_key, device_key, 0x10);
|
||||
|
@ -352,7 +352,7 @@ bool dump_keys()
|
|||
memcpy(bis_key[3], bis_key[2], 0x20);
|
||||
}
|
||||
|
||||
emummc_storage_set_mmc_partition(&storage, 0);
|
||||
emummc_storage_set_mmc_partition(&storage, EMMC_GPP);
|
||||
// Parse eMMC GPT.
|
||||
|
||||
nx_emmc_gpt_parse(&gpt, &storage);
|
||||
|
@ -513,6 +513,19 @@ static void _generate_kek(u32 ks, const void *key_source, void *master_key, cons
|
|||
se_aes_unwrap_key(ks, ks, key_seed);
|
||||
}
|
||||
|
||||
static void _get_device_key(u32 ks, void *out_device_key, u32 revision, const void *device_key, const void *master_key) {
|
||||
if (revision < KB_FIRMWARE_VERSION_400)
|
||||
memcpy(out_device_key, device_key, 0x10);
|
||||
|
||||
revision -= KB_FIRMWARE_VERSION_400;
|
||||
u8 temp_key[0x10] = {0};
|
||||
se_aes_key_set(ks, device_key, 0x10);
|
||||
se_aes_crypt_ecb(ks, 0, temp_key, 0x10, new_device_key_sources[revision], 0x10);
|
||||
se_aes_key_set(ks, master_key, 0x10);
|
||||
se_aes_unwrap_key(ks, ks, new_device_keygen_sources[revision]);
|
||||
se_aes_crypt_ecb(ks, 0, out_device_key, 0x10, temp_key, 0x10);
|
||||
}
|
||||
|
||||
static inline u32 _read_le_u32(const void *buffer, u32 offset)
|
||||
{
|
||||
return (*(u8 *)(buffer + offset + 0)) |
|
||||
|
@ -757,7 +770,7 @@ bool verifyHash(u32 hashOffset, u32 offset, u32 sz, u8 *blob)
|
|||
memcpy(hash2, blob + hashOffset, 0x20);
|
||||
}
|
||||
|
||||
if (memcmp(hash1, hash2, 0x20))
|
||||
if (memcmp(hash1, hash2, 0x20) != 0)
|
||||
{
|
||||
EPRINTF("error: hash verification failed\n");
|
||||
// gfx_hexdump(0, hash1, 0x20);
|
||||
|
@ -1030,13 +1043,6 @@ bool restoreProdinfo()
|
|||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
if (validateCrc(0x250, 0x1E, NULL))
|
||||
gfx_printf("%kValid serial checksum\n", COLOR_GREEN);
|
||||
else
|
||||
gfx_printf("%kWarning - invalid serial checksum\n", COLOR_RED);
|
||||
*/
|
||||
|
||||
result = true;
|
||||
gfx_printf("\n%kRestore from %s done!\n\n", COLOR_GREEN, name);
|
||||
out:
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
static const u8 zeros[0x10] = {0};
|
||||
static u8 zeros[0x10] = {0};
|
||||
|
||||
static const u8 keyblob_key_source[][0x10] = {
|
||||
{0xDF, 0x20, 0x6F, 0x59, 0x44, 0x54, 0xEF, 0xDC, 0x70, 0x74, 0x48, 0x3B, 0x0D, 0xED, 0x9F, 0xD3}, //1.0.0
|
||||
|
|
|
@ -38,10 +38,8 @@
|
|||
|
||||
#include "ff.h" /* Declarations of FatFs API */
|
||||
#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(...)
|
||||
#define EFSPRINTF(text, ...)
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
|
@ -532,7 +530,7 @@ static WCHAR LfnBuf[FF_MAX_LFN + 1]; /* LFN working buffer */
|
|||
#define FREE_NAMBUF() ff_memfree(lfn)
|
||||
#endif
|
||||
#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
|
||||
#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 */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
@ -3921,13 +3909,12 @@ FRESULT f_read_fast (
|
|||
FATFS *fs;
|
||||
UINT csize_bytes;
|
||||
DWORD clst;
|
||||
UINT count = 0;
|
||||
DWORD wbytes;
|
||||
UINT count;
|
||||
FSIZE_t work_sector = 0;
|
||||
FSIZE_t sector_base = 0;
|
||||
BYTE *wbuff = (BYTE*)buff;
|
||||
|
||||
// TODO support sector reading inside a cluster
|
||||
|
||||
res = validate(&fp->obj, &fs); /* Check validity of the file object */
|
||||
if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) {
|
||||
EFSPRINTF("FOV");
|
||||
|
@ -3939,6 +3926,17 @@ FRESULT f_read_fast (
|
|||
if (btr > remain) btr = (UINT)remain; /* Truncate btr by remaining bytes */
|
||||
|
||||
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? */
|
||||
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 */
|
||||
else { EFSPRINTF("CLTBL"); ABORT(fs, FR_CLTBL_NO_INIT); }
|
||||
}
|
||||
|
||||
if (clst < 2) { EFSPRINTF("CCHK"); ABORT(fs, FR_INT_ERR); }
|
||||
else if (clst == 0xFFFFFFFF) { EFSPRINTF("DSKC"); ABORT(fs, FR_DISK_ERR); }
|
||||
|
||||
fp->clust = clst; /* Set working cluster */
|
||||
|
||||
wbytes = MIN(btr, csize_bytes);
|
||||
sector_base = clst2sect(fs, fp->clust);
|
||||
count += fs->csize;
|
||||
btr -= csize_bytes;
|
||||
fp->fptr += csize_bytes;
|
||||
count = wbytes / SS(fs);
|
||||
fp->fptr += wbytes;
|
||||
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) {
|
||||
clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */
|
||||
|
@ -3965,26 +3970,25 @@ FRESULT f_read_fast (
|
|||
fp->clust = clst;
|
||||
|
||||
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 {
|
||||
if (disk_read(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR);
|
||||
wbuff += count * SS(fs);
|
||||
|
||||
sector_base = work_sector;
|
||||
count = fs->csize;
|
||||
count = wbytes / SS(fs);
|
||||
}
|
||||
|
||||
fp->fptr += MIN(btr, csize_bytes);
|
||||
btr -= MIN(btr, csize_bytes);
|
||||
|
||||
// TODO: what about if data is smaller than cluster?
|
||||
// Must read-write back that cluster.
|
||||
fp->fptr += wbytes;
|
||||
btr -= wbytes;
|
||||
|
||||
if (!btr) { /* Final cluster/sectors read. */
|
||||
if (disk_read(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
LEAVE_FF(fs, FR_OK);
|
||||
}
|
||||
#endif
|
||||
|
@ -4147,12 +4151,11 @@ FRESULT f_write_fast (
|
|||
FATFS *fs;
|
||||
UINT csize_bytes;
|
||||
DWORD clst;
|
||||
UINT count = 0;
|
||||
DWORD wbytes;
|
||||
UINT count;
|
||||
FSIZE_t work_sector = 0;
|
||||
FSIZE_t sector_base = 0;
|
||||
const BYTE *wbuff = (const BYTE*)buff;
|
||||
|
||||
// TODO support sector writing inside a cluster
|
||||
BYTE *wbuff = (BYTE*)buff;
|
||||
|
||||
res = validate(&fp->obj, &fs); /* Check validity of the file object */
|
||||
if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) {
|
||||
|
@ -4167,6 +4170,19 @@ FRESULT f_write_fast (
|
|||
}
|
||||
|
||||
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? */
|
||||
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); }
|
||||
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 */
|
||||
|
||||
wbytes = MIN(btw, csize_bytes);
|
||||
sector_base = clst2sect(fs, fp->clust);
|
||||
count += fs->csize;
|
||||
btw -= csize_bytes;
|
||||
fp->fptr += csize_bytes;
|
||||
count = wbytes / SS(fs);
|
||||
fp->fptr += wbytes;
|
||||
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) {
|
||||
clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */
|
||||
|
||||
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;
|
||||
|
||||
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 {
|
||||
if (disk_write(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR);
|
||||
wbuff += count * SS(fs);
|
||||
|
||||
sector_base = work_sector;
|
||||
count = fs->csize;
|
||||
count = wbytes / SS(fs);
|
||||
}
|
||||
|
||||
fp->fptr += MIN(btw, csize_bytes);
|
||||
btw -= MIN(btw, csize_bytes);
|
||||
fp->fptr += wbytes;
|
||||
btw -= wbytes;
|
||||
|
||||
// what about if data is smaller than cluster?
|
||||
// Probably must read-write back that cluster.
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
fp->flag |= FA_MODIFIED; /* Set file change flag */
|
||||
|
||||
LEAVE_FF(fs, FR_OK);
|
||||
|
@ -4689,19 +4712,17 @@ FRESULT f_lseek (
|
|||
DWORD *f_expand_cltbl (
|
||||
FIL* fp, /* Pointer to the file object */
|
||||
UINT tblsz, /* Size of table */
|
||||
DWORD *tbl, /* Table pointer */
|
||||
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->cltbl) { /* Allocate memory for cluster link table */
|
||||
fp->cltbl = (DWORD *)ff_memalloc(tblsz);
|
||||
fp->cltbl[0] = tblsz;
|
||||
}
|
||||
fp->cltbl = (DWORD *)tbl;
|
||||
fp->cltbl[0] = tblsz;
|
||||
if (f_lseek(fp, CREATE_LINKMAP)) { /* Create cluster link table */
|
||||
ff_memfree(fp->cltbl);
|
||||
fp->cltbl = NULL;
|
||||
fp->cltbl = (void *)0;
|
||||
EFSPRINTF("CLTBLSZ");
|
||||
return NULL;
|
||||
return (void *)0;
|
||||
}
|
||||
f_lseek(fp, 0);
|
||||
|
||||
|
@ -5842,7 +5863,7 @@ FRESULT f_mkfs (
|
|||
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 */
|
||||
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) */
|
||||
|
@ -5906,7 +5927,7 @@ FRESULT f_mkfs (
|
|||
} else {
|
||||
/* Create a single-partition in this function */
|
||||
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);
|
||||
sz_vol -= b_vol; /* Volume size */
|
||||
}
|
||||
|
@ -6130,9 +6151,6 @@ FRESULT f_mkfs (
|
|||
if (fmt == FS_FAT32) { /* FAT32: Move FAT base */
|
||||
sz_rsv += n; b_fat += n;
|
||||
} else { /* FAT: Expand FAT size */
|
||||
if (n % n_fats) { /* Adjust fractional error if needed */
|
||||
n--; sz_rsv++; b_fat++;
|
||||
}
|
||||
sz_fat += n / n_fats;
|
||||
}
|
||||
|
||||
|
@ -6196,13 +6214,13 @@ FRESULT f_mkfs (
|
|||
st_word(buf + BPB_BkBootSec32, 6); /* Offset of backup VBR (VBR + 6) */
|
||||
buf[BS_DrvNum32] = 0x80; /* Drive number (for int13) */
|
||||
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 {
|
||||
st_dword(buf + BS_VolID, GET_FATTIME()); /* VSN */
|
||||
st_word(buf + BPB_FATSz16, (WORD)sz_fat); /* FAT size [sector] */
|
||||
buf[BS_DrvNum] = 0x80; /* Drive number (for int13) */
|
||||
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) */
|
||||
if (disk_write(pdrv, buf, b_vol, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Write it to the VBR sector */
|
||||
|
|
|
@ -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_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
|
||||
#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
|
||||
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 */
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
#define FF_USE_MKFS 0
|
||||
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
|
||||
|
||||
#define FF_FASTFS 0
|
||||
#define FF_FASTFS 0
|
||||
|
||||
#if FF_FASTFS
|
||||
#define FF_USE_FASTSEEK 1
|
||||
|
|
|
@ -230,6 +230,11 @@ void se_key_acc_ctrl(u32 ks, u32 flags)
|
|||
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)
|
||||
{
|
||||
u32 *data = (u32 *)key;
|
||||
|
|
|
@ -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);
|
||||
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);
|
||||
u32 se_key_acc_ctrl_get(u32 ks);
|
||||
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_key_read(u32 ks, void *key, u32 size);
|
||||
|
|
Loading…
Reference in a new issue