Attestation compatibility guide

Guide on using remote attestation in a way that’s compatible with GrapheneOS

https://grapheneos.org/articles/attestation-compatibility-guide

Apps using SafetyNet attestation to check the authenticity/integrity of the OS can support GrapheneOS by using the standard Android hardware attestation API and permitting our official release signing keys. Android’s hardware attestation API provides a much stronger form of attestation than SafetyNet with the ability to whitelist the keys of alternate operating systems. It also avoids an unnecessary dependency on Google Play services and Google’s SafetyNet servers.

Devices have been required to ship with hardware attestation support since Android 8. You can use hardware attestation on devices running Android 8 or later when the ro.product.first_api_level system property isn’t set to 25 or below, which indicates they launched with Android 8 or later with hardware attestation support as a mandatory feature. On older devices, you can continue using SafetyNet attestation. Some low quality devices shipped broken implementations of hardware attestation despite the requirement to have it working for CDD/CTS certification and SafetyNet currently still passes on those devices wrongly claiming them to be CTS certified. If you don’t want to fail on those devices, then you can start with hardware attestation and fall back to SafetyNet attestation or do both and accept either passing as success.

After verifying the signature of the attestation certificate chain and extracting the attestation metadata, you can enforce that verifiedBootState is either Verified or SelfSigned. For the SelfSigned case, you can check that verifiedBootKey matches one of the official GrapheneOS verified boot keys. These are the base16-encoded verified boot key fingerprints for the official GrapheneOS releases:

  • 0abddeda03b6ce10548c95e0bea196faa539866f929bcdf7eca84b4203952514: Pixel 5a
  • 36a99eab7907e4fb12a70e3c41c456bcbe46c13413fbfe2436adee2b2b61120f: Pixel 5
  • dcec2d053d3ec4f1c9be414aa07e4d7d7cbd12040ad2f8831c994a83a0536866: Pixel 4a (5G)
  • 3f15fdcb82847fed97427ce00563b8f9ff34627070de5fdb17aca7849ab98cc8: Pixel 4 XL
  • 80ef268700ee42686f779a47b4a155fe1ffc2eedf836b4803caab8fa61439746: Pixel 4
  • 9f2454a1657b1b5ad7f2336b39a2611f7a40b2e0ddfd0d6553a359605928df29: Pixel 4a
  • 3f36e3482e1ff82986576552cb4fd08af09f8b09d3832314341e04c42d2919a4: Pixel 3a XL
  • 73d6c63a07610404fe16a4e07dd24e41a70d331e9d3ef7bba2d087e4761eb63a: Pixel 3a
  • 06dd526ee9b1cb92aa19d9835b68b4ff1a48a3ad31d813f27c9a7d6c271e9451: Pixel 3 XL
  • 0f9a9cc8ade73064a54a35c5509e77994e3aa37b6fb889dd53af82c3c570c5cf: Pixel 3

The verifiedBootKey field is binary data so you either need to encode it as base16 to compare with these or convert these to binary. An easy approach is storing the permitted key fingerprints in a set and enforcing that the verified boot key is in the permitted set when verifiedBootState is SelfSigned.

GrapheneOS regularly adds support for new devices so you should have a process for regularly adding the new verified boot key fingerprints from this page.

The hardware attestation API also provides other useful information signed by the hardware including the OS patch level, in a way that even an attacker exploiting the OS after boot to gain root cannot trivially bypass. It’s a better feature than the SafetyNet API designed for the lowest common denominator.

GrapheneOS users are strongly encouraged to share this documentation with app developers enforcing only being able to use the stock OS. Send an email to the developers and leave a review of the app with a link to this information. Share it with other users and create pressure to support GrapheneOS rather than locking users into the stock OS without a valid security reason. GrapheneOS not only upholds the app security model but substantially reinforces it, so it cannot be justified with reasoning based on security, anti-fraud, etc.

GrapheneOS’s attestation service has a page explaining how the Auditor app and attestation service work.