Comprehensive technical knowledge base covering 12 GSMA eSIM specifications. 84+ articles on Remote SIM Provisioning — SGP.02, SGP.22, SGP.32, SGP.41, SGP.29, SGP.23, SGP.25, SGP.26 and more.
🏠 eUICC.tech > SGP.02 M2M RSP > Profile Download: ISD-P Creation, SCP03, and Encrypted Delivery
This is the procedure every other article in this series has been building toward. Profile download (SGP.02 §3.1) is where an operator’s credentials actually land on a chip. The architecture, the PKI, the OTA channel, the ISD-R and ISD-P and ECASD: they all converge here. If you skipped the earlier articles, you’ll want to loop back: the architecture (roles and interfaces), eUICC internals (ISD-R, ISD-P, ECASD), PKI (certificates and key establishment), and OTA (ES5/ES8 tunneling) are all load-bearing here.
The download breaks into four movements: create an empty ISD-P container on the chip, run a cryptographic handshake to establish session keys (Scenario#3 mutual authentication with ECKA-EG), stream the encrypted profile package through an SCP03t tunnel, and optionally flip the new profile to active. Every bit of it is end-to-end encrypted between the SM-DP and the ISD-P; the SM-SR relays the bytes but never sees the plaintext. And if something goes wrong mid-download, cleanup routines make sure you don’t wind up with orphaned ISD-Ps littering the chip.
Before anything can be downloaded, the chip needs somewhere to put it. ISD-P creation (SGP.02 §3.1.1) spins up an empty container.
Operator SM-DP SM-SR ISD-R ISD-P
│ │ │ │ │
│─(1) download──▶│ │ │ │
│ Profile() │ │ │ │
│ │─(2) getEIS───▶│ │ │
│ │ (eid) │─(3) Retrieve │ │
│ │◀─(4) EIS──────│ EIS │ │
│ │ │ │ │
│ │─(5) Check │ │ │
│ │ eligibility │ │ │
│ │ │ │ │
│ │─(6) create───▶│ │ │
│ │ ISDP(eid, │─(7) Check │ │
│ │ iccid, ...) │ conditions │ │
│ │ │ │ │
│ │ │──(8) Trigger │ │
│ │ │ HTTPS──────▶│ │
│ │ │ │ │
│ │ │──(9) ES5.───▶│ │
│ │ │ CreateISDP │──(10) New───▶│
│ │ │ │◀─────────────│
│ │ │◀─(11) POST───│ │
│ │ │ response │ │
│ │ │ │ │
│ │ │─(12) Update │ │
│ │ │ EIS │ │
│ │◀─(13) create──│ │ │
│ │ ISDP resp. │ │ │
(1) The Operator kicks things off with ES2.DownloadProfile, providing the SM-SR identification, EID, ICCID, the desired final state (Enabled or Disabled), and the profile type. They can also ask for the profile to be enabled automatically after installation.
(2-4) The SM-DP calls ES3.GetEIS to pull the eUICC Information Set from the SM-SR. The SM-SR looks up the EID. Unknown EID → error. Found → complete EIS, including the ECASD certificate.
(5) The SM-DP runs its eligibility checks: Is this profile compatible with this eUICC type? Enough remaining memory? Is the eUICC certified? But the one that really matters: the SM-DP verifies CERT.ECASD.ECKA against the EUM Certificate and CI Root Certificate, extracting PK.ECASD.ECKA for the key establishment that comes next. If this verification fails, the whole procedure stops dead. The chip can’t be trusted.
(6-7) ES3.CreateISDP goes to the SM-SR. The SM-SR checks authorization and resources, then creates a new Profile entry in the EIS marked “In-Creation” (invisible to GetEIS until confirmed).
(8-9) The SM-SR triggers HTTPS (if not already open) and sends ES5.CreateISDP in the HTTP POST response.
(10-11) The ISD-R creates the ISD-P. The new ISD-P enters SELECTABLE state. Response flows back through the next HTTP POST.
(12-13) The SM-SR promotes the EIS entry from “In-Creation” to “Created” and returns ES3.CreateISDP response to the SM-DP.
At this point you’ve got an empty ISD-P: no keys, no profile, just an AID and an ICCID. If the SM-DP signals “no more to do,” the SM-SR can close the HTTPS session.
This is where SGP.02 gets serious. The SM-DP and eUICC need a shared SCP03 keyset, and they need to prove to each other that they are who they claim to be, without either side exposing its long-term private key (SGP.02 §3.1.2).
The mechanism is Scenario#3 from GlobalPlatform Amendment E: ECKA-EG key agreement, plus an extra SM-DP authentication step. Hence the name “Scenario#3 Mutual Authentication.”
SM-DP SM-SR ISD-R ISD-P ECASD
│ │ │ │ │
│─(1) sendData(eid, ────▶│ │ │ │
│ ES8.EstablishISDP │ │ │ │
│ KeySet(CERT.DP)) │ │ │ │
│ │─(3) HTTP 200────▶│ │ │
│ │ CERT.DP.ECDSA │──(3a)───▶│ │
│ │ │ CERT.DP │ │
│ │ │ │─(3b)─────│
│ │ │ │Verify it's│
│ │ │ │ SM-DP cert│
│ │ │ │ │
│ │ │ │─(4)──────▶│
│ │ │ │CERT.DP │
│ │ │ │ │─(5) Verify
│ │ │ │ │ with PK.CI
│ │ │ │ │ Extract PK.DP
│ │ │ │ │ Generate RC
│ │ │ │◀─(6) RC───│
│ │ │◀──(7) RC──│ │
│ │◀─(8) sendData───│ │ │
│ │ resp: RC │ │ │
│ │ │ │ │
│─(9) Generate │ │ │ │
│ (eSK.DP, ePK.DP) │ │ │ │
│ Sign(RC, ePK.DP) │ │ │ │
│ with SK.DP.ECDSA │ │ │ │
│ │ │ │ │
│─(10) sendData(eid,───▶│ │ │ │
│ ES8.EstablishISDP │ │ │ │
│ KeySet(ePK.DP, sig)) │─(11) HTTP 200───▶│ │ │
│ │ ePK.DP, sig │──(12)────▶│ │
│ │ │ │ │
│ │ │ │──(13)────▶│
│ │ │ │Verify sig │
│ │ │ │with PK.DP │
│ │ │ │Compute ShS│
│ │ │ │◀─(14) ShS─│
│ │ │ │ │
│ │ │ │─(15) │
│ │ │ │Derive │
│ │ │ │SCP03 keys │
│ │ │ │Calc receipt│
│ │ │◀──(16)───│ │
│ │ │receipt(DR)│ │
│ │◀─(18) sendData───│ │ │
│ │ resp: receipt │ │ │
│ │ │ │ │
│─(19) Compute ShS │ │ │ │
│ from eSK.DP and │ │ │ │
│ PK.ECASD.ECKA │ │ │ │
│ Derive SCP03 keys │ │ │ │
│ Verify receipt │ │ │ │
(1-3) The SM-DP sends CERT.DP.ECDSA toward the eUICC via ES3.SendData. The SM-SR relays it through the ES5 HTTPS session.
(3a-3b) The ISD-R hands the certificate to the ISD-P, which checks that it’s actually an SM-DP certificate, not an SM-SR or something else.
(4-6) The ISD-P forwards CERT.DP.ECDSA to the ECASD. Now the ECASD goes to work:
PK.CI.ECDSA, the CI root public key from manufacturingPK.DP.ECDSA (the SM-DP’s public key)The RC pulls double duty: it proves the response isn’t a replay, and the SM-DP will sign it to prove it holds the private key matching CERT.DP.ECDSA.
(7-8) The RC climbs back up the chain: ISD-P → ISD-R → SM-SR → SM-DP.
(9) The SM-DP generates an ephemeral EC key pair (ePK.DP.ECKA / eSK.DP.ECKA), brand new, never used before, never used again. Then it signs RC concatenated with ePK.DP.ECKA using its long-term private key (SK.DP.ECDSA). That signature proves two things at once: the SM-DP controls the private key behind CERT.DP.ECDSA (authentication), and the ephemeral public key genuinely came from this SM-DP (binding).
(10-11) The signed bundle (ePK.DP.ECKA plus signature over RC and ePK.DP.ECKA) heads back to the eUICC through ES3.SendData → ES5 relay.
(12-14) The ISD-P forwards to the ECASD, which:
PK.DP.ECDSAePK.DP.ECKA (the SM-DP’s ephemeral public key) and SK.ECASD.ECKA (the eUICC’s long-term private key)ECKA-EG guarantees that ShS matches what the SM-DP will independently compute using eSK.DP.ECKA and PK.ECASD.ECKA, without either side revealing its private key.
(15-16) The ISD-P optionally generates a Derivation Random (DR) if the SM-DP requested one, derives the SCP03 keyset from ShS (and DR if present) via a key derivation function, calculates a receipt (cryptographic proof that key derivation succeeded), and returns the receipt (plus optional DR) to the ISD-R.
(17-18) The receipt travels back to the SM-DP.
(19) The SM-DP independently computes ShS from eSK.DP.ECKA and PK.ECASD.ECKA (extracted from the ECASD certificate back in step 5), derives the same SCP03 keyset, and verifies the receipt. A matching receipt confirms the eUICC landed on the same key material.
Both sides now hold identical SCP03 keys and have mutually authenticated. The ISD-P transitions from SELECTABLE to PERSONALIZED.
Three security properties fall out of this handshake:
Forward secrecy. eSK.DP.ECKA is ephemeral, destroyed after use. If SK.ECASD.ECKA gets compromised later, past session keys remain unrecoverable.
Mutual authentication. The SM-DP proves itself by signing RC with SK.DP.ECDSA (verifiable against CERT.DP.ECDSA → CI root). The eUICC proves itself by computing ShS with SK.ECASD.ECKA (verified when the SM-DP’s independently computed receipt matches).
Key confirmation. The receipt gives both sides explicit confirmation they derived the same key material. No ambiguity.
Now the SCP03 channel is up. Time to actually deliver the profile (SGP.02 §3.1.3).
The download runs as a repeated call loop:
SM-DP ──ES3.SendData(profile data)──▶ SM-SR ──ES5 relay──▶ ISD-R ──▶ ISD-P
◀──ES3.SendData response───────── SM-SR ◀──ES5 POST── ISD-R ◀── ISD-P
Each iteration:
ES3.SendData with a chunk of profile data, targeted at the ISD-P AIDX-Admin-Targeted-Application: //aid/<ISD-P AID>ES3.SendData as many times as needed to stream the entire profile packageThe profile data arrives as a Profile Package conforming to the SIMalliance eUICC Profile Package Interoperable Format (version 2.3.1 minimum). It’s wrapped in SCP03t, a variant of SCP03 defined in SGP.02 §4.1.3.3 that’s tuned specifically for profile transport.
SCP03t provides:
i='70')The ISD-P’s Profile Package Interpreter decodes each TLV element and installs the corresponding Profile Component:
When every profile element has been delivered, the SM-DP calls ES3.ProfileDownloadCompleted. This tells the SM-SR the profile is fully installed, lets the SM-DP set POL2 on the profile (Operator specifies POL2 content, which may be empty), and the SM-SR updates the EIS: profile state moves from “Created” to “DISABLED”.
What happens to the SCP03 keyset after this? Three options:
If the Operator requested the profile be enabled after download:
ES5.EnableProfile to the ISD-RIf enabling fails (say connectivity drops before completion), the SM-DP returns Executed-WithWarning. The profile is downloaded and installed, just not yet active.
SGP.02 defines two cleanup sub-routines for when the download doesn’t go smoothly (§3.1.4, §3.1.5):
If something breaks during key establishment or download (before the optional enabling phase), the SM-DP calls ES3.DeleteISDP to remove the partially created ISD-P. The SM-SR relays ES5.DeleteProfile to the ISD-R, which deletes the ISD-P, but only if POL1 doesn’t forbid deletion. If POL1 blocks it, the SM-DP treats the profile installation as having succeeded anyway: the ISD-P exists on the eUICC and can’t be removed.
Before installing a new profile, the SM-DP checks the EIS for an existing ISD-P in “Created” state associated with the same SM-DP (same smdp-id). If it finds one, it deletes it first (same ICCID or not), cleaning up debris from a previous failed attempt.
Once the profile is successfully downloaded (and optionally enabled), the notification chain fires:
ES2.DownloadProfile response to the OperatorES4.HandleProfileDownloadedNotification to that M2M SPES3.HandleProfileDownloadedNotification → ES2.HandleProfileDownloadedNotificationEvery stakeholder who needs to know the profile is live gets the signal.
Based on GSMA SGP.02 v4.2 §3.1: Profile Download and Installation
| ← Previous: OTA Communication: SMS, PSK-TLS, CAT_TP, and DNS | Section Index | Next: Profile Lifecycle: Enable, Disable, Delete, and Fall-Back → |