Skip to content

Commit d01041e

Browse files
committed
Handle nonce counter wraparound by regenerating epoch for long-running devices
1 parent 1190aaf commit d01041e

1 file changed

Lines changed: 17 additions & 15 deletions

File tree

src/Utils.cpp

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -351,27 +351,29 @@ void Utils::getHighQualityRandom(RNG* rng, uint8_t* dest, size_t size) {
351351
// ========== Secure Counter Generation ==========
352352
353353
// Static state for counter generation
354-
static uint16_t s_counter_boot_id = 0;
354+
// Counter format: [epoch (2 bytes random)] [sequence (2 bytes incrementing)]
355+
// - epoch: random value, regenerated on boot or sequence wraparound
356+
// - sequence: 0-65535, increments each message
357+
// This guarantees uniqueness across devices (different epochs) and
358+
// within long-running sessions (epoch changes on wraparound)
359+
static uint16_t s_counter_epoch = 0;
355360
static uint16_t s_counter_seq = 0;
356361
357362
void Utils::generateSecureCounter(uint8_t* counter) {
358-
// Counter format: [boot_id (2)] [sequence (2)]
359-
// This ensures uniqueness even if:
360-
// - Many messages sent quickly
361-
// - Device reboots (new boot_id)
362-
// Full nonce uniqueness comes from SHA256(key || counter) derivation
363-
364-
// Initialize boot_id once per boot with random value
365-
if (s_counter_boot_id == 0) {
366-
getHardwareRandom((uint8_t*)&s_counter_boot_id, 2);
367-
// Ensure non-zero (unlikely, but handle it)
368-
if (s_counter_boot_id == 0) s_counter_boot_id = 1;
363+
// Initialize epoch on first call
364+
if (s_counter_epoch == 0) {
365+
getHardwareRandom((uint8_t*)&s_counter_epoch, 2);
366+
if (s_counter_epoch == 0) s_counter_epoch = 1;
369367
}
370368
371-
// Copy boot_id (bytes 0-1)
372-
memcpy(counter, &s_counter_boot_id, 2);
369+
// On sequence wraparound, generate new epoch
370+
if (s_counter_seq == 0xFFFF) {
371+
getHardwareRandom((uint8_t*)&s_counter_epoch, 2);
372+
if (s_counter_epoch == 0) s_counter_epoch = 1;
373+
s_counter_seq = 0;
374+
}
373375
374-
// Copy and increment sequence (bytes 2-3)
376+
memcpy(counter, &s_counter_epoch, 2);
375377
memcpy(counter + 2, &s_counter_seq, 2);
376378
s_counter_seq++;
377379
}

0 commit comments

Comments
 (0)