EECC study materials
EECC study resources

GCM Nonce Reuse in a Power-Unstable Controller Fleet

EECC · Put your knowledge to work in context.

All case studies

GCM Nonce Reuse in a Power-Unstable Controller Fleet

A building-automation vendor ships 8,200 controllers that report over MQTT using AES-128-GCM. The 96-bit nonce is a 32-bit device identifier followed by a 64-bit counter persisted in flash. To reduce flash wear, firmware 3.1 writes the counter only every 1,024 messages and keeps the working value in RAM. Brownouts cause about 3% of sites to lose power each month, and on each restart the counter resumes from the last persisted value. Separately, about 400 units left the factory with a duplicated device identifier. Keys are provisioned at manufacture by a service that derives them from the device identifier and a vendor master secret. A researcher has published captures of two controllers in one building using the same nonce and argues the fleet is broken. The vendor's security lead replies that per-device keys make nonce reuse harmless.

1. Evaluate both claims. What does nonce reuse actually give an attacker here, and who is right?

Read the worked answer

Two situations must be separated, and both parties have missed something.

Same key, same nonce is a total break of GCM. The counter-mode keystream is identical, so two ciphertexts XOR to the XOR of the plaintexts and crib-dragging recovers both. Worse, GCM's tag is GHASH over the ciphertext under an authentication key H derived from the block cipher; two message and tag pairs under the same nonce give two equations in the same unknown H, which can be solved. Once H is known the attacker can forge valid tags for arbitrary messages under that key. Confidentiality and integrity both fail.

Different keys, same nonce is harmless. GCM's security is per key, so a nonce collision between two devices with independent keys has no cryptographic consequence. The published capture alone therefore proves nothing, and the security lead's instinct is correct in principle.

The real vulnerability is the reboot counter. A controller that loses power resumes from the last persisted value, reusing up to 1,024 nonces under its own key after each brownout, at roughly 3% of 8,200 sites per month. That is thousands of same-key reuse events monthly.

The duplicated identifiers then break the reassuring half of the argument. Keys are derived from the device identifier plus a master secret, so 400 units with a duplicated identifier may share a key as well as a nonce. If they do, cross-device collisions become same-key collisions and the harmless case disappears. Verify the provisioning service: if keys derive from the identifier rather than from a per-device random secret, those 400 units belong in the fully broken category and must be rekeyed first.

2. Design the remediation: immediate containment, the nonce construction change, and how you would choose between the options.

Read the worked answer

Contain first. Rekey the units affected by the reset bug and the 400 duplicated units through the management channel, using a per-device random secret rather than anything derived from the identifier. Treat telemetry from those units across the exposure window as readable and forgeable: do not use it for billing, alarms, or access decisions.

Then fix the construction. Options, in the order I would weigh them:

  1. Fresh key per boot. Derive the session key with HKDF from a per-device master key and a 128-bit random value read from the TRNG at boot. A repeated nonce then occurs under a different key, which is the harmless case. Smallest code change, and it sidesteps the flash problem entirely.

  2. Random boot identifier in the nonce: 32-bit random boot value concatenated with a 32-bit message counter. Collision probability across boots is on the order of n^2/2^33, negligible for a device that reboots a few thousand times a year, but only if the boot value comes from a real TRNG. Combine with option 1 when RNG quality is uncertain.

  3. Reserve counter space atomically: on boot write the persisted counter forward by 2^20 using a double-buffered record with a CRC, and refuse to transmit if the record fails validation. This keeps one key, but must handle a brownout during the write itself, which is precisely their failure mode.

  4. Move to AES-GCM-SIV (RFC 8452) if the platform has the cycles. It is nonce-misuse resistant, so a repeat degrades to leaking whether two plaintexts are equal rather than to a full break, at roughly double the AES work per block.

Whichever is chosen: cap messages per key per the SP 800-38D guidance, keep the counter width honest so a message counter cannot wrap silently, add a boot self-test that refuses to transmit when nonce state is unexpected, and make the update mandatory with a fleet compliance report, because a controller that misses it keeps generating reuse.