Skip to content

Commit 8c8d1b5

Browse files
kaabiacfriedt
authored andcommitted
Bluetooth: hci_nxp: Improve MAC address uniqueness using CRC-32 hash
The previous method of deriving the local MAC address from the MCU's Unique ID (UID) by slicing the last 3 bytes had two issues: 1. **Low Entropy:** Risk of address collision because only a small portion of the UID was used, and this portion may not vary much. 2. **Offset Error:** An incorrect offset calculation could copy non-intended bytes. This commit resolves both issues by replacing the slice operation with a **CRC-32 hash** over the **entire 16-byte UID**. The lower 3 bytes (24 bits) of the resulting CRC-32 are used as the local part of the MAC address, maximizing randomization and ensuring a high probability of uniqueness across all devices. Signed-off-by: Badr Bacem KAABIA <badrbacemkaabia@gmail.com>
1 parent 50e29d0 commit 8c8d1b5

File tree

2 files changed

+17
-5
lines changed

2 files changed

+17
-5
lines changed

drivers/bluetooth/hci/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ config BT_NXP
255255
default y
256256
depends on DT_HAS_NXP_HCI_BLE_ENABLED
257257
select BT_HCI_SETUP
258+
select CRC if BT_HCI_SET_PUBLIC_ADDR
258259
help
259260
NXP HCI bluetooth interface
260261

drivers/bluetooth/hci/hci_nxp.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <zephyr/drivers/bluetooth.h>
1313
#include <zephyr/logging/log.h>
1414
#include <zephyr/sys/byteorder.h>
15+
#include <zephyr/sys/crc.h>
1516
#include <zephyr/device.h>
1617
#include <zephyr/drivers/flash.h>
1718
#include <zephyr/bluetooth/hci_types.h>
@@ -50,6 +51,7 @@ LOG_MODULE_REGISTER(bt_driver);
5051
#define HCI_CMD_BT_HOST_SLEEP_CONFIG_OCF 0x59U
5152
#define HCI_CMD_BT_HOST_SLEEP_CONFIG_PARAM_LENGTH 2U
5253
#define HCI_CMD_BT_HOST_SET_MAC_ADDR_PARAM_LENGTH 8U
54+
#define HCI_BT_MAC_ADDR_CRC_SEED 0xFFFFFFFFU
5355
#define HCI_SET_MAC_ADDR_CMD 0x0022U
5456
#define BT_USER_BD 254
5557
#define BD_ADDR_OUI 0x37U, 0x60U, 0x00U
@@ -178,6 +180,7 @@ static int bt_nxp_set_mac_address(const bt_addr_t *public_addr)
178180
uint8_t addrOUI[BD_ADDR_OUI_PART_SIZE] = {BD_ADDR_OUI};
179181
uint8_t uid[16] = {0};
180182
uint8_t uuidLen;
183+
uint32_t unique_val_crc = 0;
181184
uint8_t params[HCI_CMD_BT_HOST_SET_MAC_ADDR_PARAM_LENGTH] = {
182185
BT_USER_BD,
183186
0x06U
@@ -188,12 +191,20 @@ static int bt_nxp_set_mac_address(const bt_addr_t *public_addr)
188191
*/
189192
if (bt_addr_eq(public_addr, BT_ADDR_ANY) || bt_addr_eq(public_addr, BT_ADDR_NONE)) {
190193
PLATFORM_GetMCUUid(uid, &uuidLen);
191-
/* Set 3 LSB of MAC address from UUID */
192-
if (uuidLen > BD_ADDR_UUID_PART_SIZE) {
193-
memcpy((void *)bleDeviceAddress,
194-
(void *)(uid + uuidLen - (BD_ADDR_UUID_PART_SIZE + 1)),
195-
BD_ADDR_UUID_PART_SIZE);
194+
195+
if (uuidLen > 0) {
196+
/* Calculate a 32-bit IEEE CRC over the entire unique ID (uid)
197+
* Initial CRC value is 0xFFFFFFFFU for maximum randomization
198+
*/
199+
unique_val_crc = crc32_ieee_update(HCI_BT_MAC_ADDR_CRC_SEED, uid, uuidLen);
200+
/* Copy the lower 3 bytes (24 bits) of the CRC result */
201+
memcpy((void *)bleDeviceAddress, (const void *)&unique_val_crc,
202+
BD_ADDR_UUID_PART_SIZE);
203+
} else {
204+
LOG_ERR("UUID is empty, cannot generate address.");
205+
return -EFAULT;
196206
}
207+
197208
/* Set 3 MSB of MAC address from OUI */
198209
memcpy((void *)(bleDeviceAddress + BD_ADDR_UUID_PART_SIZE), (void *)addrOUI,
199210
BD_ADDR_OUI_PART_SIZE);

0 commit comments

Comments
 (0)