Skip to content
This repository was archived by the owner on Sep 16, 2024. It is now read-only.

Commit 3138a13

Browse files
author
iwahdan88
committed
Updated Secure BLE
BLE: Allow static passwords, remove bonded when pin changes
1 parent 655ed5e commit 3138a13

File tree

1 file changed

+122
-6
lines changed

1 file changed

+122
-6
lines changed

esp32/mods/modbt.c

Lines changed: 122 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@
5353
#include "lwip/opt.h"
5454
#include "lwip/def.h"
5555

56+
#include "mbedtls/sha1.h"
57+
#include "nvs.h"
58+
5659
/******************************************************************************
5760
DEFINE PRIVATE CONSTANTS
5861
******************************************************************************/
@@ -75,6 +78,9 @@
7578
#define MOD_BT_GATTC_MTU_EVT (0x0100)
7679
#define MOD_BT_GATTS_MTU_EVT (0x0200)
7780
#define MOD_BT_GATTS_CLOSE_EVT (0x0400)
81+
#define MOD_BT_NVS_NAMESPACE "BT_NVS"
82+
#define MOD_BT_HASH_SIZE (20)
83+
#define MOD_BT_PIN_LENGTH (6)
7884

7985
/******************************************************************************
8086
DEFINE PRIVATE TYPES
@@ -209,6 +215,11 @@ typedef struct {
209215
uint16_t config;
210216
} bt_gatts_char_obj_t;
211217

218+
typedef union {
219+
uint32_t pin;
220+
uint8_t value[4];
221+
} bt_hash_obj_t;
222+
212223
/******************************************************************************
213224
DECLARE PRIVATE DATA
214225
******************************************************************************/
@@ -250,6 +261,7 @@ static bool mod_bt_allow_resume_deinit;
250261
static uint16_t mod_bt_gatts_mtu_restore = 0;
251262
static bool mod_bt_is_conn_restore_available;
252263

264+
static nvs_handle modbt_nvs_handle;
253265
static uint8_t tx_pwr_level_to_dbm[] = {-12, -9, -6, -3, 0, 3, 6, 9};
254266
static EventGroupHandle_t bt_event_group;
255267
static uint16_t bt_conn_mtu = 0;
@@ -430,15 +442,115 @@ static esp_ble_scan_params_t ble_scan_params = {
430442
.scan_window = 0x30
431443
};
432444

