STM32WB-WBA BLE security - Out Of Band pairing


1 Bluetooth® Low Energy Security - Out Of Band Pairing method

This article is dedicated to Out Of Band (OOB) pairing, for global information regarding BLE security features, refer to BLE security wiki page.

This page provides an overview of the specific key generation method:

  • Out of Band (OOB)

The Out of Band (OOB) [1] mechanism is used to both discover devices as well as to exchange or transfer cryptographic numbers used in the pairing process. It needs to be effective from a security point of view and should be resistant to Man In The Middle (MITM) attacks.

For LE Secure Connection Pairing, if the Out Of Band pairing method is used, the public keys, nonce and confirmation values are all exchanged via a different technology than Bluetooth® Low Energy such as NFC or UART.

For LE Legacy Pairing, if the Out Of Band pairing method is used, the TK is exchanged using a different wireless technology such as NFC or UART. The main advantage to this method is that a very large TK can be used, up to 128 bits.

OOB via NFC example
Connectivity OOB via NFC example.png


Two commands are specific to the OOB method, to get and set the OOB data:

  • ACI_GAP_SET_OOB_DATA allows generating OOB data or setting OOB data from a peer device received via OOB communication. To generate the OOB data, all the parameters need to be set to zero.
ACI_GAP_SET_OOB_DATA command - Input parameters
Connectivity aci gap set oob data input param.png


ACI_GAP_SET_OOB_DATA command - Output parameters
Connectivity aci gap set oob data output param.png


  • ACI_GAP_GET_OOB_DATA allows getting (i.e. to extract from the Stack) the OOB data generated by the Stack itself.
ACI_GAP_GET_OOB_DATA command - Input parameters
Connectivity aci gap get oob data input param.png


ACI_GAP_GET_OOB_DATA command - Output parameters
Connectivity aci gap get oob data output param.png


During the phase 1 of the pairing procedure, e.g Pairing Feature Exchange, the devices exchange their capabilities using pairing request/response. The frame of these messages contains 1 field of 1 byte named "OOB Data Flag" which indicates if OOB Authentication data are present or not.
For the definition of “OOB Data Flag”, refer to the table below:

OOB Data Flag Description
Connectivity OOB Data Flag.png


2 OOB in LE Secure Connection Pairing

In LE Secure Connections pairing, if one or both devices have out of band authentication data, then the Authentication Requirements Flags (MITM) are ignored when selecting the pairing method and the Out of Band pairing method is used. Otherwise, the IO capabilities of the device are used to determine the pairing method, refer to pairing phase 2 : Key generation.

Rules for using Out-of-Band and MITM flags for LE Secure Connections pairing
Connectivity SC rules oob flag and mitm.png


The following description considers the case where a smartphone connects an STM32WB-WBA and the STM32WB-WBA provides OOB data and sends it through NFC.

2.1 Commands sequence for pairing initialization, public key generation, generation and recovery of OOB data on WB-WBA

See below the commands sequence for pairing initialization, public key generation, generation and recovery of OOB data on WB-WBA:

/* Initialize IO capability */
aci_gap_set_io_capability(0x00-display only);

/* Initialize authentication */
aci_gap_set_authentication_requirement(0x01 - bonding, 0x00 - no MITM, 0x02 - SC Support, 0x00 - keypress not supported, 0x08 -  encryption key size min, 0x10 - encryption key size max, 0x00 - fixed pin, 0x00000000 - fixed pin value, 0x00 - public address);

/* Sequence to force the regeneration of the EDCH_public key on OOB source device */
uint8_t ALL_EVENTS[8]={0xDF,0x18,0x03,0x00,0x00,0x00,0x00,0x00};
hci_le_set_event_mask(ALL_EVENTS);

/* generation of a new P-256 public key */
Hci_le_read_local_p256_public_key();

/* Reception of META EVENT */
HCI_LE_READ_LOCAL_P256_PUBLIC_KEY_COMPLETE_EVENT

/* OOB data generation */
aci_gap_set_oob_data(0x00 - device type, 0x00 - address type, 0x00 - address, 0x00 - oob data type, 0x00 - oob data len, 0x00 - oob data);

/* OOB data recovery */
aci_gap_get_oob_data(0x01-random, address type, address, oob data len, oob data);
aci_gap_get_oob_data(0x02-confirm, address type, address, oob data len, oob data);

The following section details each part of the previous sequence.

2.2 Pairing initialization commands on peripheral side

Prerequisite before pairing request: initialization of pairing conditions with 2 commands:

/* Set the IO capability of the device */ 
aci_gap_set_io_capability(0x00-display only);
/* Set the authentication requirements for the device */ 
aci_gap_set_authentication_requirement(0x01 - bonding, 0x00 - no MITM, 0x02 - SC Support, 0x00 - keypress not supported, 0x08 -  encryption key size min, 0x10 - encryption key size max, 0x00 - fixed pin, 0x00000000 - fixed pin value, 0x00 - public address);

