Safeguard
Supply Chain Security•

How a Keyboard Is Made: Switches, PCB, Firmware and Wireless Pairing

A keyboard is switches on a scanned matrix, a microcontroller running firmware and a USB or Bluetooth HID link. Each step, from pellet to paired board.

Safeguard Security Team
49 min read

A keyboard is made by moulding plastic switch parts and keycaps, building a printed circuit board that wires every switch into a grid of rows and columns, and soldering on a small microcontroller that scans that grid hundreds or thousands of times a second. The microcontroller runs firmware that turns closed switches into USB HID reports or Bluetooth LE notifications, and that firmware is flashed and tested at the factory and can usually be replaced later through a bootloader. Wireless models add a radio, a battery and a pairing step, and the security of the whole device rests on how that firmware and that pairing were built.

This post goes one level deeper than our builds of a laptop and a desktop PC, where the keyboard was one line in a parts list. For the board itself see how a printed circuit board is made, for the chip see how semiconductors are made, for USB threats in general see USB risks, BadUSB, lost drives and air gapped transfer, and for the Bluetooth side see Bluetooth LE GATT, pairing, bonding and attribute security.

Keyboard makers do not publish their moulding recipes, yields or switch test rigs. Where a standard or an official project document gives a number, we cite it. Where none does, we describe the step without inventing a figure, and any arithmetic below is labelled illustrative.

Key takeaways

  • A keyboard has seven main parts: switches (or a membrane), an optional plate, a PCB with a key matrix and usually one diode per key, a microcontroller, a USB or wireless interface, a case, and keycaps.
  • Switches come in several sensing families. Mechanical and membrane switches close an electrical contact; optical switches interrupt a light beam; Hall effect switches measure a magnet's field; capacitive designs measure a change in capacitance. Only contact based switches need classic debouncing.
  • The controller scans the matrix by driving one column at a time and reading the rows. Diodes stop "ghost" keys when several keys are held at once, a mechanism the open source QMK documentation walks through step by step.
  • Over USB, a keyboard is a Human Interface Device. The USB HID 1.11 specification (2001) defines an 8 byte boot keyboard report with room for six ordinary keys plus modifiers, which is where "6 key rollover" comes from. N key rollover needs a different report layout in the device's report descriptor.
  • Keyboard firmware is usually updated through a bootloader. Many open source keyboards use a USB DFU or UF2 bootloader, and the USB DFU 1.1 specification (2004) leaves image verification to the vendor: it defines how bytes move, not who signed them.
  • Bluetooth LE keyboards use the HID over GATT Profile, adopted with a revision date of 27 December 2011, which requires bonding and an encrypted link. Proprietary 2.4 GHz dongles follow whatever the vendor designed, and CERT/CC warned in February 2016 that several used protocols without proper encryption.
  • Hosts trust keyboards by default. The Linux kernel documentation states plainly that, by default, all USB devices are authorized. Device allow lists, port controls and procurement rules are how organisations narrow that trust.

Raw material to boxed keyboard: the step table

This is the map for the rest of the post. It names the check at each stage rather than a pass rate, because no maker we could find publishes one.

StepInputWhat happensTypical checksOutput
1. Resin and compoundingABS, PBT, polycarbonate and nylon pellets, colourantsPlastic is dried and coloured for housings, stems, keycaps and casesMoisture content, colour matchReady to mould resin
2. Switch part mouldingResin, steel tool mouldsInjection moulding forms switch housings and stems; springs are coiled from steel wire; contact leaves are stamped from copper alloy and platedDimensional checks, flash and short shots, spring force samplesSwitch components
3. Switch assemblyHousings, stems, springs, contacts or magnetsParts are assembled and closed; mechanical switches get contacts, Hall effect switches get a magnet in the stem, optical switches get a shutterForce curve and travel sampling, contact resistance or signal checks, lifecycle samplesFinished switches
4. Keycap moulding and legendsABS or PBT resinCaps are moulded once or twice (doubleshot); legends are added by second shot, dye sublimation, laser or printingFit on stems, legend sharpness, wear tests on samplesKeycap sets
5. Bare PCB fabricationCopper clad laminateTraces for the key matrix, USB lines and antenna are etched, drilled, plated, masked and finishedElectrical test for opens and shortsBare board
6. Controller siliconWafer from a chip foundryMicrocontroller with USB, and on wireless boards a Bluetooth or 2.4 GHz radio, is fabricated and packagedWafer probe and final test at the chip makerPackaged MCU or radio SoC
7. SMT assemblyBare PCB, MCU, diodes, crystal, connector, ESD parts, LEDs, battery chargerSolder paste, pick and place, reflow; switch sockets or switches addedAutomated optical inspection, X ray on fine pitch partsAssembled PCB
8. Bootloader and firmware flashAssembled PCB, signed or unsigned imagesA programmer writes the bootloader, then the application firmware, over SWD, JTAG or USB; wireless boards get a device address and calibrationReadback or checksum, version string check, USB enumerationProgrammed PCB
9. Board functional testProgrammed PCBA fixture presses or shorts every matrix position, checks LEDs, USB descriptors, and on wireless boards radio power and pairingEvery key reports the right usage; current draw; RF testTested PCB
10. Final assemblyPCB, plate, switches, stabilisers, case, battery, keycapsPlate and switches fit, stabilisers lubricated, case closed, caps pressed onFull keypress test on the finished keyboard, visual inspectionFinished keyboard
11. Compliance and packingFinished keyboardSample units go through emissions testing and, for radios, intentional radiator rules; units are labelled, boxed with cable or dongleRegulatory labels, serial and firmware version recordedBoxed keyboard

Two rows matter most for security. Step 8 is where the code that will run on the keyboard for years is chosen and written, and step 9 is the last point at which a factory confirms the device announces itself as what it claims to be.

