X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=stack%2Fsmp%2Fsmp_act.c;h=a986cbd906d032c9fbe99bd1ded4464783766353;hb=4a71fca191b41e5931b35e1b9c3a4b74ab170322;hp=c8fe9b2e1c2ed29f5f9996265c1267059025fe81;hpb=53a3d4c76e57630f66a1d63a7cd9035fbf3474f3;p=android-x86%2Fsystem-bt.git diff --git a/stack/smp/smp_act.c b/stack/smp/smp_act.c index c8fe9b2e1..a986cbd90 100644 --- a/stack/smp/smp_act.c +++ b/stack/smp/smp_act.c @@ -16,14 +16,18 @@ * ******************************************************************************/ +#include #include #include "device/include/interop.h" #include "include/bt_target.h" #include "stack/btm/btm_int.h" #include "stack/include/l2c_api.h" +#include "stack/smp/p_256_ecc_pp.h" #include "stack/smp/smp_int.h" #include "utils/include/bt_utils.h" +extern fixed_queue_t *btu_general_alarm_queue; + #if SMP_INCLUDED == TRUE const UINT8 smp_association_table[2][SMP_IO_CAP_MAX][SMP_IO_CAP_MAX] = { @@ -63,6 +67,42 @@ static bool lmp_version_below(BD_ADDR bda, uint8_t version) return acl->lmp_version < version; } +static bool pts_test_send_authentication_complete_failure(tSMP_CB *p_cb) +{ + uint8_t reason = 0; + + if (p_cb->cert_failure < 2 || p_cb->cert_failure > 6) + return false; + + SMP_TRACE_ERROR("%s failure case = %d", __func__, p_cb->cert_failure); + + switch (p_cb->cert_failure) + { + case 2: + reason = SMP_PAIR_AUTH_FAIL; + smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason); + break; + case 3: + reason = SMP_PAIR_FAIL_UNKNOWN; + smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason); + break; + case 4: + reason = SMP_PAIR_NOT_SUPPORT; + smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason); + break; + case 5: + reason = SMP_PASSKEY_ENTRY_FAIL; + smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason); + break; + case 6: + reason = SMP_REPEATED_ATTEMPTS; + smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason); + break; + } + + return true;; +} + /******************************************************************************* ** Function smp_update_key_mask ** Description This function updates the key mask for sending or receiving. @@ -358,7 +398,7 @@ void smp_send_keypress_notification(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) *******************************************************************************/ void smp_send_enc_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) { - tBTM_LE_LENC_KEYS le_key; + tBTM_LE_KEY_VALUE key; SMP_TRACE_DEBUG("%s p_cb->loc_enc_size = %d", __func__, p_cb->loc_enc_size); smp_update_key_mask (p_cb, SMP_SEC_KEY_TYPE_ENC, FALSE); @@ -367,14 +407,13 @@ void smp_send_enc_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) smp_send_cmd(SMP_OPCODE_MASTER_ID, p_cb); /* save the DIV and key size information when acting as slave device */ - memcpy(le_key.ltk, p_cb->ltk, BT_OCTET16_LEN); - le_key.div = p_cb->div; - le_key.key_size = p_cb->loc_enc_size; - le_key.sec_level = p_cb->sec_level; + memcpy(key.lenc_key.ltk, p_cb->ltk, BT_OCTET16_LEN); + key.lenc_key.div = p_cb->div; + key.lenc_key.key_size = p_cb->loc_enc_size; + key.lenc_key.sec_level = p_cb->sec_level; if ((p_cb->peer_auth_req & SMP_AUTH_BOND) && (p_cb->loc_auth_req & SMP_AUTH_BOND)) - btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_LENC, - (tBTM_LE_KEY_VALUE *)&le_key, TRUE); + btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_LENC, &key, TRUE); SMP_TRACE_WARNING ("%s", __func__); @@ -408,17 +447,17 @@ void smp_send_id_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) *******************************************************************************/ void smp_send_csrk_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) { - tBTM_LE_LCSRK_KEYS key; + tBTM_LE_KEY_VALUE key; SMP_TRACE_DEBUG("%s", __func__); smp_update_key_mask (p_cb, SMP_SEC_KEY_TYPE_CSRK, FALSE); if (smp_send_cmd(SMP_OPCODE_SIGN_INFO, p_cb)) { - key.div = p_cb->div; - key.sec_level = p_cb->sec_level; - key.counter = 0; /* initialize the local counter */ - memcpy (key.csrk, p_cb->csrk, BT_OCTET16_LEN); - btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_LCSRK, (tBTM_LE_KEY_VALUE *)&key, TRUE); + key.lcsrk_key.div = p_cb->div; + key.lcsrk_key.sec_level = p_cb->sec_level; + key.lcsrk_key.counter = 0; /* initialize the local counter */ + memcpy (key.lcsrk_key.csrk, p_cb->csrk, BT_OCTET16_LEN); + btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_LCSRK, &key, TRUE); } smp_key_distribution_by_transport(p_cb, NULL); @@ -517,6 +556,9 @@ void smp_proc_pair_fail(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) { SMP_TRACE_DEBUG("%s", __func__); p_cb->status = *(UINT8 *)p_data; + + /* Cancel pending auth complete timer if set */ + alarm_cancel(p_cb->delayed_auth_timer_ent); } /******************************************************************************* @@ -550,6 +592,10 @@ void smp_proc_pair_cmd(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) return; } + // PTS Testing failure modes + if (pts_test_send_authentication_complete_failure(p_cb)) + return; + if (p_cb->role == HCI_ROLE_SLAVE) { if (!(p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD)) @@ -705,6 +751,17 @@ void smp_process_pairing_public_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) STREAM_TO_ARRAY(p_cb->peer_publ_key.x, p, BT_OCTET32_LEN); STREAM_TO_ARRAY(p_cb->peer_publ_key.y, p, BT_OCTET32_LEN); + + Point pt; + memcpy(pt.x, p_cb->peer_publ_key.x, BT_OCTET32_LEN); + memcpy(pt.y, p_cb->peer_publ_key.y, BT_OCTET32_LEN); + + if (!ECC_ValidatePoint(&pt)) { + android_errorWriteLog(0x534e4554, "72377774"); + smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason); + return; + } + p_cb->flags |= SMP_PAIR_FLAG_HAVE_PEER_PUBL_KEY; smp_wait_for_both_public_keys(p_cb, NULL); @@ -770,14 +827,18 @@ void smp_process_keypress_notification(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) UINT8 reason = SMP_INVALID_PARAMETERS; SMP_TRACE_DEBUG("%s", __func__); - p_cb->status = *(UINT8 *)p_data; if (smp_command_has_invalid_parameters(p_cb)) { + if (p_cb->rcvd_cmd_len < 2) { // 1 (opcode) + 1 (Notif Type) bytes + android_errorWriteLog(0x534e4554, "111936834"); + } smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason); return; } + p_cb->status = *(UINT8 *)p_data; + if (p != NULL) { STREAM_TO_UINT8(p_cb->peer_keypress_notification, p); @@ -954,6 +1015,14 @@ void smp_proc_enc_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) UINT8 *p = (UINT8 *)p_data; SMP_TRACE_DEBUG("%s", __func__); + + if (smp_command_has_invalid_parameters(p_cb)) { + uint8_t reason = SMP_INVALID_PARAMETERS; + android_errorWriteLog(0x534e4554, "111937065"); + smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason); + return; + } + STREAM_TO_ARRAY(p_cb->ltk, p, BT_OCTET16_LEN); smp_key_distribution(p_cb, NULL); @@ -965,29 +1034,35 @@ void smp_proc_enc_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) void smp_proc_master_id(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) { UINT8 *p = (UINT8 *)p_data; - tBTM_LE_PENC_KEYS le_key; + tBTM_LE_KEY_VALUE le_key; SMP_TRACE_DEBUG("%s", __func__); + + if (p_cb->rcvd_cmd_len < 11) { // 1(Code) + 2(EDIV) + 8(Rand) + android_errorWriteLog(0x534e4554, "111937027"); + SMP_TRACE_ERROR("%s: Invalid command length: %d, should be at least 11", + __func__, p_cb->rcvd_cmd_len); + return; + } + smp_update_key_mask (p_cb, SMP_SEC_KEY_TYPE_ENC, TRUE); - STREAM_TO_UINT16(le_key.ediv, p); - STREAM_TO_ARRAY(le_key.rand, p, BT_OCTET8_LEN ); + STREAM_TO_UINT16(le_key.penc_key.ediv, p); + STREAM_TO_ARRAY(le_key.penc_key.rand, p, BT_OCTET8_LEN ); /* store the encryption keys from peer device */ - memcpy(le_key.ltk, p_cb->ltk, BT_OCTET16_LEN); - le_key.sec_level = p_cb->sec_level; - le_key.key_size = p_cb->loc_enc_size; + memcpy(le_key.penc_key.ltk, p_cb->ltk, BT_OCTET16_LEN); + le_key.penc_key.sec_level = p_cb->sec_level; + le_key.penc_key.key_size = p_cb->loc_enc_size; if ((p_cb->peer_auth_req & SMP_AUTH_BOND) && (p_cb->loc_auth_req & SMP_AUTH_BOND)) - btm_sec_save_le_key(p_cb->pairing_bda, - BTM_LE_KEY_PENC, - (tBTM_LE_KEY_VALUE *)&le_key, TRUE); + btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_PENC, &le_key, TRUE); smp_key_distribution(p_cb, NULL); } /******************************************************************************* -** Function smp_proc_enc_info +** Function smp_proc_id_info ** Description process identity information from peer device *******************************************************************************/ void smp_proc_id_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) @@ -995,6 +1070,14 @@ void smp_proc_id_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) UINT8 *p = (UINT8 *)p_data; SMP_TRACE_DEBUG("%s", __func__); + + if (smp_command_has_invalid_parameters(p_cb)) { + uint8_t reason = SMP_INVALID_PARAMETERS; + android_errorWriteLog(0x534e4554, "111937065"); + smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason); + return; + } + STREAM_TO_ARRAY (p_cb->tk, p, BT_OCTET16_LEN); /* reuse TK for IRK */ smp_key_distribution_by_transport(p_cb, NULL); } @@ -1006,24 +1089,23 @@ void smp_proc_id_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) void smp_proc_id_addr(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) { UINT8 *p = (UINT8 *)p_data; - tBTM_LE_PID_KEYS pid_key; + tBTM_LE_KEY_VALUE pid_key; SMP_TRACE_DEBUG("%s", __func__); smp_update_key_mask (p_cb, SMP_SEC_KEY_TYPE_ID, TRUE); - STREAM_TO_UINT8(pid_key.addr_type, p); - STREAM_TO_BDADDR(pid_key.static_addr, p); - memcpy(pid_key.irk, p_cb->tk, BT_OCTET16_LEN); + STREAM_TO_UINT8(pid_key.pid_key.addr_type, p); + STREAM_TO_BDADDR(pid_key.pid_key.static_addr, p); + memcpy(pid_key.pid_key.irk, p_cb->tk, BT_OCTET16_LEN); /* to use as BD_ADDR for lk derived from ltk */ p_cb->id_addr_rcvd = TRUE; - p_cb->id_addr_type = pid_key.addr_type; - memcpy(p_cb->id_addr, pid_key.static_addr, BD_ADDR_LEN); + p_cb->id_addr_type = pid_key.pid_key.addr_type; + memcpy(p_cb->id_addr, pid_key.pid_key.static_addr, BD_ADDR_LEN); /* store the ID key from peer device */ if ((p_cb->peer_auth_req & SMP_AUTH_BOND) && (p_cb->loc_auth_req & SMP_AUTH_BOND)) - btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_PID, - (tBTM_LE_KEY_VALUE *)&pid_key, TRUE); + btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_PID, &pid_key, TRUE); smp_key_distribution_by_transport(p_cb, NULL); } @@ -1033,20 +1115,18 @@ void smp_proc_id_addr(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) *******************************************************************************/ void smp_proc_srk_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) { - tBTM_LE_PCSRK_KEYS le_key; + tBTM_LE_KEY_VALUE le_key; SMP_TRACE_DEBUG("%s", __func__); smp_update_key_mask (p_cb, SMP_SEC_KEY_TYPE_CSRK, TRUE); /* save CSRK to security record */ - le_key.sec_level = p_cb->sec_level; - memcpy (le_key.csrk, p_data, BT_OCTET16_LEN); /* get peer CSRK */ - le_key.counter = 0; /* initialize the peer counter */ + le_key.pcsrk_key.sec_level = p_cb->sec_level; + memcpy (le_key.pcsrk_key.csrk, p_data, BT_OCTET16_LEN); /* get peer CSRK */ + le_key.pcsrk_key.counter = 0; /* initialize the peer counter */ if ((p_cb->peer_auth_req & SMP_AUTH_BOND) && (p_cb->loc_auth_req & SMP_AUTH_BOND)) - btm_sec_save_le_key(p_cb->pairing_bda, - BTM_LE_KEY_PCSRK, - (tBTM_LE_KEY_VALUE *)&le_key, TRUE); + btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_PCSRK, &le_key, TRUE); smp_key_distribution_by_transport(p_cb, NULL); } @@ -1247,7 +1327,6 @@ void smp_key_pick_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) *******************************************************************************/ void smp_key_distribution(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) { - UINT8 reason = SMP_SUCCESS; SMP_TRACE_DEBUG("%s role=%d (0-master) r_keys=0x%x i_keys=0x%x", __func__, p_cb->role, p_cb->local_r_key, p_cb->local_i_key); @@ -1269,9 +1348,22 @@ void smp_key_distribution(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) } if (p_cb->total_tx_unacked == 0) - smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason); - else + { + /* + * Instead of declaring authorization complete immediately, + * delay the event from being sent by SMP_DELAYED_AUTH_TIMEOUT_MS. + * This allows the slave to send over Pairing Failed if the + * last key is rejected. During this waiting window, the + * state should remain in SMP_STATE_BOND_PENDING. + */ + if (!alarm_is_scheduled(p_cb->delayed_auth_timer_ent)) { + SMP_TRACE_DEBUG("%s delaying auth complete.", __func__); + alarm_set_on_queue(p_cb->delayed_auth_timer_ent, SMP_DELAYED_AUTH_TIMEOUT_MS, + smp_delayed_auth_complete_timeout, NULL, btu_general_alarm_queue); + } + } else { p_cb->wait_for_authorization_complete = TRUE; + } } } } @@ -1403,6 +1495,11 @@ void smp_process_io_response(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) { if (smp_request_oob_data(p_cb)) return; } + + // PTS Testing failure modes + if (pts_test_send_authentication_complete_failure(p_cb)) + return; + smp_send_pair_rsp(p_cb, NULL); } } @@ -1440,8 +1537,6 @@ void smp_pairing_cmpl(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) { if (p_cb->total_tx_unacked == 0) { - /* update connection parameter to remote preferred */ - L2CA_EnableUpdateBleConnParams(p_cb->pairing_bda, TRUE); /* process the pairing complete */ smp_proc_pairing_cmpl(p_cb); } @@ -1480,8 +1575,11 @@ void smp_idle_terminate(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) *******************************************************************************/ void smp_fast_conn_param(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) { - /* disable connection parameter update */ - L2CA_EnableUpdateBleConnParams(p_cb->pairing_bda, FALSE); + /* Disable L2CAP connection parameter updates while bonding since + some peripherals are not able to revert to fast connection parameters + during the start of service discovery. Connection paramter updates + get enabled again once service discovery completes. */ + L2CA_EnableUpdateBleConnParams(p_cb->pairing_bda, false); } /******************************************************************************* @@ -1638,6 +1736,14 @@ void smp_process_peer_nonce(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) SMP_TRACE_DEBUG("%s start ", __func__); + // PTS Testing failure modes + if (p_cb->cert_failure == 1) { + SMP_TRACE_ERROR("%s failure case = %d", __func__, p_cb->cert_failure); + reason = p_cb->failure = SMP_CONFIRM_VALUE_ERR; + smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason); + return; + } + switch(p_cb->selected_association_model) { case SMP_MODEL_SEC_CONN_JUSTWORKS: @@ -1671,7 +1777,7 @@ void smp_process_peer_nonce(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) break; case SMP_MODEL_SEC_CONN_PASSKEY_ENT: case SMP_MODEL_SEC_CONN_PASSKEY_DISP: - if (!smp_check_commitment(p_cb)) + if (!smp_check_commitment(p_cb) && p_cb->cert_failure != 9) { reason = p_cb->failure = SMP_CONFIRM_VALUE_ERR; smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);