Commit a7c2b7ea authored by Jiri Kosina's avatar Jiri Kosina

Merge branch 'for-5.16/u2fzero' into for-linus

- support for new revision of the NitroKey U2F device firmware
  (Andrej Shadura)
parents 0cc82d61 6748031a
...@@ -289,6 +289,9 @@ ...@@ -289,6 +289,9 @@
#define USB_DEVICE_ID_CJTOUCH_MULTI_TOUCH_0020 0x0020 #define USB_DEVICE_ID_CJTOUCH_MULTI_TOUCH_0020 0x0020
#define USB_DEVICE_ID_CJTOUCH_MULTI_TOUCH_0040 0x0040 #define USB_DEVICE_ID_CJTOUCH_MULTI_TOUCH_0040 0x0040
#define USB_VENDOR_ID_CLAY_LOGIC 0x20a0
#define USB_DEVICE_ID_NITROKEY_U2F 0x4287
#define USB_VENDOR_ID_CMEDIA 0x0d8c #define USB_VENDOR_ID_CMEDIA 0x0d8c
#define USB_DEVICE_ID_CM109 0x000e #define USB_DEVICE_ID_CM109 0x000e
#define USB_DEVICE_ID_CMEDIA_HS100B 0x0014 #define USB_DEVICE_ID_CMEDIA_HS100B 0x0014
......
...@@ -26,6 +26,30 @@ ...@@ -26,6 +26,30 @@
#define HID_REPORT_SIZE 64 #define HID_REPORT_SIZE 64
enum hw_revision {
HW_U2FZERO,
HW_NITROKEY_U2F,
};
struct hw_revision_config {
u8 rng_cmd;
u8 wink_cmd;
const char *name;
};
static const struct hw_revision_config hw_configs[] = {
[HW_U2FZERO] = {
.rng_cmd = 0x21,
.wink_cmd = 0x24,
.name = "U2F Zero",
},
[HW_NITROKEY_U2F] = {
.rng_cmd = 0xc0,
.wink_cmd = 0xc2,
.name = "NitroKey U2F",
},
};
/* We only use broadcast (CID-less) messages */ /* We only use broadcast (CID-less) messages */
#define CID_BROADCAST 0xffffffff #define CID_BROADCAST 0xffffffff
...@@ -52,10 +76,6 @@ struct u2f_hid_report { ...@@ -52,10 +76,6 @@ struct u2f_hid_report {
#define U2F_HID_MSG_LEN(f) (size_t)(((f).init.bcnth << 8) + (f).init.bcntl) #define U2F_HID_MSG_LEN(f) (size_t)(((f).init.bcnth << 8) + (f).init.bcntl)
/* Custom extensions to the U2FHID protocol */
#define U2F_CUSTOM_GET_RNG 0x21
#define U2F_CUSTOM_WINK 0x24
struct u2fzero_device { struct u2fzero_device {
struct hid_device *hdev; struct hid_device *hdev;
struct urb *urb; /* URB for the RNG data */ struct urb *urb; /* URB for the RNG data */
...@@ -67,6 +87,7 @@ struct u2fzero_device { ...@@ -67,6 +87,7 @@ struct u2fzero_device {
u8 *buf_in; u8 *buf_in;
struct mutex lock; struct mutex lock;
bool present; bool present;
kernel_ulong_t hw_revision;
}; };
static int u2fzero_send(struct u2fzero_device *dev, struct u2f_hid_report *req) static int u2fzero_send(struct u2fzero_device *dev, struct u2f_hid_report *req)
...@@ -154,7 +175,7 @@ static int u2fzero_blink(struct led_classdev *ldev) ...@@ -154,7 +175,7 @@ static int u2fzero_blink(struct led_classdev *ldev)
.report_type = 0, .report_type = 0,
.msg.cid = CID_BROADCAST, .msg.cid = CID_BROADCAST,
.msg.init = { .msg.init = {
.cmd = U2F_CUSTOM_WINK, .cmd = hw_configs[dev->hw_revision].wink_cmd,
.bcnth = 0, .bcnth = 0,
.bcntl = 0, .bcntl = 0,
.data = {0}, .data = {0},
...@@ -182,7 +203,7 @@ static int u2fzero_rng_read(struct hwrng *rng, void *data, ...@@ -182,7 +203,7 @@ static int u2fzero_rng_read(struct hwrng *rng, void *data,
.report_type = 0, .report_type = 0,
.msg.cid = CID_BROADCAST, .msg.cid = CID_BROADCAST,
.msg.init = { .msg.init = {
.cmd = U2F_CUSTOM_GET_RNG, .cmd = hw_configs[dev->hw_revision].rng_cmd,
.bcnth = 0, .bcnth = 0,
.bcntl = 0, .bcntl = 0,
.data = {0}, .data = {0},
...@@ -297,6 +318,8 @@ static int u2fzero_probe(struct hid_device *hdev, ...@@ -297,6 +318,8 @@ static int u2fzero_probe(struct hid_device *hdev,
if (dev == NULL) if (dev == NULL)
return -ENOMEM; return -ENOMEM;
dev->hw_revision = id->driver_data;
dev->buf_out = devm_kmalloc(&hdev->dev, dev->buf_out = devm_kmalloc(&hdev->dev,
sizeof(struct u2f_hid_report), GFP_KERNEL); sizeof(struct u2f_hid_report), GFP_KERNEL);
if (dev->buf_out == NULL) if (dev->buf_out == NULL)
...@@ -331,7 +354,7 @@ static int u2fzero_probe(struct hid_device *hdev, ...@@ -331,7 +354,7 @@ static int u2fzero_probe(struct hid_device *hdev,
return ret; return ret;
} }
hid_info(hdev, "U2F Zero LED initialised\n"); hid_info(hdev, "%s LED initialised\n", hw_configs[dev->hw_revision].name);
ret = u2fzero_init_hwrng(dev, minor); ret = u2fzero_init_hwrng(dev, minor);
if (ret) { if (ret) {
...@@ -339,7 +362,7 @@ static int u2fzero_probe(struct hid_device *hdev, ...@@ -339,7 +362,7 @@ static int u2fzero_probe(struct hid_device *hdev,
return ret; return ret;
} }
hid_info(hdev, "U2F Zero RNG initialised\n"); hid_info(hdev, "%s RNG initialised\n", hw_configs[dev->hw_revision].name);
return 0; return 0;
} }
...@@ -359,7 +382,11 @@ static void u2fzero_remove(struct hid_device *hdev) ...@@ -359,7 +382,11 @@ static void u2fzero_remove(struct hid_device *hdev)
static const struct hid_device_id u2fzero_table[] = { static const struct hid_device_id u2fzero_table[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, { HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL,
USB_DEVICE_ID_U2F_ZERO) }, USB_DEVICE_ID_U2F_ZERO),
.driver_data = HW_U2FZERO },
{ HID_USB_DEVICE(USB_VENDOR_ID_CLAY_LOGIC,
USB_DEVICE_ID_NITROKEY_U2F),
.driver_data = HW_NITROKEY_U2F },
{ } { }
}; };
MODULE_DEVICE_TABLE(hid, u2fzero_table); MODULE_DEVICE_TABLE(hid, u2fzero_table);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment