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

Resolved "private resolvable address" does not match Android tablet (central) MAC address

Hi all,

I use nRF52832-QFAA, S132 2.0.0, SDK 11.0.0, IAR 7.5 under 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, including the IRKs array. 

I have used a few different "resolving" functions, including im_address_resolve() in id_manager.c (belongs to the peer manager in sdk 11).

This example function actually just checks 3 bytes... 

It successfully decrypts the higher 3 bytes of the address and compares it with the original lower 3 bytes.

But...

1) They are not partly nor wholly the Bluetooth MAC address of the Android tablet I am using as central.

2) How do I obtain that address?  I still don't know.

I have also modified the function to handle all 6 bytes...

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

Can someone help?

Thanks,

Gil

Parents
  • This compares the decrypted higher 3 bytes with the original lower 3 bytes:

    #define IM_ADDR_CLEARTEXT_LENGTH    3
    #define IM_ADDR_CIPHERTEXT_LENGTH   3
    #define SOC_ECB_KEY_LENGTH          16
    
    void ah(uint8_t const * p_k, uint8_t const * p_r, uint8_t * p_local_hash)
    {
        ret_code_t err_code;
        nrf_ecb_hal_data_t ecb_hal_data;
        for (uint32_t i = 0; i < SOC_ECB_KEY_LENGTH; i++)
        {
            ecb_hal_data.key[i] = p_k[SOC_ECB_KEY_LENGTH - 1 - i];
        }
        memset(ecb_hal_data.cleartext, 0, SOC_ECB_KEY_LENGTH - IM_ADDR_CLEARTEXT_LENGTH);
    
        for (uint32_t i = 0; i < IM_ADDR_CLEARTEXT_LENGTH; i++)
        {
            ecb_hal_data.cleartext[SOC_ECB_KEY_LENGTH - 1 - i] = p_r[i];
        }
    
        err_code = sd_ecb_block_encrypt(&ecb_hal_data); // Can only return NRF_SUCCESS.
        UNUSED_VARIABLE(err_code);
    
        for (uint32_t i = 0; i < IM_ADDR_CIPHERTEXT_LENGTH; i++)
        {
            p_local_hash[i] = ecb_hal_data.ciphertext[SOC_ECB_KEY_LENGTH - 1 - i];
        }
    }
    
    bool im_address_resolve(ble_gap_addr_t const * p_addr, uint8_t * p_real, ble_gap_irk_t const * p_irk)
    {
        if (p_addr->addr_type != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE)
        {
            return false;
        }
        uint8_t hash[IM_ADDR_CIPHERTEXT_LENGTH];
        uint8_t local_hash[IM_ADDR_CIPHERTEXT_LENGTH];
        uint8_t prand[IM_ADDR_CLEARTEXT_LENGTH];
        memcpy(hash, p_addr->addr, IM_ADDR_CIPHERTEXT_LENGTH);
        memcpy(prand, &p_addr->addr[IM_ADDR_CIPHERTEXT_LENGTH], IM_ADDR_CLEARTEXT_LENGTH);
        ah(p_irk->irk, prand, local_hash);
    
        memcpy(&p_real[IM_ADDR_CIPHERTEXT_LENGTH], local_hash, IM_ADDR_CIPHERTEXT_LENGTH);
        
        return (memcmp(hash, local_hash, IM_ADDR_CIPHERTEXT_LENGTH) == 0);
    }
    

Reply
  • This compares the decrypted higher 3 bytes with the original lower 3 bytes:

    #define IM_ADDR_CLEARTEXT_LENGTH    3
    #define IM_ADDR_CIPHERTEXT_LENGTH   3
    #define SOC_ECB_KEY_LENGTH          16
    
    void ah(uint8_t const * p_k, uint8_t const * p_r, uint8_t * p_local_hash)
    {
        ret_code_t err_code;
        nrf_ecb_hal_data_t ecb_hal_data;
        for (uint32_t i = 0; i < SOC_ECB_KEY_LENGTH; i++)
        {
            ecb_hal_data.key[i] = p_k[SOC_ECB_KEY_LENGTH - 1 - i];
        }
        memset(ecb_hal_data.cleartext, 0, SOC_ECB_KEY_LENGTH - IM_ADDR_CLEARTEXT_LENGTH);
    
        for (uint32_t i = 0; i < IM_ADDR_CLEARTEXT_LENGTH; i++)
        {
            ecb_hal_data.cleartext[SOC_ECB_KEY_LENGTH - 1 - i] = p_r[i];
        }
    
        err_code = sd_ecb_block_encrypt(&ecb_hal_data); // Can only return NRF_SUCCESS.
        UNUSED_VARIABLE(err_code);
    
        for (uint32_t i = 0; i < IM_ADDR_CIPHERTEXT_LENGTH; i++)
        {
            p_local_hash[i] = ecb_hal_data.ciphertext[SOC_ECB_KEY_LENGTH - 1 - i];
        }
    }
    
    bool im_address_resolve(ble_gap_addr_t const * p_addr, uint8_t * p_real, ble_gap_irk_t const * p_irk)
    {
        if (p_addr->addr_type != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE)
        {
            return false;
        }
        uint8_t hash[IM_ADDR_CIPHERTEXT_LENGTH];
        uint8_t local_hash[IM_ADDR_CIPHERTEXT_LENGTH];
        uint8_t prand[IM_ADDR_CLEARTEXT_LENGTH];
        memcpy(hash, p_addr->addr, IM_ADDR_CIPHERTEXT_LENGTH);
        memcpy(prand, &p_addr->addr[IM_ADDR_CIPHERTEXT_LENGTH], IM_ADDR_CLEARTEXT_LENGTH);
        ah(p_irk->irk, prand, local_hash);
    
        memcpy(&p_real[IM_ADDR_CIPHERTEXT_LENGTH], local_hash, IM_ADDR_CIPHERTEXT_LENGTH);
        
        return (memcmp(hash, local_hash, IM_ADDR_CIPHERTEXT_LENGTH) == 0);
    }
    

Children
No Data
Related