1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * U2F Zero LED and RNG driver 4 * 5 * Copyright 2018 Andrej Shadura <andrew@shadura.me> 6 * Loosely based on drivers/hid/hid-led.c 7 * and drivers/usb/misc/chaoskey.c 8 * 9 * This program is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public License as 11 * published by the Free Software Foundation, version 2. 12 */ 13 14 #include <linux/hid.h> 15 #include <linux/hidraw.h> 16 #include <linux/hw_random.h> 17 #include <linux/leds.h> 18 #include <linux/module.h> 19 #include <linux/mutex.h> 20 #include <linux/usb.h> 21 22 #include "usbhid/usbhid.h" 23 #include "hid-ids.h" 24 25 #define DRIVER_SHORT "u2fzero" 26 27 #define HID_REPORT_SIZE 64 28 29 enum hw_revision { 30 HW_U2FZERO, 31 HW_NITROKEY_U2F, 32 }; 33 34 struct hw_revision_config { 35 u8 rng_cmd; 36 u8 wink_cmd; 37 const char *name; 38 }; 39 40 static const struct hw_revision_config hw_configs[] = { 41 [HW_U2FZERO] = { 42 .rng_cmd = 0x21, 43 .wink_cmd = 0x24, 44 .name = "U2F Zero", 45 }, 46 [HW_NITROKEY_U2F] = { 47 .rng_cmd = 0xc0, 48 .wink_cmd = 0xc2, 49 .name = "NitroKey U2F", 50 }, 51 }; 52 53 /* We only use broadcast (CID-less) messages */ 54 #define CID_BROADCAST 0xffffffff 55 56 struct u2f_hid_msg { 57 u32 cid; 58 union { 59 struct { 60 u8 cmd; 61 u8 bcnth; 62 u8 bcntl; 63 u8 data[HID_REPORT_SIZE - 7]; 64 } init; 65 struct { 66 u8 seq; 67 u8 data[HID_REPORT_SIZE - 5]; 68 } cont; 69 }; 70 } __packed; 71 72 struct u2f_hid_report { 73 u8 report_type; 74 struct u2f_hid_msg msg; 75 } __packed; 76 77 #define U2F_HID_MSG_LEN(f) (size_t)(((f).init.bcnth << 8) + (f).init.bcntl) 78 79 struct u2fzero_device { 80 struct hid_device *hdev; 81 struct urb *urb; /* URB for the RNG data */ 82 struct led_classdev ldev; /* Embedded struct for led */ 83 struct hwrng hwrng; /* Embedded struct for hwrng */ 84 char *led_name; 85 char *rng_name; 86 u8 *buf_out; 87 u8 *buf_in; 88 struct mutex lock; 89 bool present; 90 kernel_ulong_t hw_revision; 91 }; 92 93 static int u2fzero_send(struct u2fzero_device *dev, struct u2f_hid_report *req) 94 { 95 int ret; 96 97 mutex_lock(&dev->lock); 98 99 memcpy(dev->buf_out, req, sizeof(struct u2f_hid_report)); 100 101 ret = hid_hw_output_report(dev->hdev, dev->buf_out, 102 sizeof(struct u2f_hid_msg)); 103 104 mutex_unlock(&dev->lock); 105 106 if (ret < 0) 107 return ret; 108 109 return ret == sizeof(struct u2f_hid_msg) ? 0 : -EMSGSIZE; 110 } 111 112 struct u2fzero_transfer_context { 113 struct completion done; 114 int status; 115 }; 116 117 static void u2fzero_read_callback(struct urb *urb) 118 { 119 struct u2fzero_transfer_context *ctx = urb->context; 120 121 ctx->status = urb->status; 122 complete(&ctx->done); 123 } 124 125 static int u2fzero_recv(struct u2fzero_device *dev, 126 struct u2f_hid_report *req, 127 struct u2f_hid_msg *resp) 128 { 129 int ret; 130 struct hid_device *hdev = dev->hdev; 131 struct u2fzero_transfer_context ctx; 132 133 mutex_lock(&dev->lock); 134 135 memcpy(dev->buf_out, req, sizeof(struct u2f_hid_report)); 136 137 dev->urb->context = &ctx; 138 init_completion(&ctx.done); 139 140 ret = usb_submit_urb(dev->urb, GFP_NOIO); 141 if (unlikely(ret)) { 142 hid_err(hdev, "usb_submit_urb failed: %d", ret); 143 goto err; 144 } 145 146 ret = hid_hw_output_report(dev->hdev, dev->buf_out, 147 sizeof(struct u2f_hid_msg)); 148 149 if (ret < 0) { 150 hid_err(hdev, "hid_hw_output_report failed: %d", ret); 151 goto err; 152 } 153 154 ret = (wait_for_completion_timeout( 155 &ctx.done, msecs_to_jiffies(USB_CTRL_SET_TIMEOUT))); 156 if (ret == 0) { 157 usb_kill_urb(dev->urb); 158 hid_err(hdev, "urb submission timed out"); 159 } else { 160 ret = dev->urb->actual_length; 161 memcpy(resp, dev->buf_in, ret); 162 } 163 164 err: 165 mutex_unlock(&dev->lock); 166 167 return ret; 168 } 169 170 static int u2fzero_blink(struct led_classdev *ldev) 171 { 172 struct u2fzero_device *dev = container_of(ldev, 173 struct u2fzero_device, ldev); 174 struct u2f_hid_report req = { 175 .report_type = 0, 176 .msg.cid = CID_BROADCAST, 177 .msg.init = { 178 .cmd = hw_configs[dev->hw_revision].wink_cmd, 179 .bcnth = 0, 180 .bcntl = 0, 181 .data = {0}, 182 } 183 }; 184 return u2fzero_send(dev, &req); 185 } 186 187 static int u2fzero_brightness_set(struct led_classdev *ldev, 188 enum led_brightness brightness) 189 { 190 ldev->brightness = LED_OFF; 191 if (brightness) 192 return u2fzero_blink(ldev); 193 else 194 return 0; 195 } 196 197 static int u2fzero_rng_read(struct hwrng *rng, void *data, 198 size_t max, bool wait) 199 { 200 struct u2fzero_device *dev = container_of(rng, 201 struct u2fzero_device, hwrng); 202 struct u2f_hid_report req = { 203 .report_type = 0, 204 .msg.cid = CID_BROADCAST, 205 .msg.init = { 206 .cmd = hw_configs[dev->hw_revision].rng_cmd, 207 .bcnth = 0, 208 .bcntl = 0, 209 .data = {0}, 210 } 211 }; 212 struct u2f_hid_msg resp; 213 int ret; 214 size_t actual_length; 215 /* valid packets must have a correct header */ 216 int min_length = offsetof(struct u2f_hid_msg, init.data); 217 218 if (!dev->present) { 219 hid_dbg(dev->hdev, "device not present"); 220 return 0; 221 } 222 223 ret = u2fzero_recv(dev, &req, &resp); 224 225 /* ignore errors or packets without data */ 226 if (ret < min_length) 227 return 0; 228 229 /* only take the minimum amount of data it is safe to take */ 230 actual_length = min3((size_t)ret - min_length, 231 U2F_HID_MSG_LEN(resp), max); 232 233 memcpy(data, resp.init.data, actual_length); 234 235 return actual_length; 236 } 237 238 static int u2fzero_init_led(struct u2fzero_device *dev, 239 unsigned int minor) 240 { 241 dev->led_name = devm_kasprintf(&dev->hdev->dev, GFP_KERNEL, 242 "%s%u", DRIVER_SHORT, minor); 243 if (dev->led_name == NULL) 244 return -ENOMEM; 245 246 dev->ldev.name = dev->led_name; 247 dev->ldev.max_brightness = LED_ON; 248 dev->ldev.flags = LED_HW_PLUGGABLE; 249 dev->ldev.brightness_set_blocking = u2fzero_brightness_set; 250 251 return devm_led_classdev_register(&dev->hdev->dev, &dev->ldev); 252 } 253 254 static int u2fzero_init_hwrng(struct u2fzero_device *dev, 255 unsigned int minor) 256 { 257 dev->rng_name = devm_kasprintf(&dev->hdev->dev, GFP_KERNEL, 258 "%s-rng%u", DRIVER_SHORT, minor); 259 if (dev->rng_name == NULL) 260 return -ENOMEM; 261 262 dev->hwrng.name = dev->rng_name; 263 dev->hwrng.read = u2fzero_rng_read; 264 265 return devm_hwrng_register(&dev->hdev->dev, &dev->hwrng); 266 } 267 268 static int u2fzero_fill_in_urb(struct u2fzero_device *dev) 269 { 270 struct hid_device *hdev = dev->hdev; 271 struct usb_device *udev; 272 struct usbhid_device *usbhid = hdev->driver_data; 273 unsigned int pipe_in; 274 struct usb_host_endpoint *ep; 275 276 if (dev->hdev->bus != BUS_USB) 277 return -EINVAL; 278 279 udev = hid_to_usb_dev(hdev); 280 281 if (!usbhid->urbout || !usbhid->urbin) 282 return -ENODEV; 283 284 ep = usb_pipe_endpoint(udev, usbhid->urbin->pipe); 285 if (!ep) 286 return -ENODEV; 287 288 dev->urb = usb_alloc_urb(0, GFP_KERNEL); 289 if (!dev->urb) 290 return -ENOMEM; 291 292 pipe_in = (usbhid->urbin->pipe & ~(3 << 30)) | (PIPE_INTERRUPT << 30); 293 294 usb_fill_int_urb(dev->urb, 295 udev, 296 pipe_in, 297 dev->buf_in, 298 HID_REPORT_SIZE, 299 u2fzero_read_callback, 300 NULL, 301 ep->desc.bInterval); 302 303 return 0; 304 } 305 306 static int u2fzero_probe(struct hid_device *hdev, 307 const struct hid_device_id *id) 308 { 309 struct u2fzero_device *dev; 310 unsigned int minor; 311 int ret; 312 313 if (!hid_is_usb(hdev)) 314 return -EINVAL; 315 316 dev = devm_kzalloc(&hdev->dev, sizeof(*dev), GFP_KERNEL); 317 if (dev == NULL) 318 return -ENOMEM; 319 320 dev->hw_revision = id->driver_data; 321 322 dev->buf_out = devm_kmalloc(&hdev->dev, 323 sizeof(struct u2f_hid_report), GFP_KERNEL); 324 if (dev->buf_out == NULL) 325 return -ENOMEM; 326 327 dev->buf_in = devm_kmalloc(&hdev->dev, 328 sizeof(struct u2f_hid_msg), GFP_KERNEL); 329 if (dev->buf_in == NULL) 330 return -ENOMEM; 331 332 ret = hid_parse(hdev); 333 if (ret) 334 return ret; 335 336 dev->hdev = hdev; 337 hid_set_drvdata(hdev, dev); 338 mutex_init(&dev->lock); 339 340 ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW); 341 if (ret) 342 return ret; 343 344 u2fzero_fill_in_urb(dev); 345 346 dev->present = true; 347 348 minor = ((struct hidraw *) hdev->hidraw)->minor; 349 350 ret = u2fzero_init_led(dev, minor); 351 if (ret) { 352 hid_hw_stop(hdev); 353 return ret; 354 } 355 356 hid_info(hdev, "%s LED initialised\n", hw_configs[dev->hw_revision].name); 357 358 ret = u2fzero_init_hwrng(dev, minor); 359 if (ret) { 360 hid_hw_stop(hdev); 361 return ret; 362 } 363 364 hid_info(hdev, "%s RNG initialised\n", hw_configs[dev->hw_revision].name); 365 366 return 0; 367 } 368 369 static void u2fzero_remove(struct hid_device *hdev) 370 { 371 struct u2fzero_device *dev = hid_get_drvdata(hdev); 372 373 mutex_lock(&dev->lock); 374 dev->present = false; 375 mutex_unlock(&dev->lock); 376 377 hid_hw_stop(hdev); 378 usb_poison_urb(dev->urb); 379 usb_free_urb(dev->urb); 380 } 381 382 static const struct hid_device_id u2fzero_table[] = { 383 { HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, 384 USB_DEVICE_ID_U2F_ZERO), 385 .driver_data = HW_U2FZERO }, 386 { HID_USB_DEVICE(USB_VENDOR_ID_CLAY_LOGIC, 387 USB_DEVICE_ID_NITROKEY_U2F), 388 .driver_data = HW_NITROKEY_U2F }, 389 { } 390 }; 391 MODULE_DEVICE_TABLE(hid, u2fzero_table); 392 393 static struct hid_driver u2fzero_driver = { 394 .name = "hid-" DRIVER_SHORT, 395 .probe = u2fzero_probe, 396 .remove = u2fzero_remove, 397 .id_table = u2fzero_table, 398 }; 399 400 module_hid_driver(u2fzero_driver); 401 402 MODULE_LICENSE("GPL"); 403 MODULE_AUTHOR("Andrej Shadura <andrew@shadura.me>"); 404 MODULE_DESCRIPTION("U2F Zero LED and RNG driver"); 405