Implement selectable PIN size, added support for the directional pad in PINs

This commit is contained in:
Aurora 2016-09-04 00:36:39 +02:00
parent 5cd1a207c9
commit 201fe05a06
7 changed files with 37 additions and 29 deletions

View File

@ -440,7 +440,7 @@ void patchCode(u64 progId, u8 *code, u32 size)
sizeof(stopCartUpdatesPatch), 2 sizeof(stopCartUpdatesPatch), 2
); );
u32 cpuSetting = MULTICONFIG(1); u32 cpuSetting = MULTICONFIG(2);
if(cpuSetting) if(cpuSetting)
{ {

View File

@ -43,4 +43,4 @@
#define SINGLE_PAYLOAD_BUTTONS (BUTTON_LEFT | BUTTON_RIGHT | BUTTON_UP | BUTTON_DOWN | BUTTON_START | BUTTON_X | BUTTON_Y) #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 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 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) #define PIN_BUTTONS (BUTTON_A | BUTTON_B | BUTTON_X | BUTTON_Y | BUTTON_LEFT | BUTTON_RIGHT | BUTTON_UP | BUTTON_DOWN | BUTTON_START)

View File

@ -72,6 +72,7 @@ void configMenu(bool oldPinStatus)
drawString("Press A to select, START to save", 10, 30, COLOR_WHITE); drawString("Press A to select, START to save", 10, 30, COLOR_WHITE);
const char *multiOptionsText[] = { "Screen brightness: 4( ) 3( ) 2( ) 1( )", const char *multiOptionsText[] = { "Screen brightness: 4( ) 3( ) 2( ) 1( )",
"PIN length: 4( ) 5( ) 6( ) 7( )",
"New 3DS CPU: Off( ) Clock( ) L2( ) Clock+L2( )" }; "New 3DS CPU: Off( ) Clock( ) L2( ) Clock+L2( )" };
const char *singleOptionsText[] = { "( ) Autoboot SysNAND", const char *singleOptionsText[] = { "( ) Autoboot SysNAND",
@ -89,6 +90,7 @@ void configMenu(bool oldPinStatus)
u32 enabled; u32 enabled;
} multiOptions[] = { } multiOptions[] = {
{ .posXs = {21, 26, 31, 36} }, { .posXs = {21, 26, 31, 36} },
{ .posXs = {14, 19, 24, 29} },
{ .posXs = {17, 26, 32, 44} } { .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) //Preserve the last-used boot options (last 12 bits)
configData.config &= 0x3F; configData.config &= 0x3F;
@ -230,7 +234,7 @@ void configMenu(bool oldPinStatus)
for(u32 i = 0; i < singleOptionsAmount; i++) for(u32 i = 0; i < singleOptionsAmount; i++)
configData.config |= (singleOptions[i].enabled ? 1 : 0) << (i + 16); 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); else if(oldPinStatus) fileDelete(PIN_PATH);
//Wait for the pressed buttons to change //Wait for the pressed buttons to change

View File

@ -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))) cid[0x10];
u8 __attribute__((aligned(4))) cipherText[0x10]; u8 __attribute__((aligned(4))) cipherText[0x10];
sdmmc_get_cid(1, (u32 *)cid); sdmmc_get_cid(1, (u32 *)cid);
aes_use_keyslot(4); //Console-unique keyslot whose keys are set by the ARM9 bootROM 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); sha(out, cipherText, 0x10, SHA_256_MODE);
} }

View File

@ -108,4 +108,4 @@ u32 ctrNandRead(u32 sector, u32 sectorCount, u8 *outbuf);
void setRSAMod0DerivedKeys(void); void setRSAMod0DerivedKeys(void);
void decryptExeFs(u8 *inbuf); void decryptExeFs(u8 *inbuf);
void arm9Loader(u8 *arm9Section); void arm9Loader(u8 *arm9Section);
void computePinHash(u8 *out, u8 *in, u32 blockCount); void computePinHash(u8 *out, u8 *in);

View File

