nordicBLE communication group 498676838
This lecture introduces some relevant theoretical knowledge of pairing and introduces How to realize the setting of "static password"
The program is based on the uart demo under sdk9.0
In addition, the mobile app used for testing is lightblue under IOS.
The correct term here should be called pairing code, not password. Entering this pairing code is an optional part of the pairing process
Before introducing how to set a static password, let me introduce the relevant knowledge of pairing (it will be called password directly later, instead of Pairing code)
Two devices that do not initially provide security must be paired first if they wish to do some work that requires security. Pairing involves authentication of the two devices and link encryption. If the binding bit is set during pairing, a secret key will be distributed later. The user-assigned secret key can be stored in flash so that secure boot will be faster when the two devices reconnect for the second time. There is no need to start the entire pairing process again like the first time.
The first process of pairing is the exchange of pairing information, which is used to determine the authentication method, and whether and which keys need to be distributed subsequently.
The information exchanged includes:
The input and output capabilities of the devices at both ends, such as whether there is a display, keyboard, etc.
Whether binding is required (if the binding bit is set to match).
Whether MITM is required, whether to use OOB, etc.
This information will allow the BLE protocol stack to determine an authentication method:
For example:
1: If the input and output capabilities of the devices at both ends are limited, for example, there is no keyboard or monitor, the authentication method is just work, which actually means there is no authentication.
2: If the devices at both ends have one There is a display, while the other one has a keyboard, and MITM protection is set in the pairing. Then the authentication method is passkey entery.
A pairing code will be displayed on one end, and the pairing code needs to be entered on the other end. Only then can the pairing proceed correctly.
3: If OOB is set, then the pairing code is sent through another communication method (such as NFC), instead of being displayed on one end and entered on the other as above.
The password setting in this lecture is the second case. The displayed password can be random or static. Because the device does not have a display. But we can still set the input and output capabilities to have a display because we are using a static password.
The pairing process is not just about entering the pairing code, but will also be generated based on the entered pairing code and the random numbers exchanged between the devices at both ends. The link key is used to encrypt the link and distribute subsequent long-term keys, identity resolution keys, etc. Keys required
There are many theories related to pairing, as described above It's just a rough process. The pairing process is described in detail in the security chapter of the Bluetooth specification.
Based on the above theoretical description, let’s summarize:
What we need is the function of entering the "password" , is actually part of the pairing process. The pairing process requires the exchange of pairing information first, and then the protocol stack will decide whether to enter a password based on the exchanged information.
Then what we have to do is the following steps:
1: First set the static password to be entered
2: It will be exchanged when setting up pairing Information: According to the above introduction, if we need to enter a password on the mobile phone, then we must set it to have only a display when pairing (this will display on one end and input on the other end. Although we really don’t have a display, we set a static password So it is possible), the setting requires MITM attack protection.
memset(&gap_conn_params, 0,sizeof(gap_conn_params));
gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL;
gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL;
gap_conn_params.slave_latency= SLAVE_LATENCY;
gap_conn_params.conn_sup_timeout= CONN_SUP_TIMEOUT;
err_code = sd_ble_gap_ppcp_set( &gap_conn_params);
APP_ERROR_CHECK(err_code);
//The following is the operation to set a static password
uint8_tpasskey[] = STATIC_PASSKEY; m_static_pin_option.gap_opt.passkey.p_passkey= passkey;
//This system call performs the password setting operation.
err_code=sd_ble_opt_set(BLE_GAP_OPT_PASSKEY,&m_static_pin_option)
APP_ERROR_CHECK(err_code);
}
to Set here The static password operation is completed.
Then the information to be exchanged when setting up pairing:
The following defines the macros for the information we need to exchange, That is, some macros related to security parameters.
//This is just a demonstration of a static password, no binding is required
#define SEC_PARAM_BOND 0
//Because you need to enter a password, It is a kind of MITM attack protection, so MITM is set here
#define SEC_PARAM_MITM 1
//Only the display screen is set here (actually not, but we use a static password that is known in advance, so no // Need to be displayed)
#define SEC_PARAM_IO_CAPABILITIES BLE_GAP_IO_CAPS_DISPLAY_ONLY
//Do not use out-of-band data
#define SEC_PARAM_OOB 0
//Link encryption key Length of key
#define SEC_PARAM_MIN_KEY_SIZE 7
#define SEC_PARAM_MAX_KEY_SIZE 16
Defined macro After that we need to set parameters and write a function as follows.
m_sec_params is a global variable
ble_gap_sec_params_t m_sec_params;
static void sec_params_init(void)
{
m_sec_params.bond = SEC_PARAM_BOND;
m_sec_params.mitm =SEC_PARAM_MITM;
m_sec_params.io_caps =SEC_PARAM_IO_CAPABILITIES;
m_sec_params.oob =SEC_PARAM_OO B;
m_sec_params.min_key_size = SEC_PARAM_MIN_KEY_SIZE;
m_sec_params.max_key_size = SEC_PARAM_MAX_KEY_SIZE;
}
Put this function in the main function After the conn_params_init(); function in the initialization process. The global variable set by
will be used in information exchange after pairing is started (because its internal value is the information to be exchanged).
Here we have set up the information that will be exchanged after pairing is started. But how to give this information to the peer device? First read the last step of triggering pairing, and then solve the problem of sending pairing information to the peer device.
The last step triggers pairing:
Pairing is triggered in the following situations:
1: Directly initiated by the host.
2: The slave initiates a security request. If it has been bound before, the host will directly use the saved LTK encrypted link. If not, the host will initiate a pairing request.
3: There is a concept of safe mode in BLE. When a certain attribute is set to require authentication for encrypted link access, then when the host accesses the slave's attribute device, an error will be returned if the link is unsafe, and then the host will initiate a pairing request to achieve Security requirements.
We use the third method of passively waiting for the host to trigger. Then the first thing to do is to set some attributes to require a secure link to access, then the mobile phone The pairing process will be triggered upon access.
Because we are based on uartdemo under 9.0SDK, we set the cccd (client configuration descriptor) with notify property RX feature value to require authentication and encryption Secure link.
Because enabling notify on the mobile phone requires writing CCCD
Then when the hand is connected to the board and clicks the notify button of the rx feature value, the host will send a write command to write the rx feature on the board. value cccd, because the initial link test is incomplete, then the phone will return a write error and then start the pairing process.
Set as follows:
Just do the following simple in the function that adds RX eigenvalues.
Here is only part of the code:
static uint32_t rx_char_add(ble_nus_t * p_nus, constble_nus_init_t * p_nus_init)
{
/**@snippet [Addingproprietary characteristic to S110 SoftDevice]*/
ble_gatts_char_md_tchar_md;
ble_gatts_attr_md_tcccd_md;
ble_gatts_attr_t attr_char_value;
ble_uuid_t ble_uuid;
ble_gatts_attr_md_tattr_md;
memset(&cccd_m d, 0, sizeof(cccd_md));
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
//BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
/ /Modify the above line into the following line
BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(&cccd_md.write_perm);
cccd_md.vloc =BLE_GATTS_VLOC_STACK;
memset (&char_md, 0, sizeof(char_md));
···············
·········· ·····
·············
}
This is how to act as the peer device (For example, a mobile phone) When the notify function of the rx characteristic value of the development board is enabled, pairing will be triggered
because there is no write permission. The mobile phone will send a pairing request, and then the board will reply with the pairing information,
How to reply? This is the last remaining question in step two. How to hand over pairing information to the peer device
(mobile phone).
When the phone sends a pairing request, this is an event for the board, that is, a pairing event. Finally, the
dispatch dispatch function is handed over to the event processing function of each service or module.
Then what we have to do is to reply to the pairing
information set in the second step after receiving this pairing request event. Modify on_ble_evt in the main.c file as follows header.evt_id)
{
caseBLE_GAP_EVT_CONNECTED:
err_code= bsp_indication_set(BSP_INDICATE_CONNECTED);
APP_ERROR_CHECK(err_code);
m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
break;
caseBLE_GAP_EVT_DISCONNECTED:err_code= bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code);
m_conn_handle= BLE_CONN_HANDLE_INVALID;
break;
caseBLE_GAP_EVT_SEC_PARAMS_REQUEST:
// Comment out the original Support pairing function, change it to the following pairing reply function
//err_code= sd_ble_gap_sec_params_reply(m_conn_handle,
//BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
err_code=sd_ble_gap_ sec_params_reply(m_conn_handle ,
BLE_GAP_SEC_STATUS_SUCCESS,&m_sec_params,NULL);
APP_ERROR_CHECK(err_code);
break;
caseBLE_GATTS_EVT _SYS_ATTR_MISSING: // No system attributes have beenstored.err_code=sd_ble_gatts_sys_attr_set(m_conn_handle,
NULL, 0, 0);
APP_ERROR_CHECK(err_code);
break;
default:
// No implementation needed.
break;
}
}
Everything that needs to be configured is now set up. . After the program is run. Connect the mobile phone to the board, and then access the rx characteristic value. Because this characteristic value is used to transmit the board data to the mobile phone through the Notify method, you must first click the notify button on the mobile phone to enable the board's notify function. When we click this button, a pairing box for entering the password will pop up.