From 576af29b1656a96cbc6f30a4326ad79f1d68401a Mon Sep 17 00:00:00 2001 From: jpk68 Date: Tue, 4 Aug 2026 15:49:56 -0400 Subject: [PATCH] device_trezor: update protobuf definitions --- cmake/CheckTrezor.cmake | 1 + src/device_trezor/CMakeLists.txt | 2 + src/device_trezor/trezor/fetch_protob.sh | 4 +- .../trezor/protob/messages-common.proto | 110 ++-- .../trezor/protob/messages-debug.proto | 248 ++++++-- .../trezor/protob/messages-management.proto | 549 +++++++++++++----- .../trezor/protob/messages-monero.proto | 101 ++-- .../trezor/protob/messages.proto | 240 +++++--- src/device_trezor/trezor/protob/options.proto | 72 +++ 9 files changed, 961 insertions(+), 366 deletions(-) create mode 100644 src/device_trezor/trezor/protob/options.proto diff --git a/cmake/CheckTrezor.cmake b/cmake/CheckTrezor.cmake index b436e2df5..effeac875 100644 --- a/cmake/CheckTrezor.cmake +++ b/cmake/CheckTrezor.cmake @@ -123,6 +123,7 @@ endif() if(Protobuf_FOUND AND USE_DEVICE_TREZOR) # .proto files to compile set(_proto_files "messages.proto" + "options.proto" "messages-common.proto" "messages-management.proto" "messages-monero.proto") diff --git a/src/device_trezor/CMakeLists.txt b/src/device_trezor/CMakeLists.txt index 8da075aec..80e932f02 100644 --- a/src/device_trezor/CMakeLists.txt +++ b/src/device_trezor/CMakeLists.txt @@ -28,6 +28,7 @@ set(TREZOR_PROTOB_H trezor/messages/messages.pb.h + trezor/messages/options.pb.h trezor/messages/messages-common.pb.h trezor/messages/messages-management.pb.h trezor/messages/messages-monero.pb.h @@ -35,6 +36,7 @@ set(TREZOR_PROTOB_H set(TREZOR_PROTOB_CPP trezor/messages/messages.pb.cc + trezor/messages/options.pb.cc trezor/messages/messages-common.pb.cc trezor/messages/messages-management.pb.cc trezor/messages/messages-monero.pb.cc diff --git a/src/device_trezor/trezor/fetch_protob.sh b/src/device_trezor/trezor/fetch_protob.sh index 2ca138f13..3b6c95ed6 100755 --- a/src/device_trezor/trezor/fetch_protob.sh +++ b/src/device_trezor/trezor/fetch_protob.sh @@ -9,13 +9,13 @@ fi cd trezor-common git fetch -git reset --hard bc28c316d05bf1e9ebfe3d7df1ab25831d98d168 +git reset --hard 06735a46718edf383e453febf8a870fb71ae1789 cd .. rm -rf protob mkdir protob -proto_files="messages.proto messages-common.proto messages-monero.proto messages-management.proto messages-debug.proto" +proto_files="messages.proto messages-common.proto messages-monero.proto messages-management.proto messages-debug.proto options.proto" for file in ${proto_files} do diff --git a/src/device_trezor/trezor/protob/messages-common.proto b/src/device_trezor/trezor/protob/messages-common.proto index e7a0ac715..1e15784ee 100644 --- a/src/device_trezor/trezor/protob/messages-common.proto +++ b/src/device_trezor/trezor/protob/messages-common.proto @@ -1,20 +1,21 @@ syntax = "proto2"; package hw.trezor.messages.common; +import "options.proto"; + // Sugar for easier handling in Java -option java_package = "com.satoshilabs.trezor.lib.protobuf"; option java_outer_classname = "TrezorMessageCommon"; +option java_package = "com.satoshilabs.trezor.lib.protobuf"; +// Include in BTC-only firmware option (include_in_bitcoin_only) = true; -import "messages.proto"; - /** * Response: Success of the previous request * @end */ message Success { - optional string message = 1 [default=""]; // human readable description of action or request-specific payload + optional string message = 1 [default = ""]; // human readable description of action or request-specific payload } /** @@ -39,6 +40,11 @@ message Failure { Failure_PinMismatch = 12; Failure_WipeCodeMismatch = 13; Failure_InvalidSession = 14; + Failure_Busy = 15; + Failure_ThpUnallocatedSession = 16; + Failure_InvalidProtocol = 17; + reserved 18; + Failure_InProgress = 19; Failure_FirmwareError = 99; } } @@ -49,11 +55,18 @@ message Failure { * @next ButtonAck */ message ButtonRequest { - optional ButtonRequestType code = 1; // enum identifier of the screen + optional ButtonRequestType code = 1; // enum identifier of the screen (deprecated) optional uint32 pages = 2; // if the screen is paginated, number of pages + + // this existed briefly: + // https://github.com/trezor/trezor-firmware/commit/1012ee8497b241e8ca559e386d936fa549bc0357 + reserved 3; + + optional string name = 4; // name of the screen + /** - * Type of button request - */ + * Type of button request + */ enum ButtonRequestType { ButtonRequest_Other = 1; ButtonRequest_FeeOverThreshold = 2; @@ -68,7 +81,7 @@ message ButtonRequest { ButtonRequest_PublicKey = 11; ButtonRequest_MnemonicWordCount = 12; ButtonRequest_MnemonicInput = 13; - _Deprecated_ButtonRequest_PassphraseType = 14 [deprecated=true]; + _Deprecated_ButtonRequest_PassphraseType = 14 [deprecated = true]; ButtonRequest_UnknownDerivationPath = 15; ButtonRequest_RecoveryHomepage = 16; ButtonRequest_Success = 17; @@ -82,8 +95,7 @@ message ButtonRequest { * Request: Computer agrees to wait for HW button press * @auxend */ -message ButtonAck { -} +message ButtonAck {} /** * Response: Device is asking computer to show PIN matrix and awaits PIN encoded using this matrix scheme @@ -93,8 +105,8 @@ message ButtonAck { message PinMatrixRequest { optional PinMatrixRequestType type = 1; /** - * Type of PIN request - */ + * Type of PIN request + */ enum PinMatrixRequestType { PinMatrixRequestType_Current = 1; PinMatrixRequestType_NewFirst = 2; @@ -109,7 +121,7 @@ message PinMatrixRequest { * @auxend */ message PinMatrixAck { - required string pin = 1; // matrix encoded PIN entered by user + required string pin = 1; // matrix encoded PIN entered by user } /** @@ -118,7 +130,7 @@ message PinMatrixAck { * @next PassphraseAck */ message PassphraseRequest { - optional bool _on_device = 1 [deprecated=true]; // <2.3.0 + reserved 1; // bool on_device, deprecated in 2.3.0 } /** @@ -127,27 +139,8 @@ message PassphraseRequest { */ message PassphraseAck { optional string passphrase = 1; - optional bytes _state = 2 [deprecated=true]; // <2.3.0 - optional bool on_device = 3; // user wants to enter passphrase on the device -} - -/** - * Response: Device awaits passphrase state - * Deprecated in 2.3.0 - * @next Deprecated_PassphraseStateAck - */ -message Deprecated_PassphraseStateRequest { - option deprecated = true; - optional bytes state = 1; // actual device state -} - -/** - * Request: Send passphrase state back - * Deprecated in 2.3.0 - * @auxend - */ -message Deprecated_PassphraseStateAck { - option deprecated = true; + reserved 2; // bytes state, deprecated in 2.3.0 + optional bool on_device = 3; // user wants to enter passphrase on the device } /** @@ -163,3 +156,50 @@ message HDNodeType { optional bytes private_key = 5; required bytes public_key = 6; } + +/** + * Structure representing a SLIP-0024 payment request. + * @embed + */ +message PaymentRequest { + optional bytes nonce = 1; // the nonce used in the signature computation + required string recipient_name = 2; // merchant's name + repeated PaymentRequestMemo memos = 3; // any memos that were signed as part of the request + reserved 4; // this existed briefly. obsoleted by this change: + // https://github.com/satoshilabs/slips/commit/08d36aa61722275a21617ac6a713e31ec23fdec4 + optional bytes amount = 6; // the sum of the external output amounts requested, encoded in little endian on either + // 8 or 32 bytes required for non-CoinJoin transactions; do not set this for fiat + // amounts (BUY crypto with fiat) + required bytes signature = 5; // the trusted party's signature of the paymentRequestDigest + + message PaymentRequestMemo { + optional TextMemo text_memo = 1; + optional RefundMemo refund_memo = 2; + optional CoinPurchaseMemo coin_purchase_memo = 3; + optional TextDetailsMemo text_details_memo = 4; + } + + message TextMemo { + required string text = 1; // plain-text note explaining the purpose of the payment request + } + + message TextDetailsMemo { + required string title = 1; // plain-text heading + required string text = 2; // plain-text note containing additional details about the payment + } + + message RefundMemo { + required string address = 1; // the address where the payment should be refunded if necessary + repeated uint32 address_n = 2; // BIP-32 path to derive the key from the master node + required bytes mac = 3; // the MAC returned by GetAddress + } + + message CoinPurchaseMemo { + required uint32 coin_type = 1; // the SLIP-0044 coin type of the address + required string amount = 2; // the amount the address will receive as a human-readable + // string including units, e.g. "0.025 BTC" + required string address = 3; // the address where the coin purchase will be delivered + repeated uint32 address_n = 4; // BIP-32 path to derive the key from the master node + required bytes mac = 5; // the MAC returned by GetAddress + } +} diff --git a/src/device_trezor/trezor/protob/messages-debug.proto b/src/device_trezor/trezor/protob/messages-debug.proto index efe347b27..f9ec44dee 100644 --- a/src/device_trezor/trezor/protob/messages-debug.proto +++ b/src/device_trezor/trezor/protob/messages-debug.proto @@ -1,15 +1,16 @@ syntax = "proto2"; package hw.trezor.messages.debug; -// Sugar for easier handling in Java -option java_package = "com.satoshilabs.trezor.lib.protobuf"; -option java_outer_classname = "TrezorMessageDebug"; - -option (include_in_bitcoin_only) = true; - -import "messages.proto"; import "messages-common.proto"; import "messages-management.proto"; +import "options.proto"; + +// Sugar for easier handling in Java +option java_outer_classname = "TrezorMessageDebug"; +option java_package = "com.satoshilabs.trezor.lib.protobuf"; + +// Include in BTC-only firmware +option (include_in_bitcoin_only) = true; /** * Request: "Press" the button on the device @@ -17,12 +18,12 @@ import "messages-management.proto"; * @next DebugLinkLayout */ message DebugLinkDecision { - optional DebugButton button = 1; // button press + optional DebugButton button = 1; // button press optional DebugSwipeDirection swipe = 2; // swipe direction - optional string input = 3; // keyboard input + optional string input = 3; // keyboard input /** - * Structure representing swipe direction - */ + * Structure representing swipe direction + */ enum DebugSwipeDirection { UP = 0; DOWN = 1; @@ -31,26 +32,50 @@ message DebugLinkDecision { } /** - * Structure representing button presses - */ + * Structure representing button presses + */ enum DebugButton { NO = 0; YES = 1; INFO = 2; } - optional uint32 x = 4; // touch X coordinate - optional uint32 y = 5; // touch Y coordinate - optional bool wait = 6; // wait for layout change - optional uint32 hold_ms = 7; // touch hold duration + /** + * Structure representing button presses of UI Caesar + */ + // TODO: probably delete the middle_btn as it is not a physical one + enum DebugPhysicalButton { + LEFT_BTN = 0; + MIDDLE_BTN = 1; + RIGHT_BTN = 2; + } + + optional uint32 x = 4; // touch X coordinate + optional uint32 y = 5; // touch Y coordinate + optional bool wait = 6 [deprecated = true]; // wait for layout change + optional uint32 hold_ms = 7; // touch hold duration + optional DebugPhysicalButton physical_button = 8; // physical button press + + /** + * Explicit touch event type, used to separate TOUCH_START and TOUCH_END + * If not set, defaults to full click behavior (TOUCH_START + optional hold + TOUCH_END) + */ + enum DebugTouchEventType { + TOUCH_FULL_CLICK = 0; + TOUCH_START = 1; + TOUCH_END = 2; + } + + optional DebugTouchEventType touch_event_type = 9; } /** - * Response: Device text layout + * Response: Device text layout as a list of tokens as returned by Rust * @end */ message DebugLinkLayout { - repeated string lines = 1; + option deprecated = true; + repeated string tokens = 1; } /** @@ -68,18 +93,38 @@ message DebugLinkReseedRandom { * @next Success */ message DebugLinkRecordScreen { - optional string target_directory = 1; // empty or missing to stop recording + optional string target_directory = 1; // empty or missing to stop recording + optional uint32 refresh_index = 2 [default = 0]; // which index to give the screenshots (after emulator restarts) } /** - * Request: Computer asks for device state + * Request: Host asks for device state * @start * @next DebugLinkState */ message DebugLinkGetState { - optional bool wait_word_list = 1; // Trezor T only - wait until mnemonic words are shown - optional bool wait_word_pos = 2; // Trezor T only - wait until reset word position is requested - optional bool wait_layout = 3; // wait until current layout changes + /// Wait behavior of the call. + enum DebugWaitType { + /// Respond immediately. If no layout is currently displayed, the layout + /// response will be empty. + IMMEDIATE = 0; + /// Wait for next layout. If a layout is displayed, waits for it to change. + /// If no layout is displayed, waits for one to come up. + NEXT_LAYOUT = 1; + /// Return current layout. If no layout is currently displayed, waits for + /// one to come up. + CURRENT_LAYOUT = 2; + } + + // Trezor T < 2.6.0 only - wait until mnemonic words are shown + optional bool wait_word_list = 1 [deprecated = true]; + // Trezor T < 2.6.0 only - wait until reset word position is requested + optional bool wait_word_pos = 2 [deprecated = true]; + // trezor-core only - wait until current layout changes + // changed in 2.6.4: multiple wait types instead of true/false. + optional DebugWaitType wait_layout = 3 [default = IMMEDIATE]; + // Responds immediately with an empty `DebugLinkState` (used for client-side synchronization). + optional bool return_empty_state = 4 [default = false]; } /** @@ -87,27 +132,50 @@ message DebugLinkGetState { * @end */ message DebugLinkState { - optional bytes layout = 1; // raw buffer of display - optional string pin = 2; // current PIN, blank if PIN is not set/enabled - optional string matrix = 3; // current PIN matrix - optional bytes mnemonic_secret = 4; // current mnemonic secret - optional common.HDNodeType node = 5; // current BIP-32 node - optional bool passphrase_protection = 6; // is node/mnemonic encrypted using passphrase? - optional string reset_word = 7; // word on device display during ResetDevice workflow - optional bytes reset_entropy = 8; // current entropy during ResetDevice workflow - optional string recovery_fake_word = 9; // (fake) word on display during RecoveryDevice workflow - optional uint32 recovery_word_pos = 10; // index of mnemonic word the device is expecting during RecoveryDevice workflow - optional uint32 reset_word_pos = 11; // index of mnemonic word the device is expecting during ResetDevice workflow - optional management.BackupType mnemonic_type = 12; // current mnemonic type (BIP-39/SLIP-39) - repeated string layout_lines = 13; // current layout text + optional bytes layout = 1; // raw buffer of display + optional string pin = 2; // current PIN, blank if PIN is not set/enabled + optional string matrix = 3; // current PIN matrix + optional bytes mnemonic_secret = 4; // current mnemonic secret + optional common.HDNodeType node = 5; // current BIP-32 node + optional bool passphrase_protection = 6; // is node/mnemonic encrypted using passphrase? + optional string reset_word = 7; // word on device display during ResetDevice workflow + optional bytes reset_entropy = 8; // current entropy during ResetDevice workflow + optional string recovery_fake_word = 9; // (fake) word on display during RecoveryDevice workflow + optional uint32 recovery_word_pos = 10; // index of mnemonic word the device is expecting + // during RecoveryDevice workflow + optional uint32 reset_word_pos = 11; // index of mnemonic word the device is expecting during ResetDevice workflow + optional management.BackupType mnemonic_type = 12; // current mnemonic type (BIP-39/SLIP-39) + repeated string tokens = 13; // current layout represented as a list of string tokens +} + +/** + * Request: Host asks for device pairing info + * @start + * @next DebugLinkPairingInfo + */ +message DebugLinkGetPairingInfo { + optional bytes channel_id = 1; // ID of the THP channel to get pairing info from + optional bytes handshake_hash = 2; // handshake hash of the THP channel + optional bytes nfc_secret_host = 3; // host's NFC secret (In case of NFC pairing) +} + +/** + * Response: Device pairing info + * @end + */ +message DebugLinkPairingInfo { + optional bytes channel_id = 1; // ID of the THP channel the pairing info is from + optional bytes handshake_hash = 2; // handshake hash of the THP channel + optional uint32 code_entry_code = 3; // CodeEntry pairing code + optional bytes code_qr_code = 4; // QrCode pairing code + optional bytes nfc_secret_trezor = 5; // NFC secret used in NFC pairing } /** * Request: Ask device to restart * @start */ -message DebugLinkStop { -} +message DebugLinkStop {} /** * Response: Device wants host to log event @@ -161,7 +229,6 @@ message DebugLinkFlashErase { optional uint32 sector = 1; } - /** * Request: Erase the SD card * @start @@ -173,6 +240,20 @@ message DebugLinkEraseSdCard { // if false, it will be all 0xFF bytes. } +/** + * Request: Set battery/power state on the emulator. + * @start + * @next Success + */ +message DebugLinkSetBatteryState { + optional uint32 soc = 1; // state of charge percentage (0-100) + optional bool usb_connected = 2; // USB cable connected + optional bool wireless_connected = 3; // wireless charging pad connected + optional bool ntc_connected = 4; // temperature sensor connected + optional bool charging_limited = 5; // charging current is limited + optional bool temp_control_active = 6; // temperature control is limiting charging + optional bool battery_connected = 7; // battery is physically connected +} /** * Request: Start or stop tracking layout changes @@ -180,6 +261,93 @@ message DebugLinkEraseSdCard { * @next Success */ message DebugLinkWatchLayout { + option deprecated = true; optional bool watch = 1; // if true, start watching layout. // if false, stop. } + +/** + * Request: Remove all the previous debug event state + * @start + * @next Success + */ +message DebugLinkResetDebugEvents { + option deprecated = true; +} + +/** + * Request: Set Optiga's security even counter to maximum + * @start + * @next Success + */ +message DebugLinkOptigaSetSecMax {} + +/** + * Request: Get GC heap information. + * @start + * @next DebugLinkGcInfo + */ +message DebugLinkGetGcInfo {} + +/** + * Response: GC heap information details. + * @end + */ +message DebugLinkGcInfo { + repeated DebugLinkGcInfoItem items = 1; + + /** + * Key-value pair. + */ + message DebugLinkGcInfoItem { + required string name = 1; + required uint64 value = 2; + } +} + +/** + * Request: Set logging filter string. + * @start + * @next Success + */ +message DebugLinkSetLogFilter { + optional string filter = 1; // filter string +} + +/** + * Request: Start N4W1 exchange over DebugLink (initiated by the host). + * Blocks until there is a N4W1 request to be handled. + * @start + * @next DebugLinkN4W1Read + * @next DebugLinkN4W1Write + */ +message DebugLinkN4W1Connected {} + +/** + * Request: Simulate N4W1 write over DebugLink (sent by the device). + * @start + * @next DebugLinkN4W1Response + */ +message DebugLinkN4W1Write { + optional string key = 1; + optional bytes value = 2; // if is None, the entry is deleted +} + +/** + * Request: Simulate N4W1 read over DebugLink (sent by the device). + * @start + * @next DebugLinkN4W1Response + */ +message DebugLinkN4W1Read { + optional string key = 1; +} + +/** + * Response: Simulate N4W1 read/write result over DebugLink (sent by the host). + * @next DebugLinkN4W1Read + * @next DebugLinkN4W1Write + * @next Success + */ +message DebugLinkN4W1Response { + optional bytes value = 1; // existing value is returned on write/delete, `None` if key is missing +} diff --git a/src/device_trezor/trezor/protob/messages-management.proto b/src/device_trezor/trezor/protob/messages-management.proto index 590575fce..97cdae836 100644 --- a/src/device_trezor/trezor/protob/messages-management.proto +++ b/src/device_trezor/trezor/protob/messages-management.proto @@ -1,21 +1,33 @@ syntax = "proto2"; package hw.trezor.messages.management; +import "options.proto"; + // Sugar for easier handling in Java -option java_package = "com.satoshilabs.trezor.lib.protobuf"; option java_outer_classname = "TrezorMessageManagement"; +option java_package = "com.satoshilabs.trezor.lib.protobuf"; +// Include in BTC-only firmware option (include_in_bitcoin_only) = true; -import "messages.proto"; - /** * Type of the mnemonic backup given/received by the device during reset/recovery. */ enum BackupType { - Bip39 = 0; // also called "Single Backup", see BIP-0039 - Slip39_Basic = 1; // also called "Shamir Backup", see SLIP-0039 - Slip39_Advanced = 2; // also called "Super Shamir" or "Shamir with Groups", see SLIP-0039#two-level-scheme + Bip39 = 0; // also called "Single Backup", see BIP-0039 + Slip39_Basic = 1; // also called "Shamir Backup", see SLIP-0039 + Slip39_Advanced = 2; // also called "Super Shamir" or "Shamir with Groups", see SLIP-0039#two-level-scheme + Slip39_Single_Extendable = 3; // extendable single-share Shamir backup + Slip39_Basic_Extendable = 4; // extendable multi-share Shamir backup + Slip39_Advanced_Extendable = 5; // extendable multi-share Shamir backup with groups +} + +/** + * Backup method of the mnemonic shares. + */ +enum BackupMethod { + Display = 0; // the share words are displayed on the device screen + N4W1 = 1; } /** @@ -27,13 +39,23 @@ enum SafetyCheckLevel { PromptTemporarily = 2; // like PromptAlways but reverts to Strict after reboot } +/** + * Allowed display rotation angles (in degrees from North) + */ +enum DisplayRotation { + North = 0; + East = 90; + South = 180; + West = 270; +} /** * Format of the homescreen image */ enum HomescreenFormat { - Toif144x144 = 1; - Jpeg240x240 = 2; + Toif = 1; // full-color toif + Jpeg = 2; // jpeg + ToiG = 3; // greyscale toif } /** @@ -42,8 +64,8 @@ enum HomescreenFormat { * @next Features */ message Initialize { - optional bytes session_id = 1; // assumed device session id; Trezor clears caches if it is different or empty - optional bool _skip_passphrase = 2 [deprecated=true]; // removed as part of passphrase redesign + optional bytes session_id = 1; // assumed device session id; Trezor clears caches if it is different or empty + optional bool _skip_passphrase = 2 [deprecated = true]; // removed as part of passphrase redesign optional bool derive_cardano = 3; // whether to derive Cardano Icarus root keys in this session } @@ -52,49 +74,100 @@ message Initialize { * @start * @next Features */ -message GetFeatures { -} +message GetFeatures {} /** * Response: Reports various information about the device * @end */ message Features { - optional string vendor = 1; // name of the manufacturer, e.g. "trezor.io" - required uint32 major_version = 2; // major version of the firmware/bootloader, e.g. 1 - required uint32 minor_version = 3; // minor version of the firmware/bootloader, e.g. 0 - required uint32 patch_version = 4; // patch version of the firmware/bootloader, e.g. 0 - optional bool bootloader_mode = 5; // is device in bootloader mode? - optional string device_id = 6; // device's unique identifier - optional bool pin_protection = 7; // is device protected by PIN? - optional bool passphrase_protection = 8; // is node/mnemonic encrypted using passphrase? - optional string language = 9; // device language - optional string label = 10; // device description label - optional bool initialized = 12; // does device contain seed? - optional bytes revision = 13; // SCM revision of firmware - optional bytes bootloader_hash = 14; // hash of the bootloader - optional bool imported = 15; // was storage imported from an external source? - optional bool unlocked = 16; // is the device unlocked? called "pin_cached" previously - optional bool _passphrase_cached = 17 [deprecated=true]; // is passphrase already cached in session? - optional bool firmware_present = 18; // is valid firmware loaded? - optional bool needs_backup = 19; // does storage need backup? (equals to Storage.needs_backup) - optional uint32 flags = 20; // device flags (equals to Storage.flags) - optional string model = 21; // device hardware model - optional uint32 fw_major = 22; // reported firmware version if in bootloader mode - optional uint32 fw_minor = 23; // reported firmware version if in bootloader mode - optional uint32 fw_patch = 24; // reported firmware version if in bootloader mode - optional string fw_vendor = 25; // reported firmware vendor if in bootloader mode - // optional bytes fw_vendor_keys = 26; // obsoleted, use fw_vendor - optional bool unfinished_backup = 27; // report unfinished backup (equals to Storage.unfinished_backup) - optional bool no_backup = 28; // report no backup (equals to Storage.no_backup) - optional bool recovery_mode = 29; // is recovery mode in progress - repeated Capability capabilities = 30; // list of supported capabilities + optional string vendor = 1; // name of the manufacturer, e.g. "trezor.io" + required uint32 major_version = 2; // major version of the firmware/bootloader, e.g. 1 + required uint32 minor_version = 3; // minor version of the firmware/bootloader, e.g. 0 + required uint32 patch_version = 4; // patch version of the firmware/bootloader, e.g. 0 + optional uint32 build_version = 61; // build version of the firmware/bootloader, e.g. 0 + optional bool bootloader_mode = 5; // is device in bootloader mode? + optional string device_id = 6; // device's unique identifier + optional bool pin_protection = 7; // is device protected by PIN? + optional bool passphrase_protection = 8; // is node/mnemonic encrypted using passphrase? + optional string language = 9; // device language + optional string label = 10; // device description label + optional bool initialized = 12; // does device contain seed? + optional bytes revision = 13; // SCM revision of firmware + optional bytes bootloader_hash = 14; // hash of the bootloader + optional bool imported = 15; // was storage imported from an external source? + optional bool unlocked = 16; // is the device unlocked? called "pin_cached" previously + optional bool _passphrase_cached = 17 [deprecated = true]; // is passphrase already cached in session? + optional bool firmware_present = 18; // is firmware loaded? + optional BackupAvailability backup_availability = 19; // does storage need backup? is repeated backup unlocked? + optional uint32 flags = 20; // device flags (equals to Storage.flags) + optional string model = 21; // device hardware model + optional uint32 fw_major = 22; // reported firmware version if in bootloader mode + optional uint32 fw_minor = 23; // reported firmware version if in bootloader mode + optional uint32 fw_patch = 24; // reported firmware version if in bootloader mode + optional uint32 fw_build = 62; // reported firmware version if in bootloader mode + optional string fw_vendor = 25; // reported firmware vendor if in bootloader mode + // optional bytes fw_vendor_keys = 26; // obsoleted, use fw_vendor + optional bool unfinished_backup = 27; // report unfinished backup (equals to Storage.unfinished_backup) + optional bool no_backup = 28; // report no backup (equals to Storage.no_backup) + optional RecoveryStatus recovery_status = 29; // whether or not we are in recovery mode and of what kind + repeated Capability capabilities = 30; // list of supported capabilities + optional BackupType backup_type = 31; // type of device backup (BIP-39 / SLIP-39 basic / SLIP-39 advanced) + optional bool sd_card_present = 32; // is SD card present + optional bool sd_protection = 33; // is SD Protect enabled + optional bool wipe_code_protection = 34; // is wipe code protection enabled + optional bytes session_id = 35; + optional bool passphrase_always_on_device = 36; // device enforces passphrase entry on Trezor + optional SafetyCheckLevel safety_checks = 37; // safety check level, set to Prompt to limit path + // namespace enforcement + optional uint32 auto_lock_delay_ms = 38; // number of milliseconds after which the device locks itself + optional DisplayRotation display_rotation = 39; // rotation of display (in degrees from North) + optional bool experimental_features = 40; // are experimental message types enabled? + optional bool busy = 41; // is the device busy, showing "Do not disconnect"? + optional HomescreenFormat homescreen_format = 42; // format of the homescreen, 1 = TOIf, 2 = jpg, 3 = TOIG + optional bool hide_passphrase_from_host = 43; // should we hide the passphrase when it comes from host? + optional string internal_model = 44; // internal model name + optional uint32 unit_color = 45; // color of the unit/device + optional bool unit_btconly = 46; // unit/device is intended as bitcoin only + optional uint32 homescreen_width = 47; // homescreen width in pixels + optional uint32 homescreen_height = 48; // homescreen height in pixels + optional bool bootloader_locked = 49; // bootloader is locked + optional bool language_version_matches = 50 [default = true]; // translation blob version matches firmware version + optional uint32 unit_packaging = 51; // unit/device packaging version + optional bool haptic_feedback = 52; // haptic feedback is enabled + optional RecoveryType recovery_type = 53; // what type of recovery we are in + // NB: this works in conjunction with recovery_status + optional uint32 optiga_sec = 54; // Optiga's security event counter. + optional uint32 soc = 55; // Battery state of charge (0 - 100%) + optional bool firmware_corrupted = 56; // true if the firmware is corrupted + optional uint32 auto_lock_delay_battery_ms = 57; // number of milliseconds after which + // the battery-powered device locks itself + optional bool led = 58; // RGB LED settings + optional bool usb_connected = 59; // USB connected + optional bool wireless_connected = 60; // Wireless charger connected + optional bool tap_to_wake = 63; // tap to wake is enabled (None = not supported) + + enum BackupAvailability { + /// Device is already backed up, or a previous backup has failed. + NotAvailable = 0; + /// Device is not backed up. Backup is required. + Required = 1; + /// Device is already backed up and can be backed up again. + Available = 2; + } + + enum RecoveryStatus { + Nothing = 0; // we are not in recovery mode + Recovery = 1; // we are in "Normal" or "DryRun" recovery + Backup = 2; // we are in repeated backup mode + } + enum Capability { option (has_bitcoin_only_values) = true; Capability_Bitcoin = 1 [(bitcoin_only) = true]; Capability_Bitcoin_like = 2; // Altcoins based on the Bitcoin source code - Capability_Binance = 3; + Capability_Binance = 3; // BNB Smart Chain Capability_Cardano = 4; Capability_Crypto = 5 [(bitcoin_only) = true]; // generic crypto operations for GPG, SSH, etc. Capability_EOS = 6; @@ -108,21 +181,19 @@ message Features { Capability_U2F = 14; Capability_Shamir = 15 [(bitcoin_only) = true]; Capability_ShamirGroups = 16 [(bitcoin_only) = true]; - Capability_PassphraseEntry = 17 [(bitcoin_only) = true]; // the device is capable of passphrase entry directly on the device + Capability_PassphraseEntry = 17 [(bitcoin_only) = true]; // the device is capable of passphrase entry + // directly on the device + Capability_Solana = 18; + Capability_Translations = 19 [(bitcoin_only) = true]; + Capability_Brightness = 20 [(bitcoin_only) = true]; + Capability_Haptic = 21 [(bitcoin_only) = true]; + Capability_BLE = 22 [(bitcoin_only) = true]; // Bluetooth Low Energy + Capability_NFC = 23 [(bitcoin_only) = true]; // Near Field Communications + Capability_Tron = 24; + Capability_N4W1 = 25 [(bitcoin_only) = true]; + Capability_TouchWakeup = 26 [(bitcoin_only) = true]; // Touch to wake from sleep + reserved 27; // reserved for internal use } - optional BackupType backup_type = 31; // type of device backup (BIP-39 / SLIP-39 basic / SLIP-39 advanced) - optional bool sd_card_present = 32; // is SD card present - optional bool sd_protection = 33; // is SD Protect enabled - optional bool wipe_code_protection = 34; // is wipe code protection enabled - optional bytes session_id = 35; - optional bool passphrase_always_on_device = 36; // device enforces passphrase entry on Trezor - optional SafetyCheckLevel safety_checks = 37; // safety check level, set to Prompt to limit path namespace enforcement - optional uint32 auto_lock_delay_ms = 38; // number of milliseconds after which the device locks itself - optional uint32 display_rotation = 39; // in degrees from North - optional bool experimental_features = 40; // are experimental message types enabled? - optional bool busy = 41; // is the device busy, showing "Do not disconnect"? - optional HomescreenFormat homescreen_format = 42; // format of the homescreen, 1 = TOIf 144x144, 2 = jpg 240x240 - optional bool hide_passphrase_from_host = 43; // should we hide the passphrase when it comes from host? } /** @@ -130,8 +201,7 @@ message Features { * @start * @next Success */ -message LockDevice { -} +message LockDevice {} /** * Request: Show a "Do not disconnect" dialog instead of the standard homescreen. @@ -139,37 +209,84 @@ message LockDevice { * @next Success */ message SetBusy { - optional uint32 expiry_ms = 1; // The time in milliseconds after which the dialog will automatically disappear. Overrides any previously set expiry. If not set, then the dialog is hidden. + optional uint32 expiry_ms = 1; // The time in milliseconds after which the dialog will automatically disappear. + // Overrides any previously set expiry. If not set, then the dialog is hidden. } /** - * Request: end the current session. Following actions must call Initialize again. + * Request: end the current sesson. Following actions must call Initialize again. * Cache for the current session is discarded, other sessions remain intact. * Device is not PIN-locked. * @start * @next Success */ -message EndSession { -} +message EndSession {} /** - * Request: change language and/or label of the device + * Request: change some property of the device, e.g. label or homescreen * @start * @next Success + * @next DataChunkRequest * @next Failure */ message ApplySettings { - optional string language = 1; + optional string language = 1 [deprecated = true]; optional string label = 2; optional bool use_passphrase = 3; - optional bytes homescreen = 4; - optional uint32 _passphrase_source = 5 [deprecated=true]; // ASK = 0; DEVICE = 1; HOST = 2; + optional bytes homescreen = 4; // homescreen image in single array, deprecated for 14 + optional uint32 _passphrase_source = 5 [deprecated = true]; // ASK = 0; DEVICE = 1; HOST = 2; optional uint32 auto_lock_delay_ms = 6; - optional uint32 display_rotation = 7; // in degrees from North - optional bool passphrase_always_on_device = 8; // do not prompt for passphrase, enforce device entry - optional SafetyCheckLevel safety_checks = 9; // Safety check level, set to Prompt to limit path namespace enforcement - optional bool experimental_features = 10; // enable experimental message types - optional bool hide_passphrase_from_host = 11; // do not show passphrase coming from host + optional DisplayRotation display_rotation = 7; // rotation of display (in degrees from North) + optional bool passphrase_always_on_device = 8; // do not prompt for passphrase, enforce device entry + optional SafetyCheckLevel safety_checks = 9; // Safety check level, + // set to Prompt to limit path namespace enforcement + optional bool experimental_features = 10; // enable experimental message types + optional bool hide_passphrase_from_host = 11; // do not show passphrase coming from host + optional bool haptic_feedback = 13; // enable haptic feedback + optional uint32 homescreen_length = 14; // byte length of new homescreen, device will request chunks + optional uint32 auto_lock_delay_battery_ms = 15; // time in ms after which device locks when on battery + // or wireless charger +} + +/** + * Request: change the device language via translation data. + * Does not send the translation data itself, as they are too large for one message. + * Device will request the translation data in chunks. + * @start + * @next DataChunkRequest + * @next Failure + */ +message ChangeLanguage { + // byte length of the whole translation blob (set to 0 for default language - english) + required uint32 data_length = 1; + // Prompt the user on screen. + // In certain conditions (such as freshly installed device), the confirmation prompt + // is not mandatory. Setting show_display=false will skip the prompt if that's + // the case. If the device does not allow skipping the prompt, a request with + // show_display=false will return a failure. (This way the host can safely try + // to change the language without invoking a prompt.) + // Setting show_display to true will always show the prompt. + // Leaving the option unset will show the prompt only when necessary. + optional bool show_display = 2; +} + +/** + * Response: Device asks for more data from translation/homescreen image. + * @end + * @next DataChunkAck + */ +message DataChunkRequest { + required uint32 data_length = 1; // Number of bytes being requested + required uint32 data_offset = 2; // Offset of the first byte being requested +} + +/** + * Request: Translation/homescreen payload data. + * @next DataChunkRequest + * @next Success + */ +message DataChunkAck { + required bytes data_chunk = 1; // Bytes from translation/homescreen payload } /** @@ -189,7 +306,7 @@ message ApplyFlags { * @next Failure */ message ChangePin { - optional bool remove = 1; // is PIN removal requested? + optional bool remove = 1; // is PIN removal requested? } /** @@ -199,7 +316,7 @@ message ChangePin { * @next Failure */ message ChangeWipeCode { - optional bool remove = 1; // is wipe code removal requested? + optional bool remove = 1; // is wipe code removal requested? } /** @@ -211,8 +328,8 @@ message ChangeWipeCode { message SdProtect { required SdProtectOperationType operation = 1; /** - * Structure representing SD card protection operation - */ + * Structure representing SD card protection operation + */ enum SdProtectOperationType { DISABLE = 0; ENABLE = 1; @@ -226,8 +343,8 @@ message SdProtect { * @next Success */ message Ping { - optional string message = 1 [default=""]; // message to send back in Success message - optional bool button_protection = 2; // ask for button press + optional string message = 1 [default = ""]; // message to send back in Success message + optional bool button_protection = 2; // ask for button press } /** @@ -235,8 +352,7 @@ message Ping { * @start * @next Failure */ -message Cancel { -} +message Cancel {} /** * Request: Request a sample of random data generated by hardware RNG. May be used for testing. @@ -245,7 +361,7 @@ message Cancel { * @next Failure */ message GetEntropy { - required uint32 size = 1; // size of requested entropy + required uint32 size = 1; // size of requested entropy } /** @@ -253,7 +369,7 @@ message GetEntropy { * @end */ message Entropy { - required bytes entropy = 1; // chunk of random generated bytes + required bytes entropy = 1; // chunk of random generated bytes } /** @@ -263,7 +379,7 @@ message Entropy { * @next Failure */ message GetFirmwareHash { - optional bytes challenge = 1; // Blake2s key up to 32 bytes in length. + optional bytes challenge = 1; // Blake2s key up to 32 bytes in length. } /** @@ -274,14 +390,85 @@ message FirmwareHash { required bytes hash = 1; } +/** + * Request: Request a signature of the provided challenge. + * @start + * @next AuthenticityProof + * @next AuthenticityProofSizes + * @next Failure + */ +message AuthenticateDevice { + required bytes challenge = 1; // A random challenge to sign. + optional bool stream = 2; // If set, the certificates and signatures data is sent using a stream of + // AuthenticityProofChunk responses (to avoid sending one large response). +} + +/** + * Response: Signature of the provided challenge along with a certificate issued by the Trezor company. + * @end + */ +message AuthenticityProof { + repeated bytes optiga_certificates = 1; // A certificate chain starting with the Optiga device certificate, + // followed by intermediate CA certificates, the last of which is signed by + // Trezor company's root CA. + required bytes optiga_signature = 2; // A DER-encoded signature of "\x13AuthenticateDevice:" + length-prefixed + // challenge that should be verified using the Optiga device certificate. + repeated bytes tropic_certificates = 3; // A certificate chain starting with the Tropic device certificate, + // followed by intermediate CA certificates, the last of which is signed by + // Trezor company's root CA. + optional bytes tropic_signature = 4; // A DER-encoded signature of "\x13AuthenticateDevice:" + length-prefixed + // challenge that should be verified using the Tropic device certificate. + repeated bytes mcu_certificates = 5; // An MCU device certificate signed by Trezor company's root CA. + optional bytes mcu_signature = 6; // A DER-encoded signature of "\x13AuthenticateDevice:" + length-prefixed + // challenge that should be verified using the MCU device certificate. +} + +/** + * Response: Sizes of the corresponding proof parts (see above). + * @next GetAuthenticityProofChunk + */ +message AuthenticityProofSizes { + repeated uint32 optiga_certificates = 1; + required uint32 optiga_signature = 2; + repeated uint32 tropic_certificates = 3; + optional uint32 tropic_signature = 4; + repeated uint32 mcu_certificates = 5; + optional uint32 mcu_signature = 6; +} + +/** + * Request: Request authenticity proof data chunk, or finish the workflow if `proof_type` is not set. + * @next AuthenticityProofChunk + * @next Success + */ +message GetAuthenticityProofChunk { + optional AuthenticityProofType proof_type = 1; // Specifies proof part to fetch. + optional uint32 index = 2; // If set, certificates[index] is fetched. Otherwise, signature is fetched. + required uint32 offset = 3; // Data chunk offset (in bytes). + required uint32 size = 4; // Data chunk size (in bytes). + + enum AuthenticityProofType { + OPTIGA = 0; + TROPIC = 1; + MCU = 2; + } +} + +/** + * Response: Return requested authenticity proof data chunk. + * @next GetAuthenticityProofChunk + */ +message AuthenticityProofChunk { + required bytes chunk = 1; +} + /** * Request: Request device to wipe all sensitive data and settings * @start * @next Success * @next Failure */ -message WipeDevice { -} +message WipeDevice {} /** * Request: Load seed and related internal settings from the computer @@ -290,15 +477,16 @@ message WipeDevice { * @next Failure */ message LoadDevice { - repeated string mnemonics = 1; // seed encoded as mnemonic (12, 18 or 24 words for BIP39, 20 or 33 for SLIP39) - optional string pin = 3; // set PIN protection - optional bool passphrase_protection = 4; // enable master node encryption using passphrase - optional string language = 5 [default='en-US']; // device language (IETF BCP 47 language tag) - optional string label = 6; // device label - optional bool skip_checksum = 7; // do not test mnemonic for valid BIP-39 checksum - optional uint32 u2f_counter = 8; // U2F counter - optional bool needs_backup = 9; // set "needs backup" flag - optional bool no_backup = 10; // indicate that no backup is going to be made + repeated string mnemonics = 1; // seed encoded as mnemonic (12, 18 or 24 words for BIP39, 20 or 33 for SLIP39) + optional string pin = 3; // set PIN protection + optional bool passphrase_protection = 4; // enable master node encryption using passphrase + optional string language = 5 [deprecated = true]; // deprecated (use ChangeLanguage) + optional string label = 6; // device label + optional bool skip_checksum = 7; // do not test mnemonic for valid BIP-39 checksum + optional uint32 u2f_counter = 8; // U2F counter + optional bool needs_backup = 9; // set "needs backup" flag + optional bool no_backup = 10; // indicate that no backup is going to be made + optional bool unfinished_backup = 11; // indicate that backup process has failed } /** @@ -308,16 +496,18 @@ message LoadDevice { * @next Failure */ message ResetDevice { - optional bool display_random = 1; // display entropy generated by the device before asking for additional entropy - optional uint32 strength = 2 [default=256]; // strength of seed in bits - optional bool passphrase_protection = 3; // enable master node encryption using passphrase - optional bool pin_protection = 4; // enable PIN protection - optional string language = 5 [default='en-US']; // device language (IETF BCP 47 language tag) - optional string label = 6; // device label - optional uint32 u2f_counter = 7; // U2F counter - optional bool skip_backup = 8; // postpone seed backup to BackupDevice workflow - optional bool no_backup = 9; // indicate that no backup is going to be made - optional BackupType backup_type = 10 [default=Bip39]; // type of the mnemonic backup + reserved 1; // unused display_random + optional uint32 strength = 2 [default = 256]; // strength of seed in bits + optional bool passphrase_protection = 3; // enable master node encryption using passphrase + optional bool pin_protection = 4; // enable PIN protection + optional string language = 5 [deprecated = true]; // deprecated (use ChangeLanguage) + optional string label = 6; // device label + optional uint32 u2f_counter = 7; // U2F counter + optional bool skip_backup = 8; // postpone seed backup to BackupDevice workflow + optional bool no_backup = 9; // indicate that no backup is going to be made + optional BackupType backup_type = 10 [default = Bip39]; // type of the mnemonic backup + optional bool entropy_check = 11; // run with entropy check protocol + optional BackupMethod backup_method = 12 [default = Display]; // how the mnemonic shares should be backed up } /** @@ -326,6 +516,13 @@ message ResetDevice { * @next Success */ message BackupDevice { + optional uint32 group_threshold = 1; + message Slip39Group { + required uint32 member_threshold = 1; + required uint32 member_count = 2; + } + repeated Slip39Group groups = 2; + optional BackupMethod backup_method = 3 [default = Display]; // how the mnemonic shares should be backed up } /** @@ -333,14 +530,34 @@ message BackupDevice { * @next EntropyAck */ message EntropyRequest { + optional bytes entropy_commitment = 1; // HMAC-SHA256 of Trezor's internal entropy used in entropy check. + optional bytes prev_entropy = 2; // Trezor's internal entropy from the previous round of entropy check. } /** * Request: Provide additional entropy for seed generation function * @next Success + * @next EntropyCheckReady */ message EntropyAck { - required bytes entropy = 1; // 256 bits (32 bytes) of random data + required bytes entropy = 1; // 256 bits (32 bytes) of the host's random data +} + +/** + * Response: Trezor is ready for the next phase of the entropy check protocol. + * @next EntropyCheckContinue + * @next GetPublicKey + */ +message EntropyCheckReady {} + +/** + * Request: Proceed with the next phase of the entropy check protocol, asking Trezor to either reveal its internal + * entropy or to finish and store the seed. + * @next Success + * @next EntropyRequest + */ +message EntropyCheckContinue { + optional bool finish = 1 [default = false]; // finish the entropy check protocol, store the seed } /** @@ -350,31 +567,38 @@ message EntropyAck { * @next WordRequest */ message RecoveryDevice { - optional uint32 word_count = 1; // number of words in BIP-39 mnemonic - optional bool passphrase_protection = 2; // enable master node encryption using passphrase - optional bool pin_protection = 3; // enable PIN protection - optional string language = 4; // device language (IETF BCP 47 language tag) - optional string label = 5; // device label - optional bool enforce_wordlist = 6; // enforce BIP-39 wordlist during the process - // 7 reserved for unused recovery method - optional RecoveryDeviceType type = 8; // supported recovery type - optional uint32 u2f_counter = 9; // U2F counter - optional bool dry_run = 10; // perform dry-run recovery workflow (for safe mnemonic validation) + optional uint32 word_count = 1; // number of words in BIP-39 mnemonic (T1 only) + optional bool passphrase_protection = 2; // enable master node encryption using passphrase + optional bool pin_protection = 3; // enable PIN protection + optional string language = 4 [deprecated = true]; // deprecated (use ChangeLanguage) + optional string label = 5; // device label + optional bool enforce_wordlist = 6; // enforce BIP-39 wordlist during the process (T1 only) + reserved 7; // unused recovery method + optional RecoveryDeviceInputMethod input_method = 8; // supported recovery input method (T1 only) + optional uint32 u2f_counter = 9; // U2F counter + optional RecoveryType type = 10 [default = NormalRecovery]; // the type of recovery to perform + optional BackupMethod backup_method = 11; // how the shares should be recovered from backup /** * Type of recovery procedure. These should be used as bitmask, e.g., - * `RecoveryDeviceType_ScrambledWords | RecoveryDeviceType_Matrix` + * `RecoveryDeviceInputMethod_ScrambledWords | RecoveryDeviceInputMethod_Matrix` * listing every method supported by the host computer. * - * Note that ScrambledWords must be supported by every implementation - * for backward compatibility; there is no way to not support it. + * Note that Matrix recovery is the recommended recovery method. ScrambledWords + * is allowed only for 24 word recovery, unless safety checks are disabled. */ - enum RecoveryDeviceType { + enum RecoveryDeviceInputMethod { // use powers of two when extending this field - RecoveryDeviceType_ScrambledWords = 0; // words in scrambled order - RecoveryDeviceType_Matrix = 1; // matrix recovery type + ScrambledWords = 0; // words in scrambled order + Matrix = 1; // matrix recovery type } } +enum RecoveryType { + NormalRecovery = 0; // recovery from seedphrase on an uninitialized device + DryRun = 1; // mnemonic validation + UnlockRepeatedBackup = 2; // unlock SLIP-39 repeated backup +} + /** * Response: Device is waiting for user to enter word of the mnemonic * Its position is shown only on device's internal display. @@ -383,8 +607,8 @@ message RecoveryDevice { message WordRequest { required WordRequestType type = 1; /** - * Type of Recovery Word request - */ + * Type of Recovery Word request + */ enum WordRequestType { WordRequestType_Plain = 0; WordRequestType_Matrix9 = 1; @@ -399,7 +623,7 @@ message WordRequest { * @next Failure */ message WordAck { - required string word = 1; // one word of mnemonic on asked position + required string word = 1; // one word of mnemonic on asked position } /** @@ -416,8 +640,7 @@ message SetU2FCounter { * @start * @next NextU2FCounter */ -message GetNextU2FCounter { -} +message GetNextU2FCounter {} /** * Request: Set U2F counter @@ -433,8 +656,7 @@ message NextU2FCounter { * @next PreauthorizedRequest * @next Failure */ -message DoPreauthorized { -} +message DoPreauthorized {} /** * Request: Device awaits a preauthorized operation. @@ -442,8 +664,7 @@ message DoPreauthorized { * @next SignTx * @next GetOwnershipProof */ -message PreauthorizedRequest { -} +message PreauthorizedRequest {} /** * Request: Cancel any outstanding authorization in the current session. @@ -451,15 +672,28 @@ message PreauthorizedRequest { * @next Success * @next Failure */ -message CancelAuthorization { -} +message CancelAuthorization {} /** * Request: Reboot firmware to bootloader * @start * @next Success + * @next DataChunkRequest */ message RebootToBootloader { + // Action to be performed after rebooting to bootloader + optional BootCommand boot_command = 1 [default = STOP_AND_WAIT]; + // Firmware header to be flashed after rebooting to bootloader + optional bytes firmware_header = 2; + // Deprecated (length of language blob to be installed before upgrading firmware) + reserved 3; + + enum BootCommand { + // Go to bootloader menu + STOP_AND_WAIT = 0; + // Connect to host and wait for firmware update + INSTALL_UPGRADE = 1; + } } /** @@ -467,18 +701,14 @@ message RebootToBootloader { * @start * @next Nonce */ -message GetNonce { - option (experimental_message) = true; -} +message GetNonce {} /** * Response: Contains a random nonce * @end */ message Nonce { - option (experimental_message) = true; - - required bytes nonce = 1; // a 32-byte random value generated by Trezor + required bytes nonce = 1; // a 32-byte random value generated by Trezor } /** @@ -488,8 +718,8 @@ message Nonce { * @next Failure */ message UnlockPath { - repeated uint32 address_n = 1; // prefix of the BIP-32 path leading to the account (m / purpose') - optional bytes mac = 2; // the MAC returned by UnlockedPathRequest + repeated uint32 address_n = 1; // prefix of the BIP-32 path leading to the account (m / purpose') + optional bytes mac = 2; // the MAC returned by UnlockedPathRequest } /** @@ -500,5 +730,44 @@ message UnlockPath { * @next GetAddress */ message UnlockedPathRequest { - optional bytes mac = 1; // authentication code for future UnlockPath calls + required bytes mac = 1; // authentication code for future UnlockPath calls +} + +/** + * Request: Show tutorial screens on the device + * @start + * @next Success + */ +message ShowDeviceTutorial {} + +/** + * Request: Unlocks bootloader, !irreversible! + * @start + * @next Success + * @next Failure + */ +message UnlockBootloader {} + +/** + * Request: Set device brightness + * @start + * @next Success + */ +message SetBrightness { + optional uint32 value = 1; // if not specified, let the user choose +} + +/** + * Request: Get unit serial number + * @start + * @next SerialNumber + */ +message GetSerialNumber {} + +/** + * Response: contains unit serial number + * @end + */ +message SerialNumber { + required string serial_number = 1; } diff --git a/src/device_trezor/trezor/protob/messages-monero.proto b/src/device_trezor/trezor/protob/messages-monero.proto index c88218d3b..0e9c680f2 100644 --- a/src/device_trezor/trezor/protob/messages-monero.proto +++ b/src/device_trezor/trezor/protob/messages-monero.proto @@ -2,8 +2,8 @@ syntax = "proto2"; package hw.trezor.messages.monero; // Sugar for easier handling in Java -option java_package = "com.satoshilabs.trezor.lib.protobuf"; option java_outer_classname = "TrezorMessageMonero"; +option java_package = "com.satoshilabs.trezor.lib.protobuf"; enum MoneroNetworkType { MAINNET = 0; @@ -18,12 +18,13 @@ enum MoneroNetworkType { */ message MoneroTransactionSourceEntry { repeated MoneroOutputEntry outputs = 1; // all outputs including decoys (forms the ring) - optional uint64 real_output = 2; // index denoting which item in `outputs` is our real output (not a decoy) - optional bytes real_out_tx_key = 3; // tx key located in the real output's tx + optional uint64 real_output = 2; // index denoting which item in `outputs` is our real output (not a decoy) + optional bytes real_out_tx_key = 3; // tx key located in the real output's tx repeated bytes real_out_additional_tx_keys = 4; // additional tx keys if applicable - optional uint64 real_output_in_tx_index = 5; // index of our real output in the tx (aka which output was it in the transaction) + optional uint64 real_output_in_tx_index = 5; // index of our real output in the tx + // (aka which output was it in the transaction) optional uint64 amount = 6; - optional bool rct = 7; // is RingCT used (true for newer UTXOs) + optional bool rct = 7; // is RingCT used (true for newer UTXOs) optional bytes mask = 8; optional MoneroMultisigKLRki multisig_kLRki = 9; optional uint32 subaddr_minor = 10; // minor subaddr index UTXO was sent to @@ -67,12 +68,12 @@ message MoneroTransactionDestinationEntry { * @embed */ message MoneroTransactionRsigData { - optional uint32 rsig_type = 1; // range signature (aka proof) type + optional uint32 rsig_type = 1; // range signature (aka proof) type optional uint32 offload_type = 2; - repeated uint64 grouping = 3; // aggregation scheme for BP + repeated uint64 grouping = 3; // aggregation scheme for BP - optional bytes mask = 4; // mask vector - optional bytes rsig = 5; // range sig data, all of it or partial (based on rsig_parts) + optional bytes mask = 4; // mask vector + optional bytes rsig = 5; // range sig data, all of it or partial (based on rsig_parts) repeated bytes rsig_parts = 6; optional uint32 bp_version = 7; // Bulletproof version } @@ -84,12 +85,13 @@ message MoneroTransactionRsigData { * @next Failure */ message MoneroGetAddress { - repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node - optional bool show_display = 2; // Optionally show on display before sending the result - optional MoneroNetworkType network_type = 3 [default=MAINNET]; // Network type - optional uint32 account = 4; // Major subaddr index - optional uint32 minor = 5; // Minor subaddr index - optional bytes payment_id = 6; // Payment ID for integrated address + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional bool show_display = 2; // Optionally show on display before sending the result + optional MoneroNetworkType network_type = 3 [default = MAINNET]; // Network type + optional uint32 account = 4; // Major subaddr index + optional uint32 minor = 5; // Minor subaddr index + optional bytes payment_id = 6; // Payment ID for integrated address + optional bool chunkify = 7; // display the address in chunks of 4 characters } /** @@ -97,7 +99,7 @@ message MoneroGetAddress { * @end */ message MoneroAddress { - optional bytes address = 1; + required bytes address = 1; } /** @@ -107,8 +109,8 @@ message MoneroAddress { * @next Failure */ message MoneroGetWatchKey { - repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node - optional MoneroNetworkType network_type = 2 [default=MAINNET]; // Network type + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional MoneroNetworkType network_type = 2 [default = MAINNET]; // Network type } /** @@ -116,8 +118,8 @@ message MoneroGetWatchKey { * @end */ message MoneroWatchKey { - optional bytes watch_key = 1; - optional bytes address = 2; + required bytes watch_key = 1; + required bytes address = 2; } /** @@ -128,7 +130,7 @@ message MoneroWatchKey { message MoneroTransactionInitRequest { optional uint32 version = 1; repeated uint32 address_n = 2; - optional MoneroNetworkType network_type = 3 [default=MAINNET]; // Network type + optional MoneroNetworkType network_type = 3 [default = MAINNET]; // Network type optional MoneroTransactionData tsx_data = 4; /** * Structure representing Monero initial transaction information @@ -149,6 +151,7 @@ message MoneroTransactionInitRequest { optional uint32 client_version = 13; // connected client version optional uint32 hard_fork = 14; // transaction hard fork number optional bytes monero_version = 15; // monero software version + optional bool chunkify = 16; // display the address in chunks of 4 characters } } @@ -175,7 +178,7 @@ message MoneroTransactionSetInputRequest { * @next MoneroTransactionInputViniRequest */ message MoneroTransactionSetInputAck { - optional bytes vini = 1; // xmrtypes.TxinToKey + optional bytes vini = 1; // xmrtypes.TxinToKey optional bytes vini_hmac = 2; optional bytes pseudo_out = 3; optional bytes pseudo_out_hmac = 4; @@ -189,7 +192,7 @@ message MoneroTransactionSetInputAck { */ message MoneroTransactionInputViniRequest { optional MoneroTransactionSourceEntry src_entr = 1; - optional bytes vini = 2; // xmrtypes.TxinToKey + optional bytes vini = 2; // xmrtypes.TxinToKey optional bytes vini_hmac = 3; optional bytes pseudo_out = 4; optional bytes pseudo_out_hmac = 5; @@ -201,15 +204,13 @@ message MoneroTransactionInputViniRequest { * @next MoneroTransactionInputViniRequest * @next MoneroTransactionAllInputsSetRequest */ -message MoneroTransactionInputViniAck { -} +message MoneroTransactionInputViniAck {} /** - * Request: Sub request of MoneroTransactionSign. Sent after all inputs have been sent. Useful for rangeisg offloading. + * Request: Sub request of MoneroTransactionSign. Sent after all inputs have been sent. Useful for rangesig offloading. * @next MoneroTransactionAllInputsSetAck */ -message MoneroTransactionAllInputsSetRequest { -} +message MoneroTransactionAllInputsSetRequest {} /** * Response: Response to after all inputs have been set. @@ -277,7 +278,7 @@ message MoneroTransactionAllOutSetAck { */ message MoneroTransactionSignInputRequest { optional MoneroTransactionSourceEntry src_entr = 1; - optional bytes vini = 2; // xmrtypes.TxinToKey + optional bytes vini = 2; // xmrtypes.TxinToKey optional bytes vini_hmac = 3; optional bytes pseudo_out = 4; optional bytes pseudo_out_hmac = 5; @@ -297,14 +298,14 @@ message MoneroTransactionSignInputAck { } /** - * Request: Sub request of MoneroTransactionSign. Final message of the procol after all UTXOs are signed + * Request: Sub request of MoneroTransactionSign. Final message of the protocol after all UTXOs are signed * @next MoneroTransactionFinalAck */ -message MoneroTransactionFinalRequest { -} +message MoneroTransactionFinalRequest {} /** - * Response: Contains transaction metadata and encryption keys needed for further transaction operations (e.g. multisig, send proof). + * Response: Contains transaction metadata and encryption keys needed for further transaction operations (e.g. multisig, + * send proof). * @end */ message MoneroTransactionFinalAck { @@ -323,8 +324,8 @@ message MoneroTransactionFinalAck { message MoneroKeyImageExportInitRequest { required uint64 num = 1; required bytes hash = 2; - repeated uint32 address_n = 3; // BIP-32 path to derive the key from master node - optional MoneroNetworkType network_type = 4 [default=MAINNET]; // network type + repeated uint32 address_n = 3; // BIP-32 path to derive the key from master node + optional MoneroNetworkType network_type = 4 [default = MAINNET]; // network type repeated MoneroSubAddressIndicesList subs = 5; /** * Structure representing Monero list of sub-addresses @@ -339,8 +340,7 @@ message MoneroKeyImageExportInitRequest { * Response: Response to key image sync initialization. * @next MoneroKeyImageSyncStepRequest */ -message MoneroKeyImageExportInitAck { -} +message MoneroKeyImageExportInitAck {} /** * Request: Sub request of MoneroKeyImageSync. Contains batch of the UTXO to export key image for. @@ -381,8 +381,7 @@ message MoneroKeyImageSyncStepAck { * Request: Sub request of MoneroKeyImageSync. Final message of the sync protocol. * @next MoneroKeyImageSyncFinalAck */ -message MoneroKeyImageSyncFinalRequest { -} +message MoneroKeyImageSyncFinalRequest {} /** * Response: Response to key image sync step. Contains encryption keys for exported key images. @@ -397,15 +396,15 @@ message MoneroKeyImageSyncFinalAck { * @next MoneroGetTxKeyAck */ message MoneroGetTxKeyRequest { - repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node - optional MoneroNetworkType network_type = 2 [default=MAINNET]; // network type + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional MoneroNetworkType network_type = 2 [default = MAINNET]; // network type required bytes salt1 = 3; required bytes salt2 = 4; required bytes tx_enc_keys = 5; required bytes tx_prefix_hash = 6; - optional uint32 reason = 7; // reason to display for user. e.g., tx_proof - optional bytes view_public_key = 8; // addr for derivation + optional uint32 reason = 7; // reason to display for user. e.g., tx_proof + optional bytes view_public_key = 8; // addr for derivation } /** @@ -423,8 +422,8 @@ message MoneroGetTxKeyAck { * @next MoneroLiveRefreshStartAck */ message MoneroLiveRefreshStartRequest { - repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node - optional MoneroNetworkType network_type = 2 [default=MAINNET]; // network type + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional MoneroNetworkType network_type = 2 [default = MAINNET]; // network type } /** @@ -432,9 +431,7 @@ message MoneroLiveRefreshStartRequest { * @next MoneroLiveRefreshStepRequest * @next MoneroLiveRefreshFinalRequest */ -message MoneroLiveRefreshStartAck { - -} +message MoneroLiveRefreshStartAck {} /** * Request: Request to compute a single key image during live sync @@ -462,17 +459,13 @@ message MoneroLiveRefreshStepAck { * Request: Request terminating live refresh mode. * @next MoneroLiveRefreshFinishedAck */ -message MoneroLiveRefreshFinalRequest { - -} +message MoneroLiveRefreshFinalRequest {} /** * Response: Response on termination of live refresh mode. * @end */ -message MoneroLiveRefreshFinalAck { - -} +message MoneroLiveRefreshFinalAck {} /** * Request: Universal Monero protocol implementation diagnosis request. diff --git a/src/device_trezor/trezor/protob/messages.proto b/src/device_trezor/trezor/protob/messages.proto index c0ea0ff75..50028dc0c 100644 --- a/src/device_trezor/trezor/protob/messages.proto +++ b/src/device_trezor/trezor/protob/messages.proto @@ -1,80 +1,25 @@ syntax = "proto2"; package hw.trezor.messages; +import "options.proto"; + /** * Messages for Trezor communication */ // Sugar for easier handling in Java -option java_package = "com.satoshilabs.trezor.lib.protobuf"; option java_outer_classname = "TrezorMessage"; +option java_package = "com.satoshilabs.trezor.lib.protobuf"; +// Include in BTC-only firmware option (include_in_bitcoin_only) = true; -import "google/protobuf/descriptor.proto"; - -/************************* WARNING *********************** -Due to the way extensions are accessed in pb2py, there needs to be a globally unique -name-ID mapping for extensions. That means that two different extensions, e.g. for -EnumValueOptions and FieldOptions, MUST NOT have the same ID. - -Using the same ID indicates the same purpose (protobuf does not allow multiple -extensions with the same name), such as EnumValueOptions.bitcoin_only and -FileOptions.include_in_bitcoin_only. pb2py can then find the extension under -either name. - -The convention to achieve this is as follows: - - extensions specific to a type have the same prefix: - * 50xxx for EnumValueOptions - * 51xxx for EnumOptions - * 52xxx for MessageOptions - * 53xxx for FieldOptions - - extensions that might be used across types have the same "global" prefix 60xxx -*/ -/** - * Options for specifying message direction and type of wire (normal/debug) - */ -extend google.protobuf.EnumValueOptions { - optional bool wire_in = 50002; // message can be transmitted via wire from PC to Trezor - optional bool wire_out = 50003; // message can be transmitted via wire from Trezor to PC - optional bool wire_debug_in = 50004; // message can be transmitted via debug wire from PC to Trezor - optional bool wire_debug_out = 50005; // message can be transmitted via debug wire from Trezor to PC - optional bool wire_tiny = 50006; // message is handled by Trezor when the USB stack is in tiny mode - optional bool wire_bootloader = 50007; // message is only handled by Trezor Bootloader - optional bool wire_no_fsm = 50008; // message is not handled by Trezor unless the USB stack is in tiny mode - - optional bool bitcoin_only = 60000; // enum value is available on BITCOIN_ONLY build - // (messages not marked bitcoin_only will be EXCLUDED) -} - -/** Options for tagging enum types */ -extend google.protobuf.EnumOptions { - optional bool has_bitcoin_only_values = 51001; // indicate that some values should be excluded on BITCOIN_ONLY builds -} - -/** Options for tagging message types */ -extend google.protobuf.MessageOptions { - optional bool experimental_message = 52001; // indicate that a message is intended for development and beta testing only and its definition may change at any time - optional uint32 wire_type = 52002; // override wire type specified in the MessageType enum -} - -/** Options for tagging field types */ -extend google.protobuf.FieldOptions { - optional bool experimental_field = 53001; // indicate that a field is intended for development and beta testing only -} - -/** Options for tagging files with protobuf definitions */ -extend google.protobuf.FileOptions { - optional bool include_in_bitcoin_only = 60000; // definitions are available on BITCOIN_ONLY build - // intentionally identical to `bitcoin_only` from enum -} - - /** * Mapping between Trezor wire identifier (uint) and a protobuf message */ enum MessageType { option (has_bitcoin_only_values) = true; + option (wire_enum) = true; // Management MessageType_Initialize = 0 [(bitcoin_only) = true, (wire_in) = true, (wire_tiny) = true]; @@ -102,6 +47,9 @@ enum MessageType { MessageType_BackupDevice = 34 [(bitcoin_only) = true, (wire_in) = true]; MessageType_EntropyRequest = 35 [(bitcoin_only) = true, (wire_out) = true]; MessageType_EntropyAck = 36 [(bitcoin_only) = true, (wire_in) = true]; + MessageType_PaymentRequest = 37 [(bitcoin_only) = true, (wire_in) = true]; + MessageType_EntropyCheckReady = 994 [(bitcoin_only) = true, (wire_out) = true]; + MessageType_EntropyCheckContinue = 995 [(bitcoin_only) = true, (wire_in) = true]; MessageType_PassphraseRequest = 41 [(bitcoin_only) = true, (wire_out) = true]; MessageType_PassphraseAck = 42 [(bitcoin_only) = true, (wire_in) = true, (wire_tiny) = true, (wire_no_fsm) = true]; MessageType_RecoveryDevice = 45 [(bitcoin_only) = true, (wire_in) = true]; @@ -120,21 +68,35 @@ enum MessageType { reserved 90 to 92; MessageType_UnlockPath = 93 [(bitcoin_only) = true, (wire_in) = true]; MessageType_UnlockedPathRequest = 94 [(bitcoin_only) = true, (wire_out) = true]; + MessageType_ShowDeviceTutorial = 95 [(bitcoin_only) = true, (wire_in) = true]; + MessageType_UnlockBootloader = 96 [(bitcoin_only) = true, (wire_in) = true]; + MessageType_AuthenticateDevice = 97 [(bitcoin_only) = true, (wire_in) = true]; + MessageType_AuthenticityProof = 98 [(bitcoin_only) = true, (wire_out) = true]; + MessageType_AuthenticityProofSizes = 99 [(bitcoin_only) = true, (wire_out) = true]; + MessageType_ChangeLanguage = 990 [(bitcoin_only) = true, (wire_in) = true]; + MessageType_DataChunkRequest = 991 [(bitcoin_only) = true, (wire_out) = true]; + MessageType_DataChunkAck = 992 [(bitcoin_only) = true, (wire_in) = true]; + MessageType_SetBrightness = 993 [(bitcoin_only) = true, (wire_in) = true]; + MessageType_GetSerialNumber = 996 [(bitcoin_only) = true, (wire_in) = true]; + MessageType_SerialNumber = 997 [(bitcoin_only) = true, (wire_out) = true]; + MessageType_GetAuthenticityProofChunk = 998 [(bitcoin_only) = true, (wire_in) = true]; + MessageType_AuthenticityProofChunk = 999 [(bitcoin_only) = true, (wire_out) = true]; MessageType_SetU2FCounter = 63 [(wire_in) = true]; MessageType_GetNextU2FCounter = 80 [(wire_in) = true]; MessageType_NextU2FCounter = 81 [(wire_out) = true]; - // Deprecated messages, kept for protobuf compatibility. - // Both are marked wire_out so that we don't need to implement incoming handler for legacy - MessageType_Deprecated_PassphraseStateRequest = 77 [deprecated = true]; - MessageType_Deprecated_PassphraseStateAck = 78 [deprecated = true]; + // Deprecated passphrase-related messages (used <2.3.0) + reserved 77 to 78; // Bootloader MessageType_FirmwareErase = 6 [(bitcoin_only) = true, (wire_in) = true, (wire_bootloader) = true]; MessageType_FirmwareUpload = 7 [(bitcoin_only) = true, (wire_in) = true, (wire_bootloader) = true]; MessageType_FirmwareRequest = 8 [(bitcoin_only) = true, (wire_out) = true, (wire_bootloader) = true]; - MessageType_SelfTest = 32 [(bitcoin_only) = true, (wire_in) = true, (wire_bootloader) = true]; + MessageType_ProdTestT1 = 32 [(bitcoin_only) = true, (wire_in) = true, (wire_bootloader) = true]; + + // BLE + MessageType_BleUnpair = 8001 [(bitcoin_only) = true, (wire_in) = true]; // Bitcoin MessageType_GetPublicKey = 11 [(bitcoin_only) = true, (wire_in) = true]; @@ -144,7 +106,6 @@ enum MessageType { MessageType_TxAck = 22 [(bitcoin_only) = true, (wire_in) = true]; MessageType_GetAddress = 29 [(bitcoin_only) = true, (wire_in) = true]; MessageType_Address = 30 [(bitcoin_only) = true, (wire_out) = true]; - MessageType_TxAckPaymentRequest = 37 [(wire_in) = true]; MessageType_SignMessage = 38 [(bitcoin_only) = true, (wire_in) = true]; MessageType_VerifyMessage = 39 [(bitcoin_only) = true, (wire_in) = true]; MessageType_MessageSignature = 40 [(bitcoin_only) = true, (wire_out) = true]; @@ -161,13 +122,13 @@ enum MessageType { MessageType_SignedIdentity = 54 [(bitcoin_only) = true, (wire_out) = true]; MessageType_GetECDHSessionKey = 61 [(bitcoin_only) = true, (wire_in) = true]; MessageType_ECDHSessionKey = 62 [(bitcoin_only) = true, (wire_out) = true]; - MessageType_CosiCommit = 71 [(bitcoin_only) = true, (wire_in) = true]; - MessageType_CosiCommitment = 72 [(bitcoin_only) = true, (wire_out) = true]; - MessageType_CosiSign = 73 [(bitcoin_only) = true, (wire_in) = true]; - MessageType_CosiSignature = 74 [(bitcoin_only) = true, (wire_out) = true]; + // dropped: CosiCommit, CosiCommitment, CosiSign, CosiSignature + MessageType_PaymentNotification = 52 [(bitcoin_only) = true, (wire_in) = true]; + reserved 71 to 74; // Debug - MessageType_DebugLinkDecision = 100 [(bitcoin_only) = true, (wire_debug_in) = true, (wire_tiny) = true, (wire_no_fsm) = true]; + MessageType_DebugLinkDecision = 100 + [(bitcoin_only) = true, (wire_debug_in) = true, (wire_tiny) = true, (wire_no_fsm) = true]; MessageType_DebugLinkGetState = 101 [(bitcoin_only) = true, (wire_debug_in) = true, (wire_tiny) = true]; MessageType_DebugLinkState = 102 [(bitcoin_only) = true, (wire_debug_out) = true]; MessageType_DebugLinkStop = 103 [(bitcoin_only) = true, (wire_debug_in) = true]; @@ -181,6 +142,18 @@ enum MessageType { MessageType_DebugLinkRecordScreen = 9003 [(bitcoin_only) = true, (wire_debug_in) = true]; MessageType_DebugLinkEraseSdCard = 9005 [(bitcoin_only) = true, (wire_debug_in) = true]; MessageType_DebugLinkWatchLayout = 9006 [(bitcoin_only) = true, (wire_debug_in) = true]; + MessageType_DebugLinkResetDebugEvents = 9007 [(bitcoin_only) = true, (wire_debug_in) = true]; + MessageType_DebugLinkOptigaSetSecMax = 9008 [(bitcoin_only) = true, (wire_debug_in) = true]; + MessageType_DebugLinkGetGcInfo = 9009 [(bitcoin_only) = true, (wire_debug_in) = true]; + MessageType_DebugLinkGcInfo = 9010 [(bitcoin_only) = true, (wire_debug_out) = true]; + MessageType_DebugLinkGetPairingInfo = 9011 [(bitcoin_only) = true, (wire_debug_in) = true]; + MessageType_DebugLinkPairingInfo = 9012 [(bitcoin_only) = true, (wire_debug_out) = true]; + MessageType_DebugLinkSetLogFilter = 9013 [(bitcoin_only) = true, (wire_debug_in) = true]; + MessageType_DebugLinkN4W1Connected = 9014 [(bitcoin_only) = true, (wire_debug_in) = true]; + MessageType_DebugLinkN4W1Write = 9015 [(bitcoin_only) = true, (wire_debug_out) = true]; + MessageType_DebugLinkN4W1Read = 9016 [(bitcoin_only) = true, (wire_debug_out) = true]; + MessageType_DebugLinkN4W1Response = 9017 [(bitcoin_only) = true, (wire_debug_in) = true]; + MessageType_DebugLinkSetBatteryState = 9018 [(bitcoin_only) = true, (wire_debug_in) = true]; // Ethereum MessageType_EthereumGetPublicKey = 450 [(wire_in) = true]; @@ -201,6 +174,10 @@ enum MessageType { MessageType_EthereumTypedDataValueAck = 468 [(wire_in) = true]; MessageType_EthereumTypedDataSignature = 469 [(wire_out) = true]; MessageType_EthereumSignTypedHash = 470 [(wire_in) = true]; + MessageType_EthereumDefinitionRequest = 471 [(wire_out) = true]; + MessageType_EthereumDefinitionAck = 472 [(wire_in) = true]; + MessageType_EthereumSignAuth7702 = 473 [(wire_in) = true]; + MessageType_EthereumAuth7702Signature = 474 [(wire_out) = true]; // NEM MessageType_NEMGetAddress = 67 [(wire_in) = true]; @@ -223,6 +200,7 @@ enum MessageType { MessageType_LiskPublicKey = 122 [(wire_out) = true]; */ reserved 114 to 122; + reserved 123 to 149; // reserved for internal use // Tezos MessageType_TezosGetAddress = 150 [(wire_in) = true]; @@ -246,12 +224,29 @@ enum MessageType { MessageType_StellarChangeTrustOp = 216 [(wire_in) = true]; MessageType_StellarAllowTrustOp = 217 [(wire_in) = true]; MessageType_StellarAccountMergeOp = 218 [(wire_in) = true]; - // omitted: StellarInflationOp is not a supported operation, would be 219 + reserved 219; // omitted: StellarInflationOp MessageType_StellarManageDataOp = 220 [(wire_in) = true]; MessageType_StellarBumpSequenceOp = 221 [(wire_in) = true]; MessageType_StellarManageBuyOfferOp = 222 [(wire_in) = true]; MessageType_StellarPathPaymentStrictSendOp = 223 [(wire_in) = true]; + reserved 224; // omitted: StellarCreateClaimableBalanceOp + MessageType_StellarClaimClaimableBalanceOp = 225 [(wire_in) = true]; + reserved 226; // omitted: StellarBeginSponsoringFutureReservesOp + reserved 227; // omitted: StellarEndSponsoringFutureReservesOp + reserved 228; // omitted: StellarRevokeSponsorshipOp + reserved 229; // omitted: StellarClawbackOp MessageType_StellarSignedTx = 230 [(wire_out) = true]; + reserved 231; // omitted: StellarClawbackClaimableBalanceOp + reserved 232; // omitted: StellarSetTrustLineFlagsOp + reserved 233; // omitted: StellarLiquidityPoolDepositOp + reserved 234; // omitted: StellarLiquidityPoolWithdrawOp + MessageType_StellarInvokeHostFunctionOp = 235 [(wire_in) = true]; + reserved 236; // omitted: StellarExtendFootprintTtl + reserved 237; // omitted: StellarRestoreFootprint + MessageType_StellarTxExtRequest = 238 [(wire_out) = true]; + MessageType_StellarTxExt = 239 [(wire_in) = true]; + MessageType_StellarSignSorobanAuthorization = 240 [(wire_in) = true]; + MessageType_StellarSorobanAuthorizationSignature = 241 [(wire_out) = true]; // Cardano // dropped Sign/VerifyMessage ids 300-302 @@ -287,35 +282,39 @@ enum MessageType { MessageType_CardanoTxInlineDatumChunk = 335 [(wire_in) = true]; MessageType_CardanoTxReferenceScriptChunk = 336 [(wire_in) = true]; MessageType_CardanoTxReferenceInput = 337 [(wire_in) = true]; + MessageType_CardanoSignMessageInit = 338 [(wire_in) = true]; + MessageType_CardanoMessageDataRequest = 339 [(wire_out) = true]; + MessageType_CardanoMessageDataResponse = 340 [(wire_in) = true]; + MessageType_CardanoMessageSignature = 341 [(wire_out) = true]; // Ripple MessageType_RippleGetAddress = 400 [(wire_in) = true]; MessageType_RippleAddress = 401 [(wire_out) = true]; MessageType_RippleSignTx = 402 [(wire_in) = true]; - MessageType_RippleSignedTx = 403 [(wire_in) = true]; + MessageType_RippleSignedTx = 403 [(wire_out) = true]; // Monero - MessageType_MoneroTransactionInitRequest = 501 [(wire_out) = true]; + MessageType_MoneroTransactionInitRequest = 501 [(wire_in) = true]; MessageType_MoneroTransactionInitAck = 502 [(wire_out) = true]; - MessageType_MoneroTransactionSetInputRequest = 503 [(wire_out) = true]; + MessageType_MoneroTransactionSetInputRequest = 503 [(wire_in) = true]; MessageType_MoneroTransactionSetInputAck = 504 [(wire_out) = true]; - MessageType_MoneroTransactionInputViniRequest = 507 [(wire_out) = true]; + MessageType_MoneroTransactionInputViniRequest = 507 [(wire_in) = true]; MessageType_MoneroTransactionInputViniAck = 508 [(wire_out) = true]; - MessageType_MoneroTransactionAllInputsSetRequest = 509 [(wire_out) = true]; + MessageType_MoneroTransactionAllInputsSetRequest = 509 [(wire_in) = true]; MessageType_MoneroTransactionAllInputsSetAck = 510 [(wire_out) = true]; - MessageType_MoneroTransactionSetOutputRequest = 511 [(wire_out) = true]; + MessageType_MoneroTransactionSetOutputRequest = 511 [(wire_in) = true]; MessageType_MoneroTransactionSetOutputAck = 512 [(wire_out) = true]; - MessageType_MoneroTransactionAllOutSetRequest = 513 [(wire_out) = true]; + MessageType_MoneroTransactionAllOutSetRequest = 513 [(wire_in) = true]; MessageType_MoneroTransactionAllOutSetAck = 514 [(wire_out) = true]; - MessageType_MoneroTransactionSignInputRequest = 515 [(wire_out) = true]; + MessageType_MoneroTransactionSignInputRequest = 515 [(wire_in) = true]; MessageType_MoneroTransactionSignInputAck = 516 [(wire_out) = true]; - MessageType_MoneroTransactionFinalRequest = 517 [(wire_out) = true]; + MessageType_MoneroTransactionFinalRequest = 517 [(wire_in) = true]; MessageType_MoneroTransactionFinalAck = 518 [(wire_out) = true]; - MessageType_MoneroKeyImageExportInitRequest = 530 [(wire_out) = true]; + MessageType_MoneroKeyImageExportInitRequest = 530 [(wire_in) = true]; MessageType_MoneroKeyImageExportInitAck = 531 [(wire_out) = true]; - MessageType_MoneroKeyImageSyncStepRequest = 532 [(wire_out) = true]; + MessageType_MoneroKeyImageSyncStepRequest = 532 [(wire_in) = true]; MessageType_MoneroKeyImageSyncStepAck = 533 [(wire_out) = true]; - MessageType_MoneroKeyImageSyncFinalRequest = 534 [(wire_out) = true]; + MessageType_MoneroKeyImageSyncFinalRequest = 534 [(wire_in) = true]; MessageType_MoneroKeyImageSyncFinalAck = 535 [(wire_out) = true]; MessageType_MoneroGetAddress = 540 [(wire_in) = true]; MessageType_MoneroAddress = 541 [(wire_out) = true]; @@ -340,21 +339,72 @@ enum MessageType { MessageType_EosTxActionAck = 604 [(wire_in) = true]; MessageType_EosSignedTx = 605 [(wire_out) = true]; - // Binance - MessageType_BinanceGetAddress = 700 [(wire_in) = true]; - MessageType_BinanceAddress = 701 [(wire_out) = true]; - MessageType_BinanceGetPublicKey = 702 [(wire_in) = true]; - MessageType_BinancePublicKey = 703 [(wire_out) = true]; - MessageType_BinanceSignTx = 704 [(wire_in) = true]; - MessageType_BinanceTxRequest = 705 [(wire_out) = true]; - MessageType_BinanceTransferMsg = 706 [(wire_in) = true]; - MessageType_BinanceOrderMsg = 707 [(wire_in) = true]; - MessageType_BinanceCancelMsg = 708 [(wire_in) = true]; - MessageType_BinanceSignedTx = 709 [(wire_out) = true]; + // BNB Beacon Chain (deprecated) + reserved 700 to 709; // WebAuthn MessageType_WebAuthnListResidentCredentials = 800 [(wire_in) = true]; MessageType_WebAuthnCredentials = 801 [(wire_out) = true]; MessageType_WebAuthnAddResidentCredential = 802 [(wire_in) = true]; MessageType_WebAuthnRemoveResidentCredential = 803 [(wire_in) = true]; + MessageType_WebAuthnCredentialsAck = 804 [(wire_in) = true]; + + // Solana + MessageType_SolanaGetPublicKey = 900 [(wire_in) = true]; + MessageType_SolanaPublicKey = 901 [(wire_out) = true]; + MessageType_SolanaGetAddress = 902 [(wire_in) = true]; + MessageType_SolanaAddress = 903 [(wire_out) = true]; + MessageType_SolanaSignTx = 904 [(wire_in) = true]; + MessageType_SolanaTxSignature = 905 [(wire_out) = true]; + MessageType_SolanaSignMessage = 906 [(wire_in) = true]; + MessageType_SolanaMessageSignature = 907 [(wire_out) = true]; + MessageType_SolanaVerifyMessage = 908 [(wire_in) = true]; + + // THP + MessageType_ThpCreateNewSession = 1000 [(wire_in) = true, (bitcoin_only) = true]; + reserved 1001 to 1015; // see ThpMessageType in messages-thp.proto + MessageType_ThpCredentialRequest = 1016 [(wire_in) = true, (bitcoin_only) = true]; + MessageType_ThpCredentialResponse = 1017 [(wire_out) = true, (bitcoin_only) = true]; + reserved 1018 to 1099; // see ThpMessageType in messages-thp.proto + + // Nostr + MessageType_NostrGetPubkey = 2001 [(wire_in) = true]; + MessageType_NostrPubkey = 2002 [(wire_out) = true]; + MessageType_NostrSignEvent = 2003 [(wire_in) = true]; + MessageType_NostrEventSignature = 2004 [(wire_out) = true]; + + // Evolu + MessageType_EvoluGetNode = 2100 [(bitcoin_only) = true, (wire_in) = true]; + MessageType_EvoluNode = 2101 [(bitcoin_only) = true, (wire_out) = true]; + MessageType_EvoluSignRegistrationRequest = 2102 [(bitcoin_only) = true, (wire_in) = true]; + MessageType_EvoluRegistrationRequest = 2103 [(bitcoin_only) = true, (wire_out) = true]; + MessageType_EvoluGetDelegatedIdentityKey = 2104 [(bitcoin_only) = true, (wire_in) = true]; + MessageType_EvoluDelegatedIdentityKey = 2105 [(bitcoin_only) = true, (wire_out) = true]; + MessageType_EvoluIndexManagement = 2106 [(bitcoin_only) = true, (wire_in) = true]; + MessageType_EvoluIndexManagementResponse = 2107 [(bitcoin_only) = true, (wire_out) = true]; + + // Tron + MessageType_TronGetAddress = 2200 [(wire_in) = true]; + MessageType_TronAddress = 2201 [(wire_out) = true]; + MessageType_TronSignTx = 2202 [(wire_in) = true]; + MessageType_TronSignature = 2203 [(wire_out) = true]; + MessageType_TronContractRequest = 2204 [(wire_out) = true]; + MessageType_TronTransferContract = 2205 [(wire_in) = true]; + MessageType_TronTriggerSmartContract = 2206 [(wire_in) = true]; + MessageType_TronFreezeBalanceV2Contract = 2207 [(wire_in) = true]; + MessageType_TronUnfreezeBalanceV2Contract = 2208 [(wire_in) = true]; + MessageType_TronWithdrawUnfreeze = 2209 [(wire_in) = true]; + MessageType_TronVoteWitnessContract = 2210 [(wire_in) = true]; + // 2 indexes reserved for (un)delegation. PR in review. + MessageType_TronWithdrawBalance = 2213 [(wire_in) = true]; + + // Benchmark + MessageType_BenchmarkListNames = 9100 [(bitcoin_only) = true]; + MessageType_BenchmarkNames = 9101 [(bitcoin_only) = true]; + MessageType_BenchmarkRun = 9102 [(bitcoin_only) = true]; + MessageType_BenchmarkResult = 9103 [(bitcoin_only) = true]; + + // Telemetry + MessageType_TelemetryGet = 1100 [(bitcoin_only) = true, (wire_in) = true]; + MessageType_Telemetry = 1101 [(bitcoin_only) = true, (wire_out) = true]; } diff --git a/src/device_trezor/trezor/protob/options.proto b/src/device_trezor/trezor/protob/options.proto new file mode 100644 index 000000000..93ad7366e --- /dev/null +++ b/src/device_trezor/trezor/protob/options.proto @@ -0,0 +1,72 @@ +syntax = "proto2"; +package hw.trezor.messages; + +import "google/protobuf/descriptor.proto"; + +// Sugar for easier handling in Java +option java_outer_classname = "TrezorOptions"; +option java_package = "com.satoshilabs.trezor.lib.protobuf"; + +/************************* WARNING *********************** +Due to the way extensions are accessed in pb2py, there needs to be a globally unique +name-ID mapping for extensions. That means that two different extensions, e.g. for +EnumValueOptions and FieldOptions, MUST NOT have the same ID. + +Using the same ID indicates the same purpose (protobuf does not allow multiple +extensions with the same name), such as EnumValueOptions.bitcoin_only and +FileOptions.include_in_bitcoin_only. pb2py can then find the extension under +either name. + +The convention to achieve this is as follows: + - extensions specific to a type have the same prefix: + * 50xxx for EnumValueOptions + * 51xxx for EnumOptions + * 52xxx for MessageOptions + * 53xxx for FieldOptions + - extensions that might be used across types have the same "global" prefix 60xxx +*/ + +/** + * Options for specifying message direction and type of wire (normal/debug) + */ +extend google.protobuf.EnumValueOptions { + optional bool wire_in = 50002; // message can be transmitted via wire from PC to Trezor + optional bool wire_out = 50003; // message can be transmitted via wire from Trezor to PC + optional bool wire_debug_in = 50004; // message can be transmitted via debug wire from PC to Trezor + optional bool wire_debug_out = 50005; // message can be transmitted via debug wire from Trezor to PC + optional bool wire_tiny = 50006; // message is handled by Trezor when the USB stack is in tiny mode + optional bool wire_bootloader = 50007; // message is only handled by Trezor Bootloader + optional bool wire_no_fsm = 50008; // message is not handled by Trezor unless the USB stack is in tiny mode + + optional bool bitcoin_only = 60000; // enum value is available on BITCOIN_ONLY build + // (messages not marked bitcoin_only will be EXCLUDED) +} + +/** Options for tagging enum types */ +extend google.protobuf.EnumOptions { + optional bool has_bitcoin_only_values = 51001; // indicate that some values should be excluded + // on BITCOIN_ONLY builds + optional bool wire_enum = 51002; // this enum is used for mapping wire type integer to message + // type, it cannot be used as normal enum +} + +/** Options for tagging message types */ +extend google.protobuf.MessageOptions { + optional bool experimental_message = 52001; // indicate that a message is intended for development and beta testing + // only and its definition may change at any time + optional uint32 wire_type = 52002; // override wire type specified in the MessageType enum + optional bool internal_only = 52003; // indicate that a message is intended for internal use + // only and should not be transmitted via the wire +} + +/** Options for tagging field types */ +extend google.protobuf.FieldOptions { + optional bool experimental_field = 53001; // indicate that a field is intended for development + // and beta testing only +} + +/** Options for tagging files with protobuf definitions */ +extend google.protobuf.FileOptions { + optional bool include_in_bitcoin_only = 60000; // definitions are available on BITCOIN_ONLY build + // intentionally identical to `bitcoin_only` from enum +}