Close
0%
0%

EvilKey: I Needed a FIDO2 Key. Then the Maker Brain Took Over.

A Waveshare ESP32-S3 FIDO2 key with on-device PIN entry, a touch AMOLED, a script-driven USB Tool and an IMU air mouse. Yes, it escalated.

Similar projects worth following
0 followers
I needed a FIDO2 key for my OpenAI account. One detour through Pico FIDO and a Waveshare board later, I had EvilKey: a touch-screen security key with PIN entry on the device, a deliberately launched USB scripting role and an IMU air mouse. The firmware is open source; the Manager and original microSD examples have separate licenses. The current case is home printed, while the black SLS finish shown in the concept image is planned. Build notes, limits and source links are below.

A perfectly reasonable problem, followed by a perfectly unreasonable response

My OpenAI account asked me for FIDO2 authentication while I was working with an active Daybreak Blue model. I needed a security key. The sensible plan was to buy a YubiKey, log in and get on with my life. Naturally, that is not what happened.

I found the open-source Pico FIDO project and ordered a Waveshare ESP32-S3 Touch AMOLED 1.64 board. Then came the maker's classic facepalm: I had overlooked that the community version did not give me everything I had pictured. The sensible response was still to use it as a FIDO2 key. Instead, a very old XDA Developers reflex woke up.

As a teenager I loved getting my hands dirty with firmware for early HTC phones, Windows Mobile and the first generations of Android. Back then, phones felt full of places where a curious community could improve things before manufacturers caught up. I remember how much fun it was to make an existing device do something its original menu had never imagined. That memory made me smile, then made me open the source tree. Apparently the older version of me still enjoys making hardware do extra things. Some useful. Some gloriously unnecessary.

EvilKey is the result: a FIDO2 key that acquired a dark AMOLED touch interface, on-device PIN entry, a script-driven USB tool and, because apparently a key should also steer a cursor, an air mouse. The Waveshare PCB is not my hardware design. The EvilKey firmware port, LVGL interface, Windows Manager, original microSD examples and enclosure work are my additions, with the upstream licenses and notices kept visible.

How the feature creep happened

  1. Make the key usable every day. Keep the FIDO2 role and build an interface that is readable on a 280 × 456 touch AMOLED, with large controls and a restrained dark palette.
  2. Put the PIN on the key. The touch screen provides a numeric keypad for FIDO2 built-in user verification: masked entry, a visible retry count and timeout, Backspace, Verify and Cancel. On compatible FIDO2 requests, I enter the PIN on EvilKey instead of typing it into the connected computer. The familiar host-side ClientPIN path remains available for setup and compatibility.
  3. Give it a face. The mint symbol and white crystal became a shared 3D screensaver. Both parts move in the same projected plane; the crystal turns around its vertical axis. The logo stays recognizable even when the animation briefly glitches.
  4. Win back display speed. Tune RGB565 rendering around two 64-row DMA-capable draw buffers when memory permits, with the LVGL object pool in PSRAM. Diagnostics reports the buffer layout actually allocated. On the tested device it showed 2 x 64 RGB565.
  5. Put the computer-side controls somewhere sane. The separately licensed EvilKey Manager handles device information, PIN and policy controls, credentials, display settings and offline inspection of USB Tool data.
  6. Give the security key an evil twin. USB Tool is a deliberately selected USB role with HID keyboard and mouse capabilities and optional microSD storage. The supported DuckyScript-style workflow lets a script drive host interactions: probe controls, test whether a defense can be bypassed, gather data accessible to that host session, and record results for later inspection in the Manager. That is the hacker's playground I wanted, with the interesting uses limited mainly by the supported commands, the host's permissions and the imagination of whoever writes the script. The name is not a promise of magical access: a defended machine can still say no. More importantly, a payload runs only after it is selected on the key and RUN is pressed. Merely plugging in EvilKey does not launch one. My teenage XDA self would, of course, have opened this menu first.
  7. Then add a mouse. The onboard QMI8658C turns tilt into relative USB HID pointer movement. The touchscreen provides left and right click and scrolling. Holding MOVE enables motion, releasing it pauses the pointer, and the settings...
