Expand description
Auth-bound key storage: wrapping a 32-byte key so that using it requires the platform’s user authentication.
§What it is for
An application can protect its master key with a password
(qualia2fa-core’s lock wrap), but a
password is something the user types and an attacker can guess. This crate adds
the other way in: a platform-authenticated wrap. On Android that is an AES key
in the Keystore whose use requires a BiometricPrompt CryptoObject; on Windows
it is a Windows Hello credential whose hmac-secret output is released only by a
Hello gesture.
The two wraps are independent: either one opens the same master key, and an application keeps both so that a forgotten password or a re-enrolled fingerprint does not lock the user out.
§What this crate is not
- It does not know the vault format, the password wrap or any Qualia2FA protocol.
It has no dependency on
qualia2fa-core; its key type is local. - It does no I/O. The generated bytes are returned to the caller, which decides where they live.
- It is not a substitute for a password. The platform can be unavailable, the user can remove the PIN or the fingerprint, and a credential can be invalidated by a re-enrolment; the password path must stay in place.
§How the guarantee is drawn
The wrapped bytes are encrypted with a key that lives in the platform’s
authentication boundary: the Keystore key on Android, the Hello-bound
hmac-secret on Windows. A popup whose success callback is merely checked in
user-mode is not enough — the same process can ignore the callback. The test
is “can this process decrypt the wrapped bytes without the platform releasing the
key?” If the answer is yes, the wrap is not auth-bound.
§File format
The outer blob is platform-neutral and self-describing:
magic `Q2FABIO1` (8) | version 1 (1) | backend (1) | wrapped length (4, BE)
| wrapped bytesThe backend identifies which platform wrote the blob, and the wrapped bytes are
private to that backend. See crate::format for the limits and the rejection rules.
§Status
- Implemented: the outer format, the key type, the trait, the mock backend, the
unsupported fallback, and the Windows backend (Windows Hello through WebAuthn
hmac-secret). - The Windows backend does not trust the attestation’s
bPrfEnabledflag; the firstGetAssertionis the test. On Windows 11 23H2 (WebAuthn API version 7) the credential is created with the flag at zero and the assertion returns without the secret, so the store reportsAvailability::Unavailable; the password path is unaffected. A machine where the assertion succeeds works even when the flag is zero. - Planned: the Android Keystore backend. Until it is present, Android reports
platform::stub::UnsupportedKeyStoreand the password path is the only way in.
Re-exports§
pub use host::DelegatingKeyStore;pub use host::PlatformSealer;pub use key::MASTER_KEY_LEN;pub use key::MasterKey;pub use traits::AuthBoundKeyStore;pub use traits::Availability;pub use traits::Backend;
Modules§
- format
- The platform-neutral outer blob (
master.key.bioin Qualia2FA). - host
- A store whose platform half is supplied by the host application.
- key
- The 32-byte key this library wraps.
- platform
- Platform backends.
- traits
- The platform-independent interface.
Enums§
- Error
- The unified error type of this library.
Type Aliases§
- Result
- The result type of this library.