PACE Protocol Explained: Step-by-Step with Logs

In this article, we’ll dive deep into the PACE (Password Authenticated Connection Establishment) protocol with a particular focus on the Integrated Mapping. This protocol strengthens eMRTD (electronic Machine-Readable Travel Document) security by replacing the legacy BAC (Basic Access Control).
I’ll guide you through a full PACE transaction executed using a real smart card configured as follows:
PACE Protocol:
ID_PACE_ECDH_IM_AES_CBC_CMAC_256
Elliptic Curve:
BrainpoolP256r1
Password Type:
CAN
(Card Access Number)
During this walkthrough, I'll refer to the relevant paragraphs from the ICAO specification defined in [1].
Step 1: Read EF.CardAccess (EF 011C)
Purpose: Identify supported PACE protocols and retrieve mapping/crypto algorithms.
ICAO Reference: [1] §2.1.1 & 5.4
This file contains the PACEInfo
object [1] §5.3.1 which tells the Terminal how to set up the secure communication. the PACEInfo
object includes:
Protocol identifier “ProtocolOID“ (e.g.
04007F00070202040404 = id-PACE-ECDH-IM-AES-CBC-CMAC-256
)Version (must be 0×02)
ParameterId “Curve/algorithm information” (e.g.
0×0D = BrainpoolP256r1
)
#-----------------------------------------------------------------------------------
# Step 1: Read EF.CardAccess (EF 011C)
#-----------------------------------------------------------------------------------
>> 00 B0 9C00 00
<< 31143012060A04007F0007020204040402010202010D
# Algorithm OID: 04007F00070202040404 (AES/CBC/NoPadding)
# Domain Parameter = 0x0D (13 = BrainpoolP256r1)
Step 2: MSE:SET AT — Select and Initialize PACE Protocol
Purpose: Tell the chip to activate PACE using the selected parameters
ICAO Reference: [1] §3.5.1
This command informs the chip of the selected PACEInfo
. Here, we selected the OID id-PACE-ECDH-IM-AES-CBC-CMAC-256
with BrainpoolP256r1
.
#----------------------------------------------------------------------------------- # MSE SET AT - Select and initialize PACE protocol #----------------------------------------------------------------------------------- >> 00 22 C1A4 12 800A 04007F00070202040404 8301 02 8401 0D
This is where the secure session is about to begin!
Step 3: General Authenticate #1 (Request) — Get Encrypted Nonce
Purpose: Retrieve a nonce encrypted under a key derived from the password (
CAN
)ICAO Reference: [1] §3.5.2 & 3.5.3
The Terminal sends the General Authenticate command requesting the chip's nonce.
#-----------------------------------------------------------------------------------
# General Authenticate #1 - Get encrypted nonce
#-----------------------------------------------------------------------------------
>> 10 86 0000 02 7C00 00
Step 4: General Authenticate #1 (Response)
Purpose: Receive encrypted nonce
Z
ICAO Reference: [1] §3.5.2 & 3.5.3
You get the encrypted nonce Z
, which the Terminal now needs to decrypt using the password-derived key K_pi
.
#-----------------------------------------------------------------------------------
# General Authenticate #1 Response: <SW 9000>
#-----------------------------------------------------------------------------------
<< 7C22 8020 E0F1F5BFAA44F62BC55151E3FBFA21B87C2FE3995FAE5D287B7BBD7774450498
Step 5: Decrypt the Encrypted Nonce Z to get Nonce s
- ICAO Reference: [1] §3.2, 3.4.2 & 5.8
Using the password (CAN
), you derive K_pi
and decrypt the encrypted nonce to get s
. This nonce will later be mapped onto the curve.
K_pi derivation: The key is derived by applying the SHA-256 algorithm to the password combined with the static string "00000003". The size of K_pi
in our case is 32 bytes.
# CAN: 300829
# K_PI: B653727C26263104EEE97E89BBF6312A911427C454E19C6DFF58EAB08D7FC6B9
# encrypted nonce: E0F1F5BFAA44F62BC55151E3FBFA21B87C2FE3995FAE5D287B7BBD7774450498
# decrypted nonce: 1171811C54032A1A86E2A18538C1296A5D9591CF130294794947536CA8DC97A8
Step 6: Nonce Mapping (General Authenticate #2)
Purpose: Map the nonce onto a curve point
G_map
ICAO Reference: [1] §3.2, 3.4.2.2.1 & 3.5.3
For the integrated mapping, you send a randomly generated nonce t
which is the same size as the nonce s
.
#-----------------------------------------------------------------------------------
# General Authenticate #2 - Send mapped the nonce
#-----------------------------------------------------------------------------------
>> 10 86 0000 24
7C22 8120 B04E65450A54674ED7A48C62B00D58892BFC73D551721907636102622800687B 00
Step 7: General Authenticate #2 (Response) — Get Mapped Point G_map
Purpose: PICC confirms nonce mapping
ICAO Reference: [1] §3.2, 3.4.2 & 3.5.3
This confirms that both sides are now aligned on the mapped point G_map
which is calculated using a pseudo random function [1] §3.4.2.2.3 and a point encoding function [1] §A.
#-----------------------------------------------------------------------------------
# General Authenticate #2 Response: <SW 9000>
#-----------------------------------------------------------------------------------
<< 7C02 8200
# New mapped G: 04895203FD3EF9355D3C54BC2785095C64F852E24C0EDD72D6A157478A81D846FF3B95F82A7950815B4FAEF2D3F55F0B2BF74546207DADEFFE8507BDE971325788
Step 8: General Authenticate #3 — Perform Key Agreement
Purpose: Perform ECDH key agreement using ephemeral key pairs
ICAO Reference: [1] §3.2, 3.5.2 & 3.5.3
Each side generates an ephemeral key pair (sk_PCD, pk_PCD
) and (sk_PICC, pk_PICC
) in the group field where the generator is the mapped point G_map
. They then exchange their public keys.
# Ephemeral PCD Public Key: 0493E1C675765380F07FB7620A1DAA1202B1F92000FAB048CED1F51637954B168B69865421215B764CF42F2A21B3981FB888DAD45091F9EB952511B1C72C912DC8
# Ephemeral PCD Private Key: 23F6179CD2689C71BC4670A2CC495983C50F96F4FF67E255A1D3F6B0E4EB637F
#-----------------------------------------------------------------------------------
# General Authenticate #3 - Perform Key agreement
#-----------------------------------------------------------------------------------
>> 10 86 0000 45
7C43 8341
0493E1C675765380F07FB7620A1DAA1202B1F92000FAB048CED1F51637954B168B69865421215B764CF42F2A21B3981FB888DAD45091F9EB952511B1C72C912DC800
#-----------------------------------------------------------------------------------
# General Authenticate #3 Response: <SW 9000>
#-----------------------------------------------------------------------------------
<< 7C43 8441
04705A5B3F5688F404A225F797695D5B0E63DA0F7BADB9F46CBB1127FDB0F55B94338439EAC12CD0737A60E0F8B7D49BEF6A29891EEFAA30BC5513EC3C148008EE
# Ephemeral PICC Public Key: 04705A5B3F5688F404A225F797695D5B0E63DA0F7BADB9F46CBB1127FDB0F55B94338439EAC12CD0737A60E0F8B7D49BEF6A29891EEFAA30BC5513EC3C148008EE
Step 9: Compute the Shared Secret
Purpose: The Terminal calculates the Shared Secret using
sk_PCD
andpk_PICC
, while the card calculates the same value usingsk_PICC
andpk_PCD
. The result will be the same due to Diffie-Hellman. For the ECDH scheme, theECSVDP-DH
key agreement algorithm is used to compute the Shared Secret.ICAO Reference: [1] §3.2 & 5.6
This shared secret Z
is used to derive the session keys.
# Shared Secret: 876E5413F3D3CB70212189D8B7489DA5C4637521ED2A64E5B563C753B32F4C35
Step 10: Derive Session Keys K_enc and K_mac
Purpose: Use the shared secret
Z
to deriveK_enc
andK_mac
keysICAO Reference: [1] §3.2 & 5.8
The derivation uses a Key Derivation Function (KDF) defined in the spec. It uses SHA-1 or SHA-256 to calculate the keys as explained below. Protocols based on Integrated or Generic Mapping with 128-bit keys use SHA-1 while those with 192 or 256-bit keys use SHA-256. Protocols based on Chip Authentication Mapping use SHA-256:
K_enc (encryption): SHA-X(Shared Secret || 00000001)
K_mac (integrity): SHA-X(Shared Secret || 00000002)
# Kenc: CE4D305A33AF93D9791A4465B1574BD8D78C13B15B7F0D5092204CD593311FA9
# Kmac: 2019F04A24AE368AC47C2F4CD157FA7C47B218E912375B6D2D5EF663BA9A7D76
Step 11: Terminal Authentication Token — MAC Token Creation
Purpose: Prove terminal knowledge of shared secret
ICAO Reference: [1] §3.2 & 3.4.3
The Terminal computes a MAC over its public key using K_mac
.
# Terminal Authentication Token: 17CEBFBD204F3105
Step 12: General Authenticate #4 — Mutual Authentication
Purpose: The Terminal sends the MAC token using
K_mac
. The card verifies it and responds with its own MAC tokenICAO Reference: [1] §3.5.3
#-----------------------------------------------------------------------------------
# General Authenticate #4 - Mutual Authentication
#-----------------------------------------------------------------------------------
>> 00 86 0000 0C 7C0A 8508 17CEBFBD204F3105 00
#-----------------------------------------------------------------------------------
# General Authenticate #4 Response: <SW 9000>
#-----------------------------------------------------------------------------------
<< 7C0A 8608 4C2521729B2CAD25
Step 13: Verify Chip Authentication Token
Purpose: The Terminal verifies the PICC's token
ICAO Reference: [1] §3.2 & 3.4.3
If the values match, Mutual Authentication is complete.
# Chip Authentication Token: 4C2521729B2CAD25
# Computed Chip Authentication Token: 4C2521729B2CAD25
# PACE successfully performed
PACE Successfully Performed!
At this point, the secure messaging context is established using K_enc
and K_mac
. Future APDUs can be wrapped and secured using these keys.
Complete APDU Log
At the end, I provide the full trace of APDUs exchanged between the Terminal and the Card during the PACE session:
#-----------------------------------------------------------------------------------
# Step 1: Read EF.CardAccess (EF 011C)
#-----------------------------------------------------------------------------------
>> 00 B0 9C00 00
<< 31143012060A04007F0007020204040402010202010D
# Algorithm OID: 04007F00070202040404 (AES/CBC/NoPadding)
# Domain Parameter = 0x0D (13 = BrainpoolP256r1)
#-----------------------------------------------------------------------------------
# MSE SET AT - Select and initialize PACE protocol
#-----------------------------------------------------------------------------------
>> 00 22 C1A4 12
800A 04007F00070202040404
8301 02
8401 0D
#-----------------------------------------------------------------------------------
# General Authenticate #1 - Get encrypted nonce
#-----------------------------------------------------------------------------------
>> 10 86 0000 02 7C00 00
#-----------------------------------------------------------------------------------
# General Authenticate #1 Response: <SW 9000>
#-----------------------------------------------------------------------------------
<< 7C22 8020 E0F1F5BFAA44F62BC55151E3FBFA21B87C2FE3995FAE5D287B7BBD7774450498
# CAN: 300829
# K_PI: B653727C26263104EEE97E89BBF6312A911427C454E19C6DFF58EAB08D7FC6B9
# encrypted nonce: E0F1F5BFAA44F62BC55151E3FBFA21B87C2FE3995FAE5D287B7BBD7774450498
# decrypted nonce: 1171811C54032A1A86E2A18538C1296A5D9591CF130294794947536CA8DC97A8
#-----------------------------------------------------------------------------------
# General Authenticate #2 - Send mapped the nonce
#-----------------------------------------------------------------------------------
>> 10 86 0000 24
7C22 8120 B04E65450A54674ED7A48C62B00D58892BFC73D551721907636102622800687B 00
#-----------------------------------------------------------------------------------
# General Authenticate #2 Response: <SW 9000>
#-----------------------------------------------------------------------------------
<< 7C02 8200
# New mapped G: 04895203FD3EF9355D3C54BC2785095C64F852E24C0EDD72D6A157478A81D846FF3B95F82A7950815B4FAEF2D3F55F0B2BF74546207DADEFFE8507BDE971325788
# Ephemeral PCD Public Key: 0493E1C675765380F07FB7620A1DAA1202B1F92000FAB048CED1F51637954B168B69865421215B764CF42F2A21B3981FB888DAD45091F9EB952511B1C72C912DC8
# Ephemeral PCD Private Key: 23F6179CD2689C71BC4670A2CC495983C50F96F4FF67E255A1D3F6B0E4EB637F
#-----------------------------------------------------------------------------------
# General Authenticate #3 - Perform Key agreement
#-----------------------------------------------------------------------------------
>> 10 86 0000 45
7C43 8341
0493E1C675765380F07FB7620A1DAA1202B1F92000FAB048CED1F51637954B168B69865421215B764CF42F2A21B3981FB888DAD45091F9EB952511B1C72C912DC800
#-----------------------------------------------------------------------------------
# General Authenticate #3 Response: <SW 9000>
#-----------------------------------------------------------------------------------
<< 7C43 8441
04705A5B3F5688F404A225F797695D5B0E63DA0F7BADB9F46CBB1127FDB0F55B94338439EAC12CD0737A60E0F8B7D49BEF6A29891EEFAA30BC5513EC3C148008EE
# Ephemeral PICC Public Key: 04705A5B3F5688F404A225F797695D5B0E63DA0F7BADB9F46CBB1127FDB0F55B94338439EAC12CD0737A60E0F8B7D49BEF6A29891EEFAA30BC5513EC3C148008EE
# Shared Secret: 876E5413F3D3CB70212189D8B7489DA5C4637521ED2A64E5B563C753B32F4C35
# Kenc: CE4D305A33AF93D9791A4465B1574BD8D78C13B15B7F0D5092204CD593311FA9
# Kmac: 2019F04A24AE368AC47C2F4CD157FA7C47B218E912375B6D2D5EF663BA9A7D76
# Terminal Authentication Token: 17CEBFBD204F3105
#-----------------------------------------------------------------------------------
# General Authenticate #4 - Mutual Authentication
#-----------------------------------------------------------------------------------
>> 00 86 0000 0C 7C0A 8508 17CEBFBD204F3105 00
#-----------------------------------------------------------------------------------
# General Authenticate #4 Response: <SW 9000>
#-----------------------------------------------------------------------------------
<< 7C0A 8608 4C2521729B2CAD25
# Chip Authentication Token: 4C2521729B2CAD25
# Computed Chip Authentication Token: 4C2521729B2CAD25
# PACE successfully performed
[1] : Supplemental Access Control for Machine Readable Travel Documents - Version 1.1:
Subscribe to my newsletter
Read articles from Monssif HAKKOUR directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