A dated timeline of keyboard standards and research

DateEventWhy it mattersSource
27 June 2001USB HID Device Class Definition 1.11 publishedDefines report descriptors, the boot protocol and the 8 byte boot keyboard report still used todayUSB-IF HID 1.11
5 August 2004USB Device Firmware Upgrade specification 1.1Standard way to move a firmware image into a USB device; verification left to the vendorUSB-IF DFU 1.1
2007Linux USB device authorization featureLets the operating system hold a new USB device unconfigured until it is approvedLinux kernel docs; USBGuard
27 December 2011HID over GATT Profile 1.0 revision dateDefines Bluetooth LE keyboards, mice and other HID devices, with mandatory bonding and encryptionBluetooth SIG HOGP 1.0
2014"BadUSB, On Accessories that Turn Evil" briefing at Black Hat USAShowed that reprogrammed USB controller firmware can make a device spoof other device typesBlack Hat USA 2014 archive
24 February 2016CERT/CC Vulnerability Note VU#981271Several wireless keyboard and mouse products used proprietary 2.4 GHz protocols without proper encryptionCERT/CC
1 February 2021CISA "Using Caution with USB Drives"Plain language guidance on USB device risks for individuals and organisationsCISA
26 January 2024HID Usage Tables 1.5Current table of usage codes, including the Keyboard/Keypad page (0x07)USB-IF HUT 1.5
20 June 2025ZMK project asks users to pin firmware versionsShows that open source keyboard firmware is now a versioned dependency you should pinZMK blog

What is inside a keyboard?

Pull the keycaps and unscrew the case of almost any keyboard and you find the same layers, in roughly this order from the top.

Keycaps

Keycaps are the moulded caps your fingers touch. They carry the legends and set the feel of the surface. They clip onto the switch stems, so on most mechanical boards they are interchangeable.

Switches or a membrane

Under each cap sits a switch. On a mechanical or magnetic board it is a discrete component, soldered or pressed into a socket. On most office and laptop keyboards there is no discrete switch at all: a rubber dome sheet pushes down on a printed membrane, or a scissor mechanism guides the cap onto a dome.

Plate

Many mechanical boards hold the switches in a steel, aluminium, brass, polycarbonate or FR4 plate. The plate keeps switches aligned and takes the load of typing off the solder joints. Some boards are plateless and rely on the PCB alone.

Stabilisers

Long keys such as the space bar, Shift and Enter use a wire stabiliser so the cap goes down level no matter where you press it. Stabilisers are a frequent source of rattle and are often lubricated at assembly.

PCB, diodes and the key matrix

The printed circuit board wires each switch into a grid of rows and columns, called the key matrix. On mechanical boards there is usually one small diode per switch, which stops phantom key presses when several keys are held. Membrane keyboards build the same grid out of printed conductive traces on plastic sheets instead of copper on fibreglass.

Controller

A microcontroller unit (MCU) scans the matrix, debounces it, maps positions to key codes and talks to the computer. On a wired board it needs a USB peripheral. On a wireless board the MCU is often a radio system on chip with Bluetooth LE, a proprietary 2.4 GHz mode or both, plus a battery charger and fuel gauge.

Interface, case and extras

A USB connector or a battery and antenna, the case, and sometimes backlight LEDs, a rotary encoder, a small display or a USB hub. Several extras add their own firmware or USB interfaces.

How are key switches made?

Mechanical switches

A typical mechanical switch has a two part housing, a stem, a coil spring and a pair of metal contact leaves. The housing and stem are injection moulded from engineering plastics; the spring is coiled from steel wire; the contact leaves are stamped from a copper alloy sheet and plated to resist corrosion. Pressing the key pushes the stem down, which lets one contact leaf touch the other and close a circuit. The shape of the stem and leaf set whether the switch feels linear, tactile (a bump) or clicky (a bump plus a sound from a separate click mechanism).

Because two pieces of metal meet, they bounce. For a few milliseconds after a press or release, the contacts can open and close several times, and a fast scanner would read that as several keystrokes. Firmware hides this with debouncing, covered below.

Makers rate switch lifetimes in keystrokes, and those ratings are vendor test claims under their own conditions. Wear shows up as scratchy feel, changing force or, in contact switches, intermittent chatter as contacts oxidise or deform.

Membrane and rubber dome switches

A membrane keyboard uses three thin sheets of polyester film. The top and bottom sheets are printed with conductive ink traces and pads; the middle sheet is a spacer with holes under each key. Above them sits a sheet of moulded silicone domes. Pressing a key collapses its dome, which pushes the top pad through the spacer hole onto the bottom pad and closes the circuit. Scissor switches in laptops add a pair of interlocking plastic arms that keep a thin cap level while it presses a dome. These parts are cheap to make in large sheets, quiet, and resistant to small spills, which is why most office keyboards use them. They still bounce, so they still need debouncing.

Optical switches

An optical switch places an infrared emitter and a detector on the PCB on either side of the switch. The stem carries a shutter that blocks or unblocks the beam when pressed. There are no contacts to bounce or oxidise, so the debounce problem largely goes away, though firmware still filters noise. The trade off is power: the emitters have to be pulsed, which matters on battery boards.

Hall effect magnetic switches

A Hall effect switch puts a small permanent magnet in the stem and a Hall effect sensor on the PCB under each key. As the stem moves, the magnetic field at the sensor changes and the sensor produces an analogue voltage that the controller reads. Because the controller sees a continuous position rather than a single on or off, firmware can set the actuation point per key, or report a key press as soon as the key starts moving back up (often marketed as "rapid trigger"). Calibration matters: magnets and sensors vary, so these boards usually calibrate each key at the factory or on first use, and store the results in firmware or non volatile memory.

