SIM Card Programming
Understanding how to develop applications and manage data on SIM cards
SIM Card Programming Environments
Modern SIM cards support several programming environments and technologies that enable the development of secure applications:
JavaCard
JavaCard is the most widely used programming environment for SIM cards. It's a subset of Java designed specifically for smart cards and other devices with limited memory and processing capabilities.
Key features of JavaCard include:
- Object-oriented programming model
- Applet-based architecture
- Strong security features
- Interoperability across different card platforms
- Support for post-issuance application loading
JavaCard applications are called "applets" and follow a specific lifecycle model defined by the JavaCard Runtime Environment (JCRE).
JavaCard Versions
- JavaCard 2.1: Basic functionality
- JavaCard 2.2: Added logical channels, enhanced crypto
- JavaCard 3.0: Added web applications, extended memory
- JavaCard 3.1: Enhanced security, biometric support
JavaCard Architecture
- JavaCard Virtual Machine (JCVM)
- JavaCard Runtime Environment (JCRE)
- JavaCard API
- Applet Framework
JavaCard Programming
JavaCard is the most widely used programming environment for SIM cards. Let's explore the basics of JavaCard development:
JavaCard Applet Structure
A typical JavaCard applet has the following structure:
1package com.example.simapplet;23import javacard.framework.*;45public class ExampleApplet extends Applet {6 // Constants7 private static final byte CLA_EXAMPLE = (byte) 0x80;8 private static final byte INS_GET_DATA = (byte) 0x01;9 private static final byte INS_SET_DATA = (byte) 0x02;10 11 // Data12 private byte[] data;13 14 // Constructor15 private ExampleApplet() {16 data = new byte[10];17 register();18 }19 20 // Installation method21 public static void install(byte[] bArray, short bOffset, byte bLength) {22 new ExampleApplet();23 }24 25 // Process method - handles incoming APDUs26 public void process(APDU apdu) throws ISOException {27 // Get the APDU buffer28 byte[] buffer = apdu.getBuffer();29 30 // Check for SELECT command31 if (selectingApplet()) {32 return;33 }34 35 // Check the CLA byte36 if (buffer[ISO7816.OFFSET_CLA] != CLA_EXAMPLE) {37 ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);38 }39 40 // Process the instruction41 switch (buffer[ISO7816.OFFSET_INS]) {42 case INS_GET_DATA:43 getData(apdu);44 break;45 case INS_SET_DATA:46 setData(apdu);47 break;48 default:49 ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);50 }51 }52 53 // Method to get data54 private void getData(APDU apdu) {55 byte[] buffer = apdu.getBuffer();56 short length = (short) data.length;57 58 // Send the data59 Util.arrayCopy(data, (short) 0, buffer, (short) 0, length);60 apdu.setOutgoingAndSend((short) 0, length);61 }62 63 // Method to set data64 private void setData(APDU apdu) {65 byte[] buffer = apdu.getBuffer();66 67 // Receive data68 short dataLength = apdu.setIncomingAndReceive();69 70 // Copy the received data71 Util.arrayCopy(buffer, ISO7816.OFFSET_CDATA, data, (short) 0, dataLength);72 }73}
JavaCard Lifecycle
JavaCard applets follow a specific lifecycle:
- Loading: The applet's CAP file is loaded onto the card
- Installation: The
install()
method is called - Registration: The applet calls
register()
to register with the JCRE - Selection: The applet is selected by an APDU command
- Processing: The applet processes APDU commands via
process()
- Deselection: Another applet is selected
- Uninstallation: The applet is removed from the card
JavaCard API
JavaCard provides a limited subset of Java APIs, plus specialized packages:
- javacard.framework: Core functionality
- javacard.security: Cryptographic services
- javacardx.crypto: Extended cryptography
- javacard.biometry: Biometric services (3.1+)
- javacard.framework.service: Service framework
JavaCard supports only a subset of Java language features and data types, with limitations on inheritance, objects, and dynamic memory allocation.
SIM Toolkit Programming
The SIM Application Toolkit (STK) allows SIM cards to initiate commands and interact with the mobile device [^7]. Programming STK applications involves:
Proactive Commands
STK applications use proactive commands to interact with the mobile device [^7]. These include:
- DISPLAY TEXT: Show text on the device screen
- GET INPUT: Request text input from the user
- SELECT ITEM: Display a menu for user selection
- SEND SMS: Send an SMS message
- SET UP CALL: Initiate a voice call
- LAUNCH BROWSER: Open a web browser
Event Handling
STK applications can register for various events from the mobile device [^7]:
- Menu Selection: User selects an STK menu item
- Call Control: Outgoing call is initiated
- SMS Control: Outgoing SMS is sent
- Timer Expiration: A timer set by the SIM expires
- Location Status: Device's network location changes
- Browser Termination: Browser session ends
STK Menu Example
Here's an example of a JavaCard applet that implements a simple STK menu:
1package com.example.stk;23import javacard.framework.*;4import sim.toolkit.*;56public class MenuApplet extends Applet implements ToolkitInterface, ToolkitConstants {7 // Menu items8 private static final byte ITEM_BALANCE = (byte) 1;9 private static final byte ITEM_TRANSFER = (byte) 2;10 private static final byte ITEM_SETTINGS = (byte) 3;11 12 // Menu text13 private static final String MENU_TITLE = "Banking Menu";14 private static final String[] MENU_ITEMS = {15 "Check Balance",16 "Transfer Money",17 "Settings"18 };19 20 // ToolkitRegistry reference21 private ToolkitRegistry reg;22 23 private MenuApplet() {24 // Register with the applet25 register();26 27 // Get the toolkit registry28 reg = ToolkitRegistry.getEntry();29 30 // Register for the MENU event31 reg.setEvent(EVENT_MENU_SELECTION);32 33 // Initialize the menu34 initializeMenu();35 }36 37 public static void install(byte[] bArray, short bOffset, byte bLength) {38 new MenuApplet();39 }40 41 private void initializeMenu() {42 // Create the main menu43 Menu menu = new Menu(MENU_TITLE, (short) 0, (short) MENU_TITLE.length(), (byte) 0);44 45 // Add menu items46 for (byte i = 0; i < MENU_ITEMS.length; i++) {47 menu.appendItem(MENU_ITEMS[i], (short) 0, (short) MENU_ITEMS[i].length(), (byte) (i + 1), false);48 }49 50 // Register the menu51 reg.registerMenu(menu);52 }53 54 public void process(APDU apdu) throws ISOException {55 // Process regular APDUs if needed56 if (selectingApplet()) {57 return;58 }59 60 // Other APDU processing...61 }62 63 public void processToolkit(byte event) throws ToolkitException {64 // Handle menu selection event65 if (event == EVENT_MENU_SELECTION) {66 // Get the selected item67 byte selectedItem = reg.getMenuItemIdentifier();68 69 // Handle the selection70 switch (selectedItem) {71 case ITEM_BALANCE:72 showBalance();73 break;74 case ITEM_TRANSFER:75 showTransferMenu();76 break;77 case ITEM_SETTINGS:78 showSettings();79 break;80 }81 }82 }83 84 private void showBalance() {85 // Create a display text proactive command86 ProactiveHandler handler = ProactiveHandler.getTheHandler();87 handler.init(PRO_CMD_DISPLAY_TEXT, (byte) 0x81, DEV_ID_DISPLAY);88 handler.appendTLV(TAG_TEXT_STRING, (byte) 0x04, "Your balance: $1,250.75");89 handler.send();90 }91 92 private void showTransferMenu() {93 // Implementation for transfer menu94 // ...95 }96 97 private void showSettings() {98 // Implementation for settings99 // ...100 }101}
APDU Communication
Application Protocol Data Units (APDUs) are the communication format used between a SIM card and a terminal (mobile device or card reader) [^5]. Understanding APDU structure is essential for SIM card programming:
Command APDU Structure
Field | Size | Description |
---|---|---|
CLA | 1 byte | Class byte - Indicates the command type |
INS | 1 byte | Instruction byte - Specifies the particular command |
P1, P2 | 2 bytes | Parameter bytes - Additional parameters for the command |
Lc | 0-3 bytes | Optional - Length of data to be sent |
Data | Variable | Optional - Data to be sent to the card |
Le | 0-3 bytes | Optional - Expected length of response data |
Response APDU Structure
Field | Size | Description |
---|---|---|
Data | Variable | Optional - Response data from the card |
SW1, SW2 | 2 bytes | Status Words - Indicate the result of the command |
Common Status Words
- 90 00: Success
- 61 XX: Success, XX bytes available
- 6A 82: File not found
- 6A 86: Incorrect P1/P2 parameters
- 6D 00: Instruction not supported
- 6E 00: Class not supported
- 67 00: Wrong length
- 69 82: Security status not satisfied
- 69 85: Conditions of use not satisfied
APDU Examples
SELECT Command
1// Select the MF (Master File)200 A4 00 00 02 3F 0034// Command breakdown:5// CLA: 00 - ISO/IEC 7816-4 compliant command6// INS: A4 - SELECT command7// P1: 00 - Select by file ID8// P2: 00 - First or only occurrence9// Lc: 02 - 2 bytes of data follow10// Data: 3F 00 - File ID of the MF11// Le: (absent) - No response data expected
READ BINARY Command
1// Read 10 bytes from transparent EF at offset 0200 B0 00 00 0A34// Command breakdown:5// CLA: 00 - ISO/IEC 7816-4 compliant command6// INS: B0 - READ BINARY command7// P1: 00 - High byte of offset (0)8// P2: 00 - Low byte of offset (0)9// Le: 0A - Request 10 bytes of data
UPDATE BINARY Command
1// Write 5 bytes to transparent EF at offset 0200 D6 00 00 05 01 02 03 04 0534// Command breakdown:5// CLA: 00 - ISO/IEC 7816-4 compliant command6// INS: D6 - UPDATE BINARY command7// P1: 00 - High byte of offset (0)8// P2: 00 - Low byte of offset (0)9// Lc: 05 - 5 bytes of data follow10// Data: 01 02 03 04 05 - Data to write
Over-The-Air (OTA) Programming
Over-The-Air (OTA) programming allows remote management of SIM cards after they have been deployed in the field. This is a critical capability for mobile operators and service providers:
OTA Architecture
OTA updates use a client-server architecture:
- OTA Server: Managed by the operator or service provider
- SMS Gateway: Converts server commands to SMS format
- Mobile Network: Delivers the SMS to the device
- SIM Card: Processes the OTA commands
The communication typically uses encrypted SMS messages with a special format defined in the GSM 03.48 (later 3GPP TS 23.048) specification.
OTA Operations
Common OTA operations include:
- Remote File Management: Read/write files on the SIM
- Applet Installation: Deploy new applications
- Applet Deletion: Remove applications
- Applet Personalization: Configure applications
- Key Management: Update cryptographic keys
- Profile Management: For eSIM, manage operator profiles
OTA Security
OTA operations involve sensitive operations on the SIM card, so security is paramount:
- Encryption: OTA messages are encrypted to prevent eavesdropping
- Authentication: Messages are signed to verify the sender's identity
- Integrity Protection: Ensures messages aren't tampered with in transit
- Replay Protection: Prevents reuse of previously captured messages
- Access Control: Only authorized entities can perform OTA operations
OTA Message Structure
OTA messages follow the structure defined in 3GPP TS 23.048:
1// OTA Message Structure2+------------------+3| SMS Header | Standard SMS header4+------------------+5| Command Packet | Contains the actual OTA command6| |7| +---------------+|8| | Security Header|| Contains security parameters9| +---------------+|10| | Command Header || Identifies the command type11| +---------------+|12| | Command Data || The actual command data13| +---------------+|14+------------------+1516// Example of a Remote File Management command17// (Simplified representation)18D0 // Command Packet Tag1981 // Length2002 // Command Header: Remote File Management21A4 00 00 02 3F 00 // SELECT command for MF22B0 00 00 0A // READ BINARY command for 10 bytes
SIM Card Development Tools
Several tools are available for SIM card development and testing:
Development Environments
- Eclipse with JCIDE: Popular IDE for JavaCard development
- NetBeans with JavaCard plugin: Alternative IDE
- Ant-JavaCard: Build tool for JavaCard projects
- Maven JavaCard Plugin: Maven integration for JavaCard
- GlobalPlatform Pro: Command-line tool for card management
Simulators and Emulators
- jCardSim: JavaCard simulator in pure Java
- Oracle JavaCard Simulator: Official simulator
- JCOP Tools: Simulator for NXP JCOP cards
- Gemalto Developer Suite: Comprehensive development environment
- pySim: Python tools for SIM card programming
Card Readers and Interfaces
- PC/SC Readers: Standard smart card readers
- PCSC-Lite: Linux implementation of PC/SC
- APDU Scanner: Analyze and debug APDU communication
- SIMTrace: Hardware for SIM card protocol analysis
- Osmocom SIMtrace: Open-source SIM tracing tools
SIM Programming Best Practices
Developing for SIM cards requires special considerations due to their constrained environment and security requirements:
Memory Management
- Minimize Object Creation: Create objects during installation, not during normal operation
- Reuse Arrays: Reuse existing arrays instead of creating new ones
- Avoid Recursion: Recursion can quickly exhaust the limited stack space
- Use Transient Objects: For temporary data that doesn't need to persist
- Be Aware of EEPROM Write Limitations: EEPROM has limited write cycles
Security Considerations
- Validate All Input: Never trust data received from outside the card
- Implement Secure Messaging: Encrypt sensitive communication
- Use Secure Random Numbers: For cryptographic operations
- Clear Sensitive Data: Zero out buffers containing sensitive information after use
- Implement Access Control: Restrict access to sensitive functions
- Protect Against Side-Channel Attacks: Consider timing attacks, power analysis, etc.
Performance Optimization
- Minimize EEPROM Writes: Group writes to reduce wear and improve performance
- Use RAM for Temporary Data: RAM operations are much faster than EEPROM
- Optimize Loops: Unroll small loops, minimize loop overhead
- Use Native Methods: For performance-critical operations
- Batch Operations: Process multiple items in a single command when possible
Testing and Debugging
- Test on Simulators First: Easier to debug than physical cards
- Implement Logging: Use available debug features or create your own logging mechanism
- Test Edge Cases: Buffer boundaries, maximum data sizes, etc.
- Test Security Features: Verify that security mechanisms work as expected
- Test with Different Card Readers: Ensure compatibility