Conventional wisdom says that an eSIM is permanently mounted onto a device’s motherboard. After all, that’s what makes it an embedded SIM, and that’s how it’s deployed on all smartphones supporting the technology. As a result, most people think that in order to take advantage of eSIM’s benefits, you need to buy a phone that has an eSIM.
That makes sense, right? That’s what I thought too until I learned about a product that brings eSIM to any existing Android phone. Given that there aren’t many Android phones on the market with eSIM support built-in, this opens up the technology to thousands of existing models and millions of new users.
How is it possible for a product to enable a feature that’s supposed to be built-in? Looking into this question led me down a rabbit hole of GSMA specifications and Android APIs to find out how it works, and in this week’s Android Dessert Bites, I’ll try to make sense of it all.
Meet the eSIM that's not embedded in your phone
A couple of weeks ago, I learned about a product called eSIM.me that offers to “make your smartphone eSIM compatible.” The company behind the product, Telco Village, advertises that it works with any Android device, in any country, and with any network (that supports eSIM provisioning, obviously). All you have to do is buy an eSIM.me card, insert it into your device’s SIM card slot, download the app, and then scan the QR code from your carrier to download an eSIM profile. It’s that easy.
I was initially skeptical that it would work since I thought eSIMs had to, you know, be embedded into the device. Plus, the product is fairly new, having only launched a few months ago, and the only reviews I could find were from random users on Reddit. Thankfully, a few developers I follow purchased the product and confirmed it works as advertised.
Something you may notice after setting up your own eSIM.me is that Android doesn’t recognize your provisioned SIM profiles as eSIM profiles. They’re not shown under the “downloaded SIM” section in Settings > Network & Internet > SIMs like they would be if you provision an eSIM using Google’s SIM Manager app. Instead, Android treats the eSIM profiles you download as if they’re any other physical SIMs inserted into the device. This doesn’t really change anything, but it’s an interesting quirk of this setup. To understand how this all works, we need to take a look at what’s inside the actual eSIM.me card, how it interacts with Android, and how eSIMs are normally supposed to be set up.
The card itself is obviously the most important piece of the puzzle, but despite its looks, it’s not a traditional SIM card. A traditional SIM card has a piece of silicon containing a very low-power CPU and a tiny amount of storage to store the software that communicates with the reader, the SIM profile, some messages, and some contacts. This silicon is called a UICC, or universal integrated circuit card, which is a smart card that conforms to the ETSI specification.
Traditional SIM cards come in a few form factors, from 1FF (full-size) to 2FF (mini) to micro (3FF) to nano (4FF). The eSIM.me card is triple-cut, ie. universal, so it can fit in SIM card trays ranging from 1FF to 4FF size. Traditional eSIMs come in the much smaller MFF2 (machine-to-machine) form factor, which is small enough to embed in the device’s motherboard. However, there’s nothing preventing an eSIM from being implemented in one of the form factors for the traditional removable SIM card, which is what the eSIM.me card does. (In fact, the GSMA’s consumer eSIM specification even references removable eUICCs, as does Android’s documentation on implementing eSIM.)
Like a traditional SIM card, the eSIM.me card has a piece of silicon with its own CPU and storage. But what differentiates the eSIM.me card from a traditional SIM card is that the smart card follows the newer eSIM specification from top to bottom. Instead of a traditional UICC, the eSIM.me card has an eUICC, or embedded universal integrated circuit card, which supports the GSMA’s consumer eSIM specification for managing multiple eSIM profiles and facilitates remote SIM provisioning.
The software within the eUICC, a JavaCard STK SIM applet that runs in an eSIM OS, communicates with the Android OS via application protocol data unit (APDU) commands, which are defined by the ISO-7816-4 standard. The eSIM.me app opens a logical channel to the eUICC so it can send those APDU commands. It does this through the Open Mobile API (OMAPI), which was added to Android with Android 9.
OMAPI standardizes the way apps communicate with secure elements/smart cards, such as a UICC or eUICC. The API existed prior to Android 9, but before its inclusion in AOSP, OEMs would have to include the OMAPI library in their builds so developers could use the API. Some OEMs did include the library in their pre-Android 9 builds, which is why the eSIM.me website mentions that “devices from Samsung, Huawei and Xiaomi even support eSIM.me from Android version 7.”
OMAPI’s introduction to AOSP also standardized the way that Android devices communicated with UICC/eUICC (and secure elements in general), making it possible to build an app like eSIM.me that can communicate with an eUICC across devices from different OEMs.
It would be problematic if just any app on your phone could communicate with the eUICC using the APIs I just mentioned. After all, the eUICC stores data about your SIM profile, which the carrier uses to decide whether your device can connect to their network as well as what services you’re entitled to. The eSIM.me app is just another app you can install from Google Play, so how does Android know to let it, but not any other app, communicate with the eUICC? The solution is through UICC carrier privilege rules, a mechanism that grants the owner of a UICC access to privileged telephony APIs. The eUICC within the eSIM.me card has a file in it (called the access rule file [ARF]) that stores a certificate. Android loads the certificate from the ARF and grants UICC carrier privileges to apps that are signed by that certificate. This way, the eSIM.me app can manage the eUICC despite being a user-installed app.
As a consequence of being a user-installed app, though, the eSIM.me app can’t access Android’s system APIs for eSIM management. This is why the app can’t integrate into settings and why none of the profiles it downloads are shown as downloaded SIMs. Google actually has an eSIM management app that integrates into settings, the previously mentioned “SIM Manager”, but it’s proprietary and has some GMS dependencies, so it’s not a viable option for many AOSP-based projects. A free and open source eSIM management app has been in demand for years, and there’s finally a project that addresses this need.
The quest to make an open source eSIM app
Back in 2018, Truphone, a telecom company that offers eSIM services, open sourced part of its implementation of the GSMA SGP.22 Local Profile Assistant for Device (LPAd). An LPA is the software that communicates with the SM-DP+ (Subscription Manager - Data Preparation+) that the carrier deploys to support RSP (remote SIM provisioning). The LPA helps the user download SIM profiles with a QR code (download service) or without one (discovery service).
Although Truphone didn’t open source its complete LPAd implementation, it did share the code for its SM-DP+ connector and React-Native bridge. Developer phhusson extended this work and created a prototype to show that the library is usable, but it lacked a GUI to add eSIMs. This, however, inspired developer PeterCxy’s OpenEUICC project, an open source eSIM LPA implementation licensed under GPLv2. OpenEUICC implements Android’s system APIs for eSIM management, namely EuiccManager and EuiccService, and it requests the privileged permissions needed to interface with eUICCs via the TelephonyManager API (android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS and android.permission.MODIFY_PHONE_STATE) or OMAPI (android.permission.SECURE_ELEMENT_PRIVILEGED_OPERATION) without needing to be allow listed in the ARF.
Implementing the EuiccService API is what makes the profiles downloaded by OpenEUICC show up in settings. OpenEUICC also has a rather basic UI, but because it has one, tapping the plus sign in Settings > Network & Internet invokes the app’s UI to download a new eSIM profile. However, AOSP’s Settings app does not probe for the existence of an LPA app unless the android.hardware.telephony.euicc feature is declared, so developers attempting to integrate OpenEUICC into their AOSP builds will need to take note of that.
The developer of OpenEUICC is working on support for multiple enabled profiles (MEP), a new feature of Android 13 that makes it possible to simultaneously use multiple profiles stored on a single eSIM. (I talked about this feature in detail in an earlier edition of Android Dessert Bites in case you’re interested.)
Implementing MEP requires using Android 13’s new port mapping APIs in TelephonyManager, which is why the OpenEUICC app supports communicating with the eUICC over both TelephonyManager and OMAPI. The difference between these two methods, I’m told, is in how they interface with the underlying hardware. TelephonyManager uses the radio hardware interface to communicate with the modem, which then issues APDU commands to the eUICC. OMAPI uses the secure element HAL because it’s intended to communicate with any secure element on the device, not just a UICC/eUICC. MEP involves the creation of logical interfaces that are multiplexed on a single physical interface between the eUICC and the modem, which is why the MEP APIs were added to TelephonyManager as it’s the API that involves modem calls.
One caveat with MEP is that it may not be compatible with removable eUICCs like eSIM.me. The GSMA’s SGP.21 v3.0 specification states that “support of Multiple Enabled Profiles on a removable eUICC is FFS [For Further Study].” Thus, in order to have dual SIM functionality with a product like eSIM.me, your phone either needs to already have a built-in eSIM or it needs to support dual SIM cards.
The developer of OpenEUICC considers it “feature-complete”, which means that most eSIM management capabilities have been implemented. As for whether it is ready for inclusion in AOSP-based projects looking for an eSIM management solution, the developer tells us he still has a few bugs to iron out. Beyond that, one of the more security-oriented developers I’ve spoken to expressed their wish to audit the code in OpenEUICC, including the bits from the Truphone library and other dependencies, before including it in their project. In the future, the Truphone library may need updates to account for changes to the eSIM specification, which means it needs an active maintainer. Lastly, more professional projects will want to make sure that their builds pass CTS with OpenEUICC integrated. Regardless, though, the release of OpenEUICC is a big deal for AOSP developers, because it’s the first (as far as I know) complete, open source implementation of a local profile assistant.
Thanks for reading this edition of Android Dessert Bites, and special thanks to PeterCxy for helping to fact-check this article. Telephony is not a topic I’m typically excited about, but I just couldn’t pass following up on my earlier eSIM story or miss out on talking about how what we thought we knew about eSIM was wrong. The folks over at Telco Village have a truly unique product in their hands, and I encourage anyone interested in trying out eSIM to look at what eSIM.me offers.
Next week is Google I/O, so I’ll be busy documenting all the exciting new Android announcements over on the blog (ie. I may or may not do an ADB next week!) Read the recap of Google I/O 2022 here.