]> git.gir.st - sendHID.git/blob - README.md
fix #6
[sendHID.git] / README.md
1 # hardpass
2 A hardware password manager, built around a Raspberry Pi Zero and [`pass`, the UNIX password manager](https://passwordstore.org).
3
4 This project is now maintained at [this repository](https://github.com/girst/hardpass-passwordmanager).
5
6 # sendHID
7
8 sendHID is a tool to simulate typing using the Linux USB Gadget mode.
9
10 Use a Raspberry Pi Zero (or A) to send keystrokes to a host computer.
11
12 ## using the driver
13 There are two drivers available: the legacy `g_hid` driver, which has windows support, and the new `libcomposite`, which makes emulation of multiple devices at the same time very easy. Setup instructions on the latter are below.
14
15 The neccessary drivers are available only in the Raspbian 4.4 Kernel, which you can install using `sudo BRANCH=next rpi-update`, if you haven't updated you Pi in a long time.
16
17 You also need to activate the device tree overlay `dwc2` and load the corresponding kernel module:
18 ```
19 echo "dtoverlay=dwc2" | sudo tee -a /boot/config.txt
20 echo "dwc2" | sudo tee -a /etc/modules
21 ```
22
23 To use this program, you have to enable the `libcomposite` driver on the Raspberry Pi and create a USB HID gadget.
24 You can use this bash script:
25 ```
26 #!/bin/bash
27 # this is a stripped down version of https://github.com/ckuethe/usbarmory/wiki/USB-Gadgets - I don't claim any rights
28
29 modprobe libcomposite
30 cd /sys/kernel/config/usb_gadget/
31 mkdir -p g1
32 cd g1
33 echo 0x1d6b > idVendor # Linux Foundation
34 echo 0x0104 > idProduct # Multifunction Composite Gadget
35 echo 0x0100 > bcdDevice # v1.0.0
36 echo 0x0200 > bcdUSB # USB2
37 mkdir -p strings/0x409
38 echo "fedcba9876543210" > strings/0x409/serialnumber
39 echo "girst" > strings/0x409/manufacturer
40 echo "Hardpass" > strings/0x409/product
41 N="usb0"
42 mkdir -p functions/hid.$N
43 echo 1 > functions/hid.usb0/protocol
44 echo 1 > functions/hid.usb0/subclass
45 echo 8 > functions/hid.usb0/report_length
46 echo -ne \\x05\\x01\\x09\\x06\\xa1\\x01\\x05\\x07\\x19\\xe0\\x29\\xe7\\x15\\x00\\x25\\x01\\x75\\x01\\x95\\x08\\x81\\x02\\x95\\x01\\x75\\x08\\x81\\x03\\x95\\x05\\x75\\x01\\x05\\x08\\x19\\x01\\x29\\x05\\x91\\x02\\x95\\x01\\x75\\x03\\x91\\x03\\x95\\x06\\x75\\x08\\x15\\x00\\x25\\x65\\x05\\x07\\x19\\x00\\x29\\x65\\x81\\x00\\xc0 > functions/hid.usb0/report_desc
47 C=1
48 mkdir -p configs/c.$C/strings/0x409
49 echo "Config $C: ECM network" > configs/c.$C/strings/0x409/configuration
50 echo 250 > configs/c.$C/MaxPower
51 ln -s functions/hid.$N configs/c.$C/
52 ls /sys/class/udc > UDC
53 ```
54
55 ## internals of this code
56 whenever you need to add (or remove) a new keyboard layout, the following changes have to be made:
57
58 ### adding a new key to existing layouts
59
60 1. if the key is on the keyboard, just add a new line, and use the keycode ("Usage ID (Hex)") from the table 12 on page 53pp of the [_USB HID Usage Tables_](https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf) document.
61
62 Following the keycode comes the modifier bit mask. `0x02` is Shift, `0x40` AltGraph.
63
64 Now an example adding the letter A:
65
66 ```
67 {"A", //character to translate
68 { //english layout
69 0x04, //keycode
70 0x02 //shift
71 }, { //german layout
72 0x04, //keycode
73 0x02 //shift
74 }, { //german-nodeadkeys
75 0x04, //keycode
76 0x02 //shift
77 }
78 }
79 ```
80
81 2. if it isn't on the keyboard, fill keyocde and modifier bit mask with `0x00` for the layout and use the `.unicode=0xXXXX` (See point 3 in the 'adding a new layout' section below).
82
83 ### adding a new keyboard layout (example)
84 1. in `scancodes.h` add the layout to `keysym`-struct:
85 this identifier does not need to be used outside of scancodes.{h,c}.
86 ```
87 struct keysym {
88 // ...
89 struct layout de_dv; //dvorak layout
90 // ...
91 };
92 ```
93 2. the enum `kbd1` has to be ammended:
94 ```
95 enum kbdl { //keyboard layouts:
96 // ...
97 de_DV //de_AT-Dvorak
98 };
99 ```
100 3. in `scancodes.c` you need to add a new column (containing more columns) to the big `keysyms[]` table:
101 It is suggested to explicitly name `.is_dead` and `.unicode` to avoid confusion. Also notice that `.is_dead` is part of the layout (and goes within the inner braces), while `.unicode` resides in the keysym-struct.
102 if you want to add new keys, the following must be kept in mind: `toscan()` will use the nth line of the table, if n is larger than 32 (aka. will use the ascii code to look up chars). symbols not in the 7-bit ascii standard can be put on the first 32 positions as utf-8 encoded strings, although keeping [0] to the release all chars is recommended. (some text editors will convert files to older encodings - this might break things)
103 ```
104 struct keysym keysyms[] = {
105 //...
106 {"#", {0x20, 0x02}, {0x31, 0x00}, {0x31, 0x00}, {KEY, MODIFIER}},
107 {"^", {0x23, 0x02}, {0x35, 0x00}, {0x35, 0x00}, {KEY, MODIFIER, .is_dead = 1}},
108 {"&", {0x24, 0x02}, {0x23, 0x02}, {0x23, 0x02}, {KEY, MODIFIER}, .unicode=OxHEX},
109 //...
110 };
111 ```
112 4. `tolay()` needs a new case to its switch statement:
113 This is the only place where the `layout`-idenitfier from `keysym` needs to be used.
114 ```
115 struct layout* tolay (struct keysym* s, enum kbdl layout) {
116 switch (layout) {
117 // ...
118 case de_DV: return &(s->de_dv);
119 default: return NULL;
120 }
121 }
122 ```
123 5. finally, your code must understand the new layout, represented by the `enum kbd1`-entry, `de_DV` in this example.
Imprint / Impressum