chore(core/embed): clear temporary buffer across Optiga/Tropic calls
What changed, and why it matters
This is a hardening change for the random number generator inside Trezor hardware wallets. It makes sure that temporary memory holding secret random values from the Optiga and Tropic security chips is wiped immediately after use, rather than only once at the end. It also fixes a subtle edge case where a buggy Tropic chip call could leave old Optiga randomness in the temporary buffer, potentially weakening the final random output.
Treat as a defensive hardening patch. Review whether similar temporary buffers handling entropy or cryptographic material elsewhere in the firmware are cleared immediately after use. No urgent security response is indicated, but the change should be included in the next firmware release.
Security signals we found
Sensitive intermediate buffer not cleared promptly
Potential stale-buffer reuse across RNG source boundaries
Defense-in-depth memory sanitization for secure-element entropy
Subtle correctness issue if Tropic call succeeds without writing buffer
Evidence from the diff
In rng_fill_buffer_strong(), the function fills a destination buffer by XOR-ing entropy from Optiga and/or Tropic secure elements into it. Previously, the temporary block buffer was zeroed only after the entire loop completed. The patch moves memzero(block, sizeof(block)) inside the loop, immediately after each Optiga and Tropic contribution is XOR-ed into dst. This ensures intermediate entropy does not persist across loop iterations. It also prevents a hypothetical scenario where tropic_random_buffer() returns success without writing to block, which would cause the subsequent XOR to ‘undo’ the prior Optiga XOR result using stale data.
Changed components
core/embed/sec/rng/rng_strong.cTrezor firmware strong RNGOptiga secure element integrationTropic secure element integrationInspect captured patch +2 / −2
### core/embed/sec/rng/rng_strong.c
@@ -54,6 +54,7 @@ void rng_fill_buffer_strong(void* buffer, size_t buffer_size) {
for (size_t i = 0; i < block_size; i++) {
dst[i] ^= block[i];
}
+ memzero(block, sizeof(block)); // clear entropy from Optiga
#endif
#ifdef USE_TROPIC
ensure(sectrue * tropic_random_buffer(block, block_size),
@@ -62,12 +63,11 @@ void rng_fill_buffer_strong(void* buffer, size_t buffer_size) {
for (size_t i = 0; i < block_size; i++) {
dst[i] ^= block[i];
}
+ memzero(block, sizeof(block)); // clear entropy from Tropic
#endif
dst += block_size;
remaining -= block_size;
}
-
- memzero(block, sizeof(block));
}
#else // defined(USE_OPTIGA) || defined(USE_TROPIC)Why this scored 37/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.