fix(core): libtropic overwrite bug workaround
What changed, and why it matters
This commit adds a small workaround in the Trezor hardware wallet's random number generator code. The change allocates a slightly larger temporary buffer and only uses the inner portion, leaving unused 'bumper' bytes at the end. The commit message calls this a 'libtropic overwrite bug workaround,' suggesting an external library (libtropic) may write past the requested amount of random data. The patch does not fix the underlying library bug; it only pads the local buffer so any overflow lands in harmless scratch space rather than corrupting adjacent memory. Because this affects the cryptographic random number generator used for keys and secrets, a real overwrite could have security implications, but the diff itself does not show an actual vulnerability in Trezor code or prove the bug is exploitable.
Treat this as a signal that libtropic may have a buffer-overflow bug. Trezor should confirm the exact overwrite size and root cause with the libtropic vendor, upstream a proper fix, and replace this bumper workaround with validated bounds checking or a fixed library version. Users should ensure firmware includes this workaround until a complete fix is shipped.
Security signals we found
Buffer-size workaround for suspected out-of-bounds write in external RNG library
Comment explicitly labels change as a workaround rather than a proper fix
Code is in the strong random number generator path used for cryptographic material
No changelog entry despite security-adjacent change
Patch is partial: it mitigates symptom but does not address underlying bug
Evidence from the diff
In core/embed/sec/rng/rng_common.c, rng_fill_buffer_strong() now declares block[32 + 4] and copies only MIN(remaining, sizeof(block) - 4) bytes into it on each iteration. The extra 4 bytes are never used by the caller. The comment ‘workaround’ and the commit title indicate this is a defensive shim for an overwrite behavior in libtropic’s random-buffer routine. The function still passes the reduced block_size to optiga_random_buffer() or lt_random_bytes(), so the API contract is unchanged from the caller’s perspective. No root-cause fix, bounds checking, or error handling for the suspected overwrite is present.
Changed components
core/embed/sec/rng/rng_common.crng_fill_buffer_strong()libtropic RNG integrationOptiga TRNG integration (USE_OPTIGA path)Inspect captured patch +4 / −2
diff --git a/core/embed/sec/rng/rng_common.c b/core/embed/sec/rng/rng_common.c
index dfec14fb..d370cc02 100644
--- a/core/embed/sec/rng/rng_common.c
+++ b/core/embed/sec/rng/rng_common.c
@@ -55,10 +55,12 @@ bool rng_fill_buffer_strong(void* buffer, size_t buffer_size) {
uint8_t* dst = (uint8_t*)buffer;
size_t remaining = buffer_size;
- uint8_t block[32];
+ static const int bumper = 4; // !@# workaround
+
+ uint8_t block[32 + bumper];
while (remaining > 0) {
- size_t block_size = MIN(remaining, sizeof(block));
+ size_t block_size = MIN(remaining, sizeof(block) - bumper);
#ifdef USE_OPTIGA
if (!optiga_random_buffer(block, block_size)) {
return false;
Why this scored 55/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.