/[pcsclite]/trunk/Drivers/ccid/src/commands.c
ViewVC logotype

Contents of /trunk/Drivers/ccid/src/commands.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5252 - (show annotations) (download)
Tue Sep 14 09:29:02 2010 UTC (2 years, 8 months ago) by rousseau
File MIME type: text/plain
File size: 58649 byte(s)
SecurePINVerify() & SecurePINModify(): Accept big and little endian byte
orders for multibytes fields

The application should not use HOST_TO_CCID_16() and HOST_TO_CCID_32()
any more and just use the normal byte order of the architecture.

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

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.5