This is an automated email from the ASF dual-hosted git repository. sjanc pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/mynewt-nimble.git
commit 8493d86ddbe8046660b1a7fc1b6da9db1bb86af5 Author: Szymon Janc <[email protected]> AuthorDate: Wed Oct 7 18:06:06 2026 +0200 nimble/ll: Use 64-bit packet counters for connection encryption Packet counters used for CCM nonce were intentionally stored as 32-bit values (to save RAM, code space and calculation time) while the specification defines a 39-bit counter. This was documented to result in MIC failure and disconnection after 2^32 packets. That is only true if the peer implements the full 39-bit counter, and even then the first packet(s) sent after wrap reuse a nonce with the same session key. If the peer truncates the counter in the same way (e.g. both sides are NimBLE) both counters wrap consistently and the connection continues with nonces reused for the rest of the connection. Store counters as 64-bit values, PHY API already accepts 64-bit counter. This costs 8 bytes of RAM per connection. Previous behavior can be selected by enabling BLE_LL_ENC_SHORT_PKT_CNTR. Assisted-by: Claude:claude-opus-5-5 --- nimble/controller/include/controller/ble_ll_conn.h | 14 +++++++++----- nimble/controller/syscfg.yml | 10 ++++++++++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index 733bcf4e7..02fbc3951 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -78,19 +78,23 @@ enum conn_enc_state { * Note that the LTK is the key, the SDK is the plain text, and the * session key is the cipher text portion of the encryption block. * - * NOTE: we have intentionally violated the specification by making the - * transmit and receive packet counters 32-bits as opposed to 39 (as per the - * specification). We do this to save code space, ram and calculation time. The - * only drawback is that any encrypted connection that sends more than 2^32 - * packets will suffer a MIC failure and thus be disconnected. + * Transmit and receive packet counters are stored as 64-bit values so that + * the full 39-bit packet counter (as per specification) is used in CCM + * nonce. If BLE_LL_ENC_SHORT_PKT_CNTR is enabled, counters are 32-bit which + * violates the specification, see syscfg description for consequences. */ struct ble_ll_conn_enc_data { uint8_t enc_state; uint8_t tx_encrypted; uint16_t enc_div; +#if MYNEWT_VAL(BLE_LL_ENC_SHORT_PKT_CNTR) uint32_t tx_pkt_cntr; uint32_t rx_pkt_cntr; +#else + uint64_t tx_pkt_cntr; + uint64_t rx_pkt_cntr; +#endif uint64_t host_rand_num; uint8_t iv[8]; struct ble_encryption_block enc_block; diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index d339fcf20..2e4cf1025 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -244,6 +244,16 @@ syscfg.defs: This option saves both both code and RAM. value: 'MYNEWT_VAL_BLE_LL_ROLE_CENTRAL || MYNEWT_VAL_BLE_LL_ROLE_PERIPHERAL || MYNEWT_VAL_BLE_LL_ISO' + BLE_LL_ENC_SHORT_PKT_CNTR: + description: > + Use shortened 32-bit packet counter for connection encryption + instead of 39-bit counter defined by specification. This saves + some RAM and code, but violates specification: packet counter + wraps after 2^32 packets resulting in either MIC failure (if peer + uses 39-bit counter) or CCM nonce reuse (if peer also truncates + counter) for the remaining part of the connection. + value: 0 + BLE_LL_CFG_FEAT_CONN_PARAM_REQ: description: > This option enables/disables the connection parameter request
