Skip to content

U2F attestation: trezordevkey.pem matches nothing that ships, and genkeys.sh regenerates it as a Trezor certificate #420

Description

@BitHighlander

What is wrong

Three separate problems around the U2F attestation material, found while making secret-scan green on #418.

1. trezordevkey.pem corresponds to nothing that ships

include/keepkey/firmware/u2f/trezordevkey.pem is not the attestation key and did not sign the
attestation certificate. Decoded:

trezordevkey.pem  private scalar    7126ac2bf644dc6186ad83ef1fcdf12a57b5cfa2000b8ad027e956e854c50a8b
u2f_keys.h        U2F_ATT_PRIV_KEY  306ef685c7847a12f27dbd75e1a4b09e1ed74cda921f7415838016ab71cf08d4

pem  public key   04d918bdfa8a54ac92e90da91fca7aa26454c0d17336314dde83a54b86b5df4ef0...
cert public key   04d126193155e94ec1684646d1f7ebb050c185744dbaa82c1f95a671d29b24fd75...

Neither the private scalar nor the public key matches. It is a dead file that has been in the tree since
fe3e5e001 (2019-04-27), and its only current effect is to trip secret scanners.

2. genkeys.sh would rebrand attestation to Trezor, and swap the key

# include/keepkey/firmware/u2f/genkeys.sh:36
openssl req -new -key trezordevkey.pem -out trezordevcert.req -subj "/CN=Trezor U2F"

The shipped certificate is CN=KeepKey U2F. Anyone regenerating attestation with this script would
produce a certificate claiming to be a Trezor — and, because the script reuses trezordevkey.pem when
present (line 14) and that key is not the shipped one, would also replace the device attestation identity
with the orphan key above.

So the script cannot reproduce the artifacts that are checked in, and running it silently changes both
the branding and the key.

3. The attestation certificate expires 2028-10-01

subject  = CN=KeepKey U2F
issuer   = CN=KeepKey U2F
notBefore= Oct  4 23:36:32 2018 GMT
notAfter = Oct  1 23:36:32 2028 GMT

Not urgent, but it is a dated artifact with no recorded owner or renewal plan, and the only tool for
regenerating it is broken per (2).

Why it matters

None of this is a key-compromise issue. A FIDO U2F batch attestation key is shared across a device batch
by design, is compiled into every firmware image, and is extractable from any public release binary; it
authenticates nothing and guards no funds. The real costs are:

  • a private key file in the repository that matches nothing, which makes every secret-scan finding here
    require re-investigation before it can be dismissed;
  • a regeneration script that produces the wrong identity, so the next person to touch attestation ships
    a Trezor-branded certificate signed by a key no device has ever used;
  • an expiry with no owner.

Suggested fix

  1. Delete include/keepkey/firmware/u2f/trezordevkey.pem. Note this does not clear the historical
    secret-scan finding — CI scans with fetch-depth: 0 — so the .gitleaks.toml path entry added in release: open the 7.14.2 security line from the active release #418
    must stay until history is irrelevant. Deleting it does stop the confusion.
  2. Fix genkeys.sh: -subj "/CN=KeepKey U2F", and make it fail loudly rather than silently reusing or
    generating a key, so it cannot quietly change the device identity.
  3. Decide and record an owner and a plan for the 2028 expiry.

Not done as part of #418 to keep that PR's diff to security fixes only.


Verified against 1af2ffe7de.

git show 1af2ffe7de:include/keepkey/firmware/u2f/genkeys.sh | sed -n '10,16p;34,40p'
openssl ec -in include/keepkey/firmware/u2f/trezordevkey.pem -text -noout

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    securitySecurity-relevant defect or hardening

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions