Commit cb9defc6 authored by hardy's avatar hardy

Merge remote-tracking branch 'origin/develop-NR_SA_nrUE_security_update' into integration_2021_wk44

parents cd28e3fb 1aeba176
...@@ -911,9 +911,7 @@ boolean_t nr_rrc_pdcp_config_asn1_req( ...@@ -911,9 +911,7 @@ boolean_t nr_rrc_pdcp_config_asn1_req(
uint8_t *const kRRCint, uint8_t *const kRRCint,
uint8_t *const kUPenc, uint8_t *const kUPenc,
uint8_t *const kUPint uint8_t *const kUPint
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9
#endif
,rb_id_t *const defaultDRB, ,rb_id_t *const defaultDRB,
struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list) struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list)
//struct NR_RLC_Config *rlc_Config) //struct NR_RLC_Config *rlc_Config)
...@@ -983,9 +981,7 @@ boolean_t rrc_pdcp_config_asn1_req( ...@@ -983,9 +981,7 @@ boolean_t rrc_pdcp_config_asn1_req(
uint8_t *const kRRCenc, uint8_t *const kRRCenc,
uint8_t *const kRRCint, uint8_t *const kRRCint,
uint8_t *const kUPenc uint8_t *const kUPenc
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9
#endif
,rb_id_t *const defaultDRB) ,rb_id_t *const defaultDRB)
{ {
return 0; return 0;
...@@ -1248,10 +1244,8 @@ boolean_t pdcp_data_req( ...@@ -1248,10 +1244,8 @@ boolean_t pdcp_data_req(
const sdu_size_t sdu_buffer_size, const sdu_size_t sdu_buffer_size,
unsigned char *const sdu_buffer, unsigned char *const sdu_buffer,
const pdcp_transmission_mode_t mode const pdcp_transmission_mode_t mode
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
,const uint32_t *const sourceL2Id ,const uint32_t *const sourceL2Id
,const uint32_t *const destinationL2Id ,const uint32_t *const destinationL2Id
#endif
) )
{ {
if (srb_flagP) { if (srb_flagP) {
......
...@@ -3618,9 +3618,7 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t ...@@ -3618,9 +3618,7 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t
NULL, NULL,
NULL, NULL,
NULL NULL
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
, (LTE_PMCH_InfoList_r9_t *) NULL , (LTE_PMCH_InfoList_r9_t *) NULL
#endif
, NULL); , NULL);
/* Refresh SRBs/DRBs */ /* Refresh SRBs/DRBs */
...@@ -3629,11 +3627,9 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t ...@@ -3629,11 +3627,9 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t
*SRB_configList2, // NULL, *SRB_configList2, // NULL,
*DRB_configList, *DRB_configList,
NULL NULL
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
, (LTE_PMCH_InfoList_r9_t *) NULL, , (LTE_PMCH_InfoList_r9_t *) NULL,
0, 0,
0 0
#endif
); );
} }
...@@ -6331,9 +6327,7 @@ rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ct ...@@ -6331,9 +6327,7 @@ rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ct
NULL, NULL,
NULL, NULL,
NULL NULL
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
, (LTE_PMCH_InfoList_r9_t *) NULL , (LTE_PMCH_InfoList_r9_t *) NULL
#endif
, NULL); , NULL);
/* Refresh SRBs/DRBs */ /* Refresh SRBs/DRBs */
...@@ -6342,11 +6336,9 @@ rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ct ...@@ -6342,11 +6336,9 @@ rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ct
*SRB_configList2, // NULL, *SRB_configList2, // NULL,
*DRB_configList, *DRB_configList,
NULL NULL
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
, (LTE_PMCH_InfoList_r9_t *) NULL, , (LTE_PMCH_InfoList_r9_t *) NULL,
0, 0,
0 0
#endif
); );
} }
......
...@@ -106,9 +106,7 @@ extern boolean_t nr_rrc_pdcp_config_asn1_req( ...@@ -106,9 +106,7 @@ extern boolean_t nr_rrc_pdcp_config_asn1_req(
uint8_t *const kRRCint, uint8_t *const kRRCint,
uint8_t *const kUPenc, uint8_t *const kUPenc,
uint8_t *const kUPint uint8_t *const kUPint
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9
#endif
,rb_id_t *const defaultDRB, ,rb_id_t *const defaultDRB,
struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list); struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list);
...@@ -1305,51 +1303,22 @@ rrc_gNB_process_RRCReconfigurationComplete( ...@@ -1305,51 +1303,22 @@ rrc_gNB_process_RRCReconfigurationComplete(
ue_context_pP->ue_context.ue_reestablishment_timer = 0; ue_context_pP->ue_context.ue_reestablishment_timer = 0;
#ifndef PHYSIM
uint8_t *k_kdf = NULL;
/* Derive the keys from kgnb */ /* Derive the keys from kgnb */
if (DRB_configList != NULL) { if (DRB_configList != NULL) {
k_kdf = NULL;
nr_derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm, nr_derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm,
ue_context_pP->ue_context.kgnb, ue_context_pP->ue_context.kgnb,
&k_kdf); &kUPenc);
/* kUPenc: last 128 bits of key derivation function which returns 256 bits */
kUPenc = malloc(16);
if (kUPenc == NULL) exit(1);
memcpy(kUPenc, k_kdf+16, 16);
free(k_kdf);
k_kdf = NULL;
nr_derive_key_up_int(ue_context_pP->ue_context.integrity_algorithm, nr_derive_key_up_int(ue_context_pP->ue_context.integrity_algorithm,
ue_context_pP->ue_context.kgnb, ue_context_pP->ue_context.kgnb,
&k_kdf); &kUPint);
/* kUPint: last 128 bits of key derivation function which returns 256 bits */
kUPint = malloc(16);
if (kUPint == NULL) exit(1);
memcpy(kUPint, k_kdf+16, 16);
free(k_kdf);
} }
k_kdf = NULL;
nr_derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm, nr_derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm,
ue_context_pP->ue_context.kgnb, ue_context_pP->ue_context.kgnb,
&k_kdf); &kRRCenc);
/* kRRCenc: last 128 bits of key derivation function which returns 256 bits */
kRRCenc = malloc(16);
if (kRRCenc == NULL) exit(1);
memcpy(kRRCenc, k_kdf+16, 16);
free(k_kdf);
k_kdf = NULL;
nr_derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm, nr_derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm,
ue_context_pP->ue_context.kgnb, ue_context_pP->ue_context.kgnb,
&k_kdf); &kRRCint);
/* kRRCint: last 128 bits of key derivation function which returns 256 bits */
kRRCint = malloc(16);
if (kRRCint == NULL) exit(1);
memcpy(kRRCint, k_kdf+16, 16);
free(k_kdf);
#endif
/* Refresh SRBs/DRBs */ /* Refresh SRBs/DRBs */
MSC_LOG_TX_MESSAGE(MSC_RRC_GNB, MSC_PDCP_ENB, NULL, 0, MSC_AS_TIME_FMT" CONFIG_REQ UE %x DRB (security unchanged)", MSC_LOG_TX_MESSAGE(MSC_RRC_GNB, MSC_PDCP_ENB, NULL, 0, MSC_AS_TIME_FMT" CONFIG_REQ UE %x DRB (security unchanged)",
MSC_AS_TIME_ARGS(ctxt_pP), MSC_AS_TIME_ARGS(ctxt_pP),
......
...@@ -308,43 +308,19 @@ nr_rrc_pdcp_config_security( ...@@ -308,43 +308,19 @@ nr_rrc_pdcp_config_security(
uint8_t *kUPenc = NULL; uint8_t *kUPenc = NULL;
static int print_keys= 1; static int print_keys= 1;
#ifndef PHYSIM
uint8_t *k_kdf = NULL;
/* Derive the keys from kgnb */ /* Derive the keys from kgnb */
if (SRB_configList != NULL) { if (SRB_configList != NULL) {
k_kdf = NULL;
nr_derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm, nr_derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm,
ue_context_pP->ue_context.kgnb, ue_context_pP->ue_context.kgnb,
&k_kdf); &kUPenc);
/* kUPenc: last 128 bits of key derivation function which returns 256 bits */
kUPenc = malloc(16);
if (kUPenc == NULL) exit(1);
memcpy(kUPenc, k_kdf+16, 16);
free(k_kdf);
} }
k_kdf = NULL;
nr_derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm, nr_derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm,
ue_context_pP->ue_context.kgnb, ue_context_pP->ue_context.kgnb,
&k_kdf); &kRRCenc);
/* kRRCenc: last 128 bits of key derivation function which returns 256 bits */
kRRCenc = malloc(16);
if (kRRCenc == NULL) exit(1);
memcpy(kRRCenc, k_kdf+16, 16);
free(k_kdf);
k_kdf = NULL;
nr_derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm, nr_derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm,
ue_context_pP->ue_context.kgnb, ue_context_pP->ue_context.kgnb,
&k_kdf); &kRRCint);
/* kRRCint: last 128 bits of key derivation function which returns 256 bits */
kRRCint = malloc(16);
if (kRRCint == NULL) exit(1);
memcpy(kRRCint, k_kdf+16, 16);
free(k_kdf);
#endif
if (!IS_SOFTMODEM_IQPLAYER) { if (!IS_SOFTMODEM_IQPLAYER) {
SET_LOG_DUMP(DEBUG_SECURITY) ; SET_LOG_DUMP(DEBUG_SECURITY) ;
} }
......
...@@ -52,9 +52,7 @@ extern boolean_t nr_rrc_pdcp_config_asn1_req( ...@@ -52,9 +52,7 @@ extern boolean_t nr_rrc_pdcp_config_asn1_req(
uint8_t *const kRRCint, uint8_t *const kRRCint,
uint8_t *const kUPenc, uint8_t *const kUPenc,
uint8_t *const kUPint uint8_t *const kUPint
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9
#endif
,rb_id_t *const defaultDRB, ,rb_id_t *const defaultDRB,
struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list); struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list);
...@@ -215,25 +213,12 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ ...@@ -215,25 +213,12 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
LOG_I(RRC, "selecting integrity algorithm %d\n", ue_context_p->ue_context.integrity_algorithm); LOG_I(RRC, "selecting integrity algorithm %d\n", ue_context_p->ue_context.integrity_algorithm);
/* derive UP security key */ /* derive UP security key */
unsigned char *kUPenc_kdf;
nr_derive_key_up_enc(ue_context_p->ue_context.ciphering_algorithm, nr_derive_key_up_enc(ue_context_p->ue_context.ciphering_algorithm,
ue_context_p->ue_context.kgnb, ue_context_p->ue_context.kgnb,
&kUPenc_kdf); &kUPenc);
/* 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);
unsigned char *kUPint_kdf;
nr_derive_key_up_int(ue_context_p->ue_context.integrity_algorithm, nr_derive_key_up_int(ue_context_p->ue_context.integrity_algorithm,
ue_context_p->ue_context.kgnb, ue_context_p->ue_context.kgnb,
&kUPint_kdf); &kUPint);
/* kUPint: last 128 bits of key derivation function which returns 256 bits */
kUPint = malloc(16);
if (kUPint == NULL) exit(1);
memcpy(kUPint, kUPint_kdf+16, 16);
free(kUPint_kdf);
e_NR_CipheringAlgorithm cipher_algo; e_NR_CipheringAlgorithm cipher_algo;
switch (ue_context_p->ue_context.ciphering_algorithm) { switch (ue_context_p->ue_context.ciphering_algorithm) {
......
...@@ -187,9 +187,7 @@ extern boolean_t nr_rrc_pdcp_config_asn1_req( ...@@ -187,9 +187,7 @@ extern boolean_t nr_rrc_pdcp_config_asn1_req(
uint8_t *const kRRCint, uint8_t *const kRRCint,
uint8_t *const kUPenc, uint8_t *const kUPenc,
uint8_t *const kUPint uint8_t *const kUPint
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9
#endif
,rb_id_t *const defaultDRB, ,rb_id_t *const defaultDRB,
struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list); struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list);
...@@ -1661,15 +1659,16 @@ int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB ...@@ -1661,15 +1659,16 @@ int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB
uint8_t *kRRCenc = NULL; uint8_t *kRRCenc = NULL;
uint8_t *kUPenc = NULL; uint8_t *kUPenc = NULL;
uint8_t *kRRCint = NULL; uint8_t *kRRCint = NULL;
pdcp_t *pdcp_p = NULL; nr_derive_key_up_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,
hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; NR_UE_rrc_inst[ctxt_pP->module_id].kgnb,
hashtable_rc_t h_rc; &kUPenc);
key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, DCCH, SRB_FLAG_YES); nr_derive_key_rrc_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,
h_rc = hashtable_get(pdcp_coll_p, key, (void **) &pdcp_p); NR_UE_rrc_inst[ctxt_pP->module_id].kgnb,
&kRRCenc);
if (h_rc == HASH_TABLE_OK) { nr_derive_key_rrc_int(NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm,
LOG_D(NR_RRC, "PDCP_COLL_KEY_VALUE() returns valid key = %ld\n", key); NR_UE_rrc_inst[ctxt_pP->module_id].kgnb,
LOG_D(NR_RRC, "driving kRRCenc, kRRCint and kUPenc from KgNB=" &kRRCint);
LOG_I(NR_RRC, "driving kRRCenc, kRRCint and kUPenc from KgNB="
"%02x%02x%02x%02x" "%02x%02x%02x%02x"
"%02x%02x%02x%02x" "%02x%02x%02x%02x"
"%02x%02x%02x%02x" "%02x%02x%02x%02x"
...@@ -1686,21 +1685,15 @@ int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB ...@@ -1686,21 +1685,15 @@ int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[20], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[21], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[22], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[23], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[20], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[21], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[22], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[23],
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[24], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[25], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[26], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[27], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[24], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[25], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[26], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[27],
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[28], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[29], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[30], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[31]); NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[28], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[29], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[30], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[31]);
derive_key_rrc_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kRRCenc);
derive_key_rrc_int(NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm,NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kRRCint);
derive_key_up_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kUPenc);
if (securityMode != 0xff) { if (securityMode != 0xff) {
pdcp_config_set_security(ctxt_pP, pdcp_p, 0, 0, pdcp_config_set_security(ctxt_pP, NULL, DCCH, DCCH+2,
NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm
| (NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm << 4), | (NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm << 4),
kRRCenc, kRRCint, kUPenc); kRRCenc, kRRCint, kUPenc);
} else { } else {
LOG_I(NR_RRC, "skipped pdcp_config_set_security() as securityMode == 0x%02x", securityMode); LOG_I(NR_RRC, "skipped pdcp_config_set_security() as securityMode == 0x%02x", securityMode);
} }
} else {
LOG_I(NR_RRC, "Could not get PDCP instance where key=0x%ld\n", key);
}
if (securityModeCommand->criticalExtensions.present == NR_SecurityModeCommand__criticalExtensions_PR_securityModeCommand) { if (securityModeCommand->criticalExtensions.present == NR_SecurityModeCommand__criticalExtensions_PR_securityModeCommand) {
ul_dcch_msg.message.choice.c1->choice.securityModeComplete = CALLOC(1, sizeof(NR_SecurityModeComplete_t)); ul_dcch_msg.message.choice.c1->choice.securityModeComplete = CALLOC(1, sizeof(NR_SecurityModeComplete_t));
...@@ -2044,21 +2037,12 @@ nr_rrc_ue_establish_srb2( ...@@ -2044,21 +2037,12 @@ nr_rrc_ue_establish_srb2(
} }
} }
uint8_t *k_kdf = NULL;
uint8_t *kRRCenc = NULL; uint8_t *kRRCenc = NULL;
uint8_t *kRRCint = NULL; uint8_t *kRRCint = NULL;
nr_derive_key_rrc_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm, nr_derive_key_rrc_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &k_kdf); NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kRRCenc);
kRRCenc = malloc(16);
if (kRRCenc == NULL) exit(1);
memcpy(kRRCenc, k_kdf + 16, 16);
free(k_kdf);
nr_derive_key_rrc_int(NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm, nr_derive_key_rrc_int(NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm,
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &k_kdf); NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kRRCint);
kRRCint = malloc(16);
if (kRRCint == NULL) exit(1);
memcpy(kRRCint, k_kdf + 16, 16);
free(k_kdf);
// Refresh SRBs // Refresh SRBs
nr_rrc_pdcp_config_asn1_req(ctxt_pP, nr_rrc_pdcp_config_asn1_req(ctxt_pP,
...@@ -2157,23 +2141,13 @@ nr_rrc_ue_establish_srb2( ...@@ -2157,23 +2141,13 @@ nr_rrc_ue_establish_srb2(
} }
} }
uint8_t *k_kdf = NULL;
uint8_t *kUPenc = NULL; uint8_t *kUPenc = NULL;
uint8_t *kUPint = NULL; uint8_t *kUPint = NULL;
nr_derive_key_up_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm, nr_derive_key_up_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &k_kdf); NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kUPenc);
kUPenc = malloc(16);
if (kUPenc == NULL) exit(1);
memcpy(kUPenc, k_kdf + 16, 16);
free(k_kdf);
nr_derive_key_up_int(NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm, nr_derive_key_up_int(NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm,
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &k_kdf); NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kUPint);
kUPint = malloc(16);
if (kUPint == NULL) exit(1);
memcpy(kUPint, k_kdf + 16, 16);
free(k_kdf);
MSC_LOG_TX_MESSAGE( MSC_LOG_TX_MESSAGE(
MSC_RRC_UE, MSC_RRC_UE,
...@@ -2537,6 +2511,28 @@ nr_rrc_ue_establish_srb2( ...@@ -2537,6 +2511,28 @@ nr_rrc_ue_establish_srb2(
NR_RRC_DCCH_DATA_IND (msg_p).gNB_index); NR_RRC_DCCH_DATA_IND (msg_p).gNB_index);
break; break;
case NAS_KENB_REFRESH_REQ:
memcpy((void *)NR_UE_rrc_inst[ue_mod_id].kgnb, (void *)NAS_KENB_REFRESH_REQ(msg_p).kenb, sizeof(NR_UE_rrc_inst[ue_mod_id].kgnb));
LOG_D(RRC, "[UE %d] Received %s: refreshed RRC::KgNB = "
"%02x%02x%02x%02x"
"%02x%02x%02x%02x"
"%02x%02x%02x%02x"
"%02x%02x%02x%02x"
"%02x%02x%02x%02x"
"%02x%02x%02x%02x"
"%02x%02x%02x%02x"
"%02x%02x%02x%02x\n",
ue_mod_id, ITTI_MSG_NAME (msg_p),
NR_UE_rrc_inst[ue_mod_id].kgnb[0], NR_UE_rrc_inst[ue_mod_id].kgnb[1], NR_UE_rrc_inst[ue_mod_id].kgnb[2], NR_UE_rrc_inst[ue_mod_id].kgnb[3],
NR_UE_rrc_inst[ue_mod_id].kgnb[4], NR_UE_rrc_inst[ue_mod_id].kgnb[5], NR_UE_rrc_inst[ue_mod_id].kgnb[6], NR_UE_rrc_inst[ue_mod_id].kgnb[7],
NR_UE_rrc_inst[ue_mod_id].kgnb[8], NR_UE_rrc_inst[ue_mod_id].kgnb[9], NR_UE_rrc_inst[ue_mod_id].kgnb[10], NR_UE_rrc_inst[ue_mod_id].kgnb[11],
NR_UE_rrc_inst[ue_mod_id].kgnb[12], NR_UE_rrc_inst[ue_mod_id].kgnb[13], NR_UE_rrc_inst[ue_mod_id].kgnb[14], NR_UE_rrc_inst[ue_mod_id].kgnb[15],
NR_UE_rrc_inst[ue_mod_id].kgnb[16], NR_UE_rrc_inst[ue_mod_id].kgnb[17], NR_UE_rrc_inst[ue_mod_id].kgnb[18], NR_UE_rrc_inst[ue_mod_id].kgnb[19],
NR_UE_rrc_inst[ue_mod_id].kgnb[20], NR_UE_rrc_inst[ue_mod_id].kgnb[21], NR_UE_rrc_inst[ue_mod_id].kgnb[22], NR_UE_rrc_inst[ue_mod_id].kgnb[23],
NR_UE_rrc_inst[ue_mod_id].kgnb[24], NR_UE_rrc_inst[ue_mod_id].kgnb[25], NR_UE_rrc_inst[ue_mod_id].kgnb[26], NR_UE_rrc_inst[ue_mod_id].kgnb[27],
NR_UE_rrc_inst[ue_mod_id].kgnb[28], NR_UE_rrc_inst[ue_mod_id].kgnb[29], NR_UE_rrc_inst[ue_mod_id].kgnb[30], NR_UE_rrc_inst[ue_mod_id].kgnb[31]);
break;
case NAS_UPLINK_DATA_REQ: { case NAS_UPLINK_DATA_REQ: {
uint32_t length; uint32_t length;
uint8_t *buffer; uint8_t *buffer;
......
...@@ -121,6 +121,8 @@ int nr_derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id, ...@@ -121,6 +121,8 @@ int nr_derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id,
string[6] = 0x01; string[6] = 0x01;
kdf(string, 7, key, 32, out, 32); kdf(string, 7, key, 32, out, 32);
// in NR, we use the last 16 bytes, ignoring the first 16 ones
memcpy(*out, *out+16, 16);
return 0; return 0;
} }
......
...@@ -47,6 +47,8 @@ ...@@ -47,6 +47,8 @@
uint8_t *registration_request_buf; uint8_t *registration_request_buf;
uint32_t registration_request_len; uint32_t registration_request_len;
extern char *baseNetAddress; extern char *baseNetAddress;
extern uint16_t NB_UE_INST;
static ue_sa_security_key_t ** ue_security_key;
static int nas_protected_security_header_encode( static int nas_protected_security_header_encode(
char *buffer, char *buffer,
...@@ -251,6 +253,108 @@ void derive_knas(algorithm_type_dist_t nas_alg_type, uint8_t nas_alg_id, uint8_t ...@@ -251,6 +253,108 @@ void derive_knas(algorithm_type_dist_t nas_alg_type, uint8_t nas_alg_id, uint8_t
knas_int[i] = out[16 + i]; knas_int[i] = out[16 + i];
} }
void derive_kgnb(uint8_t kamf[32], uint32_t count, uint8_t *kgnb){
/* Compute the KDF input parameter
* S = FC(0x6E) || UL NAS Count || 0x00 0x04 || 0x01 || 0x00 0x01
*/
uint8_t input[32];
// uint16_t length = 4;
// int offset = 0;
uint8_t out[32] = { 0 };
LOG_TRACE(INFO, "%s with count= %d", __FUNCTION__, count);
memset(input, 0, 32);
input[0] = 0x6E;
// P0
input[1] = count >> 24;
input[2] = (uint8_t)(count >> 16);
input[3] = (uint8_t)(count >> 8);
input[4] = (uint8_t)count;
// L0
input[5] = 0;
input[6] = 4;
// P1
input[7] = 0x01;
// L1
input[8] = 0;
input[9] = 1;
kdf(kamf, 32, input, 10, out, 32);
for (int i = 0; i < 32; i++)
kgnb[i] = out[i];
printf("kgnb : ");
for(int pp=0;pp<32;pp++)
printf("%02x ",kgnb[pp]);
printf("\n");
}
void derive_ue_keys(int Mod_id, uint8_t *buf, uicc_t *uicc) {
uint8_t ak[6];
uint8_t sqn[6];
AssertFatal (Mod_id < NB_UE_INST, "Failed, Mod_id %d is over NB_UE_INST!\n", Mod_id);
if(ue_security_key[Mod_id]){
// clear old key
memset(ue_security_key[Mod_id],0,sizeof(ue_sa_security_key_t));
}else{
// Allocate new memory
ue_security_key[Mod_id]=(ue_sa_security_key_t *)calloc(1,sizeof(ue_sa_security_key_t));
}
uint8_t *kausf = ue_security_key[Mod_id]->kausf;
uint8_t *kseaf = ue_security_key[Mod_id]->kseaf;
uint8_t *kamf = ue_security_key[Mod_id]->kamf;
uint8_t *knas_int = ue_security_key[Mod_id]->knas_int;
uint8_t *output = ue_security_key[Mod_id]->res;
uint8_t *rand = ue_security_key[Mod_id]->rand;
uint8_t *kgnb = ue_security_key[Mod_id]->kgnb;
// get RAND for authentication request
for(int index = 0; index < 16;index++){
rand[index] = buf[8+index];
}
uint8_t resTemp[16];
uint8_t ck[16], ik[16];
f2345(uicc->key, rand, resTemp, ck, ik, ak, uicc->opc);
transferRES(ck, ik, resTemp, rand, output, uicc);
for(int index = 0; index < 6; index++){
sqn[index] = buf[26+index];
}
derive_kausf(ck, ik, sqn, kausf, uicc);
derive_kseaf(kausf, kseaf, uicc);
derive_kamf(kseaf, kamf, 0x0000, uicc);
derive_knas(0x02, 2, kamf, knas_int);
derive_kgnb(kamf,0,kgnb);
printf("kausf:");
for(int i = 0; i < 32; i++){
printf("%x ", kausf[i]);
}
printf("\n");
printf("kseaf:");
for(int i = 0; i < 32; i++){
printf("%x ", kseaf[i]);
}
printf("\n");
printf("kamf:");
for(int i = 0; i < 32; i++){
printf("%x ", kamf[i]);
}
printf("\n");
printf("knas_int:\n");
for(int i = 0; i < 16; i++){
printf("%x ", knas_int[i]);
}
printf("\n");
}
void generateRegistrationRequest(as_nas_info_t *initialNasMsg, int Mod_id) { void generateRegistrationRequest(as_nas_info_t *initialNasMsg, int Mod_id) {
int size = sizeof(mm_msg_header_t); int size = sizeof(mm_msg_header_t);
fgs_nas_message_t nas_msg={0}; fgs_nas_message_t nas_msg={0};
...@@ -373,69 +477,13 @@ void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype ...@@ -373,69 +477,13 @@ void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype
} }
OctetString knas_int; static void generateAuthenticationResp(int Mod_id,as_nas_info_t *initialNasMsg, uint8_t *buf, uicc_t *uicc){
static void generateAuthenticationResp(as_nas_info_t *initialNasMsg, uint8_t *buf, uicc_t *uicc){
uint8_t ak[6];
uint8_t kausf[32]; derive_ue_keys(Mod_id,buf,uicc);
uint8_t sqn[6];
uint8_t kseaf[32];
uint8_t kamf[32];
OctetString res; OctetString res;
// get RAND for authentication request
unsigned char rand[16];
for(int index = 0; index < 16;index++){
rand[index] = buf[8+index];
}
uint8_t resTemp[16];
uint8_t ck[16], ik[16], output[16];
f2345(uicc->key, rand, resTemp, ck, ik, ak, uicc->opc);
transferRES(ck, ik, resTemp, rand, output, uicc);
// get knas_int
knas_int.length = 16;
knas_int.value = malloc(knas_int.length);
for(int index = 0; index < 6; index++){
sqn[index] = buf[26+index];
}
derive_kausf(ck, ik, sqn, kausf, uicc);
derive_kseaf(kausf, kseaf, uicc);
derive_kamf(kseaf, kamf, 0x0000, uicc);
derive_knas(0x02, 2, kamf, knas_int.value);
printf("kausf:");
for(int i = 0; i < 32; i++){
printf("%x ", kausf[i]);
}
printf("\n");
printf("kseaf:");
for(int i = 0; i < 32; i++){
printf("%x ", kseaf[i]);
}
printf("\n");
printf("kamf:");
for(int i = 0; i < 32; i++){
printf("%x ", kamf[i]);
}
printf("\n");
printf("knas_int:\n");
for(int i = 0; i < 16; i++){
printf("%x ", knas_int.value[i]);
}
printf("\n");
// set res
res.length = 16; res.length = 16;
res.value = output; res.value = calloc(1,16);
memcpy(res.value,ue_security_key[Mod_id]->res,16);
int size = sizeof(mm_msg_header_t); int size = sizeof(mm_msg_header_t);
fgs_nas_message_t nas_msg; fgs_nas_message_t nas_msg;
...@@ -465,7 +513,14 @@ static void generateAuthenticationResp(as_nas_info_t *initialNasMsg, uint8_t *bu ...@@ -465,7 +513,14 @@ static void generateAuthenticationResp(as_nas_info_t *initialNasMsg, uint8_t *bu
initialNasMsg->length = mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data), size); initialNasMsg->length = mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data), size);
} }
static void generateSecurityModeComplete(as_nas_info_t *initialNasMsg) int nas_itti_kgnb_refresh_req(const uint8_t kgnb[32], int instance) {
MessageDef *message_p;
message_p = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_KENB_REFRESH_REQ);
memcpy(NAS_KENB_REFRESH_REQ(message_p).kenb, kgnb, sizeof(NAS_KENB_REFRESH_REQ(message_p).kenb));
return itti_send_msg_to_task(TASK_RRC_NRUE, instance, message_p);
}
static void generateSecurityModeComplete(int Mod_id,as_nas_info_t *initialNasMsg)
{ {
int size = sizeof(mm_msg_header_t); int size = sizeof(mm_msg_header_t);
fgs_nas_message_t nas_msg; fgs_nas_message_t nas_msg;
...@@ -512,7 +567,7 @@ static void generateSecurityModeComplete(as_nas_info_t *initialNasMsg) ...@@ -512,7 +567,7 @@ static void generateSecurityModeComplete(as_nas_info_t *initialNasMsg)
initialNasMsg->length = security_header_len + mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data+security_header_len), size-security_header_len); initialNasMsg->length = security_header_len + mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data+security_header_len), size-security_header_len);
stream_cipher.key = knas_int.value; stream_cipher.key = ue_security_key[Mod_id]->knas_int;
stream_cipher.key_length = 16; stream_cipher.key_length = 16;
stream_cipher.count = 0; stream_cipher.count = 0;
stream_cipher.bearer = 1; stream_cipher.bearer = 1;
...@@ -532,7 +587,7 @@ static void generateSecurityModeComplete(as_nas_info_t *initialNasMsg) ...@@ -532,7 +587,7 @@ static void generateSecurityModeComplete(as_nas_info_t *initialNasMsg)
} }
} }
static void generateRegistrationComplete(as_nas_info_t *initialNasMsg, SORTransparentContainer *sortransparentcontainer) { static void generateRegistrationComplete(int Mod_id, as_nas_info_t *initialNasMsg, SORTransparentContainer *sortransparentcontainer) {
//wait send RRCReconfigurationComplete and InitialContextSetupResponse //wait send RRCReconfigurationComplete and InitialContextSetupResponse
sleep(1); sleep(1);
int length = 0; int length = 0;
...@@ -592,7 +647,7 @@ static void generateRegistrationComplete(as_nas_info_t *initialNasMsg, SORTransp ...@@ -592,7 +647,7 @@ static void generateRegistrationComplete(as_nas_info_t *initialNasMsg, SORTransp
} }
initialNasMsg->length = length; initialNasMsg->length = length;
stream_cipher.key = knas_int.value; stream_cipher.key = ue_security_key[Mod_id]->knas_int;
stream_cipher.key_length = 16; stream_cipher.key_length = 16;
stream_cipher.count = 1; stream_cipher.count = 1;
stream_cipher.bearer = 1; stream_cipher.bearer = 1;
...@@ -625,7 +680,7 @@ void decodeDownlinkNASTransport(as_nas_info_t *initialNasMsg, uint8_t * pdu_buff ...@@ -625,7 +680,7 @@ void decodeDownlinkNASTransport(as_nas_info_t *initialNasMsg, uint8_t * pdu_buff
} }
} }
static void generatePduSessionEstablishRequest(uicc_t * uicc, as_nas_info_t *initialNasMsg){ static void generatePduSessionEstablishRequest(int Mod_id, uicc_t * uicc, as_nas_info_t *initialNasMsg){
//wait send RegistrationComplete //wait send RegistrationComplete
usleep(100*150); usleep(100*150);
int size = 0; int size = 0;
...@@ -699,7 +754,7 @@ static void generatePduSessionEstablishRequest(uicc_t * uicc, as_nas_info_t *ini ...@@ -699,7 +754,7 @@ static void generatePduSessionEstablishRequest(uicc_t * uicc, as_nas_info_t *ini
initialNasMsg->length = security_header_len + mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data+security_header_len), size-security_header_len); initialNasMsg->length = security_header_len + mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data+security_header_len), size-security_header_len);
stream_cipher.key = knas_int.value; stream_cipher.key = ue_security_key[Mod_id]->knas_int;
stream_cipher.key_length = 16; stream_cipher.key_length = 16;
stream_cipher.count = 0; stream_cipher.count = 0;
stream_cipher.bearer = 1; stream_cipher.bearer = 1;
...@@ -729,6 +784,8 @@ void *nas_nrue_task(void *args_p) ...@@ -729,6 +784,8 @@ void *nas_nrue_task(void *args_p)
uint8_t msg_type = 0; uint8_t msg_type = 0;
uint8_t *pdu_buffer = NULL; uint8_t *pdu_buffer = NULL;
ue_security_key=(ue_sa_security_key_t **)calloc(1,sizeof(ue_sa_security_key_t*)*NB_UE_INST);
itti_mark_task_ready (TASK_NAS_NRUE); itti_mark_task_ready (TASK_NAS_NRUE);
MSC_START_USE(); MSC_START_USE();
...@@ -813,7 +870,7 @@ void *nas_nrue_task(void *args_p) ...@@ -813,7 +870,7 @@ void *nas_nrue_task(void *args_p)
as_nas_info_t initialNasMsg; as_nas_info_t initialNasMsg;
memset(&initialNasMsg, 0, sizeof(as_nas_info_t)); memset(&initialNasMsg, 0, sizeof(as_nas_info_t));
generateRegistrationComplete(&initialNasMsg, NULL); generateRegistrationComplete(Mod_id,&initialNasMsg, NULL);
if(initialNasMsg.length > 0){ if(initialNasMsg.length > 0){
MessageDef *message_p; MessageDef *message_p;
message_p = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_UPLINK_DATA_REQ); message_p = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_UPLINK_DATA_REQ);
...@@ -826,7 +883,7 @@ void *nas_nrue_task(void *args_p) ...@@ -826,7 +883,7 @@ void *nas_nrue_task(void *args_p)
as_nas_info_t pduEstablishMsg; as_nas_info_t pduEstablishMsg;
memset(&pduEstablishMsg, 0, sizeof(as_nas_info_t)); memset(&pduEstablishMsg, 0, sizeof(as_nas_info_t));
generatePduSessionEstablishRequest(uicc, &pduEstablishMsg); generatePduSessionEstablishRequest(Mod_id, uicc, &pduEstablishMsg);
if(pduEstablishMsg.length > 0){ if(pduEstablishMsg.length > 0){
MessageDef *message_p; MessageDef *message_p;
message_p = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_UPLINK_DATA_REQ); message_p = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_UPLINK_DATA_REQ);
...@@ -893,10 +950,11 @@ void *nas_nrue_task(void *args_p) ...@@ -893,10 +950,11 @@ void *nas_nrue_task(void *args_p)
generateIdentityResponse(&initialNasMsg,*(pdu_buffer+3), uicc); generateIdentityResponse(&initialNasMsg,*(pdu_buffer+3), uicc);
break; break;
case FGS_AUTHENTICATION_REQUEST: case FGS_AUTHENTICATION_REQUEST:
generateAuthenticationResp(&initialNasMsg, pdu_buffer, uicc); generateAuthenticationResp(Mod_id,&initialNasMsg, pdu_buffer, uicc);
break; break;
case FGS_SECURITY_MODE_COMMAND: case FGS_SECURITY_MODE_COMMAND:
generateSecurityModeComplete(&initialNasMsg); nas_itti_kgnb_refresh_req(ue_security_key[Mod_id]->kgnb, instance);
generateSecurityModeComplete(Mod_id,&initialNasMsg);
break; break;
case FGS_DOWNLINK_NAS_TRANSPORT: case FGS_DOWNLINK_NAS_TRANSPORT:
decodeDownlinkNASTransport(&initialNasMsg, pdu_buffer); decodeDownlinkNASTransport(&initialNasMsg, pdu_buffer);
......
...@@ -64,6 +64,16 @@ ...@@ -64,6 +64,16 @@
#define INITIAL_REGISTRATION 0b001 #define INITIAL_REGISTRATION 0b001
/* Security Key for SA UE */
typedef struct {
uint8_t kausf[32];
uint8_t kseaf[32];
uint8_t kamf[32];
uint8_t knas_int[16];
uint8_t res[16];
uint8_t rand[16];
uint8_t kgnb[32];
} ue_sa_security_key_t;
typedef enum fgs_protocol_discriminator_e { typedef enum fgs_protocol_discriminator_e {
/* Protocol discriminator identifier for 5GS Mobility Management */ /* Protocol discriminator identifier for 5GS Mobility Management */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment