Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 8 additions & 23 deletions lib_blewbxx/include/ble_ledger.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,30 +28,7 @@ typedef enum {
BLE_LEDGER_PROFILE_U2F = 0x0004,
} ble_ledger_profile_mask_e;

#define BLE_ADDRESS_SET_MSB (0xC0)

/* Exported defines --------------------------------------------------------*/
// Random static address is specified at
// https://wiki.st.com/stm32mcu/wiki/Connectivity:STM32WB-WBA_BLE_Privacy#Random_static_address
// In particular, the two most significant bits need to be set to 1.
#define LEDGER_BLE_get_mac_address(address) \
{ \
unsigned char se_serial[8] = {0}; \
os_serial(se_serial, sizeof(se_serial)); \
unsigned int uid = cx_crc16(se_serial, 4); \
address[0] = uid; \
address[1] = uid >> 8; \
uid = cx_crc16(se_serial + 4, 4); \
address[2] = uid; \
address[3] = uid >> 8; \
for (unsigned int i = 0; i < sizeof(se_serial); i++) { \
se_serial[i] = ~se_serial[i]; \
} \
uid = cx_crc16(se_serial, 8); \
address[4] = uid; \
address[5] = (uid >> 8) | BLE_ADDRESS_SET_MSB; \
}

#define BLE_SLAVE_CONN_INTERVAL_MIN 12 // 15ms
#define BLE_SLAVE_CONN_INTERVAL_MAX 24 // 30ms

Expand All @@ -73,6 +50,14 @@ void BLE_LEDGER_reset_pairings(void);
void BLE_LEDGER_accept_pairing(uint8_t status);
void BLE_LEDGER_name_changed(void);

/**
* @brief Derives the BLE MAC address from the product serial number.
*
* @param address_buf Pointer to a buffer of at least 6 bytes.
* @param buf_len Length of the provided buffer.
*/
void LEDGER_BLE_get_mac_address(uint8_t *address_buf, size_t buf_len);

// Rx
int BLE_LEDGER_rx_seph_evt(uint8_t *seph_buffer,
uint16_t seph_buffer_length,
Expand Down
65 changes: 65 additions & 0 deletions lib_blewbxx/src/ble_addr.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*****************************************************************************
* (c) 2025 Ledger SAS.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*****************************************************************************/

/* Includes ------------------------------------------------------------------*/
#include <string.h>

#include "os.h"
#include "os_helpers.h"
#include "lcx_crc.h"

/* Private enumerations ------------------------------------------------------*/

/* Private defines------------------------------------------------------------*/
// Flag to set the two most significant bits to 11 = random static address
#define BLE_ADDRESS_SET_MSB (0xC0)

/* Private types, structures, unions -----------------------------------------*/

/* Private macros-------------------------------------------------------------*/

/* Private functions prototypes ----------------------------------------------*/

/* Exported functions --------------------------------------------------------*/

void LEDGER_BLE_get_mac_address(uint8_t *address_buf, size_t buf_len)
{
// Ensure we have enough space for a 6-byte MAC address
if (address_buf == NULL || buf_len < 6) {
return;
}

uint8_t se_serial[8] = {0};
uint16_t uid;

os_serial(se_serial, sizeof(se_serial));

uid = cx_crc16(se_serial, 4);
address_buf[0] = (uint8_t) (uid & 0xff);
address_buf[1] = (uint8_t) (uid >> 8);
uid = cx_crc16(se_serial + 4, 4);
address_buf[2] = (uint8_t) (uid & 0xff);
address_buf[3] = (uint8_t) (uid >> 8);

// Invert the serial number bits for the final derivation
for (size_t i = 0; i < sizeof(se_serial); i++) {
se_serial[i] = ~se_serial[i];
}
uid = cx_crc16(se_serial, 8);
address_buf[4] = (uint8_t) (uid & 0xff);
// Set the two most significant bits for Random Static Address
address_buf[5] = (uint8_t) ((uid >> 8) | BLE_ADDRESS_SET_MSB);
}
Loading