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 ******************************************************************************/
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;
250261static uint16_t mod_bt_gatts_mtu_restore = 0 ;
251262static bool mod_bt_is_conn_restore_available ;
252263
264+ static nvs_handle modbt_nvs_handle ;
253265static uint8_t tx_pwr_level_to_dbm [] = {-12 , -9 , -6 , -3 , 0 , 3 , 6 , 9 };
254266static EventGroupHandle_t bt_event_group ;
255267static 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