feat(legacy): Support on-device passphrase entry.

andrewkozlik/t1-keyboard
Andrew Kozlik 3 years ago
parent b2e56342c2
commit 990e32275f

@ -68,17 +68,19 @@ static const uint32_t META_MAGIC_V10 = 0xFFFFFFFF;
#define KEY_LANGUAGE (3 | APP | FLAG_PUBLIC_SHIFTED) // string(17)
#define KEY_LABEL (4 | APP | FLAG_PUBLIC_SHIFTED) // string(33)
#define KEY_PASSPHRASE_PROTECTION (5 | APP | FLAG_PUBLIC_SHIFTED) // bool
#define KEY_HOMESCREEN (6 | APP | FLAG_PUBLIC_SHIFTED) // bytes(1024)
#define KEY_NEEDS_BACKUP (7 | APP) // bool
#define KEY_FLAGS (8 | APP) // uint32
#define KEY_U2F_COUNTER (9 | APP | FLAGS_WRITE_SHIFTED) // uint32
#define KEY_UNFINISHED_BACKUP (11 | APP) // bool
#define KEY_AUTO_LOCK_DELAY_MS (12 | APP) // uint32
#define KEY_NO_BACKUP (13 | APP) // bool
#define KEY_INITIALIZED (14 | APP | FLAG_PUBLIC_SHIFTED) // uint32
#define KEY_NODE (15 | APP) // node
#define KEY_IMPORTED (16 | APP) // bool
#define KEY_U2F_ROOT (17 | APP | FLAG_PUBLIC_SHIFTED) // node
#define KEY_HOMESCREEN (6 | APP | FLAG_PUBLIC_SHIFTED) // bytes(1024)
#define KEY_NEEDS_BACKUP (7 | APP) // bool
#define KEY_FLAGS (8 | APP) // uint32
#define KEY_U2F_COUNTER (9 | APP | FLAGS_WRITE_SHIFTED) // uint32
#define KEY_UNFINISHED_BACKUP (11 | APP) // bool
#define KEY_AUTO_LOCK_DELAY_MS (12 | APP) // uint32
#define KEY_NO_BACKUP (13 | APP) // bool
#define KEY_INITIALIZED (14 | APP | FLAG_PUBLIC_SHIFTED) // uint32
#define KEY_NODE (15 | APP) // node
#define KEY_IMPORTED (16 | APP) // bool
#define KEY_U2F_ROOT (17 | APP | FLAG_PUBLIC_SHIFTED) // node
#define KEY_PASSPHRASE_ALWAYS_ON_DEVICE \
(18 | APP | FLAG_PUBLIC_SHIFTED) // bool
#define KEY_DEBUG_LINK_PIN (255 | APP | FLAG_PUBLIC_SHIFTED) // string(10)
#define MAX_SESSIONS_COUNT 10
@ -561,6 +563,9 @@ void config_setLanguage(const char *lang) {
void config_setPassphraseProtection(bool passphrase_protection) {
config_set_bool(KEY_PASSPHRASE_PROTECTION, passphrase_protection);
if (passphrase_protection == false) {
config_setPassphraseAlwaysOnDevice(false);
}
}
bool config_getPassphraseProtection(bool *passphrase_protection) {
@ -568,6 +573,17 @@ bool config_getPassphraseProtection(bool *passphrase_protection) {
config_get_bool(KEY_PASSPHRASE_PROTECTION, passphrase_protection);
}
void config_setPassphraseAlwaysOnDevice(bool passphrase_always_on_device) {
config_set_bool(KEY_PASSPHRASE_ALWAYS_ON_DEVICE, passphrase_always_on_device);
}
bool config_getPassphraseAlwaysOnDevice(void) {
bool passphrase_always_on_device = false;
config_get_bool(KEY_PASSPHRASE_ALWAYS_ON_DEVICE,
&passphrase_always_on_device);
return passphrase_always_on_device;
}
void config_setHomescreen(const uint8_t *data, uint32_t size) {
if (data != NULL && size == HOMESCREEN_SIZE) {
storage_set(KEY_HOMESCREEN, data, size);
@ -601,30 +617,6 @@ const uint8_t *config_getSeed(void) {
memzero(passphrase, sizeof(passphrase));
return NULL;
}
// passphrase is used - confirm on the display
if (passphrase[0] != 0) {
layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("Confirm"), NULL,
_("Access hidden wallet?"), NULL,
_("Next screen will show"), _("the passphrase!"), NULL,
NULL);
if (!protectButton(ButtonRequestType_ButtonRequest_Other, false)) {
memzero(mnemonic, sizeof(mnemonic));
memzero(passphrase, sizeof(passphrase));
fsm_sendFailure(FailureType_Failure_ActionCancelled,
_("Passphrase dismissed"));
layoutHome();
return NULL;
}
layoutShowPassphrase(passphrase);
if (!protectButton(ButtonRequestType_ButtonRequest_Other, false)) {
memzero(mnemonic, sizeof(mnemonic));
memzero(passphrase, sizeof(passphrase));
fsm_sendFailure(FailureType_Failure_ActionCancelled,
_("Passphrase dismissed"));
layoutHome();
return NULL;
}
}
// if storage was not imported (i.e. it was properly generated or recovered)
bool imported = false;
config_get_bool(KEY_IMPORTED, &imported);

@ -114,6 +114,9 @@ void config_setLanguage(const char *lang);
void config_setPassphraseProtection(bool passphrase_protection);
bool config_getPassphraseProtection(bool *passphrase_protection);
void config_setPassphraseAlwaysOnDevice(bool passphrase_always_on_device);
bool config_getPassphraseAlwaysOnDevice(void);
bool config_getHomescreen(uint8_t *dest, uint16_t dest_size);
void config_setHomescreen(const uint8_t *data, uint32_t size);

@ -64,6 +64,8 @@ bool get_features(Features *resp) {
resp->wipe_code_protection = config_hasWipeCode();
resp->has_auto_lock_delay_ms = true;
resp->auto_lock_delay_ms = config_getAutoLockDelayMs();
resp->has_passphrase_always_on_device = true;
resp->passphrase_always_on_device = config_getPassphraseAlwaysOnDevice();
}
#if BITCOIN_ONLY
@ -71,7 +73,7 @@ bool get_features(Features *resp) {
resp->capabilities[0] = Capability_Capability_Bitcoin;
resp->capabilities[1] = Capability_Capability_Crypto;
#else
resp->capabilities_count = 8;
resp->capabilities_count = 9;
resp->capabilities[0] = Capability_Capability_Bitcoin;
resp->capabilities[1] = Capability_Capability_Bitcoin_like;
resp->capabilities[2] = Capability_Capability_Crypto;
@ -80,6 +82,7 @@ bool get_features(Features *resp) {
resp->capabilities[5] = Capability_Capability_NEM;
resp->capabilities[6] = Capability_Capability_Stellar;
resp->capabilities[7] = Capability_Capability_U2F;
resp->capabilities[8] = Capability_Capability_PassphraseEntry;
#endif
return resp;
}
@ -361,10 +364,6 @@ void fsm_msgEndSession(const EndSession *msg) {
}
void fsm_msgApplySettings(const ApplySettings *msg) {
CHECK_PARAM(
!msg->has_passphrase_always_on_device,
_("This firmware is incapable of passphrase entry on the device."));
CHECK_PARAM(msg->has_label || msg->has_language || msg->has_use_passphrase ||
msg->has_homescreen || msg->has_auto_lock_delay_ms,
_("No setting provided"));
@ -403,6 +402,35 @@ void fsm_msgApplySettings(const ApplySettings *msg) {
return;
}
}
if (msg->has_passphrase_always_on_device) {
bool use_passphrase = false;
if (msg->has_use_passphrase) {
use_passphrase = msg->use_passphrase;
} else {
config_getPassphraseProtection(&use_passphrase);
}
if (use_passphrase == false) {
fsm_sendFailure(FailureType_Failure_DataError,
_("Passphrase is not enabled"));
layoutHome();
return;
}
if (msg->passphrase_always_on_device) {
layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("Confirm"), NULL,
_("Do you really want to"), _("restrict passphrase"),
_("entry to be only"), _("allowed on the"),
_("device?"), NULL);
} else {
layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("Confirm"), NULL,
_("Do you really want to"), _("allow passphrase"),
_("entry on the host?"), NULL, NULL, NULL);
}
if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) {
fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL);
layoutHome();
return;
}
}
if (msg->has_homescreen) {
layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("Confirm"), NULL,
_("Do you really want to"), _("change the home"),
@ -444,6 +472,9 @@ void fsm_msgApplySettings(const ApplySettings *msg) {
if (msg->has_use_passphrase) {
config_setPassphraseProtection(msg->use_passphrase);
}
if (msg->has_passphrase_always_on_device) {
config_setPassphraseAlwaysOnDevice(msg->passphrase_always_on_device);
}
if (msg->has_homescreen) {
config_setHomescreen(msg->homescreen.bytes, msg->homescreen.size);
}

@ -112,6 +112,7 @@ bool protectButton(ButtonRequestType type, bool confirm_only) {
const char *requestPin(PinMatrixRequestType type, const char *text) {
return pin_keyboard(text);
PinMatrixRequest resp = {0};
memzero(&resp, sizeof(PinMatrixRequest));
resp.has_type = true;
@ -352,15 +353,18 @@ bool protectChangeWipeCode(bool removal) {
return ret;
}
bool protectPassphrase(char *passphrase) {
memzero(passphrase, MAX_PASSPHRASE_LEN + 1);
bool passphrase_protection = false;
config_getPassphraseProtection(&passphrase_protection);
if (!passphrase_protection) {
// passphrase already set to empty by memzero above
static bool protectPassphraseOnDevice(char *passphrase) {
const char *input = passphrase_keyboard(_("Please enter passphrase"));
if (input) {
strlcpy(passphrase, input, MAX_PASSPHRASE_LEN);
return true;
} else {
fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL);
return false;
}
}
static bool protectPassphraseOnHost(char *passphrase) {
PassphraseRequest resp = {0};
memzero(&resp, sizeof(PassphraseRequest));
usbTiny(1);
@ -377,10 +381,13 @@ bool protectPassphrase(char *passphrase) {
msg_tiny_id = 0xFFFF;
PassphraseAck *ppa = (PassphraseAck *)msg_tiny;
if (ppa->has_on_device && ppa->on_device == true) {
fsm_sendFailure(
FailureType_Failure_DataError,
_("This firmware is incapable of passphrase entry on the device."));
result = false;
if (ppa->has_passphrase) {
fsm_sendFailure(FailureType_Failure_DataError,
_("Passphrase provided when it should not be"));
result = false;
break;
}
result = protectPassphraseOnDevice(passphrase);
break;
}
if (!ppa->has_passphrase) {
@ -391,6 +398,26 @@ bool protectPassphrase(char *passphrase) {
break;
}
strlcpy(passphrase, ppa->passphrase, sizeof(ppa->passphrase));
if (passphrase[0] != '\0') {
// passphrase is used - confirm on the display
layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("Confirm"), NULL,
_("Access hidden wallet?"), NULL,
_("Next screen will show"), _("the passphrase!"),
NULL, NULL);
if (!protectButton(ButtonRequestType_ButtonRequest_Other, false)) {
fsm_sendFailure(FailureType_Failure_ActionCancelled,
_("Passphrase dismissed"));
result = false;
break;
}
layoutShowPassphrase(passphrase);
if (!protectButton(ButtonRequestType_ButtonRequest_Other, false)) {
fsm_sendFailure(FailureType_Failure_ActionCancelled,
_("Passphrase dismissed"));
result = false;
break;
}
}
result = true;
break;
}
@ -409,3 +436,19 @@ bool protectPassphrase(char *passphrase) {
layoutHome();
return result;
}
bool protectPassphrase(char *passphrase) {
memzero(passphrase, MAX_PASSPHRASE_LEN + 1);
bool passphrase_protection = false;
config_getPassphraseProtection(&passphrase_protection);
if (!passphrase_protection) {
// passphrase already set to empty by memzero above
return true;
}
if (config_getPassphraseAlwaysOnDevice()) {
return protectPassphraseOnDevice(passphrase);
} else {
return protectPassphraseOnHost(passphrase);
}
}

Loading…
Cancel
Save