This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Resolving private resolvable addresses

Is there a way to resolve a private resolvable address on connection? I have all the bonding information, IRKs etc, from everything which I'm bonded with, I'd like to work out at connection time who's connected to me. With public addresses it's easy, you compare them, with the resolvable ones it's not, you need to compute each of the IRK hashes with the first 24 bits and see if the rest of the address matches.

The AAR would do the job for me but that's blocked when the SD is running and I don't see a user-level function which accesses it for me (unlike for instance the random number generator which is exposed via a sd_ call). I'd prefer not to have to do 128 bit exponentiation mod 2^24 if I can avoid it.

I don't want to whitelist, I want to actually work out whether the private resolvable address I see is someone I've bonded with already, preferably before they start the re-bonding process.

  • Hi RK

    You can try to use some of the functions attached to match a resolvable random address if you already have the IRK. But you would have to iterate over multiple IRK's. The AAR is as you mentioned not accessible when the SD is enabled.

    Here is some functions related to IRK.

    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 match_random_address(ble_gap_addr_t address, uint8_t * p_irk_array)
    {
      ble_gap_addr_t tmp_addr;
    
      if (address.addr_type != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE)
      {
        return false;
      }
    
      memcpy(&tmp_addr.addr[3], &address.addr[3], 3);
    
      generate_address_checksum(&tmp_addr.addr[3], &tmp_addr.addr[0], p_irk_array);
      return (memcmp(address.addr, tmp_addr.addr, sizeof(address.addr)) == 0);
    }
    

    Keep in mind that I have not validated the code with the latest softdevice.

    BR Pål

  • perfect - if I'd read the spec properly and realized it was AES-128 I might have gotten further with it myself. I can work with those, thanks very much.

Related