What changed, and why it matters
This commit removes an internal retry loop from the low-level I2C driver that talks to the Optiga secure chip in the BitBox02 hardware wallet. Previously, every I2C write/read would automatically retry up to 25 times with 2 ms delays. Now it tries once and lets the upper-layer Optiga library decide whether to retry. The change is described by the vendor as a simplification that reduces redundant blocking; it is not presented as a security fix and the diff alone does not show an exploitable vulnerability.
Treat as a normal firmware maintenance commit. Review whether the upper-layer IFX I2C retry logic and slave-address retry path are actually enabled and correctly configured in the build, since the local fallback retry is now gone. No immediate security response is indicated by the supplied materials.
Security signals we found
Removal of local retry/sleep loop in low-level I2C PAL
Change aligns PAL behavior with upstream Optiga IFX I2C contract
No bounds, length, or input validation changes
No cryptographic, authentication, or secret-handling changes visible
Commit message frames change as cleanup/refactoring, not as a security fix
Evidence from the diff
The patch modifies src/optiga/pal/pal_i2c.c to eliminate a local do-while retry loop (25 iterations, 2 ms delay) around i2c_m_sync_transfer() in both pal_i2c_write() and pal_i2c_read(). It also removes includes for hal_delay.h, pal_os_timer.h, and util.h that were only used for that loop. The PAL now performs a single synchronous transfer and returns PAL_I2C_EVENT_SUCCESS, PAL_I2C_EVENT_ERROR, or PAL_I2C_EVENT_BUSY to the IFX I2C stack, matching the upstream PAL contract. The commit message states that the host library already retries asynchronously and that the special slave-address path retries pal_i2c_write() on its own, so the local loop duplicated retry logic and blocked for up to ~50 ms. Higher-level optiga_ops synchronous wrappers still busy-wait on Optiga callbacks.
Changed components
src/optiga/pal/pal_i2c.cOptiga secure-element I2C PAL layerBitBox02 firmware I2C communication with OptigaInspect captured patch +2 / −13
diff --git a/src/optiga/pal/pal_i2c.c b/src/optiga/pal/pal_i2c.c
index f78cfd0..3b28956 100644
--- a/src/optiga/pal/pal_i2c.c
+++ b/src/optiga/pal/pal_i2c.c
@@ -36,10 +36,7 @@
*/
#include "pal_i2c.h"
-#include "hal_delay.h"
#include "hal_i2c_m_sync.h"
-#include "pal_os_timer.h"
-#include "util.h"
extern struct i2c_m_sync_desc I2C_0;
#define PAL_I2C_MASTER_MAX_BITRATE (400U)
@@ -131,7 +128,6 @@ pal_status_t pal_i2c_write(const pal_i2c_t* p_i2c_context, uint8_t* p_data, uint
{
pal_status_t status = PAL_STATUS_FAILURE;
struct _i2c_m_msg packet;
- uint8_t retries = 25U;
int32_t r;
packet.addr = p_i2c_context->slave_address;
@@ -145,10 +141,7 @@ pal_status_t pal_i2c_write(const pal_i2c_t* p_i2c_context, uint8_t* p_data, uint
// Invoke the low level i2c master driver API to write to the bus
// !!!OPTIGA_LIB_PORTING_REQUIRED
- do {
- r = i2c_m_sync_transfer(p_i2c_context->p_i2c_hw_config, &packet);
- delay_ms(2U);
- } while (retries-- && r != I2C_OK);
+ r = i2c_m_sync_transfer(p_i2c_context->p_i2c_hw_config, &packet);
if (r != I2C_OK) {
// If I2C Master fails to invoke the write operation, invoke upper layer event handler
@@ -204,7 +197,6 @@ pal_status_t pal_i2c_read(const pal_i2c_t* p_i2c_context, uint8_t* p_data, uint1
// int32_t start = pal_os_timer_get_time_in_milliseconds();
pal_status_t status = PAL_STATUS_FAILURE;
struct _i2c_m_msg packet;
- uint8_t retries = 25U;
int32_t r;
packet.addr = p_i2c_context->slave_address;
@@ -217,10 +209,7 @@ pal_status_t pal_i2c_read(const pal_i2c_t* p_i2c_context, uint8_t* p_data, uint1
gp_pal_i2c_current_ctx = p_i2c_context;
// Invoke the low level i2c master driver API to read from the bus
- do {
- r = i2c_m_sync_transfer(p_i2c_context->p_i2c_hw_config, &packet);
- delay_ms(2U);
- } while (retries-- && r != I2C_OK);
+ r = i2c_m_sync_transfer(p_i2c_context->p_i2c_hw_config, &packet);
if (r != I2C_OK) {
// If I2C Master fails to invoke the read operation, invoke upper layer event handler
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.