Getting Started with EMV: PPSE, AID, and SELECT
Use POOM to select the EMV contactless PPSE, decode its TLV response, discover an application AID, and interpret SELECT status words.
In the previous lesson, we learned how an APDU is constructed:
CLA INS P1 P2 [Lc] [Data] [Le]
We also learned that a card response can contain:
[Data] SW1 SW2
Now we can use that same language to explore a payment card application. EMV is the family of specifications used by chip and contactless payment applications. A contactless reader uses APDUs to communicate with the applications available on a card.
How does a reader learn which payment applications a card makes available?
That is the question for this lab. We will not make a purchase or perform a payment transaction. We will only ask the card which applications it advertises and learn to recognize the structure of its response.
Before starting: what is EMV?
The layers we have used so far work together:
ISO/IEC 14443-A
Card discovery and selection
ISO/IEC 14443-4
ISO-DEP transport
ISO/IEC 7816-4
APDU commands and responses
EMV
Rules and data used by a payment application
EMV does not replace the previous layers. A useful way to see the relationship is:
ISO/IEC 7816-4 explains how to construct an APDU.
EMV explains which APDUs and data are used
to communicate with a payment application.
This lab focuses on two operations:
SELECT PPSE
SELECT AID
What is the PPSE?
When a terminal receives a contactless card, it does not yet know which payment applications the card contains. It first asks for a directory called the PPSE:
Proximity Payment System Environment
The DF name used to select it is:
2PAY.SYS.DDF01
Encoded as ASCII bytes in hexadecimal:
32 50 41 59 2E 53 59 53 2E 44 44 46 30 31
A successful PPSE response can describe available applications with objects such as:
| Tag | Meaning |
|---|---|
61 | Directory Entry |
4F | Application Identifier / ADF Name |
50 | Application Label |
87 | Application Priority Indicator |
Part 1: SELECT PPSE
On POOM, open THE BEAST from the main menu and select CLI. Place your own contactless card under POOM, establish ISO-DEP, then send:
nfc-core-stop
nfc-core-start
nfc-tech-set-a
nfc-card-connect
nfc-card-send 00 A4 04 00 0E 32 50 41 59 2E 53 59 53 2E 44 44 46 30 31 00
The command separates into the fields from the previous lesson:
00 | A4 | 04 | 00 | 0E | 32 50 41 59 2E 53 59 53 2E 44 44 46 30 31 | 00
CLA INS P1 P2 Lc Data Le
| Field | Value | Meaning |
|---|---|---|
CLA | 00 | ISO/IEC 7816 interindustry class |
INS | A4 | SELECT |
P1 | 04 | Select by DF name |
P2 | 00 | Selection options |
Lc | 0E | Fourteen data bytes |
Data | 32 50 ... 30 31 | 2PAY.SYS.DDF01 |
Le | 00 | Request the available response data |
In plain language, the command says:
Card, select
2PAY.SYS.DDF01and tell me which payment applications you advertise.
A real result from POOM
One test card produced the following transport exchange. Your card can return different applications, labels, lengths, or status words.
poom> nfc-card-send 00 A4 04 00 0E 32 50 41 59 2E 53 59 53 2E 44 44 46 30 31 00
[TX] 1A 00 00 A4 04 00 0E 32 50 41 59 2E 53 59 53 2E 44 44
[RX] AA 00
[TX] 0B 00 46 30 31 00
[RX] 1B 00 6F 2F 84 0E 32 50 41 59 2E 53 59 53
[TX] AA 00
[RX] 1A 00 2E 44 44 46 30 31 A5 1D BF 0C 1A 61
[TX] AB 00
[RX] 1B 00 18 4F 07 A0 00 00 00 04 10 10 50 0A
[TX] AA 00
[RX] 1A 00 4D 61 73 74 65 72 63 61 72 64 87 01
[TX] AB 00
[RX] 0B 00 01 90 00
The [TX] and [RX] blocks include ISO-DEP transport information. POOM reconstructs the APDU. At the EMV level, the response we want to interpret is:
6F 2F
84 0E 32 50 41 59 2E 53 59 53 2E 44 44 46 30 31
A5 1D
BF 0C 1A
61 18
4F 07 A0 00 00 00 04 10 10
50 0A 4D 61 73 74 65 72 63 61 72 64
87 01 01
90 00
Part 2: understand TLV
EMV makes extensive use of TLV structures:
Tag | Length | Value
For example:
50 0A 4D 61 73 74 65 72 63 61 72 64
breaks down as:
50
Tag
0A
Length = 10 bytes
4D 61 73 74 65 72 63 61 72 64
Value
A tag can occupy more than one byte. In this response, BF 0C is the single tag BF0C, not two independent tags.
Part 3: FCI Template and DF Name
6F 2F: FCI Template
The response begins with 6F 2F. Tag 6F is the File Control Information (FCI) Template. Length 2F means its value contains 0x2F, or 47, bytes.
84 0E: DF Name
84 0E
32 50 41 59 2E 53 59 53 2E 44 44 46 30 31
Tag 84 is the DF Name and 0E is a length of 14 bytes. Converting the value from ASCII hexadecimal yields:
2PAY.SYS.DDF01
The card is confirming which environment was selected.
A5, BF0C, and the Directory Entry
A5 1D
BF 0C 1A
61 18
Tag A5 contains additional FCI information. Inside it, tag BF0C contains PPSE information. Inside that structure, tag 61 is a Directory Entry describing one available application.
4F 07: Application Identifier
4F 07 A0 00 00 00 04 10 10
Tag 4F contains the Application Identifier / ADF Name. Its seven-byte value is:
AID = A0000000041010
50 0A: Application Label
50 0A 4D 61 73 74 65 72 63 61 72 64
Tag 50 is the Application Label. Its ten value bytes decode directly from ASCII hexadecimal to:
Mastercard
The label is not inferred only from the AID. The card returned the text Mastercard inside tag 50.
87 01 01: Application Priority Indicator
87 = Application Priority Indicator
01 = Length of one byte
01 = Value
We do not need to use the priority value yet. For now, recognize it as part of the application description.
90 00: command completed successfully
The response ends with:
SW1 = 90
SW2 = 00
ISO/IEC 7816-4 defines 9000 as normal processing. Therefore:
SELECT PPSE
Result: OK
The complete response now makes sense
6F 2F FCI Template
84 0E DF Name
32 50 41 59
2E 53 59 53
2E 44 44 46
30 31
"2PAY.SYS.DDF01"
A5 1D FCI Proprietary Template
BF0C 1A
61 18 Directory Entry
4F 07 Application Identifier
A0 00 00 00
04 10 10
50 0A Application Label
4D 61 73 74
65 72 63 61
72 64
"Mastercard"
87 01 Application Priority Indicator
01
90 00 Command completed successfully
In plain language, the exchange says:
POOM:
Select the contactless payment application environment.
Card:
I found it.
I advertise one application:
AID:
A0000000041010
Label:
Mastercard
Part 4: SELECT the discovered application
The PPSE response provided this seven-byte AID:
A0 00 00 00 04 10 10
Because it contains seven bytes, Lc = 07. We can construct another SELECT:
00 A4 04 00 07 A0 00 00 00 04 10 10 00
Separated into fields:
00 | A4 | 04 | 00 | 07 | A0 00 00 00 04 10 10 | 00
CLA INS P1 P2 Lc Data Le
In plain language:
Card, select the application you just advertised as
A0000000041010.
Send the AID returned by your own card. For the example above:
nfc-card-send 00 A4 04 00 07 A0 00 00 00 04 10 10 00
POOM returned:
poom> nfc-card-send 00 A4 04 00 07 A0 00 00 00 04 10 10 00
[TX] 0A 00 00 A4 04 00 07 A0 00 00 00 04 10 10 00
[RX] 0A 00 69 85
R-APDU: 69 85
Interpret 69 85
The R-APDU contains only the status words:
SW1 = 69
SW2 = 85
ISO/IEC 7816-4 classifies 69XX as Command not allowed, and 69 85 specifically as:
Conditions of use not satisfied
This is different from:
6A 82
File not found
6A 82 says the requested object was not found. 69 85 says the operation cannot run under the current conditions. ISO/IEC 7816-4 alone does not tell us which application-specific condition caused the rejection.
What the experiment does prove is:
SELECT PPSE
90 00
OK
Discovered AID
A0000000041010
Application Label
Mastercard
SELECT AID
69 85
Conditions of use not satisfied
The NFC and ISO-DEP communication is working, and the card is interpreting our APDUs.
What you should learn
- Establish ISO-DEP communication.
- Send
SELECTfor2PAY.SYS.DDF01. - Confirm a successful
90 00response. - Interpret the response as nested TLV data.
- Find the application in tag
4F. - Decode the Application Label in tag
50. - Attempt to select the discovered AID.
- Interpret
69 85asConditions of use not satisfied.
Instead of seeing 6F 2F 84 0E 32 50 ... as a single hexadecimal string, we can now recognize:
FCI
PPSE
Directory Entry
AID
Application Label
Status Words
The next step is not to send GET PROCESSING OPTIONS. First, investigate why this application returns 69 85 during SELECT AID and compare the result with another card you own or a dedicated test card.