feat(nufi-tron): add GuiGetTrxSignUrDataUnlimited
What changed, and why it matters
This commit adds a new way for the Keystone 3 hardware wallet to produce a Tron (TRX) transaction signature as a single large QR code, instead of splitting it into multiple smaller QR codes. This is a feature addition for compatibility with the NuFi wallet. There is no direct evidence in the commit that it fixes a security vulnerability; it appears to be a normal product feature.
No immediate security action is required. As a routine review step, verify that `FRAGMENT_UNLIMITED_LENGTH` does not cause buffer overflows in downstream QR encoding and that the single large QR remains within the hardware display/camera scanning limits. Also confirm the new handler is only invoked for intended Tron transaction types.
Security signals we found
No security-relevant signals detected in the diff itself.
The change is a feature addition (NuFi Tron integration) rather than a bug fix.
No bounds checks, memory allocations, or cryptographic operations were modified beyond passing a fragment-length constant.
Evidence from the diff
The change introduces GuiGetTrxSignUrDataUnlimited, which calls a refactored internal helper GuiGetTrxSignUrDataDynamic(bool unLimit). When unLimit is true, the UR/QR encoding uses FRAGMENT_UNLIMITED_LENGTH, producing one QR fragment rather than the default fragmented output. The Tron view handler in gui_chain.c is updated to register this unlimited variant alongside the existing QR-code path. The cryptographic signing path (tron_sign_keystone) is unchanged; only the UR presentation layer is affected.
Changed components
src/ui/gui_chain/gui_chain.csrc/ui/gui_chain/multi/web3/gui_trx.csrc/ui/gui_chain/multi/web3/gui_trx.hInspect captured patch +16 / −4
diff --git a/src/ui/gui_chain/gui_chain.c b/src/ui/gui_chain/gui_chain.c
index 8d35d3e..a096201 100644
--- a/src/ui/gui_chain/gui_chain.c
+++ b/src/ui/gui_chain/gui_chain.c
@@ -64,7 +64,7 @@ static const ViewHandlerEntry g_viewHandlerMap[] = {
{EthPersonalMessage, GuiGetEthSignQrCodeData, GuiGetEthSignUrDataUnlimited, GuiGetEthCheckResult, CHAIN_ETH, REMAPVIEW_ETH_PERSONAL_MESSAGE},
{EthTypedData, GuiGetEthSignQrCodeData, GuiGetEthSignUrDataUnlimited, GuiGetEthCheckResult, CHAIN_ETH, REMAPVIEW_ETH_TYPEDDATA},
{EthBatchTx, GuiGetEthBatchTxSignQrCodeData, NULL, NULL, CHAIN_ETH, REMAPVIEW_ETH_BATCH_TX},
- {TronTx, GuiGetTrxSignQrCodeData, NULL, GuiGetTrxCheckResult, CHAIN_TRX, REMAPVIEW_TRX},
+ {TronTx, GuiGetTrxSignQrCodeData, GuiGetTrxSignUrDataUnlimited, GuiGetTrxCheckResult, CHAIN_TRX, REMAPVIEW_TRX},
// avax
{AvaxTx, GuiGetAvaxSignQrCodeData, GuiGetAvaxSignUrDataUnlimited, GuiGetAvaxCheckResult, CHAIN_AVAX, REMAPVIEW_AVAX},
diff --git a/src/ui/gui_chain/multi/web3/gui_trx.c b/src/ui/gui_chain/multi/web3/gui_trx.c
index 0c1efbf..208f23f 100644
--- a/src/ui/gui_chain/multi/web3/gui_trx.c
+++ b/src/ui/gui_chain/multi/web3/gui_trx.c
@@ -119,7 +119,7 @@ void GetTrxToken(void *indata, void *param, uint32_t maxLen)
strcpy_s((char *)indata, maxLen, trx->detail->token);
}
-UREncodeResult *GuiGetTrxSignQrCodeData(void)
+static UREncodeResult *GuiGetTrxSignUrDataDynamic(bool unLimit)
{
bool enable = IsPreviousLockScreenEnable();
SetLockScreen(false);
@@ -130,6 +130,7 @@ UREncodeResult *GuiGetTrxSignQrCodeData(void)
uint8_t mfp[4];
GetMasterFingerPrint(mfp);
uint8_t seed[64];
+ uint32_t fragmentLen = unLimit ? FRAGMENT_UNLIMITED_LENGTH : FRAGMENT_MAX_LENGTH_DEFAULT;
do {
int ret = GetAccountSeed(GetCurrentAccountIndex(), seed, SecretCacheGetPassword());
@@ -140,7 +141,7 @@ UREncodeResult *GuiGetTrxSignQrCodeData(void)
encodeResult = tron_sign_keystone(data, urType, mfp, sizeof(mfp), GetCurrentAccountPublicKey(XPUB_TYPE_TRX),
SOFTWARE_VERSION, seed, GetCurrentAccountSeedLen());
} else {
- encodeResult = tron_sign_request(data, seed, GetCurrentAccountSeedLen());
+ encodeResult = tron_sign_request(data, seed, GetCurrentAccountSeedLen(), fragmentLen);
}
CHECK_CHAIN_BREAK(encodeResult);
@@ -151,4 +152,14 @@ UREncodeResult *GuiGetTrxSignQrCodeData(void)
SetLockScreen(enable);
return encodeResult;
-}
\ No newline at end of file
+}
+
+UREncodeResult *GuiGetTrxSignQrCodeData(void)
+{
+ return GuiGetTrxSignUrDataDynamic(false);
+}
+
+UREncodeResult *GuiGetTrxSignUrDataUnlimited(void)
+{
+ return GuiGetTrxSignUrDataDynamic(true);
+}
diff --git a/src/ui/gui_chain/multi/web3/gui_trx.h b/src/ui/gui_chain/multi/web3/gui_trx.h
index 6f1376f..681c5d1 100644
--- a/src/ui/gui_chain/multi/web3/gui_trx.h
+++ b/src/ui/gui_chain/multi/web3/gui_trx.h
@@ -13,3 +13,4 @@ void GetTrxContract(void *indata, void *param, uint32_t maxLen);
bool GetTrxTokenExist(void *indata, void *param);
void GetTrxToken(void *indata, void *param, uint32_t maxLen);
UREncodeResult *GuiGetTrxSignQrCodeData(void);
+UREncodeResult *GuiGetTrxSignUrDataUnlimited(void);
Why this scored 18/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.