From 9c87165bc85dbb3cbd849632b7737a2fee7ea1f0 Mon Sep 17 00:00:00 2001 From: Prasad Alatkar Date: Sun, 29 Sep 2019 16:06:27 +0800 Subject: [PATCH] BT/Bluedroid : Add support to set min encryption key requirement (Backport v3.3) - Backport(v3.3) of IDF MR!6122 - Modifies `smp_utils.c` to add check on encryption key size received from peer. - Modifies `esp_ble_gap_set_security_param` API to add minimum encryption key size requirement. --- .../api/include/api/esp_gap_ble_api.h | 13 +++++++++- components/bt/bluedroid/bta/dm/bta_dm_co.c | 14 ++++++++++- .../bt/bluedroid/bta/include/bta/bta_dm_co.h | 2 ++ .../btc/profile/std/gap/btc_gap_ble.c | 6 +++++ .../common/include/common/bte_appl.h | 3 ++- components/bt/bluedroid/stack/smp/smp_utils.c | 25 ++++++++++++++++--- 6 files changed, 57 insertions(+), 6 deletions(-) diff --git a/components/bt/bluedroid/api/include/api/esp_gap_ble_api.h b/components/bt/bluedroid/api/include/api/esp_gap_ble_api.h index 44dd7c4b2b..12bc48f1b1 100644 --- a/components/bt/bluedroid/api/include/api/esp_gap_ble_api.h +++ b/components/bt/bluedroid/api/include/api/esp_gap_ble_api.h @@ -267,14 +267,25 @@ typedef enum { typedef enum { ESP_BLE_SM_PASSKEY = 0, + /* Authentication requirements of local device */ ESP_BLE_SM_AUTHEN_REQ_MODE, + /* The IO capability of local device */ ESP_BLE_SM_IOCAP_MODE, + /* Initiator Key Distribution/Generation */ ESP_BLE_SM_SET_INIT_KEY, + /* Responder Key Distribution/Generation */ ESP_BLE_SM_SET_RSP_KEY, + /* Maximum Encryption key size to support */ ESP_BLE_SM_MAX_KEY_SIZE, + /* Minimum Encryption key size requirement from Peer */ + ESP_BLE_SM_MIN_KEY_SIZE, + /* Set static Passkey */ ESP_BLE_SM_SET_STATIC_PASSKEY, + /* Reset static Passkey */ ESP_BLE_SM_CLEAR_STATIC_PASSKEY, + /* Accept only specified SMP Authentication requirement */ ESP_BLE_SM_ONLY_ACCEPT_SPECIFIED_SEC_AUTH, + /* Enable/Disable OOB support */ ESP_BLE_SM_OOB_SUPPORT, ESP_BLE_SM_MAX_PARAM, } esp_ble_sm_param_t; @@ -589,7 +600,7 @@ typedef enum { typedef enum { ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_ADV_ADDR = 0, /*!< BLE advertising address , device info will be added into ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_ADDR_LIST */ ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_MESH_LINK_ID, /*!< BLE mesh link ID, it is for BLE mesh, device info will be added into ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_MESH_LINK_ID_LIST */ - ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_MESH_BEACON_TYPE, /*!< BLE mesh beacon AD type, the format is | Len | 0x2B | Beacon Type | Beacon Data | */ + ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_MESH_BEACON_TYPE, /*!< BLE mesh beacon AD type, the format is | Len | 0x2B | Beacon Type | Beacon Data | */ ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_MESH_PROV_SRV_ADV, /*!< BLE mesh provisioning service uuid, the format is | 0x02 | 0x01 | flags | 0x03 | 0x03 | 0x1827 | .... |` */ ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_MESH_PROXY_SRV_ADV, /*!< BLE mesh adv with proxy service uuid, the format is | 0x02 | 0x01 | flags | 0x03 | 0x03 | 0x1828 | .... |` */ } esp_ble_duplicate_exceptional_info_type_t; diff --git a/components/bt/bluedroid/bta/dm/bta_dm_co.c b/components/bt/bluedroid/bta/dm/bta_dm_co.c index 7e6cb4808f..5fdf0812a5 100644 --- a/components/bt/bluedroid/bta/dm/bta_dm_co.c +++ b/components/bt/bluedroid/bta/dm/bta_dm_co.c @@ -48,6 +48,7 @@ tBTE_APPL_CFG bte_appl_cfg = { BTM_BLE_INITIATOR_KEY_SIZE, BTM_BLE_RESPONDER_KEY_SIZE, BTM_BLE_MAX_KEY_SIZE, + BTM_BLE_MIN_KEY_SIZE, BTM_BLE_ONLY_ACCEPT_SPECIFIED_SEC_AUTH_DISABLE, BTM_BLE_OOB_DISABLE, }; @@ -407,7 +408,7 @@ void bta_dm_co_ble_set_rsp_key_req(UINT8 rsp_key) void bta_dm_co_ble_set_max_key_size(UINT8 ble_key_size) { #if (SMP_INCLUDED == TRUE) - if(ble_key_size >= BTM_BLE_MIN_KEY_SIZE && ble_key_size <= BTM_BLE_MAX_KEY_SIZE) { + if(ble_key_size >= bte_appl_cfg.ble_min_key_size && ble_key_size <= BTM_BLE_MAX_KEY_SIZE) { bte_appl_cfg.ble_max_key_size = ble_key_size; } else { APPL_TRACE_ERROR("%s error:Invalid key size value, key_size =%d",__func__, ble_key_size); @@ -415,6 +416,17 @@ void bta_dm_co_ble_set_max_key_size(UINT8 ble_key_size) #endif ///SMP_INCLUDED == TRUE } +void bta_dm_co_ble_set_min_key_size(UINT8 ble_key_size) +{ +#if (SMP_INCLUDED == TRUE) + if(ble_key_size >= BTM_BLE_MIN_KEY_SIZE && ble_key_size <= bte_appl_cfg.ble_max_key_size) { + bte_appl_cfg.ble_min_key_size = ble_key_size; + } else { + APPL_TRACE_ERROR("%s error:Invalid key size value, key_size =%d",__func__, ble_key_size); + } +#endif ///SMP_INCLUDED == TRUE +} + void bta_dm_co_ble_set_accept_auth_enable(UINT8 enable) { #if (SMP_INCLUDED == TRUE) diff --git a/components/bt/bluedroid/bta/include/bta/bta_dm_co.h b/components/bt/bluedroid/bta/include/bta/bta_dm_co.h index b9e98b4653..99667cb016 100644 --- a/components/bt/bluedroid/bta/include/bta/bta_dm_co.h +++ b/components/bt/bluedroid/bta/include/bta/bta_dm_co.h @@ -205,6 +205,8 @@ extern void bta_dm_co_ble_set_rsp_key_req(UINT8 rsp_key); extern void bta_dm_co_ble_set_max_key_size(UINT8 ble_key_size); +extern void bta_dm_co_ble_set_min_key_size(UINT8 ble_key_size); + extern void bta_dm_co_ble_set_accept_auth_enable(UINT8 enable); extern UINT8 bta_dm_co_ble_get_accept_auth_enable(void); diff --git a/components/bt/bluedroid/btc/profile/std/gap/btc_gap_ble.c b/components/bt/bluedroid/btc/profile/std/gap/btc_gap_ble.c index ef13106dde..6046c57c47 100644 --- a/components/bt/bluedroid/btc/profile/std/gap/btc_gap_ble.c +++ b/components/bt/bluedroid/btc/profile/std/gap/btc_gap_ble.c @@ -1189,6 +1189,12 @@ void btc_gap_ble_call_handler(btc_msg_t *msg) bta_dm_co_ble_set_max_key_size(key_size); break; } + case ESP_BLE_SM_MIN_KEY_SIZE: { + uint8_t key_size = 0; + STREAM_TO_UINT8(key_size, value); + bta_dm_co_ble_set_min_key_size(key_size); + break; + } case ESP_BLE_SM_SET_STATIC_PASSKEY: { uint32_t passkey = 0; for(uint8_t i = 0; i < arg->set_security_param.len; i++) diff --git a/components/bt/bluedroid/common/include/common/bte_appl.h b/components/bt/bluedroid/common/include/common/bte_appl.h index 4810bd6ff4..67f4108358 100644 --- a/components/bt/bluedroid/common/include/common/bte_appl.h +++ b/components/bt/bluedroid/common/include/common/bte_appl.h @@ -31,6 +31,7 @@ typedef struct { UINT8 ble_init_key; UINT8 ble_resp_key; UINT8 ble_max_key_size; + UINT8 ble_min_key_size; UINT8 ble_accept_auth_enable; UINT8 oob_support; #endif @@ -48,4 +49,4 @@ typedef struct { #endif } tBTE_BT_APPL_CFG; -extern tBTE_BT_APPL_CFG bte_bt_appl_cfg; \ No newline at end of file +extern tBTE_BT_APPL_CFG bte_bt_appl_cfg; diff --git a/components/bt/bluedroid/stack/smp/smp_utils.c b/components/bt/bluedroid/stack/smp/smp_utils.c index 19c2cde99b..06ec46203e 100644 --- a/components/bt/bluedroid/stack/smp/smp_utils.c +++ b/components/bt/bluedroid/stack/smp/smp_utils.c @@ -36,6 +36,7 @@ #include "smp_int.h" #include "device/controller.h" #include "btm_int.h" +#include "common/bte_appl.h" #define SMP_PAIRING_REQ_SIZE 7 #define SMP_CONFIRM_CMD_SIZE (BT_OCTET16_LEN + 1) @@ -590,7 +591,7 @@ static BT_HDR *smp_build_id_addr_cmd(UINT8 cmd_code, tSMP_CB *p_cb) p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET; UINT8_TO_STREAM (p, SMP_OPCODE_ID_ADDR); - /* Identity Address Information is used in the Transport Specific Key Distribution phase to distribute + /* Identity Address Information is used in the Transport Specific Key Distribution phase to distribute its public device address or static random address. if slave using static random address is encrypted, it should distribute its static random address */ if(btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type == BLE_ADDR_RANDOM && memcmp(btm_cb.ble_ctr_cb.addr_mgnt_cb.static_rand_addr, btm_cb.ble_ctr_cb.addr_mgnt_cb.private_addr,6) == 0) { @@ -1119,9 +1120,27 @@ BOOLEAN smp_pairing_request_response_parameters_are_valid(tSMP_CB *p_cb) return FALSE; } - if ((enc_size < SMP_ENCR_KEY_SIZE_MIN) || (enc_size > SMP_ENCR_KEY_SIZE_MAX)) { + /* `bte_appl_cfg.ble_min_enc_key_size` will be `SMP_ENCR_KEY_SIZE_MIN` by + * default if not set explicitly */ +#if (BLE_INCLUDED == TRUE) + if (enc_size < bte_appl_cfg.ble_min_key_size) { SMP_TRACE_WARNING("Rcvd from the peer cmd 0x%02x with Maximum Encryption \ - Key value (0x%02x) out of range).\n", + Key value (0x%02x) less than minimum required key size).\n", + p_cb->rcvd_cmd_code, enc_size); + return FALSE; + } +#else + if (enc_size < SMP_ENCR_KEY_SIZE_MIN) { + SMP_TRACE_WARNING("Rcvd from the peer cmd 0x%02x with Maximum Encryption \ + Key value (0x%02x) less than minimum required key size).\n", + p_cb->rcvd_cmd_code, enc_size); + return FALSE; + } +#endif + + if (enc_size > SMP_ENCR_KEY_SIZE_MAX) { + SMP_TRACE_WARNING("Rcvd from the peer cmd 0x%02x with Maximum Encryption \ + Key value (0x%02x) greater than supported by stack).\n", p_cb->rcvd_cmd_code, enc_size); return FALSE; }