Implement selectable PIN size, added support for the directional pad in PINs
This commit is contained in:
parent
5cd1a207c9
commit
201fe05a06
@ -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)
|
||||
{
|
||||
|
@ -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)
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
@ -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);
|
43
source/pin.c
43
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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
Reference in New Issue
Block a user