This repo is for the proof-of-concept for GAEN+ which implements a geospatial component to the Google/Apple Exposure Notification Framework. Our paper which discusses this flaw in the GAEN framework is titled "Replay (Far) Away: Exploiting and Fixing Google/Apple Exposure Notification Contact Tracing" and was accepted to be published in the Proceedings on the Privacy Enhancing Technologies Symposium (PoPETS) in 2022. For general information: https://petsymposium.org/, for the 2022 program: https://petsymposium.org/2022/program.php
This README is extended from the original Exposure Notifications repo, provided by the exposurenotification by Google. The following are instructions to build and run the various experiments.
- Download and open repo in Android Studio
- Follow third party instructions to build non-arm64-v8a dependencies in BUILD.md
- Navigate to /app/src/main/java/com/google/samples/ensnippets/ and open MainActivity.java
- Starting at line 77, three experiments are available to test. Uncomment the experiment you'd like to run.
- Connect phone and attempt to run the app
- Logs are displayed in the console and also
The following is the original README.
This repository contains a snapshot of code from Google Play Services' Exposure Notifications module. It was published as part of a transparency effort, and there are no current plans to update the code contained within the repo.
There are a number of features in this source set, including abstrations and JNI. The following sections provide key features with pointers to the source code.
Code: com.google.samples.exposurenotification.ble.advertising.BleAdvertiser#startAdvertising
Bluetooth Low Energy (BLE) MAC addresses rotate on average every 15 minutes to prevent remote location tracking that could be accomplished by tying together observations of a fixed MAC address.
In order to best protect user privacy, the Exposure Notifications framework ensures that Rolling Proximity Identifiers (RPIs) are never rotated without also having a corresponding change of the Bluetooth MAC address. For more details, see the full Bluetooth spec.
Because Android doesn't have a callback to notify an application that the Bluetooth MAC address is changing (or has changed), this is handled by explicitly stopping and restarting advertising whenever a new RPI is generated.
Since there isn't any callback, it is possible for the Bluetooth MAC address to rotate before a new RPI is generated. In this case the following would happen:
Time | Bluetooth MAC | RPI |
---|---|---|
:00 | 00:00:00:01 | AAA |
:09 | 00:00:00:02 | AAA |
:10 | 00:00:00:03 | BBB |
The risk posed by this is minimal, since even though an observer may be able to tie the MAC
addresses 00:00:00:01
and 00:00:00:02
together using the common RPI, the duration of both
MAC addresses is no longer than a single RPI period (~10 minutes). When the RPI rotates, the
MAC address rotates again, making it difficult to track the association of either the MAC
address or RPI to a common device.
Code: com.google.samples.exposurenotification.ble.advertising.RollingProximityIdManager#getCurrentRollingProximityId
Code: com.google.samples.exposurenotification.data.generator.TemporaryExposureKeyGenerator
Rolling Proximity Identifiers (RPIs) are generated from a Temporary Exposure Key (TEK) based on the Exposure Notification Cryptography Specification.
For more information about TEKs and RPIs, see Exposure Notifications Cryptography
Code: com.google.samples.exposurenotification.ble.advertising.BleAdvertisementGenerator
Code: com.google.samples.exposurenotification.data.generator.AssociatedEncryptedMetadataHelper
Associated Encrypted Metadata is generated by BleAdvertisementGenerator#generatePacket
based on the
Exposure Notification Cryptography Specification. This
uses BluetoothMetadata#create
to create the metadata itself.
The encryption, decryption, and generation of keys is handled by the
class AssociatedEncryptedMetadataHelper
.
For more information about Associated Encrypted Metadata, see Exposure Notifications Cryptography
Code: com.google.samples.exposurenotification.matching.MatchingJni
The core process of Key Matching is started via MatchingJni
. The class then calls into native C++ code to improve performance by avoiding Java binder calls for the many crypto operations needed.
A MatchingJni
object is initialized with a list of scanned RPIs from the past 14 days. The caller can pass a list of Diagnosis Key files, provided by the Healthcare Authority app, to the method MatchingJni#matching
. This method produces a list of TemporaryExposureKey
s corresponding to the Diagnosis Keys that the device was exposed to.