Skip to content

title: ADR-0013: Lab eSIM (SM-DP+) Stack

ADR-0013: Lab eSIM (SM-DP+) Stack

  • Status: Accepted
  • Date: 2026-08-04
  • Related: ADR-0006 (SIM vault), ADR-0002 (4G first), ADR-0008 (spectrum gate)
  • Scope: SGP.22-shaped remote SIM provisioning for Fairwave lab profiles

Context

The v0.1.0 release can only provision physical nano-SIMs (CSV batches for card bureaus). Modern phones ship without SIM trays; an operator's phone fleet needs eSIM. The CHANGELOG lists "eSIM/LPA" as future work.

A full production eSIM launch requires GSMA certification (SGP.22 conformance, security accreditation, a certified SM-DP+ operator contract). That is a multi-year program. But the download flow - SM-DP+ preparing an encrypted "bound profile package", an eUICC's LPA downloading and installing it - can be built, tested end-to-end in CI, and exercised against real phones as a lab feature, exactly like the RF path (zmq first, hardware gated).

Decision

  • Ship a lab SM-DP+ + software eUICC stack in Go (core/esim/): the full download session lifecycle (initiate authentication, key agreement, bound profile package, confirm, notification, cancel) with real cryptography: P-256 ECDH key agreement, AES-128-CMAC (NIST SP 800-38B, KAT-verified), counter-mode KDF (NIST SP 800-108 / SGP.22 5.1.1 shape), AES-128-CBC profile encryption.
  • The wire transport is JSON over HTTPS (ES9+ paths: /es9plus/initiateAuthentication etc.). The SGP.22 production transport is ASN.1/DER; our byte-level context/label/ASN.1 details are lab-defined and documented as such. Real-phone conformance requires switching the transport and validating against GSMA test tooling - tracked as an open item, not silently claimed.
  • Lab profile packages carry the Milenage credentials (Ki/OPc from the simprov lab vectors) inside the encrypted payload so a software eUICC (or a future eSIM module) can attach to the Fairwave lab network. A physical phone install requires a carrier applet; the profile metadata/files (ICCID, EF.IMSI, EF.AD, EF.UST) follow TS 131.102 layouts as far as practical.
  • Activation codes are the SGP.22 form (LPA:1$smdp$token) and render as QR PNGs; fairwave esim issue mints codes into a file-backed registry (0600 permissions, atomic writes - the vault rules of ADR-0006 apply to the registry file, which holds credential material).
  • fairwave esim serve runs the SM-DP+ as a standalone lab service; TLS termination and control-plane integration (API endpoints, store-backed registry) are follow-up milestones.
  • Lab-only: profile issuance accepts only the dummy lab vectors (MCC 999). Production eSIM issuance stays out of scope until GSMA certification - no bypass flags.

Consequences

Positive:

  • The complete SGP.22-shaped loop is CI-verified without hardware: SM-DP+, software eUICC, key agreement, tamper detection (MAC failure cancels the session), replay protection per session.
  • A physical phone can scan a QR and download a Fairwave lab profile; the remaining gap to attach is the carrier applet, which is a hardware/module milestone, not a protocol one.
  • Registry file is operator-auditable JSON with vault-grade permissions.

Negative:

  • Not interoperable with stock phone LPAs for installation yet: the ASN.1 transport and the applet integration are open items. Do not market this as SGP.22-certified.
  • The registry holds Ki/OPc plaintext (0600 file). This matches the current simprov CSV posture but is weaker than ADR-0006 encryption; the KEK-wrapped vault applies to the registry in a follow-up.
  • JSON wire protocol means every consumer (LPA, eSIM module) needs a JSON adapter, since the industry speaks DER.

Alternatives Considered

  • Buy a certified SM-DP+ (e.g. Thales, G+D): correct for production, wrong for a community lab; costs a contract and removes the educational value. Keep as the M5+ path.
  • SGP.32 (IoT eSIM) modules instead of SGP.22: simpler for hardware (no phone LPA), but does not satisfy "real eSIM on a physical phone". The software eUICC is portable to SGP.32 later.
  • Wait for an open-source SM-DP+: no maintained SGP.22 implementation exists in Go; the ones in C/C++ are single-vendor and unmaintained.
  • ADR-0006 (vault rules for the registry) · ADR-0008 (a downloaded profile still needs a gated RAN to attach) · Roadmap