Implement SUCI Profile Scheme A for 5G UE

Extend UICC configuration parsing to provide: routing_indicator,
protection_scheme, home_network_public_key, and home_network_public_key_id.
Use the protection_scheme value to decide what SUCI Profile Scheme to
apply during SUCI generation. Add support for Profile Scheme A which
provides ECIES-based encryption using Curve25519 and X9.63 KDF as outlined
in TS 33.501 Section C.3.4.1 Profile A.

When a configuration file specifies an unsupported Profile Scheme,
the NAS layer triggers a fatal error. This occurs either because
Profile Scheme B is unimplemented or the build uses OpenSSL < 3.0,
which lacks Curve25519 and X9.63 KDF support, ensuring users are
informed of the incompatibility.
This commit is contained in:
Aaron van Diepen
2026-03-31 00:44:32 +02:00
parent af4b0d53e9
commit 8ec7b4009b
15 changed files with 466 additions and 37 deletions
+50 -12
View File
@@ -78,18 +78,22 @@ The simulation reads values from a named section in the config file.
**Config options in the `uicc` section**:
| Parameter | Description | Default value |
|---------------|-----------------------------------|--------------------------------------------|
| `imsi` | User IMSI | `2089900007487` |
| `nmc_size` | Number of digits in NMC | `2` |
| `key` | Subscription key (Ki) | `fec86ba6eb707ed08905757b1bb44b8f` |
| `opc` | OPc value | `c42449363bbad02b66d16bc975d77cc1` |
| `amf` | AMF value | `8000` |
| `sqn` | Sequence number | `000000` |
| `dnn` | Default DNN (APN) | `oai` |
| `nssai_sst` | NSSAI slice/service type | `1` |
| `nssai_sd` | NSSAI slice differentiator | `0xffffff` |
| `imeisv` | IMEISV string | `6754567890123413` |
| Parameter | Description | Default value |
|------------------------------|-----------------------------------|--------------------------------------------------------------------|
| `imsi` | User IMSI | `2089900007487` |
| `nmc_size` | Number of digits in NMC | `2` |
| `key` | Subscription key (Ki) | `fec86ba6eb707ed08905757b1bb44b8f` |
| `opc` | OPc value | `c42449363bbad02b66d16bc975d77cc1` |
| `amf` | AMF value | `8000` |
| `sqn` | Sequence number | `000000` |
| `dnn` | Default DNN (APN) | `oai` |
| `nssai_sst` | NSSAI slice/service type | `1` |
| `nssai_sd` | NSSAI slice differentiator | `0xffffff` |
| `imeisv` | IMEISV string | `6754567890123413` |
| `routing_indicator` | Routing Indicator | `0000` |
| `protection_scheme` | SUCI Profile Scheme | `0` |
| `home_network_public_key_id` | Home Network Public Key ID | `1` |
| `home_network_public_key` | Home Network Public Key | `5a8d38864820197c3394b92613b20b91633cbd897119273bf8e4a6f4eec0a650` |
These are parsed and stored in the `uicc_t` structure.
@@ -116,3 +120,37 @@ The **IMEISV**, is encoded using the `fill_imeisv()` helper. This function extra
See TS 24.501 §4.4 for reference.
#### SUCI (Subscription Concealed Identifier)
The **SUCI**, is generated using the `fill_suci()` helper. This function extracts the MCC, MNC, and MSIN from the configured `imsi` with the use of `nmc_size` in the UICC context and populates the mobile identity structure.
Contains:
* MCC and MNC (public network identity)
* Routing Indicator
* Protection Scheme ID
* Home Network Public Key ID
* Concealed or clear MSIN depending on the protection scheme
If the UE is unable to generate SUCI due to configuration or crypto limitations, the UE will fail to generate a `Registration Request`.
###### 0. Null Scheme (TS 33.501 §C.2)
MSIN in cleartext.
###### 1. Profile A (TS 33.501 §C.3.4.1)
MSIN is concealed using elliptic curve cryptography.
Based on:
* Curve25519 for key agreement
* X9.63 KDF for key derivation
(requires OpenSSL ≥ 3.0)
###### 2. Profile B (TS 33.501 §C.3.4.2)
MSIN is concealed using elliptic curve cryptography.
Based on:
* P-256 for key agreement
* X9.63 KDF for key derivation
(currently not supported)
+4
View File
@@ -1066,6 +1066,8 @@ INPUT = \
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NGAP/ngap_gNB_overload.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NGAP/ngap_gNB_default_values.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/SECU/secu_defs.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/SECU/curve_25519.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/SECU/x963_kdf.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/SECU/sha_256_hmac.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/SECU/nas_stream_eea0.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/SECU/aes_128_ecb.h \
@@ -1088,6 +1090,8 @@ INPUT = \
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/SECU/aes_128_ctr.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/SECU/nas_stream_eia2.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/SECU/snow3g.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/SECU/curve_25519.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/SECU/x963_kdf.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/SECU/sha_256_hmac.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/SECU/aes_128_cbc_cmac.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/SECU/nas_stream_eia1.c \