This article demonstrates Bluetooth Smart 4.2 security features used in Simplicity Studio Bluetooth Smart SDK v2.0.0 for Blue Gecko products. The attached example is the health thermometer sample application extended with MITM and BLE 4.2 secure connections.
The BLE SDK v2.0.0 supports BLE Secure Connections according to Bluetooth specification 4.2. Including ECDH key exchange and numeric comparison with MITM. The attached example is demonstrating these features.
The BLE SDK v2.0.0 drops the plugin system, so the code examples are much simpler. However you cannot set security features on Application Builders UI as in the older BLE SDK versions. In the new SDK you have to configure every settings via API calls.
Setting up the security
To set up the security features you need to do the following steps:
Setting up attribute permissions in GATT
Enable bonding
Set up security manager
Increase security level
Handle security manager stack events
1. Setting up attribute permissions in GATT
In this example we don’t modify the GATT to be compatible with the Health Thermometer Service define by Bluetooth SIG.
But in general if you want that the read only allowed through an encrypted connection set the authenticated_read property to true in the gatt_db.bgroj file.
We have to use the gecko_cmd_sm_configure(flags, io_capabilities) API to set up security configuration.
flags
usage
bit 0
0: Allow bonding without MITM protection
1: Bonding requires MITM protection
bit 1
0: Allow encryption without bonding
1: Encryption requires bonding
bit 2
0: Allow bonding with legacy pairing
1: Secure connections only
bit 3
0: Bonding request does not need to be confirmed
1: Bonding requests need to be confirmed. Received bonding requests are notified with sm_confirm_bonding events
bit 2 to 7
reserved
The capabilities parameter tells what kind of user input and output methods are available on our device. The different io capabilities leads to different pairing methods.
io_capabilities
pairing method
sm_io_capability_displayonly
The pin printed on the console and you have to enter this pin on the phone/tablet
sm_io_capability_displayyesno
The pin printed on the console and on the phone/tablet. You have to compare the two pins and if they
match accept the bonding
sm_io_capability_keyboarddisplay
The pin printed on the console and on the phone/tablet. You have to compare the two pins and if they
match accept the bonding
sm_io_capability_keyboardonly
The pin printed on phone/tablet and you have to enter this pin on the console
sm_io_capability_noinputnooutput
MITM can’t work with this setting. Pairing and bonding will fail
In the example we call the gecko_cmd_sm_configure(0x0F, sm_io_capability_keyboarddisplay) in the gecko_evt_system_boot_id event, to force the BLE 4.2 secure connection and numeric comparison MITM protection method.
4. Increase the security level
In the connection opened event handler we have to increase call the gecko_cmd_sm_increase_security API function. This will trigger the pairing process.
Please note that the recommended way of starting the bonding process isn’t to use increase security, but to initiate the process (automatically) when a authenticated/encrypted GATT characteristic is read/written. In this example did not set up the up attribute permissions so we force pairing/bonding manually.
5a. Handle the gecko_evt_sm_passkey_display_id event
The gecko_evt_sm_passkey_display_id event indicates a request to display the passkey to the user. In the example it prints the passkey to the console.
case gecko_evt_sm_passkey_display_id:
printf("Passkey display\r\n");
printf("Enter this passkey on the tablet:\r\n%d\r\n",
evt->data.evt_sm_passkey_display.passkey);
break;
5b. Handle the gecko_evt_sm_passkey_request_id event
The gecko_evt_sm_passkey_request_id event indicates a request for the user to enter the passkey displayed on the remote device. In the example we initiate the passkey reading from the console with setting read_pk to true.
case gecko_evt_sm_passkey_request_id:
printf("Passkey request\r\n");
printf("Enter the passkey you see on the tablet\r\n");
read_pk = true;
break;
The actual passkey reading implemented in the passkey_read function. When the reading done the function calls the sm_enter_passkey API command to push the received passkey to the stack.
If the passkey was valid and the bonding completed the stack raise a gecko_msg_sm_bonded_evt_t. If the passkey was invalid or the bonding failed because of any other reason the stack will raise a gecko_evt_sm_bonding_failed_id event.
5c. Handle gecko_evt_sm_confirm_passkey_id event
This event indicates a request to display the passkey to the user then asks to confirm the displayed passkey. The example prints the pin to the console then ask for confirmation on the console with setting the read_y_n flag to true.
case gecko_evt_sm_confirm_passkey_id:
printf("Confirm passkey\r\n");
printf("Are you see the same passkey on the tablet: %d (y/n)?\r\n",
evt->data.evt_sm_confirm_passkey.passkey);
read_y_n = true;
break;
The confirmation reading implemented in the yes_no_read function. The gecko_cmd_sm_passkey_confirm called to accept or reject the displayed passkey depending on the users answer.
Test the MITM protection
1. Open a terminal and connect to the J-Link CDC UART Port with 115200 kbps, 8N1, no flow-control. After the Blue Gecko booted up you should see the following:
2. Open the Bluegecko App on your tablet/phone. Tap on the health thermometer. Then click on the other tab. Then tap on Thermometer Example device.
3. You will be prompted to pairing, the default method is the numeric comparison method. Press ‘y’ on the terminal and press Pair on the tablet/Phone.
Please note that on some older Android or IOS version you may get pairing error.
This is because we are forcing the BLE 4.2 security connections when calling the
gecko_cmd_sm_configure(0x0F, sm_io_capability_displayyesno) API function after boot.
Feel free experiment with different settings. This will lead to different pairing methods.
Once the pairing completed you will see the temperature updating.
4. Once you have paired your device and you want to pair it again, you have to clear the bonding from the phone/tablet. On the Blue Gecko all bonding deleted after boot to force the pairing and bonding process. In a "real" application you should not do this.
I need some enlightenment. I've been successfully compiled and uploaded this project into my BGM111 and BGM113 devkit. However, I keep getting error of: "The pairing procedure cannot be performed as authentication requirements cannot be met due to IO capabilities of one or both devices" when I try to connect Thermometer Example from Bluegecko app in my phone. What did I do wrong in here?
Thank you,
Eddy.
0
Hi,
You can change the security manager configuration from
gecko_cmd_sm_configure(0x0F, sm_io_capability_displayyesno) to
gecko_cmd_sm_configure(0x01, sm_io_capability_displayyesno)
to make it work.
Which OS are you using on the phone?
Cheers,
Balázs
0
Hello Balazs,
Thanks for the response. Changing 0x0F to 0x01 indeed solve the problem. I also tried the "gecko_cmd_sm_configure(0x01, sm_io_capability_displayonly);" which is also solving my problem. Can you explain to me why I can only use MITM protection flag, and not all of them as suggested in the source-code? I'm using Android 6.0.1 on my phone. Additional question, is there any sample code for the Client part? I would like to try to pair my BGM111 with my BGM113 (Client-Server based connection). I can only find Cable-replacement-client as a sample source-code and there is no tutorial on Client with pairing/bonding capability.
Thank you.
Eddy.
0
Hi,
It seems android 6 does not support BLE 4.2 secure connections during pairing. (bit 2 in flags)
I also checked on android 7 and it works there.
However I haven't find any document any document about this on android dev portals.
On IOS it supported since 8.3
There is no client part yet. But thanks for idea
Cheers,
Balázs
0
If configuring the security manager with gecko_cmd_sm_configure(0x0F, sm_io_capability_displayyesno) you set the bonding confirmation bit on.
bit 3
0: Bonding request does not need to be confirmed
1: Bonding requests need to be confirmed. Received bonding requests are notified with sm_confirm_bonding event
bit 3
0: Bonding request does not need to be confirmed
1: Bonding requests need to be confirmed. Received bonding requests are notified with sm_confirm_bonding event
This would require that gecko_evt_sm_confirm_bonding events need to be accepted before the device accepts any bonding requests and the example code does not seem to have handling for that event. Additionally, those events should not be automatically accepted, since the option allows bonding even if bonding already exists, which can present security risk.
Android 6 should support BLE 4.2 secure connections, at least my Nexus 6P did support it already in that version.
0
The example works as the example application is the initator for the bonding and therefore no bonding confirmation events is generated. However, it the remove device would initiate the bonding request the example would fail after 30 s timeout.
0
baadamff wrote:
Please note that the recommended way of starting the bonding process isn’t to use increase security, but to initiate the process (automatically) when a authenticated/encrypted GATT characteristic is read/written. In this example did not set up the up attribute permissions so we force pairing/bonding manually.
How can I pairing/bonding automaticallyon smartphone
By the way I configured like that "gecko_cmd_sm_configure(0x0B,sm_io_capability_displayonly) - 0x0B because I use old version android so if I configure Bit 2 (1) I could not connect. Did I wrong something because the event "gecko_evt_sm_confirm_bonding_id" did not occu
0
How can I use this method to connect automatically to BGM 121 when it is advertising??
I am going to use two devices
1. Android Cell Phone
2. Wireless gateway to store data on a server
What changes do I need to make in this code?
0
Hi,
I am working on BGM113, I followed above procedure to pair with device but I am not able to do that in BGM113. I got error like couldn't pair with thermometer example because PIN or passkey incorrect. Actually device want wait for passkey till it will come and bonded with the device. Device should bond with all android and iPone mobiles what to do for this problem, I want to set passkey minimum 6 and maximum 16 numbers, how to set and what changes do I need to make in code?
[Deprecated] Bluetooth Smart Security 4.2 features in BLE SDK V2.0.0
Note: This KBA has been deprecated. Please refer to the following KBA: Using Bluetooth security features in Silicon Labs Bluetooth SDK
Introduction
This article demonstrates Bluetooth Smart 4.2 security features used in Simplicity Studio Bluetooth Smart SDK v2.0.0 for Blue Gecko products. The attached example is the health thermometer sample application extended with MITM and BLE 4.2 secure connections.
The BLE SDK v2.0.0 supports BLE Secure Connections according to Bluetooth specification 4.2. Including ECDH key exchange and numeric comparison with MITM. The attached example is demonstrating these features.
The BLE SDK v2.0.0 drops the plugin system, so the code examples are much simpler. However you cannot set security features on Application Builders UI as in the older BLE SDK versions. In the new SDK you have to configure every settings via API calls.
Setting up the security
To set up the security features you need to do the following steps:
1. Setting up attribute permissions in GATT
In this example we don’t modify the GATT to be compatible with the Health Thermometer Service define by Bluetooth SIG.
But in general if you want that the read only allowed through an encrypted connection set the authenticated_read property to true in the gatt_db.bgroj file.
For example:
<characteristic uuid="7baaa53f-1569-4d3d-b59b-0af58da719d4" id="my_secret">
<!-- my sensitive data -->
<properties read="true" authenticated_read="true"/>
<value type="hex" length="20" />
</characteristic>
2. Enable bonding
To enable secure connection, first we need to allow bonding. The bonding process stores the keys which are used during secure communication.
We call the gecko_cmd_sm_set_bondable_mode(1) API function after the boot in the gecko_evt_system_boot_id event.
case gecko_evt_system_boot_id:
printf("Boot\r\n");
/* delete all bondings to force the pairing process */
gecko_cmd_sm_delete_bondings();
printf("All bonding deleted\r\n");
gecko_cmd_sm_configure(0x0F, sm_io_capability_displayyesno); /* Numeric comparison */
/* enable bondable to accommodate certain mobile OS */
gecko_cmd_sm_set_bondable_mode(1);
/* Set advertising parameters. 100ms advertisement interval. All channels used.
* The first two parameters are minimum and maximum advertising interval, both in
* units of (milliseconds * 1.6). The third parameter '7' sets advertising on all channels. */
gecko_cmd_le_gap_set_adv_parameters(160,160,7);
/* Start general advertising and enable connections. */
gecko_cmd_le_gap_set_mode(le_gap_general_discoverable, le_gap_undirected_connectable);
break;
3. Set up security manager
We have to use the gecko_cmd_sm_configure(flags, io_capabilities) API to set up security configuration.
0: Allow bonding without MITM protection
1: Bonding requires MITM protection
0: Allow encryption without bonding
1: Encryption requires bonding
0: Allow bonding with legacy pairing
1: Secure connections only
0: Bonding request does not need to be confirmed
1: Bonding requests need to be confirmed. Received bonding requests are notified with sm_confirm_bonding events
reserved
The capabilities parameter tells what kind of user input and output methods are available on our device. The different io capabilities leads to different pairing methods.
The pin printed on the console and on the phone/tablet. You have to compare the two pins and if they
match accept the bonding
The pin printed on the console and on the phone/tablet. You have to compare the two pins and if they
match accept the bonding
In the example we call the gecko_cmd_sm_configure(0x0F, sm_io_capability_keyboarddisplay) in the gecko_evt_system_boot_id event, to force the BLE 4.2 secure connection and numeric comparison MITM protection method.
4. Increase the security level
In the connection opened event handler we have to increase call the gecko_cmd_sm_increase_security API function. This will trigger the pairing process.
case gecko_evt_le_connection_opened_id:
printf("Connected\r\n");
/* Store the connection ID */
activeConnectionId = evt->data.evt_le_connection_opened.connection;
/* The HTM service typically indicates and indications cannot be given an encrypted property so
* force encryption immediately after connecting */
gecko_cmd_sm_increase_security(activeConnectionId);
break;
Please note that the recommended way of starting the bonding process isn’t to use increase security, but to initiate the process (automatically) when a authenticated/encrypted GATT characteristic is read/written. In this example did not set up the up attribute permissions so we force pairing/bonding manually.
5a. Handle the gecko_evt_sm_passkey_display_id event
The gecko_evt_sm_passkey_display_id event indicates a request to display the passkey to the user. In the example it prints the passkey to the console.
case gecko_evt_sm_passkey_display_id:
printf("Passkey display\r\n");
printf("Enter this passkey on the tablet:\r\n%d\r\n",
evt->data.evt_sm_passkey_display.passkey);
break;
5b. Handle the gecko_evt_sm_passkey_request_id event
The gecko_evt_sm_passkey_request_id event indicates a request for the user to enter the passkey displayed on the remote device. In the example we initiate the passkey reading from the console with setting read_pk to true.
case gecko_evt_sm_passkey_request_id:
printf("Passkey request\r\n");
printf("Enter the passkey you see on the tablet\r\n");
read_pk = true;
break;
The actual passkey reading implemented in the passkey_read function. When the reading done the function calls the sm_enter_passkey API command to push the received passkey to the stack.
If the passkey was valid and the bonding completed the stack raise a gecko_msg_sm_bonded_evt_t. If the passkey was invalid or the bonding failed because of any other reason the stack will raise a gecko_evt_sm_bonding_failed_id event.
5c. Handle gecko_evt_sm_confirm_passkey_id event
This event indicates a request to display the passkey to the user then asks to confirm the displayed passkey. The example prints the pin to the console then ask for confirmation on the console with setting the read_y_n flag to true.
case gecko_evt_sm_confirm_passkey_id:
printf("Confirm passkey\r\n");
printf("Are you see the same passkey on the tablet: %d (y/n)?\r\n",
evt->data.evt_sm_confirm_passkey.passkey);
read_y_n = true;
break;
The confirmation reading implemented in the yes_no_read function. The gecko_cmd_sm_passkey_confirm called to accept or reject the displayed passkey depending on the users answer.
Test the MITM protection
1. Open a terminal and connect to the J-Link CDC UART Port with 115200 kbps, 8N1, no flow-control. After the Blue Gecko booted up you should see the following:
2. Open the Bluegecko App on your tablet/phone. Tap on the health thermometer. Then click on the other tab. Then tap on Thermometer Example device.
3. You will be prompted to pairing, the default method is the numeric comparison method. Press ‘y’ on the terminal and press Pair on the tablet/Phone.
Please note that on some older Android or IOS version you may get pairing error.
This is because we are forcing the BLE 4.2 security connections when calling the
gecko_cmd_sm_configure(0x0F, sm_io_capability_displayyesno) API function after boot.
Feel free experiment with different settings. This will lead to different pairing methods.
Once the pairing completed you will see the temperature updating.
4. Once you have paired your device and you want to pair it again, you have to clear the bonding from the phone/tablet. On the Blue Gecko all bonding deleted after boot to force the pairing and bonding process. In a "real" application you should not do this.
Hello,
I need some enlightenment. I've been successfully compiled and uploaded this project into my BGM111 and BGM113 devkit. However, I keep getting error of: "The pairing procedure cannot be performed as authentication requirements cannot be met due to IO capabilities of one or both devices" when I try to connect Thermometer Example from Bluegecko app in my phone. What did I do wrong in here?
Thank you,
Eddy.
Hello Balazs,
Thanks for the response. Changing 0x0F to 0x01 indeed solve the problem. I also tried the "gecko_cmd_sm_configure(0x01, sm_io_capability_displayonly);" which is also solving my problem. Can you explain to me why I can only use MITM protection flag, and not all of them as suggested in the source-code? I'm using Android 6.0.1 on my phone.
Additional question, is there any sample code for the Client part? I would like to try to pair my BGM111 with my BGM113 (Client-Server based connection). I can only find Cable-replacement-client as a sample source-code and there is no tutorial on Client with pairing/bonding capability.
Thank you.
Eddy.
If configuring the security manager with gecko_cmd_sm_configure(0x0F, sm_io_capability_displayyesno) you set the bonding confirmation bit on.
0: Bonding request does not need to be confirmed
1: Bonding requests need to be confirmed. Received bonding requests are notified with sm_confirm_bonding event
0: Bonding request does not need to be confirmed
1: Bonding requests need to be confirmed. Received bonding requests are notified with sm_confirm_bonding event
This would require that gecko_evt_sm_confirm_bonding events need to be accepted before the device accepts any bonding requests and the example code does not seem to have handling for that event. Additionally, those events should not be automatically accepted, since the option allows bonding even if bonding already exists, which can present security risk.
Android 6 should support BLE 4.2 secure connections, at least my Nexus 6P did support it already in that version.
The example works as the example application is the initator for the bonding and therefore no bonding confirmation events is generated. However, it the remove device would initiate the bonding request the example would fail after 30 s timeout.
baadamff wrote:
Please note that the recommended way of starting the bonding process isn’t to use increase security, but to initiate the process (automatically) when a authenticated/encrypted GATT characteristic is read/written. In this example did not set up the up attribute permissions so we force pairing/bonding manually.
How can I pairing/bonding automatically on smartphone
By the way I configured like that "gecko_cmd_sm_configure(0x0B,sm_io_capability_displayonly) - 0x0B because I use old version android so if I configure Bit 2 (1) I could not connect. Did I wrong something because the event "gecko_evt_sm_confirm_bonding_id" did not occu
How can I use this method to connect automatically to BGM 121 when it is advertising??
I am going to use two devices
1. Android Cell Phone
2. Wireless gateway to store data on a server
What changes do I need to make in this code?
Hi,
I am working on BGM113, I followed above procedure to pair with device but I am not able to do that in BGM113. I got error like couldn't pair with thermometer example because PIN or passkey incorrect. Actually device want wait for passkey till it will come and bonded with the device. Device should bond with all android and iPone mobiles what to do for this problem, I want to set passkey minimum 6 and maximum 16 numbers, how to set and what changes do I need to make in code?
Thanks