1 /*
2 * Reader Drivers for GemPC devices.
3 * Work in progress, entirely untested.
4 *
5 * Copyright (C) 2003, Olaf Kirch <okir@suse.de>
6 */
7
8 #include "internal.h"
9 #include <unistd.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13
14 #define GPC_ISO_INPUT_MAX 248
15 #define GPC_ISO_EXCHANGE_MAX 254
16 #define GPC_MODE_ROS 0x08
17 #define GPC_MODE_TLP 0x01
18
19 typedef struct gpc_status {
20 /* We need a GBP driver to talk to serial readers */
21 ifd_protocol_t *p;
22 int icc_proto;
23 int card_state;
24 unsigned char cmd_buf[260];
25 size_t cmd_len;
26 } gpc_status_t;
27
28 static int gpc_transceive(ifd_reader_t *, unsigned int,
29 const unsigned char *, size_t,
30 unsigned char *, size_t, long);
31 static int gpc_transceive_t0(ifd_reader_t *, unsigned int,
32 const unsigned char *, size_t,
33 unsigned char *, size_t);
34 static int gpc_transceive_t1(ifd_reader_t *, unsigned int,
35 const unsigned char *, size_t,
36 unsigned char *, size_t);
37 static int gpc_iso_output(ifd_reader_t *,
38 const unsigned char *, size_t,
39 unsigned char *, size_t);
40 static int gpc_iso_input(ifd_reader_t *,
41 const unsigned char *, size_t,
42 unsigned char *, size_t);
43 static int gpc_iso_exchange_apdu(ifd_reader_t *,
44 const unsigned char *, size_t,
45 unsigned char *, size_t);
46 static int gpc_set_serial(ifd_reader_t *, unsigned int, int, int);
47 static int gpc_set_mode(ifd_reader_t *, int);
48 static int gpc_get_os_version(ifd_reader_t *, char *, size_t);
49 static int gpc_command(ifd_reader_t *, const void *, size_t, void *, size_t);
50 static int __gpc_command(ifd_reader_t *,
51 const void *, size_t, void *, size_t, int *);
52 static const char *gpc_strerror(int status);
53
54 /*
55 * Initialize the reader
56 */
gpc_open(ifd_reader_t * reader,const char * device_name)57 static int gpc_open(ifd_reader_t * reader, const char *device_name)
58 {
59 char buffer[256];
60 gpc_status_t *st;
61 ifd_device_t *dev;
62 int r;
63
64 ifd_debug(1, "called, device=%s", device_name);
65
66 reader->name = "Gemplus Reader (pre-alpha, untested)";
67 reader->nslots = 1;
68
69 if (!(dev = ifd_device_open(device_name)))
70 return IFD_ERROR_GENERIC;
71 reader->device = dev;
72
73 st = (gpc_status_t *) calloc(1, sizeof(*st));
74 if (!st) {
75 ct_error("out of memory");
76 return IFD_ERROR_NO_MEMORY;
77 }
78 reader->driver_data = st;
79
80 if (dev->type == IFD_DEVICE_TYPE_SERIAL) {
81 ifd_device_params_t params;
82
83 if (ifd_device_get_parameters(dev, ¶ms) < 0)
84 return IFD_ERROR_GENERIC;
85
86 params.serial.speed = 9600;
87 params.serial.bits = 8;
88 params.serial.stopbits = 1;
89 params.serial.parity = IFD_SERIAL_PARITY_NONE;
90
91 if ((r = ifd_device_set_parameters(dev, ¶ms)) < 0)
92 return r;
93
94 /* Instantiate a GBP driver for this reader */
95 if (!(st->p = ifd_protocol_new(IFD_PROTOCOL_GBP, reader, 0))) {
96 /* Something is badly hosed */
97 ct_error("unable to get GBP protocol handler");
98 return IFD_ERROR_GENERIC;
99 }
100
101 /* Tell the reader to switch to 38400 bps
102 * If the reader is already at 38400 bps, this
103 * command will fail, because we're currently
104 * driving the serial line at 9600. So don't even
105 * bother with checking the return value.
106 * Instead, pause for a moment.
107 */
108 gpc_set_serial(reader, 38400, 8, IFD_SERIAL_PARITY_NONE);
109 usleep(500000);
110 ifd_device_flush(dev);
111 params.serial.speed = 38400;
112 if ((r = ifd_device_set_parameters(dev, ¶ms)) < 0)
113 return r;
114
115 /* The line should now operate at 38400 */
116 r = gpc_set_mode(reader, GPC_MODE_ROS);
117 if (r < 0 && r != IFD_ERROR_NOT_SUPPORTED)
118 return r;
119 } else {
120 ct_error("USB devices not yet supported for GemPC readers\n");
121 return -1;
122 /*
123 sleep(1);
124 ifd_device_flush(dev);
125 */
126 }
127
128 r = gpc_get_os_version(reader, buffer, sizeof(buffer));
129 if (r >= 0) {
130 if (!strcmp(buffer, "OROS-R2.24RM"))
131 reader->name = "GCR 400";
132 else if (!strcmp(buffer, "OROS-R2.99-R1.10"))
133 reader->name = "GCR 410";
134 else if (!strcmp(buffer, "OROS-R2.99-R1.11"))
135 reader->name = "GCR 410P";
136 else if (!strcmp(buffer, "OROS-R2.99-R1.21") ||
137 !strcmp(buffer, "GemCore-R1.21-GM"))
138 reader->name = "GemPC 410";
139 else if (!strcmp(buffer, "OROS-R2.99-R1.32"))
140 reader->name = "GemPC 413";
141 ifd_debug(1,
142 "OS version \"%s\", reader identified as \"%s\"\n",
143 buffer, reader->name);
144 }
145
146 return 0;
147 }
148
149 /*
150 * Activate the reader
151 */
gpc_activate(ifd_reader_t * reader)152 static int gpc_activate(ifd_reader_t * reader)
153 {
154 ifd_debug(1, "called.");
155 return 0;
156 }
157
gpc_deactivate(ifd_reader_t * reader)158 static int gpc_deactivate(ifd_reader_t * reader)
159 {
160 return 0;
161 }
162
gpc_close(ifd_reader_t * reader)163 static int gpc_close(ifd_reader_t * reader)
164 {
165 return 0;
166 }
167
168 /*
169 * Check card status
170 */
gpc_card_status(ifd_reader_t * reader,int slot,int * status)171 static int gpc_card_status(ifd_reader_t * reader, int slot, int *status)
172 {
173 gpc_status_t *st = (gpc_status_t *) reader->driver_data;
174 unsigned char byte;
175 int r;
176
177 if (slot != 0) {
178 ct_error("gempc: bad slot index %u", slot);
179 return IFD_ERROR_INVALID_SLOT;
180 }
181
182 if ((r = gpc_command(reader, "\x17", 1, &byte, 1)) < 0)
183 return r;
184
185 ifd_debug(4, "card %spresent%s\n",
186 (byte & 0x04) ? "" : "not ",
187 (byte & 0x02) ? ", powered up" : "");
188
189 *status = (byte & 0x04) ? IFD_CARD_PRESENT : 0;
190
191 /* A power up/down transition can be used to detect
192 * a card change. */
193 if ((st->card_state & 0x02) && !(byte & 0x02))
194 *status |= IFD_CARD_STATUS_CHANGED;
195
196 st->card_state = byte;
197 return 0;
198 }
199
200 /*
201 * Reset the card and get the ATR
202 */
gpc_card_reset(ifd_reader_t * reader,int slot,void * atr,size_t size)203 static int gpc_card_reset(ifd_reader_t * reader, int slot, void *atr,
204 size_t size)
205 {
206 static unsigned char reset_auto_pps[] = { 0x12, 0x23 };
207 static unsigned char reset_no_pps[] = { 0x12, 0x13 };
208 static unsigned char reset_emv[] = { 0x12 };
209 static unsigned char set_mode[] = { 0x17, 0x00, 0x47 };
210 int r, status;
211
212 ifd_debug(1, "called.");
213
214 if (slot != 0) {
215 ct_error("gempc: bad slot index %u", slot);
216 return IFD_ERROR_INVALID_SLOT;
217 }
218
219 /* Get the card status */
220 if ((r = gpc_card_status(reader, slot, &status)) < 0)
221 return r;
222
223 if (!(status & IFD_CARD_PRESENT))
224 return IFD_ERROR_NO_CARD;
225
226 r = __gpc_command(reader, reset_auto_pps, sizeof(reset_auto_pps),
227 atr, size, &status);
228 if (r < 0 || status == 0x00)
229 return r;
230
231 /* Try again without PPS */
232 r = __gpc_command(reader, reset_no_pps, sizeof(reset_no_pps),
233 atr, size, &status);
234 if (r < 0 || status == 0x00)
235 return r;
236
237 /* Try EMV mode */
238 r = __gpc_command(reader, reset_emv, sizeof(reset_emv),
239 atr, size, &status);
240 if (r < 0 || status == 0x00)
241 return r;
242
243 /* Change Operation Mode, and retry EMV reset */
244 (void)gpc_command(reader, set_mode, sizeof(set_mode), NULL, 0);
245 r = __gpc_command(reader, reset_emv, sizeof(reset_emv),
246 atr, size, &status);
247 if (r < 0 || status == 0x00)
248 return r;
249
250 return IFD_ERROR_NO_CARD;
251 }
252
253 /*
254 * Select the card protocol
255 */
gpc_set_protocol(ifd_reader_t * reader,int nslot,int proto)256 static int gpc_set_protocol(ifd_reader_t * reader, int nslot, int proto)
257 {
258 gpc_status_t *st = (gpc_status_t *) reader->driver_data;
259 ifd_slot_t *slot;
260
261 ifd_debug(1, "called, proto=%d", proto);
262
263 if (proto != IFD_PROTOCOL_T0 && proto != IFD_PROTOCOL_T1) {
264 /* XXX FIXME - we need to call DEFINE CARD TYPE here */
265 return IFD_ERROR_NOT_SUPPORTED;
266 }
267
268 slot = &reader->slot[nslot];
269 slot->proto = ifd_protocol_new(IFD_PROTOCOL_TRANSPARENT,
270 reader, slot->dad);
271 if (slot->proto == NULL) {
272 ct_error("%s: internal error", reader->name);
273 return IFD_ERROR_GENERIC;
274 }
275
276 st->icc_proto = proto;
277 return 0;
278 }
279
280 /*
281 * Change the serial speed
282 */
gpc_set_serial(ifd_reader_t * reader,unsigned int speed,int cs,int parity)283 static int gpc_set_serial(ifd_reader_t * reader, unsigned int speed, int cs,
284 int parity)
285 {
286 unsigned char cmd[] = { 0x0A, 0x00 };
287
288 ifd_debug(1, "called, speed=%u, cs=%d, parity=%d\n", speed, cs, parity);
289
290 if (reader->device->type != IFD_DEVICE_TYPE_SERIAL)
291 return IFD_ERROR_NOT_SUPPORTED;
292
293 switch (speed) {
294 case 1200:
295 cmd[1] = 0x07;
296 break;
297 case 2400:
298 cmd[1] = 0x06;
299 break;
300 case 4800:
301 cmd[1] = 0x05;
302 break;
303 case 9600:
304 cmd[1] = 0x04;
305 break;
306 case 19200:
307 cmd[1] = 0x03;
308 break;
309 case 38400:
310 cmd[1] = 0x02;
311 break;
312 case 76800:
313 cmd[1] = 0x01;
314 break;
315 default:
316 return IFD_ERROR_NOT_SUPPORTED;
317 }
318
319 switch (cs) {
320 case 7:
321 cmd[1] |= 0x08;
322 break;
323 case 8:
324 break;
325 default:
326 return IFD_ERROR_NOT_SUPPORTED;
327 }
328
329 switch (parity) {
330 case IFD_SERIAL_PARITY_EVEN:
331 cmd[1] |= 0x10;
332 break;
333 case IFD_SERIAL_PARITY_NONE:
334 break;
335 default:
336 return IFD_ERROR_NOT_SUPPORTED;
337 }
338
339 return gpc_command(reader, cmd, sizeof(cmd), NULL, 0);
340 }
341
342 /*
343 * Set Reader mode
344 */
gpc_set_mode(ifd_reader_t * reader,int mode)345 static int gpc_set_mode(ifd_reader_t * reader, int mode)
346 {
347 unsigned char cmd[] = { 0x01, 0x00, 0x00 };
348
349 cmd[2] = mode;
350 return gpc_command(reader, cmd, sizeof(cmd), NULL, 0);
351 }
352
353 #if 0
354 /*
355 * Send command to IFD
356 *
357 * FIXME: we really need a better mechanism at the reader driver
358 * API to allow for a "transceive" operation.
359 */
360 static int gpc_send(ifd_reader_t * reader, unsigned int dad,
361 const unsigned char *buffer, size_t len)
362 {
363 gpc_status_t *st = (gpc_status_t *) reader->driver_data;
364
365 ifd_debug(3, "data:%s", ct_hexdump(buffer, len));
366
367 if (len > sizeof(st->cmd_buf))
368 return IFD_ERROR_BUFFER_TOO_SMALL;
369 memcpy(st->cmd_buf, buffer, len);
370 st->cmd_len = len;
371 return 0;
372 }
373
374 static int gpc_recv(ifd_reader_t * reader, unsigned int dad,
375 unsigned char *res_buf, size_t res_len, long timeout)
376 {
377 gpc_status_t *st = (gpc_status_t *) reader->driver_data;
378 int rc;
379
380 rc = gpc_transceive(reader, dad,
381 st->cmd_buf, st->cmd_len,
382 res_buf, res_len, timeout);
383
384 if (rc > 0)
385 ifd_debug(3, "received:%s", ct_hexdump(res_buf, rc));
386 return rc;
387 }
388 #endif
389
gpc_transparent(ifd_reader_t * reader,int nad,const void * cmd_buf,size_t cmd_len,void * res_buf,size_t res_len)390 static int gpc_transparent(ifd_reader_t * reader, int nad, const void *cmd_buf,
391 size_t cmd_len, void *res_buf, size_t res_len)
392 {
393 return gpc_transceive(reader, nad,
394 (const unsigned char *)cmd_buf, cmd_len,
395 (unsigned char *)res_buf, res_len, 0);
396 }
397
398 /*
399 * Generic transceive function
400 */
gpc_transceive(ifd_reader_t * reader,unsigned int dad,const unsigned char * cmd_buf,size_t cmd_len,unsigned char * res_buf,size_t res_len,long timeout)401 static int gpc_transceive(ifd_reader_t * reader, unsigned int dad,
402 const unsigned char *cmd_buf, size_t cmd_len,
403 unsigned char *res_buf, size_t res_len, long timeout)
404 {
405 gpc_status_t *st = (gpc_status_t *) reader->driver_data;
406 ifd_protocol_t *proto = reader->slot[0].proto;
407 long orig_timeout = 0;
408 int rc;
409
410 if (timeout) {
411 ifd_protocol_get_parameter(proto,
412 IFD_PROTOCOL_RECV_TIMEOUT,
413 &orig_timeout);
414 ifd_protocol_set_parameter(proto,
415 IFD_PROTOCOL_RECV_TIMEOUT,
416 timeout * 1000);
417 }
418
419 switch (st->icc_proto) {
420 case IFD_PROTOCOL_T0:
421 rc = gpc_transceive_t0(reader, dad,
422 cmd_buf, cmd_len, res_buf, res_len);
423 break;
424 case IFD_PROTOCOL_T1:
425 rc = gpc_transceive_t1(reader, dad,
426 cmd_buf, cmd_len, res_buf, res_len);
427 break;
428 default:
429 ct_error("protocol not supported\n");
430 rc = IFD_ERROR_NOT_SUPPORTED;
431 }
432
433 if (orig_timeout) {
434 ifd_protocol_set_parameter(proto,
435 IFD_PROTOCOL_RECV_TIMEOUT,
436 orig_timeout);
437 }
438
439 return rc;
440 }
441
gpc_transceive_t0(ifd_reader_t * reader,unsigned int dad,const unsigned char * cmd_buf,size_t cmd_len,unsigned char * res_buf,size_t res_len)442 static int gpc_transceive_t0(ifd_reader_t * reader, unsigned int dad,
443 const unsigned char *cmd_buf, size_t cmd_len,
444 unsigned char *res_buf, size_t res_len)
445 {
446 ifd_iso_apdu_t iso;
447 int rc;
448
449 if ((rc = ifd_iso_apdu_parse(cmd_buf, cmd_len, &iso)) < 0)
450 return rc;
451
452 switch (iso.cse) {
453 case IFD_APDU_CASE_1:
454 case IFD_APDU_CASE_3S:
455 rc = gpc_iso_input(reader, cmd_buf, cmd_len, res_buf, res_len);
456 break;
457 case IFD_APDU_CASE_2S:
458 rc = gpc_iso_output(reader, cmd_buf, cmd_len, res_buf, res_len);
459 break;
460 case IFD_APDU_CASE_4S:
461 /* The PC/SC IFD driver does an ISO EXCHANGE APDU here,
462 * but the specs I have say you can do this command only
463 * for T=1 cards.
464 * However, we shouldn't get here anyway for T=1, as the
465 * T=0 protocol driver splits case 4 APDUs. */
466 rc = gpc_iso_exchange_apdu(reader, cmd_buf, cmd_len,
467 res_buf, res_len);
468 break;
469 default:
470 ifd_debug(1, "Bad APDU (case %d unknown or unsupported)\n",
471 iso.cse);
472 return IFD_ERROR_INVALID_ARG;
473 }
474
475 return rc;
476 }
477
gpc_transceive_t1(ifd_reader_t * reader,unsigned int dad,const unsigned char * cmd_buf,size_t cmd_len,unsigned char * res_buf,size_t res_len)478 static int gpc_transceive_t1(ifd_reader_t * reader, unsigned int dad,
479 const unsigned char *cmd_buf, size_t cmd_len,
480 unsigned char *res_buf, size_t res_len)
481 {
482 return gpc_iso_exchange_apdu(reader, cmd_buf, cmd_len,
483 res_buf, res_len);
484 }
485
486 /*
487 * Send partial APDU to the card
488 */
gpc_iso_send_frag(ifd_reader_t * reader,unsigned char cmd,const unsigned char * cmd_buf,size_t cmd_len)489 static int gpc_iso_send_frag(ifd_reader_t * reader, unsigned char cmd,
490 const unsigned char *cmd_buf, size_t cmd_len)
491 {
492 unsigned char buffer[256];
493
494 ifd_debug(4, "called, len=%u", cmd_len);
495 if (cmd_len > sizeof(buffer) - 6)
496 return IFD_ERROR_INVALID_ARG;
497
498 buffer[0] = cmd;
499 buffer[1] = 0xFF;
500 buffer[2] = 0xFF;
501 buffer[3] = 0xFF;
502 buffer[4] = 0xFF;
503 buffer[5] = cmd_len;
504 memcpy(buffer + 6, cmd_buf, cmd_len);
505
506 return gpc_command(reader, buffer, 6 + cmd_len, buffer, sizeof(buffer));
507 }
508
509 /*
510 * Receive (potentially fragmented) response from the card
511 */
gpc_iso_recv_frag(ifd_reader_t * reader,unsigned char cmd,const unsigned char * data,size_t data_len,ct_buf_t * bp)512 static int gpc_iso_recv_frag(ifd_reader_t * reader, unsigned char cmd,
513 const unsigned char *data, size_t data_len,
514 ct_buf_t * bp)
515 {
516 static unsigned char more_data[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
517 unsigned char buffer[256];
518 int rc, status;
519
520 if (!data) {
521 data = more_data;
522 data_len = sizeof(more_data);
523 } else if (data_len > sizeof(buffer) - 1) {
524 return IFD_ERROR_BUFFER_TOO_SMALL;
525 }
526
527 buffer[0] = cmd;
528 memcpy(buffer + 1, data, data_len);
529
530 rc = __gpc_command(reader, buffer, 1 + data_len,
531 buffer, sizeof(buffer), &status);
532 if (rc < 0)
533 return rc;
534
535 ct_buf_put(bp, buffer, rc);
536 if (status != 0x00 /* success */
537 && status != 0xE7 /* not 9000 */
538 && status != 0xE5 /* not 9000 */
539 && status != 0x1B) { /* more data */
540 ct_error("error 0x%02x in ISO OUPUT/EXCHANGE APDU (%s)",
541 status, gpc_strerror(status));
542 return IFD_ERROR_COMM_ERROR;
543 }
544
545 /* so exchange/send stop looping. is 1b right here? */
546 if (status != 0x00 && status != 0x1B)
547 return 0;
548
549 return rc;
550 }
551
552 /*
553 * Send case 2 APDU to card, receive lots of data in response.
554 * Due to the limitations imposed by GBP, the reader may have
555 * to send the response fragmented into several parts.
556 */
gpc_iso_output(ifd_reader_t * reader,const unsigned char * cmd_buf,size_t cmd_len,unsigned char * res_buf,size_t res_len)557 static int gpc_iso_output(ifd_reader_t * reader, const unsigned char *cmd_buf,
558 size_t cmd_len, unsigned char *res_buf,
559 size_t res_len)
560 {
561 ct_buf_t res;
562 size_t expect = 0;
563 int rc;
564
565 ct_buf_init(&res, res_buf, res_len);
566 if (cmd_len > 4) {
567 expect = cmd_buf[4];
568 if (expect == 0)
569 expect = 256;
570 expect += 2; /* for status word */
571 if (expect > res_len)
572 expect = res_len;
573 }
574
575 while (1) {
576 rc = gpc_iso_recv_frag(reader, 0x13, cmd_buf, cmd_len, &res);
577 if (rc <= 0 || ct_buf_avail(&res) >= expect)
578 break;
579
580 cmd_buf = NULL;
581 cmd_len = 0;
582 }
583
584 if (rc < 0)
585 return rc;
586 return ct_buf_avail(&res);
587 }
588
589 /*
590 * Send APDU+data to card
591 */
gpc_iso_input(ifd_reader_t * reader,const unsigned char * cmd_buf,size_t cmd_len,unsigned char * res_buf,size_t res_len)592 static int gpc_iso_input(ifd_reader_t * reader, const unsigned char *cmd_buf,
593 size_t cmd_len, unsigned char *res_buf, size_t res_len)
594 {
595 unsigned char buffer[GPC_ISO_INPUT_MAX + 1];
596 int rc;
597
598 if (cmd_len > GPC_ISO_INPUT_MAX) {
599 size_t chunk = cmd_len - GPC_ISO_INPUT_MAX;
600
601 rc = gpc_iso_send_frag(reader, 0x14, cmd_buf + chunk, chunk);
602 if (rc < 0)
603 return rc;
604 cmd_len = GPC_ISO_INPUT_MAX;
605 }
606
607 buffer[0] = 0x14;
608 memcpy(buffer + 1, cmd_buf, cmd_len);
609
610 if (cmd_len == 4)
611 buffer[++cmd_len] = 0x00;
612
613 return gpc_command(reader, buffer, cmd_len + 1, res_buf, 2);
614 }
615
gpc_iso_exchange_apdu(ifd_reader_t * reader,const unsigned char * cmd_buf,size_t cmd_len,unsigned char * res_buf,size_t res_len)616 static int gpc_iso_exchange_apdu(ifd_reader_t * reader,
617 const unsigned char *cmd_buf, size_t cmd_len,
618 unsigned char *res_buf, size_t res_len)
619 {
620 ct_buf_t res;
621 size_t expect = 0;
622 int rc;
623
624 ct_buf_init(&res, res_buf, res_len);
625 if (cmd_len > 4) {
626 expect = cmd_buf[4];
627 if (expect == 0)
628 expect = 256;
629 expect += 2; /* for status word */
630 if (expect > res_len)
631 expect = res_len;
632 }
633
634 if (cmd_len > GPC_ISO_EXCHANGE_MAX) {
635 size_t chunk = cmd_len - GPC_ISO_EXCHANGE_MAX;
636
637 rc = gpc_iso_send_frag(reader, 0x15, cmd_buf + chunk, chunk);
638 if (rc < 0)
639 return rc;
640 cmd_len = GPC_ISO_EXCHANGE_MAX;
641 }
642
643 while (1) {
644 rc = gpc_iso_recv_frag(reader, 0x15, cmd_buf, cmd_len, &res);
645 if (rc <= 0 || ct_buf_avail(&res) >= expect)
646 break;
647
648 /* Added by Chaskiel - I don't understand why */
649 if (ct_buf_avail(&res) == 2 && expect == 258)
650 break;
651
652 cmd_buf = NULL;
653 cmd_len = 0;
654 }
655
656 if (rc < 0)
657 return rc;
658 return ct_buf_avail(&res);
659 }
660
661 /*
662 * Get the OS version
663 */
gpc_get_os_version(ifd_reader_t * reader,char * buf,size_t len)664 static int gpc_get_os_version(ifd_reader_t * reader, char *buf, size_t len)
665 {
666 static unsigned char cmd[] = { 0x22, 0x05, 0x3F, 0xE0, 0x10 };
667
668 /* Ensure NUL termination */
669 memset(buf, 0, len);
670 return gpc_command(reader, cmd, sizeof(cmd), buf, len - 1);
671 }
672
673 /*
674 * Helper functions
675 */
__gpc_command(ifd_reader_t * reader,const void * cmd,size_t cmd_len,void * res,size_t res_len,int * gpc_status)676 static int __gpc_command(ifd_reader_t * reader, const void *cmd,
677 size_t cmd_len, void *res, size_t res_len,
678 int *gpc_status)
679 {
680 gpc_status_t *st = (gpc_status_t *) reader->driver_data;
681 unsigned char buffer[257];
682 size_t len;
683 int rc;
684
685 if (res_len > sizeof(buffer) - 1)
686 return IFD_ERROR_GENERIC;
687
688 if (st->p == NULL) {
689 ct_error("No host-reader comm protocol selected\n");
690 return IFD_ERROR_GENERIC;
691 }
692
693 if (ct_config.debug >= 3)
694 ifd_debug(3, "sending:%s", ct_hexdump(cmd, cmd_len));
695
696 rc = ifd_protocol_transceive(st->p, 0,
697 cmd, cmd_len, buffer, sizeof(buffer));
698 if (rc < 0)
699 return rc;
700 if (rc == 0) {
701 ct_error("zero length response from reader?!\n");
702 return IFD_ERROR_GENERIC;
703 }
704
705 if (ct_config.debug >= 3)
706 ifd_debug(3, "received:%s", ct_hexdump(buffer, rc));
707
708 len = rc - 1;
709 if (buffer[0] != 0x00) {
710 ifd_debug(2, "reader reports status 0x%02x (%s)\n",
711 buffer[0], gpc_strerror(buffer[0]));
712 }
713 if (gpc_status)
714 *gpc_status = buffer[0];
715
716 if (len > res_len)
717 len = res_len;
718 if (len && res)
719 memcpy(res, buffer + 1, len);
720 return len;
721 }
722
gpc_command(ifd_reader_t * reader,const void * cmd,size_t cmd_len,void * res,size_t res_len)723 static int gpc_command(ifd_reader_t * reader, const void *cmd, size_t cmd_len,
724 void *res, size_t res_len)
725 {
726 int rc, status;
727
728 rc = __gpc_command(reader, cmd, cmd_len, res, res_len, &status);
729 if (rc >= 0 && status == 0x01)
730 rc = IFD_ERROR_NOT_SUPPORTED;
731 if (rc >= 0 && status != 0x00 && status != 0xE5 && status != 0xE7)
732 rc = IFD_ERROR_COMM_ERROR;
733 return rc;
734 }
735
736 /*
737 * GPC error handling
738 */
gpc_strerror(int status)739 static const char *gpc_strerror(int status)
740 {
741 switch (status) {
742 case 0x00:
743 return "Success";
744 case 0x01:
745 return "Unknown GemCore command";
746 case 0x02:
747 return "Operation impossible with this driver";
748 case 0x03:
749 return "Incorrect number of arguments";
750 case 0x10:
751 return "The first byte of the response (TS) is not valid";
752 case 0x1b:
753 return "More data available";
754 case 0x1d:
755 return "Wrong ATR TCK";
756 case 0xa0:
757 return "Error in card reset response";
758 case 0xa1:
759 return "Card protocol error";
760 case 0xa2:
761 return "Card is mute";
762 case 0xa3:
763 return "Parity error during exchange";
764 case 0xa4:
765 return "Card has aborted chaining (T=1)";
766 case 0xa5:
767 return "Reader has aborted chaining (T=1)";
768 case 0xa6:
769 return "RESYNCH successfully performed by GemCore";
770 case 0xa7:
771 return "Protocol Type Selection (PTS) error";
772 case 0xa8:
773 return "Card and reader in EMV mode";
774 case 0xe5:
775 return "Card interrupted the exchange after SW1";
776 case 0xe7:
777 return "\"Error\" returned by the card (SW is not 9000)";
778 case 0xf7:
779 return "Card removed during execution of a command";
780 case 0xfb:
781 return "Card missing";
782 }
783 return "Unknown error";
784 }
785
786 /*
787 * Driver operations
788 */
789 static struct ifd_driver_ops gempc_driver;
790
ifd_gempc_register(void)791 void ifd_gempc_register(void)
792 {
793 gempc_driver.open = gpc_open;
794 gempc_driver.close = gpc_close;
795 gempc_driver.activate = gpc_activate;
796 gempc_driver.deactivate = gpc_deactivate;
797 gempc_driver.set_protocol = gpc_set_protocol;
798 gempc_driver.card_status = gpc_card_status;
799 gempc_driver.card_reset = gpc_card_reset;
800 gempc_driver.transparent = gpc_transparent;
801 ifd_driver_register("gempc", &gempc_driver);
802 }
803