Merge branch '7-bugfix-kenb-refresh' into 'develop1B'
Resolve "Fix the attach failure at RRC::SecurityModeCommand" Closes #7 See merge request !4
This commit is contained in:
@@ -220,6 +220,14 @@ typedef struct broadcast_info_ind_s {
|
||||
#define AS_HSDUPA (1 << NET_ACCESS_HSDUPA)
|
||||
#define AS_EUTRAN (1 << NET_ACCESS_EUTRAN)
|
||||
|
||||
/*
|
||||
* NAS->AS -K_eNB refresh request
|
||||
* NAS request AS to refresh its KeNB key
|
||||
*/
|
||||
typedef struct kenb_refresh_req_s {
|
||||
Byte_t kenb[32];
|
||||
} kenb_refresh_req_t;
|
||||
|
||||
/*
|
||||
* NAS->AS - Cell Information request
|
||||
* NAS request AS to search for a suitable cell belonging to the selected
|
||||
|
||||
@@ -64,6 +64,7 @@ MESSAGE_DEF(RRC_STATE_IND, MESSAGE_PRIORITY_MED, RrcStateInd,
|
||||
MESSAGE_DEF(RRC_CONFIGURATION_REQ, MESSAGE_PRIORITY_MED, RrcConfigurationReq, rrc_configuration_req)
|
||||
|
||||
// UE: NAS -> RRC messages
|
||||
MESSAGE_DEF(NAS_KENB_REFRESH_REQ, MESSAGE_PRIORITY_MED, NasKenbRefreshReq, nas_kenb_refresh_req)
|
||||
MESSAGE_DEF(NAS_CELL_SELECTION_REQ, MESSAGE_PRIORITY_MED, NasCellSelectionReq, nas_cell_selection_req)
|
||||
MESSAGE_DEF(NAS_CONN_ESTABLI_REQ, MESSAGE_PRIORITY_MED, NasConnEstabliReq, nas_conn_establi_req)
|
||||
MESSAGE_DEF(NAS_UPLINK_DATA_REQ, MESSAGE_PRIORITY_MED, NasUlDataReq, nas_ul_data_req)
|
||||
|
||||
@@ -70,6 +70,7 @@ typedef UL_DCCH_Message_t RrcUlDcchMessage;
|
||||
|
||||
#define RRC_CONFIGURATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_configuration_req
|
||||
|
||||
#define NAS_KENB_REFRESH_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_kenb_refresh_req
|
||||
#define NAS_CELL_SELECTION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_cell_selection_req
|
||||
#define NAS_CONN_ESTABLI_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_conn_establi_req
|
||||
#define NAS_UPLINK_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_ul_data_req
|
||||
@@ -183,6 +184,7 @@ typedef struct RrcConfigurationReq_s {
|
||||
} RrcConfigurationReq;
|
||||
|
||||
// UE: NAS -> RRC messages
|
||||
typedef kenb_refresh_req_t NasKenbRefreshReq;
|
||||
typedef cell_info_req_t NasCellSelectionReq;
|
||||
typedef nas_establish_req_t NasConnEstabliReq;
|
||||
typedef ul_info_transfer_req_t NasUlDataReq;
|
||||
|
||||
@@ -182,7 +182,7 @@ typedef enum HO_STATE_e {
|
||||
#define PAYLOAD_SIZE_MAX 1024
|
||||
#define RRC_BUF_SIZE 255
|
||||
#define UNDEF_SECURITY_MODE 0xff
|
||||
#define NO_SECURITY_MODE 0x33
|
||||
#define NO_SECURITY_MODE 0x20
|
||||
|
||||
#define CBA_OFFSET 0xfff4
|
||||
// #define NUM_MAX_CBA_GROUP 4 // in the platform_constants
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#define RRC_UE_C
|
||||
|
||||
#include "assertions.h"
|
||||
#include "hashtable.h"
|
||||
#include "asn1_conversions.h"
|
||||
#include "defs.h"
|
||||
#include "PHY/TOOLS/dB_routines.h"
|
||||
@@ -107,6 +108,15 @@ extern void *bigphys_malloc(int);
|
||||
|
||||
extern int8_t dB_fixed2(uint32_t x,uint32_t y);
|
||||
|
||||
extern void pdcp_config_set_security(
|
||||
const protocol_ctxt_t* const ctxt_pP,
|
||||
pdcp_t * const pdcp_pP,
|
||||
const rb_id_t rb_idP,
|
||||
const uint16_t lc_idP,
|
||||
const uint8_t security_modeP,
|
||||
uint8_t * const kRRCenc,
|
||||
uint8_t * const kRRCint,
|
||||
uint8_t * const kUPenc);
|
||||
|
||||
// internal prototypes
|
||||
|
||||
@@ -1401,6 +1411,62 @@ rrc_ue_process_securityModeCommand(
|
||||
ul_dcch_msg.message.choice.c1.present = UL_DCCH_MessageType__c1_PR_securityModeFailure;
|
||||
}
|
||||
|
||||
|
||||
#if defined(ENABLE_SECURITY)
|
||||
uint8_t *kRRCenc = NULL;
|
||||
uint8_t *kUPenc = NULL;
|
||||
uint8_t *kRRCint = NULL;
|
||||
pdcp_t *pdcp_p = NULL;
|
||||
hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE;
|
||||
hashtable_rc_t h_rc;
|
||||
|
||||
key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti,
|
||||
ctxt_pP->enb_flag, DCCH, SRB_FLAG_YES);
|
||||
h_rc = hashtable_get(pdcp_coll_p, key, (void**) &pdcp_p);
|
||||
|
||||
if (h_rc == HASH_TABLE_OK) {
|
||||
LOG_D(RRC, "PDCP_COLL_KEY_VALUE() returns valid key = %d\n", key);
|
||||
|
||||
LOG_D(RRC, "driving kRRCenc, kRRCint and kUPenc from KeNB="
|
||||
"%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_rrc_inst[ctxt_pP->module_id].kenb[0], UE_rrc_inst[ctxt_pP->module_id].kenb[1], UE_rrc_inst[ctxt_pP->module_id].kenb[2], UE_rrc_inst[ctxt_pP->module_id].kenb[3],
|
||||
UE_rrc_inst[ctxt_pP->module_id].kenb[4], UE_rrc_inst[ctxt_pP->module_id].kenb[5], UE_rrc_inst[ctxt_pP->module_id].kenb[6], UE_rrc_inst[ctxt_pP->module_id].kenb[7],
|
||||
UE_rrc_inst[ctxt_pP->module_id].kenb[8], UE_rrc_inst[ctxt_pP->module_id].kenb[9], UE_rrc_inst[ctxt_pP->module_id].kenb[10], UE_rrc_inst[ctxt_pP->module_id].kenb[11],
|
||||
UE_rrc_inst[ctxt_pP->module_id].kenb[12], UE_rrc_inst[ctxt_pP->module_id].kenb[13], UE_rrc_inst[ctxt_pP->module_id].kenb[14], UE_rrc_inst[ctxt_pP->module_id].kenb[15],
|
||||
UE_rrc_inst[ctxt_pP->module_id].kenb[16], UE_rrc_inst[ctxt_pP->module_id].kenb[17], UE_rrc_inst[ctxt_pP->module_id].kenb[18], UE_rrc_inst[ctxt_pP->module_id].kenb[19],
|
||||
UE_rrc_inst[ctxt_pP->module_id].kenb[20], UE_rrc_inst[ctxt_pP->module_id].kenb[21], UE_rrc_inst[ctxt_pP->module_id].kenb[22], UE_rrc_inst[ctxt_pP->module_id].kenb[23],
|
||||
UE_rrc_inst[ctxt_pP->module_id].kenb[24], UE_rrc_inst[ctxt_pP->module_id].kenb[25], UE_rrc_inst[ctxt_pP->module_id].kenb[26], UE_rrc_inst[ctxt_pP->module_id].kenb[27],
|
||||
UE_rrc_inst[ctxt_pP->module_id].kenb[28], UE_rrc_inst[ctxt_pP->module_id].kenb[29], UE_rrc_inst[ctxt_pP->module_id].kenb[30], UE_rrc_inst[ctxt_pP->module_id].kenb[31]);
|
||||
|
||||
derive_key_rrc_enc(UE_rrc_inst[ctxt_pP->module_id].ciphering_algorithm,
|
||||
UE_rrc_inst[ctxt_pP->module_id].kenb, &kRRCenc);
|
||||
derive_key_rrc_int(UE_rrc_inst[ctxt_pP->module_id].integrity_algorithm,
|
||||
UE_rrc_inst[ctxt_pP->module_id].kenb, &kRRCint);
|
||||
derive_key_up_enc(UE_rrc_inst[ctxt_pP->module_id].ciphering_algorithm,
|
||||
UE_rrc_inst[ctxt_pP->module_id].kenb, &kUPenc);
|
||||
|
||||
if (securityMode != 0xff) {
|
||||
pdcp_config_set_security(ctxt_pP, pdcp_p, 0, 0,
|
||||
UE_rrc_inst[ctxt_pP->module_id].ciphering_algorithm
|
||||
| (UE_rrc_inst[ctxt_pP->module_id].integrity_algorithm << 4),
|
||||
kRRCenc, kRRCint, kUPenc);
|
||||
} else {
|
||||
LOG_W(RRC, "skipped pdcp_config_set_security() as securityMode == 0x%02x",
|
||||
securityMode);
|
||||
}
|
||||
} else {
|
||||
LOG_W(RRC, "Could not get PDCP instance where key=0x%\n", key);
|
||||
}
|
||||
|
||||
#endif //#if defined(ENABLE_SECURITY)
|
||||
|
||||
if (securityModeCommand->criticalExtensions.present == SecurityModeCommand__criticalExtensions_PR_c1) {
|
||||
if (securityModeCommand->criticalExtensions.choice.c1.present == SecurityModeCommand__criticalExtensions__c1_PR_securityModeCommand_r8) {
|
||||
|
||||
@@ -4072,6 +4138,30 @@ void *rrc_ue_task( void *args_p )
|
||||
|
||||
# if defined(ENABLE_USE_MME)
|
||||
|
||||
case NAS_KENB_REFRESH_REQ:
|
||||
memcpy((void*)UE_rrc_inst[ue_mod_id].kenb, (void*)NAS_KENB_REFRESH_REQ(msg_p).kenb, sizeof(UE_rrc_inst[ue_mod_id].kenb));
|
||||
|
||||
LOG_D(RRC, "[UE %d] Received %s: refreshed RRC::KeNB = "
|
||||
"%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, msg_name,
|
||||
UE_rrc_inst[ue_mod_id].kenb[0], UE_rrc_inst[ue_mod_id].kenb[1], UE_rrc_inst[ue_mod_id].kenb[2], UE_rrc_inst[ue_mod_id].kenb[3],
|
||||
UE_rrc_inst[ue_mod_id].kenb[4], UE_rrc_inst[ue_mod_id].kenb[5], UE_rrc_inst[ue_mod_id].kenb[6], UE_rrc_inst[ue_mod_id].kenb[7],
|
||||
UE_rrc_inst[ue_mod_id].kenb[8], UE_rrc_inst[ue_mod_id].kenb[9], UE_rrc_inst[ue_mod_id].kenb[10], UE_rrc_inst[ue_mod_id].kenb[11],
|
||||
UE_rrc_inst[ue_mod_id].kenb[12], UE_rrc_inst[ue_mod_id].kenb[13], UE_rrc_inst[ue_mod_id].kenb[14], UE_rrc_inst[ue_mod_id].kenb[15],
|
||||
UE_rrc_inst[ue_mod_id].kenb[16], UE_rrc_inst[ue_mod_id].kenb[17], UE_rrc_inst[ue_mod_id].kenb[18], UE_rrc_inst[ue_mod_id].kenb[19],
|
||||
UE_rrc_inst[ue_mod_id].kenb[20], UE_rrc_inst[ue_mod_id].kenb[21], UE_rrc_inst[ue_mod_id].kenb[22], UE_rrc_inst[ue_mod_id].kenb[23],
|
||||
UE_rrc_inst[ue_mod_id].kenb[24], UE_rrc_inst[ue_mod_id].kenb[25], UE_rrc_inst[ue_mod_id].kenb[26], UE_rrc_inst[ue_mod_id].kenb[27],
|
||||
UE_rrc_inst[ue_mod_id].kenb[28], UE_rrc_inst[ue_mod_id].kenb[29], UE_rrc_inst[ue_mod_id].kenb[30], UE_rrc_inst[ue_mod_id].kenb[31]);
|
||||
|
||||
break;
|
||||
|
||||
/* NAS messages */
|
||||
case NAS_CELL_SELECTION_REQ:
|
||||
ue_mod_id = 0; /* TODO force ue_mod_id to first UE, NAS UE not virtualized yet */
|
||||
|
||||
@@ -116,6 +116,14 @@ Description Defines the messages supported by the Access Stratum sublayer
|
||||
#define AS_HSDUPA (1 << NET_ACCESS_HSDUPA)
|
||||
#define AS_EUTRAN (1 << NET_ACCESS_EUTRAN)
|
||||
|
||||
/*
|
||||
* NAS->AS -K_eNB refresh request
|
||||
* NAS request AS to refresh its KeNB key
|
||||
*/
|
||||
typedef struct kenb_refresh_req_s {
|
||||
Byte_t kenb[32];
|
||||
} kenb_refresh_req_t;
|
||||
|
||||
/*
|
||||
* NAS->AS - Cell Information request
|
||||
* NAS request AS to search for a suitable cell belonging to the selected
|
||||
|
||||
@@ -72,6 +72,10 @@ Description Defines the security mode control EMM procedure executed by the
|
||||
#include "secu_defs.h"
|
||||
#include "msc.h"
|
||||
|
||||
#if defined(NAS_BUILT_IN_UE)
|
||||
#include "nas_itti_messaging.h"
|
||||
#endif
|
||||
|
||||
/****************************************************************************/
|
||||
/**************** E X T E R N A L D E F I N I T I O N S ****************/
|
||||
/****************************************************************************/
|
||||
@@ -293,7 +297,9 @@ int emm_proc_security_mode_command(int native_ksi, int ksi,
|
||||
|
||||
_emm_data.security->selected_algorithms.encryption = seea;
|
||||
_emm_data.security->selected_algorithms.integrity = seia;
|
||||
|
||||
#if defined(NAS_BUILT_IN_UE)
|
||||
nas_itti_kenb_refresh_req(_security_data.kenb.value);
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
* NAS security mode command not accepted by the UE
|
||||
|
||||
@@ -187,6 +187,39 @@ int nas_itti_protected_msg(const char *buffer, const nas_message_t *msg, const i
|
||||
|
||||
extern unsigned char NB_eNB_INST;
|
||||
|
||||
int nas_itti_kenb_refresh_req(const Byte_t kenb[32])
|
||||
{
|
||||
MessageDef *message_p;
|
||||
|
||||
message_p = itti_alloc_new_message(TASK_NAS_UE, NAS_KENB_REFRESH_REQ);
|
||||
|
||||
memcpy(NAS_KENB_REFRESH_REQ(message_p).kenb, kenb, sizeof(NAS_KENB_REFRESH_REQ(message_p).kenb));
|
||||
|
||||
MSC_LOG_TX_MESSAGE(
|
||||
MSC_NAS_UE,
|
||||
MSC_RRC_UE,
|
||||
NULL,0,
|
||||
"0 NAS_KENB_REFRESH_REQ KeNB "
|
||||
"%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",
|
||||
kenb[0], kenb[1], kenb[2], kenb[3],
|
||||
kenb[4], kenb[5], kenb[6], kenb[7],
|
||||
kenb[8], kenb[9], kenb[10], kenb[11],
|
||||
kenb[12], kenb[13], kenb[14], kenb[15],
|
||||
kenb[16], kenb[17], kenb[18], kenb[19],
|
||||
kenb[20], kenb[21], kenb[22], kenb[23],
|
||||
kenb[24], kenb[25], kenb[26], kenb[27],
|
||||
kenb[28], kenb[29], kenb[30], kenb[31]);
|
||||
|
||||
return itti_send_msg_to_task(TASK_RRC_UE, NB_eNB_INST + 0 /* TODO to be virtualized */, message_p);
|
||||
}
|
||||
|
||||
int nas_itti_cell_info_req(const plmn_t plmnID, const Byte_t rat)
|
||||
{
|
||||
MessageDef *message_p;
|
||||
|
||||
@@ -54,6 +54,9 @@ int nas_itti_protected_msg(
|
||||
|
||||
|
||||
# if defined(NAS_BUILT_IN_UE)
|
||||
|
||||
int nas_itti_kenb_refresh_req(const Byte_t kenb[32]);
|
||||
|
||||
int nas_itti_cell_info_req(const plmn_t plmnID, const Byte_t rat);
|
||||
|
||||
int nas_itti_nas_establish_req(as_cause_t cause, as_call_type_t type, as_stmsi_t s_tmsi, plmn_t plmnID, Byte_t *data_pP, uint32_t lengthP);
|
||||
|
||||
Reference in New Issue
Block a user