Skip to content

Repository files navigation

AmiAuth

A native two-factor authentication (2FA) code generator for classic AmigaOS.

AmiAuth implements TOTP (RFC 6238) and HOTP (RFC 4226): it stores multiple accounts, generates 6- or 8-digit codes with a live countdown, and — critically for the platform — solves the accurate-time problem that TOTP depends on. Small, self-contained, and designed to run on anything from a stock 68000 A500 up to an accelerated or emulated machine.

Status: v1.0 released (see the v1.0 milestone). The portable core (crypto, OTP, vault, otpauth:// import), the CLI, and a resident ReAction GUI commodity (live all-accounts view, add/remove/edit, clipboard copy, QR-image import, hotkey/Exchange/WBStartup, single-instance) are all RFC-verified, cross-build to real AmigaOS binaries, and have passed an interactive on-hardware verification pass on OS 3.2, including logging into GitHub with a code generated on real hardware. Post-v1.0 ideas are tracked in the v2 milestone.

AI-assisted development

Be aware: AmiAuth was written largely by an AI coding agent (Anthropic's Claude, via Claude Code), working under human direction. The scope, design decisions, and on-hardware testing were human-directed and reviewed; most of the code itself was AI-generated.

Because this is a security tool, that disclosure matters — please weigh your trust accordingly rather than taking it on faith. To make the code auditable instead of asking for blind trust, the cryptographic primitives (SHA-1, HMAC, PBKDF2, ChaCha20) are checked against their published RFC test vectors and differentially fuzzed against OpenSSL in CI, and the entire source is BSD-licensed and open for review. Read docs/SECURITY.md and judge it for yourself.

Why

No TOTP tool exists for classic AmigaOS. Anyone using an Amiga day-to-day still reaches for a phone to log into GitHub, forge sites, or their own services. AmiAuth aims to make "my A1200 is my 2FA device" a real, daily-useful thing.

Features (v1)

All implemented:

  • TOTP & HOTP — SHA-1/256/512, 6-8-digit codes, configurable period (30s default) and T0, plus Steam Guard's own TOTP variant, all validated against the official RFC (or independently-derived Steam) test vectors.
  • Easy secret entry — padding/whitespace/case-tolerant Base32 decoding and otpauth:// URI parsing, so secrets from another authenticator paste directly.
  • Multi-account store — issuer/label per account, ordered list.
  • Encrypted vault — accounts encrypted at rest with a master passphrase (PBKDF2 + ChaCha20, encrypt-then-MAC), with a per-machine KDF calibration and adaptive re-key, or an optional always-unlocked mode for single-user/headless machines. Encrypted create/save works on real hardware (AmigaOS CSPRNG).
  • Accurate time without a working clock — SNTP sync over bsdsocket, a locale.library offset, and a manual offset/nudge, layered so it works with zero config on a networked machine and degrades gracefully to a floppy-booted A500, with a red/amber/green trust indicator in the GUI.
  • CLI — dependency-free, works down to OS 2.x: CODE, INIT, ADD, LIST, GET, REMOVE, SHOW, CLOCK, SYNC, OFFSET. On Amiga it uses standard ReadArgs parsing (AmiAuth GET GitHub, options as keywords like VAULT/ITERATIONS; AmiAuth ? for the template, HELP for the command list).
  • ReAction GUI — a live all-accounts list with per-account codes + countdown, a big selected-code display and fuelgauge, add / remove / edit, clipboard copy (with auto-clear), the clock-status LED, idle auto-lock for encrypted vaults, and QR-image import (decode an otpauth:// enrolment QR from a PNG/JPEG/GIF/IFF via a file requester or drag-and-drop).
  • Background commodity — the GUI lives in Exchange, pops up on a hotkey, runs from WBStartup, and is single-instance: one resident process holds the unlocked vault, and the CLI forwards commands to it (no second passphrase prompt) rather than opening the vault independently.
  • ARexx port — script GETCODE, LIST, TIMELEFT, STATUS, LOCK, UNLOCK, SHOW/HIDE and QUIT against a resident GUI from any ARexx-aware program (no second passphrase prompt, same as CLI forwarding).
  • Localization — the CLI and GUI's strings load from locale.library message catalogs, with translations selected by the user's preferred languages.

Design principles

  • 68000 is the baseline target — everything builds and runs on a plain 68000 (-m68000), so AmiAuth works on stock hardware. Requiring 020+ needs a very good reason; anything that does (an optional AmiSSL or hand-written-asm crypto provider) is opt-in via runtime CPU dispatch, never the minimum.
  • Zero mandatory dependencies beyond the OS — all crypto is vendored; no AmiSSL requirement. bsdsocket is used only opportunistically for SNTP.
  • Portable, testable core — the OTP and crypto code is plain C with a host-side build target, so RFC vectors run in CI without an emulator.
  • Honest security — the docs state the threat model plainly. The vault protects secrets at rest; it does not defend against a compromised running OS (AmigaOS has no memory protection). See docs/SECURITY.md.

Building

make test         # host unit + RFC-vector tests
make cli          # native CLI  -> build/amiauth-host
make smoke        # end-to-end CLI smoke test
make diff         # differential fuzz vs OpenSSL (opt-in; needs libcrypto)
make m68k-docker  # AmigaOS CLI via the amiga-gcc container -> build/AmiAuth
make gui-docker   # AmigaOS ReAction GUI  -> build/AmiAuthGUI
make gui-smoke    # headless GUI render test (WB 3.2 under Copperline)

The core is portable C, so test/cli build with any host compiler. Example: build/amiauth-host CODE JBSWY3DPEHPK3PXP prints a code.

Running the GUI as a commodity

AmiAuthGUI registers as an AmigaOS Commodity: it appears in Exchange (Show/Hide/Enable/Disable/Kill), pops up on a hotkey, and is single instance — one resident process holds the unlocked vault, and a second launch just makes the running one appear. Closing the window hides it (the process stays resident, vault unlocked); the hotkey or Exchange "Show" brings it back. Quit for real from Project → Quit or Exchange's "Kill".

Drop it in WBStartup (or run from the Startup-Sequence) with these icon tooltypes:

Tooltype Default Meaning
CX_POPKEY ctrl alt a hotkey that shows/raises the window
CX_POPUP yes no = start hidden (window opens on the hotkey)
CX_PRIORITY 0 commodity broker priority
TIMESERVER pool.ntp.org SNTP server for the startup time sync (else the saved server pref)
DONOTWAIT — (WBStartup) don't make Workbench wait for it

On startup the GUI does one SNTP time sync (if a TCP/IP stack is up) so its clock is accurate — this is what lights the status LED green; it fails quietly offline and falls back to the saved offset. Without commodities.library the GUI degrades to a plain window (close = quit).

Documentation

User documentation lives at sidick.github.io/amiauth — installation, getting started, the CLI command reference, the GUI and commodity/tooltypes, vault and passphrases, time sync, settings, and troubleshooting/FAQ. The site is versioned per release (version picker in the header); its source is userdocs/ in this repository, and the same pages become the AmiAuth.guide shipped in the release archive.

Developer-facing design notes live in docs/:

Toolchain

C via amiga-gcc, GitHub Actions CI running host-side RFC vector tests, a CLI smoke test, an OpenSSL differential fuzz job, and an m68k build; Aminet packaging via aminet-release-action. The core tool targets plain 68000 to maximise the audience.

License

BSD 2-Clause. Copyright (c) 2026 Simon Dick. See LICENSE.

Bundled third-party source (the ISC-licensed quirc QR decoder) is listed in THIRDPARTY.md.

About

Native TOTP/HOTP two-factor authenticator for classic AmigaOS — CLI and ReAction GUI, runs on a stock 68000

Topics

Resources

Security policy

Stars

4 stars

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages