6. Securing your application using Legacy Pairing
Let’s take a look now on how we can enable the security features of your DA1458x or DA1453x device using Renesas’s SDK6. The first use case that we will demonstrate is the setup of a peripheral that uses the Passkey Pairing and Just Works procedure using LE Legacy Pairing.
6.1. First steps and project structure
Go to the SDK6 folder that you have downloaded on your hard drive and navigate to the projects/target_apps/ble_examples/ble_app_security/Keil_5
folder. In there open the ble_app_security.uvprojx
Keil project. This software example project already has a custom server implemented which uses the BLE security features, and we will use it as our basis for this tutorial.
You can see the project file structure on the left edge of your IDE.
You can see that there are two types of folders included in the project, some that their name begins with sdk_
and some that begin with user_
. User code is developed under the folders beginning with user_
and
all of our modifications will be on these files, but we will also take a look at some SDK6 functions when this will benefit our understanding.
- These folders are:
user_config/
, contains most configuration files:da1458x_config_advanced.h
holds advanced configuration settings.da1458x_config_basic.h
holds basic configuration settings.user_callback_config.h
appoints the callback functions that handle various events or operations.user_profiles_config.h
defines which BLE profiles (Bluetooth SIG adopted or custom ones) will be included in the user’s application.Each macro denotes the respective BLE profile that will be included.user_modules_config.h
defines which application modules are included or excluded from the user’s application. Define each macro to 0 if it’s included, or to 1 if it’s excluded. An important point to note is that these settings have no effect if the respective module is a BLE profile that it is not used in the user’s application.user_config.h
holds advertising parameters, connection parameters, compile-time security parameters, etc.user_periph_setup.h
defines hardware related settings relative to the used Development Kit.
user_platform/
, contains the implementation of target related functions and especially configuration and initialization of peripheral devices in fileuser_periph_setup.c
.user_custom_profile/
, contains our BLE server’s database declaration and configuration parameters.user_app/
, holds the user’s implementation of handling BLE events and any additional application code.
In the following figure you see the message flow diagram between the Server Application entity, the Custom Profile Service and the Remote Client.
When our device boots, the Custom Profile app initiates the service database creation of the Custom Profile. The creation of the database is confirmed and awaits for a client to connect. When the Remote Client connects, the service gets enabled and the Remote Client can now initiate requests to our server. In the above use case, the Remote Client requests to write to characteristic 1. This is indicated by the Custom Profile to the user application, which updates the value of characteristic 1. Finally our remote client disconnects, and this disables the Custom Profile Service, which in turn indicates that to the user application.
6.2. Modifying the firmware
Open the file
..._config_advanced.h
in here we are choosing DA14535 as build target (da14535_config_advanced.h
). Change the default Bluetooth Device Address. This address has to be unique in a BLE piconet.#define CFG_NVDS_TAG_BD_ADDRESS {0x05, 0x00, 0x70, 0xCA, 0xEA, 0x80}
Navigate to
user_modules_config.h
, then check and defineDLG_CUST1
andDLG_SEC
module in your application code.0
means included.#define EXCLUDE_DLG_CUSTS1 (0) // This module will be included #define EXCLUDE_DLG_SEC (0)
Define the Custom Profile associated code in your application, by defining the macro
CFG_PRF_CUST1
inuser_profiles_config.h
.#define CFG_PRF_CUST1
Open the file
user_config/user_config.h
and make the next changes:Set the sleep mode.
static const sleep_state_t app_default_sleep_mode = ARCH_SLEEP_OFF;
Set the advertising data.
#define USER_ADVERTISE_DATA ("\x03"\ ADV_TYPE_COMPLETE_LIST_16BIT_SERVICE_IDS\ ADV_UUID_DEVICE_INFORMATION_SERVICE\ "\x11"\ ADV_TYPE_COMPLETE_LIST_128BIT_SERVICE_IDS\ "\x59\x5A\x08\xE4\x86\x2A\x9E\x8F\xE9\x11\xBC\x7C\x98\x43\x42\x18")
Configure the device name.
#define USER_DEVICE_NAME "DLG-SECURITY"
Define the address mode as a public Bluetooth device address
#define USER_CFG_ADDRESS_MODE APP_CFG_ADDR_PUB
We will now continue with the security related changes in our application:
Enable the application security flag in
..._config_basic.h
file in here we are choosing DA14535 as build target (da14535_config_advanced.h
).#define CFG_APP_SECURITY
Go to file
user_config/user_profiles_config.h
and enable access to the profile characteristics using an authenticated link.#define APP_CUSTS1_SEC_REQ SRV_PERM_AUTH
In case you will be using the JustWorks association model, you have to define this to
#define APP_CUSTS1_SEC_REQ SRV_PERM_UNAUTH
In the same file, enable the UART output functionality by defining
CFG_PRINTF
.#define CFG_PRINTF
By defining this, you will enable the generation of a random number for the passkey. In case you want to use a predefined passkey, you would have to undefine the
CFG_PRINTF
macro and set your passkey in theuser_security.h
header file:#define APP_SECURITY_MITM_PASSKEY_VAL (123456)
Open the
user_config.h
file and make sure the next configuration is enabled:
Set the capabilities of the device as one that has only a display. This will invoke the Passkey Pairing procedure.
#define USER_CFG_FEAT_IO_CAP GAP_IO_CAP_DISPLAY_ONLY
In case you would like to use the JustWorks association model, define the I/O capabilities of the device as one with no input and no output.
#define USER_CFG_FEAT_IO_CAP GAP_IO_CAP_NO_INPUT_NO_OUTPUT
The out-of-band information exchange won’t be used.
#define USER_CFG_FEAT_OOB GAP_OOB_AUTH_DATA_NOT_PRESENT
For the authentication requirements, we will require bonding and MITM protection
#define USER_CFG_FEAT_AUTH_REQ (GAP_AUTH_BOND | GAP_AUTH_MITM | GAP_AUTH_SEC)
For the device security requirements, we want to use an encrypted link with user authentication for the Passkey association model
#define USER_CFG_FEAT_SEC_REQ GAP_SEC1_AUTH_PAIR_ENC
In case you will be using the JustWorks association model, you should define the above macro as
#define USER_CFG_FEAT_SEC_REQ GAP_SEC1_NOAUTH_PAIR_ENC
Define the LTK length to the default size, which is 16 bytes
#define USER_CFG_FEAT_KEY_SIZE KEY_LEN
In the key distribution phase, we will distribute the LTK, CSRK, and IDK. We will cover signing and address resolution in more detail in the next tutorial.
#define USER_CFG_FEAT_RESP_KDIST (GAP_KDIST_ENCKEY | GAP_KDIST_IDKEY | GAP_KDIST_SIGNKEY)
We can now build the software example. Choose your target in the drop-down box shown below and then hit the Build button or press F7.
6.3. Message flow
Before running the example we will take a moment to see on a higher level view how it works. All BLE events are processed using the following callbacks, which are assigned in the file user_callback_config.h
.
static const struct app_callbacks user_app_callbacks = {
.app_on_connection = user_app_connection,
.app_on_disconnect = user_app_disconnect,
.app_on_update_params_rejected = NULL,
.app_on_update_params_complete = NULL,
.app_on_set_dev_config_complete = default_app_on_set_dev_config_complete,
.app_on_adv_nonconn_complete = NULL,
.app_on_adv_undirect_complete = user_app_adv_undirect_complete,
.app_on_adv_direct_complete = NULL,
.app_on_db_init_complete = default_app_on_db_init_complete,
.app_on_scanning_completed = NULL,
.app_on_adv_report_ind = NULL,
.app_on_get_dev_name = default_app_on_get_dev_name,
.app_on_get_dev_appearance = default_app_on_get_dev_appearance,
.app_on_get_dev_slv_pref_params = default_app_on_get_dev_slv_pref_params,
.app_on_set_dev_info = default_app_on_set_dev_info,
.app_on_data_length_change = NULL,
.app_on_update_params_request = default_app_update_params_request,
.app_on_generate_static_random_addr = default_app_generate_unique_static_random_addr,
.app_on_svc_changed_cfg_ind = NULL,
.app_on_get_peer_features = NULL,
#if (BLE_APP_SEC)
.app_on_pairing_request = default_app_on_pairing_request,
.app_on_tk_exch = user_app_on_tk_exch,
.app_on_irk_exch = NULL,
.app_on_csrk_exch = default_app_on_csrk_exch,
.app_on_ltk_exch = default_app_on_ltk_exch,
.app_on_pairing_succeeded = default_app_on_pairing_succeeded,
.app_on_encrypt_ind = NULL,
.app_on_encrypt_req_ind = default_app_on_encrypt_req_ind,
.app_on_security_req_ind = NULL,
.app_on_addr_solved_ind = default_app_on_addr_solved_ind,
.app_on_addr_resolve_failed = default_app_on_addr_resolve_failed,
.app_on_ral_cmp_evt = default_app_on_ral_cmp_evt,
.app_on_ral_size_ind = NULL,
.app_on_ral_addr_ind = NULL,
#endif // (BLE_APP_SEC)
};
By defining CFG_APP_SECURITY
, the BLE_APP_SEC
guard gets defined and the latter block of code will be compiled. The user can utilize Renesas’s SDK6 default handlers, or provide
their own implementation without sacrificing modularity of their code and call the default handlers when appropriate. The function invocations that take place between different
software entities can be seen in the next message flow diagram.
6.4. Running the example
6.4.1. Using the UART
We will use the UART peripheral of our device to print the number for the pairing. If you are targeting a DA14535 device, on your DA14535 hardware kit connect the left pin of the UTX jumper connector to the P06 pin, as shown in the following figure.
For DA14531 use the following
In case you own a DA14585 or DA14586 device, configure the hardware as shown in the following figure.
Next, we have to find out our serial port. Right click on “My Computer” and click “Manage”. Under “Ports” you will find two more ports that have been enumerated when you plugged in your device. Keep in mind the one with the lowest number.
Open up your serial port terminal. Set the serial port to the one you have identified in the previous step, and enter the parameters that you can see in the following figure.
6.4.2. Running the example
In Keil, run a debug session and in the next workspace run the example:
Open the Lightblue App on your smartphone and locate the DLG-SECURITY device:
Tap on the device name. The app will connect with your device and the Pairing Feature Exchange will start. When the I/O Capabilities have been exchanged, you’ll be asked to accept pairing the device with your phone by entering the PIN. In LE legacy pairing, Authenticated man-in-the-middle (MITM) protection is only obtained by using the passkey entry pairing method or may be obtained using the out of band pairing method. The GATT database will be discovered without having the devices bonded, but when you try to access (read or write) a Characteristic, the Bonding procedure will start.
Your device on your serial terminal will display the passkey. Enter the passkey to authorize the pairing procedure:
Below you can see a Bluetooth sniffer trace of the Pairing procedure exchanged messages:
With these simple steps you have enabled security on your connection using the LE Legacy pairing. In the next pages we will talk about privacy in BLE and the access rights of your resources.