Initial commit
[platform/upstream/ccid.git] / src / commands.c
1 /*
2     commands.c: Commands sent to the card
3     Copyright (C) 2003-2010   Ludovic Rousseau
4     Copyright (C) 2005 Martin Paljak
5
6     This library is free software; you can redistribute it and/or
7     modify it under the terms of the GNU Lesser General Public
8     License as published by the Free Software Foundation; either
9     version 2.1 of the License, or (at your option) any later version.
10
11     This library is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14     Lesser General Public License for more details.
15
16         You should have received a copy of the GNU Lesser General Public License
17         along with this library; if not, write to the Free Software Foundation,
18         Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #include <config.h>
22
23 #ifdef HAVE_STRING_H
24 #include <string.h>
25 #endif
26 #ifdef HAVE_STDLIB_H
27 #include <stdlib.h>
28 #endif
29 #ifdef HAVE_ERRNO_H
30 #include <errno.h>
31 #endif
32 #ifdef HAVE_UNISTD_H
33 #include <unistd.h>
34 #endif
35
36 #include <pcsclite.h>
37 #include <ifdhandler.h>
38 #include <reader.h>
39
40 #include "misc.h"
41 #include "commands.h"
42 #include "openct/proto-t1.h"
43 #include "ccid.h"
44 #include "defs.h"
45 #include "ccid_ifdhandler.h"
46 #include "debug.h"
47 #include "utils.h"
48
49 /* All the pinpad readers I used are more or less bogus
50  * I use code to change the user command and make the firmware happy */
51 #define BOGUS_PINPAD_FIRMWARE
52
53 /* The firmware of SCM readers reports dwMaxCCIDMessageLength = 263
54  * instead of 270 so this prevents from sending a full length APDU
55  * of 260 bytes since the driver check this value */
56 #define BOGUS_SCM_FIRMWARE_FOR_dwMaxCCIDMessageLength
57
58 #ifndef offsetof
59 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
60 #endif
61
62 #define CHECK_STATUS(res) \
63         if (STATUS_NO_SUCH_DEVICE == res) \
64                 return IFD_NO_SUCH_DEVICE; \
65         if (STATUS_SUCCESS != res) \
66                 return IFD_COMMUNICATION_ERROR;
67
68 /* internal functions */
69 static RESPONSECODE CmdXfrBlockAPDU_extended(unsigned int reader_index,
70         unsigned int tx_length, unsigned char tx_buffer[], unsigned int *rx_length,
71         unsigned char rx_buffer[]);
72
73 static RESPONSECODE CmdXfrBlockTPDU_T0(unsigned int reader_index,
74         unsigned int tx_length, unsigned char tx_buffer[], unsigned int *rx_length,
75         unsigned char rx_buffer[]);
76
77 static RESPONSECODE CmdXfrBlockCHAR_T0(unsigned int reader_index, unsigned int
78         tx_length, unsigned char tx_buffer[], unsigned int *rx_length, unsigned
79         char rx_buffer[]);
80
81 static RESPONSECODE CmdXfrBlockTPDU_T1(unsigned int reader_index,
82         unsigned int tx_length, unsigned char tx_buffer[], unsigned int *rx_length,
83         unsigned char rx_buffer[]);
84
85 static void i2dw(int value, unsigned char *buffer);
86 static unsigned int bei2i(unsigned char *buffer);
87
88
89 /*****************************************************************************
90  *
91  *                                      CmdPowerOn
92  *
93  ****************************************************************************/
94 RESPONSECODE CmdPowerOn(unsigned int reader_index, unsigned int * nlength,
95         unsigned char buffer[], int voltage)
96 {
97         unsigned char cmd[10];
98         status_t res;
99         int length, count = 1;
100         unsigned int atr_len;
101         int init_voltage;
102         RESPONSECODE return_value = IFD_SUCCESS;
103         _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
104
105 #ifndef TWIN_SERIAL
106         if (PROTOCOL_ICCD_A == ccid_descriptor->bInterfaceProtocol)
107         {
108                 int r;
109                 unsigned char pcbuffer[SIZE_GET_SLOT_STATUS];
110
111                 /* first power off to reset the ICC state machine */
112                 r = CmdPowerOff(reader_index);
113                 if (r != IFD_SUCCESS)
114                         return r;
115
116                 /* wait for ready */
117                 r = CmdGetSlotStatus(reader_index, pcbuffer);
118                 if (r != IFD_SUCCESS)
119                         return r;
120
121                 /* Power On */
122                 r = ControlUSB(reader_index, 0xA1, 0x62, 0, buffer, *nlength);
123
124                 /* we got an error? */
125                 if (r < 0)
126                 {
127                         DEBUG_INFO2("ICC Power On failed: %s", strerror(errno));
128                         return IFD_COMMUNICATION_ERROR;
129                 }
130
131                 *nlength = r;
132
133                 return IFD_SUCCESS;
134         }
135
136         if (PROTOCOL_ICCD_B == ccid_descriptor->bInterfaceProtocol)
137         {
138                 int r;
139                 unsigned char tmp[MAX_ATR_SIZE+1];
140
141                 /* first power off to reset the ICC state machine */
142                 r = CmdPowerOff(reader_index);
143                 if (r != IFD_SUCCESS)
144                         return r;
145
146                 /* Power On */
147                 r = ControlUSB(reader_index, 0x21, 0x62, 1, NULL, 0);
148
149                 /* we got an error? */
150                 if (r < 0)
151                 {
152                         DEBUG_INFO2("ICC Power On failed: %s", strerror(errno));
153                         return IFD_COMMUNICATION_ERROR;
154                 }
155
156                 /* Data Block */
157                 r = ControlUSB(reader_index, 0xA1, 0x6F, 0, tmp, sizeof(tmp));
158
159                 /* we got an error? */
160                 if (r < 0)
161                 {
162                         DEBUG_INFO2("ICC Data Block failed: %s", strerror(errno));
163                         return IFD_COMMUNICATION_ERROR;
164                 }
165
166                 if (tmp[0] != 0x00)
167                 {
168                         DEBUG_CRITICAL2("bResponseType: 0x%02X", tmp[0]);
169
170                         /* Status Information? */
171                         if (0x40 == tmp[0])
172                                 ccid_error(PCSC_LOG_ERROR, tmp[2], __FILE__, __LINE__, __FUNCTION__);
173                         return IFD_COMMUNICATION_ERROR;
174                 }
175
176                 DEBUG_INFO_XXD("Data Block: ", tmp, r);
177                 if ((int)*nlength > r-1)
178                         *nlength = r-1;
179                 memcpy(buffer, tmp+1, *nlength);
180
181                 return IFD_SUCCESS;
182         }
183 #endif
184
185         /* store length of buffer[] */
186         length = *nlength;
187
188         if ((ccid_descriptor->dwFeatures & CCID_CLASS_AUTO_VOLTAGE)
189                 || (ccid_descriptor->dwFeatures & CCID_CLASS_AUTO_ACTIVATION))
190                 voltage = 0;    /* automatic voltage selection */
191         else
192         {
193                 int bVoltageSupport = ccid_descriptor->bVoltageSupport;
194
195 check_again:
196                 if ((1 == voltage) && !(bVoltageSupport & 1))
197                 {
198                         DEBUG_INFO1("5V requested but not support by reader");
199                         voltage = 2;    /* 3V */
200                 }
201
202                 if ((2 == voltage) && !(bVoltageSupport & 2))
203                 {
204                         DEBUG_INFO1("3V requested but not support by reader");
205                         voltage = 3;    /* 1.8V */
206                 }
207
208                 if ((3 == voltage) && !(bVoltageSupport & 4))
209                 {
210                         DEBUG_INFO1("1.8V requested but not support by reader");
211                         voltage = 1;    /* 5V */
212                         goto check_again;
213                 }
214         }
215         init_voltage = voltage;
216
217 again:
218         cmd[0] = 0x62; /* IccPowerOn */
219         cmd[1] = cmd[2] = cmd[3] = cmd[4] = 0;  /* dwLength */
220         cmd[5] = ccid_descriptor->bCurrentSlotIndex;    /* slot number */
221         cmd[6] = (*ccid_descriptor->pbSeq)++;
222         cmd[7] = voltage;
223         cmd[8] = cmd[9] = 0; /* RFU */
224
225         res = WritePort(reader_index, sizeof(cmd), cmd);
226         CHECK_STATUS(res)
227
228         /* reset available buffer size */
229         /* needed if we go back after a switch to ISO mode */
230         *nlength = length;
231
232         res = ReadPort(reader_index, nlength, buffer);
233         CHECK_STATUS(res)
234
235         if (*nlength < STATUS_OFFSET+1)
236         {
237                 DEBUG_CRITICAL2("Not enough data received: %d bytes", *nlength);
238                 return IFD_COMMUNICATION_ERROR;
239         }
240
241         if (buffer[STATUS_OFFSET] & CCID_COMMAND_FAILED)
242         {
243                 ccid_error(PCSC_LOG_ERROR, buffer[ERROR_OFFSET], __FILE__, __LINE__, __FUNCTION__);    /* bError */
244
245                 if (0xBB == buffer[ERROR_OFFSET] &&     /* Protocol error in EMV mode */
246                         ((GEMPC433 == ccid_descriptor->readerID)
247                         || (CHERRYXX33 == ccid_descriptor->readerID)))
248                 {
249                         unsigned char cmd_tmp[] = {0x1F, 0x01};
250                         unsigned char res_tmp[1];
251                         unsigned int res_length = sizeof(res_tmp);
252
253                         if ((return_value = CmdEscape(reader_index, cmd_tmp,
254                                 sizeof(cmd_tmp), res_tmp, &res_length, 0)) != IFD_SUCCESS)
255                                 return return_value;
256
257                         /* avoid looping if we can't switch mode */
258                         if (count--)
259                                 goto again;
260                         else
261                                 DEBUG_CRITICAL("Can't set reader in ISO mode");
262                 }
263
264                 /* continue with other voltage values */
265                 if (voltage)
266                 {
267 #ifndef NO_LOG
268                         const char *voltage_code[] = { "auto", "5V", "3V", "1.8V" };
269 #endif
270
271                         DEBUG_INFO3("Power up with %s failed. Try with %s.",
272                                 voltage_code[voltage], voltage_code[voltage-1]);
273                         voltage--;
274
275                         /* loop from 5V to 1.8V */
276                         if (0 == voltage)
277                                 voltage = 3;
278
279                         /* continue until we tried every values */
280                         if (voltage != init_voltage)
281                                 goto again;
282                 }
283
284                 return IFD_COMMUNICATION_ERROR;
285         }
286
287         /* extract the ATR */
288         atr_len = dw2i(buffer, 1);      /* ATR length */
289         if (atr_len > *nlength)
290                 atr_len = *nlength;
291         else
292                 *nlength = atr_len;
293
294         memmove(buffer, buffer+10, atr_len);
295
296         return return_value;
297 } /* CmdPowerOn */
298
299
300 /*****************************************************************************
301  *
302  *                                      SecurePINVerify
303  *
304  ****************************************************************************/
305 RESPONSECODE SecurePINVerify(unsigned int reader_index,
306         unsigned char TxBuffer[], unsigned int TxLength,
307         unsigned char RxBuffer[], unsigned int *RxLength)
308 {
309         unsigned char cmd[11+14+TxLength];
310         unsigned int a, b;
311         PIN_VERIFY_STRUCTURE *pvs;
312         _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
313         int old_read_timeout;
314         RESPONSECODE ret;
315         status_t res;
316
317         uint32_t ulDataLength;
318
319         pvs = (PIN_VERIFY_STRUCTURE *)TxBuffer;
320         cmd[0] = 0x69;  /* Secure */
321         cmd[5] = ccid_descriptor->bCurrentSlotIndex;    /* slot number */
322         cmd[6] = (*ccid_descriptor->pbSeq)++;
323         cmd[7] = 0;             /* bBWI */
324         cmd[8] = 0;             /* wLevelParameter */
325         cmd[9] = 0;
326         cmd[10] = 0;    /* bPINOperation: PIN Verification */
327
328         if (TxLength < 19+4 /* 4 = APDU size */)        /* command too short? */
329         {
330                 DEBUG_INFO3("Command too short: %d < %d", TxLength, 19+4);
331                 return IFD_NOT_SUPPORTED;
332         }
333
334         /* On little endian machines we are all set. */
335         /* If on big endian machine and caller is using host byte order */
336         ulDataLength = get_U32(&pvs->ulDataLength);
337         if ((ulDataLength + 19 == TxLength) &&
338                 (bei2i((unsigned char*)(&pvs->ulDataLength)) == ulDataLength))
339         {
340                 DEBUG_INFO1("Reversing order from big to little endian");
341                 /* If ulDataLength is big endian, assume others are too */
342                 /* reverse the byte order for 3 fields */
343                 p_bswap_16(&pvs->wPINMaxExtraDigit);
344                 p_bswap_16(&pvs->wLangId);
345                 p_bswap_32(&pvs->ulDataLength);
346         }
347         /* At this point we now have the above 3 variables in little endian */
348
349         if (dw2i(TxBuffer, 15) + 19 != TxLength) /* ulDataLength field coherency */
350         {
351                 DEBUG_INFO3("Wrong lengths: %d %d", dw2i(TxBuffer, 15) + 19, TxLength);
352                 return IFD_NOT_SUPPORTED;
353         }
354
355         /* make sure bEntryValidationCondition is valid
356          * The Cherry XX44 reader crashes with a wrong value */
357         if ((0x00 == TxBuffer[7]) || (TxBuffer[7] > 0x07))
358         {
359                 DEBUG_INFO2("Correct bEntryValidationCondition (was 0x%02X)",
360                         TxBuffer[7]);
361                 TxBuffer[7] = 0x02;
362         }
363
364 #ifdef BOGUS_PINPAD_FIRMWARE
365         /* bug circumvention for the GemPC Pinpad */
366         if ((GEMPCPINPAD == ccid_descriptor->readerID)
367                 || (VEGAALPHA == ccid_descriptor->readerID))
368         {
369                 /* the firmware reject the cases: 00h No string and FFh default
370                  * CCID message. The only value supported is 01h (display 1 message) */
371                 if (0x01 != TxBuffer[8])
372                 {
373                         DEBUG_INFO2("Correct bNumberMessage for GemPC Pinpad (was %d)",
374                                 TxBuffer[8]);
375                         TxBuffer[8] = 0x01;
376                 }
377
378                 /* The reader does not support, and actively reject, "max size reached"
379                  * and "timeout occured" validation conditions */
380                 if (0x02 != TxBuffer[7])
381                 {
382                         DEBUG_INFO2("Correct bEntryValidationCondition for GemPC Pinpad (was %d)",
383                                 TxBuffer[7]);
384                         TxBuffer[7] = 0x02;     /* validation key pressed */
385                 }
386
387         }
388
389         if ((DELLSCRK == ccid_descriptor->readerID)
390                 || (DELLSK == ccid_descriptor->readerID))
391         {
392                 /* the firmware rejects the cases: 01h-FEh and FFh default
393                  * CCID message. The only value supported is 00h (no message) */
394                 if (0x00 != TxBuffer[8])
395                 {
396                         DEBUG_INFO2("Correct bNumberMessage for Dell keyboard (was %d)",
397                                 TxBuffer[8]);
398                         TxBuffer[8] = 0x00;
399                 }
400
401                 /* avoid the command rejection because the Enter key is still
402                  * pressed. Wait a bit for the key to be released */
403                 (void)usleep(250*1000);
404         }
405
406         if (DELLSK == ccid_descriptor->readerID)
407         {
408                 /* the 2 bytes of wPINMaxExtraDigit are reversed */
409                 int tmp;
410
411                 tmp = TxBuffer[6];
412                 TxBuffer[6] = TxBuffer[5];
413                 TxBuffer[5] = tmp;
414                 DEBUG_INFO1("Correcting wPINMaxExtraDigit for Dell keyboard");
415         }
416 #endif
417
418         /* T=1 Protocol Management for a TPDU reader */
419         if ((SCARD_PROTOCOL_T1 == ccid_descriptor->cardProtocol)
420                 && (CCID_CLASS_TPDU == (ccid_descriptor->dwFeatures & CCID_CLASS_EXCHANGE_MASK)))
421         {
422                 ct_buf_t sbuf;
423                 unsigned char sdata[T1_BUFFER_SIZE];
424
425                 /* Initialize send buffer with the APDU */
426                 ct_buf_set(&sbuf,
427                         (void *)(TxBuffer + offsetof(PIN_VERIFY_STRUCTURE, abData)),
428                         TxLength - offsetof(PIN_VERIFY_STRUCTURE, abData));
429
430                 /* Create T=1 block */
431                 (void)t1_build(&((get_ccid_slot(reader_index))->t1),
432                         sdata, 0, T1_I_BLOCK, &sbuf, NULL);
433
434                 /* Increment the sequence numbers  */
435                 get_ccid_slot(reader_index)->t1.ns ^= 1;
436                 get_ccid_slot(reader_index)->t1.nr ^= 1;
437
438                 /* Copy the generated T=1 block prologue into the teoprologue
439                  * of the CCID command */
440                 memcpy(TxBuffer + offsetof(PIN_VERIFY_STRUCTURE, bTeoPrologue),
441                         sdata, 3);
442         }
443
444         /* Build a CCID block from a PC/SC V2.02.05 Part 10 block */
445         for (a = 11, b = 0; b < TxLength; b++)
446         {
447                 if (1 == b) /* bTimeOut2 field */
448                         /* Ignore the second timeout as there's nothing we can do with
449                          * it currently */
450                         continue;
451
452                 if ((b >= 15) && (b <= 18)) /* ulDataLength field (4 bytes) */
453                         /* the ulDataLength field is not present in the CCID frame
454                          * so do not copy */
455                         continue;
456
457                 /* copy the CCID block 'verbatim' */
458                 cmd[a] = TxBuffer[b];
459                 a++;
460         }
461
462         /* SPR532 and Case 1 APDU */
463         if ((SPR532 == ccid_descriptor->readerID)
464                 /* bmPINBlockString = 0 => PIN length not inserted in APDU */
465                 && (0 == TxBuffer[3])
466                 /* case 1 APDU */
467                 && (4 == TxBuffer[15]))
468         {
469                 RESPONSECODE return_value;
470                 unsigned char cmd_tmp[] = { 0x80, 0x02, 0x00 };
471                 unsigned char res_tmp[1];
472                 unsigned int res_length = sizeof(res_tmp);
473
474                 /* the SPR532 will append the PIN code without any padding */
475                 return_value = CmdEscape(reader_index, cmd_tmp, sizeof(cmd_tmp),
476                         res_tmp, &res_length, 0);
477                 if (return_value != IFD_SUCCESS)
478                         return return_value;
479
480                 /* we need to set bSeq again to avoid a "Duplicate frame detected"
481                  * error since the bSeq of CmdEscape is now greater than bSeq set at
482                  * the beginning of this function */
483                 cmd[6] = (*ccid_descriptor->pbSeq)++;
484         }
485
486         i2dw(a - 10, cmd + 1);  /* CCID message length */
487
488         old_read_timeout = ccid_descriptor -> readTimeout;
489         ccid_descriptor -> readTimeout = max(90, TxBuffer[0]+10)*1000;  /* at least 90 seconds */
490
491         res = WritePort(reader_index, a, cmd);
492         if (STATUS_SUCCESS != res)
493         {
494                 if (STATUS_NO_SUCH_DEVICE == res)
495                         ret = IFD_NO_SUCH_DEVICE;
496                 else
497                         ret = IFD_COMMUNICATION_ERROR;
498                 goto end;
499         }
500
501         ret = CCID_Receive(reader_index, RxLength, RxBuffer, NULL);
502
503         /* T=1 Protocol Management for a TPDU reader */
504         if ((SCARD_PROTOCOL_T1 == ccid_descriptor->cardProtocol)
505                 && (CCID_CLASS_TPDU == (ccid_descriptor->dwFeatures & CCID_CLASS_EXCHANGE_MASK)))
506         {
507                 /* timeout and cancel cases are faked by CCID_Receive() */
508                 if ((2 == *RxLength)
509                         /* the CCID command is rejected or failed */
510                    || (IFD_SUCCESS != ret))
511                 {
512                         /* Decrement the sequence numbers since no TPDU was sent */
513                         get_ccid_slot(reader_index)->t1.ns ^= 1;
514                         get_ccid_slot(reader_index)->t1.nr ^= 1;
515                 }
516                 else
517                 {
518                         /* FIXME: manage T=1 error blocks */
519
520                         /* defines from openct/proto-t1.c */
521                         #define PCB 1
522                         #define DATA 3
523                         #define T1_S_BLOCK              0xC0
524                         #define T1_S_RESPONSE           0x20
525                         #define T1_S_TYPE(pcb)          ((pcb) & 0x0F)
526                         #define T1_S_WTX                0x03
527
528                         /* WTX S-block */
529                         if ((T1_S_BLOCK | T1_S_WTX) == RxBuffer[PCB])
530                         {
531 /*
532  * The Swiss health care card sends a WTX request before returning the
533  * SW code. If the reader is in TPDU the driver must manage the request
534  * itself.
535  *
536  * received: 00 C3 01 09 CB
537  * openct/proto-t1.c:432:t1_transceive() S-Block request received
538  * openct/proto-t1.c:489:t1_transceive() CT sent S-block with wtx=9
539  * sending: 00 E3 01 09 EB
540  * openct/proto-t1.c:667:t1_xcv() New timeout at WTX request: 23643 sec
541  * received: 00 40 02 90 00 D2
542 */
543                                 ct_buf_t tbuf;
544                                 unsigned char sblk[1]; /* we only need 1 byte of data */
545                                 t1_state_t *t1 = &get_ccid_slot(reader_index)->t1;
546                                 unsigned int slen;
547                                 int oldReadTimeout;
548
549                                 DEBUG_COMM2("CT sent S-block with wtx=%u", RxBuffer[DATA]);
550                                 t1->wtx = RxBuffer[DATA];
551
552                                 oldReadTimeout = ccid_descriptor->readTimeout;
553                                 if (t1->wtx > 1)
554                                 {
555                                         /* set the new temporary timeout at WTX card request */
556                                         ccid_descriptor->readTimeout *= t1->wtx;
557                                         DEBUG_INFO2("New timeout at WTX request: %d sec",
558                                                         ccid_descriptor->readTimeout);
559                                 }
560
561                                 ct_buf_init(&tbuf, sblk, sizeof(sblk));
562                                 t1->wtx = RxBuffer[DATA];
563                                 ct_buf_putc(&tbuf, RxBuffer[DATA]);
564
565                                 slen = t1_build(t1, RxBuffer, 0,
566                                         T1_S_BLOCK | T1_S_RESPONSE | T1_S_TYPE(RxBuffer[PCB]),
567                                         &tbuf, NULL);
568
569                                 ret = CCID_Transmit(t1 -> lun, slen, RxBuffer, 0, t1->wtx);
570                                 if (ret != IFD_SUCCESS)
571                                         return ret;
572
573                                 /* I guess we have at least 6 bytes in RxBuffer */
574                                 *RxLength = 6;
575                                 ret = CCID_Receive(reader_index, RxLength, RxBuffer, NULL);
576                                 if (ret != IFD_SUCCESS)
577                                         return ret;
578
579                                 /* Restore initial timeout */
580                                 ccid_descriptor->readTimeout = oldReadTimeout;
581                         }
582
583                         /* get only the T=1 data */
584                         memmove(RxBuffer, RxBuffer+3, *RxLength -4);
585                         *RxLength -= 4; /* remove NAD, PCB, LEN and CRC */
586                 }
587         }
588
589 end:
590         ccid_descriptor -> readTimeout = old_read_timeout;
591         return ret;
592 } /* SecurePINVerify */
593
594
595 #ifdef BOGUS_PINPAD_FIRMWARE
596 /*****************************************************************************
597  *
598  *                                      has_gemalto_modify_pin_bug
599  *
600  ****************************************************************************/
601 static int has_gemalto_modify_pin_bug(_ccid_descriptor *ccid_descriptor)
602 {
603         /* Bug not present by default */
604         int has_bug = 0;
605
606         /* Covadis Véga-Alpha reader */
607         if (VEGAALPHA == ccid_descriptor->readerID)
608         {
609                 /* This reader has the bug (uses a Gemalto firmware) */
610                 has_bug = 1;
611         }
612         else
613         {
614                 /* Gemalto reader */
615                 if ((GET_VENDOR(ccid_descriptor->readerID) == VENDOR_GEMALTO))
616                 {
617                         has_bug = 1; /* assume it has the bug */
618
619                         if (ccid_descriptor->gemalto_firmware_features &&
620                                 ccid_descriptor->gemalto_firmware_features->bNumberMessageFix)
621                         {
622                                 /* A Gemalto reader has the ModifyPIN structure bug */
623                                 /* unless it explicitly reports it has been fixed */
624                                 has_bug = 0;
625                         }
626                 }
627         }
628
629         return has_bug;
630 } /* has_gemalto_modify_pin_bug */
631 #endif
632
633 /*****************************************************************************
634  *
635  *                                      SecurePINModify
636  *
637  ****************************************************************************/
638 RESPONSECODE SecurePINModify(unsigned int reader_index,
639         unsigned char TxBuffer[], unsigned int TxLength,
640         unsigned char RxBuffer[], unsigned int *RxLength)
641 {
642         unsigned char cmd[11+19+TxLength];
643         unsigned int a, b;
644         PIN_MODIFY_STRUCTURE *pms;
645         _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
646         int old_read_timeout;
647         RESPONSECODE ret;
648         status_t res;
649 #ifdef BOGUS_PINPAD_FIRMWARE
650         int bNumberMessage = 0; /* for GemPC Pinpad */
651         int gemalto_modify_pin_bug;
652 #endif
653         uint32_t ulDataLength;
654
655         pms = (PIN_MODIFY_STRUCTURE *)TxBuffer;
656         cmd[0] = 0x69;  /* Secure */
657         cmd[5] = ccid_descriptor->bCurrentSlotIndex;    /* slot number */
658         cmd[6] = (*ccid_descriptor->pbSeq)++;
659         cmd[7] = 0;             /* bBWI */
660         cmd[8] = 0;             /* wLevelParameter */
661         cmd[9] = 0;
662         cmd[10] = 1;    /* bPINOperation: PIN Modification */
663
664         if (TxLength < 24+4 /* 4 = APDU size */) /* command too short? */
665         {
666                 DEBUG_INFO3("Command too short: %d < %d", TxLength, 24+4);
667                 return IFD_NOT_SUPPORTED;
668         }
669
670         /* On little endian machines we are all set. */
671         /* If on big endian machine and caller is using host byte order */
672         ulDataLength = get_U32(&pms->ulDataLength);
673         if ((ulDataLength + 24 == TxLength) &&
674                 (bei2i((unsigned char*)(&pms->ulDataLength)) == ulDataLength))
675         {
676                 DEBUG_INFO1("Reversing order from big to little endian");
677                 /* If ulDataLength is big endian, assume others are too */
678                 /* reverse the byte order for 3 fields */
679                 p_bswap_16(&pms->wPINMaxExtraDigit);
680                 p_bswap_16(&pms->wLangId);
681                 p_bswap_32(&pms->ulDataLength);
682         }
683         /* At this point we now have the above 3 variables in little endian */
684
685
686         if (dw2i(TxBuffer, 20) + 24 != TxLength) /* ulDataLength field coherency */
687         {
688                 DEBUG_INFO3("Wrong lengths: %d %d", dw2i(TxBuffer, 20) + 24, TxLength);
689                 return IFD_NOT_SUPPORTED;
690         }
691
692         /* Make sure in the beginning if bNumberMessage is valid or not.
693          * 0xFF is the default value. */
694         if ((TxBuffer[11] > 3) && (TxBuffer[11] != 0xFF))
695         {
696                 DEBUG_INFO2("Wrong bNumberMessage: %d", TxBuffer[11]);
697                 return IFD_NOT_SUPPORTED;
698         }
699
700         /* Make sure bEntryValidationCondition is valid
701          * The Cherry XX44 reader crashes with a wrong value */
702         if ((0x00 == TxBuffer[10]) || (TxBuffer[10] > 0x07))
703         {
704                 DEBUG_INFO2("Correct bEntryValidationCondition (was 0x%02X)",
705                         TxBuffer[10]);
706                 TxBuffer[10] = 0x02;
707         }
708
709 #ifdef BOGUS_PINPAD_FIRMWARE
710         /* some firmwares are buggy so we try to "correct" the frame */
711         /*
712          * SPR 532 and Cherry ST 2000C has no display but requires _all_
713          * bMsgIndex fields with bNumberMessage set to 0.
714          */
715         if ((SPR532 == ccid_descriptor->readerID)
716                 || (CHERRYST2000 == ccid_descriptor->readerID))
717         {
718                 TxBuffer[11] = 0x03; /* set bNumberMessage to 3 so that
719                                                                 all bMsgIndex123 are filled */
720                 TxBuffer[14] = TxBuffer[15] = TxBuffer[16] = 0; /* bMsgIndex123 */
721         }
722
723         /* the bug is a bit different than for the Cherry ST 2000C
724          * with bNumberMessage < 3 the command seems to be accepted
725          * and the card sends 6B 80 */
726         if (CHERRYXX44 == ccid_descriptor->readerID)
727         {
728                 TxBuffer[11] = 0x03; /* set bNumberMessage to 3 so that
729                                                                 all bMsgIndex123 are filled */
730         }
731
732         /* bug circumvention for the GemPC Pinpad */
733         if ((GEMPCPINPAD == ccid_descriptor->readerID)
734                 || (VEGAALPHA == ccid_descriptor->readerID))
735         {
736                 /* The reader does not support, and actively reject, "max size reached"
737                  * and "timeout occured" validation conditions */
738                 if (0x02 != TxBuffer[10])
739                 {
740                         DEBUG_INFO2("Correct bEntryValidationCondition for GemPC Pinpad (was %d)",
741                                 TxBuffer[10]);
742                         TxBuffer[10] = 0x02;    /* validation key pressed */
743                 }
744         }
745
746         gemalto_modify_pin_bug = has_gemalto_modify_pin_bug(ccid_descriptor);
747         if (gemalto_modify_pin_bug)
748         {
749                 DEBUG_INFO1("Gemalto CCID Modify Pin Bug");
750
751                 /* The reader requests a value for bMsgIndex2 and bMsgIndex3
752                  * even if they should not be present. So we fake
753                  * bNumberMessage=3.  The real number of messages will be
754                  * corrected later in the code */
755                 bNumberMessage = TxBuffer[11];
756                 if (0x03 != TxBuffer[11])
757                 {
758                         DEBUG_INFO2("Correct bNumberMessage for GemPC Pinpad (was %d)",
759                                 TxBuffer[11]);
760                         TxBuffer[11] = 0x03; /* 3 messages */
761                 }
762         }
763
764         /* Bug workaround for Cherry KC 1000 SC */
765         if (CHERRY_KC1000SC == ccid_descriptor->readerID)
766         {
767                 /* The reader rejects bNumberMessage 0x00 in a PIN modify
768                  * command. Change it to 0xff which is accepted. */
769                 if (0x00 == TxBuffer[11])
770                 {
771                         DEBUG_INFO1("Correct bNumberMessage for Cherry KC 1000 SC (was 0)");
772                         TxBuffer[11] = 0xff;
773                 }
774         }
775 #endif
776
777         /* T=1 Protocol Management for a TPDU reader */
778         if ((SCARD_PROTOCOL_T1 == ccid_descriptor->cardProtocol)
779                 && (CCID_CLASS_TPDU == (ccid_descriptor->dwFeatures & CCID_CLASS_EXCHANGE_MASK)))
780         {
781                 ct_buf_t sbuf;
782                 unsigned char sdata[T1_BUFFER_SIZE];
783
784                 /* Initialize send buffer with the APDU */
785                 ct_buf_set(&sbuf,
786                         (void *)(TxBuffer + offsetof(PIN_MODIFY_STRUCTURE, abData)),
787                         TxLength - offsetof(PIN_MODIFY_STRUCTURE, abData));
788
789                 /* Create T=1 block */
790                 (void)t1_build(&((get_ccid_slot(reader_index))->t1),
791                         sdata, 0, T1_I_BLOCK, &sbuf, NULL);
792
793                 /* Increment the sequence numbers  */
794                 get_ccid_slot(reader_index)->t1.ns ^= 1;
795                 get_ccid_slot(reader_index)->t1.nr ^= 1;
796
797                 /* Copy the generated T=1 block prologue into the teoprologue
798                  * of the CCID command */
799                 memcpy(TxBuffer + offsetof(PIN_MODIFY_STRUCTURE, bTeoPrologue),
800                         sdata, 3);
801         }
802
803         /* Build a CCID block from a PC/SC V2.02.05 Part 10 block */
804
805         /* Do adjustments as needed - CCID spec is not exact with some
806          * details in the format of the structure, per-reader adaptions
807          * might be needed.
808          */
809         for (a = 11, b = 0; b < TxLength; b++)
810         {
811                 if (1 == b) /* bTimeOut2 */
812                         /* Ignore the second timeout as there's nothing we can do with it
813                          * currently */
814                         continue;
815
816                 if (15 == b) /* bMsgIndex2 */
817                 {
818                         /* in CCID the bMsgIndex2 is present only if bNumberMessage != 0 */
819                         if (0 == TxBuffer[11])
820                                 continue;
821                 }
822
823                 if (16 == b) /* bMsgIndex3 */
824                 {
825                         /* in CCID the bMsgIndex3 is present only if bNumberMessage == 3 */
826                         if (TxBuffer[11] < 3)
827                                 continue;
828                 }
829
830                 if ((b >= 20) && (b <= 23)) /* ulDataLength field (4 bytes) */
831                         /* the ulDataLength field is not present in the CCID frame
832                          * so do not copy */
833                         continue;
834
835                 /* copy to the CCID block 'verbatim' */
836                 cmd[a] = TxBuffer[b];
837                 a++;
838         }
839
840 #ifdef BOGUS_PINPAD_FIRMWARE
841         if ((SPR532 == ccid_descriptor->readerID)
842                 || (CHERRYST2000 == ccid_descriptor->readerID))
843         {
844                 cmd[21] = 0x00; /* set bNumberMessage to 0 */
845         }
846
847         if (gemalto_modify_pin_bug)
848                 cmd[21] = bNumberMessage;       /* restore the real value */
849 #endif
850
851         /* We know the size of the CCID message now */
852         i2dw(a - 10, cmd + 1);  /* command length (includes bPINOperation) */
853
854         old_read_timeout = ccid_descriptor -> readTimeout;
855         ccid_descriptor -> readTimeout = max(90, TxBuffer[0]+10)*1000;  /* at least 90 seconds */
856
857         res = WritePort(reader_index, a, cmd);
858         if (STATUS_SUCCESS != res)
859         {
860                 if (STATUS_NO_SUCH_DEVICE == res)
861                         ret = IFD_NO_SUCH_DEVICE;
862                 else
863                         ret = IFD_COMMUNICATION_ERROR;
864                 goto end;
865         }
866
867         ret = CCID_Receive(reader_index, RxLength, RxBuffer, NULL);
868
869         /* T=1 Protocol Management for a TPDU reader */
870         if ((SCARD_PROTOCOL_T1 == ccid_descriptor->cardProtocol)
871                 && (CCID_CLASS_TPDU == (ccid_descriptor->dwFeatures & CCID_CLASS_EXCHANGE_MASK)))
872         {
873                 /* timeout and cancel cases are faked by CCID_Receive() */
874                 if ((2 == *RxLength)
875                         /* the CCID command is rejected or failed */
876                         || (IFD_SUCCESS != ret))
877                 {
878                         /* Decrement the sequence numbers since no TPDU was sent */
879                         get_ccid_slot(reader_index)->t1.ns ^= 1;
880                         get_ccid_slot(reader_index)->t1.nr ^= 1;
881                 }
882                 else
883                 {
884                         /* get only the T=1 data */
885                         /* FIXME: manage T=1 error blocks */
886                         memmove(RxBuffer, RxBuffer+3, *RxLength -4);
887                         *RxLength -= 4; /* remove NAD, PCB, LEN and CRC */
888                 }
889         }
890
891 end:
892         ccid_descriptor -> readTimeout = old_read_timeout;
893         return ret;
894 } /* SecurePINModify */
895
896
897 /*****************************************************************************
898  *
899  *                                      Escape
900  *
901  ****************************************************************************/
902 RESPONSECODE CmdEscape(unsigned int reader_index,
903         const unsigned char TxBuffer[], unsigned int TxLength,
904         unsigned char RxBuffer[], unsigned int *RxLength, unsigned int timeout)
905 {
906         return CmdEscapeCheck(reader_index, TxBuffer, TxLength, RxBuffer, RxLength,
907                 timeout, FALSE);
908 } /* CmdEscape */
909
910
911 /*****************************************************************************
912  *
913  *                                      Escape (with check of gravity)
914  *
915  ****************************************************************************/
916 RESPONSECODE CmdEscapeCheck(unsigned int reader_index,
917         const unsigned char TxBuffer[], unsigned int TxLength,
918         unsigned char RxBuffer[], unsigned int *RxLength, unsigned int timeout,
919         int mayfail)
920 {
921         unsigned char *cmd_in, *cmd_out;
922         status_t res;
923         unsigned int length_in, length_out;
924         RESPONSECODE return_value = IFD_SUCCESS;
925         int old_read_timeout;
926         _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
927
928         /* a value of 0 do not change the default read timeout */
929         if (timeout > 0)
930         {
931                 old_read_timeout = ccid_descriptor -> readTimeout;
932                 ccid_descriptor -> readTimeout = timeout;
933         }
934
935 again:
936         /* allocate buffers */
937         length_in = 10 + TxLength;
938         if (NULL == (cmd_in = malloc(length_in)))
939         {
940                 return_value = IFD_COMMUNICATION_ERROR;
941                 goto end;
942         }
943
944         length_out = 10 + *RxLength;
945         if (NULL == (cmd_out = malloc(length_out)))
946         {
947                 free(cmd_in);
948                 return_value = IFD_COMMUNICATION_ERROR;
949                 goto end;
950         }
951
952         cmd_in[0] = 0x6B; /* PC_to_RDR_Escape */
953         i2dw(length_in - 10, cmd_in+1); /* dwLength */
954         cmd_in[5] = ccid_descriptor->bCurrentSlotIndex; /* slot number */
955         cmd_in[6] = (*ccid_descriptor->pbSeq)++;
956         cmd_in[7] = cmd_in[8] = cmd_in[9] = 0; /* RFU */
957
958         /* copy the command */
959         memcpy(&cmd_in[10], TxBuffer, TxLength);
960
961         res = WritePort(reader_index, length_in, cmd_in);
962         free(cmd_in);
963         if (res != STATUS_SUCCESS)
964         {
965                 free(cmd_out);
966                 if (STATUS_NO_SUCH_DEVICE == res)
967                         return_value = IFD_NO_SUCH_DEVICE;
968                 else
969                         return_value = IFD_COMMUNICATION_ERROR;
970                 goto end;
971         }
972
973 time_request:
974         length_out = 10 + *RxLength;
975         res = ReadPort(reader_index, &length_out, cmd_out);
976
977         /* replay the command if NAK
978          * This (generally) happens only for the first command sent to the reader
979          * with the serial protocol so it is not really needed for all the other
980          * ReadPort() calls */
981         if (STATUS_COMM_NAK == res)
982         {
983                 free(cmd_out);
984                 goto again;
985         }
986
987         if (res != STATUS_SUCCESS)
988         {
989                 free(cmd_out);
990                 if (STATUS_NO_SUCH_DEVICE == res)
991                         return_value = IFD_NO_SUCH_DEVICE;
992                 else
993                         return_value = IFD_COMMUNICATION_ERROR;
994                 goto end;
995         }
996
997         if (length_out < STATUS_OFFSET+1)
998         {
999                 free(cmd_out);
1000                 DEBUG_CRITICAL2("Not enough data received: %d bytes", length_out);
1001                 return_value = IFD_COMMUNICATION_ERROR;
1002                 goto end;
1003         }
1004
1005         if (cmd_out[STATUS_OFFSET] & CCID_TIME_EXTENSION)
1006         {
1007                 DEBUG_COMM2("Time extension requested: 0x%02X", cmd_out[ERROR_OFFSET]);
1008                 goto time_request;
1009         }
1010
1011         if (cmd_out[STATUS_OFFSET] & CCID_COMMAND_FAILED)
1012         {
1013                 /* mayfail: the error may be expected and not fatal */
1014                 ccid_error(mayfail ? PCSC_LOG_INFO : PCSC_LOG_ERROR,
1015                         cmd_out[ERROR_OFFSET], __FILE__, __LINE__, __FUNCTION__);    /* bError */
1016                 return_value = IFD_COMMUNICATION_ERROR;
1017         }
1018
1019         /* copy the response */
1020         length_out = dw2i(cmd_out, 1);
1021         if (length_out > *RxLength)
1022         {
1023                 length_out = *RxLength;
1024                 return_value = IFD_ERROR_INSUFFICIENT_BUFFER;
1025         }
1026         *RxLength = length_out;
1027         memcpy(RxBuffer, &cmd_out[10], length_out);
1028
1029         free(cmd_out);
1030
1031 end:
1032         if (timeout > 0)
1033                 ccid_descriptor -> readTimeout = old_read_timeout;
1034
1035         return return_value;
1036 } /* EscapeCheck */
1037
1038
1039 /*****************************************************************************
1040  *
1041  *                                      CmdPowerOff
1042  *
1043  ****************************************************************************/
1044 RESPONSECODE CmdPowerOff(unsigned int reader_index)
1045 {
1046         unsigned char cmd[10];
1047         status_t res;
1048         unsigned int length;
1049         RESPONSECODE return_value = IFD_SUCCESS;
1050         _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
1051
1052 #ifndef TWIN_SERIAL
1053         if (PROTOCOL_ICCD_A == ccid_descriptor->bInterfaceProtocol)
1054         {
1055                 int r;
1056
1057                 /* PowerOff */
1058                 r = ControlUSB(reader_index, 0x21, 0x63, 0, NULL, 0);
1059
1060                 /* we got an error? */
1061                 if (r < 0)
1062                 {
1063                         DEBUG_INFO2("ICC Power Off failed: %s", strerror(errno));
1064                         return IFD_COMMUNICATION_ERROR;
1065                 }
1066
1067                 return IFD_SUCCESS;
1068         }
1069
1070         if (PROTOCOL_ICCD_B == ccid_descriptor->bInterfaceProtocol)
1071         {
1072                 int r;
1073                 unsigned char buffer[3];
1074
1075                 /* PowerOff */
1076                 r = ControlUSB(reader_index, 0x21, 0x63, 0, NULL, 0);
1077
1078                 /* we got an error? */
1079                 if (r < 0)
1080                 {
1081                         DEBUG_INFO2("ICC Power Off failed: %s", strerror(errno));
1082                         return IFD_COMMUNICATION_ERROR;
1083                 }
1084
1085                 /* SlotStatus */
1086                 r = ControlUSB(reader_index, 0xA1, 0x81, 0, buffer, sizeof(buffer));
1087
1088                 /* we got an error? */
1089                 if (r < 0)
1090                 {
1091                         DEBUG_INFO2("ICC SlotStatus failed: %s", strerror(errno));
1092                         return IFD_COMMUNICATION_ERROR;
1093                 }
1094
1095                 return IFD_SUCCESS;
1096         }
1097 #endif
1098
1099         cmd[0] = 0x63; /* IccPowerOff */
1100         cmd[1] = cmd[2] = cmd[3] = cmd[4] = 0;  /* dwLength */
1101         cmd[5] = ccid_descriptor->bCurrentSlotIndex;    /* slot number */
1102         cmd[6] = (*ccid_descriptor->pbSeq)++;
1103         cmd[7] = cmd[8] = cmd[9] = 0; /* RFU */
1104
1105         res = WritePort(reader_index, sizeof(cmd), cmd);
1106         CHECK_STATUS(res)
1107
1108         length = sizeof(cmd);
1109         res = ReadPort(reader_index, &length, cmd);
1110         CHECK_STATUS(res)
1111
1112         if (length < STATUS_OFFSET+1)
1113         {
1114                 DEBUG_CRITICAL2("Not enough data received: %d bytes", length);
1115                 return IFD_COMMUNICATION_ERROR;
1116         }
1117
1118         if (cmd[STATUS_OFFSET] & CCID_COMMAND_FAILED)
1119         {
1120                 ccid_error(PCSC_LOG_ERROR, cmd[ERROR_OFFSET], __FILE__, __LINE__, __FUNCTION__);    /* bError */
1121                 return_value = IFD_COMMUNICATION_ERROR;
1122         }
1123
1124         return return_value;
1125 } /* CmdPowerOff */
1126
1127
1128 /*****************************************************************************
1129  *
1130  *                                      CmdGetSlotStatus
1131  *
1132  ****************************************************************************/
1133 RESPONSECODE CmdGetSlotStatus(unsigned int reader_index, unsigned char buffer[])
1134 {
1135         unsigned char cmd[10];
1136         status_t res;
1137         unsigned int length;
1138         RESPONSECODE return_value = IFD_SUCCESS;
1139         _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
1140
1141 #ifndef TWIN_SERIAL
1142         if (PROTOCOL_ICCD_A == ccid_descriptor->bInterfaceProtocol)
1143         {
1144                 int r;
1145                 unsigned char status[1];
1146
1147 again_status:
1148                 /* SlotStatus */
1149                 r = ControlUSB(reader_index, 0xA1, 0xA0, 0, status, sizeof(status));
1150
1151                 /* we got an error? */
1152                 if (r < 0)
1153                 {
1154                         DEBUG_INFO2("ICC Slot Status failed: %s", strerror(errno));
1155                         if (ENODEV == errno)
1156                                 return IFD_NO_SUCH_DEVICE;
1157                         return IFD_COMMUNICATION_ERROR;
1158                 }
1159
1160                 /* busy */
1161                 if (status[0] & 0x40)
1162                 {
1163                         DEBUG_INFO2("Busy: 0x%02X", status[0]);
1164                         (void)usleep(1000 * 10);
1165                         goto again_status;
1166                 }
1167
1168                 /* simulate a CCID bStatus */
1169                 /* present and active by default */
1170                 buffer[7] = CCID_ICC_PRESENT_ACTIVE;
1171
1172                 /* mute */
1173                 if (0x80 == status[0])
1174                         buffer[7] = CCID_ICC_ABSENT;
1175
1176                 /* store the status for CmdXfrBlockCHAR_T0() */
1177                 buffer[0] = status[0];
1178
1179                 return IFD_SUCCESS;
1180         }
1181
1182         if (PROTOCOL_ICCD_B == ccid_descriptor->bInterfaceProtocol)
1183         {
1184                 int r;
1185                 unsigned char buffer_tmp[3];
1186
1187                 /* SlotStatus */
1188                 r = ControlUSB(reader_index, 0xA1, 0x81, 0, buffer_tmp,
1189                         sizeof(buffer_tmp));
1190
1191                 /* we got an error? */
1192                 if (r < 0)
1193                 {
1194                         DEBUG_INFO2("ICC Slot Status failed: %s", strerror(errno));
1195                         if (ENODEV == errno)
1196                                 return IFD_NO_SUCH_DEVICE;
1197                         return IFD_COMMUNICATION_ERROR;
1198                 }
1199
1200                 /* simulate a CCID bStatus */
1201                 switch (buffer_tmp[1] & 0x03)
1202                 {
1203                         case 0:
1204                                 buffer[7] = CCID_ICC_PRESENT_ACTIVE;
1205                                 break;
1206                         case 1:
1207                                 buffer[7] = CCID_ICC_PRESENT_INACTIVE;
1208                                 break;
1209                         case 2:
1210                         case 3:
1211                                 buffer[7] = CCID_ICC_ABSENT;
1212                 }
1213                 return IFD_SUCCESS;
1214         }
1215 #endif
1216
1217 #ifdef __APPLE__
1218         if (MICROCHIP_SEC1100 == ccid_descriptor->readerID)
1219                 InterruptRead(reader_index, 10);
1220 #endif
1221
1222         cmd[0] = 0x65; /* GetSlotStatus */
1223         cmd[1] = cmd[2] = cmd[3] = cmd[4] = 0;  /* dwLength */
1224         cmd[5] = ccid_descriptor->bCurrentSlotIndex;    /* slot number */
1225         cmd[6] = (*ccid_descriptor->pbSeq)++;
1226         cmd[7] = cmd[8] = cmd[9] = 0; /* RFU */
1227
1228         res = WritePort(reader_index, sizeof(cmd), cmd);
1229         CHECK_STATUS(res)
1230
1231         length = SIZE_GET_SLOT_STATUS;
1232         res = ReadPort(reader_index, &length, buffer);
1233         CHECK_STATUS(res)
1234
1235         if (length < STATUS_OFFSET+1)
1236         {
1237                 DEBUG_CRITICAL2("Not enough data received: %d bytes", length);
1238                 return IFD_COMMUNICATION_ERROR;
1239         }
1240
1241         if ((buffer[STATUS_OFFSET] & CCID_COMMAND_FAILED)
1242                 /* card absent or mute is not an communication error */
1243                 && (buffer[ERROR_OFFSET] != 0xFE))
1244         {
1245                 return_value = IFD_COMMUNICATION_ERROR;
1246                 ccid_error(PCSC_LOG_ERROR, buffer[ERROR_OFFSET], __FILE__, __LINE__, __FUNCTION__);    /* bError */
1247         }
1248
1249         return return_value;
1250 } /* CmdGetSlotStatus */
1251
1252
1253 /*****************************************************************************
1254  *
1255  *                                      CmdXfrBlock
1256  *
1257  ****************************************************************************/
1258 RESPONSECODE CmdXfrBlock(unsigned int reader_index, unsigned int tx_length,
1259         unsigned char tx_buffer[], unsigned int *rx_length,
1260         unsigned char rx_buffer[], int protocol)
1261 {
1262         RESPONSECODE return_value = IFD_SUCCESS;
1263         _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
1264
1265         /* APDU or TPDU? */
1266         switch (ccid_descriptor->dwFeatures & CCID_CLASS_EXCHANGE_MASK)
1267         {
1268                 case CCID_CLASS_TPDU:
1269                         if (protocol == T_0)
1270                                 return_value = CmdXfrBlockTPDU_T0(reader_index,
1271                                         tx_length, tx_buffer, rx_length, rx_buffer);
1272                         else
1273                                 if (protocol == T_1)
1274                                         return_value = CmdXfrBlockTPDU_T1(reader_index, tx_length,
1275                                                 tx_buffer, rx_length, rx_buffer);
1276                                 else
1277                                         return_value = IFD_PROTOCOL_NOT_SUPPORTED;
1278                         break;
1279
1280                 case CCID_CLASS_SHORT_APDU:
1281                         return_value = CmdXfrBlockTPDU_T0(reader_index,
1282                                 tx_length, tx_buffer, rx_length, rx_buffer);
1283                         break;
1284
1285                 case CCID_CLASS_EXTENDED_APDU:
1286                         return_value = CmdXfrBlockAPDU_extended(reader_index,
1287                                 tx_length, tx_buffer, rx_length, rx_buffer);
1288                         break;
1289
1290                 case CCID_CLASS_CHARACTER:
1291                         if (protocol == T_0)
1292                                 return_value = CmdXfrBlockCHAR_T0(reader_index, tx_length,
1293                                         tx_buffer, rx_length, rx_buffer);
1294                         else
1295                                 if (protocol == T_1)
1296                                         return_value = CmdXfrBlockTPDU_T1(reader_index, tx_length,
1297                                                 tx_buffer, rx_length, rx_buffer);
1298                                 else
1299                                         return_value = IFD_PROTOCOL_NOT_SUPPORTED;
1300                         break;
1301
1302                 default:
1303                         return_value = IFD_COMMUNICATION_ERROR;
1304         }
1305
1306         return return_value;
1307 } /* CmdXfrBlock */
1308
1309
1310 /*****************************************************************************
1311  *
1312  *                                      CCID_Transmit
1313  *
1314  ****************************************************************************/
1315 RESPONSECODE CCID_Transmit(unsigned int reader_index, unsigned int tx_length,
1316         const unsigned char tx_buffer[], unsigned short rx_length, unsigned char bBWI)
1317 {
1318         unsigned char cmd[10+tx_length];        /* CCID + APDU buffer */
1319         _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
1320         status_t ret;
1321
1322 #ifndef TWIN_SERIAL
1323         if (PROTOCOL_ICCD_A == ccid_descriptor->bInterfaceProtocol)
1324         {
1325                 int r;
1326
1327                 /* Xfr Block */
1328                 r = ControlUSB(reader_index, 0x21, 0x65, 0,
1329                         (unsigned char *)tx_buffer, tx_length);
1330
1331                 /* we got an error? */
1332                 if (r < 0)
1333                 {
1334                         DEBUG_INFO2("ICC Xfr Block failed: %s", strerror(errno));
1335                         return IFD_COMMUNICATION_ERROR;
1336                 }
1337
1338                 return IFD_SUCCESS;
1339         }
1340
1341         if (PROTOCOL_ICCD_B == ccid_descriptor->bInterfaceProtocol)
1342         {
1343                 int r;
1344
1345                 /* nul block so we are chaining */
1346                 if (NULL == tx_buffer)
1347                         rx_length = 0x10;       /* bLevelParameter */
1348
1349                 /* Xfr Block */
1350                 DEBUG_COMM2("chain parameter: %d", rx_length);
1351                 r = ControlUSB(reader_index, 0x21, 0x65, rx_length << 8,
1352                         (unsigned char *)tx_buffer, tx_length);
1353
1354                 /* we got an error? */
1355                 if (r < 0)
1356                 {
1357                         DEBUG_INFO2("ICC Xfr Block failed: %s", strerror(errno));
1358                         return IFD_COMMUNICATION_ERROR;
1359                 }
1360
1361                 return IFD_SUCCESS;
1362         }
1363 #endif
1364
1365         cmd[0] = 0x6F; /* XfrBlock */
1366         i2dw(tx_length, cmd+1); /* APDU length */
1367         cmd[5] = ccid_descriptor->bCurrentSlotIndex;    /* slot number */
1368         cmd[6] = (*ccid_descriptor->pbSeq)++;
1369         cmd[7] = bBWI;  /* extend block waiting timeout */
1370         cmd[8] = rx_length & 0xFF;      /* Expected length, in character mode only */
1371         cmd[9] = (rx_length >> 8) & 0xFF;
1372
1373         memcpy(cmd+10, tx_buffer, tx_length);
1374
1375         ret = WritePort(reader_index, 10+tx_length, cmd);
1376         CHECK_STATUS(ret)
1377
1378         return IFD_SUCCESS;
1379 } /* CCID_Transmit */
1380
1381
1382 /*****************************************************************************
1383  *
1384  *                                      CCID_Receive
1385  *
1386  ****************************************************************************/
1387 RESPONSECODE CCID_Receive(unsigned int reader_index, unsigned int *rx_length,
1388         unsigned char rx_buffer[], unsigned char *chain_parameter)
1389 {
1390         unsigned char cmd[10+CMD_BUF_SIZE];     /* CCID + APDU buffer */
1391         unsigned int length;
1392         RESPONSECODE return_value = IFD_SUCCESS;
1393         status_t ret;
1394         _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
1395         unsigned int old_timeout;
1396
1397 #ifndef TWIN_SERIAL
1398         if (PROTOCOL_ICCD_A == ccid_descriptor->bInterfaceProtocol)
1399         {
1400                 unsigned char pcbuffer[SIZE_GET_SLOT_STATUS];
1401                 int r;
1402
1403                 /* wait for ready */
1404                 r = CmdGetSlotStatus(reader_index, pcbuffer);
1405                 if (r != IFD_SUCCESS)
1406                         return r;
1407
1408                 /* Data Block */
1409                 r = ControlUSB(reader_index, 0xA1, 0x6F, 0, rx_buffer, *rx_length);
1410
1411                 /* we got an error? */
1412                 if (r < 0)
1413                 {
1414                         DEBUG_INFO2("ICC Data Block failed: %s", strerror(errno));
1415                         return IFD_COMMUNICATION_ERROR;
1416                 }
1417
1418                 /* we need to store returned value */
1419                 *rx_length = r;
1420
1421                 return IFD_SUCCESS;
1422         }
1423
1424         if (PROTOCOL_ICCD_B == ccid_descriptor->bInterfaceProtocol)
1425         {
1426                 int r;
1427                 unsigned char rx_tmp[4];
1428                 unsigned char *old_rx_buffer = NULL;
1429                 int old_rx_length = 0;
1430
1431                 /* read a nul block. buffer need to be at least 4-bytes */
1432                 if (NULL == rx_buffer)
1433                 {
1434                         rx_buffer = rx_tmp;
1435                         *rx_length = sizeof(rx_tmp);
1436                 }
1437
1438                 /* the buffer must be 4 bytes minimum for ICCD-B */
1439                 if (*rx_length < 4)
1440                 {
1441                         old_rx_buffer = rx_buffer;
1442                         old_rx_length = *rx_length;
1443                         rx_buffer = rx_tmp;
1444                         *rx_length = sizeof(rx_tmp);
1445                 }
1446
1447 time_request_ICCD_B:
1448                 /* Data Block */
1449                 r = ControlUSB(reader_index, 0xA1, 0x6F, 0, rx_buffer, *rx_length);
1450
1451                 /* we got an error? */
1452                 if (r < 0)
1453                 {
1454                         DEBUG_INFO2("ICC Data Block failed: %s", strerror(errno));
1455                         return IFD_COMMUNICATION_ERROR;
1456                 }
1457
1458                 /* copy from the 4 bytes buffer if used */
1459                 if (old_rx_buffer)
1460                 {
1461                         memcpy(old_rx_buffer, rx_buffer, min(r, old_rx_length));
1462                         rx_buffer = old_rx_buffer;
1463                 }
1464
1465                 /* bResponseType */
1466                 switch (rx_buffer[0])
1467                 {
1468                         case 0x00:
1469                                 /* the abData field contains the information created by the
1470                                  * preceding request */
1471                                 break;
1472
1473                         case 0x40:
1474                                 /* Status Information */
1475                                 ccid_error(PCSC_LOG_ERROR, rx_buffer[2], __FILE__, __LINE__, __FUNCTION__);
1476                                 return IFD_COMMUNICATION_ERROR;
1477
1478                         case 0x80:
1479                                 /* Polling */
1480                         {
1481                                 int delay;
1482
1483                                 delay = (rx_buffer[2] << 8) + rx_buffer[1];
1484                                 DEBUG_COMM2("Pooling delay: %d", delay);
1485
1486                                 if (0 == delay)
1487                                         /* host select the delay */
1488                                         delay = 1;
1489                                 (void)usleep(delay * 1000 * 10);
1490                                 goto time_request_ICCD_B;
1491                         }
1492
1493                         case 0x01:
1494                         case 0x02:
1495                         case 0x03:
1496                         case 0x10:
1497                                 /* Extended case
1498                                  * Only valid for Data Block frames */
1499                                 if (chain_parameter)
1500                                         *chain_parameter = rx_buffer[0];
1501                                 break;
1502
1503                         default:
1504                                 DEBUG_CRITICAL2("Unknown bResponseType: 0x%02X", rx_buffer[0]);
1505                                 return IFD_COMMUNICATION_ERROR;
1506                 }
1507
1508                 memmove(rx_buffer, rx_buffer+1, r-1);
1509                 *rx_length = r-1;
1510
1511                 return IFD_SUCCESS;
1512         }
1513 #endif
1514
1515         /* store the original value of read timeout*/
1516         old_timeout = ccid_descriptor -> readTimeout;
1517
1518 time_request:
1519         length = sizeof(cmd);
1520         ret = ReadPort(reader_index, &length, cmd);
1521
1522         /* restore the original value of read timeout */
1523         ccid_descriptor -> readTimeout = old_timeout;
1524         CHECK_STATUS(ret)
1525
1526         if (length < STATUS_OFFSET+1)
1527         {
1528                 DEBUG_CRITICAL2("Not enough data received: %d bytes", length);
1529                 return IFD_COMMUNICATION_ERROR;
1530         }
1531
1532         if (cmd[STATUS_OFFSET] & CCID_COMMAND_FAILED)
1533         {
1534                 ccid_error(PCSC_LOG_ERROR, cmd[ERROR_OFFSET], __FILE__, __LINE__, __FUNCTION__);    /* bError */
1535                 switch (cmd[ERROR_OFFSET])
1536                 {
1537                         case 0xEF:      /* cancel */
1538                                 if (*rx_length < 2)
1539                                         return IFD_ERROR_INSUFFICIENT_BUFFER;
1540                                 rx_buffer[0]= 0x64;
1541                                 rx_buffer[1]= 0x01;
1542                                 *rx_length = 2;
1543                                 return IFD_SUCCESS;
1544
1545                         case 0xF0:      /* timeout */
1546                                 if (*rx_length < 2)
1547                                         return IFD_ERROR_INSUFFICIENT_BUFFER;
1548                                 rx_buffer[0]= 0x64;
1549                                 rx_buffer[1]= 0x00;
1550                                 *rx_length = 2;
1551                                 return IFD_SUCCESS;
1552
1553                         case 0xFD:      /* Parity error during exchange */
1554                                 return IFD_PARITY_ERROR;
1555
1556                         default:
1557                                 return IFD_COMMUNICATION_ERROR;
1558                 }
1559         }
1560
1561         if (cmd[STATUS_OFFSET] & CCID_TIME_EXTENSION)
1562         {
1563                 DEBUG_COMM2("Time extension requested: 0x%02X", cmd[ERROR_OFFSET]);
1564
1565                 /* compute the new value of read timeout */
1566                 if (cmd[ERROR_OFFSET] > 0)
1567                         ccid_descriptor -> readTimeout *= cmd[ERROR_OFFSET];
1568
1569                 DEBUG_COMM2("New timeout: %d ms", ccid_descriptor -> readTimeout);
1570                 goto time_request;
1571         }
1572
1573         /* we have read less (or more) data than the CCID frame says to contain */
1574         if (length-10 != dw2i(cmd, 1))
1575         {
1576                 DEBUG_CRITICAL3("Can't read all data (%d out of %d expected)",
1577                         length-10, dw2i(cmd, 1));
1578                 return_value = IFD_COMMUNICATION_ERROR;
1579         }
1580
1581         length = dw2i(cmd, 1);
1582         if (length <= *rx_length)
1583                 *rx_length = length;
1584         else
1585         {
1586                 DEBUG_CRITICAL2("overrun by %d bytes", length - *rx_length);
1587                 length = *rx_length;
1588                 return_value = IFD_ERROR_INSUFFICIENT_BUFFER;
1589         }
1590
1591         /* Kobil firmware bug. No support for chaining */
1592         if (length && (NULL == rx_buffer))
1593         {
1594                 DEBUG_CRITICAL2("Nul block expected but got %d bytes", length);
1595                 return_value = IFD_COMMUNICATION_ERROR;
1596         }
1597         else
1598                 memcpy(rx_buffer, cmd+10, length);
1599
1600         /* Extended case?
1601          * Only valid for RDR_to_PC_DataBlock frames */
1602         if (chain_parameter)
1603                 *chain_parameter = cmd[CHAIN_PARAMETER_OFFSET];
1604
1605         return return_value;
1606 } /* CCID_Receive */
1607
1608
1609 /*****************************************************************************
1610  *
1611  *                                      CmdXfrBlockAPDU_extended
1612  *
1613  ****************************************************************************/
1614 static RESPONSECODE CmdXfrBlockAPDU_extended(unsigned int reader_index,
1615         unsigned int tx_length, unsigned char tx_buffer[], unsigned int *rx_length,
1616         unsigned char rx_buffer[])
1617 {
1618         RESPONSECODE return_value;
1619         _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
1620         unsigned char chain_parameter;
1621         unsigned int local_tx_length, sent_length;
1622         unsigned int local_rx_length = 0, received_length;
1623         int buffer_overflow = 0;
1624
1625         if (PROTOCOL_ICCD_B == ccid_descriptor->bInterfaceProtocol)
1626         {
1627                 /* length is on 16-bits only
1628                  * if a size > 0x1000 is used then usb_control_msg() fails with
1629                  * "Invalid argument" */
1630                 if (*rx_length > 0x1000)
1631                         *rx_length = 0x1000;
1632         }
1633
1634         DEBUG_COMM2("T=0 (extended): %d bytes", tx_length);
1635
1636         /* send the APDU */
1637         sent_length = 0;
1638
1639         /* we suppose one command is enough */
1640         chain_parameter = 0x00;
1641
1642         local_tx_length = tx_length - sent_length;
1643         if (local_tx_length > CMD_BUF_SIZE)
1644         {
1645                 local_tx_length = CMD_BUF_SIZE;
1646                 /* the command APDU begins with this command, and continue in the next
1647                  * PC_to_RDR_XfrBlock */
1648                 chain_parameter = 0x01;
1649         }
1650         if (local_tx_length > ccid_descriptor->dwMaxCCIDMessageLength-10)
1651         {
1652                 local_tx_length = ccid_descriptor->dwMaxCCIDMessageLength-10;
1653                 chain_parameter = 0x01;
1654         }
1655
1656 send_next_block:
1657         return_value = CCID_Transmit(reader_index, local_tx_length, tx_buffer,
1658                 chain_parameter, 0);
1659         if (return_value != IFD_SUCCESS)
1660                 return return_value;
1661
1662         sent_length += local_tx_length;
1663         tx_buffer += local_tx_length;
1664
1665         /* we just sent the last block (0x02) or only one block was needded (0x00) */
1666         if ((0x02 == chain_parameter) || (0x00 == chain_parameter))
1667                 goto receive_block;
1668
1669         /* read a nul block */
1670         return_value = CCID_Receive(reader_index, &local_rx_length, NULL, NULL);
1671         if (return_value != IFD_SUCCESS)
1672                 return return_value;
1673
1674         /* size of the next block */
1675         if (tx_length - sent_length > local_tx_length)
1676         {
1677                 /* the abData field continues a command APDU and
1678                  * another block is to follow */
1679                 chain_parameter = 0x03;
1680         }
1681         else
1682         {
1683                 /* this abData field continues a command APDU and ends
1684                  * the APDU command */
1685                 chain_parameter = 0x02;
1686
1687                 /* last (smaller) block */
1688                 local_tx_length = tx_length - sent_length;
1689         }
1690
1691         goto send_next_block;
1692
1693 receive_block:
1694         /* receive the APDU */
1695         received_length = 0;
1696
1697 receive_next_block:
1698         local_rx_length = *rx_length - received_length;
1699         return_value = CCID_Receive(reader_index, &local_rx_length, rx_buffer,
1700                 &chain_parameter);
1701         if (IFD_ERROR_INSUFFICIENT_BUFFER == return_value)
1702         {
1703                 buffer_overflow = 1;
1704
1705                 /* we continue to read all the response APDU */
1706                 return_value = IFD_SUCCESS;
1707         }
1708
1709         if (return_value != IFD_SUCCESS)
1710                 return return_value;
1711
1712         /* advance in the reiceiving buffer */
1713         rx_buffer += local_rx_length;
1714         received_length += local_rx_length;
1715
1716         switch (chain_parameter)
1717         {
1718                 /* the response APDU begins and ends in this command */
1719                 case 0x00:
1720                 /* this abData field continues the response APDU and ends the response
1721                  * APDU */
1722                 case 0x02:
1723                         break;
1724
1725                 /* the response APDU begins with this command and is to continue */
1726                 case 0x01:
1727                 /* this abData field continues the response APDU and another block is
1728                  * to follow */
1729                 case 0x03:
1730                 /* empty abData field, continuation of the command APDU is expected in
1731                  * next PC_to_RDR_XfrBlock command */
1732                 case 0x10:
1733                         /* send a nul block */
1734                         /* set wLevelParameter to 0010h: empty abData field,
1735                          * continuation of response APDU is
1736                          * expected in the next RDR_to_PC_DataBlock. */
1737                         return_value = CCID_Transmit(reader_index, 0, NULL, 0x10, 0);
1738                         if (return_value != IFD_SUCCESS)
1739                                 return return_value;
1740
1741                         goto receive_next_block;
1742         }
1743
1744         *rx_length = received_length;
1745
1746         /* generate an overflow detected by pcscd */
1747         if (buffer_overflow)
1748                 (*rx_length)++;
1749
1750         return IFD_SUCCESS;
1751 } /* CmdXfrBlockAPDU_extended */
1752
1753
1754 /*****************************************************************************
1755  *
1756  *                                      CmdXfrBlockTPDU_T0
1757  *
1758  ****************************************************************************/
1759 static RESPONSECODE CmdXfrBlockTPDU_T0(unsigned int reader_index,
1760         unsigned int tx_length, unsigned char tx_buffer[], unsigned int *rx_length,
1761         unsigned char rx_buffer[])
1762 {
1763         RESPONSECODE return_value = IFD_SUCCESS;
1764         _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
1765
1766         DEBUG_COMM2("T=0: %d bytes", tx_length);
1767
1768         /* command length too big for CCID reader? */
1769         if (tx_length > ccid_descriptor->dwMaxCCIDMessageLength-10)
1770         {
1771 #ifdef BOGUS_SCM_FIRMWARE_FOR_dwMaxCCIDMessageLength
1772                 if (263 == ccid_descriptor->dwMaxCCIDMessageLength)
1773                 {
1774                         DEBUG_INFO3("Command too long (%d bytes) for max: %d bytes."
1775                                 " SCM reader with bogus firmware?",
1776                                 tx_length, ccid_descriptor->dwMaxCCIDMessageLength-10);
1777                 }
1778                 else
1779 #endif
1780                 {
1781                         DEBUG_CRITICAL3("Command too long (%d bytes) for max: %d bytes",
1782                                 tx_length, ccid_descriptor->dwMaxCCIDMessageLength-10);
1783                         return IFD_COMMUNICATION_ERROR;
1784                 }
1785         }
1786
1787         /* command length too big for CCID driver? */
1788         if (tx_length > CMD_BUF_SIZE)
1789         {
1790                 DEBUG_CRITICAL3("Command too long (%d bytes) for max: %d bytes",
1791                                 tx_length, CMD_BUF_SIZE);
1792                 return IFD_COMMUNICATION_ERROR;
1793         }
1794
1795         return_value = CCID_Transmit(reader_index, tx_length, tx_buffer, 0, 0);
1796         if (return_value != IFD_SUCCESS)
1797                 return return_value;
1798
1799         return CCID_Receive(reader_index, rx_length, rx_buffer, NULL);
1800 } /* CmdXfrBlockTPDU_T0 */
1801
1802
1803 /*****************************************************************************
1804  *
1805  *                                      T0CmdParsing
1806  *
1807  ****************************************************************************/
1808 static RESPONSECODE T0CmdParsing(unsigned char *cmd, unsigned int cmd_len,
1809         /*@out@*/ unsigned int *exp_len)
1810 {
1811         *exp_len = 0;
1812
1813         /* Ref: 7816-4 Annex A */
1814         switch (cmd_len)
1815         {
1816                 case 4: /* Case 1 */
1817                         *exp_len = 2; /* SW1 and SW2 only */
1818                         break;
1819
1820                 case 5: /* Case 2 */
1821                         if (cmd[4] != 0)
1822                                 *exp_len = cmd[4] + 2;
1823                         else
1824                                 *exp_len = 256 + 2;
1825                         break;
1826
1827                 default: /* Case 3 */
1828                         if (cmd_len > 5 && cmd_len == (unsigned int)(cmd[4] + 5))
1829                                 *exp_len = 2; /* SW1 and SW2 only */
1830                         else
1831                                 return IFD_COMMUNICATION_ERROR; /* situation not supported */
1832                         break;
1833         }
1834
1835         return IFD_SUCCESS;
1836 } /* T0CmdParsing */
1837
1838
1839 /*****************************************************************************
1840  *
1841  *                                      T0ProcACK
1842  *
1843  ****************************************************************************/
1844 static RESPONSECODE T0ProcACK(unsigned int reader_index,
1845         unsigned char **snd_buf, unsigned int *snd_len,
1846         unsigned char **rcv_buf, unsigned int *rcv_len,
1847         unsigned char **in_buf, unsigned int *in_len,
1848         unsigned int proc_len, int is_rcv)
1849 {
1850         RESPONSECODE return_value;
1851         unsigned int ret_len;
1852
1853         DEBUG_COMM2("Enter, is_rcv = %d", is_rcv);
1854
1855         if (is_rcv == 1)
1856         {       /* Receiving mode */
1857                 unsigned int remain_len;
1858                 unsigned char tmp_buf[512];
1859
1860                 if (*in_len > 0)
1861                 {       /* There are still available data in our buffer */
1862                         if (*in_len >= proc_len)
1863                         {
1864                                 /* We only need to get the data from our buffer */
1865                                 memcpy(*rcv_buf, *in_buf, proc_len);
1866                                 *rcv_buf += proc_len;
1867                                 *in_buf += proc_len;
1868                                 *rcv_len += proc_len;
1869                                 *in_len -= proc_len;
1870
1871                                 return IFD_SUCCESS;
1872                         }
1873                         else
1874                         {
1875                                 /* Move all data in the input buffer to the reply buffer */
1876                                 remain_len = proc_len - *in_len;
1877                                 memcpy(*rcv_buf, *in_buf, *in_len);
1878                                 *rcv_buf += *in_len;
1879                                 *in_buf += *in_len;
1880                                 *rcv_len += *in_len;
1881                                 *in_len = 0;
1882                         }
1883                 }
1884                 else
1885                         /* There is no data in our tmp_buf,
1886                          * we have to read all data we needed */
1887                         remain_len = proc_len;
1888
1889                 /* Read the expected data from the smartcard */
1890                 if (*in_len != 0)
1891                 {
1892                         DEBUG_CRITICAL("*in_len != 0");
1893                         return IFD_COMMUNICATION_ERROR;
1894                 }
1895
1896                 memset(tmp_buf, 0, sizeof(tmp_buf));
1897
1898 #ifdef O2MICRO_OZ776_PATCH
1899                 if((0 != remain_len) && (0 == (remain_len + 10) % 64))
1900         {
1901                         /* special hack to avoid a command of size modulo 64
1902                          * we send two commands instead */
1903             ret_len = 1;
1904             return_value = CCID_Transmit(reader_index, 0, *snd_buf, ret_len, 0);
1905             if (return_value != IFD_SUCCESS)
1906                 return return_value;
1907             return_value = CCID_Receive(reader_index, &ret_len, tmp_buf, NULL);
1908             if (return_value != IFD_SUCCESS)
1909                 return return_value;
1910
1911             ret_len = remain_len - 1;
1912             return_value = CCID_Transmit(reader_index, 0, *snd_buf, ret_len, 0);
1913             if (return_value != IFD_SUCCESS)
1914                 return return_value;
1915             return_value = CCID_Receive(reader_index, &ret_len, &tmp_buf[1],
1916                                 NULL);
1917             if (return_value != IFD_SUCCESS)
1918                 return return_value;
1919
1920             ret_len += 1;
1921         }
1922         else
1923 #endif
1924                 {
1925                         ret_len = remain_len;
1926                         return_value = CCID_Transmit(reader_index, 0, *snd_buf, ret_len, 0);
1927                         if (return_value != IFD_SUCCESS)
1928                                 return return_value;
1929
1930                         return_value = CCID_Receive(reader_index, &ret_len, tmp_buf, NULL);
1931                         if (return_value != IFD_SUCCESS)
1932                                 return return_value;
1933                 }
1934                 memcpy(*rcv_buf, tmp_buf, remain_len);
1935                 *rcv_buf += remain_len, *rcv_len += remain_len;
1936
1937                 /* If ret_len != remain_len, our logic is erroneous */
1938                 if (ret_len != remain_len)
1939                 {
1940                         DEBUG_CRITICAL("ret_len != remain_len");
1941                         return IFD_COMMUNICATION_ERROR;
1942                 }
1943         }
1944         else
1945         {       /* Sending mode */
1946
1947                 return_value = CCID_Transmit(reader_index, proc_len, *snd_buf, 1, 0);
1948                 if (return_value != IFD_SUCCESS)
1949                         return return_value;
1950
1951                 *snd_len -= proc_len;
1952                 *snd_buf += proc_len;
1953         }
1954
1955         DEBUG_COMM("Exit");
1956
1957         return IFD_SUCCESS;
1958 } /* T0ProcACK */
1959
1960
1961 /*****************************************************************************
1962  *
1963  *                                      T0ProcSW1
1964  *
1965  ****************************************************************************/
1966 static RESPONSECODE T0ProcSW1(unsigned int reader_index,
1967         unsigned char *rcv_buf, unsigned int *rcv_len,
1968         unsigned char *in_buf, unsigned int in_len)
1969 {
1970         RESPONSECODE return_value = IFD_SUCCESS;
1971         UCHAR tmp_buf[512];
1972         unsigned char sw1, sw2;
1973
1974         /* store the SW1 */
1975         sw1 = *rcv_buf = *in_buf;
1976         rcv_buf++;
1977         in_buf++;
1978         in_len--;
1979         (*rcv_len)++;
1980
1981         /* store the SW2 */
1982         if (0 == in_len)
1983         {
1984                 return_value = CCID_Transmit(reader_index, 0, rcv_buf, 1, 0);
1985                 if (return_value != IFD_SUCCESS)
1986                         return return_value;
1987
1988                 in_len = 1;
1989
1990                 return_value = CCID_Receive(reader_index, &in_len, tmp_buf, NULL);
1991                 if (return_value != IFD_SUCCESS)
1992                         return return_value;
1993
1994                 in_buf = tmp_buf;
1995         }
1996         sw2 = *rcv_buf = *in_buf;
1997         in_len--;
1998         (*rcv_len)++;
1999
2000         DEBUG_COMM3("Exit: SW=%02X %02X", sw1, sw2);
2001
2002         return return_value;
2003 } /* T0ProcSW1 */
2004
2005
2006 /*****************************************************************************
2007  *
2008  *                                      CmdXfrBlockCHAR_T0
2009  *
2010  ****************************************************************************/
2011 static RESPONSECODE CmdXfrBlockCHAR_T0(unsigned int reader_index,
2012         unsigned int snd_len, unsigned char snd_buf[], unsigned int *rcv_len,
2013         unsigned char rcv_buf[])
2014 {
2015         int is_rcv;
2016         unsigned char cmd[5];
2017         unsigned char tmp_buf[512];
2018         unsigned int exp_len, in_len;
2019         unsigned char ins, *in_buf;
2020         RESPONSECODE return_value = IFD_SUCCESS;
2021         _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
2022
2023         DEBUG_COMM2("T=0: %d bytes", snd_len);
2024
2025         if (PROTOCOL_ICCD_A == ccid_descriptor->bInterfaceProtocol)
2026         {
2027                 unsigned char pcbuffer[SIZE_GET_SLOT_STATUS];
2028                 unsigned int backup_len;
2029
2030                 /* length is on 16-bits only
2031                  * if a size > 0x1000 is used then usb_control_msg() fails with
2032                  * "Invalid argument" */
2033                 if (*rcv_len > 0x1000)
2034                         *rcv_len = 0x1000;
2035
2036                 backup_len = *rcv_len;
2037
2038                 /* Command to send to the smart card (must be 5 bytes) */
2039                 memset(cmd, 0, sizeof(cmd));
2040                 if (snd_len == 4)
2041                 {
2042                         memcpy(cmd, snd_buf, 4);
2043                         snd_buf += 4;
2044                         snd_len -= 4;
2045                 }
2046                 else
2047                 {
2048                         memcpy(cmd, snd_buf, 5);
2049                         snd_buf += 5;
2050                         snd_len -= 5;
2051                 }
2052
2053                 /* at most 5 bytes */
2054                 return_value = CCID_Transmit(reader_index, 5, cmd, 0, 0);
2055                 if (return_value != IFD_SUCCESS)
2056                         return return_value;
2057
2058                 /* wait for ready */
2059                 pcbuffer[0] = 0;
2060                 return_value = CmdGetSlotStatus(reader_index, pcbuffer);
2061                 if (return_value != IFD_SUCCESS)
2062                         return return_value;
2063
2064                 if (0x10 == pcbuffer[0])
2065                 {
2066                         if (snd_len > 0)
2067                         {
2068                                 /* continue sending the APDU */
2069                                 return_value = CCID_Transmit(reader_index, snd_len, snd_buf,
2070                                         0, 0);
2071                                 if (return_value != IFD_SUCCESS)
2072                                         return return_value;
2073                         }
2074                         else
2075                         {
2076                                 /* read apdu data */
2077                                 return_value = CCID_Receive(reader_index, rcv_len, rcv_buf,
2078                                                 NULL);
2079                                 if (return_value != IFD_SUCCESS)
2080                                         return return_value;
2081                         }
2082                 }
2083
2084                 return_value = CmdGetSlotStatus(reader_index, pcbuffer);
2085                 if (return_value != IFD_SUCCESS)
2086                         return return_value;
2087
2088                 /* SW1-SW2 available */
2089                 if (0x20 == pcbuffer[0])
2090                 {
2091                         /* backup apdu data length */
2092                         /* if no data recieved before - backup length must be zero */
2093                         backup_len = (backup_len == *rcv_len) ? 0 : *rcv_len;
2094
2095                         /* wait for 2 bytes (SW1-SW2) */
2096                         *rcv_len = 2;
2097
2098                         return_value = CCID_Receive(reader_index, rcv_len,
2099                                 rcv_buf + backup_len, NULL);
2100                         if (return_value != IFD_SUCCESS)
2101                                 DEBUG_CRITICAL("CCID_Receive failed");
2102
2103                         /* restore recieved length */
2104                         *rcv_len += backup_len;
2105                 }
2106                 return return_value;
2107         }
2108
2109         in_buf = tmp_buf;
2110         in_len = 0;
2111         *rcv_len = 0;
2112
2113         return_value = T0CmdParsing(snd_buf, snd_len, &exp_len);
2114         if (return_value != IFD_SUCCESS)
2115         {
2116                 DEBUG_CRITICAL("T0CmdParsing failed");
2117                 return IFD_COMMUNICATION_ERROR;
2118         }
2119
2120         if (snd_len == 5 || snd_len == 4)
2121                 is_rcv = 1;
2122         else
2123                 is_rcv = 0;
2124
2125         /* Command to send to the smart card (must be 5 bytes, from 7816 p.15) */
2126         memset(cmd, 0, sizeof(cmd));
2127         if (snd_len == 4)
2128         {
2129                 memcpy(cmd, snd_buf, 4);
2130                 snd_buf += 4;
2131                 snd_len -= 4;
2132         }
2133         else
2134         {
2135                 memcpy(cmd, snd_buf, 5);
2136                 snd_buf += 5;
2137                 snd_len -= 5;
2138         }
2139
2140         /* Make sure this is a valid command by checking the INS field */
2141         ins = cmd[1];
2142         if ((ins & 0xF0) == 0x60 ||     /* 7816-3 8.3.2 */
2143                 (ins & 0xF0) == 0x90)
2144         {
2145                 DEBUG_CRITICAL2("fatal: INS (0x%02X) = 0x6X or 0x9X", ins);
2146                 return IFD_COMMUNICATION_ERROR;
2147         }
2148
2149         return_value = CCID_Transmit(reader_index, 5, cmd, 1, 0);
2150         if (return_value != IFD_SUCCESS)
2151                 return return_value;
2152
2153         while (1)
2154         {
2155                 if (in_len == 0)
2156                 {
2157                         in_len = 1;
2158                         return_value = CCID_Receive(reader_index, &in_len, tmp_buf, NULL);
2159                         if (return_value != IFD_SUCCESS)
2160                         {
2161                                 DEBUG_CRITICAL("CCID_Receive failed");
2162                                 return return_value;
2163                         }
2164                         in_buf = tmp_buf;
2165                 }
2166                 if (in_len == 0)
2167                 {
2168                         /* Suppose we should be able to get data.
2169                          * If not, error. Set the time-out error */
2170                         DEBUG_CRITICAL("error: in_len = 0");
2171                         return IFD_RESPONSE_TIMEOUT;
2172                 }
2173
2174                 /* Start to process the procedure bytes */
2175                 if (*in_buf == 0x60)
2176                 {
2177                         in_len = 0;
2178                         return_value = CCID_Transmit(reader_index, 0, cmd, 1, 0);
2179
2180                         if (return_value != IFD_SUCCESS)
2181                                 return return_value;
2182
2183                         continue;
2184                 }
2185                 else if (*in_buf == ins || *in_buf == (ins ^ 0x01))
2186                 {
2187                         /* ACK => To transfer all remaining data bytes */
2188                         in_buf++, in_len--;
2189                         if (is_rcv)
2190                                 return_value = T0ProcACK(reader_index, &snd_buf, &snd_len,
2191                                         &rcv_buf, rcv_len, &in_buf, &in_len, exp_len - *rcv_len, 1);
2192                         else
2193                                 return_value = T0ProcACK(reader_index, &snd_buf, &snd_len,
2194                                         &rcv_buf, rcv_len, &in_buf, &in_len, snd_len, 0);
2195
2196                         if (*rcv_len == exp_len)
2197                                 return return_value;
2198
2199                         continue;
2200                 }
2201                 else if (*in_buf == (ins ^ 0xFF) || *in_buf == (ins ^ 0xFE))
2202                 {
2203                         /* ACK => To transfer 1 remaining bytes */
2204                         in_buf++, in_len--;
2205                         return_value = T0ProcACK(reader_index, &snd_buf, &snd_len,
2206                                 &rcv_buf, rcv_len, &in_buf, &in_len, 1, is_rcv);
2207
2208                         if (return_value != IFD_SUCCESS)
2209                                 return return_value;
2210
2211                         continue;
2212                 }
2213                 else if ((*in_buf & 0xF0) == 0x60 || (*in_buf & 0xF0) == 0x90)
2214                         /* SW1 */
2215                         return T0ProcSW1(reader_index, rcv_buf, rcv_len, in_buf, in_len);
2216
2217                 /* Error, unrecognized situation found */
2218                 DEBUG_CRITICAL2("Unrecognized Procedure byte (0x%02X) found!", *in_buf);
2219                 return_value = IFD_COMMUNICATION_ERROR;
2220                 return return_value;
2221         }
2222
2223         return return_value;
2224 } /* CmdXfrBlockCHAR_T0 */
2225
2226
2227 /*****************************************************************************
2228  *
2229  *                                      CmdXfrBlockTPDU_T1
2230  *
2231  ****************************************************************************/
2232 static RESPONSECODE CmdXfrBlockTPDU_T1(unsigned int reader_index,
2233         unsigned int tx_length, unsigned char tx_buffer[], unsigned int *rx_length,
2234         unsigned char rx_buffer[])
2235 {
2236         RESPONSECODE return_value = IFD_SUCCESS;
2237         int ret;
2238
2239         DEBUG_COMM3("T=1: %d and %d bytes", tx_length, *rx_length);
2240
2241         ret = t1_transceive(&((get_ccid_slot(reader_index)) -> t1), 0,
2242                 tx_buffer, tx_length, rx_buffer, *rx_length);
2243
2244         if (ret < 0)
2245                 return_value = IFD_COMMUNICATION_ERROR;
2246         else
2247                 *rx_length = ret;
2248
2249         return return_value;
2250 } /* CmdXfrBlockTPDU_T1 */
2251
2252
2253 /*****************************************************************************
2254  *
2255  *                                      SetParameters
2256  *
2257  ****************************************************************************/
2258 RESPONSECODE SetParameters(unsigned int reader_index, char protocol,
2259         unsigned int length, unsigned char buffer[])
2260 {
2261         unsigned char cmd[10+length];   /* CCID + APDU buffer */
2262         _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
2263         status_t res;
2264
2265         DEBUG_COMM2("length: %d bytes", length);
2266
2267         cmd[0] = 0x61; /* SetParameters */
2268         i2dw(length, cmd+1);    /* APDU length */
2269         cmd[5] = ccid_descriptor->bCurrentSlotIndex;    /* slot number */
2270         cmd[6] = (*ccid_descriptor->pbSeq)++;
2271         cmd[7] = protocol;      /* bProtocolNum */
2272         cmd[8] = cmd[9] = 0; /* RFU */
2273
2274         memcpy(cmd+10, buffer, length);
2275
2276         res = WritePort(reader_index, 10+length, cmd);
2277         CHECK_STATUS(res)
2278
2279         length = sizeof(cmd);
2280         res = ReadPort(reader_index, &length, cmd);
2281         CHECK_STATUS(res)
2282
2283         if (length < STATUS_OFFSET+1)
2284         {
2285                 DEBUG_CRITICAL2("Not enough data received: %d bytes", length);
2286                 return IFD_COMMUNICATION_ERROR;
2287         }
2288
2289         if (cmd[STATUS_OFFSET] & CCID_COMMAND_FAILED)
2290         {
2291                 ccid_error(PCSC_LOG_ERROR, cmd[ERROR_OFFSET], __FILE__, __LINE__, __FUNCTION__);    /* bError */
2292                 if (0x00 == cmd[ERROR_OFFSET])  /* command not supported */
2293                         return IFD_NOT_SUPPORTED;
2294                 else
2295                         if ((cmd[ERROR_OFFSET] >= 1) && (cmd[ERROR_OFFSET] <= 127))
2296                                 /* a parameter is not changeable */
2297                                 return IFD_SUCCESS;
2298                         else
2299                                 return IFD_COMMUNICATION_ERROR;
2300         }
2301
2302         return IFD_SUCCESS;
2303 } /* SetParameters */
2304
2305
2306 /*****************************************************************************
2307  *
2308  *                                      isCharLevel
2309  *
2310  ****************************************************************************/
2311 int isCharLevel(int reader_index)
2312 {
2313         return CCID_CLASS_CHARACTER == (get_ccid_descriptor(reader_index)->dwFeatures & CCID_CLASS_EXCHANGE_MASK);
2314 } /* isCharLevel */
2315
2316
2317 /*****************************************************************************
2318  *
2319  *                                      i2dw
2320  *
2321  ****************************************************************************/
2322 static void i2dw(int value, unsigned char buffer[])
2323 {
2324         buffer[0] = value & 0xFF;
2325         buffer[1] = (value >> 8) & 0xFF;
2326         buffer[2] = (value >> 16) & 0xFF;
2327         buffer[3] = (value >> 24) & 0xFF;
2328 } /* i2dw */
2329
2330 /*****************************************************************************
2331 *
2332 *                  bei2i (big endian integer to host order interger)
2333 *
2334 ****************************************************************************/
2335
2336 static unsigned int bei2i(unsigned char buffer[])
2337 {
2338         return (buffer[0]<<24) + (buffer[1]<<16) + (buffer[2]<<8) + buffer[3];
2339 }