Skip to content

rettichschnidi/ExposureNotification

Repository files navigation

Exposure Notification

Overview

This code project contains code snippets from the iOS implementation of Exposure Notification. These snippets don't represent the entirety of the Exposure Notification implementation. Instead, it focuses on the critical paths needed to understand the functionality of the most significant parts of the codebase. This project is separated into four groups of functionality.

File Signature Validation

An app that uses ExposureNotification.framework provides Temporary Exposure Keys that represent possible exposure to the framework via files as described in the article, Setting Up an Exposure Notification Server.

These files must be signed by Apple before they will be checked against the on-device database of a user for possible matches. An EN server must always sign files with the private key that corresponds to the latest public key provided to Apple using SHA-256 with ECDSA. The classes contained within the File Signature Validation group contain the implementation of the parsing and signature verification for these files.

The signature verification flow is implemented by ENFileSignatureVerification. The general file parsing and signature verification flow is as follows:

  1. An ENFile object is created for the key file via opening either with -[ENFile openWithFD:reading:error:], or -[ENFile openWithFileSystemRepresentation:reading:error:].
  2. An ENSignatureFile object is created for the corresponding signature file via creation with [ENSignatureFile signatureFileWithBytes:length:error:], or opening with -[ENSignatureFile openWithFileSystemRepresentation:reading:error:].
  3. An ENFileSignatureVerification object is created, with the public key that corresponds to the private key used to create the signature file.
  4. Both the ENFile and ENSignatureFile are passed into -[ENFileSignatureVerification validateFile:withSignatureFile:], which returns YES if the signature is valid, and NO if the signature is not valid.

Cryptography

Secure and random key generation are critical to enabling the Privacy Preserving aspect of Exposure Notification. The methods contained in ENCryptography implement the Exposure Notification cryptography specification, using the corecrypto library.

The flow for generating Temporary Exposure Keys and Rolling Proximity Identifiers is as follows:

  1. A Temporary Exposure Key (TEK) must be generated using cryptographically random bytes. This can be done by calling ENGenerateTEK(...).
  2. A Rolling Proximity Identifier Key (RPIK) is derived from the generated TEK by calling ENGenerateRPIK(...) with the TEK generated in Step 1.
  3. With both the TEK from Step 1, and the RPIK from Step 2, a Rolling Proximity Identifier (RPI) can be generated by calling ENGenerateRollingProximityIdentifier(...) with an interval number corresponding to the 10 minute window during which this RPI is broadcast. The interval number is determined with the following formula, where timestamp is in Unix Epoch Time: ENIntervalNumber(Timestamp) ← Timestamp / 60×10.
  4. Alternatively, 144 RPI can be generated by calling ENGenerate144RollingProximityIdentifiers(...) with the interval number argument corresponding to the interval number of the first RPI of the group, with each subsequent RPI incrementing the interval number by 1.
  5. An Associated Encrypted Metadata Key (AEMK) is derived from the TEK generated in Step 1 via a call to ENGenerateAEMK(...).
  6. Using the AEMK generated in Step 5, and the metadata to be included in the Exposure Notification advertisement (as described in the Bluetooth specification), the Associated Encrypted Metadata is generated by calling ENEncryptAEM(...).

Advertisement Matching and Scoring

When a user has a confirmed or potential exposure to COVID-19, the framework identifies them as affected and shares their diagnosis keys to alert other users to potential exposure. These diagnosis keys are then aggregated by the regional Public Health Authority, packaged into an ENFile, downloaded by all opted-in devices, and compared against a user's on-device database to detect possible exposures. The files in the Advertisement Matching and Scoring implement the matching and risk score calculation paths of Exposure Notification.