433-
static void set_secure_parameters(esp_ble_io_cap_t *iocap){
434-
esp_ble_auth_req_t auth_req = ESP_LE_AUTH_BOND;
445+
STATIC mp_obj_t bt_nvram_erase (mp_obj_t self_in) {
446+
if (nvs_open(MOD_BT_NVS_NAMESPACE, NVS_READWRITE, &modbt_nvs_handle) != ESP_OK) {
447+
mp_printf(&mp_plat_print, "Error opening secure BLE NVS namespace!\n");
448+
}
449+
450+
if (ESP_OK != nvs_erase_all(modbt_nvs_handle)) {
451+
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
452+
}
453+
nvs_commit(modbt_nvs_handle);
454+
nvs_close(modbt_nvs_handle);
455+
456+
return mp_const_none;
457+
}
458+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bt_nvram_erase_obj, bt_nvram_erase);
459+
460+
static void create_hash(uint32_t pin, uint8_t *h_value)
461+
{
462+
bt_hash_obj_t pin_hash;
463+
mbedtls_sha1_context sha1_context;
464+
465+
mbedtls_sha1_init(&sha1_context);
466+
mbedtls_sha1_starts_ret(&sha1_context);
467+
468+
pin_hash.pin = pin;
469+
mbedtls_sha1_update_ret(&sha1_context, pin_hash.value, 4);
470+
471+
mbedtls_sha1_finish_ret(&sha1_context, h_value);
472+
mbedtls_sha1_free(&sha1_context);
473+
}
474+
475+
static bool is_pin_valid(uint32_t pin)
476+
{
477+
int digits = 0;
478+
479+
while(pin != 0)
480+
{
481+
digits++;
482+
pin /= 10;
483+
}
484+
485+
if (digits != MOD_BT_PIN_LENGTH){
486+
return false;
487+
}
488+
489+
return true;
490+
}
491+
static bool pin_changed(uint32_t new_pin)
492+
{
493+
bool ret = false;
494+
uint32_t h_size = MOD_BT_HASH_SIZE;
495+
uint8_t h_stored[MOD_BT_HASH_SIZE] = {0};
496+
uint8_t h_created[MOD_BT_HASH_SIZE] = {0};
497+
const char *key = "bt_pin_hash";
498+
esp_err_t esp_err = ESP_OK;
499+
500+
if (nvs_open(MOD_BT_NVS_NAMESPACE, NVS_READWRITE, &modbt_nvs_handle) != ESP_OK) {
501+
mp_printf(&mp_plat_print, "Error opening secure BLE NVS namespace!\n");
502+
}
503+
nvs_get_blob(modbt_nvs_handle, key, h_stored, &h_size);
504+
505+
create_hash(new_pin, h_created);
506+
507+
if (memcmp(h_stored, h_created, MOD_BT_HASH_SIZE) != 0) {
508+
esp_err = nvs_set_blob(modbt_nvs_handle, key, h_created, h_size);
509+
if (esp_err == ESP_OK) {
510+
nvs_commit(modbt_nvs_handle);
511+
ret = true;
512+
}
513+
}
514+
515+
nvs_close(modbt_nvs_handle);
516+
517+
return ret;
518+
}
519+
520+
static void remove_all_bonded_devices(void)
521+
{
522+
int dev_num = esp_ble_get_bond_device_num();
523+
524+
esp_ble_bond_dev_t *dev_list = heap_caps_malloc(sizeof(esp_ble_bond_dev_t) * dev_num, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
525+
esp_ble_get_bond_device_list(&dev_num, dev_list);
526+
for (int i = 0; i < dev_num; i++) {
527+
esp_ble_remove_bond_device(dev_list[i].bd_addr);
528+
}
529+
530+
free(dev_list);
531+
}
532+
533+
static void set_secure_parameters(uint32_t passKey){
534+
535+
if (pin_changed(passKey)) {
536+
remove_all_bonded_devices();
537+
}
538+
539+
uint32_t passkey = passKey;
540+
esp_ble_gap_set_security_param(ESP_BLE_SM_SET_STATIC_PASSKEY, &passkey, sizeof(uint32_t));
541+
542+
esp_ble_auth_req_t auth_req = ESP_LE_AUTH_REQ_SC_MITM_BOND;
435543
esp_ble_gap_set_security_param(ESP_BLE_SM_AUTHEN_REQ_MODE, &auth_req, sizeof(uint8_t));
436544

437-
esp_ble_gap_set_security_param(ESP_BLE_SM_IOCAP_MODE, iocap, sizeof(uint8_t));
545+
esp_ble_io_cap_t iocap = ESP_IO_CAP_OUT;
546+
esp_ble_gap_set_security_param(ESP_BLE_SM_IOCAP_MODE, &iocap, sizeof(uint8_t));
438547

439548
uint8_t key_size = 16;
440549
esp_ble_gap_set_security_param(ESP_BLE_SM_MAX_KEY_SIZE, &key_size, sizeof(uint8_t));
441550

551+
uint8_t auth_option = ESP_BLE_ONLY_ACCEPT_SPECIFIED_AUTH_DISABLE;
552+
esp_ble_gap_set_security_param(ESP_BLE_SM_ONLY_ACCEPT_SPECIFIED_SEC_AUTH, &auth_option, sizeof(uint8_t));
553+
442554
uint8_t init_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK;
443555
esp_ble_gap_set_security_param(ESP_BLE_SM_SET_INIT_KEY, &init_key, sizeof(uint8_t));
444556

@@ -963,8 +1075,11 @@ static mp_obj_t bt_init_helper(bt_obj_t *self, const mp_arg_val_t *args) {
9631075
if (args[3].u_bool){
9641076
bt_obj.secure = true;
9651077

966-
esp_ble_io_cap_t io_cap = args[4].u_int;
967-
set_secure_parameters(&io_cap);
1078+
uint32_t passKey = args[4].u_int;
1079+
if (!is_pin_valid(passKey)){
1080+
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Only 6 digit (0-9) pins are allowed"));
1081+
}
1082+
set_secure_parameters(passKey);
9681083
}
9691084

9701085
return mp_const_none;
@@ -976,7 +1091,7 @@ STATIC const mp_arg_t bt_init_args[] = {
9761091
{ MP_QSTR_antenna, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
9771092
{ MP_QSTR_modem_sleep, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
9781093
{ MP_QSTR_secure, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
979-
{ MP_QSTR_io_cap, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = ESP_IO_CAP_NONE} },
1094+
{ MP_QSTR_pin, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 123456} },
9801095
{ MP_QSTR_mtu, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = BT_MTU_SIZE_MAX} },
9811096

9821097
};
@@ -1949,6 +2064,7 @@ STATIC const mp_map_elem_t bt_locals_dict_table[] = {
19492064
{ MP_OBJ_NEW_QSTR(MP_QSTR_modem_sleep), (mp_obj_t)&bt_modem_sleep_obj },
19502065
{ MP_OBJ_NEW_QSTR(MP_QSTR_tx_power), (mp_obj_t)&bt_tx_power_obj },
19512066
{ MP_OBJ_NEW_QSTR(MP_QSTR_gatts_mtu), (mp_obj_t)&bt_gatts_get_mtu_obj },
2067+
{ MP_OBJ_NEW_QSTR(MP_QSTR_nvram_erase), (mp_obj_t)&bt_nvram_erase_obj },
19522068

19532069

19542070
// exceptions

0 commit comments

Comments
 (0)