gap: support classic OOB pairing

new gap_ssp_remote_oob_data allows to report receive OOB data
set OOB data flag in IO Capabilities reply
respond to remote oob data request
This commit is contained in:
Matthias Ringwald 2021-02-04 15:40:54 +01:00
parent f21849cb27
commit 1849becd40
5 changed files with 99 additions and 4 deletions

View File

@ -738,6 +738,16 @@ int gap_ssp_confirmation_response(const bd_addr_t addr);
*/
int gap_ssp_confirmation_negative(const bd_addr_t addr);
/**
* @brief Report Remote OOB Data
* @param bd_addr
* @param c_192 Simple Pairing Hash C derived from P-192 public key
* @param r_192 Simple Pairing Randomizer derived from P-192 public key
* @param c_256 Simple Pairing Hash C derived from P-256 public key
* @param r_256 Simple Pairing Randomizer derived from P-256 public key
*/
uint8_t gap_ssp_remote_oob_data(const bd_addr_t addr, const uint8_t * c_192, const uint8_t * r_192, const uint8_t * c_256, const uint8_t * r_256);
/**
* @brief Enter Sniff mode
* @param con_handle

View File

@ -2155,6 +2155,7 @@ static void handle_command_complete_event(uint8_t * packet, uint16_t size){
}
break;
#endif
default:
break;
}
@ -2557,7 +2558,14 @@ static void event_handler(uint8_t *packet, uint16_t size){
hci_add_connection_flags_for_flipped_bd_addr(&packet[2], RECV_IO_CAPABILITIES_REQUEST);
hci_add_connection_flags_for_flipped_bd_addr(&packet[2], SEND_IO_CAPABILITIES_REPLY);
break;
#ifdef ENABLE_CLASSIC_PAIRING_OOB
case HCI_EVENT_REMOTE_OOB_DATA_REQUEST:
hci_add_connection_flags_for_flipped_bd_addr(&packet[2], SSP_PAIRING_ACTIVE);
hci_add_connection_flags_for_flipped_bd_addr(&packet[2], SEND_REMOTE_OOB_DATA_REPLY);
break;
#endif
case HCI_EVENT_USER_CONFIRMATION_REQUEST:
hci_add_connection_flags_for_flipped_bd_addr(&packet[2], SSP_PAIRING_ACTIVE);
if (!hci_stack->ssp_auto_accept) break;
@ -2569,6 +2577,7 @@ static void event_handler(uint8_t *packet, uint16_t size){
if (!hci_stack->ssp_auto_accept) break;
hci_add_connection_flags_for_flipped_bd_addr(&packet[2], SEND_USER_PASSKEY_REPLY);
break;
case HCI_EVENT_MODE_CHANGE:
handle = hci_event_mode_change_get_handle(packet);
conn = hci_connection_for_handle(handle);
@ -4181,13 +4190,56 @@ static bool hci_run_general_pending_commands(void){
if (gap_mitm_protection_required_for_security_level(connection->requested_security_level)){
authreq |= 1;
}
hci_send_cmd(&hci_io_capability_request_reply, &connection->address, hci_stack->ssp_io_capability, NULL, authreq);
uint8_t have_oob_data = 0;
#ifdef ENABLE_CLASSIC_PAIRING_OOB
if (connection->classic_oob_c_192 != NULL){
have_oob_data |= 1;
}
if (connection->classic_oob_c_256 != NULL){
have_oob_data |= 2;
}
#endif
hci_send_cmd(&hci_io_capability_request_reply, &connection->address, hci_stack->ssp_io_capability, have_oob_data, authreq);
} else {
hci_send_cmd(&hci_io_capability_request_negative_reply, &connection->address, ERROR_CODE_PAIRING_NOT_ALLOWED);
}
return true;
}
#ifdef ENABLE_CLASSIC_PAIRING_OOB
if (connection->authentication_flags & SEND_REMOTE_OOB_DATA_REPLY){
connectionClearAuthenticationFlags(connection, SEND_REMOTE_OOB_DATA_REPLY);
const uint8_t zero[16] = { 0 };
const uint8_t * r_192 = zero;
const uint8_t * c_192 = zero;
const uint8_t * r_256 = zero;
const uint8_t * c_256 = zero;
// verify P-256 OOB
if ((connection->classic_oob_c_256 != NULL) && ((hci_stack->local_supported_commands[1] & 0x08u) != 0)) {
c_256 = connection->classic_oob_c_256;
if (connection->classic_oob_r_256 != NULL) {
r_256 = connection->classic_oob_r_256;
}
}
// verify P-192 OOB
if ((connection->classic_oob_c_192 != NULL)) {
c_192 = connection->classic_oob_c_192;
if (connection->classic_oob_r_192 != NULL) {
r_192 = connection->classic_oob_r_192;
}
}
// Reply
if (c_256 != zero) {
hci_send_cmd(&hci_remote_oob_extended_data_request_reply, &connection->address, c_192, r_192, c_256, r_256);
} else if (c_192 != zero){
hci_send_cmd(&hci_remote_oob_data_request_reply, &connection->address, c_192, r_192);
} else {
hci_send_cmd(&hci_remote_oob_data_request_negative_reply, &connection->address);
}
return true;
}
#endif
if (connection->authentication_flags & SEND_USER_CONFIRM_REPLY){
connectionClearAuthenticationFlags(connection, SEND_USER_CONFIRM_REPLY);
hci_send_cmd(&hci_user_confirmation_request_reply, &connection->address);
@ -5853,6 +5905,28 @@ int gap_ssp_confirmation_negative(const bd_addr_t addr){
return gap_pairing_set_state_and_run(addr, GAP_PAIRING_STATE_SEND_CONFIRMATION_NEGATIVE);
}
#ifdef ENABLE_CLASSIC_PAIRING_OOB
/**
* @brief Report Remote OOB Data
* @param bd_addr
* @param c_192 Simple Pairing Hash C derived from P-192 public key
* @param r_192 Simple Pairing Randomizer derived from P-192 public key
* @param c_256 Simple Pairing Hash C derived from P-256 public key
* @param r_256 Simple Pairing Randomizer derived from P-256 public key
*/
uint8_t gap_ssp_remote_oob_data(const bd_addr_t addr, const uint8_t * c_192, const uint8_t * r_192, const uint8_t * c_256, const uint8_t * r_256){
hci_connection_t * connection = hci_connection_for_bd_addr_and_type(addr, BD_ADDR_TYPE_ACL);
if (connection == NULL) {
return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
}
connection->classic_oob_c_192 = c_192;
connection->classic_oob_r_192 = r_192;
connection->classic_oob_c_256 = c_256;
connection->classic_oob_r_256 = r_256;
return ERROR_CODE_SUCCESS;
}
#endif
/**
* @brief Set inquiry mode: standard, with RSSI, with RSSI + Extended Inquiry Results. Has to be called before power on.
* @param inquiry_mode see bluetooth_defines.h

View File

@ -199,6 +199,9 @@ typedef enum {
SEND_USER_CONFIRM_REPLY = 0x0200,
SEND_USER_PASSKEY_REPLY = 0x0400,
// Classic OOB
SEND_REMOTE_OOB_DATA_REPLY = 0x0800,
// pairing status
LEGACY_PAIRING_ACTIVE = 0x1000,
SSP_PAIRING_ACTIVE = 0x2000,
@ -595,6 +598,13 @@ typedef struct {
l2cap_state_t l2cap_state;
#endif
#ifdef ENABLE_CLASSIC_PAIRING_OOB
const uint8_t * classic_oob_c_192;
const uint8_t * classic_oob_r_192;
const uint8_t * classic_oob_c_256;
const uint8_t * classic_oob_r_256;
#endif
} hci_connection_t;

View File

@ -869,7 +869,7 @@ const hci_cmd_t hci_write_secure_connections_host_support = {
/**
*/
const hci_cmd_t hci_read_local_extended_oob_data = {
HCI_OPCODE_HCI_READ_LOCAL_EXTENDED_OB_DATA, ""
HCI_OPCODE_HCI_READ_LOCAL_EXTENDED_OOB_DATA, ""
// return status, C_192, R_192, R_256, C_256
};

