Using the SIMcard as a Security Module (HSM)

Publication date:
Last update: 2021-12-31
Author:

 

The previous article stated that SIMcards can grant carrier privileges. These privileges let you get the highest and most sensitive Android permissions, without rooting the device. Therefore, it is clear that both the mobile operators and the Android vendors do trust the SIM as a security device.

The SIMcard as a Security Module (HSM)

The SIMcards are devices designed to resist any hacking attempt. These devices include automatic locking mechanisms to protect sensitive information. For example, SIM tracing and debugging equipment can cost thousands of dollars, even though it may only intercepts data exchanged between the SIM and the phone, like a network sniffer. These devices are unable to clone the card or extract the keys.

 

HSM modules

Since the SIM is very secure, more secure than any type of software protection, there are several use cases for the SIM as a Hardware Security Module (HSM). HSM modules are physical cryptographic processors implemented to safeguard and manage cryptographic keys. Although there are HSM emulators in software, physical HSM modules can be more secure. This makes reverse engineering almost impossible because there is no way to read the processor memory externally. In contrast, software emulators cannot protect the memory physically. SIM manufacturers use the same argument to support that physical chips are more secure than virtual SIMs.

Mini-SIM, micro-SIM, nano-SIM, eSIM

Virtual SIMs should not be confused with the evolution of eSIM. The latter virtualizes the data contained in the SIM, but the storage device is a physical chip, which protects memory access in the same way as the traditional SIM does. This chip is not removable. That's why eSIM is the embedded version of the SIM.

The mobile subscription authentication keys are stored inside the SIM. However, the SIM can store additional keys. For example, some banks use this feature to encrypt the mobile transactions. Bank keys are different from the mobile network authentication keys, but they are stored and protected in the same way.

 

APDU commands

The communication between the phone and the SIM is implemented using APDU commands, as defined in the ISO/IEC 7816-4 standard.1

Traditionally the phone initiates the communication. The communication is synchronous. It means that a response from the SIM is expected before sending the next APDU:

Communication with the SIM using APDU commands

The APDU command sent to the SIM includes a mandatory 4-octets header: CLA, INS, P1 and P2.

CLAClass: ETSI, 3GPP, Global Platform2
INSInstruction code
P1Parameter #1
P2Parameter #2

 

The remaining part of the APDU is optional. It may include additional data. For example, this additional data is used to select a file or an applet in the SIM, send some data to the applet and so on. The data format is application-specific, but the length of the APDU has to comply with the ISO/IEC 7816-4 standard.

After processing the APDU the SIM produces a response. According to the standard, the last two octets of the response, known as Status Word (SW), indicate the status of the result. Usually the value 9000 in hexadecimal corresponds to a successful result. Let's see an example of an APDU and the corresponding response:

>> 00 A4 00 00 02 3F 00
<< 90 00

The content of the APDU can be interpreted according to the ETSI TS 102.221 standard,3 as follows:

APDU: SELECT MF

The CLA octet is telling that the instruction class is 3G. The INS octet corresponds to the SELECT instruction. Parameters 1 and 2 can indicate the selection mode. In this case, we are selecting the root directory known as Master File (MF) with identifier 3F00. The LC octet, preceding the MF identifier, specifies the length of the additional data. In this case, the value is 2 because the MF identifier requires 2 octets. The root directory is present in all SIM file systems. Therefore, this APDU should work properly on any 3G-compatible SIM.

 

JavaCard applets

Let's suppose that the SIM has a cryptographic applet installed, which is used to encrypt sensitive data. The applets are identified by a unique ID known as AID. Let's suppose that the AID of our test applet is 01020304050607. Normally the AID is longer, but let's suppose it is this short for simplicity. Therefore, the APDU to select this applet would be:

>> 00 A4 04 00 07 01 02 03 04 05 06 07 00
<< 90 00

After selecting the applet, we can send another APDU containing the data to encrypt.

For more information about JavaCard applets and code examples, refer to the Oracle JavaCard official site. The basic examples can be compiled using free tools, available from the same site, and installed in a test SIM. The vast majority of the current SIMcards support this technology. Note that JavaCard is a Java-based technology. JavaCard applet development is somewhat similar to Java application development, except that memory management is different because memory is very limited in the SIM. The JavaCard bytecode format is different from the JVM bytecode, but this difference is transparent to the developers.

JavaCard applets can use the SIM Application Toolkit technology, which allows executing proactive commands to send SMS, display notifications and interactive menus, among other features.

 

Submitting APDU through AT+CSIM

The simplest way to put this into practice is to use a GSM modem to send the APDU through a terminal emulator, such as Hyper Terminal or PuTTY. You can also use the free Java library CelerCOM for the same purpose.

GSM modems

If you have a GSM modem, there is no need to use a card reader and specialized software to send APDU. Most GSM modems support the AT command AT+CSIM, which allows encapsulating APDU commands for the SIM. Internally, Android uses this command to transmit the APDU created through the TelephonyManager service.

For example, the APDU to select the MF directory can be sent as follows:

AT+CSIM=14,"00a40000023f00"

