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