Capacitive switches

Capacitive designs measure a change in capacitance as a conical spring or a plate approaches a pad on the PCB, again without metal contacts. Like magnetic switches, they need analogue sensing circuitry and per key thresholds in firmware.

Comparison: switch sensing methods

Switch typeWhat is sensedDebounce needMain wear mechanismAdjustable actuation
Mechanical (contact leaf)Metal contacts touchingHigh; contacts bounceContact wear, oxidation, spring fatigueNo, fixed by the leaf
Membrane or rubber domePrinted pads pressed togetherHighDome fatigue, trace crackingNo
Scissor over domePrinted pads under a domeHighDome and hinge wearNo
OpticalInfrared beam blocked or unblockedLow; filter noise onlySpring and housing wear, emitter ageingUsually no
Hall effect magneticMagnetic field strength at a sensorLow; filter noise and driftSpring wear, magnet or sensor driftYes, set in firmware
CapacitiveChange in capacitance at a padLow; threshold tuningSpring and dome wearSometimes, in firmware

Debounce, in numbers

The open source QMK firmware documentation sets its default debounce time at 5 milliseconds and lets a board change it with a single line in config.h. It describes two families of algorithm. An "eager" algorithm reports a change immediately, then ignores further changes for the debounce time, which is fast but not resistant to electrical noise. A "defer" algorithm waits until there have been no changes for the debounce time, then reports, which resists noise at the cost of latency. QMK's sym_defer_g applies one global timer to the whole keyboard; sym_defer_pk keeps a timer per key.

Worked example (illustrative). Suppose a contact bounces for 3 ms after a press and the board uses a 5 ms deferred debounce with a 1 ms USB polling interval. The firmware sees the first change at t = 0, sees changes until t = 3 ms, then waits 5 quiet milliseconds and reports the key at about t = 8 ms. The host then picks it up at the next poll, so up to 1 ms more, for a total of up to about 9 ms. An eager algorithm would report at t = 0 and pick it up within 1 ms, but a single noise spike could also produce a false press. That is the trade the debounce setting makes, and it is why magnetic and optical boards advertise lower latency: they have less bounce to wait out.

How are keycaps made?

ABS versus PBT

Most keycaps are moulded from one of two plastics. ABS (acrylonitrile butadiene styrene) moulds easily, takes colour well and is common on office and gaming boards; over time the surface of frequently used ABS caps tends to polish and look shiny. PBT (polybutylene terephthalate) is harder to mould accurately because it shrinks more as it cools, but it resists wear and shine better and has a drier, textured feel. Neither is a security property, but the choice drives which legend method a maker can use.

Doubleshot moulding

Doubleshot keycaps are moulded twice. The first shot forms the legend in one colour of plastic; the second shot moulds the cap body around it in another colour. The legend goes all the way through the wall of the cap, so it cannot wear off. The tooling is expensive and every legend needs its own mould detail, which is why doubleshot sets tend to have fewer language variants.

Dye sublimation

Dye sublimation prints the legend onto the cap with a dye that, under heat, diffuses into the plastic below the surface. It works best on PBT and with dark legends on light caps, because the dye cannot lighten a darker plastic.

Laser etching and printing

Laser etching burns or foams the surface to create a contrasting legend, and lasers can also remove a painted coating to reveal a backlit translucent layer underneath. Pad printing and UV printing put ink on the surface; it is cheap and flexible but wears faster on high use keys. Backlit "shine through" caps use a translucent base that is painted and then laser cut.

Legend methodDurabilityWorks onTypical use
DoubleshotLegend cannot wear offABS and PBTEnthusiast and premium sets, backlit caps
Dye sublimationVery durable, below the surfaceMostly PBT, light capsEnthusiast sets with dark legends
Laser etched or laser cut paintDurable to fairly durableABS and PBTOffice keyboards, backlit laptops
Pad or UV printedWears on heavy use keysMost plasticsLow cost keyboards, novelty caps

How does the controller scan the matrix?

Why a matrix

Giving every key its own wire to the controller would need one input pin per key. A matrix shares wires. Worked example (illustrative): a 104 key full size layout can sit in a 6 row by 18 column matrix, which has 108 positions and needs 6 + 18 = 24 pins instead of 104. A 60 percent board with 61 keys fits in a 5 by 14 matrix, 70 positions on 19 pins. That saving is why every keyboard, from a membrane office board to a split ergonomic board, uses a matrix of some kind.

The scan loop

The QMK documentation describes the loop plainly. The firmware drives one column at a time to a logical 1 and reads all the rows at once. If a switch at that column is closed, the 1 passes through it to its row and the firmware sees that row go high. Repeat for every column, store the result as a bit map, compare it with the last scan, debounce the differences, and you know which keys went down or up. The loop runs continuously, many times per millisecond on a modern MCU.

Ghosting and why diodes fix it

Without diodes, current can take a detour. Hold three keys that form three corners of a rectangle in the matrix, and the scan reads the fourth corner as pressed too, because current flows backwards through the held switches. QMK's documentation calls this ghosting and shows that it happens only in specific combinations, but more often on bigger boards. A diode in series with each switch lets current flow only one way, so the detour is blocked and the firmware reads exactly the keys that are down. Membrane keyboards usually have no diodes, so their controllers detect impossible combinations and refuse to report them; the user sees this as a limit on how many keys work together.

From matrix position to key code

