blob: 470416c82798e815acbd292b96121c083df38255 [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
Harald Welteeb93f632019-05-11 20:08:09 +020069/* CCID Class-Specific Control Request (Section 5.3 / Table 5.3-1) */
70enum ccid_class_spec_req {
71 CLASS_SPEC_CCID_ABORT = 0x01,
72 CLASS_SPEC_CCID_GET_CLOCK_FREQ = 0x02,
73 CLASS_SPEC_CCID_GET_DATA_RATES = 0x03
74};
75
Harald Welte63653742019-01-03 16:54:16 +010076/***********************************************************************
77 * Bulk OUT
78 ***********************************************************************/
79
80/* Section 6.1.1 */
81enum ccid_power_select {
82 CCID_PWRSEL_AUTO = 0x00,
83 CCID_PWRSEL_5V0 = 0x01,
84 CCID_PWRSEL_3V0 = 0x02,
85 CCID_PWRSEL_1V8 = 0x03,
86};
87
88/* Section 6.1.1 */
89struct ccid_pc_to_rdr_icc_power_on {
90 struct ccid_header hdr;
91 uint8_t bPowerSelect;
92 uint8_t abRFU[2];
93} __attribute__ ((packed));
94/* Response: RDR_to_PC_DataBlock */
95
96/* Section 6.1.2 */
97struct ccid_pc_to_rdr_icc_power_off {
98 struct ccid_header hdr;
99 uint8_t abRFU[3];
100} __attribute__ ((packed));
101/* Response: RDR_to_PC_SlotStatus */
102
103/* Section 6.1.3 */
104struct ccid_pc_to_rdr_get_slot_status {
105 struct ccid_header hdr;
106 uint8_t abRFU[3];
107} __attribute__ ((packed));
108/* Response: RDR_to_PC_SlotStatus */
109
110/* Section 6.1.4 */
111struct ccid_pc_to_rdr_xfr_block {
112 struct ccid_header hdr;
113 uint8_t bBWI;
114 uint16_t wLevelParameter;
115 uint8_t abData[0];
116} __attribute__ ((packed));
117/* Response: RDR_to_PC_DataBlock */
118
119/* Section 6.1.5 */
120struct ccid_pc_to_rdr_get_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.6 */
127struct ccid_pc_to_rdr_reset_parameters {
128 struct ccid_header hdr;
129 uint8_t abRFU[3];
130} __attribute__ ((packed));
131/* Response: RDR_to_PC_Parameters */
132
133/* Section 6.1.7 */
134struct ccid_proto_data_t0 {
135 uint8_t bmFindexDindex;
136 uint8_t bmTCCKST0;
137 uint8_t bGuardTimeT0;
138 uint8_t bWaitingIntegerT0;
139 uint8_t bClockStop;
140} __attribute__ ((packed));
141struct ccid_proto_data_t1 {
142 uint8_t bmFindexDindex;
143 uint8_t bmTCCKST1;
144 uint8_t bGuardTimeT1;
145 uint8_t bWaitingIntegersT1;
146 uint8_t bClockStop;
147 uint8_t bFSC;
148 uint8_t bNadValue;
149} __attribute__ ((packed));
150struct ccid_pc_to_rdr_set_parameters {
151 struct ccid_header hdr;
152 uint8_t bProtocolNum;
153 uint8_t abRFU[2];
154 union {
155 struct ccid_proto_data_t0 t0;
156 struct ccid_proto_data_t1 t1;
157 } abProtocolData;
158} __attribute__ ((packed));
159/* Response: RDR_to_PC_Parameters */
160
161/* Section 6.1.8 */
162struct ccid_pc_to_rdr_escape {
163 struct ccid_header hdr;
164 uint8_t abRFU[3];
165 uint8_t abData[0];
166} __attribute__ ((packed));
167/* Response: RDR_to_PC_Escape */
168
169/* Section 6.1.9 */
170enum ccid_clock_command {
171 CCID_CLOCK_CMD_RESTART = 0x00,
172 CCID_CLOCK_CMD_STOP = 0x01,
173};
174struct ccid_pc_to_rdr_icc_clock {
175 struct ccid_header hdr;
176 uint8_t bClockCommand;
177 uint8_t abRFU[2];
178} __attribute__ ((packed));
179/* response: RDR_to_PC_SlotStatus */
180
181/* Section 6.1.10 */
182struct ccid_pc_to_rdr_t0apdu {
183 struct ccid_header hdr;
184 uint8_t bmChanges;
185 uint8_t bClassGetResponse;
186 uint8_t bClassEnvelope;
187} __attribute__ ((packed));
188/* Response: RDR_to_PC_SlotStatus */
189
190/* Section 6.1.11 */
191struct ccid_pc_to_rdr_secure {
192 struct ccid_header hdr;
193 uint8_t bBWI;
194 uint16_t wLevelParameter;
195 uint8_t abData[0];
196} __attribute__ ((packed));
197struct ccid_pin_operation_data {
198 uint8_t bPINOperation;
199 uint8_t abPNDataStructure[0];
200} __attribute__ ((packed));
201struct ccid_pin_verification_data {
202 uint8_t bTimeOut;
203 uint8_t bmFormatString;
204 uint8_t bmPINBlockString;
205 uint8_t bmPINLengthFormat;
206 uint16_t wPINMaxExtraDigit;
207 uint8_t bEntryValidationCondition;
208 uint8_t bNumberMessage;
209 uint16_t wLangId;
210 uint8_t bMsgIndex;
211 uint8_t bTecPrologue;
212 uint8_t abPINApdu[0];
213} __attribute__ ((packed));
214/* Response: RDR_to_PC_DataBlock */
215
216/* Section 6.1.12 */
217struct ccid_pc_to_rdr_mechanical {
218 struct ccid_header hdr;
219 uint8_t bFunction; /* ccid_mech_function */
220 uint8_t abRFU[2];
221} __attribute__ ((packed));
222enum ccid_mech_function {
223 CCID_MECH_FN_ACCEPT_CARD = 0x01,
224 CCID_MECH_FN_EJECT_CARD = 0x02,
225 CCID_MECH_FN_CAPTURE_CARD = 0x03,
226 CCID_MECH_FN_LOCK_CARD = 0x04,
227 CCID_MECH_FN_UNLOCK_CARD = 0x05,
228};
229/* Response: RDR_to_PC_SlotStatus */
230
231/* Section 6.1.13 */
232struct ccid_pc_to_rdr_abort {
233 struct ccid_header hdr;
234 uint8_t abRFU[3];
235} __attribute__ ((packed));
236/* Response: RDR_to_PC_SlotStatus */
237
238/* Section 6.1.14 */
239struct ccid_pc_to_rdr_set_rate_and_clock {
240 struct ccid_header hdr;
241 uint8_t abRFU[3];
242 uint32_t dwClockFrequency;
243 uint32_t dwDataRate;
244} __attribute__ ((packed));
245/* Response: RDR_to_PC_DataRateAndClockFrequency */
246
247union ccid_pc_to_rdr {
248 struct ccid_pc_to_rdr_icc_power_on icc_power_on;
249 struct ccid_pc_to_rdr_icc_power_off icc_power_off;
250 struct ccid_pc_to_rdr_get_slot_status get_slot_status;
251 struct ccid_pc_to_rdr_xfr_block xfr_block;
252 struct ccid_pc_to_rdr_get_parameters get_parameters;
253 struct ccid_pc_to_rdr_reset_parameters reset_parameters;
254 struct ccid_pc_to_rdr_set_parameters set_parameters;
255 struct ccid_pc_to_rdr_escape escape;
256 struct ccid_pc_to_rdr_icc_clock icc_clock;
257 struct ccid_pc_to_rdr_t0apdu t0apdu;
258 struct ccid_pc_to_rdr_secure secure;
259 struct ccid_pc_to_rdr_mechanical mechanical;
260 struct ccid_pc_to_rdr_abort abort;
261 struct ccid_pc_to_rdr_set_rate_and_clock set_rate_and_clock;
262};
263
264/***********************************************************************
265 * Bulk IN
266 ***********************************************************************/
267
268/* CCID message header on BULK-IN endpoint */
269struct ccid_header_in {
270 struct ccid_header hdr;
271 uint8_t bStatus;
272 uint8_t bError;
273} __attribute__ ((packed));
274
275/* Section 6.2.1 RDR_to_PC_DataBlock */
276struct ccid_rdr_to_pc_data_block {
277 struct ccid_header_in hdr;
278 uint8_t bChainParameter;
279 uint8_t abData[0];
280} __attribute__ ((packed));
281
282/* Section 6.2.2 RDR_to_PC_SlotStatus */
283struct ccid_rdr_to_pc_slot_status {
284 struct ccid_header_in hdr;
285 uint8_t bClockStatus;
286} __attribute__ ((packed));
287enum ccid_clock_status {
288 CCID_CLOCK_STATUS_RUNNING = 0x00,
289 CCID_CLOCK_STATUS_STOPPED_L = 0x01,
290 CCID_CLOCK_STATUS_STOPPED_H = 0x02,
291 CCID_CLOCK_STATUS_STOPPED_UNKN = 0x03,
292};
293
294/* Section 6.2.3 RDR_to_PC_Parameters */
295struct ccid_rdr_to_pc_parameters {
296 struct ccid_header_in hdr;
297 union {
298 struct ccid_proto_data_t0 t0;
299 struct ccid_proto_data_t1 t1;
300 } abProtocolData;
301} __attribute__ ((packed));
302
303/* Section 6.2.4 RDR_to_PC_Escape */
304struct ccid_rdr_to_pc_escape {
305 struct ccid_header hdr;
306 uint8_t bRFU;
307 uint8_t abData[0];
308} __attribute__ ((packed));
309
310/* Section 6.2.5 RDR_to_PC_DataRateAndClockFrequency */
311struct ccid_rdr_to_pc_data_rate_and_clock {
312 struct ccid_header hdr;
313 uint8_t bRFU;
314 uint32_t dwClockFrequency;
315 uint32_t dwDataRate;
316} __attribute__ ((packed));
317
318/* Section 6.2.6 */
319#define CCID_ICC_STATUS_MASK 0x03
320#define CCID_ICC_STATUS_PRES_ACT 0x00
321#define CCID_ICC_STATUS_PRES_INACT 0x01
322#define CCID_ICC_STATUS_NO_ICC 0x02
323#define CCID_CMD_STATUS_MASK 0xC0
324#define CCID_CMD_STATUS_OK 0x00
325#define CCID_CMD_STATUS_FAILED 0x40
326#define CCID_CMD_STATUS_TIME_EXT 0x80
327/* Table 6.2-2: Slot Error value when bmCommandStatus == 1 */
328enum ccid_error_code {
329 CCID_ERR_CMD_ABORTED = 0xff,
330 CCID_ERR_ICC_MUTE = 0xfe,
331 CCID_ERR_XFR_PARITY_ERROR = 0xfd,
332 CCID_ERR_XFR_OVERRUN = 0xfc,
333 CCID_ERR_HW_ERROR = 0xfb,
334 CCID_ERR_BAD_ATR_TS = 0xf8,
335 CCID_ERR_BAD_ATR_TCK = 0xf7,
336 CCID_ERR_ICC_PROTOCOL_NOT_SUPPORTED = 0xf6,
337 CCID_ERR_ICC_CLASS_NOT_SUPPORTED = 0xf5,
338 CCID_ERR_PROCEDURE_BYTE_CONFLICT = 0xf4,
339 CCID_ERR_DEACTIVATED_PROTOCOL = 0xf3,
340 CCID_ERR_BUSY_WITH_AUTO_SEQUENCE = 0xf2,
341 CCID_ERR_PIN_TIMEOUT = 0xf0,
342 CCID_ERR_PIN_CANCELLED = 0xef,
343 CCID_ERR_CMD_SLOT_BUSY = 0xe0,
344 CCID_ERR_CMD_NOT_SUPPORTED = 0x00
345};
346
347union ccid_rdr_to_pc {
348 struct ccid_rdr_to_pc_data_block data_block;
349 struct ccid_rdr_to_pc_slot_status slot_status;
350 struct ccid_rdr_to_pc_parameters parameters;
351 struct ccid_rdr_to_pc_escape escape;
352 struct ccid_rdr_to_pc_data_rate_and_clock rate_and_clock;
353};
354
355/***********************************************************************
356 * Interupt IN
357 ***********************************************************************/
358
359/* Section 6.3.1 */
360struct ccid_rdr_to_pc_notify_slot_change {
361 uint8_t bMessageType;
362 uint8_t bmSlotCCState[0]; /* as long as bNumSlots/4 padded to next byte */
363} __attribute__ ((packed));
364
365/* Section 6.3.1 */
366struct ccid_rdr_to_pc_hardware_error {
367 struct ccid_header hdr;
368 uint8_t bHardwareErrorCode;
369} __attribute__ ((packed));
370
371union ccid_rdr_to_pc_irq {
372 struct ccid_rdr_to_pc_notify_slot_change slot_change;
373 struct ccid_rdr_to_pc_hardware_error hw_error;
374};