logical channels 7816

cyber-posts

Logical Channels in ISO/IEC 7816-4

ISO/IEC 7816-4 defines logical channels as a mechanism to run multiple independent sessions on a single physical smart card connection. Each channel maintains its own state:

  • Currently selected application (DF – Dedicated File)
  • Current file (EF – Elementary File)
  • Security status (e.g., PIN verified, keys in use)

This is essential for multi-application cards (common in eID, health cards, or credential systems) where you might need to access identity data and a signing certificate at the same time without deselecting one to use the other.

Key facts

  • Channel 0 → basic channel, always open at card reset (ATR), cannot be closed.
  • Additional channels → typically 1–3 (total 4 channels); some modern/JavaCard implementations support up to 19.
  • Channels are independent → no interleaving of command-response pairs across channels (you finish one command before the next, but you can switch channels between commands).
  • Support level → indicated by the card (e.g., in ATR historical bytes or card capabilities data objects).

How the channel number is encoded (most common case – channels 0–3)
The channel number is in the CLA byte of every APDU, in bits b2 and b1:

Channelb2 b1CLA example (standard interindustry, no SM/chaining)
0000x00
1010x01
2100x02
3110x03

To switch channel in code: cla = (base_cla & 0xFC) | channel_number (clears low bits then ORs the number).

Opening and closing channels
Two ways:

  1. Implicit (most common): Send any command (usually SELECT) with CLA indicating a closed channel → the card opens it automatically if supported.
  2. Explicit: Use the MANAGE CHANNEL command (INS = 0x70).

MANAGE CHANNEL details

  • Open (P1 = 0x00):
  • P2 = 0x00 → card assigns an available channel and returns it.
  • P2 = 0x01–0x03 → request a specific channel.
  • Le = 0x01 if P2=0x00 (to get the assigned number), absent otherwise.
  • Close (P1 = 0x80):
  • P2 = channel number to close (bits b2 b1).

Practical examples (APDUs in hex)

  1. Explicit open, card assigns (sent on channel 0):
   Command:  00 70 00 00 01
   Response: 02 90 00   ← card assigned channel 2 (data byte = 02)
  1. Explicit open, request channel 1:
   Command:  00 70 00 01
   Response: 90 00        ← success, no data needed
  1. Use the channel – SELECT an application on channel 1:
   Command:  01 A4 04 00 0A A0 00 00 00 63 50 4B 43 53 2D 31 35   ← example PKSC#15 AID
  1. Close channel 1 (sent on channel 0):
   Command:  00 70 80 01
   Response: 90 00
  1. Implicit open example – directly open channel 2 and select:
   Command:  02 A4 04 00 ... (AID)

Quick code snippet (Python-like with pcsc/pyscard style)

def send_on_channel(conn, base_cla, ins, p1, p2, data=b'', le=None, channel=0):
    cla = (base_cla & 0xFC) | channel   # set channel in low bits
    apdu = bytes([cla, ins, p1, p2]) + len_field + data + le_field
    response, sw1, sw2 = conn.transmit(apdu)
    return response, sw1, sw2

# Example: open channel 1 implicitly by selecting on it
send_on_channel(conn, 0x00, 0xA4, 0x04, 0x00, data=aid, channel=1)

This gives you concurrent access – perfect for credential systems where one channel can stay authenticated to an identity app while another performs operations in a different app. Tomorrow you can build on this (e.g., how security status can be shared or isolated across channels).

Leave a Reply

Your email address will not be published. Required fields are marked *