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!

  • Hi,

    There is a function called im_address_resolve in id_manager.c (belongs to the peer manager in sdk 11) that you might be able to check against to see if you get the correct address.

    You will only get an IRK match on the connected event if you are using the whitelist and the address matches the whitelist. So enabling the whitelist would also be a way to identify the peer.

    Which address are you checking against by the way? have you stored the identity address?

Reply
  • Hi,

    There is a function called im_address_resolve in id_manager.c (belongs to the peer manager in sdk 11) that you might be able to check against to see if you get the correct address.

    You will only get an IRK match on the connected event if you are using the whitelist and the address matches the whitelist. So enabling the whitelist would also be a way to identify the peer.

    Which address are you checking against by the way? have you stored the identity address?

Children
Related