From 78315a58573f370dd679856042aa32fba14bc84a Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Fri, 8 May 2020 15:49:50 +0200 Subject: [PATCH] GAP: gap_set_security_level sets required security level for incoming and outgoing connections --- CHANGELOG.md | 1 + src/classic/avdtp_sink.c | 2 +- src/classic/avdtp_source.c | 2 +- src/classic/avrcp.c | 2 +- src/classic/avrcp_browsing_controller.c | 2 +- src/classic/avrcp_browsing_target.c | 2 +- src/classic/bnep.c | 2 +- src/classic/bnep.h | 1 + src/classic/hid_device.c | 4 ++-- src/classic/rfcomm.c | 2 +- src/classic/rfcomm.h | 1 + src/gap.h | 15 +++++++++++++-- src/hci.c | 11 +++++++++++ src/hci.h | 1 + src/l2cap.c | 4 ++-- 15 files changed, 39 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c53fefde..b1f6aa397 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Added - example/le_mitm: MITM implementation that forwards ATT PDUs and allows for pairing +- GAP: gap_set_security_level sets required security level for incoming and outgoing connections ### Changed - L2CAP ERTM: send extended features request only once per HCI connection diff --git a/src/classic/avdtp_sink.c b/src/classic/avdtp_sink.c index 162f02202..91dd89f8e 100644 --- a/src/classic/avdtp_sink.c +++ b/src/classic/avdtp_sink.c @@ -120,7 +120,7 @@ void avdtp_sink_init(avdtp_context_t * avdtp_context){ avdtp_sink_context->stream_endpoints_id_counter = 0; avdtp_sink_context->packet_handler = packet_handler; - l2cap_register_service(&packet_handler, BLUETOOTH_PSM_AVDTP, 0xffff, LEVEL_2); + l2cap_register_service(&packet_handler, BLUETOOTH_PSM_AVDTP, 0xffff, gap_get_security_level()); } avdtp_stream_endpoint_t * avdtp_sink_create_stream_endpoint(avdtp_sep_type_t sep_type, avdtp_media_type_t media_type){ diff --git a/src/classic/avdtp_source.c b/src/classic/avdtp_source.c index 57401d5a5..505e1c8df 100644 --- a/src/classic/avdtp_source.c +++ b/src/classic/avdtp_source.c @@ -176,7 +176,7 @@ void avdtp_source_init(avdtp_context_t * avdtp_context){ avdtp_source_context->stream_endpoints_id_counter = 0; avdtp_source_context->packet_handler = packet_handler; - l2cap_register_service(&packet_handler, BLUETOOTH_PSM_AVDTP, 0xffff, LEVEL_2); + l2cap_register_service(&packet_handler, BLUETOOTH_PSM_AVDTP, 0xffff, gap_get_security_level()); } diff --git a/src/classic/avrcp.c b/src/classic/avrcp.c index f11a25a51..923f07509 100644 --- a/src/classic/avrcp.c +++ b/src/classic/avrcp.c @@ -823,7 +823,7 @@ void avrcp_init(void){ connections = NULL; if (l2cap_service_registered) return; - int status = l2cap_register_service(&avrcp_packet_handler, BLUETOOTH_PSM_AVCTP, 0xffff, LEVEL_2); + int status = l2cap_register_service(&avrcp_packet_handler, BLUETOOTH_PSM_AVCTP, 0xffff, gap_get_security_level()); if (status != ERROR_CODE_SUCCESS) return; l2cap_service_registered = 1; } diff --git a/src/classic/avrcp_browsing_controller.c b/src/classic/avrcp_browsing_controller.c index 4fecd3482..82eca3e6c 100644 --- a/src/classic/avrcp_browsing_controller.c +++ b/src/classic/avrcp_browsing_controller.c @@ -695,7 +695,7 @@ static void avrcp_browsing_controller_packet_handler(uint8_t packet_type, uint16 void avrcp_browsing_controller_init(void){ avrcp_controller_context.browsing_packet_handler = avrcp_browsing_controller_packet_handler; - l2cap_register_service(&avrcp_browsing_controller_packet_handler, PSM_AVCTP_BROWSING, 0xffff, LEVEL_2); + l2cap_register_service(&avrcp_browsing_controller_packet_handler, PSM_AVCTP_BROWSING, 0xffff, gap_get_security_level()); } void avrcp_browsing_controller_register_packet_handler(btstack_packet_handler_t callback){ diff --git a/src/classic/avrcp_browsing_target.c b/src/classic/avrcp_browsing_target.c index daa2b1364..069f60384 100644 --- a/src/classic/avrcp_browsing_target.c +++ b/src/classic/avrcp_browsing_target.c @@ -393,7 +393,7 @@ static void avrcp_browsing_target_packet_handler(uint8_t packet_type, uint16_t c void avrcp_browsing_target_init(void){ avrcp_target_context.browsing_packet_handler = avrcp_browsing_target_packet_handler; - l2cap_register_service(&avrcp_browsing_target_packet_handler, PSM_AVCTP_BROWSING, 0xffff, LEVEL_2); + l2cap_register_service(&avrcp_browsing_target_packet_handler, PSM_AVCTP_BROWSING, 0xffff, gap_get_security_level()); } void avrcp_browsing_target_register_packet_handler(btstack_packet_handler_t callback){ diff --git a/src/classic/bnep.c b/src/classic/bnep.c index 389d108ca..9c3bb3770 100644 --- a/src/classic/bnep.c +++ b/src/classic/bnep.c @@ -1567,7 +1567,7 @@ static void bnep_handle_can_send_now(uint16_t l2cap_cid){ /* BNEP BTStack API */ void bnep_init(void) { - bnep_security_level = LEVEL_2; + bnep_security_level = gap_get_security_level(); } void bnep_set_required_security_level(gap_security_level_t security_level) diff --git a/src/classic/bnep.h b/src/classic/bnep.h index a66ed265d..8949a48f2 100644 --- a/src/classic/bnep.h +++ b/src/classic/bnep.h @@ -194,6 +194,7 @@ int bnep_set_multicast_filter(uint16_t bnep_cid, bnep_multi_filter_t *filter, ui /** * @brief Set security level required for incoming connections, need to be called before registering services. + * @deprecated use gap_set_security_level instead */ void bnep_set_required_security_level(gap_security_level_t security_level); diff --git a/src/classic/hid_device.c b/src/classic/hid_device.c index 7749af707..72080ddd7 100644 --- a/src/classic/hid_device.c +++ b/src/classic/hid_device.c @@ -851,8 +851,8 @@ void hid_device_init(uint8_t boot_protocol_mode_supported, uint16_t descriptor_l hci_device_set_report = dummy_set_report; hci_device_report_data = dummy_report_data; - l2cap_register_service(packet_handler, PSM_HID_INTERRUPT, 100, LEVEL_2); - l2cap_register_service(packet_handler, PSM_HID_CONTROL, 100, LEVEL_2); + l2cap_register_service(packet_handler, PSM_HID_INTERRUPT, 100, gap_get_security_level()); + l2cap_register_service(packet_handler, PSM_HID_CONTROL, 100, gap_get_security_level()); } /** diff --git a/src/classic/rfcomm.c b/src/classic/rfcomm.c index 8604523ff..385ff4a47 100644 --- a/src/classic/rfcomm.c +++ b/src/classic/rfcomm.c @@ -2186,7 +2186,7 @@ void rfcomm_init(void){ rfcomm_multiplexers = NULL; rfcomm_services = NULL; rfcomm_channels = NULL; - rfcomm_security_level = LEVEL_2; + rfcomm_security_level = gap_get_security_level(); } void rfcomm_set_required_security_level(gap_security_level_t security_level){ diff --git a/src/classic/rfcomm.h b/src/classic/rfcomm.h index 83a482c00..cb77cc440 100644 --- a/src/classic/rfcomm.h +++ b/src/classic/rfcomm.h @@ -274,6 +274,7 @@ void rfcomm_init(void); /** * @brief Set security level required for incoming connections, need to be called before registering services. + * @deprecated use gap_set_security_level instead */ void rfcomm_set_required_security_level(gap_security_level_t security_level); diff --git a/src/gap.h b/src/gap.h index f0e58de7c..c96d6088d 100644 --- a/src/gap.h +++ b/src/gap.h @@ -188,13 +188,24 @@ void gap_set_bondable_mode(int enabled); */ int gap_get_bondable_mode(void); +/** + * @brief Set security level for all outgoing and incoming connections. Default: LEVEL_2 + * @param security_level + * @note has to be called before services or profiles are initialized + */ +void gap_set_security_level(gap_security_level_t security_level); + +/** + * @brief Get security level + * @return security_level + */ +gap_security_level_t gap_get_security_level(void); + /** * @brief Register filter for rejecting classic connections. Callback will return 1 accept connection, 0 on reject. */ - void gap_register_classic_connection_filter(int (*accept_callback)(bd_addr_t addr)); - /* Configure Secure Simple Pairing */ /** diff --git a/src/hci.c b/src/hci.c index 740443f37..522760a83 100644 --- a/src/hci.c +++ b/src/hci.c @@ -2886,6 +2886,9 @@ void hci_init(const hci_transport_t *transport, const void *config){ // Allow Role Switch hci_stack->allow_role_switch = 1; + // Default / minimum security level = 2 + hci_stack->gap_security_level = LEVEL_2; + // Errata-11838 mandates 7 bytes for GAP Security Level 1-3, we use 16 as default hci_stack->gap_required_encyrption_key_size = 16; #endif @@ -2982,6 +2985,14 @@ void gap_set_required_encryption_key_size(uint8_t encryption_key_size){ if (encryption_key_size > 16) return; hci_stack->gap_required_encyrption_key_size = encryption_key_size; } + +void gap_set_security_level(gap_security_level_t security_level){ + hci_stack->gap_security_level = security_level; +} + +gap_security_level_t gap_get_security_level(void){ + return hci_stack->gap_security_level; +} #endif #ifdef ENABLE_CLASSIC diff --git a/src/hci.h b/src/hci.h index 1e1e1328c..1c38d6681 100644 --- a/src/hci.h +++ b/src/hci.h @@ -771,6 +771,7 @@ typedef struct { // Errata-11838 mandates 7 bytes for GAP Security Level 1-3, we use 16 as default uint8_t gap_required_encyrption_key_size; uint16_t link_supervision_timeout; + gap_security_level_t gap_security_level; #endif // single buffer for HCI packet assembly + additional prebuffer for H4 drivers diff --git a/src/l2cap.c b/src/l2cap.c index 01a12f431..41e8c3008 100644 --- a/src/l2cap.c +++ b/src/l2cap.c @@ -1925,8 +1925,8 @@ static void l2cap_handle_remote_supported_features_received(l2cap_channel_t * ch if (l2cap_security_level_0_allowed_for_PSM(channel->psm) == 0){ // request security level 2 channel->state = L2CAP_STATE_WAIT_OUTGOING_SECURITY_LEVEL_UPDATE; - channel->required_security_level = LEVEL_2; - gap_request_security_level(channel->con_handle, LEVEL_2); + channel->required_security_level = gap_get_security_level(); + gap_request_security_level(channel->con_handle, gap_get_security_level()); return; }