1 /*
2  * Implementation of T=1
3  *
4  * Copyright (C) 2003, Olaf Kirch <okir@suse.de>
5  *
6  * improvements by:
7  * Copyright (C) 2004 Ludovic Rousseau <ludovic.rousseau@free.fr>
8  * Copyright (C) 2011 Advanced Card Systems Ltd. <info@acs.com.hk>
9  */
10 
11 #include <config.h>
12 
13 #include <pcsclite.h>
14 #include <ifdhandler.h>
15 #include "commands.h"
16 #include "buffer.h"
17 #include "debug.h"
18 #include "proto-t1.h"
19 #include "checksum.h"
20 
21 #include "ccid.h"
22 
23 #ifdef HAVE_STRING_H
24 #include <string.h>
25 #endif
26 
27 #include "defs.h"
28 #include "ccid_ifdhandler.h"
29 
30 /* I block */
31 #define T1_I_SEQ_SHIFT		6
32 
33 /* R block */
34 #define T1_IS_ERROR(pcb)	((pcb) & 0x0F)
35 #define T1_EDC_ERROR		0x01
36 #define T1_OTHER_ERROR		0x02
37 #define T1_R_SEQ_SHIFT		4
38 
39 /* S block stuff */
40 #define T1_S_IS_RESPONSE(pcb)	((pcb) & T1_S_RESPONSE)
41 #define T1_S_TYPE(pcb)		((pcb) & 0x0F)
42 #define T1_S_RESPONSE		0x20
43 #define T1_S_RESYNC		0x00
44 #define T1_S_IFS		0x01
45 #define T1_S_ABORT		0x02
46 #define T1_S_WTX		0x03
47 
48 #define swap_nibbles(x) ( (x >> 4) | ((x & 0xF) << 4) )
49 
50 #ifndef TRUE
51 #define TRUE 1
52 #define FALSE 0
53 #endif
54 
55 #define NAD 0
56 #define PCB 1
57 #define LEN 2
58 #define DATA 3
59 
60 /* internal state, do not mess with it. */
61 /* should be != DEAD after reset/init */
62 enum {
63 	SENDING, RECEIVING, RESYNCH, DEAD
64 };
65 
66 static void t1_set_checksum(t1_state_t *, int);
67 static unsigned int t1_block_type(unsigned char);
68 static unsigned int t1_seq(unsigned char);
69 static unsigned int t1_rebuild(t1_state_t *t1, unsigned char *block);
70 static unsigned int t1_compute_checksum(t1_state_t *, unsigned char *, size_t);
71 static int t1_verify_checksum(t1_state_t *, unsigned char *, size_t);
72 static int t1_xcv(t1_state_t *, unsigned char *, size_t, size_t);
73 
74 /*
75  * Set default T=1 protocol parameters
76  */
t1_set_defaults(t1_state_t * t1)77 static void t1_set_defaults(t1_state_t * t1)
78 {
79 	t1->retries = 3;
80 	/* This timeout is rather insane, but we need this right now
81 	 * to support cryptoflex keygen */
82 	t1->ifsc = 32;
83 	t1->ifsd = 32;
84 	t1->nr = 0;
85 	t1->ns = 0;
86 	t1->wtx = 0;
87 }
88 
t1_set_checksum(t1_state_t * t1,int csum)89 static void t1_set_checksum(t1_state_t * t1, int csum)
90 {
91 	switch (csum) {
92 	case IFD_PROTOCOL_T1_CHECKSUM_LRC:
93 		t1->rc_bytes = 1;
94 		t1->checksum = csum_lrc_compute;
95 		break;
96 	case IFD_PROTOCOL_T1_CHECKSUM_CRC:
97 		t1->rc_bytes = 2;
98 		t1->checksum = csum_crc_compute;
99 		break;
100 	}
101 }
102 
103 /*
104  * Attach t1 protocol
105  */
t1_init(t1_state_t * t1,int lun)106 int t1_init(t1_state_t * t1, int lun)
107 {
108 	t1_set_defaults(t1);
109 	t1_set_param(t1, IFD_PROTOCOL_T1_CHECKSUM_LRC, 0);
110 	t1_set_param(t1, IFD_PROTOCOL_T1_STATE, SENDING);
111 	t1_set_param(t1, IFD_PROTOCOL_T1_MORE, FALSE);
112 
113 	t1->lun = lun;
114 
115 	return 0;
116 }
117 
118 /*
119  * Detach t1 protocol
120  */
t1_release(t1_state_t * t1)121 void t1_release(/*@unused@*/ t1_state_t * t1)
122 {
123 	(void)t1;
124 	/* NOP */
125 }
126 
127 /*
128  * Get/set parmaters for T1 protocol
129  */
t1_set_param(t1_state_t * t1,int type,long value)130 int t1_set_param(t1_state_t * t1, int type, long value)
131 {
132 	switch (type) {
133 	case IFD_PROTOCOL_T1_CHECKSUM_LRC:
134 	case IFD_PROTOCOL_T1_CHECKSUM_CRC:
135 		t1_set_checksum(t1, type);
136 		break;
137 	case IFD_PROTOCOL_T1_IFSC:
138 		t1->ifsc = value;
139 		break;
140 	case IFD_PROTOCOL_T1_IFSD:
141 		t1->ifsd = value;
142 		break;
143 	case IFD_PROTOCOL_T1_STATE:
144 		t1->state = value;
145 		break;
146 	case IFD_PROTOCOL_T1_MORE:
147 		t1->more = value;
148 		break;
149 	default:
150 		DEBUG_INFO2("Unsupported parameter %d", type);
151 		return -1;
152 	}
153 
154 	return 0;
155 }
156 
157 /*
158  * Send an APDU through T=1
159  */
t1_transceive(t1_state_t * t1,unsigned int dad,const void * snd_buf,size_t snd_len,void * rcv_buf,size_t rcv_len)160 int t1_transceive(t1_state_t * t1, unsigned int dad,
161 		const void *snd_buf, size_t snd_len,
162 		void *rcv_buf, size_t rcv_len)
163 {
164 	ct_buf_t sbuf, rbuf, tbuf;
165 	unsigned char sdata[T1_BUFFER_SIZE], sblk[5];
166 	unsigned int slen, retries, resyncs;
167 	size_t last_send = 0;
168 
169 	if (snd_len == 0)
170 		return -1;
171 
172 	/* we can't talk to a dead card / reader. Reset it! */
173 	if (t1->state == DEAD)
174 	{
175 		DEBUG_CRITICAL("T=1 state machine is DEAD. Reset the card first.");
176 		return -1;
177 	}
178 
179 	t1->state = SENDING;
180 	retries = t1->retries;
181 	resyncs = 3;
182 
183 	/* Initialize send/recv buffer */
184 	ct_buf_set(&sbuf, (void *)snd_buf, snd_len);
185 	ct_buf_init(&rbuf, rcv_buf, rcv_len);
186 
187 	/* Send the first block */
188 	slen = t1_build(t1, sdata, dad, T1_I_BLOCK, &sbuf, &last_send);
189 
190 	while (1) {
191 		unsigned char pcb;
192 		int n;
193 
194 		retries--;
195 
196 		n = t1_xcv(t1, sdata, slen, sizeof(sdata));
197 		if (-2 == n)
198 		{
199 			DEBUG_COMM("Parity error");
200 			/* ISO 7816-3 Rule 7.4.2 */
201 			if (retries <= 0)
202 				goto resync;
203 
204 			/* ISO 7816-3 Rule 7.2 */
205 			if (T1_R_BLOCK == t1_block_type(t1->previous_block[PCB]))
206 			{
207 				DEBUG_COMM("Rule 7.2");
208 				slen = t1_rebuild(t1, sdata);
209 				continue;
210 			}
211 
212 			slen = t1_build(t1, sdata,
213 					dad, T1_R_BLOCK | T1_EDC_ERROR,
214 					NULL, NULL);
215 			continue;
216 		}
217 
218 		if (n < 0) {
219 			DEBUG_CRITICAL("fatal: transmit/receive failed");
220 			t1->state = DEAD;
221 			goto error;
222 		}
223 
224 		if ((sdata[NAD] != swap_nibbles(dad)) /* wrong NAD */
225 			|| (sdata[LEN] == 0xFF))	/* length == 0xFF (illegal) */
226 		{
227 			DEBUG_COMM("R-BLOCK required");
228 			/* ISO 7816-3 Rule 7.4.2 */
229 			if (retries <= 0)
230 				goto resync;
231 
232 			/* ISO 7816-3 Rule 7.2 */
233 			if (T1_R_BLOCK == t1_block_type(t1->previous_block[PCB]))
234 			{
235 				DEBUG_COMM("Rule 7.2");
236 				slen = t1_rebuild(t1, sdata);
237 				continue;
238 			}
239 
240 			slen = t1_build(t1, sdata,
241 				dad, T1_R_BLOCK | T1_OTHER_ERROR,
242 				NULL, NULL);
243 			continue;
244 		}
245 
246 		if (!t1_verify_checksum(t1, sdata, n)) {
247 			DEBUG_COMM("checksum failed");
248 			/* ISO 7816-3 Rule 7.4.2 */
249 			if (retries <= 0)
250 				goto resync;
251 
252 			/* ISO 7816-3 Rule 7.2 */
253 			if (T1_R_BLOCK == t1_block_type(t1->previous_block[PCB]))
254 			{
255 				DEBUG_COMM("Rule 7.2");
256 				slen = t1_rebuild(t1, sdata);
257 				continue;
258 			}
259 
260 			slen = t1_build(t1, sdata,
261 				dad, T1_R_BLOCK | T1_EDC_ERROR,
262 				NULL, NULL);
263 			continue;
264 		}
265 
266 		pcb = sdata[PCB];
267 		switch (t1_block_type(pcb)) {
268 		case T1_R_BLOCK:
269 			if ((sdata[LEN] != 0x00)	/* length != 0x00 (illegal) */
270 				|| (pcb & 0x20)			/* b6 of pcb is set */
271 			   )
272 			{
273 				DEBUG_COMM("R-Block required");
274 				/* ISO 7816-3 Rule 7.4.2 */
275 				if (retries <= 0)
276 					goto resync;
277 
278 				/* ISO 7816-3 Rule 7.2 */
279 				if (T1_R_BLOCK == t1_block_type(t1->previous_block[1]))
280 				{
281 					DEBUG_COMM("Rule 7.2");
282 					slen = t1_rebuild(t1, sdata);
283 					continue;
284 				}
285 
286 				slen = t1_build(t1, sdata,
287 						dad, T1_R_BLOCK | T1_OTHER_ERROR,
288 						NULL, NULL);
289 				continue;
290 			}
291 
292 			if (((t1_seq(pcb) != t1->ns)	/* wrong sequence number & no bit more */
293 					&& ! t1->more)
294 			   )
295 			{
296 				DEBUG_COMM4("received: %d, expected: %d, more: %d",
297 					t1_seq(pcb), t1->ns, t1->more);
298 
299 				/* ISO 7816-3 Rule 7.4.2 */
300 				if (retries <= 0)
301 					goto resync;
302 
303 				/* ISO 7816-3 Rule 7.2 */
304 				if (T1_R_BLOCK == t1_block_type(t1->previous_block[PCB]))
305 				{
306 					DEBUG_COMM("Rule 7.2");
307 					slen = t1_rebuild(t1, sdata);
308 					continue;
309 				}
310 
311 				DEBUG_COMM("R-Block required");
312 				slen = t1_build(t1, sdata,
313 						dad, T1_R_BLOCK | T1_OTHER_ERROR,
314 						NULL, NULL);
315 				continue;
316 			}
317 
318 			if (t1->state == RECEIVING) {
319 				/* ISO 7816-3 Rule 7.2 */
320 				if (T1_R_BLOCK == t1_block_type(t1->previous_block[1]))
321 				{
322 					/* ISO 7816-3 Rule 7.4.2 */
323 					if (retries <= 0)
324 						goto resync;
325 
326 					DEBUG_COMM("Rule 7.2");
327 					slen = t1_rebuild(t1, sdata);
328 					continue;
329 				}
330 
331 				DEBUG_COMM("");
332 				slen = t1_build(t1, sdata,
333 						dad, T1_R_BLOCK,
334 						NULL, NULL);
335 				break;
336 			}
337 
338 			/* If the card terminal requests the next
339 			 * sequence number, it received the previous
340 			 * block successfully */
341 			if (t1_seq(pcb) != t1->ns) {
342 				ct_buf_get(&sbuf, NULL, last_send);
343 				last_send = 0;
344 				t1->ns ^= 1;
345 			}
346 
347 			/* If there's no data available, the ICC
348 			 * shouldn't be asking for more */
349 			if (ct_buf_avail(&sbuf) == 0)
350 				goto resync;
351 
352 			slen = t1_build(t1, sdata, dad, T1_I_BLOCK,
353 					&sbuf, &last_send);
354 			break;
355 
356 		case T1_I_BLOCK:
357 			/* The first I-block sent by the ICC indicates
358 			 * the last block we sent was received successfully. */
359 			if (t1->state == SENDING) {
360 				DEBUG_COMM("");
361 				ct_buf_get(&sbuf, NULL, last_send);
362 				last_send = 0;
363 				t1->ns ^= 1;
364 			}
365 
366 			t1->state = RECEIVING;
367 
368 			/* If the block sent by the card doesn't match
369 			 * what we expected it to send, reply with
370 			 * an R block */
371 			if (t1_seq(pcb) != t1->nr) {
372 				DEBUG_COMM("wrong nr");
373 
374 				/* ISO 7816-3 Rule 7.4.2 */
375 				if (retries <= 0)
376 					goto resync;
377 
378 				slen = t1_build(t1, sdata, dad,
379 						T1_R_BLOCK | T1_OTHER_ERROR,
380 						NULL, NULL);
381 				continue;
382 			}
383 
384 			t1->nr ^= 1;
385 
386 			if (ct_buf_put(&rbuf, sdata + 3, sdata[LEN]) < 0)
387 			{
388 				DEBUG_CRITICAL2("buffer overrun by %d bytes", sdata[LEN] - (rbuf.size - rbuf.tail));
389 				goto error;
390 			}
391 
392 			if ((pcb & T1_MORE_BLOCKS) == 0)
393 				goto done;
394 
395 			slen = t1_build(t1, sdata, dad, T1_R_BLOCK, NULL, NULL);
396 			break;
397 
398 		case T1_S_BLOCK:
399 			if (T1_S_IS_RESPONSE(pcb) && t1->state == RESYNCH) {
400 				/* ISO 7816-3 Rule 6.2 */
401 				DEBUG_COMM("S-Block answer received");
402 				/* ISO 7816-3 Rule 6.3 */
403 				t1->state = SENDING;
404 				last_send = 0;
405 				resyncs = 3;
406 				retries = t1->retries;
407 				ct_buf_init(&rbuf, rcv_buf, rcv_len);
408 				slen = t1_build(t1, sdata, dad, T1_I_BLOCK,
409 						&sbuf, &last_send);
410 				continue;
411 			}
412 
413 			if (T1_S_IS_RESPONSE(pcb))
414 			{
415 				/* ISO 7816-3 Rule 7.4.2 */
416 				if (retries <= 0)
417 					goto resync;
418 
419 				/* ISO 7816-3 Rule 7.2 */
420 				if (T1_R_BLOCK == t1_block_type(t1->previous_block[PCB]))
421 				{
422 					DEBUG_COMM("Rule 7.2");
423 					slen = t1_rebuild(t1, sdata);
424 					continue;
425 				}
426 
427 				DEBUG_CRITICAL("wrong response S-BLOCK received");
428 				slen = t1_build(t1, sdata,
429 						dad, T1_R_BLOCK | T1_OTHER_ERROR,
430 						NULL, NULL);
431 				continue;
432 			}
433 
434 			ct_buf_init(&tbuf, sblk, sizeof(sblk));
435 
436 			DEBUG_COMM("S-Block request received");
437 			switch (T1_S_TYPE(pcb)) {
438 			case T1_S_RESYNC:
439 				if (sdata[LEN] != 0)
440 				{
441 					DEBUG_COMM2("Wrong length: %d", sdata[LEN]);
442 					slen = t1_build(t1, sdata, dad,
443 						T1_R_BLOCK | T1_OTHER_ERROR,
444 						NULL, NULL);
445 					continue;
446 				}
447 
448 				DEBUG_COMM("Resync requested");
449 				/* the card is not allowed to send a resync. */
450 				goto resync;
451 
452 			case T1_S_ABORT:
453 				if (sdata[LEN] != 0)
454 				{
455 					DEBUG_COMM2("Wrong length: %d", sdata[LEN]);
456 					slen = t1_build(t1, sdata, dad,
457 						T1_R_BLOCK | T1_OTHER_ERROR,
458 						NULL, NULL);
459 					continue;
460 				}
461 
462 				/* ISO 7816-3 Rule 9 */
463 				DEBUG_CRITICAL("abort requested");
464 				break;
465 
466 			case T1_S_IFS:
467 				if (sdata[LEN] != 1)
468 				{
469 					DEBUG_COMM2("Wrong length: %d", sdata[LEN]);
470 					slen = t1_build(t1, sdata, dad,
471 						T1_R_BLOCK | T1_OTHER_ERROR,
472 						NULL, NULL);
473 					continue;
474 				}
475 
476 				DEBUG_CRITICAL2("CT sent S-block with ifs=%u", sdata[DATA]);
477 				if (sdata[DATA] == 0)
478 					goto resync;
479 				t1->ifsc = sdata[DATA];
480 				ct_buf_putc(&tbuf, sdata[DATA]);
481 				break;
482 
483 			case T1_S_WTX:
484 				if (sdata[LEN] != 1)
485 				{
486 					DEBUG_COMM2("Wrong length: %d", sdata[LEN]);
487 					slen = t1_build(t1, sdata, dad,
488 						T1_R_BLOCK | T1_OTHER_ERROR,
489 						NULL, NULL);
490 					continue;
491 				}
492 
493 				DEBUG_COMM2("CT sent S-block with wtx=%u", sdata[DATA]);
494 				t1->wtx = sdata[DATA];
495 				ct_buf_putc(&tbuf, sdata[DATA]);
496 				break;
497 
498 			default:
499 				DEBUG_CRITICAL2("T=1: Unknown S block type 0x%02x", T1_S_TYPE(pcb));
500 				goto resync;
501 			}
502 
503 			slen = t1_build(t1, sdata, dad,
504 				T1_S_BLOCK | T1_S_RESPONSE | T1_S_TYPE(pcb),
505 				&tbuf, NULL);
506 		}
507 
508 		/* Everything went just splendid */
509 		retries = t1->retries;
510 		continue;
511 
512 resync:
513 		/* the number or resyncs is limited, too */
514 		/* ISO 7816-3 Rule 6.4 */
515 		if (resyncs == 0)
516 			goto error;
517 
518 		/* ISO 7816-3 Rule 6 */
519 		resyncs--;
520 		t1->ns = 0;
521 		t1->nr = 0;
522 		slen = t1_build(t1, sdata, dad, T1_S_BLOCK | T1_S_RESYNC, NULL,
523 				NULL);
524 		t1->state = RESYNCH;
525 		t1->more = FALSE;
526 		retries = 1;
527 		continue;
528 	}
529 
530 done:
531 	return ct_buf_avail(&rbuf);
532 
533 error:
534 	t1->state = DEAD;
535 	return -1;
536 }
537 
t1_block_type(unsigned char pcb)538 static unsigned t1_block_type(unsigned char pcb)
539 {
540 	switch (pcb & 0xC0) {
541 	case T1_R_BLOCK:
542 		return T1_R_BLOCK;
543 	case T1_S_BLOCK:
544 		return T1_S_BLOCK;
545 	default:
546 		return T1_I_BLOCK;
547 	}
548 }
549 
t1_seq(unsigned char pcb)550 static unsigned int t1_seq(unsigned char pcb)
551 {
552 	switch (pcb & 0xC0) {
553 	case T1_R_BLOCK:
554 		return (pcb >> T1_R_SEQ_SHIFT) & 1;
555 	case T1_S_BLOCK:
556 		return 0;
557 	default:
558 		return (pcb >> T1_I_SEQ_SHIFT) & 1;
559 	}
560 }
561 
t1_build(t1_state_t * t1,unsigned char * block,unsigned char dad,unsigned char pcb,ct_buf_t * bp,size_t * lenp)562 unsigned int t1_build(t1_state_t * t1, unsigned char *block,
563 	unsigned char dad, unsigned char pcb,
564 	ct_buf_t *bp, size_t *lenp)
565 {
566 	unsigned int len;
567 	char more = FALSE;
568 
569 	len = bp ? ct_buf_avail(bp) : 0;
570 	if (len > t1->ifsc) {
571 		pcb |= T1_MORE_BLOCKS;
572 		len = t1->ifsc;
573 		more = TRUE;
574 	}
575 
576 	/* Add the sequence number */
577 	switch (t1_block_type(pcb)) {
578 	case T1_R_BLOCK:
579 		pcb |= t1->nr << T1_R_SEQ_SHIFT;
580 		break;
581 	case T1_I_BLOCK:
582 		pcb |= t1->ns << T1_I_SEQ_SHIFT;
583 		t1->more = more;
584 		DEBUG_COMM2("more bit: %d", more);
585 		break;
586 	}
587 
588 	block[0] = dad;
589 	block[1] = pcb;
590 	block[2] = len;
591 
592 	if (len)
593 		memcpy(block + 3, ct_buf_head(bp), len);
594 	if (lenp)
595 		*lenp = len;
596 
597 	len = t1_compute_checksum(t1, block, len + 3);
598 
599 	/* memorize the last sent block */
600 	/* only 4 bytes since we are only interesed in R-blocks */
601 	memcpy(t1->previous_block, block, 4);
602 
603 	return len;
604 }
605 
606 static unsigned int
t1_rebuild(t1_state_t * t1,unsigned char * block)607 t1_rebuild(t1_state_t *t1, unsigned char *block)
608 {
609 	unsigned char pcb = t1 -> previous_block[1];
610 
611 	/* copy the last sent block */
612 	if (T1_R_BLOCK == t1_block_type(pcb))
613 		memcpy(block, t1 -> previous_block, 4);
614 	else
615 	{
616 		DEBUG_CRITICAL2("previous block was not R-Block: %02X", pcb);
617 		return 0;
618 	}
619 
620 	return 4;
621 }
622 
623 /*
624  * Build/verify checksum
625  */
t1_compute_checksum(t1_state_t * t1,unsigned char * data,size_t len)626 static unsigned int t1_compute_checksum(t1_state_t * t1,
627 	unsigned char *data, size_t len)
628 {
629 	return len + t1->checksum(data, len, data + len);
630 }
631 
t1_verify_checksum(t1_state_t * t1,unsigned char * rbuf,size_t len)632 static int t1_verify_checksum(t1_state_t * t1, unsigned char *rbuf,
633 	size_t len)
634 {
635 	unsigned char csum[2];
636 	int m, n;
637 
638 	m = len - t1->rc_bytes;
639 	n = t1->rc_bytes;
640 
641 	if (m < 0)
642 		return 0;
643 
644 	t1->checksum(rbuf, m, csum);
645 	if (!memcmp(rbuf + m, csum, n))
646 		return 1;
647 
648 	return 0;
649 }
650 
651 /*
652  * Send/receive block
653  */
t1_xcv(t1_state_t * t1,unsigned char * block,size_t slen,size_t rmax)654 static int t1_xcv(t1_state_t * t1, unsigned char *block, size_t slen,
655 	size_t rmax)
656 {
657 	int n;
658 	CcidDesc *ccid_slot;
659 	_ccid_descriptor *ccid_desc;
660 	int oldReadTimeout;
661 	unsigned int rmax_int;
662 
663 	DEBUG_XXD("sending: ", block, slen);
664 
665 	ccid_slot = get_ccid_slot(t1->lun);
666 	ccid_desc = get_ccid_descriptor(t1->lun);
667 	oldReadTimeout = ccid_desc->readTimeout;
668 
669 	if (t1->wtx > 1)
670 	{
671 		/* set the new temporary timeout at WTX card request */
672 		ccid_desc->readTimeout *=  t1->wtx;
673 		DEBUG_INFO2("New timeout at WTX request: %d sec",
674 			ccid_desc->readTimeout);
675 	}
676 
677 	if (isCharLevel(t1->lun))
678 	{
679 		rmax = 3;
680 
681 		n = ccid_slot->pTransmitT1(t1 -> lun, slen, block, rmax, t1->wtx);
682 		if (n != IFD_SUCCESS)
683 			return -1;
684 
685 		/* the second argument of CCID_Receive() is (unsigned int *)
686 		 * so we can't use &rmax since &rmax is a (size_t *) and may not
687 		 * be the same on 64-bits architectures for example (iMac G5) */
688 		rmax_int = rmax;
689 		n = ccid_slot->pReceive(t1 -> lun, &rmax_int, block, NULL);
690 
691 		if (n == IFD_PARITY_ERROR)
692 			return -2;
693 		if (n != IFD_SUCCESS)
694 			return -1;
695 
696 		rmax = block[2] + 1;
697 
698 		n = ccid_slot->pTransmitT1(t1 -> lun, 0, block, rmax, t1->wtx);
699 		if (n != IFD_SUCCESS)
700 			return -1;
701 
702 		rmax_int = rmax;
703 		n = ccid_slot->pReceive(t1 -> lun, &rmax_int, &block[3], NULL);
704 		rmax = rmax_int;
705 		if (n == IFD_PARITY_ERROR)
706 			return -2;
707 		if (n != IFD_SUCCESS)
708 			return -1;
709 
710 		n = rmax + 3;
711 	}
712 	else
713 	{
714 		n = ccid_slot->pTransmitT1(t1 -> lun, slen, block, 0, t1->wtx);
715 		t1->wtx = 0;	/* reset to default value */
716 		if (n != IFD_SUCCESS)
717 			return -1;
718 
719 		/* Get the response en bloc */
720 		rmax_int = rmax;
721 		n = ccid_slot->pReceive(t1 -> lun, &rmax_int, block, NULL);
722 		rmax = rmax_int;
723 		if (n == IFD_PARITY_ERROR)
724 			return -2;
725 		if (n != IFD_SUCCESS)
726 			return -1;
727 
728 		n = rmax;
729 	}
730 
731 	if (n >= 0)
732 	{
733 		int m;
734 
735 		m = block[2] + 3 + t1->rc_bytes;
736 		if (m < n)
737 			n = m;
738 	}
739 
740 	if (n >= 0)
741 		DEBUG_XXD("received: ", block, n);
742 
743 	/* Restore initial timeout */
744 	ccid_desc->readTimeout = oldReadTimeout;
745 
746 	return n;
747 }
748 
t1_negotiate_ifsd(t1_state_t * t1,unsigned int dad,int ifsd)749 int t1_negotiate_ifsd(t1_state_t * t1, unsigned int dad, int ifsd)
750 {
751 	ct_buf_t sbuf;
752 	unsigned char sdata[T1_BUFFER_SIZE];
753 	unsigned int slen;
754 	unsigned int retries;
755 	size_t snd_len;
756 	int n;
757 	unsigned char snd_buf[1];
758 
759 	retries = t1->retries;
760 
761 	/* S-block IFSD request */
762 	snd_buf[0] = ifsd;
763 	snd_len = 1;
764 
765 	/* Initialize send/recv buffer */
766 	ct_buf_set(&sbuf, (void *)snd_buf, snd_len);
767 
768 	while (TRUE)
769 	{
770 		/* Build the block */
771 		slen = t1_build(t1, sdata, 0, T1_S_BLOCK | T1_S_IFS, &sbuf, NULL);
772 
773 		/* Send the block */
774 		n = t1_xcv(t1, sdata, slen, sizeof(sdata));
775 
776 		retries--;
777 		/* ISO 7816-3 Rule 7.4.2 */
778 		if (retries <= 0)
779 			goto error;
780 
781 		if (-1 == n)
782 		{
783 			DEBUG_CRITICAL("fatal: transmit/receive failed");
784 			goto error;
785 		}
786 
787 		if ((-2 == n)								/* Parity error */
788 			|| (sdata[DATA] != ifsd)				/* Wrong ifsd received */
789 			|| (sdata[NAD] != swap_nibbles(dad))	/* wrong NAD */
790 			|| (!t1_verify_checksum(t1, sdata, n))	/* checksum failed */
791 			|| (n != 4 + (int)t1->rc_bytes)				/* wrong frame length */
792 			|| (sdata[LEN] != 1)					/* wrong data length */
793 			|| (sdata[PCB] != (T1_S_BLOCK | T1_S_RESPONSE | T1_S_IFS))) /* wrong PCB */
794 			continue;
795 
796 		/* no more error */
797 		goto done;
798 	}
799 
800 done:
801 	return n;
802 
803 error:
804 	t1->state = DEAD;
805 	return -1;
806 }
807