1# Gatt Security Server Example Walkthrough 2 3## Introduction 4 5In this document, a description of the security GATT Server BLE example for the ESP32 is presented. The security configuration enables a GATT Server acting as a slave device to bond with a master and establish an encrypted link between them. This functionality is defined by the [Bluetooth Specification version 4.2](https://www.bluetooth.com/specifications/bluetooth-core-specification) and implemented on the ESP-IDF BLE stack, specifically on the Security Manager Protocol (SMP) API. 6 7BLE security involves three interrelated concepts: pairing, bonding and encryption. Pairing concerns with the exchange of security features and types of keys needed. In addition, the pairing procedure takes care of the generation and exchange of shared keys. The core specification defines the legacy pairing and Secure Connections pairing (introduced in Bluetooth 4.2), which are both supported by ESP32. Once the exchange of shared keys is completed, a temporary encrypted link is established to exchange short term and long term keys. Bonding refers to storing the exchanged keys for subsequent connections so that they do not have to be transmitted again. Finally, encryption pertains to the ciphering of plain text data using the AES-128 engine and the shared keys. Server attributes may also be defined to allow only encrypted write and read messages. At any point of the communication, a slave device can always ask to start encryption by issuing a security request to the other peer device, which returns a security response by calling an API. 8 9This document only describes the security configuration. The rest of the GATT server functionalities, such as defining the service table, are explained in the GATT Server example walkthrough documentation. For a better understanding of this example workflow, it is recommended that the reader is familiar with the pairing feature exchange and key generation defined in the section 3.5 of the [Bluetooth Specification Version 4.2](https://www.bluetooth.com/specifications/bluetooth-core-specification) [Vol 3, Part H]. 10 11## Setting Security Parameters 12 13The ESP32 requires a series of security parameters in order to define how the pairing request and response are going to be built. The Pairing Response packet built by the GATT Server includes fields such as the input/output capabilities, Secure Connections pairing, authenticated Man-In-The-Middle (MITM) protection or no security requirements (see Section 2.3.1 of the [Bluetooth Specification Version 4.2](https://www.bluetooth.com/specifications/bluetooth-core-specification) [Vol 3, Part H]). In this example, this procedure is done in the `app_main()` function. The pairing request is sent by the initiator which in this case is a remote GATT client. The ESP32 server implemented in this example receives this request and replies with a pairing response, which contains the same security parameters in order for both devices to agree on the resources available and the applicable pairing algorithm (*Just Works* or *Passkey Entry*). Both the pairing request and response commands have the following parameters: 14 15* *IO Capability*: describes if the device has input/output capabilities such as a display or a keyboard. 16* *OOB Flag*: describes if the device supports Out of Band passkey exchange, for example using NFC or Wi-Fi to exchange keys as TKs. 17* *Authorization Request*: indicates the requested security properties such as Bonding, Secure Connections (SC), MITM protection or none that will be present in the Pairing Request and Response packets. 18* *Maximum Encryption Key Size*: maximum encryption key size in octets. 19* *Initiator Key Distribution/Generation*: indicates which keys the initiator is requesting to distribute/generate or use during the Transport Specific Key Distribution phase. In the pairing request, these keys are requested, while in the pairing response, these keys are confirmed to be distributed. 20* *Responder Key Distribution/Generation*: indicates which keys the initiator is requesting the responder to distribute/generate or use during the Transport Specific Key Distribution phase. In the pairing request, these keys are requested, while in the pairing response, these keys are confirmed to be distributed. 21 22In code, these parameters are defined as follows: 23 24* *IO Capability*: 25 26 ```c 27 esp_ble_io_cap_t iocap = ESP_IO_CAP_NONE;//set the IO capability to No Input No Output 28 ``` 29 30 The possible values for *IO Capabilities* are: 31 32 ```c 33 ESP_IO_CAP_OUT 0 /*!< DisplayOnly */ 34 ESP_IO_CAP_IO 1 /*!< DisplayYesNo */ 35 ESP_IO_CAP_IN 2 /*!< KeyboardOnly */ 36 ESP_IO_CAP_NONE 3 /*!< NoInputNoOutput */ 37 ESP_IO_CAP_KBDISP 4 /*!< Keyboard display */ 38 ``` 39 40* *Authorization Request*: 41 42 ```c 43 esp_ble_auth_req_t auth_req = ESP_LE_AUTH_BOND; //bonding with peer device after authentication 44 ``` 45 46 The possible values for *Authorization Request* are a combination of Bonding, MITM protection and Secure Connections requests: 47 48 ```c 49 ESP_LE_AUTH_NO_BOND: No bonding. 50 ESP_LE_AUTH_BOND: Bonding is performed. 51 ESP_LE_AUTH_REQ_MITM: MITM Protection is enabled. 52 ESP_LE_AUTH_REQ_SC_ONLY: Secure Connections without bonding enabled. 53 ESP_LE_AUTH_REQ_SC_BOND: Secure Connections with bonding enabled. 54 ESP_LE_AUTH_REQ_SC_MITM: Secure Connections with MITM Protection and no bonding enabled. 55 ESP_LE_AUTH_REQ_SC_MITM_BOND: Secure Connections with MITM Protection and bonding enabled. 56 ``` 57 58* *Maximum Encryption Key Size*: 59 60 ```c 61 uint8_t key_size = 16; //the key size should be 7~16 bytes 62 ``` 63 64* *Initiator Key Distribution/Generation*: 65 66 ```c 67 uint8_t init_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK; 68 ``` 69 70 The initiator distributes the LTK and IRK keys by the setting the EncKey and IdKey masks. 71 72* *Responder Key Distribution/Generation*: 73 74 ```c 75 uint8_t rsp_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK; 76 ``` 77 78 The responder distributes the LTK and IRK keys by the setting the *EncKey* and *IdKey* masks. 79 80 Once defined, the parameters are set using the `esp_ble_gap_set_security_param()` function. This function sets the parameter type, the parameter value and the parameter length: 81 82 ```c 83 esp_ble_gap_set_security_param(ESP_BLE_SM_AUTHEN_REQ_MODE, &auth_req, sizeof(uint8_t)); 84 esp_ble_gap_set_security_param(ESP_BLE_SM_IOCAP_MODE, &iocap, sizeof(uint8_t)); 85 esp_ble_gap_set_security_param(ESP_BLE_SM_MAX_KEY_SIZE, &key_size, sizeof(uint8_t)); 86 esp_ble_gap_set_security_param(ESP_BLE_SM_SET_INIT_KEY, &init_key, sizeof(uint8_t)); 87 esp_ble_gap_set_security_param(ESP_BLE_SM_SET_RSP_KEY, &rsp_key, sizeof(uint8_t)); 88 ``` 89 90 This information is enough for the BLE stack to perform the pairing process, including pairing confirmation and key generation. The procedure is invisible to the user and executed automatically by the stack. 91 92## Connecting and Bonding to a Peer Device 93 94The security parameters set previously are stored locally to be used later when the master device connects to the slave. Every time a remote device connects to the local GATT server, the connection event `ESP_GATTS_CONNECT_EVT` is triggered. This event is employed to perform the pairing and bonding process by invoking the `esp_ble_set_encryption()` function which takes as parameters the remote device address and the type of encryption that will be performed. The BLE stack then executes the actual pairing process in the background. In this example, the encryption includes MITM protection. 95 96```c 97case ESP_GATTS_CONNECT_EVT: 98 //start security connect with peer device when receive the connect event sent by the master. 99 esp_ble_set_encryption(param->connect.remote_bda, ESP_BLE_SEC_ENCRYPT_MITM); 100 break; 101``` 102The types of encryptions available are: 103 104* `ESP_BLE_SEC_NONE` 105* `ESP_BLE_SEC_ENCRYPT` 106* `ESP_BLE_SEC_ENCRYPT_NO_MITM` 107* `ESP_BLE_SEC_ENCRYPT_MITM` 108 109The difference between `ESP_BLE_SEC_ENCRYPT` and `ESP_BLE_SEC_ENCRYPT_NO_MITM` lies in the fact that a previous connection might have a security level that needs to be upgraded, therefore requires to exchange keys again. 110 111In this example, the I/O capabilities are set to *No Input No Output*, therefore the *Just Works* pairing method, which doesn't not require the generation of a random 6-digit passkey, is used (For details, please refer to the the table below). The user may modify the example to set the I/O capabilities to use other than *No Input No Output*. Therefore, depending on the I/O capabilities of the remote device, a passkey might be generated on the ESP32 which is presented to the user with the `ESP_GAP_BLE_PASSKEY_NOTIF_EVT`: 112 113```c 114case ESP_GAP_BLE_PASSKEY_NOTIF_EVT: 115 ///the app will receive this evt when the IO has Output capability and the peer device IO has Input capability. 116 ///show the passkey number to the user to input it in the peer device. 117 ESP_LOGE(GATTS_TABLE_TAG, "The passkey Notify number:%d", param->ble_security.key_notif.passkey); 118 break; 119``` 120 121The combination of input and output capabilities that determine which algorithm is used are: 122 123| | Display Only | Display Yes/No | Keyboard Only | No Input No Output | Keyboard Display| 124| :-- | :------------- | :------------- | :------------- | :----------------- | :-------------- | 125| **Display Only** | Just Works | Just Works | Passkey Entry | Just Works | Passkey Entry | 126| **Display Yes/No** | Just Works | Just Works | Passkey Entry | Just Works | Passkey Entry | 127| **Keyboard Only** | Passkey Entry | Passkey Entry | Passkey Entry | Just Works | Passkey Entry | 128| **No Input No Output** | Just Works | Just Works | Just Works | Just Works | Just Works | 129| **Keyboard Display** | Passkey Entry | Passkey Entry | Passkey Entry | Just Works | Passkey Entry | 130 131 132## Exchanging Keys 133 134When the client connects to the server and the pairing is done successfully, the keys indicated by the `init_key` and `rsp_key` security parameters are exchanged. In this example the following keys are generated and distributed: 135 136* Local device LTK 137* Local device IRK 138* Local device CSRK 139* Peer device LTK 140* Peer device IRK 141 142Note that for this example only, the peer device CSRK is not exchanged. For each key exchange message, an `ESP_GAP_BLE_KEY_EVT` event is triggered, which can be used to print the type of key received: 143 144```c 145case ESP_GAP_BLE_KEY_EVT: 146 //shows the ble key info share with peer device to the user. 147 ESP_LOGI(GATTS_TABLE_TAG, "key type = %s", esp_key_type_to_str(param->ble_security.ble_key.key_type)); 148 break; 149``` 150 151When the keys are exchanged successfully, the pairing process is done. This triggers an `ESP_GAP_BLE_AUTH_CMPL_EVT` event, which is used to print information such as remote device, address type and pair status: 152 153```c 154case ESP_GAP_BLE_AUTH_CMPL_EVT: { 155 esp_bd_addr_t bd_addr; 156 memcpy(bd_addr, param->ble_security.auth_cmpl.bd_addr, 157 sizeof(esp_bd_addr_t)); 158 ESP_LOGI(GATTS_TABLE_TAG, "remote BD_ADDR: %08x%04x",\ 159 (bd_addr[0] << 24) + (bd_addr[1] << 16) + (bd_addr[2] << 8) + 160 bd_addr[3], 161 (bd_addr[4] << 8) + bd_addr[5]); 162 ESP_LOGI(GATTS_TABLE_TAG, "address type = %d", 163 param->ble_security.auth_cmpl.addr_type); 164 ESP_LOGI(GATTS_TABLE_TAG, "pair status = %s", 165 param->ble_security.auth_cmpl.success ? "success" : "fail"); 166 break; 167} 168``` 169 170## Security Permission for Attributes 171 172When defining the attributes of the server, different permissions can be set to the write and read events. Attributes permissions can be: 173 174* Permission to read 175* Permission to read with encryption 176* Permission to read with encryption and MITM protection 177* Permission to write 178* Permission to write with encryption 179* Permission to write with encryption and MITM protection 180* Permission to signed write 181* Permission to signed write with MITM protection 182 183These permissions are defined in the API as: 184 185* `ESP_GATT_PERM_READ` 186* `ESP_GATT_PERM_READ_ENCRYPTED` 187* `ESP_GATT_PERM_READ_ENC_MITM` 188* `ESP_GATT_PERM_WRITE` 189* `ESP_GATT_PERM_WRITE_ENCRYPTED` 190* `ESP_GATT_PERM_WRITE_ENC_MITM` 191* `ESP_GATT_PERM_WRITE_SIGNED` 192* `ESP_GATT_PERM_WRITE_SIGNED_MITM` 193 194When creating the services table, each attribute can have permissions to read or write, with or without encryption. When an attribute has encrypted permissions and a peer device that does not have the required security clearance tries to read or write to that attribute, the local host sends an Insufficient Authorization Error. In the example, the following attributes are defined with permissions with encryption: 195 196```c 197… 198// Body Sensor Location Characteristic Value 199 [HRS_IDX_BOBY_SENSOR_LOC_VAL] = { 200 {ESP_GATT_AUTO_RSP}, 201 {ESP_UUID_LEN_16, 202 (uint8_t *)&body_sensor_location_uuid, 203 ESP_GATT_PERM_READ_ENCRYPTED, 204 sizeof(uint8_t), 205 sizeof(body_sensor_loc_val), 206 (uint8_t *)body_sensor_loc_val} 207 }, 208… 209// Heart Rate Control Point Characteristic Value 210 [HRS_IDX_HR_CTNL_PT_VAL] = { 211 {ESP_GATT_AUTO_RSP}, 212 {ESP_UUID_LEN_16, 213 (uint8_t *)&heart_rate_ctrl_point, 214 ESP_GATT_PERM_WRITE_ENCRYPTED|ESP_GATT_PERM_READ_ENCRYPTED, 215 sizeof(uint8_t), 216 sizeof(heart_ctrl_point), 217 (uint8_t *)heart_ctrl_point} 218 }, 219… 220``` 221 222## Security Requests 223 224During the communication between a master and a slave device, the slave might request to start encryption at any moment by issuing a security request command. This command will trigger an `ESP_GAP_BLE_SEC_REQ_EVT` event on the master, which will reply a positive (true) security response to the peer device to accept the request or a negative (false) one to reject the request. In this example, this event is used to reply a start encryption response by using the `esp_ble_gap_security_rsp()` API call. 225 226```c 227case ESP_GAP_BLE_SEC_REQ_EVT: 228 /* send the positive (true) security response to the peer device to accept the security request. 229 If not accept the security request, should send the security response with negative(false) accept value*/ 230 esp_ble_gap_security_rsp(param->ble_security.ble_req.bd_addr, true); 231 break; 232``` 233## Conclusion 234 235In this document, a review of the security aspects of the GATT Server has been realized. BLE security encompasses Pairing, Bonding and Encryption. In order to establish a secured link between a master and a slave device, security parameters that define the capabilities and features each device possess are set. The combination of features and capabilities of the peer devices results in the selection of the appropriate pairing method which the BLE stack then executes. Immediately, the required keys are generated and exchanged, and the encryption of subsequent messages is started using the AES-128 engine and these keys. These steps trigger different events that are managed by the GATT and GAP event handlers which can be used to print useful information such as the types of keys exchanged and the pairing status. In addition, attribute permissions are appointed to allow only encrypted read and write events when needed. The rest of the Security GATT server functionalities such as defining services and characteristics are implemented in the same way as presented in the GATT Server example.