NSA: finalize nea2 security for gNB
- a new section in the configuration file to select security algorithms,
with new code to deal with it
- cleanup CG-ConfigInfo: specs seem to indicate that we must not
add mcg_RB_Config; the gNB has to deal with that
- as a consequence, modify fill_default_rbconfig() that is called in
every cases and needs security and bearer parameters
The new section in the configuration file looks like:
security = {
# preferred ciphering algorithms
# the first one of the list that an UE supports in chosen
# valid values: nea0, nea1, nea2, nea3
ciphering_algorithms = ( "nea0", "nea2" );
# preferred integrity algorithms
# the first one of the list that an UE supports in chosen
# valid values: nia0, nia1, nia2, nia3
integrity_algorithms = ( "nia0" );
};
This commit is contained in:
@@ -513,6 +513,101 @@ void RCconfig_nr_macrlc() {
|
||||
|
||||
}
|
||||
|
||||
void config_security(gNB_RRC_INST *rrc)
|
||||
{
|
||||
paramdef_t logparams_defaults[] = SECURITY_GLOBALPARAMS_DESC;
|
||||
int ret = config_get(logparams_defaults,
|
||||
sizeof(logparams_defaults) / sizeof(paramdef_t),
|
||||
CONFIG_STRING_SECURITY);
|
||||
int i;
|
||||
|
||||
if (ret < 0) {
|
||||
LOG_W(RRC, "configuration file does not contain a \"security\" section, applying default parameters (no security)\n");
|
||||
rrc->security.ciphering_algorithms[0] = 0; /* nea0 = no ciphering */
|
||||
rrc->security.ciphering_algorithms_count = 1;
|
||||
rrc->security.integrity_algorithms[0] = 0; /* nia0 = no integrity */
|
||||
rrc->security.integrity_algorithms_count = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].numelt > 4) {
|
||||
LOG_E(RRC, "too much ciphering algorithms in section \"security\" of the configuration file, maximum is 4\n");
|
||||
exit(1);
|
||||
}
|
||||
if (logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].numelt > 4) {
|
||||
LOG_E(RRC, "too much integrity algorithms in section \"security\" of the configuration file, maximum is 4\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* get ciphering algorithms */
|
||||
rrc->security.ciphering_algorithms_count = 0;
|
||||
for (i = 0; i < logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].numelt; i++) {
|
||||
if (!strcmp(logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].strlistptr[i], "nea0")) {
|
||||
rrc->security.ciphering_algorithms[rrc->security.ciphering_algorithms_count] = 0;
|
||||
rrc->security.ciphering_algorithms_count++;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].strlistptr[i], "nea1")) {
|
||||
rrc->security.ciphering_algorithms[rrc->security.ciphering_algorithms_count] = 1;
|
||||
rrc->security.ciphering_algorithms_count++;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].strlistptr[i], "nea2")) {
|
||||
rrc->security.ciphering_algorithms[rrc->security.ciphering_algorithms_count] = 2;
|
||||
rrc->security.ciphering_algorithms_count++;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].strlistptr[i], "nea3")) {
|
||||
rrc->security.ciphering_algorithms[rrc->security.ciphering_algorithms_count] = 3;
|
||||
rrc->security.ciphering_algorithms_count++;
|
||||
continue;
|
||||
}
|
||||
LOG_E(RRC, "unknown ciphering algorithm \"%s\" in section \"security\" of the configuration file\n",
|
||||
logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].strlistptr[i]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* get integrity algorithms */
|
||||
rrc->security.integrity_algorithms_count = 0;
|
||||
for (i = 0; i < logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].numelt; i++) {
|
||||
if (!strcmp(logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].strlistptr[i], "nia0")) {
|
||||
rrc->security.integrity_algorithms[rrc->security.integrity_algorithms_count] = 0;
|
||||
rrc->security.integrity_algorithms_count++;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].strlistptr[i], "nia1")) {
|
||||
rrc->security.integrity_algorithms[rrc->security.integrity_algorithms_count] = 1;
|
||||
rrc->security.integrity_algorithms_count++;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].strlistptr[i], "nia2")) {
|
||||
rrc->security.integrity_algorithms[rrc->security.integrity_algorithms_count] = 2;
|
||||
rrc->security.integrity_algorithms_count++;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].strlistptr[i], "nia3")) {
|
||||
rrc->security.integrity_algorithms[rrc->security.integrity_algorithms_count] = 3;
|
||||
rrc->security.integrity_algorithms_count++;
|
||||
continue;
|
||||
}
|
||||
LOG_E(RRC, "unknown integrity algorithm \"%s\" in section \"security\" of the configuration file\n",
|
||||
logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].strlistptr[i]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (rrc->security.ciphering_algorithms_count == 0) {
|
||||
LOG_W(RRC, "no preferred ciphering algorithm set in configuration file, applying default parameters (no security)\n");
|
||||
rrc->security.ciphering_algorithms[0] = 0; /* nea0 = no ciphering */
|
||||
rrc->security.ciphering_algorithms_count = 1;
|
||||
}
|
||||
|
||||
if (rrc->security.integrity_algorithms_count == 0) {
|
||||
LOG_W(RRC, "no preferred integrity algorithm set in configuration file, applying default parameters (no security)\n");
|
||||
rrc->security.integrity_algorithms[0] = 0; /* nia0 = no integrity */
|
||||
rrc->security.integrity_algorithms_count = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
|
||||
|
||||
int num_gnbs = 0;
|
||||
@@ -679,7 +774,7 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
|
||||
}//End for (k=0; k <num_gnbs ; k++)
|
||||
}//End if (num_gnbs>0)
|
||||
|
||||
|
||||
config_security(rrc);
|
||||
}//End RCconfig_NRRRC function
|
||||
|
||||
int RCconfig_nr_gtpu(void ) {
|
||||
|
||||
@@ -452,4 +452,27 @@ typedef enum {
|
||||
#define CONFIG_HLP_WORKER "coding and FEP worker thread WORKER_DISABLE or WORKER_ENABLE\n"
|
||||
#define CONFIG_HLP_PARALLEL "PARALLEL_SINGLE_THREAD, PARALLEL_RU_L1_SPLIT, or PARALLEL_RU_L1_TRX_SPLIT(RU_L1_TRX_SPLIT by defult)\n"
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* security configuration */
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
#define CONFIG_STRING_SECURITY "security"
|
||||
|
||||
#define SECURITY_CONFIG_CIPHERING "ciphering_algorithms"
|
||||
#define SECURITY_CONFIG_INTEGRITY "integrity_algorithms"
|
||||
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* security configuration */
|
||||
/* optname help paramflags XXXptr defXXXval type numelt */
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
#define SECURITY_GLOBALPARAMS_DESC { \
|
||||
{SECURITY_CONFIG_CIPHERING, "preferred ciphering algorithms\n", 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST, 0}, \
|
||||
{SECURITY_CONFIG_INTEGRITY, "preferred integrity algorithms\n", 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST, 0}, \
|
||||
}
|
||||
|
||||
#define SECURITY_CONFIG_CIPHERING_IDX 0
|
||||
#define SECURITY_CONFIG_INTEGRITY_IDX 1
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
#endif
|
||||
|
||||
@@ -4426,69 +4426,11 @@ static int encode_CG_ConfigInfo(
|
||||
struct NR_RadioBearerConfig *rb_config = NULL;
|
||||
asn_enc_rval_t enc_rval;
|
||||
int RRC_OK = 1;
|
||||
int index = 0;
|
||||
char temp_buff[ASN_MAX_ENCODE_SIZE];
|
||||
NR_UE_CapabilityRAT_ContainerList_t *ue_cap_rat_container_list = NULL;
|
||||
NR_UE_CapabilityRAT_Container_t *ue_cap_rat_container_MRDC = NULL;
|
||||
NR_UE_CapabilityRAT_Container_t *ue_cap_rat_container_nr = NULL;
|
||||
int RAT_Container_count = 0;
|
||||
rb_config = calloc(1,sizeof(struct NR_RadioBearerConfig));
|
||||
AssertFatal(rb_config != NULL,"failed to allocate memory for rb_config");
|
||||
|
||||
if(ue_context_pP->ue_context.DRB_configList->list.count != 0) {
|
||||
rb_config->drb_ToAddModList = calloc(1,sizeof(struct NR_DRB_ToAddModList ));
|
||||
AssertFatal(rb_config->drb_ToAddModList != NULL,"failed to allocated memory for drbtoaddmodlist");
|
||||
rb_config->drb_ToAddModList->list.count = NUMBEROF_DRBS_TOBE_ADDED;
|
||||
rb_config->drb_ToAddModList->list.array
|
||||
= calloc(NUMBEROF_DRBS_TOBE_ADDED, sizeof(struct NR_DRB_ToAddMod *));
|
||||
AssertFatal( rb_config->drb_ToAddModList->list.array != NULL,
|
||||
"falied to allocate memory for list.array");
|
||||
|
||||
for(index = 0; index < NUMBEROF_DRBS_TOBE_ADDED; index++) {
|
||||
rb_config->drb_ToAddModList->list.array[index]
|
||||
= calloc(1,sizeof(struct NR_DRB_ToAddMod));
|
||||
AssertFatal(rb_config->drb_ToAddModList->list.array[index] != NULL,
|
||||
"failed to allocate memory for drb_toaddmod");
|
||||
rb_config->drb_ToAddModList->list.array[index]->drb_Identity
|
||||
= ue_context_pP->ue_context.DRB_configList->list.array[index]->drb_Identity;
|
||||
|
||||
if(ue_context_pP->ue_context.DRB_configList->list.array[index]->eps_BearerIdentity) {
|
||||
rb_config->drb_ToAddModList->list.array[index]->cnAssociation
|
||||
= calloc(1,sizeof(struct NR_DRB_ToAddMod__cnAssociation));
|
||||
AssertFatal(rb_config->drb_ToAddModList->list.array[index]->cnAssociation != NULL,
|
||||
"failed to allocate memory cnAssociation");
|
||||
rb_config->drb_ToAddModList->list.array[index]->cnAssociation->present
|
||||
= NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity;
|
||||
rb_config->drb_ToAddModList->list.array[index]->cnAssociation->choice.eps_BearerIdentity
|
||||
= *(ue_context_pP->ue_context.DRB_configList->list.array[index]->eps_BearerIdentity);
|
||||
}
|
||||
|
||||
rb_config->drb_ToAddModList->list.array[index]->pdcp_Config = calloc(1,sizeof(struct NR_PDCP_Config));
|
||||
rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb = calloc(1,sizeof(struct NR_PDCP_Config__drb));
|
||||
rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->discardTimer = calloc(1,sizeof(long));
|
||||
*rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->discardTimer
|
||||
= *(ue_context_pP->ue_context.DRB_configList->list.array[index]->pdcp_Config->discardTimer);
|
||||
rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->pdcp_SN_SizeUL = calloc(1,sizeof(long));
|
||||
*rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->pdcp_SN_SizeUL
|
||||
= NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits;
|
||||
rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->pdcp_SN_SizeDL = calloc(1,sizeof(long));
|
||||
*rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->pdcp_SN_SizeDL
|
||||
= NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits;
|
||||
rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->headerCompression.present
|
||||
= NR_PDCP_Config__drb__headerCompression_PR_notUsed;
|
||||
rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->headerCompression.choice.notUsed = 0;
|
||||
rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->t_Reordering = calloc(1,sizeof(long));
|
||||
*rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->t_Reordering
|
||||
= NR_PDCP_Config__t_Reordering_ms0;
|
||||
}
|
||||
|
||||
rb_config->securityConfig = calloc(1,sizeof(struct NR_SecurityConfig ));
|
||||
rb_config->securityConfig->securityAlgorithmConfig = calloc(1,sizeof(struct NR_SecurityAlgorithmConfig));
|
||||
rb_config->securityConfig->securityAlgorithmConfig->cipheringAlgorithm = NR_CipheringAlgorithm_nea2;
|
||||
rb_config->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm = NULL;
|
||||
rb_config->securityConfig->keyToUse = calloc(1,sizeof(long));
|
||||
*rb_config->securityConfig->keyToUse = NR_SecurityConfig__keyToUse_secondary;
|
||||
}
|
||||
|
||||
cg_configinfo = calloc(1,sizeof(struct NR_CG_ConfigInfo));
|
||||
AssertFatal(cg_configinfo != NULL,"failed to allocate memory for cg_configinfo");
|
||||
@@ -4548,15 +4490,6 @@ static int encode_CG_ConfigInfo(
|
||||
(const char *)temp_buff, (enc_rval.encoded+7)>>3);
|
||||
}
|
||||
|
||||
cg_configinfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo->mcg_RB_Config
|
||||
= calloc(1,sizeof(OCTET_STRING_t));
|
||||
AssertFatal(cg_configinfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo->
|
||||
mcg_RB_Config != NULL, "failed to allocate memory for mcg_rb_config");
|
||||
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_RadioBearerConfig,NULL,(void *)rb_config,temp_buff,ASN_MAX_ENCODE_SIZE);
|
||||
AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n",
|
||||
enc_rval.failed_type->name, enc_rval.encoded);
|
||||
OCTET_STRING_fromBuf(cg_configinfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo->mcg_RB_Config,
|
||||
(const char *)temp_buff, (enc_rval.encoded+7)>>3);
|
||||
// this xer_fprint can be enabled for additional debugging messages
|
||||
// xer_fprint(stdout,&asn_DEF_NR_CG_ConfigInfo,(void *)cg_configinfo);
|
||||
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CG_ConfigInfo,NULL,(void *)cg_configinfo,
|
||||
|
||||
@@ -447,6 +447,15 @@ typedef struct {
|
||||
//---------------------------------------------------
|
||||
|
||||
|
||||
typedef struct {
|
||||
/* nea0 = 0, nea1 = 1, ... */
|
||||
int ciphering_algorithms[4];
|
||||
int ciphering_algorithms_count;
|
||||
|
||||
/* nia0 = 0, nia1 = 1, ... */
|
||||
int integrity_algorithms[4];
|
||||
int integrity_algorithms_count;
|
||||
} nr_security_configuration_t;
|
||||
|
||||
//---NR---(completely change)---------------------
|
||||
typedef struct gNB_RRC_INST_s {
|
||||
@@ -479,6 +488,8 @@ typedef struct gNB_RRC_INST_s {
|
||||
int srb1_timer_status_prohibit;
|
||||
int srs_enable[MAX_NUM_CCs];
|
||||
|
||||
// security configuration (preferred algorithms)
|
||||
nr_security_configuration_t security;
|
||||
} gNB_RRC_INST;
|
||||
|
||||
#include "nr_rrc_proto.h" //should be put here otherwise compilation error
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "LTE_UE-CapabilityRAT-ContainerList.h"
|
||||
#include "NR_CG-Config.h"
|
||||
#include "NR_CG-ConfigInfo.h"
|
||||
#include "NR_SecurityConfig.h"
|
||||
|
||||
int rrc_init_nr_global_param(void);
|
||||
|
||||
@@ -90,7 +91,10 @@ void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon
|
||||
int n_physical_antenna_ports,
|
||||
int initial_csi_index);
|
||||
|
||||
void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig);
|
||||
void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig,
|
||||
int eps_bearer_id, int rb_id,
|
||||
e_NR_CipheringAlgorithm ciphering_algorithm,
|
||||
e_NR_SecurityConfig__keyToUse key_to_use);
|
||||
|
||||
int generate_CG_Config(gNB_RRC_INST *rrc,
|
||||
NR_CG_Config_t *cg_Config,
|
||||
|
||||
@@ -125,20 +125,6 @@ void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc, NR_UE_CapabilityRAT_ContainerL
|
||||
xer_fprint(stdout, &asn_DEF_NR_UE_MRDC_Capability, ue_context_p->ue_context.UE_Capability_MRDC);
|
||||
}
|
||||
|
||||
if(cg_config_info && cg_config_info->mcg_RB_Config) {
|
||||
asn_dec_rval_t dec_rval = uper_decode(NULL,
|
||||
&asn_DEF_NR_RadioBearerConfig,
|
||||
(void **)&ue_context_p->ue_context.rb_config,
|
||||
cg_config_info->mcg_RB_Config->buf,
|
||||
cg_config_info->mcg_RB_Config->size, 0, 0);
|
||||
|
||||
if((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
|
||||
AssertFatal(1==0,"[InterNode] Failed to decode mcg_rb_config (%zu bits), size of OCTET_STRING %lu\n",
|
||||
dec_rval.consumed, cg_config_info->mcg_RB_Config->size);
|
||||
}
|
||||
}
|
||||
|
||||
xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void *)ue_context_p->ue_context.rb_config);
|
||||
rrc_add_nsa_user(rrc,ue_context_p, m);
|
||||
}
|
||||
|
||||
@@ -154,6 +140,8 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
|
||||
gtpv1u_enb_create_tunnel_req_t create_tunnel_req;
|
||||
gtpv1u_enb_create_tunnel_resp_t create_tunnel_resp;
|
||||
protocol_ctxt_t ctxt={0};
|
||||
unsigned char *kUPenc = NULL;
|
||||
int i;
|
||||
// NR RRCReconfiguration
|
||||
AssertFatal(rrc->Nb_ue < MAX_NR_RRC_UE_CONTEXTS,"cannot add another UE\n");
|
||||
ue_context_p->ue_context.reconfig = calloc(1,sizeof(NR_RRCReconfiguration_t));
|
||||
@@ -164,9 +152,91 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
|
||||
NR_RRCReconfiguration_IEs_t *reconfig_ies=calloc(1,sizeof(NR_RRCReconfiguration_IEs_t));
|
||||
ue_context_p->ue_context.reconfig->criticalExtensions.choice.rrcReconfiguration = reconfig_ies;
|
||||
carrier->initial_csi_index[rrc->Nb_ue] = 0;
|
||||
ue_context_p->ue_context.rb_config = calloc(1,sizeof(NR_RRCReconfiguration_t));
|
||||
if (get_softmodem_params()->phy_test == 1 || get_softmodem_params()->do_ra == 1 || get_softmodem_params()->sa == 1){
|
||||
ue_context_p->ue_context.rb_config = calloc(1,sizeof(NR_RRCReconfiguration_t));
|
||||
fill_default_rbconfig(ue_context_p->ue_context.rb_config);
|
||||
fill_default_rbconfig(ue_context_p->ue_context.rb_config,
|
||||
5 /* EPS bearer ID */,
|
||||
1 /* drb ID */,
|
||||
NR_CipheringAlgorithm_nea0,
|
||||
NR_SecurityConfig__keyToUse_master);
|
||||
} else {
|
||||
/* TODO: handle more than one bearer */
|
||||
if (m == NULL) {
|
||||
LOG_E(RRC, "fatal: m==NULL\n");
|
||||
exit(1);
|
||||
}
|
||||
if (m->nb_e_rabs_tobeadded != 1) {
|
||||
LOG_E(RRC, "fatal: m->nb_e_rabs_tobeadded = %d, should be 1\n", m->nb_e_rabs_tobeadded);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* store security key and security capabilities */
|
||||
memcpy(ue_context_p->ue_context.kgnb, m->kgnb, 32);
|
||||
ue_context_p->ue_context.security_capabilities.nRencryption_algorithms = m->security_capabilities.encryption_algorithms;
|
||||
ue_context_p->ue_context.security_capabilities.nRintegrity_algorithms = m->security_capabilities.integrity_algorithms;
|
||||
|
||||
/* Select ciphering algorithm based on gNB configuration file and
|
||||
* UE's supported algorithms.
|
||||
* We take the first from the list that is supported by the UE.
|
||||
* The ordering of the list comes from the configuration file.
|
||||
*/
|
||||
/* preset nea0 as fallback */
|
||||
ue_context_p->ue_context.ciphering_algorithm = 0;
|
||||
for (i = 0; i < rrc->security.ciphering_algorithms_count; i++) {
|
||||
int nea_mask[4] = {
|
||||
0,
|
||||
0x8000, /* nea1 */
|
||||
0x4000, /* nea2 */
|
||||
0x2000 /* nea3 */
|
||||
};
|
||||
if (rrc->security.ciphering_algorithms[i] == 0) {
|
||||
/* nea0 already preselected */
|
||||
break;
|
||||
}
|
||||
if (ue_context_p->ue_context.security_capabilities.nRencryption_algorithms & nea_mask[rrc->security.ciphering_algorithms[i]]) {
|
||||
ue_context_p->ue_context.ciphering_algorithm = rrc->security.ciphering_algorithms[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LOG_I(RRC, "selecting ciphering algorithm %d\n", (int)ue_context_p->ue_context.ciphering_algorithm);
|
||||
|
||||
/* integrity: no integrity protection for DRB in ENDC mode
|
||||
* as written in 38.331: "If UE is connected to E-UTRA/EPC, this field
|
||||
* indicates the integrity protection algorithm to be used for SRBs
|
||||
* configured with NR PDCP, as specified in TS 33.501"
|
||||
* So nothing for DRB. Plus a test with a COTS UE revealed that it
|
||||
* did not apply integrity on the DRB.
|
||||
*/
|
||||
ue_context_p->ue_context.integrity_algorithm = 0;
|
||||
|
||||
LOG_I(RRC, "selecting integrity algorithm %d\n", ue_context_p->ue_context.integrity_algorithm);
|
||||
|
||||
/* derive UP security key */
|
||||
unsigned char *kUPenc_kdf;
|
||||
nr_derive_key_up_enc(ue_context_p->ue_context.ciphering_algorithm,
|
||||
ue_context_p->ue_context.kgnb,
|
||||
&kUPenc_kdf);
|
||||
/* kUPenc: last 128 bits of key derivation function which returns 256 bits */
|
||||
kUPenc = malloc(16);
|
||||
if (kUPenc == NULL) exit(1);
|
||||
memcpy(kUPenc, kUPenc_kdf+16, 16);
|
||||
free(kUPenc_kdf);
|
||||
|
||||
e_NR_CipheringAlgorithm cipher_algo;
|
||||
switch (ue_context_p->ue_context.ciphering_algorithm) {
|
||||
case 0: cipher_algo = NR_CipheringAlgorithm_nea0; break;
|
||||
case 1: cipher_algo = NR_CipheringAlgorithm_nea1; break;
|
||||
case 2: cipher_algo = NR_CipheringAlgorithm_nea2; break;
|
||||
case 3: cipher_algo = NR_CipheringAlgorithm_nea3; break;
|
||||
default: LOG_E(RRC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); exit(1);
|
||||
}
|
||||
|
||||
fill_default_rbconfig(ue_context_p->ue_context.rb_config,
|
||||
m->e_rabs_tobeadded[0].e_rab_id,
|
||||
m->e_rabs_tobeadded[0].drb_ID,
|
||||
cipher_algo,
|
||||
NR_SecurityConfig__keyToUse_secondary);
|
||||
}
|
||||
fill_default_reconfig(carrier->servingcellconfigcommon,
|
||||
reconfig_ies,
|
||||
@@ -282,30 +352,6 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
|
||||
ctxt.eNB_index);
|
||||
}
|
||||
|
||||
/* store security key and security capabilities*/
|
||||
memcpy(ue_context_p->ue_context.kgnb, m->kgnb, 32);
|
||||
ue_context_p->ue_context.security_capabilities.nRencryption_algorithms = m->security_capabilities.encryption_algorithms;
|
||||
ue_context_p->ue_context.security_capabilities.nRintegrity_algorithms = m->security_capabilities.integrity_algorithms;
|
||||
|
||||
/* select ciphering algorithm based on gNB configuration file and
|
||||
* UE's supported algorithms
|
||||
*/
|
||||
/* hardcode ciphering to nea2 of the moment */
|
||||
ue_context_p->ue_context.ciphering_algorithm = 2; //NR_CipheringAlgorithm_nea2;
|
||||
/* integrity: no integrity protection */
|
||||
ue_context_p->ue_context.integrity_algorithm = 0;
|
||||
|
||||
/* derive UP security key */
|
||||
unsigned char *kUPenc_kdf, *kUPenc;
|
||||
nr_derive_key_up_enc(ue_context_p->ue_context.ciphering_algorithm,
|
||||
ue_context_p->ue_context.kgnb,
|
||||
&kUPenc_kdf);
|
||||
/* kUPenc: last 128 bits of key derivation function which returns 256 bits */
|
||||
kUPenc = malloc(16);
|
||||
if (kUPenc == NULL) exit(1);
|
||||
memcpy(kUPenc, kUPenc_kdf+16, 16);
|
||||
free(kUPenc_kdf);
|
||||
|
||||
nr_rrc_pdcp_config_asn1_req(
|
||||
&ctxt,
|
||||
(NR_SRB_ToAddModList_t *) NULL,
|
||||
|
||||
@@ -1329,7 +1329,10 @@ void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon
|
||||
reconfig->nonCriticalExtension = NULL;
|
||||
}
|
||||
|
||||
void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig) {
|
||||
void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig,
|
||||
int eps_bearer_id, int rb_id,
|
||||
e_NR_CipheringAlgorithm ciphering_algorithm,
|
||||
e_NR_SecurityConfig__keyToUse key_to_use) {
|
||||
|
||||
rbconfig->srb_ToAddModList = NULL;
|
||||
rbconfig->srb3_ToRelease = NULL;
|
||||
@@ -1337,8 +1340,8 @@ void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig) {
|
||||
NR_DRB_ToAddMod_t *drb_ToAddMod = calloc(1,sizeof(*drb_ToAddMod));
|
||||
drb_ToAddMod->cnAssociation = calloc(1,sizeof(*drb_ToAddMod->cnAssociation));
|
||||
drb_ToAddMod->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity;
|
||||
drb_ToAddMod->cnAssociation->choice.eps_BearerIdentity= 5;
|
||||
drb_ToAddMod->drb_Identity = 1;
|
||||
drb_ToAddMod->cnAssociation->choice.eps_BearerIdentity= eps_bearer_id;
|
||||
drb_ToAddMod->drb_Identity = rb_id;
|
||||
drb_ToAddMod->reestablishPDCP = NULL;
|
||||
drb_ToAddMod->recoverPDCP = NULL;
|
||||
drb_ToAddMod->pdcp_Config = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config));
|
||||
@@ -1367,12 +1370,12 @@ void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig) {
|
||||
|
||||
rbconfig->securityConfig = calloc(1,sizeof(*rbconfig->securityConfig));
|
||||
rbconfig->securityConfig->securityAlgorithmConfig = calloc(1,sizeof(*rbconfig->securityConfig->securityAlgorithmConfig));
|
||||
rbconfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm = NR_CipheringAlgorithm_nea0;
|
||||
rbconfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm = ciphering_algorithm;
|
||||
rbconfig->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm=NULL;
|
||||
rbconfig->securityConfig->keyToUse = calloc(1,sizeof(*rbconfig->securityConfig->keyToUse));
|
||||
*rbconfig->securityConfig->keyToUse = NR_SecurityConfig__keyToUse_master;
|
||||
*rbconfig->securityConfig->keyToUse = key_to_use;
|
||||
|
||||
xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void*)rbconfig);
|
||||
// xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void*)rbconfig);
|
||||
}
|
||||
/* Function to set or overwrite PTRS DL RRC parameters */
|
||||
void rrc_config_dl_ptrs_params(NR_BWP_Downlink_t *bwp, int *ptrsNrb, int *ptrsMcs, int *epre_Ratio, int * reOffset)
|
||||
|
||||
@@ -278,6 +278,18 @@ THREAD_STRUCT = (
|
||||
}
|
||||
);
|
||||
|
||||
security = {
|
||||
# preferred ciphering algorithms
|
||||
# the first one of the list that an UE supports in chosen
|
||||
# valid values: nea0, nea1, nea2, nea3
|
||||
ciphering_algorithms = ( "nea0", "nea2" );
|
||||
|
||||
# preferred integrity algorithms
|
||||
# the first one of the list that an UE supports in chosen
|
||||
# valid values: nia0, nia1, nia2, nia3
|
||||
integrity_algorithms = ( "nia0" );
|
||||
};
|
||||
|
||||
log_config :
|
||||
{
|
||||
global_log_level ="info";
|
||||
|
||||
Reference in New Issue
Block a user