From: chaoskagami Date: Sat, 9 Jul 2016 04:58:05 +0000 (-0400) Subject: Crypto changes X-Git-Tag: v0.2.0~26 X-Git-Url: https://chaos.moe/g/?a=commitdiff_plain;h=8cac9b4584fd0c3af268d0893bc5c58b4e11044e;p=corbenik%2Fcorbenik.git Crypto changes --- diff --git a/source/common.h b/source/common.h index 46eedd1..4113dda 100644 --- a/source/common.h +++ b/source/common.h @@ -9,7 +9,6 @@ #include "std/unused.h" #include "firm/fcram.h" -#include "firm/crypto.h" #include "firm/headers.h" #include "patch_format.h" diff --git a/source/firm/crypto.c b/source/firm/crypto.c deleted file mode 100644 index 67d8e86..0000000 --- a/source/firm/crypto.c +++ /dev/null @@ -1,376 +0,0 @@ -// From http://github.com/b1l1s/ctr - -#include "crypto.h" - -#include -#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; -} diff --git a/source/firm/crypto.h b/source/firm/crypto.h deleted file mode 100644 index baa33f6..0000000 --- a/source/firm/crypto.h +++ /dev/null @@ -1,136 +0,0 @@ -// From http://github.com/b1l1s/ctr - -#ifndef __CRYPTO_H -#define __CRYPTO_H - -#include -#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 diff --git a/source/firm/fcram.c b/source/firm/fcram.c index 1949451..7b81b32 100644 --- a/source/firm/fcram.c +++ b/source/firm/fcram.c @@ -6,6 +6,6 @@ void *fcram_static_mem = (void*)FCRAM_STATIC_ALLOC_LOC; 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; } diff --git a/source/firm/firm.c b/source/firm/firm.c index 78d0b9f..b33e4bd 100644 --- a/source/firm/firm.c +++ b/source/firm/firm.c @@ -3,6 +3,9 @@ #include #include +#include +#include + #include "../common.h" #include "../misc/sha256.h" @@ -25,6 +28,47 @@ static int update_96_keys = 0; 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() { @@ -33,7 +77,7 @@ 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; @@ -54,7 +98,7 @@ decrypt_cetk_key(void *key, const void *cetk) 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; @@ -76,11 +120,11 @@ decrypt_cetk_key(void *key, const void *cetk) 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)); @@ -99,8 +143,8 @@ decrypt_firm_title(firm_h *dest, ncch_h *ncch, uint32_t *size, void *key) 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) @@ -110,12 +154,12 @@ decrypt_firm_title(firm_h *dest, ncch_h *ncch, uint32_t *size, void *key) 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 @@ -145,18 +189,18 @@ decrypt_arm9bin(arm9bin_h *header, uint64_t firm_title, uint8_t version) 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) @@ -337,18 +381,18 @@ boot_firm() // 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; } @@ -356,7 +400,7 @@ boot_firm() } 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"); @@ -387,17 +431,17 @@ find_proc9(firm_h *firm, firm_section_h *process9, exefs_h **p9exefs) 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; } diff --git a/source/std/memory.c b/source/std/memory.c index aab59c2..bb33b68 100644 --- a/source/std/memory.c +++ b/source/std/memory.c @@ -46,8 +46,9 @@ void 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