T=0 vs T=1 Smart Card Protocol — When to Use Which
Every smart card uses either T=0 (byte-oriented) or T=1 (block-oriented) for data transmission at the ISO 7816-3 layer. If you're writing code that talks to smart cards via PC/SC, understanding the difference is critical — it affects how you handle GET RESPONSE, APDU chaining, and error detection.
Quick Comparison
| Feature | T=0 | T=1 |
|---|---|---|
| Type | Byte-oriented (half-duplex) | Block-oriented (half-duplex) |
| Error Detection | Parity bit only (no LRC/CRC) | LRC or CRC per block |
| Procedure Byte | ACK / NULL / SW1 after each byte | N/A — blocks acknowledged as units |
| Case 2/4 APDU Le | GET RESPONSE required if response > 256 bytes | Native — Le in APDU works directly |
| Chain Commands | Not supported | Block chaining (More bit) |
| Throughput | ~9,600-38,400 bps | Up to 600+ kbps (with PPS negotiation) |
| Card Support | Legacy GSM SIM, older banking cards | EMV payment, Java Card, eUICC/eSIM, modern cards |
T=0: Byte-Oriented Protocol
In T=0, the card sends a procedure byte after every byte from the terminal. This byte tells the terminal what to do next:
INS(echo) — Send all remaining command data~INS(complement) — Send next data byte0x60(NULL) — Wait, card is processingSW1— End of command, SW2 follows
The GET RESPONSE issue: When the card has more data than fits in Le, it returns 61 XX status. The terminal must then issue a GET RESPONSE APDU (00 C0 00 00 XX) to retrieve the remaining data. This is the #1 gotcha for developers new to T=0.
T=1: Block-Oriented Protocol
T=1 sends data in blocks — I-blocks (information), R-blocks (ready/ack), and S-blocks (supervisory). Each block has:
Prologue: NAD | PCB | LEN (3 bytes) Data: APDU or response data (0-254 bytes) Epilogue: LRC or CRC (1-2 bytes)
T=1 supports block chaining — if the APDU data exceeds one block, the More Data bit signals continuation. This eliminates the need for GET RESPONSE. All modern smart cards (EMV, Java Card, eUICC) use T=1 for this reason.
PC/SC Handling
Good news: PC/SC abstracts both protocols. SCardTransmit() handles GET RESPONSE and block chaining transparently for most cases. Your application just sends the APDU and receives the response.
Bad news: Some legacy T=0 cards require manual GET RESPONSE handling in the application. If you're working with older SIM or banking cards, be prepared to handle 61 XX yourself.
Which Protocol to Use?
- Modern development: Always T=1. Faster, more reliable, no GET RESPONSE workaround.
- Interop with legacy cards: Support both. PC/SC auto-negotiates the protocol during
SCardConnect(). - Testing: Use our APDU Command Builder to test commands on both T=0 and T=1 cards.
Related
PC/SC Programming Guide — Practical examples | ISO 7816 Complete Guide — Protocol deep dive | APDU Response Debugger — Debug SW1 SW2