The firmware then looks up each matrix position in a keymap and turns it into a usage code from the USB HID Usage Tables. In HID Usage Tables 1.5 (26 January 2024), the Keyboard/Keypad page is page 0x07. On that page, usage 0x04 is "Keyboard a and A", usage 0x28 is "Keyboard Return (ENTER)", usage 0xE1 is "Keyboard LeftShift", and usage 0x01 is "Keyboard ErrorRollOver". The keyboard never sends letters. It sends positions on a standard page, and the operating system's layout setting decides that usage 0x04 means "a" on a US layout and something else on another.

How does a keyboard talk to the computer over USB HID?

Descriptors first

When a keyboard is plugged in, the host asks it for descriptors. The device descriptor names its vendor ID and product ID, the interface descriptor declares class 3 (HID), and a HID report descriptor describes, in a compact byte code, the exact layout of every report the device will send and receive. The USB HID 1.11 specification says one goal of the class was to be as compact as possible, and the Linux kernel's introduction to HID report descriptors shows how to read one from /sys/bus/hid/devices/.../report_descriptor and decode it with tools such as hid-tools.

The boot protocol and the 8 byte report

A BIOS or UEFI setup screen should not have to parse report descriptors, so the HID specification defines a fixed "boot protocol". A keyboard that sets interface subclass 1 (Boot Interface) and protocol 1 (Keyboard) promises to send this 8 byte input report when the host asks for boot protocol:

ByteMeaning
0Modifier keys, one bit each: left Ctrl, left Shift, left Alt, left GUI, right Ctrl, right Shift, right Alt, right GUI
1Reserved for OEM use; usually zero
2 to 7Up to six key codes from the Keyboard/Keypad page

It also defines a 1 byte output report the host sends back to light the Num Lock, Caps Lock, Scroll Lock, Compose and Kana LEDs. The specification says the keyboard must report a list of keys currently pressed, not make and break events, and that "Repeat Rate" and "Delay Before First Repeat" are implemented by the host. When the host's HID driver loads, it switches the keyboard from boot protocol to report protocol with a Set_Protocol request and from then on reads the reports the report descriptor describes.

Worked example: Shift plus A

Press left Shift and then A. The modifier byte sets bit 1 for left Shift, which is 0x02, and the first key code slot holds 0x04 for "a and A":

02 00 04 00 00 00 00 00   left Shift + a
00 00 00 00 00 00 00 00   all keys released

The host sees the transition from no keys to Shift plus 0x04 and, with a US layout, produces a capital A. If you hold the keys, the keyboard keeps reporting the same state; the host's repeat timer decides when to type a second A.

Rollover: 6KRO, ErrorRollOver and NKRO

The boot report has six key slots, so a boot protocol keyboard can report at most six ordinary keys plus any modifiers at once. HID 1.11 says the keyboard must report a "phantom state" by filling every array slot with the ErrorRollOver usage when more keys are pressed than the report can carry, and that it may do the same when it cannot tell which keys are really down, such as a ghosting combination on an undioded matrix. Worked example: hold seven letter keys and a compliant boot keyboard sends 00 00 01 01 01 01 01 01, telling the host that the set of keys is not reliable.

N key rollover (NKRO) avoids that limit by describing a different report in the report descriptor, typically a bit map with one bit per usage instead of six array slots. The open source QMK firmware exposes this as an NKRO_ENABLE build option and notes that its NKRO, mouse keys and media keys are combined onto one shared endpoint by default. A board offering NKRO usually still presents a boot compatible interface so it works in firmware setup screens.

Polling rate

USB keyboards send reports over an interrupt IN endpoint, and the endpoint descriptor's bInterval field asks the host to poll it at a fixed interval. The example descriptors in HID 1.11 use bInterval 0x0A, which asks for a poll every 10 ms. Keyboards advertised at 1,000 Hz ask for 1 ms, and some boards on faster USB connections ask for shorter intervals still. QMK lets a board set this with USB_POLLING_INTERVAL_MS. The polling interval is the upper bound on how long a ready report waits for the host; as the debounce example showed, the switch and the firmware usually add more.

What firmware runs on a keyboard?

Vendor firmware

Most keyboards run closed firmware written by the keyboard maker or by the maker of the controller chip's reference design. It includes the matrix scan, debounce, keymap, lighting effects, macro storage and, on wireless boards, a radio stack. A companion desktop application often talks to the keyboard over a vendor defined HID interface to change lighting and macros or to update firmware. That application is software you install with administrator rights, with its own dependencies and update channel.

Open source keyboard firmware

Enthusiast and many small batch keyboards run open source firmware. Two projects have extensive official documentation:

  • QMK mainly targets wired keyboards on AVR and ARM microcontrollers, is licensed under the GPL (its repository lists GPL 2.0 licensing), and is built from a large shared repository of keyboard definitions. You set up a build environment with the qmk command line tool, compile with qmk compile and flash with qmk flash.
  • ZMK is MIT licensed and built on the Zephyr real time operating system. Its documentation lists low latency Bluetooth LE, multi device BLE connectivity, USB and wireless split keyboards as supported features, and explicitly does not plan support for 8 bit AVR chips. ZMK's recommended setup is a personal "zmk-config" repository on GitHub, where GitHub Actions builds your firmware in the cloud and you download the resulting .uf2 or .hex file.

That second detail matters for supply chain thinking. In June 2025 the ZMK documentation team asked users to pin their ZMK version, explaining that unpinned configurations build against the main branch and can pick up breaking changes. Pinning means changing revision: main to a release tag such as v0.2 in config/west.yml and changing the reusable workflow reference in .github/workflows/build.yml from @main to the same tag. In other words, keyboard firmware built this way is a dependency graph: your keymap, ZMK, Zephyr, hardware modules and a CI workflow, all fetched at build time.

Bootloaders: how new firmware gets in

A bootloader is a small program that runs before the main firmware and can write a new image to flash. QMK's flashing guide lists many, and they fall into a few families:

