diff --git a/openair2/COMMON/as_message.h b/openair2/COMMON/as_message.h index 30810a325eace63c944b947bfb8c0a6487094e80..976a398061f1c7235df20e43f1d3103a6c057f4e 100644 --- a/openair2/COMMON/as_message.h +++ b/openair2/COMMON/as_message.h @@ -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 diff --git a/openair2/COMMON/rrc_messages_def.h b/openair2/COMMON/rrc_messages_def.h index 27d3a6bdd432a54776a8f2fbe0e16eb127403ad4..83cd8558d424c86f91012d9b87cc63a85ea45b6c 100644 --- a/openair2/COMMON/rrc_messages_def.h +++ b/openair2/COMMON/rrc_messages_def.h @@ -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) diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index ffe194265fd2413be9894fdfb4e384b6b7997fd7..1befc4a676e458b3f50767ee97b564322619c3cf 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -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; diff --git a/openair2/RRC/LITE/defs.h b/openair2/RRC/LITE/defs.h index 04d1fcc9f5ab81176d220617fe932baeaa2c0380..c9fac320158328c9af0ea1c12b0f2cea2649c8b7 100644 --- a/openair2/RRC/LITE/defs.h +++ b/openair2/RRC/LITE/defs.h @@ -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 diff --git a/openair2/RRC/LITE/rrc_UE.c b/openair2/RRC/LITE/rrc_UE.c index b51b00241fb5fc75960b4e4baa72a1ea52550f06..c240ac4f76a295acf368203e7418281a2a16b217 100644 --- a/openair2/RRC/LITE/rrc_UE.c +++ b/openair2/RRC/LITE/rrc_UE.c @@ -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 */ diff --git a/openair3/NAS/COMMON/API/NETWORK/l2_message.h b/openair3/NAS/COMMON/API/NETWORK/l2_message.h index 02e5d87354eeba634236231964ada5f1dd28e443..9c349b8d06fdcbfa8089c3ff1423be04e64b13bd 100644 --- a/openair3/NAS/COMMON/API/NETWORK/l2_message.h +++ b/openair3/NAS/COMMON/API/NETWORK/l2_message.h @@ -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 diff --git a/openair3/NAS/UE/EMM/SecurityModeControl.c b/openair3/NAS/UE/EMM/SecurityModeControl.c index fd7e4c39917a353f095ab6a5adcd6327c62c1ce5..9f4186412e45011dd85071e5cd0ddc59831ddbbd 100755 --- a/openair3/NAS/UE/EMM/SecurityModeControl.c +++ b/openair3/NAS/UE/EMM/SecurityModeControl.c @@ -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 diff --git a/openair3/NAS/UE/nas_itti_messaging.c b/openair3/NAS/UE/nas_itti_messaging.c index 7b8f630b8985a5fe0c4a60566b4e21b3b3c8f60e..a28c7394b29ea1f350a5037ee0b6534962bd54cd 100755 --- a/openair3/NAS/UE/nas_itti_messaging.c +++ b/openair3/NAS/UE/nas_itti_messaging.c @@ -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; diff --git a/openair3/NAS/UE/nas_itti_messaging.h b/openair3/NAS/UE/nas_itti_messaging.h index 9ea80f63c09f8f192f2d7d240311149600558b0d..a9db232d70b299bd34fd651a7d6fca2df1257e78 100755 --- a/openair3/NAS/UE/nas_itti_messaging.h +++ b/openair3/NAS/UE/nas_itti_messaging.h @@ -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);