-
Notifications
You must be signed in to change notification settings - Fork 2.1k
ieee802154_security: Nonce is reused after reboot #16844
Description
Description
The frame counter used with ieee802154_security is initialized with 0 at startup. While it is protected against overflow, it is not protected against being reset, and that reset happens whenever the device restarts.
As the key is flashed into the device in ieee802154_security's normal operation, and the sender LL address is constant per device, the same nonce (varying only through the resetting frame counter) is used in the AES encryption multiple times. Reuse of the same (nonce, key) breaks confidentiality guarantees.
(AES-CCM is used here, so AIU it's not as bad as if GCM were used, when there'd be key leakage).
Steps to reproduce the issue
(All done on microbit-v2; I have high confidence in this working on any 802.15.4 encryption capable device).
- Sniff for packages, eg. by building the default module.
- Build the gcoap example with
USEMODULE+=ieee802154_security - Send out a GET request to the sniffer module, path
/hello_world/coap - Repeat the request a few times (to cancel any jitter in the number of messages sent during startup)
- Reboot the device, eg. by power cycling it
- Send out GET requests to the same address, path
/.well-known/core
Expected results
- Requests after the reboot use different sequence numbers.
Actual results
- Requests after the reboot start from the same zero sequence number again.
- Requests have byte-wise identical requests in regions of equal content, eg. (asterisks mine)
~~ SNIP 0 - size: 45 byte, type: NETTYPE_UNDEF (0)
00000000 06 05 00 00 00 9B 51 C4 68 F6 D4 E9 4D 96 *89 5E*
00000010 1F F2 60 BC *95* 33 80 F2 *20* FE 90 EE 78 4A D5 74
00000020 *39 91 74* F6 84 6E DE C4 CC 3C 05 7A 60
~~ SNIP 0 - size: 45 byte, type: NETTYPE_UNDEF (0)
00000000 06 05 00 00 00 9B 51 C4 68 F6 D4 E9 7A AB *89 5E*
00000010 0A D1 65 84 *95* 75 92 FB *20* FD E2 F2 79 57 CE 7E
00000020 *39 91 74* E5 91 6F 6B A7 FE CE 0F A9 14
(Note the 20 in the second row where the shared "l" of "hello" and "well" is, as well as the "\x04co" of the "core" / "coap" option; variation is in MIDs (first row bytes 12-13), token (second row, first 4 bytes) and the diverting texts).
Versions and cross-references
All since introduction in 2021.01 until current HEAD.
Since #16841, the module in question has been marked as experimental.
Disclosing this has been discussed in the closed security list, and was deemed responsible given the overall circumstances.
CVE-2021-41061 has been assigned to this issue.
Road forward
This is not trivial to fix, as we don't have any committed persistence inside generic devices, and even with 6TiSCH minimal security the problem is just shifted (for section 4.6 requires monotony of ASNs on the device which is equivalent to this problem, although it'd shift the attack difficulty to an active replay of old beacons). Likewise, most advanced modes need persistence, until (with ace-ake-authz) asymmetric negotiation comes into play.
Off my head I don't know any standard solutions that can do with neither asymmetric cryptography nor local persistence; some randomness based scheme could possibly be deployed but it'd be very ad-hoc, custom and eventually not easier than the existing solutions.
I think that the discussion in #16730 can serve as a starting point.