Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bad USB: Add support for UTF-8 and multi-keystroke characters #3496

Draft
wants to merge 1 commit into
base: dev
Choose a base branch
from

Conversation

vanguacamolie
Copy link
Contributor

@vanguacamolie vanguacamolie commented Mar 4, 2024

What's new

This PR adds support for new keyboard layouts that couldn’t be supported before. Currently, Bad USB is unable to type the following characters on most Dutch keyboards: ` ~ ^ ' ". This is because US-International (the de facto keyboard layout used in the Netherlands) requires a space to be pressed after typing any of these characters, otherwise it will attempt to merge the character with the next one.

It tries to solve this by creating a new version of the .kl format, one that removes the following limitations:

  • Only being able to use ASCII characters
  • Only being able map characters to a single key + modifiers

By solving it in this generic way, we hit two birds with one stone and also allow non-ASCII characters to be entered using the standard STRING command.

The only limitation that still remains is that characters have to be composed of a single Unicode codepoint. For example, while this make it possible for a keyboard layout to support é when encoded as U+00E9 LATIN SMALL LETTER E WITH ACUTE, it will not be possible to support é when encoded as U+0065 LATIN SMALL LETTER E + U+0301 COMBINING ACUTE ACCENT. The latter form seems to be much less common, however, so I don't expect this to be a big issue.

The new file format is implemented in a fully backwards compatible way, allowing users to keep using existing .kl files they may have added.

The documentation of the new file format can be found in documentation/file_formats/BadUsbKeyboardFormat.md. This commit also adds the keyboard layout en-US-intl.kl, which implements the US-International keyboard layout.

Before:

d6b1257f1de44beb80a102be163b6ce282278c83.mp4

After:

d7cb95e15f52374726ec4299761c114817163614.mp4

Verification

One may use the following Bad USB script to verify that every key in en-US-intl.kl types correctly. One needs to configure their keyboard layout to US-International for this. On Linux, this is called English (US, intl., with dead keys).

STRING cat > /dev/null <<"EOF"
ENTER
STRING ~  !¹ @  #  $£ %  ^  &  *  (  )  _  +÷
ENTER
STRING `  1¡ 2² 3³ 4¤ 5€ 6¼ 7½ 8¾ 9‘ 0’ -¥ =×
ENTER
ENTER
STRING     QÄ WÅ EÉ R  TÞ YÜ UÚ IÍ OÓ PÖ {  }  |¦
ENTER
STRING     qä wå eé r® tþ yü uú ií oó pö [« ]» \¬
ENTER
ENTER
STRING      AÁ S§ DÐ F  G  H  J  K  LØ :° "
ENTER
STRING      aá sß dð f  g  h  j  k  lø l¶ '
ENTER
ENTER
STRING       ZÆ X  C¢ V  B  NÑ M  <Ç >  ?
ENTER
STRING       zæ x  c© v  b  nñ mµ ,ç .  /¿
ENTER
STRING EOF
ENTER

One should also verify that the default keyboard layout and the v1 keyboard layouts still work. One may also try to corrupt the v2 keyboard layout (easiest way is to remove a byte from the end), and verify that it falls back to the default keyboard layout.

Checklist (For Reviewer)

  • PR has description of feature/bug or link to Confluence/Jira task
  • Description contains actions to verify feature/bugfix
  • I've built this code, uploaded it to the device and verified feature/bugfix

@vanguacamolie vanguacamolie changed the title bad_usb: add new keyboard layout file format Bad USB: Add support for UTF-8 and multi-keystroke characters Mar 7, 2024
@hedger hedger added USB BadUSB + physical USB interface Applications Non-core applications labels Mar 15, 2024
@skotopes
Copy link
Member

@vanguacamolie can you merge latest dev to your branch?

@vanguacamolie
Copy link
Contributor Author

@skotopes Will do. The merge conflict is a bit tricky though so it may take a bit.

@skotopes skotopes marked this pull request as draft March 26, 2024 07:29
@skotopes
Copy link
Member

Please un-draft when ready

The existing .kl file format is quite limited. It only supports ASCII
characters, and it assumes all characters can be pressed using a single
key on the user's keyboard.

The latter assumption is false even when just considering ASCII
characters. For example, the US-International keyboard layout, which
is the de facto standard keyboard layout in the Netherlands, uses dead
keys for the following characters: ` ~ ^ ' ". To type any of these
characters, one needs to press the same key as in the ANSI QWERTY
layout, but followed by a space. This is not possible to describe in the
current keyboard layout, thus making Dutch computers immune to Bad USB.

The new file format makes this possible, by mapping characters to a
sequence of keys, rather than just a single key. It also expands the
format to support any Unicode codepoint, thus unlocking Bad USB to a
much wider audience. Characters composed of multiple codepoints are not
supported though, thus while this does make it possible to support
é when encoded as U+00E9 LATIN SMALL LETTER E WITH ACUTE, it does not
support é when encoded as U+0065 LATIN SMALL LETTER E + U+0301 COMBINING
ACUTE ACCENT.

The new file format is implemented in a fully backwards compatible way,
allowing users to keep using existing .kl files they may have added.

The documentation of the new file format can be found in
documentation/file_formats/BadUsbKeyboardFormat.md. This commit also
adds the keyboard layout en-US-intl.kl, which implements the
US-International keyboard layout.

Signed-off-by: Guacamolie <[email protected]>
@vanguacamolie
Copy link
Contributor Author

PR is currently blocked by #3552

@skotopes
Copy link
Member

@vanguacamolie looks like #3552 was fixed, anything else we can help you with?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Applications Non-core applications USB BadUSB + physical USB interface
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants