Skip to content
Closed
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
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.
17 changes: 17 additions & 0 deletions docs/security/evidence/rom-printf-integer-percent/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Integer percent rendering on the THOR/Maya withdraw confirm

Emulator captures for the change that routes all device `snprintf` calls to
newlib's integer-only `sniprintf` and rewrites the last two float format
users (`%3.2f` in `thorchain.c` / `mayachain.c`) as integer basis-point math.

- `01-thorchain-withdraw-25.05pct.png` — ETH router `deposit()` carrying memo
`WITHDRAW:ETH.USDT-0xdac17f958d2ee523a2206206994597c13d831ec7:2505`.
2505 bps renders as `25.05%`: the integer path preserves the `%02d`
zero-padding of the fractional digits.
- `02-thorchain-sending-eth.png` — the amount screen from the same flow,
showing `%llu`-family rendering is unaffected.

Reproduce with `scripts/emulator/capture-thor-percent.py` against kkemu
(`KEEPKEY_SCREENSHOT=1`, abandon test seed, no PIN). Emulator captures do not
satisfy Gate-3 on their own — an on-device pass of the THOR withdraw screen
and one Osmosis `%llu` amount screen is still owed before release.
28 changes: 28 additions & 0 deletions include/keepkey/board/bsd_compat.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#ifndef KEEPKEY_BOARD_BSD_COMPAT_H
#define KEEPKEY_BOARD_BSD_COMPAT_H

/*
* Declarations for BSD libc extensions that macOS/BSD expose via <string.h>
* but glibc (Linux) and MinGW (Windows) do not. The emulator build compiles
* lib/board/strlcpy.c + strlcat.c when the libc lacks the definitions
* (KK_HAVE_STRLCPY / KK_HAVE_STRLCAT), so only the prototypes are missing.
*
* Force-included for non-Apple emulator builds (see CMakeLists.txt) so every
* translation unit sees the prototypes without us having to chase down ~20
* call sites — and without touching the real hardware (ARM) build at all.
*/

#include <stddef.h>

#ifdef __cplusplus
extern "C" {
#endif

size_t strlcpy(char *dst, const char *src, size_t siz);
size_t strlcat(char *dst, const char *src, size_t siz);

#ifdef __cplusplus
}
#endif

#endif /* KEEPKEY_BOARD_BSD_COMPAT_H */
4 changes: 4 additions & 0 deletions include/keepkey/board/confirm_sm.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ bool confirm(ButtonRequestType type, const char* request_title,
const char* request_body, ...)
__attribute__((format(printf, 3, 4)));

bool confirm_with_icon(ButtonRequestType type, IconType iconNum,
const char* request_title, const char* request_body, ...)
__attribute__((format(printf, 4, 5)));

