From 201fe05a067db9539aa867fa5d5f282e6d168dce Mon Sep 17 00:00:00 2001 From: Aurora Date: Sun, 4 Sep 2016 00:36:39 +0200 Subject: [PATCH] Implement selectable PIN size, added support for the directional pad in PINs --- injector/source/patcher.c | 2 +- source/buttons.h | 2 +- source/config.c | 6 +++++- source/crypto.c | 7 +++---- source/crypto.h | 2 +- source/pin.c | 43 ++++++++++++++++++++++----------------- source/pin.h | 4 ++-- 7 files changed, 37 insertions(+), 29 deletions(-) diff --git a/injector/source/patcher.c b/injector/source/patcher.c index 46f68fd..348f925 100644 --- a/injector/source/patcher.c +++ b/injector/source/patcher.c @@ -440,7 +440,7 @@ void patchCode(u64 progId, u8 *code, u32 size) sizeof(stopCartUpdatesPatch), 2 ); - u32 cpuSetting = MULTICONFIG(1); + u32 cpuSetting = MULTICONFIG(2); if(cpuSetting) { diff --git a/source/buttons.h b/source/buttons.h index 83f9a04..7c85fff 100644 --- a/source/buttons.h +++ b/source/buttons.h @@ -43,4 +43,4 @@ #define SINGLE_PAYLOAD_BUTTONS (BUTTON_LEFT | BUTTON_RIGHT | BUTTON_UP | BUTTON_DOWN | BUTTON_START | BUTTON_X | BUTTON_Y) #define L_PAYLOAD_BUTTONS (BUTTON_R1 | BUTTON_A | BUTTON_SELECT) #define MENU_BUTTONS (BUTTON_LEFT | BUTTON_RIGHT | BUTTON_UP | BUTTON_DOWN | BUTTON_A | BUTTON_START) -#define PIN_BUTTONS (BUTTON_A | BUTTON_B | BUTTON_X | BUTTON_Y | BUTTON_START) \ No newline at end of file +#define PIN_BUTTONS (BUTTON_A | BUTTON_B | BUTTON_X | BUTTON_Y | BUTTON_LEFT | BUTTON_RIGHT | BUTTON_UP | BUTTON_DOWN | BUTTON_START) \ No newline at end of file diff --git a/source/config.c b/source/config.c index 262add0..cb70d84 100644 --- a/source/config.c +++ b/source/config.c @@ -72,6 +72,7 @@ void configMenu(bool oldPinStatus) drawString("Press A to select, START to save", 10, 30, COLOR_WHITE); const char *multiOptionsText[] = { "Screen brightness: 4( ) 3( ) 2( ) 1( )", + "PIN length: 4( ) 5( ) 6( ) 7( )", "New 3DS CPU: Off( ) Clock( ) L2( ) Clock+L2( )" }; const char *singleOptionsText[] = { "( ) Autoboot SysNAND", @@ -89,6 +90,7 @@ void configMenu(bool oldPinStatus) u32 enabled; } multiOptions[] = { { .posXs = {21, 26, 31, 36} }, + { .posXs = {14, 19, 24, 29} }, { .posXs = {17, 26, 32, 44} } }; @@ -221,6 +223,8 @@ void configMenu(bool oldPinStatus) } } + u32 oldPinLength = MULTICONFIG(1); + //Preserve the last-used boot options (last 12 bits) configData.config &= 0x3F; @@ -230,7 +234,7 @@ void configMenu(bool oldPinStatus) for(u32 i = 0; i < singleOptionsAmount; i++) configData.config |= (singleOptions[i].enabled ? 1 : 0) << (i + 16); - if(CONFIG(7)) newPin(oldPinStatus); + if(CONFIG(7)) newPin(oldPinStatus && MULTICONFIG(1) == oldPinLength); else if(oldPinStatus) fileDelete(PIN_PATH); //Wait for the pressed buttons to change diff --git a/source/crypto.c b/source/crypto.c index e6a4751..30f4b5f 100755 --- a/source/crypto.c +++ b/source/crypto.c @@ -457,14 +457,13 @@ void arm9Loader(u8 *arm9Section) } } -void computePinHash(u8 *out, u8 *in, u32 blockCount) +void computePinHash(u8 *out, u8 *in) { u8 __attribute__((aligned(4))) cid[0x10]; u8 __attribute__((aligned(4))) cipherText[0x10]; + sdmmc_get_cid(1, (u32 *)cid); - aes_use_keyslot(4); //Console-unique keyslot whose keys are set by the ARM9 bootROM - aes(cipherText, in, blockCount, cid, AES_CBC_ENCRYPT_MODE, AES_INPUT_BE | AES_INPUT_NORMAL); - + aes(cipherText, in, 1, cid, AES_CBC_ENCRYPT_MODE, AES_INPUT_BE | AES_INPUT_NORMAL); sha(out, cipherText, 0x10, SHA_256_MODE); } \ No newline at end of file diff --git a/source/crypto.h b/source/crypto.h index c7221c8..be2d3b4 100755 --- a/source/crypto.h +++ b/source/crypto.h @@ -108,4 +108,4 @@ u32 ctrNandRead(u32 sector, u32 sectorCount, u8 *outbuf); void setRSAMod0DerivedKeys(void); void decryptExeFs(u8 *inbuf); void arm9Loader(u8 *arm9Section); -void computePinHash(u8 *out, u8 *in, u32 blockCount); \ No newline at end of file +void computePinHash(u8 *out, u8 *in); \ No newline at end of file diff --git a/source/pin.c b/source/pin.c index 8b30d75..b8e2bd1 100644 --- a/source/pin.c +++ b/source/pin.c @@ -26,6 +26,7 @@ */ #include "draw.h" +#include "config.h" #include "screen.h" #include "utils.h" #include "memory.h" @@ -36,7 +37,7 @@ static char pinKeyToLetter(u32 pressed) { - const char keys[] = "AB--------XY"; + const char keys[] = "AB--RLUD--XY"; u32 i; for(i = 31; pressed > 1; i--) pressed /= 2; @@ -53,12 +54,13 @@ void newPin(bool allowSkipping) drawString("PIN: ", 10, 10 + 2 * SPACING_Y, COLOR_WHITE); //Pad to AES block length with zeroes - u8 __attribute__((aligned(4))) enteredPassword[16 * ((PIN_LENGTH + 15) / 16)] = {0}; + u8 __attribute__((aligned(4))) enteredPassword[0x10] = {0}; - u32 cnt = 0; + u8 length = 4 + MULTICONFIG(1), + cnt = 0; int charDrawPos = 5 * SPACING_X; - while(cnt < PIN_LENGTH) + while(cnt < length) { u32 pressed; do @@ -82,18 +84,20 @@ void newPin(bool allowSkipping) } PINData pin; - u8 __attribute__((aligned(4))) tmp[32]; - u8 __attribute__((aligned(4))) zeroes[16] = {0}; memcpy(pin.magic, "PINF", 4); pin.formatVersionMajor = PIN_VERSIONMAJOR; pin.formatVersionMinor = PIN_VERSIONMINOR; + pin.length = length; - computePinHash(tmp, zeroes, 1); - memcpy(pin.testHash, tmp, 32); + u8 __attribute__((aligned(4))) tmp[0x20]; + u8 __attribute__((aligned(4))) zeroes[0x10] = {0}; - computePinHash(tmp, enteredPassword, (PIN_LENGTH + 15) / 16); - memcpy(pin.hash, tmp, 32); + computePinHash(tmp, zeroes); + memcpy(pin.testHash, tmp, sizeof(tmp)); + + computePinHash(tmp, enteredPassword); + memcpy(pin.hash, tmp, sizeof(tmp)); if(!fileWrite(&pin, PIN_PATH, sizeof(PINData))) error("Error writing the PIN file"); @@ -108,21 +112,22 @@ bool verifyPin(void) if(fileRead(&pin, PIN_PATH) != sizeof(PINData) || memcmp(pin.magic, "PINF", 4) != 0 || pin.formatVersionMajor != PIN_VERSIONMAJOR || - pin.formatVersionMinor != PIN_VERSIONMINOR) + pin.formatVersionMinor != PIN_VERSIONMINOR || + pin.length != 4 + MULTICONFIG(1)) return false; - u8 __attribute__((aligned(4))) zeroes[16] = {0}; - u8 __attribute__((aligned(4))) tmp[32]; + u8 __attribute__((aligned(4))) zeroes[0x10] = {0}; + u8 __attribute__((aligned(4))) tmp[0x20]; - computePinHash(tmp, zeroes, 1); + computePinHash(tmp, zeroes); //Test vector verification (SD card has, or hasn't been used on another console) if(memcmp(pin.testHash, tmp, 32) != 0) return false; //Pad to AES block length with zeroes - u8 __attribute__((aligned(4))) enteredPassword[16 * ((PIN_LENGTH + 15) / 16)] = {0}; + u8 __attribute__((aligned(4))) enteredPassword[0x10] = {0}; - u32 cnt = 0; + u8 cnt = 0; bool unlock = false; int charDrawPos = 5 * SPACING_X; @@ -151,10 +156,10 @@ bool verifyPin(void) drawCharacter(key, 10 + charDrawPos, 10 + 2 * SPACING_Y, COLOR_WHITE); charDrawPos += 2 * SPACING_X; - if(cnt >= PIN_LENGTH) + if(cnt >= pin.length) { - computePinHash(tmp, enteredPassword, (PIN_LENGTH + 15) / 16); - unlock = memcmp(pin.hash, tmp, 32) == 0; + computePinHash(tmp, enteredPassword); + unlock = memcmp(pin.hash, tmp, sizeof(tmp)) == 0; if(!unlock) { diff --git a/source/pin.h b/source/pin.h index 65acd14..831882e 100644 --- a/source/pin.h +++ b/source/pin.h @@ -30,16 +30,16 @@ #include "types.h" -#define PIN_LENGTH 4 #define PIN_PATH "/luma/pin.bin" #define PIN_VERSIONMAJOR 1 -#define PIN_VERSIONMINOR 0 +#define PIN_VERSIONMINOR 1 typedef struct __attribute__((packed)) { char magic[4]; u16 formatVersionMajor, formatVersionMinor; + u8 length; u8 testHash[32]; u8 hash[32]; } PINData;