Skip to content
Open
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
42 changes: 15 additions & 27 deletions scripts/generate-test-report.py
Original file line number Diff line number Diff line change
Expand Up @@ -779,12 +779,11 @@ def parse_junit(path):
('V', 'EVM Clear-Signing', '7.14.0',
'NEW: Verified transaction metadata for EVM contracts. Host sends a signed blob with contract '
'name, function, and decoded parameters. Device verifies blob signature against trusted key, '
'then shows human-readable details with VERIFIED icon. AdvancedMode policy gates blind-signing '
'(disabled by default = blind signing blocked).',
'then shows human-readable details with VERIFIED icon. Blind-sign policy gating is deferred '
'to firmware 7.15+.',
[
'CLEAR-SIGN: Signed metadata -> verify signature -> VERIFIED icon + method + decoded args',
'BLIND BLOCKED: No metadata + AdvancedMode off -> device refuses',
'BLIND ALLOWED: No metadata + AdvancedMode on -> warning -> sign',
'BLIND SIGN: No metadata + AdvancedMode on -> contract data signed (no gate until 7.15+)',
],
[
('V1', 'test_msg_ethereum_clear_signing', 'test_valid_metadata_returns_verified',
Expand All @@ -800,22 +799,17 @@ def parse_junit(path):
'Tampered contract rejected', 'Modified contract address fails signature check.', []),
('V5', 'test_msg_ethereum_clear_signing', 'test_no_metadata_then_sign_unchanged',
'No metadata = blind sign path',
'Without metadata, transaction goes through blind-sign path (gated by AdvancedMode).',
'Without metadata, transaction goes through existing blind-sign path.',
['Blind sign warning']),
('V6', 'test_msg_ethereum_clear_signing', 'test_signature_verification',
'Signature verification math', 'Unit test for the metadata blob signature algorithm.', []),
('V7', 'test_msg_ethereum_clear_signing', 'test_tampered_blob_fails_verification',
'Tampered blob fails', 'Any byte change in the blob invalidates the signature.', []),
('V8', 'test_msg_ethereum_signtx', 'test_ethereum_blind_sign_blocked',
'Blind sign BLOCKED (AdvancedMode OFF)',
'Contract data with AdvancedMode disabled. Device shows BLOCKED screen and refuses to sign. '
'This is the default behavior -- blind signing must be explicitly enabled.',
['BLOCKED screen']),
('V9', 'test_msg_ethereum_signtx', 'test_ethereum_blind_sign_allowed',
'Blind sign ALLOWED (AdvancedMode ON)',
'Contract data with AdvancedMode enabled. Device shows BLIND SIGNATURE warning '
'before proceeding. User sees raw data and must explicitly confirm.',
['BLIND SIGNATURE warning']),
('V8', 'test_msg_ethereum_signtx', 'test_ethereum_blind_sign_allowed',
'Blind sign permitted (AdvancedMode ON)',
'Contract data with AdvancedMode enabled. Device allows signing. '
'Blind-sign blocking deferred to 7.15+.',
[]),
]),

('S', 'Solana', '7.14.0',
Expand Down Expand Up @@ -863,13 +857,11 @@ def parse_junit(path):
]),