bool confirm_constant_power(ButtonRequestType type, const char* request_title,
const char* request_body, ...)
__attribute__((format(printf, 3, 4)));
Expand Down
25 changes: 25 additions & 0 deletions include/keepkey/board/draw.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,31 @@ void draw_char_simple(Canvas* canvas, const Font* font, char c, uint8_t color,
void draw_box(Canvas* canvas, BoxDrawableParams* p);
void draw_box_simple(Canvas* canvas, uint8_t color, uint16_t x, uint16_t y,
uint16_t width, uint16_t height);
/*
* draw_bitmap_mono_rle_valid() - Validate an RLE stream against a geometry.
*
* Pure and side-effect-free: decodes nothing, writes nothing, touches no
* canvas. Returns true iff the stream is EXACTLY well-formed for a w*h image:
* - every packet count is valid (never 0, never 0x80/-128 — the decoder's
* counter is int8_t and cannot represent a 128 literal),
* - no run straddles the end of the image,
* - exactly w*h pixels are produced, and
* - the whole input is consumed (no trailing packets).
*
* The drawing path is lenient by construction (it stops once the canvas is
* full), so callers that accept host-supplied streams MUST validate here at
* the trust boundary rather than infer validity from a successful draw.
*
* INPUT
* - data: RLE stream
* - length: stream length in bytes
* - w, h: target image geometry
* OUTPUT
* true iff the stream decodes exactly to w*h pixels
*/
bool draw_bitmap_mono_rle_valid(const uint8_t* data, uint32_t length,
uint16_t w, uint16_t h);

bool draw_bitmap_mono_rle(Canvas* canvas, const AnimationFrame* frame,
bool erase);

Expand Down
5 changes: 5 additions & 0 deletions include/keepkey/board/font.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#ifndef FONT_H
#define FONT_H

#include <stddef.h>
#include <stdint.h>

/* Data pertaining to the image of a character */
Expand Down Expand Up @@ -53,5 +54,9 @@ uint32_t font_width(const Font* font);

uint32_t calc_str_width(const Font* font, const char* str);
uint32_t calc_str_line(const Font* font, const char* str, uint16_t line_width);
uint32_t calc_str_line_n(const Font* font, const char* str, size_t str_len,
uint16_t line_width);
size_t calc_str_page(const Font* font, const char* str, size_t str_len,
uint16_t line_width, uint32_t max_lines);

#endif
15 changes: 15 additions & 0 deletions include/keepkey/board/layout.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ typedef enum {
typedef enum {
NO_ICON = 0,
ETHEREUM_ICON,
VERIFIED_ICON,
/* A runtime-supplied 1bpp mono RLE bitmap (e.g. a loaded clear-sign identity
* logo). The frame is set via layout_set_runtime_icon() before the confirm;
* drawn by layout_add_icon(). */
RUNTIME_ICON,
} IconType;

typedef void (*AnimateCallback)(void* data, uint32_t duration,
Expand Down Expand Up @@ -111,6 +116,12 @@ void layout_constant_power_notification(const char* str1, const char* str2,
NotificationType type);
void layout_notification_icon(NotificationType type, DrawableParams* sp);
void layout_add_icon(IconType type);

/// \brief Set the frame drawn for RUNTIME_ICON on the next confirm. Pass NULL
/// to clear. The AnimationFrame + its Image must outlive the confirm
/// (typically file-static in the caller).
struct AnimationFrame_;
void layout_set_runtime_icon(const struct AnimationFrame_* frame);
void layout_warning(const char* str);
void layout_warning_static(const char* str);
void layout_simple_message(const char* str);
Expand All @@ -124,6 +135,10 @@ void animating_progress_handler(const char* desc, int permil);
void layoutProgress(const char* desc, int permil);
void layoutProgressForAuth(const char* otp, const char* desc, int permil);
void layoutProgressSwipe(const char* desc, int permil);
void layoutProgressTrickle(const char* desc, int base_permil,
int target_permil);
void layoutProgressTrickleStop(void);
void layout_animate_poll(void);
void layout_add_animation(AnimateCallback callback, void* data,
uint32_t duration);
void layout_animate_images(void* data, uint32_t duration, uint32_t elapsed);
Expand Down
5 changes: 2 additions & 3 deletions include/keepkey/board/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,7 @@ void dec64_to_str(uint64_t dec64_val, char* str);

bool is_valid_ascii(const uint8_t* data, uint32_t size);

int base_to_precision(uint8_t* dest, const uint8_t* value,
const uint8_t dest_len, const uint8_t value_len,
const uint8_t precision);
int base_to_precision(uint8_t* dest, const uint8_t* value, size_t dest_len,
size_t value_len, uint8_t precision);

#endif
14 changes: 14 additions & 0 deletions include/keepkey/firmware/app_confirm.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

#include <inttypes.h>
#include <stdbool.h>
#include <stddef.h>

#define CONFIRM_SIGN_IDENTITY_TITLE 32
#define CONFIRM_SIGN_IDENTITY_BODY 416
Expand All @@ -46,10 +47,23 @@ bool confirm_load_device(bool is_node);
bool confirm_address(const char* desc, const char* address);
bool confirm_xpub(const char* node_str, const char* xpub);
bool confirm_sign_identity(const IdentityType* identity, const char* challenge);
/**
* Review every byte of a length-delimited payload. Printable ASCII and LF line
* breaks are paged as text; any payload containing another control/non-ASCII
* byte is paged as complete hexadecimal. Page boundaries use the OLED
* renderer's actual font and word-wrap budget, so no accepted byte can be
* clipped below the third row.
*/
bool confirm_bytes_is_text(const uint8_t* data, size_t size);
bool confirm_bytes(ButtonRequestType button_request, const char* title,
const uint8_t* data, size_t size);
bool confirm_cosmos_address(const char* desc, const char* address);
bool confirm_osmosis_address(const char* desc, const char* address);
bool confirm_ethereum_address(const char* desc, const char* address);
bool confirm_nano_address(const char* desc, const char* address);
#if ZCASH_PRIVACY
bool confirm_zcash_address(const char* desc, const char* address);
#endif
bool confirm_omni(ButtonRequestType button_request, const char* title,
const uint8_t* data, uint32_t size);
bool confirm_data(ButtonRequestType button_request, const char* title,
Expand Down
10 changes: 9 additions & 1 deletion include/keepkey/firmware/app_layout.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,16 @@ void layout_ethereum_address_notification(const char* desc, const char* address,
NotificationType type);
void layout_nano_address_notification(const char* desc, const char* address,
NotificationType type);
#if ZCASH_PRIVACY
void layout_zcash_address_notification(const char* desc, const char* address,
NotificationType type);
void layout_zcash_address_text_notification(const char* desc,
const char* address,
NotificationType type);
#endif
void layout_pin(const char* str, char* pin);
void layout_cipher(const char* current_word, const char* cipher);
void layout_cipher(const char* current_word, const char* cipher,
const char* prev_word_info);
void layout_address(const char* address, QRSize qr_size);
void set_leaving_handler(leaving_handler_t leaving_func);

Expand Down
51 changes: 39 additions & 12 deletions lib/board/confirm_sm.c
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,29 @@ bool confirm(ButtonRequestType type, const char* request_title,
return ret;
}

bool confirm_with_icon(ButtonRequestType type, IconType iconNum,
const char* request_title, const char* request_body,
...) {
button_request_acked = false;

va_list vl;
va_start(vl, request_body);
vsnprintf(strbuf, sizeof(strbuf), request_body, vl);
va_end(vl);

ButtonRequest resp;
memset(&resp, 0, sizeof(ButtonRequest));
resp.has_code = true;
resp.code = type;
msg_write(MessageType_MessageType_ButtonRequest, &resp);

bool ret =
confirm_helper(request_title, strbuf, &layout_standard_notification,
false, iconNum, false);
memzero(strbuf, sizeof(strbuf));
return ret;
}

bool confirm_constant_power(ButtonRequestType type, const char* request_title,
const char* request_body, ...) {
button_request_acked = false;
Expand Down Expand Up @@ -414,10 +437,11 @@ bool review(ButtonRequestType type, const char* request_title,
resp.code = type;
msg_write(MessageType_MessageType_ButtonRequest, &resp);

(void)confirm_helper(request_title, strbuf, &layout_standard_notification,
false, NO_ICON, false);
bool ret =
confirm_helper(request_title, strbuf, &layout_standard_notification,
false, NO_ICON, false);
memzero(strbuf, sizeof(strbuf));
return true;
return ret;
}

bool review_without_button_request(const char* request_title,
Expand All @@ -429,10 +453,11 @@ bool review_without_button_request(const char* request_title,
vsnprintf(strbuf, sizeof(strbuf), request_body, vl);
va_end(vl);

(void)confirm_helper(request_title, strbuf, &layout_standard_notification,
false, NO_ICON, false);
bool ret =
confirm_helper(request_title, strbuf, &layout_standard_notification,
false, NO_ICON, false);
memzero(strbuf, sizeof(strbuf));
return true;
return ret;
}

bool review_with_icon(ButtonRequestType type, IconType iconNum,
Expand All @@ -452,10 +477,11 @@ bool review_with_icon(ButtonRequestType type, IconType iconNum,
resp.code = type;
msg_write(MessageType_MessageType_ButtonRequest, &resp);

(void)confirm_helper(request_title, strbuf, &layout_standard_notification,
false, iconNum, false);
bool ret =
confirm_helper(request_title, strbuf, &layout_standard_notification,
false, iconNum, false);
memzero(strbuf, sizeof(strbuf));
return true;
return ret;
}

bool review_immediate(ButtonRequestType type, const char* request_title,
Expand All @@ -474,8 +500,9 @@ bool review_immediate(ButtonRequestType type, const char* request_title,
resp.code = type;
msg_write(MessageType_MessageType_ButtonRequest, &resp);

(void)confirm_helper(request_title, strbuf, &layout_standard_notification,
false, NO_ICON, true);
bool ret =
confirm_helper(request_title, strbuf, &layout_standard_notification,
false, NO_ICON, true);
memzero(strbuf, sizeof(strbuf));
return true;
return ret;
}
Loading
Loading