Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix screensaver for nanosp/nanox and add PIN lock in screensaver/app exit #43

Merged
merged 4 commits into from
Mar 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 19 additions & 8 deletions src/apdu_sign.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,14 +117,16 @@ static bool parse_allowed_operations(struct parsed_operation_group *const out,
}

size_t baking_sign_complete(bool const send_hash, volatile uint32_t *flags) {
size_t result = 0;
switch (G.magic_byte) {
case MAGIC_BYTE_TENDERBAKE_BLOCK:
case MAGIC_BYTE_TENDERBAKE_PREENDORSEMENT:
case MAGIC_BYTE_TENDERBAKE_ENDORSEMENT:
case MAGIC_BYTE_BLOCK:
case MAGIC_BYTE_BAKING_OP:
guard_baking_authorized(&G.parsed_baking_data, &global.path_with_curve);
return perform_signature(true, send_hash);
result = perform_signature(true, send_hash);
ux_empty_screen();
spalmer25 marked this conversation as resolved.
Show resolved Hide resolved
break;

case MAGIC_BYTE_UNSAFE_OP: {
Expand All @@ -143,31 +145,34 @@ size_t baking_sign_complete(bool const send_hash, volatile uint32_t *flags) {
send_hash ? sign_with_hash_ok : sign_without_hash_ok;
prompt_register_delegate(ok_c, sign_reject);
*flags = IO_ASYNCH_REPLY;
return 0;
result = 0;
} else {
THROW(EXC_SECURITY);
}
THROW(EXC_SECURITY);
break;
case OPERATION_TAG_ATHENS_REVEAL:
case OPERATION_TAG_BABYLON_REVEAL:
case OPERATION_TAG_NONE:
// Reveal cases
if (bip32_path_with_curve_eq(&global.path_with_curve, &N_data.baking_key) &&
// ops->signing is generated from G.bip32_path and G.curve
COMPARE(&G.maybe_ops.v.operation.source, &G.maybe_ops.v.signing) == 0)
return perform_signature(true, send_hash);
THROW(EXC_SECURITY);
COMPARE(&G.maybe_ops.v.operation.source, &G.maybe_ops.v.signing) == 0) {
result = perform_signature(true, send_hash);
} else {
THROW(EXC_SECURITY);
}
break;
default:
THROW(EXC_SECURITY);
}
THROW(EXC_SECURITY);
break;
}
case MAGIC_BYTE_UNSAFE_OP2:
case MAGIC_BYTE_UNSAFE_OP3:
default:
PARSE_ERROR();
}
return result;
}

#define P1_FIRST 0x00
Expand Down Expand Up @@ -196,6 +201,9 @@ static size_t handle_apdu(bool const enable_hashing,
bool const enable_parsing,
uint8_t const instruction,
volatile uint32_t *flags) {
if (os_global_pin_is_validated() != BOLOS_UX_OK) {
THROW(EXC_SECURITY);
}
uint8_t *const buff = &G_io_apdu_buffer[OFFSET_CDATA];
uint8_t const p1 = G_io_apdu_buffer[OFFSET_P1];
uint8_t const buff_size = G_io_apdu_buffer[OFFSET_LC];
Expand Down Expand Up @@ -284,8 +292,11 @@ size_t handle_apdu_sign_with_hash(uint8_t instruction, volatile uint32_t *flags)
}