('T', 'TRON', '7.14.0',
'NEW: TRON with protobuf deserialization and reconstruct-then-sign. 13 hardcoded TRC-20 tokens. '
'Device reconstructs tx hash from parsed fields (not raw blob) for clear-sign path.',
'NEW: TRON with secp256k1 signing, base58 addresses. Blind-sign via raw_data. '
'Structured reconstruct-then-sign and TRC-20 clear-signing deferred to 7.15+.',
[
'ADDRESS: m/44\'/195\'/0\'/0/0 -> full 34-char base58 TRON address',
'STRUCTURED: Parse fields -> reconstruct hash -> show amount + address -> sign',
'TRC-20: Decode transfer(to,amount) ABI -> show token name + decoded amount',
'LEGACY: Raw protobuf -> blind sign warning',
'BLIND-SIGN: Raw protobuf data -> hash + sign',
],
[
('T1', 'test_msg_tron_getaddress', 'test_tron_get_address',
Expand All @@ -880,13 +872,9 @@ def parse_junit(path):
'Deterministic derivation', 'Same path always produces same address.', []),
('T3b', 'test_msg_tron_getaddress', 'test_tron_show_address',
'Show address on OLED', 'Full 34-char Base58Check TRON address with QR code.', ['TRON QR + 34-char address']),
('T4', 'test_msg_tron_signtx', 'test_tron_sign_transfer_structured',
'Sign TRX transfer', 'Structured clear-sign with full address display.', ['TRX send']),
('T5', 'test_msg_tron_signtx', 'test_tron_sign_transfer_legacy_raw_data',
'Sign TRX legacy raw', 'Raw protobuf data triggers blind sign path.', ['Blind sign']),
('T6', 'test_msg_tron_signtx', 'test_tron_sign_trc20_transfer',
'Sign TRC-20 USDT transfer', 'Known TRC-20 token decoded from ABI data. Shows "Send 1.00 USDT to [address]".', ['Token + amount']),
('T7', 'test_msg_tron_signtx', 'test_tron_sign_missing_fields_rejected',
('T4', 'test_msg_tron_signtx', 'test_tron_sign_transfer_legacy_raw_data',
'Sign TRX blind (raw_data)', 'Raw protobuf data triggers blind sign path.', ['Blind sign']),
('T5', 'test_msg_tron_signtx', 'test_tron_sign_missing_fields_rejected',
'Missing fields rejected', 'Incomplete transaction data is refused.', []),
]),

Expand Down
32 changes: 4 additions & 28 deletions tests/test_msg_ethereum_signtx.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,36 +95,13 @@ def test_ethereum_signtx_data(self):

self.client.apply_policy("AdvancedMode", 0)

def test_ethereum_blind_sign_blocked(self):
"""AdvancedMode OFF + contract data = device refuses to sign.

OLED shows 'BLOCKED -- Blind signing requires AdvancedMode' then Failure.
"""
self.requires_firmware("7.14.0")
self.setup_mnemonic_nopin_nopassphrase()
self.client.apply_policy("AdvancedMode", 0)

try:
self.client.ethereum_sign_tx(
n=[0, 0],
nonce=0,
gas_price=20,
gas_limit=20,
to=binascii.unhexlify("1d1c328764a41bda0492b66baa30c4a339ff85ef"),
value=0,
data=b"abcdefghijklmnop" * 16,
)
self.fail("Expected Failure — blind signing should be blocked")
except CallException as e:
self.assertIn("Blind signing disabled", str(e))

def test_ethereum_blind_sign_allowed(self):
"""AdvancedMode ON + contract data = device shows BLIND SIGNATURE warning.
"""Contract data = device allows blind signing (no gate until 7.15+).

OLED shows 'BLIND SIGNATURE -- You are signing raw contract data'
before showing the data and allowing signing.
Blind-sign policy gating (AdvancedMode) is deferred to firmware 7.15+.
On 7.10-7.14 blind signing is always permitted with AdvancedMode ON.
"""
self.requires_firmware("7.14.0")
self.requires_fullFeature()
self.setup_mnemonic_nopin_nopassphrase()
self.client.apply_policy("AdvancedMode", 1)

Expand All @@ -137,7 +114,6 @@ def test_ethereum_blind_sign_allowed(self):
value=0,
data=b"abcdefghijklmnop" * 16,
)
# Should succeed — AdvancedMode allows blind signing
self.assertIsNotNone(sig_v)
self.client.apply_policy("AdvancedMode", 0)

Expand Down
4 changes: 4 additions & 0 deletions tests/test_msg_solana_signtx.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ def build_system_transfer_tx(from_pubkey, to_pubkey, lamports, blockhash=None):

tx = bytearray()

# Signature count (compact-u16: 0 signatures for unsigned tx)
tx.append(0)

# Header
tx.append(1) # num_required_sigs
tx.append(0) # num_readonly_signed
Expand Down Expand Up @@ -191,6 +194,7 @@ def _build_tx(self, from_pubkey, accounts, program_id, instr_data, extra_account
all_accounts = [from_pubkey] + (extra_accounts or []) + accounts + [program_id]
blockhash = b'\xBB' * 32
tx = bytearray()
tx.append(0) # signature count (compact-u16: 0 = unsigned)
tx.append(1) # num_required_sigs
tx.append(0) # num_readonly_signed
tx.append(1 + len(accounts) + (len(extra_accounts) if extra_accounts else 0)) # num_readonly_unsigned
Expand Down
10 changes: 8 additions & 2 deletions tests/test_msg_tron_signtx.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,11 @@ def test_tron_get_address(self):
self.assertTrue(resp.address.startswith('T'))
self.assertEqual(len(resp.address), 34)

@unittest.skip("Structured TRON signing deferred to 7.15+; firmware only supports raw_data blind-sign")
def test_tron_sign_transfer_structured(self):
"""Test TRX transfer using structured fields (reconstruct-then-sign)."""
"""Test TRX transfer using structured fields (reconstruct-then-sign).
Deferred to 7.15+ — firmware currently only supports raw_data path.
"""
self.requires_fullFeature()
self.setup_mnemonic_allallall()

Expand Down Expand Up @@ -112,8 +115,11 @@ def test_tron_sign_missing_fields_rejected(self):
with pytest.raises(CallException) as exc:
self.client.call(msg)

@unittest.skip("Structured TRON TRC-20 signing deferred to 7.15+; firmware only supports raw_data blind-sign")
def test_tron_sign_trc20_transfer(self):
"""Test TRC-20 USDT transfer using trigger_smart."""
"""Test TRC-20 USDT transfer using trigger_smart.
Deferred to 7.15+ — firmware currently only supports raw_data path.
"""
self.requires_fullFeature()
self.setup_mnemonic_allallall()

Expand Down
Loading