Summary
In the passphrase-protected branch, `storage_setAuthData()` derives `authdataKey` from `session.passphrase` and uses it to encrypt the authblock, then scrubs `plaintextAuthBlock` before returning -- but never scrubs `authdataKey` itself.
Impact (medium)
Every write of the CTAP2/passkey authblock while a passphrase is cached leaves this passphrase-derived key resident on the stack after the call returns.
Fix direction
Add `memzero(authdataKey, sizeof(authdataKey))` alongside the existing `plaintextAuthBlock` scrub.
Summary
In the passphrase-protected branch, `storage_setAuthData()` derives `authdataKey` from `session.passphrase` and uses it to encrypt the authblock, then scrubs `plaintextAuthBlock` before returning -- but never scrubs `authdataKey` itself.
Impact (medium)
Every write of the CTAP2/passkey authblock while a passphrase is cached leaves this passphrase-derived key resident on the stack after the call returns.
Fix direction
Add `memzero(authdataKey, sizeof(authdataKey))` alongside the existing `plaintextAuthBlock` scrub.