2.3 Public Key generation

The peripheral is the device where the OOB data is extracted. The central is the device where OOB data is set.

Following sequence is performed before the connection:

On peripheral side:
Sequence to force the regeneration of the EDCH_public key on source device
First action: set LE Event Mask to require which LE events are generated by the HCI for the host.

hci_le_set_event_mask command is used to control which LE events are generated by the HCI for the Host.
Default value of this event mask is 0x000000000003185F. Refer to hci_le_set_event_mask command description.
To receive LE Read Local P-256 Public Key Complete Event, bitmask 0x80 is needed.
The new mask value is 0x00000000000318DF.

uint8_t ALL_EVENTS[8]={0xDF,0x18,0x03,0x00,0x00,0x00,0x00,0x00};
hci_le_set_event_mask(ALL_EVENTS);

Second action: generation of a new P-256 public key (first action necessary to receive the event)

Hci_le_read_local_p256_public_key();

HCI_LE_META_EVENT event received :

HCI_LE_READ_LOCAL_P256_PUBLIC_KEY_COMPLETE_EVENT

contains Local_P256_Public_Key field.

2.4 OOB data generation

Command used to generate OOB data on device data source:

aci_gap_set_oob_data(0x00 - device type, 0x00 - address type, 0x00 - address, 0x00 - oob data type, 0x00 - oob data len, 0x00 - oob data);

Previous command is sent with all data equal to zero.

2.5 OOB data recovery

For SC secure pairing:
Two commands are used to recover the generated OOB data on the device data source.
First command:

aci_gap_get_oob_data(oob_data_type=0x01-random);

HCI_COMMAND_COMPLETE_EVENT event received, contains the following fields:
address_type
address
OOB_data_type 0x01 (Random SC)
OOB_data_length
OOB_data : RANDOM_DATA – local pairing data intended for the remote device, to be sent via NFC

Second command:

aci_gap_get_oob_data(oob_data_type=0x02-confirm);

HCI_COMMAND_COMPLETE_EVENT event received, contains the following fields:
address_type
address
OOB_data_type 0x02 (Confirm SC)
OOB_data_length
OOB_data : CONFIRM_DATA – local pairing data intended for the remote device, to be sent via NFC

RANDOM_DATA and CONFIRM_DATA generated by the BLE stack are written to ST25 (NFC shield).

2.6 OOB data written into NFC shield

Below is a code example of OOB data written into the NFC shield:

Ndef_Bluetooth_OOB_t NdefBle = { 


                                    .LeOptionalMask = (NDEF_BLUETOOTH_OPTION(BLUETOOTH_EIR_LE_SECURE_CONNECTIONS_CONFIRMATION_VALUE) |
                                                       NDEF_BLUETOOTH_OPTION(BLUETOOTH_EIR_LE_SECURE_CONNECTIONS_RANDOM_VALUE)),

                                    .LocalName = "ST25OOB",
                                    .OptionalMask = NDEF_BLUETOOTH_OPTION(BLUETOOTH_EIR_COMPLETE_LOCAL_NAME),

                                    .Type = NDEF_BLUETOOTH_BLE,
                                    .Role = NDEF_BLE_ROLE_PERIPH_ONLY,
                                    .DeviceAddressType = NDEF_BLE_PUBLIC_ADDRESS_TYPE

                                  };


  for(int i = 5; i >= 0; i --)
    NdefBle.DeviceAddress[i] = bd_addr[5-i];

   status = aci_gap_get_oob_data(1, &at,add,&len, rand);
   status = aci_gap_get_oob_data(2, &at,add,&len, hash);

  for(int i = 5; i >= 0; i --)
    NdefBle.DeviceAddress[i] = add[5-i];
  for(int i = 15; i >= 0; i --)
  {
    NdefBle.SimplePairingRandomizer[i] = rand[15-i];
    NdefBle.SimplePairingHash[i] = hash[15-i];
  }
   NfcTag_SelectProtocol(NFCTAG_TYPE5);

   NFC04A1_NFCTAG_Init(0);
   NDEF_ClearNDEF();
   NDEF_AppendBluetoothOOB(&NdefBle, NULL);

2.7 Transfer of OOB data through NFC

  • RANDOM_DATA = rb
  • CONFIRM_DATA = Cb
Random data and Confirm Data transferred through NFC
Connectivity phoneNFC.png


2.8 Sequence diagram of OOB data transfer between two STM32WB/WBA in LE Secure Connection - central generates OOB data

OOB pairing sequence
Connectivity OOB SC.png


3 OOB in LE Legacy Pairing

In LE legacy pairing, if both devices have Out of Band authentication data, then the Authentication Requirements Flags are ignored when selecting the pairing method and the Out of Band pairing method is used. Otherwise, the IO capabilities of the device are used to determine the pairing method, refer to pairing phase 2 : Key generation. In case of LE legacy pairing, only one device generates the TK and both are using the same TK.

Rules for using Out-of-Band and MITM flags for LE legacy pairing
Connectivity LE Legacy Pairing oob flag mitm.png


The following description considers the case where two WBs are connected and exchange OOB data via UART.

3.1 Commands sequence for pairing initialization, generation and recovery of OOB data on WB/WBA

See below the commands sequence for pairing initialization, public key generation, generation and recovery of OOB data on WB-WBA:

/* Initialize IO capability */
aci_gap_set_io_capability(0x00-display only);

/* Initialize authentication */
aci_gap_set_authentication_requirement(0x01 - bonding, 0x00 - no MITM, 0x00 - Legacy pairing Support, 0x00 - keypress not supported, 0x08 -  encryption key size min, 0x10 - encryption key size max, 0x00 - fixed pin, 0x00000000 - fixed pin value, 0x00 - public address);

/* OOB data generation */
aci_gap_set_oob_data(0x00 - device type, 0x00 - address type, 0x00 - address, 0x00 - oob data type, 0x00 - oob data len, 0x00 - oob data);

/* OOB data recovery */
aci_gap_get_oob_data(0x00-TK, address type, address, oob data len, oob data);

3.2 Pairing initialization commands

Prerequisite before pairing request: initialization of pairing conditions with 2 commands:

/* Set the IO capability of the device */ 
aci_gap_set_io_capability(0x00-display only)
/* Set the authentication requirements for the device */ 
aci_gap_set_authentication_requirement(0x01 - bonding, 0x00 - no MITM, 0x00 - Legacy pairing Support, 0x00 - keypress not supported, 0x08 -  encryption key size min, 0x10 - encryption key size max, 0x00 - fixed pin, 0x00000000 - fixed pin value, 0x00 - public address);

3.3 OOB data generation

In LE legacy pairing, only one device generates the TK, here assume it's the central and both are using the same TK. Command used to generate OOB data on device data source:

aci_gap_set_oob_data(0x00 - device type, 0x00 - address type, 0x00 - address, 0x00 - oob data type, 0x00 - oob data len, 0x00 - oob data);

The previous command is sent with all data equal to zero.

3.4 OOB data recovery

To recover the generated OOB data on device data source:

aci_gap_get_oob_data(oob_data_type=0x00-TK)

HCI_COMMAND_COMPLETE_EVENT event received, contains the following fields:
address_type
address
OOB_data_type 0x00 (TK)
OOB_data_length
OOB_data : TK - local pairing data intended for the remote device, to be sent via UART

3.5 Set OOB data on central side

Once OOB data are generated on the central side, it's necessary to set OOB data on the central side with peer device information (address and address type) exchanged previously through UART in this case. Use the following command to set the OOB data:

aci_gap_set_oob_data(0x01 - remote device, 
                     remote address type, 
                     remote address,
                     0x00 - oob data type = TK, 
                     TK size, 
                     TK);

3.6 Set OOB data on peripheral side

Once OOB data are generated on the central side, it's necessary to set OOB data on the peripheral side with peer device information (address, address type, TK, TK size) exchanged previously through UART in this case. Use the following command to set the OOB data, where local means peripheral and remote means central:

aci_gap_set_oob_data(0x00 - local device, 
                     local address type, 
                     local address,
                     0x00 - oob data type = TK, 
                     TK size, 
                     TK);
aci_gap_set_oob_data(0x01 - remote device, 
                     remote address type, 
                     remote address,
                     0x00 - oob data type = TK, 
                     TK size, 
                     TK);

3.7 Example of OOB data transfer between two STM32WB/WBA in LE Legacy Pairing - central generates OOB data

OOB pairing sequence
Connectivity OOB Legacy.png


4 ST example : Out Of Band pairing

4.1 STM32WB55 + X-NUCLEO-NFC04A1 and Android smartphone

The ST25DV-I2C secure connection out-of-band pairing demonstration[2] runs on the STM32WB55 board plus a X-NUCLEO-NFC04A1 shield, featuring a ST25DV-I2C tag connected to an STM32WB55 device through the I2C bus. A user manual[3] is also available describing the demonstration and a video[4] presents the demonstration.

4.2 LE Secure connection OOB pairing using UART between two STM32WB55

This example, based on P2P Client and P2P Server application, demonstrates the exchange of OOB data between two STM32WB55s using UART and how to manage LE secure connection OOB pairing. Examples are available under STM32 Hotspot GitHub: Client application [5] and Server application [6].

4.3 LE Legacy OOB pairing using UART between two STM32WB55

This example, based on P2P Client and P2P Server application, demonstrates the exchange of OOB data between two STM32WB55s using UART and how to manage LE Legacy OOB pairing. Examples are available under STM32 Hotspot GitHub: Client application [7] and Server application [8].

5 References