@ -26,6 +26,7 @@
*/ */
#include "draw.h" #include "draw.h"
#include "config.h"
#include "screen.h" #include "screen.h"
#include "utils.h" #include "utils.h"
#include "memory.h" #include "memory.h"
@ -36,7 +37,7 @@
static char pinKeyToLetter(u32 pressed) static char pinKeyToLetter(u32 pressed)
{ {
const char keys[] = "AB--------XY"; const char keys[] = "AB--RLUD--XY";
u32 i; u32 i;
for(i = 31; pressed > 1; i--) pressed /= 2; 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); drawString("PIN: ", 10, 10 + 2 * SPACING_Y, COLOR_WHITE);
//Pad to AES block length with zeroes //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; int charDrawPos = 5 * SPACING_X;
while(cnt < PIN_LENGTH) while(cnt < length)
{ {
u32 pressed; u32 pressed;
do do
@ -82,18 +84,20 @@ void newPin(bool allowSkipping)
} }
PINData pin; PINData pin;
u8 __attribute__((aligned(4))) tmp[32];
u8 __attribute__((aligned(4))) zeroes[16] = {0};
memcpy(pin.magic, "PINF", 4); memcpy(pin.magic, "PINF", 4);
pin.formatVersionMajor = PIN_VERSIONMAJOR; pin.formatVersionMajor = PIN_VERSIONMAJOR;
pin.formatVersionMinor = PIN_VERSIONMINOR; pin.formatVersionMinor = PIN_VERSIONMINOR;
pin.length = length;
computePinHash(tmp, zeroes, 1); u8 __attribute__((aligned(4))) tmp[0x20];
memcpy(pin.testHash, tmp, 32); u8 __attribute__((aligned(4))) zeroes[0x10] = {0};
computePinHash(tmp, enteredPassword, (PIN_LENGTH + 15) / 16); computePinHash(tmp, zeroes);
memcpy(pin.hash, tmp, 32); memcpy(pin.testHash, tmp, sizeof(tmp));
computePinHash(tmp, enteredPassword);
memcpy(pin.hash, tmp, sizeof(tmp));
if(!fileWrite(&pin, PIN_PATH, sizeof(PINData))) if(!fileWrite(&pin, PIN_PATH, sizeof(PINData)))
error("Error writing the PIN file"); error("Error writing the PIN file");
@ -108,21 +112,22 @@ bool verifyPin(void)
if(fileRead(&pin, PIN_PATH) != sizeof(PINData) || if(fileRead(&pin, PIN_PATH) != sizeof(PINData) ||
memcmp(pin.magic, "PINF", 4) != 0 || memcmp(pin.magic, "PINF", 4) != 0 ||
pin.formatVersionMajor != PIN_VERSIONMAJOR || pin.formatVersionMajor != PIN_VERSIONMAJOR ||
pin.formatVersionMinor != PIN_VERSIONMINOR) pin.formatVersionMinor != PIN_VERSIONMINOR ||
pin.length != 4 + MULTICONFIG(1))
return false; return false;
u8 __attribute__((aligned(4))) zeroes[16] = {0}; u8 __attribute__((aligned(4))) zeroes[0x10] = {0};
u8 __attribute__((aligned(4))) tmp[32]; 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) //Test vector verification (SD card has, or hasn't been used on another console)
if(memcmp(pin.testHash, tmp, 32) != 0) return false; if(memcmp(pin.testHash, tmp, 32) != 0) return false;
//Pad to AES block length with zeroes //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; bool unlock = false;
int charDrawPos = 5 * SPACING_X; int charDrawPos = 5 * SPACING_X;
@ -151,10 +156,10 @@ bool verifyPin(void)
drawCharacter(key, 10 + charDrawPos, 10 + 2 * SPACING_Y, COLOR_WHITE); drawCharacter(key, 10 + charDrawPos, 10 + 2 * SPACING_Y, COLOR_WHITE);
charDrawPos += 2 * SPACING_X; charDrawPos += 2 * SPACING_X;
if(cnt >= PIN_LENGTH) if(cnt >= pin.length)
{ {
computePinHash(tmp, enteredPassword, (PIN_LENGTH + 15) / 16); computePinHash(tmp, enteredPassword);
unlock = memcmp(pin.hash, tmp, 32) == 0; unlock = memcmp(pin.hash, tmp, sizeof(tmp)) == 0;
if(!unlock) if(!unlock)
{ {

View File

@ -30,16 +30,16 @@
#include "types.h" #include "types.h"
#define PIN_LENGTH 4
#define PIN_PATH "/luma/pin.bin" #define PIN_PATH "/luma/pin.bin"
#define PIN_VERSIONMAJOR 1 #define PIN_VERSIONMAJOR 1
#define PIN_VERSIONMINOR 0 #define PIN_VERSIONMINOR 1
typedef struct __attribute__((packed)) typedef struct __attribute__((packed))
{ {
char magic[4]; char magic[4];
u16 formatVersionMajor, formatVersionMinor; u16 formatVersionMajor, formatVersionMinor;
u8 length;
u8 testHash[32]; u8 testHash[32];
u8 hash[32]; u8 hash[32];
} PINData; } PINData;