doc/unofficial_desfire_bible.md
MIFARE DESFire is a family of contactless smart card ICs (Integrated Circuits) compliant with ISO/IEC 14443-4 Type A. This comprehensive reference documents all DESFire versions from Classic (D40) through EV3, including the cost-optimized Light variant. Every technical detail includes inline citations to ensure accuracy and traceability.
This bible covers:
| Feature | Classic/EV0 | EV1 | EV2 | EV3 | Light |
|---|---|---|---|---|---|
| Memory Options | 4KB | 2/4/8KB | 2/4/8KB | 2/4/8/16KB | 0.5/2KB |
| Max Applications | 28 1 | 28 1 | Unlimited 2 | Unlimited 2 | 1 3 |
| Files per App | 16 4 | 32 4 | 32 5 | 32 5 | 32 3 |
| Frame Size | 64B | 64B | 128B 5 | 256B 6 | 64B |
| DES/3DES | ✓ | ✓ | ✓ | ✓ | ✗ |
| AES-128 | ✗ | ✓ 4 | ✓ | ✓ | ✓ 3 |
| Random UID | ✗ | ✓ 4 | ✓ | ✓ | ✗ |
| VCA | ✗ | ✗ | ✓ 5 | ✓ | ✗ |
| Proximity Check | ✗ | ✗ | ✓ 5 | ✓ | ✗ |
| Transaction MAC | ✗ | ✗ | ✓ 5 | ✓ | Limited |
| Transaction Timer | ✗ | ✗ | ✗ | ✓ 6 | ✗ |
| SDM/SUN | ✗ | ✗ | ✗ | ✓ 6 | ✗ |
| Speed | 106 kbps | 848 kbps 4 | 848 kbps | 1.6x EV1 6 | 106 kbps |
| CC Certification | ✗ | EAL4+ | EAL5+ | EAL5+ 7 | EAL4+ |
All DESFire cards follow a hierarchical structure:
PICC (Card) Level
├── Master Application (AID 0x000000)
│ ├── PICC Master Key
│ └── Card Configuration
└── Applications (AID 0x000001 - 0xFFFFFF)
├── Application Master Key
├── Application Keys (0-13)
└── Files (0-31)
├── Standard Data Files
├── Backup Files
├── Value Files
├── Linear Record Files
└── Cyclic Record Files
Value: 4 bytes (signed int32)
Each file has configurable access rights [Source: AN11004.pdf]:
Communication settings per file:
Proximity Check [Source: AN12696.pdf]:
Virtual Card Architecture (VCA) [Source: AN12696.pdf]:
Transaction MAC (TMAC) [Source: AN12696.pdf, MF2DLHX0.pdf]:
Secure Messaging v2 [Source: AN12696.pdf]:
Transaction Timer [Source: AN12753.pdf]:
Secure Dynamic Messaging (SDM) [Source: AN12753.pdf]:
Common Criteria EAL5+ [Source: plt-05618-a.0-mifare-desfire-ev3-application-note.pdf]:
CA 01 00 00 0F 81 creates AID 0x000001 with 1 AES keyPCD → PICC: 90 0A 00 00 01 [KeyNo] 00
└─ Authenticate command (0x0A)
[Source: DESFire DES authentication D40-DES authentification.pdf, line 7]
PICC → PCD: [Ek(RndB)] 91 AF
└─ 8 bytes encrypted RndB
[Source: DESFire DES authentication D40-DES authentification.pdf, line 9]
[Source: DESFire DES authentication D40-DES authentification.pdf, lines 23-39]
PCD → PICC: 90 AF 00 00 10 [Ek(RndA || RndB_rot)] 00
[Source: DESFire DES authentication D40-DES authentification.pdf, line 41]
PICC → PCD: [Ek(RndA_rot)] 91 00
PCD decrypts and verifies rotated RndA matches [Source: DESFire DES authentication D40-DES authentification.pdf, lines 43-56]
Similar flow but with 16-byte blocks:
[Source: DESFire.py, lines 79-144]
Capability Exchange:
PCD → PICC: 71 [KeyNo] [Len] [PCDcap2]
PICC → PCD: [TI] [PDcap2] [PCDcap2] AF
[Source: desfire_ev3_authentication.pdf, lines 18-25]
Complete Authentication:
PCD → PICC: 77 [KeyNo]
Requires previous EV2First in same session [Source: desfire_ev3_authentication.pdf, lines 27-30]
SessionKey = RndA[0:4] || RndB[0:4]
[Source: DESFire DES authentication D40-DES authentification.pdf, lines 66-71]
SessionKey = RndA[0:4] || RndB[0:4] || RndA[4:8] || RndB[4:8]
[Source: DESFire.py, lines 135-136]
SessionKey = RndA[0:4] || RndB[0:4] ||
RndA[6:10] || RndB[6:10] ||
RndA[12:16] || RndB[12:16]
[Source: DESFire.py, lines 138-141]
SessionKey = RndA[0:4] || RndB[0:4] || RndA[12:16] || RndB[12:16]
[Source: DESFire.py, lines 143-144]
# Generate L by encrypting zero block
L = AES_Encrypt(Key, 0x00000000000000000000000000000000)
# Generate K1
K1 = L << 1
if MSB(L) == 1:
K1 = K1 XOR Rb # Rb = 0x87 for AES
# Generate K2
K2 = K1 << 1
if MSB(K1) == 1:
K2 = K2 XOR Rb
[Source: mifare_desfire_crypto.c, lines 95-123]
[Source: mifare_desfire_crypto.c, lines 126-151]
Command: CD [FileNo] [CommSettings] [AccessRights] [FileSize]
Example: CD 01 00 00 00 00 10 00 00 // File 01, plain, free access, 16 bytes
[Source: protocols.h, line 357]
Command: BD [FileNo] [Offset-3B] [Length-3B]
Example: BD 01 00 00 00 10 00 00 // Read 16 bytes from offset 0
[Source: protocols.h, line 367]
Command: 3D [FileNo] [Offset-3B] [Length-3B] [Data]
Example: 3D 01 00 00 00 04 00 00 DE AD BE EF // Write 4 bytes
[Source: protocols.h, line 368]
Command: CC [FileNo] [CommSettings] [AccessRights] [LowerLimit-4B] [UpperLimit-4B] [Value-4B] [LimitedCreditEnable]
Example: CC 02 00 00 00 00 00 00 00 E8 03 00 00 00 00 00 00 01
// Value file 02, limits 0-1000, initial 0, limited credit enabled
[Source: protocols.h, line 359]
Command: 0C [FileNo] [Amount-4B]
Example: 0C 02 64 00 00 00 // Credit 100 to file 02
[Source: protocols.h, line 370]
Command: DC [FileNo] [Amount-4B]
Example: DC 02 0A 00 00 00 // Debit 10 from file 02
[Source: protocols.h, line 371]
Command: C1 [FileNo] [CommSettings] [AccessRights] [RecordSize-3B] [MaxRecords-3B]
Example: C1 03 00 00 00 20 00 00 0A 00 00
// Linear record file 03, 32-byte records, max 10 records
[Source: protocols.h, line 360]
Command: 3B [FileNo] [Offset-3B] [Length-3B] [Data]
Example: 3B 03 00 00 00 20 00 00 [32 bytes of data]
[Source: protocols.h, line 373]
Command: BB [FileNo] [RecordNo-3B] [NumRecords-3B]
Example: BB 03 00 00 00 05 00 00 // Read 5 records starting from record 0
[Source: protocols.h, line 374]
For Backup and Value files:
[Source: protocols.h, lines 376-377]
Prepare Diversification Input:
M = [Constant] || [UID] || [AID] || [SystemIdentifier]
Constants:
Calculate Diversified Key:
DiversifiedKey = CMAC(MasterKey, M)
[Source: mifare_key_deriver.c, lines 101-177]
IV = EncryptedFlag || TI || .pdfCtr || ZeroPadding
# Create application 0x000001 with 5 AES keys
aid = [0x01, 0x00, 0x00]
key_settings = 0x0F # All keys changeable, free directory
num_keys = 0x85 # 5 keys, AES encryption (bit 7 set)
command = [0xCA] + aid + [key_settings, num_keys]
response = send_command(command)
# Authenticate first
authenticate_aes(key_no=0x01, key=master_key)
# Create MACed file
create_std_file(file_no=0x01,
comm_settings=0x01, # MACed
access_rights=0x0000, # Free access
file_size=32)
# Write data (will be MACed automatically)
write_data(file_no=0x01, offset=0, data=b"Secure data here")
# Create value file with limits
create_value_file(file_no=0x02,
lower_limit=0,
upper_limit=10000,
initial_value=1000,
limited_credit=True)
# Perform operations
credit(file_no=0x02, amount=500) # Balance: 1500
debit(file_no=0x02, amount=200) # Balance: 1300
# Commit all changes
commit_transaction()
End of The Unofficial DESFire Bible
Compiled from official documentation and implementation sources All information includes inline citations for verification Last updated: Based on DESFire EV3 specifications