How to Navigate a Smart Card File System — SELECT, READ BINARY, READ RECORD

Every smart card stores data in a hierarchical file system defined by ISO 7816-4. Whether you're reading EMV payment records, extracting a SIM phonebook, or debugging a PIV card, the navigation pattern is the same: SELECT a file, then READ it. This guide covers the full file system model with real APDU traces you can use immediately.

1. The ISO 7816-4 File Model: MF, DF, EF

The file system is a tree with three node types:

TypeFull NameRoleMax per Card
MFMaster FileRoot directory. Every card has exactly one MF, selected at reset on some cards (FID = 3F 00)1
DFDedicated FileDirectory / application container. Holds EFs and child DFs. Can be selected by FID or AIDUnlimited (card memory permitting)
EFElementary FileLeaf node containing actual data. Cannot contain other files. Must be under MF or a DFUnlimited

The typical structure looks like this:

MF (3F 00)                        ← Root
├── EF.DIR (2F 00)                ← Application directory (list of AIDs)
├── DF.CardManager                ← GlobalPlatform card manager (security domain)
├── DF.PIV (A0 00 00 03 08)       ← PIV application
│   ├── EF.CardHolderUUID
│   ├── EF.Certificate
│   └── EF.KeyHistory
├── DF.EMV (A0 00 00 00 03 10)    ← EMV payment application (1PAY.SYS.DDF01)
│   ├── EF.ICC (2F 01)            ← ICC public key certificate
│   └── DF.Visa (A0 00 00 00 03 10 10)  ← Visa AID
│       ├── EF.Record (SFI 01)    ← Payment records (track 2 equivalent data)
│       └── EF.Log (SFI 02)       ← Transaction log
└── DF.SIM (7F 20)                ← GSM/UICC telecom
    ├── DF.GSM (7F 20)
    │   └── EF.IMSI (6F 07)
    └── EF.ICCID (2F E2)
Key insight: DFs are the directories. EFs are the data files. You SELECT a DF to enter it, then SELECT or READ its child EFs. The MF is just a special DF at the root.

2. File Types: How Data Is Stored

EFs come in four structural types. The type determines which READ command to use:

TypeStructureRead CommandUsed For
TransparentRaw byte sequence (binary blob)READ BINARYCertificates, keys, ATR historical bytes, serial numbers
Linear FixedFixed-length records (record 1, 2, 3...)READ RECORDEMV payment records, phonebook entries, transaction logs
Linear VariableVariable-length recordsREAD RECORDFree-form text, logs with variable entries
CyclicFixed-length ring buffer (newest overwrites oldest)READ RECORDATR event log, transaction counters

The file type is discovered by parsing the File Control Information (FCI) returned after SELECT — see section 5 below.

3. The SELECT Command — Finding Your File

SELECT (INS A4) navigates to any file in the tree. P1 controls the selection method:

P1ValueSelection MethodData Field
00Select by FIDDirect file identifier (2 bytes)FID (e.g. 3F 00 for MF)
04Select by AIDApplication identifier (5-16 bytes)AID (e.g. A0 00 00 00 03 10 10 for Visa)
08Select by path (from MF)Absolute path from rootSequence of FIDs
09Select by path (from current DF)Relative path from current positionSequence of FIDs

P2 is normally 00 (return FCI) or 0C (no FCI, faster). Always use 00 when exploring — the FCI tells you the file type, size, and access conditions.

Select the MF (Root)

>> 00 A4 00 00 02 3F 00
<< 90 00                          # MF selected, at root now

Select an EMV Application by AID

>> 00 A4 04 00 07 A0 00 00 00 03 10 10   # Select Visa AID
<< 6F 1F 84 07 A0 00 00 00 03 10 10      # FCI template: AID confirmed
   A5 14 88 01 01 5F 2D 02 7A 65 ...       # SFI, language preference etc.
   90 00                                    # Success

Select an EF by FID (After Selecting Parent DF)

>> 00 A4 00 00 02 2F 01            # Select EF.ICC (under EMV DF)
<< 6F 17 82 01 05 83 02 2F 01      # FCI: file descriptor + FID
   86 03 15 00 FF                  # Security attribute
   8A 01 01                        # Life cycle status
   90 00                           # Success

