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:
@@ -17,7 +17,7 @@
|
||||
static int decode_guti_5gs_mobile_identity(Guti5GSMobileIdentity_t *guti, const uint8_t *buffer);
|
||||
|
||||
static int encode_guti_5gs_mobile_identity(const Guti5GSMobileIdentity_t *guti, uint8_t *buffer);
|
||||
static int encode_suci_5gs_mobile_identity(const Suci5GSMobileIdentity_t *suci, uint8_t *buffer);
|
||||
static int encode_suci_5gs_mobile_identity(const Suci5GSMobileIdentity_t *suci, uint8_t *buffer, uint32_t len);
|
||||
static int encode_imeisv_5gs_mobile_identity(const Imeisv5GSMobileIdentity_t *imeisv, uint8_t *buffer);
|
||||
|
||||
int encode_stmsi_5gs_mobile_identity(uint8_t *buffer, const Stmsi5GSMobileIdentity_t *stmsi, uint32_t len)
|
||||
@@ -121,7 +121,7 @@ int encode_5gs_mobile_identity(const FGSMobileIdentity *fgsmobileidentity, uint8
|
||||
}
|
||||
|
||||
if (fgsmobileidentity->suci.typeofidentity == FGS_MOBILE_IDENTITY_SUCI) {
|
||||
encoded_rc = encode_suci_5gs_mobile_identity(&fgsmobileidentity->suci, buffer + encoded);
|
||||
encoded_rc = encode_suci_5gs_mobile_identity(&fgsmobileidentity->suci, buffer + encoded, len);
|
||||
}
|
||||
|
||||
if (fgsmobileidentity->imeisv.typeofidentity == FGS_MOBILE_IDENTITY_IMEISV) {
|
||||
@@ -218,9 +218,13 @@ static int encode_guti_5gs_mobile_identity(const Guti5GSMobileIdentity_t *guti,
|
||||
return encoded;
|
||||
}
|
||||
|
||||
static int encode_suci_5gs_mobile_identity(const Suci5GSMobileIdentity_t *suci, uint8_t *buffer)
|
||||
static int encode_suci_5gs_mobile_identity(const Suci5GSMobileIdentity_t *suci, uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
uint32_t encoded = 0;
|
||||
|
||||
if (len < 8)
|
||||
return -1;
|
||||
|
||||
*(buffer + encoded) = (suci->supiformat << 4) | (suci->typeofidentity);
|
||||
encoded++;
|
||||
*(buffer + encoded) = ((suci->mccdigit2 & 0xf) << 4) | (suci->mccdigit1 & 0xf);
|
||||
@@ -242,15 +246,34 @@ static int encode_suci_5gs_mobile_identity(const Suci5GSMobileIdentity_t *suci,
|
||||
*(buffer + encoded) = suci->homenetworkpki;
|
||||
encoded++;
|
||||
|
||||
const char *ptr = suci->schemeoutput;
|
||||
while (ptr < suci->schemeoutput + strlen(suci->schemeoutput)) {
|
||||
buffer[encoded] = ((*(ptr + 1) - '0') << 4) | (*(ptr) - '0');
|
||||
encoded++;
|
||||
ptr += 2;
|
||||
}
|
||||
DevAssert(suci->schemeoutput);
|
||||
size_t rawlen = strlen(suci->schemeoutput);
|
||||
size_t outlen = (rawlen + 1) / 2;
|
||||
|
||||
if (strlen(suci->schemeoutput) % 2 == 1)
|
||||
buffer[encoded++] = ((*(ptr - 1) - '0')) | 0xF0;
|
||||
if (len - encoded < outlen)
|
||||
return -1;
|
||||
|
||||
if (suci->protectionschemeId == 0) {
|
||||
AssertFatal(suci->homenetworkpki == 0,
|
||||
"Invalid SUCI: homenetworkpki=%u with null protection scheme (must be 0)\n",
|
||||
suci->homenetworkpki);
|
||||
int rc = digit_string_to_bcd_value(buffer + encoded, suci->schemeoutput, outlen);
|
||||
AssertFatal(rc == 0,
|
||||
"BCD encoding failed (rc=%d, input=\"%s\", len=%zu, out_len=%zu)\n",
|
||||
rc,
|
||||
suci->schemeoutput,
|
||||
rawlen,
|
||||
outlen);
|
||||
} else {
|
||||
int rc = hex_string_to_hex_value(buffer + encoded, suci->schemeoutput, outlen);
|
||||
AssertFatal(rc == 0,
|
||||
"Encoding SUCI schemeoutput failed (rc=%d, input=\"%s\", len=%zu, out_len=%zu)\n",
|
||||
rc,
|
||||
suci->schemeoutput,
|
||||
rawlen,
|
||||
outlen);
|
||||
}
|
||||
encoded += outlen;
|
||||
return encoded;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ typedef struct {
|
||||
uint8_t spare6: 1;
|
||||
uint8_t protectionschemeId: 4;
|
||||
uint8_t homenetworkpki;
|
||||
char schemeoutput[32];
|
||||
char schemeoutput[128];
|
||||
} Suci5GSMobileIdentity_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "nr_nas_msg.h"
|
||||
#include <netinet/in.h>
|
||||
#include "NR_NAS_defs.h"
|
||||
#include <openssl/opensslv.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -53,6 +54,18 @@
|
||||
#include "key_nas_deriver.h"
|
||||
#include "nr-uesoftmodem.h"
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
#include "curve_25519.h"
|
||||
#include "aes_128_ctr.h"
|
||||
#include "x963_kdf.h"
|
||||
#include "sha_256_hmac.h"
|
||||
static const char hex[] = "0123456789abcdef";
|
||||
#elif OPENSSL_VERSION_NUMBER >= 0x10100000L
|
||||
#define MY_OPENSSL_VERSION_STR OpenSSL_version(OPENSSL_VERSION)
|
||||
#else
|
||||
#define MY_OPENSSL_VERSION_STR SSLeay_version(SSLEAY_VERSION)
|
||||
#endif
|
||||
|
||||
static nr_ue_nas_t nr_ue_nas[MAX_NUM_NR_UE_INST] = {0};
|
||||
|
||||
nr_ue_nas_t *get_nr_ue_nas_info(uint8_t ue_inst)
|
||||
@@ -388,6 +401,83 @@ static security_state_t nas_security_rx_process(nr_ue_nas_t *nas, byte_array_t b
|
||||
return NAS_SECURITY_INTEGRITY_PASSED;
|
||||
}
|
||||
|
||||
static void suci_profile_scheme_a_generate_output(const uint8_t home_network_public_key[32],
|
||||
const char *msin,
|
||||
const size_t msin_len,
|
||||
char *schemeoutput)
|
||||
{
|
||||
/* 1> Eph. key pair generation */
|
||||
uint8_t eph_priv[32] = {0};
|
||||
uint8_t eph_pub[32] = {0};
|
||||
x25519_generate_keypair(eph_priv, eph_pub);
|
||||
|
||||
/* 2> Key agreement */
|
||||
uint8_t eph_shared_key[32] = {0};
|
||||
x25519_shared_secret(eph_priv, home_network_public_key, eph_shared_key);
|
||||
|
||||
explicit_bzero(eph_priv, 32);
|
||||
|
||||
/* 3> Key derivation */
|
||||
uint8_t kdf_output[64] = {0};
|
||||
byte_array_t kdf_secret = {.buf = eph_shared_key, .len = 32};
|
||||
byte_array_t kdf_info = {.buf = eph_pub, .len = 32};
|
||||
x963_kdf(kdf_secret, kdf_info, 64, kdf_output);
|
||||
|
||||
explicit_bzero(eph_shared_key, 32);
|
||||
|
||||
aes_128_t aes_ctx;
|
||||
aes_ctx.type = AES_INITIALIZATION_VECTOR_16;
|
||||
memcpy(aes_ctx.key, kdf_output, 16);
|
||||
memcpy(aes_ctx.iv16.iv, kdf_output + 16, 16);
|
||||
|
||||
uint8_t eph_mac_key[32] = {0};
|
||||
memcpy(eph_mac_key, kdf_output + 32, 32);
|
||||
|
||||
explicit_bzero(kdf_output, 64);
|
||||
|
||||
/* 4> Symmetric encryption */
|
||||
size_t msin_bcd_len = (msin_len + 1) / 2;
|
||||
uint8_t msin_bcd[msin_bcd_len];
|
||||
memset(msin_bcd, 0, msin_bcd_len);
|
||||
|
||||
int rc = digit_string_to_bcd_value(msin_bcd, msin, msin_bcd_len);
|
||||
AssertFatal(rc == 0, "Encoding MSIN failed (rc=%d, input=\"%s\", len=%zu, out_len=%zu)", rc, msin, msin_len, msin_bcd_len);
|
||||
|
||||
byte_array_t payload = {.buf = msin_bcd, .len = msin_bcd_len};
|
||||
uint8_t ciphertext[msin_bcd_len];
|
||||
aes_128_ctr(&aes_ctx, payload, msin_bcd_len, ciphertext);
|
||||
|
||||
explicit_bzero(aes_ctx.key, 16);
|
||||
explicit_bzero(aes_ctx.iv16.iv, 16);
|
||||
explicit_bzero(msin_bcd, msin_bcd_len);
|
||||
|
||||
/* 5> MAC function */
|
||||
uint8_t mac_full[32] = {0};
|
||||
byte_array_t mac_input = {.buf = ciphertext, .len = msin_bcd_len};
|
||||
sha_256_hmac(eph_mac_key, mac_input, 32, mac_full);
|
||||
|
||||
explicit_bzero(eph_mac_key, 32);
|
||||
|
||||
/* Build SUCI scheme output --- */
|
||||
/* eph_pub (32 bytes -> 64 hex chars) */
|
||||
for (int i = 0; i < 32; i++) {
|
||||
*schemeoutput++ = hex[eph_pub[i] >> 4];
|
||||
*schemeoutput++ = hex[eph_pub[i] & 0x0F];
|
||||
}
|
||||
|
||||
/* ciphertext (~45 bytes -> ~90 hex chars) */
|
||||
for (int i = 0; i < msin_bcd_len; i++) {
|
||||
*schemeoutput++ = hex[ciphertext[i] >> 4];
|
||||
*schemeoutput++ = hex[ciphertext[i] & 0x0F];
|
||||
}
|
||||
|
||||
/* MAC (8 bytes -> 16 hex chars) */
|
||||
for (int i = 0; i < 8; i++) {
|
||||
*schemeoutput++ = hex[mac_full[i] >> 4];
|
||||
*schemeoutput++ = hex[mac_full[i] & 0x0F];
|
||||
}
|
||||
}
|
||||
|
||||
static int fill_suci(FGSMobileIdentity *mi, const uicc_t *uicc)
|
||||
{
|
||||
mi->suci.typeofidentity = FGS_MOBILE_IDENTITY_SUCI;
|
||||
@@ -397,7 +487,50 @@ static int fill_suci(FGSMobileIdentity *mi, const uicc_t *uicc)
|
||||
mi->suci.mccdigit1 = uicc->imsiStr[0] - '0';
|
||||
mi->suci.mccdigit2 = uicc->imsiStr[1] - '0';
|
||||
mi->suci.mccdigit3 = uicc->imsiStr[2] - '0';
|
||||
memcpy(mi->suci.schemeoutput, uicc->imsiStr + 3 + uicc->nmc_size, strlen(uicc->imsiStr) - (3 + uicc->nmc_size));
|
||||
|
||||
mi->suci.routingindicatordigit1 = uicc->routing_indicatorStr[0] - '0';
|
||||
mi->suci.routingindicatordigit2 = uicc->routing_indicatorStr[1] - '0';
|
||||
mi->suci.routingindicatordigit3 = uicc->routing_indicatorStr[2] - '0';
|
||||
mi->suci.routingindicatordigit4 = uicc->routing_indicatorStr[3] - '0';
|
||||
|
||||
char *msin = uicc->imsiStr + 3 + uicc->nmc_size;
|
||||
uint8_t msin_len = strlen(msin);
|
||||
|
||||
mi->suci.protectionschemeId = uicc->protection_scheme;
|
||||
switch (uicc->protection_scheme) {
|
||||
case 0: /* Null scheme (TS 33.501 C.2) */
|
||||
{
|
||||
mi->suci.homenetworkpki = 0;
|
||||
memcpy(mi->suci.schemeoutput, msin, msin_len);
|
||||
break;
|
||||
}
|
||||
case 1: /* Profile A (TS 33.501 C.3.4.1) */
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
mi->suci.homenetworkpki = uicc->home_network_public_key_id;
|
||||
suci_profile_scheme_a_generate_output(uicc->home_network_public_key, msin, msin_len, mi->suci.schemeoutput);
|
||||
#else
|
||||
AssertFatal(false,
|
||||
"Protection Scheme not supported when using a version below OpenSSL 3.0 %d (OpenSSL version: %s)\n",
|
||||
uicc->protection_scheme,
|
||||
MY_OPENSSL_VERSION_STR);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case 2: /* Profile B (TS 33.501 C.3.4.2) */
|
||||
{
|
||||
mi->suci.homenetworkpki = uicc->home_network_public_key_id;
|
||||
|
||||
AssertFatal(false, "Unsupported Protection Scheme in UICC %d\n", uicc->protection_scheme);
|
||||
|
||||
break;
|
||||
}
|
||||
default: // Unknown schemes
|
||||
{
|
||||
AssertFatal(false, "Unknown Protection Scheme in UICC %d\n", uicc->protection_scheme);
|
||||
}
|
||||
}
|
||||
|
||||
LOG_D(NAS,
|
||||
"SUCI in registration request: SUPI type: %d Type of Identity: %u MCC: %u%u%u, MNC: %u%u%u, \
|
||||
Routing Indicator %d%d%d%d Protection Scheme ID: %u, Home Network PKI: %u, Scheme Output: %s\n",
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
|
||||
*/
|
||||
|
||||
#include "curve_25519.h"
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
|
||||
/* code for version 3.0 or greater */
|
||||
|
||||
#include "common/utils/assertions.h"
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/core_names.h>
|
||||
|
||||
void x25519_generate_keypair(uint8_t priv[32], uint8_t pub[32])
|
||||
{
|
||||
DevAssert(priv != NULL);
|
||||
DevAssert(pub != NULL);
|
||||
|
||||
EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_X25519, NULL);
|
||||
DevAssert(pctx != NULL);
|
||||
|
||||
int rc = EVP_PKEY_keygen_init(pctx);
|
||||
DevAssert(rc == 1);
|
||||
|
||||
EVP_PKEY *pkey = NULL;
|
||||
rc = EVP_PKEY_keygen(pctx, &pkey);
|
||||
DevAssert(rc == 1);
|
||||
|
||||
EVP_PKEY_CTX_free(pctx);
|
||||
|
||||
size_t len = 32;
|
||||
|
||||
rc = EVP_PKEY_get_raw_private_key(pkey, priv, &len);
|
||||
DevAssert(rc == 1 && len == 32);
|
||||
|
||||
rc = EVP_PKEY_get_raw_public_key(pkey, pub, &len);
|
||||
DevAssert(rc == 1 && len == 32);
|
||||
|
||||
EVP_PKEY_free(pkey);
|
||||
}
|
||||
|
||||
void x25519_shared_secret(const uint8_t priv[32], const uint8_t peer_pub[32], uint8_t secret[32])
|
||||
{
|
||||
DevAssert(priv != NULL);
|
||||
DevAssert(peer_pub != NULL);
|
||||
DevAssert(secret != NULL);
|
||||
|
||||
EVP_PKEY *pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_X25519, NULL, priv, 32);
|
||||
DevAssert(pkey != NULL);
|
||||
|
||||
EVP_PKEY *peerkey = EVP_PKEY_new_raw_public_key(EVP_PKEY_X25519, NULL, peer_pub, 32);
|
||||
DevAssert(peerkey != NULL);
|
||||
|
||||
EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, NULL);
|
||||
DevAssert(ctx != NULL);
|
||||
|
||||
int rc = EVP_PKEY_derive_init(ctx);
|
||||
DevAssert(rc == 1);
|
||||
|
||||
rc = EVP_PKEY_derive_set_peer(ctx, peerkey);
|
||||
DevAssert(rc == 1);
|
||||
|
||||
size_t len = 32;
|
||||
rc = EVP_PKEY_derive(ctx, secret, &len);
|
||||
DevAssert(rc == 1 && len == 32);
|
||||
|
||||
EVP_PKEY_free(pkey);
|
||||
EVP_PKEY_free(peerkey);
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
|
||||
*/
|
||||
|
||||
#ifndef CURVE_25519_OAI_H
|
||||
#define CURVE_25519_OAI_H
|
||||
|
||||
#include <openssl/opensslv.h>
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
|
||||
/* code for version 3.0 or greater */
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
void x25519_generate_keypair(uint8_t priv[32], uint8_t pub[32]);
|
||||
|
||||
void x25519_shared_secret(const uint8_t priv[32], const uint8_t peer_pub[32], uint8_t secret[32]);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
|
||||
*/
|
||||
|
||||
#include "x963_kdf.h"
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
|
||||
/* code for version 3.0 or greater */
|
||||
|
||||
#include <string.h>
|
||||
#include "common/utils/assertions.h"
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/kdf.h>
|
||||
#include <openssl/core_names.h>
|
||||
|
||||
void x963_kdf(const byte_array_t sharedsecret, const byte_array_t sharedinfo, size_t len, uint8_t out[len])
|
||||
{
|
||||
DevAssert(sharedsecret.buf != NULL);
|
||||
DevAssert(sharedsecret.len > 0);
|
||||
DevAssert(out != NULL);
|
||||
DevAssert(len > 0);
|
||||
|
||||
EVP_KDF *kdf = EVP_KDF_fetch(NULL, "X963KDF", NULL);
|
||||
DevAssert(kdf != NULL);
|
||||
|
||||
EVP_KDF_CTX *kctx = EVP_KDF_CTX_new(kdf);
|
||||
DevAssert(kctx != NULL);
|
||||
|
||||
EVP_KDF_free(kdf);
|
||||
|
||||
OSSL_PARAM params[4], *p = params;
|
||||
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, SN_sha256, strlen(SN_sha256));
|
||||
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, sharedsecret.buf, sharedsecret.len);
|
||||
|
||||
if (sharedinfo.buf != NULL && sharedinfo.len > 0) {
|
||||
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO, sharedinfo.buf, sharedinfo.len);
|
||||
}
|
||||
|
||||
*p = OSSL_PARAM_construct_end();
|
||||
|
||||
int rc = EVP_KDF_derive(kctx, out, len, params);
|
||||
DevAssert(rc == 1);
|
||||
|
||||
EVP_KDF_CTX_free(kctx);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
|
||||
*/
|
||||
|
||||
#ifndef x963_KDF_OAI_H
|
||||
#define x963_KDF_OAI_H
|
||||
|
||||
#include <openssl/opensslv.h>
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
|
||||
/* code for version 3.0 or greater */
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "byte_array.h"
|
||||
|
||||
void x963_kdf(const byte_array_t sharedsecret, const byte_array_t sharedinfo, size_t len, uint8_t out[len]);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -14,21 +14,26 @@ extern uint16_t NB_UE_INST;
|
||||
" key: cyphering key\n"\
|
||||
" opc: cyphering OPc\n"\
|
||||
" imiesv: string with IMEISV value\n"
|
||||
#define DEFAULT_HOME_NETWORK_PUBLIC_KEY "5a8d38864820197c3394b92613b20b91633cbd897119273bf8e4a6f4eec0a650"
|
||||
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* configuration parameters for the rfsimulator device */
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
#define UICC_PARAMS_DESC { \
|
||||
{"imsi", "USIM IMSI\n", 0, .strptr=&uicc->imsiStr, .defstrval="2089900007487", TYPE_STRING, 0 }, \
|
||||
{"nmc_size" "number of digits in NMC", 0, .iptr=&uicc->nmc_size, .defintval=2, TYPE_INT, 0 }, \
|
||||
{"key", "USIM Ki\n", 0, .strptr=&uicc->keyStr, .defstrval="fec86ba6eb707ed08905757b1bb44b8f", TYPE_STRING, 0 }, \
|
||||
{"opc", "USIM OPc\n", 0, .strptr=&uicc->opcStr, .defstrval="c42449363bbad02b66d16bc975d77cc1", TYPE_STRING, 0 }, \
|
||||
{"amf", "USIM amf\n", 0, .strptr=&uicc->amfStr, .defstrval="8000", TYPE_STRING, 0 }, \
|
||||
{"sqn", "USIM sqn\n", 0, .strptr=&uicc->sqnStr, .defstrval="000000", TYPE_STRING, 0 }, \
|
||||
{"dnn", "UE dnn (apn)\n", 0, .strptr=&uicc->dnnStr, .defstrval="oai", TYPE_STRING, 0 }, \
|
||||
{"nssai_sst", "UE nssai\n", 0, .iptr=&uicc->nssai_sst, .defintval=1, TYPE_INT, 0 }, \
|
||||
{"nssai_sd", "UE nssai\n", 0, .iptr=&uicc->nssai_sd, .defintval=0xffffff, TYPE_INT, 0 }, \
|
||||
{"imeisv", "IMEISV\n", 0, .strptr=&uicc->imeisvStr, .defstrval="6754567890123413", TYPE_STRING, 0 }, \
|
||||
#define UICC_PARAMS_DESC { \
|
||||
{"imsi", "USIM IMSI\n", 0, .strptr=&uicc->imsiStr, .defstrval="2089900007487", TYPE_STRING, 0}, \
|
||||
{"nmc_size", "number of digits in NMC", 0, .iptr=&uicc->nmc_size, .defintval=2, TYPE_INT, 0}, \
|
||||
{"key", "USIM Ki\n", 0, .strptr=&uicc->keyStr, .defstrval="fec86ba6eb707ed08905757b1bb44b8f", TYPE_STRING, 0}, \
|
||||
{"opc", "USIM OPc\n", 0, .strptr=&uicc->opcStr, .defstrval="c42449363bbad02b66d16bc975d77cc1", TYPE_STRING, 0}, \
|
||||
{"amf", "USIM amf\n", 0, .strptr=&uicc->amfStr, .defstrval="8000", TYPE_STRING, 0}, \
|
||||
{"sqn", "USIM sqn\n", 0, .strptr=&uicc->sqnStr, .defstrval="000000", TYPE_STRING, 0}, \
|
||||
{"dnn", "UE dnn (apn)\n", 0, .strptr=&uicc->dnnStr, .defstrval="oai", TYPE_STRING, 0}, \
|
||||
{"nssai_sst", "UE nssai\n", 0, .iptr=&uicc->nssai_sst, .defintval=1, TYPE_INT, 0}, \
|
||||
{"nssai_sd", "UE nssai\n", 0, .iptr=&uicc->nssai_sd, .defintval=0xffffff, TYPE_INT, 0}, \
|
||||
{"imeisv", "IMEISV\n", 0, .strptr=&uicc->imeisvStr, .defstrval="6754567890123413", TYPE_STRING, 0}, \
|
||||
{"routing_indicator", "Routing Indicator\n", 0, .strptr = &uicc->routing_indicatorStr, .defstrval="0000", TYPE_STRING, 0}, \
|
||||
{"protection_scheme", "SUCI Profile Scheme\n", 0, .iptr = &uicc->protection_scheme, .defintval=0, TYPE_INT, 0}, \
|
||||
{"home_network_public_key_id", "Home Network Public Key ID\n", 0, .iptr=&uicc->home_network_public_key_id, .defintval=1, TYPE_INT, 0}, \
|
||||
{"home_network_public_key", "Home Network Public Key\n", 0, .strptr=&uicc->home_network_public_keyStr, .defstrval=DEFAULT_HOME_NETWORK_PUBLIC_KEY, TYPE_STRING, 0}, \
|
||||
};
|
||||
|
||||
static uicc_t** uiccArray=NULL;
|
||||
@@ -62,6 +67,7 @@ uicc_t *init_uicc(char *sectionName) {
|
||||
to_hex(uicc->opcStr,uicc->opc, sizeof(uicc->opc) );
|
||||
to_hex(uicc->sqnStr,uicc->sqn, sizeof(uicc->sqn) );
|
||||
to_hex(uicc->amfStr,uicc->amf, sizeof(uicc->amf) );
|
||||
to_hex(uicc->home_network_public_keyStr, uicc->home_network_public_key, sizeof(uicc->home_network_public_key));
|
||||
return uicc;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,10 @@ typedef struct {
|
||||
int nssai_sd;
|
||||
pdu_session_config_t pdu_sessions[256];
|
||||
int n_pdu_sessions;
|
||||
char *routing_indicatorStr;
|
||||
int protection_scheme;
|
||||
char *home_network_public_keyStr;
|
||||
int home_network_public_key_id;
|
||||
uint8_t key[16];
|
||||
uint8_t opc[16];
|
||||
uint8_t amf[2];
|
||||
@@ -49,6 +53,7 @@ typedef struct {
|
||||
uint8_t ck[16];
|
||||
uint8_t ik[16];
|
||||
uint8_t milenage_res[8];
|
||||
uint8_t home_network_public_key[32];
|
||||
} uicc_t;
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user