Read more »

evilkey-sls-concept-hero.png

Concept visualization of the planned black SLS finish. The real working enclosure is currently home printed; this is not a production photograph.

Portable Network Graphics (PNG) - 1.90 MB - 09/26/2026 at 12:37

Preview

ready.png

Code-derived READY screen preview; not camera footage.

Portable Network Graphics (PNG) - 410.20 kB - 09/26/2026 at 12:37

Preview

pin.png

Code-derived on-device FIDO2 PIN keypad preview with illustrative masked digits; not a live PIN capture.

Portable Network Graphics (PNG) - 453.30 kB - 09/26/2026 at 12:37

Preview

diagnostics.png

Code-derived Diagnostics preview. A real device test previously showed 2 x 64 RGB565 draw buffers.

Portable Network Graphics (PNG) - 412.94 kB - 09/26/2026 at 12:37

Preview

usb-tool.png

Code-derived USB Tool screen preview. Scripts require local selection and RUN.

Portable Network Graphics (PNG) - 413.49 kB - 09/26/2026 at 12:37

Preview

View all 10 files

  • 1 × Waveshare ESP32-S3 Touch AMOLED 1.64 (PCB V1) ESP32-S3 board with 280 x 456 touch AMOLED and QMI8658C; this firmware targets PCB V1.
  • 1 × Short USB-C data cable / loop The prototype uses a short Unitek C14179ABK-style loop. Any equivalent cable must support USB data.
  • 1 × Custom home-printed prototype enclosure Current working case fitted to the Waveshare PCB V1. A professionally printed black SLS finish is planned, not yet produced.
  • 1 × M5 × 10 mm flat-point grub screw One M5 threaded, 10 mm long grub screw with a flat point, used in the current prototype assembly.
  • 4 × M2 × 5 mm screws Four screws fasten the Waveshare PCB V1 from the underside of the printed enclosure.

  • Would you build an EvilKey DIY kit?

    Michal Wojciechowski • 3 hours ago • 0 comments

    I am considering a complete DIY EvilKey kit based on the tested Waveshare ESP32-S3 Touch AMOLED 1.64 PCB V1, including a physical printed enclosure and a guide to assembly, flashing and testing. I am also considering a separately sold printable enclosure file for people who already own the board or prefer to print their own case.

    Before defining the kit or accepting any orders, I would like to understand what would make it useful and realistic for builders. Please leave a comment with any of the following answers:

    1. Would you be interested in building it? Yes / Maybe / No.
    2. Do you already own the Waveshare PCB V1? Yes / No / Unsure.
    3. Which option fits you: complete kit with a physical case / electronics-only kit plus a printable case file / printable case file only?
    4. What would you need in the box or in the instructions to assemble it confidently?
    5. Which country would it need to ship to, and what total kit price before shipping would you consider reasonable?
    6. Which feature matters most to you: FIDO2, on-device PIN entry, the touch UI, Air Mouse, USB Tool, or the ability to modify the firmware?

    You can answer just the questions relevant to you. A brief comment such as Yes; no board; kit without case + printable file; Germany; FIDO2 + Air Mouse is useful. Please do not post email addresses, shipping addresses or authentication data in the comments.

    This is an interest check, not a preorder, reservation or promise of a sale. The exact contents, price, supported board revisions, fulfillment countries and launch date remain undecided. Any future listing will link back to the source and assembly instructions at https://github.com/mwr666/EvilKey-firmware.

  • One display, three USB roles: how EvilKey keeps the controls responsive

    Michal Wojciechowski • 3 hours ago • 0 comments

    The EvilKey prototype uses Waveshare's ESP32-S3 Touch AMOLED 1.64 PCB V1. Its compact board already combines a 280 × 456 touch AMOLED, native USB, a QMI8658C motion sensor and a microSD slot. That made it possible to build an interactive key without adding a separate motion sensor or external display controller. Waveshare also sells a V2 revision with different pin assignments, so the current firmware target is explicitly V1.

    The user interface was designed around short, readable screens and touch regions large enough to operate while holding the device. For display performance, the firmware tries to allocate two 64-row RGB565 draw buffers in DMA-capable internal memory and places the LVGL object pool in PSRAM. The Diagnostics page reports the buffer arrangement that actually started, instead of assuming the preferred configuration was available.

    The FIDO2 PIN screen is a functional part of that interface. For built-in user-verification requests, EvilKey accepts a configured numeric FIDO PIN on its own 3 × 4 touch keypad. Digits are masked; the screen shows retry count and timeout, while Backspace, Verify and Cancel remain large touch targets. The local check uses the existing PIN verifier and retry budget. Standard ClientPIN is still advertised because host-side setup and clients that do not use built-in UV need it. This avoids claiming that every login is host-PIN-free. The PIN flow notes explain the protocol scope. The interface preview is code-derived; a filmed demonstration of the final on-device PIN flow is still pending.

    Air Mouse is an example of a mode that needs both hardware and interface design. On entry, it samples the QMI8658C to establish a neutral orientation. Tilt becomes a relative HID pointer with a shared radial dead zone, smoothing and fractional movement accumulation, so diagonal motion does not have to choose between horizontal and vertical movement. A large MOVE touch region acts as a hold-to-move clutch. The other touch regions remain available for click and scroll; on-device settings provide recalibration, sensitivity and vertical inversion.

    USB roles are intentionally distinct. The Air Mouse role enumerates as a relative mouse; the USB Tool role is selected separately; FIDO is the normal role. USB Tool scripts require local selection and a press of RUN. This keeps the behavior inspectable and prevents a script from running merely because the device was connected.

    Diagram of EvilKey FIDO, Air Mouse and USB Tool roles

    The three USB roles are selected separately. The diagram describes intended enumeration, not three modes active at once.

    The current firmware passed a physical smoke test of Air Mouse controls and return to FIDO. Long-running drift, repeated reconnection and complete product qualification are still separate work. The repository records the exact scope of the tests and documents the source and firmware build: https://github.com/mwr666/EvilKey-firmware

    Next I am gathering feedback on a possible DIY kit. The following project log asks what makers would actually want included, and whether they would print the enclosure themselves.

