From d1f490243e0c73b1886a72cfd64697f7a8eb9882 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 9 Feb 2024 14:39:06 +0100 Subject: [PATCH] nrUE: check integrity of SecurityModeCommand We AssertFatal() if integrity fails. To be refined if needed. --- openair2/COMMON/pdcp_messages_types.h | 4 +++ openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c | 3 +++ openair2/RRC/NR_UE/rrc_UE.c | 30 +++++++++++++++++------ 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/openair2/COMMON/pdcp_messages_types.h b/openair2/COMMON/pdcp_messages_types.h index d7c84a24a1..0620858223 100644 --- a/openair2/COMMON/pdcp_messages_types.h +++ b/openair2/COMMON/pdcp_messages_types.h @@ -96,6 +96,10 @@ typedef struct NRRrcDcchDataInd_s { uint16_t rnti; uint8_t module_id; uint8_t gNB_index; // LG: needed in UE + /* these three variables are needed for RRC to check integrity of the PDCP SDU */ + uint32_t mac; + uint32_t header; + uint32_t count; } NRRrcDcchDataInd; typedef struct RrcPcchDataReq_s { diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index 259579d347..f0480f7be1 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -784,6 +784,9 @@ srb_found: NR_RRC_DCCH_DATA_IND(message_p).dcch_index = srb_id; NR_RRC_DCCH_DATA_IND(message_p).sdu_p = rrc_buffer_p; NR_RRC_DCCH_DATA_IND(message_p).sdu_size = size; + NR_RRC_DCCH_DATA_IND(message_p).mac = mac; + NR_RRC_DCCH_DATA_IND(message_p).header = header; + NR_RRC_DCCH_DATA_IND(message_p).count = count; ue_id_t ue_id = ue->ue_id; itti_send_msg_to_task(TASK_RRC_NRUE, ue_id, message_p); } diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 076728e925..f3230f27e4 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -1004,7 +1004,13 @@ static int8_t nr_rrc_ue_decode_ccch(NR_UE_RRC_INST_t *rrc, } static void nr_rrc_ue_process_securityModeCommand(NR_UE_RRC_INST_t *ue_rrc, - NR_SecurityModeCommand_t *const securityModeCommand) + NR_SecurityModeCommand_t *const securityModeCommand, + int srb_id, + const uint8_t *msg, + int msg_size, + uint32_t mac, + uint32_t header, + uint32_t count) { uint8_t security_mode; @@ -1093,10 +1099,13 @@ static void nr_rrc_ue_process_securityModeCommand(NR_UE_RRC_INST_t *ue_rrc, } LOG_T(NR_RRC, "\n"); - // TODO the SecurityModeCommand message needs to pass the integrity protection check - // for the UE to declare AS security to be activated + // the SecurityModeCommand message needs to pass the integrity protection check + // for the UE to declare AS security to be activated + bool integrity_pass = nr_pdcp_check_integrity_srb(ue_rrc->ue_id, srb_id, msg, msg_size, mac, header, count); + AssertFatal(integrity_pass, "SecurityModeCommand integrity failed\n"); + ue_rrc->as_security_activated = true; - int srb_id = 1; // SecurityModeComplete in SRB1 + srb_id = 1; // SecurityModeComplete in SRB1 nr_pdcp_data_req_srb(ue_rrc->ue_id, srb_id, 0, (enc_rval.encoded + 7) / 8, buffer, deliver_pdu_srb_rlc, NULL); /* after encoding SecurityModeComplete we activate both ciphering and integrity */ @@ -1548,7 +1557,10 @@ static int nr_rrc_ue_decode_dcch(NR_UE_RRC_INST_t *rrc, const srb_id_t Srb_id, const uint8_t *const Buffer, size_t Buffer_size, - const uint8_t gNB_indexP) + const uint8_t gNB_indexP, + uint32_t mac, + uint32_t header, + uint32_t count) { NR_DL_DCCH_Message_t *dl_dcch_msg = NULL; @@ -1632,7 +1644,8 @@ static int nr_rrc_ue_decode_dcch(NR_UE_RRC_INST_t *rrc, break; case NR_DL_DCCH_MessageType__c1_PR_securityModeCommand: LOG_I(NR_RRC, "Received securityModeCommand (gNB %d)\n", gNB_indexP); - nr_rrc_ue_process_securityModeCommand(rrc, c1->choice.securityModeCommand); + nr_rrc_ue_process_securityModeCommand(rrc, c1->choice.securityModeCommand, + Srb_id, Buffer, Buffer_size, mac, header, count); break; } } break; @@ -1737,7 +1750,10 @@ void *rrc_nrue(void *notUsed) NR_RRC_DCCH_DATA_IND(msg_p).dcch_index, NR_RRC_DCCH_DATA_IND(msg_p).sdu_p, NR_RRC_DCCH_DATA_IND(msg_p).sdu_size, - NR_RRC_DCCH_DATA_IND(msg_p).gNB_index); + NR_RRC_DCCH_DATA_IND(msg_p).gNB_index, + NR_RRC_DCCH_DATA_IND(msg_p).mac, + NR_RRC_DCCH_DATA_IND(msg_p).header, + NR_RRC_DCCH_DATA_IND(msg_p).count); break; case NAS_KENB_REFRESH_REQ: