release: integrate 7.14.1 firmware updates#425
Conversation
a82357e to
81bdf19
Compare
CI's python-dylib-tests job runs `pytest test_dylib_screenshot.py` from
deps/python-keepkey/tests, but the previous submodule pin (7141dc8) did
not contain that file, so pytest exited 4 ("file or directory not
found") and the job failed.
Bump python-keepkey to 571c829, which adds the regression test for the
ringbuf capacity + DebugLinkGetState canvas-refresh fixes that landed
on this release branch.
…t tests The screenshot regression added in 40eda37 hung CI for 25min because tests/config.py had no KK_TRANSPORT=dylib branch, so it fell through to UDPTransport against an emulator that the python-dylib-tests job doesn't start. Bumps python-keepkey to f1a77c3 which adds: - keepkeylib/transport_dylib.py: ctypes singleton over libkkemu, pumps kkemu_poll on every read/write - tests/config.py: KK_TRANSPORT=dylib KK_DYLIB=... branch + a _KNOWN_TRANSPORTS guard so a typo'd value errors at import instead of silently falling back to UDP - tests/test_dylib_confirm_flow.py: confirm-flow regression (skipped pending the firmware confirm-helper fix) Verified locally: 5 passed, 1 skipped in 0.22s.
….1-python-keepkey)
Both release branches are now merged to master.
There was a problem hiding this comment.
Pull request overview
Integrates the upstream 7.14.1 firmware work into develop, adding new emulator capabilities (including an in-process shared library) and extending message-signing support for TRON/TON/Solana, along with CI coverage for the dylib emulator path.
Changes:
- Add
libkkemushared-library emulator mode (ring-buffer I/O, framebuffer capture) alongside the existing UDP-basedkkemubinary. - Add TRON TIP-191 signing + verify and TIP-712 typed-hash signing; add TON raw Ed25519 message signing (AdvancedMode-gated); add Solana off-chain domain-separated message signing.
- Extend CI to build and run python-keepkey dylib screenshot tests (macOS), and update build system options/policies for cross-directory linking + PIC.
Reviewed changes
Copilot reviewed 28 out of 28 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
CMakeLists.txt |
Adds CMP0079 policy handling and KK_BUILD_DYLIB option; enables global PIC when building dylib. |
tools/emulator/CMakeLists.txt |
Refactors firmware lib list and wires it into both kkemu (UDP) and kkemulator_dylib (shared lib) link steps. |
lib/emulator/CMakeLists.txt |
Adds kkemulator_dylib shared library target and includes new dylib-specific sources. |
lib/emulator/udp.c |
Adds dylib trampolines (ring-buffer mode) and supports configurable UDP port via env var in standalone mode. |
lib/emulator/setup.c |
Adds setup_urandom_only() for dylib mode initialization. |
lib/emulator/ringbuf.h |
Introduces ring buffer interface/constants for HID-report transport. |
lib/emulator/ringbuf.c |
Implements ring buffer push/pop used by the dylib transport. |
lib/emulator/libkkemu.c |
Implements libkkemu public API, ring-buffer transport, flash buffer handling, and display capture ring. |
include/keepkey/emulator/setup.h |
Exposes setup_urandom_only() for dylib build. |
include/keepkey/emulator/libkkemu.h |
Adds public C API for in-process emulator usage (init/poll/read/write/display/frame capture). |
lib/firmware/tron.c |
Adds TIP-191 message hashing/signing, signature verification, and TIP-712 typed-hash digest signing. |
lib/firmware/ton.c |
Adds raw Ed25519 message signing primitive for TON. |
lib/firmware/solana.c |
Adds Solana off-chain, domain-separated message signing envelope + signature generation. |
lib/firmware/messagemap.def |
Registers new TRON/TON/Solana message types and responses in the dispatch map. |
include/keepkey/firmware/fsm.h |
Declares new FSM handlers for TRON/TON/Solana message types. |
lib/firmware/fsm_msg_tron.h |
Adds TRON SignMessage / VerifyMessage / SignTypedHash handlers with on-device review flows. |
lib/firmware/fsm_msg_ton.h |
Adds TON SignMessage handler with AdvancedMode policy gate and user confirmation. |
lib/firmware/fsm_msg_solana.h |
Adds Solana SignOffchainMessage handler with format/version validation and confirmation UI. |
lib/firmware/fsm_msg_debug.h |
Adjusts DebugLinkGetState to refresh display without forcing animations. |
include/keepkey/transport/messages-tron.options |
Adds nanopb sizing constraints for new TRON message types. |
include/keepkey/transport/messages-ton.options |
Adds nanopb sizing constraints for TON SignMessage/response. |
include/keepkey/transport/messages-solana.options |
Adds nanopb sizing constraints for Solana off-chain message signing types. |
include/keepkey/firmware/tron.h |
Exposes TRON message sign/verify and TIP-712 typed-hash signing APIs. |
include/keepkey/firmware/ton.h |
Exposes TON message signing API and documents required policy gate. |
include/keepkey/firmware/solana.h |
Exposes Solana off-chain message signing API. |
.github/workflows/ci.yml |
Adds macOS dylib build + python-keepkey screenshot tests; threads dylib job into publish prerequisites and report label. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| /* | ||
| * Captures every display_refresh() into a ring of 1-bit packed snapshots. | ||
| * The host drains via kkemu_pop_frame(). Adjacent identical frames are | ||
| * skipped so an idle firmware doesn't spam the ring. | ||
| * | ||
| * Sized for ~4 seconds at 16ms refresh; if the host falls behind the | ||
| * oldest frames are dropped (write advances past read). | ||
| */ | ||
| #define FRAME_PACKED_SIZE 2048 | ||
| #define FRAME_RING_SIZE 64 |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Agent-Logs-Url: https://github.com/keepkey/keepkey-firmware/sessions/b03afbba-5c03-46ee-8b5f-2901060e7b9e Co-authored-by: pastaghost <62026038+pastaghost@users.noreply.github.com>
…ture Copilot autofix in 2746ed3 copy-pasted the has_* pattern from the TronMessageSignature path (where fields are 'optional' so nanopb emits has_* flags) into tron_typed_hash_sign(), where the response type is TronTypedDataSignature with 'required' fields — no has_* exists, so the build broke on every target.
| int kkemu_write(const uint8_t* data, size_t len, int iface) { | ||
| if (!libkkemu_initialized) return -1; | ||
| if (len != KKEMU_PACKET_SIZE) return -1; | ||
|
|
||
| RingBuf* rb = (iface == KKEMU_IFACE_MAIN) ? &rb_main_in : &rb_debug_in; | ||
| return ringbuf_push(rb, data, len) ? 0 : -1; | ||
| } | ||
|
|
||
| int kkemu_read(uint8_t* buf, size_t len, int iface) { | ||
| if (!libkkemu_initialized) return 0; | ||
| if (len < KKEMU_PACKET_SIZE) return 0; | ||
|
|
||
| RingBuf* rb = (iface == KKEMU_IFACE_MAIN) ? &rb_main_out : &rb_debug_out; |
There was a problem hiding this comment.
The Copilot sandbox token doesn't have permission to create issues in this repo. Here is the ready-to-file issue — please paste it into a new issue:
Title: libkkemu: kkemu_write/kkemu_read silently route invalid iface values to debug queue
Body:
Bug
kkemu_write() and kkemu_read() use a ternary to select the ring buffer:
// lib/emulator/libkkemu.c:245
RingBuf* rb = (iface == KKEMU_IFACE_MAIN) ? &rb_main_in : &rb_debug_in;
// lib/emulator/libkkemu.c:253
RingBuf* rb = (iface == KKEMU_IFACE_MAIN) ? &rb_main_out : &rb_debug_out;Any iface value that is not KKEMU_IFACE_MAIN (0) — including values like 2, -1, or 99 — is silently treated as KKEMU_IFACE_DEBUG (1). This makes API misuse invisible to callers and can cause cross-channel message contamination.
Expected behaviour
Both functions should explicitly validate iface and return an error for any value that is neither KKEMU_IFACE_MAIN nor KKEMU_IFACE_DEBUG.
Suggested fix
int kkemu_write(const uint8_t* data, size_t len, int iface) {
if (!libkkemu_initialized) return -1;
if (len != KKEMU_PACKET_SIZE) return -1;
if (iface != KKEMU_IFACE_MAIN && iface != KKEMU_IFACE_DEBUG) return -1;
RingBuf* rb = (iface == KKEMU_IFACE_MAIN) ? &rb_main_in : &rb_debug_in;
return ringbuf_push(rb, data, len) ? 0 : -1;
}
int kkemu_read(uint8_t* buf, size_t len, int iface) {
if (!libkkemu_initialized) return 0;
if (len < KKEMU_PACKET_SIZE) return 0;
if (iface != KKEMU_IFACE_MAIN && iface != KKEMU_IFACE_DEBUG) return 0;
RingBuf* rb = (iface == KKEMU_IFACE_MAIN) ? &rb_main_out : &rb_debug_out;
return ringbuf_pop(rb, buf, KKEMU_PACKET_SIZE) ? KKEMU_PACKET_SIZE : 0;
}Affected files
lib/emulator/libkkemu.c(lines 241–255)include/keepkey/emulator/libkkemu.h(API docs forkkemu_write/kkemu_read)
Context
Identified during review of the release-7141 PR (7.14.1 firmware integration).
There was a problem hiding this comment.
Try to create the issue again.
| if (!libkkemu_initialized) return 0; | ||
| if (len < KKEMU_PACKET_SIZE) return 0; | ||
|
|
||
| RingBuf* rb = (iface == KKEMU_IFACE_MAIN) ? &rb_main_out : &rb_debug_out; |
There was a problem hiding this comment.
The Copilot sandbox token doesn't have permission to create issues in this repo. Here is the ready-to-file issue — please paste it into a new issue:
Title: libkkemu: kkemu_read silently routes invalid iface values to debug queue
Body:
Bug
kkemu_read() selects the output ring buffer with a ternary:
// lib/emulator/libkkemu.c:253
RingBuf* rb = (iface == KKEMU_IFACE_MAIN) ? &rb_main_out : &rb_debug_out;Any iface value that is not KKEMU_IFACE_MAIN (0) — including garbage values like 2, -1, or 99 — is silently treated as KKEMU_IFACE_DEBUG (1). This makes API misuse invisible to callers and can cause callers to receive data from the wrong channel.
Expected behaviour
kkemu_read() should explicitly validate iface and return 0 (no data) for any value that is neither KKEMU_IFACE_MAIN nor KKEMU_IFACE_DEBUG.
Suggested fix
int kkemu_read(uint8_t* buf, size_t len, int iface) {
if (!libkkemu_initialized) return 0;
if (len < KKEMU_PACKET_SIZE) return 0;
if (iface != KKEMU_IFACE_MAIN && iface != KKEMU_IFACE_DEBUG) return 0;
RingBuf* rb = (iface == KKEMU_IFACE_MAIN) ? &rb_main_out : &rb_debug_out;
return ringbuf_pop(rb, buf, KKEMU_PACKET_SIZE) ? KKEMU_PACKET_SIZE : 0;
}Affected files
lib/emulator/libkkemu.c(lines 249–255)include/keepkey/emulator/libkkemu.h(API doc forkkemu_read)
Context
Identified during review of the release-7141 PR (7.14.1 firmware integration). See also the companion issue for kkemu_write() which has the same problem.
There was a problem hiding this comment.
Try to create the issue again.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
|
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details. Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
// kkemu_write (lib/emulator/libkkemu.c:245)
RingBuf* rb = (iface == KKEMU_IFACE_MAIN) ? &rb_main_in : &rb_debug_in;
// kkemu_read (lib/emulator/libkkemu.c:253)
Rin` (http block)
>
> If you need me to access, download, or install something from one of these locations, you can either:
>
> - Configure [Actions setup steps](https://gh.io/copilot/actions-setup-steps) to set up my environment, which run before the firewall is enabled
> - Add the appropriate URLs or hosts to the custom allowlist in this repository's [Copilot coding agent settings](https://github.com/keepkey/keepkey-firmware/settings/copilot/coding_agent) (admins only)
>
> </details> |
|
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details. Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
// lib/emulator/libkkemu.c:253
RingBuf* rb = (iface == KKEMU_IFACE_MAIN) ? &rb_main_out : &rb_debug_out;Any
|
…uced by 0f73158) The Copilot Autofix suggestion that broke the build at 2746ed3 was re-applied via the GitHub UI in 0f73158 with the same payload. TronTypedDataSignature.{address,signature} are 'required' in the proto so nanopb does not emit has_* flags — the lines do not compile. Please dismiss the underlying code-scanning finding rather than re-applying the suggested fix, or this will recur.
Summary
Integrates the 7.14.1 firmware work onto upstream
developfrom upstream branchrelease-7141.Includes:
deps/device-protocolto release: device-protocol 7.14.1 message-signing sync device-protocol#103 head73ca75fdeps/python-keepkeyto release: python-keepkey 7.14.1 message-signing bindings python-keepkey#194 head7141dc8Notes:
Validation
git diff --check keepkey/develop..HEAD