#pragma once #include "mbedtls/aes.h" int bt_encrypt_be(const uint8_t *key, const uint8_t *plaintext, uint8_t *enc_data) { mbedtls_aes_context ctx; mbedtls_aes_init(&ctx); if (mbedtls_aes_setkey_enc(&ctx, key, 128) != 0) { mbedtls_aes_free(&ctx); return -1; } if (mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_ENCRYPT, plaintext, enc_data) != 0) { mbedtls_aes_free(&ctx); return -1; } mbedtls_aes_free(&ctx); return 0; } struct encryption_block { uint8_t key[16]; uint8_t plain_text[16]; uint8_t cipher_text[16]; }; inline bool ble_ll_resolv_rpa(const uint8_t *rpa, const uint8_t *irk) { struct encryption_block ecb; auto irk32 = (const uint32_t *)irk; auto key32 = (uint32_t *)&ecb.key[0]; auto pt32 = (uint32_t *)&ecb.plain_text[0]; key32[0] = irk32[0]; key32[1] = irk32[1]; key32[2] = irk32[2]; key32[3] = irk32[3]; pt32[0] = 0; pt32[1] = 0; pt32[2] = 0; pt32[3] = 0; ecb.plain_text[15] = rpa[5 - 3]; ecb.plain_text[14] = rpa[5 - 4]; ecb.plain_text[13] = rpa[5 - 5]; bt_encrypt_be(ecb.key, ecb.plain_text, ecb.cipher_text); if (ecb.cipher_text[15] != rpa[5 - 0] || ecb.cipher_text[14] != rpa[5 - 1] || ecb.cipher_text[13] != rpa[5 - 2]) return false; return true; } static const char * ble_device_name(const uint8_t * rpa) { static constexpr uint8_t irk_martins_apple_watch[] = {0xaa, 0x67, 0x54, 0x2b, 0x82, 0xc0, 0xe0, 0x5d, 0x65, 0xc2, 0x7f, 0xb7, 0xe3, 0x13, 0xab, 0xa5}; static constexpr uint8_t irk_martins_iphone[] = {0x84, 0x0e, 0x38, 0x92, 0x64, 0x4c, 0x1e, 0xbd, 0x15, 0x94, 0xa9, 0x06, 0x9c, 0x14, 0xce, 0x0d}; if(ble_ll_resolv_rpa(rpa, irk_martins_apple_watch)) { return "martins_apple_watch"; } else if(ble_ll_resolv_rpa(rpa, irk_martins_iphone)) { return "martins_iphone"; } else { return nullptr; } }