int perform_signature(bool const on_hash, bool const send_hash) {
write_high_water_mark(&G.parsed_baking_data);
if (os_global_pin_is_validated() != BOLOS_UX_OK) {
THROW(EXC_SECURITY);
}

write_high_water_mark(&G.parsed_baking_data);
size_t tx = 0;
if (send_hash && on_hash) {
memcpy(&G_io_apdu_buffer[tx], G.final_hash, sizeof(G.final_hash));
Expand Down
2 changes: 2 additions & 0 deletions src/globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ typedef struct {
char screen_title[PROMPT_WIDTH + 1];
// Value to be displayed on the screen.
char screen_value[VALUE_WIDTH + 1];
// Screensaver is on/off.
bool is_blank_screen;
} dynamic_display;

void *stack_root;
Expand Down
1 change: 1 addition & 0 deletions src/ui.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ void ux_confirm_screen(ui_callback_t ok_c, ui_callback_t cxl_c);

void ux_idle_screen(ui_callback_t ok_c, ui_callback_t cxl_c);

void ux_empty_screen(void);
/* Initializes the formatter stack. Should be called once before calling `push_ui_callback()`. */
void init_screen_stack();
/* User MUST call `init_screen_stack()` before calling this function for the first time. */
Expand Down
13 changes: 7 additions & 6 deletions src/ui_bagl.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,13 @@ UX_STEP_NOCB(ux_variable_display,
});
UX_STEP_INIT(ux_init_lower_border, NULL, NULL, { display_next_state(false); });

UX_STEP_NOCB(ux_app_is_ready_step,
nn,
{
"Application",
"is ready",
});
UX_STEP_CB(ux_app_is_ready_step,
nn,
ux_empty_screen(),
{
"Application",
"is ready",
});

UX_STEP_CB(ux_idle_quit_step,
pb,
Expand Down
55 changes: 55 additions & 0 deletions src/ui_empty.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#ifdef HAVE_BAGL
#include "bolos_target.h"
#include "globals.h"
#include "ui.h"

const bagl_element_t empty_screen_elements[] = {{{BAGL_RECTANGLE,
BAGL_NONE,
0,
0,
BAGL_WIDTH,
BAGL_HEIGHT,
0,
0,
BAGL_FILL,
0x000000,
0xFFFFFF,
0,
0},
.text = NULL},
{}};

typedef struct ux_layout_empty_params_s {
} ux_layout_empty_params_t;

void ux_layout_empty_init(unsigned int stack_slot) {
ux_stack_init(stack_slot);
G_ux.stack[stack_slot].element_arrays[0].element_array = empty_screen_elements;
G_ux.stack[stack_slot].element_arrays[0].element_array_count = ARRAYLEN(empty_screen_elements);
G_ux.stack[stack_slot].element_arrays_count = 1;
G_ux.stack[stack_slot].button_push_callback = ux_flow_button_callback;
ux_stack_display(stack_slot);
}

void ux_layout_empty_screen_init(__attribute__((unused)) unsigned int x) {
}

void return_to_idle() {
global.dynamic_display.is_blank_screen = false;
ux_idle_screen(NULL, NULL);
}

UX_STEP_CB(empty_screen_step, empty, return_to_idle(), {});
UX_STEP_INIT(empty_screen_border, NULL, NULL, { return_to_idle(); });
UX_FLOW(ux_empty_flow, &empty_screen_step, &empty_screen_border, FLOW_LOOP);

void ux_empty_screen() {
if (global.dynamic_display.is_blank_screen == false) {
global.dynamic_display.is_blank_screen = true;
ux_flow_init(0, ux_empty_flow, NULL);
}
}
#else
void ux_empty_screen() {
}
#endif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
43 changes: 17 additions & 26 deletions test/python/test_instructions.py
Original file line number Diff line number Diff line change
Expand Up @@ -331,17 +331,13 @@ def test_sign_preattestation(
f"Expected hash {preattestation.hash.hex()} but got {preattestation_hash.hex()}"
account.check_signature(signature, bytes(preattestation))

tezos_navigator.assert_screen(
name="black_screen",
snap_path=snap_path / "app_context"
)

tezos_navigator.check_app_context(
account,
chain_id=main_chain_id,
main_hwm=Hwm(1, 2),
test_hwm=Hwm(0, 0),
snap_path=snap_path
snap_path=snap_path,
black_screen=True
)


Expand Down Expand Up @@ -381,17 +377,13 @@ def test_sign_attestation(
f"Expected hash {attestation.hash.hex()} but got {attestation_hash.hex()}"
account.check_signature(signature, bytes(attestation))

tezos_navigator.assert_screen(
name="black_screen",
snap_path=snap_path / "app_context"
)

tezos_navigator.check_app_context(
account,
chain_id=main_chain_id,
main_hwm=Hwm(1, 2),
test_hwm=Hwm(0, 0),
snap_path=snap_path
snap_path=snap_path,
black_screen=True
)


Expand Down Expand Up @@ -431,17 +423,13 @@ def test_sign_attestation_dal(
f"Expected hash {attestation.hash.hex()} but got {attestation_hash.hex()}"
account.check_signature(signature, bytes(attestation))

tezos_navigator.assert_screen(
name="black_screen",
snap_path=snap_path / "app_context"
)

tezos_navigator.check_app_context(
account,
chain_id=main_chain_id,
main_hwm=Hwm(1, 2),
test_hwm=Hwm(0, 0),
snap_path=snap_path
snap_path=snap_path,
black_screen=True
)


Expand Down Expand Up @@ -481,17 +469,13 @@ def test_sign_block(
f"Expected hash {block.hash.hex()} but got {block_hash.hex()}"
account.check_signature(signature, bytes(block))

tezos_navigator.assert_screen(
name="black_screen",
snap_path=snap_path / "app_context"
)

tezos_navigator.check_app_context(
account,
chain_id=main_chain_id,
main_hwm=Hwm(1, 2),
test_hwm=Hwm(0, 0),
snap_path=snap_path
snap_path=snap_path,
black_screen=True
)


Expand Down Expand Up @@ -1001,7 +985,8 @@ def test_sign_when_no_chain_setup(
chain_id=DEFAULT_CHAIN_ID,
main_hwm=Hwm(1, 0),
test_hwm=Hwm(0, 0),
snap_path=Path("sign_1_0")
snap_path=Path("sign_1_0"),
black_screen=True
)

attestation = build_attestation(
Expand All @@ -1016,7 +1001,8 @@ def test_sign_when_no_chain_setup(
chain_id=DEFAULT_CHAIN_ID,
main_hwm=Hwm(2, 0),
test_hwm=Hwm(0, 0),
snap_path=Path("sign_2_0")
snap_path=Path("sign_2_0"),
black_screen=True
)

attestation = build_attestation(
Expand Down Expand Up @@ -1063,6 +1049,8 @@ def test_sign_when_chain_is_setup(
chain_id=main_chain_id,
main_hwm=Hwm(1, 0),
test_hwm=Hwm(0, 0),
snap_path=Path("sign_1_0"),
black_screen=True
)

attestation = build_attestation(
Expand All @@ -1077,6 +1065,8 @@ def test_sign_when_chain_is_setup(
chain_id=main_chain_id,
main_hwm=Hwm(1, 0),
test_hwm=Hwm(2, 0),
snap_path=Path("sign_2_0"),
black_screen=True
)

attestation = build_attestation(
Expand All @@ -1092,6 +1082,7 @@ def test_sign_when_chain_is_setup(
chain_id=main_chain_id,
main_hwm=Hwm(1, 0),
test_hwm=Hwm(2, 0),
snap_path=Path("sign_2_0")
)


Expand Down
13 changes: 12 additions & 1 deletion test/python/utils/navigator.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,20 @@ def check_app_context(self,
chain_id: str,
main_hwm: Hwm,
test_hwm: Hwm,
snap_path: Path = Path("")) -> None:
snap_path: Path = Path(""),
black_screen: bool = False) -> None:
"""Check that the app context."""

if black_screen:
self.assert_screen(
name="black_screen",
snap_path=snap_path / "app_context"
)
self.backend.right_click()
self.assert_screen(
name="home_screen",
snap_path=snap_path / "app_context"
)
received_chain_id, received_main_hwm, received_test_hwm = self.client.get_all_hwm()

assert received_chain_id == chain_id, \
Expand Down
Loading