This APDU is the first step of the SecureChannel v2 handshake, introduced in 4.0. The protocol needs no pairing: the card proves its identity with its factory identity certificate, so a client can connect to a card it has never seen before. A session is aborted when the application is deselected, either directly or because of a card reset/tear.
The client generates an ephemeral secp256k1 key pair and a random 256-bit HKDF salt, and sends salt || client_eph_pub. The card then:
shared_X, the X coordinate of the ECDH shared secret between the two ephemeral keys.
PRK = HMAC-SHA256(salt, shared_X)
OKM = HKDF-Expand(PRK, "sc_v2_ccm", 32)
key_h2c = OKM[0..15]
key_c2h = OKM[16..31]
The two directions use independent keys. key_h2c encrypts host-to-card traffic, key_c2h card-to-host traffic.
"sc_v2_ccm" || salt || client_eph_pub || card_eph_pub with its authentikey.
card_eph_pub || signature.
The client verifies that signature using the public key from the certificate received in the SELECT response. Because the transcript includes the client's own ephemeral key, an active attacker substituting it is detected. This is the same construction as TLS 1.3's Finished messages.
After a successful OPEN SECURE CHANNEL command, every command is sent with the SECURED APDU instruction (INS 0x18) and every response is encrypted. Unlike SecureChannel v1, the entire inner APDU — CLA, INS, P1, P2, LC and data — is encrypted, not just the data field. Nothing useful about the command is visible on the wire apart from the wrapper header and the payload length.
Payloads are protected with AES-128-CCM (8-byte authentication tag). The nonce is a 13-byte counter starting at zero for the session and incremented after every card response. No nonce bytes are transmitted: request and reply of a round trip share the same counter value, which is safe because the two directions use different keys. A counter overflow (2^104 round trips) tears the session down.
Because responses can only carry data when the ISO status word indicates success, all responses over an open secure channel have SW 0x9000. The real status word is the last two bytes of the decrypted response payload and must be interpreted by the client. The only status word returned in the clear is 0x6982, which signals a secure channel failure — the session is then reset and the handshake must be repeated.
The maximum plaintext for a command is 247 bytes and for a response 245 bytes.
Version 1 relied on a shared secret established out of band by PAIR and required an explicit MUTUALLY AUTHENTICATE step. Its OPEN SECURE CHANNEL command has the same CLA/INS but a completely different shape:
Key derivation worked as follows:
Only the data field of a C-APDU was encrypted, so CLA, INS, P1 and P2 travelled in clear and were covered by the MAC instead. Data was padded with ISO/IEC 9797-1 Method 2, encrypted with AES-CBC, and a AES-CBC-MAC was calculated over the whole APDU and prepended to the data field. The IV for each message was the previous MAC from the counterpart, which both chained the messages and prevented replays. Because AES-CBC requires 16-byte multiples, the effective maximum payload was 223 bytes.