4. READ BINARY — Extracting Data from Transparent Files

READ BINARY (INS B0) reads raw bytes from a transparent EF. P1-P2 form a 15-bit file offset (bit 8 of P1 is reserved, must be 0):

# P1 = high byte of offset (bit 8 = 0, so 0x00-0x7F valid)
# P2 = low byte of offset (0x00-0xFF, full range)
# Offset = (P1 & 0x7F) << 8 | P2

# Read 10 bytes from offset 0:
>> 00 B0 00 00 0A
<< 47 75 61 6E 67 7A 68 6F 75 20 90 00    # "Guangzhou " + SW OK

The offset calculation trips people up:

# Requested offset: 256 (0x0100)
# P1 = (256 >> 8) & 0x7F = 0x01
# P2 = 256 & 0xFF = 0x00
>> 00 B0 01 00 10               # Read 16 bytes from offset 256 (correct)

# Requested offset: 32768 (0x8000) — exceeds 15-bit limit
# Cards with files > 32KB use "odd INS" B1 for the high bit
>> 00 B1 00 00 10               # READ BINARY with odd INS (high offset)

Read EMV Payment Record by SFI

EMV uses Short File Identifier (SFI) instead of FID for efficiency. SFI values are 1-30, encoded in P2 bits 3-7 with the first record flag in bit 0-2:

# SFI 01, read all records — use READ RECORD (see section 5)
# For transparent files referenced by SFI:
>> 00 B0 81 00 00               # SFI 01, offset 0, read all (Le=0)
Maximum offset: P1 bit 8 is reserved (must be 0), so the 15-bit offset maximum is 32,767 bytes. Files larger than 32KB require READ BINARY with odd INS (B1) to access the upper half. This is rare — most smart card files are under 32KB.

5. READ RECORD — Retrieving Structured Data

READ RECORD (INS B2) reads records from linear-fixed, linear-variable, or cyclic files. P1 = record number (1-based, or 00 for current). P2 controls the read mode:

P2ModeDescription
04P1 = record numberRead specific record by index
05P1 = 0, read firstRead from first record
06P1 = 0, read lastRead from last record
02P1 = 0, read nextRead next record (sequential iteration)
03P1 = 0, read previousRead previous record

Read EMV Application Data Records

# After selecting an EMV application, read payment records by SFI:
# SFI 01 (Track 2 equivalent data), Record 01
>> 00 B2 01 1C 00               # P2 = (SFI << 3) | 4 = (1 << 3) | 4 = 0x1C
<< 70 3A 57 13 47 69 73 78 ...  # Record template with Track 2 data
   90 00

# SFI 02 (transaction log), read all records sequentially:
>> 00 B2 01 2C 00               # Record 1 of SFI 02
<< ... 90 00
>> 00 B2 02 2C 00               # Record 2 of SFI 02
<< ... 90 00

Read SIM Phonebook (Linear Fixed)

# SIM phonebook is at 7F10/6F3A (ADN — Abbreviated Dialing Numbers)
>> 00 A4 00 00 02 7F 10         # Select DF.TELECOM
<< 90 00
>> 00 A4 00 00 02 6F 3A         # Select EF.ADN
<< ... 90 00                     # FCI tells us record length (e.g. 0x1C = 28 bytes)

>> 00 B2 01 04 1C               # READ RECORD 1, length 28
<< 4D 6F 6D 05 81 10 ...        # Record data (name + number encoded)
   90 00

6. Parsing File Control Information (FCI)

After every SELECT, the card returns an FCI template containing critical metadata about the selected file. The FCI is a BER-TLV structure under tag 6F:

TagNameWhat It Tells You
81File SizeTotal data size in bytes (for transparent files)
82File DescriptorByte 1: file type + structure. See decode table below
83File IdentifierThe FID (2 bytes) — confirms you selected the right file
84DF NameThe AID (5-16 bytes) — confirms application identity
86Security AttributesAccess conditions for READ, UPDATE, etc.
88SFIShort File Identifier (1 byte) — used by EMV

File Descriptor Byte Decode

