diff --git a/tiny-firmware/firmware/fsm_impl.c b/tiny-firmware/firmware/fsm_impl.c index e3aa50b..ad9f8cd 100644 --- a/tiny-firmware/firmware/fsm_impl.c +++ b/tiny-firmware/firmware/fsm_impl.c @@ -535,18 +535,23 @@ ErrCode_t msgPingImpl(Ping* msg) return ErrOk; } -ErrCode_t msgChangePinImpl(ChangePin* msg, const char* (*funcRequestPin)(PinMatrixRequestType, const char*)) +ErrCode_t msgChangePinImpl(ChangePin* msg, ErrCode_t (*funcRequestPin)(PinMatrixRequestType, const char*, char*)) { bool removal = msg->has_remove && msg->remove; if (removal) { storage_setPin(""); storage_update(); - } else { - if (!protectChangePinEx(funcRequestPin)) { - return ErrPinMismatch; - } } - return ErrOk; + ErrCode_t err = protectChangePinEx(funcRequestPin); + switch (err) { + case ErrPinRequired: + case ErrPinCancelled: + case ErrPinMismatch: + case ErrOk: + return err; + default: + return ErrUnexpectedMessage; + } } ErrCode_t msgWipeDeviceImpl(WipeDevice* msg) diff --git a/tiny-firmware/firmware/fsm_impl.h b/tiny-firmware/firmware/fsm_impl.h index 4c63ae6..194566d 100644 --- a/tiny-firmware/firmware/fsm_impl.h +++ b/tiny-firmware/firmware/fsm_impl.h @@ -192,7 +192,7 @@ ErrCode_t msgGetFeaturesImpl(Features* resp); ErrCode_t msgPingImpl(Ping* msg); -ErrCode_t msgChangePinImpl(ChangePin* msg, const char* (*)(PinMatrixRequestType, const char*)); +ErrCode_t msgChangePinImpl(ChangePin* msg, ErrCode_t(*)(PinMatrixRequestType, const char *, char *)); ErrCode_t msgWipeDeviceImpl(WipeDevice* msg); diff --git a/tiny-firmware/firmware/protect.c b/tiny-firmware/firmware/protect.c index 8af30ac..068ea4b 100644 --- a/tiny-firmware/firmware/protect.c +++ b/tiny-firmware/firmware/protect.c @@ -112,7 +112,7 @@ bool protectButton(ButtonRequestType type, bool confirm_only) return result; } -const char* requestPin(PinMatrixRequestType type, const char* text) +ErrCode_t requestPin(PinMatrixRequestType type, const char* text, char *out_pin) { PinMatrixRequest resp; memset(&resp, 0, sizeof(PinMatrixRequest)); @@ -128,16 +128,23 @@ const char* requestPin(PinMatrixRequestType type, const char* text) PinMatrixAck* pma = (PinMatrixAck*)msg_tiny; pinmatrix_done(pma->pin); // convert via pinmatrix usbTiny(0); - return pma->pin; + memcpy(out_pin, pma->pin, sizeof(pma->pin)); + return ErrOk; } if (msg_tiny_id == MessageType_MessageType_Cancel || msg_tiny_id == MessageType_MessageType_Initialize) { pinmatrix_done(0); if (msg_tiny_id == MessageType_MessageType_Initialize) { protectAbortedByInitialize = true; + msg_tiny_id = 0xFFFF; + usbTiny(0); + // TODO what does means Initialize here? + return ErrOk; + } + if (msg_tiny_id == MessageType_MessageType_Cancel) { + msg_tiny_id = 0xFFFF; + usbTiny(0); + return ErrPinCancelled; } - msg_tiny_id = 0xFFFF; - usbTiny(0); - return 0; } #if DEBUG_LINK if (msg_tiny_id == MessageType_MessageType_DebugLinkGetState) { @@ -195,11 +202,20 @@ bool protectPin(bool use_cached) wait--; } usbTiny(0); - const char* pin; - pin = requestPin(PinMatrixRequestType_PinMatrixRequestType_Current, _("Please enter current PIN:")); - if (!pin) { - fsm_sendFailure(FailureType_Failure_PinCancelled, NULL, 0); - return false; + char pin[10] = {0}; + { + PinMatrixAck pm = {0}; + _Static_assert(sizeof(pin) == sizeof(pm.pin), "invalid pin buffer size"); + } + switch (requestPin(PinMatrixRequestType_PinMatrixRequestType_Current, _("Please enter current PIN:"), pin)) { + case ErrOk: + break; + case ErrPinCancelled: + fsm_sendFailure(FailureType_Failure_PinCancelled, NULL, 0); + return false; + default: + fsm_sendFailure(FailureType_Failure_UnexpectedMessage, NULL, 0); + return false; } if (!storage_increasePinFails(fails)) { fsm_sendFailure(FailureType_Failure_PinInvalid, NULL, 0); @@ -221,33 +237,55 @@ bool protectChangePin() return protectChangePinEx(NULL); } -bool protectChangePinEx(const char* (*funcRequestPin)(PinMatrixRequestType, const char*)) +ErrCode_t protectChangePinEx(ErrCode_t (*funcRequestPin)(PinMatrixRequestType, const char*, char*)) { static CONFIDENTIAL char pin_compare[17]; + memset(pin_compare, 0, sizeof(pin_compare)); if (funcRequestPin == NULL) { funcRequestPin = requestPin; } - - const char* pin = funcRequestPin(PinMatrixRequestType_PinMatrixRequestType_NewFirst, _("Please enter new PIN:")); - - if (!pin) { - return false; + static CONFIDENTIAL char pin[10] = {0}; + memset(pin, 0, sizeof(pin)); + { + PinMatrixAck pm = {0}; + _Static_assert(sizeof(pin) == sizeof(pm.pin), "invalid pin buffer size"); + } + ErrCode_t err = funcRequestPin(PinMatrixRequestType_PinMatrixRequestType_NewFirst, _("Please enter new PIN:"), pin); + if (err != ErrOk) { + memset(pin_compare, 0, sizeof(pin_compare)); + memset(pin, 0, sizeof(pin)); + return err; + } + { + char empty_pin[sizeof(pin)] = {0}; + if (!memcmp(pin, empty_pin, sizeof(pin))) { + memset(pin_compare, 0, sizeof(pin_compare)); + memset(pin, 0, sizeof(pin)); + return ErrPinRequired; + } } - strlcpy(pin_compare, pin, sizeof(pin_compare)); - - pin = funcRequestPin(PinMatrixRequestType_PinMatrixRequestType_NewSecond, _("Please re-enter new PIN:")); - - const bool result = pin && *pin && (strncmp(pin_compare, pin, sizeof(pin_compare)) == 0); - - if (result) { + memset(pin, 0, sizeof(pin)); + err = funcRequestPin(PinMatrixRequestType_PinMatrixRequestType_NewSecond, _("Please re-enter new PIN:"), pin); + { + char empty_pin[sizeof(pin)] = {0}; + if (!memcmp(pin, empty_pin, sizeof(pin))) { + memset(pin_compare, 0, sizeof(pin_compare)); + memset(pin, 0, sizeof(pin)); + return ErrPinRequired; + } + } + if (strncmp(pin_compare, pin, sizeof(pin_compare)) == 0) { storage_setPin(pin_compare); storage_update(); + } else { + memset(pin_compare, 0, sizeof(pin_compare)); + memset(pin, 0, sizeof(pin)); + return ErrPinMismatch; } - - memzero(pin_compare, sizeof(pin_compare)); - - return result; + memset(pin_compare, 0, sizeof(pin_compare)); + memset(pin, 0, sizeof(pin)); + return ErrOk; } bool protectPassphrase(void) diff --git a/tiny-firmware/firmware/protect.h b/tiny-firmware/firmware/protect.h index 5a413c7..edb0a9b 100644 --- a/tiny-firmware/firmware/protect.h +++ b/tiny-firmware/firmware/protect.h @@ -18,10 +18,11 @@ * along with this library. If not, see . */ -#ifndef __PROTECT_H__ -#define __PROTECT_H__ +#ifndef __PROTECT_HANDLER_H__ +#define __PROTECT_HANDLER_H__ #include "types.pb.h" +#include "tiny-firmware/firmware/error.h" #include bool protectButton(ButtonRequestType type, bool confirm_only); @@ -32,7 +33,7 @@ bool protectPassphrase(void); extern bool protectAbortedByInitialize; // Symbols exported for testing -bool protectChangePinEx(const char* (*)(PinMatrixRequestType, const char*)); -const char* requestPin(PinMatrixRequestType type, const char* text); +ErrCode_t protectChangePinEx(ErrCode_t (*)(PinMatrixRequestType, const char*, char*)); +ErrCode_t requestPin(PinMatrixRequestType type, const char* text, char *out_pin); -#endif +#endif // __PROTECT_HANDLER_H__ diff --git a/tiny-firmware/firmware/reset.c b/tiny-firmware/firmware/reset.c index 34b18a6..ce32d9e 100644 --- a/tiny-firmware/firmware/reset.c +++ b/tiny-firmware/firmware/reset.c @@ -41,7 +41,7 @@ void reset_init(bool display_random, uint32_t _strength, bool passphrase_protect reset_init_ex(display_random, _strength, passphrase_protection, pin_protection, language, label, _skip_backup, NULL); } -void reset_init_ex(bool display_random, uint32_t _strength, bool passphrase_protection, bool pin_protection, const char* language, const char* label, bool _skip_backup, const char* (*funcRequestPin)(PinMatrixRequestType, const char*)) +void reset_init_ex(bool display_random, uint32_t _strength, bool passphrase_protection, bool pin_protection, const char* language, const char* label, bool _skip_backup, ErrCode_t (*funcRequestPin)(PinMatrixRequestType, const char*, char*)) { if (funcRequestPin == NULL) { funcRequestPin = requestPin; @@ -70,13 +70,20 @@ void reset_init_ex(bool display_random, uint32_t _strength, bool passphrase_prot return; } } - - if (pin_protection && !protectChangePinEx(funcRequestPin)) { - fsm_sendFailure(FailureType_Failure_PinMismatch, NULL, 0); - layoutHome(); - return; + if (pin_protection) { + ErrCode_t err = protectChangePinEx(funcRequestPin); + switch (err) { + case ErrOk: + break; + case ErrPinMismatch: + fsm_sendFailure(FailureType_Failure_PinMismatch, NULL, 0); + layoutHome(); + return; + default: + fsm_sendFailure(FailureType_Failure_UnexpectedMessage, NULL, 0); + return; + } } - storage_setPassphraseProtection(passphrase_protection); storage_setLanguage(language); if (label != NULL && strcmp("", label) != 0) { diff --git a/tiny-firmware/firmware/reset.h b/tiny-firmware/firmware/reset.h index 679a2ad..82a8ad6 100644 --- a/tiny-firmware/firmware/reset.h +++ b/tiny-firmware/firmware/reset.h @@ -40,6 +40,6 @@ uint32_t reset_get_int_entropy(uint8_t* entropy); const char* reset_get_word(void); // Functions exported or testing purposes -void reset_init_ex(bool display_random, uint32_t _strength, bool passphrase_protection, bool pin_protection, const char* language, const char* label, bool _skip_backup, const char* (*funcRequestPin)(PinMatrixRequestType mt, const char* msg)); +void reset_init_ex(bool display_random, uint32_t _strength, bool passphrase_protection, bool pin_protection, const char* language, const char* label, bool _skip_backup, ErrCode_t (*funcRequestPin)(PinMatrixRequestType mt, const char* msg, char *out_pin)); #endif