Important
Moved to gg1nids12/zerofido-tpm — same project with the full history and the latest releases. This fork is archived.
Проект переехал в gg1nids12/zerofido-tpm — та же история и новые релизы. Этот форк в архиве.
Warning
Development fork — work in progress. This is the tpm branch of
gg1nids12/zerofido, a modified version of
ZeroFIDO by Alex Stoyanov (MinorGlitch).
It is tested on one Flipper Zero with Momentum firmware mntm-012. Keep backup sign-in
methods on every account. License (GPL-3.0-or-later) and authorship of the original are
preserved; every change is listed in CHANGES-TPM.md.
Версия в разработке — доработка ZeroFIDO. Проверена на одном Flipper Zero с прошивкой
Momentum mntm-012. Оставляйте на аккаунтах запасной способ входа.
You need: a Flipper Zero with Momentum firmware mntm-012.
- Download zerofido.fap.
- Copy it to the Flipper: plug the Flipper into your computer, open
qFlipper → File manager → SD Card →
apps→USBand dragzerofido.fapinto that folder (createUSBif it is missing). - Open it on the Flipper: Apps → USB → ZeroFIDO.
Done. With the cable in a computer the Flipper is a USB security key: on a website choose security key, then press OK on the Flipper when it vibrates.
Without a cable on Windows (Bluetooth), once: open ZeroFIDO, unplug the cable → on the PC Settings → Bluetooth & devices → Add device → Bluetooth → choose FIDO … → the PC and the Flipper show the same 6-digit code → press OK on the Flipper and Connect on the PC. From then on sign-ins work without the cable.
Нужно: Flipper Zero с прошивкой Momentum mntm-012.
- Скачайте zerofido.fap.
- Скопируйте на Флиппер: подключите его к компьютеру, откройте
qFlipper → File manager → SD Card →
apps→USBи перетащите тудаzerofido.fap(если папкиUSBнет — создайте). - Откройте на Флиппере: Apps → USB → ZeroFIDO.
Готово. С кабелем в компьютере Флиппер работает как USB-ключ: на сайте выберите «ключ безопасности» и нажмите OK на Флиппере, когда он завибрирует.
Без кабеля на Windows (Bluetooth), один раз: откройте ZeroFIDO, отключите кабель → на ПК Параметры → Bluetooth и устройства → Добавить устройство → Bluetooth → выберите FIDO … → на ПК и на Флиппере один и тот же код из 6 цифр → OK на Флиппере и Подключить на ПК. Дальше вход работает без кабеля.
Details, PIN and security notes: Installation, Security notes. Подробности, PIN и безопасность: Установка (по-русски).
| Upstream ZeroFIDO 0.8 | This fork | |
|---|---|---|
| Transports | USB HID, NFC | USB HID + Bluetooth LE (Windows), chosen automatically; NFC off by default |
| PIN check | PIN hash stored on the SD card | No PIN hash stored. Slow check (~1 s) through the Flipper's device-unique AES key |
| Passkeys created with a PIN | Wrapped with the device key | Also bound to the PIN (per-passkey key from a PIN-protected master key) |
| PIN retries | Counted after the check | Counted before the check (a power cut cannot hide a wrong guess) |
| Legacy U2F inside the app, packed attestation | On | Off by default (build flags) — the Flipper's built-in U2F app is separate |
| AAGUID | ZeroFIDO model id | All zero (sites see no model marker) |
| Screens | Dialog with Approve/Deny | U2F-like: OK approves, Left/Back deny, vibration + blue light when OK is needed |
| Several passkeys for one site (sign-in without a user name) | Chosen on the Flipper screen | Chosen on the PC screen (with a PIN): one OK on the Flipper, Windows lists the accounts |
How it picks the transport: cable to a PC → USB key; no cable → Bluetooth. A request that arrives over Bluetooth takes over at once (unless a PC is busy with the USB key) and the app returns to the cable rule after 10 s without Bluetooth traffic.
More: docs/BLUETOOTH.md (Bluetooth transport), docs/TPM_HARDENING.md (PIN vault and key protection), CHANGES-TPM.md (all changes).
- Flipper Zero with Momentum firmware
mntm-012(FAP API 87.x). Other firmware needs a build against its own SDK (see Build it yourself); only Momentummntm-012is tested. - microSD card in the Flipper.
- For Bluetooth: a Windows 10/11 PC with Bluetooth. Android and iPhone browsers do not use Bluetooth security keys; use the USB cable there.
- Download zerofido.fap (all versions: Releases).
- Copy it to the Flipper's SD card as
apps/USB/zerofido.fap— with qFlipper (File manager → SD Card → apps → USB), the Flipper mobile app, or a card reader. - On the Flipper: Apps → USB → ZeroFIDO. In Momentum you can also put it on the main menu (Momentum settings → Interface → Main menu).
- Open ZeroFIDO. With the cable in a PC the screen says Connect to a device (USB key); without a cable it says Bluetooth ready.
- Optional but recommended: set a PIN. With the cable in, use Windows Settings → Accounts → Sign-in options → Security key → Manage, or the app menu (Right → Menu → PIN). Prefer a long PIN (8+ characters, letters allowed) — see Security notes.
- Open ZeroFIDO on the Flipper, no cable.
- On the PC: Settings → Bluetooth & devices → Add device → Bluetooth → FIDO <your Flipper's name>.
- The PC and the Flipper show the same 6-digit code. Press OK on the Flipper and Connect on the PC. Only confirm codes when you are pairing your own PC.
On a site that supports passkeys or security keys, choose security key. Enter the PIN on the PC if asked. The Flipper vibrates and blinks blue — press OK. If you have several accounts on the site and sign in without typing a user name, Windows then shows the list of accounts on the PC screen (this needs a PIN; without one the choice stays on the Flipper). Test sites: webauthn.io, passkeys.io.
When you leave ZeroFIDO, the Flipper's normal Bluetooth (mobile app) comes back.
# ufbt with the SDK that matches your firmware, e.g. Momentum mntm-012:
ufbt update --index-url=https://up.momentum-fw.dev/firmware/directory.json --channel=release
ZEROFIDO_PROFILE=full ufbt # dist/zerofido.fapBuild flags of this fork (environment variables, 1/0):
| Flag | Default | Effect |
|---|---|---|
ZEROFIDO_BLE |
1 |
Bluetooth LE FIDO transport (full profile) |
ZEROFIDO_NFC |
0 |
NFC transport in the full profile (the nfc profile always has it) |
ZEROFIDO_U2F |
0 |
Legacy U2F (CTAP1) inside ZeroFIDO |
ZEROFIDO_PACKED_ATTESTATION |
0 |
Packed attestation and the ZeroFIDO AAGUID |
ZEROFIDO_TRACE |
1 |
Service trace: command/status codes and timings only |
ZEROFIDO_NFC_XLOG |
1 |
Light NFC exchange log (APDU headers and status words), when NFC is on |
ZEROFIDO_NFC_LAB |
0 |
Lab build: stays in NFC with the cable in (for NFC debugging) |
Passkeys and the PIN vault live in /ext/apps_data/zerofido/ on the SD card, encrypted with the
Flipper's device-unique key: a copy of that folder works only on the same Flipper. Back it up
before updates. Removing the app: delete apps/USB/zerofido.fap (and the data folder to wipe
the passkeys).
- The Flipper Zero has no secure element and no secure boot. Anyone holding the Flipper can run their own firmware, use the device key and try PINs outside the retry counter, about one per second (the PIN check is deliberately slow). A 4-digit PIN falls in hours, a 6-digit one in days; a long PIN with letters is the real protection. A stolen SD card alone is useless.
- The retry counter is stored on the SD card; someone with the Flipper and its card can roll it back by restoring old files.
- Bluetooth: pairing needs the 6-digit code confirmed with OK on the Flipper; FIDO requests are accepted only from a paired, encrypted and authenticated link. Every sign-in still needs OK on the Flipper (and the PIN when the site asks for it).
- The approval screen shows the end of long site names (where the real domain is) and ignores OK for 0.4 s after a request appears, so an OK meant for something else does not approve it.
- Leaving the app wipes the PIN-derived key from memory; it also expires 32 s after the last PIN use.
Что нужно: Flipper Zero с прошивкой Momentum mntm-012, карта microSD; для Bluetooth —
компьютер с Windows 10/11 и Bluetooth (Android и iPhone ключи по Bluetooth не используют —
там кабель).
- Скачайте zerofido.fap (все версии: Releases).
- Скопируйте на карту Флиппера как
apps/USB/zerofido.fap(qFlipper → File manager → SD Card → apps → USB, мобильное приложение Flipper или картридер). - На Флиппере: Apps → USB → ZeroFIDO. В Momentum можно вынести в главное меню (настройки Momentum → Interface → Main menu).
- Кабель в компьютере — работает как USB-ключ; без кабеля — по Bluetooth.
- PIN по желанию (рекомендуется, длинный — 8+ символов, можно с буквами): с кабелем в Windows Параметры → Учётные записи → Варианты входа → Ключ безопасности → Управление, или в меню приложения (вправо → Menu → PIN).
- Спаривание с Windows по Bluetooth (один раз): ZeroFIDO открыт, кабель отключён → на ПК Параметры → Bluetooth и устройства → Добавить устройство → Bluetooth → FIDO <имя Флиппера> → на ПК и на Флиппере один и тот же код из 6 цифр → OK на Флиппере и Подключить на ПК. Подтверждайте код, только когда спариваете свой компьютер.
- Вход: на сайте выберите «ключ безопасности», при запросе введите PIN на ПК; Флиппер вибрирует и мигает синим — нажмите OK. Если аккаунтов на сайте несколько и вы входите без имени, список аккаунтов покажет Windows на экране ПК (нужен PIN; без PIN выбор — на Флиппере). Проверка: webauthn.io.
- При выходе из ZeroFIDO обычный Bluetooth Флиппера (мобильное приложение) возвращается.
Данные: passkey и хранилище PIN — в /ext/apps_data/zerofido/, зашифрованы ключом этого
Флиппера (копия папки работает только на нём же). Делайте копию перед обновлениями.
Безопасность: у Флиппера нет защищённого чипа — с Флиппером в руках PIN можно перебирать
(~1 попытка в секунду), поэтому главная защита — длинный PIN.
The text below is the original ZeroFIDO README. Where it differs from the fork (transports, U2F, attestation), the tables above apply.
ZeroFIDO turns a Flipper Zero into a passkey and security-key app. Install the .fap,
open ZeroFIDO, and approve sign-ins on services that support FIDO2/WebAuthn or legacy U2F.
The app stores credentials on the Flipper, asks for local approval, supports ClientPIN,
and speaks the CTAP2/FIDO2 protocol used by browsers and security keys. USB HID handles
desktop browser flows. NFC builds handle phone flows.
NFC has been tested on iPhone. Android NFC support is next. In the meantime, connect the Flipper to the phone over USB when the phone accepts USB security keys.
U2F and FIDO2.0 pass their respective tests in the current FIDO Conformance Tools suite. FIDO2.1 support is in development behind a developer-only build flag. Bug reports, feature requests, and pull requests are welcome.
- Download a release
.fapfrom GitHub Releases. - Copy it to your Flipper SD card under the Tools apps folder, or install it through qFlipper or Flipper Lab.
- Open ZeroFIDO on the Flipper.
- Register it as a passkey or security key on a site that supports WebAuthn/FIDO2.
- Approve registration and sign-in prompts on the Flipper screen.
| Capability | Status |
|---|---|
| USB HID | Supported in the usb and full release profiles |
| NFC | Supported in the nfc and full release profiles |
| U2F V2 | Supported |
| FIDO2.0 / CTAP2.0 | Supported |
| FIDO2.1 / CTAP2.1 | Developer-only experimental build flag |
ClientPIN |
Supported |
| Discoverable credentials | Supported |
| Attestation | Local software attestation when requested |
ZeroFIDO builds as an external .fap in the Flipper Tools category.
Open ZeroFIDO before starting a passkey or security-key flow.
- On desktop, connect the Flipper over USB and use the USB HID build.
- On phones, hold the Flipper near the NFC reader and use the NFC build. NFC is currently tested on iPhone; Android NFC support is planned. If the phone supports USB security keys, USB is the fallback.
- When the Flipper asks for approval, confirm only if the site and account look right.
- If a site asks for a PIN, use the browser or phone prompt. ZeroFIDO keeps the PIN retry state on the Flipper and uses the standard CTAP PIN token flow.
ZeroFIDO includes an on-device Settings screen.
| Setting | Use |
|---|---|
| Transport | Choose USB HID or NFC when the build includes both transports. |
| Attestation | Choose how MakeCredential answers attestation requests. |
| PIN | Set, change, or manage the ClientPIN used by sites that require user verification. |
| Auto-accept | Test mode for flows that should not require a touch prompt. Only appears when built with ZEROFIDO_AUTO_ACCEPT_REQUESTS=1. |
- ZeroFIDO runs on general-purpose Flipper Zero hardware. There is no secure element, so physical access to the device changes the risk model.
- Credential private keys are generated on the device and stored only after being wrapped with the Flipper crypto enclave unique key and a per-record IV. App storage still contains the metadata needed to find and use credentials, including relying-party IDs, user fields, public keys, wrapped private keys, IVs, and counters.
- Counter floor files and PIN retry state are sealed with the same Flipper crypto APIs. ZeroFIDO protects key material and rollback-sensitive state; it does not encrypt the whole app directory.
- Attestation is local software attestation, not hardware-backed vendor provenance, and ZeroFIDO is not FIDO Alliance certified.
- Keep at least one backup sign-in method for accounts you care about.
Choosing Attest: none or Attest: packed
ZeroFIDO defaults to Attest: none and supports two MakeCredential attestation modes from the
on-device Settings screen:
Attest: nonereturnsfmt: "none"with an empty attestation statement. The credential is still created normally, but ZeroFIDO does not include the local attestation certificate chain or attestation signature.Attest: packedallows local software packed attestation when the relying party requests direct attestation. This identifies the ZeroFIDO install, not hardware-backed vendor provenance.
If the CTAP request includes attestationFormats and names a supported format, that explicit
preference wins over the saved setting. ZeroFIDO currently supports none and packed.
Developer setup, builds, validation, releases, and certification metadata
Install uv, then sync the Python tools:
uv syncThe Python toolchain declares Python 3.14+ in pyproject.toml. C validation expects
clang-format, clang-tidy, cppcheck, and a host C compiler.
On macOS:
brew install llvm cppcheckThe app manifest reads ZEROFIDO_PROFILE at build time. The default profile is usb, with
the stable FIDO2.0 profile enabled by default. Release builds default to
ZEROFIDO_RELEASE_DIAGNOSTICS=0.
| Profile | Build flag | Use |
|---|---|---|
| USB HID only | ZEROFIDO_PROFILE=usb |
Default; desktop browser WebAuthn and U2F testing. |
| NFC only | ZEROFIDO_PROFILE=nfc |
Phone and NFC conformance work. |
| Full | ZEROFIDO_PROFILE=full |
Both transports in one app. |
Release-default builds exclude the NFC trace implementation. Diagnostics must opt in:
ZEROFIDO_PROFILE=nfc ZEROFIDO_RELEASE_DIAGNOSTICS=1 uv run python -m ufbtBuild a profile:
ZEROFIDO_PROFILE=nfc uv run python -m ufbt
ZEROFIDO_PROFILE=usb uv run python -m ufbt
ZEROFIDO_PROFILE=full uv run python -m ufbtBuild and launch on a connected Flipper:
ZEROFIDO_PROFILE=usb uv run python -m ufbt launchThe normal build output is dist/zerofido.fap.
Run the maintained Python tests:
uv run python -m unittest discover -s tests -t . -p 'test_*.py'Run native protocol regressions:
uv run python tools/run_protocol_regressions.pyThe native harness checks packed attestation, runtime Attest: none, explicit
attestationFormats: ["none"], and required packed-attestation failures.
Run C formatting and analyzers:
uv run python tools/check_c.py format
uv run python tools/check_c.py format --fix
uv run python tools/check_c.py tidy
uv run python tools/check_c.py cppcheck
uv run python tools/check_c.py native
uv run python tools/check_c.py allCheck SDK symbols against a local Flipper firmware checkout:
uv run python host_tools/check_symbol_gate.py --sdk-root <flipper-firmware-checkout>Check and package a built .fap with the release export gate:
uv run python host_tools/check_symbol_gate.py \
--fap dist/zerofido.fap \
--output-fap dist/zerofido-release.fapList and probe FIDO HID devices:
uv run python host_tools/ctaphid_probe.py --cmd list
uv run python host_tools/ctaphid_probe.py --cmd init
uv run python host_tools/ctaphid_probe.py --cmd getinfo
uv run python host_tools/ctaphid_probe.py --cmd makecredential
uv run python host_tools/ctaphid_probe.py --cmd getassertionRun U2F transport probes:
uv run python host_tools/ctaphid_probe.py --cmd u2fversion
uv run python host_tools/ctaphid_probe.py --cmd u2fregister --u2f-cert-out metadata/u2f-attestation.der
uv run python host_tools/ctaphid_probe.py --cmd u2finvalidcla
uv run python host_tools/ctaphid_probe.py --cmd u2fversiondata
uv run python host_tools/ctaphid_probe.py --cmd u2fauthinvalidCapture a FIDO2 attestation leaf certificate from MakeCredential:
uv run python host_tools/ctaphid_probe.py \
--cmd makecredential \
--fido2-cert-out metadata/fido2-attestation.derCapture NFC trace lines from the Flipper USB CDC console:
uv run python host_tools/nfc_trace_console.py --port auto
uv run python host_tools/nfc_trace_console.py --port <serial-port> --level info --output .tmp/nfc-trace.logThe iPhone NFC transport notes are in docs/writeup_ios.md.
Capture reconnecting crash logs from the same CDC console:
uv run python tools/flipper_crash_log.py --port auto --output .tmp/flipper-crash.logPrint firmware footprint data after building:
uv run python host_tools/size_ledger.py --artifact dist/zerofido.fap --artifact dist/zerofido-release.fapBuild a release .fap for the selected profile and verify that the app exports only
zerofido_main:
ZEROFIDO_PROFILE=usb \
ZEROFIDO_RELEASE_DIAGNOSTICS=0 \
uv run python host_tools/package_release.pyPackage an existing dist/zerofido.fap without rebuilding:
uv run python host_tools/package_release.py \
--skip-build \
--fap dist/zerofido.fap \
--output-fap dist/zerofido-release.fapThe packaged artifact lands at dist/zerofido-release.fap by default.
The Build profiles workflow verifies every push and pull request. The Release workflow
publishes GitHub Releases from existing v* tags.
Create and push a tag:
git tag v0.7.0
git push origin v0.7.0The release workflow builds the nfc, usb, and full profiles with
ZEROFIDO_RELEASE_DIAGNOSTICS=0, packages the stripped *-release.fap artifacts, and uploads
SHA256SUMS.
You can also run the workflow from GitHub Actions with an existing tag such as v0.7.0.
Metadata and captured attestation certificates belong to your local certification run. Keep them
under metadata/; git ignores that directory. The exporter creates metadata/ and a default
metadata/statement.json when they are missing.
uv run python host_tools/export_certification_metadata.py \
--statement metadata/statement.json \
--profile fido2-2.0 \
--client-pin-state unset
uv run python host_tools/export_certification_metadata.py \
--statement metadata/statement.json \
--profile fido2-2.1-experimental \
--client-pin-state unsetThe fido2-2.1-experimental metadata profile is for development builds created with
ZEROFIDO_DEV_FIDO2_1=1; release builds ship the FIDO2.0 profile.
The default outputs are:
metadata/metadata-ctap20.jsonmetadata/metadata-ctap21-experimental.json
For FIDO2 packed attestation chain checks, export metadata with the certificate returned by the same device:
uv run python host_tools/ctaphid_probe.py \
--cmd makecredential \
--fido2-cert-out metadata/fido2-attestation.der
uv run python host_tools/export_certification_metadata.py \
--statement metadata/statement.json \
--profile fido2-2.0 \
--fido2-attestation-cert metadata/fido2-attestation.derFor U2F, export metadata from the certificate returned by U2F Register:
uv run python host_tools/ctaphid_probe.py \
--cmd u2fregister \
--u2f-cert-out metadata/u2f-attestation.der
uv run python host_tools/export_certification_metadata.py \
--statement metadata/statement.json \
--profile u2f \
--u2f-attestation-cert metadata/u2f-attestation.derIf U2F metadata reports an attestation SKID or certificate-path mismatch, regenerate
metadata/u2f-attestation.der and metadata/metadata-u2f.json from the same device build you are
testing. Older builds regenerated U2F attestation during reset, so metadata captured before a reset
can be stale.
If the conformance tool changes PIN state, regenerate metadata with the matching
--client-pin-state before rerunning that profile.
ZeroFIDO is built and maintained in spare time. If it helped you, you can support the work here:
Support is optional and does not affect releases, issues, or support requests.
ZeroFIDO uses the GNU General Public License, version 3 or later. See LICENSE.
Dependency and provenance notes live in THIRD_PARTY_NOTICES.md.









