26
26
27
27
#define HID_REPORT_SIZE 64
28
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
+
29
53
/* We only use broadcast (CID-less) messages */
30
54
#define CID_BROADCAST 0xffffffff
31
55
@@ -52,10 +76,6 @@ struct u2f_hid_report {
52
76
53
77
#define U2F_HID_MSG_LEN (f ) (size_t)(((f).init.bcnth << 8) + (f).init.bcntl)
54
78
55
- /* Custom extensions to the U2FHID protocol */
56
- #define U2F_CUSTOM_GET_RNG 0x21
57
- #define U2F_CUSTOM_WINK 0x24
58
-
59
79
struct u2fzero_device {
60
80
struct hid_device * hdev ;
61
81
struct urb * urb ; /* URB for the RNG data */
@@ -67,6 +87,7 @@ struct u2fzero_device {
67
87
u8 * buf_in ;
68
88
struct mutex lock ;
69
89
bool present ;
90
+ kernel_ulong_t hw_revision ;
70
91
};
71
92
72
93
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
175
.report_type = 0 ,
155
176
.msg .cid = CID_BROADCAST ,
156
177
.msg .init = {
157
- .cmd = U2F_CUSTOM_WINK ,
178
+ .cmd = hw_configs [ dev -> hw_revision ]. wink_cmd ,
158
179
.bcnth = 0 ,
159
180
.bcntl = 0 ,
160
181
.data = {0 },
@@ -182,7 +203,7 @@ static int u2fzero_rng_read(struct hwrng *rng, void *data,
182
203
.report_type = 0 ,
183
204
.msg .cid = CID_BROADCAST ,
184
205
.msg .init = {
185
- .cmd = U2F_CUSTOM_GET_RNG ,
206
+ .cmd = hw_configs [ dev -> hw_revision ]. rng_cmd ,
186
207
.bcnth = 0 ,
187
208
.bcntl = 0 ,
188
209
.data = {0 },
@@ -297,6 +318,8 @@ static int u2fzero_probe(struct hid_device *hdev,
297
318
if (dev == NULL )
298
319
return - ENOMEM ;
299
320
321
+ dev -> hw_revision = id -> driver_data ;
322
+
300
323
dev -> buf_out = devm_kmalloc (& hdev -> dev ,
301
324
sizeof (struct u2f_hid_report ), GFP_KERNEL );
302
325
if (dev -> buf_out == NULL )
@@ -331,15 +354,15 @@ static int u2fzero_probe(struct hid_device *hdev,
331
354
return ret ;
332
355
}
333
356
334
- hid_info (hdev , "U2F Zero LED initialised\n" );
357
+ hid_info (hdev , "%s LED initialised\n" , hw_configs [ dev -> hw_revision ]. name );
335
358
336
359
ret = u2fzero_init_hwrng (dev , minor );
337
360
if (ret ) {
338
361
hid_hw_stop (hdev );
339
362
return ret ;
340
363
}
341
364
342
- hid_info (hdev , "U2F Zero RNG initialised\n" );
365
+ hid_info (hdev , "%s RNG initialised\n" , hw_configs [ dev -> hw_revision ]. name );
343
366
344
367
return 0 ;
345
368
}
@@ -359,7 +382,11 @@ static void u2fzero_remove(struct hid_device *hdev)
359
382
360
383
static const struct hid_device_id u2fzero_table [] = {
361
384
{ HID_USB_DEVICE (USB_VENDOR_ID_CYGNAL ,
362
- USB_DEVICE_ID_U2F_ZERO ) },
385
+ USB_DEVICE_ID_U2F_ZERO ),
386
+ .driver_data = HW_U2FZERO },
387
+ { HID_USB_DEVICE (USB_VENDOR_ID_CLAY_LOGIC ,
388
+ USB_DEVICE_ID_NITROKEY_U2F ),
389
+ .driver_data = HW_NITROKEY_U2F },
363
390
{ }
364
391
};
365
392
MODULE_DEVICE_TABLE (hid , u2fzero_table );
0 commit comments