Skip to main content

Module counter_encoding

Module counter_encoding 

Source
Expand description

Encoding of the 8-byte initial value for the ATECC608B monotonic counters (Counter0 at bytes 52..60 of the config zone, Counter1 at bytes 60..68).

The chip stores each counter as a redundant 8-byte structure split into two 16-bit linear (“lin”) halves and two 16-bit binary (“bin”) halves. Linear halves encode the low 5 bits of the count by clearing one bit per increment (popcount-style); binary halves encode the high 16 bits as a normal big-endian unsigned 16-bit integer. The two halves are offset by 16 increments so a corruption of either is detected by the chip.

Writing 0xFF to all 8 bytes does not represent “count = 0”. It leaves bin_a and bin_b at 0xFFFF, which the chip interprets as a high-bit count near the hardware ceiling (2^21 - 1). A chip that is config-locked with this stray initialization comes out of the lock with count ≈ 2_097_120 (= 0xFFFF * 32), losing virtually all of its 2^21 lifetime increments.

The correct factory initialization is FF FF FF FF 00 00 00 00, which decodes to count = 0. The function in this module produces that, plus any other target count up to the maximum.

§Reference

Translation of calib_write_config_counter in lib/calib/calib_basic.c of Microchip CryptoAuthLib. The formula:

    lin_a = 0xFFFF >> (counter_value % 32)
    lin_b = 0xFFFF >> ((counter_value - 16) % 32)     if counter_value >= 16 else 0xFFFF
    bin_a = counter_value / 32
    bin_b = (counter_value - 16) / 32                  if counter_value >= 16 else 0

is serialized big-endian as:

    bytes = [lin_a_hi, lin_a_lo, lin_b_hi, lin_b_lo,
             bin_a_hi, bin_a_lo, bin_b_hi, bin_b_lo]

Constants§

COUNTER_MAX_VALUE
Maximum supported counter value on the ATECC608B (2^21 - 1).
COUNTER_STORAGE_SIZE
Number of bytes consumed by one counter in the config zone.

Functions§

encode_counter_value
Encode a target counter value into the 8-byte storage representation the ATECC608B expects in the configuration zone.