1 /*
2 * driver for some CCID-compliant devices
3 *
4 * Copyright 2003, Chaskiel Grundman <cg2v@andrew.cmu.edu>
5 *
6 * 2005-04-20: Harald Welte <laforge@gnumonks.org>
7 * Add support for PCMCIA based CCID Device (CardMan 4040)
8 *
9 * 2005-05-22: Harald Welte <laforge@gnumonks.org>
10 * Add suport for OmniKey Cardman 5121 RFID extensions
11 */
12
13 #include "internal.h"
14 #include "usb-descriptors.h"
15 #include "atr.h"
16 #include <stdlib.h>
17 #include <string.h>
18 #include <sys/stat.h>
19 #include <unistd.h>
20
21 #define CCID_ERR_ABORTED 0xFF /* CMD ABORTED */
22 #define CCID_ERR_ICC_MUTE 0xFE
23 #define CCID_ERR_XFR_PARITY 0xFD /* XFR PARITY ERROR */
24 #define CCID_ERR_OVERRUN 0xFC /* XFR OVERRUN */
25 #define CCID_ERR_HW_ERROR 0xFB
26 #define CCID_ERR_BAD_ATR_TS 0xF8
27 #define CCID_ERR_BAD_ATR_TCK 0xF7
28 #define CCID_ERR_PROT_NOSUP 0xF6 /* ICC PROTOCOL NOT SUPPORTED */
29 #define CCID_ERR_CLASS_NOSUP 0xF5 /* ICC CLASS NOT SUPPORTED */
30 #define CCID_ERR_BAD_PROC_BYTE 0xF4 /* PROCEDURE BYTE CONFLICT */
31 #define CCID_ERR_XXX 0xF3 /* DEACTIVATED PROTOCOL (?) */
32 #define CCID_ERR_BUSY_AUTO_SEQ 0xF2 /* BUSY WITH AUTO SEQUENCE */
33 #define CCID_ERR_PIN_TIMEOUT 0xF0
34 #define CCID_ERR_PIN_CANCELED 0xEF
35 #define CCID_ERR_SLOT_BUSY 0xE0 /* CMD SLOT BUSY */
36
37 #define CCID_OFFSET_MSGTYPE 0
38 #define CCID_OFFSET_LENGTH 1
39 #define CCID_OFFSET_SLOT 5
40 #define CCID_OFFSET_SEQ 6
41
42 #define CCID_REQ_ABORT 1
43 #define CCID_REQ_GETCLOCKRATE 2
44 #define CCID_REQ_GETDATARATE 3
45
46 #define CCID_CMD_FIRST 0x60
47
48 #define CCID_CMD_ICCPOWERON 0x62
49 #define CCID_CMD_ICCPOWEROFF 0x63
50 #define CCID_CMD_GETSLOTSTAT 0x65
51 #define CCID_CMD_XFRBLOCK 0x6F
52 #define CCID_CMD_GETPARAMS 0x6C
53 #define CCID_CMD_RESETPARAMS 0x6D
54 #define CCID_CMD_SETPARAMS 0x61
55 #define CCID_CMD_ESCAPE 0x6B
56 #define CCID_CMD_ICCCLOCK 0x6E
57 #define CCID_CMD_T0APDU 0x6A
58 #define CCID_CMD_SECURE 0x69
59 #define CCID_CMD_MECHANICAL 0x71
60 #define CCID_CMD_ABORT 0x72
61 #define CCID_CMD_SET_DR_FREQ 0x73
62
63 #define CCID_RESP_DATA 0x80
64 #define CCID_RESP_SLOTSTAT 0x81
65 #define CCID_RESP_PARAMS 0x82
66 #define CCID_RESP_ESCAPE 0x83
67 #define CCID_RESP_DR_FREQ 0x84
68
69 /* maximum sensical size:
70 * 10 bytes ccid header + 4 bytes command header +
71 * 1 byte Lc + 255 bytes data + 1 byte Le = 271
72 */
73 #define CCID_MAX_MSG_LEN 271
74
75 static int msg_expected[] = {
76 0,
77 CCID_RESP_PARAMS,
78 CCID_RESP_DATA,
79 CCID_RESP_SLOTSTAT,
80 0,
81 CCID_RESP_SLOTSTAT,
82 0, 0, 0,
83 CCID_RESP_DATA,
84 CCID_RESP_SLOTSTAT,
85 CCID_RESP_ESCAPE,
86 CCID_RESP_PARAMS,
87 CCID_RESP_PARAMS,
88 CCID_RESP_SLOTSTAT,
89 CCID_RESP_DATA,
90 0,
91 CCID_RESP_SLOTSTAT,
92 CCID_RESP_SLOTSTAT,
93 CCID_RESP_DR_FREQ
94 };
95
96 enum {
97 TYPE_APDU,
98 TYPE_TPDU,
99 TYPE_CHAR
100 };
101
102 /* Some "ccid" devices have non-compliant descriptors. (perhaps their
103 design predates the approval of the standard?)
104 Attempt to recognize them anyway.
105 */
106 static struct force_parse_device_st {
107 unsigned short vendor;
108 unsigned short product;
109 } force_parse_devices[] = {
110 {
111 0x04e6, 0xe003}, /* SCM SPR 532 */
112 {
113 0x046a, 0x003e}, /* Cherry SmartTerminal ST-2XXX */
114 {
115 0x413c, 0x2100}, /* Dell USB Smartcard Keyboard */
116 {
117 0x04e6, 0x5120}, /* SCM SCR331-DI (NTT) */
118 {
119 0x04e6, 0x5111}, /* SCM SCR331-DI */
120 {
121 0x08e6, 0x1359}, /* Verisign secure storage token */
122 {
123 0x08e6, 0xACE0}, /* Verisign secure token */
124 {
125 0, 0}
126 };
127
128 #define SUPPORT_T0 0x1
129 #define SUPPORT_T1 0x2
130 #define SUPPORT_ESCAPE 0x80
131
132 #define SUPPORT_50V 1
133 #define SUPPORT_33V 2
134 #define SUPPORT_18V 4
135 #define AUTO_VOLTAGE 0x80
136
137 #define FLAG_NO_PTS 1
138 #define FLAG_NO_SETPARAM 2
139 #define FLAG_AUTO_ACTIVATE 4
140 #define FLAG_AUTO_ATRPARSE 8
141
142 #define USB_CCID_DESCRIPTOR_LENGTH 54
143 struct usb_ccid_descriptor {
144 uint8_t bLength;
145 uint8_t bDescriptorType;
146 uint16_t bcdCCID;
147 uint8_t bMaxSlotIndex;
148 uint8_t bVoltageSupport;
149 uint32_t dwProtocols;
150 uint32_t dwDefaultClock;
151 uint32_t dwMaximumClock;
152 uint8_t bNumClockRatesSupported;
153 uint32_t dwDataRate;
154 uint32_t dwMaxDataRate;
155 uint8_t bNumDataRatesSupported;
156 uint32_t dwMaxIFSD;
157 uint32_t dwSynchProtocols;
158 uint32_t dwMechanical;
159 uint32_t dwFeatures;
160 uint32_t dwMaxCCIDMessageLength;
161 uint8_t bClassGetResponse;
162 uint8_t bClassEnvelope;
163 uint16_t wLcdLayout;
164 uint8_t bPINSupport;
165 uint8_t bMaxCCIDBusySlots;
166 };
167
ccid_parse_descriptor(struct usb_ccid_descriptor * ret,unsigned char * in,size_t inlen)168 static int ccid_parse_descriptor(struct usb_ccid_descriptor *ret,
169 unsigned char *in, size_t inlen)
170 {
171 if (inlen < USB_CCID_DESCRIPTOR_LENGTH)
172 return 1;
173
174 ret->bLength = in[0];
175 if (ret->bLength < USB_CCID_DESCRIPTOR_LENGTH)
176 return 1;
177 ret->bDescriptorType = in[1];
178 ret->bcdCCID = in[3] << 8 | in[2];
179 ret->bMaxSlotIndex = in[4];
180 ret->bVoltageSupport = in[5];
181 ret->dwProtocols = in[9] << 24 | in[8] << 16 | in[7] << 8 | in[6];
182 ret->dwDefaultClock =
183 in[13] << 24 | in[12] << 16 | in[11] << 8 | in[10];
184 ret->dwMaximumClock =
185 in[17] << 24 | in[16] << 16 | in[15] << 8 | in[14];
186 ret->bNumClockRatesSupported = in[18];
187 ret->dwDataRate = in[22] << 24 | in[21] << 16 | in[20] << 8 | in[19];
188 ret->dwMaxDataRate = in[26] << 24 | in[25] << 16 | in[24] << 8 | in[23];
189 ret->bNumDataRatesSupported = in[27];
190 ret->dwMaxIFSD = in[31] << 24 | in[30] << 16 | in[29] << 8 | in[28];
191 ret->dwSynchProtocols =
192 in[35] << 24 | in[34] << 16 | in[33] << 8 | in[32];
193 ret->dwMechanical = in[39] << 24 | in[38] << 16 | in[37] << 8 | in[36];
194 ret->dwFeatures = in[43] << 24 | in[42] << 16 | in[41] << 8 | in[40];
195 ret->dwMaxCCIDMessageLength = in[47] << 24 | in[46] << 16 |
196 in[45] << 8 | in[44];
197 ret->bClassGetResponse = in[48];
198 ret->bClassEnvelope = in[49];
199 ret->wLcdLayout = in[51] << 8 | in[50];
200 ret->bPINSupport = in[52];
201 ret->bMaxCCIDBusySlots = in[53];
202
203 return 0;
204 }
205
206 /*
207 * CT status
208 */
209 typedef struct ccid_status {
210 int reader_type;
211 int usb_interface;
212 int proto_support;
213 int voltage_support;
214 int ifsd;
215 int maxmsg;
216 int flags;
217 unsigned char icc_present[OPENCT_MAX_SLOTS];
218 unsigned char icc_proto[OPENCT_MAX_SLOTS];
219 unsigned char *sbuf[OPENCT_MAX_SLOTS];
220 size_t slen[OPENCT_MAX_SLOTS];
221 unsigned char seq;
222 int support_events;
223 int events_active;
224 ifd_usb_capture_t *event_cap;
225 } ccid_status_t;
226
ccid_checkresponse(void * status,int r)227 static int ccid_checkresponse(void *status, int r)
228 {
229 unsigned char *p = (unsigned char *)status;
230
231 if ((p[7] >> 6 & 3) == 0)
232 return 0;
233
234 /* XXX */
235 if ((p[7] >> 6 & 3) == 2) {
236 /*ct_error("card requests more time"); */
237 return -300;
238 }
239
240 switch (p[8]) {
241 case CCID_ERR_ICC_MUTE:
242 return IFD_ERROR_NO_CARD;
243 case CCID_ERR_XFR_PARITY:
244 case CCID_ERR_OVERRUN:
245 return IFD_ERROR_COMM_ERROR;
246 case CCID_ERR_BAD_ATR_TS:
247 case CCID_ERR_BAD_ATR_TCK:
248 return IFD_ERROR_NO_ATR;
249 case CCID_ERR_PROT_NOSUP:
250 case CCID_ERR_CLASS_NOSUP:
251 return IFD_ERROR_INCOMPATIBLE_DEVICE;
252 case CCID_ERR_BAD_PROC_BYTE:
253 return IFD_ERROR_INVALID_ARG;
254 case CCID_ERR_BUSY_AUTO_SEQ:
255 case CCID_ERR_SLOT_BUSY:
256 return IFD_ERROR_TIMEOUT;
257 case CCID_ERR_PIN_TIMEOUT:
258 return IFD_ERROR_USER_TIMEOUT;
259 case CCID_ERR_PIN_CANCELED:
260 return IFD_ERROR_USER_ABORT;
261 case CCID_OFFSET_MSGTYPE:
262 return IFD_ERROR_NOT_SUPPORTED;
263 case CCID_OFFSET_SLOT:
264 return IFD_ERROR_INVALID_SLOT;
265 }
266 return IFD_ERROR_GENERIC;
267 }
268
ccid_prepare_cmd(ifd_reader_t * reader,unsigned char * out,size_t outsz,int slot,unsigned char cmd,const void * ctl,const void * snd,size_t sendlen)269 static int ccid_prepare_cmd(ifd_reader_t * reader, unsigned char *out,
270 size_t outsz, int slot, unsigned char cmd,
271 const void *ctl, const void *snd, size_t sendlen)
272 {
273 ccid_status_t *st = (ccid_status_t *) reader->driver_data;
274 unsigned char *p = out;
275
276 if (slot >= reader->nslots)
277 return IFD_ERROR_INVALID_SLOT;
278 if (sendlen + 10 > outsz) /* this probably means the apdu is larger
279 than the supported MaxMessageSize - 10 */
280 return IFD_ERROR_NOT_SUPPORTED;
281 *p++ = cmd;
282 *p++ = sendlen & 0xFF;
283 *p++ = (sendlen >> 8) & 0xFF;
284 *p++ = (sendlen >> 16) & 0xFF;
285 *p++ = (sendlen >> 24) & 0xFF;
286 *p++ = slot;
287 *p++ = st->seq++;
288 if (ctl)
289 memcpy(p, (unsigned char *)ctl, 3);
290 else
291 memset(p, 0, 3);
292
293 if (sendlen)
294 memcpy(&p[3], (unsigned char *)snd, sendlen);
295 return sendlen + 10;
296 }
297
ccid_extract_data(const void * in,size_t inlen,void * out,size_t outlen)298 static int ccid_extract_data(const void *in, size_t inlen, void *out,
299 size_t outlen)
300 {
301 unsigned char dlen[4];
302 size_t len;
303
304 if (inlen < 5) {
305 ct_error("short response from reader?!");
306 return IFD_ERROR_BUFFER_TOO_SMALL;
307 }
308
309 memcpy(dlen, ((char *)in) + 1, 4);
310 len = dlen[0] | dlen[1] << 8 | dlen[2] << 16 | dlen[3] << 24;
311 if (len == 0)
312 return 0;
313 if (inlen < len + 10) {
314 ct_error("truncated response from reader");
315 return IFD_ERROR_BUFFER_TOO_SMALL;
316 }
317 if (outlen < len) {
318 ct_error("user buffer too small (%d < %d)", outlen, len);
319 return IFD_ERROR_BUFFER_TOO_SMALL;
320 }
321 memcpy(out, ((char *)in) + 10, len);
322 return len;
323 }
324
ccid_command(ifd_reader_t * reader,const unsigned char * cmd,size_t cmd_len,unsigned char * res,size_t res_len)325 static int ccid_command(ifd_reader_t * reader, const unsigned char *cmd,
326 size_t cmd_len, unsigned char *res, size_t res_len)
327 {
328 int rc;
329 size_t req_len;
330
331 if (!cmd_len || !res_len) {
332 ct_error("missing parameters to ccid_command");
333 return IFD_ERROR_INVALID_ARG;
334 }
335 req_len = res_len;
336 if (ct_config.debug >= 3)
337 ifd_debug(3, "sending:%s", ct_hexdump(cmd, cmd_len));
338
339 rc = ifd_device_send(reader->device, cmd, cmd_len);
340 if (rc < 0) {
341 ifd_debug(1, "ifd_device_send failed %d", rc);
342 return rc;
343 }
344 while (1) {
345 rc = ifd_device_recv(reader->device, res, req_len, 10000);
346 if (rc < 0)
347 return rc;
348 if (rc == 0) {
349 ct_error("zero length response from reader?!");
350 return IFD_ERROR_GENERIC;
351 }
352 if (ct_config.debug >= 3)
353 ifd_debug(3, "received:%s", ct_hexdump(res, rc));
354
355 if (rc < 9) {
356 return IFD_ERROR_GENERIC;
357 }
358 if (cmd[CCID_OFFSET_SLOT] == res[CCID_OFFSET_SLOT] &&
359 cmd[CCID_OFFSET_SEQ] == res[CCID_OFFSET_SEQ]) {
360 res_len = rc;
361 rc = ccid_checkresponse(res, res_len);
362 if (rc == -300) {
363 continue;
364 }
365 if (rc < 0)
366 return rc;
367 break;
368 }
369
370 }
371 return res_len;
372 }
373
ccid_simple_rcommand(ifd_reader_t * reader,int slot,int cmd,void * ctl,void * res,size_t res_len)374 static int ccid_simple_rcommand(ifd_reader_t * reader, int slot, int cmd,
375 void *ctl, void *res, size_t res_len)
376 {
377 ccid_status_t *st = reader->driver_data;
378 unsigned char cmdbuf[10];
379 unsigned char resbuf[CCID_MAX_MSG_LEN + 1];
380 int r;
381
382 r = ccid_prepare_cmd(reader, cmdbuf, 10, slot, cmd, ctl, NULL, 0);
383 if (r < 0)
384 return r;
385
386 r = ccid_command(reader, cmdbuf, 10, resbuf, st->maxmsg);
387 if (r < 0)
388 return r;
389 if (resbuf[0] != msg_expected[cmd - CCID_CMD_FIRST]) {
390 ct_error("Received a message of type x%02x instead of x%02x",
391 resbuf[0], msg_expected[cmd - CCID_CMD_FIRST]);
392 return -1;
393 }
394
395 if (res_len)
396 r = ccid_extract_data(&resbuf, r, res, res_len);
397 return r;
398 }
399
ccid_simple_wcommand(ifd_reader_t * reader,int slot,int cmd,void * ctl,void * data,size_t data_len)400 static int ccid_simple_wcommand(ifd_reader_t * reader, int slot, int cmd,
401 void *ctl, void *data, size_t data_len)
402 {
403 ccid_status_t *st = reader->driver_data;
404 unsigned char cmdbuf[CCID_MAX_MSG_LEN + 1];
405 unsigned char resbuf[CCID_MAX_MSG_LEN + 1];
406 int r;
407
408 r = ccid_prepare_cmd(reader, cmdbuf, st->maxmsg, slot, cmd, ctl, data,
409 data_len);
410 if (r < 0)
411 return r;
412
413 r = ccid_command(reader, cmdbuf, r, resbuf, st->maxmsg);
414 if (r < 0)
415 return r;
416 if (resbuf[0] != msg_expected[cmd - CCID_CMD_FIRST]) {
417 ct_error("Received a message of type x%02x instead of x%02x",
418 resbuf[0], msg_expected[cmd - CCID_CMD_FIRST]);
419 return -1;
420 }
421
422 return r;
423 }
424
425 #ifdef notyet
ccid_abort(ifd_reader_t * reader,int slot)426 static int ccid_abort(ifd_reader_t * reader, int slot)
427 {
428 ccid_status_t *st = (ccid_status_t *) reader->driver_data;
429
430 int r;
431 if (ifd_device_type(reader->device) == IFD_DEVICE_TYPE_USB) {
432 r = ifd_usb_control(reader->device, 0x21
433 /*USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE */
434 ,
435 CCID_REQ_ABORT, st->seq << 8 | slot,
436 st->usb_interface, NULL, 0, 10000);
437 if (r < 0)
438 return r;
439 r = ccid_simple_wcommand(reader, slot, CCID_CMD_ABORT, NULL,
440 NULL, 0);
441 return r;
442 } else
443 if (ifd_device_type(reader->device == IFD_DEVICE_TYPE_PCMCIA_BLOCK))
444 {
445 /* FIXME */
446 return IFD_ERROR_NOT_SUPPORTED;
447 }
448 return IFD_ERROR_NOT_SUPPORTED;
449 }
450 #endif
451
ccid_exchange(ifd_reader_t * reader,int slot,const void * sbuf,size_t slen,void * rbuf,size_t rlen)452 static int ccid_exchange(ifd_reader_t * reader, int slot,
453 const void *sbuf, size_t slen, void *rbuf, size_t rlen)
454 {
455 ccid_status_t *st = reader->driver_data;
456 unsigned char sendbuf[CCID_MAX_MSG_LEN + 1];
457 unsigned char recvbuf[CCID_MAX_MSG_LEN + 1];
458 int r;
459 unsigned char ctlbuf[3], *ctlptr=NULL;
460
461 ctlptr=NULL;
462 if (st->reader_type == TYPE_CHAR) {
463 ctlbuf[0] = 0;
464 ctlbuf[1] = rlen & 0xff;
465 ctlbuf[2] = (rlen >> 8) & 0xff;
466 ctlptr = ctlbuf;
467 }
468
469 r = ccid_prepare_cmd(reader, sendbuf, st->maxmsg,
470 slot, CCID_CMD_XFRBLOCK, ctlptr, sbuf, slen);
471 if (r < 0)
472 return r;
473
474 r = ccid_command(reader, &sendbuf[0], r, recvbuf, st->maxmsg);
475 if (r < 0)
476 return r;
477 return ccid_extract_data(&recvbuf, r, rbuf, rlen);
478 }
479
ccid_open_usb(ifd_device_t * dev,ifd_reader_t * reader)480 static int ccid_open_usb(ifd_device_t * dev, ifd_reader_t * reader)
481 {
482 ccid_status_t *st;
483 ifd_device_params_t params;
484 int r, i, c, ifc, alt, num_alt;
485 struct ifd_usb_device_descriptor de;
486 struct ifd_usb_config_descriptor conf;
487 struct ifd_usb_interface_descriptor *intf;
488 struct usb_ccid_descriptor ccid = { 0 };
489 int force_parse;
490 struct force_parse_device_st *force_dev;
491 unsigned char *_class;
492 unsigned char *p;
493 int support_events = 0;
494
495 #define PCSCLITE_FILE "/var/run/pcscd/pcscd.comm"
496 struct stat buf;
497
498 /* give priority to pcsc-lite for CCID devices */
499 if (0 == stat(PCSCLITE_FILE, &buf))
500 sleep(3);
501
502 if (ifd_usb_get_device(dev, &de)) {
503 ct_error("ccid: device descriptor not found");
504 ifd_device_close(dev);
505 return -1;
506 }
507
508 force_parse = 0;
509 for (force_dev = force_parse_devices; force_dev->vendor; force_dev++) {
510 if (de.idVendor == force_dev->vendor &&
511 de.idProduct == force_dev->product) {
512 force_parse = 1;
513 break;
514 }
515 }
516
517 intf = NULL;
518 p = NULL;
519 r = i = 0;
520 memset(&conf, 0, sizeof(conf));
521 for (c = 0; c < de.bNumConfigurations; c++) {
522 if (ifd_usb_get_config(dev, c, &conf)) {
523 ct_error("ccid: config descriptor %d not found", c);
524 continue;
525 }
526 if (!conf.interface)
527 continue;
528
529 for (ifc = 0; ifc < conf.bNumInterfaces; ifc++) {
530 num_alt = conf.interface[ifc].num_altsetting;
531 for (alt = 0; alt < num_alt; alt++) {
532 int typeok = 0;
533 int ok = 0;
534 intf = &conf.interface[ifc].altsetting[alt];
535 if (intf->bInterfaceClass == 0xb ||
536 intf->bInterfaceSubClass == 0 ||
537 intf->bInterfaceProtocol == 0)
538 typeok = 1;
539 /* accept class 0xFF if force_parse != 0 */
540 if (force_parse
541 && intf->bInterfaceClass == 0xff)
542 typeok = 1;
543 if (intf->bNumEndpoints < 2
544 || intf->bNumEndpoints > 3)
545 typeok = 0;
546 if (typeok == 0) {
547 intf = NULL;
548 continue;
549 }
550 if (intf->bNumEndpoints == 2) {
551 params.usb.ep_intr = 0;
552 ok |= 4;
553 }
554 if (intf->bNumEndpoints == 3) {
555 support_events = 1;
556 }
557 for (i = 0; i < intf->bNumEndpoints; i++) {
558 if (((intf->endpoint[i].bmAttributes &
559 IFD_USB_ENDPOINT_TYPE_MASK) ==
560 IFD_USB_ENDPOINT_TYPE_BULK) &&
561 (intf->endpoint[i].
562 bEndpointAddress &
563 IFD_USB_ENDPOINT_DIR_MASK) ==
564 IFD_USB_ENDPOINT_OUT) {
565 ok |= 1;
566 params.usb.ep_o =
567 intf->endpoint[i].
568 bEndpointAddress;
569 }
570 if (((intf->endpoint[i].bmAttributes &
571 IFD_USB_ENDPOINT_TYPE_MASK) ==
572 IFD_USB_ENDPOINT_TYPE_BULK) &&
573 (intf->endpoint[i].
574 bEndpointAddress &
575 IFD_USB_ENDPOINT_DIR_MASK) ==
576 IFD_USB_ENDPOINT_IN) {
577 ok |= 2;
578 params.usb.ep_i =
579 intf->endpoint[i].
580 bEndpointAddress;
581 }
582 if (((intf->endpoint[i].bmAttributes &
583 IFD_USB_ENDPOINT_TYPE_MASK) ==
584 IFD_USB_ENDPOINT_TYPE_INTERRUPT) &&
585 (intf->endpoint[i].
586 bEndpointAddress &
587 IFD_USB_ENDPOINT_DIR_MASK) ==
588 IFD_USB_ENDPOINT_IN) {
589 ok |= 4;
590 params.usb.ep_intr =
591 intf->endpoint[i].
592 bEndpointAddress;
593 }
594 }
595 if (ok == 7)
596 break;
597 intf = NULL;
598 }
599 if (!intf)
600 continue;
601 if (!intf->extralen) {
602 int i;
603 /* Buggy O2 Micro CCID SC Reader has zero extra len at interface level but not endpoint descriptor.
604 * Patch the interface level field and proceed.
605 * ProdID 7762 reader is in Dell Latitude D620 and 7772 is in D630.
606 */
607 if( de.idVendor == 0x0b97 && (de.idProduct == 0x7762 || de.idProduct == 0x7772) ) {
608 ct_error("ccid: extra len is zero, patching O2 Micro support");
609 for (i=0; i<intf->bNumEndpoints; i++) {
610 /* find the extra[] array */
611 if( intf->endpoint[i].extralen == 54 ) {
612 /* get the extra[] from the endpoint */
613 intf->extralen = 54;
614 /* avoid double free on close, allocate here */
615 intf->extra = malloc(54);
616 if( intf->extra ) {
617 memcpy( intf->extra, intf->endpoint[i].extra, 54 );
618 break;
619 }
620 else {
621 intf = NULL;
622 continue;
623 }
624 }
625 }
626 }
627 else {
628 intf = NULL;
629 ct_error("ccid: extra len is zero, continuing");
630 continue;
631 }
632 }
633
634 r = intf->extralen;
635 _class = intf->extra;
636 i = 0;
637 p = _class + i;
638 /* 0x21 == USB_TYPE_CLASS | 0x1 */
639 /* accept descriptor type 0xFF if force_parse != 0 */
640 while (i < r && p[0] > 2 &&
641 (p[1] != 0x21 &&
642 (force_parse == 0 || p[1] != 0xff))) {
643 i += p[0];
644 p = _class + i;
645 }
646 if (i >= r || p[0] < 2 ||
647 (p[1] != 0x21 &&
648 (force_parse == 0 || p[1] != 0xff))) {
649 intf = NULL;
650 }
651 if (intf)
652 break;
653 }
654 if (intf)
655 break;
656 ifd_usb_free_configuration(&conf);
657 }
658
659 if (!intf) {
660 ct_error("ccid: class descriptor not found");
661 ifd_device_close(dev);
662 return -1;
663 }
664
665 /* Don't touch the device configuration if it's the one and only.
666 * The reason for this is that in multi purpose devices (eg keyboards
667 * with an integrated reader) some interfaces might already be in use.
668 * Trying to change the device configuration in such a case will produce
669 * this kernel message on Linux:
670 * usbfs: interface X claimed while 'ifdhandler' sets config #N
671 * and often the call will fail with EBUSY.
672 * Actually a bit better fix could be implemented in usb_set_params.
673 * The code there should check if the device is already in the requested
674 * configuration and thus if the change is needed after all. However
675 * implementing this would need a bunch of new sysdep functions to
676 * determine the current device configuration.
677 * So IMHO we should postpone this hard work until some USB device
678 * surfaces that really needs such magic.
679 *
680 * Antti Andreimann <Antti.Andreimann@mail.ee> Thu Feb 2 2006
681 */
682 if (de.bNumConfigurations > 1)
683 params.usb.configuration = conf.bConfigurationValue;
684 else
685 params.usb.configuration = -1;
686
687 params.usb.interface = intf->bInterfaceNumber;
688 if (num_alt > 1 || intf->bAlternateSetting > 0)
689 params.usb.altsetting = intf->bAlternateSetting;
690 else
691 params.usb.altsetting = -1;
692
693 r = ccid_parse_descriptor(&ccid, p, r - i);
694 ifd_usb_free_configuration(&conf);
695 if (r) {
696 ct_error("ccid: class descriptor is invalid");
697 ifd_device_close(dev);
698 return -1;
699 }
700
701 if (ccid.bcdCCID != 0x100 && ccid.bcdCCID != 0x110) {
702 ct_error("ccid: unknown ccid version %02x.%02x supported only 1.00, 1.10",
703 (ccid.bcdCCID >> 8) & 0xff,
704 (ccid.bcdCCID >> 0) & 0xff
705 );
706 ifd_device_close(dev);
707 return -1;
708 }
709
710 if ((st = (ccid_status_t *) calloc(1, sizeof(*st))) == NULL) {
711 ct_error("out of memory");
712 return IFD_ERROR_NO_MEMORY;
713 }
714
715 st->usb_interface = intf->bInterfaceNumber;
716 memset(st->icc_present, -1, OPENCT_MAX_SLOTS);
717 st->voltage_support = ccid.bVoltageSupport & 0x7;
718 st->proto_support = ccid.dwProtocols;
719 if ((st->proto_support & 3) == 0) {
720 ct_error
721 ("ccid: device does not provide any supported protocols");
722 free(st);
723 ifd_device_close(dev);
724 return -1;
725 }
726
727 /* "When a CCID doesn't declare the values 00000010h and 00000020h, the
728 * frequency or the baud rate must be made via manufacturer proprietary
729 * PC_to_RDR_Escape command." - ccid class specification v1.00
730 *
731 * "The value of the lower word (=0840) indicates that the host will only
732 * send requests that are valid for the USB-ICC." - ISO/IEC 7816-12:2005
733 * 7.2/Table 8
734 */
735 if ((ccid.dwFeatures & 0xFFFF) != 0x0840
736 && ~ccid.dwFeatures & (0x10 | 0x20)) {
737 ct_error("ccid: required card initialization features missing");
738 free(st);
739 ifd_device_close(dev);
740 return -1;
741 }
742
743 st->reader_type = TYPE_CHAR;
744
745 if (ccid.dwFeatures & 0x10000) {
746 st->reader_type = TYPE_TPDU;
747 } else if (ccid.dwFeatures & 0x60000) {
748 st->reader_type = TYPE_APDU;
749 }
750 if (ccid.dwFeatures & 0x2)
751 st->flags |= FLAG_AUTO_ATRPARSE;
752 if (ccid.dwFeatures & 0x4)
753 st->flags |= FLAG_AUTO_ACTIVATE;
754 if (ccid.dwFeatures & 0x8)
755 st->voltage_support |= AUTO_VOLTAGE;
756 if (ccid.dwFeatures & 0x40)
757 st->flags |= FLAG_NO_PTS | FLAG_NO_SETPARAM;
758 if (ccid.dwFeatures & 0x80)
759 st->flags |= FLAG_NO_PTS;
760 st->ifsd = ccid.dwMaxIFSD;
761
762 /* must provide AUTO or at least one of 5/3.3/1.8 */
763 if (st->voltage_support == 0) {
764 ct_error
765 ("ccid: device does not provide any supported voltages");
766 free(st);
767 ifd_device_close(dev);
768 return -1;
769 }
770
771 if (ccid.dwMaxCCIDMessageLength > CCID_MAX_MSG_LEN) {
772 st->maxmsg = CCID_MAX_MSG_LEN;
773 } else {
774 st->maxmsg = ccid.dwMaxCCIDMessageLength;
775 }
776
777 reader->driver_data = st;
778 reader->device = dev;
779 reader->nslots = ccid.bMaxSlotIndex + 1;
780
781 if (ifd_device_set_parameters(dev, ¶ms) < 0) {
782 ifd_device_close(dev);
783 return -1;
784 }
785 if (de.idVendor == 0x08e6 && de.idProduct == 0x3437) {
786 unsigned char settpdu[] = { 0xA0, 0x1 };
787 unsigned char setiso[] = { 0x1F, 0x1 };
788 r = ccid_simple_wcommand(reader, 0, CCID_CMD_ESCAPE, NULL,
789 settpdu, 2);
790 if (r < 0) {
791 ct_error("ccid: cannot set GemPlus TPDU mode");
792 ifd_device_close(dev);
793 return -1;
794 }
795 r = ccid_simple_wcommand(reader, 0, CCID_CMD_ESCAPE, NULL,
796 setiso, 2);
797 if (r < 0) {
798 ct_error("ccid: cannot set GemPlus ISO APDU mode");
799 ifd_device_close(dev);
800 return -1;
801 }
802 st->reader_type = TYPE_TPDU;
803 }
804
805 if (de.idVendor == 0x076b && de.idProduct == 0x5121) {
806 /* special handling of RFID part of OmniKey 5121 */
807 reader->nslots++; /* one virtual slot for RFID escape */
808 st->proto_support |= SUPPORT_ESCAPE;
809 }
810
811 st->support_events = support_events;
812
813 ifd_debug(3, "Accepted %04x:%04x with features 0x%x and protocols 0x%x events=%d", de.idVendor, de.idProduct, ccid.dwFeatures, ccid.dwProtocols, st->support_events);
814 return 0;
815 }
816
ccid_open_pcmcia_block(ifd_device_t * dev,ifd_reader_t * reader)817 static int ccid_open_pcmcia_block(ifd_device_t * dev, ifd_reader_t * reader)
818 {
819 ccid_status_t *st;
820 /* unfortunately I know of no sanity checks that we could do with the
821 * hardware to confirm we're actually accessing a real pcmcia/ccid
822 * device -HW */
823
824 if ((st = (ccid_status_t *) calloc(1, sizeof(*st))) == NULL)
825 return IFD_ERROR_NO_MEMORY;
826
827 /* setup fake ccid_status_t based on totally guessed values */
828 memset(st->icc_present, -1, OPENCT_MAX_SLOTS);
829 st->voltage_support = 0x7;
830 st->proto_support = SUPPORT_T0 | SUPPORT_T1;
831 st->reader_type = TYPE_APDU;
832 st->voltage_support |= AUTO_VOLTAGE;
833 st->ifsd = 1; /* ? */
834 st->maxmsg = CCID_MAX_MSG_LEN;
835 st->flags = FLAG_AUTO_ATRPARSE | FLAG_NO_PTS; /*|FLAG_NO_SETPARAM; */
836
837 reader->driver_data = st;
838 reader->device = dev;
839 reader->nslots = 1;
840
841 return 0;
842 }
843
844 /*
845 * Initialize the device
846 */
ccid_open(ifd_reader_t * reader,const char * device_name)847 static int ccid_open(ifd_reader_t * reader, const char *device_name)
848 {
849 ifd_device_t *dev;
850 reader->name = "CCID Compatible";
851 if (!(dev = ifd_device_open(device_name)))
852 return -1;
853 if (ifd_device_type(dev) == IFD_DEVICE_TYPE_USB)
854 return ccid_open_usb(dev, reader);
855 else if (ifd_device_type(dev) == IFD_DEVICE_TYPE_PCMCIA_BLOCK)
856 return ccid_open_pcmcia_block(dev, reader);
857 else {
858 ct_error("ccid: device %s is not a supported device",
859 device_name);
860 ifd_device_close(dev);
861 return -1;
862 }
863 }
864
865 /*
866 * Close the device
867 */
ccid_close(ifd_reader_t * reader)868 static int ccid_close(ifd_reader_t * reader)
869 {
870 ccid_status_t *st = (ccid_status_t *) reader->driver_data;
871
872 ifd_debug(1, "called.");
873
874 if (st->event_cap != NULL) {
875 ifd_usb_end_capture(reader->device, st->event_cap);
876 st->event_cap = NULL;
877 }
878
879 return 0;
880 }
881
ccid_activate(ifd_reader_t * reader)882 static int ccid_activate(ifd_reader_t * reader)
883 {
884 ifd_debug(1, "called.");
885 return 0;
886 }
887
ccid_deactivate(ifd_reader_t * reader)888 static int ccid_deactivate(ifd_reader_t * reader)
889 {
890 ifd_debug(1, "called.");
891 return 0;
892 }
893
ccid_card_status(ifd_reader_t * reader,int slot,int * status)894 static int ccid_card_status(ifd_reader_t * reader, int slot, int *status)
895 {
896 ccid_status_t *st = (ccid_status_t *) reader->driver_data;
897 int r, stat;
898 unsigned char ret[20];
899 unsigned char cmdbuf[10];
900
901 if (ifd_device_type(reader->device) == IFD_DEVICE_TYPE_USB &&
902 reader->device->settings.usb.ep_intr) {
903 ifd_usb_capture_t *cap;
904 int any = 0;
905 int i, j, bits;
906
907 if (st->proto_support & SUPPORT_ESCAPE
908 && slot == reader->nslots - 1) {
909 ifd_debug(1,
910 "virtual escape slot, setting card present\n");
911 *status = IFD_CARD_PRESENT;
912 return 0;
913 }
914
915 i = 1 + (slot / 4);
916 j = 2 * (slot % 4);
917 stat = 0;
918
919 r = ifd_usb_begin_capture(reader->device,
920 IFD_USB_URB_TYPE_INTERRUPT,
921 reader->device->settings.usb.ep_intr,
922 8, &cap);
923 if (r < 0) {
924 ct_error("ccid: begin capture: %d", r);
925 return r;
926 }
927 /* read any bufferred interrupt pipe messages */
928 while (1) {
929 r = ifd_usb_capture(reader->device, cap, ret, 8, 100);
930 if (r < 0)
931 break;
932 if (ret[0] != 0x50)
933 continue;
934 ifd_debug(3, "status received:%s", ct_hexdump(ret, r));
935 bits = (ret[i] >> j) & 0x3;
936 if (bits & 2)
937 stat |= IFD_CARD_STATUS_CHANGED;
938 if (bits & 1)
939 stat |= IFD_CARD_PRESENT;
940 else
941 stat &= ~IFD_CARD_PRESENT;
942 any = 1;
943 }
944 ifd_usb_end_capture(reader->device, cap);
945 if (any) {
946 ifd_debug(1, "polled result: %d", stat);
947 st->icc_present[slot] = stat & IFD_CARD_PRESENT;
948 *status = stat;
949 return 0;
950 }
951 if (st->icc_present[slot] != 0xFF) {
952 ifd_debug(1, "cached result: %d",
953 st->icc_present[slot]);
954 *status = st->icc_present[slot];
955 return 0;
956 }
957 }
958
959 r = ccid_prepare_cmd(reader, cmdbuf, 10, 0, CCID_CMD_GETSLOTSTAT,
960 NULL, NULL, 0);
961 if (r < 0)
962 return r;
963 r = ccid_command(reader, cmdbuf, 10, ret, 10);
964 if (r == IFD_ERROR_NO_CARD) {
965 stat = 0;
966 }
967 else if (r < 0) {
968 return r;
969 }
970 else {
971 switch (ret[7] & 3) {
972 case 2:
973 stat = 0;
974 break;
975 default:
976 stat = IFD_CARD_PRESENT;
977 break;
978 }
979 }
980
981 ifd_debug(1, "probed result: %d", IFD_CARD_STATUS_CHANGED | stat);
982
983 *status = IFD_CARD_STATUS_CHANGED | stat;
984 st->icc_present[slot] = stat;
985 return 0;
986 }
987
988 static int ccid_set_protocol(ifd_reader_t * reader, int s, int proto);
989
990 /*
991 * Reset
992 */
993 static int
ccid_card_reset(ifd_reader_t * reader,int slot,void * atr,size_t size)994 ccid_card_reset(ifd_reader_t * reader, int slot, void *atr, size_t size)
995 {
996 ccid_status_t *st = (ccid_status_t *) reader->driver_data;
997 unsigned char buffer[IFD_MAX_ATR_LEN];
998 char ctlbuf[3];
999 int n, r, i;
1000 int status;
1001
1002 r = ccid_card_status(reader, slot, &status);
1003 if (r < 0)
1004 return r;
1005 if (!(status & IFD_CARD_PRESENT))
1006 return IFD_ERROR_NO_CARD;
1007
1008 if (st->proto_support & SUPPORT_ESCAPE && slot == reader->nslots - 1) {
1009 ifd_debug(1, "slot: %d, setting atr to 0xff", slot);
1010 *((char *)atr) = 0xff;
1011 ccid_set_protocol(reader, slot, IFD_PROTOCOL_ESCAPE);
1012 return 1;
1013 }
1014 memset(ctlbuf, 0, 3);
1015
1016 n = -1;
1017 if (st->voltage_support & AUTO_VOLTAGE
1018 || st->flags & FLAG_AUTO_ACTIVATE) {
1019 ifd_debug(1, "called. powering on with auto voltage selection");
1020 n = ccid_simple_rcommand(reader, slot, CCID_CMD_ICCPOWERON,
1021 ctlbuf, buffer, IFD_MAX_ATR_LEN);
1022 }
1023 if (n < 0 && (st->voltage_support & AUTO_VOLTAGE) == 0) {
1024 ifd_debug(1,
1025 "called. powering on with manual voltage selection");
1026 for (i = 1; i <= 3; i++) {
1027 if ((st->voltage_support & (1 << (i - 1))) == 0)
1028 continue;
1029 ifd_debug(3, "Trying voltage parameter %d", i);
1030 ctlbuf[0] = i;
1031 n = ccid_simple_rcommand(reader, slot,
1032 CCID_CMD_ICCPOWERON, ctlbuf,
1033 buffer, IFD_MAX_ATR_LEN);
1034 if (n > 0)
1035 break;
1036 }
1037 }
1038 if (n < 0)
1039 return n;
1040 if (n > size)
1041 return IFD_ERROR_BUFFER_TOO_SMALL;
1042 memcpy(atr, buffer, n);
1043
1044 return n;
1045 }
1046
ccid_set_protocol(ifd_reader_t * reader,int s,int proto)1047 static int ccid_set_protocol(ifd_reader_t * reader, int s, int proto)
1048 {
1049 ccid_status_t *st = (ccid_status_t *) reader->driver_data;
1050 unsigned char parambuf[17], ctl[3];
1051 ifd_slot_t *slot;
1052 ifd_protocol_t *p;
1053 ifd_atr_info_t atr_info;
1054 int r, paramlen;
1055
1056 slot = &reader->slot[s];
1057
1058 /* If we support RFID escaping, we only allow ESCAPE protocol
1059 * at the last (== virtual) slot */
1060 if ((st->proto_support & SUPPORT_ESCAPE)
1061 && (proto != IFD_PROTOCOL_ESCAPE)
1062 && (s == reader->nslots - 1)) {
1063 ct_error("reader doesn't support this protocol at this slot\n");
1064 return IFD_ERROR_NOT_SUPPORTED;
1065 }
1066
1067 switch (proto) {
1068 case IFD_PROTOCOL_T0:
1069 if (!(st->proto_support & SUPPORT_T0)) {
1070 ct_error("reader does not support this protocol");
1071 return IFD_ERROR_NOT_SUPPORTED;
1072 }
1073 break;
1074 case IFD_PROTOCOL_T1:
1075 if (!(st->proto_support & SUPPORT_T1)) {
1076 ct_error("reader does not support this protocol");
1077 return IFD_ERROR_NOT_SUPPORTED;
1078 }
1079 break;
1080 case IFD_PROTOCOL_ESCAPE:
1081 /* virtual "escape" fallthrough protocol for stacking RFID
1082 * protocol stack on top of openct */
1083 if (!(st->proto_support & SUPPORT_ESCAPE)) {
1084 ct_error("reader does not support this protocol");
1085 return IFD_ERROR_NOT_SUPPORTED;
1086 }
1087 if (s != reader->nslots - 1) {
1088 ct_error
1089 ("reader doesn't support this protocol at this slot");
1090 return IFD_ERROR_NOT_SUPPORTED;
1091 }
1092 p = ifd_protocol_new(IFD_PROTOCOL_ESCAPE, reader, slot->dad);
1093 if (!p) {
1094 ct_error("%s: internal error", reader->name);
1095 return -1;
1096 }
1097 if (slot->proto) {
1098 ifd_protocol_free(slot->proto);
1099 slot->proto = NULL;
1100 }
1101 slot->proto = p;
1102 st->icc_proto[s] = proto;
1103 ifd_debug(1, "set protocol to ESCAPE\n");
1104 return 0;
1105 break;
1106 default:
1107 ct_error("protocol unknown");
1108 return IFD_ERROR_NOT_SUPPORTED;
1109 }
1110
1111 if (st->reader_type == TYPE_APDU) {
1112 p = ifd_protocol_new(IFD_PROTOCOL_TRANSPARENT,
1113 reader, slot->dad);
1114 if (p == NULL) {
1115 ct_error("%s: internal error", reader->name);
1116 return -1;
1117 }
1118 if (slot->proto) {
1119 ifd_protocol_free(slot->proto);
1120 slot->proto = NULL;
1121 }
1122 slot->proto = p;
1123 st->icc_proto[s] = proto;
1124 return 0;
1125 }
1126
1127 r = ifd_atr_parse(&atr_info, slot->atr, slot->atr_len);
1128 if (r < 0) {
1129 ct_error("%s: Bad ATR", reader->name);
1130 return r;
1131 }
1132 /* ccid doesn't have a parameter for this */
1133 if (atr_info.TC[0] == 255)
1134 atr_info.TC[0] = -1;
1135
1136 /*
1137 * guard time increase must precede PTS
1138 * we don't need to do this separate step if
1139 * a) the ccid does automatic parameter setting, or
1140 * b) the ccid parses the atr itself, or
1141 * c) the ccid does pts itself when we set parameters, or
1142 * d) the ICC does not require extra guard time
1143 * In all but the first case, we'll do parameter setting later,
1144 * so fetch the default parameters now.
1145 */
1146 if ((st->flags & FLAG_NO_SETPARAM) == 0) {
1147 memset(parambuf, 0, sizeof(parambuf));
1148 memset(ctl, 0, 3);
1149 r = ccid_simple_rcommand(reader, s, CCID_CMD_GETPARAMS,
1150 ctl, parambuf, 7);
1151 if (r < 0)
1152 return r;
1153 if (proto == IFD_PROTOCOL_T0) {
1154 paramlen = 5;
1155 ctl[0] = 0;
1156 }
1157 else {
1158 paramlen = 7;
1159 ctl[0] = 1;
1160 }
1161 if ((st->flags & (FLAG_NO_PTS | FLAG_AUTO_ATRPARSE)) == 0 &&
1162 atr_info.TC[0] != -1) {
1163
1164 parambuf[2] = atr_info.TC[0];
1165 r = ccid_simple_wcommand(reader, s, CCID_CMD_SETPARAMS,
1166 ctl, parambuf, paramlen);
1167 if (r < 0)
1168 return r;
1169 }
1170 }
1171
1172 if ((st->flags & FLAG_NO_PTS) == 0 &&
1173 (proto == IFD_PROTOCOL_T1 || atr_info.TA[0] != -1)) {
1174
1175 unsigned char pts[7], ptsret[7];
1176 int ptslen;
1177
1178 ptslen = ifd_build_pts(&atr_info, proto, pts, sizeof(pts));
1179 if (ptslen < 0) {
1180 ct_error("%s: Could not perform PTS: %s", reader->name,
1181 ct_strerror(r));
1182 return ptslen;
1183 }
1184 r = ccid_exchange(reader, s, pts, ptslen, ptsret,
1185 ptslen);
1186 if (r < 0)
1187 return r;
1188 r = ifd_verify_pts(&atr_info, proto, ptsret, r);
1189 if (r) {
1190 ct_error("%s: Bad PTS response", reader->name);
1191 return r;
1192 }
1193 }
1194
1195 if ((st->flags & FLAG_NO_SETPARAM) == 0 &&
1196 ((st->flags & FLAG_AUTO_ATRPARSE) == 0 ||
1197 proto != IFD_PROTOCOL_T0)) {
1198
1199 /* if FLAG_AUTO_ATRPARSE, only set the protocol. */
1200 if ((st->flags & FLAG_AUTO_ATRPARSE) == 0) {
1201 if (proto == IFD_PROTOCOL_T0) {
1202 /* TA1 -> Fi | Di */
1203 if (atr_info.TA[0] != -1)
1204 parambuf[0] = atr_info.TA[0];
1205 /* TC1 -> N */
1206 if (atr_info.TC[0] != -1)
1207 parambuf[2] = atr_info.TC[0];
1208 /* TC2 -> WI */
1209 if (atr_info.TC[1] != -1)
1210 parambuf[3] = atr_info.TC[1];
1211 /* TA3 -> clock stop parameter */
1212 /* XXX check for IFD clock stop support */
1213 if (atr_info.TA[2] != -1)
1214 parambuf[4] = atr_info.TA[2] >> 6;
1215 }
1216 else if (proto == IFD_PROTOCOL_T1) {
1217 if (atr_info.TA[0] != -1)
1218 parambuf[0] = atr_info.TA[0];
1219 parambuf[1] = 0x10;
1220 /* TC3 -> LRC/CRC selection */
1221 if (atr_info.TC[2] == 1)
1222 parambuf[1] |= 0x1;
1223 else
1224 parambuf[1] &= 0xfe;
1225 /* TC1 -> N */
1226 if (atr_info.TC[0] != -1)
1227 parambuf[2] = atr_info.TC[0];
1228 /* atr_info->TB3 -> BWI/CWI */
1229 if (atr_info.TB[2] != -1)
1230 parambuf[3] = atr_info.TB[2];
1231 /* TA3 -> IFSC */
1232 if (atr_info.TA[2] != -1)
1233 parambuf[5] = atr_info.TA[2];
1234 /*
1235 * XXX CCID supports setting up clock stop for T=1, but the
1236 * T=1 ATR does not define a clock-stop byte.
1237 */
1238 }
1239 }
1240 r = ccid_simple_wcommand(reader, s, CCID_CMD_SETPARAMS, ctl,
1241 parambuf, paramlen);
1242 if (r < 0)
1243 return r;
1244 }
1245
1246 memset(¶mbuf[r], 0, sizeof(parambuf) - r);
1247 if (proto == IFD_PROTOCOL_T0) {
1248 if (st->reader_type == TYPE_CHAR) {
1249 p = ifd_protocol_new(proto,
1250 reader, slot->dad);
1251 } else {
1252 p = ifd_protocol_new(IFD_PROTOCOL_TRANSPARENT,
1253 reader, slot->dad);
1254 }
1255 } else {
1256 p = ifd_protocol_new(proto, reader, slot->dad);
1257 if (p) {
1258 /* guessing that ifsc is limited by ifsd */
1259 if (atr_info.TA[2] != -1)
1260 ifd_protocol_set_parameter(p,
1261 IFD_PROTOCOL_T1_IFSC,
1262 atr_info.TA[2] >
1263 st->ifsd ? st->
1264 ifsd : atr_info.
1265 TA[2]);
1266 ifd_protocol_set_parameter(p, IFD_PROTOCOL_T1_IFSD,
1267 st->ifsd);
1268 if (atr_info.TC[2] == 1)
1269 ifd_protocol_set_parameter(p,
1270 IFD_PROTOCOL_T1_CHECKSUM_CRC,
1271 0);
1272 }
1273 }
1274 if (p == NULL) {
1275 ct_error("%s: internal error", reader->name);
1276 return -1;
1277 }
1278 /* ccid_recv needs to know the exact expected data length */
1279 if (st->reader_type == TYPE_CHAR)
1280 ifd_protocol_set_parameter(p, IFD_PROTOCOL_BLOCK_ORIENTED, 0);
1281 if (slot->proto) {
1282 ifd_protocol_free(slot->proto);
1283 slot->proto = NULL;
1284 }
1285 slot->proto = p;
1286 st->icc_proto[s] = proto;
1287 return 0;
1288 }
1289
ccid_escape(ifd_reader_t * reader,int slot,const void * sbuf,size_t slen,void * rbuf,size_t rlen)1290 static int ccid_escape(ifd_reader_t * reader, int slot, const void *sbuf,
1291 size_t slen, void *rbuf, size_t rlen)
1292 {
1293 unsigned char sendbuf[CCID_MAX_MSG_LEN];
1294 unsigned char recvbuf[CCID_MAX_MSG_LEN];
1295 int r;
1296
1297 ifd_debug(1, "slot: %d, slen %d, rlen %d", slot, slen, rlen);
1298
1299 r = ccid_prepare_cmd(reader, sendbuf, sizeof(sendbuf), slot,
1300 CCID_CMD_ESCAPE, NULL, sbuf, slen);
1301 if (r < 0)
1302 return r;
1303
1304 r = ccid_command(reader, &sendbuf[0], r, recvbuf, sizeof(recvbuf));
1305 if (r < 0)
1306 return r;
1307
1308 return ccid_extract_data(&recvbuf, r, rbuf, rlen);
1309 }
1310
1311 static int
ccid_transparent(ifd_reader_t * reader,int slot,const void * sbuf,size_t slen,void * rbuf,size_t rlen)1312 ccid_transparent(ifd_reader_t * reader, int slot,
1313 const void *sbuf, size_t slen, void *rbuf, size_t rlen)
1314 {
1315 ccid_status_t *st = (ccid_status_t *) reader->driver_data;
1316
1317 ifd_debug(1, "called.");
1318 if (st->reader_type == TYPE_APDU ||
1319 (st->reader_type == TYPE_TPDU &&
1320 st->icc_proto[slot] == IFD_PROTOCOL_T0))
1321 return ccid_exchange(reader, slot, sbuf, slen, rbuf, rlen);
1322 return IFD_ERROR_NOT_SUPPORTED;
1323 }
1324
ccid_send(ifd_reader_t * reader,unsigned int dad,const unsigned char * buffer,size_t len)1325 static int ccid_send(ifd_reader_t * reader, unsigned int dad,
1326 const unsigned char *buffer, size_t len)
1327 {
1328 ccid_status_t *st = (ccid_status_t *) reader->driver_data;
1329 unsigned char *apdu;
1330
1331 ifd_debug(1, "called.");
1332 if (st->sbuf[dad]) {
1333 free(st->sbuf[dad]);
1334 st->sbuf[dad] = NULL;
1335 st->slen[dad] = 0;
1336 }
1337
1338 apdu = (unsigned char *)calloc(1, len);
1339 if (!apdu) {
1340 ct_error("out of memory");
1341 return IFD_ERROR_NO_MEMORY;
1342 }
1343 memcpy(apdu, buffer, len);
1344 st->sbuf[dad] = apdu;
1345 st->slen[dad] = len;
1346 return 0;
1347 }
1348
ccid_recv(ifd_reader_t * reader,unsigned int dad,unsigned char * buffer,size_t len,long timeout)1349 static int ccid_recv(ifd_reader_t * reader, unsigned int dad,
1350 unsigned char *buffer, size_t len, long timeout)
1351 {
1352 ccid_status_t *st = (ccid_status_t *) reader->driver_data;
1353 int r;
1354
1355 ifd_debug(1, "called.");
1356
1357 r = ccid_exchange(reader, dad, st->sbuf[dad], st->slen[dad], buffer,
1358 len);
1359 if (st->sbuf[dad])
1360 free(st->sbuf[dad]);
1361 st->sbuf[dad] = NULL;
1362 st->slen[dad] = 0;
1363 if (r < 0)
1364 ifd_debug(3, "failed: %d", r);
1365 return r;
1366 }
1367
ccid_before_command(ifd_reader_t * reader)1368 static int ccid_before_command(ifd_reader_t * reader)
1369 {
1370 ccid_status_t *st = (ccid_status_t *) reader->driver_data;
1371 int rc;
1372
1373 ifd_debug(1, "called.");
1374
1375 if (!st->events_active) {
1376 return 0;
1377 }
1378
1379 if (st->event_cap == NULL) {
1380 return 0;
1381 }
1382
1383 rc = ifd_usb_end_capture(reader->device, st->event_cap);
1384 st->event_cap = NULL;
1385
1386 return rc;
1387 }
1388
ccid_after_command(ifd_reader_t * reader)1389 static int ccid_after_command(ifd_reader_t * reader)
1390 {
1391 ccid_status_t *st = (ccid_status_t *) reader->driver_data;
1392
1393 ifd_debug(1, "called.");
1394
1395 if (!st->events_active) {
1396 return 0;
1397 }
1398
1399 if (st->event_cap != NULL) {
1400 return 0;
1401 }
1402
1403 return ifd_usb_begin_capture(
1404 reader->device,
1405 IFD_USB_URB_TYPE_INTERRUPT,
1406 reader->device->settings.usb.ep_intr,
1407 8, &st->event_cap
1408 );
1409 }
1410
ccid_get_eventfd(ifd_reader_t * reader,short * events)1411 static int ccid_get_eventfd(ifd_reader_t * reader, short *events)
1412 {
1413 ccid_status_t *st = (ccid_status_t *) reader->driver_data;
1414 int fd;
1415
1416 ifd_debug(1, "called.");
1417
1418 if (!st->support_events) {
1419 return -1;
1420 }
1421
1422 fd = ifd_device_get_eventfd(reader->device, events);
1423
1424 if (fd != -1) {
1425 st->events_active = 1;
1426 }
1427
1428 return fd;
1429 }
1430
ccid_event(ifd_reader_t * reader,int * status,size_t status_size)1431 static int ccid_event(ifd_reader_t * reader, int *status, size_t status_size)
1432 {
1433 ccid_status_t *st = (ccid_status_t *) reader->driver_data;
1434 unsigned char ret[20];
1435 int bytes;
1436
1437 ifd_debug(1, "called.");
1438
1439 if (status_size < reader->nslots) {
1440 return IFD_ERROR_BUFFER_TOO_SMALL;
1441 }
1442
1443 bytes = ifd_usb_capture_event(reader->device, st->event_cap, ret, 8);
1444 if (bytes < 0) {
1445 return bytes;
1446 }
1447
1448 if (bytes > 0 && ret[0] == 0x50) {
1449 int slot;
1450 ifd_debug(3, "status received:%s", ct_hexdump(ret, bytes));
1451 for (slot=0;slot<reader->nslots;slot++) {
1452 if (1 + (slot / 4) < bytes) {
1453 int bits = (ret[1 + (slot / 4)] >> (2 * (slot % 4))) & 0x3;
1454 if (bits & 2)
1455 status[slot] |= IFD_CARD_STATUS_CHANGED;
1456 if (bits & 1)
1457 status[slot] |= IFD_CARD_PRESENT;
1458 else
1459 status[slot] &= ~IFD_CARD_PRESENT;
1460
1461 ifd_debug(1, "slot %d event result: %08x", slot, status[slot]);
1462 st->icc_present[slot] = status[slot] & IFD_CARD_PRESENT;
1463 }
1464 }
1465 }
1466
1467 return 0;
1468 }
1469
ccid_error(ifd_reader_t * reader)1470 static int ccid_error(ifd_reader_t * reader)
1471 {
1472 (void)reader;
1473
1474 ifd_debug(1, "called.");
1475
1476 return IFD_ERROR_DEVICE_DISCONNECTED;
1477 }
1478
1479 /*
1480 * Driver operations
1481 */
1482 static struct ifd_driver_ops ccid_driver;
1483
1484 /*
1485 * Initialize this module
1486 */
ifd_ccid_register(void)1487 void ifd_ccid_register(void)
1488 {
1489 ccid_driver.open = ccid_open;
1490 ccid_driver.close = ccid_close;
1491 ccid_driver.activate = ccid_activate;
1492 ccid_driver.deactivate = ccid_deactivate;
1493 ccid_driver.card_status = ccid_card_status;
1494 ccid_driver.card_reset = ccid_card_reset;
1495 ccid_driver.set_protocol = ccid_set_protocol;
1496 ccid_driver.transparent = ccid_transparent;
1497 ccid_driver.send = ccid_send;
1498 ccid_driver.recv = ccid_recv;
1499 ccid_driver.escape = ccid_escape;
1500 ccid_driver.before_command = ccid_before_command;
1501 ccid_driver.after_command = ccid_after_command;
1502 ccid_driver.get_eventfd = ccid_get_eventfd;
1503 ccid_driver.event = ccid_event;
1504 ccid_driver.error = ccid_error;
1505
1506 ifd_driver_register("ccid", &ccid_driver);
1507 }
1508