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