The value 14 is the length of the APDU in characters.

If the modem responds with a generic error like +CME ERROR it may be possible that the modem doesn't support the AT+CSIM command. Most GSM modems do support this command. It is even possible to use an Android phone as a modem, but it is more practical to use a dedicated USB modem.

The AT+CSIM command can be useful to verify the validity of the APDU. It is recommended to do these tests before using the same APDU in an Android application.

 

Open Mobile API

If we have already installed the JavaCard applet in the test SIM and validated the APDU commands, the next step is implementing an Android application to interact with the SIM.

Android supports sending APDU through the TelephonyManager service since version 5.1. Since Android 9 this functionality is available through SEService. The latter option is based on the Open Mobile API v34 specification maintained by the Trusted Connectivity Alliance. This organization, formerly known as SIMAlliance, is made up of the SIM manufacturers. All these APIs require elevated permissions. However, if we are using a test SIM, we can install the hash of our development key inside ARA or ARF to obtain carrier privileges, as explained in the previous article.

There are alternative implementations, based on the Open Mobile API. One of the best-known ones is Secure Element Evaluation Kit (SEEK).5 This API was created by Giesecke & Devrient, a SIMcard manufacturer.

Here's an example that produces the same APDU, the one we tested earlier with AT+CSIM, using TelephonyManager:

import android.telephony.TelephonyManager;
import android.telephony.IccOpenLogicalChannelResponse;

   TelephonyManager tm = (TelephonyManager)getSystemService("phone");
   IccOpenLogicalChannelResponse resp =
      tm.iccOpenLogicalChannel(
         "01020304050607", // AID
         0                 // p2
   );
   int ch = resp.getChannel();
   if(ch > 0){
      String sResp =
         tm.iccTransmitApduLogicalChannel(
            ch,
            CLA, INS, P1, P2, P3, DATA
      );
      tm.iccCloseLogicalChannel(ch);
   }
 

This code tries to select the JavaCard applet with AID 01020304050607. After that, it submits the APDU corresponding to the CLA, INS, P1, P2, P3 and DATA parameters. Parameter P3 is optional. If not applicable, a negative value can be specified to send the APDU with 4 octets only: CLA, INS, P1 and P2.

Sometimes the SIMcard responds with SW 61XX. That is, the octet before the last one in the APDU response has the hexadecimal value 61. This means that the APDU cannot be processed at the moment, but it can be retried. A reliable implementation should process these 61XX responses and generate at least one retry. It is important to limit the retries to avoid overloading the SIM and producing infinite loops. A single retry may be enough.

Implementing error handling is important. The above code should be enclosed in a try/catch block. Moreover, these TelephonyManager APIs require the MODIFY_PHONE_STATE permission. This permission can be granted at installation time until Android 2.2. Since Android 2.3 this permission can be obtained by system applications (pre-installed) or through carrier privileges. The latter option is more recommended, as explained above.

Here is another example, using the Open Mobile API:

import android.se.omapi.SEService;
import android.se.omapi.Session;
import android.se.omapi.Channel;
import android.se.omapi.Reader;
import java.util.concurrent.Executors;

   ExecutorService exe =
      Executors.newSingleThreadExecutor();
   SEService se = new SEService(
      this, // context
      exe,  // callbacks processor
      this  // listener
   );
   Reader[] rdrs = se.getReaders();
   if(rdrs.length > 0){
      Session sess = rdrs[0].openSession();
      Channel ch = sess.openLogicalChannel(
         // AID
         new byte[]{ 1, 2, 3, 4, 5, 6, 7 },
         0 // p2
      );
      byte[] respApdu = ch.transmit(
         new byte[]{ /* APDU */ }
      );
      ch.close();
   }
 

Note that in this case the APDU are encoded as byte arrays, not hexadecimal strings. Another important difference is that the API can handle retries automatically; there is no need to process SW 61XX responses.

In this case, it is also recommended to add a try/catch block to handle errors. One of the possible errors is the lack of permissions.

The TelefonyManager and SEService examples can be combined to implement a solution compatible with different Android versions.

 

Conclusions

The SIM is useful as a security module to store sensitive data, implementing encryption and decryption services, among other uses. The main advantage has to do with the physical security of the SIM.

Android apps require elevated permissions to interact with the SIM. Obtaining these permissions is possible through the carrier privileges, which can be granted through the SIM itself.

There are different Android APIs to interact with the SIM. The availability of these APIs depends on the manufacturer and the operating system version. It is possible to combine the APIs to support multiple devices.

 

References

  1. «ISO/IEC 7816-4», ISO/IEC JTC 1/SC 17 (2005)
  2. «Global Platform Technology Card Specification v2.3.1», Global Platform (2018)
  3. «Smart Cards; UICC-Terminal interface; Physical and logical characteristics (Release 15)», ETSI (2018)
  4. «Open Mobile API v3.0», Trusted Connectivity Alliance (2016)
  5. Michael Roland, Michael Hölzl (2016). «Open Mobile API: Accessing the UICC on Android Devices», University of Applied Sciences Upper Austria.