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
2 changes: 1 addition & 1 deletion docs/release/7.14.2.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ landed, so the table below is the current state, not what #440 originally set.

| Path | Default device | Why |
|---|---|---|
| ETH `personal_sign` | **works** | `confirm_bytes()` paginates every signed byte, so #432's gate was dropped |
| ETH `personal_sign` | **works** | `confirm_bytes()` paginates every signed byte; hold scrolls quickly, release pauses, and a fresh final hold approves, so #432's gate was dropped |
| TRON `SignMessage` | **works** | same — pager, gate dropped |
| Bitcoin-family `SignMessage` | **works** | same |
| ETH **structured EIP-712** | **DISABLED** | withdrawn pending complete canonical hardening |
Expand Down
12 changes: 6 additions & 6 deletions docs/security/7.14.2-signing-hardening.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ what the device signs.
| Ethereum EIP-712 and TRON TIP-712 precomputed hashes | Require AdvancedMode, validate digest lengths, and show an explicit blind-signing warning before the existing address/hash confirmations. |
| Structured Ethereum EIP-712 | Fail closed at the endpoint. The legacy parser/display path is disabled until canonical types, values, JSON shape, addresses, integers, booleans, and primary type are fully bound to the hash. |
| EOS unknown actions | Require AdvancedMode and include `EOS_NewAccount` in the structured-action allowlist. The gate does not depend on `review()`, which discards `confirm_helper()`'s result on this line. |
| Exact signed-content review | Add an exact-byte OLED pager. Spaces, backslashes, controls, and non-ASCII bytes are rendered as `\xNN`; page boundaries are calculated from the actual OLED font metrics; every page requires confirmation. This closes the #428 leading-whitespace and clipped-suffix pattern without changing unrelated generic dialogs. |
| Exact signed-content review | Add an exact-byte OLED pager. Spaces, backslashes, controls, and non-ASCII bytes are rendered as `\xNN`; page boundaries are calculated from the actual OLED renderer, including a rejected final glyph. Holding the button advances at 120 ms per page, releasing pauses on the current page, and reaching the final page requires a release plus a fresh hold before approval. The same renderer-backed scrolling replaces the generic `Cut Off` warning for complete formatted bodies. This closes the #428 leading-whitespace and clipped-suffix pattern without approving a prefix. |
| Binance transfers | Validate the complete transfer shape, positive/equal amounts, canonical bounded denomination grammar, message/session state, and serialization results before signing. |
| Cosmos IBC | Retain receiver disclosure, require the signed `uatom` denomination, and review sender/receiver through the exact-byte pager. |
| Generic Tendermint | Bind every ACK to the initialized protocol and the original chain name, denomination, and message-type prefix; use those bound values for display and hashing. |
Expand All @@ -39,11 +39,11 @@ structured EIP-712 endpoint.
## Regression evidence

- Pinned `kktech/firmware:v15` emulator build: passed.
- Board unit tests: 6/6 passed, including exact rendering of whitespace,
newlines, backslashes, embedded NULs, and an oversized whitespace-prefix
payload whose suffix must appear on a later page.
- Focused firmware tests: 16/16 passed across Binance, Cosmos/Tendermint, EOS,
and Ethereum policy/parser behavior.
- Board unit tests: 11/11 passed, including exact rendering of whitespace,
newlines, backslashes, embedded NULs, complete long-hex pagination at both
standard and icon widths, and an oversized whitespace-prefix payload whose
suffix must appear on a later page.
- Firmware unit tests: 78/78 passed across the complete emulator unit target.
- Crypto unit tests: 4/4 passed.
- Release-style `arm-none-eabi` build: `firmware.keepkey.elf` linked
successfully.
Expand Down
41 changes: 39 additions & 2 deletions include/keepkey/board/confirm_sm.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#include "keepkey/board/layout.h"

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

/* implement a means to display debug information */
#ifdef DEBUG_ON
Expand Down Expand Up @@ -53,7 +55,19 @@
/* The number of milliseconds to wait for a confirmation */
#define CONFIRM_TIMEOUT_MS 1200

typedef enum { HOME, CONFIRM_WAIT, CONFIRMED, FINISHED } DisplayState;
/* Long confirmations advance quickly while the button remains down. The
* initial delay prevents an ordinary tap from skipping the first page; later
* pages move at roughly eight screens per second. */
#define CONFIRM_SCROLL_INITIAL_MS 300
#define CONFIRM_SCROLL_PERIOD_MS 120

typedef enum {
HOME,
SCROLLING,
CONFIRM_WAIT,
CONFIRMED,
FINISHED
} DisplayState;

typedef enum {
LAYOUT_REQUEST,
Expand Down Expand Up @@ -86,17 +100,40 @@ typedef struct {
typedef void (*layout_notification_t)(const char* str1, const char* str2,
NotificationType type);

/** Format the largest displayable prefix of data into a NUL-terminated page.
*
* The return value is the number of input bytes represented by the page.
*/
typedef size_t (*confirm_page_formatter_t)(const uint8_t* data, size_t size,
char* out, size_t out_len,
uint16_t body_width);

/// \brief Will a confirmation body fit on the screen it is drawn on?
///
/// draw_string() stops drawing once a glyph no longer fits the canvas and
/// reports nothing, so a body taller than BODY_ROWS rows is shown in part with
/// nothing on screen to say so. Callers that measure first can say so.
/// nothing on screen to say so. Callers use this boundary to paginate first.
///
/// \param body The body text as it will be drawn (NULL reads as "").
/// \param body_width Wrap width: BODY_WIDTH, or BODY_WIDTH_WITH_ICON.
/// \returns true iff the whole body will be on screen.
bool confirm_body_fits(const char* body, uint16_t body_width);

/** Split ordinary confirmation text using the real OLED renderer boundary. */
size_t confirm_body_format_page(const uint8_t* data, size_t size, char* out,
size_t out_len, uint16_t body_width);

/**
* Confirm a formatter-backed, potentially multi-page value.
*
* A long value starts on page one. Holding advances pages automatically;
* releasing pauses on the current page. After the final page has been shown,
* the user must release and perform a fresh hold to approve.
*/
bool confirm_paged(ButtonRequestType type, const char* request_title,
const uint8_t* data, size_t size,
confirm_page_formatter_t formatter);

/// User confirmation.
/// \param type The kind of button request to send to the host.
/// \param request_title Title of confirm message.
Expand Down
Loading