Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5b245db6 authored by Jakub Pawlowski's avatar Jakub Pawlowski Committed by android-build-merger
Browse files

Fix buffer overflow in btif_dm_data_copy

am: 4664aad7

Change-Id: Icc0b739672cf0683edf9bfc5d8244b1ceb87a1b6
parents 4e77d15f 4664aad7
Loading
Loading
Loading
Loading
+31 −36
Original line number Diff line number Diff line
@@ -332,7 +332,7 @@ void smp_send_keypress_notification(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
 * Description  send encryption information command.
 ******************************************************************************/
void smp_send_enc_info(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
  tBTM_LE_LENC_KEYS le_key;
  tBTM_LE_KEY_VALUE 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);
@@ -341,15 +341,14 @@ 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(le_key.lenc_key.ltk, p_cb->ltk, BT_OCTET16_LEN);
  le_key.lenc_key.div = p_cb->div;
  le_key.lenc_key.key_size = p_cb->loc_enc_size;
  le_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, &le_key, true);

  SMP_TRACE_WARNING("%s", __func__);

@@ -381,17 +380,16 @@ void smp_send_id_info(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
 * Description  send CSRK command.
 ******************************************************************************/
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);
@@ -907,7 +905,7 @@ 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_t* p = (uint8_t*)p_data;
  tBTM_LE_PENC_KEYS le_key;
  tBTM_LE_KEY_VALUE le_key;

  SMP_TRACE_DEBUG("%s", __func__);

@@ -920,18 +918,17 @@ void smp_proc_master_id(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {

  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);
}
@@ -962,25 +959,24 @@ 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_t* p = (uint8_t*)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);
}

@@ -989,21 +985,20 @@ void smp_proc_id_addr(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
 * Description  process security information from peer device
 ******************************************************************************/
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;
  maybe_non_aligned_memcpy(le_key.csrk, p_data,
  le_key.pcsrk_key.sec_level = p_cb->sec_level;
  maybe_non_aligned_memcpy(le_key.pcsrk_key.csrk, p_data,
                           BT_OCTET16_LEN);    /* get peer CSRK */
  le_key.counter = 0;                          /* initialize the peer counter */
  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);
}

+13 −15
Original line number Diff line number Diff line
@@ -1431,25 +1431,23 @@ bool smp_check_commitment(tSMP_CB* p_cb) {
 *
 ******************************************************************************/
void smp_save_secure_connections_long_term_key(tSMP_CB* p_cb) {
  tBTM_LE_LENC_KEYS lle_key;
  tBTM_LE_PENC_KEYS ple_key;
  tBTM_LE_KEY_VALUE lle_key;
  tBTM_LE_KEY_VALUE ple_key;

  SMP_TRACE_DEBUG("%s-Save LTK as local LTK key", __func__);
  memcpy(lle_key.ltk, p_cb->ltk, BT_OCTET16_LEN);
  lle_key.div = 0;
  lle_key.key_size = p_cb->loc_enc_size;
  lle_key.sec_level = p_cb->sec_level;
  btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_LENC,
                      (tBTM_LE_KEY_VALUE*)&lle_key, true);
  memcpy(lle_key.lenc_key.ltk, p_cb->ltk, BT_OCTET16_LEN);
  lle_key.lenc_key.div = 0;
  lle_key.lenc_key.key_size = p_cb->loc_enc_size;
  lle_key.lenc_key.sec_level = p_cb->sec_level;
  btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_LENC, &lle_key, true);

  SMP_TRACE_DEBUG("%s-Save LTK as peer LTK key", __func__);
  ple_key.ediv = 0;
  memset(ple_key.rand, 0, BT_OCTET8_LEN);
  memcpy(ple_key.ltk, p_cb->ltk, BT_OCTET16_LEN);
  ple_key.sec_level = p_cb->sec_level;
  ple_key.key_size = p_cb->loc_enc_size;
  btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_PENC,
                      (tBTM_LE_KEY_VALUE*)&ple_key, true);
  ple_key.penc_key.ediv = 0;
  memset(ple_key.penc_key.rand, 0, BT_OCTET8_LEN);
  memcpy(ple_key.penc_key.ltk, p_cb->ltk, BT_OCTET16_LEN);
  ple_key.penc_key.sec_level = p_cb->sec_level;
  ple_key.penc_key.key_size = p_cb->loc_enc_size;
  btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_PENC, &ple_key, true);
}

/*******************************************************************************