The flow for finding matching advertisements and determining their risk score is as follows:

  1. An ENAdvertisementDatabase is initialized with a folder containing a SQLite database named en_advertisements.db that has one table with the schema defined in -[ENAdvertisementSQLiteStore initializeAdvertisementTable].
  2. An ENExposureConfiguration is created with the configuration values to be used in the creation of ENExposureDetectionSummary and ENExposureInfo objects.
  3. With the ENAdvertisementDatabase created in Step 1, and the ENExposureConfiguration created in Step 2, an ENExposureDetectionDaemonSession is initialized via -[ENExposureDetectionDaemonSession initWithDatabase:configuration:].
  4. -[ENExposureDetectionDaemonSession addFile:] is called repeatedly for each ENFile that contains Temporary Exposure Keys that represent possible COIVD-19 exposures. For each ENFile provided: 4.1. The Temporary Exposure Keys are grouped into batches, with each batch being passed into -[ENAdvertisementDatabaseQuerySession matchCountForKeys:attenuationThreshold:error:]. 4.2. The Temporary Exposure Keys are passed into -[ENAdvertisementDatabase advertisementsBufferMatchingDailyKeys:] to produce a buffer that contains all matching advertisements, ordered by the TEK used to generate the advertisements. 4.3 The matching advertisement buffer is passed into -[ENAdvertisementDatabaseQuerySession aggregateExposureInfoForAdvertisementBuffer:] to hydrate the advertisements within the buffer into ENAdvertisement objects, grouped by the TEK used to generate the advertisements within the group. 4.4 The group of ENAdvertisement objects will be filtered by -[ENAdvertisementDatabaseQuerySession filterAdvertisements:] to remove any advertisements that are suspected to have been invalidly emitted. 4.5. The remaining ENAdvertisement objects within the group are used to create an ENExposureInfo object via -[ENAdvertisementDatabaseQuerySession exposureInfoForAdvertisements:], according to the ENExposureConfiguration that was generated in Step 2.
  5. When all ENFile objects have been passed into -[ENExposureDetectionDaemonSession addFile:], an ENExposureDetectionSummary object can be generated for all matching advertisements by calling -[ENExposureDetectionDaemonSession generateSummary].
  6. To retrieve more granular information about the possible exposures, all generated ENExposureInfo objects can be retrieved by calling -[ENExposureDetectionDaemonSession exposureInfo].

Bluetooth Hardware Integration

Exposure Notification uses Bluetooth Low Energy (BLE) to anonymize and exchange RPIs between users that have opted in. The files contained with the Bluetooth Hardware Integration group demonstrate the usage of the iOS Bluetooth stack to exchange these identifiers. The operation of the Bluetooth stack falls into two categories: advertisement scanning, and advertisement broadcasting.

The flow for scanning for Exposure Notification advertisements is as follows:

  1. Periodically a device will initialize a scan for Exposure Notification advertisements by calling ExposureNotificationManager::startScanning(). Advice for scanning behavior can be found in the Bluetooth specification.
  2. For any Exposure Notification advertisement found while scanning, ExposureNotificationManager::bluetoothDeviceFoundCallback(...) will be called with the contents of the scan result.
  3. After a sufficient amount of time has been spent scanning at the configured duty cycle, the scan will be stopped by calling ExposureNotificationManager::stopScanning().
  4. When the scan has stopped a call to ExposureNotificationManager::scanDidStop() will aggregate and save all observed advertisements in the on-device database.

The flow for generating an Exposure Notification advertisement is as follows:

  1. When the iOS device rotates its Bluetooth MAC address, a new Exposure Notification advertisement will be generated by calling ExposureNotificationManager::generateAdvertisingPayload(...).
  2. Within ExposureNotificationManager::generateAdvertisingPayload(...), the TEK and RPI that correspond to the current Unix Epoch Time interval number are retrieved.
  3. The radiated transmission power used to broadcast the Exposure Notification advertisements is retrieved from the Bluetooth stack by calling ExposureNotificationManager::getPlatformRadiatedLeTxPower()
  4. The Associated Encrypted Metadata for the current advertisement is generated by calling ENEncryptAEM(...)
  5. The current RPI and AEMK are concatenated to construct the Exposure Notification payload to be advertised until the next Bluetooth MAC address rotation.