Merge pull request #16 from jhoenicke/master

PIN handling - constant time.
This commit is contained in:
Pavol Rusnak 2015-02-26 11:38:53 +01:00
commit 402886e00d
3 changed files with 22 additions and 11 deletions

View File

@ -156,16 +156,16 @@ bool protectPin(bool use_cached)
delay(10000000); delay(10000000);
} }
} }
storage_increasePinFails();
bool increase_failed = (fails >= storage_getPinFails());
const char *pin; const char *pin;
pin = requestPin(PinMatrixRequestType_PinMatrixRequestType_Current, "Please enter current PIN:"); pin = requestPin(PinMatrixRequestType_PinMatrixRequestType_Current, "Please enter current PIN:");
if (!pin) { if (!pin) {
fsm_sendFailure(FailureType_Failure_PinCancelled, "PIN Cancelled"); fsm_sendFailure(FailureType_Failure_PinCancelled, "PIN Cancelled");
return false; return false;
} }
storage_increasePinFails();
bool increase_failed = (fails >= storage_getPinFails());
if (storage_isPinCorrect(pin) && !increase_failed) { if (storage_isPinCorrect(pin) && !increase_failed) {
session_cachePin(pin); session_cachePin();
storage_resetPinFails(); storage_resetPinFails();
return true; return true;
} else { } else {

View File

@ -48,7 +48,6 @@ static bool sessionRootNodeCached;
static HDNode sessionRootNode; static HDNode sessionRootNode;
static bool sessionPinCached; static bool sessionPinCached;
static char sessionPin[17];
static bool sessionPassphraseCached; static bool sessionPassphraseCached;
static char sessionPassphrase[51]; static char sessionPassphrase[51];
@ -122,7 +121,7 @@ void session_clear(void)
{ {
sessionRootNodeCached = false; memset(&sessionRootNode, 0, sizeof(sessionRootNode)); sessionRootNodeCached = false; memset(&sessionRootNode, 0, sizeof(sessionRootNode));
sessionPassphraseCached = false; memset(&sessionPassphrase, 0, sizeof(sessionPassphrase)); sessionPassphraseCached = false; memset(&sessionPassphrase, 0, sizeof(sessionPassphrase));
sessionPinCached = false; memset(&sessionPin, 0, sizeof(sessionPin)); sessionPinCached = false;
} }
static uint8_t meta_backup[FLASH_META_LEN]; static uint8_t meta_backup[FLASH_META_LEN];
@ -306,14 +305,27 @@ const uint8_t *storage_getHomescreen(void)
return (storage.has_homescreen && storage.homescreen.size == 1024) ? storage.homescreen.bytes : 0; return (storage.has_homescreen && storage.homescreen.size == 1024) ? storage.homescreen.bytes : 0;
} }
/* Check whether pin matches storage. The pin must be a null-terminated
* string with at most 9 characters.
*/
bool storage_isPinCorrect(const char *pin) bool storage_isPinCorrect(const char *pin)
{ {
return strcmp(storage.pin, pin) == 0; /* The execution time of the following code only depends on the
* (public) input. This avoids timing attacks.
*/
char diff = 0;
uint32_t i = 0;
while (pin[i]) {
diff |= storage.pin[i] - pin[i];
i++;
}
diff |= storage.pin[i];
return diff == 0;
} }
bool storage_hasPin(void) bool storage_hasPin(void)
{ {
return storage.has_pin && strlen(storage.pin) > 0; return storage.has_pin && storage.pin[0] != 0;
} }
void storage_setPin(const char *pin) void storage_setPin(const char *pin)
@ -340,15 +352,14 @@ bool session_isPassphraseCached(void)
return sessionPassphraseCached; return sessionPassphraseCached;
} }
void session_cachePin(const char *pin) void session_cachePin(void)
{ {
strlcpy(sessionPin, pin, sizeof(sessionPin));
sessionPinCached = true; sessionPinCached = true;
} }
bool session_isPinCached(void) bool session_isPinCached(void)
{ {
return sessionPinCached && strcmp(sessionPin, storage.pin) == 0; return sessionPinCached;
} }
void storage_resetPinFails(void) void storage_resetPinFails(void)

View File

@ -52,7 +52,7 @@ bool session_isPassphraseCached(void);
bool storage_isPinCorrect(const char *pin); bool storage_isPinCorrect(const char *pin);
bool storage_hasPin(void); bool storage_hasPin(void);
void storage_setPin(const char *pin); void storage_setPin(const char *pin);
void session_cachePin(const char *pin); void session_cachePin(void);
bool session_isPinCached(void); bool session_isPinCached(void);
void storage_resetPinFails(void); void storage_resetPinFails(void);
void storage_increasePinFails(void); void storage_increasePinFails(void);