Bootloader familyHow you enter itHow you flashNotes from the official docs
Chip vendor USB DFU on AVRBootloader keycode, reset button, or shorting reset to grounddfu-programmer or QMK ToolboxQMK says Atmel's DFU bootloader comes on all USB AVRs by default, with a couple of exceptions
Arduino style (Caterina)Reset, often double tapavrdudeUsed by Arduino boards and clones
ROM DFU on STM32 and APM32Bootloader keycode, reset button, or bridging BOOT0dfu-utilQMK notes most USB capable STM32 parts have a factory bootloader that cannot be modified or deleted
UF2 mass storage (RP2040 and others)Hold BOOTSEL while plugging in, double tap reset, or bootloader keycodeCopy a .uf2 file onto the drive that appearsAny application that can copy a file can flash it
Vendor proprietaryVendor app or key combinationVendor updater, sometimes over a HID interfaceBehaviour defined only by the vendor

A bootloader that ships in mask ROM cannot be bricked, which is convenient, but it also cannot be patched, and it will accept whatever image the protocol delivers unless the chip has its own secure boot feature turned on.

What the USB DFU standard does and does not promise

The USB Device Firmware Upgrade specification 1.1 (5 August 2004) defines four phases: enumeration, where the device advertises a DFU interface alongside its normal one; reconfiguration, where the host resets the device into DFU mode; transfer, where the host sends the image in blocks and polls status; and manifestation, where the host resets the device again and it runs the new firmware. It defines a file suffix with a CRC so a host can check a file is meant for that device, and status codes such as errFILE, for a file that "fails some vendor-specific verification test", and errVERIFY, for programmed memory that failed verification.

What it does not define is cryptographic authenticity. Whether an image must be signed, by whom, and whether the device refuses an older vulnerable version is up to the vendor. DFU also defines an optional upload direction (DFU_UPLOAD) whose stated purpose is to retrieve and archive a device's firmware, so a device that leaves upload enabled lets anyone with the cable read its firmware back. None of this makes DFU unsafe; it means that "supports DFU" tells you nothing about signed updates. Ask the vendor.

Firmware on the Linux side: fwupd and LVFS

On Linux, the fwupd daemon and the Linux Vendor Firmware Service (LVFS) give users one place to see device firmware versions and receive vendor uploaded updates. The LVFS describes itself as a secure portal where hardware vendors upload firmware in a standard .cab archive with metadata, used by major Linux distributions for clients such as fwupdmgr. Whether your keyboard appears there depends entirely on whether its maker publishes to the LVFS.

How do wireless keyboards pair?

Bluetooth LE: HID over GATT

Bluetooth LE keyboards follow the HID over GATT Profile (HOGP). The Bluetooth SIG describes it as defining how a Bluetooth LE device can support HID services over the LE stack using the Generic Attribute Profile. The HID Service carries the same report descriptor and reports as USB HID, wrapped in GATT characteristics, plus a Boot Keyboard Input Report characteristic for simple hosts.

Security is written into the profile. HOGP 1.0 says HID Devices shall bond and use LE Security Mode 1 with Security Level 2 or 3, all supported HID Service characteristics shall require that security, and the HID Host shall bond with the HID Device. When a bonded keyboard reconnects, the host starts encryption to check the bond is still valid, and if encryption fails the host must, after user interaction, pair again.

ZMK's own documentation is unusually frank about what that leaves. It says BLE connections are secured by an initial pairing and bonding process that sets up long term keys using Elliptic Curve Diffie Hellman, and that the only known weakness in that protocol is an active man in the middle attack during the initial pairing, which the Numeric Comparison association model can mitigate. ZMK describes its support for Numeric Comparison as experimental. The practical lesson for any BLE keyboard: pair it somewhere private, and treat an unexpected request to pair again as a reason to check before accepting.

ZMK also stores each bond in a "profile", so one keyboard can be bonded to several hosts and switched between them. Its documentation warns that bond key mismatches between profiles and hosts cause confusing behaviour, which is the most common reason a wireless keyboard "stops working" after an operating system reinstall: the host forgot the bond and the keyboard did not.

Proprietary 2.4 GHz dongles

Many wireless keyboards instead pair with a small USB receiver over a proprietary protocol in the 2.4 GHz band. In the United States, these radios typically operate under 47 CFR 15.247, which covers frequency hopping and digitally modulated intentional radiators in the 2400 to 2483.5 MHz band, or under the lower power rules for that band. Those rules govern power, bandwidth and interference. They say nothing about encryption, pairing or authentication; that is entirely the vendor's design.

The receiver is itself a USB device with a microcontroller, a radio and firmware. To the host it is a keyboard (often a keyboard and a mouse). To the radio side it is a receiver that decides which over the air packets to accept. If it accepts something it should not, the host has no way to tell, because the host only sees a HID keyboard sending reports.

What published research on dongles showed

On 24 February 2016, CERT/CC published Vulnerability Note VU#981271, titled "Multiple wireless keyboard/mouse devices use an unsafe proprietary wireless protocol". It classified the issue as CWE-311, missing encryption of sensitive data, and said that several wireless input devices using proprietary 2.4 GHz protocols lacked proper encryption, so someone within radio range, typically a few metres in a home, could inject keystrokes, read keystroke data, or cause the victim's receiver to pair with a new input device. CERT/CC noted the issue did not affect Bluetooth devices, recorded that at least one affected vendor released updated receiver firmware, and advised users of other models to weigh their own threat model until updates arrived.

