blob: c3c740ca7deb3b087feff29b0e7a91d631c4ec12 [file] [log] [blame]
Harald Welte63653742019-01-03 16:54:16 +01001#pragma once
2#include <stdint.h>
3
4/* Identifies the length of type of subordinate descriptors of a CCID device
5 * Table 5.1-1 Smart Card Device Class descriptors */
6struct usb_ccid_class_descriptor {
7 uint8_t bLength;
8 uint8_t bDescriptorType;
9 uint16_t bcdCCID;
10 uint8_t bMaxSlotIndex;
11 uint8_t bVoltageSupport;
12 uint32_t dwProtocols;
13 uint32_t dwDefaultClock;
14 uint32_t dwMaximumClock;
15 uint8_t bNumClockSupported;
16 uint32_t dwDataRate;
17 uint32_t dwMaxDataRate;
18 uint8_t bNumDataRatesSupported;
19 uint32_t dwMaxIFSD;
20 uint32_t dwSynchProtocols;
21 uint32_t dwMechanical;
22 uint32_t dwFeatures;
23 uint32_t dwMaxCCIDMessageLength;
24 uint8_t bClassGetResponse;
25 uint8_t bClassEnvelope;
26 uint16_t wLcdLayout;
27 uint8_t bPINSupport;
28 uint8_t bMaxCCIDBusySlots;
29} __attribute__((packed));
30/* handling of bulk out from host */
31
32enum ccid_msg_type {
33 /* Section 6.3 / Table 6.3-1: Interrupt IN */
34 RDR_to_PC_NotifySlotChange = 0x50,
35 RDR_to_PC_HardwareError = 0x51,
36
37 /* Section 6.1 / Table 6.1-1: Bulk OUT */
38 PC_to_RDR_IccPowerOn = 0x62,
39 PC_to_RDR_IccPowerOff = 0x63,
40 PC_to_RDR_GetSlotStatus = 0x65,
41 PC_to_RDR_XfrBlock = 0x6f,
42 PC_to_RDR_GetParameters = 0x6c,
43 PC_to_RDR_ResetParameters = 0x6d,
44 PC_to_RDR_SetParameters = 0x61,
45 PC_to_RDR_Escape = 0x6b,
46 PC_to_RDR_IccClock = 0x6e,
47 PC_to_RDR_T0APDU = 0x6a,
48 PC_to_RDR_Secure = 0x69,
49 PC_to_RDR_Mechanical = 0x71,
50 PC_to_RDR_Abort = 0x72,
51 PC_to_RDR_SetDataRateAndClockFrequency = 0x73,
52
53 /* Section 6.2 / Table 6.2-1: Bulk IN */
54 RDR_to_PC_DataBlock = 0x80,
55 RDR_to_PC_SlotStatus = 0x81,
56 RDR_to_PC_Parameters = 0x82,
57 RDR_to_PC_Escape = 0x83,
58 RDR_to_PC_DataRateAndClockFrequency = 0x84,
59};
60
61/* CCID message header on BULK-OUT endpoint */
62struct ccid_header {
63 uint8_t bMessageType;
64 uint32_t dwLength;
65 uint8_t bSlot;
66 uint8_t bSeq;
67} __attribute__ ((packed));
68
69/***********************************************************************
70 * Bulk OUT
71 ***********************************************************************/
72
73/* Section 6.1.1 */
74enum ccid_power_select {
75 CCID_PWRSEL_AUTO = 0x00,
76 CCID_PWRSEL_5V0 = 0x01,
77 CCID_PWRSEL_3V0 = 0x02,
78 CCID_PWRSEL_1V8 = 0x03,
79};
80
81/* Section 6.1.1 */
82struct ccid_pc_to_rdr_icc_power_on {
83 struct ccid_header hdr;
84 uint8_t bPowerSelect;
85 uint8_t abRFU[2];
86} __attribute__ ((packed));
87/* Response: RDR_to_PC_DataBlock */
88
89/* Section 6.1.2 */
90struct ccid_pc_to_rdr_icc_power_off {
91 struct ccid_header hdr;
92 uint8_t abRFU[3];
93} __attribute__ ((packed));
94/* Response: RDR_to_PC_SlotStatus */
95
96/* Section 6.1.3 */
97struct ccid_pc_to_rdr_get_slot_status {
98 struct ccid_header hdr;
99 uint8_t abRFU[3];
100} __attribute__ ((packed));
101/* Response: RDR_to_PC_SlotStatus */
102
103/* Section 6.1.4 */
104struct ccid_pc_to_rdr_xfr_block {
105 struct ccid_header hdr;
106 uint8_t bBWI;
107 uint16_t wLevelParameter;
108 uint8_t abData[0];
109} __attribute__ ((packed));
110/* Response: RDR_to_PC_DataBlock */
111
112/* Section 6.1.5 */
113struct ccid_pc_to_rdr_get_parameters {
114 struct ccid_header hdr;
115 uint8_t abRFU[3];
116} __attribute__ ((packed));
117/* Response: RDR_to_PC_Parameters */
118
119/* Section 6.1.6 */
120struct ccid_pc_to_rdr_reset_parameters {
121 struct ccid_header hdr;
122 uint8_t abRFU[3];
123} __attribute__ ((packed));
124/* Response: RDR_to_PC_Parameters */
125
126/* Section 6.1.7 */
127struct ccid_proto_data_t0 {
128 uint8_t bmFindexDindex;
129 uint8_t bmTCCKST0;
130 uint8_t bGuardTimeT0;
131 uint8_t bWaitingIntegerT0;
132 uint8_t bClockStop;
133} __attribute__ ((packed));
134struct ccid_proto_data_t1 {
135 uint8_t bmFindexDindex;
136 uint8_t bmTCCKST1;
137 uint8_t bGuardTimeT1;
138 uint8_t bWaitingIntegersT1;
139 uint8_t bClockStop;
140 uint8_t bFSC;
141 uint8_t bNadValue;
142} __attribute__ ((packed));
143struct ccid_pc_to_rdr_set_parameters {
144 struct ccid_header hdr;
145 uint8_t bProtocolNum;
146 uint8_t abRFU[2];
147 union {
148 struct ccid_proto_data_t0 t0;
149 struct ccid_proto_data_t1 t1;
150 } abProtocolData;
151} __attribute__ ((packed));
152/* Response: RDR_to_PC_Parameters */
153
154/* Section 6.1.8 */
155struct ccid_pc_to_rdr_escape {
156 struct ccid_header hdr;
157 uint8_t abRFU[3];
158 uint8_t abData[0];
159} __attribute__ ((packed));
160/* Response: RDR_to_PC_Escape */
161
162/* Section 6.1.9 */
163enum ccid_clock_command {
164 CCID_CLOCK_CMD_RESTART = 0x00,
165 CCID_CLOCK_CMD_STOP = 0x01,
166};
167struct ccid_pc_to_rdr_icc_clock {
168 struct ccid_header hdr;
169 uint8_t bClockCommand;
170 uint8_t abRFU[2];
171} __attribute__ ((packed));
172/* response: RDR_to_PC_SlotStatus */
173
174/* Section 6.1.10 */
175struct ccid_pc_to_rdr_t0apdu {
176 struct ccid_header hdr;
177 uint8_t bmChanges;
178 uint8_t bClassGetResponse;
179 uint8_t bClassEnvelope;
180} __attribute__ ((packed));
181/* Response: RDR_to_PC_SlotStatus */
182
183/* Section 6.1.11 */
184struct ccid_pc_to_rdr_secure {
185 struct ccid_header hdr;
186 uint8_t bBWI;
187 uint16_t wLevelParameter;
188 uint8_t abData[0];
189} __attribute__ ((packed));
190struct ccid_pin_operation_data {
191 uint8_t bPINOperation;
192 uint8_t abPNDataStructure[0];
193} __attribute__ ((packed));
194struct ccid_pin_verification_data {
195 uint8_t bTimeOut;
196 uint8_t bmFormatString;
197 uint8_t bmPINBlockString;
198 uint8_t bmPINLengthFormat;
199 uint16_t wPINMaxExtraDigit;
200 uint8_t bEntryValidationCondition;
201 uint8_t bNumberMessage;
202 uint16_t wLangId;
203 uint8_t bMsgIndex;
204 uint8_t bTecPrologue;
205 uint8_t abPINApdu[0];
206} __attribute__ ((packed));
207/* Response: RDR_to_PC_DataBlock */
208
209/* Section 6.1.12 */
210struct ccid_pc_to_rdr_mechanical {
211 struct ccid_header hdr;
212 uint8_t bFunction; /* ccid_mech_function */
213 uint8_t abRFU[2];
214} __attribute__ ((packed));
215enum ccid_mech_function {
216 CCID_MECH_FN_ACCEPT_CARD = 0x01,
217 CCID_MECH_FN_EJECT_CARD = 0x02,
218 CCID_MECH_FN_CAPTURE_CARD = 0x03,
219 CCID_MECH_FN_LOCK_CARD = 0x04,
220 CCID_MECH_FN_UNLOCK_CARD = 0x05,
221};
222/* Response: RDR_to_PC_SlotStatus */
223
224/* Section 6.1.13 */
225struct ccid_pc_to_rdr_abort {
226 struct ccid_header hdr;
227 uint8_t abRFU[3];
228} __attribute__ ((packed));
229/* Response: RDR_to_PC_SlotStatus */
230
231/* Section 6.1.14 */
232struct ccid_pc_to_rdr_set_rate_and_clock {
233 struct ccid_header hdr;
234 uint8_t abRFU[3];
235 uint32_t dwClockFrequency;
236 uint32_t dwDataRate;
237} __attribute__ ((packed));
238/* Response: RDR_to_PC_DataRateAndClockFrequency */
239
240union ccid_pc_to_rdr {
241 struct ccid_pc_to_rdr_icc_power_on icc_power_on;
242 struct ccid_pc_to_rdr_icc_power_off icc_power_off;
243 struct ccid_pc_to_rdr_get_slot_status get_slot_status;
244 struct ccid_pc_to_rdr_xfr_block xfr_block;
245 struct ccid_pc_to_rdr_get_parameters get_parameters;
246 struct ccid_pc_to_rdr_reset_parameters reset_parameters;
247 struct ccid_pc_to_rdr_set_parameters set_parameters;
248 struct ccid_pc_to_rdr_escape escape;
249 struct ccid_pc_to_rdr_icc_clock icc_clock;
250 struct ccid_pc_to_rdr_t0apdu t0apdu;
251 struct ccid_pc_to_rdr_secure secure;
252 struct ccid_pc_to_rdr_mechanical mechanical;
253 struct ccid_pc_to_rdr_abort abort;
254 struct ccid_pc_to_rdr_set_rate_and_clock set_rate_and_clock;
255};
256
257/***********************************************************************
258 * Bulk IN
259 ***********************************************************************/
260
261/* CCID message header on BULK-IN endpoint */
262struct ccid_header_in {
263 struct ccid_header hdr;
264 uint8_t bStatus;
265 uint8_t bError;
266} __attribute__ ((packed));
267
268/* Section 6.2.1 RDR_to_PC_DataBlock */
269struct ccid_rdr_to_pc_data_block {
270 struct ccid_header_in hdr;
271 uint8_t bChainParameter;
272 uint8_t abData[0];
273} __attribute__ ((packed));
274
275/* Section 6.2.2 RDR_to_PC_SlotStatus */
276struct ccid_rdr_to_pc_slot_status {
277 struct ccid_header_in hdr;
278 uint8_t bClockStatus;
279} __attribute__ ((packed));
280enum ccid_clock_status {
281 CCID_CLOCK_STATUS_RUNNING = 0x00,
282 CCID_CLOCK_STATUS_STOPPED_L = 0x01,
283 CCID_CLOCK_STATUS_STOPPED_H = 0x02,
284 CCID_CLOCK_STATUS_STOPPED_UNKN = 0x03,
285};
286
287/* Section 6.2.3 RDR_to_PC_Parameters */
288struct ccid_rdr_to_pc_parameters {
289 struct ccid_header_in hdr;
290 union {
291 struct ccid_proto_data_t0 t0;
292 struct ccid_proto_data_t1 t1;
293 } abProtocolData;
294} __attribute__ ((packed));
295
296/* Section 6.2.4 RDR_to_PC_Escape */
297struct ccid_rdr_to_pc_escape {
298 struct ccid_header hdr;
299 uint8_t bRFU;
300 uint8_t abData[0];
301} __attribute__ ((packed));
302
303/* Section 6.2.5 RDR_to_PC_DataRateAndClockFrequency */
304struct ccid_rdr_to_pc_data_rate_and_clock {
305 struct ccid_header hdr;
306 uint8_t bRFU;
307 uint32_t dwClockFrequency;
308 uint32_t dwDataRate;
309} __attribute__ ((packed));
310
311/* Section 6.2.6 */
312#define CCID_ICC_STATUS_MASK 0x03
313#define CCID_ICC_STATUS_PRES_ACT 0x00
314#define CCID_ICC_STATUS_PRES_INACT 0x01
315#define CCID_ICC_STATUS_NO_ICC 0x02
316#define CCID_CMD_STATUS_MASK 0xC0
317#define CCID_CMD_STATUS_OK 0x00
318#define CCID_CMD_STATUS_FAILED 0x40
319#define CCID_CMD_STATUS_TIME_EXT 0x80
320/* Table 6.2-2: Slot Error value when bmCommandStatus == 1 */
321enum ccid_error_code {
322 CCID_ERR_CMD_ABORTED = 0xff,
323 CCID_ERR_ICC_MUTE = 0xfe,
324 CCID_ERR_XFR_PARITY_ERROR = 0xfd,
325 CCID_ERR_XFR_OVERRUN = 0xfc,
326 CCID_ERR_HW_ERROR = 0xfb,
327 CCID_ERR_BAD_ATR_TS = 0xf8,
328 CCID_ERR_BAD_ATR_TCK = 0xf7,
329 CCID_ERR_ICC_PROTOCOL_NOT_SUPPORTED = 0xf6,
330 CCID_ERR_ICC_CLASS_NOT_SUPPORTED = 0xf5,
331 CCID_ERR_PROCEDURE_BYTE_CONFLICT = 0xf4,
332 CCID_ERR_DEACTIVATED_PROTOCOL = 0xf3,
333 CCID_ERR_BUSY_WITH_AUTO_SEQUENCE = 0xf2,
334 CCID_ERR_PIN_TIMEOUT = 0xf0,
335 CCID_ERR_PIN_CANCELLED = 0xef,
336 CCID_ERR_CMD_SLOT_BUSY = 0xe0,
337 CCID_ERR_CMD_NOT_SUPPORTED = 0x00
338};
339
340union ccid_rdr_to_pc {
341 struct ccid_rdr_to_pc_data_block data_block;
342 struct ccid_rdr_to_pc_slot_status slot_status;
343 struct ccid_rdr_to_pc_parameters parameters;
344 struct ccid_rdr_to_pc_escape escape;
345 struct ccid_rdr_to_pc_data_rate_and_clock rate_and_clock;
346};
347
348/***********************************************************************
349 * Interupt IN
350 ***********************************************************************/
351
352/* Section 6.3.1 */
353struct ccid_rdr_to_pc_notify_slot_change {
354 uint8_t bMessageType;
355 uint8_t bmSlotCCState[0]; /* as long as bNumSlots/4 padded to next byte */
356} __attribute__ ((packed));
357
358/* Section 6.3.1 */
359struct ccid_rdr_to_pc_hardware_error {
360 struct ccid_header hdr;
361 uint8_t bHardwareErrorCode;
362} __attribute__ ((packed));
363
364union ccid_rdr_to_pc_irq {
365 struct ccid_rdr_to_pc_notify_slot_change slot_change;
366 struct ccid_rdr_to_pc_hardware_error hw_error;
367};