1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-25 07:48:10 +00:00

core: Add support for ChangeWipeCode message.

This commit is contained in:
Andrew Kozlik 2019-10-18 20:12:17 +02:00
parent a9b98ab966
commit a168d661cf
7 changed files with 157 additions and 2 deletions

View File

@ -173,6 +173,36 @@ STATIC mp_obj_t mod_trezorconfig_change_pin(size_t n_args,
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorconfig_change_pin_obj, 4,
4, mod_trezorconfig_change_pin);
/// def change_wipe_code(
/// pin: int,
/// ext_salt: Optional[bytes],
/// wipe_code: int,
/// ) -> bool:
/// """
/// Change wipe code. Returns True on success, False on failure.
/// """
STATIC mp_obj_t mod_trezorconfig_change_wipe_code(size_t n_args,
const mp_obj_t *args) {
uint32_t pin = trezor_obj_get_uint(args[0]);
uint32_t wipe_code = trezor_obj_get_uint(args[2]);
mp_buffer_info_t ext_salt_b;
const uint8_t *ext_salt = NULL;
if (args[1] != mp_const_none) {
mp_get_buffer_raise(args[1], &ext_salt_b, MP_BUFFER_READ);
if (ext_salt_b.len != EXTERNAL_SALT_SIZE)
mp_raise_msg(&mp_type_ValueError, "Invalid length of external salt.");
ext_salt = ext_salt_b.buf;
}
if (sectrue != storage_change_wipe_code(pin, ext_salt, wipe_code)) {
return mp_const_false;
}
return mp_const_true;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(
mod_trezorconfig_change_wipe_code_obj, 3, 3,
mod_trezorconfig_change_wipe_code);
/// def get(app: int, key: int, public: bool = False) -> Optional[bytes]:
/// """
/// Gets the value of the given key for the given app (or None if not set).
@ -324,6 +354,8 @@ STATIC const mp_rom_map_elem_t mp_module_trezorconfig_globals_table[] = {
MP_ROM_PTR(&mod_trezorconfig_get_pin_rem_obj)},
{MP_ROM_QSTR(MP_QSTR_change_pin),
MP_ROM_PTR(&mod_trezorconfig_change_pin_obj)},
{MP_ROM_QSTR(MP_QSTR_change_wipe_code),
MP_ROM_PTR(&mod_trezorconfig_change_wipe_code_obj)},
{MP_ROM_QSTR(MP_QSTR_get), MP_ROM_PTR(&mod_trezorconfig_get_obj)},
{MP_ROM_QSTR(MP_QSTR_set), MP_ROM_PTR(&mod_trezorconfig_set_obj)},
{MP_ROM_QSTR(MP_QSTR_delete), MP_ROM_PTR(&mod_trezorconfig_delete_obj)},

View File

@ -46,6 +46,6 @@
/*
* Current storage version.
*/
#define NORCOW_VERSION ((uint32_t)0x00000001)
#define NORCOW_VERSION ((uint32_t)0x00000002)
#endif

View File

@ -60,6 +60,17 @@ def change_pin(
"""
# extmod/modtrezorconfig/modtrezorconfig.c
def change_wipe_code(
pin: int,
ext_salt: Optional[bytes],
wipe_code: int,
) -> bool:
"""
Change wipe code. Returns True on success, False on failure.
"""
# extmod/modtrezorconfig/modtrezorconfig.c
def get(app: int, key: int, public: bool = False) -> Optional[bytes]:
"""

View File

@ -117,3 +117,11 @@ async def show_pin_invalid(ctx: wire.Context) -> None:
text = Text("Wrong PIN", ui.ICON_WRONG, ui.RED)
text.normal("The PIN you entered is", "invalid.")
await confirm(ctx, text, confirm=None, cancel="Close")
async def show_pin_matches_wipe_code(ctx: wire.Context) -> None:
from apps.common.confirm import confirm
text = Text("Invalid PIN", ui.ICON_WRONG, ui.RED)
text.normal("The new PIN must be", "different from your", "wipe code.")
await confirm(ctx, text, confirm=None, cancel="Close")

View File

@ -13,3 +13,4 @@ def boot() -> None:
wire.add(MessageType.SetU2FCounter, __name__, "set_u2f_counter")
wire.add(MessageType.GetNextU2FCounter, __name__, "get_next_u2f_counter")
wire.add(MessageType.SdProtect, __name__, "sd_protect")
wire.add(MessageType.ChangeWipeCode, __name__, "change_wipe_code")

View File

@ -10,6 +10,7 @@ from apps.common.request_pin import (
request_pin_and_sd_salt,
request_pin_confirm,
show_pin_invalid,
show_pin_matches_wipe_code,
)
if False:
@ -40,7 +41,10 @@ async def change_pin(ctx: wire.Context, msg: ChangePin) -> Success:
# write into storage
if not config.change_pin(pin_to_int(curpin), pin_to_int(newpin), salt, salt):
await show_pin_invalid(ctx)
if newpin:
await show_pin_matches_wipe_code(ctx)
else:
await show_pin_invalid(ctx)
raise wire.PinInvalid("PIN invalid")
if newpin:

View File

@ -0,0 +1,99 @@
from storage import is_initialized
from trezor import config, ui, wire
from trezor.messages.Success import Success
from trezor.pin import pin_to_int
from trezor.ui.popup import Popup
from trezor.ui.text import Text
from apps.common.confirm import require_confirm
from apps.common.layout import show_success
from apps.common.request_pin import (
request_pin_ack,
request_pin_and_sd_salt,
show_pin_invalid,
)
if False:
from trezor.messages.ChangeWipeCode import ChangeWipeCode
async def change_wipe_code(ctx: wire.Context, msg: ChangeWipeCode) -> Success:
if not is_initialized():
raise wire.NotInitialized("Device is not initialized")
# Confirm that user wants to set or remove the wipe code.
await _require_confirm_action(ctx, msg)
# Get the unlocking PIN.
pin, salt = await request_pin_and_sd_salt(ctx)
if not msg.remove:
# Pre-check the entered PIN.
if config.has_pin() and not config.check_pin(pin_to_int(pin), salt):
await show_pin_invalid(ctx)
raise wire.PinInvalid("PIN invalid")
# Get new wipe code.
wipe_code = await _request_wipe_code_confirm(ctx, pin)
else:
wipe_code = ""
# Write into storage.
if not config.change_wipe_code(pin_to_int(pin), salt, pin_to_int(wipe_code)):
await show_pin_invalid(ctx)
raise wire.PinInvalid("PIN invalid")
if wipe_code:
msg_screen = "set the wipe code."
msg_wire = "Wipe code set"
else:
msg_screen = "disabled the wipe code."
msg_wire = "Wipe code removed"
await show_success(ctx, ("You have successfully", msg_screen))
return Success(message=msg_wire)
def _require_confirm_action(ctx: wire.Context, msg: ChangeWipeCode) -> None:
if msg.remove:
text = Text("Disable wipe code", ui.ICON_CONFIG)
text.normal("Do you really want to")
text.bold("disable wipe code")
text.bold("protection?")
return require_confirm(ctx, text)
else:
text = Text("Set wipe code", ui.ICON_CONFIG)
text.normal("Do you really want to")
text.bold("set the wipe code?")
return require_confirm(ctx, text)
async def _request_wipe_code_confirm(ctx: wire.Context, pin: str) -> str:
while True:
code1 = await request_pin_ack(ctx, "Enter new wipe code")
if code1 == pin:
await _wipe_code_invalid()
continue
code2 = await request_pin_ack(ctx, "Re-enter new wipe code")
if code1 == code2:
return code1
await _wipe_code_mismatch()
async def _wipe_code_invalid() -> None:
text = Text("Invalid wipe code", ui.ICON_WRONG, ui.RED)
text.normal("The wipe code must be", "different from your PIN.")
text.normal("")
text.normal("Please try again.")
popup = Popup(text, 3000) # show for 3 seconds
await popup
async def _wipe_code_mismatch() -> None:
text = Text("Code mismatch", ui.ICON_WRONG, ui.RED)
text.normal("The wipe codes you", "entered do not match.")
text.normal("")
text.normal("Please try again.")
popup = Popup(text, 3000) # show for 3 seconds
await popup