The mechanism, in concept: some receivers accepted unencrypted packets formatted as keystrokes even when the paired keyboard normally encrypted its traffic, and some would accept a new device pairing without the user starting it. The fix was receiver firmware that rejects unencrypted keystroke packets and only pairs when the user asks. The lessons last longer than the specific products:

  • A dongle is a computer with firmware, and its firmware needs updates like anything else.
  • Pairing must be a deliberate, user initiated act on both sides.
  • Encryption that the receiver does not enforce is not encryption.
  • Updating the keyboard alone may not help; the receiver is often the component that needs the patch.

Comparison: wired, Bluetooth LE and 2.4 GHz dongle

PropertyWired USBBluetooth LE (HOGP)Proprietary 2.4 GHz dongle
Who defines the linkUSB-IF HID classBluetooth SIG HOGP and CoreThe vendor
EncryptionNone needed on the cableRequired by HOGP (Security Mode 1, Level 2 or 3)Vendor defined; varies by product
PairingNone; plug inBonding with long term keysVendor defined; often factory paired
Over the air exposureNonePairing window is the weak pointDepends entirely on receiver firmware
Firmware to patchKeyboardKeyboard, plus the host's Bluetooth stackKeyboard and receiver
Works in BIOS or UEFI setupYes, via boot protocolOften not until the OS loadsUsually yes, receiver presents a USB HID device
Fits a high security areaEasiest to approvePossible with a pairing procedureOnly with vendor documentation of encryption and signed updates

What are keystroke injection devices, and why do hosts trust any USB keyboard?

A keystroke injection device is any gadget that presents itself to a computer as a keyboard and then types something its owner chose in advance. Physically it can look like a flash drive, a cable, a charging gadget or a real keyboard. The concept is simple, and because this post does not give attack instructions we will leave it there: the device enumerates as a HID keyboard and sends ordinary key reports.

Hosts trust it for two structural reasons.

First, USB HID has no authentication. Every field in the device descriptor and report descriptor is the device's own claim. A vendor ID and product ID identify a product line, not a genuine unit, and nothing in the HID class asks the device to prove anything. The Linux kernel's USB authorization documentation says it directly: "By default, all USB devices are authorized." It adds that just checking whether the class, type and protocol match something is the worst security verification you can make, and that real assurance needs cryptography.

Second, keyboards are how people log in and recover systems. An operating system that refused new keyboards would lock users out of their own machines after a hardware fault, so every mainstream desktop accepts them by default.

The 2014 Black Hat USA briefing "BadUSB, On Accessories that Turn Evil" showed a related point: the controller firmware in ordinary USB devices can be reprogrammed so the device spoofs other device types in order to take control of a computer. For keyboards themselves, the same idea applies to replaced firmware: a keyboard whose bootloader accepts unsigned images can be turned into a device that types on its own.

The defences are layered and mostly organisational. Hosts can allow list USB devices by class, vendor, product, serial and port, so a "flash drive" that also exposes a keyboard interface is rejected. NIST SP 800-53 Rev. 5 control SC-41, Port and I/O Device Access, has organisations disable or remove ports on defined systems, and notes that physically disabling or removing them is the stronger action. MP-7, Media Use, restricts types of media and prohibits portable storage with no identifiable owner, while CM-8, System Component Inventory, and SR-11, Component Authenticity, cover knowing what is attached and keeping counterfeits out. Short screen lock timeouts help too, since many injection scenarios need an unlocked session.

How do you check a keyboard's firmware and update it safely?

The steps below are for Linux, with macOS and Windows equivalents where they exist. Read the warnings before the flashing steps: writing the wrong image to the wrong device can leave a keyboard unusable until you reach its bootloader by hand.

1. Identify the keyboard and its interfaces

# List USB devices with vendor and product IDs
lsusb

# Show every interface the keyboard exposes (replace with your IDs)
lsusb -v -d 1234:5678 2>/dev/null | grep -E "bcdDevice|iProduct|bInterfaceClass|bInterfaceSubClass|bInterfaceProtocol|bInterval"

bcdDevice is the device release number, which many vendors tie to firmware version. Count the interfaces: a plain keyboard usually has one or two HID interfaces. Extra interfaces (mass storage, network, a vendor specific class) deserve a question to the vendor.

On macOS, system_profiler SPUSBDataType lists USB devices and system_profiler SPBluetoothDataType lists paired Bluetooth devices. On Windows, Get-PnpDevice -Class Keyboard in PowerShell lists keyboard devices, and Device Manager shows the hardware IDs.

2. Read the HID report descriptor

# Find the HID device entries for the keyboard
ls /sys/bus/hid/devices/

# Dump the report descriptor (read only)
sudo hexdump -C /sys/bus/hid/devices/0003:1234:5678.0001/report_descriptor

The Linux kernel's HID introduction shows exactly this, and points to tools that decode the bytes into readable usages. A descriptor that defines keyboard usages on an interface you did not expect, or several keyboard collections, is worth understanding before you approve the device.

3. Check for vendor firmware through fwupd

fwupdmgr get-devices      # versions fwupd can see
fwupdmgr refresh          # fetch LVFS metadata
fwupdmgr get-updates      # updates published for your devices

If the keyboard or its receiver is listed, fwupd shows the current version and any update the vendor has published to the LVFS. If it is not listed, the vendor's own updater is the source of truth; download it only from the vendor's site, and record the version before and after.

4. For open source firmware, pin and build reproducibly

For a QMK board, record the commit you build from:

qmk setup                    # first time only
cd ~/qmk_firmware && git rev-parse HEAD
qmk compile -kb <keyboard> -km <keymap>
sha256sum *.hex *.bin *.uf2 2>/dev/null

For ZMK, pin the version in your zmk-config repository as the ZMK documentation describes:

# config/west.yml
manifest:
  remotes:
    - name: zmkfirmware
      url-base: https://github.com/zmkfirmware
  projects:
    - name: zmk
      remote: zmkfirmware
      revision: v0.3          # a release tag, not main
      import: app/west.yml
  self:
    path: config