# Byte format:  | 7 6 5 4 3 | 2 1 0 |
#                | File type  | Structure |
#
# File type (bits 3-7):
#   0x0: EF (working)
#   0x1: EF (internal — for card OS only)
#   0x2: EF (proprietary)
#   0x8: DF (directory)
#
# Structure (bits 0-2) — only meaningful for EF:
#   0x0: No info given
#   0x1: Transparent
#   0x2: Linear fixed
#   0x3: Linear variable
#   0x4: Cyclic

# Example: 82 01 01  → File descriptor byte = 0x01
# Bits 7-3 = 00000 → EF (working)
# Bits 2-0 = 001 → Transparent

# Example: 82 01 02  → File descriptor byte = 0x02
# Bits 7-3 = 00000 → EF (working)
# Bits 2-0 = 010 → Linear fixed

# Example: 82 01 38  → File descriptor byte = 0x38
# Bits 7-3 = 00111 → DF (directory)
# So this is a DF, not an EF
Test this yourself: Paste any FCI hex dump into our ISO 7816-4 File System Explorer — it auto-decodes the file descriptor, extracts the FID/AID, shows access conditions, and maps the full file tree.

7. Complete Navigation Workflow

Here's the standard pattern for exploring an unknown card:

# Step 1: Select MF (always safe to start here)
>> 00 A4 00 00 02 3F 00
<< ... 90 00

# Step 2: Read application directory (EF.DIR at FID 2F00)
>> 00 A4 00 00 02 2F 00
<< 6F 15 82 01 01 83 02 2F 00    # FCI: transparent EF, FID 2F00
   81 02 02 00                    # File size: 512 bytes (0x0200)
   90 00

# Step 3: READ BINARY to get AID list
>> 00 B0 00 00 00               # Read all (Le=0 = until end or SW)
<< 61 08 4F 06 A0 00 00 00 03   # AID #1 (EMV PSE)
   10 00 90 00

# Step 4: Select each AID and explore
>> 00 A4 04 00 06 A0 00 00 00 03 10 00
<< ... 90 00                     # FCI returned

# Step 5: Inside the application, SELECT the file of interest
>> 00 A4 00 00 02 2F 01
<< ... 90 00                     # FCI returned, now know file type + size

# Step 6: READ BINARY or READ RECORD depending on file type
>> 00 B0 00 00 00               # or READ RECORD for structured files
<< ... 90 00

8. Common Errors and Fixes

ErrorMeaningFix
6A 82File not found — FID or AID doesn't exist under current DFSelect correct parent DF first, or verify FID/AID spelling
69 82Security not satisfied — need PIN or authentication before reading this fileVerify PIN or establish secure channel first
6A 86Wrong P1-P2 — invalid offset (bit 8 of P1 set), or invalid record numberCheck P1-P2 encoding. For offset > 32767, use odd INS B1
67 00Wrong length — Le exceeds file size or record lengthCheck file size from FCI response (81 tag), reduce Le
6B 00Wrong Le — requested length doesn't match expectedUse 00 for Le (read until end) and handle 61XX response
69 85Conditions not satisfied — wrong DF selected, or file not in current stateEnsure parent DF is selected; check file lifecycle status
62 83Selected file in terminated state — cannot readFile is locked/deactivated; try a different file or re-personalize the card

9. T=0 vs T=1 Considerations

File navigation commands work the same way on both protocols, but T=0 requires special handling for data returned in response:

# T=0 READ BINARY with unknown file size:
>> 00 B0 00 00 00               # Le = 0 (read all)
# T=0 card responds:
<< 61 1A                         # "I have 0x1A (26) bytes — ask with GET RESPONSE"
>> 00 C0 00 00 1A               # GET RESPONSE, Le = 0x1A
<< ...data... 90 00

# T=1 card responds directly:
>> 00 B0 00 00 00               # Le = 0
<< ...data... 90 00              # Data returned inline
Pro tip: Always wrap your file reads in a 61XX/6CXX handling loop. Our APDU Response Debugger auto-decodes all status words — paste 61 1A and it tells you exactly how many bytes to request.

Related Tools

ISO 7816-4 File System Explorer — Visual file tree with FCI decoding | APDU Command Builder — Build SELECT/READ commands | APDU Response Debugger — Decode SW1 SW2 instantly | ATR Decoder — Parse card capabilities before navigation | ISO 7816 Protocol Reference — Full protocol reference