2626
2727#define HID_REPORT_SIZE 64
2828
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+
2953/* We only use broadcast (CID-less) messages */
3054#define CID_BROADCAST 0xffffffff
3155
@@ -52,10 +76,6 @@ struct u2f_hid_report {
5276
5377#define U2F_HID_MSG_LEN (f ) (size_t)(((f).init.bcnth << 8) + (f).init.bcntl)
5478
55- /* Custom extensions to the U2FHID protocol */
56- #define U2F_CUSTOM_GET_RNG 0x21
57- #define U2F_CUSTOM_WINK 0x24
58-
5979struct u2fzero_device {
6080 struct hid_device * hdev ;
6181 struct urb * urb ; /* URB for the RNG data */
@@ -67,6 +87,7 @@ struct u2fzero_device {
6787 u8 * buf_in ;
6888 struct mutex lock ;
6989 bool present ;
90+ kernel_ulong_t hw_revision ;
7091};
7192
7293static int u2fzero_send (struct u2fzero_device * dev , struct u2f_hid_report * req )
@@ -154,7 +175,7 @@ static int u2fzero_blink(struct led_classdev *ldev)
154175 .report_type = 0 ,
155176 .msg .cid = CID_BROADCAST ,
156177 .msg .init = {
157- .cmd = U2F_CUSTOM_WINK ,
178+ .cmd = hw_configs [ dev -> hw_revision ]. wink_cmd ,
158179 .bcnth = 0 ,
159180 .bcntl = 0 ,
160181 .data = {0 },
@@ -182,7 +203,7 @@ static int u2fzero_rng_read(struct hwrng *rng, void *data,
182203 .report_type = 0 ,
183204 .msg .cid = CID_BROADCAST ,
184205 .msg .init = {
185- .cmd = U2F_CUSTOM_GET_RNG ,
206+ .cmd = hw_configs [ dev -> hw_revision ]. rng_cmd ,
186207 .bcnth = 0 ,
187208 .bcntl = 0 ,
188209 .data = {0 },
@@ -295,6 +316,8 @@ static int u2fzero_probe(struct hid_device *hdev,
295316 if (dev == NULL )
296317 return - ENOMEM ;
297318
319+ dev -> hw_revision = id -> driver_data ;
320+
298321 dev -> buf_out = devm_kmalloc (& hdev -> dev ,
299322 sizeof (struct u2f_hid_report ), GFP_KERNEL );
300323 if (dev -> buf_out == NULL )
@@ -329,15 +352,15 @@ static int u2fzero_probe(struct hid_device *hdev,
329352 return ret ;
330353 }
331354
332- hid_info (hdev , "U2F Zero LED initialised\n" );
355+ hid_info (hdev , "%s LED initialised\n" , hw_configs [ dev -> hw_revision ]. name );
333356
334357 ret = u2fzero_init_hwrng (dev , minor );
335358 if (ret ) {
336359 hid_hw_stop (hdev );
337360 return ret ;
338361 }
339362
340- hid_info (hdev , "U2F Zero RNG initialised\n" );
363+ hid_info (hdev , "%s RNG initialised\n" , hw_configs [ dev -> hw_revision ]. name );
341364
342365 return 0 ;
343366}
@@ -357,7 +380,11 @@ static void u2fzero_remove(struct hid_device *hdev)
357380
358381static const struct hid_device_id u2fzero_table [] = {
359382 { HID_USB_DEVICE (USB_VENDOR_ID_CYGNAL ,
360- USB_DEVICE_ID_U2F_ZERO ) },
383+ USB_DEVICE_ID_U2F_ZERO ),
384+ .driver_data = HW_U2FZERO },
385+ { HID_USB_DEVICE (USB_VENDOR_ID_CLAY_LOGIC ,
386+ USB_DEVICE_ID_NITROKEY_U2F ),
387+ .driver_data = HW_NITROKEY_U2F },
361388 { }
362389};
363390MODULE_DEVICE_TABLE (hid , u2fzero_table );
0 commit comments