# .github/workflows/build.yml
name: Build ZMK firmware
on: [push, pull_request, workflow_dispatch]
jobs:
  build:
    uses: zmkfirmware/zmk/.github/workflows/build-user-config.yml@v0.3

Use the release tag current when you read this; the ZMK documentation listed v0.3 as the latest release when we checked. Keep the downloaded build artifact and its hash with the commit that produced it.

5. Before flashing: the device check

Warning. Flashing erases the keyboard's current firmware. Disconnect every other device that uses the same bootloader type (another keyboard, a development board) so the tool cannot pick the wrong one, keep a working second keyboard attached, and confirm the target before you write.

# Put the keyboard in its bootloader, then confirm exactly one target appears
lsusb | grep -i -E "dfu|bootloader"
dfu-util -l               # for DFU bootloaders: must list exactly one device
lsblk -o NAME,LABEL,SIZE,MODEL   # for UF2: confirm the new drive's label and size

If more than one candidate appears, or the label and size do not match your board's documentation, stop.

6. Flash with the documented tool

Warning. This writes to the device. Run it only after step 5 shows one matching target.

# QMK, any supported bootloader
qmk flash -kb <keyboard> -km <keymap>

# STM32 ROM DFU example, as given in the QMK flashing docs
dfu-util -a 0 -d 0483:DF11 -s 0x8000000:leave -D firmware.bin

# UF2 bootloader: copy the file to the drive that appeared in step 5
cp firmware.uf2 /media/$USER/<BOOTLOADER_LABEL>/

7. Verify

Unplug and replug. Check lsusb -v shows the expected bcdDevice or version string, test every key with a key tester or evtest, and for wireless boards remove and recreate the Bluetooth bond so host and keyboard agree on keys.

8. Lock down which HID devices a Linux host accepts

The kernel authorization feature lets a host hold new devices unconfigured:

# Inspect, do not change, the current default for each USB bus
cat /sys/bus/usb/devices/usb*/authorized_default

The kernel documentation explains that writing 0 deauthorizes new devices by default and that writing 2 authorizes only devices on internal ports. Do not set 0 on a remote machine whose only keyboard is USB unless you have another way in. Most teams use a policy daemon instead. The open source USBGuard project builds on this kernel feature, and its rule language documentation includes a policy that allows flash drives but rejects any that also present a HID keyboard, communications or wireless interface:

allow with-interface equals { 08:*:* }
reject with-interface all-of { 08:*:* 03:00:* }
reject with-interface all-of { 08:*:* 03:01:* }
reject with-interface all-of { 08:*:* e0:*:* }
reject with-interface all-of { 08:*:* 02:*:* }

USBGuard's own documentation notes that block listing is the wrong long term approach and that an allow list is stronger. Generate a starting policy from the devices currently attached, review it, then enforce it.

What should an organisation require of keyboards?

RequirementWhyHow to check
Wired by default in sensitive areasRemoves the radio attack surface entirelyProcurement standard
Bluetooth LE only, no proprietary dongle, where wireless is neededHOGP mandates bonding and encryptionVendor data sheet names HOGP; pair in a controlled place
Documented encryption for any 2.4 GHz receiverEncryption is vendor definedWritten vendor statement; update history for receiver firmware
Signed firmware updates and rollback protectionDFU alone does not require themVendor security documentation; ask whether unsigned images are refused
A published update channelLets you patch the receiver and keyboardVendor support page or LVFS listing
No unexpected USB interfacesExtra interfaces widen what the device can dolsusb -v at intake; compare against an approved list
Asset tagging and inventoryNIST CM-8 component inventoryRecord vendor ID, product ID, serial and firmware version
Host device controlSC-41 port control and allow listingEndpoint policy; USBGuard or equivalent on Linux
Companion software reviewed like any appConfigurator apps run with high privilegesSoftware approval process, dependency review
Supplier authenticitySR-11 component authenticityBuy through authorised channels; check packaging and IDs

Common mistakes

  • Treating a keyboard as passive hardware. It runs firmware, often has a bootloader that accepts new images, and a wireless receiver is a separate computer with its own firmware.
  • Patching the keyboard but not the receiver. Dongle research showed the receiver is often where the fix lives.
  • Assuming vendor ID and product ID prove identity. They are claims made by the device. Allow lists based on them reduce accidents, not determined attackers; combine them with physical controls.
  • Accepting a surprise Bluetooth pairing request. HOGP's weak point is the pairing moment. Re-pair only when you started it.
  • Building open source firmware from an unpinned branch. ZMK's own maintainers recommend pinning to a release tag; the same goes for a QMK commit.
  • Flashing with several bootloader devices attached. The tool may write to the wrong one. Confirm exactly one target first.
  • Relying on block lists in device control. An allow list of known good devices and interface sets is the stronger pattern.
  • Assuming "1,000 Hz" means 1 ms end to end. Debounce and scan time usually add more than the poll interval.

FAQ

What is inside a mechanical keyboard?

Keycaps, switches, often a plate, stabilisers for long keys, a PCB that wires the switches into a row and column matrix with one diode per switch, a microcontroller running firmware, a USB connector or a battery and radio, and the case.

How does a keyboard send a key press to the computer?

The controller scans the matrix, debounces the result, looks up each pressed position in its keymap and sends a USB HID report listing the usage codes of keys that are down. The host compares each report with the last one and turns changes into key events using the selected layout.

What is the difference between 6KRO and NKRO?

6KRO comes from the USB HID boot keyboard report, which has six key slots plus a modifier byte, so six ordinary keys can be reported at once. NKRO uses a different report layout, usually a bit map, so every key can be reported simultaneously. Most NKRO boards still offer a boot compatible mode for firmware setup screens.

