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 },
@@ -297,6 +318,8 @@ static int u2fzero_probe(struct hid_device *hdev,
297318 if (dev == NULL )
298319 return - ENOMEM ;
299320
321+ dev -> hw_revision = id -> driver_data ;
322+
300323 dev -> buf_out = devm_kmalloc (& hdev -> dev ,
301324 sizeof (struct u2f_hid_report ), GFP_KERNEL );
302325 if (dev -> buf_out == NULL )
@@ -331,15 +354,15 @@ static int u2fzero_probe(struct hid_device *hdev,
331354 return ret ;
332355 }
333356
334- hid_info (hdev , "U2F Zero LED initialised\n" );
357+ hid_info (hdev , "%s LED initialised\n" , hw_configs [ dev -> hw_revision ]. name );
335358
336359 ret = u2fzero_init_hwrng (dev , minor );
337360 if (ret ) {
338361 hid_hw_stop (hdev );
339362 return ret ;
340363 }
341364
342- hid_info (hdev , "U2F Zero RNG initialised\n" );
365+ hid_info (hdev , "%s RNG initialised\n" , hw_configs [ dev -> hw_revision ]. name );
343366
344367 return 0 ;
345368}
@@ -359,7 +382,11 @@ static void u2fzero_remove(struct hid_device *hdev)
359382
360383static const struct hid_device_id u2fzero_table [] = {
361384 { 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 },
363390 { }
364391};
365392MODULE_DEVICE_TABLE (hid , u2fzero_table );
0 commit comments