View File

@ -163,7 +163,7 @@ typedef enum {
HCI_OPCODE_HCI_READ_LE_HOST_SUPPORTED = HCI_OPCODE (OGF_CONTROLLER_BASEBAND, 0x6c),
HCI_OPCODE_HCI_WRITE_LE_HOST_SUPPORTED = HCI_OPCODE (OGF_CONTROLLER_BASEBAND, 0x6d),
HCI_OPCODE_HCI_WRITE_SECURE_CONNECTIONS_HOST_SUPPORT = HCI_OPCODE (OGF_CONTROLLER_BASEBAND, 0x7a),
HCI_OPCODE_HCI_READ_LOCAL_EXTENDED_OB_DATA = HCI_OPCODE (OGF_CONTROLLER_BASEBAND, 0x7d),
HCI_OPCODE_HCI_READ_LOCAL_EXTENDED_OOB_DATA = HCI_OPCODE (OGF_CONTROLLER_BASEBAND, 0x7d),
HCI_OPCODE_HCI_READ_LOOPBACK_MODE = HCI_OPCODE (OGF_TESTING, 0x01),
HCI_OPCODE_HCI_WRITE_LOOPBACK_MODE = HCI_OPCODE (OGF_TESTING, 0x02),
HCI_OPCODE_HCI_ENABLE_DEVICE_UNDER_TEST_MODE = HCI_OPCODE (OGF_TESTING, 0x03),
@ -286,6 +286,7 @@ extern const hci_cmd_t hci_remote_name_request;
extern const hci_cmd_t hci_remote_name_request_cancel;
extern const hci_cmd_t hci_remote_oob_data_request_negative_reply;
extern const hci_cmd_t hci_remote_oob_data_request_reply;
extern const hci_cmd_t hci_remote_oob_extended_data_request_reply;
extern const hci_cmd_t hci_reset;
extern const hci_cmd_t hci_role_discovery;
extern const hci_cmd_t hci_set_connection_encryption;