Skip to content

fix(hive): enforce SLIP-48 path in SignTx + specific memo-length error#305

Merged
BitHighlander merged 2 commits into
developfrom
fix/hive-sign-hardening
Jul 15, 2026
Merged

fix(hive): enforce SLIP-48 path in SignTx + specific memo-length error#305
BitHighlander merged 2 commits into
developfrom
fix/hive-sign-hardening

Conversation

@BitHighlander

Copy link
Copy Markdown
Owner

Closes the two remaining hive-audit firmware findings (F3/F4) against rc9 (develop 9ce5a013).

F3 — path enforcement gap in HiveSignTx

HiveSignAccountCreate/HiveSignAccountUpdate already validate the SLIP-0048 path shape; the transfer handler did not — it derived from any host-supplied address_n. A compromised host could request a Hive signature with a key from another coin's derivation tree. fsm_msgHiveSignTx now enforces m/48'/13'/role'/account'/0' (all hardened, role ∈ {owner, active, memo, posting}) via the same hive_slip48_path_ok helper, hoisted above all three handlers.

F4 — memo-length silent failure

Memo >440 bytes previously died in the serializer bounds guard and surfaced as a generic "Hive signing failed". The handler now pre-checks and returns "Hive memo too long (max 440 bytes)". HIVE_MAX_MEMO_LEN moves to hive.h so handler and serializer share one limit; the serializer guard stays as backstop.

Documentation corrections (audit F1/F2 fallout)

  • hive.h: 13' is the de-facto Ledger-compatible network index (LedgerHQ/app-hive, hive-ledger-cli), not the slip-0048.md registry value (0xbee = 3054', which no wallet ships). Deliberate choice for seed-level ecosystem compatibility.
  • hive.c: hived post-HF28 enforces only BIP-0062 low-S (fc is_canonicalis_bip_0062_canonical; openhive-network/hive full_transaction.cpp); the strict legacy Graphene predicate we pass to ecdsa_sign_digest is belt-and-suspenders, kept.

python-keepkey pin bump (560b897 → 02fa3ea)

New negative coverage on BitHighlander/python-keepkey branch fix/hive-sign-hardening-tests:

  • foreign path (BIP-44 BTC), wrong network (3054'), unassigned role (2') — all rejected with "Invalid Hive SLIP-0048 path"
  • memo 441 → specific error; memo 440 boundary still signs and recovers to the active key
  • config.py: KK_FORCE_UDP=1 local-only escape hatch (skip HID/WebUSB autodetect when a real device is plugged in; not for CI)

Verification (local, macOS ARM64 emulator)

  • firmware-unit: 191/191 pass
  • test_msg_hive.py over UDP emulator: 10/10 pass (5 pre-existing + 5 new)

No wire-format or signature-byte changes — safe for the 7.15.0 line; the F6 attestation fixture can be captured on any hive-bearing rc.

- HiveSignTx now rejects address_n outside m/48'/13'/role'/account'/0'
  (account_create/update already enforced this; the transfer handler was
  the gap — a compromised host could request a Hive signature with a key
  from another coin's derivation tree)
- memo >440 bytes fails up front with a specific message instead of
  surfacing as a generic 'Hive signing failed' from the serializer guard
- HIVE_MAX_MEMO_LEN moves to hive.h so the fsm handler shares the limit
- hive.h documents that 13' is the de-facto Ledger-compatible network
  index, not the slip-0048.md registry value (0xbee); hive.c documents
  that hived post-HF28 only enforces BIP-0062 low-S, so the strict
  legacy canonical predicate is belt-and-suspenders
- pin python-keepkey 560b897 -> 02fa3ea: negative tests for all three
  path rejections + memo limit + 440 boundary

Emulator-verified on develop (rc9 base): 191/191 firmware-unit,
10/10 test_msg_hive.py over UDP emulator.
hive_slip48_path_ok now takes the required role: transfers demand
active' (post-HF28 hived rejects higher-role substitution, and the cold
owner key must never sign a spend), account_create/account_update demand
owner' (the sponsor attestation recovers to the device owner key, and
update replaces the owner authority itself).

Pin python-keepkey 02fa3ea -> 35555d7: transfer rejects owner/memo/
posting/unassigned roles; account ops reject an active-role path.
Emulator-verified: 191/191 firmware-unit, 11/11 test_msg_hive.py.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant