Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Resolving random private address ... where is the IRKs array?

Hi all,

I use nRF52832-QFAA, S132 2.0.0, SDK 11.0.0, IAR 7.5, Windows

Upon connection, I am trying to resolve the peer "random private resolvable" address (not for whitelisting, just to check who I am connected to).

I have most information needed, but I don't know where to get the IRKs array.  Can someone help?

Thanks,

Gil

Code is below:

void generate_address_checksum(uint8_t * p_random, uint8_t * p_checksum, uint8_t * p_irk_array)
{
  nrf_ecb_hal_data_t encryption_data = {0};
  uint32_t errcode;
  uint8_t i;

  /* Reverse the array as the ECB expect it in big endian format */
  for (i=0; i<sizeof(encryption_data.key); i++)
  {
    encryption_data.key[i] = p_irk_array[sizeof(encryption_data.key)-1-i];
    if (i < 3)
    {
      encryption_data.cleartext[15-i] = p_random[i];
    }
  }

  errcode = sd_ecb_block_encrypt(&encryption_data);
  if(errcode)
  {
    ASSERT(false);
  }
  
  for (i=0; i<3; i++)
  {
    p_checksum[i] = encryption_data.ciphertext[15-i];
  }
}

bool ble_get_peer_address(ble_gap_addr_t orig_address, ble_gap_addr_t * res_address, uint8_t * p_irk_array)
{
  ble_gap_addr_t tmp_addr;
  bool result = false;

  if (orig_address.addr_type == BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE)
  {
      memcpy(&tmp_addr.addr[3], &orig_address.addr[3], 3);

      generate_address_checksum(&tmp_addr.addr[3], &tmp_addr.addr[0], p_irk_array);
      if (memcmp(orig_address.addr, tmp_addr.addr, sizeof(orig_address.addr)) == 0)
      {
          // Save address
          memcpy(res_address->addr, tmp_addr.addr, sizeof(res_address->addr));
          result = true;
      }
  }
  return result;
}

//-------------------------------------------------------------------------
//
//-------------------------------------------------------------------------
void ble_conn_on_ble_evt(ble_evt_t * p_ble_evt)
{
    ble_gap_addr_t tmp_addr;
    uint8_t *p_irk_array = NULL;
    
    if (p_ble_evt->header.evt_id == BLE_GAP_EVT_CONNECTED)
    {
        // update connection handle
        m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
        // update stats
        g_ble_conn_stats.conn_req++;
        g_ble_conn_stats.last_conn_ticks = get_tickcount();

// Incorrect ... not resolved yet
/*
        g_ble_conn_stats.central_mac0  = p_ble_evt->evt.gap_evt.params.connected.peer_addr.addr[5];
        g_ble_conn_stats.central_mac1  = p_ble_evt->evt.gap_evt.params.connected.peer_addr.addr[4];
        g_ble_conn_stats.central_mac2  = p_ble_evt->evt.gap_evt.params.connected.peer_addr.addr[3];
        g_ble_conn_stats.central_mac3  = p_ble_evt->evt.gap_evt.params.connected.peer_addr.addr[2];
        g_ble_conn_stats.central_mac4  = p_ble_evt->evt.gap_evt.params.connected.peer_addr.addr[1];
        g_ble_conn_stats.central_mac5  = p_ble_evt->evt.gap_evt.params.connected.peer_addr.addr[0];
*/

// Must resolve it first:
        // Match flag
        //p_ble_evt->evt.gap_evt.params.connected.irk_match;
        // Index
        //p_ble_evt->evt.gap_evt.params.connected.irk_match_idx;

        // Missing: Get p_irk_array somewhere!!! Please HELP!!!
        // Then...
        
        if (ble_get_peer_address(p_ble_evt->evt.gap_evt.params.connected.peer_addr,
                                 &tmp_addr, 
                                 p_irk_array))
        {
            g_ble_conn_stats.central_mac0  = tmp_addr.addr[5];
            g_ble_conn_stats.central_mac1  = tmp_addr.addr[4];
            g_ble_conn_stats.central_mac2  = tmp_addr.addr[3];
            g_ble_conn_stats.central_mac3  = tmp_addr.addr[2];
            g_ble_conn_stats.central_mac4  = tmp_addr.addr[1];
            g_ble_conn_stats.central_mac5  = tmp_addr.addr[0];
        }
        else
        {
            g_ble_conn_stats.central_mac0  = 0;
            g_ble_conn_stats.central_mac1  = 0;
            g_ble_conn_stats.central_mac2  = 0;
            g_ble_conn_stats.central_mac3  = 0;
            g_ble_conn_stats.central_mac4  = 0;
            g_ble_conn_stats.central_mac5  = 0;
        }

...

}

Parents
  • Update:

    After reading this post ...

    https://devzone.nordicsemi.com/f/nordic-q-a/9612/reading-irk-and-gap_evt-params-connected-irk_match-issue

    … I realized that I have to wait for BLE_GAP_EVT_SEC_PARAMS_REQUEST and BLE_GAP_EVT_AUTH_STATUS in my dm_ble_evt_handler() function.

    So I moved my code there, and modified it:

    void decypher_address(uint8_t * p_random, uint8_t * p_real, uint8_t * p_irk_array)
    {
      nrf_ecb_hal_data_t encryption_data = {0};
      uint32_t errcode;
      uint8_t i;
    
      /* Reverse the array as the ECB expect it in big endian format */
      for (i=0; i<sizeof(encryption_data.key); i++)
      {
        encryption_data.key[i] = p_irk_array[sizeof(encryption_data.key)-1-i];
        if (i < 6)
        {
          encryption_data.cleartext[15-i] = p_random[i];
        }
      }
    
      errcode = sd_ecb_block_encrypt(&encryption_data);
      if(errcode)
      {
        ASSERT(false);
      }
      
      for (i=0; i<6; i++)
      {
        p_real[i] = encryption_data.ciphertext[15-i];
      }
    }
    
    void dm_ble_evt_handler(ble_evt_t * p_ble_evt)
    {
    
    ...
    
            case BLE_GAP_EVT_AUTH_STATUS:
    
    ...
    
          ble_gap_addr_t tmp_addr;
          uint8_t idx = p_ble_evt->evt.gap_evt.params.connected.irk_match_idx;
    
    //      if (p_ble_evt->evt.gap_evt.params.connected.irk_match)
          {
              decypher_address((uint8_t *)m_connection_table[idx].peer_addr.addr,
                                         tmp_addr.addr, 
                                         m_peer_table[handle.device_id].peer_id.id_info.irk);
    
              g_ble_conn_stats.central_mac0  = tmp_addr.addr[5];
              g_ble_conn_stats.central_mac1  = tmp_addr.addr[4];
              g_ble_conn_stats.central_mac2  = tmp_addr.addr[3];
              g_ble_conn_stats.central_mac3  = tmp_addr.addr[2];
              g_ble_conn_stats.central_mac4  = tmp_addr.addr[1];
              g_ble_conn_stats.central_mac5  = tmp_addr.addr[0];
          }
    /*
          else
          {
              g_ble_conn_stats.central_mac0  = 0;
              g_ble_conn_stats.central_mac1  = 0;
              g_ble_conn_stats.central_mac2  = 0;
              g_ble_conn_stats.central_mac3  = 0;
              g_ble_conn_stats.central_mac4  = 0;
              g_ble_conn_stats.central_mac5  = 0;
          }
    */
    
    ...
    
    }

    Now I know that the IRKs are in m_peer_table[handle.device_id].peer_id.id_info.irk array

    but the resolved MAC address does not match the Android tablet's MAC address. Disappointed

    I have checked that auth_status is BLE_GAP_SEC_STATUS_SUCCESS and addr_type really is BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE

    Please notice that ...

    p_ble_evt->evt.gap_evt.params.connected.irk_match

    and

    p_ble_evt->evt.gap_evt.params.connected.irk_match_idx

    ... are both 0 ... I don't know if that is a problem.

    Thanks!

Reply
  • Update:

    After reading this post ...

    https://devzone.nordicsemi.com/f/nordic-q-a/9612/reading-irk-and-gap_evt-params-connected-irk_match-issue

    … I realized that I have to wait for BLE_GAP_EVT_SEC_PARAMS_REQUEST and BLE_GAP_EVT_AUTH_STATUS in my dm_ble_evt_handler() function.

    So I moved my code there, and modified it:

    void decypher_address(uint8_t * p_random, uint8_t * p_real, uint8_t * p_irk_array)
    {
      nrf_ecb_hal_data_t encryption_data = {0};
      uint32_t errcode;
      uint8_t i;
    
      /* Reverse the array as the ECB expect it in big endian format */
      for (i=0; i<sizeof(encryption_data.key); i++)
      {
        encryption_data.key[i] = p_irk_array[sizeof(encryption_data.key)-1-i];
        if (i < 6)
        {
          encryption_data.cleartext[15-i] = p_random[i];
        }
      }
    
      errcode = sd_ecb_block_encrypt(&encryption_data);
      if(errcode)
      {
        ASSERT(false);
      }
      
      for (i=0; i<6; i++)
      {
        p_real[i] = encryption_data.ciphertext[15-i];
      }
    }
    
    void dm_ble_evt_handler(ble_evt_t * p_ble_evt)
    {
    
    ...
    
            case BLE_GAP_EVT_AUTH_STATUS:
    
    ...
    
          ble_gap_addr_t tmp_addr;
          uint8_t idx = p_ble_evt->evt.gap_evt.params.connected.irk_match_idx;
    
    //      if (p_ble_evt->evt.gap_evt.params.connected.irk_match)
          {
              decypher_address((uint8_t *)m_connection_table[idx].peer_addr.addr,
                                         tmp_addr.addr, 
                                         m_peer_table[handle.device_id].peer_id.id_info.irk);
    
              g_ble_conn_stats.central_mac0  = tmp_addr.addr[5];
              g_ble_conn_stats.central_mac1  = tmp_addr.addr[4];
              g_ble_conn_stats.central_mac2  = tmp_addr.addr[3];
              g_ble_conn_stats.central_mac3  = tmp_addr.addr[2];
              g_ble_conn_stats.central_mac4  = tmp_addr.addr[1];
              g_ble_conn_stats.central_mac5  = tmp_addr.addr[0];
          }
    /*
          else
          {
              g_ble_conn_stats.central_mac0  = 0;
              g_ble_conn_stats.central_mac1  = 0;
              g_ble_conn_stats.central_mac2  = 0;
              g_ble_conn_stats.central_mac3  = 0;
              g_ble_conn_stats.central_mac4  = 0;
              g_ble_conn_stats.central_mac5  = 0;
          }
    */
    
    ...
    
    }

    Now I know that the IRKs are in m_peer_table[handle.device_id].peer_id.id_info.irk array

    but the resolved MAC address does not match the Android tablet's MAC address. Disappointed

    I have checked that auth_status is BLE_GAP_SEC_STATUS_SUCCESS and addr_type really is BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE

    Please notice that ...

    p_ble_evt->evt.gap_evt.params.connected.irk_match

    and

    p_ble_evt->evt.gap_evt.params.connected.irk_match_idx

    ... are both 0 ... I don't know if that is a problem.

    Thanks!

Children
Related