kkeyroost

Learn · Token2 Molto2

Token2 Molto2

A programmable hardware TOTP token: it shows rolling 6-digit codes on a little screen, with no app, no battery anxiety, and no network — the original device keyroost was built to program.

keyroost screenshot — Programming a Token2 Molto2 slot, with the slot rail and per-slot TOTP settings.
Programming a Token2 Molto2 slot, with the slot rail and per-slot TOTP settings.

What it is

The Molto2 / Molto2v2 is a standalone TOTP token. You load account seeds into numbered slots, and the device displays the current code for each — entirely offline. Unlike a phone authenticator, there's no OS to compromise and nothing syncing to a cloud; unlike a single-account token, it holds many. It programs over a smart-card (PC/SC) interface.

Independent implementation

keyroost's Molto2 support was built by observing the device protocol and its public reference tool — it is not a fork of any vendor software. The wire format, SM4-CBC MAC, and config TLV are documented in the project's PROTOCOL.md.

Programming & bulk import

Load a single slot from an otpauth:// URI, or migrate a whole set of accounts at once:

keyroost can also sync the device clock to the host — important, because TOTP depends on accurate time, and a drifted clock shows wrong codes.

The customer key

Writes to the Molto2 are authenticated with a device customer key — a secret that gates programming so that not just anyone with physical access can reprogram your token. Sensitive commands are wrapped in an SM4-CBC MAC keyed by it.

Rotating & resetting are consequential

Rotating the customer key or factory-resetting the token changes what it will accept. A factory reset wipes the loaded profiles and restores the default customer key, and the token makes you confirm it with its own button. Make sure you can re-derive every seed before you do either. See resetting →

What keyroost does with the Molto2

k

Read slot occupancy and titles; program a slot from an otpauth:// URI; set a slot's title or delete it; bulk-import from Aegis / 2FAS / an otpauth:// list; sync the host clock; rotate the customer key; and factory-reset — over a pure-Rust protocol layer (SM4, SHA-1, APDU builders, MAC) with no external crypto dependencies.

The single-profile siblings (OTPC, miniOTP, C30x)

The Molto2 holds many accounts; Token2 also makes a family of single-profile programmable tokens that hold exactly one. These are card- and fob-shaped tokens — OTPC-P1-i / OTPC-P2-i, miniOTP-2-i / miniOTP-3-i, C301-i, and C302-i — that show one rolling code on a small display. keyroost programs them over the same kind of smart-card (PC/SC) interface as the Molto2, over a contactless or contact (chip) reader.

No customer key — a fixed device key

Unlike the Molto2, these tokens don't have a per-device customer key. They authenticate with a single fixed device key, so there's nothing to rotate or lose — but equally, anyone with physical access and a reader can reprogram one. The wire protocol (a close relative of the Molto2's, same SM4 cipher and MAC) is documented independently in the project's PROTOCOL-token2prog.md.

k

From the CLI: keyroostctl prog info (serial, model, on-device clock), keyroostctl prog seed (seed from stdin or an environment variable — --base32-stdin / --base32-env, so it stays out of ps and shell history), and keyroostctl prog config (algorithm, time-step, display timeout). The GUI offers the same on a dedicated programmable-token pane.

Troubleshooting

These are behaviors of the Molto2 hardware and the smart-card layer, not bugs in keyroost — any smart-card software talks to the token the same way and sees the same thing.

The token stops charging while it's plugged into a computer

The Molto2 stops charging the moment your operating system's smart-card service enumerates it — on Linux, when pcscd brings up the card interface. This happens as soon as the token is detected, before any program authenticates or writes to it, so no particular application causes it. To charge the token, use a plain USB power source — a charger or power-only cable with no computer attached. (On a nearly full battery it tops off in about half a minute and then stops, which is normal.)

The token isn't detected / doesn't show up

The Molto2's card interface sometimes fails to initialize on first contact, so the token is present on USB but no smart-card reader ever appears. The smart-card service only attempts initialization at the moment the token is plugged in — so waiting doesn't help, and neither does restarting the service. Each replug is a fresh attempt:

Don't restart the smart-card service to fix detection

Restarting pcscd can't help here — it only retries a token's initialization when the token is plugged in — and restarting it while the token has a healthy, active connection pulls the card interface out from under it and hangs the firmware: the screen freezes. If that happens, power-cycle the token (turn it off and back on) and it comes back cleanly.

I programmed a slot but it doesn't show a code

A slot shows a rolling code only once it has a seed (the TOTP secret). Writing only a title sets a label and nothing else — use the full write (seed + title + settings), not the title-only action, when you want the slot to generate codes.

Can anyone read my slot titles without the customer key?

Yes. The Molto2 answers title and occupancy reads without the customer key, so anyone with physical access to the token can list which slots are used and how they're labeled. Don't put secrets in slot titles. Seeds and codes are never readable back off the device.

Authoritative resources