diff --git a/openair2/COMMON/pdcp_messages_types.h b/openair2/COMMON/pdcp_messages_types.h index 0620858223..b97fdef986 100644 --- a/openair2/COMMON/pdcp_messages_types.h +++ b/openair2/COMMON/pdcp_messages_types.h @@ -88,18 +88,18 @@ typedef struct NRRrcDcchDataReq_s { uint8_t gNB_index; } NRRrcDcchDataReq; +#include "openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_data.h" + typedef struct NRRrcDcchDataInd_s { uint32_t frame; uint8_t dcch_index; uint32_t sdu_size; uint8_t *sdu_p; - 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; + uint16_t rnti; + uint8_t module_id; + uint8_t gNB_index; // LG: needed in UE + /* 'msg_integrity' is needed for RRC to check integrity of the PDCP SDU */ + nr_pdcp_integrity_data_t msg_integrity; } NRRrcDcchDataInd; typedef struct RrcPcchDataReq_s { diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c index 7e38c4fa9d..98162d003c 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c @@ -55,8 +55,6 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity, int sdap_header_size = 0; int rx_deliv_sn; uint32_t rx_deliv_hfn; - uint32_t mac = 0; - uint32_t header = 0; if (entity->entity_suspended) { LOG_W(PDCP, "PDCP entity %d is suspended. Quit RX procedure.\n", entity->rb_id); @@ -123,19 +121,14 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity, rcvd_count = (rcvd_hfn << entity->sn_size) | rcvd_sn; + nr_pdcp_integrity_data_t msg_integrity = { 0 }; + /* the MAC-I/header/rcvd_count is needed by some RRC procedures, store it */ if (entity->has_integrity || entity->type == NR_PDCP_SRB) { - mac = (uint32_t)buffer[size-4] - | ((uint32_t)buffer[size-3] << 8) - | ((uint32_t)buffer[size-2] << 16) - | ((uint32_t)buffer[size-1] << 24); - - /* higher byte of 'header' is its size, next 2 or 3 bytes are the header */ - header = (uint32_t)header_size << 24; - if (header_size == 2) - header |= (buffer[0] << 16) | (buffer[1] << 8); - else - header |= (buffer[0] << 16) | (buffer[1] << 8) | buffer[2]; + msg_integrity.count = rcvd_count; + memcpy(msg_integrity.mac, &buffer[size-4], 4); + msg_integrity.header_size = header_size; + memcpy(msg_integrity.header, buffer, header_size); } if (entity->has_ciphering) @@ -170,7 +163,7 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity, sdu = nr_pdcp_new_sdu(rcvd_count, (char *)buffer + header_size, size - header_size - integrity_size, - mac, header); + &msg_integrity); entity->rx_list = nr_pdcp_sdu_list_add(entity->rx_list, sdu); entity->rx_size += size-header_size; @@ -187,7 +180,7 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity, nr_pdcp_sdu_t *cur = entity->rx_list; entity->deliver_sdu(entity->deliver_sdu_data, entity, cur->buffer, cur->size, - cur->mac, cur->header, cur->count); + &cur->msg_integrity); entity->rx_list = cur->next; entity->rx_size -= cur->size; entity->stats.txsdu_pkts++; @@ -299,33 +292,26 @@ static int nr_pdcp_entity_process_sdu(nr_pdcp_entity_t *entity, static bool nr_pdcp_entity_check_integrity(struct nr_pdcp_entity_t *entity, const uint8_t *buffer, int buffer_size, - uint32_t mac, - uint32_t header, - uint32_t count) + const nr_pdcp_integrity_data_t *msg_integrity) { if (!entity->has_integrity) return false; - int header_size = (header >> 24) & 0xff; + int header_size = msg_integrity->header_size; uint8_t b[buffer_size + header_size]; - b[0] = (header >> 16) & 0xff; - b[1] = (header >> 8) & 0xff; - if (header_size == 3) - b[2] = header & 0xff; + for (int i = 0; i < header_size; i++) + b[i] = msg_integrity->header[i]; + memcpy(b + header_size, buffer, buffer_size); - unsigned char integrity[4]; - entity->integrity(entity->integrity_context, integrity, + unsigned char mac[4]; + entity->integrity(entity->integrity_context, mac, b, buffer_size + header_size, - entity->rb_id, count, entity->is_gnb ? 0 : 1); - uint32_t nmac = (uint32_t)integrity[0] - | ((uint32_t)integrity[1] << 8) - | ((uint32_t)integrity[2] << 16) - | ((uint32_t)integrity[3] << 24); + entity->rb_id, msg_integrity->count, entity->is_gnb ? 0 : 1); - return nmac == mac; + return memcmp(mac, msg_integrity->mac, 4) == 0; } /* may be called several times, take care to clean previous settings */ @@ -410,7 +396,7 @@ static void check_t_reordering(nr_pdcp_entity_t *entity) nr_pdcp_sdu_t *cur = entity->rx_list; entity->deliver_sdu(entity->deliver_sdu_data, entity, cur->buffer, cur->size, - cur->mac, cur->header, cur->count); + &cur->msg_integrity); entity->rx_list = cur->next; entity->rx_size -= cur->size; entity->stats.txsdu_pkts++; @@ -424,7 +410,7 @@ static void check_t_reordering(nr_pdcp_entity_t *entity) nr_pdcp_sdu_t *cur = entity->rx_list; entity->deliver_sdu(entity->deliver_sdu_data, entity, cur->buffer, cur->size, - cur->mac, cur->header, cur->count); + &cur->msg_integrity); entity->rx_list = cur->next; entity->rx_size -= cur->size; entity->stats.txsdu_pkts++; @@ -455,7 +441,7 @@ static void deliver_all_sdus(nr_pdcp_entity_t *entity) nr_pdcp_sdu_t *cur = entity->rx_list; entity->deliver_sdu(entity->deliver_sdu_data, entity, cur->buffer, cur->size, - cur->mac, cur->header, cur->count); + &cur->msg_integrity); entity->rx_list = cur->next; entity->rx_size -= cur->size; entity->stats.txsdu_pkts++; @@ -577,7 +563,7 @@ nr_pdcp_entity_t *new_nr_pdcp_entity( bool has_sdap_tx, void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, char *buf, int size, - uint32_t mac, uint32_t header, uint32_t count), + const nr_pdcp_integrity_data_t *msg_integrity), void *deliver_sdu_data, void (*deliver_pdu)(void *deliver_pdu_data, ue_id_t ue_id, int rb_id, char *buf, int size, int sdu_id), diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h index 058aabc87e..5d2fd56f70 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h @@ -107,16 +107,14 @@ typedef struct nr_pdcp_entity_t { /* check_integrity is used by RRC */ bool (*check_integrity)(struct nr_pdcp_entity_t *entity, const uint8_t *buffer, int buffer_length, - uint32_t mac, - uint32_t header, - uint32_t count); + const nr_pdcp_integrity_data_t *msg_integrity); void (*set_time)(struct nr_pdcp_entity_t *entity, uint64_t now); /* callbacks provided to the PDCP module */ void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, char *buf, int size, - uint32_t mac, uint32_t header, uint32_t count); + const nr_pdcp_integrity_data_t *msg_integrity); void *deliver_sdu_data; void (*deliver_pdu)(void *deliver_pdu_data, ue_id_t ue_id, int rb_id, char *buf, int size, int sdu_id); @@ -188,7 +186,7 @@ nr_pdcp_entity_t *new_nr_pdcp_entity( bool has_sdap_tx, void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, char *buf, int size, - uint32_t mac, uint32_t header, uint32_t count), + const nr_pdcp_integrity_data_t *msg_integrity), void *deliver_sdu_data, void (*deliver_pdu)(void *deliver_pdu_data, ue_id_t ue_id, int rb_id, char *buf, int size, int sdu_id), diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_data.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_data.h new file mode 100644 index 0000000000..6f14a7092a --- /dev/null +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_data.h @@ -0,0 +1,34 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef _NR_PDCP_INTEGRITY_DATA_H_ +#define _NR_PDCP_INTEGRITY_DATA_H_ + +#include + +typedef struct { + uint32_t count; + uint8_t mac[4]; + uint8_t header_size; + uint8_t header[3]; +} nr_pdcp_integrity_data_t; + +#endif /* _NR_PDCP_INTEGRITY_DATA_H_ */ diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index f0480f7be1..b3b756addc 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -659,7 +659,7 @@ uint64_t nr_pdcp_module_init(uint64_t _pdcp_optmask, int id) static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity, char *buf, int size, - uint32_t mac, uint32_t header, uint32_t count) + const nr_pdcp_integrity_data_t *msg_integrity) { nr_pdcp_ue_t *ue = _ue; int rb_id; @@ -743,7 +743,7 @@ static void deliver_pdu_drb_gnb(void *deliver_pdu_data, ue_id_t ue_id, int rb_id static void deliver_sdu_srb(void *_ue, nr_pdcp_entity_t *entity, char *buf, int size, - uint32_t mac, uint32_t header, uint32_t count) + const nr_pdcp_integrity_data_t *msg_integrity) { nr_pdcp_ue_t *ue = _ue; int srb_id; @@ -784,9 +784,7 @@ 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; + memcpy(&NR_RRC_DCCH_DATA_IND(message_p).msg_integrity, msg_integrity, sizeof(*msg_integrity)); ue_id_t ue_id = ue->ue_id; itti_send_msg_to_task(TASK_RRC_NRUE, ue_id, message_p); } @@ -1069,9 +1067,7 @@ bool nr_pdcp_check_integrity_srb(ue_id_t ue_id, int srb_id, const uint8_t *msg, int msg_size, - uint32_t mac, - uint32_t header, - uint32_t count) + const nr_pdcp_integrity_data_t *msg_integrity) { nr_pdcp_ue_t *ue; nr_pdcp_entity_t *rb; @@ -1088,7 +1084,7 @@ bool nr_pdcp_check_integrity_srb(ue_id_t ue_id, return false; } - bool ret = rb->check_integrity(rb, msg, msg_size, mac, header, count); + bool ret = rb->check_integrity(rb, msg, msg_size, msg_integrity); nr_pdcp_manager_unlock(nr_pdcp_ue_manager); diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h index 2e87aa9023..99f7fcdc81 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h @@ -91,9 +91,7 @@ bool nr_pdcp_check_integrity_srb(ue_id_t ue_id, int srb_id, const uint8_t *msg, int msg_size, - uint32_t mac, - uint32_t header, - uint32_t count); + const nr_pdcp_integrity_data_t *msg_integrity); bool cu_f1u_data_req(protocol_ctxt_t *ctxt_pP, const srb_flag_t srb_flagP, diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.c index 48af4b945a..783bc1c3bc 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.c @@ -25,7 +25,7 @@ #include nr_pdcp_sdu_t *nr_pdcp_new_sdu(uint32_t count, char *buffer, int size, - uint32_t mac, uint32_t header) + const nr_pdcp_integrity_data_t *msg_integrity) { nr_pdcp_sdu_t *ret = calloc(1, sizeof(nr_pdcp_sdu_t)); if (ret == NULL) @@ -36,8 +36,7 @@ nr_pdcp_sdu_t *nr_pdcp_new_sdu(uint32_t count, char *buffer, int size, exit(1); memcpy(ret->buffer, buffer, size); ret->size = size; - ret->mac = mac; - ret->header = header; + memcpy(&ret->msg_integrity, msg_integrity, sizeof(*msg_integrity)); return ret; } diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.h index 91d63fefe1..0452e71cfa 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.h @@ -24,24 +24,18 @@ #include +#include "nr_pdcp_integrity_data.h" + typedef struct nr_pdcp_sdu_t { - uint32_t count; - char *buffer; - int size; - uint32_t mac; - /* 'header' is decomposed into two parts: higher byte is the size of the - * header (2 or 3 bytes), then the next two or three bytes are the header - * so the size is: (header >> 24) & 0xff - * and first byte of header is: (header >> 16) & 0xff - * second byte of header is: (header >> 8) & 0xff - * and if there is a third, it is: header & 0xff - */ - uint32_t header; - struct nr_pdcp_sdu_t *next; + uint32_t count; + char *buffer; + int size; + nr_pdcp_integrity_data_t msg_integrity; + struct nr_pdcp_sdu_t *next; } nr_pdcp_sdu_t; nr_pdcp_sdu_t *nr_pdcp_new_sdu(uint32_t count, char *buffer, int size, - uint32_t mac, uint32_t header); + const nr_pdcp_integrity_data_t *msg_integrity); nr_pdcp_sdu_t *nr_pdcp_sdu_list_add(nr_pdcp_sdu_t *l, nr_pdcp_sdu_t *sdu); int nr_pdcp_sdu_in_list(nr_pdcp_sdu_t *l, uint32_t count); void nr_pdcp_free_sdu(nr_pdcp_sdu_t *sdu); diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 20e941f90f..9e09db1a72 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -1008,9 +1008,7 @@ static void nr_rrc_ue_process_securityModeCommand(NR_UE_RRC_INST_t *ue_rrc, int srb_id, const uint8_t *msg, int msg_size, - uint32_t mac, - uint32_t header, - uint32_t count) + const nr_pdcp_integrity_data_t *msg_integrity) { LOG_I(NR_RRC, "Receiving from SRB1 (DL-DCCH), Processing securityModeCommand\n"); @@ -1072,7 +1070,7 @@ static void nr_rrc_ue_process_securityModeCommand(NR_UE_RRC_INST_t *ue_rrc, // 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); + bool integrity_pass = nr_pdcp_check_integrity_srb(ue_rrc->ue_id, srb_id, msg, msg_size, msg_integrity); if (!integrity_pass) { /* - continue using the configuration used prior to the reception of the SecurityModeCommand message, i.e. * neither apply integrity protection nor ciphering. @@ -1589,10 +1587,7 @@ static int nr_rrc_ue_decode_dcch(NR_UE_RRC_INST_t *rrc, const uint8_t *const Buffer, size_t Buffer_size, const uint8_t gNB_indexP, - uint32_t mac, - uint32_t header, - uint32_t count) - + const nr_pdcp_integrity_data_t *msg_integrity) { NR_DL_DCCH_Message_t *dl_dcch_msg = NULL; if (Srb_id != 1 && Srb_id != 2) { @@ -1676,7 +1671,7 @@ static int nr_rrc_ue_decode_dcch(NR_UE_RRC_INST_t *rrc, 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, - Srb_id, Buffer, Buffer_size, mac, header, count); + Srb_id, Buffer, Buffer_size, msg_integrity); break; } } break; @@ -1782,9 +1777,7 @@ void *rrc_nrue(void *notUsed) 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).mac, - NR_RRC_DCCH_DATA_IND(msg_p).header, - NR_RRC_DCCH_DATA_IND(msg_p).count); + &NR_RRC_DCCH_DATA_IND(msg_p).msg_integrity); break; case NAS_KENB_REFRESH_REQ: