Commit 6748031a authored by Andrej Shadura's avatar Andrej Shadura Committed by Jiri Kosina

HID: u2fzero: Support NitroKey U2F revision of the device

NitroKey produced a clone of U2F Zero with a different firmware,
which moved extra commands into the vendor range.
Disambiguate hardware revisions and select the correct configuration in
u2fzero_probe.

Link: https://github.com/Nitrokey/nitrokey-fido-u2f-firmware/commit/a93c16b41fSigned-off-by: default avatarAndrej Shadura <andrew.shadura@collabora.co.uk>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent 42d43c92
......@@ -288,6 +288,9 @@
#define USB_DEVICE_ID_CJTOUCH_MULTI_TOUCH_0020 0x0020
#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_DEVICE_ID_CM109 0x000e
#define USB_DEVICE_ID_CMEDIA_HS100B 0x0014
......
......@@ -26,6 +26,30 @@
#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 */
#define CID_BROADCAST 0xffffffff
......@@ -52,10 +76,6 @@ struct u2f_hid_report {
#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 hid_device *hdev;
struct urb *urb; /* URB for the RNG data */
......@@ -67,6 +87,7 @@ struct u2fzero_device {
u8 *buf_in;
struct mutex lock;
bool present;
kernel_ulong_t hw_revision;
};
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)
.report_type = 0,
.msg.cid = CID_BROADCAST,
.msg.init = {
.cmd = U2F_CUSTOM_WINK,
.cmd = hw_configs[dev->hw_revision].wink_cmd,
.bcnth = 0,
.bcntl = 0,
.data = {0},
......@@ -182,7 +203,7 @@ static int u2fzero_rng_read(struct hwrng *rng, void *data,
.report_type = 0,
.msg.cid = CID_BROADCAST,
.msg.init = {
.cmd = U2F_CUSTOM_GET_RNG,
.cmd = hw_configs[dev->hw_revision].rng_cmd,
.bcnth = 0,
.bcntl = 0,
.data = {0},
......@@ -295,6 +316,8 @@ static int u2fzero_probe(struct hid_device *hdev,
if (dev == NULL)
return -ENOMEM;
dev->hw_revision = id->driver_data;
dev->buf_out = devm_kmalloc(&hdev->dev,
sizeof(struct u2f_hid_report), GFP_KERNEL);
if (dev->buf_out == NULL)
......@@ -329,7 +352,7 @@ static int u2fzero_probe(struct hid_device *hdev,
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);
if (ret) {
......@@ -337,7 +360,7 @@ static int u2fzero_probe(struct hid_device *hdev,
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;
}
......@@ -357,7 +380,11 @@ static void u2fzero_remove(struct hid_device *hdev)
static const struct hid_device_id u2fzero_table[] = {
{ 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);
......
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