Merge pull request #1725 from GriffinRichards/security-signature

Sector security -> signature
This commit is contained in:
GriffinR 2022-08-12 10:47:10 -04:00 committed by GitHub
commit 574cf1ddb9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 56 additions and 54 deletions

View File

@ -9,8 +9,8 @@
#define NUM_SAVE_SLOTS 2
// If the sector's security field is not this value then the sector is either invalid or empty.
#define SECTOR_SECURITY_NUM 0x8012025
// If the sector's signature field is not this value then the sector is either invalid or empty.
#define SECTOR_SIGNATURE 0x8012025
#define SPECIAL_SECTOR_SENTINEL 0xB39D
@ -72,12 +72,12 @@ struct SaveSector
u8 unused[SECTOR_FOOTER_SIZE - 12]; // Unused portion of the footer
u16 id;
u16 checksum;
u32 security;
u32 signature;
u32 counter;
}; // size is SECTOR_SIZE (0x1000)
#define SECTOR_SECURITY_OFFSET offsetof(struct SaveSector, security)
#define SECTOR_COUNTER_OFFSET offsetof(struct SaveSector, counter)
#define SECTOR_SIGNATURE_OFFSET offsetof(struct SaveSector, signature)
#define SECTOR_COUNTER_OFFSET offsetof(struct SaveSector, counter)
extern u16 gLastWrittenSector;
extern u32 gLastSaveCounter;
@ -99,7 +99,7 @@ u8 TrySavingData(u8 saveType);
bool8 LinkFullSave_Init(void);
bool8 LinkFullSave_WriteSector(void);
bool8 LinkFullSave_ReplaceLastSector(void);
bool8 LinkFullSave_SetLastSectorSecurity(void);
bool8 LinkFullSave_SetLastSectorSignature(void);
bool8 WriteSaveBlock2(void);
bool8 WriteSaveBlock1Sector(void);
u8 LoadGameSave(u8 saveType);

View File

@ -15,7 +15,8 @@
#include "constants/items.h"
#include "constants/trainer_hill.h"
STATIC_ASSERT(sizeof(struct TrainerHillChallenge) <= SECTOR_DATA_SIZE, TrainerHillChallengeFreeSpace);
// Save data using TryWriteSpecialSaveSector is allowed to exceed SECTOR_DATA_SIZE (up to the counter field)
STATIC_ASSERT(sizeof(struct TrainerHillChallenge) <= SECTOR_COUNTER_OFFSET, TrainerHillChallengeFreeSpace);
struct SendRecvMgr
{

View File

@ -67,7 +67,8 @@ struct RecordedBattleSave
u32 checksum;
};
STATIC_ASSERT(sizeof(struct RecordedBattleSave) <= SECTOR_DATA_SIZE, RecordedBattleSaveFreeSpace);
// Save data using TryWriteSpecialSaveSector is allowed to exceed SECTOR_DATA_SIZE (up to the counter field)
STATIC_ASSERT(sizeof(struct RecordedBattleSave) <= SECTOR_COUNTER_OFFSET, RecordedBattleSaveFreeSpace);
EWRAM_DATA u32 gRecordedBattleRngSeed = 0;
EWRAM_DATA u32 gBattlePalaceMoveSelectionRngValue = 0;

View File

