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 "internal.h"
11 #include <sys/poll.h>
12 #include <unistd.h>
13 #include <stdlib.h>
14 #include <string.h>
15
16 typedef struct {
17 ifd_protocol_t base;
18 int state;
19 int block_oriented;
20
21 unsigned char ns;
22 unsigned char nr;
23 unsigned int ifsc;
24 unsigned int ifsd;
25
26 unsigned int timeout, wtx;
27 unsigned int retries;
28 unsigned int rc_bytes;
29
30 unsigned int (*checksum) (const unsigned char *,
31 size_t, unsigned char *);
32 } t1_state_t;
33
34 /* T=1 protocol constants */
35 #define T1_I_BLOCK 0x00
36 #define T1_R_BLOCK 0x80
37 #define T1_S_BLOCK 0xC0
38 #define T1_MORE_BLOCKS 0x20
39
40 /* I block */
41 #define T1_I_SEQ_SHIFT 6
42
43 /* R block */
44 #define T1_IS_ERROR(pcb) ((pcb) & 0x0F)
45 #define T1_EDC_ERROR 0x01
46 #define T1_OTHER_ERROR 0x02
47 #define T1_R_SEQ_SHIFT 4
48
49 /* S block stuff */
50 #define T1_S_IS_RESPONSE(pcb) ((pcb) & T1_S_RESPONSE)
51 #define T1_S_TYPE(pcb) ((pcb) & 0x0F)
52 #define T1_S_RESPONSE 0x20
53 #define T1_S_RESYNC 0x00
54 #define T1_S_IFS 0x01
55 #define T1_S_ABORT 0x02
56 #define T1_S_WTX 0x03
57
58 #define T1_BUFFER_SIZE (3 + 254 + 2)
59
60 #define NAD 0
61 #define PCB 1
62 #define LEN 2
63 #define DATA 3
64
65 /* internal state, do not mess with it. */
66 /* should be != DEAD after reset/init */
67 enum {
68 SENDING, RECEIVING, RESYNCH, DEAD
69 };
70
71 static void t1_set_checksum(t1_state_t *, int);
72 static unsigned int t1_block_type(unsigned char);
73 static unsigned int t1_seq(unsigned char);
74 static unsigned int t1_build(t1_state_t *, unsigned char *,
75 unsigned char, unsigned char,
76 ct_buf_t *, size_t *);
77 static unsigned int t1_compute_checksum(t1_state_t *, unsigned char *, size_t);
78 static int t1_verify_checksum(t1_state_t *, unsigned char *, size_t);
79 static int t1_xcv(t1_state_t *, unsigned char *, size_t, size_t);
80
81 /*
82 * Set default T=1 protocol parameters
83 */
t1_set_defaults(t1_state_t * t1)84 static void t1_set_defaults(t1_state_t * t1)
85 {
86 t1->retries = 3;
87 /* This timeout is rather insane, but we need this right now
88 * to support cryptoflex keygen */
89 t1->timeout = 20000;
90 t1->ifsc = 32;
91 t1->ifsd = 32;
92 t1->nr = 0;
93 t1->ns = 0;
94 t1->wtx = 0;
95 }
96
t1_set_checksum(t1_state_t * t1,int csum)97 static void t1_set_checksum(t1_state_t * t1, int csum)
98 {
99 switch (csum) {
100 case IFD_PROTOCOL_T1_CHECKSUM_LRC:
101 t1->rc_bytes = 1;
102 t1->checksum = csum_lrc_compute;
103 break;
104 case IFD_PROTOCOL_T1_CHECKSUM_CRC:
105 t1->rc_bytes = 2;
106 t1->checksum = csum_crc_compute;
107 break;
108 }
109 }
110
111 /*
112 * Attach t1 protocol
113 */
t1_init(ifd_protocol_t * prot)114 static int t1_init(ifd_protocol_t * prot)
115 {
116 t1_state_t *t1 = (t1_state_t *) prot;
117
118 t1_set_defaults(t1);
119 t1_set_checksum(t1, IFD_PROTOCOL_T1_CHECKSUM_LRC);
120
121 /* If the device is attached through USB etc, assume the
122 * device will do the framing for us */
123 if (prot->reader->device->type != IFD_DEVICE_TYPE_SERIAL)
124 t1->block_oriented = 1;
125 return 0;
126 }
127
128 /*
129 * Detach t1 protocol
130 */
t1_release(ifd_protocol_t * prot)131 static void t1_release(ifd_protocol_t * prot)
132 {
133 /* NOP */
134 }
135
136 /*
137 * Get/set parmaters for T1 protocol
138 */
t1_set_param(ifd_protocol_t * prot,int type,long value)139 static int t1_set_param(ifd_protocol_t * prot, int type, long value)
140 {
141 t1_state_t *t1 = (t1_state_t *) prot;
142
143 switch (type) {
144 case IFD_PROTOCOL_RECV_TIMEOUT:
145 t1->timeout = value;
146 break;
147 case IFD_PROTOCOL_BLOCK_ORIENTED:
148 t1->block_oriented = value;
149 break;
150 case IFD_PROTOCOL_T1_CHECKSUM_LRC:
151 case IFD_PROTOCOL_T1_CHECKSUM_CRC:
152 t1_set_checksum(t1, type);
153 break;
154 case IFD_PROTOCOL_T1_IFSC:
155 t1->ifsc = value;
156 break;
157 case IFD_PROTOCOL_T1_IFSD:
158 t1->ifsd = value;
159 break;
160 default:
161 ct_error("Unsupported parameter %d", type);
162 return -1;
163 }
164
165 return 0;
166 }
167
t1_get_param(ifd_protocol_t * prot,int type,long * result)168 static int t1_get_param(ifd_protocol_t * prot, int type, long *result)
169 {
170 t1_state_t *t1 = (t1_state_t *) prot;
171 long value;
172
173 switch (type) {
174 case IFD_PROTOCOL_RECV_TIMEOUT:
175 value = t1->timeout;
176 break;
177 case IFD_PROTOCOL_BLOCK_ORIENTED:
178 value = t1->block_oriented;
179 break;
180 default:
181 ct_error("Unsupported parameter %d", type);
182 return -1;
183 }
184
185 if (result)
186 *result = value;
187
188 return 0;
189 }
190
191 /*
192 * Send an APDU through T=1
193 */
t1_transceive(ifd_protocol_t * prot,int dad,const void * snd_buf,size_t snd_len,void * rcv_buf,size_t rcv_len)194 static int t1_transceive(ifd_protocol_t * prot, int dad, const void *snd_buf,
195 size_t snd_len, void *rcv_buf, size_t rcv_len)
196 {
197 t1_state_t *t1 = (t1_state_t *) prot;
198 ct_buf_t sbuf, rbuf, tbuf;
199 unsigned char sdata[T1_BUFFER_SIZE], sblk[5];
200 unsigned int slen, retries, resyncs, sent_length = 0;
201 size_t last_send = 0;
202
203 if (snd_len == 0)
204 return -1;
205
206 /* we can't talk to a dead card / reader. Reset it! */
207 if (t1->state == DEAD)
208 return -1;
209
210 t1->state = SENDING;
211 retries = t1->retries;
212 resyncs = 3;
213
214 /* Initialize send/recv buffer */
215 ct_buf_set(&sbuf, (void *)snd_buf, snd_len);
216 ct_buf_init(&rbuf, rcv_buf, rcv_len);
217
218 /* Send the first block */
219 slen = t1_build(t1, sdata, dad, T1_I_BLOCK, &sbuf, &last_send);
220
221 while (1) {
222 unsigned char pcb;
223 int n;
224
225 retries--;
226
227 if ((n = t1_xcv(t1, sdata, slen, sizeof(sdata))) < 0) {
228 ifd_debug(1, "fatal: transmit/receive failed");
229 t1->state = DEAD;
230 goto error;
231 }
232
233 if (!t1_verify_checksum(t1, sdata, n)) {
234 ifd_debug(1, "checksum failed");
235 if (retries == 0 || sent_length)
236 goto resync;
237 slen = t1_build(t1, sdata,
238 dad, T1_R_BLOCK | T1_EDC_ERROR,
239 NULL, NULL);
240 continue;
241 }
242
243 pcb = sdata[PCB];
244 switch (t1_block_type(pcb)) {
245 case T1_R_BLOCK:
246 if (T1_IS_ERROR(pcb)) {
247 ifd_debug(1, "received error block, err=%d",
248 T1_IS_ERROR(pcb));
249 goto resync;
250 }
251
252 if (t1->state == RECEIVING) {
253 slen = t1_build(t1, sdata,
254 dad, T1_R_BLOCK, NULL, NULL);
255 break;
256 }
257
258 /* If the card terminal requests the next
259 * sequence number, it received the previous
260 * block successfully */
261 if (t1_seq(pcb) != t1->ns) {
262 ct_buf_get(&sbuf, NULL, last_send);
263 sent_length += last_send;
264 last_send = 0;
265 t1->ns ^= 1;
266 }
267
268 /* If there's no data available, the ICC
269 * shouldn't be asking for more */
270 if (ct_buf_avail(&sbuf) == 0)
271 goto resync;
272
273 slen = t1_build(t1, sdata, dad, T1_I_BLOCK,
274 &sbuf, &last_send);
275 break;
276
277 case T1_I_BLOCK:
278 /* The first I-block sent by the ICC indicates
279 * the last block we sent was received successfully. */
280 if (t1->state == SENDING) {
281 ct_buf_get(&sbuf, NULL, last_send);
282 last_send = 0;
283 t1->ns ^= 1;
284 }
285
286 t1->state = RECEIVING;
287
288 /* If the block sent by the card doesn't match
289 * what we expected it to send, reply with
290 * an R block */
291 if (t1_seq(pcb) != t1->nr) {
292 slen = t1_build(t1, sdata, dad,
293 T1_R_BLOCK | T1_OTHER_ERROR,
294 NULL, NULL);
295 continue;
296 }
297
298 t1->nr ^= 1;
299
300 if (ct_buf_put(&rbuf, sdata + 3, sdata[LEN]) < 0)
301 goto error;
302
303 if ((pcb & T1_MORE_BLOCKS) == 0)
304 goto done;
305
306 slen = t1_build(t1, sdata, dad, T1_R_BLOCK, NULL, NULL);
307 break;
308
309 case T1_S_BLOCK:
310 if (T1_S_IS_RESPONSE(pcb) && t1->state == RESYNCH) {
311 t1->state = SENDING;
312 sent_length = 0;
313 last_send = 0;
314 resyncs = 3;
315 retries = t1->retries;
316 ct_buf_init(&rbuf, rcv_buf, rcv_len);
317 slen = t1_build(t1, sdata, dad, T1_I_BLOCK,
318 &sbuf, &last_send);
319 continue;
320 }
321
322 if (T1_S_IS_RESPONSE(pcb))
323 goto resync;
324
325 ct_buf_init(&tbuf, sblk, sizeof(sblk));
326
327 switch (T1_S_TYPE(pcb)) {
328 case T1_S_RESYNC:
329 /* the card is not allowed to send a resync. */
330 goto resync;
331 case T1_S_ABORT:
332 ifd_debug(1, "abort requested");
333 break;
334 case T1_S_IFS:
335 ifd_debug(1, "CT sent S-block with ifs=%u",
336 sdata[DATA]);
337 if (sdata[DATA] == 0)
338 goto resync;
339 t1->ifsc = sdata[DATA];
340 ct_buf_putc(&tbuf, sdata[DATA]);
341 break;
342 case T1_S_WTX:
343 /* We don't handle the wait time extension
344 * yet */
345 ifd_debug(1, "CT sent S-block with wtx=%u",
346 sdata[DATA]);
347 t1->wtx = sdata[DATA];
348 ct_buf_putc(&tbuf, sdata[DATA]);
349 break;
350 default:
351 ct_error("T=1: Unknown S block type 0x%02x",
352 T1_S_TYPE(pcb));
353 goto resync;
354 }
355
356 slen = t1_build(t1, sdata, dad,
357 T1_S_BLOCK | T1_S_RESPONSE |
358 T1_S_TYPE(pcb), &tbuf, NULL);
359 }
360
361 /* Everything went just splendid */
362 retries = t1->retries;
363 continue;
364
365 resync:
366 /* the number or resyncs is limited, too */
367 if (resyncs == 0)
368 goto error;
369 resyncs--;
370 t1->ns = 0;
371 t1->nr = 0;
372 slen = t1_build(t1, sdata, dad, T1_S_BLOCK | T1_S_RESYNC, NULL,
373 NULL);
374 t1->state = RESYNCH;
375 continue;
376 }
377
378 done:
379 return ct_buf_avail(&rbuf);
380
381 error:
382 t1->state = DEAD;
383 return -1;
384 }
385
t1_resynchronize(ifd_protocol_t * p,int nad)386 static int t1_resynchronize(ifd_protocol_t * p, int nad)
387 {
388 t1_state_t *t1 = (t1_state_t *) p;
389 unsigned char block[4];
390 unsigned int retries = 3;
391
392 if (p->reader && p->reader->device)
393 ifd_device_flush(p->reader->device);
394
395 while (retries--) {
396 t1->ns = 0;
397 t1->nr = 0;
398
399 block[0] = nad;
400 block[1] = T1_S_BLOCK | T1_S_RESYNC;
401 block[2] = 0;
402 t1_compute_checksum(t1, block, 3);
403
404 if (t1_xcv(t1, block, 4, sizeof(block)) != 4) {
405 ifd_debug(1, "fatal: transmit/receive failed");
406 break;
407 }
408
409 if (!t1_verify_checksum(t1, block, 4)) {
410 ifd_debug(1, "checksum failed");
411 continue;
412 }
413
414 if (block[1] == (T1_S_BLOCK | T1_S_RESPONSE | T1_S_RESYNC))
415 return 0;
416 }
417
418 t1->state = DEAD;
419 return -1;
420 }
421
t1_block_type(unsigned char pcb)422 static unsigned t1_block_type(unsigned char pcb)
423 {
424 switch (pcb & 0xC0) {
425 case T1_R_BLOCK:
426 return T1_R_BLOCK;
427 case T1_S_BLOCK:
428 return T1_S_BLOCK;
429 default:
430 return T1_I_BLOCK;
431 }
432 }
433
t1_seq(unsigned char pcb)434 static unsigned int t1_seq(unsigned char pcb)
435 {
436 switch (pcb & 0xC0) {
437 case T1_R_BLOCK:
438 return (pcb >> T1_R_SEQ_SHIFT) & 1;
439 case T1_S_BLOCK:
440 return 0;
441 default:
442 return (pcb >> T1_I_SEQ_SHIFT) & 1;
443 }
444 }
445
t1_build(t1_state_t * t1,unsigned char * block,unsigned char dad,unsigned char pcb,ct_buf_t * bp,size_t * lenp)446 static unsigned int t1_build(t1_state_t * t1, unsigned char *block,
447 unsigned char dad, unsigned char pcb,
448 ct_buf_t * bp, size_t * lenp)
449 {
450 unsigned int len;
451
452 len = bp ? ct_buf_avail(bp) : 0;
453 if (len > t1->ifsc) {
454 pcb |= T1_MORE_BLOCKS;
455 len = t1->ifsc;
456 }
457
458 /* Add the sequence number */
459 switch (t1_block_type(pcb)) {
460 case T1_R_BLOCK:
461 pcb |= t1->nr << T1_R_SEQ_SHIFT;
462 break;
463 case T1_I_BLOCK:
464 pcb |= t1->ns << T1_I_SEQ_SHIFT;
465 break;
466 }
467
468 block[0] = dad;
469 block[1] = pcb;
470 block[2] = len;
471
472 if (len)
473 memcpy(block + 3, ct_buf_head(bp), len);
474 if (lenp)
475 *lenp = len;
476
477 return t1_compute_checksum(t1, block, len + 3);
478 }
479
480 /*
481 * Protocol struct
482 */
483 struct ifd_protocol_ops ifd_protocol_t1 = {
484 IFD_PROTOCOL_T1, /* id */
485 "T=1", /* name */
486 sizeof(t1_state_t), /* size */
487 t1_init, /* init */
488 t1_release, /* release */
489 t1_set_param, /* set_param */
490 t1_get_param, /* get_param */
491 t1_resynchronize, /* resynchronize */
492 t1_transceive, /* transceive */
493 NULL, /* sync_read */
494 NULL, /* sync_write */
495 };
496
497 /*
498 * Build/verify checksum
499 */
t1_compute_checksum(t1_state_t * t1,unsigned char * data,size_t len)500 static unsigned int t1_compute_checksum(t1_state_t * t1, unsigned char *data,
501 size_t len)
502 {
503 return len + t1->checksum(data, len, data + len);
504 }
505
t1_verify_checksum(t1_state_t * t1,unsigned char * rbuf,size_t len)506 static int t1_verify_checksum(t1_state_t * t1, unsigned char *rbuf, size_t len)
507 {
508 unsigned char csum[2];
509 int m, n;
510
511 m = len - t1->rc_bytes;
512 n = t1->rc_bytes;
513
514 if (m < 0)
515 return 0;
516
517 t1->checksum(rbuf, m, csum);
518 if (!memcmp(rbuf + m, csum, n))
519 return 1;
520
521 return 0;
522 }
523
524 /*
525 * Send/receive block
526 */
t1_xcv(t1_state_t * t1,unsigned char * block,size_t slen,size_t rmax)527 static int t1_xcv(t1_state_t * t1, unsigned char *block, size_t slen,
528 size_t rmax)
529 {
530 ifd_protocol_t *prot = &t1->base;
531 unsigned int rlen, timeout;
532 int n, m;
533
534 if (ct_config.debug >= 3)
535 ifd_debug(3, "sending %s", ct_hexdump(block, slen));
536
537 n = ifd_send_command(prot, block, slen);
538 if (n < 0)
539 return n;
540
541 /* Maximum amount of data we'll receive - some devices
542 * such as the eToken need this. If you request more, it'll
543 * just barf */
544 rlen = 3 + t1->ifsd + t1->rc_bytes;
545
546 /* timeout. For now our WTX treatment is very dumb */
547 timeout = t1->timeout + 1000 * t1->wtx;
548 t1->wtx = 0;
549
550 if (t1->block_oriented) {
551 /* Note - Linux USB seems to have an off by one error, you
552 * actually need the + 1 to get the RC byte */
553 rlen++;
554 if (rlen < rmax)
555 rmax = rlen;
556
557 /* Get the response en bloc */
558 n = ifd_recv_response(prot, block, rmax, timeout);
559 if (n >= 0) {
560 m = block[2] + 3 + t1->rc_bytes;
561 if (m < n)
562 n = m;
563 }
564 } else {
565 /* Get the header */
566 if (ifd_recv_response(prot, block, 3, timeout) < 0)
567 return -1;
568
569 n = block[2] + t1->rc_bytes;
570 if (n + 3 > rmax || block[2] >= 254) {
571 ct_error("receive buffer too small");
572 return -1;
573 }
574
575 /* Now get the rest */
576 if (ifd_recv_response(prot, block + 3, n, t1->timeout) < 0)
577 return -1;
578
579 n += 3;
580 }
581
582 if (n >= 0 && ct_config.debug >= 3)
583 ifd_debug(3, "received %s", ct_hexdump(block, n));
584
585 return n;
586 }
587
t1_negotiate_ifsd(ifd_protocol_t * proto,unsigned int dad,int ifsd)588 int t1_negotiate_ifsd(ifd_protocol_t * proto, unsigned int dad, int ifsd)
589 {
590 t1_state_t *t1 = (t1_state_t *) proto;
591 ct_buf_t sbuf;
592 unsigned char sdata[T1_BUFFER_SIZE];
593 unsigned int slen;
594 unsigned int retries;
595 size_t snd_len;
596 int n;
597 unsigned char snd_buf[1], pcb;
598
599 retries = t1->retries;
600
601 /* S-block IFSD request */
602 snd_buf[0] = ifsd;
603 snd_len = 1;
604
605 /* Initialize send/recv buffer */
606 ct_buf_set(&sbuf, (void *)snd_buf, snd_len);
607
608 while (1) {
609 /* Build the block */
610 slen =
611 t1_build(t1, sdata, dad, T1_S_BLOCK | T1_S_IFS, &sbuf,
612 NULL);
613
614 if ((n = t1_xcv(t1, sdata, slen, sizeof(sdata))) < 0) {
615 ifd_debug(1, "fatal: transmit/receive failed");
616 t1->state = DEAD;
617 goto error;
618 }
619
620 if (!t1_verify_checksum(t1, sdata, n)) {
621 ifd_debug(1, "checksum failed");
622 if (retries == 0)
623 goto error;
624 continue;
625 }
626 pcb = sdata[1];
627 if (t1_block_type(pcb) == T1_S_BLOCK &&
628 T1_S_TYPE(pcb) == T1_S_IFS && T1_S_IS_RESPONSE(pcb)) {
629 if (sdata[LEN] != 1 || sdata[DATA] != ifsd)
630 goto error;
631 break;
632 }
633 if (retries == 0)
634 goto error;
635 }
636
637 return n;
638
639 error:
640 t1_resynchronize(proto, dad);
641 return -1;
642 }
643