Fix several alignment assumptions

This commit is contained in:
d0k3 2019-05-08 00:18:34 +02:00
parent c3152838db
commit 9cc31b6f56
20 changed files with 48 additions and 36 deletions

View File

@ -2,10 +2,13 @@
#include "aes.h"
// FIXME some things make assumptions about alignemnts!
// setup_aeskey? and set_ctr do not anymore (c) d0k3
void setup_aeskeyX(uint8_t keyslot, const void* keyx)
{
const uint32_t * _keyx = (const uint32_t*)keyx;
uint32_t _keyx[4] __attribute__((aligned(32)));
for (uint32_t i = 0; i < 16u; i++)
((uint8_t*)_keyx)[i] = ((uint8_t*)keyx)[i];
*REG_AESCNT = (*REG_AESCNT) | AES_CNT_INPUT_ENDIAN | AES_CNT_INPUT_ORDER;
*REG_AESKEYCNT = (*REG_AESKEYCNT >> 6 << 6) | keyslot | 0x80;
if (keyslot > 3) {
@ -25,7 +28,10 @@ void setup_aeskeyX(uint8_t keyslot, const void* keyx)
void setup_aeskeyY(uint8_t keyslot, const void* keyy)
{
const uint32_t * _keyy = (const uint32_t*)keyy;
uint32_t _keyy[4] __attribute__((aligned(32)));
for (uint32_t i = 0; i < 16u; i++)
((uint8_t*)_keyy)[i] = ((uint8_t*)keyy)[i];
*REG_AESCNT = (*REG_AESCNT) | AES_CNT_INPUT_ENDIAN | AES_CNT_INPUT_ORDER;
*REG_AESKEYCNT = (*REG_AESKEYCNT >> 6 << 6) | keyslot | 0x80;
if (keyslot > 3) {
@ -45,7 +51,10 @@ void setup_aeskeyY(uint8_t keyslot, const void* keyy)
void setup_aeskey(uint8_t keyslot, const void* key)
{
const uint32_t * _key = (const uint32_t*)key;
uint32_t _key[4] __attribute__((aligned(32)));
for (uint32_t i = 0; i < 16u; i++)
((uint8_t*)_key)[i] = ((uint8_t*)key)[i];
*REG_AESCNT = (*REG_AESCNT) | AES_CNT_INPUT_ENDIAN | AES_CNT_INPUT_ORDER;
*REG_AESKEYCNT = (*REG_AESKEYCNT >> 6 << 6) | keyslot | 0x80;
if (keyslot > 3) {
@ -73,7 +82,10 @@ void use_aeskey(uint32_t keyno)
void set_ctr(void* iv)
{
uint32_t * _iv = (uint32_t*)iv;
uint32_t _iv[4] __attribute__((aligned(32)));
for (uint32_t i = 0; i < 16u; i++)
((uint8_t*)_iv)[i] = ((uint8_t*)iv)[i];
*REG_AESCNT = (*REG_AESCNT) | AES_CNT_INPUT_ENDIAN | AES_CNT_INPUT_ORDER;
*(REG_AESCTR + 0) = _iv[3];
*(REG_AESCTR + 1) = _iv[2];

View File

@ -24,7 +24,7 @@ typedef struct {
u8 keyUnitType; // 0 for ALL units / 1 for devkit exclusive / 2 for retail exclusive
u8 isEncrypted; // 0 if not / anything else if it is
u8 key[16];
} __attribute__((packed)) AesKeyInfo;
} __attribute__((packed)) __attribute__((aligned(16))) AesKeyInfo;
u32 GetUnitKeysType(void);
void CryptAesKeyInfo(AesKeyInfo* info);

View File

@ -18,7 +18,7 @@ static FilCryptInfo filcrypt[NUM_FILCRYPTINFO] = { 0 };
char alias_drv[NUM_ALIAS_DRV]; // 1 char ASCII drive number of the alias drive / 0x00 if unused
char alias_path[NUM_ALIAS_DRV][128]; // full path to resolve the alias into
u8 sd_keyy[NUM_ALIAS_DRV][16]; // key Y belonging to alias drive
u8 sd_keyy[NUM_ALIAS_DRV][16] __attribute__((aligned(4))); // key Y belonging to alias drive
int alias_num (const TCHAR* path) {
int num = -1;
@ -152,7 +152,7 @@ FRESULT fx_open (FIL* fp, const TCHAR* path, BYTE mode) {
} else {
// get AES counter, see: http://www.3dbrew.org/wiki/Extdata#Encryption
// path is the part of the full path after //Nintendo 3DS/<ID0>/<ID1>
u8 hashstr[256];
u8 hashstr[256] __attribute__((aligned(4)));
u8 sha256sum[32];
u32 plen = 0;
// poor man's ASCII -> UTF-16 / uppercase -> lowercase

View File

@ -4,7 +4,7 @@
// http://3dbrew.org/wiki/SpotPass#Content_Header
u32 CheckBossHash(BossHeader* boss, bool encrypted) {
u8 hash_area[0x14] = { 0 };
u8 hash_area[0x14] __attribute__((aligned(4))) = { 0 };
u8 boss_sha256[0x20];
u8 l_sha256[0x20];

View File

@ -38,7 +38,7 @@ typedef struct {
u8 ticket_padding[0x40 - (TICKET_SIZE % 0x40)];
TitleMetaData tmd;
TmdContentChunk content_list[TMD_MAX_CONTENTS];
} __attribute__((packed)) CiaStub;
} __attribute__((packed, aligned(16))) CiaStub;
typedef struct { // first 0x20 bytes are identical with CIA header
u32 size_header;

View File

@ -13,6 +13,6 @@ typedef struct {
ExeFsFileHeader files[10];
u8 reserved[0x20];
u8 hashes[10][0x20];
} __attribute__((packed)) ExeFsHeader;
} __attribute__((packed, aligned(16))) ExeFsHeader;
u32 ValidateExeFsHeader(ExeFsHeader* exefs, u32 size);

View File

@ -29,7 +29,7 @@ u32 ValidateAgbSaveHeader(AgbSaveHeader* header) {
// http://problemkaputt.de/gbatek.htm#gbacartridgeheader
u32 ValidateAgbHeader(AgbHeader* agb) {
const u8 logo_sha[0x20] = { AGBLOGO_SHA256 };
u8 logo[0x9C];
u8 logo[0x9C] __attribute__((aligned(4)));
// check fixed value
if (agb->fixed != 0x96) return 1;

View File

@ -86,7 +86,7 @@ typedef struct {
u8 checksum; // header checksum, required
u8 reserved[2]; // always 0x00
// stuff for multiboot not included
} __attribute__((packed)) AgbHeader;
} __attribute__((packed, aligned(16))) AgbHeader;
u32 ValidateAgbSaveHeader(AgbSaveHeader* header);

View File

@ -52,7 +52,7 @@ u32 GetNcchCtr(u8* ctr, NcchHeader* ncch, u8 section) {
}
u32 GetNcchSeed(u8* seed, NcchHeader* ncch) {
static u8 lseed[16+8] = { 0 }; // seed plus title ID for easy validation
static u8 lseed[16+8] __attribute__((aligned(4))) = { 0 }; // seed plus title ID for easy validation
u64 titleId = ncch->programId;
u32 hash_seed = ncch->hash_seed;
u32 sha256sum[8];
@ -175,7 +175,7 @@ u32 SetNcchKey(NcchHeader* ncch, u16 crypto, u32 keyid) {
static u8 lsignature[16] = { 0 };
static u64 ltitleId = 0;
if ((memcmp(lsignature, ncch->signature, 16) != 0) || (ltitleId != ncch->programId)) {
u8 keydata[16+16];
u8 keydata[16+16] __attribute__((aligned(4)));
memcpy(keydata, ncch->signature, 16);
if (GetNcchSeed(keydata + 16, ncch) != 0)
return 1;

View File

@ -54,7 +54,7 @@ typedef struct {
u64 aci_limit_title_id;
u32 aci_limit_core_version;
u8 aci_limit_data[0x200 - 0xC];
} __attribute__((packed)) NcchExtHeader;
} __attribute__((packed, aligned(16))) NcchExtHeader;
// see: https://www.3dbrew.org/wiki/NCCH#NCCH_Header
typedef struct {

View File

@ -41,7 +41,7 @@ typedef struct {
u8 reserved3[2];
u8 timelimits[0x40];
u8 content_index[0xAC];
} __attribute__((packed)) Ticket;
} __attribute__((packed, aligned(4))) Ticket;
u32 ValidateTicket(Ticket* ticket);
u32 ValidateTicketSignature(Ticket* ticket);

View File

@ -54,7 +54,7 @@ u32 GetTitleKey(u8* titlekey, Ticket* ticket) {
Ticket* TicketFromTickDbChunk(u8* chunk, u8* title_id, bool legit_pls) {
// chunk must be aligned to 0x200 byte in file and at least 0x400 byte big
Ticket* tick = (Ticket*) (chunk + 0x18);
Ticket* tick = (Ticket*) (void*) (chunk + 0x18);
if ((getle32(chunk + 0x10) == 0) || (getle32(chunk + 0x14) != sizeof(Ticket))) return NULL;
if (ValidateTicket(tick) != 0) return NULL; // ticket not validated
if (title_id && (memcmp(title_id, tick->title_id, 8) != 0)) return NULL; // title id not matching

View File

@ -22,13 +22,13 @@ typedef struct {
u8 type[2];
u8 size[8];
u8 hash[0x20];
} __attribute__((packed)) TmdContentChunk;
} __attribute__((packed, aligned(4))) TmdContentChunk;
typedef struct {
u8 index[2];
u8 cmd_count[2];
u8 hash[0x20];
} __attribute__((packed)) TmdContentInfo;
} __attribute__((packed, aligned(4))) TmdContentInfo;
typedef struct {
u8 sig_type[4];
@ -55,7 +55,7 @@ typedef struct {
u8 reserved3[2];
u8 contentinfo_hash[0x20];
TmdContentInfo contentinfo[64];
} __attribute__((packed)) TitleMetaData;
} __attribute__((packed, aligned(4))) TitleMetaData;
u32 ValidateTmd(TitleMetaData* tmd);
u32 ValidateTmdSignature(TitleMetaData* tmd);

View File

@ -17,7 +17,7 @@ typedef struct {
u8 signature[0x100];
u8 unknown[0x8]; // normally zero
u8 codeseed[0x8]; // the actual data
} __attribute__((packed)) LocalFriendCodeSeed;
} __attribute__((packed, aligned(4))) LocalFriendCodeSeed;
// /private/movable.sed file
// see: http://3dbrew.org/wiki/Nand/private/movable.sed
@ -28,7 +28,7 @@ typedef struct {
u8 keyy_high[8];
u8 unknown[0x10];
u8 cmac[0x10];
} __attribute__((packed)) MovableSed;
} __attribute__((packed, aligned(4))) MovableSed;
// /rw/sys/SecureInfo_A (/_B) file
// see: http://3dbrew.org/wiki/Nandrw/sys/SecureInfo_A
@ -37,7 +37,7 @@ typedef struct {
u8 region;
u8 unknown;
char serial[0xF];
} __attribute__((packed)) SecureInfo;
} __attribute__((packed, aligned(4))) SecureInfo;
// includes all essential system files
// (this is of our own making)
@ -58,4 +58,4 @@ typedef struct {
u8 padding_hwcal0[0x200 - (SIZE_HWCAL%0x200)];
u8 hwcal1[SIZE_HWCAL];
u8 padding_hwcal1[0x200 - (SIZE_HWCAL%0x200)];
} __attribute__((packed)) EssentialBackup;
} __attribute__((packed, aligned(16))) EssentialBackup;

View File

@ -26,7 +26,7 @@ static const u32 np_keyslots[10][4] = { // [NP_TYPE][NP_SUBTYPE]
{ 0xFF, 0xFF, 0xFF, 0xFF } // BONUS (custom)
};
static u8 slot0x05KeyY[0x10] = { 0x00 }; // need to load this from FIRM0 / external file
static u8 slot0x05KeyY[0x10] __attribute__((aligned(4))) = { 0x00 }; // need to load this from FIRM0 / external file
static const u8 slot0x05KeyY_sha256[0x20] = { // hash for slot0x05KeyY (16 byte)
0x98, 0x24, 0x27, 0x14, 0x22, 0xB0, 0x6B, 0xF2, 0x10, 0x96, 0x9C, 0x36, 0x42, 0x53, 0x7C, 0x86,
0x62, 0x22, 0x5C, 0xFD, 0x6F, 0xAE, 0x9B, 0x0A, 0x85, 0xA5, 0xCE, 0x21, 0xAA, 0xB6, 0xC8, 0x4D
@ -195,7 +195,7 @@ bool CheckSlot0x05Crypto(void)
bool CheckSector0x96Crypto(void)
{
if (!Crypto0x96) {
u8 buffer[0x200];
u8 buffer[0x200] __attribute__((aligned(4)));
ReadNandSectors(buffer, SECTOR_SECRET, 1, 0x11, NAND_SYSNAND);
Crypto0x96 = (sha_cmp(KEY95_SHA256, buffer, 16, SHA256_MODE) == 0);
}
@ -213,7 +213,7 @@ bool CheckGenuineNandNcsd(void)
0xA4, 0xBD, 0x25, 0x03, 0x06, 0x03, 0x47, 0x0B, 0x24, 0x5A, 0x86, 0x6A, 0x43, 0x60, 0xBC, 0x84,
};
u8 gen_hdr[0x100];
u8 gen_hdr[0x100] __attribute__((aligned(4)));
if ((ReadNandBytes(gen_hdr, 0x100, 0x100, 0xFF, NAND_SYSNAND) != 0) ||
(ReadNandBytes(gen_hdr + 0xBE, 0x1BE, 0x42, 0x03, NAND_SYSNAND) != 0))
return false;

View File

@ -2403,7 +2403,7 @@ u32 BuildSeedInfo(const char* path, bool dump) {
char path_str[128];
if (path_in && (strnlen(path_in, 16) == 2)) { // when only a drive is given...
// grab the key Y from movable.sed
u8 movable_keyy[16];
u8 movable_keyy[16] __attribute__((aligned(4)));
snprintf(path_str, 128, "%s/private/movable.sed", path_in);
if (fvx_qread(path_str, movable_keyy, 0x110, 0x10, NULL) != FR_OK)
return 1;

View File

@ -160,7 +160,7 @@ u32 CalculateFileCmac(const char* path, u8* cmac) {
else if (!cmac_type) return 1;
const u32 cmac_keyslot[] = { CMAC_KEYSLOT };
u8 hashdata[0x200];
u8 hashdata[0x200] __attribute__((aligned(4)));
u32 keyslot = cmac_keyslot[cmac_type];
u32 hashsize = 0;
@ -247,7 +247,7 @@ u32 FixFileCmac(const char* path) {
u32 FixAgbSaveCmac(void* data, u8* cmac, const char* sddrv) {
AgbSaveHeader* agbsave = (AgbSaveHeader*) (void*) data;
u8 temp[0x30]; // final hash @temp+0x00
u8 temp[0x30] __attribute__((aligned(4))); // final hash @temp+0x00
// safety check
if (ValidateAgbSaveHeader(agbsave) != 0)

View File

@ -527,7 +527,7 @@ u32 SafeInstallFirmBuffered(const char* path, u32 slots, u8* buffer, u32 bufsiz)
}
// check sector 0x96 on N3DS, offer fix if required
u8 sector0x96[0x200];
u8 sector0x96[0x200] __attribute__((aligned(4)));
bool fix_sector0x96 = false;
ReadNandSectors(sector0x96, 0x96, 1, 0x11, NAND_SYSNAND);
if (!IS_O3DS && !CheckSector0x96Crypto()) {
@ -605,7 +605,7 @@ u32 SafeInstallFirm(const char* path, u32 slots) {
u32 SafeInstallKeyDb(const char* path) {
const u8 perfect_sha[] = { KEYDB_PERFECT_HASH };
u8 keydb[KEYDB_PERFECT_SIZE];
u8 keydb[KEYDB_PERFECT_SIZE] __attribute__((aligned(4)));
char pathstr[32 + 1]; // truncated path string
TruncateString(pathstr, path, 32, 8);

View File

@ -402,7 +402,7 @@ void upd_var(const char* name) {
if (!name || (strncmp(name, env_id0_name, _VAR_NAME_LEN) == 0)) {
const char* path = emu ? "4:/private/movable.sed" : "1:/private/movable.sed";
char env_id0[32+1];
u8 sd_keyy[0x10];
u8 sd_keyy[0x10] __attribute__((aligned(4)));
if (FileGetData(path, sd_keyy, 0x10, 0x110) == 0x10) {
u32 sha256sum[8];
sha_quick(sha256sum, sd_keyy, 0x10, SHA256_MODE);

View File

@ -93,7 +93,7 @@ bool ReadVNandDir(VirtualFile* vfile, VirtualDir* vdir) { // uses a generic vdir
}
if (vfile->flags & VFLAG_KEYDB) {
const u8 perfect_sha[] = { KEYDB_PERFECT_HASH };
u8 keydb[KEYDB_PERFECT_SIZE];
u8 keydb[KEYDB_PERFECT_SIZE] __attribute__((aligned(4)));
ReadNandBytes(keydb, vfile->offset, KEYDB_PERFECT_SIZE, vfile->keyslot, nand_src);
if (sha_cmp(perfect_sha, keydb, KEYDB_PERFECT_SIZE, SHA256_MODE) != 0) continue;
vfile->size = KEYDB_PERFECT_SIZE;