@ -196,7 +196,7 @@ static u8 HandleWriteSector(u16 sectorId, const struct SaveSectorLocation *locat
// Set footer data
gReadWriteSector->id = sectorId;
gReadWriteSector->security = SECTOR_SECURITY_NUM;
gReadWriteSector->signature = SECTOR_SIGNATURE;
gReadWriteSector->counter = gSaveCounter;
// Copy current data to temp buffer for writing
@ -217,7 +217,7 @@ static u8 HandleWriteSectorNBytes(u8 sectorId, u8 *data, u16 size)
for (i = 0; i < SECTOR_SIZE; i++)
((u8 *)sector)[i] = 0;
sector->security = SECTOR_SECURITY_NUM;
sector->signature = SECTOR_SIGNATURE;
// Copy data to temp buffer for writing
for (i = 0; i < size; i++)
@ -306,7 +306,7 @@ static u8 HandleReplaceSectorAndVerify(u16 sectorId, const struct SaveSectorLoca
return status;
}
// Similar to HandleWriteSector, but fully erases the sector first, and skips writing the first security byte
// Similar to HandleWriteSector, but fully erases the sector first, and skips writing the first signature byte
static u8 HandleReplaceSector(u16 sectorId, const struct SaveSectorLocation *locations)
{
u16 i;
@ -330,7 +330,7 @@ static u8 HandleReplaceSector(u16 sectorId, const struct SaveSectorLocation *loc
// Set footer data
gReadWriteSector->id = sectorId;
gReadWriteSector->security = SECTOR_SECURITY_NUM;
gReadWriteSector->signature = SECTOR_SIGNATURE;
gReadWriteSector->counter = gSaveCounter;
// Copy current data to temp buffer for writing
@ -344,8 +344,8 @@ static u8 HandleReplaceSector(u16 sectorId, const struct SaveSectorLocation *loc
status = SAVE_STATUS_OK;
// Write new save data up to security field
for (i = 0; i < SECTOR_SECURITY_OFFSET; i++)
// Write new save data up to signature field
for (i = 0; i < SECTOR_SIGNATURE_OFFSET; i++)
{
if (ProgramFlashByte(sector, i, ((u8 *)gReadWriteSector)[i]))
{
@ -362,14 +362,14 @@ static u8 HandleReplaceSector(u16 sectorId, const struct SaveSectorLocation *loc
}
else
{
// Writing save data succeeded, write security and counter
// Writing save data succeeded, write signature and counter
status = SAVE_STATUS_OK;
// Write security (skipping the first byte) and counter fields.
// The byte of security that is skipped is instead written by WriteSectorSecurityByte or WriteSectorSecurityByte_NoOffset
for (i = 0; i < SECTOR_SIZE - (SECTOR_SECURITY_OFFSET + 1); i++)
// Write signature (skipping the first byte) and counter fields.
// The byte of signature that is skipped is instead written by WriteSectorSignatureByte or WriteSectorSignatureByte_NoOffset
for (i = 0; i < SECTOR_SIZE - (SECTOR_SIGNATURE_OFFSET + 1); i++)
{
if (ProgramFlashByte(sector, SECTOR_SECURITY_OFFSET + 1 + i, ((u8 *)gReadWriteSector)[SECTOR_SECURITY_OFFSET + 1 + i]))
if (ProgramFlashByte(sector, SECTOR_SIGNATURE_OFFSET + 1 + i, ((u8 *)gReadWriteSector)[SECTOR_SIGNATURE_OFFSET + 1 + i]))
{
status = SAVE_STATUS_ERROR;
break;
@ -378,7 +378,7 @@ static u8 HandleReplaceSector(u16 sectorId, const struct SaveSectorLocation *loc
if (status == SAVE_STATUS_ERROR)
{
// Writing security/counter failed
// Writing signature/counter failed
SetDamagedSectorBits(ENABLE, sector);
return SAVE_STATUS_ERROR;
}
@ -391,16 +391,16 @@ static u8 HandleReplaceSector(u16 sectorId, const struct SaveSectorLocation *loc
}
}
static u8 WriteSectorSecurityByte_NoOffset(u16 sectorId, const struct SaveSectorLocation *locations)
static u8 WriteSectorSignatureByte_NoOffset(u16 sectorId, const struct SaveSectorLocation *locations)
{
// Adjust sector id for current save slot
// This first line lacking -1 is the only difference from WriteSectorSecurityByte
// This first line lacking -1 is the only difference from WriteSectorSignatureByte
u16 sector = sectorId + gLastWrittenSector;
sector %= NUM_SECTORS_PER_SLOT;
sector += NUM_SECTORS_PER_SLOT * (gSaveCounter % NUM_SAVE_SLOTS);
// Write just the first byte of the security field, which was skipped by HandleReplaceSector
if (ProgramFlashByte(sector, SECTOR_SECURITY_OFFSET, SECTOR_SECURITY_NUM & 0xFF))
// Write just the first byte of the signature field, which was skipped by HandleReplaceSector
if (ProgramFlashByte(sector, SECTOR_SIGNATURE_OFFSET, SECTOR_SIGNATURE & 0xFF))
{
// Sector is damaged, so enable the bit in gDamagedSaveSectors and restore the last written sector and save counter.
SetDamagedSectorBits(ENABLE, sector);
@ -416,15 +416,15 @@ static u8 WriteSectorSecurityByte_NoOffset(u16 sectorId, const struct SaveSector
}
}
static u8 CopySectorSecurityByte(u16 sectorId, const struct SaveSectorLocation *locations)
static u8 CopySectorSignatureByte(u16 sectorId, const struct SaveSectorLocation *locations)
{
// Adjust sector id for current save slot
u16 sector = sectorId + gLastWrittenSector - 1;
sector %= NUM_SECTORS_PER_SLOT;
sector += NUM_SECTORS_PER_SLOT * (gSaveCounter % NUM_SAVE_SLOTS);
// Copy just the first byte of the security field from the read/write buffer
if (ProgramFlashByte(sector, SECTOR_SECURITY_OFFSET, ((u8 *)gReadWriteSector)[SECTOR_SECURITY_OFFSET]))
// Copy just the first byte of the signature field from the read/write buffer
if (ProgramFlashByte(sector, SECTOR_SIGNATURE_OFFSET, ((u8 *)gReadWriteSector)[SECTOR_SIGNATURE_OFFSET]))
{
// Sector is damaged, so enable the bit in gDamagedSaveSectors and restore the last written sector and save counter.
SetDamagedSectorBits(ENABLE, sector);
@ -440,15 +440,15 @@ static u8 CopySectorSecurityByte(u16 sectorId, const struct SaveSectorLocation *
}
}
static u8 WriteSectorSecurityByte(u16 sectorId, const struct SaveSectorLocation *locations)
static u8 WriteSectorSignatureByte(u16 sectorId, const struct SaveSectorLocation *locations)
{
// Adjust sector id for current save slot
u16 sector = sectorId + gLastWrittenSector - 1;
sector %= NUM_SECTORS_PER_SLOT;
sector += NUM_SECTORS_PER_SLOT * (gSaveCounter % NUM_SAVE_SLOTS);
// Write just the first byte of the security field, which was skipped by HandleReplaceSector
if (ProgramFlashByte(sector, SECTOR_SECURITY_OFFSET, SECTOR_SECURITY_NUM & 0xFF))
// Write just the first byte of the signature field, which was skipped by HandleReplaceSector
if (ProgramFlashByte(sector, SECTOR_SIGNATURE_OFFSET, SECTOR_SIGNATURE & 0xFF))
{
// Sector is damaged, so enable the bit in gDamagedSaveSectors and restore the last written sector and save counter.
SetDamagedSectorBits(ENABLE, sector);
@ -500,8 +500,8 @@ static u8 CopySaveSlotData(u16 sectorId, struct SaveSectorLocation *locations)
checksum = CalculateChecksum(gReadWriteSector->data, locations[id].size);
// Only copy data for sectors whose security and checksum fields are correct
if (gReadWriteSector->security == SECTOR_SECURITY_NUM && gReadWriteSector->checksum == checksum)
// Only copy data for sectors whose signature and checksum fields are correct
if (gReadWriteSector->signature == SECTOR_SIGNATURE && gReadWriteSector->checksum == checksum)
{
u16 j;
for (j = 0; j < locations[id].size; j++)
@ -519,7 +519,7 @@ static u8 GetSaveValidStatus(const struct SaveSectorLocation *locations)
u32 saveSlot1Counter = 0;
u32 saveSlot2Counter = 0;
u32 validSectorFlags = 0;
bool8 securityPassed = FALSE;
bool8 signatureValid = FALSE;
u8 saveSlot1Status;
u8 saveSlot2Status;
@ -527,9 +527,9 @@ static u8 GetSaveValidStatus(const struct SaveSectorLocation *locations)
for (i = 0; i < NUM_SECTORS_PER_SLOT; i++)
{
ReadFlashSector(i, gReadWriteSector);
if (gReadWriteSector->security == SECTOR_SECURITY_NUM)
if (gReadWriteSector->signature == SECTOR_SIGNATURE)
{
securityPassed = TRUE;
signatureValid = TRUE;
checksum = CalculateChecksum(gReadWriteSector->data, locations[gReadWriteSector->id].size);
if (gReadWriteSector->checksum == checksum)
{
@ -539,7 +539,7 @@ static u8 GetSaveValidStatus(const struct SaveSectorLocation *locations)
}
}
if (securityPassed)
if (signatureValid)
{
if (validSectorFlags == (1 << NUM_SECTORS_PER_SLOT) - 1)
saveSlot1Status = SAVE_STATUS_OK;
@ -548,20 +548,20 @@ static u8 GetSaveValidStatus(const struct SaveSectorLocation *locations)
}
else
{
// No sectors in slot 1 have the security number, treat it as empty
// No sectors in slot 1 have the correct signature, treat it as empty
saveSlot1Status = SAVE_STATUS_EMPTY;
}
validSectorFlags = 0;
securityPassed = FALSE;
signatureValid = FALSE;
// Check save slot 2
for (i = 0; i < NUM_SECTORS_PER_SLOT; i++)
{
ReadFlashSector(i + NUM_SECTORS_PER_SLOT, gReadWriteSector);
if (gReadWriteSector->security == SECTOR_SECURITY_NUM)
if (gReadWriteSector->signature == SECTOR_SIGNATURE)
{
securityPassed = TRUE;
signatureValid = TRUE;
checksum = CalculateChecksum(gReadWriteSector->data, locations[gReadWriteSector->id].size);
if (gReadWriteSector->checksum == checksum)
{
@ -571,7 +571,7 @@ static u8 GetSaveValidStatus(const struct SaveSectorLocation *locations)
}
}
if (securityPassed)
if (signatureValid)
{
if (validSectorFlags == (1 << NUM_SECTORS_PER_SLOT) - 1)
saveSlot2Status = SAVE_STATUS_OK;
@ -580,7 +580,7 @@ static u8 GetSaveValidStatus(const struct SaveSectorLocation *locations)
}
else
{
// No sectors in slot 2 have the security number, treat it as empty.
// No sectors in slot 2 have the correct signature, treat it as empty.
saveSlot2Status = SAVE_STATUS_EMPTY;
}
@ -642,12 +642,12 @@ static u8 TryLoadSaveSector(u8 sectorId, u8 *data, u16 size)
u16 i;
struct SaveSector *sector = &gSaveDataBuffer;
ReadFlashSector(sectorId, sector);
if (sector->security == SECTOR_SECURITY_NUM)
if (sector->signature == SECTOR_SIGNATURE)
{
u16 checksum = CalculateChecksum(sector->data, size);
if (sector->id == checksum)
{
// Security and checksum are correct, copy data
// Signature and checksum are correct, copy data
for (i = 0; i < size; i++)
data[i] = sector->data[i];
return SAVE_STATUS_OK;
@ -660,7 +660,7 @@ static u8 TryLoadSaveSector(u8 sectorId, u8 *data, u16 size)
}
else
{
// Incorrect security value
// Incorrect signature value
return SAVE_STATUS_EMPTY;
}
}
@ -747,7 +747,7 @@ u8 HandleSavingData(u8 saveType)
for(i = SECTOR_ID_SAVEBLOCK2; i <= SECTOR_ID_SAVEBLOCK1_END; i++)
HandleReplaceSector(i, gRamSaveSectorLocations);
for(i = SECTOR_ID_SAVEBLOCK2; i <= SECTOR_ID_SAVEBLOCK1_END; i++)
WriteSectorSecurityByte_NoOffset(i, gRamSaveSectorLocations);
WriteSectorSignatureByte_NoOffset(i, gRamSaveSectorLocations);
break;
case SAVE_OVERWRITE_DIFFERENT_FILE:
// Erase Hall of Fame
@ -818,9 +818,9 @@ bool8 LinkFullSave_ReplaceLastSector(void)
return FALSE;
}
bool8 LinkFullSave_SetLastSectorSecurity(void)
bool8 LinkFullSave_SetLastSectorSignature(void)
{
CopySectorSecurityByte(NUM_SECTORS_PER_SLOT, gRamSaveSectorLocations);
CopySectorSignatureByte(NUM_SECTORS_PER_SLOT, gRamSaveSectorLocations);
if (gDamagedSaveSectors)
DoSaveFailedScreen(SAVE_NORMAL);
return FALSE;
@ -852,14 +852,14 @@ bool8 WriteSaveBlock1Sector(void)
{
// Write a single sector of SaveBlock1
HandleReplaceSectorAndVerify(gIncrementalSectorId + 1, gRamSaveSectorLocations);
WriteSectorSecurityByte(sectorId, gRamSaveSectorLocations);
WriteSectorSignatureByte(sectorId, gRamSaveSectorLocations);
}
else
{
// Beyond SaveBlock1, don't write the sector.
// Does write 1 byte of the next sector's security field, but as these
// Does write 1 byte of the next sector's signature field, but as these
// are the same for all valid sectors it doesn't matter.
WriteSectorSecurityByte(sectorId, gRamSaveSectorLocations);
WriteSectorSignatureByte(sectorId, gRamSaveSectorLocations);
finished = TRUE;
}
@ -1030,7 +1030,7 @@ void Task_LinkFullSave(u8 taskId)
case 8:
if (IsLinkTaskFinished())
{
LinkFullSave_SetLastSectorSecurity();
LinkFullSave_SetLastSectorSignature();
tState = 9;
}
break;

View File

@ -4708,7 +4708,7 @@ static void CB2_SaveAndEndTrade(void)
case 42:
if (_IsLinkTaskFinished())
{
LinkFullSave_SetLastSectorSecurity();
LinkFullSave_SetLastSectorSignature();
gMain.state = 5;
}
break;
@ -5012,7 +5012,7 @@ static void CB2_SaveAndEndWirelessTrade(void)
case 8:
if (_IsLinkTaskFinished())
{
LinkFullSave_SetLastSectorSecurity();
LinkFullSave_SetLastSectorSignature();
gMain.state = 9;
}
break;