What changed, and why it matters
This commit fixes a low-level programming bug in how the Passport hardware wallet builds a special data format (CBOR) when exporting a public key to the Unchained Capital service. The original code passed raw numbers to a buffer-extension function in a way that could produce incorrect byte sequences. The fix wraps those numbers as explicit byte arrays. The commit also contains unrelated cosmetic changes to the simulator's README and adds clipboard keybindings to the simulator's terminal window.
Treat as a routine correctness fix. Review whether the old `_append_cbor_uint()` behavior could have produced parseable-but-wrong CBOR that might mislead Unchained Capital into deriving an unexpected multisig address. If so, consider a security advisory for users who exported keys before the fix. No urgent action is required for the simulator changes.
Security signals we found
CBOR serialization correctness fix in hardware-wallet export path
Potential for malformed or truncated public-key export payload before patch
No explicit security framing, CVE, or researcher attribution in commit
Changes limited to a single wallet integration module and simulator tooling
Evidence from the diff
In unchained.py, _append_cbor_uint() appends CBOR-encoded unsigned integers to a mutable bytearray using result.extend(...). The original code passed tuples of integers directly to extend(), which is valid for bytearray.extend() in CPython but is ambiguous and can behave differently depending on the exact iterable interpretation or MicroPython implementation. The patch converts each tuple to an explicit bytes(...) object before extending, ensuring deterministic byte-level output. This function is used inside create_unchained_hdkey_cbor() to serialize an HD public key for Unchained Capital accounts. The other two files (simulator/README.md and simulator/simulator.py) contain non-security changes: README whitespace removal and adding XTerm clipboard copy/paste resources.
Changed components
ports/stm32/boards/Passport/modules/wallets/unchained.pysimulator/README.mdsimulator/simulator.pyInspect captured patch +17 / −14
### ports/stm32/boards/Passport/modules/wallets/unchained.py
@@ -22,15 +22,15 @@ def _append_cbor_uint(result, value):
if value < 24:
result.append(value)
elif value <= 0xff:
- result.extend((0x18, value))
+ result.extend(bytes([0x18, value]))
elif value <= 0xffff:
- result.extend((0x19, value >> 8, value & 0xff))
+ result.extend(bytes([0x19, value >> 8, value & 0xff]))
else:
- result.extend((0x1a,
- (value >> 24) & 0xff,
- (value >> 16) & 0xff,
- (value >> 8) & 0xff,
- value & 0xff))
+ result.extend(bytes([0x1a,
+ (value >> 24) & 0xff,
+ (value >> 16) & 0xff,
+ (value >> 8) & 0xff,
+ value & 0xff]))
def create_unchained_hdkey_cbor(public_key,
### simulator/README.md
@@ -37,5 +37,3 @@ setenv PKG_CONFIG_PATH /usr/local/opt/libffi/lib/pkgconfig
- Sorry we haven't gotten around to that yet, but certainly would be possible to build
this on Linux or FreeBSD... but not Windows.
-
-
### simulator/simulator.py
@@ -459,11 +459,16 @@ def sock_cleanup():
+ sys.argv[1:]
print('cc_cmd: {}'.format(passport_cmd))
- xterm = subprocess.Popen(['xterm', '-title', 'Passport Simulator REPL',
- '-geom', '132x72+0+0', '-e'] + passport_cmd,
- env=env,
- stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL,
- pass_fds=pass_fds, shell=False)
+ xterm = subprocess.Popen([
+ 'xterm', '-title', 'Passport Simulator REPL', '-geom', '132x72+0+0',
+ '-xrm', 'XTerm*selectToClipboard: true',
+ '-xrm', 'XTerm*VT100*translations: #override\n'
+ 'Ctrl Shift <Key>C: copy-selection(CLIPBOARD)\n'
+ 'Ctrl Shift <Key>V: insert-selection(CLIPBOARD)',
+ '-e'] + passport_cmd,
+ env=env,
+ stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL,
+ pass_fds=pass_fds, shell=False)
print("COMMAND: " + " ".join(passport_cmd))
Why this scored 35/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.