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?

  • Hi Runar

    The Android tablet's Bluetooth MAC address is 80 4E 70 0F 05 9C

    The passed structure:

    The received randomized address is (ten 00 then) 7E 82 66 88 8F D8

    The received key is 25 29 EF 50 0B 2C 45 66 85 16 95 65 0C D3 AE 1C

    The result is (ten "don't care" then) 00 8B D1 34 EA BF .. which does not match the MAC Disappointed

    I will try the im_address_resolve() that you suggested and will let you know... Thanks!

    Cheers,

    Gil

Reply
  • Hi Runar

    The Android tablet's Bluetooth MAC address is 80 4E 70 0F 05 9C

    The passed structure:

    The received randomized address is (ten 00 then) 7E 82 66 88 8F D8

    The received key is 25 29 EF 50 0B 2C 45 66 85 16 95 65 0C D3 AE 1C

    The result is (ten "don't care" then) 00 8B D1 34 EA BF .. which does not match the MAC Disappointed

    I will try the im_address_resolve() that you suggested and will let you know... Thanks!

    Cheers,

    Gil

Children
No Data
Related