Open biemster opened 7 months ago
For anybody working on this the specification seems to be here (https://developers.google.com/nearby/fast-pair/specifications/extensions/fmdn)
This is very interesting.
Note: Some interesting blogpost: https://security.googleblog.com/2024/04/find-my-device-network-security-privacy-protections.html
not sure yet. From that page, device manufacturers at least have to do a google NDA to ship a find my device compatible device, but that's pretty normal right?
My question is if Google / Android phones are now reporting Apple's FindMy devices to their (or even Apple's) server as well. If Google isn't releasing info on how to request the data from their server, it probably needs to be hacked like it was done with Apple before. If Android now sends location reports to Apple's server it would enlarge the FindMy network instantly without the need to make any changes for Apple and us.
Yea I'm fairly certain that's not happening. The google Find my Device network is separate. There are some architectural changes too. I think the only crossover between the networks is individual devices detecting unwanted trackers.
This new standard has some details on the protocol https://datatracker.ietf.org/doc/draft-detecting-unwanted-location-trackers/01/
also there is a spec https://developers.google.com/nearby/fast-pair/specifications/extensions/fmdn there are a lot more GATT services/characteristics required like Get_Accessory_Category_Response
flipper guys also planning it https://github.com/MatthewKuKanich/FindMyFlipper/issues/43
not sure if fast pair is relevant
.. Fast Pair
: https://developers.google.com/nearby/fast-pair/specifications/introduction
.. Fast Pair roles
: https://developers.google.com/nearby/fast-pair/specifications/configuration#roles
.. Fast Pair Model Registration
: https://developers.google.com/nearby/fast-pair/specifications/service/modelregistration
.. Fast Pair TX power
: https://developers.google.com/nearby/fast-pair/specifications/configuration#transmit_power
.. Fast Pair Advertising
: https://developers.google.com/nearby/fast-pair/specifications/service/provider
.. Fast Pair GATT Characteristics
: https://developers.google.com/nearby/fast-pair/specifications/characteristics
.. Fast Pair Procedure
: https://developers.google.com/nearby/fast-pair/specifications/service/gatt
.. Verifying Fast Pair
: https://developers.google.com/nearby/fast-pair/help#verifying_fast_pair
.. Fast Pair Personalized Name extension
: https://developers.google.com/nearby/fast-pair/specifications/extensions/personalizedname
.. Fast Pair Certification Guidelines for Personalized Name
: https://developers.google.com/nearby/fast-pair/certification-guideline#2_personalized_name
.. Fast Pair Battery Notification extension
: https://developers.google.com/nearby/fast-pair/specifications/extensions/batterynotification
.. Fast Pair Find My Device Network extension
: https://developers.google.com/nearby/fast-pair/specifications/extensions/fmdn
.. Fast Pair FMDN advertising
: https://developers.google.com/nearby/fast-pair/specifications/extensions/fmdn#advertised-frames
.. Fast Pair Locator Tag Specific Guidelines
: https://developers.google.com/nearby/fast-pair/specifications/extensions/fmdn#locator-tag
.. _Fast Pair Unwanted Tracking Prevention Guidelines
: https://developers.google.com/nearby/fast-pair/specifications/extensions/fmdn#unwanted-tracking-prevention
More info that people have started collecting here: https://github.com/seemoo-lab/openhaystack/discussions/210
Maybe helpful: from Nordic Semiconductor (manufacturer of nRF52840 - Multiprotocol Bluetooth 5.4 SoC supporting Bluetooth Low Energy, Bluetooth mesh, NFC, Thread and Zigbee) Bluetooth Fast Pair: Locator tag (doc) https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/samples/bluetooth/fast_pair/locator_tag/README.html Bluetooth: Fast Pair locator tag (zephyr source code) https://github.com/NordicBuilder/sdk-nrf/tree/0e99b70bcb259379b2faa87f9e2abcaf5de1e7a0/samples/bluetooth/fast_pair/locator_tag Fast Pair Validator (exclusively for manufacturers of bluetooth devices) https://play.google.com/store/apps/details?id=com.google.location.nearby.apps.fastpair.validator
I added an esp32 micropython script that sends the FMDN advertisement as detailed in https://developers.google.com/nearby/fast-pair/specifications/extensions/fmdn#advertised-frames table 8. I have no clue yet how to compute the ephemeral id or how to retrieve the reports through the google api's yet, but it's a start!
nRF Connect reports this as an Eddystone, with the ephemeral id as the data field.
I added an esp32 micropython script that sends the FMDN advertisement as detailed in https://developers.google.com/nearby/fast-pair/specifications/extensions/fmdn#advertised-frames table 8. I have no clue yet how to compute the ephemeral id or how to retrieve the reports through the google api's yet, but it's a start!
nRF Connect reports this as an Eddystone, with the ephemeral id as the data field.
I just got some Chipolo tags, if you need me to scrape some data that might help, happy to do so.
I just got some Chipolo tags, if you need me to scrape some data that might help, happy to do so.
That would be great! Are you able to mitm proxy an android with the account your chipolos are registered on? (and confirming they advertise as an eddystone with a 20 byte data field would already be of huge help)
chipolo review, https://youtu.be/3EAu08m5Lbc?feature=shared&t=285 currently worse than Samsung's, which is closer to Apple's, but hopefully will change with time.
I have no clue yet how to compute the ephemeral id or how to retrieve the reports through the google api's yet, but it's a start!
I don't know if they improved meanwhile, but it's described here
As I understand the specifications, the Ephemeral Key is just a random 32 bytes generated by the tag once. It doesn't have to be known by the smartphone or tag owner. It's then used as an AES key (ECB mode!) for encrypting a dumb message. This makes a pseudo random number (s
) that's used in the later crypto operations.
I'm not sure I'm getting the logic here, it seems so stupid, I'm missing something. The dumb message (which is doubled to fit in 256 bits) is made of only 22 bits of actual changing data. There's seconds' timer counter whose 10 low bits are cleared (so only 22 bits useful in theory, but since it counts from 0, those are guessable quite easily). Technically, the counter actually update ~4 times per hour.
Then you AES ECB encrypt it and get r'
. There's a small micmac to build a 160 bits's X coordinate of the number on the curve using the usual ECC computations.
As for the ephemeral identity key, they say this, meaning that it's possible to fetch it if the tracker is not provisioned. In that case, everything is deterministic.
If you ever intend to make a fully featured device (one that does support the provisioning process), then it means implementing this (which is, AFAIU, not very complex to compute, but probably more to implement the persistent state in flash, in your reversed engineered firmware)
wow, thank you for your analysis!
As it's done with the airtags it should be kept as simple as possible, ie
My guess is that they use randomness as IV during provisioning, just to prevent same bytes showing up in the air.
ECB is normal if data is less than block size/packets are infrequent and they don't want to worry about keeping last state/losing packets.
This could be interesting to you as well:
Note: I have not been able to query location reports from the server yet. This will be the hardest part, since it requires HTTPS and Firebase authentication with a private API from Google.
The former repository is really useful, I didn't know it was possible to write crypto code over finite field that simply with python, always did it with C++ (and a not that simple interface). I've hard time figuring out what the second repo is actually doing (except making an HTTP request to https://android.googleapis.com/nova/nbe_list_devices
).
I think this line is wrong however.
They say in the documentation that you should clear the 10 low bits of the second / timestamp counter. That's because they are using a fixed key for encrypting the eid
and user fetching the report should be able to query the expected report, so she must guess the content of r
and thus the timestamp. By zeroing the 10 low bits, you have to guess a timestamp by steps of 1024 second, which is much easier that trying to guess a timestamp by step of 1 second.
While requesting location report is useful per se, it can be done actually with an Android phone meanwhile. Being able to have a tag that's speaking the right protocol so that an unmodified Android phone fills the location report's database at Google would confirm the protocol implementation in the tag is working. That would probably solve many problems already.
Hey there, I verified the EID calculation with real trackers. It should be correct.
What you seem to forget is that the timestamp and padding is not the EID. The EID is calculated by encryption using AES-ECB with the EIK and then projecting the result to the elliptic curve. Then, the EID is the x coordinate of this calculation, just like in my code.
Ok, I don't know in fact what the tracker are doing, I don't have any. Here they say: 12 - 15 | TS[0]...TS[3] | Beacon time counter, in 32-bit big-endian format. The K lowest bits are cleared.
The part I was referring to is The K lowest bits are cleared.
Seems like, to me that the beacon time counter should be TS & ~1023
, since K is 10. So it should only have 22 bits of actual data, and incrementing every 1024 seconds.
They say:
Note: The device is assumed to have a 32-bit time counter in seconds.
Note: Rotation period exponent is fixed and set to 10, corresponding to 1024 seconds.
Once you know it, you can recreate this EID just by knowing the time distance with the last or first provisioning (since everything is known in the algorithm). So you can compute Rx from both side (tracker & consumer's smartphone) which is required for encrypting and decrypting the EID, as described here (since you can deduce Ry from Rx).
So if you don't mask the low bits, you'll not find the expected Rx from the consumer's smartphone that'll mask them out. (It'll only be correct once every 1024 seconds, but since the clock are unlikely to be synchronized, I don't think the tracker will emit a report that'll be captured by a nearby phone at the exact moment when its time counter is 0 for the 10 low bits).
Ah, now I know what you mean. It's true that the counter for the EID calculation only counts in multiples of 1024.
Since all other code only called the EID calculation with multiples of 1024 as the offset value, this was not a problem. But you are right, this should be made more explicit in the code.
Well, I think we talk about different acronyms (in their immense wisdom, they used E for both ephemeral and encrypted). The Ephemeral ID computation, which I've found in your code here maps to this, right ? (It looks like it does)
Yet, it's missing the part that's masking the low 10 bits, as specified.
It's not the encrypted ID yet, but it's required to compute the encrypted ID
I've updated the file to make it more clear that only multiples of 1024 can be used. The file does specify the complete EID calculation. If you have more questions, please open an issue in my repository.
Google just activated their own Find My network on Android this weekend. Details are still scarce, so let's collect all technical info needed to send the BLE advertisement and subsequently query this network here. The BLE part can then be implemented here: https://github.com/biemster/st17h66_RF (and I will also finally put the Apple FindMy advertisement there then as well, so the chip can do both)