<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Resolve BLE address using Zephry</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/98066/resolve-ble-address-using-zephry</link><description>Hello, 
 I&amp;#39;m using VS Code and Zephyr to develeop a application for the nRF52840. I am currently scanning for devices, however the device i am looking for uses a random private resolvable address. 
 Currently i already have a hardcoded list of IRK values</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Thu, 29 Jun 2023 02:42:26 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/98066/resolve-ble-address-using-zephry" /><item><title>RE: Resolve BLE address using Zephry</title><link>https://devzone.nordicsemi.com/thread/433569?ContentTypeID=1</link><pubDate>Thu, 29 Jun 2023 02:42:26 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:23b2ae10-aac9-4c56-86e9-f67971e6ba1b</guid><dc:creator>John</dc:creator><description>&lt;p&gt;Hi&amp;nbsp;&lt;span&gt;Jarno, really thanks for your sharing.^^&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Resolve BLE address using Zephry</title><link>https://devzone.nordicsemi.com/thread/433442?ContentTypeID=1</link><pubDate>Wed, 28 Jun 2023 11:30:15 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:0ef918e3-3d0e-44e1-845d-a8c5251d583d</guid><dc:creator>Jarno</dc:creator><description>&lt;p&gt;Sure, here is the code i used:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;#include &amp;lt;psa/crypto.h&amp;gt;
#include &amp;lt;psa/crypto_extra.h&amp;gt;

void reverse(uint8_t *p_data, uint8_t len)
{
	uint8_t temp;
	for (uint32_t i = 0; i &amp;lt; len / 2; i++)
	{
		temp = p_data[i];
		p_data[i] = p_data[len - 1 - i];
		p_data[len - 1 - i] = temp;
	}
}

// IRKs
uint8_t irks[NUM_IRKS][16] = {
	{}, // Insert IRKs here
	{}, 
};

psa_key_id_t key_ids[NUM_IRKS];

void setup_key(uint8_t const *key, mbedtls_svc_key_id_t *key_id)
{
	psa_status_t status;
	psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
	psa_set_key_usage_flags(&amp;amp;attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
	psa_set_key_algorithm(&amp;amp;attributes, PSA_ALG_ECB_NO_PADDING);
	psa_set_key_type(&amp;amp;attributes, PSA_KEY_TYPE_AES);
	psa_set_key_bits(&amp;amp;attributes, 16 * 8);
	psa_set_key_lifetime(&amp;amp;attributes, PSA_KEY_LIFETIME_VOLATILE);

	uint8_t ecb_key[16];
	for (uint32_t i = 0; i &amp;lt; 16; i++)
	{
		ecb_key[i] = key[16 - 1 - i];
	}

	status = psa_import_key(&amp;amp;attributes, ecb_key, 16, key_id);
	if (status != PSA_SUCCESS)
	{
		printk(&amp;quot;PSA key import failed\n&amp;quot;);
		return;
	}
}

// Function to perform ECB encryption
void encrypt_ecb(uint8_t *input, uint8_t *output, mbedtls_svc_key_id_t key_id)
{
	size_t ciphertext_size;
	psa_status_t status;

	status = psa_cipher_encrypt(key_id, PSA_ALG_ECB_NO_PADDING, input, 16, output, 16, &amp;amp;ciphertext_size);
	if (status != PSA_SUCCESS)
	{
		printk(&amp;quot;PSA encryption failed\n&amp;quot;);
		return;
	}
}

void ah(mbedtls_svc_key_id_t key_id, uint8_t *p_r, uint8_t *p_local_hash)
{
	uint8_t ecb_plaintext[16];
	uint8_t ecb_ciphertext[16];

	memset(ecb_plaintext, 0, 16 - 3);

	for (uint32_t i = 0; i &amp;lt; 3; i++)
	{
		ecb_plaintext[16 - 1 - i] = p_r[i];
	}

	encrypt_ecb(ecb_plaintext, ecb_ciphertext, key_id);

	for (uint32_t i = 0; i &amp;lt; 3; i++)
	{
		p_local_hash[i] = ecb_ciphertext[16 - 1 - i];
	}
}

int resolve_address(uint8_t *p_addr)
{

	uint8_t hash[3];
	uint8_t local_hash[3];
	uint8_t prand[3];

	memcpy(hash, p_addr, 3);
	memcpy(prand, &amp;amp;p_addr[3], 3);

	for (int i = 0; i &amp;lt; NUM_IRKS; i++)
	{
		ah(key_ids[i], prand, local_hash);
		if (memcmp(hash, local_hash, 3) == 0)
		{
			return i;
		}
	}
	return -1;
}

void main(void)
{

	for (int i = 0; i &amp;lt; NUM_IRKS; i++)
	{
		reverse(irks[i], 16);
		setup_key(irks[i], &amp;amp;key_ids[i]);
	}
	
	// Rest of the main function
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;I took me quite a while to figure this all out, hope this helps you out as well!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Resolve BLE address using Zephry</title><link>https://devzone.nordicsemi.com/thread/433200?ContentTypeID=1</link><pubDate>Tue, 27 Jun 2023 11:25:26 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:b508c041-21b5-4a07-93e9-5d4ae4e95258</guid><dc:creator>John</dc:creator><description>&lt;p&gt;Hi&amp;nbsp;Jarno,&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I also need to check whether the broadcasting&amp;nbsp; &lt;span&gt;random private resolvable &lt;/span&gt;BLE Address is previously bonded peer using&amp;nbsp; VS Code and Zephyr recently.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Could you please share&amp;nbsp;your address_resolve() function for reference?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Resolve BLE address using Zephry</title><link>https://devzone.nordicsemi.com/thread/418567?ContentTypeID=1</link><pubDate>Fri, 31 Mar 2023 11:39:27 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:ba12510b-4ae2-4b42-9a26-26bc5fc323c7</guid><dc:creator>Jarno</dc:creator><description>&lt;p&gt;Thank you very much for the information. I currently have a working implementation by scanning for all devices and resolving the addresses manually. I have implemented the address_resolve() function myself with inspiration from the im_address_resolve() in id_manager.c and using the PSA crypto library for the ECB encryption.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Resolve BLE address using Zephry</title><link>https://devzone.nordicsemi.com/thread/417697?ContentTypeID=1</link><pubDate>Mon, 27 Mar 2023 13:33:40 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:b78241f7-7d8d-4a7d-8c1e-14b0ccae0285</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;If you have a bond with the device, the IRK will be added to the filter accept list when you use&amp;nbsp;bt_le_filter_accept_list_add(). However, there is no API for adding just IRK&amp;#39;s. Technically it should be possible to modify the host implementation to support it, but I do not have any suggestion on how to do it. Also, the AAR is reserved by the stack.&lt;/p&gt;
&lt;p&gt;Perhaps you can scan for any device and do the address resolution in SW? And then, try to connect to that specific address? You can take a look at the implementation of&amp;nbsp;im_address_resolve() in id_manager.c the old nRF5 SDK, which does this.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>