1 /*****************************************************************************
2 * Copyright ©2017-2019 Gemalto – a Thales Company. All rights Reserved.
3 *
4 * This copy is licensed under the Apache License, Version 2.0 (the "License");
5 * You may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
7 * http://www.apache.org/licenses/LICENSE-2.0 or https://www.apache.org/licenses/LICENSE-2.0.html
8 *
9 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 * See the License for the specific language governing permissions and limitations under the License.
11
12 ****************************************************************************/
13
14 /**
15 * @file
16 * $Author$
17 * $Revision$
18 * $Date$
19 *
20 * T=1 implementation.
21 *
22 */
23
24 #include <stddef.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <stdarg.h>
30 #include <unistd.h>
31 #include <ctype.h>
32 #include <stdint.h>
33 #include <fcntl.h>
34 #include <log/log.h>
35
36 #include "iso7816_t1.h"
37 #include "checksum.h"
38 #include "transport.h"
39
40 #define T1_REQUEST_RESYNC 0x00
41 #define T1_REQUEST_IFS 0x01
42 #define T1_REQUEST_ABORT 0x02
43 #define T1_REQUEST_WTX 0x03
44 #define T1_REQUEST_RESET 0x05 /* Custom RESET for SPI version */
45
46 #define MAX_RETRIES 3
47
48 #define MAX_WTX_ROUNDS 200
49
50 #define WTX_MAX_VALUE 1
51
52 static void
t1_init_recv_window(struct t1_state * t1,void * buf,size_t n)53 t1_init_recv_window(struct t1_state *t1, void *buf, size_t n)
54 {
55 t1->recv.start = t1->recv.end = buf;
56 t1->recv.size = n;
57 }
58
59 static ptrdiff_t
t1_recv_window_free_size(struct t1_state * t1)60 t1_recv_window_free_size(struct t1_state *t1)
61 {
62 return (ptrdiff_t)t1->recv.size - (t1->recv.end - t1->recv.start);
63 }
64
65 static void
t1_recv_window_append(struct t1_state * t1,const void * buf,int n)66 t1_recv_window_append(struct t1_state *t1, const void *buf, int n)
67 {
68 ptrdiff_t free = t1_recv_window_free_size(t1);
69 if (n > free)
70 n = (int)free;
71 if (n > 0) {
72 memcpy(t1->recv.end, buf, (size_t)n);
73 t1->recv.end += n;
74 }
75 }
76
77 static ptrdiff_t
t1_recv_window_size(struct t1_state * t1)78 t1_recv_window_size(struct t1_state *t1)
79 {
80 return t1->recv.end - t1->recv.start;
81 }
82
83 static void
t1_close_recv_window(struct t1_state * t1)84 t1_close_recv_window(struct t1_state *t1)
85 {
86 t1->recv.start = t1->recv.end;
87 t1->recv.size = 0;
88 }
89
90 static void
t1_init_send_window(struct t1_state * t1,const void * buf,size_t n)91 t1_init_send_window(struct t1_state *t1, const void *buf, size_t n)
92 {
93 t1->send.start = buf;
94 t1->send.end = t1->send.start + n;
95 }
96
97 static ptrdiff_t
t1_send_window_size(struct t1_state * t1)98 t1_send_window_size(struct t1_state *t1)
99 {
100 return t1->send.end - t1->send.start;
101 }
102
103 static void
t1_close_send_window(struct t1_state * t1)104 t1_close_send_window(struct t1_state *t1)
105 {
106 t1->send.end = t1->send.start;
107 }
108
109 static int
do_chk(struct t1_state * t1,uint8_t * buf)110 do_chk(struct t1_state *t1, uint8_t *buf)
111 {
112 int n = 3 + buf[2];
113
114 switch (t1->chk_algo) {
115 case CHECKSUM_LRC:
116 buf[n] = lrc8(buf, n);
117 n++;
118 break;
119
120 case CHECKSUM_CRC: {
121 uint16_t crc = crc_ccitt(0xFFFF, buf, n);
122 buf[n++] = (uint8_t)(crc >> 8);
123 buf[n++] = (uint8_t)(crc);
124 break;
125 }
126 }
127 return n;
128 }
129
130 static int
chk_is_good(struct t1_state * t1,const uint8_t * buf)131 chk_is_good(struct t1_state *t1, const uint8_t *buf)
132 {
133 int n = 3 + buf[2];
134 int match;
135
136 switch (t1->chk_algo) {
137 case CHECKSUM_LRC:
138 match = (buf[n] == lrc8(buf, n));
139 break;
140
141 case CHECKSUM_CRC: {
142 uint16_t crc = crc_ccitt(0xFFFF, buf, n);
143 match = (crc == (buf[n + 1] | (buf[n] << 8)));
144 break;
145 }
146
147 default:
148 match = 0;
149 }
150 return match;
151 }
152
153 static int
write_iblock(struct t1_state * t1,uint8_t * buf)154 write_iblock(struct t1_state *t1, uint8_t *buf)
155 {
156 ptrdiff_t n = t1_send_window_size(t1);
157 uint8_t pcb;
158
159 /* Card asking for more data whereas nothing is left.*/
160 if (n <= 0)
161 return -EBADMSG;
162
163 if (n > t1->ifsc)
164 n = t1->ifsc, pcb = 0x20;
165 else
166 pcb = 0;
167
168 if (t1->send.next)
169 pcb |= 0x40;
170
171 buf[0] = t1->nad;
172 buf[1] = pcb;
173 buf[2] = (uint8_t)n;
174 memcpy(buf + 3, t1->send.start, (size_t)n);
175 return do_chk(t1, buf);
176 }
177
178 static int
write_rblock(struct t1_state * t1,int n,uint8_t * buf)179 write_rblock(struct t1_state *t1, int n, uint8_t *buf)
180 {
181 buf[0] = t1->nad;
182 buf[1] = 0x80 | (n & 3);
183 if (t1->recv.next)
184 buf[1] |= 0x10;
185 buf[2] = 0;
186 return do_chk(t1, buf);
187 }
188
189 static int
write_request(struct t1_state * t1,int request,uint8_t * buf)190 write_request(struct t1_state *t1, int request, uint8_t *buf)
191 {
192 buf[0] = t1->nad;
193 buf[1] = 0xC0 | request;
194
195 request &= 0x1F;
196 if (T1_REQUEST_IFS == request) {
197 /* On response, resend card IFS, else this is request for device IFS */
198 buf[2] = 1;
199 if (buf[1] & 0x20)
200 buf[3] = t1->ifsc;
201 else
202 buf[3] = t1->ifsd;
203 } else if (T1_REQUEST_WTX == request) {
204 buf[2] = 1;
205 buf[3] = t1->wtx;
206 } else
207 buf[2] = 0;
208
209 return do_chk(t1, buf);
210 }
211
212 static void
ack_iblock(struct t1_state * t1)213 ack_iblock(struct t1_state *t1)
214 {
215 ptrdiff_t n = t1_send_window_size(t1);
216
217 if (n > t1->ifsc)
218 n = t1->ifsc;
219 t1->send.start += n;
220
221 /* Next packet sequence number */
222 t1->send.next ^= 1;
223 }
224
225 /* 0 if not more block, 1 otherwize */
226 static int
parse_iblock(struct t1_state * t1,uint8_t * buf)227 parse_iblock(struct t1_state *t1, uint8_t *buf)
228 {
229 uint8_t pcb = buf[1];
230 uint8_t next = !!(pcb & 0x40);
231
232 if (t1->recv.next == next) {
233 t1->recv.next ^= 1;
234 t1_recv_window_append(t1, buf + 3, buf[2]);
235 t1->recv_size += buf[2];
236 }
237
238 /* 1 if more to come */
239 return !!(pcb & 0x20);
240 }
241
242 static int
parse_rblock(struct t1_state * t1,uint8_t * buf)243 parse_rblock(struct t1_state *t1, uint8_t *buf)
244 {
245 int r = 0;
246 uint8_t pcb = buf[1];
247 uint8_t next = !!(pcb & 0x10);
248
249 switch (pcb & 0x2F) {
250 case 0:
251 if ((t1->send.next ^ next) != 0) {
252 /* Acknowledge previous block */
253 t1->retries = MAX_RETRIES;
254 ack_iblock(t1);
255 } else {
256 t1->retries--;
257 if (t1->retries <= 0) r = -ETIMEDOUT;
258 }
259 break;
260
261 case 1:
262 t1->retries--;
263 t1->send.next = next;
264 r = -EREMOTEIO;
265 /* CRC error on previous block, will resend */
266 break;
267
268 case 2:
269 /* Error */
270 t1->state.halt = 1; r = -EIO;
271 break;
272
273 case 3:
274 t1->retries--;
275 r = -EREMOTEIO;
276 t1->state.request = 1;
277 t1->request = T1_REQUEST_RESYNC;
278 break;
279
280 default:
281 t1->state.halt = 1; r = -EOPNOTSUPP;
282 break;
283 }
284 return r;
285 }
286
287 static int
parse_request(struct t1_state * t1,uint8_t * buf)288 parse_request(struct t1_state *t1, uint8_t *buf)
289 {
290 int n = 0;
291
292 uint8_t request = buf[1] & 0x3F;
293
294 t1->request = request;
295 switch (request) {
296 case T1_REQUEST_RESYNC:
297 n = -EOPNOTSUPP;
298 break;
299
300 case T1_REQUEST_IFS:
301 if (buf[2] != 1)
302 n = -EBADMSG;
303 else if ((buf[3] == 0) || (buf[3] == 0xFF))
304 n = -EBADMSG;
305 else
306 t1->ifsc = buf[3];
307 break;
308
309 case T1_REQUEST_ABORT:
310 if (buf[2] == 0) {
311 t1->state.aborted = 1;
312 t1_close_send_window(t1);
313 t1_close_recv_window(t1);
314 } else
315 n = -EBADMSG;
316 break;
317
318 case T1_REQUEST_WTX:
319 if (buf[2] > 1) {
320 n = -EBADMSG;
321 break;
322 } else if (buf[2] == 1) {
323 t1->wtx = buf[3];
324 if (t1->wtx_max_value)
325 if (t1->wtx > WTX_MAX_VALUE)
326 t1->wtx = WTX_MAX_VALUE;
327 if (t1->wtx_max_rounds) {
328 t1->wtx_rounds--;
329 if (t1->wtx_rounds <= 0) {
330 t1->retries = 0;
331 n = -EBADE;
332 }
333 }
334 }
335 break;
336
337 default:
338 n = -EOPNOTSUPP;
339 break;
340 }
341
342 /* Prepare response for next loop step */
343 if (n == 0)
344 t1->state.reqresp = 1;
345
346 return n;
347 }
348
349 /* Find if ATR is changing IFSC value */
350 static void
parse_atr(struct t1_state * t1)351 parse_atr(struct t1_state *t1)
352 {
353 const uint8_t *atr = t1->atr;
354 size_t n = t1->atr_length;
355 int c, y, tck, proto = 0, ifsc = -1;
356
357 /* Parse T0 byte */
358 tck = y = (n > 0 ? atr[0] : 0);
359
360 /* Parse interface bytes */
361 for (size_t j = 1; j < n; j++) {
362 c = atr[j];
363 tck ^= c;
364
365 if ((y & 0xF0) == 0x80)
366 /* This is TDi byte */
367 y = c, proto |= (1 << (c & 15));
368 else if (y >= 16) {
369 /* First TA for T=1 */
370 if ((ifsc < 0) && ((y & 0x1F) == 0x11))
371 ifsc = c;
372 /* Clear interface byte flag just seen */
373 y &= y - 16;
374 } else /* No more interface bytes */
375 y = -1;
376 }
377
378 /* If TA for T=1 seen and ATR checksum is valid */
379 if ((proto & 2) && (tck == 0))
380 t1->ifsc = (uint8_t)ifsc;
381 }
382
383 /* 1 if expected response, 0 if reemit I-BLOCK, negative value is error */
384 static int
parse_response(struct t1_state * t1,uint8_t * buf)385 parse_response(struct t1_state *t1, uint8_t *buf)
386 {
387 int r;
388 uint8_t pcb = buf[1];
389
390 r = 0;
391
392 /* Not a response ? */
393 if (pcb & 0x20) {
394 pcb &= 0x1F;
395 if (pcb == t1->request) {
396 r = 1;
397 switch (pcb) {
398 case T1_REQUEST_IFS:
399 t1->need_ifsd_sync = 0;
400 if ((buf[2] != 1) && (buf[3] != t1->ifsd))
401 r = -EBADMSG;
402 break;
403
404 case T1_REQUEST_RESET:
405 t1->need_reset = 0;
406 if (buf[2] <= sizeof(t1->atr)) {
407 t1->atr_length = buf[2];
408 if (t1->atr_length)
409 memcpy(t1->atr, buf + 3, t1->atr_length);
410 parse_atr(t1);
411 } else
412 r = -EBADMSG;
413 break;
414 case T1_REQUEST_RESYNC:
415 t1->need_resync = 0;
416 t1->send.next = 0;
417 t1->recv.next = 0;
418 break;
419 case T1_REQUEST_ABORT:
420
421 default:
422 /* We never emitted those requests */
423 r = -EBADMSG;
424 break;
425 }
426 }
427 }
428 return r;
429 }
430
431 enum { T1_IBLOCK, T1_RBLOCK, T1_SBLOCK };
432
433 static int
block_kind(const uint8_t * buf)434 block_kind(const uint8_t *buf)
435 {
436 if ((buf[1] & 0x80) == 0)
437 return T1_IBLOCK;
438 else if ((buf[1] & 0x40) == 0)
439 return T1_RBLOCK;
440 else
441 return T1_SBLOCK;
442 }
443
444 static int
read_block(struct t1_state * t1)445 read_block(struct t1_state *t1)
446 {
447 int n;
448
449 n = block_recv(t1, t1->buf, sizeof(t1->buf));
450
451 if (n < 0)
452 return n;
453 else if (n < 3)
454 return -EBADMSG;
455 else {
456 if (!chk_is_good(t1, t1->buf))
457 return -EREMOTEIO;
458
459 if (t1->buf[0] != t1->nadc)
460 return -EBADMSG;
461
462 if (t1->buf[2] == 255)
463 return -EBADMSG;
464 }
465
466 return n;
467 }
468
469 static int
t1_loop(struct t1_state * t1)470 t1_loop(struct t1_state *t1)
471 {
472 int len;
473 int n = 0;
474
475 /* Will happen on first run */
476 if (t1->need_reset) {
477 t1->state.request = 1;
478 t1->request = T1_REQUEST_RESET;
479 } else if (t1->need_resync) {
480 t1->state.request = 1;
481 t1->request = T1_REQUEST_RESYNC;
482 }else if(t1->need_ifsd_sync){
483 t1->state.request = 1;
484 t1->request = T1_REQUEST_IFS;
485 t1->ifsd = 254;
486 }
487
488 while (!t1->state.halt && t1->retries) {
489 if (t1->state.request)
490 n = write_request(t1, t1->request, t1->buf);
491 else if (t1->state.reqresp) {
492 n = write_request(t1, 0x20 | t1->request, t1->buf);
493 /* If response is not seen, card will repost request */
494 t1->state.reqresp = 0;
495 } else if (t1->state.badcrc)
496 /* FIXME "1" -> T1_RBLOCK_CRC_ERROR */
497 n = write_rblock(t1, 1, t1->buf);
498 else if (t1->state.timeout)
499 n = write_rblock(t1, 0, t1->buf);
500 else if (t1_send_window_size(t1))
501 n = write_iblock(t1, t1->buf);
502 else if (t1->state.aborted)
503 n = -EPIPE;
504 else if (t1_recv_window_size(t1) >= 0)
505 /* Acknowledges block received so far */
506 n = write_rblock(t1, 0, t1->buf);
507 else
508 /* Card did not send an I-BLOCK for response */
509 n = -EBADMSG;
510
511 if (n < 0)
512 break;
513
514 len = block_send(t1, t1->buf, n);
515 if (len < 0) {
516 /* failure to send is permanent, give up immediately */
517 n = len;
518 break;
519 }
520
521 n = read_block(t1);
522 if (n < 0) {
523 t1->retries--;
524 switch (n) {
525 /* Error that trigger recovery */
526 case -EREMOTEIO:
527 /* Emit checksum error R-BLOCK */
528 t1->state.badcrc = 1;
529 continue;
530
531 case -ETIMEDOUT:
532 /* resend block */
533 t1->state.timeout = 1;
534 /* restore checksum failure error */
535 if (t1->state.badcrc)
536 n = -EREMOTEIO;
537 continue;
538
539 /* Block read implementation failed */
540 case -EBADMSG: /* fall through */
541
542 /* Other errors are platform specific and not recoverable. */
543 default:
544 t1->retries = 0;
545 continue;
546 }
547 /* Shall never reach this line */
548 break;
549 }
550
551 if (t1->state.badcrc)
552 if ((t1->buf[1] & 0xEF) == 0x81) {
553 /* Resent bad checksum R-BLOCK when response is CRC failure. */
554 t1->retries--;
555 n = -EREMOTEIO;
556 continue;
557 }
558
559 t1->state.badcrc = 0;
560 t1->state.timeout = 0;
561
562 if (t1->state.request) {
563 if (block_kind(t1->buf) == T1_SBLOCK) {
564 n = parse_response(t1, t1->buf);
565 switch (n) {
566 case 0:
567 /* Asked to emit same former I-BLOCK */
568 break;
569
570 case 1:
571 t1->state.request = 0;
572 /* Nothing to do ? leave */
573 if (t1_recv_window_free_size(t1) == 0)
574 t1->state.halt = 1, n = 0;
575 t1->retries = MAX_RETRIES;
576 if(t1->request == T1_REQUEST_RESET) {
577 t1->state.request = 1;
578 t1->request = T1_REQUEST_IFS;
579 t1->ifsd = 254;
580 t1->need_ifsd_sync = 1;
581 }
582 continue;
583
584 default: /* Negative return is error */
585 t1->state.halt = 1;
586 continue;
587 }
588 }
589 /* Re-emit request until response received */
590 t1->retries--;
591 n = -EBADE;
592 } else {
593 switch (block_kind(t1->buf)) {
594 case T1_IBLOCK:
595 t1->retries = MAX_RETRIES;
596 if (t1_send_window_size(t1))
597 /* Acknowledges last IBLOCK sent */
598 ack_iblock(t1);
599 n = parse_iblock(t1, t1->buf);
600 if (t1->state.aborted)
601 continue;
602 if (t1->recv_size > t1->recv_max) {
603 /* Too much data received */
604 n = -EMSGSIZE;
605 t1->state.halt = 1;
606 continue;
607 }
608 if ((n == 0) && (t1_send_window_size(t1) == 0))
609 t1->state.halt = 1;
610 t1->wtx_rounds = t1->wtx_max_rounds;
611 break;
612
613 case T1_RBLOCK:
614 n = parse_rblock(t1, t1->buf);
615 t1->wtx_rounds = t1->wtx_max_rounds;
616 break;
617
618 case T1_SBLOCK:
619 n = parse_request(t1, t1->buf);
620 if (n == 0)
621 /* Send request response on next loop. */
622 t1->state.reqresp = 1;
623 else if ((n == -EBADMSG) || (n == -EOPNOTSUPP))
624 t1->state.halt = 1;
625 break;
626 }
627 }
628 }
629 return n;
630 }
631
632 static void
t1_clear_states(struct t1_state * t1)633 t1_clear_states(struct t1_state *t1)
634 {
635 t1->state.halt = 0;
636 t1->state.request = 0;
637 t1->state.reqresp = 0;
638 t1->state.badcrc = 0;
639 t1->state.timeout = 0;
640 t1->state.aborted = 0;
641
642 t1->wtx = 1;
643 t1->retries = MAX_RETRIES;
644 t1->request = 0xFF;
645
646 t1->wtx_rounds = t1->wtx_max_rounds;
647
648 t1->send.start = t1->send.end = NULL;
649 t1->recv.start = t1->recv.end = NULL;
650 t1->recv.size = 0;
651
652 t1->recv_size = 0; /* Also count discarded bytes */
653 }
654
655 static void
t1_init(struct t1_state * t1)656 t1_init(struct t1_state *t1)
657 {
658 t1_clear_states(t1);
659
660 t1->chk_algo = CHECKSUM_LRC;
661 t1->ifsc = 32;
662 t1->ifsd = 32;
663 t1->bwt = 300; /* milliseconds */
664
665 t1->send.next = 0;
666 t1->recv.next = 0;
667
668 t1->need_reset = 1;
669 t1->need_resync = 0;
670 t1->spi_fd = -1;
671
672 t1->wtx_max_rounds = MAX_WTX_ROUNDS;
673 t1->wtx_max_value = 1;
674
675 t1->recv_max = 65536 + 2; /* Maximum for extended APDU response */
676 t1->recv_size = 0;
677 }
678
679 static void
t1_release(struct t1_state * t1)680 t1_release(struct t1_state *t1)
681 {
682 t1->state.halt = 1;
683 }
684
685 static void
t1_bind(struct t1_state * t1,int src,int dst)686 t1_bind(struct t1_state *t1, int src, int dst)
687 {
688 src &= 7;
689 dst &= 7;
690
691 t1->nad = src | (dst << 4);
692 t1->nadc = dst | (src << 4);
693 }
694
695 static int
696 t1_reset(struct t1_state *t1);
697
698 static int
t1_transceive(struct t1_state * t1,const void * snd_buf,size_t snd_len,void * rcv_buf,size_t rcv_len)699 t1_transceive(struct t1_state *t1, const void *snd_buf,
700 size_t snd_len, void *rcv_buf, size_t rcv_len)
701 {
702 int n, r;
703
704 t1_clear_states(t1);
705
706 t1_init_send_window(t1, snd_buf, snd_len);
707 t1_init_recv_window(t1, rcv_buf, rcv_len);
708
709 n = t1_loop(t1);
710 if (n == 0)
711 /* Received APDU response */
712 n = (int)t1_recv_window_size(t1);
713 else if (n < 0 && t1->state.aborted != 1){
714 if (!(t1->state.request == 1 && t1->request == T1_REQUEST_RESET))
715 {
716 /*Request Soft RESET to the secure element*/
717 r = t1_reset(t1);
718 if (r < 0) n = -0xDEAD; /*Fatal error meaning eSE is not responding to reset*/
719 }
720 }
721 return n;
722 }
723
724 static int
t1_negotiate_ifsd(struct t1_state * t1,int ifsd)725 t1_negotiate_ifsd(struct t1_state *t1, int ifsd)
726 {
727 t1_clear_states(t1);
728 t1->state.request = 1;
729
730 t1->request = T1_REQUEST_IFS;
731 t1->ifsd = ifsd;
732 return t1_loop(t1);
733 }
734
735 static int
t1_reset(struct t1_state * t1)736 t1_reset(struct t1_state *t1)
737 {
738 t1_clear_states(t1);
739 t1->need_reset = 1;
740
741 return t1_loop(t1);
742 }
743
744 static int
t1_resync(struct t1_state * t1)745 t1_resync(struct t1_state *t1)
746 {
747 t1_clear_states(t1);
748 t1->need_resync = 1;
749
750 return t1_loop(t1);
751 }
752
753 void
isot1_init(struct t1_state * t1)754 isot1_init(struct t1_state *t1)
755 {
756 return t1_init(t1);
757 }
758
759 void
isot1_release(struct t1_state * t1)760 isot1_release(struct t1_state *t1)
761 {
762 t1_release(t1);
763 }
764
765 void
isot1_bind(struct t1_state * t1,int src,int dst)766 isot1_bind(struct t1_state *t1, int src, int dst)
767 {
768 t1_bind(t1, src, dst);
769 }
770
771 int
isot1_transceive(struct t1_state * t1,const void * snd_buf,size_t snd_len,void * rcv_buf,size_t rcv_len)772 isot1_transceive(struct t1_state *t1, const void *snd_buf,
773 size_t snd_len, void *rcv_buf, size_t rcv_len)
774 {
775 return t1_transceive(t1, snd_buf, snd_len, rcv_buf, rcv_len);
776 }
777
778 int
isot1_negotiate_ifsd(struct t1_state * t1,int ifsd)779 isot1_negotiate_ifsd(struct t1_state *t1, int ifsd)
780 {
781 return t1_negotiate_ifsd(t1, ifsd);
782 }
783
784 int
isot1_reset(struct t1_state * t1)785 isot1_reset(struct t1_state *t1)
786 {
787 return t1_reset(t1);
788 }
789
790 int
isot1_resync(struct t1_state * t1)791 isot1_resync(struct t1_state *t1)
792 {
793 return t1_resync(t1);
794 }
795
796 int
isot1_get_atr(struct t1_state * t1,void * atr,size_t n)797 isot1_get_atr(struct t1_state *t1, void *atr, size_t n)
798 {
799 int r = 0;
800
801 if (t1->need_reset)
802 r = t1_reset(t1);
803 if (r >= 0) {
804 if (t1->atr_length <= n) {
805 r = t1->atr_length;
806 memcpy(atr, t1->atr, r);
807 } else
808 r = -EFAULT;
809 }
810 return r;
811 }
812