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
);
u32 cpuSetting = MULTICONFIG(1);
u32 cpuSetting = MULTICONFIG(2);
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 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)
#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);
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

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))) 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);
}

View File

@ -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);
void computePinHash(u8 *out, u8 *in);

View File

@ -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)
{

View File

@ -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;