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