xref: /aosp_15_r20/external/crosvm/devices/src/usb/backend/fido_backend/constants.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1 // Copyright 2024 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 use usb_util::DescriptorType;
6 
7 // How long it takes for the security key to become inactive and time out all previously pending
8 // transactions since last activity.
9 pub const TRANSACTION_TIMEOUT_MILLIS: u64 = 120_000;
10 
11 // How long to wait before timing out and canceling a USB transfer from the guest if the host
12 // security key is unresponsive.
13 pub const USB_TRANSFER_TIMEOUT_MILLIS: u64 = 5_000;
14 
15 // 5ms is the default USB interrupt polling rate according to specs.
16 pub const USB_POLL_RATE_MILLIS: u64 = 5;
17 
18 // Some applications expect a very short RTT when handling packets between host key and guest, half
19 // a millisecond seems like a decent compromise.
20 pub const PACKET_POLL_RATE_NANOS: u64 = 50_000;
21 
22 // Total max number of transactions we can hold in our key. Any more transactions will push older
23 // transactions away from the stack.
24 pub const MAX_TRANSACTIONS: usize = 4;
25 
26 // Max number of incoming packets still to be processed by the guest
27 pub const U2FHID_MAX_IN_PENDING: usize = 32;
28 
29 pub const U2FHID_PACKET_SIZE: usize = 64;
30 pub const PACKET_INIT_HEADER_SIZE: usize = 7;
31 pub const PACKET_CONT_HEADER_SIZE: usize = 5;
32 pub const PACKET_INIT_DATA_SIZE: usize = U2FHID_PACKET_SIZE - PACKET_INIT_HEADER_SIZE;
33 pub const PACKET_CONT_DATA_SIZE: usize = U2FHID_PACKET_SIZE - PACKET_CONT_HEADER_SIZE;
34 pub const BROADCAST_CID: u32 = 0xFFFFFFFF;
35 
36 pub const NONCE_SIZE: usize = 8;
37 pub const EMPTY_NONCE: [u8; NONCE_SIZE] = [0u8; NONCE_SIZE];
38 
39 // It's a valid init packet only if the 7th bit of the cmd field is set
40 pub const PACKET_INIT_VALID_CMD: u8 = 0b1000_0000;
41 pub const U2FHID_ERROR_CMD: u8 = 0xBF;
42 
43 pub const U2FHID_CONTROL_ENDPOINT: u8 = 0x00;
44 pub const U2FHID_IN_ENDPOINT: u8 = 0x81;
45 pub const U2FHID_OUT_ENDPOINT: u8 = 0x01;
46 
47 // Generic HID commands
48 pub const HID_GET_IDLE: u8 = 0x02;
49 pub const HID_SET_IDLE: u8 = 0x0A;
50 pub const HID_GET_REPORT_DESC: u8 = 0x22;
51 
52 pub const HID_MAX_DESCRIPTOR_SIZE: usize = 4096;
53 
54 // Descriptor data taken from: https://github.com/gl-sergei/u2f-token/blob/master/src/usb-hid.c
55 // With minor modifications for our own PID and VID and other strings
56 pub const U2FHID_DEVICE_DESC: &[u8] = &[
57     18,
58     DescriptorType::Device as u8,
59     0x10,
60     0x01,
61     0x00,
62     0x00,
63     0x00,
64     0x40,
65     // Google Vendor ID
66     0xd1,
67     0x18,
68     // Unique Product ID
69     0xd0,
70     0xf1,
71     0x00,
72     0x01,
73     0,
74     0,
75     0,
76     1,
77 ];
78 
79 pub const HID_REPORT_DESC_HEADER: &[u8] = &[
80     0x06, 0xd0, 0xf1, // Usage Page (FIDO)
81     0x09, 0x01, // Usage (FIDO)
82 ];
83 
84 pub const U2FHID_CONFIG_DESC: &[u8] = &[
85     9,
86     DescriptorType::Configuration as u8,
87     /* Configuration Descriptor. */
88     41,
89     0x00, /* wTotalLength. */
90     0x01, /* bNumInterfaces. */
91     0x01, /* bConfigurationValue. */
92     0,    /* iConfiguration. */
93     0x80, /* bmAttributes. */
94     15,   /* bMaxPower (100mA). */
95     /* Interface Descriptor. */
96     9, /* bLength: Interface Descriptor size */
97     DescriptorType::Interface as u8,
98     0,    /* bInterfaceNumber: Number of Interface */
99     0x00, /* bAlternateSetting: Alternate setting */
100     0x02, /* bNumEndpoints: Two endpoints used */
101     0x03, /* bInterfaceClass: HID */
102     0x00, /* bInterfaceSubClass: no boot */
103     0x00, /* bInterfaceProtocol: 0=none */
104     0x00, /* iInterface */
105     /* HID Descriptor. */
106     9,    /* bLength: HID Descriptor size */
107     0x21, /* bDescriptorType: HID */
108     0x10,
109     0x01, /* bcdHID: HID Class Spec release number */
110     0x00, /* bCountryCode: Hardware target country */
111     0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
112     0x22, /* bDescriptorType */
113     0x22,
114     0, /* wItemLength: Total length of Report descriptor */
115     /* Endpoint IN1 Descriptor */
116     7, /* bLength: Endpoint Descriptor size */
117     DescriptorType::Endpoint as u8,
118     0x81, /* bEndpointAddress: (IN1) */
119     0x03, /* bmAttributes: Interrupt */
120     0x40,
121     0x00, /* wMaxPacketSize: 64 */
122     0x05, /* bInterval (5ms) */
123     /* Endpoint OUT1 Descriptor */
124     7, /* bLength: Endpoint Descriptor size */
125     DescriptorType::Endpoint as u8,
126     0x01, /* bEndpointAddress: (OUT1) */
127     0x03, /* bmAttributes: Interrupt */
128     0x40,
129     0x00, /* wMaxPacketSize: 64 */
130     0x05, /* bInterval (5ms) */
131 ];
132 
133 pub const HID_REPORT_DESC: &[u8] = &[
134     0x06, 0xd0, 0xf1, /* USAGE_PAGE (FIDO Alliance) */
135     0x09, 0x01, /* USAGE (Keyboard) */
136     0xa1, 0x01, /* COLLECTION (Application) */
137     0x09, 0x20, /* USAGE (Input report data) */
138     0x15, 0x00, /* LOGICAL_MINIMUM (0) */
139     0x26, 0xff, 0x00, /* LOGICAL_MAXIMUM (255) */
140     0x75, 0x08, /* REPORT_SIZE (8) */
141     0x95, 0x40, /* REPORT_COUNT (64) */
142     0x81, 0x02, /* INPUT (Data,Var,Abs); Modifier byte */
143     0x09, 0x21, /* USAGE (Output report data) */
144     0x15, 0x00, /* LOGICAL_MINIMUM (0) */
145     0x26, 0xff, 0x00, /* LOGICAL_MAXIMUM (255) */
146     0x75, 0x08, /* REPORT_SIZE (8) */
147     0x95, 0x40, /* REPORT_COUNT (64) */
148     0x91, 0x02, /* OUTPUT (Data,Var,Abs); Modifier byte */
149     0xc0, /* END_COLLECTION */
150 ];
151