View all 2 project logs

  • 1
    Identify PCB V1 and gather the parts

    This build targets the Waveshare ESP32-S3 Touch AMOLED 1.64, PCB V1. Check the revision on the physical board before installing firmware. The current EvilKey image and case have not been validated for PCB V2.

    Gather one V1 board, a USB-C cable that carries data, the printed V1 enclosure, the short Unitek USB-C loop shown in the prototype, four M2 × 5 mm screws that secure the board from below, and one M5 × 10 mm flat-point grub screw that locks the loop into the case. A microSD card is optional for USB Tool examples. The display, touch panel and IMU are already on the board; this prototype is USB powered and has no battery.

  • 2
    Prepare the Windows firmware toolchain

    Download the complete source from the public EvilKey firmware repository. Read installation information before changing a board that holds FIDO credentials.

    On Windows install Arduino CLI, Python, Git, Arduino-ESP32 3.3.12 and the Waveshare PCB V1 board definition. The project pins its upstream revisions. Its USB stack checker may require the documented local TinyUSB hook in the shared Arduino core; follow the checker output instead of substituting a different board package.

  • 3
    Prepare and build the firmware

    From a terminal opened in the extracted public repository, run these commands in order:

    1. cd firmware
    2. python prepare_arduino.py
    3. python build_arduino.py

    The build checks the USB stack and writes the image to firmware/build-arduino/EvilKeyV1.ino.bin. If preparation reports a missing pinned USB hook, resolve it using the repository instructions and rerun the build. Keep the build output and error messages together; do not flash an image from a different board revision.

View all 8 instructions

Enjoy this project?

Share

Discussions

Does this project spark your interest?

Become a member to follow this project and never miss any updates