#include "std/unused.h"
#include "firm/fcram.h"
-#include "firm/crypto.h"
#include "firm/headers.h"
#include "patch_format.h"
+++ /dev/null
-// From http://github.com/b1l1s/ctr
-
-#include "crypto.h"
-
-#include <stddef.h>
-#include "../std/memory.h"
-/* original version by megazig */
-
-#ifndef __thumb__
-#define BSWAP32(x) \
- { \
- __asm__("eor r1, %1, %1, ror #16\n\t" \
- "bic r1, r1, #0xFF0000\n\t" \
- "mov %0, %1, ror #8\n\t" \
- "eor %0, %0, r1, lsr #8\n\t" \
- : "=r"(x) \
- : "0"(x) \
- : "r1"); \
- };
-
-#define ADD_u128_uint32_t(u128_0, u128_1, u128_2, u128_3, uint32_t_0) \
- { \
- __asm__("adds %0, %4\n\t" \
- "addcss %1, %1, #1\n\t" \
- "addcss %2, %2, #1\n\t" \
- "addcs %3, %3, #1\n\t" \
- : "+r"(u128_0), "+r"(u128_1), "+r"(u128_2), "+r"(u128_3) \
- : "r"(uint32_t_0) \
- : "cc"); \
- }
-#else
-#define BSWAP32(x) \
- { \
- x = __builtin_bswap32(x); \
- }
-
-#define ADD_u128_uint32_t(u128_0, u128_1, u128_2, u128_3, uint32_t_0) \
- { \
- __asm__("mov r4, #0\n\t" \
- "add %0, %0, %4\n\t" \
- "adc %1, %1, r4\n\t" \
- "adc %2, %2, r4\n\t" \
- "adc %3, %3, r4\n\t" \
- : "+r"(u128_0), "+r"(u128_1), "+r"(u128_2), "+r"(u128_3) \
- : "r"(uint32_t_0) \
- : "cc", "r4"); \
- }
-#endif /*__thumb__*/
-
-void
-aes_setkey(uint8_t keyslot, const void *key, uint32_t keyType, uint32_t mode)
-{
- if (keyslot <= 0x03)
- return; // Ignore TWL keys for now
-
- uint32_t *key32 = (uint32_t *)key;
- *REG_AESCNT = (*REG_AESCNT & ~(AES_CNT_INPUT_ENDIAN | AES_CNT_INPUT_ORDER)) | mode;
- *REG_AESKEYCNT = (*REG_AESKEYCNT >> 6 << 6) | keyslot | AES_KEYCNT_WRITE;
-
- REG_AESKEYFIFO[keyType] = key32[0];
- REG_AESKEYFIFO[keyType] = key32[1];
- REG_AESKEYFIFO[keyType] = key32[2];
- REG_AESKEYFIFO[keyType] = key32[3];
-}
-
-void
-aes_use_keyslot(uint8_t keyslot)
-{
- if (keyslot > 0x3F)
- return;
-
- *REG_AESKEYSEL = keyslot;
- *REG_AESCNT = *REG_AESCNT | 0x04000000; /* mystery bit */
-}
-
-void
-aes_setiv(const void *iv, uint32_t mode)
-{
- const uint32_t *iv32 = (const uint32_t *)iv;
- *REG_AESCNT = (*REG_AESCNT & ~(AES_CNT_INPUT_ENDIAN | AES_CNT_INPUT_ORDER)) | mode;
-
- // Word order for IV can't be changed in REG_AESCNT and always default to
- // reversed
- if (mode & AES_INPUT_NORMAL) {
- REG_AESCTR[0] = iv32[3];
- REG_AESCTR[1] = iv32[2];
- REG_AESCTR[2] = iv32[1];
- REG_AESCTR[3] = iv32[0];
- } else {
- REG_AESCTR[0] = iv32[0];
- REG_AESCTR[1] = iv32[1];
- REG_AESCTR[2] = iv32[2];
- REG_AESCTR[3] = iv32[3];
- }
-}
-
-void
-aes_advctr(void *ctr, uint32_t val, uint32_t mode)
-{
- uint32_t *ctr32 = (uint32_t *)ctr;
-
- int i;
- if (mode & AES_INPUT_BE) {
- for (i = 0; i < 4; ++i) // Endian swap
- BSWAP32(ctr32[i]);
- }
-
- if (mode & AES_INPUT_NORMAL) {
- ADD_u128_uint32_t(ctr32[3], ctr32[2], ctr32[1], ctr32[0], val);
- } else {
- ADD_u128_uint32_t(ctr32[0], ctr32[1], ctr32[2], ctr32[3], val);
- }
-
- if (mode & AES_INPUT_BE) {
- for (i = 0; i < 4; ++i) // Endian swap
- BSWAP32(ctr32[i]);
- }
-}
-
-void
-aes_change_ctrmode(void *ctr, uint32_t fromMode, uint32_t toMode)
-{
- uint32_t *ctr32 = (uint32_t *)ctr;
- int i;
- if ((fromMode ^ toMode) & AES_CNT_INPUT_ENDIAN) {
- for (i = 0; i < 4; ++i)
- BSWAP32(ctr32[i]);
- }
-
- if ((fromMode ^ toMode) & AES_CNT_INPUT_ORDER) {
- uint32_t temp = ctr32[0];
- ctr32[0] = ctr32[3];
- ctr32[3] = temp;
-
- temp = ctr32[1];
- ctr32[1] = ctr32[2];
- ctr32[2] = temp;
- }
-}
-
-void
-aes_batch(void *dst, const void *src, uint32_t blockCount)
-{
- *REG_AESBLKCNT = blockCount << 16;
- *REG_AESCNT |= AES_CNT_START;
-
- const uint32_t *src32 = (const uint32_t *)src;
- uint32_t *dst32 = (uint32_t *)dst;
-
- uint32_t wbc = blockCount;
- uint32_t rbc = blockCount;
-
- while (rbc) {
- if (wbc && ((*REG_AESCNT & 0x1F) <= 0xC)) // There's space for at least 4 ints
- {
- *REG_AESWRFIFO = *src32++;
- *REG_AESWRFIFO = *src32++;
- *REG_AESWRFIFO = *src32++;
- *REG_AESWRFIFO = *src32++;
- wbc--;
- }
-
- if (rbc && ((*REG_AESCNT & (0x1F << 0x5)) >= (0x4 << 0x5))) // At least 4 ints available for read
- {
- *dst32++ = *REG_AESRDFIFO;
- *dst32++ = *REG_AESRDFIFO;
- *dst32++ = *REG_AESRDFIFO;
- *dst32++ = *REG_AESRDFIFO;
- rbc--;
- }
- }
-}
-
-inline void
-aes_setmode(uint32_t mode)
-{
- *REG_AESCNT = mode | AES_CNT_INPUT_ORDER | AES_CNT_OUTPUT_ORDER | AES_CNT_INPUT_ENDIAN | AES_CNT_OUTPUT_ENDIAN | AES_CNT_FLUSH_READ | AES_CNT_FLUSH_WRITE;
-}
-
-void
-aes(void *dst, const void *src, uint32_t blockCount, void *iv, uint32_t mode, uint32_t ivMode)
-{
- aes_setmode(mode);
-
- uint32_t blocks;
- while (blockCount != 0) {
- if ((mode & AES_ALL_MODES) != AES_ECB_ENCRYPT_MODE && (mode & AES_ALL_MODES) != AES_ECB_DECRYPT_MODE)
- aes_setiv(iv, ivMode);
-
- blocks = (blockCount >= 0xFFFF) ? 0xFFFF : blockCount;
-
- // Save the last block for the next decryption CBC batch's iv
- if ((mode & AES_ALL_MODES) == AES_CBC_DECRYPT_MODE) {
- memcpy(iv, src + (blocks - 1) * AES_BLOCK_SIZE, AES_BLOCK_SIZE);
- aes_change_ctrmode(iv, AES_INPUT_BE | AES_INPUT_NORMAL, ivMode);
- }
-
- // Process the current batch
- aes_batch(dst, src, blocks);
-
- // Save the last block for the next encryption CBC batch's iv
- if ((mode & AES_ALL_MODES) == AES_CBC_ENCRYPT_MODE) {
- memcpy(iv, dst + (blocks - 1) * AES_BLOCK_SIZE, AES_BLOCK_SIZE);
- aes_change_ctrmode(iv, AES_INPUT_BE | AES_INPUT_NORMAL, ivMode);
- }
-
- // Advance counter for CTR mode
- else if ((mode & AES_ALL_MODES) == AES_CTR_MODE)
- aes_advctr(iv, blocks, ivMode);
-
- src += blocks * AES_BLOCK_SIZE;
- dst += blocks * AES_BLOCK_SIZE;
- blockCount -= blocks;
- }
-}
-
-void
-ncch_getctr(const ncch_h *ncch, uint8_t *ctr, uint8_t type)
-{
- uint32_t version = ncch->version;
- const uint8_t *partitionID = ncch->partitionID;
-
- int i;
- for (i = 0; i < 16; i++)
- ctr[i] = 0x00;
-
- if (version == 2 || version == 0) {
- for (i = 0; i < 8; i++)
- ctr[i] = partitionID[7 - i]; // Convert to big endian & normal input
- ctr[8] = type;
- } else if (version == 1) {
- int x = 0;
- if (type == NCCHTYPE_EXHEADER)
- x = MEDIA_UNITS;
- else if (type == NCCHTYPE_EXEFS)
- x = ncch->exeFSOffset * MEDIA_UNITS;
- else if (type == NCCHTYPE_ROMFS)
- x = ncch->exeFSOffset * MEDIA_UNITS;
-
- for (i = 0; i < 8; i++)
- ctr[i] = partitionID[i];
- for (i = 0; i < 4; i++)
- ctr[i + 12] = (x >> ((3 - i) * 8)) & 0xFF;
- }
-}
-
-void
-sha_wait_idle()
-{
- while (*REG_SHA_CNT & 1)
- ;
-}
-
-void
-sha(void *res, const void *src, uint32_t size, uint32_t mode)
-{
- sha_wait_idle();
- *REG_SHA_CNT = mode | SHA_CNT_OUTPUT_ENDIAN | SHA_NORMAL_ROUND;
-
- const uint32_t *src32 = (const uint32_t *)src;
- int i;
- while (size >= 0x40) {
- sha_wait_idle();
- for (i = 0; i < 4; ++i) {
- *REG_SHA_INFIFO = *src32++;
- *REG_SHA_INFIFO = *src32++;
- *REG_SHA_INFIFO = *src32++;
- *REG_SHA_INFIFO = *src32++;
- }
-
- size -= 0x40;
- }
-
- sha_wait_idle();
- memcpy((void *)REG_SHA_INFIFO, src32, size);
-
- *REG_SHA_CNT = (*REG_SHA_CNT & ~SHA_NORMAL_ROUND) | SHA_FINAL_ROUND;
-
- while (*REG_SHA_CNT & SHA_FINAL_ROUND)
- ;
- sha_wait_idle();
-
- uint32_t hashSize = SHA_256_HASH_SIZE;
- if (mode == SHA_224_MODE)
- hashSize = SHA_224_HASH_SIZE;
- else if (mode == SHA_1_MODE)
- hashSize = SHA_1_HASH_SIZE;
-
- memcpy(res, (void *)REG_SHA_HASH, hashSize);
-}
-
-void
-rsa_wait_idle()
-{
- while (*REG_RSA_CNT & 1)
- ;
-}
-
-void
-rsa_use_keyslot(uint32_t keyslot)
-{
- *REG_RSA_CNT = (*REG_RSA_CNT & ~RSA_CNT_KEYSLOTS) | (keyslot << 4);
-}
-
-void
-rsa_setkey(uint32_t keyslot, const void *mod, const void *exp, uint32_t mode)
-{
- rsa_wait_idle();
- *REG_RSA_CNT = (*REG_RSA_CNT & ~RSA_CNT_KEYSLOTS) | (keyslot << 4) | RSA_IO_BE | RSA_IO_NORMAL;
-
- uint32_t size = mode * 4;
-
- volatile uint32_t *keyslotCnt = REG_RSA_SLOT0 + (keyslot << 4);
- keyslotCnt[0] &= ~(RSA_SLOTCNT_KEY_SET | RSA_SLOTCNT_WPROTECT);
- keyslotCnt[1] = mode;
-
- memcpy((void *)REG_RSA_MOD_END - size, mod, size);
-
- if (exp == NULL) {
- size -= 4;
- while (size) {
- *REG_RSA_EXPFIFO = 0;
- size -= 4;
- }
- *REG_RSA_EXPFIFO = 0x01000100; // 0x00010001 byteswapped
- } else {
- const uint32_t *exp32 = (const uint32_t *)exp;
- while (size) {
- *REG_RSA_EXPFIFO = *exp32++;
- size -= 4;
- }
- }
-}
-
-int
-rsa_iskeyset(uint32_t keyslot)
-{
- return *(REG_RSA_SLOT0 + (keyslot << 4)) & 1;
-}
-
-void
-rsa(void *dst, const void *src, uint32_t size)
-{
- uint32_t keyslot = (*REG_RSA_CNT & RSA_CNT_KEYSLOTS) >> 4;
- if (rsa_iskeyset(keyslot) == 0)
- return;
-
- rsa_wait_idle();
- *REG_RSA_CNT |= RSA_IO_BE | RSA_IO_NORMAL;
-
- // Pad the message with zeroes so that it's a multiple of 8
- // and write the message with the end aligned with the register
- uint32_t padSize = ((size + 7) & ~7) - size;
- memset((void *)REG_RSA_TXT_END - (size + padSize), 0, padSize);
- memcpy((void *)REG_RSA_TXT_END - size, src, size);
-
- // Start
- *REG_RSA_CNT |= RSA_CNT_START;
-
- rsa_wait_idle();
- memcpy(dst, (void *)REG_RSA_TXT_END - size, size);
-}
-
-int
-rsa_verify(const void *data, uint32_t size, const void *sig, uint32_t mode)
-{
- uint8_t dataHash[SHA_256_HASH_SIZE];
- sha(dataHash, data, size, SHA_256_MODE);
-
- uint8_t decSig[0x100]; // Way too big, need to request a work area
-
- uint32_t sigSize = mode * 4;
- rsa(decSig, sig, sigSize);
-
- return memcmp(dataHash, decSig + (sigSize - SHA_256_HASH_SIZE), SHA_256_HASH_SIZE) == 0;
-}
+++ /dev/null
-// From http://github.com/b1l1s/ctr
-
-#ifndef __CRYPTO_H
-#define __CRYPTO_H
-
-#include <stdint.h>
-#include "headers.h"
-
-/**************************AES****************************/
-#define REG_AESCNT ((volatile uint32_t *)0x10009000)
-#define REG_AESBLKCNT ((volatile uint32_t *)0x10009004)
-#define REG_AESWRFIFO ((volatile uint32_t *)0x10009008)
-#define REG_AESRDFIFO ((volatile uint32_t *)0x1000900C)
-#define REG_AESKEYSEL ((volatile uint8_t *)0x10009010)
-#define REG_AESKEYCNT ((volatile uint8_t *)0x10009011)
-#define REG_AESCTR ((volatile uint32_t *)0x10009020)
-
-#define REG_AESKEYFIFO ((volatile uint32_t *)0x10009100)
-#define REG_AESKEYXFIFO ((volatile uint32_t *)0x10009104)
-#define REG_AESKEYYFIFO ((volatile uint32_t *)0x10009108)
-
-#define AES_CCM_DECRYPT_MODE (0u << 27)
-#define AES_CCM_ENCRYPT_MODE (1u << 27)
-#define AES_CTR_MODE (2u << 27)
-#define AES_CTR_MODE (2u << 27)
-#define AES_CBC_DECRYPT_MODE (4u << 27)
-#define AES_CBC_ENCRYPT_MODE (5u << 27)
-#define AES_ECB_DECRYPT_MODE (6u << 27)
-#define AES_ECB_ENCRYPT_MODE (7u << 27)
-#define AES_ALL_MODES (7u << 27)
-
-#define AES_CNT_START 0x80000000
-#define AES_CNT_INPUT_ORDER 0x02000000
-#define AES_CNT_OUTPUT_ORDER 0x01000000
-#define AES_CNT_INPUT_ENDIAN 0x00800000
-#define AES_CNT_OUTPUT_ENDIAN 0x00400000
-#define AES_CNT_FLUSH_READ 0x00000800
-#define AES_CNT_FLUSH_WRITE 0x00000400
-
-#define AES_INPUT_BE (AES_CNT_INPUT_ENDIAN)
-#define AES_INPUT_LE 0
-#define AES_INPUT_NORMAL (AES_CNT_INPUT_ORDER)
-#define AES_INPUT_REVERSED 0
-
-#define AES_TEMP_KEYSLOT 0x11
-
-#define AES_BLOCK_SIZE 0x10
-
-#define AES_KEYCNT_WRITE (1 << 0x7)
-#define AES_KEYNORMAL 0
-#define AES_KEYX 1
-#define AES_KEYY 2
-
-/**************************SHA****************************/
-#define REG_SHA_CNT ((volatile uint32_t *)0x1000A000)
-#define REG_SHA_BLKCNT ((volatile uint32_t *)0x1000A004)
-#define REG_SHA_HASH ((volatile uint32_t *)0x1000A040)
-#define REG_SHA_INFIFO ((volatile uint32_t *)0x1000A080)
-
-#define SHA_CNT_STATE 0x00000003
-#define SHA_CNT_UNK2 0x00000004
-#define SHA_CNT_OUTPUT_ENDIAN 0x00000008
-#define SHA_CNT_MODE 0x00000030
-#define SHA_CNT_ENABLE 0x00010000
-#define SHA_CNT_ACTIVE 0x00020000
-
-#define SHA_HASH_READY 0x00000000
-#define SHA_NORMAL_ROUND 0x00000001
-#define SHA_FINAL_ROUND 0x00000002
-
-#define SHA_OUTPUT_BE SHA_CNT_OUTPUT_ENDIAN
-#define SHA_OUTPUT_LE 0
-
-#define SHA_256_MODE 0
-#define SHA_224_MODE 0x00000010
-#define SHA_1_MODE 0x00000020
-
-#define SHA_256_HASH_SIZE (256 / 8)
-#define SHA_224_HASH_SIZE (224 / 8)
-#define SHA_1_HASH_SIZE (160 / 8)
-
-/**************************RSA****************************/
-#define REG_RSA_CNT ((volatile uint32_t *)0x1000B000)
-#define REG_RSA_SLOT0 ((volatile uint32_t *)0x1000B100)
-#define REG_RSA_SLOT1 ((volatile uint32_t *)0x1000B110)
-#define REG_RSA_SLOT2 ((volatile uint32_t *)0x1000B120)
-#define REG_RSA_SLOT3 ((volatile uint32_t *)0x1000B130)
-#define REG_RSA_EXPFIFO ((volatile uint32_t *)0x1000B200)
-#define REG_RSA_MOD_END ((volatile uint32_t *)0x1000B500)
-#define REG_RSA_TXT_END ((volatile uint32_t *)0x1000B900)
-
-#define RSA_CNT_START 0x00000001
-#define RSA_CNT_KEYSLOTS 0x000000F0
-#define RSA_CNT_IO_ENDIAN 0x00000100
-#define RSA_CNT_IO_ORDER 0x00000200
-
-#define RSA_SLOTCNT_KEY_SET 0x00000001
-#define RSA_SLOTCNT_WPROTECT 0x00000002 // Write protect
-
-#define RSA_IO_BE RSA_CNT_IO_ENDIAN
-#define RSA_IO_LE 0
-#define RSA_IO_NORMAL RSA_CNT_IO_ORDER
-#define RSA_IO_REVERSED 0
-
-#define RSA_TEMP_KEYSLOT 0
-
-#define RSA_1024_MODE 0x20
-#define RSA_2048_MODE 0x40
-
-void aes_setkey(uint8_t keyslot, const void *key, uint32_t keyType, uint32_t mode);
-void aes_use_keyslot(uint8_t keyslot);
-
-void aes(void *dst, const void *src, uint32_t blockCount, void *iv, uint32_t mode, uint32_t ivMode);
-
-void aes_setiv(const void *iv, uint32_t mode);
-void aes_advctr(void *ctr, uint32_t val, uint32_t mode);
-void aes_change_ctrmode(void *ctr, uint32_t fromMode, uint32_t toMode);
-
-void aes_batch(void *dst, const void *src, uint32_t blockCount);
-
-void sha(void *res, const void *src, uint32_t size, uint32_t mode);
-
-void rsa_setkey(uint32_t keyslot, const void *mod, const void *exp, uint32_t mode);
-void rsa_use_keyslot(uint32_t keyslot);
-
-int rsa_verify(const void *data, uint32_t size, const void *sig, uint32_t mode);
-
-typedef enum {
- NCCHTYPE_EXHEADER = 1,
- NCCHTYPE_EXEFS = 2,
- NCCHTYPE_ROMFS = 3,
-} ctr_ncchtypes;
-
-void ncch_getctr(const ncch_h *ncch, uint8_t *ctr, uint8_t type);
-
-#endif
void *static_allocate(size_t bytes) {
size_t aligned_bytes = bytes + (4 - (bytes % 4)); // Align to integer size (for ARM processor)
void *ret = fcram_static_mem;
- fcram_static_mem += aligned_bytes;
+ fcram_static_mem = (uint8_t*)fcram_static_mem + aligned_bytes;
return ret;
}
#include <stdint.h>
#include <stddef.h>
+#include <ctr9/io.h>
+#include <ctr9/aes.h>
+
#include "../common.h"
#include "../misc/sha256.h"
static volatile uint32_t *const a11_entry = (volatile uint32_t *)0x1FFFFFF8;
+typedef enum {
+ NCCHTYPE_EXHEADER = 1,
+ NCCHTYPE_EXEFS = 2,
+ NCCHTYPE_ROMFS = 3,
+} ctr_ncchtypes;
+
+void
+ncch_getctr(const ncch_h *ncch, uint8_t *ctr, uint8_t type)
+{
+ uint32_t version = ncch->version;
+ const uint8_t *partitionID = ncch->partitionID;
+ int i;
+
+ for (i = 0; i < 16; i++)
+ ctr[i] = 0x00;
+
+ if (version == 2 || version == 0) {
+ for (i = 0; i < 8; i++)
+ ctr[i] = partitionID[7 - i]; // Convert to big endian & normal input
+ ctr[8] = type;
+ } else if (version == 1) {
+ int x = 0;
+ if (type == NCCHTYPE_EXHEADER)
+ x = MEDIA_UNITS;
+ else if (type == NCCHTYPE_EXEFS)
+ x = ncch->exeFSOffset * MEDIA_UNITS;
+ else if (type == NCCHTYPE_ROMFS)
+ x = ncch->exeFSOffset * MEDIA_UNITS;
+ for (i = 0; i < 8; i++)
+ ctr[i] = partitionID[i];
+ for (i = 0; i < 4; i++)
+ ctr[i + 12] = (x >> ((3 - i) * 8)) & 0xFF;
+ }
+}
+
+void
+aes(void *dst, const void *src, uint32_t blockCount, void *iv, uint32_t mode, uint32_t ivMode)
+{
+ set_ctr(iv);
+}
+
void
slot0x11key96_init()
{
uint8_t key[AES_BLOCK_SIZE];
if (read_file(key, PATH_SLOT0X11KEY96, AES_BLOCK_SIZE) != 0 || read_file(key, PATH_ALT_SLOT0X11KEY96, AES_BLOCK_SIZE) != 0) {
// Read key successfully.
- aes_setkey(0x11, key, AES_KEYNORMAL, AES_INPUT_BE | AES_INPUT_NORMAL);
+ setup_aeskey(0x11, key);
// Tell boot_firm it needs to regenerate the keys.
update_96_keys = 1;
if (sigtype != SIG_TYPE_RSA2048_SHA256)
return 1;
- ticket_h *ticket = (ticket_h *)(cetk + sizeof(sigtype) + 0x13C);
+ ticket_h *ticket = (ticket_h *)((uint8_t*)cetk + sizeof(sigtype) + 0x13C);
if (ticket->ticketCommonKeyYIndex != 1)
return 1;
if (i < p9_base)
return 1;
- aes_setkey(0x3D, common_key_y, AES_KEYY, AES_INPUT_BE | AES_INPUT_NORMAL);
+ setup_aeskeyY(0x3D, common_key_y);
common_key_y_init = 1;
}
- aes_use_keyslot(0x3D);
+ use_aeskey(0x3D);
memcpy(iv, ticket->titleID, sizeof(ticket->titleID));
memcpy(key, ticket->titleKey, sizeof(ticket->titleKey));
uint8_t exefs_iv[16] = { 0 };
fprintf(BOTTOM_SCREEN, "n");
- aes_setkey(0x16, key, AES_KEYNORMAL, AES_INPUT_BE | AES_INPUT_NORMAL);
- aes_use_keyslot(0x16);
+ setup_aeskey(0x16, key);
+ use_aeskey(0x16);
aes(ncch, ncch, *size / AES_BLOCK_SIZE, firm_iv, AES_CBC_DECRYPT_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
if (ncch->magic != NCCH_MAGIC)
ncch_getctr(ncch, exefs_iv, NCCHTYPE_EXEFS);
// Get the exefs offset and size from the NCCH
- exefs_h *exefs = (exefs_h *)((void *)ncch + ncch->exeFSOffset * MEDIA_UNITS);
+ exefs_h *exefs = (exefs_h *)((uint8_t *)ncch + ncch->exeFSOffset * MEDIA_UNITS);
uint32_t exefs_size = ncch->exeFSSize * MEDIA_UNITS;
fprintf(BOTTOM_SCREEN, "e");
- aes_setkey(0x2C, exefs_key, AES_KEYY, AES_INPUT_BE | AES_INPUT_NORMAL);
- aes_use_keyslot(0x2C);
+ setup_aeskeyY(0x2C, exefs_key);
+ use_aeskey(0x2C);
aes(exefs, exefs, exefs_size / AES_BLOCK_SIZE, exefs_iv, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
// Get the decrypted FIRM
slot0x11key96_init();
slot = 0x16;
- aes_use_keyslot(0x11);
+ use_aeskey(0x11);
aes(decrypted_keyx, header->slot0x16keyX, 1, NULL, AES_ECB_DECRYPT_MODE, 0);
- aes_setkey(slot, decrypted_keyx, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL);
+ setup_aeskeyX(slot, decrypted_keyx);
}
- aes_setkey(slot, header->keyy, AES_KEYY, AES_INPUT_BE | AES_INPUT_NORMAL);
- aes_setiv(header->ctr, AES_INPUT_BE | AES_INPUT_NORMAL);
+ setup_aeskeyY(slot, header->keyy);
+ set_ctr(header->ctr);
void *arm9bin = (uint8_t *)header + 0x800;
int size = atoi(header->size);
- aes_use_keyslot(slot);
+ use_aeskey(slot);
aes(arm9bin, arm9bin, size / AES_BLOCK_SIZE, header->ctr, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
if (firm_title == NATIVE_FIRM_TITLEID)
// depending on which firmware you're booting from.
// TODO: Don't use the hardcoded offset.
if (update_96_keys && fsig->console == console_n3ds && fsig->version > 0x0F) {
- void *keydata = find_section_key();
+ uint8_t *keydata = find_section_key();
if (!keydata) {
abort("Couldn't find key!\n");
}
wait();
- aes_use_keyslot(0x11);
+ use_aeskey(0x11);
uint8_t keyx[AES_BLOCK_SIZE];
for (int slot = 0x19; slot < 0x20; slot++) {
aes(keyx, keydata, 1, NULL, AES_ECB_DECRYPT_MODE, 0);
- aes_setkey(slot, keyx, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL);
+ setup_aeskeyX(slot, keyx);
*(uint8_t *)(keydata + 0xF) += 1;
}
}
for (firm_section_h *section = firm_loc->section; section < firm_loc->section + 4 && section->address != 0; section++) {
- memcpy((void *)section->address, (void *)firm_loc + section->offset, section->size);
+ memcpy((void *)section->address, (void *)((uint8_t*)firm_loc + section->offset), section->size);
}
fprintf(BOTTOM_SCREEN, "Copied FIRM\n");
break;
if (section->type == FIRM_TYPE_ARM9) {
- void *arm9section = (void *)firm + section->offset;
+ uint8_t *arm9section = (uint8_t *)firm + section->offset;
while (arm9section < arm9section + section->size) {
if (!memcmp(arm9section, "Process9", 8)) { // Process9
- ncch_h *ncch = (ncch_h *)(arm9section - sizeof(ncch_h));
+ ncch_h *ncch = (ncch_h *)((uint8_t*)arm9section - sizeof(ncch_h));
if (ncch->magic == NCCH_MAGIC) {
// Found Process9
ncch_ex_h *p9exheader = (ncch_ex_h *)(ncch + 1);
*p9exefs = (exefs_h *)(p9exheader + 1);
process9->address = p9exheader->sci.textCodeSet.address;
process9->size = (*p9exefs)->fileHeaders[0].size;
- process9->offset = (void *)((*p9exefs) + 1) - (void *)firm;
+ process9->offset = ((uint32_t)((*p9exefs) + 1) - (uint32_t)firm);
fprintf(BOTTOM_SCREEN, "p");
return 0;
}
memmove(void *dest, const void *src, size_t size)
{
// memcpy does the job of moving backwards just fine
- if (dest < src || src + size <= dest) {
- return memcpy(dest, src, size);
+ if (dest < src || (uint8_t*)src + size <= (uint8_t*)dest) {
+ memcpy(dest, src, size);
+ return;
}
// Moving forward is just a reverse memcpy