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