Just continue my work on implementing LESC MITM on hear_rate_collector (Please check my development environment settings here as well).
Since sd_api_v6 on pc-ble-driver doesn't work with sd_ble_gap_authenticate on PCA10059. I switched to sd_api_v3.
Then sd_ble_gap_authenticate returns OK.
Then I added sd_ble_gap_sec_params_reply as such:
diff --git a/examples/heart_rate_collector/main.c b/examples/heart_rate_collector/main.c index 3ee6c9c..8aa379a 100644 --- a/examples/heart_rate_collector/main.c +++ b/examples/heart_rate_collector/main.c @@ -104,6 +104,15 @@ enum #define STRING_BUFFER_SIZE 50 +#define SEC_PARAM_BOND 1 /**< Perform bonding. */ +#define SEC_PARAM_MITM 1 /**< Man In The Middle protection not required. */ +#define SEC_PARAM_LESC 1 /**< LE Secure Connections enabled. */ +#define SEC_PARAM_KEYPRESS 0 /**< Keypress notifications not enabled. */ +#define SEC_PARAM_IO_CAPABILITIES BLE_GAP_IO_CAPS_KEYBOARD_DISPLAY /**< No I/O capabilities. */ +#define SEC_PARAM_OOB 0 /**< Out Of Band data not available. */ +#define SEC_PARAM_MIN_KEY_SIZE 7 /**< Minimum encryption key size. */ +#define SEC_PARAM_MAX_KEY_SIZE 16 /**< Maximum encryption key size. */ + typedef struct { uint8_t * p_data; /**< Pointer to data. */ @@ -166,6 +175,21 @@ static const ble_gap_conn_params_t m_connection_param = (uint16_t)CONNECTION_SUPERVISION_TIMEOUT }; +/** @brief Predefined example public key that is associated with example private key + * @ref alice_raw_private_key. + */ +static const uint8_t m_raw_public_key[] = +{ + 0x02, 0x17, 0xE6, 0x17, 0xF0, 0xB6, 0x44, 0x39, + 0x28, 0x27, 0x8F, 0x96, 0x99, 0x9E, 0x69, 0xA2, + 0x3A, 0x4F, 0x2C, 0x15, 0x2B, 0xDF, 0x6D, 0x6C, + 0xDF, 0x66, 0xE5, 0xB8, 0x02, 0x82, 0xD4, 0xED, + 0x19, 0x4A, 0x7D, 0xEB, 0xCB, 0x97, 0x71, 0x2D, + 0x2D, 0xDA, 0x3C, 0xA8, 0x5A, 0xA8, 0x76, 0x5A, + 0x56, 0xF4, 0x5F, 0xC7, 0x58, 0x59, 0x96, 0x52, + 0xF2, 0x89, 0x7C, 0x65, 0x30, 0x6E, 0x57, 0x94, +}; + /** Global functions */ @@ -608,7 +632,26 @@ static void on_connected(const ble_gap_evt_t * const p_ble_gap_evt) m_connection_handle = p_ble_gap_evt->conn_handle; m_connection_is_in_progress = false; - service_discovery_start(); + ble_gap_sec_params_t m_sec_params; /**< Security requirements for this application. */ + memset(&m_sec_params, 0, sizeof(m_sec_params)); + m_sec_params.bond = SEC_PARAM_BOND; + m_sec_params.mitm = SEC_PARAM_MITM; + m_sec_params.lesc = SEC_PARAM_LESC; + m_sec_params.keypress = SEC_PARAM_KEYPRESS; + m_sec_params.io_caps = SEC_PARAM_IO_CAPABILITIES; + m_sec_params.oob = SEC_PARAM_OOB; + m_sec_params.min_key_size = SEC_PARAM_MIN_KEY_SIZE; + m_sec_params.max_key_size = SEC_PARAM_MAX_KEY_SIZE; + + uint32_t error_code = sd_ble_gap_authenticate(m_adapter, m_connection_handle, &m_sec_params); + if (error_code != NRF_SUCCESS) + { + printf("sd_ble_gap_authenticate failed with error code: 0x%04X\n", error_code); + } else + { + printf("sd_ble_gap_authenticate succeeded\n"); + } + fflush(stdout); } /**@brief Function called on BLE_GAP_EVT_ADV_REPORT event. @@ -686,6 +729,37 @@ static void on_timeout(const ble_gap_evt_t * const p_ble_gap_evt) } } +/**@brief Function called on BLE_GAP_EVT_SEC_PARAMS_REQUEST event. + * + * @param[in] ble_gap_evt_t Security parameters request. + */ +static void on_sec_params_request(const ble_gap_evt_t * const p_ble_gap_evt) +{ + printf("BLE_GAP_EVT_SEC_PARAMS_REQUEST received: "); + ble_gap_sec_keyset_t s_sec_keyset; /**< Security key set for both local and peer keys. */ + memset(&s_sec_keyset, 0, sizeof(s_sec_keyset)); + s_sec_keyset.keys_peer.p_enc_key = NULL; + s_sec_keyset.keys_peer.p_id_key = NULL; + s_sec_keyset.keys_peer.p_sign_key = NULL; + s_sec_keyset.keys_peer.p_pk = NULL; + s_sec_keyset.keys_own.p_enc_key = NULL; + s_sec_keyset.keys_own.p_id_key = NULL; + s_sec_keyset.keys_own.p_sign_key = NULL; + s_sec_keyset.keys_own.p_pk = NULL; + // s_sec_keyset.keys_own.p_pk = &m_raw_public_key; + uint32_t err_code = sd_ble_gap_sec_params_reply(m_adapter, m_connection_handle, + BLE_GAP_SEC_STATUS_SUCCESS, NULL, &s_sec_keyset); + if (err_code != NRF_SUCCESS) + { + printf("Security parameters reply failed, err_code 0x%04X\n", err_code); + } + else + { + printf("Security parameters replied.\n"); + } + fflush(stdout); +} + /**@brief Function called on BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP event. * * @details Update service state and proceed to discovering the service's GATT characteristics. @@ -854,6 +928,36 @@ static void on_hvx(const ble_gattc_evt_t * const p_ble_gattc_evt) fflush(stdout); } +#if NRF_SD_BLE_API >= 5 +/**@brief Function called on BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST event. + * + * @details Data length update request + * + * @param[in] p_ble_gap_evt Data length update request Event. + */ +static void on_conn_data_length_update_request(const ble_gap_evt_t * const p_ble_gap_evt) +{ + printf("BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST received: "); + + ble_gap_data_length_params_t const dlp = + { + .max_rx_octets = 27, /* ref: NRF_SDH_BLE_GAP_DATA_LENGTH in sdk_config.h */ + .max_tx_octets = 27, /* ref: NRF_SDH_BLE_GAP_DATA_LENGTH in sdk_config.h */ + .max_rx_time_us = BLE_GAP_DATA_LENGTH_AUTO, + .max_tx_time_us = BLE_GAP_DATA_LENGTH_AUTO + }; + + ble_gap_data_length_limitation_t dll = { 0 }; + + uint32_t err_code = sd_ble_gap_data_length_update(m_adapter, m_connection_handle, &dlp, &dll); + if (err_code != NRF_SUCCESS) + { + printf("sd_ble_gap_data_length_update failed, err_code %d\n", err_code); + fflush(stdout); + } +} +#endif + /**@brief Function called on BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST event. * * @details Update GAP connection parameters. @@ -951,6 +1055,30 @@ static void ble_evt_dispatch(adapter_t * adapter, ble_evt_t * p_ble_evt) on_timeout(&(p_ble_evt->evt.gap_evt)); break; + case BLE_GAP_EVT_SEC_PARAMS_REQUEST: + on_sec_params_request(&(p_ble_evt->evt.gap_evt)); + break; + + case BLE_GAP_EVT_CONN_SEC_UPDATE: + printf("BLE_GAP_EVT_AUTH_STATUS: status=0x%x bond=0x%x lv4: %d kdist_own:0x%x kdist_peer:0x%x\n", + p_ble_evt->evt.gap_evt.params.auth_status.auth_status, + p_ble_evt->evt.gap_evt.params.auth_status.bonded, + p_ble_evt->evt.gap_evt.params.auth_status.sm1_levels.lv4, + *((uint8_t *)&p_ble_evt->evt.gap_evt.params.auth_status.kdist_own), + *((uint8_t *)&p_ble_evt->evt.gap_evt.params.auth_status.kdist_peer)); + fflush(stdout); + if (p_ble_evt->evt.gap_evt.params.auth_status.auth_status == BLE_GAP_SEC_STATUS_SUCCESS) + { + service_discovery_start(); + } + else + { + printf("Authorization failed with code: %u!\n", + p_ble_evt->evt.gap_evt.params.auth_status.auth_status); + fflush(stdout); + } + break; + case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP: on_service_discovery_response(&(p_ble_evt->evt.gattc_evt)); break; @@ -971,6 +1099,20 @@ static void ble_evt_dispatch(adapter_t * adapter, ble_evt_t * p_ble_evt) on_hvx(&(p_ble_evt->evt.gattc_evt)); break; + case BLE_GAP_EVT_CONN_PARAM_UPDATE: + { + printf("Connection interval updated: 0x%x, 0x%x.\n", + p_ble_evt->evt.gap_evt.params.conn_param_update.conn_params.min_conn_interval, + p_ble_evt->evt.gap_evt.params.conn_param_update.conn_params.max_conn_interval); + fflush(stdout); + } break; + + #if NRF_SD_BLE_API >= 5 + case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST: + on_conn_data_length_update_request(&(p_ble_evt->evt.gap_evt)); + break; + #endif + case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST: on_conn_params_update_request(&(p_ble_evt->evt.gap_evt)); break; @@ -1077,6 +1219,6 @@ int main(int argc, char * argv[]) // Toggle notifications on the HRM characteristic every time user input is received. cccd_value ^= BLE_CCCD_NOTIFY; - hrm_cccd_set(cccd_value); + // hrm_cccd_set(cccd_value); } }
Then I got error 16 which is NRF_ERROR_INVALID_ADDR:
$ ./heart_rate_collector_v3 /dev/ttyACM0 Serial port used: /dev/ttyACM0 Baud rate used: 1000000 Info: Successfully opened /dev/ttyACM0. Baud rate: 1000000. Flow control: none. Parity: none. Status: 6, message: Target Reset performed Status: 7, message: Connection active Scan started Received advertisement report with device address: 0xF69EF1EC5743 Connection established sd_ble_gap_authenticate succeeded BLE_GAP_EVT_SEC_PARAMS_REQUEST received: Security parameters reply failed, err_code 0x0010
I also tried PCA10040 with sd_api_v3 connectivity firmware but got the same error.
BR/Chencheng