Skip to content

authenticator: TOTP secrets survive device lock #398

Description

@BitHighlander

Summary

lib/firmware/authenticator.c:38 holds TOTP secrets in RAM:

static CONFIDENTIAL authType authData[AUTHDATA_SIZE] = {0};

It is cleared on exactly one path — the explicit, user-confirmed wipeAuthdata Ping subcommand (wipeAuthData(), authenticator.c:90-101). It is not cleared when the device locks, when the session is cleared, on Cancel/Initialize, or on wipe.

So a screensaver auto-lock leaves every stored TOTP shared secret resident in SRAM on a device the user believes is locked.

Why it was not fixed alongside the other retained-secret fixes

The sibling leaks in signing.c (privkey) and fsm.c (the derived HDNode) were one-line memzero additions into the existing teardown. This one is not: authData is a cache populated from storage by getAuthData() (authenticator.c:46), and there is load-state around it — authenticator.c:239 carries the comment "in theory an OTP could be requested on a dirty local". Zeroing the buffer without correctly resetting the load flag risks silently breaking TOTP, so it was deliberately left alone rather than patched blind.

Acceptance criteria

  • Determine the cache/load-flag semantics of getAuthData()
  • Clear authData on loss of authorization, re-reading from storage on next use
  • Test that a TOTP code is still correct after a lock/unlock cycle
  • Test that the buffer is zero while locked

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