Why end-to-end keytsroke encryption, from simple HW to application?
"End to end cryptography" is well known.
- Components (like the USB-host and stack including usbhid, the primary "billion dollar target") should be able to route data without understanding it (or, in some cases, without knowing the exact destination, like an RS485 or CAN-bus, or Tor). Messages can be forwarded to listeners without drawing attention "catch me, here goes the keystroke data in plaintext"
- consider that today an ordinary PC has more bandwidth and greater transistor count than a whole campus had in the old days when the PC/AT keyboard was defined (and 14..90 nm Si verification is beyond reach for most of us)
- Often the existing components could do this right with sane software / firmware. A proper keyboard (with a few kbytes more memory, and a HW multiplier) would cost max +1 USD more (implementing it outside the keyboard costs 6..10 USD, similar to an USB hub; it can cost 0 when a "multikbd crypto mux" device is used, eg. in a [multiseat setup] and saves an USB hub)
The same protocols and software (eg. multiplexers and demultiplexers) would be useful not just for keystroke data, but virtually any realtime automotive, industrial, environmental, communication, soho or security data (saving millions of kg of copper and providing better redundancy and tapper-free datapath, eg. from microphones or motion detectors).
- The lack of democratically issued currency is a very significant risk to our society.
- [Ethereum] is apparently the first network in history that allows businesses to issue their currency (in a non-centralized way: so it cannot be shutdown by adversary/gov without shutting down the whole internet)
- bitcoin or ether are NOT issued democratically, but ethereum allows any number of issued currencies via "contracts" (custom-defined programs/conditions)
- the lack of keyboard to application secure path is an obvious security risk, endusers and operators simply have no secure method to enter secret keys into financial applications (geth, or wallet, or market-GUI). "geth" below is shorthand for any smart application to handle encrypted keystroke events
- [coinmarketcap] is growing, currently (2016-07) between 10 and 100 Billion USD
Honest businesses prefer an honest money supply (which historically didn't exist for thousands of years, or existed in isolation and was effectively suppressed), and fast, secure transactions (that need secure method to enter secret passphrase for signature or communications).
Proposed architecture
- PS2 keyboard (or USB)
- small (low power consumption, low cost) ARM or AVR hardware (with status LEDs and/or directly connected LCD)
- recognizes some special hotkeys to switch between N keys; or to send unencrypted keystrokes transparently if chosen by user
- connected via serial or USB-serial port
- even the USB HID could be used ("keystroke steganography")
- however simple PS2 and uart-serial are highly preferred because of their simplicity: easily captured via 4+ channel logic-analyzer ("bitscope") like saleae. If protocol is well defined, stream can be analyzed for compliance
- xorg / xinput / x11proto-input-dev
- demultiplexer / dispatcher could run outside or inside xorg process (in some library)
- [evdev] is the generic way (useful even if one opts to bypass evdev and use pipes instead of /dev/input/* )
- [libevdev] [evdev article]
- window manager (like xfce)
- old applications (eg. gtk, expecting keystrokes from xserver)
- advanced secure applications understanding end-to-end encrypted keystroke data (geth with some added code)
Searching for a better place to host this:
- Tor wiki (or git?)
- in some way this is very similar (in concept, and implementation) to Tor.
- The packets are smaller (eg. 32 bytes instead of 300..1460 bytes) and the packet overhead should ideally be smaller than 40 bytes and the routers should be lightweight (not "gated").
- In PC, some data would be read from serial port, and demultiplexed into pipes (still encrypted) from which "geth" (the target applications) could fetch for decrypt inside (possibly with necessary code linked in: if someone security-minded considers crypto related shared libraries an unnecessary risk and rather sacrifices some RAM for security).
- xorg wiki ? [xorg] developers are system integration professionals, and know a lot about keystrokes and listeners (and much experience with queues, network and pipes); at least some xorg.conf snippet will be needed to "bridge" to existing X11 applications
- [xterm or some xterm variant] with some compromise (decrypt in another process ? suboptimal, but maybe still better than decrypt inside or around libX11, and very quick improvement for many apps not yet empowered)
- libncurses (same compromise as xterm, also wide "audience")
- geth : while the most important application, geth "doc" is confusing enough without this, so not the best place for hosting
- gnupg ?
- gnupg has a lot of nice code.
- However, some official gnupg (bad) advice (that gnupg should be exec-d rather than the necessary code linked where needed) suggests that not every gnupg developer is concerned with application security
- but probably many are; a gnupg fork recommending static linking of security-related apps (perhaps obfuscated and "code-salted" before compile) might be worthwhile, to draw attention to the dynamic-linking security risks
- socat / stunnel / libssl ?
- busybox / dropbear ?
- a really nice small footprint system useful for maintenance, audit, bootstrap and other purposes with an ssh implementation. Good job !
- some "secure linux" or BSD coders ?
- concerned with application security and doing a good job. (perhaps already solved some special case at least?)
- webrtc ?
- experience: realtime connection through firewalls (and multiplexing voice, video and other data)
- other ... ?
VEMS has
- proven (and easy to tunnel; somewhat like PPP) communication protocol to send runtime data from firmware to app
- although not encrypted; and obviously other method like COBS or COBS-R or some improved version (escaping \0 by P+1 where P is number of nonzero bytes _before_ this char) can be used (easy to solve)
- and firmware code to interface with PS2 keyboard.
- (not before used for keyboard crypto) ; currently rarely used at all
To be defined (to be useful)
- signalling handshake command-set eg. to agree on new keys
- handshake: application can inject public key to ARM, and ARM can send back random symmetric key to the application for further data encryption.
- The costly pubkey operation (~1..4 sec for small microcontroller) normally happens only once during application startup; after that, sending keystroke data to that application is lightning fast.
- how/when xorg is notified: switching between crypto keys => typically switching window focus also
- even if xorg can not decrypt the datasream sent to geth, it can switch to the xterm geth is running in
- xorg could prevent other apps seeing alien streams (which they cannot decrypt anyway, but might hold some statistic value, and processing noise => undesired cache contention)
- hotkey to enter ("shared secret") passphrase to keyboard (usecase: sspp generated by app => shown on screen; entered via keyboard => not sent to PC, just stored in device memory: sspp used for secure comm)
- although a bit geeky, one-way channel (perhaps with redundancy and FEC) is suitable this way (no datapath from app to keyboard, other than the human)
Apparently evdev [struct input_event] (simple 16 byte stuct with 4 fields) is the most common standard interface (the tty or faketty could also work, but is different).
[uinput evdev notes from Peter Hutterer]
Proof of concept with Xephyr (check logs carefully, easy to get tricked):\n
cat </dev/input/event9 >/tmp/inev9 /usr/bin/Xephyr :2 -keybd ephyr,,device=/tmp/inev9,xkbrules=evdev,xkbmodel=evdev,xkblayout=us -mouse ephyr,5,device=/dev/input/event11 -verbosity 100 -evdev &
Needs Xephyr patch (which is not merged in Debian and Ubuntu for some weird reason).
X can be configured to read from /dev/input/eventN evdev, but does NOT work with named pipe (X attempts ioctl which fails on pipe created with mknod /path/pip p )
Conclusion: on the PC-side it should be straightforward to bypass the USB host HW (of many or all PC-s) is (almost certainly) trained to sniff;
However, if using uinput and evdev and libinput (unmodified geth), the kernel sees the plaintext (marked as EV_KEY data) but the USB HW can be bypassed (or see encrypted serial data). Modified libinput would be better, and:
To decrypt inside geth (not another process), modified geth (or suitable libinput or faketty) library needed.
Usefulness
Anyone with some knowledge about computer security or USB knows that currently keystrokes are crying out "catch me please" when traveling from keyboard to application (via a deep HW and SW stack), and the user has no option to "tunnel" keystroke data securely to the application
Some will argue that sufficient security can be reached by:
- buy any PC HW
- use windows-... (many backdoors, without sourcecode no way to make it secure)
- install some antivirus software (add another backdoor)
Marcell thinks this is not the case, but this beyond the scope of this page. Those who think so should simply silently go away. For extremely high value [offline wallets] to store and use keys are very reasonable (who would argues that ?). However, for smaller value (or to secure everyday communications) some practical method still needed to handle secret keys.
When the next multi-billion dollar theft will be publicly known (probably already happened, but traditional "create money and not inform" banks don't publish) we'll know more about which practice is more secure.
- the USB host IP-designer (or fab) can easily allow keystrokes to be logged (eg. to hidden flash), and later sent (eg. via wifi or Ethernet from HW or via TCP/IP network from some collaborating app; but even via sonic noise or IR if such HW is installed)
- NSA is known to pressurize network operators and HW-manufacturers; it would be very surprising if keystrokes would not be their first victim (because of the relatively small volume, and high value)
If different methods provide different security:
- keystrokes are begging to be caught => very easy to log (most likely they are acquirable by manufacturer and/or NSA)
- keystrokes travel encrypted to sensitive applications when user likes so
- this makes it immensely more difficult to dig out (from application memory)
- today's HW are (Marcell's opinion) likely not designed for that (and application can be changed easily, even after HW was purchased);
- => definitely a better way, and only costs a few dollars nowadays, so those who prefer security should have the option
Should be a reasonable first step, even if more secure (and more costly) method will be possible later for Completely secure key => known application running on custom hardware (perhaps verified etched Si). Hopefully we don't need to solder 6000 gates to sign in a secure way :-)
DIY or closed source ?
- home-built firmware should be uploadable to the PS2-uart multikey keystroke-encryption HW
- otherwise if HW is backdoored by manufacturer to send same keystrokes to more than 1 subscriber (or nonvolatile log and later retrieve) => if manufacturer can also start an application to hook in; sensitive data can be leaked (and everything would appear to work properly exactly as currently with windows or X one does not notice leaks when happening):
- even the protocol analyzer might not notice it;
- especially if no extra data is sent, but leaked via the secret "not-completely-random" keys (that are small, but generated on every application startup).
- Some will prefer only 1 crypto-key at a time (only to application under her control), and all other data (not as sensitive as crypto keys) to be sent plain. This makes it fully verifiable (and using more than 1 keyboards or kb-switch and more than 1 encrpytion HW is possible of course)
Some will implement in
- FPGA with some RAM and mblite-plus core (~15 USD)
- "Apollo computer" style discrete (gates or transistors) would be more costly (footprint also) and only for "fun" or university project
- FPGA is very RAM limited (of course external SRAM or DRAM can be added). The mem requirements of RSA (especially with Karatsuba recursive multiplication) apparently fits in ~16kbyte (unverified)
- ARM microcontroller (~6 USD; reasonably low price and MIPS or ARM => most likely good choice). 20 kbyte SRAM is minimum (more is good :-)
- AVR microcontroller: OK for prototypes, but for convenience (pubkey crypto to exchange keys without effort from the user) ARM is faster
- old PC: could work, but avoid it (except for "proof of concept" maybe).
- new PC: or notebook, or orange-pi or raspberry-pi : not safe to assume that USB keyboard data never leak; but running apps on them might be safe, especially if Faraday-caged (in OLD PC-supply metal box ?) and not connected to "default gw" (perhaps not connected to internet at all; or only some controlled app connected via some dedicated gateway)
Same HW, different applications
Input-outputs and LED-indication (pushbuttons not strictly needed but do not hurt either)
- analyze 2 (or more) knock-sensor inputs (configurable bandpass filter)
- data acquisition
- (8..12 or more extra analog inputs => PC and/or v3 ; this is actually implemented in sw)
- generate RANDOM entropy (always useful).
- send gadget RSA pubkey via UART, framed data (perhaps alternating between high baudrate and low baudrate)
- the low baudrate (1200..2400 baud) could be captured with soundcard also (available signal input to most PC-s: USB and audio).
- deploy several simmkeys (an app on PC could generate simmkey and deploy it using gadget RSA pubkey),
- and select the N'th simmkey for keystroke data => app (when switching between windows; or when the app is in focus and needs secure input; no other app could decrypt the encrypted keystroke data, than the one that generated the simmkey in the first place)
- LED indication is very important to know which simmkey is actually selected (switching RATE-limit might be needed, to prevent stealth switching). One LED indicating "recent key-switch" would be lit for min 500 msec (configurable) time after simmkey-switch
- certain "input-combination" (some digital signal pulled midway to 1.65V ? Or some capacitor connected between GND and certain input) at powerup (or 2..3 consequtive powerups) would initiate "generate new gadget RSA keypair".
- Not sure if generating new RSA keypair would provide any extra security
- the RSA key inside the ARM SRAM is hardly compromised. If RSA key is generated from non-random data in the first place (because the device fw or operation is tweaked), it might be generated that way any number of times.
- perhaps the key-generation could be influenced; possibly keypair generated from passphrase ("DSA-tool" style)
- disable JTAG and STLINK ?
- these tamper methods are NOT usable without physical access anyway. With physical access: if the device is replaced, the change of keys / and pubkey is noticed easily.
- Optimally debug / flash-read and SRAM-read should be disabled (only possible after full device erase) ... Does STM32F103 support that level of flash protection ?
LCD version (displays text, fingerprint, status; perhaps photo)
- highly secure chat (text not appearing in PC memory at all)
- show pubkey (fingerprint) on LCD
ECDH instead of RSA
- [ECDH on ARM]
- small mem footprint, fast