Why do mechanical keyboards have diodes?

Without a diode in series with each switch, holding certain three key combinations makes a fourth, unpressed key appear pressed, an effect called ghosting. Diodes let current flow one way only, so the controller reads exactly the keys that are down.

Are Hall effect keyboards more reliable than mechanical ones?

They remove the metal contacts that bounce and wear, so they need less debouncing and can adjust actuation in firmware. They still have springs, housings and electronics that wear, and they depend on calibration. Reliability depends on the specific design and its testing.

Are Bluetooth keyboards secure?

Bluetooth LE keyboards that follow the HID over GATT Profile must bond and use an encrypted link. The main exposure is the pairing moment, when an attacker nearby could try to sit in the middle. Pair in a private place, use authenticated pairing where offered, and keep the keyboard and host Bluetooth stack updated.

Are wireless keyboards with USB dongles safe to use?

It depends on the product. Proprietary 2.4 GHz protocols are defined by each vendor, and in February 2016 CERT/CC warned that several lacked proper encryption. Choose models whose vendors document encryption and publish receiver firmware updates, and update the receiver, not just the keyboard.

How do I check my keyboard's firmware version?

On Linux run lsusb -v and read bcdDevice, then fwupdmgr get-devices to see whether fwupd recognises it. On macOS use system_profiler SPUSBDataType. Many vendors also show the version in their configuration app. For open source firmware, record the commit or release tag you built.

Can a keyboard get a virus?

A keyboard whose bootloader accepts unsigned firmware can be reprogrammed to behave differently, including typing on its own, and research presented at Black Hat USA in 2014 showed the same idea for USB controller firmware in general. That requires replacing its firmware, usually with physical access. Buying from authorised channels, preferring signed updates and controlling which USB devices hosts accept all reduce the risk.

What is a keyboard bootloader?

A small program that runs before the main firmware and can write a new firmware image to flash. Common types on open source boards are USB DFU, Arduino style serial bootloaders and UF2, which appears as a drive you copy a file onto. Some live in read only memory and cannot be erased.

Where Safeguard fits, honestly

Safeguard does not make, test or analyse keyboards. It does not scan keyboard or receiver firmware, verify firmware signatures, generate a hardware bill of materials, manage devices or enforce USB policy on endpoints, and its models are single purpose security models for software. The fit is narrower and it sits in the software around the keyboard. Configurator and macro apps your team builds or packages, internal device inventory tools that collect lsusb and fwupd output, and build tooling for custom keyboards in your repositories all pull open source dependencies through ordinary package managers. Safeguard scans repositories, container images and SBOM files for known vulnerable components, shows which projects carry a given component and version, and can open fix pull requests when a fixed version exists, with autonomous remediation switched off by default.

A keyboard's firmware is built from open source projects, real time operating systems and CI workflows fetched at build time, and every laptop rebuild pulls its companion apps and their libraries again. The fit is indirect, because Safeguard does not touch the keyboard hardware or its firmware image, but the software you write and package to configure, inventory and update peripherals is part of your software supply chain like everything else.

Fix it without waiting for upstream

Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.

1. Autonomous remediation: pull requests, not tickets

When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation covers eight categories, including dependencies, licenses, security posture and findings. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.

2. Gold Open Source: the safe version in seconds, free

gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds. The safeguard-sh/gold-scan-action GitHub Action can fail a build on a known exploited vulnerability, on any known vulnerability, or never, so a version you have just removed cannot quietly come back in next week's merge.

3. Gold Registry: start from components that are already fixed

registry.safeguard.sh provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs, zero malware and a completed license check, with SLSA L3 or higher provenance, a Sigstore signature and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.

When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. This fork and patch flow is in early access today, so ask which packages it covers before you plan around it.

Your situationWhat to use
A fixed version existsAutonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version
You need to know today whether you are affectedGold Open Source lookup and "Am I affected?" checker, free and without login
You want vulnerable versions to stop shippingThe Gold scan GitHub Action in CI, plus Safeguard policies and gates
Upstream has no fix yet, or will not ship oneA custom Gold request; fork and patch (early access)
You want to start clean on new projectsPull hardened components and images from Gold Registry

One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.

See how Safeguard would help

The first demo is a real Safeguard CLI session asked to fix a lodash CVE: it reads the finding and advisory, asks before each command, edits package.json to lodash 4.17.21, runs npm install and npm test with approval, and pushes nothing. The same flow fits a keyboard configurator app or a device inventory dashboard your team maintains in a JavaScript repository.

Click through it at your own pace, or open it full screen.

The second demo sets up the Safeguard runner on your own machine, approves it with its device code and scans from the terminal. That suits teams who keep peripheral tooling, firmware build scripts or workstation images in repositories they prefer to scan locally.

Click through it at your own pace, or open it full screen.

The third demo is a real Android session: send work to a computer running the CLI and approve each command on the phone with Allow once, Allow for turn or Deny. An engineer away from a desk can approve a dependency fix in a fleet tooling repository without anything running unattended.

Click through it at your own pace, or open it full screen.

To try it on your own repositories, download Safeguard and follow the CLI documentation.

Quick check

Why can a boot protocol keyboard report only six ordinary keys at once?

The USB HID 1.11 boot keyboard report is 8 bytes: one modifier byte, one reserved byte and six key code slots. When more than six non modifier keys are down, the keyboard fills every slot with the ErrorRollOver usage instead.

Does a keyboard that supports USB DFU have signed firmware updates?

Not necessarily. The USB DFU 1.1 specification defines how an image is transferred and checked for the right device, but leaves any authenticity check to the vendor. Ask the vendor whether unsigned or older images are refused.

Sources

Last reviewed: 23 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.