Commit message: None
CVE: CVE-2018-9510
CWE: CWE-200
Vulnerability description: In smp_proc_enc_info of smp_act.cc, there is a possible out of bounds read due to a missing bounds check. This could lead to remote information disclosure over Bluetooth with no additional execution privileges needed. User interaction is not needed for exploitation. Product: Android Versions: Android-7.0 Android-7.1.1 Android-7.1.2 Android-8.0 Android-8.1 Android-9.0 Android ID: A-111937065

Project: Android

static bool pts_test_send_authentication_complete_failure(tSMP_CB* p_cb) {
 uint8_t reason = p_cb->cert_failure;
 if (reason == SMP_PAIR_AUTH_FAIL || reason == SMP_PAIR_FAIL_UNKNOWN ||
      reason == SMP_PAIR_NOT_SUPPORT || reason == SMP_PASSKEY_ENTRY_FAIL ||
      reason == SMP_REPEATED_ATTEMPTS) {
    tSMP_INT_DATA smp_int_data;
    smp_int_data.status = reason;
    smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
 return true;
 }
 return false;
}

Project: Android

void smp_both_have_public_keys(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
  SMP_TRACE_DEBUG("%s", __func__);

 /* invokes DHKey computation */
  smp_compute_dhkey(p_cb);

 /* on slave side invokes sending local public key to the peer */
 if (p_cb->role == HCI_ROLE_SLAVE) smp_send_pair_public_key(p_cb, NULL);

  smp_sm_event(p_cb, SMP_SC_DHKEY_CMPLT_EVT, NULL);
}

Project: Android

void smp_br_check_authorization_request(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
  SMP_TRACE_DEBUG("%s rcvs i_keys=0x%x r_keys=0x%x (i-initiator r-responder)",
                  __func__, p_cb->local_i_key, p_cb->local_r_key);

 /* In LE SC mode LK field is ignored when BR/EDR transport is used */
  p_cb->local_i_key &= ~SMP_SEC_KEY_TYPE_LK;
  p_cb->local_r_key &= ~SMP_SEC_KEY_TYPE_LK;

 /* In LE SC mode only IRK, IAI, CSRK are exchanged with the peer.
  ** Set local_r_key on master to expect only these keys. */
 if (p_cb->role == HCI_ROLE_MASTER) {
    p_cb->local_r_key &= (SMP_SEC_KEY_TYPE_ID | SMP_SEC_KEY_TYPE_CSRK);
 }

 /* Check if H7 function needs to be used for key derivation*/
 if ((p_cb->loc_auth_req & SMP_H7_SUPPORT_BIT) &&
 (p_cb->peer_auth_req & SMP_H7_SUPPORT_BIT)) {
    p_cb->key_derivation_h7_used = TRUE;
 }
  SMP_TRACE_DEBUG("%s: use h7 = %d", __func__, p_cb->key_derivation_h7_used);

  SMP_TRACE_DEBUG(
 "%s rcvs upgrades: i_keys=0x%x r_keys=0x%x (i-initiator r-responder)",
      __func__, p_cb->local_i_key, p_cb->local_r_key);

 if (/*((p_cb->peer_auth_req & SMP_AUTH_BOND) ||
          (p_cb->loc_auth_req & SMP_AUTH_BOND)) &&*/
 (p_cb->local_i_key || p_cb->local_r_key)) {
    smp_br_state_machine_event(p_cb, SMP_BR_BOND_REQ_EVT, NULL);

 /* if no peer key is expected, start master key distribution */
 if (p_cb->role == HCI_ROLE_MASTER && p_cb->local_r_key == 0)
      smp_key_distribution_by_transport(p_cb, NULL);
 } else {
    tSMP_INT_DATA smp_int_data;
    smp_int_data.status = SMP_SUCCESS;
    smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &smp_int_data);
 }
}

Project: Android

void smp_br_pairing_complete(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
  SMP_TRACE_DEBUG("%s", __func__);

 if (p_cb->total_tx_unacked == 0) {
 /* process the pairing complete */
    smp_proc_pairing_cmpl(p_cb);
 }
}

Project: Android

void smp_fast_conn_param(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
 /* 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);
}

Project: Android

void smp_move_to_secure_connections_phase2(tSMP_CB* p_cb,
                                           tSMP_INT_DATA* p_data) {
  SMP_TRACE_DEBUG("%s", __func__);
  smp_sm_event(p_cb, SMP_SC_PHASE1_CMPLT_EVT, NULL);
}

Project: Android

void smp_send_csrk_info(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
  tBTM_LE_LCSRK_KEYS 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);
 }

  smp_key_distribution_by_transport(p_cb, NULL);
}

Project: Android

void smp_send_enc_info(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
  tBTM_LE_LENC_KEYS le_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);

  smp_send_cmd(SMP_OPCODE_ENCRYPT_INFO, p_cb);
  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;

 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);

  SMP_TRACE_WARNING("%s", __func__);

  smp_key_distribution(p_cb, NULL);
}

Project: Android

void smp_send_keypress_notification(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
  p_cb->local_keypress_notification = p_data->status;
  smp_send_cmd(SMP_OPCODE_PAIR_KEYPR_NOTIF, p_cb);
}

Project: Android

void smp_start_enc(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
  tBTM_STATUS cmd;

  SMP_TRACE_DEBUG("%s", __func__);
 if (p_data != NULL)
    cmd = btm_ble_start_encrypt(p_cb->pairing_bda, true, p_data->key.p_data);
 else
    cmd = btm_ble_start_encrypt(p_cb->pairing_bda, false, NULL);

 if (cmd != BTM_CMD_STARTED && cmd != BTM_BUSY) {
    tSMP_INT_DATA smp_int_data;
    smp_int_data.status = SMP_ENC_FAIL;
    smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
 }
}

Project: Android

static void smp_update_key_mask(tSMP_CB* p_cb, uint8_t key_type, bool recv) {
  SMP_TRACE_DEBUG(
 "%s before update role=%d recv=%d local_i_key = %02x, local_r_key = %02x",
      __func__, p_cb->role, recv, p_cb->local_i_key, p_cb->local_r_key);

 if (((p_cb->le_secure_connections_mode_is_used) || (p_cb->smp_over_br)) &&
 ((key_type == SMP_SEC_KEY_TYPE_ENC) ||
 (key_type == SMP_SEC_KEY_TYPE_LK))) {
 /* in LE SC mode LTK, CSRK and BR/EDR LK are derived locally instead of
    ** being exchanged with the peer */
    p_cb->local_i_key &= ~key_type;
    p_cb->local_r_key &= ~key_type;
 } else if (p_cb->role == HCI_ROLE_SLAVE) {
 if (recv)
      p_cb->local_i_key &= ~key_type;
 else
      p_cb->local_r_key &= ~key_type;
 } else {
 if (recv)
      p_cb->local_r_key &= ~key_type;
 else
      p_cb->local_i_key &= ~key_type;
 }

  SMP_TRACE_DEBUG("updated local_i_key = %02x, local_r_key = %02x",
                  p_cb->local_i_key, p_cb->local_r_key);
}