diff --git a/CHANGELOG.md b/CHANGELOG.md index c1c3337e..b2eec930 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [0.12.0] 2024-??-?? + +### Added + +- NFC always enabled on Stax & Flex OSes +- Starting Speculos with the `--nfc` argument will funel all communications as NFC + ## [0.11.0] 2024-11-12 ### Added diff --git a/speculos/mcu/nfc.py b/speculos/mcu/nfc.py index 28c1bd14..15278316 100644 --- a/speculos/mcu/nfc.py +++ b/speculos/mcu/nfc.py @@ -2,11 +2,9 @@ Forward NFC packets between the MCU and the SE """ -from abc import ABC, abstractmethod -from construct import Int8ub, Int16ub, Int16ul, Struct -import binascii import enum import logging +from typing import List, Optional class SephNfcTag(enum.IntEnum): @@ -18,42 +16,36 @@ class NFC: def __init__(self, _queue_event_packet): self._queue_event_packet = _queue_event_packet self.packets_to_send = [] - self.MTU=140 + self.MTU = 140 self.rx_sequence = 0 self.rx_size = 0 - self.rx_data = [] - + self.rx_data: bytes = b'' self.logger = logging.getLogger("nfc") - - def handle_rapdu_chunk(self, data): + def handle_rapdu_chunk(self, data: bytes) -> Optional[List[bytes]]: """concatenate apdu chunks into full apdu""" - # example of data # 0000050000002b3330000409312e302e302d72633104e600000008362e312e302d646508352e312e302d6465010001009000 # only APDU packets are suported if data[2] != 0x05: - return None + return sequence = int.from_bytes(data[3:5], 'big') - if self.rx_sequence != sequence: - print(f"Unexpected sequence number:{sequence}") - return None + assert self.rx_sequence == sequence, f"Unexpected sequence number:{sequence}" if sequence == 0: self.rx_size = int.from_bytes(data[5:7], "big") self.rx_data = data[7:] else: - self.rx_data.append(data[5:]) + self.rx_data += data[5:] if len(self.rx_data) == self.rx_size: - #prepare for next call + # prepare for next call self.rx_sequence = 0 return self.rx_data - - return None - + else: + self.rx_sequence += 1 def apdu(self, data): chunks: List[bytes] = [] @@ -65,11 +57,11 @@ def apdu(self, data): data = data[size:] for i, chunk in enumerate(chunks): - # ledger protocol header + # Ledger protocol header header = bytes([0x00, 0x00, 0x05]) # APDU header += i.to_bytes(2, "big") # first packet contains the size of full buffer if i == 0: header += data_len.to_bytes(2, "big") - self._queue_event_packet(SephNfcTag.NFC_APDU_EVENT, header+chunk) + self._queue_event_packet(SephNfcTag.NFC_APDU_EVENT, header + chunk) diff --git a/speculos/mcu/seproxyhal.py b/speculos/mcu/seproxyhal.py index 8d3b6147..b3532ced 100644 --- a/speculos/mcu/seproxyhal.py +++ b/speculos/mcu/seproxyhal.py @@ -459,7 +459,7 @@ def can_read(self, screen: DisplayNotifier): elif tag == SephTag.NFC_RAPDU: data = self.nfc.handle_rapdu_chunk(data) - if data: + if data is not None: for c in self.apdu_callbacks: c(data) screen.display.forward_to_apdu_client(data) diff --git a/src/bolos/os.c b/src/bolos/os.c index 596a13dd..ccbe8a67 100644 --- a/src/bolos/os.c +++ b/src/bolos/os.c @@ -9,6 +9,7 @@ #define OS_SETTING_PLANEMODE_OLD 5 #define OS_SETTING_PLANEMODE_NEW 6 #define OS_SETTING_SOUND 9 +#define OS_SETTING_FEATURES 14 #undef PATH_MAX #define PATH_MAX 1024 @@ -54,7 +55,7 @@ unsigned long sys_os_setting_get(unsigned int setting_id, return 1; } if (((hw_model == MODEL_STAX) || (hw_model == MODEL_FLEX)) && - setting_id == OS_SETTING_SOUND) { + (setting_id == OS_SETTING_SOUND || setting_id == OS_SETTING_FEATURES)) { return 0xff; } }