diff --git a/firmware/Makefile b/firmware/Makefile index eff59afc2..710c36f4d 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -37,6 +37,7 @@ OBJS += ../trezor-crypto/aes_modes.o OBJS += ../trezor-qrenc/qr_encode.o +OBJS += protob/pb_common.o OBJS += protob/pb_decode.o OBJS += protob/pb_encode.o OBJS += protob/messages.pb.o diff --git a/firmware/protob/messages.options b/firmware/protob/messages.options index 2342ca2b8..cd887bb65 100644 --- a/firmware/protob/messages.options +++ b/firmware/protob/messages.options @@ -12,7 +12,6 @@ ApplySettings.label max_size:33 Ping.message max_size:256 Success.message max_size:256 -Success.payload max_size:1024 Failure.message max_size:256 @@ -49,12 +48,12 @@ RecoveryDevice.label max_size:33 WordAck.word max_size:12 SignMessage.address_n max_count:8 -SignMessage.message max_size:256 +SignMessage.message max_size:1024 SignMessage.coin_name max_size:17 VerifyMessage.address max_size:35 VerifyMessage.signature max_size:65 -VerifyMessage.message max_size:256 +VerifyMessage.message max_size:1024 MessageSignature.address max_size:35 MessageSignature.signature max_size:65 @@ -64,13 +63,24 @@ EncryptMessage.message max_size:1024 EncryptMessage.address_n max_count:8 EncryptMessage.coin_name max_size:17 +EncryptedMessage.nonce max_size:33 +EncryptedMessage.message max_size:1120 +EncryptedMessage.hmac max_size:8 + DecryptMessage.address_n max_count:8 -DecryptMessage.message max_size:1024 +DecryptMessage.nonce max_size:33 +DecryptMessage.message max_size:1120 # 1 + 9 + 1024 + 21 + 65 +DecryptMessage.hmac max_size:8 + +DecryptedMessage.address max_size:35 +DecryptedMessage.message max_size:1024 CipherKeyValue.address_n max_count:8 CipherKeyValue.key max_size:256 CipherKeyValue.value max_size:1024 +CipheredKeyValue.value max_size:1024 + EstimateTxSize.coin_name max_size:17 SignTx.coin_name max_size:17 diff --git a/firmware/protob/messages.pb.c b/firmware/protob/messages.pb.c index 1b51ed724..72b7d0438 100644 --- a/firmware/protob/messages.pb.c +++ b/firmware/protob/messages.pb.c @@ -1,8 +1,12 @@ /* Automatically generated nanopb constant definitions */ -/* Generated by nanopb-0.2.8 */ +/* Generated by nanopb-0.3.1 */ #include "messages.pb.h" +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + const char GetAddress_coin_name_default[17] = "Bitcoin"; const char LoadDevice_language_default[17] = "english"; const uint32_t ResetDevice_strength_default = 128u; @@ -20,21 +24,21 @@ const pb_field_t Initialize_fields[1] = { }; const pb_field_t Features_fields[16] = { - PB_FIELD2( 1, STRING , OPTIONAL, STATIC , FIRST, Features, vendor, vendor, 0), - PB_FIELD2( 2, UINT32 , OPTIONAL, STATIC , OTHER, Features, major_version, vendor, 0), - PB_FIELD2( 3, UINT32 , OPTIONAL, STATIC , OTHER, Features, minor_version, major_version, 0), - PB_FIELD2( 4, UINT32 , OPTIONAL, STATIC , OTHER, Features, patch_version, minor_version, 0), - PB_FIELD2( 5, BOOL , OPTIONAL, STATIC , OTHER, Features, bootloader_mode, patch_version, 0), - PB_FIELD2( 6, STRING , OPTIONAL, STATIC , OTHER, Features, device_id, bootloader_mode, 0), - PB_FIELD2( 7, BOOL , OPTIONAL, STATIC , OTHER, Features, pin_protection, device_id, 0), - PB_FIELD2( 8, BOOL , OPTIONAL, STATIC , OTHER, Features, passphrase_protection, pin_protection, 0), - PB_FIELD2( 9, STRING , OPTIONAL, STATIC , OTHER, Features, language, passphrase_protection, 0), - PB_FIELD2( 10, STRING , OPTIONAL, STATIC , OTHER, Features, label, language, 0), - PB_FIELD2( 11, MESSAGE , REPEATED, STATIC , OTHER, Features, coins, label, &CoinType_fields), - PB_FIELD2( 12, BOOL , OPTIONAL, STATIC , OTHER, Features, initialized, coins, 0), - PB_FIELD2( 13, BYTES , OPTIONAL, STATIC , OTHER, Features, revision, initialized, 0), - PB_FIELD2( 14, BYTES , OPTIONAL, STATIC , OTHER, Features, bootloader_hash, revision, 0), - PB_FIELD2( 15, BOOL , OPTIONAL, STATIC , OTHER, Features, imported, bootloader_hash, 0), + PB_FIELD( 1, STRING , OPTIONAL, STATIC , FIRST, Features, vendor, vendor, 0), + PB_FIELD( 2, UINT32 , OPTIONAL, STATIC , OTHER, Features, major_version, vendor, 0), + PB_FIELD( 3, UINT32 , OPTIONAL, STATIC , OTHER, Features, minor_version, major_version, 0), + PB_FIELD( 4, UINT32 , OPTIONAL, STATIC , OTHER, Features, patch_version, minor_version, 0), + PB_FIELD( 5, BOOL , OPTIONAL, STATIC , OTHER, Features, bootloader_mode, patch_version, 0), + PB_FIELD( 6, STRING , OPTIONAL, STATIC , OTHER, Features, device_id, bootloader_mode, 0), + PB_FIELD( 7, BOOL , OPTIONAL, STATIC , OTHER, Features, pin_protection, device_id, 0), + PB_FIELD( 8, BOOL , OPTIONAL, STATIC , OTHER, Features, passphrase_protection, pin_protection, 0), + PB_FIELD( 9, STRING , OPTIONAL, STATIC , OTHER, Features, language, passphrase_protection, 0), + PB_FIELD( 10, STRING , OPTIONAL, STATIC , OTHER, Features, label, language, 0), + PB_FIELD( 11, MESSAGE , REPEATED, STATIC , OTHER, Features, coins, label, &CoinType_fields), + PB_FIELD( 12, BOOL , OPTIONAL, STATIC , OTHER, Features, initialized, coins, 0), + PB_FIELD( 13, BYTES , OPTIONAL, STATIC , OTHER, Features, revision, initialized, 0), + PB_FIELD( 14, BYTES , OPTIONAL, STATIC , OTHER, Features, bootloader_hash, revision, 0), + PB_FIELD( 15, BOOL , OPTIONAL, STATIC , OTHER, Features, imported, bootloader_hash, 0), PB_LAST_FIELD }; @@ -43,39 +47,38 @@ const pb_field_t ClearSession_fields[1] = { }; const pb_field_t ApplySettings_fields[3] = { - PB_FIELD2( 1, STRING , OPTIONAL, STATIC , FIRST, ApplySettings, language, language, 0), - PB_FIELD2( 2, STRING , OPTIONAL, STATIC , OTHER, ApplySettings, label, language, 0), + PB_FIELD( 1, STRING , OPTIONAL, STATIC , FIRST, ApplySettings, language, language, 0), + PB_FIELD( 2, STRING , OPTIONAL, STATIC , OTHER, ApplySettings, label, language, 0), PB_LAST_FIELD }; const pb_field_t ChangePin_fields[2] = { - PB_FIELD2( 1, BOOL , OPTIONAL, STATIC , FIRST, ChangePin, remove, remove, 0), + PB_FIELD( 1, BOOL , OPTIONAL, STATIC , FIRST, ChangePin, remove, remove, 0), PB_LAST_FIELD }; const pb_field_t Ping_fields[5] = { - PB_FIELD2( 1, STRING , OPTIONAL, STATIC , FIRST, Ping, message, message, 0), - PB_FIELD2( 2, BOOL , OPTIONAL, STATIC , OTHER, Ping, button_protection, message, 0), - PB_FIELD2( 3, BOOL , OPTIONAL, STATIC , OTHER, Ping, pin_protection, button_protection, 0), - PB_FIELD2( 4, BOOL , OPTIONAL, STATIC , OTHER, Ping, passphrase_protection, pin_protection, 0), + PB_FIELD( 1, STRING , OPTIONAL, STATIC , FIRST, Ping, message, message, 0), + PB_FIELD( 2, BOOL , OPTIONAL, STATIC , OTHER, Ping, button_protection, message, 0), + PB_FIELD( 3, BOOL , OPTIONAL, STATIC , OTHER, Ping, pin_protection, button_protection, 0), + PB_FIELD( 4, BOOL , OPTIONAL, STATIC , OTHER, Ping, passphrase_protection, pin_protection, 0), PB_LAST_FIELD }; -const pb_field_t Success_fields[3] = { - PB_FIELD2( 1, STRING , OPTIONAL, STATIC , FIRST, Success, message, message, 0), - PB_FIELD2( 2, BYTES , OPTIONAL, STATIC , OTHER, Success, payload, message, 0), +const pb_field_t Success_fields[2] = { + PB_FIELD( 1, STRING , OPTIONAL, STATIC , FIRST, Success, message, message, 0), PB_LAST_FIELD }; const pb_field_t Failure_fields[3] = { - PB_FIELD2( 1, ENUM , OPTIONAL, STATIC , FIRST, Failure, code, code, 0), - PB_FIELD2( 2, STRING , OPTIONAL, STATIC , OTHER, Failure, message, code, 0), + PB_FIELD( 1, ENUM , OPTIONAL, STATIC , FIRST, Failure, code, code, 0), + PB_FIELD( 2, STRING , OPTIONAL, STATIC , OTHER, Failure, message, code, 0), PB_LAST_FIELD }; const pb_field_t ButtonRequest_fields[3] = { - PB_FIELD2( 1, ENUM , OPTIONAL, STATIC , FIRST, ButtonRequest, code, code, 0), - PB_FIELD2( 2, STRING , OPTIONAL, STATIC , OTHER, ButtonRequest, data, code, 0), + PB_FIELD( 1, ENUM , OPTIONAL, STATIC , FIRST, ButtonRequest, code, code, 0), + PB_FIELD( 2, STRING , OPTIONAL, STATIC , OTHER, ButtonRequest, data, code, 0), PB_LAST_FIELD }; @@ -84,12 +87,12 @@ const pb_field_t ButtonAck_fields[1] = { }; const pb_field_t PinMatrixRequest_fields[2] = { - PB_FIELD2( 1, ENUM , OPTIONAL, STATIC , FIRST, PinMatrixRequest, type, type, 0), + PB_FIELD( 1, ENUM , OPTIONAL, STATIC , FIRST, PinMatrixRequest, type, type, 0), PB_LAST_FIELD }; const pb_field_t PinMatrixAck_fields[2] = { - PB_FIELD2( 1, STRING , REQUIRED, STATIC , FIRST, PinMatrixAck, pin, pin, 0), + PB_FIELD( 1, STRING , REQUIRED, STATIC , FIRST, PinMatrixAck, pin, pin, 0), PB_LAST_FIELD }; @@ -102,40 +105,40 @@ const pb_field_t PassphraseRequest_fields[1] = { }; const pb_field_t PassphraseAck_fields[2] = { - PB_FIELD2( 1, STRING , REQUIRED, STATIC , FIRST, PassphraseAck, passphrase, passphrase, 0), + PB_FIELD( 1, STRING , REQUIRED, STATIC , FIRST, PassphraseAck, passphrase, passphrase, 0), PB_LAST_FIELD }; const pb_field_t GetEntropy_fields[2] = { - PB_FIELD2( 1, UINT32 , REQUIRED, STATIC , FIRST, GetEntropy, size, size, 0), + PB_FIELD( 1, UINT32 , REQUIRED, STATIC , FIRST, GetEntropy, size, size, 0), PB_LAST_FIELD }; const pb_field_t Entropy_fields[2] = { - PB_FIELD2( 1, BYTES , REQUIRED, STATIC , FIRST, Entropy, entropy, entropy, 0), + PB_FIELD( 1, BYTES , REQUIRED, STATIC , FIRST, Entropy, entropy, entropy, 0), PB_LAST_FIELD }; const pb_field_t GetPublicKey_fields[2] = { - PB_FIELD2( 1, UINT32 , REPEATED, STATIC , FIRST, GetPublicKey, address_n, address_n, 0), + PB_FIELD( 1, UINT32 , REPEATED, STATIC , FIRST, GetPublicKey, address_n, address_n, 0), PB_LAST_FIELD }; const pb_field_t PublicKey_fields[3] = { - PB_FIELD2( 1, MESSAGE , REQUIRED, STATIC , FIRST, PublicKey, node, node, &HDNodeType_fields), - PB_FIELD2( 2, STRING , OPTIONAL, STATIC , OTHER, PublicKey, xpub, node, 0), + PB_FIELD( 1, MESSAGE , REQUIRED, STATIC , FIRST, PublicKey, node, node, &HDNodeType_fields), + PB_FIELD( 2, STRING , OPTIONAL, STATIC , OTHER, PublicKey, xpub, node, 0), PB_LAST_FIELD }; const pb_field_t GetAddress_fields[4] = { - PB_FIELD2( 1, UINT32 , REPEATED, STATIC , FIRST, GetAddress, address_n, address_n, 0), - PB_FIELD2( 2, STRING , OPTIONAL, STATIC , OTHER, GetAddress, coin_name, address_n, &GetAddress_coin_name_default), - PB_FIELD2( 3, BOOL , OPTIONAL, STATIC , OTHER, GetAddress, show_display, coin_name, 0), + PB_FIELD( 1, UINT32 , REPEATED, STATIC , FIRST, GetAddress, address_n, address_n, 0), + PB_FIELD( 2, STRING , OPTIONAL, STATIC , OTHER, GetAddress, coin_name, address_n, &GetAddress_coin_name_default), + PB_FIELD( 3, BOOL , OPTIONAL, STATIC , OTHER, GetAddress, show_display, coin_name, 0), PB_LAST_FIELD }; const pb_field_t Address_fields[2] = { - PB_FIELD2( 1, STRING , REQUIRED, STATIC , FIRST, Address, address, address, 0), + PB_FIELD( 1, STRING , REQUIRED, STATIC , FIRST, Address, address, address, 0), PB_LAST_FIELD }; @@ -144,23 +147,23 @@ const pb_field_t WipeDevice_fields[1] = { }; const pb_field_t LoadDevice_fields[8] = { - PB_FIELD2( 1, STRING , OPTIONAL, STATIC , FIRST, LoadDevice, mnemonic, mnemonic, 0), - PB_FIELD2( 2, MESSAGE , OPTIONAL, STATIC , OTHER, LoadDevice, node, mnemonic, &HDNodeType_fields), - PB_FIELD2( 3, STRING , OPTIONAL, STATIC , OTHER, LoadDevice, pin, node, 0), - PB_FIELD2( 4, BOOL , OPTIONAL, STATIC , OTHER, LoadDevice, passphrase_protection, pin, 0), - PB_FIELD2( 5, STRING , OPTIONAL, STATIC , OTHER, LoadDevice, language, passphrase_protection, &LoadDevice_language_default), - PB_FIELD2( 6, STRING , OPTIONAL, STATIC , OTHER, LoadDevice, label, language, 0), - PB_FIELD2( 7, BOOL , OPTIONAL, STATIC , OTHER, LoadDevice, skip_checksum, label, 0), + PB_FIELD( 1, STRING , OPTIONAL, STATIC , FIRST, LoadDevice, mnemonic, mnemonic, 0), + PB_FIELD( 2, MESSAGE , OPTIONAL, STATIC , OTHER, LoadDevice, node, mnemonic, &HDNodeType_fields), + PB_FIELD( 3, STRING , OPTIONAL, STATIC , OTHER, LoadDevice, pin, node, 0), + PB_FIELD( 4, BOOL , OPTIONAL, STATIC , OTHER, LoadDevice, passphrase_protection, pin, 0), + PB_FIELD( 5, STRING , OPTIONAL, STATIC , OTHER, LoadDevice, language, passphrase_protection, &LoadDevice_language_default), + PB_FIELD( 6, STRING , OPTIONAL, STATIC , OTHER, LoadDevice, label, language, 0), + PB_FIELD( 7, BOOL , OPTIONAL, STATIC , OTHER, LoadDevice, skip_checksum, label, 0), PB_LAST_FIELD }; const pb_field_t ResetDevice_fields[7] = { - PB_FIELD2( 1, BOOL , OPTIONAL, STATIC , FIRST, ResetDevice, display_random, display_random, 0), - PB_FIELD2( 2, UINT32 , OPTIONAL, STATIC , OTHER, ResetDevice, strength, display_random, &ResetDevice_strength_default), - PB_FIELD2( 3, BOOL , OPTIONAL, STATIC , OTHER, ResetDevice, passphrase_protection, strength, 0), - PB_FIELD2( 4, BOOL , OPTIONAL, STATIC , OTHER, ResetDevice, pin_protection, passphrase_protection, 0), - PB_FIELD2( 5, STRING , OPTIONAL, STATIC , OTHER, ResetDevice, language, pin_protection, &ResetDevice_language_default), - PB_FIELD2( 6, STRING , OPTIONAL, STATIC , OTHER, ResetDevice, label, language, 0), + PB_FIELD( 1, BOOL , OPTIONAL, STATIC , FIRST, ResetDevice, display_random, display_random, 0), + PB_FIELD( 2, UINT32 , OPTIONAL, STATIC , OTHER, ResetDevice, strength, display_random, &ResetDevice_strength_default), + PB_FIELD( 3, BOOL , OPTIONAL, STATIC , OTHER, ResetDevice, passphrase_protection, strength, 0), + PB_FIELD( 4, BOOL , OPTIONAL, STATIC , OTHER, ResetDevice, pin_protection, passphrase_protection, 0), + PB_FIELD( 5, STRING , OPTIONAL, STATIC , OTHER, ResetDevice, language, pin_protection, &ResetDevice_language_default), + PB_FIELD( 6, STRING , OPTIONAL, STATIC , OTHER, ResetDevice, label, language, 0), PB_LAST_FIELD }; @@ -169,17 +172,17 @@ const pb_field_t EntropyRequest_fields[1] = { }; const pb_field_t EntropyAck_fields[2] = { - PB_FIELD2( 1, BYTES , OPTIONAL, STATIC , FIRST, EntropyAck, entropy, entropy, 0), + PB_FIELD( 1, BYTES , OPTIONAL, STATIC , FIRST, EntropyAck, entropy, entropy, 0), PB_LAST_FIELD }; const pb_field_t RecoveryDevice_fields[7] = { - PB_FIELD2( 1, UINT32 , OPTIONAL, STATIC , FIRST, RecoveryDevice, word_count, word_count, 0), - PB_FIELD2( 2, BOOL , OPTIONAL, STATIC , OTHER, RecoveryDevice, passphrase_protection, word_count, 0), - PB_FIELD2( 3, BOOL , OPTIONAL, STATIC , OTHER, RecoveryDevice, pin_protection, passphrase_protection, 0), - PB_FIELD2( 4, STRING , OPTIONAL, STATIC , OTHER, RecoveryDevice, language, pin_protection, &RecoveryDevice_language_default), - PB_FIELD2( 5, STRING , OPTIONAL, STATIC , OTHER, RecoveryDevice, label, language, 0), - PB_FIELD2( 6, BOOL , OPTIONAL, STATIC , OTHER, RecoveryDevice, enforce_wordlist, label, 0), + PB_FIELD( 1, UINT32 , OPTIONAL, STATIC , FIRST, RecoveryDevice, word_count, word_count, 0), + PB_FIELD( 2, BOOL , OPTIONAL, STATIC , OTHER, RecoveryDevice, passphrase_protection, word_count, 0), + PB_FIELD( 3, BOOL , OPTIONAL, STATIC , OTHER, RecoveryDevice, pin_protection, passphrase_protection, 0), + PB_FIELD( 4, STRING , OPTIONAL, STATIC , OTHER, RecoveryDevice, language, pin_protection, &RecoveryDevice_language_default), + PB_FIELD( 5, STRING , OPTIONAL, STATIC , OTHER, RecoveryDevice, label, language, 0), + PB_FIELD( 6, BOOL , OPTIONAL, STATIC , OTHER, RecoveryDevice, enforce_wordlist, label, 0), PB_LAST_FIELD }; @@ -188,91 +191,111 @@ const pb_field_t WordRequest_fields[1] = { }; const pb_field_t WordAck_fields[2] = { - PB_FIELD2( 1, STRING , REQUIRED, STATIC , FIRST, WordAck, word, word, 0), + PB_FIELD( 1, STRING , REQUIRED, STATIC , FIRST, WordAck, word, word, 0), PB_LAST_FIELD }; const pb_field_t SignMessage_fields[4] = { - PB_FIELD2( 1, UINT32 , REPEATED, STATIC , FIRST, SignMessage, address_n, address_n, 0), - PB_FIELD2( 2, BYTES , REQUIRED, STATIC , OTHER, SignMessage, message, address_n, 0), - PB_FIELD2( 3, STRING , OPTIONAL, STATIC , OTHER, SignMessage, coin_name, message, &SignMessage_coin_name_default), + PB_FIELD( 1, UINT32 , REPEATED, STATIC , FIRST, SignMessage, address_n, address_n, 0), + PB_FIELD( 2, BYTES , REQUIRED, STATIC , OTHER, SignMessage, message, address_n, 0), + PB_FIELD( 3, STRING , OPTIONAL, STATIC , OTHER, SignMessage, coin_name, message, &SignMessage_coin_name_default), PB_LAST_FIELD }; const pb_field_t VerifyMessage_fields[4] = { - PB_FIELD2( 1, STRING , OPTIONAL, STATIC , FIRST, VerifyMessage, address, address, 0), - PB_FIELD2( 2, BYTES , OPTIONAL, STATIC , OTHER, VerifyMessage, signature, address, 0), - PB_FIELD2( 3, BYTES , OPTIONAL, STATIC , OTHER, VerifyMessage, message, signature, 0), + PB_FIELD( 1, STRING , OPTIONAL, STATIC , FIRST, VerifyMessage, address, address, 0), + PB_FIELD( 2, BYTES , OPTIONAL, STATIC , OTHER, VerifyMessage, signature, address, 0), + PB_FIELD( 3, BYTES , OPTIONAL, STATIC , OTHER, VerifyMessage, message, signature, 0), PB_LAST_FIELD }; const pb_field_t MessageSignature_fields[3] = { - PB_FIELD2( 1, STRING , OPTIONAL, STATIC , FIRST, MessageSignature, address, address, 0), - PB_FIELD2( 2, BYTES , OPTIONAL, STATIC , OTHER, MessageSignature, signature, address, 0), + PB_FIELD( 1, STRING , OPTIONAL, STATIC , FIRST, MessageSignature, address, address, 0), + PB_FIELD( 2, BYTES , OPTIONAL, STATIC , OTHER, MessageSignature, signature, address, 0), PB_LAST_FIELD }; const pb_field_t EncryptMessage_fields[6] = { - PB_FIELD2( 1, BYTES , OPTIONAL, STATIC , FIRST, EncryptMessage, pubkey, pubkey, 0), - PB_FIELD2( 2, BYTES , OPTIONAL, STATIC , OTHER, EncryptMessage, message, pubkey, 0), - PB_FIELD2( 3, BOOL , OPTIONAL, STATIC , OTHER, EncryptMessage, display_only, message, 0), - PB_FIELD2( 4, UINT32 , REPEATED, STATIC , OTHER, EncryptMessage, address_n, display_only, 0), - PB_FIELD2( 5, STRING , OPTIONAL, STATIC , OTHER, EncryptMessage, coin_name, address_n, &EncryptMessage_coin_name_default), + PB_FIELD( 1, BYTES , OPTIONAL, STATIC , FIRST, EncryptMessage, pubkey, pubkey, 0), + PB_FIELD( 2, BYTES , OPTIONAL, STATIC , OTHER, EncryptMessage, message, pubkey, 0), + PB_FIELD( 3, BOOL , OPTIONAL, STATIC , OTHER, EncryptMessage, display_only, message, 0), + PB_FIELD( 4, UINT32 , REPEATED, STATIC , OTHER, EncryptMessage, address_n, display_only, 0), + PB_FIELD( 5, STRING , OPTIONAL, STATIC , OTHER, EncryptMessage, coin_name, address_n, &EncryptMessage_coin_name_default), + PB_LAST_FIELD +}; + +const pb_field_t EncryptedMessage_fields[4] = { + PB_FIELD( 1, BYTES , OPTIONAL, STATIC , FIRST, EncryptedMessage, nonce, nonce, 0), + PB_FIELD( 2, BYTES , OPTIONAL, STATIC , OTHER, EncryptedMessage, message, nonce, 0), + PB_FIELD( 3, BYTES , OPTIONAL, STATIC , OTHER, EncryptedMessage, hmac, message, 0), PB_LAST_FIELD }; -const pb_field_t DecryptMessage_fields[3] = { - PB_FIELD2( 1, UINT32 , REPEATED, STATIC , FIRST, DecryptMessage, address_n, address_n, 0), - PB_FIELD2( 2, BYTES , OPTIONAL, STATIC , OTHER, DecryptMessage, message, address_n, 0), +const pb_field_t DecryptMessage_fields[5] = { + PB_FIELD( 1, UINT32 , REPEATED, STATIC , FIRST, DecryptMessage, address_n, address_n, 0), + PB_FIELD( 2, BYTES , OPTIONAL, STATIC , OTHER, DecryptMessage, nonce, address_n, 0), + PB_FIELD( 3, BYTES , OPTIONAL, STATIC , OTHER, DecryptMessage, message, nonce, 0), + PB_FIELD( 4, BYTES , OPTIONAL, STATIC , OTHER, DecryptMessage, hmac, message, 0), + PB_LAST_FIELD +}; + +const pb_field_t DecryptedMessage_fields[3] = { + PB_FIELD( 1, BYTES , OPTIONAL, STATIC , FIRST, DecryptedMessage, message, message, 0), + PB_FIELD( 2, STRING , OPTIONAL, STATIC , OTHER, DecryptedMessage, address, message, 0), PB_LAST_FIELD }; const pb_field_t CipherKeyValue_fields[7] = { - PB_FIELD2( 1, UINT32 , REPEATED, STATIC , FIRST, CipherKeyValue, address_n, address_n, 0), - PB_FIELD2( 2, STRING , OPTIONAL, STATIC , OTHER, CipherKeyValue, key, address_n, 0), - PB_FIELD2( 3, BYTES , OPTIONAL, STATIC , OTHER, CipherKeyValue, value, key, 0), - PB_FIELD2( 4, BOOL , OPTIONAL, STATIC , OTHER, CipherKeyValue, encrypt, value, 0), - PB_FIELD2( 5, BOOL , OPTIONAL, STATIC , OTHER, CipherKeyValue, ask_on_encrypt, encrypt, 0), - PB_FIELD2( 6, BOOL , OPTIONAL, STATIC , OTHER, CipherKeyValue, ask_on_decrypt, ask_on_encrypt, 0), + PB_FIELD( 1, UINT32 , REPEATED, STATIC , FIRST, CipherKeyValue, address_n, address_n, 0), + PB_FIELD( 2, STRING , OPTIONAL, STATIC , OTHER, CipherKeyValue, key, address_n, 0), + PB_FIELD( 3, BYTES , OPTIONAL, STATIC , OTHER, CipherKeyValue, value, key, 0), + PB_FIELD( 4, BOOL , OPTIONAL, STATIC , OTHER, CipherKeyValue, encrypt, value, 0), + PB_FIELD( 5, BOOL , OPTIONAL, STATIC , OTHER, CipherKeyValue, ask_on_encrypt, encrypt, 0), + PB_FIELD( 6, BOOL , OPTIONAL, STATIC , OTHER, CipherKeyValue, ask_on_decrypt, ask_on_encrypt, 0), + PB_LAST_FIELD +}; + +const pb_field_t CipheredKeyValue_fields[2] = { + PB_FIELD( 1, BYTES , OPTIONAL, STATIC , FIRST, CipheredKeyValue, value, value, 0), PB_LAST_FIELD }; const pb_field_t EstimateTxSize_fields[4] = { - PB_FIELD2( 1, UINT32 , REQUIRED, STATIC , FIRST, EstimateTxSize, outputs_count, outputs_count, 0), - PB_FIELD2( 2, UINT32 , REQUIRED, STATIC , OTHER, EstimateTxSize, inputs_count, outputs_count, 0), - PB_FIELD2( 3, STRING , OPTIONAL, STATIC , OTHER, EstimateTxSize, coin_name, inputs_count, &EstimateTxSize_coin_name_default), + PB_FIELD( 1, UINT32 , REQUIRED, STATIC , FIRST, EstimateTxSize, outputs_count, outputs_count, 0), + PB_FIELD( 2, UINT32 , REQUIRED, STATIC , OTHER, EstimateTxSize, inputs_count, outputs_count, 0), + PB_FIELD( 3, STRING , OPTIONAL, STATIC , OTHER, EstimateTxSize, coin_name, inputs_count, &EstimateTxSize_coin_name_default), PB_LAST_FIELD }; const pb_field_t TxSize_fields[2] = { - PB_FIELD2( 1, UINT32 , OPTIONAL, STATIC , FIRST, TxSize, tx_size, tx_size, 0), + PB_FIELD( 1, UINT32 , OPTIONAL, STATIC , FIRST, TxSize, tx_size, tx_size, 0), PB_LAST_FIELD }; const pb_field_t SignTx_fields[4] = { - PB_FIELD2( 1, UINT32 , REQUIRED, STATIC , FIRST, SignTx, outputs_count, outputs_count, 0), - PB_FIELD2( 2, UINT32 , REQUIRED, STATIC , OTHER, SignTx, inputs_count, outputs_count, 0), - PB_FIELD2( 3, STRING , OPTIONAL, STATIC , OTHER, SignTx, coin_name, inputs_count, &SignTx_coin_name_default), + PB_FIELD( 1, UINT32 , REQUIRED, STATIC , FIRST, SignTx, outputs_count, outputs_count, 0), + PB_FIELD( 2, UINT32 , REQUIRED, STATIC , OTHER, SignTx, inputs_count, outputs_count, 0), + PB_FIELD( 3, STRING , OPTIONAL, STATIC , OTHER, SignTx, coin_name, inputs_count, &SignTx_coin_name_default), PB_LAST_FIELD }; const pb_field_t SimpleSignTx_fields[5] = { - PB_FIELD2( 1, MESSAGE , REPEATED, STATIC , FIRST, SimpleSignTx, inputs, inputs, &TxInputType_fields), - PB_FIELD2( 2, MESSAGE , REPEATED, STATIC , OTHER, SimpleSignTx, outputs, inputs, &TxOutputType_fields), - PB_FIELD2( 3, MESSAGE , REPEATED, STATIC , OTHER, SimpleSignTx, transactions, outputs, &TransactionType_fields), - PB_FIELD2( 4, STRING , OPTIONAL, STATIC , OTHER, SimpleSignTx, coin_name, transactions, &SimpleSignTx_coin_name_default), + PB_FIELD( 1, MESSAGE , REPEATED, STATIC , FIRST, SimpleSignTx, inputs, inputs, &TxInputType_fields), + PB_FIELD( 2, MESSAGE , REPEATED, STATIC , OTHER, SimpleSignTx, outputs, inputs, &TxOutputType_fields), + PB_FIELD( 3, MESSAGE , REPEATED, STATIC , OTHER, SimpleSignTx, transactions, outputs, &TransactionType_fields), + PB_FIELD( 4, STRING , OPTIONAL, STATIC , OTHER, SimpleSignTx, coin_name, transactions, &SimpleSignTx_coin_name_default), PB_LAST_FIELD }; const pb_field_t TxRequest_fields[4] = { - PB_FIELD2( 1, ENUM , OPTIONAL, STATIC , FIRST, TxRequest, request_type, request_type, 0), - PB_FIELD2( 2, MESSAGE , OPTIONAL, STATIC , OTHER, TxRequest, details, request_type, &TxRequestDetailsType_fields), - PB_FIELD2( 3, MESSAGE , OPTIONAL, STATIC , OTHER, TxRequest, serialized, details, &TxRequestSerializedType_fields), + PB_FIELD( 1, ENUM , OPTIONAL, STATIC , FIRST, TxRequest, request_type, request_type, 0), + PB_FIELD( 2, MESSAGE , OPTIONAL, STATIC , OTHER, TxRequest, details, request_type, &TxRequestDetailsType_fields), + PB_FIELD( 3, MESSAGE , OPTIONAL, STATIC , OTHER, TxRequest, serialized, details, &TxRequestSerializedType_fields), PB_LAST_FIELD }; const pb_field_t TxAck_fields[2] = { - PB_FIELD2( 1, MESSAGE , OPTIONAL, STATIC , FIRST, TxAck, tx, tx, &TransactionType_fields), + PB_FIELD( 1, MESSAGE , OPTIONAL, STATIC , FIRST, TxAck, tx, tx, &TransactionType_fields), PB_LAST_FIELD }; @@ -281,12 +304,12 @@ const pb_field_t FirmwareErase_fields[1] = { }; const pb_field_t FirmwareUpload_fields[2] = { - PB_FIELD2( 1, BYTES , REQUIRED, STATIC , FIRST, FirmwareUpload, payload, payload, 0), + PB_FIELD( 1, BYTES , REQUIRED, STATIC , FIRST, FirmwareUpload, payload, payload, 0), PB_LAST_FIELD }; const pb_field_t DebugLinkDecision_fields[2] = { - PB_FIELD2( 1, BOOL , REQUIRED, STATIC , FIRST, DebugLinkDecision, yes_no, yes_no, 0), + PB_FIELD( 1, BOOL , REQUIRED, STATIC , FIRST, DebugLinkDecision, yes_no, yes_no, 0), PB_LAST_FIELD }; @@ -295,16 +318,16 @@ const pb_field_t DebugLinkGetState_fields[1] = { }; const pb_field_t DebugLinkState_fields[11] = { - PB_FIELD2( 1, BYTES , OPTIONAL, STATIC , FIRST, DebugLinkState, layout, layout, 0), - PB_FIELD2( 2, STRING , OPTIONAL, STATIC , OTHER, DebugLinkState, pin, layout, 0), - PB_FIELD2( 3, STRING , OPTIONAL, STATIC , OTHER, DebugLinkState, matrix, pin, 0), - PB_FIELD2( 4, STRING , OPTIONAL, STATIC , OTHER, DebugLinkState, mnemonic, matrix, 0), - PB_FIELD2( 5, MESSAGE , OPTIONAL, STATIC , OTHER, DebugLinkState, node, mnemonic, &HDNodeType_fields), - PB_FIELD2( 6, BOOL , OPTIONAL, STATIC , OTHER, DebugLinkState, passphrase_protection, node, 0), - PB_FIELD2( 7, STRING , OPTIONAL, STATIC , OTHER, DebugLinkState, reset_word, passphrase_protection, 0), - PB_FIELD2( 8, BYTES , OPTIONAL, STATIC , OTHER, DebugLinkState, reset_entropy, reset_word, 0), - PB_FIELD2( 9, STRING , OPTIONAL, STATIC , OTHER, DebugLinkState, recovery_fake_word, reset_entropy, 0), - PB_FIELD2( 10, UINT32 , OPTIONAL, STATIC , OTHER, DebugLinkState, recovery_word_pos, recovery_fake_word, 0), + PB_FIELD( 1, BYTES , OPTIONAL, STATIC , FIRST, DebugLinkState, layout, layout, 0), + PB_FIELD( 2, STRING , OPTIONAL, STATIC , OTHER, DebugLinkState, pin, layout, 0), + PB_FIELD( 3, STRING , OPTIONAL, STATIC , OTHER, DebugLinkState, matrix, pin, 0), + PB_FIELD( 4, STRING , OPTIONAL, STATIC , OTHER, DebugLinkState, mnemonic, matrix, 0), + PB_FIELD( 5, MESSAGE , OPTIONAL, STATIC , OTHER, DebugLinkState, node, mnemonic, &HDNodeType_fields), + PB_FIELD( 6, BOOL , OPTIONAL, STATIC , OTHER, DebugLinkState, passphrase_protection, node, 0), + PB_FIELD( 7, STRING , OPTIONAL, STATIC , OTHER, DebugLinkState, reset_word, passphrase_protection, 0), + PB_FIELD( 8, BYTES , OPTIONAL, STATIC , OTHER, DebugLinkState, reset_entropy, reset_word, 0), + PB_FIELD( 9, STRING , OPTIONAL, STATIC , OTHER, DebugLinkState, recovery_fake_word, reset_entropy, 0), + PB_FIELD( 10, UINT32 , OPTIONAL, STATIC , OTHER, DebugLinkState, recovery_word_pos, recovery_fake_word, 0), PB_LAST_FIELD }; @@ -313,9 +336,9 @@ const pb_field_t DebugLinkStop_fields[1] = { }; const pb_field_t DebugLinkLog_fields[4] = { - PB_FIELD2( 1, UINT32 , OPTIONAL, STATIC , FIRST, DebugLinkLog, level, level, 0), - PB_FIELD2( 2, STRING , OPTIONAL, STATIC , OTHER, DebugLinkLog, bucket, level, 0), - PB_FIELD2( 3, STRING , OPTIONAL, STATIC , OTHER, DebugLinkLog, text, bucket, 0), + PB_FIELD( 1, UINT32 , OPTIONAL, STATIC , FIRST, DebugLinkLog, level, level, 0), + PB_FIELD( 2, STRING , OPTIONAL, STATIC , OTHER, DebugLinkLog, bucket, level, 0), + PB_FIELD( 3, STRING , OPTIONAL, STATIC , OTHER, DebugLinkLog, text, bucket, 0), PB_LAST_FIELD }; @@ -329,11 +352,11 @@ const pb_field_t DebugLinkLog_fields[4] = { * numbers or field sizes that are larger than what can fit in 8 or 16 bit * field descriptors. */ -STATIC_ASSERT((pb_membersize(Features, coins[0]) < 65536 && pb_membersize(PublicKey, node) < 65536 && pb_membersize(LoadDevice, node) < 65536 && pb_membersize(SimpleSignTx, inputs[0]) < 65536 && pb_membersize(SimpleSignTx, outputs[0]) < 65536 && pb_membersize(SimpleSignTx, transactions[0]) < 65536 && pb_membersize(TxRequest, details) < 65536 && pb_membersize(TxRequest, serialized) < 65536 && pb_membersize(TxAck, tx) < 65536 && pb_membersize(DebugLinkState, node) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_Initialize_Features_ClearSession_ApplySettings_ChangePin_Ping_Success_Failure_ButtonRequest_ButtonAck_PinMatrixRequest_PinMatrixAck_Cancel_PassphraseRequest_PassphraseAck_GetEntropy_Entropy_GetPublicKey_PublicKey_GetAddress_Address_WipeDevice_LoadDevice_ResetDevice_EntropyRequest_EntropyAck_RecoveryDevice_WordRequest_WordAck_SignMessage_VerifyMessage_MessageSignature_EncryptMessage_DecryptMessage_CipherKeyValue_EstimateTxSize_TxSize_SignTx_SimpleSignTx_TxRequest_TxAck_FirmwareErase_FirmwareUpload_DebugLinkDecision_DebugLinkGetState_DebugLinkState_DebugLinkStop_DebugLinkLog) +PB_STATIC_ASSERT((pb_membersize(Features, coins[0]) < 65536 && pb_membersize(PublicKey, node) < 65536 && pb_membersize(LoadDevice, node) < 65536 && pb_membersize(SimpleSignTx, inputs[0]) < 65536 && pb_membersize(SimpleSignTx, outputs[0]) < 65536 && pb_membersize(SimpleSignTx, transactions[0]) < 65536 && pb_membersize(TxRequest, details) < 65536 && pb_membersize(TxRequest, serialized) < 65536 && pb_membersize(TxAck, tx) < 65536 && pb_membersize(DebugLinkState, node) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_Initialize_Features_ClearSession_ApplySettings_ChangePin_Ping_Success_Failure_ButtonRequest_ButtonAck_PinMatrixRequest_PinMatrixAck_Cancel_PassphraseRequest_PassphraseAck_GetEntropy_Entropy_GetPublicKey_PublicKey_GetAddress_Address_WipeDevice_LoadDevice_ResetDevice_EntropyRequest_EntropyAck_RecoveryDevice_WordRequest_WordAck_SignMessage_VerifyMessage_MessageSignature_EncryptMessage_EncryptedMessage_DecryptMessage_DecryptedMessage_CipherKeyValue_CipheredKeyValue_EstimateTxSize_TxSize_SignTx_SimpleSignTx_TxRequest_TxAck_FirmwareErase_FirmwareUpload_DebugLinkDecision_DebugLinkGetState_DebugLinkState_DebugLinkStop_DebugLinkLog) #endif #if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) -#error Field descriptor for Success.payload is too large. Define PB_FIELD_16BIT to fix this. +#error Field descriptor for EncryptedMessage.message is too large. Define PB_FIELD_16BIT to fix this. #endif diff --git a/firmware/protob/messages.pb.h b/firmware/protob/messages.pb.h index ac41e9849..41f70a2f5 100644 --- a/firmware/protob/messages.pb.h +++ b/firmware/protob/messages.pb.h @@ -1,11 +1,15 @@ /* Automatically generated nanopb header */ -/* Generated by nanopb-0.2.8 */ +/* Generated by nanopb-0.3.1 */ -#ifndef _PB_MESSAGES_PB_H_ -#define _PB_MESSAGES_PB_H_ +#ifndef PB_MESSAGES_PB_H_INCLUDED +#define PB_MESSAGES_PB_H_INCLUDED #include "pb.h" #include "types.pb.h" +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + #ifdef __cplusplus extern "C" { #endif @@ -35,6 +39,7 @@ typedef enum _MessageType { MessageType_MessageType_TxRequest = 21, MessageType_MessageType_TxAck = 22, MessageType_MessageType_CipherKeyValue = 23, + MessageType_MessageType_CipheredKeyValue = 48, MessageType_MessageType_ClearSession = 24, MessageType_MessageType_ApplySettings = 25, MessageType_MessageType_ButtonRequest = 26, @@ -46,8 +51,10 @@ typedef enum _MessageType { MessageType_MessageType_SignMessage = 38, MessageType_MessageType_VerifyMessage = 39, MessageType_MessageType_MessageSignature = 40, - MessageType_MessageType_EncryptMessage = 48, - MessageType_MessageType_DecryptMessage = 49, + MessageType_MessageType_EncryptMessage = 49, + MessageType_MessageType_EncryptedMessage = 50, + MessageType_MessageType_DecryptMessage = 51, + MessageType_MessageType_DecryptedMessage = 52, MessageType_MessageType_PassphraseRequest = 41, MessageType_MessageType_PassphraseAck = 42, MessageType_MessageType_EstimateTxSize = 43, @@ -130,13 +137,10 @@ typedef struct _ChangePin { bool remove; } ChangePin; -typedef struct { - size_t size; - uint8_t bytes[1024]; -} CipherKeyValue_value_t; +typedef PB_BYTES_ARRAY_T(1024) CipherKeyValue_value_t; typedef struct _CipherKeyValue { - size_t address_n_count; + pb_size_t address_n_count; uint32_t address_n[8]; bool has_key; char key[256]; @@ -150,6 +154,13 @@ typedef struct _CipherKeyValue { bool ask_on_decrypt; } CipherKeyValue; +typedef PB_BYTES_ARRAY_T(1024) CipheredKeyValue_value_t; + +typedef struct _CipheredKeyValue { + bool has_value; + CipheredKeyValue_value_t value; +} CipheredKeyValue; + typedef struct _DebugLinkDecision { bool yes_no; } DebugLinkDecision; @@ -163,15 +174,9 @@ typedef struct _DebugLinkLog { char text[256]; } DebugLinkLog; -typedef struct { - size_t size; - uint8_t bytes[1024]; -} DebugLinkState_layout_t; +typedef PB_BYTES_ARRAY_T(1024) DebugLinkState_layout_t; -typedef struct { - size_t size; - uint8_t bytes[128]; -} DebugLinkState_reset_entropy_t; +typedef PB_BYTES_ARRAY_T(128) DebugLinkState_reset_entropy_t; typedef struct _DebugLinkState { bool has_layout; @@ -196,27 +201,35 @@ typedef struct _DebugLinkState { uint32_t recovery_word_pos; } DebugLinkState; -typedef struct { - size_t size; - uint8_t bytes[1024]; -} DecryptMessage_message_t; +typedef PB_BYTES_ARRAY_T(33) DecryptMessage_nonce_t; + +typedef PB_BYTES_ARRAY_T(1120) DecryptMessage_message_t; + +typedef PB_BYTES_ARRAY_T(8) DecryptMessage_hmac_t; typedef struct _DecryptMessage { - size_t address_n_count; + pb_size_t address_n_count; uint32_t address_n[8]; + bool has_nonce; + DecryptMessage_nonce_t nonce; bool has_message; DecryptMessage_message_t message; + bool has_hmac; + DecryptMessage_hmac_t hmac; } DecryptMessage; -typedef struct { - size_t size; - uint8_t bytes[65]; -} EncryptMessage_pubkey_t; +typedef PB_BYTES_ARRAY_T(1024) DecryptedMessage_message_t; -typedef struct { - size_t size; - uint8_t bytes[1024]; -} EncryptMessage_message_t; +typedef struct _DecryptedMessage { + bool has_message; + DecryptedMessage_message_t message; + bool has_address; + char address[35]; +} DecryptedMessage; + +typedef PB_BYTES_ARRAY_T(65) EncryptMessage_pubkey_t; + +typedef PB_BYTES_ARRAY_T(1024) EncryptMessage_message_t; typedef struct _EncryptMessage { bool has_pubkey; @@ -225,25 +238,34 @@ typedef struct _EncryptMessage { EncryptMessage_message_t message; bool has_display_only; bool display_only; - size_t address_n_count; + pb_size_t address_n_count; uint32_t address_n[8]; bool has_coin_name; char coin_name[17]; } EncryptMessage; -typedef struct { - size_t size; - uint8_t bytes[1024]; -} Entropy_entropy_t; +typedef PB_BYTES_ARRAY_T(33) EncryptedMessage_nonce_t; + +typedef PB_BYTES_ARRAY_T(1120) EncryptedMessage_message_t; + +typedef PB_BYTES_ARRAY_T(8) EncryptedMessage_hmac_t; + +typedef struct _EncryptedMessage { + bool has_nonce; + EncryptedMessage_nonce_t nonce; + bool has_message; + EncryptedMessage_message_t message; + bool has_hmac; + EncryptedMessage_hmac_t hmac; +} EncryptedMessage; + +typedef PB_BYTES_ARRAY_T(1024) Entropy_entropy_t; typedef struct _Entropy { Entropy_entropy_t entropy; } Entropy; -typedef struct { - size_t size; - uint8_t bytes[128]; -} EntropyAck_entropy_t; +typedef PB_BYTES_ARRAY_T(128) EntropyAck_entropy_t; typedef struct _EntropyAck { bool has_entropy; @@ -264,15 +286,9 @@ typedef struct _Failure { char message[256]; } Failure; -typedef struct { - size_t size; - uint8_t bytes[20]; -} Features_revision_t; +typedef PB_BYTES_ARRAY_T(20) Features_revision_t; -typedef struct { - size_t size; - uint8_t bytes[32]; -} Features_bootloader_hash_t; +typedef PB_BYTES_ARRAY_T(32) Features_bootloader_hash_t; typedef struct _Features { bool has_vendor; @@ -295,7 +311,7 @@ typedef struct _Features { char language[17]; bool has_label; char label[33]; - size_t coins_count; + pb_size_t coins_count; CoinType coins[4]; bool has_initialized; bool initialized; @@ -307,17 +323,14 @@ typedef struct _Features { bool imported; } Features; -typedef struct { - size_t size; - uint8_t bytes[0]; -} FirmwareUpload_payload_t; +typedef PB_BYTES_ARRAY_T(0) FirmwareUpload_payload_t; typedef struct _FirmwareUpload { FirmwareUpload_payload_t payload; } FirmwareUpload; typedef struct _GetAddress { - size_t address_n_count; + pb_size_t address_n_count; uint32_t address_n[8]; bool has_coin_name; char coin_name[17]; @@ -330,7 +343,7 @@ typedef struct _GetEntropy { } GetEntropy; typedef struct _GetPublicKey { - size_t address_n_count; + pb_size_t address_n_count; uint32_t address_n[8]; } GetPublicKey; @@ -351,10 +364,7 @@ typedef struct _LoadDevice { bool skip_checksum; } LoadDevice; -typedef struct { - size_t size; - uint8_t bytes[65]; -} MessageSignature_signature_t; +typedef PB_BYTES_ARRAY_T(65) MessageSignature_signature_t; typedef struct _MessageSignature { bool has_address; @@ -423,13 +433,10 @@ typedef struct _ResetDevice { char label[33]; } ResetDevice; -typedef struct { - size_t size; - uint8_t bytes[256]; -} SignMessage_message_t; +typedef PB_BYTES_ARRAY_T(1024) SignMessage_message_t; typedef struct _SignMessage { - size_t address_n_count; + pb_size_t address_n_count; uint32_t address_n[8]; SignMessage_message_t message; bool has_coin_name; @@ -444,26 +451,19 @@ typedef struct _SignTx { } SignTx; typedef struct _SimpleSignTx { - size_t inputs_count; + pb_size_t inputs_count; TxInputType inputs[0]; - size_t outputs_count; + pb_size_t outputs_count; TxOutputType outputs[0]; - size_t transactions_count; + pb_size_t transactions_count; TransactionType transactions[0]; bool has_coin_name; char coin_name[17]; } SimpleSignTx; -typedef struct { - size_t size; - uint8_t bytes[1024]; -} Success_payload_t; - typedef struct _Success { bool has_message; char message[256]; - bool has_payload; - Success_payload_t payload; } Success; typedef struct _TxAck { @@ -485,15 +485,9 @@ typedef struct _TxSize { uint32_t tx_size; } TxSize; -typedef struct { - size_t size; - uint8_t bytes[65]; -} VerifyMessage_signature_t; +typedef PB_BYTES_ARRAY_T(65) VerifyMessage_signature_t; -typedef struct { - size_t size; - uint8_t bytes[256]; -} VerifyMessage_message_t; +typedef PB_BYTES_ARRAY_T(1024) VerifyMessage_message_t; typedef struct _VerifyMessage { bool has_address; @@ -520,6 +514,110 @@ extern const char EstimateTxSize_coin_name_default[17]; extern const char SignTx_coin_name_default[17]; extern const char SimpleSignTx_coin_name_default[17]; +/* Initializer values for message structs */ +#define Initialize_init_default {0} +#define Features_init_default {false, "", false, 0, false, 0, false, 0, false, 0, false, "", false, 0, false, 0, false, "", false, "", 0, {CoinType_init_default, CoinType_init_default, CoinType_init_default, CoinType_init_default}, false, 0, false, {0, {0}}, false, {0, {0}}, false, 0} +#define ClearSession_init_default {0} +#define ApplySettings_init_default {false, "", false, ""} +#define ChangePin_init_default {false, 0} +#define Ping_init_default {false, "", false, 0, false, 0, false, 0} +#define Success_init_default {false, ""} +#define Failure_init_default {false, (FailureType)0, false, ""} +#define ButtonRequest_init_default {false, (ButtonRequestType)0, false, ""} +#define ButtonAck_init_default {0} +#define PinMatrixRequest_init_default {false, (PinMatrixRequestType)0} +#define PinMatrixAck_init_default {""} +#define Cancel_init_default {0} +#define PassphraseRequest_init_default {0} +#define PassphraseAck_init_default {""} +#define GetEntropy_init_default {0} +#define Entropy_init_default {{0, {0}}} +#define GetPublicKey_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}} +#define PublicKey_init_default {HDNodeType_init_default, false, ""} +#define GetAddress_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}, false, "Bitcoin", false, 0} +#define Address_init_default {""} +#define WipeDevice_init_default {0} +#define LoadDevice_init_default {false, "", false, HDNodeType_init_default, false, "", false, 0, false, "english", false, "", false, 0} +#define ResetDevice_init_default {false, 0, false, 128u, false, 0, false, 0, false, "english", false, ""} +#define EntropyRequest_init_default {0} +#define EntropyAck_init_default {false, {0, {0}}} +#define RecoveryDevice_init_default {false, 0, false, 0, false, 0, false, "english", false, "", false, 0} +#define WordRequest_init_default {0} +#define WordAck_init_default {""} +#define SignMessage_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}, {0, {0}}, false, "Bitcoin"} +#define VerifyMessage_init_default {false, "", false, {0, {0}}, false, {0, {0}}} +#define MessageSignature_init_default {false, "", false, {0, {0}}} +#define EncryptMessage_init_default {false, {0, {0}}, false, {0, {0}}, false, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, false, "Bitcoin"} +#define EncryptedMessage_init_default {false, {0, {0}}, false, {0, {0}}, false, {0, {0}}} +#define DecryptMessage_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}, false, {0, {0}}, false, {0, {0}}, false, {0, {0}}} +#define DecryptedMessage_init_default {false, {0, {0}}, false, ""} +#define CipherKeyValue_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}, false, "", false, {0, {0}}, false, 0, false, 0, false, 0} +#define CipheredKeyValue_init_default {false, {0, {0}}} +#define EstimateTxSize_init_default {0, 0, false, "Bitcoin"} +#define TxSize_init_default {false, 0} +#define SignTx_init_default {0, 0, false, "Bitcoin"} +#define SimpleSignTx_init_default {0, {}, 0, {}, 0, {}, false, "Bitcoin"} +#define TxRequest_init_default {false, (RequestType)0, false, TxRequestDetailsType_init_default, false, TxRequestSerializedType_init_default} +#define TxAck_init_default {false, TransactionType_init_default} +#define FirmwareErase_init_default {0} +#define FirmwareUpload_init_default {{0, {0}}} +#define DebugLinkDecision_init_default {0} +#define DebugLinkGetState_init_default {0} +#define DebugLinkState_init_default {false, {0, {0}}, false, "", false, "", false, "", false, HDNodeType_init_default, false, 0, false, "", false, {0, {0}}, false, "", false, 0} +#define DebugLinkStop_init_default {0} +#define DebugLinkLog_init_default {false, 0, false, "", false, ""} +#define Initialize_init_zero {0} +#define Features_init_zero {false, "", false, 0, false, 0, false, 0, false, 0, false, "", false, 0, false, 0, false, "", false, "", 0, {CoinType_init_zero, CoinType_init_zero, CoinType_init_zero, CoinType_init_zero}, false, 0, false, {0, {0}}, false, {0, {0}}, false, 0} +#define ClearSession_init_zero {0} +#define ApplySettings_init_zero {false, "", false, ""} +#define ChangePin_init_zero {false, 0} +#define Ping_init_zero {false, "", false, 0, false, 0, false, 0} +#define Success_init_zero {false, ""} +#define Failure_init_zero {false, (FailureType)0, false, ""} +#define ButtonRequest_init_zero {false, (ButtonRequestType)0, false, ""} +#define ButtonAck_init_zero {0} +#define PinMatrixRequest_init_zero {false, (PinMatrixRequestType)0} +#define PinMatrixAck_init_zero {""} +#define Cancel_init_zero {0} +#define PassphraseRequest_init_zero {0} +#define PassphraseAck_init_zero {""} +#define GetEntropy_init_zero {0} +#define Entropy_init_zero {{0, {0}}} +#define GetPublicKey_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}} +#define PublicKey_init_zero {HDNodeType_init_zero, false, ""} +#define GetAddress_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}, false, "", false, 0} +#define Address_init_zero {""} +#define WipeDevice_init_zero {0} +#define LoadDevice_init_zero {false, "", false, HDNodeType_init_zero, false, "", false, 0, false, "", false, "", false, 0} +#define ResetDevice_init_zero {false, 0, false, 0, false, 0, false, 0, false, "", false, ""} +#define EntropyRequest_init_zero {0} +#define EntropyAck_init_zero {false, {0, {0}}} +#define RecoveryDevice_init_zero {false, 0, false, 0, false, 0, false, "", false, "", false, 0} +#define WordRequest_init_zero {0} +#define WordAck_init_zero {""} +#define SignMessage_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}, {0, {0}}, false, ""} +#define VerifyMessage_init_zero {false, "", false, {0, {0}}, false, {0, {0}}} +#define MessageSignature_init_zero {false, "", false, {0, {0}}} +#define EncryptMessage_init_zero {false, {0, {0}}, false, {0, {0}}, false, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, false, ""} +#define EncryptedMessage_init_zero {false, {0, {0}}, false, {0, {0}}, false, {0, {0}}} +#define DecryptMessage_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}, false, {0, {0}}, false, {0, {0}}, false, {0, {0}}} +#define DecryptedMessage_init_zero {false, {0, {0}}, false, ""} +#define CipherKeyValue_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}, false, "", false, {0, {0}}, false, 0, false, 0, false, 0} +#define CipheredKeyValue_init_zero {false, {0, {0}}} +#define EstimateTxSize_init_zero {0, 0, false, ""} +#define TxSize_init_zero {false, 0} +#define SignTx_init_zero {0, 0, false, ""} +#define SimpleSignTx_init_zero {0, {}, 0, {}, 0, {}, false, ""} +#define TxRequest_init_zero {false, (RequestType)0, false, TxRequestDetailsType_init_zero, false, TxRequestSerializedType_init_zero} +#define TxAck_init_zero {false, TransactionType_init_zero} +#define FirmwareErase_init_zero {0} +#define FirmwareUpload_init_zero {{0, {0}}} +#define DebugLinkDecision_init_zero {0} +#define DebugLinkGetState_init_zero {0} +#define DebugLinkState_init_zero {false, {0, {0}}, false, "", false, "", false, "", false, HDNodeType_init_zero, false, 0, false, "", false, {0, {0}}, false, "", false, 0} +#define DebugLinkStop_init_zero {0} +#define DebugLinkLog_init_zero {false, 0, false, "", false, ""} + /* Field tags (for use in manual encoding/decoding) */ #define Address_address_tag 1 #define ApplySettings_language_tag 1 @@ -533,6 +631,7 @@ extern const char SimpleSignTx_coin_name_default[17]; #define CipherKeyValue_encrypt_tag 4 #define CipherKeyValue_ask_on_encrypt_tag 5 #define CipherKeyValue_ask_on_decrypt_tag 6 +#define CipheredKeyValue_value_tag 1 #define DebugLinkDecision_yes_no_tag 1 #define DebugLinkLog_level_tag 1 #define DebugLinkLog_bucket_tag 2 @@ -548,12 +647,19 @@ extern const char SimpleSignTx_coin_name_default[17]; #define DebugLinkState_recovery_fake_word_tag 9 #define DebugLinkState_recovery_word_pos_tag 10 #define DecryptMessage_address_n_tag 1 -#define DecryptMessage_message_tag 2 +#define DecryptMessage_nonce_tag 2 +#define DecryptMessage_message_tag 3 +#define DecryptMessage_hmac_tag 4 +#define DecryptedMessage_message_tag 1 +#define DecryptedMessage_address_tag 2 #define EncryptMessage_pubkey_tag 1 #define EncryptMessage_message_tag 2 #define EncryptMessage_display_only_tag 3 #define EncryptMessage_address_n_tag 4 #define EncryptMessage_coin_name_tag 5 +#define EncryptedMessage_nonce_tag 1 +#define EncryptedMessage_message_tag 2 +#define EncryptedMessage_hmac_tag 3 #define Entropy_entropy_tag 1 #define EntropyAck_entropy_tag 1 #define EstimateTxSize_outputs_count_tag 1 @@ -623,7 +729,6 @@ extern const char SimpleSignTx_coin_name_default[17]; #define SimpleSignTx_transactions_tag 3 #define SimpleSignTx_coin_name_tag 4 #define Success_message_tag 1 -#define Success_payload_tag 2 #define TxAck_tx_tag 1 #define TxRequest_request_type_tag 1 #define TxRequest_details_tag 2 @@ -641,7 +746,7 @@ extern const pb_field_t ClearSession_fields[1]; extern const pb_field_t ApplySettings_fields[3]; extern const pb_field_t ChangePin_fields[2]; extern const pb_field_t Ping_fields[5]; -extern const pb_field_t Success_fields[3]; +extern const pb_field_t Success_fields[2]; extern const pb_field_t Failure_fields[3]; extern const pb_field_t ButtonRequest_fields[3]; extern const pb_field_t ButtonAck_fields[1]; @@ -668,8 +773,11 @@ extern const pb_field_t SignMessage_fields[4]; extern const pb_field_t VerifyMessage_fields[4]; extern const pb_field_t MessageSignature_fields[3]; extern const pb_field_t EncryptMessage_fields[6]; -extern const pb_field_t DecryptMessage_fields[3]; +extern const pb_field_t EncryptedMessage_fields[4]; +extern const pb_field_t DecryptMessage_fields[5]; +extern const pb_field_t DecryptedMessage_fields[3]; extern const pb_field_t CipherKeyValue_fields[7]; +extern const pb_field_t CipheredKeyValue_fields[2]; extern const pb_field_t EstimateTxSize_fields[4]; extern const pb_field_t TxSize_fields[2]; extern const pb_field_t SignTx_fields[4]; @@ -691,7 +799,7 @@ extern const pb_field_t DebugLinkLog_fields[4]; #define ApplySettings_size 54 #define ChangePin_size 2 #define Ping_size 265 -#define Success_size 1286 +#define Success_size 259 #define Failure_size 265 #define ButtonRequest_size 265 #define ButtonAck_size 0 @@ -714,12 +822,15 @@ extern const pb_field_t DebugLinkLog_fields[4]; #define RecoveryDevice_size 66 #define WordRequest_size 0 #define WordAck_size 14 -#define SignMessage_size 326 -#define VerifyMessage_size 363 +#define SignMessage_size 1094 +#define VerifyMessage_size 1131 #define MessageSignature_size 104 #define EncryptMessage_size 1163 -#define DecryptMessage_size 1075 +#define EncryptedMessage_size 1168 +#define DecryptMessage_size 1216 +#define DecryptedMessage_size 1064 #define CipherKeyValue_size 1340 +#define CipheredKeyValue_size 1027 #define EstimateTxSize_size 31 #define TxSize_size 6 #define SignTx_size 31 diff --git a/firmware/protob/pb.h b/firmware/protob/pb.h index b5cb3ea4b..34d14b040 100644 --- a/firmware/protob/pb.h +++ b/firmware/protob/pb.h @@ -2,8 +2,8 @@ * stuff. For the high-level interface, see pb_encode.h and pb_decode.h. */ -#ifndef _PB_H_ -#define _PB_H_ +#ifndef PB_H_INCLUDED +#define PB_H_INCLUDED /***************************************************************** * Nanopb compilation time options. You can change these here by * @@ -46,7 +46,7 @@ /* Version of the nanopb library. Just in case you want to check it in * your own program. */ -#define NANOPB_VERSION nanopb-0.2.7 +#define NANOPB_VERSION nanopb-0.3.1 /* Include all the system headers needed by nanopb. You will need the * definitions of the following: @@ -80,8 +80,8 @@ # define PB_PACKED_STRUCT_START # define PB_PACKED_STRUCT_END # define pb_packed __attribute__((packed)) -#elif defined(__ICCARM__) - /* For IAR ARM compiler */ +#elif defined(__ICCARM__) || defined(__CC_ARM) + /* For IAR ARM and Keil MDK-ARM compilers */ # define PB_PACKED_STRUCT_START _Pragma("pack(push, 1)") # define PB_PACKED_STRUCT_END _Pragma("pack(pop)") # define pb_packed @@ -98,23 +98,27 @@ #endif /* Handly macro for suppressing unreferenced-parameter compiler warnings. */ -#ifndef UNUSED -#define UNUSED(x) (void)(x) +#ifndef PB_UNUSED +#define PB_UNUSED(x) (void)(x) #endif /* Compile-time assertion, used for checking compatible compilation options. - * If this does not work properly on your compiler, use #define STATIC_ASSERT - * to disable it. + * If this does not work properly on your compiler, use + * #define PB_NO_STATIC_ASSERT to disable it. * * But before doing that, check carefully the error message / place where it * comes from to see if the error has a real cause. Unfortunately the error * message is not always very clear to read, but you can see the reason better - * in the place where the STATIC_ASSERT macro was called. + * in the place where the PB_STATIC_ASSERT macro was called. */ -#ifndef STATIC_ASSERT -#define STATIC_ASSERT(COND,MSG) typedef char STATIC_ASSERT_MSG(MSG, __LINE__, __COUNTER__)[(COND)?1:-1]; -#define STATIC_ASSERT_MSG(MSG, LINE, COUNTER) STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) -#define STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) static_assertion_##MSG##LINE##COUNTER +#ifndef PB_NO_STATIC_ASSERT +#ifndef PB_STATIC_ASSERT +#define PB_STATIC_ASSERT(COND,MSG) typedef char PB_STATIC_ASSERT_MSG(MSG, __LINE__, __COUNTER__)[(COND)?1:-1]; +#define PB_STATIC_ASSERT_MSG(MSG, LINE, COUNTER) PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) +#define PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) pb_static_assertion_##MSG##LINE##COUNTER +#endif +#else +#define PB_STATIC_ASSERT(COND,MSG) #endif /* Number of required fields to keep track of. */ @@ -187,12 +191,15 @@ typedef uint8_t pb_type_t; * and array counts. */ #if defined(PB_FIELD_32BIT) +#define PB_SIZE_MAX ((uint32_t)-1) typedef uint32_t pb_size_t; typedef int32_t pb_ssize_t; #elif defined(PB_FIELD_16BIT) +#define PB_SIZE_MAX ((uint16_t)-1) typedef uint16_t pb_size_t; typedef int16_t pb_ssize_t; #else +#define PB_SIZE_MAX ((uint8_t)-1) typedef uint8_t pb_size_t; typedef int8_t pb_ssize_t; #endif @@ -206,8 +213,8 @@ typedef uint8_t pb_type_t; * PB_FIELD_32BIT. */ PB_PACKED_STRUCT_START -typedef struct _pb_field_t pb_field_t; -struct _pb_field_t { +typedef struct pb_field_s pb_field_t; +struct pb_field_s { pb_size_t tag; pb_type_t type; pb_size_t data_offset; /* Offset of field data, relative to previous field. */ @@ -228,27 +235,27 @@ PB_PACKED_STRUCT_END * If you get errors here, it probably means that your stdint.h is not * correct for your platform. */ -STATIC_ASSERT(sizeof(int8_t) == 1, INT8_T_WRONG_SIZE) -STATIC_ASSERT(sizeof(uint8_t) == 1, UINT8_T_WRONG_SIZE) -STATIC_ASSERT(sizeof(int16_t) == 2, INT16_T_WRONG_SIZE) -STATIC_ASSERT(sizeof(uint16_t) == 2, UINT16_T_WRONG_SIZE) -STATIC_ASSERT(sizeof(int32_t) == 4, INT32_T_WRONG_SIZE) -STATIC_ASSERT(sizeof(uint32_t) == 4, UINT32_T_WRONG_SIZE) -STATIC_ASSERT(sizeof(int64_t) == 8, INT64_T_WRONG_SIZE) -STATIC_ASSERT(sizeof(uint64_t) == 8, UINT64_T_WRONG_SIZE) +PB_STATIC_ASSERT(sizeof(int8_t) == 1, INT8_T_WRONG_SIZE) +PB_STATIC_ASSERT(sizeof(uint8_t) == 1, UINT8_T_WRONG_SIZE) +PB_STATIC_ASSERT(sizeof(int16_t) == 2, INT16_T_WRONG_SIZE) +PB_STATIC_ASSERT(sizeof(uint16_t) == 2, UINT16_T_WRONG_SIZE) +PB_STATIC_ASSERT(sizeof(int32_t) == 4, INT32_T_WRONG_SIZE) +PB_STATIC_ASSERT(sizeof(uint32_t) == 4, UINT32_T_WRONG_SIZE) +PB_STATIC_ASSERT(sizeof(int64_t) == 8, INT64_T_WRONG_SIZE) +PB_STATIC_ASSERT(sizeof(uint64_t) == 8, UINT64_T_WRONG_SIZE) /* This structure is used for 'bytes' arrays. * It has the number of bytes in the beginning, and after that an array. * Note that actual structs used will have a different length of bytes array. */ -#define PB_BYTES_ARRAY_T(n) struct { size_t size; uint8_t bytes[n]; } +#define PB_BYTES_ARRAY_T(n) struct { pb_size_t size; uint8_t bytes[n]; } #define PB_BYTES_ARRAY_T_ALLOCSIZE(n) ((size_t)n + offsetof(pb_bytes_array_t, bytes)) -struct _pb_bytes_array_t { - size_t size; +struct pb_bytes_array_s { + pb_size_t size; uint8_t bytes[1]; }; -typedef struct _pb_bytes_array_t pb_bytes_array_t; +typedef struct pb_bytes_array_s pb_bytes_array_t; /* This structure is used for giving the callback function. * It is stored in the message structure and filled in by the method that @@ -268,10 +275,10 @@ typedef struct _pb_bytes_array_t pb_bytes_array_t; * * The callback can be null if you want to skip a field. */ -typedef struct _pb_istream_t pb_istream_t; -typedef struct _pb_ostream_t pb_ostream_t; -typedef struct _pb_callback_t pb_callback_t; -struct _pb_callback_t { +typedef struct pb_istream_s pb_istream_t; +typedef struct pb_ostream_s pb_ostream_t; +typedef struct pb_callback_s pb_callback_t; +struct pb_callback_s { #ifdef PB_OLD_CALLBACK_STYLE /* Deprecated since nanopb-0.2.1 */ union { @@ -304,9 +311,9 @@ typedef enum { * if you want to catch all unknown fields, you can also create a custom * pb_extension_type_t with your own callback. */ -typedef struct _pb_extension_type_t pb_extension_type_t; -typedef struct _pb_extension_t pb_extension_t; -struct _pb_extension_type_t { +typedef struct pb_extension_type_s pb_extension_type_t; +typedef struct pb_extension_s pb_extension_t; +struct pb_extension_type_s { /* Called for each unknown field in the message. * If you handle the field, read off all of its data and return true. * If you do not handle the field, do not read anything and return true. @@ -328,7 +335,7 @@ struct _pb_extension_type_t { const void *arg; }; -struct _pb_extension_t { +struct pb_extension_s { /* Type describing the extension field. Usually you'll initialize * this to a pointer to the automatically generated structure. */ const pb_extension_type_t *type; @@ -358,6 +365,9 @@ struct _pb_extension_t { # endif #endif +/* This is used to inform about need to regenerate .pb.h/.pb.c files. */ +#define PB_PROTO_HEADER_VERSION 30 + /* These macros are used to declare pb_field_t's in the constant array. */ /* Size of a structure member, in bytes. */ #define pb_membersize(st, m) (sizeof ((st*)0)->m) @@ -469,26 +479,15 @@ struct _pb_extension_t { * SINT32, SINT64, STRING, UINT32, UINT64 or EXTENSION * - Field rules: REQUIRED, OPTIONAL or REPEATED * - Allocation: STATIC or CALLBACK + * - Placement: FIRST or OTHER, depending on if this is the first field in structure. * - Message name * - Field name * - Previous field name (or field name again for first field) * - Pointer to default value or submsg fields. */ -#define PB_FIELD(tag, type, rules, allocation, message, field, prevfield, ptr) \ - PB_ ## rules ## _ ## allocation(tag, message, field, \ - PB_DATAOFFSET_CHOOSE(message, field, prevfield), \ - PB_LTYPE_MAP_ ## type, ptr) - -/* This is a new version of the macro used by nanopb generator from - * version 0.2.3 onwards. It avoids the use of a ternary expression in - * the initialization, which confused some compilers. - * - * - Placement: FIRST or OTHER, depending on if this is the first field in structure. - * - */ -#define PB_FIELD2(tag, type, rules, allocation, placement, message, field, prevfield, ptr) \ - PB_ ## rules ## _ ## allocation(tag, message, field, \ +#define PB_FIELD(tag, type, rules, allocation, placement, message, field, prevfield, ptr) \ + PB_ ## rules ## _ ## allocation(tag, message, field, \ PB_DATAOFFSET_ ## placement(message, field, prevfield), \ PB_LTYPE_MAP_ ## type, ptr) @@ -502,7 +501,7 @@ struct _pb_extension_t { #ifdef PB_NO_ERRMSG #define PB_RETURN_ERROR(stream,msg) \ do {\ - UNUSED(stream); \ + PB_UNUSED(stream); \ return false; \ } while(0) #define PB_GET_ERROR(stream) "(errmsg disabled)" diff --git a/firmware/protob/pb_common.c b/firmware/protob/pb_common.c new file mode 100644 index 000000000..a9cade639 --- /dev/null +++ b/firmware/protob/pb_common.c @@ -0,0 +1,90 @@ +/* pb_common.c: Common support functions for pb_encode.c and pb_decode.c. + * + * 2014 Petteri Aimonen + */ + +#include "pb_common.h" + +bool pb_field_iter_begin(pb_field_iter_t *iter, const pb_field_t *fields, void *dest_struct) +{ + iter->start = fields; + iter->pos = fields; + iter->required_field_index = 0; + iter->dest_struct = dest_struct; + iter->pData = (char*)dest_struct + iter->pos->data_offset; + iter->pSize = (char*)iter->pData + iter->pos->size_offset; + + return (iter->pos->tag != 0); +} + +bool pb_field_iter_next(pb_field_iter_t *iter) +{ + const pb_field_t *prev_field = iter->pos; + + if (prev_field->tag == 0) + { + /* Handle empty message types, where the first field is already the terminator. + * In other cases, the iter->pos never points to the terminator. */ + return false; + } + + iter->pos++; + + if (iter->pos->tag == 0) + { + /* Wrapped back to beginning, reinitialize */ + (void)pb_field_iter_begin(iter, iter->start, iter->dest_struct); + return false; + } + else + { + /* Increment the pointers based on previous field size */ + size_t prev_size = prev_field->data_size; + + if (PB_ATYPE(prev_field->type) == PB_ATYPE_STATIC && + PB_HTYPE(prev_field->type) == PB_HTYPE_REPEATED) + { + /* In static arrays, the data_size tells the size of a single entry and + * array_size is the number of entries */ + prev_size *= prev_field->array_size; + } + else if (PB_ATYPE(prev_field->type) == PB_ATYPE_POINTER) + { + /* Pointer fields always have a constant size in the main structure. + * The data_size only applies to the dynamically allocated area. */ + prev_size = sizeof(void*); + } + + if (PB_HTYPE(prev_field->type) == PB_HTYPE_REQUIRED) + { + /* Count the required fields, in order to check their presence in the + * decoder. */ + iter->required_field_index++; + } + + iter->pData = (char*)iter->pData + prev_size + iter->pos->data_offset; + iter->pSize = (char*)iter->pData + iter->pos->size_offset; + return true; + } +} + +bool pb_field_iter_find(pb_field_iter_t *iter, uint32_t tag) +{ + const pb_field_t *start = iter->pos; + + do { + if (iter->pos->tag == tag && + PB_LTYPE(iter->pos->type) != PB_LTYPE_EXTENSION) + { + /* Found the wanted field */ + return true; + } + + (void)pb_field_iter_next(iter); + } while (iter->pos != start); + + /* Searched all the way back to start, and found nothing. */ + return false; +} + + diff --git a/firmware/protob/pb_common.h b/firmware/protob/pb_common.h new file mode 100644 index 000000000..60b3d3749 --- /dev/null +++ b/firmware/protob/pb_common.h @@ -0,0 +1,42 @@ +/* pb_common.h: Common support functions for pb_encode.c and pb_decode.c. + * These functions are rarely needed by applications directly. + */ + +#ifndef PB_COMMON_H_INCLUDED +#define PB_COMMON_H_INCLUDED + +#include "pb.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Iterator for pb_field_t list */ +struct pb_field_iter_s { + const pb_field_t *start; /* Start of the pb_field_t array */ + const pb_field_t *pos; /* Current position of the iterator */ + unsigned required_field_index; /* Zero-based index that counts only the required fields */ + void *dest_struct; /* Pointer to start of the structure */ + void *pData; /* Pointer to current field value */ + void *pSize; /* Pointer to count/has field */ +}; +typedef struct pb_field_iter_s pb_field_iter_t; + +/* Initialize the field iterator structure to beginning. + * Returns false if the message type is empty. */ +bool pb_field_iter_begin(pb_field_iter_t *iter, const pb_field_t *fields, void *dest_struct); + +/* Advance the iterator to the next field. + * Returns false when the iterator wraps back to the first field. */ +bool pb_field_iter_next(pb_field_iter_t *iter); + +/* Advance the iterator until it points at a field with the given tag. + * Returns false if no such field exists. */ +bool pb_field_iter_find(pb_field_iter_t *iter, uint32_t tag); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif + diff --git a/firmware/protob/pb_decode.c b/firmware/protob/pb_decode.c index 9a48c60fc..d1efd1b51 100644 --- a/firmware/protob/pb_decode.c +++ b/firmware/protob/pb_decode.c @@ -15,36 +15,23 @@ #include "pb.h" #include "pb_decode.h" +#include "pb_common.h" /************************************** * Declarations internal to this file * **************************************/ -/* Iterator for pb_field_t list */ -typedef struct { - const pb_field_t *start; /* Start of the pb_field_t array */ - const pb_field_t *pos; /* Current position of the iterator */ - unsigned field_index; /* Zero-based index of the field. */ - unsigned required_field_index; /* Zero-based index that counts only the required fields */ - void *dest_struct; /* Pointer to the destination structure to decode to */ - void *pData; /* Pointer where to store current field value */ - void *pSize; /* Pointer where to store the size of current array field */ -} pb_field_iterator_t; - typedef bool (*pb_decoder_t)(pb_istream_t *stream, const pb_field_t *field, void *dest) checkreturn; static bool checkreturn buf_read(pb_istream_t *stream, uint8_t *buf, size_t count); static bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest); static bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, uint8_t *buf, size_t *size); -static void pb_field_init(pb_field_iterator_t *iter, const pb_field_t *fields, void *dest_struct); -static bool pb_field_next(pb_field_iterator_t *iter); -static bool checkreturn pb_field_find(pb_field_iterator_t *iter, uint32_t tag); -static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter); -static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter); -static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter); +static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter); +static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter); +static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter); static bool checkreturn default_extension_decoder(pb_istream_t *stream, pb_extension_t *extension, uint32_t tag, pb_wire_type_t wire_type); -static bool checkreturn decode_extension(pb_istream_t *stream, uint32_t tag, pb_wire_type_t wire_type, pb_field_iterator_t *iter); -static bool checkreturn find_extension_field(pb_field_iterator_t *iter); +static bool checkreturn decode_extension(pb_istream_t *stream, uint32_t tag, pb_wire_type_t wire_type, pb_field_iter_t *iter); +static bool checkreturn find_extension_field(pb_field_iter_t *iter); static void pb_message_set_to_defaults(const pb_field_t fields[], void *dest_struct); static bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_t *field, void *dest); static bool checkreturn pb_dec_uvarint(pb_istream_t *stream, const pb_field_t *field, void *dest); @@ -57,6 +44,11 @@ static bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_t static bool checkreturn pb_skip_varint(pb_istream_t *stream); static bool checkreturn pb_skip_string(pb_istream_t *stream); +#ifdef PB_ENABLE_MALLOC +static bool checkreturn allocate_field(pb_istream_t *stream, void *pData, size_t data_size, size_t array_size); +static void pb_release_single_field(const pb_field_iter_t *iter); +#endif + /* --- Function pointers to field decoders --- * Order in the array must match pb_action_t LTYPE numbering. */ @@ -338,75 +330,11 @@ void pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream) #endif } -static void pb_field_init(pb_field_iterator_t *iter, const pb_field_t *fields, void *dest_struct) -{ - iter->start = iter->pos = fields; - iter->field_index = 0; - iter->required_field_index = 0; - iter->pData = (char*)dest_struct + iter->pos->data_offset; - iter->pSize = (char*)iter->pData + iter->pos->size_offset; - iter->dest_struct = dest_struct; -} - -static bool pb_field_next(pb_field_iterator_t *iter) -{ - bool notwrapped = true; - size_t prev_size = iter->pos->data_size; - - if (PB_ATYPE(iter->pos->type) == PB_ATYPE_STATIC && - PB_HTYPE(iter->pos->type) == PB_HTYPE_REPEATED) - { - prev_size *= iter->pos->array_size; - } - else if (PB_ATYPE(iter->pos->type) == PB_ATYPE_POINTER) - { - prev_size = sizeof(void*); - } - - if (iter->pos->tag == 0) - return false; /* Only happens with empty message types */ - - if (PB_HTYPE(iter->pos->type) == PB_HTYPE_REQUIRED) - iter->required_field_index++; - - iter->pos++; - iter->field_index++; - if (iter->pos->tag == 0) - { - iter->pos = iter->start; - iter->field_index = 0; - iter->required_field_index = 0; - iter->pData = iter->dest_struct; - prev_size = 0; - notwrapped = false; - } - - iter->pData = (char*)iter->pData + prev_size + iter->pos->data_offset; - iter->pSize = (char*)iter->pData + iter->pos->size_offset; - return notwrapped; -} - -static bool checkreturn pb_field_find(pb_field_iterator_t *iter, uint32_t tag) -{ - unsigned start = iter->field_index; - - do { - if (iter->pos->tag == tag && - PB_LTYPE(iter->pos->type) != PB_LTYPE_EXTENSION) - { - return true; - } - (void)pb_field_next(iter); - } while (iter->field_index != start); - - return false; -} - /************************* * Decode a single field * *************************/ -static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter) +static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter) { pb_type_t type; pb_decoder_t func; @@ -429,7 +357,7 @@ static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t { /* Packed array */ bool status = true; - size_t *size = (size_t*)iter->pSize; + pb_size_t *size = (pb_size_t*)iter->pSize; pb_istream_t substream; if (!pb_make_string_substream(stream, &substream)) return false; @@ -454,7 +382,7 @@ static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t else { /* Repeated field */ - size_t *size = (size_t*)iter->pSize; + pb_size_t *size = (pb_size_t*)iter->pSize; void *pItem = (uint8_t*)iter->pData + iter->pos->data_size * (*size); if (*size >= iter->pos->array_size) PB_RETURN_ERROR(stream, "array overflow"); @@ -470,16 +398,37 @@ static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t #ifdef PB_ENABLE_MALLOC /* Allocate storage for the field and store the pointer at iter->pData. - * array_size is the number of entries to reserve in an array. */ + * array_size is the number of entries to reserve in an array. + * Zero size is not allowed, use pb_free() for releasing. + */ static bool checkreturn allocate_field(pb_istream_t *stream, void *pData, size_t data_size, size_t array_size) { void *ptr = *(void**)pData; - size_t size = array_size * data_size; + + if (data_size == 0 || array_size == 0) + PB_RETURN_ERROR(stream, "invalid size"); + + /* Check for multiplication overflows. + * This code avoids the costly division if the sizes are small enough. + * Multiplication is safe as long as only half of bits are set + * in either multiplicand. + */ + { + const size_t check_limit = (size_t)1 << (sizeof(size_t) * 4); + if (data_size >= check_limit || array_size >= check_limit) + { + const size_t size_max = (size_t)-1; + if (size_max / array_size < data_size) + { + PB_RETURN_ERROR(stream, "size too large"); + } + } + } /* Allocate new or expand previous allocation */ /* Note: on failure the old pointer will remain in the structure, * the message must be freed by caller also on error return. */ - ptr = pb_realloc(ptr, size); + ptr = pb_realloc(ptr, array_size * data_size); if (ptr == NULL) PB_RETURN_ERROR(stream, "realloc failed"); @@ -488,7 +437,7 @@ static bool checkreturn allocate_field(pb_istream_t *stream, void *pData, size_t } /* Clear a newly allocated item in case it contains a pointer, or is a submessage. */ -static void initialize_pointer_field(void *pItem, pb_field_iterator_t *iter) +static void initialize_pointer_field(void *pItem, pb_field_iter_t *iter) { if (PB_LTYPE(iter->pos->type) == PB_LTYPE_STRING || PB_LTYPE(iter->pos->type) == PB_LTYPE_BYTES) @@ -502,11 +451,11 @@ static void initialize_pointer_field(void *pItem, pb_field_iterator_t *iter) } #endif -static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter) +static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter) { #ifndef PB_ENABLE_MALLOC - UNUSED(wire_type); - UNUSED(iter); + PB_UNUSED(wire_type); + PB_UNUSED(iter); PB_RETURN_ERROR(stream, "no malloc support"); #else pb_type_t type; @@ -519,6 +468,13 @@ static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_ { case PB_HTYPE_REQUIRED: case PB_HTYPE_OPTIONAL: + if (PB_LTYPE(type) == PB_LTYPE_SUBMESSAGE && + *(void**)iter->pData != NULL) + { + /* Duplicate field, have to release the old allocation first. */ + pb_release_single_field(iter); + } + if (PB_LTYPE(type) == PB_LTYPE_STRING || PB_LTYPE(type) == PB_LTYPE_BYTES) { @@ -539,7 +495,7 @@ static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_ { /* Packed array, multiple items come in at once. */ bool status = true; - size_t *size = (size_t*)iter->pSize; + pb_size_t *size = (pb_size_t*)iter->pSize; size_t allocated_size = *size; void *pItem; pb_istream_t substream; @@ -549,7 +505,7 @@ static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_ while (substream.bytes_left) { - if (*size + 1 > allocated_size) + if ((size_t)*size + 1 > allocated_size) { /* Allocate more storage. This tries to guess the * number of remaining entries. Round the division @@ -571,6 +527,16 @@ static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_ status = false; break; } + + if (*size == PB_SIZE_MAX) + { +#ifndef PB_NO_ERRMSG + stream->errmsg = "too many array entries"; +#endif + status = false; + break; + } + (*size)++; } pb_close_string_substream(stream, &substream); @@ -580,9 +546,12 @@ static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_ else { /* Normal repeated field, i.e. only one item at a time. */ - size_t *size = (size_t*)iter->pSize; + pb_size_t *size = (pb_size_t*)iter->pSize; void *pItem; + if (*size == PB_SIZE_MAX) + PB_RETURN_ERROR(stream, "too many array entries"); + (*size)++; if (!allocate_field(stream, iter->pData, iter->pos->data_size, *size)) return false; @@ -598,7 +567,7 @@ static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_ #endif } -static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter) +static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter) { pb_callback_t *pCallback = (pb_callback_t*)iter->pData; @@ -645,7 +614,7 @@ static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type } } -static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter) +static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter) { switch (PB_ATYPE(iter->pos->type)) { @@ -669,16 +638,15 @@ static bool checkreturn default_extension_decoder(pb_istream_t *stream, pb_extension_t *extension, uint32_t tag, pb_wire_type_t wire_type) { const pb_field_t *field = (const pb_field_t*)extension->type->arg; - pb_field_iterator_t iter; + pb_field_iter_t iter; if (field->tag != tag) return true; - iter.start = field; - iter.pos = field; - iter.field_index = 0; - iter.required_field_index = 0; - iter.dest_struct = extension->dest; + /* Fake a field iterator for the extension field. + * It is not actually safe to advance this iterator, but decode_field + * will not even try to. */ + (void)pb_field_iter_begin(&iter, field, extension->dest); iter.pData = extension->dest; iter.pSize = &extension->found; @@ -688,7 +656,7 @@ static bool checkreturn default_extension_decoder(pb_istream_t *stream, /* Try to decode an unknown field as an extension field. Tries each extension * decoder in turn, until one of them handles the field or loop ends. */ static bool checkreturn decode_extension(pb_istream_t *stream, - uint32_t tag, pb_wire_type_t wire_type, pb_field_iterator_t *iter) + uint32_t tag, pb_wire_type_t wire_type, pb_field_iter_t *iter) { pb_extension_t *extension = *(pb_extension_t* const *)iter->pData; size_t pos = stream->bytes_left; @@ -713,15 +681,15 @@ static bool checkreturn decode_extension(pb_istream_t *stream, /* Step through the iterator until an extension field is found or until all * entries have been checked. There can be only one extension field per * message. Returns false if no extension field is found. */ -static bool checkreturn find_extension_field(pb_field_iterator_t *iter) +static bool checkreturn find_extension_field(pb_field_iter_t *iter) { - unsigned start = iter->field_index; + const pb_field_t *start = iter->pos; do { if (PB_LTYPE(iter->pos->type) == PB_LTYPE_EXTENSION) return true; - (void)pb_field_next(iter); - } while (iter->field_index != start); + (void)pb_field_iter_next(iter); + } while (iter->pos != start); return false; } @@ -729,17 +697,15 @@ static bool checkreturn find_extension_field(pb_field_iterator_t *iter) /* Initialize message fields to default values, recursively */ static void pb_message_set_to_defaults(const pb_field_t fields[], void *dest_struct) { - pb_field_iterator_t iter; - pb_field_init(&iter, fields, dest_struct); + pb_field_iter_t iter; + + if (!pb_field_iter_begin(&iter, fields, dest_struct)) + return; /* Empty message type */ do { pb_type_t type; type = iter.pos->type; - - /* Avoid crash on empty message types (zero fields) */ - if (iter.pos->tag == 0) - continue; if (PB_ATYPE(type) == PB_ATYPE_STATIC) { @@ -752,7 +718,7 @@ static void pb_message_set_to_defaults(const pb_field_t fields[], void *dest_str else if (PB_HTYPE(type) == PB_HTYPE_REPEATED) { /* Set array count to 0, no need to initialize contents. */ - *(size_t*)iter.pSize = 0; + *(pb_size_t*)iter.pSize = 0; continue; } @@ -780,14 +746,14 @@ static void pb_message_set_to_defaults(const pb_field_t fields[], void *dest_str /* Initialize array count to 0. */ if (PB_HTYPE(type) == PB_HTYPE_REPEATED) { - *(size_t*)iter.pSize = 0; + *(pb_size_t*)iter.pSize = 0; } } else if (PB_ATYPE(type) == PB_ATYPE_CALLBACK) { /* Don't overwrite callback */ } - } while (pb_field_next(&iter)); + } while (pb_field_iter_next(&iter)); } /********************* @@ -798,9 +764,11 @@ bool checkreturn pb_decode_noinit(pb_istream_t *stream, const pb_field_t fields[ { uint8_t fields_seen[(PB_MAX_REQUIRED_FIELDS + 7) / 8] = {0, 0, 0, 0, 0, 0, 0, 0}; uint32_t extension_range_start = 0; - pb_field_iterator_t iter; + pb_field_iter_t iter; - pb_field_init(&iter, fields, dest_struct); + /* Return value ignored, as empty message types will be correctly handled by + * pb_field_iter_find() anyway. */ + (void)pb_field_iter_begin(&iter, fields, dest_struct); while (stream->bytes_left) { @@ -816,7 +784,7 @@ bool checkreturn pb_decode_noinit(pb_istream_t *stream, const pb_field_t fields[ return false; } - if (!pb_field_find(&iter, tag)) + if (!pb_field_iter_find(&iter, tag)) { /* No match found, check if it matches an extension. */ if (tag >= extension_range_start) @@ -869,7 +837,7 @@ bool checkreturn pb_decode_noinit(pb_istream_t *stream, const pb_field_t fields[ do { req_field_count = iter.required_field_index; last_type = iter.pos->type; - } while (pb_field_next(&iter)); + } while (pb_field_iter_next(&iter)); /* Fixup if last field was also required. */ if (PB_HTYPE(last_type) == PB_HTYPE_REQUIRED && iter.pos->tag != 0) @@ -918,58 +886,66 @@ bool pb_decode_delimited(pb_istream_t *stream, const pb_field_t fields[], void * } #ifdef PB_ENABLE_MALLOC -void pb_release(const pb_field_t fields[], void *dest_struct) +static void pb_release_single_field(const pb_field_iter_t *iter) { - pb_field_iterator_t iter; - pb_field_init(&iter, fields, dest_struct); - - do + pb_type_t type; + type = iter->pos->type; + + if (PB_ATYPE(type) == PB_ATYPE_POINTER) { - pb_type_t type; - type = iter.pos->type; - - /* Avoid crash on empty message types (zero fields) */ - if (iter.pos->tag == 0) - continue; - - if (PB_ATYPE(type) == PB_ATYPE_POINTER) + if (PB_HTYPE(type) == PB_HTYPE_REPEATED && + (PB_LTYPE(type) == PB_LTYPE_STRING || + PB_LTYPE(type) == PB_LTYPE_BYTES)) { - if (PB_HTYPE(type) == PB_HTYPE_REPEATED && - (PB_LTYPE(type) == PB_LTYPE_STRING || - PB_LTYPE(type) == PB_LTYPE_BYTES)) + /* Release entries in repeated string or bytes array */ + void **pItem = *(void***)iter->pData; + pb_size_t count = *(pb_size_t*)iter->pSize; + while (count--) { - /* Release entries in repeated string or bytes array */ - void **pItem = *(void***)iter.pData; - size_t count = *(size_t*)iter.pSize; - while (count--) - { - pb_free(*pItem); - *pItem++ = NULL; - } + pb_free(*pItem); + *pItem++ = NULL; } - else if (PB_LTYPE(type) == PB_LTYPE_SUBMESSAGE) + *(pb_size_t*)iter->pSize = 0; + } + else if (PB_LTYPE(type) == PB_LTYPE_SUBMESSAGE) + { + /* Release fields in submessages */ + void *pItem = *(void**)iter->pData; + if (pItem) { - /* Release fields in submessages */ - void *pItem = *(void**)iter.pData; - size_t count = (pItem ? 1 : 0); + pb_size_t count = 1; if (PB_HTYPE(type) == PB_HTYPE_REPEATED) { - count = *(size_t*)iter.pSize; + count = *(pb_size_t*)iter->pSize; + *(pb_size_t*)iter->pSize = 0; } while (count--) { - pb_release((const pb_field_t*)iter.pos->ptr, pItem); - pItem = (uint8_t*)pItem + iter.pos->data_size; + pb_release((const pb_field_t*)iter->pos->ptr, pItem); + pItem = (uint8_t*)pItem + iter->pos->data_size; } } - - /* Release main item */ - pb_free(*(void**)iter.pData); - *(void**)iter.pData = NULL; } - } while (pb_field_next(&iter)); + + /* Release main item */ + pb_free(*(void**)iter->pData); + *(void**)iter->pData = NULL; + } +} + +void pb_release(const pb_field_t fields[], void *dest_struct) +{ + pb_field_iter_t iter; + + if (!pb_field_iter_begin(&iter, fields, dest_struct)) + return; /* Empty message type */ + + do + { + pb_release_single_field(&iter); + } while (pb_field_iter_next(&iter)); } #endif @@ -1083,42 +1059,50 @@ static bool checkreturn pb_dec_svarint(pb_istream_t *stream, const pb_field_t *f static bool checkreturn pb_dec_fixed32(pb_istream_t *stream, const pb_field_t *field, void *dest) { - UNUSED(field); + PB_UNUSED(field); return pb_decode_fixed32(stream, dest); } static bool checkreturn pb_dec_fixed64(pb_istream_t *stream, const pb_field_t *field, void *dest) { - UNUSED(field); + PB_UNUSED(field); return pb_decode_fixed64(stream, dest); } static bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest) { uint32_t size; + size_t alloc_size; pb_bytes_array_t *bdest; if (!pb_decode_varint32(stream, &size)) return false; + if (size > PB_SIZE_MAX) + PB_RETURN_ERROR(stream, "bytes overflow"); + + alloc_size = PB_BYTES_ARRAY_T_ALLOCSIZE(size); + if (size > alloc_size) + PB_RETURN_ERROR(stream, "size too large"); + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) { #ifndef PB_ENABLE_MALLOC PB_RETURN_ERROR(stream, "no malloc support"); #else - if (!allocate_field(stream, dest, PB_BYTES_ARRAY_T_ALLOCSIZE(size), 1)) + if (!allocate_field(stream, dest, alloc_size, 1)) return false; bdest = *(pb_bytes_array_t**)dest; #endif } else { - if (PB_BYTES_ARRAY_T_ALLOCSIZE(size) > field->data_size) + if (alloc_size > field->data_size) PB_RETURN_ERROR(stream, "bytes overflow"); bdest = (pb_bytes_array_t*)dest; } - - bdest->size = size; + + bdest->size = (pb_size_t)size; return pb_read(stream, bdest->bytes, size); } @@ -1133,6 +1117,9 @@ static bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_t *fi /* Space for null terminator */ alloc_size = size + 1; + if (alloc_size < size) + PB_RETURN_ERROR(stream, "size too large"); + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) { #ifndef PB_ENABLE_MALLOC diff --git a/firmware/protob/pb_decode.h b/firmware/protob/pb_decode.h index 8dc67408a..3d433155b 100644 --- a/firmware/protob/pb_decode.h +++ b/firmware/protob/pb_decode.h @@ -3,8 +3,8 @@ * field descriptions created by nanopb_generator.py. */ -#ifndef _PB_DECODE_H_ -#define _PB_DECODE_H_ +#ifndef PB_DECODE_H_INCLUDED +#define PB_DECODE_H_INCLUDED #include "pb.h" @@ -25,7 +25,7 @@ extern "C" { * is different than from the main stream. Don't use bytes_left to compute * any pointers. */ -struct _pb_istream_t +struct pb_istream_s { #ifdef PB_BUFFER_ONLY /* Callback pointer is not used in buffer-only configuration. diff --git a/firmware/protob/pb_encode.c b/firmware/protob/pb_encode.c index dc5a27349..cdd789555 100644 --- a/firmware/protob/pb_encode.c +++ b/firmware/protob/pb_encode.c @@ -5,6 +5,7 @@ #include "pb.h" #include "pb_encode.h" +#include "pb_common.h" /* Use the GCC warn_unused_result attribute to check that all return values * are propagated correctly. On other compilers and gcc before 3.4.0 just @@ -245,7 +246,7 @@ static bool checkreturn encode_basic_field(pb_ostream_t *stream, break; case PB_HTYPE_REPEATED: - if (!encode_array(stream, field, pData, *(const size_t*)pSize, func)) + if (!encode_array(stream, field, pData, *(const pb_size_t*)pSize, func)) return false; break; @@ -310,7 +311,7 @@ static bool checkreturn encode_extension_field(pb_ostream_t *stream, const pb_field_t *field, const void *pData) { const pb_extension_t *extension = *(const pb_extension_t* const *)pData; - UNUSED(field); + PB_UNUSED(field); while (extension) { @@ -333,42 +334,38 @@ static bool checkreturn encode_extension_field(pb_ostream_t *stream, * Encode all fields * *********************/ +static void *remove_const(const void *p) +{ + /* Note: this casts away const, in order to use the common field iterator + * logic for both encoding and decoding. */ + union { + void *p1; + const void *p2; + } t; + t.p2 = p; + return t.p1; +} + bool checkreturn pb_encode(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct) { - const pb_field_t *field = fields; - const void *pData = src_struct; - size_t prev_size = 0; + pb_field_iter_t iter; + if (!pb_field_iter_begin(&iter, fields, remove_const(src_struct))) + return true; /* Empty message type */ - while (field->tag != 0) - { - pData = (const char*)pData + prev_size + field->data_offset; - if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) - prev_size = sizeof(const void*); - else - prev_size = field->data_size; - - /* Special case for static arrays */ - if (PB_ATYPE(field->type) == PB_ATYPE_STATIC && - PB_HTYPE(field->type) == PB_HTYPE_REPEATED) - { - prev_size *= field->array_size; - } - - if (PB_LTYPE(field->type) == PB_LTYPE_EXTENSION) + do { + if (PB_LTYPE(iter.pos->type) == PB_LTYPE_EXTENSION) { /* Special case for the extension field placeholder */ - if (!encode_extension_field(stream, field, pData)) + if (!encode_extension_field(stream, iter.pos, iter.pData)) return false; } else { /* Regular field */ - if (!encode_field(stream, field, pData)) + if (!encode_field(stream, iter.pos, iter.pData)) return false; } - - field++; - } + } while (pb_field_iter_next(&iter)); return true; } @@ -602,13 +599,13 @@ static bool checkreturn pb_enc_svarint(pb_ostream_t *stream, const pb_field_t *f static bool checkreturn pb_enc_fixed64(pb_ostream_t *stream, const pb_field_t *field, const void *src) { - UNUSED(field); + PB_UNUSED(field); return pb_encode_fixed64(stream, src); } static bool checkreturn pb_enc_fixed32(pb_ostream_t *stream, const pb_field_t *field, const void *src) { - UNUSED(field); + PB_UNUSED(field); return pb_encode_fixed32(stream, src); } @@ -633,7 +630,6 @@ static bool checkreturn pb_enc_bytes(pb_ostream_t *stream, const pb_field_t *fie static bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_t *field, const void *src) { - /* strnlen() is not always available, so just use a loop */ size_t size = 0; size_t max_size = field->data_size; const char *p = (const char*)src; @@ -647,6 +643,7 @@ static bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_t *fi } else { + /* strnlen() is not always available, so just use a loop */ while (size < max_size && *p != '\0') { size++; diff --git a/firmware/protob/pb_encode.h b/firmware/protob/pb_encode.h index f82bac8f8..e992c8dca 100644 --- a/firmware/protob/pb_encode.h +++ b/firmware/protob/pb_encode.h @@ -3,8 +3,8 @@ * field descriptions created by nanopb_generator.py. */ -#ifndef _PB_ENCODE_H_ -#define _PB_ENCODE_H_ +#ifndef PB_ENCODE_H_INCLUDED +#define PB_ENCODE_H_INCLUDED #include "pb.h" @@ -24,7 +24,7 @@ extern "C" { * 4) Substreams will modify max_size and bytes_written. Don't use them * to calculate any pointers. */ -struct _pb_ostream_t +struct pb_ostream_s { #ifdef PB_BUFFER_ONLY /* Callback pointer is not used in buffer-only configuration. diff --git a/firmware/protob/storage.pb.c b/firmware/protob/storage.pb.c index 7625797cf..bd177d78e 100644 --- a/firmware/protob/storage.pb.c +++ b/firmware/protob/storage.pb.c @@ -1,20 +1,24 @@ /* Automatically generated nanopb constant definitions */ -/* Generated by nanopb-0.2.8 */ +/* Generated by nanopb-0.3.1 */ #include "storage.pb.h" +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + const pb_field_t Storage_fields[10] = { - PB_FIELD2( 1, UINT32 , REQUIRED, STATIC , FIRST, Storage, version, version, 0), - PB_FIELD2( 2, MESSAGE , OPTIONAL, STATIC , OTHER, Storage, node, version, &HDNodeType_fields), - PB_FIELD2( 3, STRING , OPTIONAL, STATIC , OTHER, Storage, mnemonic, node, 0), - PB_FIELD2( 4, BOOL , OPTIONAL, STATIC , OTHER, Storage, passphrase_protection, mnemonic, 0), - PB_FIELD2( 5, UINT32 , OPTIONAL, STATIC , OTHER, Storage, pin_failed_attempts, passphrase_protection, 0), - PB_FIELD2( 6, STRING , OPTIONAL, STATIC , OTHER, Storage, pin, pin_failed_attempts, 0), - PB_FIELD2( 7, STRING , OPTIONAL, STATIC , OTHER, Storage, language, pin, 0), - PB_FIELD2( 8, STRING , OPTIONAL, STATIC , OTHER, Storage, label, language, 0), - PB_FIELD2( 9, BOOL , OPTIONAL, STATIC , OTHER, Storage, imported, label, 0), + PB_FIELD( 1, UINT32 , REQUIRED, STATIC , FIRST, Storage, version, version, 0), + PB_FIELD( 2, MESSAGE , OPTIONAL, STATIC , OTHER, Storage, node, version, &HDNodeType_fields), + PB_FIELD( 3, STRING , OPTIONAL, STATIC , OTHER, Storage, mnemonic, node, 0), + PB_FIELD( 4, BOOL , OPTIONAL, STATIC , OTHER, Storage, passphrase_protection, mnemonic, 0), + PB_FIELD( 5, UINT32 , OPTIONAL, STATIC , OTHER, Storage, pin_failed_attempts, passphrase_protection, 0), + PB_FIELD( 6, STRING , OPTIONAL, STATIC , OTHER, Storage, pin, pin_failed_attempts, 0), + PB_FIELD( 7, STRING , OPTIONAL, STATIC , OTHER, Storage, language, pin, 0), + PB_FIELD( 8, STRING , OPTIONAL, STATIC , OTHER, Storage, label, language, 0), + PB_FIELD( 9, BOOL , OPTIONAL, STATIC , OTHER, Storage, imported, label, 0), PB_LAST_FIELD }; @@ -28,7 +32,7 @@ const pb_field_t Storage_fields[10] = { * numbers or field sizes that are larger than what can fit in 8 or 16 bit * field descriptors. */ -STATIC_ASSERT((pb_membersize(Storage, node) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_Storage) +PB_STATIC_ASSERT((pb_membersize(Storage, node) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_Storage) #endif #if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) @@ -39,7 +43,7 @@ STATIC_ASSERT((pb_membersize(Storage, node) < 65536), YOU_MUST_DEFINE_PB_FIELD_3 * numbers or field sizes that are larger than what can fit in the default * 8 bit descriptors. */ -STATIC_ASSERT((pb_membersize(Storage, node) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_Storage) +PB_STATIC_ASSERT((pb_membersize(Storage, node) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_Storage) #endif diff --git a/firmware/protob/storage.pb.h b/firmware/protob/storage.pb.h index 1814c27c4..82d1ba0cf 100644 --- a/firmware/protob/storage.pb.h +++ b/firmware/protob/storage.pb.h @@ -1,11 +1,15 @@ /* Automatically generated nanopb header */ -/* Generated by nanopb-0.2.8 */ +/* Generated by nanopb-0.3.1 */ -#ifndef _PB_STORAGE_PB_H_ -#define _PB_STORAGE_PB_H_ +#ifndef PB_STORAGE_PB_H_INCLUDED +#define PB_STORAGE_PB_H_INCLUDED #include "pb.h" #include "types.pb.h" +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + #ifdef __cplusplus extern "C" { #endif @@ -34,6 +38,10 @@ typedef struct _Storage { /* Default values for struct fields */ +/* Initializer values for message structs */ +#define Storage_init_default {0, false, HDNodeType_init_default, false, "", false, 0, false, 0, false, "", false, "", false, "", false, 0} +#define Storage_init_zero {0, false, HDNodeType_init_zero, false, "", false, 0, false, 0, false, "", false, "", false, "", false, 0} + /* Field tags (for use in manual encoding/decoding) */ #define Storage_version_tag 1 #define Storage_node_tag 2 diff --git a/firmware/protob/types.pb.c b/firmware/protob/types.pb.c index 1d9e61f17..66c417590 100644 --- a/firmware/protob/types.pb.c +++ b/firmware/protob/types.pb.c @@ -1,82 +1,86 @@ /* Automatically generated nanopb constant definitions */ -/* Generated by nanopb-0.2.8 */ +/* Generated by nanopb-0.3.1 */ #include "types.pb.h" +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + const uint32_t TxInputType_sequence_default = 4294967295u; const InputScriptType TxInputType_script_type_default = InputScriptType_SPENDADDRESS; const pb_field_t HDNodeType_fields[7] = { - PB_FIELD2( 1, UINT32 , REQUIRED, STATIC , FIRST, HDNodeType, depth, depth, 0), - PB_FIELD2( 2, UINT32 , REQUIRED, STATIC , OTHER, HDNodeType, fingerprint, depth, 0), - PB_FIELD2( 3, UINT32 , REQUIRED, STATIC , OTHER, HDNodeType, child_num, fingerprint, 0), - PB_FIELD2( 4, BYTES , REQUIRED, STATIC , OTHER, HDNodeType, chain_code, child_num, 0), - PB_FIELD2( 5, BYTES , OPTIONAL, STATIC , OTHER, HDNodeType, private_key, chain_code, 0), - PB_FIELD2( 6, BYTES , OPTIONAL, STATIC , OTHER, HDNodeType, public_key, private_key, 0), + PB_FIELD( 1, UINT32 , REQUIRED, STATIC , FIRST, HDNodeType, depth, depth, 0), + PB_FIELD( 2, UINT32 , REQUIRED, STATIC , OTHER, HDNodeType, fingerprint, depth, 0), + PB_FIELD( 3, UINT32 , REQUIRED, STATIC , OTHER, HDNodeType, child_num, fingerprint, 0), + PB_FIELD( 4, BYTES , REQUIRED, STATIC , OTHER, HDNodeType, chain_code, child_num, 0), + PB_FIELD( 5, BYTES , OPTIONAL, STATIC , OTHER, HDNodeType, private_key, chain_code, 0), + PB_FIELD( 6, BYTES , OPTIONAL, STATIC , OTHER, HDNodeType, public_key, private_key, 0), PB_LAST_FIELD }; const pb_field_t CoinType_fields[5] = { - PB_FIELD2( 1, STRING , OPTIONAL, STATIC , FIRST, CoinType, coin_name, coin_name, 0), - PB_FIELD2( 2, STRING , OPTIONAL, STATIC , OTHER, CoinType, coin_shortcut, coin_name, 0), - PB_FIELD2( 3, UINT32 , OPTIONAL, STATIC , OTHER, CoinType, address_type, coin_shortcut, 0), - PB_FIELD2( 4, UINT64 , OPTIONAL, STATIC , OTHER, CoinType, maxfee_kb, address_type, 0), + PB_FIELD( 1, STRING , OPTIONAL, STATIC , FIRST, CoinType, coin_name, coin_name, 0), + PB_FIELD( 2, STRING , OPTIONAL, STATIC , OTHER, CoinType, coin_shortcut, coin_name, 0), + PB_FIELD( 3, UINT32 , OPTIONAL, STATIC , OTHER, CoinType, address_type, coin_shortcut, 0), + PB_FIELD( 4, UINT64 , OPTIONAL, STATIC , OTHER, CoinType, maxfee_kb, address_type, 0), PB_LAST_FIELD }; const pb_field_t MultisigRedeemScriptType_fields[3] = { - PB_FIELD2( 1, BYTES , REPEATED, STATIC , FIRST, MultisigRedeemScriptType, pubkeys, pubkeys, 0), - PB_FIELD2( 2, BYTES , REPEATED, STATIC , OTHER, MultisigRedeemScriptType, signatures, pubkeys, 0), + PB_FIELD( 1, BYTES , REPEATED, STATIC , FIRST, MultisigRedeemScriptType, pubkeys, pubkeys, 0), + PB_FIELD( 2, BYTES , REPEATED, STATIC , OTHER, MultisigRedeemScriptType, signatures, pubkeys, 0), PB_LAST_FIELD }; const pb_field_t TxInputType_fields[8] = { - PB_FIELD2( 1, UINT32 , REPEATED, STATIC , FIRST, TxInputType, address_n, address_n, 0), - PB_FIELD2( 2, BYTES , REQUIRED, STATIC , OTHER, TxInputType, prev_hash, address_n, 0), - PB_FIELD2( 3, UINT32 , REQUIRED, STATIC , OTHER, TxInputType, prev_index, prev_hash, 0), - PB_FIELD2( 4, BYTES , OPTIONAL, STATIC , OTHER, TxInputType, script_sig, prev_index, 0), - PB_FIELD2( 5, UINT32 , OPTIONAL, STATIC , OTHER, TxInputType, sequence, script_sig, &TxInputType_sequence_default), - PB_FIELD2( 6, ENUM , OPTIONAL, STATIC , OTHER, TxInputType, script_type, sequence, &TxInputType_script_type_default), - PB_FIELD2( 7, MESSAGE , OPTIONAL, STATIC , OTHER, TxInputType, multisig, script_type, &MultisigRedeemScriptType_fields), + PB_FIELD( 1, UINT32 , REPEATED, STATIC , FIRST, TxInputType, address_n, address_n, 0), + PB_FIELD( 2, BYTES , REQUIRED, STATIC , OTHER, TxInputType, prev_hash, address_n, 0), + PB_FIELD( 3, UINT32 , REQUIRED, STATIC , OTHER, TxInputType, prev_index, prev_hash, 0), + PB_FIELD( 4, BYTES , OPTIONAL, STATIC , OTHER, TxInputType, script_sig, prev_index, 0), + PB_FIELD( 5, UINT32 , OPTIONAL, STATIC , OTHER, TxInputType, sequence, script_sig, &TxInputType_sequence_default), + PB_FIELD( 6, ENUM , OPTIONAL, STATIC , OTHER, TxInputType, script_type, sequence, &TxInputType_script_type_default), + PB_FIELD( 7, MESSAGE , OPTIONAL, STATIC , OTHER, TxInputType, multisig, script_type, &MultisigRedeemScriptType_fields), PB_LAST_FIELD }; const pb_field_t TxOutputType_fields[5] = { - PB_FIELD2( 1, STRING , OPTIONAL, STATIC , FIRST, TxOutputType, address, address, 0), - PB_FIELD2( 2, UINT32 , REPEATED, STATIC , OTHER, TxOutputType, address_n, address, 0), - PB_FIELD2( 3, UINT64 , REQUIRED, STATIC , OTHER, TxOutputType, amount, address_n, 0), - PB_FIELD2( 4, ENUM , REQUIRED, STATIC , OTHER, TxOutputType, script_type, amount, 0), + PB_FIELD( 1, STRING , OPTIONAL, STATIC , FIRST, TxOutputType, address, address, 0), + PB_FIELD( 2, UINT32 , REPEATED, STATIC , OTHER, TxOutputType, address_n, address, 0), + PB_FIELD( 3, UINT64 , REQUIRED, STATIC , OTHER, TxOutputType, amount, address_n, 0), + PB_FIELD( 4, ENUM , REQUIRED, STATIC , OTHER, TxOutputType, script_type, amount, 0), PB_LAST_FIELD }; const pb_field_t TxOutputBinType_fields[3] = { - PB_FIELD2( 1, UINT64 , REQUIRED, STATIC , FIRST, TxOutputBinType, amount, amount, 0), - PB_FIELD2( 2, BYTES , REQUIRED, STATIC , OTHER, TxOutputBinType, script_pubkey, amount, 0), + PB_FIELD( 1, UINT64 , REQUIRED, STATIC , FIRST, TxOutputBinType, amount, amount, 0), + PB_FIELD( 2, BYTES , REQUIRED, STATIC , OTHER, TxOutputBinType, script_pubkey, amount, 0), PB_LAST_FIELD }; const pb_field_t TransactionType_fields[8] = { - PB_FIELD2( 1, UINT32 , OPTIONAL, STATIC , FIRST, TransactionType, version, version, 0), - PB_FIELD2( 2, MESSAGE , REPEATED, STATIC , OTHER, TransactionType, inputs, version, &TxInputType_fields), - PB_FIELD2( 3, MESSAGE , REPEATED, STATIC , OTHER, TransactionType, bin_outputs, inputs, &TxOutputBinType_fields), - PB_FIELD2( 4, UINT32 , OPTIONAL, STATIC , OTHER, TransactionType, lock_time, bin_outputs, 0), - PB_FIELD2( 5, MESSAGE , REPEATED, STATIC , OTHER, TransactionType, outputs, lock_time, &TxOutputType_fields), - PB_FIELD2( 6, UINT32 , OPTIONAL, STATIC , OTHER, TransactionType, inputs_cnt, outputs, 0), - PB_FIELD2( 7, UINT32 , OPTIONAL, STATIC , OTHER, TransactionType, outputs_cnt, inputs_cnt, 0), + PB_FIELD( 1, UINT32 , OPTIONAL, STATIC , FIRST, TransactionType, version, version, 0), + PB_FIELD( 2, MESSAGE , REPEATED, STATIC , OTHER, TransactionType, inputs, version, &TxInputType_fields), + PB_FIELD( 3, MESSAGE , REPEATED, STATIC , OTHER, TransactionType, bin_outputs, inputs, &TxOutputBinType_fields), + PB_FIELD( 4, UINT32 , OPTIONAL, STATIC , OTHER, TransactionType, lock_time, bin_outputs, 0), + PB_FIELD( 5, MESSAGE , REPEATED, STATIC , OTHER, TransactionType, outputs, lock_time, &TxOutputType_fields), + PB_FIELD( 6, UINT32 , OPTIONAL, STATIC , OTHER, TransactionType, inputs_cnt, outputs, 0), + PB_FIELD( 7, UINT32 , OPTIONAL, STATIC , OTHER, TransactionType, outputs_cnt, inputs_cnt, 0), PB_LAST_FIELD }; const pb_field_t TxRequestDetailsType_fields[3] = { - PB_FIELD2( 1, UINT32 , OPTIONAL, STATIC , FIRST, TxRequestDetailsType, request_index, request_index, 0), - PB_FIELD2( 2, BYTES , OPTIONAL, STATIC , OTHER, TxRequestDetailsType, tx_hash, request_index, 0), + PB_FIELD( 1, UINT32 , OPTIONAL, STATIC , FIRST, TxRequestDetailsType, request_index, request_index, 0), + PB_FIELD( 2, BYTES , OPTIONAL, STATIC , OTHER, TxRequestDetailsType, tx_hash, request_index, 0), PB_LAST_FIELD }; const pb_field_t TxRequestSerializedType_fields[4] = { - PB_FIELD2( 1, UINT32 , OPTIONAL, STATIC , FIRST, TxRequestSerializedType, signature_index, signature_index, 0), - PB_FIELD2( 2, BYTES , OPTIONAL, STATIC , OTHER, TxRequestSerializedType, signature, signature_index, 0), - PB_FIELD2( 3, BYTES , OPTIONAL, STATIC , OTHER, TxRequestSerializedType, serialized_tx, signature, 0), + PB_FIELD( 1, UINT32 , OPTIONAL, STATIC , FIRST, TxRequestSerializedType, signature_index, signature_index, 0), + PB_FIELD( 2, BYTES , OPTIONAL, STATIC , OTHER, TxRequestSerializedType, signature, signature_index, 0), + PB_FIELD( 3, BYTES , OPTIONAL, STATIC , OTHER, TxRequestSerializedType, serialized_tx, signature, 0), PB_LAST_FIELD }; @@ -85,7 +89,7 @@ typedef struct { } wire_in_struct; static const pb_field_t wire_in_field = - PB_FIELD2(50002, BOOL , OPTEXT, STATIC , FIRST, wire_in_struct, wire_in, wire_in, 0); + PB_FIELD(50002, BOOL , OPTEXT, STATIC , FIRST, wire_in_struct, wire_in, wire_in, 0); const pb_extension_type_t wire_in = { NULL, @@ -98,7 +102,7 @@ typedef struct { } wire_out_struct; static const pb_field_t wire_out_field = - PB_FIELD2(50003, BOOL , OPTEXT, STATIC , FIRST, wire_out_struct, wire_out, wire_out, 0); + PB_FIELD(50003, BOOL , OPTEXT, STATIC , FIRST, wire_out_struct, wire_out, wire_out, 0); const pb_extension_type_t wire_out = { NULL, @@ -111,7 +115,7 @@ typedef struct { } wire_debug_in_struct; static const pb_field_t wire_debug_in_field = - PB_FIELD2(50004, BOOL , OPTEXT, STATIC , FIRST, wire_debug_in_struct, wire_debug_in, wire_debug_in, 0); + PB_FIELD(50004, BOOL , OPTEXT, STATIC , FIRST, wire_debug_in_struct, wire_debug_in, wire_debug_in, 0); const pb_extension_type_t wire_debug_in = { NULL, @@ -124,7 +128,7 @@ typedef struct { } wire_debug_out_struct; static const pb_field_t wire_debug_out_field = - PB_FIELD2(50005, BOOL , OPTEXT, STATIC , FIRST, wire_debug_out_struct, wire_debug_out, wire_debug_out, 0); + PB_FIELD(50005, BOOL , OPTEXT, STATIC , FIRST, wire_debug_out_struct, wire_debug_out, wire_debug_out, 0); const pb_extension_type_t wire_debug_out = { NULL, @@ -142,7 +146,7 @@ const pb_extension_type_t wire_debug_out = { * numbers or field sizes that are larger than what can fit in 8 or 16 bit * field descriptors. */ -STATIC_ASSERT((pb_membersize(TxInputType, multisig) < 65536 && pb_membersize(TransactionType, inputs[0]) < 65536 && pb_membersize(TransactionType, bin_outputs[0]) < 65536 && pb_membersize(TransactionType, outputs[0]) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_HDNodeType_CoinType_MultisigRedeemScriptType_TxInputType_TxOutputType_TxOutputBinType_TransactionType_TxRequestDetailsType_TxRequestSerializedType) +PB_STATIC_ASSERT((pb_membersize(TxInputType, multisig) < 65536 && pb_membersize(TransactionType, inputs[0]) < 65536 && pb_membersize(TransactionType, bin_outputs[0]) < 65536 && pb_membersize(TransactionType, outputs[0]) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_HDNodeType_CoinType_MultisigRedeemScriptType_TxInputType_TxOutputType_TxOutputBinType_TransactionType_TxRequestDetailsType_TxRequestSerializedType) #endif #if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) diff --git a/firmware/protob/types.pb.h b/firmware/protob/types.pb.h index 8f532605c..3b91af929 100644 --- a/firmware/protob/types.pb.h +++ b/firmware/protob/types.pb.h @@ -1,9 +1,13 @@ /* Automatically generated nanopb header */ -/* Generated by nanopb-0.2.8 */ +/* Generated by nanopb-0.3.1 */ -#ifndef _PB_TYPES_PB_H_ -#define _PB_TYPES_PB_H_ +#ifndef PB_TYPES_PB_H_INCLUDED +#define PB_TYPES_PB_H_INCLUDED #include "pb.h" +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + #ifdef __cplusplus extern "C" { #endif @@ -72,20 +76,11 @@ typedef struct _CoinType { uint64_t maxfee_kb; } CoinType; -typedef struct { - size_t size; - uint8_t bytes[32]; -} HDNodeType_chain_code_t; +typedef PB_BYTES_ARRAY_T(32) HDNodeType_chain_code_t; -typedef struct { - size_t size; - uint8_t bytes[32]; -} HDNodeType_private_key_t; +typedef PB_BYTES_ARRAY_T(32) HDNodeType_private_key_t; -typedef struct { - size_t size; - uint8_t bytes[33]; -} HDNodeType_public_key_t; +typedef PB_BYTES_ARRAY_T(33) HDNodeType_public_key_t; typedef struct _HDNodeType { uint32_t depth; @@ -98,27 +93,18 @@ typedef struct _HDNodeType { HDNodeType_public_key_t public_key; } HDNodeType; -typedef struct { - size_t size; - uint8_t bytes[65]; -} MultisigRedeemScriptType_pubkeys_t; +typedef PB_BYTES_ARRAY_T(65) MultisigRedeemScriptType_pubkeys_t; -typedef struct { - size_t size; - uint8_t bytes[80]; -} MultisigRedeemScriptType_signatures_t; +typedef PB_BYTES_ARRAY_T(80) MultisigRedeemScriptType_signatures_t; typedef struct _MultisigRedeemScriptType { - size_t pubkeys_count; + pb_size_t pubkeys_count; MultisigRedeemScriptType_pubkeys_t pubkeys[5]; - size_t signatures_count; + pb_size_t signatures_count; MultisigRedeemScriptType_signatures_t signatures[4]; } MultisigRedeemScriptType; -typedef struct { - size_t size; - uint8_t bytes[520]; -} TxOutputBinType_script_pubkey_t; +typedef PB_BYTES_ARRAY_T(520) TxOutputBinType_script_pubkey_t; typedef struct _TxOutputBinType { uint64_t amount; @@ -128,16 +114,13 @@ typedef struct _TxOutputBinType { typedef struct _TxOutputType { bool has_address; char address[35]; - size_t address_n_count; + pb_size_t address_n_count; uint32_t address_n[8]; uint64_t amount; OutputScriptType script_type; } TxOutputType; -typedef struct { - size_t size; - uint8_t bytes[32]; -} TxRequestDetailsType_tx_hash_t; +typedef PB_BYTES_ARRAY_T(32) TxRequestDetailsType_tx_hash_t; typedef struct _TxRequestDetailsType { bool has_request_index; @@ -146,15 +129,9 @@ typedef struct _TxRequestDetailsType { TxRequestDetailsType_tx_hash_t tx_hash; } TxRequestDetailsType; -typedef struct { - size_t size; - uint8_t bytes[80]; -} TxRequestSerializedType_signature_t; +typedef PB_BYTES_ARRAY_T(80) TxRequestSerializedType_signature_t; -typedef struct { - size_t size; - uint8_t bytes[1024]; -} TxRequestSerializedType_serialized_tx_t; +typedef PB_BYTES_ARRAY_T(1024) TxRequestSerializedType_serialized_tx_t; typedef struct _TxRequestSerializedType { bool has_signature_index; @@ -165,18 +142,12 @@ typedef struct _TxRequestSerializedType { TxRequestSerializedType_serialized_tx_t serialized_tx; } TxRequestSerializedType; -typedef struct { - size_t size; - uint8_t bytes[32]; -} TxInputType_prev_hash_t; +typedef PB_BYTES_ARRAY_T(32) TxInputType_prev_hash_t; -typedef struct { - size_t size; - uint8_t bytes[520]; -} TxInputType_script_sig_t; +typedef PB_BYTES_ARRAY_T(520) TxInputType_script_sig_t; typedef struct _TxInputType { - size_t address_n_count; + pb_size_t address_n_count; uint32_t address_n[8]; TxInputType_prev_hash_t prev_hash; uint32_t prev_index; @@ -193,13 +164,13 @@ typedef struct _TxInputType { typedef struct _TransactionType { bool has_version; uint32_t version; - size_t inputs_count; + pb_size_t inputs_count; TxInputType inputs[1]; - size_t bin_outputs_count; + pb_size_t bin_outputs_count; TxOutputBinType bin_outputs[1]; bool has_lock_time; uint32_t lock_time; - size_t outputs_count; + pb_size_t outputs_count; TxOutputType outputs[1]; bool has_inputs_cnt; uint32_t inputs_cnt; @@ -217,6 +188,26 @@ extern const pb_extension_type_t wire_debug_out; extern const uint32_t TxInputType_sequence_default; extern const InputScriptType TxInputType_script_type_default; +/* Initializer values for message structs */ +#define HDNodeType_init_default {0, 0, 0, {0, {0}}, false, {0, {0}}, false, {0, {0}}} +#define CoinType_init_default {false, "", false, "", false, 0, false, 0} +#define MultisigRedeemScriptType_init_default {0, {{0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}}, 0, {{0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}}} +#define TxInputType_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}, {0, {0}}, 0, false, {0, {0}}, false, 4294967295u, false, InputScriptType_SPENDADDRESS, false, MultisigRedeemScriptType_init_default} +#define TxOutputType_init_default {false, "", 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, (OutputScriptType)0} +#define TxOutputBinType_init_default {0, {0, {0}}} +#define TransactionType_init_default {false, 0, 0, {TxInputType_init_default}, 0, {TxOutputBinType_init_default}, false, 0, 0, {TxOutputType_init_default}, false, 0, false, 0} +#define TxRequestDetailsType_init_default {false, 0, false, {0, {0}}} +#define TxRequestSerializedType_init_default {false, 0, false, {0, {0}}, false, {0, {0}}} +#define HDNodeType_init_zero {0, 0, 0, {0, {0}}, false, {0, {0}}, false, {0, {0}}} +#define CoinType_init_zero {false, "", false, "", false, 0, false, 0} +#define MultisigRedeemScriptType_init_zero {0, {{0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}}, 0, {{0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}}} +#define TxInputType_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}, {0, {0}}, 0, false, {0, {0}}, false, 0, false, (InputScriptType)0, false, MultisigRedeemScriptType_init_zero} +#define TxOutputType_init_zero {false, "", 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, (OutputScriptType)0} +#define TxOutputBinType_init_zero {0, {0, {0}}} +#define TransactionType_init_zero {false, 0, 0, {TxInputType_init_zero}, 0, {TxOutputBinType_init_zero}, false, 0, 0, {TxOutputType_init_zero}, false, 0, false, 0} +#define TxRequestDetailsType_init_zero {false, 0, false, {0, {0}}} +#define TxRequestSerializedType_init_zero {false, 0, false, {0, {0}}, false, {0, {0}}} + /* Field tags (for use in manual encoding/decoding) */ #define CoinType_coin_name_tag 1 #define CoinType_coin_shortcut_tag 2 diff --git a/firmware/transaction.c b/firmware/transaction.c index 69acabd73..bd02bb1cc 100644 --- a/firmware/transaction.c +++ b/firmware/transaction.c @@ -372,16 +372,14 @@ bool transactionMessageVerify(uint8_t *message, uint32_t message_len, uint8_t *s pubkey[0] = 0x04; bn_write_be(&cp.x, pubkey + 1); bn_write_be(&cp.y, pubkey + 33); - // check if the address is correct when provided - if (address) { - ecdsa_address_decode(address, decoded); - if (compressed) { - pubkey[0] = 0x02 | (cp.y.val[0] & 0x01); - } - ecdsa_get_address(pubkey, decoded[0], addr); - if (strcmp(addr, address) != 0) { - return false; - } + // check if the address is correct + ecdsa_address_decode(address, decoded); + if (compressed) { + pubkey[0] = 0x02 | (cp.y.val[0] & 0x01); + } + ecdsa_get_address(pubkey, decoded[0], addr); + if (strcmp(addr, address) != 0) { + return false; } // check if signature verifies the digest if (ecdsa_verify_digest(pubkey, signature + 1, hash) != 0) { diff --git a/trezor-common b/trezor-common index 71a02eb83..e675d5fd7 160000 --- a/trezor-common +++ b/trezor-common @@ -1 +1 @@ -Subproject commit 71a02eb83dfa4a5f0543743bc8fcfbd74fc0b7d0 +Subproject commit e675d5fd7684e437bb35fb24330234d43ee2e4db